diff options
Diffstat (limited to 'networking/ftpd.c')
-rw-r--r-- | networking/ftpd.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/networking/ftpd.c b/networking/ftpd.c index 2d2a3a44c..6adcb1dee 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
@@ -622,7 +622,7 @@ popen_ls(const char *opt) | |||
622 | pid_t pid; | 622 | pid_t pid; |
623 | 623 | ||
624 | argv[0] = "ftpd"; | 624 | argv[0] = "ftpd"; |
625 | argv[1] = opt; /* "-l" or "-1" */ | 625 | argv[1] = opt; /* "-lA" or "-1A" */ |
626 | argv[2] = "--"; | 626 | argv[2] = "--"; |
627 | argv[3] = G.ftp_arg; | 627 | argv[3] = G.ftp_arg; |
628 | argv[4] = NULL; | 628 | argv[4] = NULL; |
@@ -699,7 +699,7 @@ handle_dir_common(int opts) | |||
699 | if (!(opts & USE_CTRL_CONN) && !port_or_pasv_was_seen()) | 699 | if (!(opts & USE_CTRL_CONN) && !port_or_pasv_was_seen()) |
700 | return; /* port_or_pasv_was_seen emitted error response */ | 700 | return; /* port_or_pasv_was_seen emitted error response */ |
701 | 701 | ||
702 | ls_fd = popen_ls((opts & LONG_LISTING) ? "-l" : "-1"); | 702 | ls_fd = popen_ls((opts & LONG_LISTING) ? "-lA" : "-1A"); |
703 | ls_fp = xfdopen_for_read(ls_fd); | 703 | ls_fp = xfdopen_for_read(ls_fd); |
704 | /* FIXME: filenames with embedded newlines are mishandled */ | 704 | /* FIXME: filenames with embedded newlines are mishandled */ |
705 | 705 | ||
@@ -1102,10 +1102,11 @@ enum { | |||
1102 | #if !BB_MMU | 1102 | #if !BB_MMU |
1103 | OPT_l = (1 << 0), | 1103 | OPT_l = (1 << 0), |
1104 | OPT_1 = (1 << 1), | 1104 | OPT_1 = (1 << 1), |
1105 | OPT_A = (1 << 2), | ||
1105 | #endif | 1106 | #endif |
1106 | OPT_v = (1 << ((!BB_MMU) * 2 + 0)), | 1107 | OPT_v = (1 << ((!BB_MMU) * 3 + 0)), |
1107 | OPT_S = (1 << ((!BB_MMU) * 2 + 1)), | 1108 | OPT_S = (1 << ((!BB_MMU) * 3 + 1)), |
1108 | OPT_w = (1 << ((!BB_MMU) * 2 + 2)) * ENABLE_FEATURE_FTP_WRITE, | 1109 | OPT_w = (1 << ((!BB_MMU) * 3 + 2)) * ENABLE_FEATURE_FTP_WRITE, |
1109 | }; | 1110 | }; |
1110 | 1111 | ||
1111 | int ftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1112 | int ftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -1126,12 +1127,11 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1126 | G.timeout = 2 * 60; | 1127 | G.timeout = 2 * 60; |
1127 | opt_complementary = "t+:T+:vv:SS"; | 1128 | opt_complementary = "t+:T+:vv:SS"; |
1128 | #if BB_MMU | 1129 | #if BB_MMU |
1129 | opts = getopt32(argv, "vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); | 1130 | opts = getopt32(argv, "vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); |
1130 | #else | 1131 | #else |
1131 | opts = getopt32(argv, "l1vS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); | 1132 | opts = getopt32(argv, "l1AvS" IF_FEATURE_FTP_WRITE("w") "t:T:", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); |
1132 | if (opts & (OPT_l|OPT_1)) { | 1133 | if (opts & (OPT_l|OPT_1)) { |
1133 | /* Our secret backdoor to ls */ | 1134 | /* Our secret backdoor to ls */ |
1134 | /* TODO: pass -A? It shows dot files */ | ||
1135 | /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ | 1135 | /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ |
1136 | if (fchdir(3) != 0) | 1136 | if (fchdir(3) != 0) |
1137 | _exit(127); | 1137 | _exit(127); |
@@ -1172,18 +1172,6 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1172 | if (logmode) | 1172 | if (logmode) |
1173 | applet_name = xasprintf("%s[%u]", applet_name, (int)getpid()); | 1173 | applet_name = xasprintf("%s[%u]", applet_name, (int)getpid()); |
1174 | 1174 | ||
1175 | #if !BB_MMU | ||
1176 | G.root_fd = -1; | ||
1177 | #endif | ||
1178 | argv += optind; | ||
1179 | if (argv[0]) { | ||
1180 | #if !BB_MMU | ||
1181 | G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY); | ||
1182 | close_on_exec_on(G.root_fd); | ||
1183 | #endif | ||
1184 | xchroot(argv[0]); | ||
1185 | } | ||
1186 | |||
1187 | //umask(077); - admin can set umask before starting us | 1175 | //umask(077); - admin can set umask before starting us |
1188 | 1176 | ||
1189 | /* Signals. We'll always take -EPIPE rather than a rude signal, thanks */ | 1177 | /* Signals. We'll always take -EPIPE rather than a rude signal, thanks */ |
@@ -1199,23 +1187,22 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1199 | WRITE_OK(FTP_GREET); | 1187 | WRITE_OK(FTP_GREET); |
1200 | signal(SIGALRM, timeout_handler); | 1188 | signal(SIGALRM, timeout_handler); |
1201 | 1189 | ||
1202 | #ifdef IF_WE_WANT_TO_REQUIRE_LOGIN | 1190 | #if ENABLE_FEATURE_FTP_AUTHENTICATION |
1203 | { | 1191 | { |
1204 | smallint user_was_specified = 0; | 1192 | struct passwd *pw = NULL; |
1193 | |||
1205 | while (1) { | 1194 | while (1) { |
1206 | uint32_t cmdval = cmdio_get_cmd_and_arg(); | 1195 | uint32_t cmdval = cmdio_get_cmd_and_arg(); |
1207 | 1196 | ||
1208 | if (cmdval == const_USER) { | 1197 | if (cmdval == const_USER) { |
1209 | if (G.ftp_arg == NULL || strcasecmp(G.ftp_arg, "anonymous") != 0) | 1198 | pw = getpwnam(G.ftp_arg); |
1210 | cmdio_write_raw(STR(FTP_LOGINERR)" Server is anonymous only\r\n"); | 1199 | cmdio_write_raw(STR(FTP_GIVEPWORD)" Please specify password\r\n"); |
1211 | else { | ||
1212 | user_was_specified = 1; | ||
1213 | cmdio_write_raw(STR(FTP_GIVEPWORD)" Please specify the password\r\n"); | ||
1214 | } | ||
1215 | } else if (cmdval == const_PASS) { | 1200 | } else if (cmdval == const_PASS) { |
1216 | if (user_was_specified) | 1201 | if (check_password(pw, G.ftp_arg) > 0) { |
1217 | break; | 1202 | break; /* login success */ |
1218 | cmdio_write_raw(STR(FTP_NEEDUSER)" Login with USER\r\n"); | 1203 | } |
1204 | cmdio_write_raw(STR(FTP_LOGINERR)" Login failed\r\n"); | ||
1205 | pw = NULL; | ||
1219 | } else if (cmdval == const_QUIT) { | 1206 | } else if (cmdval == const_QUIT) { |
1220 | WRITE_OK(FTP_GOODBYE); | 1207 | WRITE_OK(FTP_GOODBYE); |
1221 | return 0; | 1208 | return 0; |
@@ -1223,10 +1210,24 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1223 | cmdio_write_raw(STR(FTP_LOGINERR)" Login with USER and PASS\r\n"); | 1210 | cmdio_write_raw(STR(FTP_LOGINERR)" Login with USER and PASS\r\n"); |
1224 | } | 1211 | } |
1225 | } | 1212 | } |
1213 | change_identity(pw); | ||
1226 | } | 1214 | } |
1227 | WRITE_OK(FTP_LOGINOK); | 1215 | WRITE_OK(FTP_LOGINOK); |
1228 | #endif | 1216 | #endif |
1229 | 1217 | ||
1218 | /* Do this after auth, else /etc/passwd is not accessible */ | ||
1219 | #if !BB_MMU | ||
1220 | G.root_fd = -1; | ||
1221 | #endif | ||
1222 | argv += optind; | ||
1223 | if (argv[0]) { | ||
1224 | #if !BB_MMU | ||
1225 | G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY); | ||
1226 | close_on_exec_on(G.root_fd); | ||
1227 | #endif | ||
1228 | xchroot(argv[0]); | ||
1229 | } | ||
1230 | |||
1230 | /* RFC-959 Section 5.1 | 1231 | /* RFC-959 Section 5.1 |
1231 | * The following commands and options MUST be supported by every | 1232 | * The following commands and options MUST be supported by every |
1232 | * server-FTP and user-FTP, except in cases where the underlying | 1233 | * server-FTP and user-FTP, except in cases where the underlying |