*/
#ifndef lint
-static char rcsid[] = "$Id: auth.c,v 1.30 1997/03/04 03:37:21 paulus Exp $";
+static char rcsid[] = "$Id: auth.c,v 1.35 1997/11/27 06:49:15 paulus Exp $";
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <utmp.h>
+#include <fcntl.h>
+#if defined(_PATH_LASTLOG) && defined(_linux_)
+#include <lastlog.h>
+#endif
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-#if defined(SVR4) || defined(_linux_)
-#include <crypt.h>
-#else
-#if defined(SUNOS4) || defined(ULTRIX)
-extern char *crypt();
-#endif
-#endif
-
#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_modules.h>
#ifdef HAS_SHADOW
#include <shadow.h>
+#ifndef SVR4
#include <shadow/pwauth.h>
+#endif
#ifndef PW_PPP
#define PW_PPP PW_LOGIN
#endif
/* Records which authentication operations haven't completed yet. */
static int auth_pending[NUM_PPP];
-/* Set if we have successfully called login() */
+/* Set if we have successfully called plogin() */
static int logged_in;
/* Set if we have run the /etc/ppp/auth-up script. */
#define CHAP_WITHPEER 4
#define CHAP_PEER 8
+extern char *crypt __P((const char *, const char *));
+
/* Prototypes for procedures local to this file. */
static void network_phase __P((int));
-static void check_idle __P((caddr_t));
-static void connect_time_expired __P((caddr_t));
-static int login __P((char *, char *, char **, int *));
-static void logout __P((void));
+static void check_idle __P((void *));
+static void connect_time_expired __P((void *));
+static int plogin __P((char *, char *, char **, int *));
+static void plogout __P((void));
static int null_login __P((int));
static int get_pap_passwd __P((char *));
static int have_pap_secret __P((void));
static void free_wordlist __P((struct wordlist *));
static void auth_script __P((char *));
static void set_allowed_addrs __P((int, struct wordlist *));
-#ifdef CBCP_SUPPORT
-static void callback_phase __P((int));
-#endif
/*
* An Open on LCP has requested a change from Dead to Establish phase.
if (phase == PHASE_DEAD)
return;
if (logged_in)
- logout();
+ plogout();
phase = PHASE_DEAD;
syslog(LOG_NOTICE, "Connection terminated.");
}
if (protp->protocol != PPP_CCP)
++num_np_open;
}
+
+ if (num_np_open == 0)
+ /* nothing to do */
+ lcp_close(0, "No network protocols running");
}
/*
np_up(unit, proto)
int unit, proto;
{
- if (num_np_up == 0 && idle_time_limit > 0) {
- TIMEOUT(check_idle, NULL, idle_time_limit);
+ if (num_np_up == 0) {
+ /*
+ * At this point we consider that the link has come up successfully.
+ */
+ need_holdoff = 0;
+
+ if (idle_time_limit > 0)
+ TIMEOUT(check_idle, NULL, idle_time_limit);
/*
* Set a timeout to close the connection once the maximum
*/
static void
check_idle(arg)
- caddr_t arg;
+ void *arg;
{
struct ppp_idle idle;
time_t itime;
if (itime >= idle_time_limit) {
/* link is idle: shut it down. */
syslog(LOG_INFO, "Terminating connection due to lack of activity.");
- need_holdoff = 0;
lcp_close(0, "Link inactive");
} else {
TIMEOUT(check_idle, NULL, idle_time_limit - itime);
*/
static void
connect_time_expired(arg)
- caddr_t arg;
+ void *arg;
{
syslog(LOG_INFO, "Connect time expired");
lcp_close(0, "Connect time expired"); /* Close connection */
option_error("can't override device name when noauth option used");
exit(1);
}
- if (connector != NULL && connector_info.priv == 0
- || disconnector != NULL && disconnector_info.priv == 0
- || welcomer != NULL && welcomer_info.priv == 0) {
+ if ((connector != NULL && connector_info.priv == 0)
+ || (disconnector != NULL && disconnector_info.priv == 0)
+ || (welcomer != NULL && welcomer_info.priv == 0)) {
option_error("can't override connect, disconnect or welcome");
option_error("option values when noauth option used");
exit(1);
}
if (uselogin && ret == UPAP_AUTHACK) {
- ret = login(user, passwd, msg, msglen);
+ ret = plogin(user, passwd, msg, msglen);
if (ret == UPAP_AUTHNAK) {
syslog(LOG_WARNING, "PAP login failure for %s", user);
}
#endif
/*
- * login - Check the user name and password against the system
+ * plogin - Check the user name and password against the system
* password database, and login the user if OK.
*
* returns:
*/
static int
-login(user, passwd, msg, msglen)
+plogin(user, passwd, msg, msglen)
char *user;
char *passwd;
char **msg;
#else /* #ifdef USE_PAM */
struct passwd *pw;
- char *epasswd;
#ifdef HAS_SHADOW
struct spwd *spwd;
if (strncmp(tty, "/dev/", 5) == 0)
tty += 5;
logwtmp(tty, user, remote_name); /* Add wtmp login entry */
+
+#ifdef _PATH_LASTLOG
+ {
+ struct lastlog ll;
+ int fd;
+
+ if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
+ (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET);
+ memset((void *)&ll, 0, sizeof(ll));
+ (void)time(&ll.ll_time);
+ (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
+ (void)write(fd, (char *)&ll, sizeof(ll));
+ (void)close(fd);
+ }
+ }
+#endif
logged_in = TRUE;
return (UPAP_AUTHACK);
}
/*
- * logout - Logout the user.
+ * plogout - Logout the user.
*/
static void
-logout()
+plogout()
{
char *tty;
{
char *filename;
FILE *f;
+ int ret;
struct wordlist *addrs;
char secret[MAXWORDLEN];
if (f == NULL)
return 0;
check_access(f, filename);
- if (scan_authfile(f, user,
- remote_name[0]? remote_name: NULL,
- (u_int32_t)0, secret, NULL, filename) < 0)
+ ret = scan_authfile(f, user,
+ remote_name[0]? remote_name: NULL,
+ (u_int32_t)0, secret, NULL, filename);
+ fclose(f);
+ if (ret < 0)
return 0;
if (passwd != NULL) {
strncpy(passwd, secret, MAXSECRETLEN);
if (ptr_mask != NULL)
*ptr_mask = '/';
- if (a == -1L)
+ if (a == (u_int32_t)-1L)
syslog (LOG_WARNING,
"unknown host %s in auth. address list",
addrs->word);