first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[kai/samba.git] / source3 / passdb / pass_check.c
index 9005864b08c21828af4626097b43dfe4f5d3a043..11ce0d754e8ab06b806281fe89d3e5e186134344 100644 (file)
@@ -32,7 +32,7 @@ static char this_salt[100]="";
 static char this_crypted[100]="";
 
 
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
 /*******************************************************************
 check on PAM authentication
 ********************************************************************/
@@ -136,6 +136,10 @@ static BOOL pam_auth(char *user,char *password)
 
 
 #ifdef WITH_AFS
+
+#include <afs/stds.h>
+#include <afs/kautils.h>
+
 /*******************************************************************
 check on AFS authentication
 ********************************************************************/
@@ -158,6 +162,7 @@ static BOOL afs_auth(char *user,char *password)
                                       &reason) == 0) {
                return(True);
        }
+       DEBUG(1,("AFS authentication for \"%s\" failed (%s)\n", user, reason));
        return(False);
 }
 #endif
@@ -165,6 +170,9 @@ static BOOL afs_auth(char *user,char *password)
 
 #ifdef WITH_DFS
 
+#include <dce/dce_error.h>
+#include <dce/sec_login.h>
+
 /*****************************************************************
  This new version of the DFS_AUTH code was donated by Karsten Muuss
  <muuss@or.uni-bonn.de>. It fixes the following problems with the
@@ -195,6 +203,7 @@ static BOOL dfs_auth(char *user,char *password)
        sec_passwd_rec_t passwd_rec;
        sec_login_auth_src_t auth_src = sec_login_auth_src_network;
        unsigned char dce_errstr[dce_c_error_string_len];
+       gid_t egid;
 
        if (dcelogin_atmost_once) return(False);
 
@@ -322,14 +331,16 @@ static BOOL dfs_auth(char *user,char *password)
         * back to being root on error though. JRA.
         */
        
-       if (setregid(-1, pw->pw_gid) != 0) {
+       egid = getegid();
+
+       if (set_effective_gid(pw->pw_gid) != 0) {
                DEBUG(0,("Can't set egid to %d (%s)\n", 
                         pw->pw_gid, strerror(errno)));
                return False;
        }
 
-       if (setreuid(-1, pw->pw_uid) != 0) {
-               setgid(0);
+       if (set_effective_uid(pw->pw_uid) != 0) {
+               set_effective_gid(egid);
                DEBUG(0,("Can't set euid to %d (%s)\n", 
                         pw->pw_uid, strerror(errno)));
                return False;
@@ -340,24 +351,17 @@ static BOOL dfs_auth(char *user,char *password)
                                     &my_dce_sec_context,
                                     &err) == 0) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE Setup Identity for %s failed: %s\n",
                         user,dce_errstr));
-               return(False);
+               goto err;
        }
 
        sec_login_get_pwent(my_dce_sec_context, 
                            (sec_login_passwd_t*)&pw, &err);
        if (err != error_status_ok ) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        passwd_rec.version_number = sec_passwd_c_version_none;
@@ -370,24 +374,16 @@ static BOOL dfs_auth(char *user,char *password)
                                    &auth_src, &err);
        if (err != error_status_ok ) { 
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n",
                         user,dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        sec_login_certify_identity(my_dce_sec_context, &err);
        if (err != error_status_ok) { 
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE certify identity failed: %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
 
        if (auth_src != sec_login_auth_src_network) { 
@@ -401,10 +397,7 @@ static BOOL dfs_auth(char *user,char *password)
                         user,dce_errstr));
                
                sec_login_purge_context(&my_dce_sec_context, &err);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
-               return(False);
+               goto err;
        }
        
        sec_login_get_pwent(my_dce_sec_context, 
@@ -412,11 +405,7 @@ static BOOL dfs_auth(char *user,char *password)
        if (err != error_status_ok) {
                dce_error_inq_text(err, dce_errstr, &err2);
                DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
-
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
-               return(False);
+               goto err;
        }
        
        DEBUG(0,("DCE login succeeded for principal %s on pid %d\n",
@@ -434,21 +423,24 @@ static BOOL dfs_auth(char *user,char *password)
        sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
        if (err != error_status_ok) {
                dce_error_inq_text(err, dce_errstr, &err2);
-               /* Go back to root, JRA. */
-               setuid(0);
-               setgid(0);
                DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr));
-               
-               return(False);
+               goto err;
        }
        
-       setuid(0);
-       setgid(0);
+       set_effective_uid(0);
+       set_effective_gid(0);
        
        DEBUG(0,("DCE context expires: %s",asctime(localtime(&expire_time))));
        
        dcelogin_atmost_once = 1;
        return (True);
+
+err:
+
+       /* Go back to root, JRA. */
+       set_effective_uid(0);
+       set_effective_gid(egid);
+       return(False);
 }
 
 void dfs_unlogin(void)
@@ -467,6 +459,9 @@ void dfs_unlogin(void)
 #endif
 
 #ifdef KRB5_AUTH
+
+#include <krb5.h>
+
 /*******************************************************************
 check on Kerberos authentication
 ********************************************************************/
@@ -506,7 +501,7 @@ static BOOL krb5_auth(char *user,char *password)
                return(False);
        }
 
-       memset((char *)&kcreds, 0, sizeof(kcreds));
+       ZERO_STRUCT(kcreds);
 
        kcreds.client = kprinc;
        
@@ -542,6 +537,8 @@ static BOOL krb5_auth(char *user,char *password)
 #endif /* KRB5_AUTH */
 
 #ifdef KRB4_AUTH
+#include <krb.h>
+
 /*******************************************************************
 check on Kerberos authentication
 ********************************************************************/
@@ -555,7 +552,7 @@ static BOOL krb4_auth(char *user,char *password)
        }
 
        (void) slprintf(tkfile, sizeof(tkfile) - 1, "/tmp/samba_tkt_%d", 
-                       getpid());
+                       (int)getpid());
   
        krb_set_tkt_string(tkfile);
        if (krb_verify_user(user, "", realm,
@@ -612,6 +609,7 @@ static char *osf1_bigcrypt(char *password,char *salt1)
        
        StrnCpy(salt,salt1,2);
        StrnCpy(result,salt1,2);
+       result[2]='\0';
 
        for (i=0; i<parts;i++) {
                p1 = crypt(p2,salt);
@@ -678,7 +676,7 @@ core of password checking routine
 static BOOL password_check(char *password)
 {
 
-#ifdef HAVE_PAM
+#ifdef WITH_PAM
        /* This falls through if the password check fails
           - if HAVE_CRYPT is not defined this causes an error msg
           saying Warning - no crypt available
@@ -689,23 +687,23 @@ static BOOL password_check(char *password)
           Hence we make a direct return to avoid a second chance!!!
        */
        return (pam_auth(this_user,password));
-#endif
+#endif /* WITH_PAM */
        
 #ifdef WITH_AFS
        if (afs_auth(this_user,password)) return(True);
-#endif
+#endif /* WITH_AFS */
        
 #ifdef WITH_DFS
        if (dfs_auth(this_user,password)) return(True);
-#endif 
+#endif /* WITH_DFS */
 
 #ifdef KRB5_AUTH
        if (krb5_auth(this_user,password)) return(True);
-#endif
+#endif /* KRB5_AUTH */
 
 #ifdef KRB4_AUTH
        if (krb4_auth(this_user,password)) return(True);
-#endif
+#endif /* KRB4_AUTH */
 
 #ifdef OSF1_ENH_SEC
        {
@@ -716,26 +714,42 @@ static BOOL password_check(char *password)
          }
          return ret;
        }
-#endif
+#endif /* OSF1_ENH_SEC */
 
 #ifdef ULTRIX_AUTH
        return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0);
-#endif
+#endif /* ULTRIX_AUTH */
 
 #ifdef LINUX_BIGCRYPT
        return(linux_bigcrypt(password,this_salt,this_crypted));
-#endif
+#endif /* LINUX_BIGCRYPT */
+
+#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
+
+       /*
+        * Some systems have bigcrypt in the C library but might not
+        * actually use it for the password hashes (HPUX 10.20) is
+        * a noteable example. So we try bigcrypt first, followed
+        * by crypt.
+        */
+
+       if(strcmp(bigcrypt(password,this_salt),this_crypted) == 0)
+               return True;
+       else 
+               return (strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
+#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 
 #ifdef HAVE_BIGCRYPT
        return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0);
-#endif
+#endif /* HAVE_BIGCRYPT */
 
 #ifndef HAVE_CRYPT
        DEBUG(1,("Warning - no crypt available\n"));
        return(False);
-#else
+#else /* HAVE_CRYPT */
        return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#endif
+#endif /* HAVE_CRYPT */
+#endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 }
 
 
@@ -793,7 +807,7 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
 
                spass = getspnam(pass->pw_name);
                if (spass && spass->sp_pwdp) {
-                       pass->pw_passwd = spass->sp_pwdp;
+                       pstrcpy(pass->pw_passwd,spass->sp_pwdp);
                }
        }
 #elif defined(IA_UINFO)
@@ -813,7 +827,7 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
        {
                struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
                if (pr_pw && pr_pw->ufld.fd_encrypt)
-                       pass->pw_passwd = pr_pw->ufld.fd_encrypt;
+                       pstrcpy(pass->pw_passwd,pr_pw->ufld.fd_encrypt);
        }
 #endif
 
@@ -827,9 +841,8 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
                        fstrcpy(pass->pw_name,mypasswd->ufld.fd_name);
                        fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt);
                } else {
-                       DEBUG(5,("No entry for user %s in protected database !\n",
+                       DEBUG(5,("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
                                 user));
-                       return(False);
                }
        }
 #endif
@@ -847,9 +860,12 @@ BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
        /* extract relevant info */
        fstrcpy(this_user,pass->pw_name);  
        fstrcpy(this_salt,pass->pw_passwd);
+
+#if defined(HAVE_TRUNCATED_SALT)
        /* crypt on some platforms (HPUX in particular)
           won't work with more than 2 salt characters. */
        this_salt[2] = 0;
+#endif
        
        fstrcpy(this_crypted,pass->pw_passwd);