Date: Sun, 11 Feb 2018 13:35:31 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329123 - head/usr.bin/lock Message-ID: <201802111335.w1BDZVIL026043@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 <bsd.prog.mk> 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 <time.h> #include <unistd.h> +#include <security/pam_appl.h> +#include <security/openpam.h> /* 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 */ }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802111335.w1BDZVIL026043>