16191277 problem in SERVICE/FTP-SERVER
authorTomas Klacko <tomas.klacko@oracle.com>
Thu, 13 Jun 2013 15:56:39 -0700
changeset 1343 a66d36656846
parent 1342 1b53e0a91d50
child 1344 48d2ae15d995
16191277 problem in SERVICE/FTP-SERVER 16761173 proftpd in inetd mode, randomly fails to accept connections
components/proftpd/Makefile
components/proftpd/mod_gss-patches/ip4-mapped-gss-channel-bindings.patch
components/proftpd/patches/disable_mod_ctrls_for_inetd_3819.patch
components/proftpd/patches/encode-bug3769.patch
components/proftpd/patches/getipnodebyname.patch
components/proftpd/patches/mod_tls_self_signed.patch
components/proftpd/patches/proftpd-error_code.patch
components/proftpd/patches/proftpd-ioctl-s11.patch
components/proftpd/patches/proftpd-retry.patch
components/proftpd/proftpd.p5m
components/proftpd/resolve.deps
--- a/components/proftpd/Makefile	Thu Jun 13 06:49:48 2013 -0700
+++ b/components/proftpd/Makefile	Thu Jun 13 15:56:39 2013 -0700
@@ -26,24 +26,24 @@
 include ../../make-rules/shared-macros.mk
 
 COMPONENT_NAME=		proftpd
-COMPONENT_VERSION=	1.3.3
-COMPONENT_SUBVERSION=	g
+COMPONENT_VERSION=	1.3.4
+COMPONENT_SUBVERSION=	c
 HUMAN_VERSION=		$(COMPONENT_VERSION)$(COMPONENT_SUBVERSION)
 COMPONENT_PROJECT_URL=	http://www.proftpd.org/
 COMPONENT_SRC=		$(COMPONENT_NAME)-$(HUMAN_VERSION)
 COMPONENT_ARCHIVE=	$(COMPONENT_SRC).tar.gz
 COMPONENT_ARCHIVE_HASH=	\
-    sha256:1705192f8053978fdfc02d89ff500b385d7703555ac311d31c0d1c3accaaec76
+    sha256:fb80dd422969b8c900920a30a56f5e272862275d244d3857a980f5f2386ea912
 COMPONENT_ARCHIVE_URL=	ftp://ftp.proftpd.org/distrib/source/$(COMPONENT_ARCHIVE)
 COMPONENT_BUGDB=	service/ftp-server
 
 # mod_gss subcomponent
 COMPONENT_NAME_1=	mod_gss
-COMPONENT_VERSION_1=	$(COMPONENT_VERSION)
+COMPONENT_VERSION_1=	1.3.6
 COMPONENT_SRC_1=	$(COMPONENT_NAME_1)-$(COMPONENT_VERSION_1)
 COMPONENT_ARCHIVE_1=	$(COMPONENT_SRC_1).tar.gz
 COMPONENT_ARCHIVE_HASH_1= \
-    sha256:24702cf0333720730cc269eb30529061365b1384fdce274bc3d46ccfc300934e
+    sha256:bd1cb3f8ba0668981beb54d8b4de10ab204199327a464debd9da19196bbb23c4
 COMPONENT_ARCHIVE_URL_1= http://downloads.sourceforge.net/gssmod/$(COMPONENT_ARCHIVE_1)
 
 include ../../make-rules/prep.mk
@@ -82,7 +82,6 @@
 	cd $(BUILD_DIR) ; \
 	$(UNPACK) $(UNPACK_ARGS) ../$(COMPONENT_ARCHIVE_1) ; \
 	cd $(COMPONENT_SRC_1) ; \
-	$(GPATCH) -p1 < ../../mod_gss-patches/*; \
 	./configure CC="$(CC)" CFLAGS="-I/usr/include/kerberosv5" ; \
 	$(CP) mod_gss.c mod_auth_gss.c $(SOURCE_DIR)/contrib ; \
 	$(CP) mod_gss.h $(SOURCE_DIR)/include ; \
--- a/components/proftpd/mod_gss-patches/ip4-mapped-gss-channel-bindings.patch	Thu Jun 13 06:49:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
---- a/mod_gss.c.in
-+++ b/mod_gss.c.in
[email protected]@ -1412,6 +1412,87 @@ MODRET gss_auth(cmd_rec *cmd) {
-     return HANDLED(cmd);
- }
- 
-+#ifdef USE_IPV6 /* { */
-+#define IPV6_STR_SIZE   128
-+
-+static int ip6_to_str(struct in6_addr* addr, char* buf, int size) {
-+
-+    const char *err;
-+
-+    if(size<IPV6_STR_SIZE)
-+        return 0;
-+
-+    memset(buf, 0, size);
-+    err=inet_ntop(AF_INET6, addr, buf, size-1);
-+    if(err!=buf)
-+        return 0;
-+
-+    return 1;
-+}
-+
-+static int ip6_to_ip4(struct in6_addr *ip6, struct in_addr *ip4) {
-+
-+    char buf[IPV6_STR_SIZE];
-+
-+    if (!ip6_to_str(ip6, buf, IPV6_STR_SIZE))
-+        return 0;
-+
-+    const char *ip4_str=strrchr(buf, ':');
-+    if (ip4_str == 0)
-+        return 0;
-+
-+    ip4_str++;
-+    if (!inet_aton(ip4_str, ip4))
-+        return 0;
-+
-+    return 1;
-+}
-+
-+static int set_chan_v4mapped(
-+    gss_channel_bindings_t chan, struct in_addr *ia, struct in_addr *aa) {
-+
-+    if (!ip6_to_ip4(&(session.c->remote_addr->na_addr.v6.sin6_addr), ia))
-+        return 0;
-+
-+    if (!ip6_to_ip4(&(session.c->local_addr->na_addr.v6.sin6_addr), aa))
-+        return 0;
-+
-+    chan->initiator_addrtype = GSS_C_AF_INET;
-+    chan->initiator_address.length = sizeof(struct in_addr);
-+    chan->initiator_address.value = ia;
-+
-+    chan->acceptor_addrtype = GSS_C_AF_INET;
-+    chan->acceptor_address.length = sizeof(struct in_addr);
-+    chan->acceptor_address.value = aa;
-+
-+    chan->application_data.length = 0;
-+    chan->application_data.value = 0;
-+
-+    return 1;
-+}
-+
-+static int try_v4mapped() {
-+
-+    struct in6_addr* addr;
-+
-+    if (pr_netaddr_get_family(session.c->remote_addr) != AF_INET6)
-+        return 0;
-+
-+    if (pr_netaddr_get_family(session.c->local_addr) != AF_INET6)
-+        return 0;
-+
-+    addr = (struct in6_addr*)pr_netaddr_get_inaddr(session.c->remote_addr);
-+    if (!IN6_IS_ADDR_V4MAPPED(addr))
-+        return 0;
-+
-+    addr = (struct in6_addr*)pr_netaddr_get_inaddr(session.c->local_addr);
-+    if (!IN6_IS_ADDR_V4MAPPED(addr))
-+        return 0;
-+
-+    return 1;
-+}
-+#endif /* } */
-+
- /*
-    AUTHENTICATION/SECURITY DATA (ADAT)
- 
[email protected]@ -1527,6 +1608,12 @@ MODRET gss_adat(cmd_rec *cmd) {
-     char *gbuf ;
-   
-     gss_channel_bindings_t chan=GSS_C_NO_CHANNEL_BINDINGS;
-+    gss_channel_bindings_t chan_sl=GSS_C_NO_CHANNEL_BINDINGS;
-+#ifdef USE_IPV6
-+    gss_channel_bindings_t chan_v4m=GSS_C_NO_CHANNEL_BINDINGS;
-+    struct in_addr ia;
-+    struct in_addr aa;
-+#endif
- 
-     if (!gss_engine)
-         return DECLINED(cmd);
[email protected]@ -1631,13 +1718,22 @@ MODRET gss_adat(cmd_rec *cmd) {
- 	    continue;
- 	}
- 
-+        chan_sl = chan;
-+#ifdef USE_IPV6
-+        if (try_v4mapped()) {
-+            chan_v4m = pcalloc(cmd->tmp_pool,sizeof(*chan_v4m));
-+            if (set_chan_v4mapped(chan_v4m, &ia, &aa))
-+                chan_sl = chan_v4m;
-+        }
-+#endif
-+
- 	found++;
- 	gcontext = GSS_C_NO_CONTEXT;
- 	accept_maj = gss_accept_sec_context(&accept_min,
- 	   				    &gcontext, /* context_handle */
- 					    server_creds, /* verifier_cred_handle */
- 					    &tok, /* input_token */
--					    chan, /* channel bindings */
-+					    chan_sl, /* channel bindings */
- 					    &client, /* src_name */
- 					    &mechid, /* mech_type */
- 					    &out_tok, /* output_token */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/proftpd/patches/disable_mod_ctrls_for_inetd_3819.patch	Thu Jun 13 15:56:39 2013 -0700
@@ -0,0 +1,44 @@
+--- a/modules/mod_ctrls.c
++++ b/modules/mod_ctrls.c
[email protected]@ -1157,7 +1157,8 @@ static void ctrls_shutdown_ev(const void *event_data, void *user_data) {
+ }
+ 
+ static void ctrls_postparse_ev(const void *event_data, void *user_data) {
+-  if (!ctrls_engine) {
++  if (ctrls_engine == FALSE ||
++      ServerType == SERVER_INETD) {
+     return;
+   }
+ 
+diff --git a/src/ctrls.c b/src/ctrls.c
+index 232bb7d..1f47c73 100644
+--- a/src/ctrls.c
++++ b/src/ctrls.c
[email protected]@ -1975,7 +1975,7 @@ void init_ctrls(void) {
+ 
+   sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+   if (sockfd < 0) {
+-    pr_log_pri(PR_LOG_DEBUG, "unable to create Unix domain socket: %s",
++    pr_log_debug(DEBUG10, "unable to create Unix domain socket: %s",
+       strerror(errno));
+     return;
+   }
[email protected]@ -1986,7 +1986,7 @@ void init_ctrls(void) {
+   socklen = sizeof(struct sockaddr_un);
+ 
+   if (bind(sockfd, (struct sockaddr *) &sockun, socklen) < 0) {
+-    pr_log_pri(PR_LOG_DEBUG,
++    pr_log_debug(DEBUG10,
+       "unable to bind to Unix domain socket at '%s': %s",
+       sockpath, strerror(errno));
+     (void) close(sockfd);
[email protected]@ -1995,7 +1995,7 @@ void init_ctrls(void) {
+   }
+ 
+   if (fstat(sockfd, &st) < 0) {
+-    pr_log_pri(PR_LOG_DEBUG,
++    pr_log_debug(DEBUG10,
+       "unable to stat Unix domain socket at '%s': %s",
+       sockpath, strerror(errno));
+     (void) close(sockfd);
+
--- a/components/proftpd/patches/encode-bug3769.patch	Thu Jun 13 06:49:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
---- a/src/encode.c
-+++ b/src/encode.c
[email protected]@ -194,10 +194,12 @@ int encode_init(void) {
- 
- char *pr_decode_str(pool *p, const char *in, size_t inlen, size_t *outlen) {
- #ifdef HAVE_ICONV
--  size_t inbuflen, outbuflen;
-+  size_t inbuflen, outbuflen, outbufsz;
-   char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res = NULL;
- 
--  if (!p || !in || !outlen) {
-+  if (p == NULL ||
-+      in == NULL ||
-+      outlen == NULL) {
-     errno = EINVAL;
-     return NULL;
-   }
[email protected]@ -229,7 +231,11 @@ char *pr_decode_str(pool *p, const char *in, size_t inlen, size_t *outlen) {
-     return NULL;
- 
-   *outlen = sizeof(outbuf) - outbuflen;
--  res = pcalloc(p, *outlen);
-+
-+  /* We allocate one byte more, for a terminating NUL. */
-+  outbufsz = sizeof(outbuf) - outbuflen + 1;
-+  res = pcalloc(p, outbufsz);
-+
-   memcpy(res, outbuf, *outlen);
- 
-   return res;
[email protected]@ -242,10 +248,12 @@ char *pr_decode_str(pool *p, const char *in, size_t inlen, size_t *outlen) {
- 
- char *pr_encode_str(pool *p, const char *in, size_t inlen, size_t *outlen) {
- #ifdef HAVE_ICONV
--  size_t inbuflen, outbuflen;
-+  size_t inbuflen, outbuflen, outbufsz;
-   char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res;
- 
--  if (!p || !in || !outlen) {
-+  if (p == NULL ||
-+      in == NULL ||
-+      outlen == NULL) {
-     errno = EINVAL;
-     return NULL;
-   }
[email protected]@ -277,7 +285,11 @@ char *pr_encode_str(pool *p, const char *in, size_t inlen, size_t *outlen) {
-     return NULL;
- 
-   *outlen = sizeof(outbuf) - outbuflen;
--  res = pcalloc(p, *outlen);
-+
-+  /* We allocate one byte more, for a terminating NUL. */
-+  outbufsz = sizeof(outbuf) - outbuflen + 1;
-+
-+  res = pcalloc(p, outbufsz);
-   memcpy(res, outbuf, *outlen);
- 
-   return res;
-diff --git a/src/fsio.c b/src/fsio.c
-index 40ef466..8bf5069 100644
---- a/src/fsio.c
-+++ b/src/fsio.c
[email protected]@ -2058,7 +2058,7 @@ char *pr_fs_decode_path(pool *p, const char *path) {
-     return (char *) path;
-   }
- 
--  res = pr_decode_str(p, path, strlen(path) + 1, &outlen);
-+  res = pr_decode_str(p, path, strlen(path), &outlen);
-   if (!res) {
-     pr_trace_msg("encode", 1, "error decoding path '%s': %s", path,
-       strerror(errno));
[email protected]@ -2081,7 +2081,7 @@ char *pr_fs_encode_path(pool *p, const char *path) {
-     return (char *) path;
-   }
- 
--  res = pr_encode_str(p, path, strlen(path) + 1, &outlen);
-+  res = pr_encode_str(p, path, strlen(path), &outlen);
-   if (!res) {
-     pr_trace_msg("encode", 1, "error encoding path '%s': %s", path,
-       strerror(errno));
-
--- a/components/proftpd/patches/getipnodebyname.patch	Thu Jun 13 06:49:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
---- a/src/netaddr.c
-+++ b/src/netaddr.c
[email protected]@ -1295,12 +1295,19 @@ const char *pr_netaddr_get_dnsstr(pr_netaddr_t *na) {
-     buf[sizeof(buf)-1] = '\0';
- 
-     if (res == 0) {
-+      int err_num;
-+      int flags;
-       char **checkaddr;
-       struct hostent *hent = NULL;
-       unsigned char ok = FALSE;
-       int family = pr_netaddr_get_family(na);
-       void *inaddr = pr_netaddr_get_inaddr(na);
--    
-+
-+//#ifdef HAVE_GETIPNODEBYNAME
-+#if 1
-+      flags=AI_V4MAPPED;
-+      hent=getipnodebyname(buf, family, flags, &err_num);
-+#else
- #ifdef HAVE_GETHOSTBYNAME2
-       if (pr_netaddr_is_v4mappedv6(na) == TRUE) {
-         family = AF_INET;
[email protected]@ -1311,6 +1318,7 @@ const char *pr_netaddr_get_dnsstr(pr_netaddr_t *na) {
- #else
-       hent = gethostbyname(buf);
- #endif /* HAVE_GETHOSTBYNAME2 */
-+#endif /* HAVE_GETIPNODEBYNAME */
- 
-       if (hent != NULL) {
- 
-
--- a/components/proftpd/patches/mod_tls_self_signed.patch	Thu Jun 13 06:49:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
---- a/contrib/mod_tls.c
-+++ b/contrib/mod_tls.c
[email protected]@ -3962,6 +3962,7 @@ static int tls_verify_cb(int ok, X509_STORE_CTX *ctx) {
-       case X509_V_ERR_CERT_HAS_EXPIRED:
-       case X509_V_ERR_CERT_REVOKED:
-       case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
-+      case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
-       case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
-       case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
-       case X509_V_ERR_APPLICATION_VERIFICATION:
[email protected]@ -3986,17 +3987,6 @@ static int tls_verify_cb(int ok, X509_STORE_CTX *ctx) {
-         break;
-       }
- 
--      case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
--        /* XXX this is strange. we get this error for certain clients
--         * (i.e. Jeff Altman's kftp) when all is ok. I think it's because the
--         * client is actually sending the whole CA cert. This must be figured
--         * out, but we let it pass for now. If the CA cert isn't available
--         * locally, we will fail anyway.
--         */
--        tls_log("%s", X509_verify_cert_error_string(ctx->error));
--        ok = 1;
--        break;
--
-       default:
-         tls_log("error verifying client certificate: [%d] %s",
-           ctx->error, X509_verify_cert_error_string(ctx->error));
-
--- a/components/proftpd/patches/proftpd-error_code.patch	Thu Jun 13 06:49:48 2013 -0700
+++ b/components/proftpd/patches/proftpd-error_code.patch	Thu Jun 13 15:56:39 2013 -0700
@@ -1,20 +1,36 @@
---- proftpd-1.3.3e/modules/mod_core.c	Sun Feb 20 18:36:38 2011
-+++ proftpd-1.3.3e/modules/mod_core.c	Tue Jun  7 02:34:09 2011
[email protected]@ -3974,11 +3974,13 @@
-   dir = dir_canonical_path(cmd->tmp_pool, dir);
+--- a/include/dirtree.h
++++ b/include/dirtree.h
[email protected]@ -113,6 +113,9 @@ typedef struct cmd_struc {
+   pr_table_t *notes;		/* Private data for passing/retaining between handlers */
+ 
+   int cmd_id;			/* Index into commands list, for faster comparisons */
++  int error_code;               /* Stores errno of failed file transfer
++                                 * commands. Required for Solaris auditing.
++                                 */
+ } cmd_rec;
  
-   if (!dir) {
+ struct config_struc {
+diff --git a/modules/mod_core.c b/modules/mod_core.c
+index ff400f6..18a47c2 100644
+--- a/modules/mod_core.c
++++ b/modules/mod_core.c
[email protected]@ -4554,6 +4554,7 @@ MODRET core_rmd(cmd_rec *cmd) {
+   dir = dir_canonical_path(cmd->tmp_pool, dir);
+   if (dir == NULL) {
+     int xerrno = EINVAL;
 +    cmd->error_code = EINVAL;
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EINVAL));
-     return PR_ERROR(cmd);
-   }
+ 
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
+ 
[email protected]@ -4563,6 +4564,7 @@ MODRET core_rmd(cmd_rec *cmd) {
  
    if (!dir_check_canon(cmd->tmp_pool, cmd, cmd->group, dir, NULL)) {
+     int xerrno = EACCES;
 +    cmd->error_code = EACCES;
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EACCES));
-     return PR_ERROR(cmd);
-   }
[email protected]@ -3985,6 +3987,7 @@
+ 
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
+ 
[email protected]@ -4572,6 +4574,7 @@ MODRET core_rmd(cmd_rec *cmd) {
  
    if (pr_fsio_rmdir(dir) < 0) {
      int xerrno = errno;
@@ -22,83 +38,71 @@
  
      (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
        "error removing directory '%s': %s", cmd->argv[0], session.user,
[email protected]@ -4033,11 +4036,13 @@
- 
[email protected]@ -4628,6 +4631,7 @@ MODRET core_mkd(cmd_rec *cmd) {
    dir = dir_canonical_path(cmd->tmp_pool, dir);
-   if (!dir) {
+   if (dir == NULL) {
+     int xerrno = EINVAL;
 +    cmd->error_code = EINVAL;
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EINVAL));
-     return PR_ERROR(cmd);
-   }
+ 
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
+ 
[email protected]@ -4637,6 +4641,7 @@ MODRET core_mkd(cmd_rec *cmd) {
  
    if (!dir_check_canon(cmd->tmp_pool, cmd, cmd->group, dir, NULL)) {
+     int xerrno = EACCES;
 +    cmd->error_code = EACCES;
+ 
      pr_log_debug(DEBUG8, "%s command denied by <Limit> config", cmd->argv[0]);
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EACCES));
-     return PR_ERROR(cmd);
[email protected]@ -4045,6 +4050,7 @@
- 
-   if (pr_fsio_mkdir(dir, 0777) < 0) {
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
[email protected]@ -4648,6 +4653,7 @@ MODRET core_mkd(cmd_rec *cmd) {
+   if (pr_fsio_smkdir(cmd->tmp_pool, dir, 0777, session.fsuid,
+       session.fsgid) < 0) {
      int xerrno = errno;
 +    cmd->error_code = errno;
  
      (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
        "error making directory '%s': %s", cmd->argv[0], session.user,
[email protected]@ -4067,6 +4073,7 @@
-     if (pr_fsio_chown(dir, session.fsuid, session.fsgid) == -1) {
-       iserr++;
-       err = errno;
-+      cmd->error_code = errno;
-     }
-     PRIVS_RELINQUISH
- 
[email protected]@ -4111,6 +4118,7 @@
-     }
- 
-     if (res == -1) {
-+      cmd->error_code = errno;
-       pr_log_pri(PR_LOG_WARNING, "%schown() failed: %s",
-         use_root_privs ? "root " : "", strerror(errno));
- 
[email protected]@ -4153,6 +4161,7 @@
-   if (!path ||
[email protected]@ -4694,6 +4700,7 @@ MODRET core_mdtm(cmd_rec *cmd) {
        !dir_check(cmd->tmp_pool, cmd, cmd->group, path, NULL) ||
        pr_fsio_stat(path, &st) == -1) {
+     int xerrno = errno;
 +    cmd->error_code = errno;
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno));
-     return PR_ERROR(cmd);
+ 
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
  
[email protected]@ -4251,11 +4260,13 @@
-   /* If told to delete a symlink, don't delete the file it points to!  */
[email protected]@ -4805,6 +4812,7 @@ MODRET core_dele(cmd_rec *cmd) {
    path = dir_canonical_path(cmd->tmp_pool, path);
-   if (!path) {
-+    cmd->error_code = ENOENT;
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(ENOENT));
-     return PR_ERROR(cmd);
-   }
+   if (path == NULL) {
+     int xerrno = ENOENT;
++    cmd->error_code = ENONET;
+ 
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
+ 
[email protected]@ -4814,6 +4822,7 @@ MODRET core_dele(cmd_rec *cmd) {
  
    if (!dir_check_canon(cmd->tmp_pool, cmd, cmd->group, path, NULL)) {
+     int xerrno = errno;
 +    cmd->error_code = errno;
+ 
      pr_log_debug(DEBUG7, "deleting '%s' denied by <Limit> configuration", path);
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno));
-     return PR_ERROR(cmd);
[email protected]@ -4268,6 +4279,7 @@
-   memset(&st, 0, sizeof(st));
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
[email protected]@ -4830,6 +4839,7 @@ MODRET core_dele(cmd_rec *cmd) {
    pr_fs_clear_cache();
    if (pr_fsio_lstat(path, &st) < 0) {
+     int xerrno = errno;
 +    cmd->error_code = errno;
-     pr_log_debug(DEBUG3, "unable to lstat '%s': %s", path, strerror(errno));
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno));
-     return PR_ERROR(cmd);
[email protected]@ -4278,6 +4290,7 @@
-    * EISDIR).
+ 
+     pr_log_debug(DEBUG3, "unable to lstat '%s': %s", path, strerror(xerrno));
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
[email protected]@ -4844,6 +4854,7 @@ MODRET core_dele(cmd_rec *cmd) {
     */
    if (S_ISDIR(st.st_mode)) {
+     int xerrno = EISDIR;
 +    cmd->error_code = EISDIR;
+ 
      (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
        "error deleting '%s': %s", cmd->argv[0], session.user,
-       (unsigned long) session.uid, (unsigned long) session.gid, path,
[email protected]@ -4291,6 +4304,7 @@
[email protected]@ -4860,6 +4871,7 @@ MODRET core_dele(cmd_rec *cmd) {
   
    if (pr_fsio_unlink(path) < 0) {
      int xerrno = errno;
@@ -106,7 +110,7 @@
  
      (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
        "error deleting '%s': %s", cmd->argv[0], session.user,
[email protected]@ -4375,6 +4389,7 @@
[email protected]@ -4951,6 +4963,7 @@ MODRET core_rnto(cmd_rec *cmd) {
        !dir_check_canon(cmd->tmp_pool, cmd, cmd->group, path, NULL) ||
        pr_fsio_rename(session.xfer.path, path) == -1) {
      int xerrno = errno;
@@ -114,7 +118,7 @@
  
      if (xerrno != EXDEV) {
        (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
[email protected]@ -4391,6 +4406,7 @@
[email protected]@ -4997,6 +5010,7 @@ MODRET core_rnto(cmd_rec *cmd) {
       */
      if (pr_fs_copy_file(session.xfer.path, path) < 0) {
        xerrno = errno;
@@ -122,7 +126,7 @@
  
        (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
          "error copying '%s' to '%s': %s", cmd->argv[0], session.user,
[email protected]@ -4404,6 +4420,8 @@
[email protected]@ -5012,6 +5026,8 @@ MODRET core_rnto(cmd_rec *cmd) {
  
      /* Once copied, unlink the original file. */
      if (pr_fsio_unlink(session.xfer.path) < 0) {
@@ -131,17 +135,19 @@
        pr_log_debug(DEBUG0, "error unlinking '%s': %s", session.xfer.path,
          strerror(errno));
      }
[email protected]@ -4458,6 +4476,7 @@
-   if (!path ||
[email protected]@ -5069,6 +5085,7 @@ MODRET core_rnfr(cmd_rec *cmd) {
        !dir_check_canon(cmd->tmp_pool, cmd, cmd->group, path, NULL) ||
        !exists(path)) {
+     int xerrno = errno;
 +    cmd->error_code = errno;
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno));
-     return PR_ERROR(cmd);
-   }
---- proftpd-1.3.3e/modules/mod_xfer.c	Fri Feb 25 18:46:45 2011
-+++ x/proftpd-1.3.3e/modules/mod_xfer.c	Tue Jun  7 03:45:03 2011
[email protected]@ -1180,6 +1180,7 @@
+ 
+     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
+ 
+diff --git a/modules/mod_xfer.c b/modules/mod_xfer.c
+index c153bb3..762b542 100644
+--- a/modules/mod_xfer.c
++++ b/modules/mod_xfer.c
[email protected]@ -1211,6 +1211,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
  
    if (cmd->argc < 2) {
      pr_response_add_err(R_500, _("'%s' not understood"), get_full_cmd(cmd));
@@ -149,15 +155,15 @@
      errno = EINVAL;
      return PR_ERROR(cmd);
    }
[email protected]@ -1190,6 +1191,7 @@
[email protected]@ -1221,6 +1222,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
    if (!path ||
        !dir_check(cmd->tmp_pool, cmd, cmd->group, path, NULL)) {
      int xerrno = errno;
 +    cmd->error_code = errno;
  
-     pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
- 
[email protected]@ -1200,6 +1202,7 @@
+     pr_log_debug(DEBUG8, "%s %s denied by <Limit> configuration", cmd->argv[0],
+       cmd->arg);
[email protected]@ -1233,6 +1235,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
    if (xfer_check_limit(cmd) < 0) {
      pr_response_add_err(R_451, _("%s: Too many transfers"), cmd->arg);
      errno = EPERM;
@@ -165,7 +171,7 @@
      return PR_ERROR(cmd);
    }
  
[email protected]@ -1212,6 +1215,7 @@
[email protected]@ -1245,6 +1248,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
      pr_log_debug(DEBUG6, "AllowOverwrite denied permission for %s", cmd->arg);
      pr_response_add_err(R_550, _("%s: Overwrite permission denied"), cmd->arg);
      errno = EACCES;
@@ -173,23 +179,24 @@
      return PR_ERROR(cmd);
    }
  
[email protected]@ -1233,6 +1237,7 @@
-        ) {
-       pr_response_add_err(R_550, _("%s: Not a regular file"), cmd->arg);
-       errno = EPERM;
-+      cmd->error_code = EPERM;
[email protected]@ -1268,6 +1272,8 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
+ 
+       /* Deliberately use EISDIR for anything non-file (e.g. directories). */
+       errno = EISDIR;
++      cmd->error_code = EISDIR;
++
        return PR_ERROR(cmd);
      }
    }
[email protected]@ -1250,6 +1255,7 @@
-       cmd->arg);
[email protected]@ -1286,6 +1292,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
      session.restart_pos = 0L;
      session.xfer.xfer_type = STOR_DEFAULT;
+     errno = EPERM;
 +    cmd->error_code = EPERM;
-     errno = EPERM;
      return PR_ERROR(cmd);
    }
[email protected]@ -1256,9 +1262,11 @@
+ 
[email protected]@ -1304,9 +1311,11 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
  
    /* Otherwise everthing is good */
    if (pr_table_add(cmd->notes, "mod_xfer.store-path",
@@ -202,15 +209,23 @@
  
    c = find_config(CURRENT_CONF, CONF_PARAM, "HiddenStores", FALSE);
    if (c &&
[email protected]@ -1269,6 +1277,7 @@
-     if (session.restart_pos) {
[email protected]@ -1319,6 +1328,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
        pr_response_add_err(R_501,
          _("REST not compatible with server configuration"));
+       errno = EINVAL;
 +      cmd->error_code = EINVAL;
-       errno = EINVAL;
        return PR_ERROR(cmd);
      }
[email protected]@ -1333,6 +1342,7 @@
+ 
[email protected]@ -1328,6 +1338,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) {
+       pr_response_add_err(R_550,
+         _("APPE not compatible with server configuration"));
+       errno = EINVAL;
++      cmd->error_code = EINVAL;
+       return PR_ERROR(cmd);
+     }
+ 
[email protected]@ -1391,6 +1402,7 @@ MODRET xfer_pre_stou(cmd_rec *cmd) {
  
    tmpfd = mkstemp(filename);
    if (tmpfd < 0) {
@@ -218,15 +233,15 @@
      pr_log_pri(PR_LOG_ERR, "error: unable to use mkstemp(): %s",
        strerror(errno));
  
[email protected]@ -1357,6 +1367,7 @@
- 
[email protected]@ -1416,6 +1428,7 @@ MODRET xfer_pre_stou(cmd_rec *cmd) {
    if (!filename ||
        !dir_check(cmd->tmp_pool, cmd, cmd->group, filename, NULL)) {
+     int xerrno = errno;
 +    cmd->error_code = errno;
-     int xerrno = errno;
  
      /* Do not forget to delete the file created by mkstemp(3) if there is
[email protected]@ -1434,6 +1445,7 @@
+      * an error.
[email protected]@ -1495,6 +1508,7 @@ MODRET xfer_pre_appe(cmd_rec *cmd) {
    if (xfer_check_limit(cmd) < 0) {
      pr_response_add_err(R_451, _("%s: Too many transfers"), cmd->arg);
      errno = EPERM;
@@ -234,7 +249,7 @@
      return PR_ERROR(cmd);
    }
  
[email protected]@ -1487,6 +1499,7 @@
[email protected]@ -1550,6 +1564,7 @@ MODRET xfer_stor(cmd_rec *cmd) {
        O_WRONLY|(session.restart_pos ? 0 : O_CREAT|O_EXCL));
      if (stor_fh == NULL) {
        ferrno = errno;
@@ -242,7 +257,7 @@
  
        (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
          "error opening '%s': %s", cmd->argv[0], session.user,
[email protected]@ -1499,6 +1512,7 @@
[email protected]@ -1562,6 +1577,7 @@ MODRET xfer_stor(cmd_rec *cmd) {
  
      if (stor_fh) {
        if (pr_fsio_lseek(stor_fh, 0, SEEK_END) == (off_t) -1) {
@@ -250,7 +265,7 @@
          pr_log_debug(DEBUG4, "unable to seek to end of '%s' for appending: %s",
            cmd->arg, strerror(errno));
          (void) pr_fsio_close(stor_fh);
[email protected]@ -1507,6 +1521,7 @@
[email protected]@ -1570,6 +1586,7 @@ MODRET xfer_stor(cmd_rec *cmd) {
  
      } else {
        ferrno = errno;
@@ -258,7 +273,7 @@
  
        (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
          "error opening '%s': %s", cmd->argv[0], session.user,
[email protected]@ -1520,6 +1535,7 @@
[email protected]@ -1583,6 +1600,7 @@ MODRET xfer_stor(cmd_rec *cmd) {
          O_WRONLY|(session.restart_pos ? 0 : O_TRUNC|O_CREAT));
      if (stor_fh == NULL) {
        ferrno = errno;
@@ -266,7 +281,7 @@
  
        (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
          "error opening '%s': %s", cmd->argv[0], session.user,
[email protected]@ -1533,11 +1549,13 @@
[email protected]@ -1596,11 +1614,13 @@ MODRET xfer_stor(cmd_rec *cmd) {
      int xerrno = 0;
  
      if (pr_fsio_lseek(stor_fh, session.restart_pos, SEEK_SET) == -1) {
@@ -280,7 +295,7 @@
        pr_log_debug(DEBUG4, "unable to stat '%s': %s", cmd->arg,
          strerror(errno));
        xerrno = errno;
[email protected]@ -1665,6 +1683,7 @@
[email protected]@ -1748,6 +1768,7 @@ MODRET xfer_stor(cmd_rec *cmd) {
      res = pr_fsio_write(stor_fh, lbuf, len);
      if (res != len) {
        int xerrno = EIO;
@@ -288,35 +303,37 @@
  
        if (res < 0)
          xerrno = errno;
[email protected]@ -1716,16 +1735,19 @@
[email protected]@ -1806,18 +1827,21 @@ MODRET xfer_stor(cmd_rec *cmd) {
         */
  #if defined(EDQUOT)
-       if (errno == EDQUOT) {
+       if (xerrno == EDQUOT) {
 +        cmd->error_code = EDQUOT;
-         pr_response_add_err(R_552, "%s: %s", cmd->arg, strerror(errno));
+         pr_response_add_err(R_552, "%s: %s", cmd->arg, strerror(xerrno));
+         errno = xerrno;
          return PR_ERROR(cmd);
        }
  #elif defined(EFBIG)
-       if (errno == EFBIG) {
+       if (xerrno == EFBIG) {
 +        cmd->error_code = EFBIG;
-         pr_response_add_err(R_552, "%s: %s", cmd->arg, strerror(errno));
+         pr_response_add_err(R_552, "%s: %s", cmd->arg, strerror(xerrno));
+         errno = xerrno;
          return PR_ERROR(cmd);
        }
  #endif
  
-+      cmd->error_code = errno;
-       pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno));
++      cmd->error_code = EFBIG;
+       pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
+       errno = xerrno;
        return PR_ERROR(cmd);
-     }
[email protected]@ -1733,6 +1755,7 @@
[email protected]@ -1826,6 +1850,7 @@ MODRET xfer_stor(cmd_rec *cmd) {
      if (session.xfer.path &&
          session.xfer.path_hidden) {
        if (pr_fsio_rename(session.xfer.path_hidden, session.xfer.path) != 0) {
-+         cmd->error_code = errno;
++        cmd->error_code = errno;
  
          /* This should only fail on a race condition with a chmod/chown
           * or if STOR_APPEND is on and the permissions are squirrely.
[email protected]@ -1830,6 +1853,7 @@
[email protected]@ -1924,6 +1949,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) {
    if (cmd->argc < 2) {
      pr_response_add_err(R_500, _("'%s' not understood"), get_full_cmd(cmd));
      errno = EINVAL;
@@ -324,15 +341,15 @@
      return PR_ERROR(cmd);
    }
  
[email protected]@ -1839,6 +1863,7 @@
[email protected]@ -1933,6 +1959,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) {
    if (!dir ||
        !dir_check(cmd->tmp_pool, cmd, cmd->group, dir, NULL)) {
      int xerrno = errno;
-+    cmd->error_code = errno;
++    cmd->error_code = EINVAL;
  
      pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno));
  
[email protected]@ -1849,6 +1874,7 @@
[email protected]@ -1955,6 +1982,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) {
    if (xfer_check_limit(cmd) < 0) {
      pr_response_add_err(R_451, _("%s: Too many transfers"), cmd->arg);
      errno = EPERM;
@@ -340,15 +357,15 @@
      return PR_ERROR(cmd);
    }
  
[email protected]@ -1865,6 +1891,7 @@
-      ) {
-     pr_response_add_err(R_550, _("%s: Not a regular file"), cmd->arg);
-     errno = EPERM;
-+    cmd->error_code = EPERM;
[email protected]@ -1977,6 +2005,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) {
+ 
+     /* Deliberately use EISDIR for anything non-file (e.g. directories). */
+     errno = EISDIR;
++    cmd->error_code = EISDIR;
      return PR_ERROR(cmd);
    }
  
[email protected]@ -1879,6 +1906,7 @@
[email protected]@ -1991,6 +2020,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) {
        cmd->arg);
      session.restart_pos = 0L;
      errno = EPERM;
@@ -356,7 +373,7 @@
      return PR_ERROR(cmd);
    }
  
[email protected]@ -1908,6 +1936,7 @@
[email protected]@ -2020,6 +2050,7 @@ MODRET xfer_retr(cmd_rec *cmd) {
    retr_fh = pr_fsio_open(dir, O_RDONLY);
    if (retr_fh == NULL) {
      int xerrno = errno;
@@ -364,23 +381,25 @@
  
      (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): "
        "error opening '%s': %s", cmd->argv[0], session.user,
[email protected]@ -1921,6 +1950,7 @@
[email protected]@ -2033,6 +2064,8 @@ MODRET xfer_retr(cmd_rec *cmd) {
    if (pr_fsio_stat(dir, &st) < 0) {
      /* Error stat'ing the file. */
      int xerrno = errno;
 +    cmd->error_code = errno;
++
      pr_fsio_close(retr_fh);
      errno = xerrno;
  
[email protected]@ -1945,6 +1975,7 @@
[email protected]@ -2057,6 +2090,8 @@ MODRET xfer_retr(cmd_rec *cmd) {
      if (pr_fsio_lseek(retr_fh, session.restart_pos,
          SEEK_SET) == (off_t) -1) {
        int xerrno = errno;
 +      cmd->error_code = errno;
++
        pr_fsio_close(retr_fh);
        errno = xerrno;
        retr_fh = NULL;
[email protected]@ -2003,6 +2034,7 @@
[email protected]@ -2115,6 +2150,7 @@ MODRET xfer_retr(cmd_rec *cmd) {
      retr_abort();
  
      /* Set errno to EPERM ("Operation not permitted") */
@@ -388,22 +407,12 @@
      pr_data_abort(EPERM, FALSE);
      return PR_ERROR(cmd);
    }
[email protected]@ -2034,6 +2066,7 @@
[email protected]@ -2146,6 +2182,7 @@ MODRET xfer_retr(cmd_rec *cmd) {
         * is preserved; errno itself might be overwritten in retr_abort().
         */
        int xerrno = errno;
 +      cmd->error_code = errno;
  
        retr_abort();
+ 
 
---- proftpd-1.3.3e/include/dirtree.h	Fri Mar 25 17:49:04 2011
-+++ x/proftpd-1.3.3e/include/dirtree.h	Tue Jun  7 02:07:51 2011
[email protected]@ -113,6 +113,8 @@
-   int  class;			/* The command class */
-   int  stash_index;		/* hack to speed up symbol hashing in modules.c */
-   pr_table_t *notes;		/* Private data for passing/retaining between handlers */
-+
-+  int error_code;		/* stores errno of failed file transfer commands*/
- } cmd_rec;
- 
- struct config_struc {
--- a/components/proftpd/patches/proftpd-ioctl-s11.patch	Thu Jun 13 06:49:48 2013 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
---- a/src/inet.c
-+++ b/src/inet.c
[email protected]@ -1238,7 +1238,7 @@ conn_t *pr_inet_openrw(pool *p, conn_t *c, pr_netaddr_t *addr, int strm_type,
-   res->mode = CM_OPEN;
- 
- #if defined(HAVE_STROPTS_H) && defined(I_SRDOPT) && defined(RPROTDIS) && \
--    defined(SOLARIS2)
-+    defined(SOLARIS2) && !defined(SOLARIS2_11)
-   /* This is needed to work around control messages in STREAMS devices
-    * (as on Solaris 9/NFS).
-    */
-
--- a/components/proftpd/patches/proftpd-retry.patch	Thu Jun 13 06:49:48 2013 -0700
+++ b/components/proftpd/patches/proftpd-retry.patch	Thu Jun 13 15:56:39 2013 -0700
@@ -1,32 +1,37 @@
---- proftpd-1.3.3e/src/data.c	Thu Mar  3 09:10:03 2011
-+++ proftpd-1.3.3e/src/data.c	Wed Oct  5 08:07:57 2011
[email protected]@ -337,44 +337,55 @@
+--- a/src/data.c
++++ b/src/data.c
[email protected]@ -333,6 +333,7 @@ static int data_pasv_open(char *reason, off_t size) {
  static int data_active_open(char *reason, off_t size) {
    conn_t *c;
    int rev;
 +  int retries = 0;
+   pr_netaddr_t *bind_addr;
  
    if (!reason && session.xfer.filename)
-     reason = session.xfer.filename;
[email protected]@ -348,45 +349,55 @@ static int data_active_open(char *reason, off_t size) {
+     bind_addr = pr_netaddr_v6tov4(session.xfer.p, session.c->local_addr);
+   }
  
--  session.d = pr_inet_create_conn(session.pool, NULL, -1,
--    session.c->local_addr, session.c->local_port-1, TRUE);
+-  session.d = pr_inet_create_conn(session.pool, -1, bind_addr,
+-    session.c->local_port-1, TRUE);
 +  for (;;) {
-+    session.d = pr_inet_create_conn(session.pool, NULL, -1,
-+      session.c->local_addr, session.c->local_port-1, TRUE);
++    session.d = pr_inet_create_conn(session.pool, -1, bind_addr,
++      session.c->local_port-1, TRUE);
  
 -  /* Set the "stalled" timer, if any, to prevent the connection
 -   * open from taking too long
 -   */
--  if (timeout_stalled)
+-  if (timeout_stalled) {
 -    pr_timer_add(timeout_stalled, PR_TIMER_STALLED, NULL, stalled_timeout_cb,
 -      "TimeoutStalled");
+-  }
 +    /* Set the "stalled" timer, if any, to prevent the connection
 +     * open from taking too long
 +     */
-+    if (timeout_stalled)
++    if (timeout_stalled) {
 +      pr_timer_add(timeout_stalled, PR_TIMER_STALLED, NULL, stalled_timeout_cb,
 +        "TimeoutStalled");
++    }
  
 -  rev = pr_netaddr_set_reverse_dns(ServerUseReverseDNS);
 +    rev = pr_netaddr_set_reverse_dns(ServerUseReverseDNS);
@@ -37,27 +42,34 @@
 -  if (session.xfer.direction == PR_NETIO_IO_RD) {
 -    pr_inet_set_socket_opts(session.d->pool, session.d,
 -      (main_server->tcp_rcvbuf_override ? main_server->tcp_rcvbuf_len : 0), 0);
--    pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
--      0, 1, 1);
 +    if (session.xfer.direction == PR_NETIO_IO_RD) {
 +      pr_inet_set_socket_opts(session.d->pool, session.d,
 +        (main_server->tcp_rcvbuf_override ? main_server->tcp_rcvbuf_len : 0), 0);
-+      pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
-+        0, 1, 1);
      
 -  } else {
 -    pr_inet_set_socket_opts(session.d->pool, session.d,
 -      0, (main_server->tcp_sndbuf_override ? main_server->tcp_sndbuf_len : 0));
--    pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
--      0, 1, 1);
 -  }
 +    } else {
 +      pr_inet_set_socket_opts(session.d->pool, session.d,
 +        0, (main_server->tcp_sndbuf_override ? main_server->tcp_sndbuf_len : 0));
-+      pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
-+        0, 1, 1);
 +    }
  
+-  /* Make sure that the necessary socket options are set on the socket prior
+-   * to the call to connect(2).
+-   */
+-  pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
+-    IPTOS_THROUGHPUT, 1);
+-  pr_inet_generate_socket_event("core.data-connect", main_server,
+-    session.d->local_addr, session.d->listen_fd);
++    /* Make sure that the necessary socket options are set on the socket prior
++     * to the call to connect(2).
++     */
++    pr_inet_set_proto_opts(session.pool, session.d, main_server->tcp_mss_len, 0,
++      IPTOS_THROUGHPUT, 1);
++    pr_inet_generate_socket_event("core.data-connect", main_server,
++      session.d->local_addr, session.d->listen_fd);
+ 
 -  if (pr_inet_connect(session.d->pool, session.d, &session.data_addr,
 +    if (pr_inet_connect(session.d->pool, session.d, &session.data_addr,
        session.data_port) == -1) {
@@ -83,3 +95,4 @@
    }
  
    c = pr_inet_openrw(session.pool, session.d, NULL, PR_NETIO_STRM_DATA,
+
--- a/components/proftpd/proftpd.p5m	Thu Jun 13 06:49:48 2013 -0700
+++ b/components/proftpd/proftpd.p5m	Thu Jun 13 15:56:39 2013 -0700
@@ -158,12 +158,12 @@
 license proftpd.license license="GPLv2 (mod_gss)" \
     com.oracle.info.description="the ProFPTD GSS Engine" \
     com.oracle.info.name=mod_gss \
-    com.oracle.info.tpno=4477 \
-    com.oracle.info.version=1.3.3
+    com.oracle.info.tpno=13480 \
+    com.oracle.info.version=1.3.6
 license proftpd.license license="GPLv2 (proftpd)" \
     com.oracle.info.description="the ProFTPD server and utilities" \
     com.oracle.info.name=proftpd \
-    com.oracle.info.tpno=6824 \
-    com.oracle.info.version=1.3.3g
+    com.oracle.info.tpno=13478 \
+    com.oracle.info.version=1.3.4c
 
 user ftpuser=false gcos-field="FTPD Reserved UID" username="ftp" uid=21 group="ftp"
--- a/components/proftpd/resolve.deps	Thu Jun 13 06:49:48 2013 -0700
+++ b/components/proftpd/resolve.deps	Thu Jun 13 15:56:39 2013 -0700
@@ -5,3 +5,4 @@
 system/library/security/gss
 system/linker
 system/network
+service/security/kerberos-5