From 629098536b9cbb38826d232a7bb25f19b602c0f6 Mon Sep 17 00:00:00 2001 From: Daniel O'Callaghan Date: Tue, 15 Apr 1997 07:00:35 +0000 Subject: Reviewed by: Brian Somers pppd now creates /var/run/ttyXn.if file containing the interface name; check that a 'login' user is not listed in /etc/ppp/ppp.disabled; check that a 'login' user's shell is listed in /etc/ppp/ppp.shells; make sure that passwordless 'login' logins are recorded in wtmp and utmp. --- usr.sbin/pppd/auth.c | 99 +++++++++++++++++++++++++++++++++++------------ usr.sbin/pppd/main.c | 26 ++++++++++++- usr.sbin/pppd/pathnames.h | 5 ++- usr.sbin/pppd/pppd.8 | 17 +++++++- 4 files changed, 119 insertions(+), 28 deletions(-) diff --git a/usr.sbin/pppd/auth.c b/usr.sbin/pppd/auth.c index 44d4bcb9059e..56fbd286d82d 100644 --- a/usr.sbin/pppd/auth.c +++ b/usr.sbin/pppd/auth.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: auth.c,v 1.12 1997/02/22 16:11:32 peter Exp $"; +static char rcsid[] = "$Id: auth.c,v 1.13 1997/04/13 01:06:56 brian Exp $"; #endif #include @@ -469,6 +469,39 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) } +/* + * Check if an "entry" is in the file "fname" - used by ppplogin. + * Taken from libexec/ftpd/ftpd.c + * Returns: 0 if not found, 1 if found, 2 if file can't be opened for reading. + */ +static int +checkfile(fname, name) + char *fname; + char *name; +{ + FILE *fd; + int found = 0; + char *p, line[BUFSIZ]; + + if ((fd = fopen(fname, "r")) != NULL) { + while (fgets(line, sizeof(line), fd) != NULL) + if ((p = strchr(line, '\n')) != NULL) { + *p = '\0'; + if (line[0] == '#') + continue; + if (strcmp(line, name) == 0) { + found = 1; + break; + } + } + (void) fclose(fd); + } else { + return(2); + } + return (found); +} + + /* * ppplogin - Check the user name and password against the system * password database, and login the user if OK. @@ -477,6 +510,8 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg, msglen) * UPAP_AUTHNAK: Login failed. * UPAP_AUTHACK: Login succeeded. * In either case, msg points to an appropriate message. + * + * UPAP_AUTHACK should only be returned *after* wtmp and utmp are updated. */ static int ppplogin(user, passwd, msg, msglen) @@ -500,6 +535,24 @@ ppplogin(user, passwd, msg, msglen) return (UPAP_AUTHNAK); } +/* + * Check that the user is not listed in /etc/ppp/ppp.disabled + * and that the user's shell is listed in /etc/ppp/ppp.shells + * if /etc/ppp/ppp.shells exists. + */ + + if (checkfile(_PATH_PPPDISABLED, user) == 1) { + syslog(LOG_WARNING, "upap user %s: account disabled in %s", + user, _PATH_PPPDISABLED); + return (UPAP_AUTHNAK); + } + + if (checkfile(_PATH_PPPSHELLS, pw->pw_shell) == 0) { + syslog(LOG_WARNING, "upap user %s: shell %s not in %s", + user, pw->pw_shell, _PATH_PPPSHELLS); + return (UPAP_AUTHNAK); + } + #ifdef HAS_SHADOW if ((spwd = getspnam(user)) == NULL) { pw->pw_passwd = ""; @@ -509,44 +562,42 @@ ppplogin(user, passwd, msg, msglen) #endif /* - * XXX If no passwd, let them login without one. + * If there is a password, check it. */ - if (pw->pw_passwd == '\0') { - return (UPAP_AUTHACK); - } + if (pw->pw_passwd[0] != '\0') { #ifdef HAS_SHADOW - if ((pw->pw_passwd && pw->pw_passwd[0] == '@' - && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL)) - || !valid (passwd, pw)) { - return (UPAP_AUTHNAK); - } + if ((pw->pw_passwd && pw->pw_passwd[0] == '@' + && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL)) + || !valid (passwd, pw)) { + return (UPAP_AUTHNAK); + } #else - epasswd = crypt(passwd, pw->pw_passwd); - if (strcmp(epasswd, pw->pw_passwd)) { - return (UPAP_AUTHNAK); - } + epasswd = crypt(passwd, pw->pw_passwd); + if (strcmp(epasswd, pw->pw_passwd)) { + return (UPAP_AUTHNAK); + } #endif - if (pw->pw_expire) { - (void)gettimeofday(&tp, (struct timezone *)NULL); - if (tp.tv_sec >= pw->pw_expire) { - syslog(LOG_INFO, "user %s account expired", user); - return (UPAP_AUTHNAK); + if (pw->pw_expire) { + (void)gettimeofday(&tp, (struct timezone *)NULL); + if (tp.tv_sec >= pw->pw_expire) { + syslog(LOG_INFO, "pap user %s account expired", user); + return (UPAP_AUTHNAK); + } } - } + } /* if password */ + syslog(LOG_INFO, "user %s logged in", user); - /* - * Write a wtmp entry for this user. - */ + /* Log in wtmp and utmp using login() */ + tty = devnam; if (strncmp(tty, "/dev/", 5) == 0) tty += 5; logged_in = TRUE; - /* Log in wtmp and utmp using login() */ memset((void *)&utmp, 0, sizeof(utmp)); (void)time(&utmp.ut_time); (void)strncpy(utmp.ut_name, user, sizeof(utmp.ut_name)); diff --git a/usr.sbin/pppd/main.c b/usr.sbin/pppd/main.c index ee7dec1dd99d..c13a90d5f1d6 100644 --- a/usr.sbin/pppd/main.c +++ b/usr.sbin/pppd/main.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id$"; +static char rcsid[] = "$Id: main.c,v 1.10 1997/02/22 16:11:48 peter Exp $"; #endif #include @@ -67,6 +67,7 @@ int ifunit; /* Interface unit number */ char *progname; /* Name of this program */ char hostname[MAXNAMELEN]; /* Our hostname */ static char pidfilename[MAXPATHLEN]; /* name of pid file */ +static char iffilename[MAXPATHLEN]; /* name of if file */ static char default_devnam[MAXPATHLEN]; /* name of default device */ static pid_t pid; /* Our pid */ static pid_t pgrpid; /* Process Group ID */ @@ -154,10 +155,11 @@ main(argc, argv) int argc; char *argv[]; { - int i, nonblock; + int i, n, nonblock; struct sigaction sa; struct cmd *cmdp; FILE *pidfile; + FILE *iffile; char *p; struct passwd *pw; struct timeval timo; @@ -393,6 +395,21 @@ main(argc, argv) pidfilename[0] = 0; } + /* write interface unit number to file */ + for (n = strlen(devnam); n > 0 ; n--) + if (devnam[n] == '/') { + n = n++; + break; + } + (void) sprintf(iffilename, "%s%s.if", _PATH_VARRUN, &devnam[n]); + if ((iffile = fopen(iffilename, "w")) != NULL) { + fprintf(iffile, "ppp%d\n", ifunit); + (void) fclose(iffile); + } else { + syslog(LOG_ERR, "Failed to create if file %s: %m", iffilename); + iffilename[0] = 0; + } + /* * Set device for non-blocking reads. */ @@ -448,6 +465,11 @@ main(argc, argv) syslog(LOG_WARNING, "unable to delete pid file: %m"); pidfilename[0] = 0; + if (iffile) + if (unlink(iffilename) < 0 && errno != ENOENT) + syslog(LOG_WARNING, "unable to delete if file: %m"); + iffilename[0] = 0; + } while (persist); die(0); diff --git a/usr.sbin/pppd/pathnames.h b/usr.sbin/pppd/pathnames.h index d0ec2ff6a70a..7033ff094336 100644 --- a/usr.sbin/pppd/pathnames.h +++ b/usr.sbin/pppd/pathnames.h @@ -1,7 +1,7 @@ /* * define path names * - * $Id$ + * $Id: pathnames.h,v 1.5 1997/02/22 16:11:52 peter Exp $ */ #ifdef HAVE_PATHS_H @@ -20,3 +20,6 @@ #define _PATH_TTYOPT "/etc/ppp/options." #define _PATH_CONNERRS "/etc/ppp/connect-errors" #define _PATH_USEROPT ".ppprc" +#define _PATH_PPPDISABLED "/etc/ppp/ppp.disabled" +#define _PATH_PPPSHELLS "/etc/ppp/ppp.shells" + diff --git a/usr.sbin/pppd/pppd.8 b/usr.sbin/pppd/pppd.8 index 76cef600f7da..e0e8bfa19d2d 100644 --- a/usr.sbin/pppd/pppd.8 +++ b/usr.sbin/pppd/pppd.8 @@ -1,5 +1,5 @@ .\" manual page [] for pppd 2.0 -.\" $Id: pppd.8,v 1.9 1997/02/22 16:11:54 peter Exp $ +.\" $Id: pppd.8,v 1.10 1997/04/13 01:07:00 brian Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph @@ -566,6 +566,11 @@ set of IP addresses that each user can use. Typically, when using the \fBlogin\fR option, the secret in /etc/ppp/pap-secrets would be "", to avoid the need to have the same secret in two places. .LP +Additional checks are performed when the \fBlogin\fR option is used. +If the file /etc/ppp/ppp.disabled exists, and the user is listed in it, +the authentication fails. If the file /etc/ppp/ppp.shells exists and +the user's normal login shell is not listed, the authentication fails. +.LP Secrets are selected from the CHAP secrets file as follows: .TP 2 * @@ -682,6 +687,9 @@ process. This signal acts as a toggle. .B /var/run/ppp\fIn\fB.pid \fR(BSD or Linux), \fB/etc/ppp/ppp\fIn\fB.pid \fR(others) Process-ID for \fIpppd\fR process on ppp interface unit \fIn\fR. .TP +.B /var/run/tty\fIXn\fB.if \fR(BSD or Linux), \fB/etc/ppp/tty\fIXn\fB.if \fR(others) +Interface for \fIpppd\fR process on serial device /dev/tty\fIXn\fR. +.TP .B /etc/ppp/ip-up A program or script which is executed when the link is available for sending and receiving IP packets (that is, IPCP has come up). It is @@ -726,6 +734,13 @@ User default options, read before command-line options. .B /etc/ppp/options.\fIttyname System default options for the serial port being used, read after command-line options. +.TP +.B /etc/ppp/ppp.disabled +Lists users who may not use the system password PAP authentication. +.TP +.B /etc/ppp/ppp.shells +Lists user shells which are approved for system password PAP authentication +logins. .SH SEE ALSO .IR chat(8), .IR ppp(8) -- cgit v1.2.3