svn commit: samba r15398 - branches/SAMBA_3_0/source/nsswitch trunk/source/nsswitch

gd at samba.org gd at samba.org
Tue May 2 19:22:40 GMT 2006


Author: gd
Date: 2006-05-02 19:22:39 +0000 (Tue, 02 May 2006)
New Revision: 15398

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=15398

Log:
Attempt to send the correct warning when a password change was attempted
too early.

Guenther

Modified:
   branches/SAMBA_3_0/source/nsswitch/pam_winbind.c
   branches/SAMBA_3_0/source/nsswitch/pam_winbind.h
   branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c
   trunk/source/nsswitch/pam_winbind.c
   trunk/source/nsswitch/pam_winbind.h
   trunk/source/nsswitch/winbindd_pam.c


Changeset:
Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/pam_winbind.c	2006-05-02 19:20:49 UTC (rev 15397)
+++ branches/SAMBA_3_0/source/nsswitch/pam_winbind.c	2006-05-02 19:22:39 UTC (rev 15398)
@@ -320,7 +320,8 @@
 				const char *pass, 
 				const char *member, 
 				const char *cctype,
-				int process_result)
+				int process_result,
+				time_t *pwd_last_set)
 {
 	struct winbindd_request request;
 	struct winbindd_response response;
@@ -329,6 +330,10 @@
 	ZERO_STRUCT(request);
 	ZERO_STRUCT(response);
 
+	if (pwd_last_set) {
+		*pwd_last_set = 0;
+	}
+
 	strncpy(request.data.auth.user, user, 
 		sizeof(request.data.auth.user)-1);
 
@@ -401,6 +406,10 @@
 	
 	ret = pam_winbind_request_log(pamh, ctrl, WINBINDD_PAM_AUTH, &request, &response, user);
 
+	if (pwd_last_set) {
+		*pwd_last_set = response.data.auth.info3.pass_last_set_time;
+	}
+
 	if ((ctrl & WINBIND_KRB5_AUTH) && 
 	    response.data.auth.krb5ccname[0] != '\0') {
 
@@ -487,7 +496,8 @@
 				     int ctrl,
 				     const char *user, 
 				     const char *oldpass,
-				     const char *newpass) 
+				     const char *newpass,
+				     time_t pwd_last_set) 
 {
 	struct winbindd_request request;
 	struct winbindd_response response;
@@ -541,8 +551,14 @@
 
 		/* FIXME: avoid to send multiple PAM messages after another */
 		switch (response.data.auth.reject_reason) {
-			case 0:
+			case -1:
 				break;
+			case REJECT_REASON_OTHER:
+				if ((response.data.auth.policy.min_passwordage > 0)) &&
+				    (pwd_last_set + response.data.auth.policy.min_passwordage > time(NULL)) {
+					PAM_WB_REMARK_DIRECT(pamh, "NT_STATUS_PWD_TOO_RECENT");
+				}
+				break;
 			case REJECT_REASON_TOO_SHORT:
 				PAM_WB_REMARK_DIRECT(pamh, "NT_STATUS_PWD_TOO_SHORT");
 				break;
@@ -892,7 +908,7 @@
 	cctype = get_krb5_cc_type_from_config(argc, argv, ctrl, d);
 
 	/* Now use the username to look up password */
-	retval = winbind_auth_request(pamh, ctrl, username, password, member, cctype, True);
+	retval = winbind_auth_request(pamh, ctrl, username, password, member, cctype, True, NULL);
 
 	if (retval == PAM_NEW_AUTHTOK_REQD ||
 	    retval == PAM_AUTHTOK_EXPIRED) {
@@ -1174,6 +1190,8 @@
 
 	if (flags & PAM_PRELIM_CHECK) {
 		
+		time_t pwdlastset_prelim = 0;
+		
 		/* instruct user what is happening */
 #define greeting "Changing password for "
 		Announce = (char *) malloc(sizeof(greeting) + strlen(user));
@@ -1198,16 +1216,18 @@
 		}
 		/* verify that this is the password for this user */
 		
-		retval = winbind_auth_request(pamh, ctrl, user, pass_old, NULL, NULL, False);
+		retval = winbind_auth_request(pamh, ctrl, user, pass_old, NULL, NULL, False, &pwdlastset_prelim);
 
-		if (retval != PAM_ACCT_EXPIRED 
-		    && retval != PAM_AUTHTOK_EXPIRED
-		    && retval != PAM_NEW_AUTHTOK_REQD 
-		    && retval != PAM_SUCCESS) {
+		if (retval != PAM_ACCT_EXPIRED && 
+		    retval != PAM_AUTHTOK_EXPIRED &&
+		    retval != PAM_NEW_AUTHTOK_REQD &&
+		    retval != PAM_SUCCESS) {
 			pass_old = NULL;
 			goto out;
 		}
 		
+		pam_set_data(pamh, PAM_WINBIND_PWD_LAST_SET, (void *)pwdlastset_prelim, _pam_winbind_cleanup_func);
+
 		retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
 		pass_old = NULL;
 		if (retval != PAM_SUCCESS) {
@@ -1215,6 +1235,8 @@
 		}
 	} else if (flags & PAM_UPDATE_AUTHTOK) {
 	
+		time_t pwdlastset_update = 0;
+		
 		/*
 		 * obtain the proposed password
 		 */
@@ -1272,8 +1294,9 @@
 		 * By reaching here we have approved the passwords and must now
 		 * rebuild the password database file.
 		 */
+		pam_get_data( pamh, PAM_WINBIND_PWD_LAST_SET, (const void **)&pwdlastset_update);
 
-		retval = winbind_chauthtok_request(pamh, ctrl, user, pass_old, pass_new);
+		retval = winbind_chauthtok_request(pamh, ctrl, user, pass_old, pass_new, pwdlastset_update);
 		if (retval) {
 			_pam_overwrite(pass_new);
 			_pam_overwrite(pass_old);
@@ -1288,7 +1311,7 @@
 			const char *member = get_member_from_config(argc, argv, ctrl, d);
 			const char *cctype = get_krb5_cc_type_from_config(argc, argv, ctrl, d);
 
-			retval = winbind_auth_request(pamh, ctrl, user, pass_new, member, cctype, False);
+			retval = winbind_auth_request(pamh, ctrl, user, pass_new, member, cctype, False, NULL);
 			_pam_overwrite(pass_new);
 			_pam_overwrite(pass_old);
 			pass_old = pass_new = NULL;

Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.h
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/pam_winbind.h	2006-05-02 19:20:49 UTC (rev 15397)
+++ branches/SAMBA_3_0/source/nsswitch/pam_winbind.h	2006-05-02 19:22:39 UTC (rev 15398)
@@ -107,6 +107,7 @@
 
 #define PAM_WINBIND_NEW_AUTHTOK_REQD "PAM_WINBIND_NEW_AUTHTOK_REQD"
 #define PAM_WINBIND_HOMEDIR "PAM_WINBIND_HOMEDIR"
+#define PAM_WINBIND_PWD_LAST_SET "PAM_WINBIND_PWD_LAST_SET"
 
 #define SECONDS_PER_DAY 86400
 

Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c	2006-05-02 19:20:49 UTC (rev 15397)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c	2006-05-02 19:22:39 UTC (rev 15398)
@@ -1652,6 +1652,9 @@
 	oldpass = state->request.data.chauthtok.oldpass;
 	newpass = state->request.data.chauthtok.newpass;
 
+	/* Initialize reject reason */
+	state->response.data.auth.reject_reason = Undefined;
+
 	/* Get sam handle */
 
 	result = cm_connect_sam(contact_domain, state->mem_ctx, &cli,
@@ -1690,8 +1693,6 @@
 		DEBUG(10,("Password change with chgpasswd3 failed with: %s, retrying chgpasswd_user\n", 
 			nt_errstr(result)));
 		
-		state->response.data.auth.reject_reason = 0;
-
 		result = rpccli_samr_chgpasswd_user(cli, state->mem_ctx, user, newpass, oldpass);
 	}
 

Modified: trunk/source/nsswitch/pam_winbind.c
===================================================================
--- trunk/source/nsswitch/pam_winbind.c	2006-05-02 19:20:49 UTC (rev 15397)
+++ trunk/source/nsswitch/pam_winbind.c	2006-05-02 19:22:39 UTC (rev 15398)
@@ -320,7 +320,8 @@
 				const char *pass, 
 				const char *member, 
 				const char *cctype,
-				int process_result)
+				int process_result,
+				time_t *pwd_last_set)
 {
 	struct winbindd_request request;
 	struct winbindd_response response;
@@ -329,6 +330,10 @@
 	ZERO_STRUCT(request);
 	ZERO_STRUCT(response);
 
+	if (pwd_last_set) {
+		*pwd_last_set = 0;
+	}
+
 	strncpy(request.data.auth.user, user, 
 		sizeof(request.data.auth.user)-1);
 
@@ -401,6 +406,10 @@
 	
 	ret = pam_winbind_request_log(pamh, ctrl, WINBINDD_PAM_AUTH, &request, &response, user);
 
+	if (pwd_last_set) {
+		*pwd_last_set = response.data.auth.info3.pass_last_set_time;
+	}
+
 	if ((ctrl & WINBIND_KRB5_AUTH) && 
 	    response.data.auth.krb5ccname[0] != '\0') {
 
@@ -487,7 +496,8 @@
 				     int ctrl,
 				     const char *user, 
 				     const char *oldpass,
-				     const char *newpass) 
+				     const char *newpass,
+				     time_t pwd_last_set) 
 {
 	struct winbindd_request request;
 	struct winbindd_response response;
@@ -541,8 +551,14 @@
 
 		/* FIXME: avoid to send multiple PAM messages after another */
 		switch (response.data.auth.reject_reason) {
-			case 0:
+			case -1:
 				break;
+			case REJECT_REASON_OTHER:
+				if ((response.data.auth.policy.min_passwordage > 0)) &&
+				    (pwd_last_set + response.data.auth.policy.min_passwordage > time(NULL)) {
+					PAM_WB_REMARK_DIRECT(pamh, "NT_STATUS_PWD_TOO_RECENT");
+				}
+				break;
 			case REJECT_REASON_TOO_SHORT:
 				PAM_WB_REMARK_DIRECT(pamh, "NT_STATUS_PWD_TOO_SHORT");
 				break;
@@ -892,7 +908,7 @@
 	cctype = get_krb5_cc_type_from_config(argc, argv, ctrl, d);
 
 	/* Now use the username to look up password */
-	retval = winbind_auth_request(pamh, ctrl, username, password, member, cctype, True);
+	retval = winbind_auth_request(pamh, ctrl, username, password, member, cctype, True, NULL);
 
 	if (retval == PAM_NEW_AUTHTOK_REQD ||
 	    retval == PAM_AUTHTOK_EXPIRED) {
@@ -1174,6 +1190,8 @@
 
 	if (flags & PAM_PRELIM_CHECK) {
 		
+		time_t pwdlastset_prelim = 0;
+		
 		/* instruct user what is happening */
 #define greeting "Changing password for "
 		Announce = (char *) malloc(sizeof(greeting) + strlen(user));
@@ -1198,16 +1216,18 @@
 		}
 		/* verify that this is the password for this user */
 		
-		retval = winbind_auth_request(pamh, ctrl, user, pass_old, NULL, NULL, False);
+		retval = winbind_auth_request(pamh, ctrl, user, pass_old, NULL, NULL, False, &pwdlastset_prelim);
 
-		if (retval != PAM_ACCT_EXPIRED 
-		    && retval != PAM_AUTHTOK_EXPIRED
-		    && retval != PAM_NEW_AUTHTOK_REQD 
-		    && retval != PAM_SUCCESS) {
+		if (retval != PAM_ACCT_EXPIRED && 
+		    retval != PAM_AUTHTOK_EXPIRED &&
+		    retval != PAM_NEW_AUTHTOK_REQD &&
+		    retval != PAM_SUCCESS) {
 			pass_old = NULL;
 			goto out;
 		}
 		
+		pam_set_data(pamh, PAM_WINBIND_PWD_LAST_SET, (void *)pwdlastset_prelim, _pam_winbind_cleanup_func);
+
 		retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
 		pass_old = NULL;
 		if (retval != PAM_SUCCESS) {
@@ -1215,6 +1235,8 @@
 		}
 	} else if (flags & PAM_UPDATE_AUTHTOK) {
 	
+		time_t pwdlastset_update = 0;
+		
 		/*
 		 * obtain the proposed password
 		 */
@@ -1272,8 +1294,9 @@
 		 * By reaching here we have approved the passwords and must now
 		 * rebuild the password database file.
 		 */
+		pam_get_data( pamh, PAM_WINBIND_PWD_LAST_SET, (const void **)&pwdlastset_update);
 
-		retval = winbind_chauthtok_request(pamh, ctrl, user, pass_old, pass_new);
+		retval = winbind_chauthtok_request(pamh, ctrl, user, pass_old, pass_new, pwdlastset_update);
 		if (retval) {
 			_pam_overwrite(pass_new);
 			_pam_overwrite(pass_old);
@@ -1288,7 +1311,7 @@
 			const char *member = get_member_from_config(argc, argv, ctrl, d);
 			const char *cctype = get_krb5_cc_type_from_config(argc, argv, ctrl, d);
 
-			retval = winbind_auth_request(pamh, ctrl, user, pass_new, member, cctype, False);
+			retval = winbind_auth_request(pamh, ctrl, user, pass_new, member, cctype, False, NULL);
 			_pam_overwrite(pass_new);
 			_pam_overwrite(pass_old);
 			pass_old = pass_new = NULL;

Modified: trunk/source/nsswitch/pam_winbind.h
===================================================================
--- trunk/source/nsswitch/pam_winbind.h	2006-05-02 19:20:49 UTC (rev 15397)
+++ trunk/source/nsswitch/pam_winbind.h	2006-05-02 19:22:39 UTC (rev 15398)
@@ -107,6 +107,7 @@
 
 #define PAM_WINBIND_NEW_AUTHTOK_REQD "PAM_WINBIND_NEW_AUTHTOK_REQD"
 #define PAM_WINBIND_HOMEDIR "PAM_WINBIND_HOMEDIR"
+#define PAM_WINBIND_PWD_LAST_SET "PAM_WINBIND_PWD_LAST_SET"
 
 #define SECONDS_PER_DAY 86400
 

Modified: trunk/source/nsswitch/winbindd_pam.c
===================================================================
--- trunk/source/nsswitch/winbindd_pam.c	2006-05-02 19:20:49 UTC (rev 15397)
+++ trunk/source/nsswitch/winbindd_pam.c	2006-05-02 19:22:39 UTC (rev 15398)
@@ -1652,6 +1652,9 @@
 	oldpass = state->request.data.chauthtok.oldpass;
 	newpass = state->request.data.chauthtok.newpass;
 
+	/* Initialize reject reason */
+	state->response.data.auth.reject_reason = Undefined;
+
 	/* Get sam handle */
 
 	result = cm_connect_sam(contact_domain, state->mem_ctx, &cli,
@@ -1690,8 +1693,6 @@
 		DEBUG(10,("Password change with chgpasswd3 failed with: %s, retrying chgpasswd_user\n", 
 			nt_errstr(result)));
 		
-		state->response.data.auth.reject_reason = 0;
-
 		result = rpccli_samr_chgpasswd_user(cli, state->mem_ctx, user, newpass, oldpass);
 	}
 



More information about the samba-cvs mailing list