diff options
Diffstat (limited to 'libexec/ftpd/ftpcmd.y')
-rw-r--r-- | libexec/ftpd/ftpcmd.y | 78 |
1 files changed, 58 insertions, 20 deletions
diff --git a/libexec/ftpd/ftpcmd.y b/libexec/ftpd/ftpcmd.y index 6da9f218e4a5..14ac1220a33a 100644 --- a/libexec/ftpd/ftpcmd.y +++ b/libexec/ftpd/ftpcmd.y @@ -90,6 +90,8 @@ extern char proctitle[]; extern int usedefault; extern int transflag; extern char tmpline[]; +extern int readonly; +extern int noepsv; off_t restart_point; @@ -132,6 +134,8 @@ extern int epsvall; %token <i> NUMBER %type <i> check_login octal_number byte_size +%type <i> check_login_ro octal_number byte_size +%type <i> check_login_epsv octal_number byte_size %type <i> struct_code mode_code type_code form_code %type <s> pathstring pathname password username ext_arg %type <s> ALL @@ -318,7 +322,7 @@ cmd else if ($2) long_passive("LPSV", PF_UNSPEC); } - | EPSV check_login SP NUMBER CRLF + | EPSV check_login_epsv SP NUMBER CRLF { if ($2) { int pf; @@ -338,7 +342,7 @@ cmd long_passive("EPSV", pf); } } - | EPSV check_login SP ALL CRLF + | EPSV check_login_epsv SP ALL CRLF { if ($2) { reply(200, @@ -346,7 +350,7 @@ cmd epsvall++; } } - | EPSV check_login CRLF + | EPSV check_login_epsv CRLF { if ($2) long_passive("EPSV", PF_UNSPEC); @@ -435,14 +439,14 @@ cmd if ($4 != NULL) free($4); } - | STOR check_login SP pathname CRLF + | STOR check_login_ro SP pathname CRLF { if ($2 && $4 != NULL) store($4, "w", 0); if ($4 != NULL) free($4); } - | APPE check_login SP pathname CRLF + | APPE check_login_ro SP pathname CRLF { if ($2 && $4 != NULL) store($4, "a", 0); @@ -486,14 +490,14 @@ cmd statcmd(); } } - | DELE check_login SP pathname CRLF + | DELE check_login_ro SP pathname CRLF { if ($2 && $4 != NULL) delete($4); if ($4 != NULL) free($4); } - | RNTO check_login SP pathname CRLF + | RNTO check_login_ro SP pathname CRLF { if ($2) { if (fromname) { @@ -513,8 +517,12 @@ cmd } | CWD check_login CRLF { - if ($2) - cwd(pw->pw_dir); + if ($2) { + if (guest) + cwd("/"); + else + cwd(pw->pw_dir); + } } | CWD check_login SP pathname CRLF { @@ -546,14 +554,14 @@ cmd { reply(200, "NOOP command successful."); } - | MKD check_login SP pathname CRLF + | MKD check_login_ro SP pathname CRLF { if ($2 && $4 != NULL) makedir($4); if ($4 != NULL) free($4); } - | RMD check_login SP pathname CRLF + | RMD check_login_ro SP pathname CRLF { if ($2 && $4 != NULL) removedir($4); @@ -603,7 +611,7 @@ cmd } } } - | SITE SP CHMOD check_login SP octal_number SP pathname CRLF + | SITE SP CHMOD check_login_ro SP octal_number SP pathname CRLF { if ($4 && ($8 != NULL)) { if ($6 > 0777) @@ -640,7 +648,7 @@ cmd } } } - | STOU check_login SP pathname CRLF + | STOU check_login_ro SP pathname CRLF { if ($2 && $4 != NULL) store($4, "w", 1); @@ -719,7 +727,7 @@ cmd } ; rcmd - : RNFR check_login SP pathname CRLF + : RNFR check_login_ro SP pathname CRLF { char *renamefrom(); @@ -970,12 +978,31 @@ octal_number check_login : /* empty */ { - if (logged_in) - $$ = 1; - else { - reply(530, "Please login with USER and PASS."); - $$ = 0; - } + $$ = check_login1(); + } + ; + +check_login_epsv + : /* empty */ + { + if (noepsv) { + reply(500, "EPSV command disabled"); + $$ = 0; + } + else + $$ = check_login1(); + } + ; + +check_login_ro + : /* empty */ + { + if (readonly) { + reply(550, "Permission denied."); + $$ = 0; + } + else + $$ = check_login1(); } ; @@ -1574,6 +1601,17 @@ port_check(pcmd) return 0; } +static int +check_login1() +{ + if (logged_in) + return 1; + else { + reply(530, "Please login with USER and PASS."); + return 0; + } +} + #ifdef INET6 /* Return 1, if port check is done. Return 0, if not yet. */ static int |