From owner-svn-src-all@freebsd.org Sun Feb 11 13:35:32 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6BF8EF18CA8; Sun, 11 Feb 2018 13:35:32 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 1A1BB787E8; Sun, 11 Feb 2018 13:35:32 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 0BA6023915; Sun, 11 Feb 2018 13:35:32 +0000 (UTC) (envelope-from trasz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w1BDZVjE026045; Sun, 11 Feb 2018 13:35:31 GMT (envelope-from trasz@FreeBSD.org) Received: (from trasz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1BDZVIL026043; Sun, 11 Feb 2018 13:35:31 GMT (envelope-from trasz@FreeBSD.org) Message-Id: <201802111335.w1BDZVIL026043@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: trasz set sender to trasz@FreeBSD.org using -f From: Edward Tomasz Napierala Date: Sun, 11 Feb 2018 13:35:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329123 - head/usr.bin/lock X-SVN-Group: head X-SVN-Commit-Author: trasz X-SVN-Commit-Paths: head/usr.bin/lock X-SVN-Commit-Revision: 329123 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Feb 2018 13:35:32 -0000 Author: trasz Date: Sun Feb 11 13:35:31 2018 New Revision: 329123 URL: https://svnweb.freebsd.org/changeset/base/329123 Log: Make lock(1) use PAM. This makes the -p option work again. (Well, kind of, because the whole idea of this utility is rather broken.) This originally come from NetBSD, and was later reworked a bit. Reviewed by: des@ (earlier version) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D4981 Modified: head/usr.bin/lock/Makefile head/usr.bin/lock/lock.c Modified: head/usr.bin/lock/Makefile ============================================================================== --- head/usr.bin/lock/Makefile Sun Feb 11 10:23:32 2018 (r329122) +++ head/usr.bin/lock/Makefile Sun Feb 11 13:35:31 2018 (r329123) @@ -5,6 +5,6 @@ PROG= lock BINOWN= root BINMODE=4555 -LIBADD= crypt +LIBADD= pam .include Modified: head/usr.bin/lock/lock.c ============================================================================== --- head/usr.bin/lock/lock.c Sun Feb 11 10:23:32 2018 (r329122) +++ head/usr.bin/lock/lock.c Sun Feb 11 13:35:31 2018 (r329123) @@ -73,6 +73,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include /* for openpam_ttyconv() */ + #define TIMEOUT 15 static void quit(int); @@ -91,19 +94,23 @@ static int vtyunlock; /* Unlock flag and code. */ int main(int argc, char **argv) { + static const struct pam_conv pamc = { &openpam_ttyconv, NULL }; + pam_handle_t *pamh; struct passwd *pw; struct itimerval ntimer, otimer; struct tm *timp; time_t timval; - int ch, failures, sectimeout, usemine, vtylock; - char *ap, *cryptpw, *mypw, *ttynam, *tzn; + int ch, failures, pam_err, sectimeout, usemine, vtylock; + char *ap, *ttynam, *tzn; char hostname[MAXHOSTNAMELEN], s[BUFSIZ], s1[BUFSIZ]; openlog("lock", 0, LOG_AUTH); + pam_err = PAM_SYSTEM_ERR; /* pacify GCC */ + sectimeout = TIMEOUT; + pamh = NULL; pw = NULL; - mypw = NULL; usemine = 0; no_timeout = 0; vtylock = 0; @@ -117,7 +124,6 @@ main(int argc, char **argv) usemine = 1; if (!(pw = getpwuid(getuid()))) errx(1, "unknown uid %d", getuid()); - mypw = strdup(pw->pw_passwd); break; case 'n': no_timeout = 1; @@ -131,9 +137,11 @@ main(int argc, char **argv) } timeout.tv_sec = sectimeout * 60; - /* discard privs */ - if (setuid(getuid()) != 0) - errx(1, "setuid failed"); + if (!usemine) { /* -p with PAM or S/key needs privs */ + /* discard privs */ + if (setuid(getuid()) != 0) + errx(1, "setuid failed"); + } if (tcgetattr(0, &tty)) /* get information for header */ exit(1); @@ -153,7 +161,11 @@ main(int argc, char **argv) ntty = tty; ntty.c_lflag &= ~ECHO; (void)tcsetattr(0, TCSADRAIN|TCSASOFT, &ntty); - if (!mypw) { + if (usemine) { + pam_err = pam_start("lock", pw->pw_name, &pamc, &pamh); + if (pam_err != PAM_SUCCESS) + err(1, "pam_start: %s", pam_strerror(NULL, pam_err)); + } else { /* get key and check again */ (void)printf("Key: "); if (!fgets(s, sizeof(s), stdin) || *s == '\n') @@ -171,7 +183,6 @@ main(int argc, char **argv) exit(1); } s[0] = '\0'; - mypw = s1; } /* set signal handlers */ @@ -216,19 +227,27 @@ main(int argc, char **argv) failures = 0; for (;;) { + if (usemine) { + pam_err = pam_authenticate(pamh, 0); + if (pam_err == PAM_SUCCESS) + break; + + if (pam_err != PAM_AUTH_ERR && + pam_err != PAM_USER_UNKNOWN && + pam_err != PAM_MAXTRIES) { + syslog(LOG_ERR, "pam_authenticate: %s", + pam_strerror(pamh, pam_err)); + } + + goto tryagain; + } (void)printf("Key: "); if (!fgets(s, sizeof(s), stdin)) { clearerr(stdin); hi(0); goto tryagain; } - if (usemine) { - s[strlen(s) - 1] = '\0'; - cryptpw = crypt(s, mypw); - if (cryptpw != NULL && !strcmp(mypw, cryptpw)) - break; - } - else if (!strcmp(s, s1)) + if (!strcmp(s, s1)) break; (void)printf("\07\n"); failures++; @@ -243,6 +262,8 @@ tryagain: if (getuid() == 0) syslog(LOG_NOTICE, "ROOT UNLOCK ON hostname %s port %s", hostname, ttynam); + if (usemine) + (void)pam_end(pamh, pam_err); quit(0); return(0); /* not reached */ }