summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim McDonough <jmcd@samba.org>2007-06-26 20:09:41 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:23:36 -0500
commit9c3db7adf3efb7e485ac0a7301f31a1ab6338435 (patch)
tree43872efb41a9ca0ce4fe74c47bf52d12a258d01c
parent53637791023ec35f669244d7ea24ceaf6cf30d18 (diff)
downloadsamba-9c3db7adf3efb7e485ac0a7301f31a1ab6338435.tar.gz
samba-9c3db7adf3efb7e485ac0a7301f31a1ab6338435.tar.bz2
samba-9c3db7adf3efb7e485ac0a7301f31a1ab6338435.zip
r23616: Fix bugzilla #4719: must change password is not set from usrmgr.exe.
This was only affecting the newer versions of usrmgr.exe, because they use a user_info_25 struct. The password is getting set separately inside that code, so the password last set time was getting set from the password change logic. We also were not parsing a number of fields (like logon hours) from the user_info_25. That should also be fixed. (This used to be commit afabd68b6ae874aceba708dc36808ed007ad496c)
-rw-r--r--source3/include/rpc_samr.h15
-rw-r--r--source3/rpc_parse/parse_samr.c21
-rw-r--r--source3/rpc_server/srv_samr_nt.c9
-rw-r--r--source3/rpc_server/srv_samr_util.c43
4 files changed, 84 insertions, 4 deletions
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index 2d931e67fc..d34ecdb5fb 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -262,7 +262,19 @@ typedef struct sam_user_info_25
uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
uint32 fields_present;
- uint32 unknown_5[5];
+ uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
+ /* uint8 pad[2] */
+ uint32 ptr_logon_hrs; /* pointer to logon hours */
+
+ /* Was unknown_5. */
+ uint16 bad_password_count;
+ uint16 logon_count;
+
+ uint8 padding1[6];
+
+ uint8 passmustchange; /* 0x00 must change = 0x01 */
+
+ uint8 padding2;
uint8 pass[532];
@@ -276,6 +288,7 @@ typedef struct sam_user_info_25
UNISTR2 uni_workstations; /* login from workstations unicode string */
UNISTR2 uni_comment;
UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
+ LOGON_HRS logon_hrs;
} SAM_USER_INFO_25;
/* SAM_USER_INFO_26 */
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index e7726fbb26..1a4048e54b 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -6134,9 +6134,26 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str
if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present))
return False;
- if(!prs_uint32s(False, "unknown_5 ", ps, depth, usr->unknown_5, 5))
+ if(!prs_uint16("logon_divs ", ps, depth, &usr->logon_divs)) /* logon divisions per week */
+ return False;
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
+ return False;
+
+ if(!prs_uint16("bad_password_count ", ps, depth, &usr->bad_password_count))
+ return False;
+ if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count))
return False;
+ if(!prs_uint8s(False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1)))
+ return False;
+ if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
+ return False;
+ if(!prs_uint8("padding2 ", ps, depth, &usr->padding2))
+ return False;
+
+
if(!prs_uint8s(False, "password ", ps, depth, usr->pass, sizeof(usr->pass)))
return False;
@@ -6172,13 +6189,11 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str
if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth))
return False;
-#if 0 /* JRA - unknown... */
/* ok, this is only guess-work (as usual) */
if (usr->ptr_logon_hrs) {
if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
return False;
}
-#endif
return True;
}
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index b392f289a8..e28fc59136 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -3357,11 +3357,17 @@ static BOOL set_user_info_pw(uint8 *pass, struct samu *pwd)
uint32 len;
pstring plaintext_buf;
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);
ZERO_STRUCT(plaintext_buf);
@@ -3404,6 +3410,9 @@ static BOOL set_user_info_pw(uint8 *pass, struct samu *pwd)
ZERO_STRUCT(plaintext_buf);
+ /* 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"));
/* update the SAMBA password */
diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c
index 8acc1785ef..42ad462ee7 100644
--- a/source3/rpc_server/srv_samr_util.c
+++ b/source3/rpc_server/srv_samr_util.c
@@ -670,4 +670,47 @@ void copy_id25_to_sam_passwd(struct samu *to, SAM_USER_INFO_25 *from)
pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
}
}
+
+ if (from->fields_present & ACCT_LOGON_HOURS) {
+ DEBUG(15,("INFO_25 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
+ if (from->logon_divs != pdb_get_logon_divs(to)) {
+ pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
+ }
+
+ DEBUG(15,("INFO_25 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
+ if (from->logon_hrs.len != pdb_get_hours_len(to)) {
+ pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
+ }
+
+ DEBUG(15,("INFO_25 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
+ /* Fix me: only update if it changes --metze */
+ pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
+ }
+
+ if (from->fields_present & ACCT_BAD_PWD_COUNT) {
+ DEBUG(10,("INFO_25 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
+ if (from->bad_password_count != pdb_get_bad_password_count(to)) {
+ pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
+ }
+ }
+
+ if (from->fields_present & ACCT_NUM_LOGONS) {
+ DEBUG(10,("INFO_25 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
+ if (from->logon_count != pdb_get_logon_count(to)) {
+ pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
+ }
+ }
+
+ /* If the must change flag is set, the last set time goes to zero.
+ the must change and can change fields also do, but they are
+ calculated from policy, not set from the wire */
+
+ if (from->fields_present & ACCT_EXPIRED_FLAG) {
+ DEBUG(10,("INFO_25 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
+ if (from->passmustchange == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+ pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
+ } else {
+ pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
+ }
+ }
}