From 7dfcd32923d14cdb94c362507b2c89ad3e23c7c7 Mon Sep 17 00:00:00 2001 From: eugen Date: Mon, 6 Nov 2017 11:11:44 +0000 Subject: [PATCH] MFC r324364: ftpd(8): fix user context handling Apply authenticated user context after update of wtmp(5) at start of session, so that ftpd process is not killed by kernel with SIGXFSZ when user has "filesize" limit lower than size of system wtmp file. Same applies to session finalization: revert to super-user context before update of wtmp. If ftpd hits limit while writing a file at user request, do not get killed with SIGXFSZ instantly but apparently ignore the signal, process error and report it to the user, and continue with the session. PR: 143570 Approved by: mav (mentor) git-svn-id: svn://svn.freebsd.org/base/stable/10@325472 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- libexec/ftpd/ftpd.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index 4120c1051..d3a9d001c 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -420,6 +420,10 @@ main(int argc, char *argv[], char **envp) } } + /* handle filesize limit gracefully */ + sa.sa_handler = SIG_IGN; + (void)sigaction(SIGXFSZ, &sa, NULL); + if (daemon_mode) { int *ctl_sock, fd, maxfd = -1, nfds, i; fd_set defreadfds, readfds; @@ -1185,14 +1189,14 @@ end_login(void) #endif (void) seteuid(0); - if (logged_in && dowtmp) - ftpd_logwtmp(wtmpid, NULL, NULL); - pw = NULL; #ifdef LOGIN_CAP setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN | LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH | LOGIN_SETENV)); #endif + if (logged_in && dowtmp) + ftpd_logwtmp(wtmpid, NULL, NULL); + pw = NULL; #ifdef USE_PAM if (pamh) { if ((e = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) @@ -1464,7 +1468,7 @@ pass(char *passwd) } } setusercontext(lc, pw, 0, LOGIN_SETALL & - ~(LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV)); + ~(LOGIN_SETRESOURCES | LOGIN_SETUSER | LOGIN_SETPATH | LOGIN_SETENV)); #else setlogin(pw->pw_name); (void) initgroups(pw->pw_name, pw->pw_gid); @@ -1506,6 +1510,10 @@ pass(char *passwd) (struct sockaddr *)&his_addr); logged_in = 1; +#ifdef LOGIN_CAP + setusercontext(lc, pw, 0, LOGIN_SETRESOURCES); +#endif + if (guest && stats && statfd < 0) #ifdef VIRTUAL_HOSTING statfd = open(thishost->statfile, O_WRONLY|O_APPEND); @@ -2756,6 +2764,11 @@ dologout(int status) if (logged_in && dowtmp) { (void) seteuid(0); +#ifdef LOGIN_CAP + setusercontext(NULL, getpwuid(0), 0, LOGIN_SETALL & ~(LOGIN_SETLOGIN | + LOGIN_SETUSER | LOGIN_SETGROUP | LOGIN_SETPATH | + LOGIN_SETENV)); +#endif ftpd_logwtmp(wtmpid, NULL, NULL); } /* beware of flushing buffers after a SIGPIPE */ -- 2.45.0