Author: mimir Date: 2007-08-29 10:42:53 +0000 (Wed, 29 Aug 2007) New Revision: 24770
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24770 Log: Use infolevel 25 to set the machine account's password (just like winxp). This correctly updates pwdLastSet field on win2k3 server. rafal Modified: branches/SAMBA_3_0/source/rpc_parse/parse_samr.c branches/SAMBA_3_0/source/utils/net_domain.c Changeset: Modified: branches/SAMBA_3_0/source/rpc_parse/parse_samr.c =================================================================== --- branches/SAMBA_3_0/source/rpc_parse/parse_samr.c 2007-08-29 10:12:43 UTC (rev 24769) +++ branches/SAMBA_3_0/source/rpc_parse/parse_samr.c 2007-08-29 10:42:53 UTC (rev 24770) @@ -5940,6 +5940,25 @@ } } + +/************************************************************************* + 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. ********************************************************************/ Modified: branches/SAMBA_3_0/source/utils/net_domain.c =================================================================== --- branches/SAMBA_3_0/source/utils/net_domain.c 2007-08-29 10:12:43 UTC (rev 24769) +++ branches/SAMBA_3_0/source/utils/net_domain.c 2007-08-29 10:42:53 UTC (rev 24770) @@ -209,10 +209,14 @@ 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 */ @@ -283,24 +287,49 @@ status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol, SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - /* Create a random machine account password */ + /* Create a random machine account password and generate the hash */ - E_md4hash( clear_pw, md4_trust_password); + 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)); - /* Set password on machine account */ + /* Fill in the additional account flags now */ + acb_info |= ACB_PWNOEXP; + if ( dom_type == ND_TYPE_AD ) { +#if !defined(ENCTYPE_ARCFOUR_HMAC) + acb_info |= ACB_USE_DES_KEY_ONLY; +#endif + ;; + } + + /* Set password and account flags on machine account */ + ZERO_STRUCT(ctr); - ZERO_STRUCT(p24); + ZERO_STRUCT(p25); - init_sam_user_info24(&p24, (char *)pwbuf,24); + 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 = 24; - ctr.info.id24 = &p24; + ctr.switch_value = infolevel; + ctr.info.id25 = &p25; - status = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol, - 24, &cli->user_session_key, &ctr); + 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", @@ -308,35 +337,6 @@ return status; } - - /* 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; - - /* Fill in the additional account flags now */ - - acb_info |= ACB_PWNOEXP; - if ( dom_type == ND_TYPE_AD ) { -#if !defined(ENCTYPE_ARCFOUR_HMAC) - acb_info |= ACB_USE_DES_KEY_ONLY; -#endif - ;; - } - - init_sam_user_info16(&p16, acb_info); - - status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16, - &cli->user_session_key, &ctr); - rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol); cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */