diff --git a/libexec/ftpd/ftpcmd.y b/libexec/ftpd/ftpcmd.y index 2da3ef272024..381d87c5feee 100644 --- a/libexec/ftpd/ftpcmd.y +++ b/libexec/ftpd/ftpcmd.y @@ -94,6 +94,7 @@ extern char tmpline[]; extern int readonly; extern int noepsv; extern int noretr; +extern int noguestretr; off_t restart_point; @@ -440,7 +441,7 @@ cmd } | RETR check_login SP pathname CRLF { - if (noretr) + if (noretr || (guest && noguestretr)) reply(500, "RETR command is disabled"); else if ($2 && $4 != NULL) retrieve((char *) 0, $4); diff --git a/libexec/ftpd/ftpd.8 b/libexec/ftpd/ftpd.8 index 1b643800e6f9..157403c3716b 100644 --- a/libexec/ftpd/ftpd.8 +++ b/libexec/ftpd/ftpd.8 @@ -51,6 +51,7 @@ .Op Fl U .Op Fl r .Op Fl o +.Op Fl O .Op Fl E .Op Fl T Ar maxtimeout .Op Fl t Ar timeout @@ -161,6 +162,12 @@ All commands which may modify the local filesystem are disabled. .It Fl o Put server in write-only mode. RETR is disabled, preventing downloads. +.It Fl O +Put server in write-only mode for anonymous users only. +RETR is disabled for anonymous users, preventing anonymous downloads. +This has no effect if +.Fl o +is also specified. .It Fl E Disable the EPSV command. This is useful for servers behind older firewalls. diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index 93f0a90b27b0..e3e074883040 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -150,6 +150,7 @@ int pdata = -1; /* for passive mode */ int readonly=0; /* Server is in readonly mode. */ int noepsv=0; /* EPSV command is disabled. */ int noretr=0; /* RETR command is disabled. */ +int noguestretr=0; /* RETR command is disabled for anon users. */ sig_atomic_t transflag; off_t file_size; @@ -301,7 +302,7 @@ main(argc, argv, envp) #endif /* OLD_SETPROCTITLE */ - while ((ch = getopt(argc, argv, "AdlDESURrt:T:u:voa:p:46")) != -1) { + while ((ch = getopt(argc, argv, "AdlDESURrt:T:u:vOoa:p:46")) != -1) { switch (ch) { case 'D': daemon_mode++; @@ -384,6 +385,10 @@ main(argc, argv, envp) family = AF_INET6; break; + case 'O': + noguestretr = 1; + break; + case 'o': noretr = 1; break;