diff options
author | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2018-02-11 13:35:31 +0000 |
---|---|---|
committer | Edward Tomasz Napierala <trasz@FreeBSD.org> | 2018-02-11 13:35:31 +0000 |
commit | 11db7fa42b29067aef2788610bf898f9b495e7dd (patch) | |
tree | ce6b178fa46d64f510013124f2a09956e82d0951 /usr.bin/lock | |
parent | b42712a8b77881b9c2a70976de2f388c5a9ddb2f (diff) | |
download | src-11db7fa42b29067aef2788610bf898f9b495e7dd.tar.gz src-11db7fa42b29067aef2788610bf898f9b495e7dd.zip |
Notes
Diffstat (limited to 'usr.bin/lock')
-rw-r--r-- | usr.bin/lock/Makefile | 2 | ||||
-rw-r--r-- | usr.bin/lock/lock.c | 53 |
2 files changed, 38 insertions, 17 deletions
diff --git a/usr.bin/lock/Makefile b/usr.bin/lock/Makefile index cc5d68907fbb..68ed4ee451da 100644 --- a/usr.bin/lock/Makefile +++ b/usr.bin/lock/Makefile @@ -5,6 +5,6 @@ PROG= lock BINOWN= root BINMODE=4555 -LIBADD= crypt +LIBADD= pam .include <bsd.prog.mk> diff --git a/usr.bin/lock/lock.c b/usr.bin/lock/lock.c index f51ff9cb7432..d8644f7010a9 100644 --- a/usr.bin/lock/lock.c +++ b/usr.bin/lock/lock.c @@ -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 */ } |