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.
This commit is contained in:
parent
960aa5e071
commit
80643af02b
@ -173,8 +173,7 @@ static struct ftphost {
|
|||||||
char remotehost[NI_MAXHOST];
|
char remotehost[NI_MAXHOST];
|
||||||
char *ident = NULL;
|
char *ident = NULL;
|
||||||
|
|
||||||
static char ttyline[20];
|
static char wtmpid[20];
|
||||||
char *tty = ttyline; /* for klogin */
|
|
||||||
|
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
static int auth_pam(struct passwd**, const char*);
|
static int auth_pam(struct passwd**, const char*);
|
||||||
@ -584,8 +583,7 @@ gotchild:
|
|||||||
|
|
||||||
data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
|
data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1);
|
||||||
|
|
||||||
/* set this here so klogin can use it... */
|
(void)snprintf(wtmpid, sizeof(wtmpid), "%xftpd", getpid());
|
||||||
(void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid());
|
|
||||||
|
|
||||||
/* Try to handle urgent data inline */
|
/* Try to handle urgent data inline */
|
||||||
#ifdef SO_OOBINLINE
|
#ifdef SO_OOBINLINE
|
||||||
@ -1180,8 +1178,8 @@ end_login(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void) seteuid(0);
|
(void) seteuid(0);
|
||||||
if (logged_in && dowtmp)
|
if (logged_in && dowtmp && !dochroot)
|
||||||
ftpd_logwtmp(ttyline, "", NULL);
|
ftpd_logwtmp(wtmpid, "", NULL);
|
||||||
pw = NULL;
|
pw = NULL;
|
||||||
#ifdef LOGIN_CAP
|
#ifdef LOGIN_CAP
|
||||||
setusercontext(NULL, getpwuid(0), 0,
|
setusercontext(NULL, getpwuid(0), 0,
|
||||||
@ -1476,9 +1474,16 @@ skip:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* open wtmp before chroot */
|
dochroot =
|
||||||
if (dowtmp)
|
checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue)
|
||||||
ftpd_logwtmp(ttyline, pw->pw_name,
|
#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);
|
(struct sockaddr *)&his_addr);
|
||||||
logged_in = 1;
|
logged_in = 1;
|
||||||
|
|
||||||
@ -1491,13 +1496,6 @@ skip:
|
|||||||
if (statfd < 0)
|
if (statfd < 0)
|
||||||
stats = 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,
|
* For a chrooted local user,
|
||||||
* a) see whether ftpchroot(5) specifies a chroot directory,
|
* a) see whether ftpchroot(5) specifies a chroot directory,
|
||||||
@ -2732,9 +2730,9 @@ void
|
|||||||
dologout(int status)
|
dologout(int status)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (logged_in && dowtmp) {
|
if (logged_in && dowtmp && !dochroot) {
|
||||||
(void) seteuid(0);
|
(void) seteuid(0);
|
||||||
ftpd_logwtmp(ttyline, "", NULL);
|
ftpd_logwtmp(wtmpid, "", NULL);
|
||||||
}
|
}
|
||||||
/* beware of flushing buffers after a SIGPIPE */
|
/* beware of flushing buffers after a SIGPIPE */
|
||||||
_exit(status);
|
_exit(status);
|
||||||
|
@ -46,47 +46,35 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <libutil.h>
|
||||||
#include <time.h>
|
|
||||||
#include <timeconv.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <utmp.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <libutil.h>
|
#include <unistd.h>
|
||||||
|
#include <utmpx.h>
|
||||||
#include "extern.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
|
void
|
||||||
ftpd_logwtmp(line, name, addr)
|
ftpd_logwtmp(char *id, char *user, struct sockaddr *addr)
|
||||||
char *line, *name;
|
|
||||||
struct sockaddr *addr;
|
|
||||||
{
|
{
|
||||||
struct utmp ut;
|
struct utmpx ut;
|
||||||
struct stat buf;
|
|
||||||
char host[UT_HOSTSIZE];
|
|
||||||
|
|
||||||
if (addr == NULL)
|
memset(&ut, 0, sizeof(ut));
|
||||||
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)
|
if (*user != '\0') {
|
||||||
return;
|
/* Log in. */
|
||||||
if (fstat(fd, &buf) == 0) {
|
ut.ut_type = USER_PROCESS;
|
||||||
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
(void)strncpy(ut.ut_user, user, sizeof(ut.ut_user));
|
||||||
(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
if (addr != NULL)
|
||||||
(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
realhostname_sa(ut.ut_host, sizeof(ut.ut_host),
|
||||||
ut.ut_time = _time_to_time32(time(NULL));
|
addr, addr->sa_len);
|
||||||
if (write(fd, &ut, sizeof(struct utmp)) !=
|
} else {
|
||||||
sizeof(struct utmp))
|
/* Log out. */
|
||||||
(void)ftruncate(fd, buf.st_size);
|
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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user