summaryrefslogtreecommitdiff
path: root/source3
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 /source3
parent60fb367fd94c19889ec4909b23c3e21dcda2e7d5 (diff)
downloadsamba-a0a32cf5d520937f492d32c743011741522f2d40.tar.gz
samba-a0a32cf5d520937f492d32c743011741522f2d40.tar.bz2
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)
Diffstat (limited to 'source3')
-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 90f1a2243b..ddbe0a6255 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 0c9b5ad571..3f1908e242 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 */