Index: contrib/libpam//libpam_misc/misc_conv.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam_misc/Attic/misc_conv.c,v retrieving revision 1.6 diff -u -r1.6 misc_conv.c --- contrib/libpam//libpam_misc/misc_conv.c 20 Jan 2002 17:54:33 -0000 1.6 +++ contrib/libpam//libpam_misc/misc_conv.c 6 Feb 2002 16:20:47 -0000 @@ -1,4 +1,37 @@ /* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* * $Id: misc_conv.c,v 1.3 2001/01/20 22:29:47 agmorgan Exp $ * $FreeBSD: src/contrib/libpam/libpam_misc/misc_conv.c,v 1.6 2002/01/20 17:54:33 markm Exp $ * @@ -128,6 +161,65 @@ return 0; } +#include + +static char * +my_askpass(const char *askpass, const char *prompt) +{ + pid_t pid; + size_t len; + char *nl, *pass; + int p[2], status; + char buf[1024]; + + if (prompt == NULL) { + } + if (fflush(stdout) != 0) + /* error("ssh_askpass: fflush: %s", strerror(errno)); */ + return NULL; + if (askpass == NULL) + /* fatal("internal error: askpass undefined"); */ + return NULL; + if (pipe(p) < 0) + /* fatal("ssh_askpass: pipe: %s", strerror(errno)); */ + return NULL; + if ((pid = fork()) < 0) + /* fatal("ssh_askpass: fork: %s", strerror(errno)); */ + return NULL; + if (pid == 0) { + seteuid(getuid()); + setuid(getuid()); + close(p[0]); + if (prompt[0] && prompt[strlen(prompt) - 1] == ':') { + prompt = strdup(prompt); + if (prompt == NULL) + /* fatal("my_askpass: Unable to dup prompt"); */ + _exit(1); + prompt[strlen(prompt)-1] = '\0'; + } + if (dup2(p[1], STDOUT_FILENO) < 0) + /* fatal("ssh_askpass: dup2: %s", strerror(errno)); */ + _exit(1); + execlp(askpass, askpass, prompt, (char *) 0); + /* fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno)); */ + _exit(1); + } + close(p[1]); + len = read(p[0], buf, sizeof buf); + close(p[0]); + while (waitpid(pid, &status, 0) < 0) + if (errno != EINTR) + break; + if (len <= 1) + return xstrdup(""); + nl = strchr(buf, '\n'); + if (nl) + *nl = '\0'; + pass = xstrdup(buf); + memset(buf, 0, sizeof(buf)); + return pass; +} + /* read a line of input string, giving prompt when appropriate */ static char *read_string(int echo, const char *prompt) { @@ -137,13 +229,24 @@ struct sigaction old_sig; int delay, nc, have_term=0; sigset_t oset, nset; + int ttyfd = -1; D(("called with echo='%s', prompt='%s'.", echo ? "ON":"OFF" , prompt)); + if (getenv("DISPLAY")) { + return my_askpass("/usr/X11R6/bin/ssh-askpass", prompt); + } if (isatty(STDIN_FILENO)) { /* terminal state */ + ttyfd = STDIN_FILENO; + } else if (isatty(STDERR_FILENO)) { + ttyfd = STDERR_FILENO; + } else if (isatty(STDOUT_FILENO)) { + ttyfd = STDOUT_FILENO; + } + if (ttyfd >= 0) { /* is a terminal so record settings and flush it */ - if ( tcgetattr(STDIN_FILENO, &term_before) != 0 ) { + if ( tcgetattr(ttyfd, &term_before) != 0 ) { D(("")); return NULL; } @@ -174,15 +277,15 @@ fprintf(stderr, "%s", prompt); /* this may, or may not set echo off -- drop pending input */ if (have_term) - (void) tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_tmp); + (void) tcsetattr(ttyfd, TCSAFLUSH, &term_tmp); if ( delay > 0 && set_alarm(delay, &old_sig) ) { D(("")); break; } else { - nc = read(STDIN_FILENO, line, INPUTSIZE-1); + nc = read(ttyfd, line, INPUTSIZE-1); if (have_term) { - (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &term_before); + (void) tcsetattr(ttyfd, TCSADRAIN, &term_before); if (!echo || expired) /* do we need a newline? */ fprintf(stderr,"\n"); } @@ -216,7 +319,7 @@ cleanexit: if (have_term) { (void)sigprocmask(SIG_SETMASK, &oset, NULL); - (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &term_before); + (void) tcsetattr(ttyfd, TCSADRAIN, &term_before); } return input; } Index: lib/libpam//modules/pam_unix/pam_unix.c =================================================================== RCS file: /home/ncvs/src/lib/libpam/modules/pam_unix/pam_unix.c,v retrieving revision 1.16 diff -u -r1.16 pam_unix.c --- lib/libpam//modules/pam_unix/pam_unix.c 19 Jan 2002 18:29:49 -0000 1.16 +++ lib/libpam//modules/pam_unix/pam_unix.c 9 Feb 2002 20:24:50 -0000 @@ -117,11 +117,14 @@ PAM_LOG("Got user: %s", user); - lc = login_getclass(NULL); + asprintf(&password_prompt, "Password for %s:", user); + /* lc = login_getclass(NULL); password_prompt = login_getcapstr(lc, "passwd_prompt", PASSWORD_PROMPT, PASSWORD_PROMPT); login_close(lc); - lc = NULL; + lc = NULL; */ + /* XXX Is not the use of login_getcapstr above a leak? It looks like + * one. */ if (pwd != NULL) { Index: usr.bin/su//su.c =================================================================== RCS file: /home/ncvs/src/usr.bin/su/su.c,v retrieving revision 1.47 diff -u -r1.47 su.c --- usr.bin/su//su.c 12 Sep 2001 19:15:02 -0000 1.47 +++ usr.bin/su//su.c 6 Feb 2002 15:39:06 -0000 @@ -227,8 +227,12 @@ retcode = pam_authenticate(pamh, 0); if (retcode != PAM_SUCCESS) { - syslog(LOG_ERR, "pam_authenticate: %s", - pam_strerror(pamh, retcode)); + if (retcode == PAM_AUTH_ERR) + syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s%s", + username, user, ontty()); + else + syslog(LOG_ERR, "pam_authenticate: %s", + pam_strerror(pamh, retcode)); errx(1, "Sorry"); } retcode = pam_get_item(pamh, PAM_USER, (const void **)&p); @@ -467,12 +471,18 @@ static char * ontty(void) { - char *p; + char *ttyp; + char *ttyd; static char buf[MAXPATHLEN + 4]; buf[0] = 0; - p = ttyname(STDERR_FILENO); - if (p) - snprintf(buf, sizeof(buf), " on %s", p); + ttyp = ttyname(STDERR_FILENO); + ttyd = getenv("DISPLAY"); + if (ttyp && ttyd) + snprintf(buf, sizeof(buf), " on %s (%s)", ttyp, ttyd); + else if (ttyp) + snprintf(buf, sizeof(buf), " on %s", ttyp); + else if (ttyd) + snprintf(buf, sizeof(buf), " on X display '%s'", ttyd); return buf; }