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
This commit is contained in:
parent
b42712a8b7
commit
11db7fa42b
@ -5,6 +5,6 @@ PROG= lock
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
|
||||
LIBADD= crypt
|
||||
LIBADD= pam
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -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 @@ main(int argc, char **argv)
|
||||
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 */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user