Index: libexec/ftpd/ftpd.8 =================================================================== --- libexec/ftpd/ftpd.8 +++ libexec/ftpd/ftpd.8 @@ -33,7 +33,8 @@ .Nd Internet File Transfer Protocol server .Sh SYNOPSIS .Nm -.Op Fl 468ABDdEhMmOoRrSUvW +.Op Fl 468BDdEhMmOoRrSUvW +.Brq Fl A|n .Op Fl l Op Fl l .Op Fl a Ar address .Op Fl P Ar port @@ -148,6 +149,13 @@ existing files if allowed by file system permissions. By default, anonymous users cannot modify existing files; in particular, files to upload will be created under a unique name. +.It Fl n +Disable anonymous FTP access. +The +.Fl n +option is mutually exclusive with the +.Fl A +option. .It Fl O Put server in write-only mode for anonymous users only. RETR is disabled for anonymous users, preventing anonymous downloads. Index: libexec/ftpd/ftpd.c =================================================================== --- libexec/ftpd/ftpd.c +++ libexec/ftpd/ftpd.c @@ -106,6 +106,7 @@ int restricted_data_ports = 1; int paranoid = 1; /* be extra careful about security */ int anon_only = 0; /* Only anonymous ftp allowed */ +int noanon = 0; /* disable anonymous ftp */ int assumeutf8 = 0; /* Assume that server file names are in UTF-8 */ int guest; int dochroot; @@ -269,7 +270,7 @@ openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); while ((ch = getopt(argc, argv, - "468a:ABdDEhlmMoOp:P:rRSt:T:u:UvW")) != -1) { + "468a:ABdDEhlmMnoOp:P:rRSt:T:u:UvW")) != -1) { switch (ch) { case '4': family = (family == AF_INET6) ? AF_UNSPEC : AF_INET; @@ -327,6 +328,10 @@ noguestmkd = 1; break; + case 'n': + noanon = 1; + break; + case 'o': noretr = 1; break; @@ -396,6 +401,11 @@ } } + if (noanon && anon_only) { + syslog(LOG_ERR, "-n and -A are mutually exclusive"); + exit(1); + } + /* handle filesize limit gracefully */ sa.sa_handler = SIG_IGN; (void)sigaction(SIGXFSZ, &sa, NULL); @@ -995,7 +1005,8 @@ #else pw = sgetpwnam("ftp"); #endif - if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) { + if (!noanon && + (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0)) { if (checkuser(_PATH_FTPUSERS, "ftp", 0, NULL, &ecode) || (ecode != 0 && ecode != ENOENT)) reply(530, "User %s access denied.", name);