diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index 32c15f8df1d1..681fdc342881 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -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,16 @@ skip: } #endif - /* open wtmp before chroot */ - if (dowtmp) - ftpd_logwtmp(ttyline, pw->pw_name, + 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; + + if (dowtmp && !dochroot) + ftpd_logwtmp(wtmpid, pw->pw_name, (struct sockaddr *)&his_addr); logged_in = 1; @@ -1491,13 +1496,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 +2730,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); diff --git a/libexec/ftpd/logwtmp.c b/libexec/ftpd/logwtmp.c index 29bea5cef0d0..3d810dd4b649 100644 --- a/libexec/ftpd/logwtmp.c +++ b/libexec/ftpd/logwtmp.c @@ -46,47 +46,35 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include -#include -#include -#include +#include #include #include -#include +#include +#include #include "extern.h" -static int fd = -1; - -/* - * 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) { - struct utmp ut; - struct stat buf; - char host[UT_HOSTSIZE]; + struct utmpx ut; - if (addr == NULL) - host[0] = '\0'; - else - realhostname_sa(host, sizeof(host), addr, addr->sa_len); + memset(&ut, 0, sizeof(ut)); - 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); + 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; } + + ut.ut_pid = getpid(); + gettimeofday(&ut.ut_tv, NULL); + (void)strncpy(ut.ut_id, id, sizeof(ut.ut_id)); + + pututxline(&ut); }