diff options
Diffstat (limited to 'mail/poppassd/files/patch-poppassd.c')
-rw-r--r-- | mail/poppassd/files/patch-poppassd.c | 552 |
1 files changed, 0 insertions, 552 deletions
diff --git a/mail/poppassd/files/patch-poppassd.c b/mail/poppassd/files/patch-poppassd.c deleted file mode 100644 index e4169d6097b8..000000000000 --- a/mail/poppassd/files/patch-poppassd.c +++ /dev/null @@ -1,552 +0,0 @@ ---- poppassd.c.orig Thu Jan 4 23:19:36 2007 -+++ poppassd.c Thu Jan 4 23:24:26 2007 -@@ -13,11 +13,11 @@ - * - * Doesn't actually change any passwords itself. It simply listens for - * incoming requests, gathers the required information (user name, old -- * password, new password) and executes /bin/passwd, talking to it over -+ * password, new password) and executes /usr/bin/passwd, talking to it over - * a pseudo-terminal pair. The advantage of this is that we don't need - * to have any knowledge of either the password file format (which may - * include dbx files that need to be rebuilt) or of any file locking -- * protocol /bin/passwd and cohorts may use (and which isn't documented). -+ * protocol /usr/bin/passwd and cohorts may use (and which isn't documented). - * - * The current version has been tested at NU under SunOS release 4.1.2 - * and 4.1.3, and under HP-UX 8.02 and 9.01. We have tested the server -@@ -29,7 +29,7 @@ - * Note that unencrypted passwords are transmitted over the network. If - * this bothers you, think hard about whether you want to implement the - * password changing feature. On the other hand, it's no worse than what -- * happens when you run /bin/passwd while connected via telnet or rlogin. -+ * happens when you run /usr/bin/passwd while connected via telnet or rlogin. - * Well, maybe it is, since the use of a dedicated port makes it slightly - * easier for a network snooper to snarf passwords off the wire. - * -@@ -44,10 +44,10 @@ - * - * The front-end code (which talks to the client) is directly - * descended from Leavitt's original version. The back-end pseudo-tty stuff -- * (which talks to /bin/password) is directly descended from Smith's -+ * (which talks to /usr/bin/password) is directly descended from Smith's - * version, with changes for SunOS and HP-UX by Norstad (with help from - * sample code in "Advanced Programming in the UNIX Environment" -- * by W. Richard Stevens). The code to report /bin/passwd error messages -+ * by W. Richard Stevens). The code to report /usr/bin/passwd error messages - * back to the client in the final 500 response, and a new version of the - * code to find the next free pty, is by Norstad. - * -@@ -112,7 +112,7 @@ - - #define SUCCESS 1 - #define FAILURE 0 --#define BUFSIZE 512 -+#define BUFSIZE 768 - - #include <sys/types.h> - #include <sys/stat.h> -@@ -125,12 +125,23 @@ - #include <ctype.h> - #include <strings.h> - #include <errno.h> --#include <varargs.h> -+#include <stdarg.h> - #include <pwd.h> - #include <string.h> - #include <termios.h> - #include <dirent.h> -+#include <libutil.h> - -+/* prototypes to keep modern compilers happy */ -+void ReadFromClient (char *line); -+void WriteToClient (char *fmt, ...); -+int chkPass (char *user, char *pass, struct passwd *pw); -+int dochild (int master, char *slavedev, char *user); -+int expect (int master, char **expected, char *buf); -+void getemess (int master, char **expected, char *buf); -+int match (char *str, char *pat); -+int talktochild (int master, char *user, char *oldpass, char *newpass, char *emess); -+void writestring (int fd, char *s); - - /* Prompt strings expected from the "passwd" command. If you want - * to port this program to yet another flavor of UNIX, you may need to add -@@ -145,19 +156,24 @@ - static char *P1[] = - {"Old password:", - "Changing password for *.\nOld password:", -+ "Changing local password for *.\nOld password:", -+ "Changing local password for *\nOld Password:", - "Changing password for * on *.\nOld password:", - "Changing NIS password for * on *.\nOld password:", -+ "Changing NIS password for *\nOld Password:", - "Changing password for *\n*'s Old password:", - ""}; - - static char *P2[] = - {"\nNew password:", -+ "\n*\n*\n*\n*\n*\n*\n*\n*\n*\n*\n*\nEnter new password: ", - "\n*'s New password:", - ""}; - - static char *P3[] = - {"\nRe-enter new password:", - "\nRetype new password:", -+ "\nRe-type new password: ", - "\nEnter the new password again:", - "\n*Re-enter *'s new password:", - "\nVerify:", -@@ -165,13 +181,14 @@ - - static char *P4[] = - {"\n", -+ "\npasswd: rebuilding the database...\npasswd: done\n", -+ "\npasswd: updating the database...\npasswd: done\n", - "NIS entry changed on *\n", -+ "\n\nNIS password has been changed on *.\n", - ""}; - - --main (argc, argv) --int argc; --char *argv[]; -+int main (int argc, char *argv[]) - { - char line[BUFSIZE]; - char user[BUFSIZE]; -@@ -180,17 +197,14 @@ - char emess[BUFSIZE]; - char *slavedev; - struct passwd *pw, *getpwnam(); -+ struct termios stermios; - int c, master; - pid_t pid, wpid; - int wstat; - - *user = *oldpass = *newpass = 0; - -- if (openlog ("poppassd", LOG_PID, LOG_LOCAL2) < 0) -- { -- WriteToClient ("500 Can't open syslog."); -- exit (1); -- } -+ openlog ("poppassd", LOG_PID, LOG_LOCAL2); - - WriteToClient ("200 poppassd v%s hello, who are you?", VERSION); - ReadFromClient (line); -@@ -212,12 +226,16 @@ - - if ((pw = getpwnam (user)) == NULL) - { -- WriteToClient ("500 Unknown user, %s.", user); -+ syslog (LOG_ERR, "Unknown user, %s", user); -+ sleep (5); -+ WriteToClient ("500 Old password is incorrect."); - exit(1); - } - - if (chkPass (user, oldpass, pw) == FAILURE) - { -+ syslog (LOG_ERR, "Incorrect password from %s", user); -+ sleep (5); - WriteToClient ("500 Old password is incorrect."); - exit(1); - } -@@ -232,215 +250,118 @@ - WriteToClient ("500 New password required."); - exit(1); - } -- /* get pty to talk to password program */ -- if ((master = findpty (&slavedev)) < 0) -- { -- syslog (LOG_ERR, "can't find pty"); -- WriteToClient("500 Server busy - try again later."); -- exit (1); -- } -- -- /* fork child process to talk to password program */ -- if ((pid = fork()) < 0) /* Error, can't fork */ -- { -- syslog (LOG_ERR, "can't fork for passwd: %m"); -- WriteToClient ("500 Server error (can't fork passwd), get help!"); -- exit (1); -- } - -- if (pid) /* Parent */ -- { -- sleep (1); /* Make sure child is ready. Is this really needed? */ -- if (talktochild (master, user, oldpass, newpass, emess) == FAILURE) -- { -- syslog (LOG_ERR, "failed attempt by %s", user); -- if (*emess == '\0') { -- WriteToClient ("500 Unable to change password." ); -- } else { -- WriteToClient ("500 %s", emess); -- } -- exit(1); -- } -- -- if ((wpid = waitpid (pid, &wstat, 0)) < 0) -- { -- syslog (LOG_ERR, "wait for /bin/passwd child failed: %m"); -- WriteToClient ("500 Server error (wait failed), get help!"); -- exit (1); -- } -- -- if (pid != wpid) -- { -- syslog (LOG_ERR, "wrong child (/bin/passwd waited for!"); -- WriteToClient ("500 Server error (wrong child), get help!"); -- exit (1); -- } -- -- if (WIFEXITED (wstat) == 0) -- { -- syslog (LOG_ERR, "child (/bin/passwd) killed?"); -- WriteToClient ("500 Server error (funny wstat), get help!"); -- exit (1); -- } -- -- if (WEXITSTATUS (wstat) != 0) -- { -- syslog (LOG_ERR, "child (/bin/passwd) exited abnormally"); -- WriteToClient ("500 Server error (abnormal exit), get help!"); -- exit (1); -- } -- -- syslog (LOG_ERR, "password changed for %s", user); -- WriteToClient ("200 Password changed, thank-you."); -- -- ReadFromClient (line); -- if (strncmp(line, "quit", 4) != 0) { -- WriteToClient("500 Quit required."); -+ /* we need a pty to run passwd on but we have to make sure it is set up -+ as we like it - no echo, canonical input processing, no map NL to CR/NL -+ on outputs - otherwise our expect function will be confused */ -+ (void)memset((void *)&stermios, 0, sizeof(stermios)); -+ stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); -+ stermios.c_lflag |= ICANON; -+ stermios.c_oflag &= ~(ONLCR); -+ -+ /* get a pty and fork */ -+ switch(pid = forkpty(&master, NULL, &stermios, NULL)) { -+ case -1: -+ /* failure - can't get pty, can't fork etc */ -+ WriteToClient("500 Server Error - Contact Your Administrator"); -+ exit(1); -+ break; -+ case 0: -+ /* slave/child */ -+ /* Set login name */ -+ if (setlogin(user) < 0) { -+ syslog(LOG_ERR, "setlogin failed: %m"); -+ WriteToClient("500 Server Error - Contact Your Administrator"); -+ return(0); -+ } -+ setuid (pw->pw_uid); -+ setgid (pw->pw_gid); -+ dochild (master, NULL, user); -+ break; -+ default: -+ /* master/parent */ -+ sleep (1); /* Make sure child is ready. Is this really needed? */ -+ if (talktochild (master, user, oldpass, newpass, emess) == FAILURE) -+ { -+ syslog (LOG_ERR, "failed attempt by %s", user); -+ if (*emess == '\0') { -+ WriteToClient ("500 Password change unsuccessful, try a different password." ); -+ } else { -+ WriteToClient ("500 %s", emess); -+ } -+ exit(1); -+ } -+ -+ break; -+ } -+ -+ if ((wpid = waitpid (pid, &wstat, 0)) < 0) -+ { -+ syslog (LOG_ERR, "wait for /usr/bin/passwd child failed: %m"); -+ WriteToClient ("500 Server error (wait failed), get help!"); -+ exit (1); -+ } -+ -+ if (pid != wpid) -+ { -+ syslog (LOG_ERR, "wrong child (/usr/bin/passwd) waited for!"); -+ WriteToClient ("500 Server error (wrong child), get help!"); -+ exit (1); -+ } -+ -+ if (WIFEXITED (wstat) == 0) -+ { -+ syslog (LOG_ERR, "child (/usr/bin/passwd) killed?"); -+ WriteToClient ("500 Server error (funny wstat), get help!"); -+ exit (1); -+ } -+ -+ if (WEXITSTATUS (wstat) != 0) -+ { -+ syslog (LOG_ERR, "child (/usr/bin/passwd) exited abnormally"); -+ WriteToClient ("500 Server error (abnormal exit), get help!"); -+ exit (1); -+ } -+ -+ syslog (LOG_ERR, "password changed for %s", user); -+ WriteToClient ("200 Password changed, thank-you."); -+ -+ ReadFromClient (line); -+ if (strncmp(line, "quit", 4) != 0) { -+ WriteToClient("500 Quit required."); - exit (1); -- } -+ } - -- WriteToClient("200 Bye."); -- exit (0); -- } -- else /* Child */ -- { -- /* -- * Become the user trying who's password is being changed. We're -- * about to exec /bin/passwd with is setuid root anyway, but this -- * way it looks to the child completely like it's being run by -- * the normal user, which makes it do its own password verification -- * before doing any thing. In theory, we've already verified the -- * password, but this extra level of checking doesn't hurt. Besides, -- * the way I do it here, if somebody manages to change somebody -- * else's password, you can complain to your vendor about security -- * holes, not to me! -- */ -- setuid (pw->pw_uid); -- setgid (pw->pw_gid); -- dochild (master, slavedev, user); -- } -+ WriteToClient("200 Bye."); -+ exit (0); - } - - /* - * dochild - * -- * Do child stuff - set up slave pty and execl /bin/passwd. -+ * Do child stuff - set up slave pty and execl /usr/bin/passwd. - * - * Code adapted from "Advanced Programming in the UNIX Environment" - * by W. Richard Stevens. - * - */ - --dochild (master, slavedev, user) --int master; --char *slavedev, *user; -+int dochild (int master, char *slavedev, char *user) - { -- int slave; -- struct termios stermios; -+ /* Fork /usr/bin/passwd. */ - -- /* Start new session - gets rid of controlling terminal. */ -- -- if (setsid() < 0) { -- syslog(LOG_ERR, "setsid failed: %m"); -- return(0); -- } -- -- /* Open slave pty and acquire as new controlling terminal. */ -- -- if ((slave = open(slavedev, O_RDWR)) < 0) { -- syslog(LOG_ERR, "can't open slave pty: %m"); -- return(0); -- } -- -- /* Close master. */ -- -- close(master); -- -- /* Make slave stdin/out/err of child. */ -- -- if (dup2(slave, STDIN_FILENO) != STDIN_FILENO) { -- syslog(LOG_ERR, "dup2 error to stdin: %m"); -- return(0); -- } -- if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) { -- syslog(LOG_ERR, "dup2 error to stdout: %m"); -- return(0); -- } -- if (dup2(slave, STDERR_FILENO) != STDERR_FILENO) { -- syslog(LOG_ERR, "dup2 error to stderr: %m"); -- return(0); -- } -- if (slave > 2) close(slave); -- -- /* Set proper terminal attributes - no echo, canonical input processing, -- no map NL to CR/NL on output. */ -- -- if (tcgetattr(0, &stermios) < 0) { -- syslog(LOG_ERR, "tcgetattr error: %m"); -- return(0); -- } -- stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); -- stermios.c_lflag |= ICANON; -- stermios.c_oflag &= ~(ONLCR); -- if (tcsetattr(0, TCSANOW, &stermios) < 0) { -- syslog(LOG_ERR, "tcsetattr error: %m"); -- return(0); -- } -- -- /* Fork /bin/passwd. */ -- -- if (execl("/bin/passwd", "passwd", user, (char*)0) < 0) { -- syslog(LOG_ERR, "can't exec /bin/passwd: %m"); -+ if (execl("/usr/bin/passwd", "passwd", user, (char*)0) < 0) { -+ syslog(LOG_ERR, "can't exec /usr/bin/passwd: %m"); - return(0); - } - } - -- --/* -- * findpty() -- * -- * Finds the first available pseudo-terminal master/slave pair. The master -- * side is opened and a fd returned as the function value. A pointer to the -- * name of the slave side (i.e. "/dev/ttyp0") is returned in the argument, -- * which should be a char**. The name itself is stored in a static buffer. -- * -- * A negative value is returned on any sort of error. -- * -- * Modified by Norstad to remove assumptions about number of pty's allocated -- * on this UNIX box. -- */ --findpty (slave) --char **slave; --{ -- int master; -- static char *line = "/dev/ptyXX"; -- DIR *dirp; -- struct dirent *dp; -- -- dirp = opendir("/dev"); -- while ((dp = readdir(dirp)) != NULL) { -- if (strncmp(dp->d_name, "pty", 3) == 0 && strlen(dp->d_name) == 5) { -- line[8] = dp->d_name[3]; -- line[9] = dp->d_name[4]; -- if ((master = open(line, O_RDWR)) >= 0) { -- line[5] = 't'; -- *slave = line; -- closedir(dirp); -- return (master); -- } -- } -- } -- closedir(dirp); -- return (-1); --} -- - /* - * writestring() - * - * Write a string in a single write() system call. - */ --writestring (fd, s) --char *s; -+void writestring (int fd, char *s) - { - int l; - -@@ -458,9 +379,7 @@ - * FAILURE if any errors are encountered (in which case, it can be assumed - * that the password wasn't changed). - */ --talktochild (master, user, oldpass, newpass, emess) --int master; --char *user, *oldpass, *newpass, *emess; -+int talktochild (int master, char *user, char *oldpass, char *newpass, char *emess) - { - char buf[BUFSIZE]; - char pswd[BUFSIZE+1]; -@@ -485,9 +404,11 @@ - } - - writestring(master, pswd); -- -+ sleep(2); - if (!expect(master, P4, buf)) return FAILURE; - -+ close(master); -+ - return SUCCESS; - } - -@@ -507,9 +428,7 @@ - * the pattern. - * 2 if the string matches the full pattern. - */ --match (str, pat) --char *str; --char *pat; -+int match (char *str, char *pat) - { - int result; - -@@ -542,10 +461,7 @@ - * is not an initial segment of or exact match for at least one of - * the expected strings, the function returns FAILURE. - */ --expect (master, expected, buf) --int master; --char **expected; --char *buf; -+int expect (int master, char **expected, char *buf) - { - int n, m; - char **s; -@@ -596,10 +512,7 @@ - * returning just the error message text. Newlines in the error message - * text are replaced by spaces. - */ --getemess (master, expected, buf) --int master; --char **expected; --char *buf; -+void getemess (int master, char **expected, char *buf) - { - int n, m; - char **s; -@@ -630,21 +543,18 @@ - } - } - --WriteToClient (fmt, va_alist) --char *fmt; --va_dcl -+void WriteToClient (char *fmt, ...) - { - va_list ap; - -- va_start (ap); -+ va_start (ap, fmt); - vfprintf (stdout, fmt, ap); - fputs ("\r\n", stdout ); - fflush (stdout); - va_end (ap); - } - --ReadFromClient (line) --char *line; -+void ReadFromClient (char *line) - { - char *sp; - int i; -@@ -659,10 +569,7 @@ - for (sp = line; isalpha(*sp); sp++) *sp = tolower(*sp); - } - --int chkPass (user, pass, pw) --char *user; --char *pass; --struct passwd *pw; -+int chkPass (char *user, char *pass, struct passwd *pw) - { - /* Compare the supplied password with the password file entry */ - if (strcmp (crypt (pass, pw->pw_passwd), pw->pw_passwd) != 0) |