summaryrefslogtreecommitdiffstats
path: root/libexec/ftpd
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2000-12-16 19:19:19 +0000
committerphk <phk@FreeBSD.org>2000-12-16 19:19:19 +0000
commit10d3e9963aa4451ef5328ff50b0e57d9fe52d71b (patch)
tree3386819d499fc9ec354a34dbcdc18c4d2cd1d748 /libexec/ftpd
parentfb055f99b3b41b7a3f47da83c3d8240649326f7f (diff)
downloadFreeBSD-src-10d3e9963aa4451ef5328ff50b0e57d9fe52d71b.zip
FreeBSD-src-10d3e9963aa4451ef5328ff50b0e57d9fe52d71b.tar.gz
Add option -E to disable EPSV which throws certain stateful firewalls
into confusion. Add option -r to make ftpd support only read-only operations. Submitted by: Flemming (F3) Jacobsen <fj@batmule.dk> Reviewed by: phk
Diffstat (limited to 'libexec/ftpd')
-rw-r--r--libexec/ftpd/ftpcmd.y70
-rw-r--r--libexec/ftpd/ftpd.842
-rw-r--r--libexec/ftpd/ftpd.c12
3 files changed, 89 insertions, 35 deletions
diff --git a/libexec/ftpd/ftpcmd.y b/libexec/ftpd/ftpcmd.y
index c30acef..4084d8f 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);
@@ -425,14 +429,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);
@@ -474,14 +478,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) {
@@ -537,14 +541,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);
@@ -594,7 +598,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)
@@ -628,7 +632,7 @@ cmd
timeout);
}
}
- | STOU check_login SP pathname CRLF
+ | STOU check_login_ro SP pathname CRLF
{
if ($2 && $4 != NULL)
store($4, "w", 1);
@@ -706,7 +710,7 @@ cmd
}
;
rcmd
- : RNFR check_login SP pathname CRLF
+ : RNFR check_login_ro SP pathname CRLF
{
char *renamefrom();
@@ -954,12 +958,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(202, "Command ignored. Server is in readonly mode.");
+ $$ = 0;
+ }
+ else
+ $$ = check_login1();
}
;
@@ -1558,6 +1581,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
diff --git a/libexec/ftpd/ftpd.8 b/libexec/ftpd/ftpd.8
index fc7608d..a7c0e14 100644
--- a/libexec/ftpd/ftpd.8
+++ b/libexec/ftpd/ftpd.8
@@ -50,6 +50,8 @@ Internet File Transfer Protocol server
.Op Fl R
.Op Fl S
.Op Fl U
+.Op Fl r
+.Op Fl E
.Op Fl T Ar maxtimeout
.Op Fl t Ar timeout
.Op Fl a Ar address
@@ -153,6 +155,11 @@ When
is not specified, accept IPv4 connection via AF_INET socket.
.It Fl A
Allow only anonymous ftp access.
+.It Fl r
+Put server in read-only mode. All commands which may modify the local
+filesystem is disabled.
+.It Fl E
+Disable the EPSV command. This is usefull for servers behind older FireWalls.
.El
.Pp
The file
@@ -178,20 +185,27 @@ relative to the login environment. This means the one in
in the anonymous user's case.
.Pp
The ftp server currently supports the following ftp requests.
-The case of the requests is ignored.
+The case of the requests is ignored. Requests marked [RW] are
+disabled if
+.Fl r
+is specified.
.Bl -column "Request" -offset indent
.It Sy Request Ta Sy "Description"
.It ABOR Ta "abort previous command"
.It ACCT Ta "specify account (ignored)"
.It ALLO Ta "allocate storage (vacuously)"
-.It APPE Ta "append to a file"
+.It APPE Ta "append to a file [RW]"
.It CDUP Ta "change to parent of current working directory"
.It CWD Ta "change working directory"
-.It DELE Ta "delete a file"
+.It DELE Ta "delete a file [RW]"
+.It EPRT Ta "specify data connection port, multiprotocol"
+.It EPSV Ta "prepare for server-to-server transfer, multiprotocol"
.It HELP Ta "give help information"
.It LIST Ta "give list files in a directory" Pq Dq Li "ls -lgA"
-.It MKD Ta "make a directory"
+.It LPRT Ta "specify data connection port, multiprotocol"
+.It LPSV Ta "prepare for server-to-server transfer, multiprotocol"
.It MDTM Ta "show last modification time of file"
+.It MKD Ta "make a directory [RW]"
.It MODE Ta "specify data transfer" Em mode
.It NLST Ta "give name list of files in directory"
.It NOOP Ta "do nothing"
@@ -202,27 +216,23 @@ The case of the requests is ignored.
.It QUIT Ta "terminate session"
.It REST Ta "restart incomplete transfer"
.It RETR Ta "retrieve a file"
-.It RMD Ta "remove a directory"
-.It RNFR Ta "specify rename-from file name"
-.It RNTO Ta "specify rename-to file name"
+.It RMD Ta "remove a directory [RW]"
+.It RNFR Ta "specify rename-from file name [RW]"
+.It RNTO Ta "specify rename-to file name [RW]"
.It SITE Ta "non-standard commands (see next section)"
.It SIZE Ta "return size of file"
.It STAT Ta "return status of server"
-.It STOR Ta "store a file"
-.It STOU Ta "store a file with a unique name"
+.It STOR Ta "store a file [RW]"
+.It STOU Ta "store a file with a unique name [RW]"
.It STRU Ta "specify data transfer" Em structure
.It SYST Ta "show operating system type of server system"
.It TYPE Ta "specify data transfer" Em type
.It USER Ta "specify user name"
.It XCUP Ta "change to parent of current working directory (deprecated)"
.It XCWD Ta "change working directory (deprecated)"
-.It XMKD Ta "make a directory (deprecated)"
+.It XMKD Ta "make a directory (deprecated) [RW]"
.It XPWD Ta "print the current working directory (deprecated)"
-.It XRMD Ta "remove a directory (deprecated)"
-.It LPSV Ta "prepare for server-to-server transfer, multiprotocol"
-.It LPRT Ta "specify data connection port, multiprotocol"
-.It EPSV Ta "prepare for server-to-server transfer, multiprotocol"
-.It EPRT Ta "specify data connection port, multiprotocol"
+.It XRMD Ta "remove a directory (deprecated) [RW]"
.El
.Pp
The following non-standard or
@@ -235,7 +245,7 @@ SITE request.
.It Sy Request Ta Sy Description
.It UMASK Ta change umask, e.g. ``SITE UMASK 002''
.It IDLE Ta set idle-timer, e.g. ``SITE IDLE 60''
-.It CHMOD Ta "change mode of a file, e.g. ``SITE CHMOD 755 filename''"
+.It CHMOD Ta "change mode of a file [RW], e.g. ``SITE CHMOD 755 filename'' "
.It HELP Ta give help information
.El
.Pp
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index b77c133..2c8591b 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -148,6 +148,8 @@ int stru; /* avoid C keyword */
int mode;
int usedefault = 1; /* for data transfers */
int pdata = -1; /* for passive mode */
+int readonly=0; /* Server is in readonly mode. */
+int noepsv=0; /* EPSV command is disabled. */
sig_atomic_t transflag;
off_t file_size;
off_t byte_count;
@@ -290,7 +292,7 @@ main(argc, argv, envp)
#endif /* OLD_SETPROCTITLE */
- while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:46")) != -1) {
+ while ((ch = getopt(argc, argv, "AdlDESURrt:T:u:va:p:46")) != -1) {
switch (ch) {
case 'D':
daemon_mode++;
@@ -300,10 +302,18 @@ main(argc, argv, envp)
debug++;
break;
+ case 'E':
+ noepsv = 1;
+ break;
+
case 'l':
logging++; /* > 1 == extra logging */
break;
+ case 'r':
+ readonly = 1;
+ break;
+
case 'R':
paranoid = 0;
break;
OpenPOWER on IntegriCloud