svn commit: r202018 - user/ed/utmpx/libexec/ftpd

Ed Schouten ed at FreeBSD.org
Sun Jan 10 17:15:37 UTC 2010


Author: ed
Date: Sun Jan 10 17:15:36 2010
New Revision: 202018
URL: http://svn.freebsd.org/changeset/base/202018

Log:
  Make ftpd work with utmpx.
  
  Unfortunately we can't allow utmpx to be used with chroot as well. The
  interface doesn't allow us to keep file descriptors to the database
  files alive.

Modified:
  user/ed/utmpx/libexec/ftpd/ftpd.c
  user/ed/utmpx/libexec/ftpd/logwtmp.c

Modified: user/ed/utmpx/libexec/ftpd/ftpd.c
==============================================================================
--- user/ed/utmpx/libexec/ftpd/ftpd.c	Sun Jan 10 16:58:12 2010	(r202017)
+++ user/ed/utmpx/libexec/ftpd/ftpd.c	Sun Jan 10 17:15:36 2010	(r202018)
@@ -173,8 +173,7 @@ static struct ftphost {
 char	remotehost[NI_MAXHOST];
 char	*ident = NULL;
 
-static char	ttyline[20];
-char		*tty = ttyline;		/* for klogin */
+static char	wtmpid[20];
 
 #ifdef USE_PAM
 static int	auth_pam(struct passwd**, const char*);
@@ -584,8 +583,7 @@ gotchild:
 
 	data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
 
-	/* set this here so klogin can use it... */
-	(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
+	(void)snprintf(wtmpid, sizeof(wtmpid), "%xftpd", getpid());
 
 	/* Try to handle urgent data inline */
 #ifdef SO_OOBINLINE
@@ -1180,8 +1178,8 @@ end_login(void)
 #endif
 
 	(void) seteuid(0);
-	if (logged_in && dowtmp)
-		ftpd_logwtmp(ttyline, "", NULL);
+	if (logged_in && dowtmp && !dochroot)
+		ftpd_logwtmp(wtmpid, "", NULL);
 	pw = NULL;
 #ifdef	LOGIN_CAP
 	setusercontext(NULL, getpwuid(0), 0,
@@ -1476,9 +1474,17 @@ skip:
 	}
 #endif
 
+	dochroot =
+		checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue)
+#ifdef	LOGIN_CAP	/* Allow login.conf configuration as well */
+		|| login_getcapbool(lc, "ftp-chroot", 0)
+#endif
+	;
+	chrootdir = NULL;
+
 	/* open wtmp before chroot */
-	if (dowtmp)
-		ftpd_logwtmp(ttyline, pw->pw_name,
+	if (dowtmp && !dochroot)
+		ftpd_logwtmp(wtmpid, pw->pw_name,
 		    (struct sockaddr *)&his_addr);
 	logged_in = 1;
 
@@ -1491,13 +1497,6 @@ skip:
 		if (statfd < 0)
 			stats = 0;
 
-	dochroot =
-		checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue)
-#ifdef	LOGIN_CAP	/* Allow login.conf configuration as well */
-		|| login_getcapbool(lc, "ftp-chroot", 0)
-#endif
-	;
-	chrootdir = NULL;
 	/*
 	 * For a chrooted local user,
 	 * a) see whether ftpchroot(5) specifies a chroot directory,
@@ -2732,9 +2731,9 @@ void
 dologout(int status)
 {
 
-	if (logged_in && dowtmp) {
+	if (logged_in && dowtmp && !dochroot) {
 		(void) seteuid(0);
-		ftpd_logwtmp(ttyline, "", NULL);
+		ftpd_logwtmp(wtmpid, "", NULL);
 	}
 	/* beware of flushing buffers after a SIGPIPE */
 	_exit(status);

Modified: user/ed/utmpx/libexec/ftpd/logwtmp.c
==============================================================================
--- user/ed/utmpx/libexec/ftpd/logwtmp.c	Sun Jan 10 16:58:12 2010	(r202017)
+++ user/ed/utmpx/libexec/ftpd/logwtmp.c	Sun Jan 10 17:15:36 2010	(r202018)
@@ -46,53 +46,35 @@ __FBSDID("$FreeBSD$");
 #include <arpa/inet.h>
 #include <sys/socket.h>
 
-#include <fcntl.h>
-#include <time.h>
-#include <timeconv.h>
-#include <netdb.h>
-#if 0
-#include <utmp.h>
-#endif
-#include <unistd.h>
+#include <libutil.h>
 #include <stdio.h>
 #include <string.h>
-#include <libutil.h>
+#include <unistd.h>
+#include <utmpx.h>
 #include "extern.h"
 
-#if 0
-static int fd = -1;
-#endif
-
-/*
- * Modified version of logwtmp that holds wtmp file open
- * after first call, for use with ftp (which may chroot
- * after login, but before logout).
- */
 void
-ftpd_logwtmp(line, name, addr)
-	char *line, *name;
-	struct sockaddr *addr;
+ftpd_logwtmp(char *id, char *user, struct sockaddr *addr)
 {
-#if 0
-	struct utmp ut;
-	struct stat buf;
-	char host[UT_HOSTSIZE];
-
-	if (addr == NULL)
-		host[0] = '\0';
-	else
-		realhostname_sa(host, sizeof(host), addr, addr->sa_len);
-
-	if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
-		return;
-	if (fstat(fd, &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_time = _time_to_time32(time(NULL));
-		if (write(fd, &ut, sizeof(struct utmp)) !=
-		    sizeof(struct utmp))
-			(void)ftruncate(fd, buf.st_size);
+	struct utmpx ut;
+
+	memset(&ut, 0, sizeof(ut));
+
+	if (*user != '\0') {
+		/* Log in. */
+		ut.ut_type = USER_PROCESS;
+		(void)strncpy(ut.ut_user, user, sizeof(ut.ut_user));
+		if (addr != NULL)
+			realhostname_sa(ut.ut_host, sizeof(ut.ut_host),
+			    addr, addr->sa_len);
+	} else {
+		/* Log out. */
+		ut.ut_type = DEAD_PROCESS;
 	}
-#endif
+
+	ut.ut_pid = getpid();
+	gettimeofday(&ut.ut_tv, NULL);
+	(void)strncpy(ut.ut_id, id, sizeof(ut.ut_id));
+
+	pututxline(&ut);
 }


More information about the svn-src-user mailing list