summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2010-01-13 18:28:41 +0000
committered <ed@FreeBSD.org>2010-01-13 18:28:41 +0000
commita0af351d02a6107aa858c4b27ec786f93c2cd0cb (patch)
treebba33bd7c021d55d4f3ce0d7bc3973c0a2db3b3b /libexec
parent14920edb233365f033171b90f9170b4f6d0eb2bd (diff)
downloadFreeBSD-src-a0af351d02a6107aa858c4b27ec786f93c2cd0cb.zip
FreeBSD-src-a0af351d02a6107aa858c4b27ec786f93c2cd0cb.tar.gz
Port ftpd to utmpx.
Unfortunately I have to partially wreck its functionality, though. ftpd used to keep a file descriptor to the wtmp, which allowed it to work from within a chroot. The current utmpx implementation doesn't offer a way to do this. Maybe we can address this in the future, if it turns out to be a real issue.
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ftpd/ftpd.c34
-rw-r--r--libexec/ftpd/logwtmp.c56
2 files changed, 38 insertions, 52 deletions
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 32c15f8..681fdc3 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 29bea5c..3d810dd 100644
--- a/libexec/ftpd/logwtmp.c
+++ b/libexec/ftpd/logwtmp.c
@@ -46,47 +46,35 @@ __FBSDID("$FreeBSD$");
#include <arpa/inet.h>
#include <sys/socket.h>
-#include <fcntl.h>
-#include <time.h>
-#include <timeconv.h>
-#include <netdb.h>
-#include <utmp.h>
-#include <unistd.h>
+#include <libutil.h>
#include <stdio.h>
#include <string.h>
-#include <libutil.h>
+#include <unistd.h>
+#include <utmpx.h>
#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);
}
OpenPOWER on IntegriCloud