[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-603-g842edcd

Günther Deschner gd at samba.org
Fri Mar 20 09:41:27 GMT 2009


The branch, master has been updated
       via  842edcd2b08763a35dbdea3518fcc039aa70aad4 (commit)
      from  da46c371006d7cb5bceba790070d805b303ade98 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 842edcd2b08763a35dbdea3518fcc039aa70aad4
Author: Günther Deschner <gd at samba.org>
Date:   Thu Nov 27 17:49:25 2008 +0100

    s3-samr: try to to fix password_expired flag handling.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h            |    6 ++
 source3/rpc_server/srv_samr_nt.c   |  120 +++++++++++++++++++++---------------
 source3/rpc_server/srv_samr_util.c |   87 +++++++++++++++++++++++++-
 3 files changed, 161 insertions(+), 52 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 3d87f75..d815448 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5898,6 +5898,8 @@ NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread,
 
 /* The following definitions come from rpc_server/srv_samr_util.c  */
 
+void copy_id18_to_sam_passwd(struct samu *to,
+			     struct samr_UserInfo18 *from);
 void copy_id20_to_sam_passwd(struct samu *to,
 			     struct samr_UserInfo20 *from);
 void copy_id21_to_sam_passwd(const char *log_prefix,
@@ -5905,8 +5907,12 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
 			     struct samr_UserInfo21 *from);
 void copy_id23_to_sam_passwd(struct samu *to,
 			     struct samr_UserInfo23 *from);
+void copy_id24_to_sam_passwd(struct samu *to,
+			     struct samr_UserInfo24 *from);
 void copy_id25_to_sam_passwd(struct samu *to,
 			     struct samr_UserInfo25 *from);
+void copy_id26_to_sam_passwd(struct samu *to,
+			     struct samr_UserInfo26 *from);
 
 /* The following definitions come from rpc_server/srv_spoolss_nt.c  */
 
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index dcbd096..c60d904 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -3636,12 +3636,7 @@ static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18,
 		pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
 	}
 
-	if (id18->password_expired) {
-		pdb_set_pass_last_set_time(pwd, 0, PDB_CHANGED);
-	} else {
-		/* FIXME */
-		pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED);
-	}
+	copy_id18_to_sam_passwd(pwd, id18);
 
 	return pdb_update_sam_account(pwd);
 }
@@ -3848,23 +3843,16 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx,
  set_user_info_pw
  ********************************************************************/
 
-static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
-			     int level)
+static bool set_user_info_pw(uint8 *pass, struct samu *pwd)
 {
 	uint32 len = 0;
 	char *plaintext_buf = NULL;
 	uint32 acct_ctrl;
-	time_t last_set_time;
-	enum pdb_value_state last_set_state;
 
 	DEBUG(5, ("Attempting administrator password change for user %s\n",
 		  pdb_get_username(pwd)));
 
 	acct_ctrl = pdb_get_acct_ctrl(pwd);
-	/* we need to know if it's expired, because this is an admin change, not a
-	   user change, so it's still expired when we're done */
-	last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
-	last_set_time = pdb_get_pass_last_set_time(pwd);
 
 	if (!decode_pw_buffer(talloc_tos(),
 				pass,
@@ -3907,29 +3895,38 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd,
 
 	memset(plaintext_buf, '\0', strlen(plaintext_buf));
 
-	/*
-	 * A level 25 change does reset the pwdlastset field, a level 24
-	 * change does not. I know this is probably not the full story, but
-	 * it is needed to make XP join LDAP correctly, without it the later
-	 * auth2 check can fail with PWD_MUST_CHANGE.
-	 */
-	if (level != 25) {
-		/*
-		 * restore last set time as this is an admin change, not a
-		 * user pw change
-		 */
-		pdb_set_pass_last_set_time (pwd, last_set_time,
-					    last_set_state);
+	DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
+
+	return True;
+}
+
+/*******************************************************************
+ set_user_info_24
+ ********************************************************************/
+
+static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx,
+				 struct samr_UserInfo24 *id24,
+				 struct samu *pwd)
+{
+	NTSTATUS status;
+
+	if (id24 == NULL) {
+		DEBUG(5, ("set_user_info_24: NULL id24\n"));
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
+	if (!set_user_info_pw(id24->password.data, pwd)) {
+		return NT_STATUS_WRONG_PASSWORD;
+	}
 
-	/* update the SAMBA password */
-	if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
-		return False;
+	copy_id24_to_sam_passwd(pwd, id24);
+
+	status = pdb_update_sam_account(pwd);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
  	}
 
-	return True;
+	return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -3955,6 +3952,14 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
+	if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) ||
+	    (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) {
+
+		if (!set_user_info_pw(id25->password.data, pwd)) {
+			return NT_STATUS_WRONG_PASSWORD;
+		}
+	}
+
 	copy_id25_to_sam_passwd(pwd, id25);
 
 	/* write the change out */
@@ -3981,6 +3986,36 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx,
 }
 
 /*******************************************************************
+ set_user_info_26
+ ********************************************************************/
+
+static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx,
+				 struct samr_UserInfo26 *id26,
+				 struct samu *pwd)
+{
+	NTSTATUS status;
+
+	if (id26 == NULL) {
+		DEBUG(5, ("set_user_info_26: NULL id26\n"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (!set_user_info_pw(id26->password.data, pwd)) {
+		return NT_STATUS_WRONG_PASSWORD;
+	}
+
+	copy_id26_to_sam_passwd(pwd, id26);
+
+	status = pdb_update_sam_account(pwd);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	return NT_STATUS_OK;
+}
+
+
+/*******************************************************************
  samr_SetUserInfo
  ********************************************************************/
 
@@ -4139,10 +4174,8 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 
 			dump_data(100, info->info24.password.data, 516);
 
-			if (!set_user_info_pw(info->info24.password.data, pwd,
-					      switch_value)) {
-				status = NT_STATUS_WRONG_PASSWORD;
-			}
+			status = set_user_info_24(p->mem_ctx,
+						  &info->info24, pwd);
 			break;
 
 		case 25:
@@ -4157,13 +4190,6 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 
 			status = set_user_info_25(p->mem_ctx,
 						  &info->info25, pwd);
-			if (!NT_STATUS_IS_OK(status)) {
-				goto done;
-			}
-			if (!set_user_info_pw(info->info25.password.data, pwd,
-					      switch_value)) {
-				status = NT_STATUS_WRONG_PASSWORD;
-			}
 			break;
 
 		case 26:
@@ -4176,18 +4202,14 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
 
 			dump_data(100, info->info26.password.data, 516);
 
-			if (!set_user_info_pw(info->info26.password.data, pwd,
-					      switch_value)) {
-				status = NT_STATUS_WRONG_PASSWORD;
-			}
+			status = set_user_info_26(p->mem_ctx,
+						  &info->info26, pwd);
 			break;
 
 		default:
 			status = NT_STATUS_INVALID_INFO_CLASS;
 	}
 
- done:
-
 	TALLOC_FREE(pwd);
 
 	if (has_enough_rights) {
diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c
index ef588ae..0681560 100644
--- a/source3/rpc_server/srv_samr_util.c
+++ b/source3/rpc_server/srv_samr_util.c
@@ -36,6 +36,27 @@
 		((s1) && (s2) && (strcmp((s1), (s2)) != 0))
 
 /*************************************************************
+ Copies a struct samr_UserInfo18 to a struct samu
+**************************************************************/
+
+void copy_id18_to_sam_passwd(struct samu *to,
+			     struct samr_UserInfo18 *from)
+{
+	struct samr_UserInfo21 i;
+
+	if (from == NULL || to == NULL) {
+		return;
+	}
+
+	ZERO_STRUCT(i);
+
+	i.fields_present	= SAMR_FIELD_EXPIRED_FLAG;
+	i.password_expired	= from->password_expired;
+
+	copy_id21_to_sam_passwd("INFO_18", to, &i);
+}
+
+/*************************************************************
  Copies a struct samr_UserInfo20 to a struct samu
 **************************************************************/
 
@@ -336,7 +357,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
 	if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) {
 		DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l,
 			from->password_expired));
-		if (from->password_expired == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+		if (from->password_expired != 0) {
 			pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
 		} else {
 			/* A subtlety here: some windows commands will
@@ -345,9 +366,27 @@ void copy_id21_to_sam_passwd(const char *log_prefix,
 			   in these caess.  "net user /dom <user> /active:y"
 			   for example, to clear an autolocked acct.
 			   We must check to see if it's expired first. jmcd */
+
+			uint32_t pwd_max_age = 0;
+			time_t now = time(NULL);
+
+			pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age);
+
+			if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) {
+				pwd_max_age = get_time_t_max();
+			}
+
 			stored_time = pdb_get_pass_last_set_time(to);
-			if (stored_time == 0)
-				pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
+
+			/* we will only *set* a pwdlastset date when
+			   a) the last pwdlastset time was 0 (user was forced to
+			      change password).
+			   b) the users password has not expired. gd. */
+
+			if ((stored_time == 0) ||
+			    ((now - stored_time) > pwd_max_age)) {
+				pdb_set_pass_last_set_time(to, now, PDB_CHANGED);
+			}
 		}
 	}
 }
@@ -368,6 +407,27 @@ void copy_id23_to_sam_passwd(struct samu *to,
 }
 
 /*************************************************************
+ Copies a struct samr_UserInfo24 to a struct samu
+**************************************************************/
+
+void copy_id24_to_sam_passwd(struct samu *to,
+			     struct samr_UserInfo24 *from)
+{
+	struct samr_UserInfo21 i;
+
+	if (from == NULL || to == NULL) {
+		return;
+	}
+
+	ZERO_STRUCT(i);
+
+	i.fields_present	= SAMR_FIELD_EXPIRED_FLAG;
+	i.password_expired	= from->password_expired;
+
+	copy_id21_to_sam_passwd("INFO_24", to, &i);
+}
+
+/*************************************************************
  Copies a struct samr_UserInfo25 to a struct samu
 **************************************************************/
 
@@ -380,3 +440,24 @@ void copy_id25_to_sam_passwd(struct samu *to,
 
 	copy_id21_to_sam_passwd("INFO_25", to, &from->info);
 }
+
+/*************************************************************
+ Copies a struct samr_UserInfo26 to a struct samu
+**************************************************************/
+
+void copy_id26_to_sam_passwd(struct samu *to,
+			     struct samr_UserInfo26 *from)
+{
+	struct samr_UserInfo21 i;
+
+	if (from == NULL || to == NULL) {
+		return;
+	}
+
+	ZERO_STRUCT(i);
+
+	i.fields_present	= SAMR_FIELD_EXPIRED_FLAG;
+	i.password_expired	= from->password_expired;
+
+	copy_id21_to_sam_passwd("INFO_26", to, &i);
+}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list