diff -r 138732f62341 -r 90c18e89db60 components/proftpd/patches/proftpd-error_code.patch --- a/components/proftpd/patches/proftpd-error_code.patch Fri Aug 09 12:58:20 2013 -0700 +++ b/components/proftpd/patches/proftpd-error_code.patch Mon Aug 12 02:14:11 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 -@@ -3974,11 +3974,13 @@ - dir = dir_canonical_path(cmd->tmp_pool, dir); +--- a/include/dirtree.h ++++ b/include/dirtree.h +@@ -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 +@@ -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)); + +@@ -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); - } -@@ -3985,6 +3987,7 @@ + + pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno)); + +@@ -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, -@@ -4033,11 +4036,13 @@ - +@@ -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)); + +@@ -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 config", cmd->argv[0]); - pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EACCES)); - return PR_ERROR(cmd); -@@ -4045,6 +4050,7 @@ - - if (pr_fsio_mkdir(dir, 0777) < 0) { + pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno)); +@@ -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, -@@ -4067,6 +4073,7 @@ - if (pr_fsio_chown(dir, session.fsuid, session.fsgid) == -1) { - iserr++; - err = errno; -+ cmd->error_code = errno; - } - PRIVS_RELINQUISH - -@@ -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)); - -@@ -4153,6 +4161,7 @@ - if (!path || +@@ -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)); -@@ -4251,11 +4260,13 @@ - /* If told to delete a symlink, don't delete the file it points to! */ +@@ -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)); + +@@ -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 configuration", path); - pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno)); - return PR_ERROR(cmd); -@@ -4268,6 +4279,7 @@ - memset(&st, 0, sizeof(st)); + pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno)); +@@ -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); -@@ -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)); +@@ -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, -@@ -4291,6 +4304,7 @@ +@@ -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, -@@ -4375,6 +4389,7 @@ +@@ -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): " -@@ -4391,6 +4406,7 @@ +@@ -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, -@@ -4404,6 +4420,8 @@ +@@ -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)); } -@@ -4458,6 +4476,7 @@ - if (!path || +@@ -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 -@@ -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 +@@ -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); } -@@ -1190,6 +1191,7 @@ +@@ -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)); - -@@ -1200,6 +1202,7 @@ + pr_log_debug(DEBUG8, "%s %s denied by configuration", cmd->argv[0], + cmd->arg); +@@ -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); } -@@ -1212,6 +1215,7 @@ +@@ -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); } -@@ -1233,6 +1237,7 @@ - ) { - pr_response_add_err(R_550, _("%s: Not a regular file"), cmd->arg); - errno = EPERM; -+ cmd->error_code = EPERM; +@@ -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); } } -@@ -1250,6 +1255,7 @@ - cmd->arg); +@@ -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); } -@@ -1256,9 +1262,11 @@ + +@@ -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 && -@@ -1269,6 +1277,7 @@ - if (session.restart_pos) { +@@ -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); } -@@ -1333,6 +1342,7 @@ + +@@ -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); + } + +@@ -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)); -@@ -1357,6 +1367,7 @@ - +@@ -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 -@@ -1434,6 +1445,7 @@ + * an error. +@@ -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); } -@@ -1487,6 +1499,7 @@ +@@ -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, -@@ -1499,6 +1512,7 @@ +@@ -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); -@@ -1507,6 +1521,7 @@ +@@ -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, -@@ -1520,6 +1535,7 @@ +@@ -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, -@@ -1533,11 +1549,13 @@ +@@ -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; -@@ -1665,6 +1683,7 @@ +@@ -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; -@@ -1716,16 +1735,19 @@ +@@ -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); - } -@@ -1733,6 +1755,7 @@ +@@ -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. -@@ -1830,6 +1853,7 @@ +@@ -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); } -@@ -1839,6 +1863,7 @@ +@@ -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)); -@@ -1849,6 +1874,7 @@ +@@ -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); } -@@ -1865,6 +1891,7 @@ - ) { - pr_response_add_err(R_550, _("%s: Not a regular file"), cmd->arg); - errno = EPERM; -+ cmd->error_code = EPERM; +@@ -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); } -@@ -1879,6 +1906,7 @@ +@@ -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); } -@@ -1908,6 +1936,7 @@ +@@ -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, -@@ -1921,6 +1950,7 @@ +@@ -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; -@@ -1945,6 +1975,7 @@ +@@ -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; -@@ -2003,6 +2034,7 @@ +@@ -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); } -@@ -2034,6 +2066,7 @@ +@@ -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 -@@ -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 {