summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafal Szczesniak <mimir@samba.org>2007-08-29 11:02:04 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:30:19 -0500
commita0a32cf5d520937f492d32c743011741522f2d40 (patch)
tree43b6640339e99e522df8084b12adb2b5c0da1bd6
parent60fb367fd94c19889ec4909b23c3e21dcda2e7d5 (diff)
downloadsamba-a0a32cf5d520937f492d32c743011741522f2d40.tar.gz
samba-a0a32cf5d520937f492d32c743011741522f2d40.tar.xz
samba-a0a32cf5d520937f492d32c743011741522f2d40.zip
r24771: Use infolevel 25 to set the machine account's password (just like winxp).
This correctly updates pwdLastSet field on win2k3 server. rafal (This used to be commit dd6d44c1665121cff9ccc2c09580169ca4d330b9)
-rw-r--r--source3/rpc_parse/parse_samr.c19
-rw-r--r--source3/utils/net_domain.c82
2 files changed, 60 insertions, 41 deletions
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index 90f1a2243ba..ddbe0a6255f 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -5930,6 +5930,25 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
}
}
+
+/*************************************************************************
+ init_samr_user_info25P
+ fields_present = ACCT_NT_PWD_SET | ACCT_LM_PWD_SET | ACCT_FLAGS
+*************************************************************************/
+
+void init_sam_user_info25P(SAM_USER_INFO_25 * usr,
+ uint32 fields_present, uint32 acb_info,
+ char newpass[532])
+{
+ usr->fields_present = fields_present;
+ ZERO_STRUCT(usr->padding1);
+ ZERO_STRUCT(usr->padding2);
+
+ usr->acb_info = acb_info;
+ memcpy(usr->pass, newpass, sizeof(usr->pass));
+}
+
+
/*******************************************************************
reads or writes a structure.
********************************************************************/
diff --git a/source3/utils/net_domain.c b/source3/utils/net_domain.c
index 0c9b5ad5714..3f1908e242d 100644
--- a/source3/utils/net_domain.c
+++ b/source3/utils/net_domain.c
@@ -208,10 +208,14 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
uint32 num_rids, *name_types, *user_rids;
uint32 flags = 0x3e8;
uint32 acb_info = ACB_WSTRUST;
- uchar pwbuf[516];
+ uint32 fields_present;
+ uchar pwbuf[532];
SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_24 p24;
- SAM_USER_INFO_16 p16;
+ SAM_USER_INFO_25 p25;
+ const int infolevel = 25;
+ struct MD5Context md5ctx;
+ uchar md5buffer[16];
+ DATA_BLOB digested_session_key;
uchar md4_trust_password[16];
/* Open the domain */
@@ -282,44 +286,25 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
-
- /* Create a random machine account password */
-
- E_md4hash( clear_pw, md4_trust_password);
- encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE);
-
- /* Set password on machine account */
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(p24);
-
- init_sam_user_info24(&p24, (char *)pwbuf,24);
-
- ctr.switch_value = 24;
- ctr.info.id24 = &p24;
-
- status = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
- 24, &cli->user_session_key, &ctr);
-
- if ( !NT_STATUS_IS_OK(status) ) {
- d_fprintf( stderr, "Failed to set password for machine account (%s)\n",
- nt_errstr(status));
+ if (!NT_STATUS_IS_OK(status)) {
return status;
}
+
+ /* Create a random machine account password and generate the hash */
-
- /* Why do we have to try to (re-)set the ACB to be the same as what
- we passed in the samr_create_dom_user() call? When a NT
- workstation is joined to a domain by an administrator the
- acb_info is set to 0x80. For a normal user with "Add
- workstations to the domain" rights the acb_info is 0x84. I'm
- not sure whether it is supposed to make a difference or not. NT
- seems to cope with either value so don't bomb out if the set
- userinfo2 level 0x10 fails. -tpot */
-
- ZERO_STRUCT(ctr);
- ctr.switch_value = 16;
- ctr.info.id16 = &p16;
+ E_md4hash(clear_pw, md4_trust_password);
+ encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE);
+
+ generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer));
+ digested_session_key = data_blob_talloc(mem_ctx, 0, 16);
+
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, md5buffer, sizeof(md5buffer));
+ MD5Update(&md5ctx, cli->user_session_key.data, cli->user_session_key.length);
+ MD5Final(digested_session_key.data, &md5ctx);
+
+ SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key);
+ memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer));
/* Fill in the additional account flags now */
@@ -331,10 +316,25 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
;;
}
- init_sam_user_info16(&p16, acb_info);
+ /* Set password and account flags on machine account */
- status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16,
- &cli->user_session_key, &ctr);
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(p25);
+
+ fields_present = ACCT_NT_PWD_SET | ACCT_LM_PWD_SET | ACCT_FLAGS;
+ init_sam_user_info25P(&p25, fields_present, acb_info, (char *)pwbuf);
+
+ ctr.switch_value = infolevel;
+ ctr.info.id25 = &p25;
+
+ status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol,
+ infolevel, &cli->user_session_key, &ctr);
+
+ if ( !NT_STATUS_IS_OK(status) ) {
+ d_fprintf( stderr, "Failed to set password for machine account (%s)\n",
+ nt_errstr(status));
+ return status;
+ }
rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */