END_TEST START_TEST (dir_canonical_vpath_test) { char *res; const char *path; res = dir_canonical_vpath(NULL, NULL); fail_unless(res == NULL, "Failed to handle null arguments"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); res = dir_canonical_vpath(p, NULL); fail_unless(res == NULL, "Failed to handle null path"); fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL, strerror(errno), errno); mark_point(); path = "/foo"; res = dir_canonical_vpath(p, path); fail_unless(path != NULL, "Failed to get canonical vpath for '%s': %s", path, strerror(errno)); fail_unless(strcmp(res, path) == 0, "Expected '%s', got '%s'", path, res); }
MODRET copy_cpto(cmd_rec *cmd) { register unsigned int i; const char *from, *to = ""; unsigned char *authenticated = NULL; if (copy_engine == FALSE) { return PR_DECLINED(cmd); } if (cmd->argc < 3 || strncasecmp(cmd->argv[1], "CPTO", 5) != 0) { return PR_DECLINED(cmd); } authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE); if (authenticated == NULL || *authenticated == FALSE) { pr_response_add_err(R_530, _("Please login with USER and PASS")); pr_cmd_set_errno(cmd, EPERM); errno = EPERM; return PR_ERROR(cmd); } CHECK_CMD_MIN_ARGS(cmd, 3); from = pr_table_get(session.notes, "mod_copy.cpfr-path", NULL); if (from == NULL) { pr_response_add_err(R_503, _("Bad sequence of commands")); pr_cmd_set_errno(cmd, EPERM); errno = EPERM; return PR_ERROR(cmd); } /* Construct the target file name by concatenating all the parameters after * the "SITE CPTO", separating them with spaces. */ for (i = 2; i <= cmd->argc-1; i++) { char *decoded_path; decoded_path = pr_fs_decode_path2(cmd->tmp_pool, cmd->argv[i], FSIO_DECODE_FL_TELL_ERRORS); if (decoded_path == NULL) { int xerrno = errno; pr_log_debug(DEBUG8, "'%s' failed to decode properly: %s", (char *) cmd->argv[i], strerror(xerrno)); pr_response_add_err(R_550, _("%s: Illegal character sequence in filename"), cmd->arg); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } to = pstrcat(cmd->tmp_pool, to, *to ? " " : "", decoded_path, NULL); } to = dir_canonical_vpath(cmd->tmp_pool, to); if (copy_paths(cmd->tmp_pool, from, to) < 0) { int xerrno = errno; pr_response_add_err(R_550, "%s: %s", (char *) cmd->argv[1], strerror(xerrno)); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } pr_response_add(R_250, "%s", _("Copy successful")); return PR_HANDLED(cmd); }
MODRET copy_cpfr(cmd_rec *cmd) { register unsigned int i; int res; char *path = ""; unsigned char *authenticated = NULL; if (copy_engine == FALSE) { return PR_DECLINED(cmd); } if (cmd->argc < 3 || strncasecmp(cmd->argv[1], "CPFR", 5) != 0) { return PR_DECLINED(cmd); } authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE); if (authenticated == NULL || *authenticated == FALSE) { pr_response_add_err(R_530, _("Please login with USER and PASS")); pr_cmd_set_errno(cmd, EPERM); errno = EPERM; return PR_ERROR(cmd); } CHECK_CMD_MIN_ARGS(cmd, 3); /* Construct the target file name by concatenating all the parameters after * the "SITE CPFR", separating them with spaces. */ for (i = 2; i <= cmd->argc-1; i++) { char *decoded_path; decoded_path = pr_fs_decode_path2(cmd->tmp_pool, cmd->argv[i], FSIO_DECODE_FL_TELL_ERRORS); if (decoded_path == NULL) { int xerrno = errno; pr_log_debug(DEBUG8, "'%s' failed to decode properly: %s", (char *) cmd->argv[i], strerror(xerrno)); pr_response_add_err(R_550, _("%s: Illegal character sequence in filename"), cmd->arg); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } path = pstrcat(cmd->tmp_pool, path, *path ? " " : "", decoded_path, NULL); } res = pr_filter_allow_path(CURRENT_CONF, path); switch (res) { case 0: break; case PR_FILTER_ERR_FAILS_ALLOW_FILTER: pr_log_debug(DEBUG2, MOD_COPY_VERSION ": 'CPFR %s' denied by PathAllowFilter", path); pr_response_add_err(R_550, _("%s: Forbidden filename"), path); pr_cmd_set_errno(cmd, EPERM); errno = EPERM; return PR_ERROR(cmd); case PR_FILTER_ERR_FAILS_DENY_FILTER: pr_log_debug(DEBUG2, MOD_COPY_VERSION ": 'CPFR %s' denied by PathDenyFilter", path); pr_response_add_err(R_550, _("%s: Forbidden filename"), path); pr_cmd_set_errno(cmd, EPERM); errno = EPERM; return PR_ERROR(cmd); } /* Allow renaming a symlink, even a dangling one. */ path = dir_canonical_vpath(cmd->tmp_pool, path); if (!path || !dir_check_canon(cmd->tmp_pool, cmd, cmd->group, path, NULL) || !exists2(cmd->tmp_pool, path)) { int xerrno = errno; pr_response_add_err(R_550, "%s: %s", path, strerror(xerrno)); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } if (pr_table_add(session.notes, "mod_copy.cpfr-path", pstrdup(session.pool, path), 0) < 0) { pr_trace_msg(trace_channel, 4, "error adding 'mod_copy.cpfr-path' note: %s", strerror(errno)); } pr_response_add(R_350, _("File or directory exists, ready for destination name")); return PR_HANDLED(cmd); }
MODRET copy_copy(cmd_rec *cmd) { if (copy_engine == FALSE) { return PR_DECLINED(cmd); } if (cmd->argc < 2) { return PR_DECLINED(cmd); } if (strncasecmp(cmd->argv[1], "COPY", 5) == 0) { char *cmd_name, *decoded_path, *from, *to; unsigned char *authenticated; if (cmd->argc != 4) { return PR_DECLINED(cmd); } authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE); if (authenticated == NULL || *authenticated == FALSE) { pr_response_add_err(R_530, _("Please login with USER and PASS")); pr_cmd_set_errno(cmd, EPERM); errno = EPERM; return PR_ERROR(cmd); } /* XXX What about paths which contain spaces? */ decoded_path = pr_fs_decode_path2(cmd->tmp_pool, cmd->argv[2], FSIO_DECODE_FL_TELL_ERRORS); if (decoded_path == NULL) { int xerrno = errno; pr_log_debug(DEBUG8, "'%s' failed to decode properly: %s", (char *) cmd->argv[2], strerror(xerrno)); pr_response_add_err(R_550, _("%s: Illegal character sequence in filename"), (char *) cmd->argv[2]); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } from = dir_canonical_vpath(cmd->tmp_pool, decoded_path); decoded_path = pr_fs_decode_path2(cmd->tmp_pool, cmd->argv[3], FSIO_DECODE_FL_TELL_ERRORS); if (decoded_path == NULL) { int xerrno = errno; pr_log_debug(DEBUG8, "'%s' failed to decode properly: %s", (char *) cmd->argv[3], strerror(xerrno)); pr_response_add_err(R_550, _("%s: Illegal character sequence in filename"), (char *) cmd->argv[3]); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } to = dir_canonical_vpath(cmd->tmp_pool, decoded_path); cmd_name = cmd->argv[0]; pr_cmd_set_name(cmd, "SITE_COPY"); if (!dir_check(cmd->tmp_pool, cmd, G_WRITE, to, NULL)) { int xerrno = EPERM; pr_cmd_set_name(cmd, cmd_name); pr_response_add_err(R_550, "%s: %s", (char *) cmd->argv[3], strerror(xerrno)); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } pr_cmd_set_name(cmd, cmd_name); if (copy_paths(cmd->tmp_pool, from, to) < 0) { int xerrno = errno; pr_response_add_err(R_550, "%s: %s", (char *) cmd->argv[1], strerror(xerrno)); pr_cmd_set_errno(cmd, xerrno); errno = xerrno; return PR_ERROR(cmd); } pr_response_add(R_200, _("SITE %s command successful"), (char *) cmd->argv[1]); return PR_HANDLED(cmd); } if (strncasecmp(cmd->argv[1], "HELP", 5) == 0) { pr_response_add(R_214, _("CPFR <sp> pathname")); pr_response_add(R_214, _("CPTO <sp> pathname")); } return PR_DECLINED(cmd); }