From: Rafal Szczesniak Date: Wed, 29 Aug 2007 11:02:04 +0000 (+0000) Subject: r24771: Use infolevel 25 to set the machine account's password (just like winxp). X-Git-Tag: release-3-0-28a~35 X-Git-Url: http://git.samba.org/samba.git/?p=tprouty%2Fsamba.git;a=commitdiff_plain;h=2ced9b906fe9044edf6efbca6175aa481c2a4451 r24771: Use infolevel 25 to set the machine account's password (just like winxp). This correctly updates pwdLastSet field on win2k3 server. rafal --- diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c index 0d83e454ef..d452c1fe82 100644 --- a/source/rpc_parse/parse_samr.c +++ b/source/rpc_parse/parse_samr.c @@ -5870,6 +5870,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/source/utils/net_domain.c b/source/utils/net_domain.c index ac7e0dad73..533bb9c698 100644 --- a/source/utils/net_domain.c +++ b/source/utils/net_domain.c @@ -210,10 +210,14 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli, uint32 flags = 0x3e8; uint32 acb_info = ACB_WSTRUST; uint32 acct_flags=0; - 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 */ @@ -289,44 +293,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 */ @@ -338,10 +323,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 */