]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/auth.c
update from Al
[ppp.git] / pppd / auth.c
index c87f4003a244b2328c3aebfdce0602bf4057e67f..f384cb800cabcd066ca62ad670c1d7fc936e01b7 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: auth.c,v 1.25 1996/07/01 01:10:24 paulus Exp $";
+static char rcsid[] = "$Id: auth.c,v 1.29 1996/10/08 06:43:15 paulus Exp $";
 #endif
 
 #include <stdio.h>
@@ -54,7 +54,7 @@ static char rcsid[] = "$Id: auth.c,v 1.25 1996/07/01 01:10:24 paulus Exp $";
 #ifdef SVR4
 #include <crypt.h>
 #else
-#ifdef SUNOS4
+#if defined(SUNOS4) || defined(ULTRIX)
 extern char *crypt();
 #endif
 #endif
@@ -62,6 +62,7 @@ extern char *crypt();
 #ifdef USE_PAM
 #include <security/pam_appl.h>
 #include <security/pam_modules.h>
+int isexpired (struct passwd *, struct spwd *);
 #endif
 
 #ifdef HAS_SHADOW
@@ -78,12 +79,11 @@ extern char *crypt();
 #include "ipcp.h"
 #include "upap.h"
 #include "chap.h"
+#ifdef CBCP_SUPPORT
+#include "cbcp.h"
+#endif
 #include "pathnames.h"
 
-#if defined(sun) && defined(sparc)
-#include <alloca.h>
-#endif /*sparc*/
-
 /* Used for storing a sequence of words.  Usually malloced. */
 struct wordlist {
     struct wordlist    *next;
@@ -144,6 +144,9 @@ static int  scan_authfile __P((FILE *, char *, char *, u_int32_t, char *,
                               struct wordlist **, char *));
 static void free_wordlist __P((struct wordlist *));
 static void auth_script __P((char *));
+#ifdef CBCP_SUPPORT
+static void callback_phase __P((int));
+#endif
 
 /*
  * An Open on LCP has requested a change from Dead to Establish phase.
@@ -244,7 +247,7 @@ link_established(unit)
        auth |= PAP_PEER;
     }
     if (ho->neg_chap) {
-       ChapAuthWithPeer(unit, our_name, ho->chap_mdtype);
+       ChapAuthWithPeer(unit, user, ho->chap_mdtype);
        auth |= CHAP_WITHPEER;
     } else if (ho->neg_upap) {
        if (passwd[0] == 0) {
@@ -280,6 +283,17 @@ network_phase(unit)
        did_authup = 1;
     }
 
+#ifdef CBCP_SUPPORT
+    /*
+     * If we negotiated callback, do it now.
+     */
+    if (go->neg_cbcp) {
+       phase = PHASE_CALLBACK;
+       (*cbcp_protent.open)(unit);
+       return;
+    }
+#endif
+
     phase = PHASE_NETWORK;
 #if 0
     if (!demand)
@@ -341,7 +355,7 @@ auth_peer_success(unit, protocol, name, namelen)
 
     /*
      * If there is no more authentication still to be done,
-     * proceed to the network phase.
+     * proceed to the network (or callback) phase.
      */
     if ((auth_pending[unit] &= ~bit) == 0)
         network_phase(unit);
@@ -389,7 +403,7 @@ auth_withpeer_success(unit, protocol)
 
     /*
      * If there is no more authentication still being done,
-     * proceed to the network phase.
+     * proceed to the network (or callback) phase.
      */
     if ((auth_pending[unit] &= ~bit) == 0)
        network_phase(unit);
@@ -451,6 +465,7 @@ check_idle(arg)
     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);
@@ -491,11 +506,32 @@ auth_check_options()
     }
 
     if (auth_required && !can_auth) {
-       fprintf(stderr, "\
-pppd: peer authentication required but no suitable secret(s) found\n");
+       option_error("peer authentication required but no suitable secret(s) found\n");
+       if (remote_name[0] == 0)
+           option_error("for authenticating any peer to us (%s)\n", our_name);
+       else
+           option_error("for authenticating peer %s to us (%s)\n",
+                        remote_name, our_name);
        exit(1);
     }
 
+    /*
+     * Check whether the user tried to override certain values
+     * set by root.
+     */
+    if (!auth_required && auth_req_info.priv > 0) {
+       if (!default_device && devnam_info.priv == 0) {
+           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) {
+           option_error("can't override connect, disconnect or welcome");
+           option_error("option values when noauth option used");
+           exit(1);
+       }
+    }
 }
 
 /*
@@ -514,7 +550,7 @@ auth_reset(unit)
 
     ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
     ao->neg_chap = !refuse_chap
-       && have_chap_secret(our_name, remote_name, (u_int32_t)0);
+       && have_chap_secret(user, remote_name, (u_int32_t)0);
 
     if (go->neg_upap && !uselogin && !have_pap_secret())
        go->neg_upap = 0;
@@ -750,7 +786,7 @@ login(user, passwd, msg, msglen)
  * Define the fields for the credintial validation
  */
     (void) pam_set_item (pamh, PAM_AUTHTOK, passwd);
-    (void) pam_set_item (pamh, PAM_TTY, devnam);
+    (void) pam_set_item (pamh, PAM_TTY,     devnam);
 /*
  * Validate the user
  */
@@ -779,14 +815,20 @@ login(user, passwd, msg, msglen)
     struct spwd *getspnam();
 #endif
 
-    if ((pw = getpwnam(user)) == NULL) {
+    pw = getpwnam(user);
+    if (pw == NULL) {
        return (UPAP_AUTHNAK);
     }
 
 #ifdef HAS_SHADOW
-    if ((spwd = getspnam(user)) == NULL) {
-        pw->pw_passwd = "";
-    } else {
+    spwd = getspnam(user);
+    endspent();
+    if (spwd) {
+       /* check the age of the password entry */
+       if (isexpired(pw, spwd)) {
+           syslog(LOG_WARNING,"Expired password for %s",user);
+           return (UPAP_AUTHNAK);
+       }
        pw->pw_passwd = spwd->sp_pwdp;
     }
 #endif
@@ -794,33 +836,12 @@ login(user, passwd, msg, msglen)
     /*
      * XXX If no passwd, let them login without one.
      */
-    if (pw->pw_passwd == '\0') {
-       return (UPAP_AUTHACK);
-    }
-
-#ifdef HAS_SHADOW
-    if (pw->pw_passwd) {
-       if (pw->pw_passwd[0] == '@') {
-           if (pw_auth (pw->pw_passwd+1, pw->pw_name, PW_PPP, NULL)) {
-               return (UPAP_AUTHNAK);
-           }
-       } else {
-           epasswd = pw_encrypt(passwd, pw->pw_passwd);
-           if (strcmp(epasswd, pw->pw_passwd)) {
-               return (UPAP_AUTHNAK);
-           }
-       }
-       /* check the age of the password entry */
-       if (spwd && (isexpired (pw, spwd) != 0)) {
+    if (pw->pw_passwd != NULL && *pw->pw_passwd != '\0') {
+       epasswd = crypt(passwd, pw->pw_passwd);
+       if (strcmp(epasswd, pw->pw_passwd) != 0) {
            return (UPAP_AUTHNAK);
        }
     }
-#else
-    epasswd = crypt(passwd, pw->pw_passwd);
-    if (strcmp(epasswd, pw->pw_passwd)) {
-       return (UPAP_AUTHNAK);
-    }
-#endif
 #endif /* #ifdef USE_PAM */
 
     syslog(LOG_INFO, "user %s logged in", user);
@@ -900,7 +921,8 @@ null_login(unit)
  * could be found.
  */
 static int
-get_pap_passwd(char *passwd)
+get_pap_passwd(passwd)
+    char *passwd;
 {
     char *filename;
     FILE *f;