diff options
Diffstat (limited to 'libexec/ftpd/ftpd.c')
-rw-r--r-- | libexec/ftpd/ftpd.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index 77091967864..a61380bc10c 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ftpd.c,v 1.7 1996/07/29 00:03:19 downsj Exp $ */ +/* $OpenBSD: ftpd.c,v 1.8 1996/07/29 03:06:35 downsj Exp $ */ /* $NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $ */ /* @@ -61,6 +61,7 @@ static char rcsid[] = "$NetBSD: ftpd.c,v 1.15 1995/06/03 22:46:47 mycroft Exp $" #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> +#include <netinet/tcp.h> #define FTP_NAMES #include <arpa/ftp.h> @@ -116,6 +117,7 @@ int debug = 0; int timeout = 900; /* timeout after 15 minutes of inactivity */ int maxtimeout = 7200;/* don't allow idle time to be set beyond 2 hours */ int logging; +int high_data_ports = 0; int guest; #ifdef STATS int stats; @@ -232,9 +234,9 @@ main(argc, argv, envp) char *cp, line[LINE_MAX]; FILE *fd; #ifdef STATS - char *argstr = "dDlSt:T:u:Uv"; + char *argstr = "dDhlSt:T:u:Uv"; #else - char *argstr = "dDlt:T:u:Uv"; + char *argstr = "dDhlt:T:u:Uv"; #endif tzset(); /* in case no timezone database in ~ftp */ @@ -252,6 +254,10 @@ main(argc, argv, envp) daemon_mode = 1; break; + case 'h': + high_data_ports = 1; + break; + case 'l': logging++; /* > 1 == extra logging */ break; @@ -300,6 +306,8 @@ main(argc, argv, envp) } } + (void) freopen(_PATH_DEVNULL, "w", stderr); + /* * LOG_NDELAY sets up the logging connection immediately, * necessary for anonymous ftp's that chroot and can't do it later. @@ -376,7 +384,6 @@ main(argc, argv, envp) } } - (void) freopen(_PATH_DEVNULL, "w", stderr); (void) signal(SIGPIPE, lostconn); (void) signal(SIGCHLD, SIG_IGN); if ((long)signal(SIGURG, myoob) < 0) @@ -998,6 +1005,23 @@ getdatasock(mode) if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); #endif +#ifdef TCP_NOPUSH + /* + * Turn off push flag to keep sender TCP from sending short packets + * at the boundaries of each write(). Should probably do a SO_SNDBUF + * to set the send buffer size as well, but that may not be desirable + * in heavy-load situations. + */ + on = 1; + if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, (char *)&on, sizeof on) < 0) + syslog(LOG_WARNING, "setsockopt (TCP_NOPUSH): %m"); +#endif +#ifdef SO_SNDBUF + on = 65536; + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&on, sizeof on) < 0) + syslog(LOG_WARNING, "setsockopt (SO_SNDBUF): %m"); +#endif + return (fdopen(s, mode)); bad: /* Return the real value of errno (close may change it) */ @@ -1665,22 +1689,38 @@ myoob(signo) void passive() { - int len; + int len, on; + u_short port; char *p, *a; + if (pw == NULL) { + reply(530, "Please login with USER and PASS"); + return; + } pdata = socket(AF_INET, SOCK_STREAM, 0); if (pdata < 0) { perror_reply(425, "Can't open passive connection"); return; } + + on = high_data_ports ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT; + (void) seteuid((uid_t)0); + if (setsockopt(pdata, IPPROTO_IP, IP_PORTRANGE, + (char *)&on, sizeof(on)) < 0) { + (void) seteuid((uid_t)pw->pw_uid); + goto pasv_error; + } + pasv_addr = ctrl_addr; pasv_addr.sin_port = 0; (void) seteuid((uid_t)0); - if (bind(pdata, (struct sockaddr *)&pasv_addr, sizeof(pasv_addr)) < 0) { + if (bind(pdata, (struct sockaddr *)&pasv_addr, + sizeof(pasv_addr)) < 0) { (void) seteuid((uid_t)pw->pw_uid); goto pasv_error; } (void) seteuid((uid_t)pw->pw_uid); + len = sizeof(pasv_addr); if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0) goto pasv_error; |