diff options
Diffstat (limited to 'source3/utils/net_domain.c')
-rw-r--r-- | source3/utils/net_domain.c | 82 |
1 files changed, 41 insertions, 41 deletions
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 */ |