diff options
Diffstat (limited to 'contrib/lukemftpd')
-rw-r--r-- | contrib/lukemftpd/src/ftpd.c | 372 | ||||
-rw-r--r-- | contrib/lukemftpd/src/ftpd.conf.5 | 11 | ||||
-rw-r--r-- | contrib/lukemftpd/src/ftpusers.5 | 7 |
3 files changed, 171 insertions, 219 deletions
diff --git a/contrib/lukemftpd/src/ftpd.c b/contrib/lukemftpd/src/ftpd.c index db89e87..b623919 100644 --- a/contrib/lukemftpd/src/ftpd.c +++ b/contrib/lukemftpd/src/ftpd.c @@ -1,7 +1,7 @@ -/* $NetBSD: ftpd.c,v 1.158 2004-08-09 12:56:47 lukem Exp $ */ +/* $NetBSD: ftpd.c,v 1.150 2003/01/22 04:46:08 lukem Exp $ */ /* - * Copyright (c) 1997-2004 The NetBSD Foundation, Inc. + * Copyright (c) 1997-2001 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -48,7 +48,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -105,9 +109,10 @@ __COPYRIGHT( #if 0 static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95"; #else -__RCSID("$NetBSD: ftpd.c,v 1.158 2004-08-09 12:56:47 lukem Exp $"); +__RCSID("$NetBSD: ftpd.c,v 1.150 2003/01/22 04:46:08 lukem Exp $"); #endif #endif /* not lint */ +__FBSDID("$FreeBSD$"); /* * FTP server. @@ -140,6 +145,7 @@ __RCSID("$NetBSD: ftpd.c,v 1.158 2004-08-09 12:56:47 lukem Exp $"); #include <limits.h> #include <netdb.h> #include <pwd.h> +#include <setjmp.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> @@ -169,10 +175,8 @@ __RCSID("$NetBSD: ftpd.c,v 1.158 2004-08-09 12:56:47 lukem Exp $"); #include "pathnames.h" #include "version.h" -volatile sig_atomic_t transflag; -volatile sig_atomic_t urgflag; - int data; +jmp_buf urgcatch; int sflag; int stru; /* avoid C keyword */ int mode; @@ -180,8 +184,7 @@ int dataport; /* use specific data port */ int dopidfile; /* maintain pid file */ int doutmp; /* update utmp file */ int dowtmp; /* update wtmp file */ -int doxferlog; /* syslog/write wu-ftpd style xferlog entries */ -int xferlogfd; /* fd to write wu-ftpd xferlog entries to */ +int doxferlog; /* syslog wu-ftpd style xferlog entries */ int dropprivs; /* if privileges should or have been dropped */ int mapped; /* IPv4 connection on AF_INET6 socket */ off_t file_size; @@ -197,9 +200,6 @@ static struct utmpx utmpx; /* for utmpx */ static const char *anondir = NULL; static const char *confdir = _DEFAULT_CONFDIR; -static char *curname; /* current USER name */ -static size_t curname_len; /* length of curname (include NUL) */ - #if defined(KERBEROS) || defined(KERBEROS5) int has_ccache = 0; int notickets = 1; @@ -223,12 +223,26 @@ int swaitint = SWAITINT; enum send_status { SS_SUCCESS, - SS_ABORTED, /* transfer aborted */ SS_NO_TRANSFER, /* no transfer made yet */ SS_FILE_ERROR, /* file read error */ SS_DATA_ERROR /* data send error */ }; + +#ifdef USE_OPIE +#include <opie.h> +static struct opie opiedata; +static char opieprompt[OPIE_CHALLENGE_MAX+1]; +static int pwok; +#endif + +#ifdef USE_PAM +#include <security/pam_appl.h> +pam_handle_t *pamh = NULL; +#include "pamize.h" +#endif + + static int bind_pasv_addr(void); static int checkuser(const char *, const char *, int, int, char **); static int checkaccess(const char *); @@ -239,10 +253,7 @@ static char *gunique(const char *); static void login_utmp(const char *, const char *, const char *); static void logremotehost(struct sockinet *); static void lostconn(int); -static void toolong(int); -static void sigquit(int); -static void sigurg(int); -static int handleoobcmd(void); +static void myoob(int); static int receive_data(FILE *, FILE *); static int send_data(FILE *, FILE *, const struct stat *, int); static struct passwd *sgetpwnam(const char *); @@ -274,9 +285,7 @@ main(int argc, char *argv[]) krb5_error_code kerror; #endif char *p; - const char *xferlogname = NULL; long l; - struct sigaction sa; connections = 1; debug = 0; @@ -288,7 +297,6 @@ main(int argc, char *argv[]) doutmp = 0; /* default: Do NOT log to utmp */ dowtmp = 1; /* default: DO log to wtmp */ doxferlog = 0; /* default: Do NOT syslog xferlog */ - xferlogfd = -1; /* default: Do NOT write xferlog file */ dropprivs = 0; mapped = 0; usedefault = 1; @@ -305,7 +313,7 @@ main(int argc, char *argv[]) */ openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP); - while ((ch = getopt(argc, argv, "a:c:C:de:h:HlL:P:qQrst:T:uUvV:wWX")) + while ((ch = getopt(argc, argv, "a:c:C:de:h:HlP:qQrst:T:uUvV:wWX")) != -1) { switch (ch) { case 'a': @@ -344,10 +352,6 @@ main(int argc, char *argv[]) logging++; /* > 1 == extra logging */ break; - case 'L': - xferlogname = optarg; - break; - case 'P': errno = 0; p = NULL; @@ -409,7 +413,7 @@ main(int argc, char *argv[]) break; case 'X': - doxferlog |= 1; + doxferlog = 1; break; default: @@ -422,23 +426,6 @@ main(int argc, char *argv[]) if (EMPTYSTR(confdir)) confdir = _DEFAULT_CONFDIR; - errno = 0; - l = sysconf(_SC_LOGIN_NAME_MAX); - if (l == -1 && errno != 0) { - syslog(LOG_ERR, "sysconf _SC_LOGIN_NAME_MAX: %m"); - exit(1); - } else if (l <= 0) { - syslog(LOG_WARNING, "using conservative LOGIN_NAME_MAX value"); - curname_len = _POSIX_LOGIN_NAME_MAX; - } else - curname_len = (size_t)l; - curname = malloc(curname_len); - if (curname == NULL) { - syslog(LOG_ERR, "malloc: %m"); - exit(1); - } - curname[0] = '\0'; - memset((char *)&his_addr, 0, sizeof(his_addr)); addrlen = sizeof(his_addr.si_su); if (getpeername(0, (struct sockaddr *)&his_addr.si_su, &addrlen) < 0) { @@ -519,26 +506,10 @@ main(int argc, char *argv[]) (void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid()); (void) freopen(_PATH_DEVNULL, "w", stderr); - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sa.sa_flags = SA_RESTART; - sigemptyset(&sa.sa_mask); - (void) sigaction(SIGCHLD, &sa, NULL); - - sa.sa_handler = sigquit; - sa.sa_flags = SA_RESTART; - sigfillset(&sa.sa_mask); /* block all sigs in these handlers */ - (void) sigaction(SIGHUP, &sa, NULL); - (void) sigaction(SIGINT, &sa, NULL); - (void) sigaction(SIGQUIT, &sa, NULL); - (void) sigaction(SIGTERM, &sa, NULL); - sa.sa_handler = lostconn; - (void) sigaction(SIGPIPE, &sa, NULL); - sa.sa_handler = toolong; - (void) sigaction(SIGALRM, &sa, NULL); - sa.sa_handler = sigurg; - (void) sigaction(SIGURG, &sa, NULL); + (void) signal(SIGPIPE, lostconn); + (void) signal(SIGCHLD, SIG_IGN); + if (signal(SIGURG, myoob) == SIG_ERR) + syslog(LOG_WARNING, "signal: %m"); /* Try to handle urgent data inline */ #ifdef SO_OOBINLINE @@ -594,16 +565,7 @@ main(int argc, char *argv[]) else reply(220, "%s FTP server (%s) ready.", hostname, version); - if (xferlogname != NULL) { - xferlogfd = open(xferlogname, O_WRONLY | O_APPEND | O_CREAT, - 0660); - if (xferlogfd == -1) - syslog(LOG_WARNING, "open xferlog `%s': %m", - xferlogname); - else - doxferlog |= 2; - } - + (void) setjmp(errcatch); ftp_loop(); /* NOTREACHED */ } @@ -617,37 +579,6 @@ lostconn(int signo) dologout(1); } -static void -toolong(int signo) -{ - - /* XXXSIGRACE */ - reply(421, - "Timeout (" LLF " seconds): closing control connection.", - (LLT)curclass.timeout); - if (logging) - syslog(LOG_INFO, "User %s timed out after " LLF " seconds", - (pw ? pw->pw_name : "unknown"), (LLT)curclass.timeout); - dologout(1); -} - -static void -sigquit(int signo) -{ - - if (debug) - syslog(LOG_DEBUG, "got signal %d", signo); - dologout(1); -} - -static void -sigurg(int signo) -{ - - urgflag = 1; -} - - /* * Save the result of a getpwnam. Used for USER command, since * the data returned must not be clobbered by any other command @@ -681,6 +612,7 @@ sgetpwnam(const char *name) static int login_attempts; /* number of failed login attempts */ static int askpasswd; /* had USER command, ask for PASSwd */ static int permitted; /* USER permitted */ +static char curname[LOGIN_NAME_MAX]; /* current USER name */ /* * USER command. @@ -754,7 +686,7 @@ user(const char *name) } else pw = sgetpwnam(name); - strlcpy(curname, name, curname_len); + strlcpy(curname, name, sizeof(curname)); /* check user in /etc/ftpusers, and setup class */ permitted = checkuser(_PATH_FTPUSERS, curname, 1, 0, &class); @@ -828,6 +760,18 @@ user(const char *name) curname); } else #endif + +#ifdef USE_OPIE + if (opiechallenge(&opiedata, (char *)curname, opieprompt) == + 0) { + pwok = (pw != NULL) && + opieaccessfile(remotehost) && + opiealways(pw->pw_dir); + reply(331, "Response to %s %s for %s.", + opieprompt, pwok ? "requested" : "required", + curname); + } else +#endif reply(331, "Password required for %s.", curname); } @@ -1020,10 +964,10 @@ login_utmp(const char *line, const char *name, const char *host) (void)strncpy(utmpx.ut_name, name, sizeof(utmpx.ut_name)); (void)strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line)); (void)strncpy(utmpx.ut_host, host, sizeof(utmpx.ut_host)); - ftpd_loginx(&utmpx); + loginx(&utmpx); } if (dowtmp) - ftpd_logwtmpx(line, name, host, 0, USER_PROCESS); + logwtmpx(line, name, host, 0, USER_PROCESS); #endif #ifdef SUPPORT_UTMP if (doutmp) { @@ -1032,10 +976,10 @@ login_utmp(const char *line, const char *name, const char *host) (void)strncpy(utmp.ut_name, name, sizeof(utmp.ut_name)); (void)strncpy(utmp.ut_line, line, sizeof(utmp.ut_line)); (void)strncpy(utmp.ut_host, host, sizeof(utmp.ut_host)); - ftpd_login(&utmp); + login(&utmp); } if (dowtmp) - ftpd_logwtmp(line, name, host); + logwtmp(line, name, host); #endif } @@ -1049,15 +993,15 @@ logout_utmp(void) okwtmp = logoutx(ttyline, 0, DEAD_PROCESS) & dowtmp; #endif #ifdef SUPPORT_UTMP - okwtmp = ftpd_logout(ttyline) & dowtmp; + okwtmp = logout(ttyline) & dowtmp; #endif } if (okwtmp) { #ifdef SUPPORT_UTMPX - ftpd_logwtmpx(ttyline, "", "", 0, DEAD_PROCESS); + logwtmpx(ttyline, "", "", 0, DEAD_PROCESS); #endif #ifdef SUPPORT_UTMP - ftpd_logwtmp(ttyline, "", ""); + logwtmp(ttyline, "", ""); #endif } } @@ -1070,6 +1014,9 @@ logout_utmp(void) static void end_login(void) { +#ifdef USE_PAM + int e; +#endif logout_utmp(); show_chdir_messages(-1); /* flush chdir cache */ if (pw != NULL && pw->pw_passwd != NULL) @@ -1082,11 +1029,23 @@ end_login(void) gidcount = 0; curclass.type = CLASS_REAL; (void) seteuid((uid_t)0); +#ifdef USE_PAM + if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) + syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, e)); + if ((e = pam_close_session(pamh,0)) != PAM_SUCCESS) + syslog(LOG_ERR, "pam_close_session: %s", pam_strerror(pamh, e)); + if ((e = pam_end(pamh, e)) != PAM_SUCCESS) + syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e)); + pamh = NULL; +#endif } void pass(const char *passwd) { +#ifdef USE_PAM + int e; +#endif int rval; char root[MAXPATHLEN]; @@ -1127,6 +1086,27 @@ pass(const char *passwd) } } #endif + +#ifdef USE_PAM + rval = auth_pam(&pw, passwd); + if (rval >= 0) { +#ifdef USE_OPIE + opieunlock(); +#endif + goto skip; + } +#endif +#ifdef USE_OPIE + if (opieverify(&opiedata, (char *)passwd) == 0) { + /* OPIE says ok, check expire time */ + if (pw->pw_expire && time(NULL) >= pw->pw_expire) + rval = 2; + else + rval = 0; + goto skip; + } +#endif + if (!sflag) rval = checkpassword(pw, passwd); else @@ -1176,11 +1156,20 @@ pass(const char *passwd) } (void) initgroups(pw->pw_name, pw->pw_gid); /* cache groups for cmds.c::matchgroup() */ - gidcount = getgroups(0, NULL); - if (gidlist) - free(gidlist); - gidlist = malloc(gidcount * sizeof *gidlist); - gidcount = getgroups(gidcount, gidlist); + gidcount = getgroups(sizeof(gidlist), gidlist); + +#ifdef USE_PAM + if (pamh) { + if ((e = pam_open_session(pamh, 0)) != PAM_SUCCESS) { + syslog(LOG_ERR, "pam_open_session: %s", + pam_strerror(pamh, e)); + } else if ((e = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != + PAM_SUCCESS) { + syslog(LOG_ERR, "pam_setcred: %s", + pam_strerror(pamh, e)); + } + } +#endif /* open utmp/wtmp before chroot */ login_utmp(ttyline, pw->pw_name, remotehost); @@ -1294,7 +1283,6 @@ pass(const char *passwd) } break; } - setsid(); setlogin(pw->pw_name); if (dropprivs || (curclass.type != CLASS_REAL && @@ -1845,8 +1833,6 @@ send_data_with_read(int filefd, int netfd, const struct stat *st, int isdata) error = SS_FILE_ERROR; else if (write_data(netfd, buf, c, &bufrem, &then, isdata)) error = SS_DATA_ERROR; - else if (urgflag && handleoobcmd()) - error = SS_ABORTED; else continue; @@ -1913,8 +1899,6 @@ send_data_with_mmap(int filefd, int netfd, const struct stat *st, int isdata) isdata); (void) madvise(win, mapsize, MADV_DONTNEED); munmap(win, mapsize); - if (urgflag && handleoobcmd()) - return (SS_ABORTED); if (error) return (SS_DATA_ERROR); off += mapsize; @@ -1936,9 +1920,10 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata) { int c, filefd, netfd, rval; - urgflag = 0; transflag = 1; rval = -1; + if (setjmp(urgcatch)) + goto cleanup_send_data; switch (type) { @@ -1946,8 +1931,6 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata) /* XXXLUKEM: rate limit ascii send (get) */ (void) alarm(curclass.timeout); while ((c = getc(instr)) != EOF) { - if (urgflag && handleoobcmd()) - goto cleanup_send_data; byte_count++; if (c == '\n') { if (ferror(outstr)) @@ -1988,7 +1971,6 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata) case SS_SUCCESS: break; - case SS_ABORTED: case SS_NO_TRANSFER: goto cleanup_send_data; @@ -2014,12 +1996,11 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata) file_err: (void) alarm(0); perror_reply(551, "Error on input file"); - goto cleanup_send_data; + /* FALLTHROUGH */ cleanup_send_data: (void) alarm(0); transflag = 0; - urgflag = 0; if (isdata) { total_files_out++; total_files++; @@ -2041,22 +2022,16 @@ receive_data(FILE *instr, FILE *outstr) int c, bare_lfs, netfd, filefd, rval; off_t byteswritten; char buf[BUFSIZ]; - struct sigaction sa, sa_saved; #ifdef __GNUC__ (void) &bare_lfs; #endif - memset(&sa, 0, sizeof(sa)); - sigfillset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sa.sa_handler = lostconn; - (void) sigaction(SIGALRM, &sa, &sa_saved); - bare_lfs = 0; - urgflag = 0; transflag = 1; rval = -1; byteswritten = 0; + if (setjmp(urgcatch)) + goto cleanup_recv_data; #define FILESIZECHECK(x) \ do { \ @@ -2086,8 +2061,6 @@ receive_data(FILE *instr, FILE *outstr) if ((c = read(netfd, buf, MIN(sizeof(buf), bufrem))) <= 0) goto recvdone; - if (urgflag && handleoobcmd()) - goto cleanup_recv_data; FILESIZECHECK(byte_count + c); if ((d = write(filefd, buf, c)) != c) goto file_err; @@ -2106,8 +2079,6 @@ receive_data(FILE *instr, FILE *outstr) } } else { while ((c = read(netfd, buf, sizeof(buf))) > 0) { - if (urgflag && handleoobcmd()) - goto cleanup_recv_data; FILESIZECHECK(byte_count + c); if (write(filefd, buf, c) != c) goto file_err; @@ -2133,8 +2104,6 @@ receive_data(FILE *instr, FILE *outstr) (void) alarm(curclass.timeout); /* XXXLUKEM: rate limit ascii receive (put) */ while ((c = getc(instr)) != EOF) { - if (urgflag && handleoobcmd()) - goto cleanup_recv_data; byte_count++; total_data_in++; total_data++; @@ -2200,9 +2169,7 @@ receive_data(FILE *instr, FILE *outstr) cleanup_recv_data: (void) alarm(0); - (void) sigaction(SIGALRM, &sa_saved, NULL); transflag = 0; - urgflag = 0; total_files_in++; total_files++; total_xfers_in++; @@ -2492,24 +2459,29 @@ fatal(const char *s) void reply(int n, const char *fmt, ...) { - char msg[MAXPATHLEN * 2 + 100]; - size_t b; - va_list ap; + off_t b; + va_list ap; + va_start(ap, fmt); b = 0; if (n == 0) - b = snprintf(msg, sizeof(msg), " "); + cprintf(stdout, " "); else if (n < 0) - b = snprintf(msg, sizeof(msg), "%d-", -n); + cprintf(stdout, "%d-", -n); else - b = snprintf(msg, sizeof(msg), "%d ", n); - va_start(ap, fmt); - vsnprintf(msg + b, sizeof(msg) - b, fmt, ap); + cprintf(stdout, "%d ", n); + b = vprintf(fmt, ap); va_end(ap); - cprintf(stdout, "%s\r\n", msg); + total_bytes += b; + total_bytes_out += b; + cprintf(stdout, "\r\n"); (void)fflush(stdout); - if (debug) - syslog(LOG_DEBUG, "<--- %s", msg); + if (debug) { + syslog(LOG_DEBUG, "<--- %d%c", abs(n), (n < 0) ? '-' : ' '); + va_start(ap, fmt); + vsyslog(LOG_DEBUG, fmt, ap); + va_end(ap); + } } static void @@ -2531,8 +2503,6 @@ logremotehost(struct sockinet *who) /* * Record logout in wtmp file and exit with supplied status. - * NOTE: because this is called from signal handlers it cannot - * use stdio (or call other functions that use stdio). */ void dologout(int status) @@ -2550,8 +2520,6 @@ dologout(int status) #endif } /* beware of flushing buffers after a SIGPIPE */ - if (xferlogfd != -1) - close(xferlogfd); _exit(status); } @@ -2559,21 +2527,17 @@ void abor(void) { - if (!transflag) - return; tmpline[0] = '\0'; is_oob = 0; reply(426, "Transfer aborted. Data connection closed."); reply(226, "Abort successful"); - transflag = 0; /* flag that the transfer has aborted */ + longjmp(urgcatch, 1); } void statxfer(void) { - if (!transflag) - return; tmpline[0] = '\0'; is_oob = 0; if (file_size != (off_t) -1) @@ -2586,39 +2550,22 @@ statxfer(void) (LLT)byte_count, PLURAL(byte_count)); } -/* - * Call when urgflag != 0 to handle Out Of Band commands. - * Returns non zero if the OOB command aborted the transfer - * by setting transflag to 0. (c.f., "ABOR"). - */ -static int -handleoobcmd() +static void +myoob(int signo) { char *cp; - if (!urgflag) - return (0); - urgflag = 0; /* only process if transfer occurring */ if (!transflag) - return (0); + return; cp = tmpline; if (getline(cp, sizeof(tmpline), stdin) == NULL) { reply(221, "You could at least say goodbye."); dologout(0); } - /* - * Manually parse OOB commands, because we can't - * recursively call the yacc parser... - */ - if (strcasecmp(cp, "ABOR\r\n") == 0) { - abor(); - } else if (strcasecmp(cp, "STAT\r\n") == 0) { - statxfer(); - } else { - /* XXX: error with "500 unknown command" ? */ - } - return (transflag == 0); + is_oob = 1; + ftp_handle_line(cp); + is_oob = 0; } static int @@ -3034,8 +2981,7 @@ send_file_list(const char *whichf) DIR *dirp = NULL; struct dirent *dir; FILE *dout = NULL; - char **dirlist, *dirname, *p; - char *notglob = NULL; + char **dirlist, *dirname, *notglob, *p; int simple = 0; int freeglob = 0; glob_t gl; @@ -3046,7 +2992,6 @@ send_file_list(const char *whichf) (void) &simple; (void) &freeglob; #endif - urgflag = 0; p = NULL; if (strpbrk(whichf, "~{[*?") != NULL) { @@ -3056,11 +3001,11 @@ send_file_list(const char *whichf) freeglob = 1; if (glob(whichf, flags, 0, &gl)) { reply(550, "not found"); - goto cleanup_send_file_list; + goto out; } else if (gl.gl_pathc == 0) { errno = ENOENT; perror_reply(550, whichf); - goto cleanup_send_file_list; + goto out; } dirlist = gl.gl_pathv; } else { @@ -3071,6 +3016,10 @@ send_file_list(const char *whichf) } /* XXX: } for vi sm */ + if (setjmp(urgcatch)) { + transflag = 0; + goto out; + } while ((dirname = *dirlist++) != NULL) { int trailingslash = 0; @@ -3086,7 +3035,7 @@ send_file_list(const char *whichf) argv[1] = dirname; retrieve(argv, dirname); - goto cleanup_send_file_list; + goto out; } perror_reply(550, whichf); goto cleanup_send_file_list; @@ -3101,8 +3050,8 @@ send_file_list(const char *whichf) if (dout == NULL) { dout = dataconn("file list", (off_t)-1, "w"); if (dout == NULL) - goto cleanup_send_file_list; - transflag = 1; + goto out; + transflag++; } cprintf(dout, "%s%s\n", dirname, type == TYPE_A ? "\r" : ""); @@ -3119,9 +3068,6 @@ send_file_list(const char *whichf) while ((dir = readdir(dirp)) != NULL) { char nbuf[MAXPATHLEN]; - if (urgflag && handleoobcmd()) - goto cleanup_send_file_list; - if (ISDOTDIR(dir->d_name) || ISDOTDOTDIR(dir->d_name)) continue; @@ -3144,8 +3090,8 @@ send_file_list(const char *whichf) dout = dataconn("file list", (off_t)-1, "w"); if (dout == NULL) - goto cleanup_send_file_list; - transflag = 1; + goto out; + transflag++; } p = nbuf; if (nbuf[0] == '.' && nbuf[1] == '/') @@ -3165,9 +3111,9 @@ send_file_list(const char *whichf) reply(226, "Transfer complete."); cleanup_send_file_list: - closedataconn(dout); transflag = 0; - urgflag = 0; + closedataconn(dout); + out: total_xfers++; total_xfers_out++; if (notglob) @@ -3198,7 +3144,7 @@ conffilename(const char *s) * if error != NULL, append ": " + error * * if doxferlog != 0, bytes != -1, and command is "get", "put", - * or "append", syslog and/or write a wu-ftpd style xferlog entry + * or "append", syslog a wu-ftpd style xferlog entry */ void logxfer(const char *command, off_t bytes, const char *file1, const char *file2, @@ -3241,6 +3187,7 @@ logxfer(const char *command, off_t bytes, const char *file1, const char *file2, syslog(LOG_INFO, "%s", buf); } + /* * syslog wu-ftpd style log entry, prefixed with "xferlog: " */ @@ -3255,15 +3202,21 @@ logxfer(const char *command, off_t bytes, const char *file1, const char *file2, return; time(&now); - len = snprintf(buf, sizeof(buf), - "%.24s %ld %s " LLF " %s %c %s %c %c %s FTP 0 * %c\n", + syslog(LOG_INFO, + "xferlog%s: %.24s %ld %s " LLF " %s %c %s %c %c %s FTP 0 * %c", /* - * XXX: wu-ftpd puts ' (send)' or ' (recv)' in the syslog message, and removes + * XXX: wu-ftpd puts (send) or (recv) in the syslog message, and removes * the full date. This may be problematic for accurate log parsing, * given that syslog messages don't contain the full date. */ +#if 1 /* lukem's method; easier to convert to actual xferlog file */ + "", ctime(&now), +#else /* wu-ftpd's syslog method, with an extra unneeded space */ + (direction == 'i') ? " (recv)" : " (send)", + "", +#endif elapsed == NULL ? 0 : elapsed->tv_sec + (elapsed->tv_usec > 0), remotehost, (LLT) bytes, @@ -3279,13 +3232,6 @@ logxfer(const char *command, off_t bytes, const char *file1, const char *file2, curclass.type == CLASS_GUEST ? pw->pw_passwd : pw->pw_name, error != NULL ? 'i' : 'c' ); - - if ((doxferlog & 2) && xferlogfd != -1) - write(xferlogfd, buf, len); - if ((doxferlog & 1)) { - buf[len-1] = '\n'; /* strip \n from syslog message */ - syslog(LOG_INFO, "xferlog: %s", buf); - } } /* diff --git a/contrib/lukemftpd/src/ftpd.conf.5 b/contrib/lukemftpd/src/ftpd.conf.5 index 4d22bc6..9e2bc14 100644 --- a/contrib/lukemftpd/src/ftpd.conf.5 +++ b/contrib/lukemftpd/src/ftpd.conf.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: ftpd.conf.5,v 1.28 2003-06-27 18:59:54 wiz Exp $ +.\" $NetBSD: ftpd.conf.5,v 1.24 2002/11/29 14:40:00 lukem Exp $ .\" .\" Copyright (c) 1997-2001 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -34,6 +34,9 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" +.\" $FreeBSD$ +.\" +.\" .Dd November 30, 2002 .Dt FTPD.CONF 5 .Os @@ -100,7 +103,7 @@ A .Xr chroot 2 is performed after login. .It Sy CHROOT -.Xr chroot 2 Ns ed +.Xr chroot 2 ed users (as per .Xr ftpchroot 5 ) . A @@ -170,7 +173,7 @@ is not specified or .Ar class is .Dq none , -use the default behavior (see below). +use the default behaviour (see below). Otherwise, .Ar pathformat is parsed to create a directory to create as the root directory with @@ -311,7 +314,7 @@ is not specified or .Ar class is .Dq none , -use the default behavior (see below). +use the default behaviour (see below). Otherwise, .Ar pathformat is parsed to create a directory to change into upon login, and to use diff --git a/contrib/lukemftpd/src/ftpusers.5 b/contrib/lukemftpd/src/ftpusers.5 index 83b8466..3f5119b 100644 --- a/contrib/lukemftpd/src/ftpusers.5 +++ b/contrib/lukemftpd/src/ftpusers.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: ftpusers.5,v 1.15 2003-07-26 19:32:07 salo Exp $ +.\" $NetBSD: ftpusers.5,v 1.13 2001/12/01 16:24:24 wiz Exp $ .\" .\" Copyright (c) 1997-2001 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -34,6 +34,9 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" +.\" $FreeBSD$ +.\" +.\" .Dd July 17, 2000 .Dt FTPUSERS 5 .Os @@ -91,7 +94,7 @@ or an .Xr fnmatch 3 glob to match against the remote hostname (e.g, -.Sq *.NetBSD.org ) . +.Sq *.netbsd.org ) . .It Sy directive If .Dq allow |