[PATCH] introduce NT_STATUS codes to pass_check.c

Andrew Bartlett abartlet at pcug.org.au
Sat May 12 12:07:01 GMT 2001


This patch adds NT_STATUS codes to the pass_check.c file, avoiding the
need to run our password-cracker against PAM if, for example, the
account was expired.

Tested with the PAM modifications in my previous patch.

Also cleans up an unused variable warning.

-- 
Andrew Bartlett
abartlet at pcug.org.au
-------------- next part --------------
Index: source/passdb/pass_check.c
===================================================================
RCS file: /cvsroot/samba/source/passdb/pass_check.c,v
retrieving revision 1.11.4.6
diff -u -r1.11.4.6 pass_check.c
--- source/passdb/pass_check.c	2001/05/01 17:19:58	1.11.4.6
+++ source/passdb/pass_check.c	2001/05/05 14:12:35
@@ -28,8 +28,10 @@
 
 /* these are kept here to keep the string_combinations function simple */
 static char this_user[100] = "";
+#ifndef WITH_PAM
 static char this_salt[100] = "";
 static char this_crypted[100] = "";
+#endif
 
 #ifdef WITH_AFS
 
@@ -550,11 +552,12 @@
 offset is the first char to try and change (start with 0)
 it assumes the string starts lowercased
 ****************************************************************************/
-static BOOL string_combinations2(char *s, int offset, BOOL (*fn) (char *),
+static uint32 string_combinations2(char *s, int offset, uint32 (*fn) (char *),
 				 int N)
 {
 	int len = strlen(s);
 	int i;
+	uint32 nt_status;
 
 #ifdef PASSWORD_LENGTH
 	len = MIN(len, PASSWORD_LENGTH);
@@ -568,11 +571,11 @@
 		if (!islower(c))
 			continue;
 		s[i] = toupper(c);
-		if (string_combinations2(s, i + 1, fn, N - 1))
-			return (True);
+		if ((nt_status = string_combinations2(s, i + 1, fn, N - 1)) != NT_STATUS_WRONG_PASSWORD)
+			return (nt_status);
 		s[i] = c;
 	}
-	return (False);
+	return (NT_STATUS_WRONG_PASSWORD);
 }
 
 /****************************************************************************
@@ -582,67 +585,82 @@
 offset is the first char to try and change (start with 0)
 it assumes the string starts lowercased
 ****************************************************************************/
-static BOOL string_combinations(char *s, BOOL (*fn) (char *), int N)
+static uint32 string_combinations(char *s, uint32 (*fn) (char *), int N)
 {
 	int n;
+	uint32 nt_status;
 	for (n = 1; n <= N; n++)
-		if (string_combinations2(s, 0, fn, n))
-			return (True);
-	return (False);
+		if ((nt_status = string_combinations2(s, 0, fn, n)) != NT_STATUS_WRONG_PASSWORD)
+			return nt_status;
+	return (NT_STATUS_WRONG_PASSWORD);
 }
 
 
 /****************************************************************************
 core of password checking routine
 ****************************************************************************/
-static BOOL password_check(char *password)
+static uint32 password_check(char *password)
 {
-
 #ifdef WITH_PAM
-	return (smb_pam_passcheck(this_user, password) == NT_STATUS_NOPROBLEMO);
+	return smb_pam_passcheck(this_user, password);
+#else
+   BOOL ret; 
 #endif /* WITH_PAM */
 
 #ifdef WITH_AFS
 	if (afs_auth(this_user, password))
-		return (True);
+		return (NT_STATUS_NOPROBLEMO);
 #endif /* WITH_AFS */
 
 #ifdef WITH_DFS
 	if (dfs_auth(this_user, password))
-		return (True);
+		return (NT_STATUS_NOPROBLEMO);
 #endif /* WITH_DFS */
 
 #ifdef KRB5_AUTH
 	if (krb5_auth(this_user, password))
-		return (True);
+		return (NT_STATUS_NOPROBLEMO);
 #endif /* KRB5_AUTH */
 
 #ifdef KRB4_AUTH
 	if (krb4_auth(this_user, password))
-		return (True);
+		return (NT_STATUS_NOPROBLEMO);
 #endif /* KRB4_AUTH */
 
 #ifdef OSF1_ENH_SEC
-	{
-		BOOL ret =
-			(strcmp
-			 (osf1_bigcrypt(password, this_salt),
+	
+	        ret = (strcmp(osf1_bigcrypt(password, this_salt),
 			  this_crypted) == 0);
 		if (!ret) {
 			DEBUG(2,
 			      ("OSF1_ENH_SEC failed. Trying normal crypt.\n"));
 			ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
 		}
-		return ret;
-	}
+	        if (ret) {
+		        return NT_STATUS_NOPROBLEMO;
+		} else {
+		        return NT_STATUS_WRONG_PASSWORD;
+		}
+
 #endif /* OSF1_ENH_SEC */
 
 #ifdef ULTRIX_AUTH
-	return (strcmp((char *)crypt16(password, this_salt), this_crypted) == 0);
+	ret = (strcmp((char *)crypt16(password, this_salt), this_crypted) == 0);
+        if (ret) {
+          return NT_STATUS_NOPROBLEMO;
+        } else {
+	  return NT_STATUS_WRONG_PASSWORD;
+	}
+
 #endif /* ULTRIX_AUTH */
 
 #ifdef LINUX_BIGCRYPT
-	return (linux_bigcrypt(password, this_salt, this_crypted));
+	ret = (linux_bigcrypt(password, this_salt, this_crypted));
+        if (ret) {
+	  return NT_STATUS_NOPROBLEMO;
+	} else {
+	  return NT_STATUS_WRONG_PASSWORD;
+	}
 #endif /* LINUX_BIGCRYPT */
 
 #if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
@@ -655,20 +673,35 @@
 	 */
 
 	if (strcmp(bigcrypt(password, this_salt), this_crypted) == 0)
-		return True;
+		return NT_STATUS_NOPROBLEMO;
 	else
-		return (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+		ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+                if (ret) {
+		  return NT_STATUS_NOPROBLEMO;
+		} else {
+		  return NT_STATUS_WRONG_PASSWORD;
+		}
 #else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 
 #ifdef HAVE_BIGCRYPT
-	return (strcmp(bigcrypt(password, this_salt), this_crypted) == 0);
+	ret = (strcmp(bigcrypt(password, this_salt), this_crypted) == 0);
+        if (ret) {
+	  return NT_STATUS_NOPROBLEMO;
+	} else {
+	  return NT_STATUS_WRONG_PASSWORD;
+	}
 #endif /* HAVE_BIGCRYPT */
 
 #ifndef HAVE_CRYPT
 	DEBUG(1, ("Warning - no crypt available\n"));
-	return (False);
+	return (NT_STATUS_LOGON_FAILURE);
 #else /* HAVE_CRYPT */
-	return (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+	ret = (strcmp((char *)crypt(password, this_salt), this_crypted) == 0);
+        if (ret) {
+	  return NT_STATUS_NOPROBLEMO;
+	} else {
+	  return NT_STATUS_WRONG_PASSWORD;
+	}
 #endif /* HAVE_CRYPT */
 #endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
 }
@@ -679,28 +712,28 @@
 check if a username/password is OK
 the function pointer fn() points to a function to call when a successful
 match is found and is used to update the encrypted password file 
-return True on correct match, False otherwise
+return NT_STATUS_NOPROBLEMO on correct match, NT_STATUS_WRONG_PASSWORD otherwise
 ****************************************************************************/
-
-BOOL pass_check(char *user, char *password, int pwlen, struct passwd *pwd,
+uint32 pass_check(char *user, char *password, int pwlen, struct passwd *pwd,
 		BOOL (*fn) (char *, char *))
 {
 	pstring pass2;
 	int level = lp_passwordlevel();
+	uint32 nt_status;
 	struct passwd *pass = NULL;
 
-	if (password)
-		password[pwlen] = 0;
-
 #if DEBUG_PASSWORD
 	DEBUG(100, ("checking user=[%s] pass=[%s]\n", user, password));
 #endif
 
+	if (password)
+		password[pwlen] = 0;
+
 	if (!password)
-		return (False);
+		return (NT_STATUS_WRONG_PASSWORD);
 
 	if (((!*password) || (!pwlen)) && !lp_null_passwords())
-		return (False);
+		return (NT_STATUS_WRONG_PASSWORD);
 
 	if (pwd && !user) {
 		pass = (struct passwd *)pwd;
@@ -726,7 +759,7 @@
 
 	if (!pass) {
 		DEBUG(3, ("Couldn't find user %s\n", user));
-		return (False);
+		return (NT_STATUS_NO_SUCH_USER);
 	}
 
 #ifdef HAVE_GETSPNAM
@@ -790,7 +823,6 @@
 #endif
 
 	/* extract relevant info */
-	fstrcpy(this_user, pass->pw_name);
 	fstrcpy(this_salt, pass->pw_passwd);
 
 #if defined(HAVE_TRUNCATED_SALT)
@@ -805,30 +837,34 @@
 		if (!lp_null_passwords()) {
 			DEBUG(2, ("Disallowing %s with null password\n",
 				  this_user));
-			return (False);
+			return (NT_STATUS_WRONG_PASSWORD);
 		}
 		if (!*password) {
 			DEBUG(3,
 			      ("Allowing access to %s with null password\n",
 			       this_user));
-			return (True);
+			return (NT_STATUS_NOPROBLEMO);
 		}
 	}
 
 #endif /* WITH_PAM */
 
 	/* try it as it came to us */
-	if (password_check(password)) {
-		if (fn)
-			fn(user, password);
-		return (True);
-	}
+        nt_status = password_check(password);
+        if (nt_status == NT_STATUS_NOPROBLEMO) {
+                if (fn)
+                        fn(user, password);
+		return (nt_status);
+	} else if (nt_status != NT_STATUS_WRONG_PASSWORD) {
+                /* No point continuing if its not the password thats to blame (ie PAM disabled). */
+                return (nt_status);
+        }
 
 	/* if the password was given to us with mixed case then we don't
-	   need to proceed as we know it hasn't been case modified by the
-	   client */
+	 * need to proceed as we know it hasn't been case modified by the
+	 * client */
 	if (strhasupper(password) && strhaslower(password)) {
-		return (False);
+		return (NT_STATUS_WRONG_PASSWORD);
 	}
 
 	/* make a copy of it */
@@ -837,10 +873,11 @@
 	/* try all lowercase if it's currently all uppercase */
 	if (strhasupper(password)) {
 		strlower(password);
-		if (password_check(password)) {
-			if (fn)
+		nt_status = password_check(password);
+		if (nt_status == NT_STATUS_NOPROBLEMO) {
+		        if (fn)
 				fn(user, password);
-			return (True);
+			return (nt_status);
 		}
 	}
 
@@ -848,20 +885,24 @@
 	if (level < 1) {
 		/* restore it */
 		fstrcpy(password, pass2);
-		return (False);
+		return (NT_STATUS_WRONG_PASSWORD);
 	}
 
 	/* last chance - all combinations of up to level chars upper! */
 	strlower(password);
 
-	if (string_combinations(password, password_check, level)) {
-		if (fn)
+        nt_status = (string_combinations(password, password_check, level)); 
+        if (nt_status == NT_STATUS_NOPROBLEMO) {
+                if (fn)
 			fn(user, password);
-		return (True);
+		return (NT_STATUS_NOPROBLEMO);
 	}
-
+        
 	/* restore it */
 	fstrcpy(password, pass2);
 
-	return (False);
+	return (NT_STATUS_WRONG_PASSWORD);
 }
+
+
+
Index: source/smbd/password.c
===================================================================
RCS file: /cvsroot/samba/source/smbd/password.c,v
retrieving revision 1.186.2.20
diff -u -r1.186.2.20 password.c
--- source/smbd/password.c	2001/04/30 20:37:44	1.186.2.20
+++ source/smbd/password.c	2001/05/05 14:12:49
@@ -628,7 +628,7 @@
 
 	return (pass_check(user, password, pwlen, pwd, 
 			  lp_update_encrypted() ? 
-			  update_smbpassword_file : NULL));
+			  update_smbpassword_file : NULL) == NT_STATUS_NOPROBLEMO);
 }
 
 /****************************************************************************
Index: source/web/cgi.c
===================================================================
RCS file: /cvsroot/samba/source/web/cgi.c,v
retrieving revision 1.37.2.3
diff -u -r1.37.2.3 cgi.c
--- source/web/cgi.c	2001/03/09 01:06:59	1.37.2.3
+++ source/web/cgi.c	2001/05/05 14:12:52
@@ -377,7 +377,7 @@
 
 	tested_pass = True;
 
-	if(pass_check(user, user_pass, strlen(user_pass), NULL, NULL) == True) {
+	if(pass_check(user, user_pass, strlen(user_pass), NULL, NULL) == NT_STATUS_NOPROBLEMO) {
 
 		/*
 		 * Password was ok.


More information about the samba-technical mailing list