diff options
author | Rafal Szczesniak <mimir@samba.org> | 2007-08-29 11:02:04 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:30:19 -0500 |
commit | a0a32cf5d520937f492d32c743011741522f2d40 (patch) | |
tree | 43b6640339e99e522df8084b12adb2b5c0da1bd6 | |
parent | 60fb367fd94c19889ec4909b23c3e21dcda2e7d5 (diff) | |
download | samba-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)
-rw-r--r-- | source3/rpc_parse/parse_samr.c | 19 | ||||
-rw-r--r-- | source3/utils/net_domain.c | 82 |
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 */ |