aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2004-08-18 06:29:48 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2004-08-18 06:29:48 +0000
commit3a802515c66410d4be197709554a1888484563a8 (patch)
treee63b8bfc2f7ea7fd3c82cf52e4c952c3c661f2dd
parentfc25b5d977bc6ecd82285aa7b7619d7e9ff05915 (diff)
downloadsrc-3a802515c66410d4be197709554a1888484563a8.tar.gz
src-3a802515c66410d4be197709554a1888484563a8.zip
Import of LukeM's ftpd taken from the NetBSD CVS repo on 9-Aug-2004.
This closes the remotely exploitable vulnerability documented at ftp://ftp.netbsd.org/pub/NetBSD/security/advisories/NetBSD-SA2004-009.txt.asc http://www.vuxml.org/freebsd/c4b025bb-f05d-11d8-9837-000c41e2cdad.html
Notes
Notes: svn path=/vendor/lukemftpd/dist/; revision=133936
-rw-r--r--contrib/lukemftpd/libnetbsd/strsuftoll.c41
-rw-r--r--contrib/lukemftpd/src/Makefile27
-rw-r--r--contrib/lukemftpd/src/cmds.c15
-rw-r--r--contrib/lukemftpd/src/conf.c7
-rw-r--r--contrib/lukemftpd/src/extern.h32
-rw-r--r--contrib/lukemftpd/src/ftpcmd.y66
-rw-r--r--contrib/lukemftpd/src/ftpd.822
-rw-r--r--contrib/lukemftpd/src/ftpd.c295
-rw-r--r--contrib/lukemftpd/src/ftpd.conf.512
-rw-r--r--contrib/lukemftpd/src/ftpusers.56
-rw-r--r--contrib/lukemftpd/src/logutmp.c53
-rw-r--r--contrib/lukemftpd/src/logwtmp.c46
-rw-r--r--contrib/lukemftpd/src/pathnames.h8
-rw-r--r--contrib/lukemftpd/src/popen.c13
-rw-r--r--contrib/lukemftpd/src/version.h6
15 files changed, 407 insertions, 242 deletions
diff --git a/contrib/lukemftpd/libnetbsd/strsuftoll.c b/contrib/lukemftpd/libnetbsd/strsuftoll.c
index 52155ea776e3..3e3bfd5e3d7a 100644
--- a/contrib/lukemftpd/libnetbsd/strsuftoll.c
+++ b/contrib/lukemftpd/libnetbsd/strsuftoll.c
@@ -1,6 +1,6 @@
-/* $NetBSD: strsuftoll.c,v 1.1 2002/11/29 12:58:17 lukem Exp $ */
+/* $NetBSD: strsuftoll.c,v 1.5 2004/01/17 23:02:51 dbj Exp $ */
/*-
- * Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 2001-2002,2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -50,11 +50,7 @@
* 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. 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
+ * 3. 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.
*
@@ -71,20 +67,20 @@
* SUCH DAMAGE.
*/
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: strsuftoll.c,v 1.1 2002/11/29 12:58:17 lukem Exp $");
+__RCSID("$NetBSD: strsuftoll.c,v 1.5 2004/01/17 23:02:51 dbj Exp $");
#endif /* LIBC_SCCS and not lint */
#ifdef _LIBC
#include "namespace.h"
#endif
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#if !HAVE_STRSUFTOLL
#include <sys/types.h>
@@ -100,16 +96,11 @@ __RCSID("$NetBSD: strsuftoll.c,v 1.1 2002/11/29 12:58:17 lukem Exp $");
#include <string.h>
#ifdef _LIBC
-# define _STRSUFTOLL _strsuftoll
-# define _STRSUFTOLLX _strsuftollx
# ifdef __weak_alias
__weak_alias(strsuftoll, _strsuftoll)
__weak_alias(strsuftollx, _strsuftollx)
# endif
-#else /* !LIBC */
-# define _STRSUFTOLL strsuftoll
-# define _STRSUFTOLLX strsuftollx
-#endif /* !LIBC */
+#endif /* LIBC */
/*
* Convert an expression of the following forms to a (u)int64_t.
@@ -117,8 +108,10 @@ __weak_alias(strsuftollx, _strsuftollx)
* 2) A positive decimal number followed by a b (mult by 512).
* 3) A positive decimal number followed by a k (mult by 1024).
* 4) A positive decimal number followed by a m (mult by 1048576).
- * 5) A positive decimal number followed by a w (mult by sizeof int)
- * 6) Two or more positive decimal numbers (with/without k,b or w).
+ * 5) A positive decimal number followed by a g (mult by 1073741824).
+ * 6) A positive decimal number followed by a t (mult by 1099511627776).
+ * 7) A positive decimal number followed by a w (mult by sizeof int)
+ * 8) Two or more positive decimal numbers (with/without k,b or w).
* separated by x (also * for backwards compatibility), specifying
* the product of the indicated values.
* Returns the result upon successful conversion, or exits with an
@@ -127,7 +120,7 @@ __weak_alias(strsuftollx, _strsuftollx)
*/
/* LONGLONG */
long long
-_STRSUFTOLL(const char *desc, const char *val,
+strsuftoll(const char *desc, const char *val,
long long min, long long max)
{
long long result;
@@ -145,7 +138,7 @@ _STRSUFTOLL(const char *desc, const char *val,
*/
/* LONGLONG */
long long
-_STRSUFTOLLX(const char *desc, const char *val,
+strsuftollx(const char *desc, const char *val,
long long min, long long max, char *ebuf, size_t ebuflen)
{
long long num, t;
@@ -161,7 +154,7 @@ _STRSUFTOLLX(const char *desc, const char *val,
while (isspace((unsigned char)*val)) /* Skip leading space */
val++;
- num = strtoll(val, &expr, 0);
+ num = strtoll(val, &expr, 10);
if (errno == ERANGE)
goto erange; /* Overflow */
@@ -244,7 +237,7 @@ _STRSUFTOLLX(const char *desc, const char *val,
/* LONGLONG */
snprintf(ebuf, ebuflen,
"%s %lld is greater than %lld.",
- desc, (long long)num, (long long)min);
+ desc, (long long)num, (long long)max);
return (0);
}
*ebuf = '\0';
diff --git a/contrib/lukemftpd/src/Makefile b/contrib/lukemftpd/src/Makefile
index a70e43b8b554..82c37d119e0b 100644
--- a/contrib/lukemftpd/src/Makefile
+++ b/contrib/lukemftpd/src/Makefile
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.49 2002/08/22 00:09:38 christos Exp $
+# $NetBSD: Makefile,v 1.51 2003-07-23 08:01:27 itojun Exp $
# @(#)Makefile 8.2 (Berkeley) 4/4/94
.include <bsd.own.mk>
@@ -28,19 +28,24 @@ LDADD+= -lskey
ftpd.o ftpcmd.o: version.h
-# XXX Kerberos support is broken right now.
+#.if (${USE_KERBEROS} != "no")
+#
#.PATH: ${NETBSDSRCDIR}/usr.bin/login
-
-#.ifdef KERBEROS5
+#
#SRCS+= k5login.c
#CPPFLAGS+=-DKERBEROS5
-#DPADD+= ${LIBKRB5} ${LIBK5CRYPTO} ${LIBCOM_ERR}
-#LDADD+= -lkrb5 -lk5crypto -lcom_err
-#.else
-#SRCS+= klogin.c
-#CPPFLAGS+=-DKERBEROS
-#DPADD+= ${LIBKRB} ${LIBDES} ${LIBCOM_ERR}
-#LDADD+= -lkrb -kdes -lcom_err
+#CPPFLAGS+=-DKERBEROS5 -I${DESTDIR}/usr/include/krb5
+#DPADD+= ${LIBKRB5} ${LIBASN1}
+#LDADD+= -lkrb5 -lasn1
+#
+#SRCS+= klogin.c
+#CPPFLAGS+=-DKERBEROS -I${DESTDIR}/usr/include/kerberosIV
+#DPADD+= ${LIBKRB}
+#LDADD+= -lkrb
+#
+#DPADD+= ${LIBCRYPTO} ${LIBROKEN} ${LIBCOM_ERR}
+#LDADD+= -lcrypto -lroken -lcom_err
+#
#.endif
.include <bsd.prog.mk>
diff --git a/contrib/lukemftpd/src/cmds.c b/contrib/lukemftpd/src/cmds.c
index 7a287ea59275..7c8e2afe1471 100644
--- a/contrib/lukemftpd/src/cmds.c
+++ b/contrib/lukemftpd/src/cmds.c
@@ -1,7 +1,7 @@
-/* $NetBSD: cmds.c,v 1.20 2003/01/08 18:07:31 manu Exp $ */
+/* $NetBSD: cmds.c,v 1.23 2004-08-09 12:56:47 lukem Exp $ */
/*
- * Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -48,11 +48,7 @@
* 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. 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
+ * 3. 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.
*
@@ -101,7 +97,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: cmds.c,v 1.20 2003/01/08 18:07:31 manu Exp $");
+__RCSID("$NetBSD: cmds.c,v 1.23 2004-08-09 12:56:47 lukem Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -111,7 +107,6 @@ __RCSID("$NetBSD: cmds.c,v 1.20 2003/01/08 18:07:31 manu Exp $");
#include <dirent.h>
#include <errno.h>
-#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -812,7 +807,7 @@ static void
mlsname(FILE *fp, factelem *fe)
{
char realfile[MAXPATHLEN];
- int i, userf;
+ int i, userf = 0;
for (i = 0; i < FACTTABSIZE; i++) {
if (facttab[i].enabled)
diff --git a/contrib/lukemftpd/src/conf.c b/contrib/lukemftpd/src/conf.c
index 8f05793edbe4..0c142fcc9374 100644
--- a/contrib/lukemftpd/src/conf.c
+++ b/contrib/lukemftpd/src/conf.c
@@ -1,7 +1,7 @@
-/* $NetBSD: conf.c,v 1.50 2002/11/16 03:10:34 itojun Exp $ */
+/* $NetBSD: conf.c,v 1.52 2004-08-09 12:56:47 lukem Exp $ */
/*-
- * Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: conf.c,v 1.50 2002/11/16 03:10:34 itojun Exp $");
+__RCSID("$NetBSD: conf.c,v 1.52 2004-08-09 12:56:47 lukem Exp $");
#endif /* not lint */
#include <sys/types.h>
@@ -51,7 +51,6 @@ __RCSID("$NetBSD: conf.c,v 1.50 2002/11/16 03:10:34 itojun Exp $");
#include <fcntl.h>
#include <glob.h>
#include <netdb.h>
-#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/contrib/lukemftpd/src/extern.h b/contrib/lukemftpd/src/extern.h
index 25cdf112be16..9da3da4ca018 100644
--- a/contrib/lukemftpd/src/extern.h
+++ b/contrib/lukemftpd/src/extern.h
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.44 2002/05/30 00:24:47 enami Exp $ */
+/* $NetBSD: extern.h,v 1.50 2004-08-09 12:56:47 lukem Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -12,11 +12,7 @@
* 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. 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
+ * 3. 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.
*
@@ -36,7 +32,7 @@
*/
/*-
- * Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -147,9 +143,6 @@ char *getline(char *, int, FILE *);
void init_curclass(void);
void logxfer(const char *, off_t, const char *, const char *,
const struct timeval *, const char *);
-#if 0
-void logwtmp(const char *, const char *, const char *);
-#endif
struct tab *lookup(struct tab *, const char *);
void makedir(const char *);
void mlsd(const char *);
@@ -184,6 +177,21 @@ void user(const char *);
char *xstrdup(const char *);
void yyerror(char *);
+#ifdef SUPPORT_UTMP
+struct utmp;
+
+void ftpd_logwtmp(const char *, const char *, const char *);
+void ftpd_login(const struct utmp *ut);
+int ftpd_logout(const char *line);
+#endif
+
+#ifdef SUPPORT_UTMPX
+struct utmpx;
+
+void ftpd_loginx(const struct utmpx *);
+void ftpd_logwtmpx(const char *, const char *, const char *, int, int);
+#endif
+
#include <netinet/in.h>
#if defined(__NetBSD__)
@@ -302,11 +310,10 @@ GLOBAL struct sockinet pasv_addr;
GLOBAL int connections;
GLOBAL struct ftpclass curclass;
GLOBAL int debug;
-GLOBAL jmp_buf errcatch;
GLOBAL char *emailaddr;
GLOBAL int form;
GLOBAL int gidcount; /* number of entries in gidlist[] */
-GLOBAL gid_t gidlist[NGROUPS_MAX];
+GLOBAL gid_t *gidlist;
GLOBAL int hasyyerrored;
GLOBAL char hostname[MAXHOSTNAMELEN+1];
GLOBAL char homedir[MAXPATHLEN];
@@ -324,7 +331,6 @@ GLOBAL int quietmessages;
GLOBAL char remotehost[MAXHOSTNAMELEN+1];
GLOBAL off_t restart_point;
GLOBAL char tmpline[FTP_BUFLEN];
-GLOBAL sig_atomic_t transflag;
GLOBAL int type;
GLOBAL int usedefault; /* for data transfers */
GLOBAL const char *version;
diff --git a/contrib/lukemftpd/src/ftpcmd.y b/contrib/lukemftpd/src/ftpcmd.y
index 42a7131e3d39..484398d678dc 100644
--- a/contrib/lukemftpd/src/ftpcmd.y
+++ b/contrib/lukemftpd/src/ftpcmd.y
@@ -1,7 +1,7 @@
-/* $NetBSD: ftpcmd.y,v 1.73 2003/01/22 04:33:35 lukem Exp $ */
+/* $NetBSD: ftpcmd.y,v 1.80 2004-08-09 12:56:47 lukem Exp $ */
/*-
- * Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -48,11 +48,7 @@
* 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. 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
+ * 3. 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.
*
@@ -83,7 +79,7 @@
#if 0
static char sccsid[] = "@(#)ftpcmd.y 8.3 (Berkeley) 4/6/94";
#else
-__RCSID("$NetBSD: ftpcmd.y,v 1.73 2003/01/22 04:33:35 lukem Exp $");
+__RCSID("$NetBSD: ftpcmd.y,v 1.80 2004-08-09 12:56:47 lukem Exp $");
#endif
#endif /* not lint */
@@ -98,8 +94,6 @@ __RCSID("$NetBSD: ftpcmd.y,v 1.73 2003/01/22 04:33:35 lukem Exp $");
#include <ctype.h>
#include <errno.h>
#include <pwd.h>
-#include <setjmp.h>
-#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -128,7 +122,7 @@ char *fromname;
%union {
struct {
- off_t o;
+ LLT ll;
int i;
} u;
char *s;
@@ -138,7 +132,7 @@ char *fromname;
A B C E F I
L N P R S T
- SP CRLF COMMA
+ SP CRLF COMMA ALL
USER PASS ACCT CWD CDUP SMNT
QUIT REIN PORT PASV TYPE STRU
@@ -164,7 +158,6 @@ char *fromname;
LEXERR
%token <s> STRING
-%token <s> ALL
%token <u> NUMBER
%type <u.i> check_login octal_number byte_size
@@ -179,7 +172,7 @@ char *fromname;
cmd_sel
: cmd
{
- fromname = NULL;
+ REASSIGN(fromname, NULL);
restart_point = (off_t) 0;
}
@@ -459,8 +452,7 @@ cmd
if (check_write($3, 0)) {
if (fromname) {
renamecmd(fromname, $3);
- free(fromname);
- fromname = NULL;
+ REASSIGN(fromname, NULL);
} else {
reply(503, "Bad sequence of commands.");
}
@@ -548,7 +540,7 @@ cmd
| SITE SP CHMOD SP octal_number SP pathname CRLF
{
if (check_write($7, 0)) {
- if ($5 > 0777)
+ if (($5 == -1) || ($5 > 0777))
reply(501,
"CHMOD: Mode value must be between 0 and 0777");
else if (chmod($7, $5) < 0)
@@ -883,8 +875,8 @@ rcmd
: REST check_login SP NUMBER CRLF
{
if ($2) {
- fromname = NULL;
- restart_point = $4.o;
+ REASSIGN(fromname, NULL);
+ restart_point = (off_t)$4.ll;
reply(350,
"Restarting at " LLF ". Send STORE or RETRIEVE to initiate transfer.",
(LLT)restart_point);
@@ -894,8 +886,10 @@ rcmd
| RNFR SP pathname CRLF
{
restart_point = (off_t) 0;
- if (check_write($3, 0))
+ if (check_write($3, 0)) {
+ REASSIGN(fromname, NULL);
fromname = renamefrom($3);
+ }
if ($3 != NULL)
free($3);
}
@@ -987,7 +981,7 @@ host_long_port6
memset(&data_dest, 0, sizeof(data_dest));
#endif /* INET6 */
/* reject invalid LPRT command */
- if ($1.i != 6.i || $3.i != 16.i || $37.i != 2)
+ if ($1.i != 6 || $3.i != 16 || $37.i != 2)
memset(&data_dest, 0, sizeof(data_dest));
}
;
@@ -1302,8 +1296,7 @@ struct tab sitetab[] = {
static int check_write(const char *, int);
static void help(struct tab *, const char *);
static void port_check(const char *, int);
-static void toolong(int);
-static int yylex(void);
+ int yylex(void);
extern int epsvall;
@@ -1449,19 +1442,6 @@ getline(char *s, int n, FILE *iop)
return (s);
}
-static void
-toolong(int signo)
-{
-
- 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);
-}
-
void
ftp_handle_line(char *cp)
{
@@ -1475,7 +1455,6 @@ ftp_loop(void)
{
while (1) {
- (void) signal(SIGALRM, toolong);
(void) alarm(curclass.timeout);
if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
reply(221, "You could at least say goodbye.");
@@ -1487,7 +1466,7 @@ ftp_loop(void)
/*NOTREACHED*/
}
-static int
+int
yylex(void)
{
static int cpos, state;
@@ -1626,15 +1605,14 @@ yylex(void)
c = cmdp[cpos];
cmdp[cpos] = '\0';
yylval.u.i = atoi(cp);
- yylval.u.o = strtoull(cp, (char **)NULL, 10);
+ yylval.u.ll = STRTOLL(cp, (char **)NULL, 10);
cmdp[cpos] = c;
return (NUMBER);
}
if (strncasecmp(&cmdp[cpos], "ALL", 3) == 0
- && !isalnum(cmdp[cpos + 3])) {
- yylval.s = xstrdup("ALL");
+ && !isalnum(cmdp[cpos + 3])) {
cpos += 3;
- return ALL;
+ return (ALL);
}
switch (cmdp[cpos++]) {
@@ -1720,9 +1698,7 @@ yylex(void)
}
yyerror(NULL);
state = CMD;
- is_oob = 0;
- longjmp(errcatch, 0);
- /* NOTREACHED */
+ return (0);
}
/* ARGSUSED */
diff --git a/contrib/lukemftpd/src/ftpd.8 b/contrib/lukemftpd/src/ftpd.8
index d02463389f38..76e7e007f709 100644
--- a/contrib/lukemftpd/src/ftpd.8
+++ b/contrib/lukemftpd/src/ftpd.8
@@ -1,6 +1,6 @@
-.\" $NetBSD: ftpd.8,v 1.69 2002/02/08 01:30:07 ross Exp $
+.\" $NetBSD: ftpd.8,v 1.74 2003-08-07 09:46:39 agc Exp $
.\"
-.\" Copyright (c) 1997-2002 The NetBSD Foundation, Inc.
+.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
@@ -45,11 +45,7 @@
.\" 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. 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
+.\" 3. 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.
.\"
@@ -67,7 +63,7 @@
.\"
.\" @(#)ftpd.8 8.2 (Berkeley) 4/19/94
.\"
-.Dd October 25, 2002
+.Dd February 26, 2003
.Dt FTPD 8
.Os
.Sh NAME
@@ -82,6 +78,7 @@ Internet File Transfer Protocol server
.Op Fl C Ar user
.Op Fl e Ar emailaddr
.Op Fl h Ar hostname
+.Op Fl L Ar xferlogfile
.Op Fl P Ar dataport
.Op Fl V Ar version
.Sh DESCRIPTION
@@ -172,6 +169,13 @@ session is logged using syslog with a facility of
If this option is specified more than once, the retrieve (get), store (put),
append, delete, make directory, remove directory and rename operations and
their file name arguments are also logged.
+.It Fl L Ar xferlogfile
+Log
+.Tn wu-ftpd
+style
+.Sq xferlog
+entries to
+.Ar xferlogfile .
.It Fl P Ar dataport
Use
.Ar dataport
@@ -392,7 +396,7 @@ interprets file names according to the
.Dq globbing
conventions used by
.Xr csh 1 .
-This allows users to utilize the metacharacters
+This allows users to use the metacharacters
.Dq Li \&*?[]{}~ .
.Ss User authentication
.Nm
diff --git a/contrib/lukemftpd/src/ftpd.c b/contrib/lukemftpd/src/ftpd.c
index 5f6cd24978c4..db89e873ede3 100644
--- a/contrib/lukemftpd/src/ftpd.c
+++ b/contrib/lukemftpd/src/ftpd.c
@@ -1,7 +1,7 @@
-/* $NetBSD: ftpd.c,v 1.150 2003/01/22 04:46:08 lukem Exp $ */
+/* $NetBSD: ftpd.c,v 1.158 2004-08-09 12:56:47 lukem Exp $ */
/*
- * Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -48,11 +48,7 @@
* 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. 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
+ * 3. 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.
*
@@ -109,7 +105,7 @@ __COPYRIGHT(
#if 0
static char sccsid[] = "@(#)ftpd.c 8.5 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: ftpd.c,v 1.150 2003/01/22 04:46:08 lukem Exp $");
+__RCSID("$NetBSD: ftpd.c,v 1.158 2004-08-09 12:56:47 lukem Exp $");
#endif
#endif /* not lint */
@@ -144,7 +140,6 @@ __RCSID("$NetBSD: ftpd.c,v 1.150 2003/01/22 04:46:08 lukem Exp $");
#include <limits.h>
#include <netdb.h>
#include <pwd.h>
-#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
@@ -174,8 +169,10 @@ __RCSID("$NetBSD: ftpd.c,v 1.150 2003/01/22 04:46:08 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;
@@ -183,7 +180,8 @@ int dataport; /* use specific data port */
int dopidfile; /* maintain pid file */
int doutmp; /* update utmp file */
int dowtmp; /* update wtmp file */
-int doxferlog; /* syslog wu-ftpd style xferlog entries */
+int doxferlog; /* syslog/write wu-ftpd style xferlog entries */
+int xferlogfd; /* fd to write wu-ftpd xferlog entries to */
int dropprivs; /* if privileges should or have been dropped */
int mapped; /* IPv4 connection on AF_INET6 socket */
off_t file_size;
@@ -199,6 +197,9 @@ 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;
@@ -222,6 +223,7 @@ 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 */
@@ -237,7 +239,10 @@ 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 myoob(int);
+static void toolong(int);
+static void sigquit(int);
+static void sigurg(int);
+static int handleoobcmd(void);
static int receive_data(FILE *, FILE *);
static int send_data(FILE *, FILE *, const struct stat *, int);
static struct passwd *sgetpwnam(const char *);
@@ -269,7 +274,9 @@ 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;
@@ -281,6 +288,7 @@ 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;
@@ -297,7 +305,7 @@ main(int argc, char *argv[])
*/
openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
- while ((ch = getopt(argc, argv, "a:c:C:de:h:HlP:qQrst:T:uUvV:wWX"))
+ while ((ch = getopt(argc, argv, "a:c:C:de:h:HlL:P:qQrst:T:uUvV:wWX"))
!= -1) {
switch (ch) {
case 'a':
@@ -336,6 +344,10 @@ main(int argc, char *argv[])
logging++; /* > 1 == extra logging */
break;
+ case 'L':
+ xferlogname = optarg;
+ break;
+
case 'P':
errno = 0;
p = NULL;
@@ -397,7 +409,7 @@ main(int argc, char *argv[])
break;
case 'X':
- doxferlog = 1;
+ doxferlog |= 1;
break;
default:
@@ -410,6 +422,23 @@ 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) {
@@ -490,10 +519,26 @@ main(int argc, char *argv[])
(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
(void) freopen(_PATH_DEVNULL, "w", stderr);
- (void) signal(SIGPIPE, lostconn);
- (void) signal(SIGCHLD, SIG_IGN);
- if (signal(SIGURG, myoob) == SIG_ERR)
- syslog(LOG_WARNING, "signal: %m");
+
+ 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);
/* Try to handle urgent data inline */
#ifdef SO_OOBINLINE
@@ -549,7 +594,16 @@ main(int argc, char *argv[])
else
reply(220, "%s FTP server (%s) ready.", hostname, version);
- (void) setjmp(errcatch);
+ 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;
+ }
+
ftp_loop();
/* NOTREACHED */
}
@@ -563,6 +617,37 @@ 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
@@ -596,7 +681,6 @@ 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.
@@ -670,7 +754,7 @@ user(const char *name)
} else
pw = sgetpwnam(name);
- strlcpy(curname, name, sizeof(curname));
+ strlcpy(curname, name, curname_len);
/* check user in /etc/ftpusers, and setup class */
permitted = checkuser(_PATH_FTPUSERS, curname, 1, 0, &class);
@@ -936,10 +1020,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));
- loginx(&utmpx);
+ ftpd_loginx(&utmpx);
}
if (dowtmp)
- logwtmpx(line, name, host, 0, USER_PROCESS);
+ ftpd_logwtmpx(line, name, host, 0, USER_PROCESS);
#endif
#ifdef SUPPORT_UTMP
if (doutmp) {
@@ -948,10 +1032,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));
- login(&utmp);
+ ftpd_login(&utmp);
}
if (dowtmp)
- logwtmp(line, name, host);
+ ftpd_logwtmp(line, name, host);
#endif
}
@@ -965,15 +1049,15 @@ logout_utmp(void)
okwtmp = logoutx(ttyline, 0, DEAD_PROCESS) & dowtmp;
#endif
#ifdef SUPPORT_UTMP
- okwtmp = logout(ttyline) & dowtmp;
+ okwtmp = ftpd_logout(ttyline) & dowtmp;
#endif
}
if (okwtmp) {
#ifdef SUPPORT_UTMPX
- logwtmpx(ttyline, "", "", 0, DEAD_PROCESS);
+ ftpd_logwtmpx(ttyline, "", "", 0, DEAD_PROCESS);
#endif
#ifdef SUPPORT_UTMP
- logwtmp(ttyline, "", "");
+ ftpd_logwtmp(ttyline, "", "");
#endif
}
}
@@ -1092,7 +1176,11 @@ pass(const char *passwd)
}
(void) initgroups(pw->pw_name, pw->pw_gid);
/* cache groups for cmds.c::matchgroup() */
- gidcount = getgroups(sizeof(gidlist), gidlist);
+ gidcount = getgroups(0, NULL);
+ if (gidlist)
+ free(gidlist);
+ gidlist = malloc(gidcount * sizeof *gidlist);
+ gidcount = getgroups(gidcount, gidlist);
/* open utmp/wtmp before chroot */
login_utmp(ttyline, pw->pw_name, remotehost);
@@ -1206,6 +1294,7 @@ pass(const char *passwd)
}
break;
}
+ setsid();
setlogin(pw->pw_name);
if (dropprivs ||
(curclass.type != CLASS_REAL &&
@@ -1756,6 +1845,8 @@ 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;
@@ -1822,6 +1913,8 @@ 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;
@@ -1843,10 +1936,9 @@ 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) {
@@ -1854,6 +1946,8 @@ 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))
@@ -1894,6 +1988,7 @@ 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;
@@ -1919,11 +2014,12 @@ send_data(FILE *instr, FILE *outstr, const struct stat *st, int isdata)
file_err:
(void) alarm(0);
perror_reply(551, "Error on input file");
- /* FALLTHROUGH */
+ goto cleanup_send_data;
cleanup_send_data:
(void) alarm(0);
transflag = 0;
+ urgflag = 0;
if (isdata) {
total_files_out++;
total_files++;
@@ -1945,16 +2041,22 @@ 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 { \
@@ -1984,6 +2086,8 @@ 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;
@@ -2002,6 +2106,8 @@ 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;
@@ -2027,6 +2133,8 @@ 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++;
@@ -2092,7 +2200,9 @@ 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++;
@@ -2382,29 +2492,24 @@ fatal(const char *s)
void
reply(int n, const char *fmt, ...)
{
- off_t b;
- va_list ap;
+ char msg[MAXPATHLEN * 2 + 100];
+ size_t b;
+ va_list ap;
- va_start(ap, fmt);
b = 0;
if (n == 0)
- cprintf(stdout, " ");
+ b = snprintf(msg, sizeof(msg), " ");
else if (n < 0)
- cprintf(stdout, "%d-", -n);
+ b = snprintf(msg, sizeof(msg), "%d-", -n);
else
- cprintf(stdout, "%d ", n);
- b = vprintf(fmt, ap);
+ b = snprintf(msg, sizeof(msg), "%d ", n);
+ va_start(ap, fmt);
+ vsnprintf(msg + b, sizeof(msg) - b, fmt, ap);
va_end(ap);
- total_bytes += b;
- total_bytes_out += b;
- cprintf(stdout, "\r\n");
+ cprintf(stdout, "%s\r\n", msg);
(void)fflush(stdout);
- if (debug) {
- syslog(LOG_DEBUG, "<--- %d%c", abs(n), (n < 0) ? '-' : ' ');
- va_start(ap, fmt);
- vsyslog(LOG_DEBUG, fmt, ap);
- va_end(ap);
- }
+ if (debug)
+ syslog(LOG_DEBUG, "<--- %s", msg);
}
static void
@@ -2426,6 +2531,8 @@ 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)
@@ -2443,6 +2550,8 @@ dologout(int status)
#endif
}
/* beware of flushing buffers after a SIGPIPE */
+ if (xferlogfd != -1)
+ close(xferlogfd);
_exit(status);
}
@@ -2450,17 +2559,21 @@ void
abor(void)
{
+ if (!transflag)
+ return;
tmpline[0] = '\0';
is_oob = 0;
reply(426, "Transfer aborted. Data connection closed.");
reply(226, "Abort successful");
- longjmp(urgcatch, 1);
+ transflag = 0; /* flag that the transfer has aborted */
}
void
statxfer(void)
{
+ if (!transflag)
+ return;
tmpline[0] = '\0';
is_oob = 0;
if (file_size != (off_t) -1)
@@ -2473,22 +2586,39 @@ statxfer(void)
(LLT)byte_count, PLURAL(byte_count));
}
-static void
-myoob(int signo)
+/*
+ * 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()
{
char *cp;
+ if (!urgflag)
+ return (0);
+ urgflag = 0;
/* only process if transfer occurring */
if (!transflag)
- return;
+ return (0);
cp = tmpline;
if (getline(cp, sizeof(tmpline), stdin) == NULL) {
reply(221, "You could at least say goodbye.");
dologout(0);
}
- is_oob = 1;
- ftp_handle_line(cp);
- is_oob = 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);
}
static int
@@ -2904,7 +3034,8 @@ send_file_list(const char *whichf)
DIR *dirp = NULL;
struct dirent *dir;
FILE *dout = NULL;
- char **dirlist, *dirname, *notglob, *p;
+ char **dirlist, *dirname, *p;
+ char *notglob = NULL;
int simple = 0;
int freeglob = 0;
glob_t gl;
@@ -2915,6 +3046,7 @@ send_file_list(const char *whichf)
(void) &simple;
(void) &freeglob;
#endif
+ urgflag = 0;
p = NULL;
if (strpbrk(whichf, "~{[*?") != NULL) {
@@ -2924,11 +3056,11 @@ send_file_list(const char *whichf)
freeglob = 1;
if (glob(whichf, flags, 0, &gl)) {
reply(550, "not found");
- goto out;
+ goto cleanup_send_file_list;
} else if (gl.gl_pathc == 0) {
errno = ENOENT;
perror_reply(550, whichf);
- goto out;
+ goto cleanup_send_file_list;
}
dirlist = gl.gl_pathv;
} else {
@@ -2939,10 +3071,6 @@ send_file_list(const char *whichf)
}
/* XXX: } for vi sm */
- if (setjmp(urgcatch)) {
- transflag = 0;
- goto out;
- }
while ((dirname = *dirlist++) != NULL) {
int trailingslash = 0;
@@ -2958,7 +3086,7 @@ send_file_list(const char *whichf)
argv[1] = dirname;
retrieve(argv, dirname);
- goto out;
+ goto cleanup_send_file_list;
}
perror_reply(550, whichf);
goto cleanup_send_file_list;
@@ -2973,8 +3101,8 @@ send_file_list(const char *whichf)
if (dout == NULL) {
dout = dataconn("file list", (off_t)-1, "w");
if (dout == NULL)
- goto out;
- transflag++;
+ goto cleanup_send_file_list;
+ transflag = 1;
}
cprintf(dout, "%s%s\n", dirname,
type == TYPE_A ? "\r" : "");
@@ -2991,6 +3119,9 @@ 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;
@@ -3013,8 +3144,8 @@ send_file_list(const char *whichf)
dout = dataconn("file list", (off_t)-1,
"w");
if (dout == NULL)
- goto out;
- transflag++;
+ goto cleanup_send_file_list;
+ transflag = 1;
}
p = nbuf;
if (nbuf[0] == '.' && nbuf[1] == '/')
@@ -3034,9 +3165,9 @@ send_file_list(const char *whichf)
reply(226, "Transfer complete.");
cleanup_send_file_list:
- transflag = 0;
closedataconn(dout);
- out:
+ transflag = 0;
+ urgflag = 0;
total_xfers++;
total_xfers_out++;
if (notglob)
@@ -3067,7 +3198,7 @@ conffilename(const char *s)
* if error != NULL, append ": " + error
*
* if doxferlog != 0, bytes != -1, and command is "get", "put",
- * or "append", syslog a wu-ftpd style xferlog entry
+ * or "append", syslog and/or write a wu-ftpd style xferlog entry
*/
void
logxfer(const char *command, off_t bytes, const char *file1, const char *file2,
@@ -3110,7 +3241,6 @@ 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: "
*/
@@ -3125,21 +3255,15 @@ logxfer(const char *command, off_t bytes, const char *file1, const char *file2,
return;
time(&now);
- syslog(LOG_INFO,
- "xferlog%s: %.24s %ld %s " LLF " %s %c %s %c %c %s FTP 0 * %c",
+ len = snprintf(buf, sizeof(buf),
+ "%.24s %ld %s " LLF " %s %c %s %c %c %s FTP 0 * %c\n",
/*
- * 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,
@@ -3155,6 +3279,13 @@ 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 f06c9077d087..4d22bc6aaeb9 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.24 2002/11/29 14:40:00 lukem Exp $
+.\" $NetBSD: ftpd.conf.5,v 1.28 2003-06-27 18:59:54 wiz Exp $
.\"
.\" Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -80,7 +80,7 @@ is used to determine which
.Nm
entries apply to the user.
The following special classes exist when parsing entries in
-.Nm "" :
+.Nm :
.Bl -tag -width "chroot" -compact -offset indent
.It Sy all
Matches any class.
@@ -100,7 +100,7 @@ A
.Xr chroot 2
is performed after login.
.It Sy CHROOT
-.Xr chroot 2 ed
+.Xr chroot 2 Ns ed
users (as per
.Xr ftpchroot 5 ) .
A
@@ -114,7 +114,7 @@ The
.Xr ftpd 8
.Sy STAT
command will return the class settings for the current user as defined by
-.Nm "" ,
+.Nm ,
unless the
.Sy private
directive is set for the class.
@@ -170,7 +170,7 @@ is not specified or
.Ar class
is
.Dq none ,
-use the default behaviour (see below).
+use the default behavior (see below).
Otherwise,
.Ar pathformat
is parsed to create a directory to create as the root directory with
@@ -311,7 +311,7 @@ is not specified or
.Ar class
is
.Dq none ,
-use the default behaviour (see below).
+use the default behavior (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 7b2603553a61..83b846640548 100644
--- a/contrib/lukemftpd/src/ftpusers.5
+++ b/contrib/lukemftpd/src/ftpusers.5
@@ -1,4 +1,4 @@
-.\" $NetBSD: ftpusers.5,v 1.12 2001/12/01 10:16:06 lukem Exp $
+.\" $NetBSD: ftpusers.5,v 1.15 2003-07-26 19:32:07 salo Exp $
.\"
.\" Copyright (c) 1997-2001 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -91,7 +91,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
@@ -159,7 +159,7 @@ or to the home directory of the user.
If the file does not exist, the root directory change is not performed.
.Pp
The syntax is similar to
-.Nm "" ,
+.Nm ,
except that the
.Sy class
argument is ignored.
diff --git a/contrib/lukemftpd/src/logutmp.c b/contrib/lukemftpd/src/logutmp.c
index cdd05bc7895d..c93a8ebd347a 100644
--- a/contrib/lukemftpd/src/logutmp.c
+++ b/contrib/lukemftpd/src/logutmp.c
@@ -1,7 +1,6 @@
/*
* Portions Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
- * Portions Copyright (c) 1996, Jason Downs. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -11,11 +10,7 @@
* 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. 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
+ * 3. 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.
*
@@ -32,7 +27,33 @@
* SUCH DAMAGE.
*/
+/*
+ * Portions Copyright (c) 1996, Jason Downs. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
#include <sys/types.h>
+#include <sys/param.h>
#include <fcntl.h>
#include <stdio.h>
@@ -41,8 +62,13 @@
#include <ttyent.h>
#include <unistd.h>
#include <utmp.h>
+#ifdef SUPPORT_UTMPX
+#include <utmpx.h>
+#endif
#include <util.h>
+#include "extern.h"
+
typedef struct utmp UTMP;
static int fd = -1;
@@ -54,7 +80,7 @@ static int topslot = -1;
*/
void
-login(const UTMP *ut)
+ftpd_login(const struct utmp *ut)
{
UTMP ubuf;
@@ -94,7 +120,7 @@ login(const UTMP *ut)
}
int
-logout(const char *line)
+ftpd_logout(const char *line)
{
UTMP ut;
int rval;
@@ -118,3 +144,14 @@ logout(const char *line)
}
return(rval);
}
+
+#ifdef SUPPORT_UTMPX
+/*
+ * special version of loginx which updates utmpx only.
+ */
+void
+ftpd_loginx(const struct utmpx *ut)
+{
+ (void)pututxline(ut);
+}
+#endif
diff --git a/contrib/lukemftpd/src/logwtmp.c b/contrib/lukemftpd/src/logwtmp.c
index 5da4a1d63654..93b61a919dbe 100644
--- a/contrib/lukemftpd/src/logwtmp.c
+++ b/contrib/lukemftpd/src/logwtmp.c
@@ -1,4 +1,4 @@
-/* $NetBSD: logwtmp.c,v 1.17 2002/09/12 08:55:31 itojun Exp $ */
+/* $NetBSD: logwtmp.c,v 1.22 2004-08-09 12:56:48 lukem Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -12,11 +12,7 @@
* 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. 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
+ * 3. 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.
*
@@ -40,7 +36,7 @@
#if 0
static char sccsid[] = "@(#)logwtmp.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: logwtmp.c,v 1.17 2002/09/12 08:55:31 itojun Exp $");
+__RCSID("$NetBSD: logwtmp.c,v 1.22 2004-08-09 12:56:48 lukem Exp $");
#endif
#endif /* not lint */
@@ -48,15 +44,18 @@ __RCSID("$NetBSD: logwtmp.c,v 1.17 2002/09/12 08:55:31 itojun Exp $");
#include <sys/param.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <fcntl.h>
-#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <utmp.h>
+#ifdef SUPPORT_UTMPX
+#include <utmpx.h>
+#endif
#include <util.h>
#ifdef KERBEROS5
@@ -66,6 +65,9 @@ __RCSID("$NetBSD: logwtmp.c,v 1.17 2002/09/12 08:55:31 itojun Exp $");
#include "extern.h"
static int fd = -1;
+#ifdef SUPPORT_UTMPX
+static int fdx = -1;
+#endif
/*
* Modified version of logwtmp that holds wtmp file open
@@ -73,7 +75,7 @@ static int fd = -1;
* after login, but before logout).
*/
void
-logwtmp(const char *line, const char *name, const char *host)
+ftpd_logwtmp(const char *line, const char *name, const char *host)
{
struct utmp ut;
struct stat buf;
@@ -90,3 +92,29 @@ logwtmp(const char *line, const char *name, const char *host)
(void)ftruncate(fd, buf.st_size);
}
}
+
+#ifdef SUPPORT_UTMPX
+void
+ftpd_logwtmpx(const char *line, const char *name, const char *host, int status, int utx_type)
+{
+ struct utmpx ut;
+ struct stat buf;
+
+ if (fdx < 0 && (fdx = open(_PATH_WTMPX, O_WRONLY|O_APPEND, 0)) < 0)
+ return;
+ if (fstat(fdx, &buf) == 0) {
+ (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
+ (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
+ ut.ut_type = utx_type;
+ if (WIFEXITED(status))
+ ut.ut_exit.e_exit = (uint16_t)WEXITSTATUS(status);
+ if (WIFSIGNALED(status))
+ ut.ut_exit.e_termination = (uint16_t)WTERMSIG(status);
+ (void)gettimeofday(&ut.ut_tv, NULL);
+ if(write(fdx, (char *)&ut, sizeof(struct utmpx)) !=
+ sizeof(struct utmpx))
+ (void)ftruncate(fdx, buf.st_size);
+ }
+}
+#endif
diff --git a/contrib/lukemftpd/src/pathnames.h b/contrib/lukemftpd/src/pathnames.h
index 056122ec22c0..f2a48111c2ad 100644
--- a/contrib/lukemftpd/src/pathnames.h
+++ b/contrib/lukemftpd/src/pathnames.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pathnames.h,v 1.9 2000/01/08 11:09:56 lukem Exp $ */
+/* $NetBSD: pathnames.h,v 1.11 2003-08-07 09:46:40 agc Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -12,11 +12,7 @@
* 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. 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
+ * 3. 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.
*
diff --git a/contrib/lukemftpd/src/popen.c b/contrib/lukemftpd/src/popen.c
index 7a7c6c461ac1..a987475e5581 100644
--- a/contrib/lukemftpd/src/popen.c
+++ b/contrib/lukemftpd/src/popen.c
@@ -1,7 +1,7 @@
-/* $NetBSD: popen.c,v 1.28 2003/01/16 09:41:38 kleink Exp $ */
+/* $NetBSD: popen.c,v 1.30 2004-08-09 12:56:48 lukem Exp $ */
/*-
- * Copyright (c) 1999-2001 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -51,11 +51,7 @@
* 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. 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
+ * 3. 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.
*
@@ -78,7 +74,7 @@
#if 0
static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 4/6/94";
#else
-__RCSID("$NetBSD: popen.c,v 1.28 2003/01/16 09:41:38 kleink Exp $");
+__RCSID("$NetBSD: popen.c,v 1.30 2004-08-09 12:56:48 lukem Exp $");
#endif
#endif /* not lint */
@@ -88,7 +84,6 @@ __RCSID("$NetBSD: popen.c,v 1.28 2003/01/16 09:41:38 kleink Exp $");
#include <errno.h>
#include <glob.h>
-#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/contrib/lukemftpd/src/version.h b/contrib/lukemftpd/src/version.h
index 4ffeb8a9b601..d18fc73dc572 100644
--- a/contrib/lukemftpd/src/version.h
+++ b/contrib/lukemftpd/src/version.h
@@ -1,6 +1,6 @@
-/* $NetBSD: version.h,v 1.50 2003/01/22 04:46:08 lukem Exp $ */
+/* $NetBSD: version.h,v 1.57 2004-08-09 12:56:48 lukem Exp $ */
/*-
- * Copyright (c) 1999-2002 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999-2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -36,5 +36,5 @@
*/
#ifndef FTPD_VERSION
-#define FTPD_VERSION "NetBSD-ftpd 20030122"
+#define FTPD_VERSION "NetBSD-ftpd 20040809"
#endif