vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| this diff changes two things in ftpd. it makes syscalls in the monitor process restartable when a signal occurs, as was the case before privsep and it only wait()'s for it's own slave processes now. please test this and report back to me, even if it doesn't break anything for you... thanks, moritz Index: ftpcmd.y ================================================== ================= RCS file: /cvs/src/libexec/ftpd/ftpcmd.y,v retrieving revision 1.47 diff -u -r1.47 ftpcmd.y --- ftpcmd.y 2004/12/06 23:04:14 1.47 +++ ftpcmd.y 2004/12/08 14:58:56 @@ -168,7 +168,7 @@ /* Terminate unprivileged pre-auth slave */ if (quit) - _exit(PREAUTH_SLAVE_DIED); + _exit(0); } | PORT check_login_epsvall SP host_port CRLF { Index: monitor.c ================================================== ================= RCS file: /cvs/src/libexec/ftpd/monitor.c,v retrieving revision 1.5 diff -u -r1.5 monitor.c --- monitor.c 2004/12/06 20:52:04 1.5 +++ monitor.c 2004/12/08 14:58:57 @@ -60,12 +60,10 @@ int nullfd; pid_t slave_pid = -1; enum monitor_state state = PREAUTH; -volatile sig_atomic_t quit = 0; void send_data(int, void *, size_t); void recv_data(int, void *, size_t); -int recv_cmd(int, void *, size_t); -int handle_cmds(void); +void handle_cmds(void); void set_monitor_signals(void); void sig_pass_to_slave(int); void sig_chld(int); @@ -114,22 +112,6 @@ } } -/* - * Receive command from socket and return 1 if something fails. - * If command was received successfuly, 0 is returned. - */ -int -recv_cmd(int sock, void *buf, size_t len) -{ - ssize_t n; - - n = read(sock, buf, len); - if (n <= 0) - return (1); - - return (0); -} - void set_monitor_signals(void) { @@ -137,7 +119,7 @@ int i; sigfillset(&act.sa_mask); - act.sa_flags = 0; + act.sa_flags = SA_RESTART; act.sa_handler = SIG_DFL; for (i = 1; i < _NSIG; i++) @@ -207,10 +189,7 @@ setproctitle("%s: [priv pre-auth]", remotehost); #endif - if (handle_cmds() == 1) { - debugmsg("slave lost. monitor quits now."); - _exit(0); - } + handle_cmds(); /* User-privileged slave */ return (0); @@ -250,28 +229,24 @@ } /* - * Handles commands received from the slave process. It returns twice. - * It returns 0 for the user-privileged slave process after successful - * authentication and 1 if the user-privileged slave died. + * Handles commands received from the slave process. It will not return + * except in one situation: After successful authentication it will + * return as the user-privileged slave process. */ -int +void handle_cmds(void) { enum monitor_command cmd; enum auth_ret auth; int err, s, slavequit, serrno; + pid_t preauth_slave_pid; size_t len; struct sockaddr sa; socklen_t salen; char *name, *pw; - while (quit == 0) { - if (recv_cmd(fd_slave, &cmd, sizeof(cmd)) != 0) { - if (quit == 1) - break; - else - continue; - } + for (; + recv_data(fd_slave, &cmd, sizeof(cmd)); switch (cmd) { case CMD_USER: @@ -297,6 +272,8 @@ recv_data(fd_slave, pw, len); pw[len] = '\0'; + preauth_slave_pid = slave_pid; + auth = pass(pw); bzero(pw, len); free(pw); @@ -312,9 +289,8 @@ case AUTH_SLAVE: /* User-privileged slave */ debugmsg("user-privileged slave started"); - return (0); + return; /* NOTREACHED */ - break; case AUTH_MONITOR: /* Post-auth monitor */ debugmsg("monitor went into post-auth phase"); @@ -327,11 +303,14 @@ send_data(fd_slave, &slavequit, sizeof(slavequit)); + + while (waitpid(preauth_slave_pid, NULL, 0) < 0 + && errno == EINTR) + ; break; default: fatalx("bad return value from pass()"); /* NOTREACHED */ - break; } break; case CMD_BIND: @@ -368,11 +347,9 @@ default: fatalx("monitor received unknown command %d", cmd); /* NOTREACHED */ - break; } } - - return (1); + /* NOTREACHED */ } void @@ -394,13 +371,10 @@ int stat, olderrno = errno; do { - pid = waitpid(-1, &stat, WNOHANG); + pid = waitpid(slave_pid, &stat, WNOHANG); + if (pid > 0) + _exit(0); } while (pid == -1 && errno == EINTR); - - if (pid == slave_pid && stat != PREAUTH_SLAVE_DIED) { - quit = 1; - slave_pid = -1; - } errno = olderrno; } Index: monitor.h ================================================== ================= RCS file: /cvs/src/libexec/ftpd/monitor.h,v retrieving revision 1.1 diff -u -r1.1 monitor.h --- monitor.h 2004/11/28 18:49:30 1.1 +++ monitor.h 2004/12/08 14:58:57 @@ -20,7 +20,6 @@ #define _MONITOR_H #define FTPD_PRIVSEP_USER "_ftp" -#define PREAUTH_SLAVE_DIED 3 enum auth_ret { AUTH_FAILED, |