mirror of
https://github.com/samba-team/samba.git
synced 2025-11-28 12:23:49 +03:00
r24771: Use infolevel 25 to set the machine account's password (just like winxp).
This correctly updates pwdLastSet field on win2k3 server. rafal
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
b83626676c
commit
dd6d44c166
@@ -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.
|
reads or writes a structure.
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|||||||
@@ -208,10 +208,14 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
|
|||||||
uint32 num_rids, *name_types, *user_rids;
|
uint32 num_rids, *name_types, *user_rids;
|
||||||
uint32 flags = 0x3e8;
|
uint32 flags = 0x3e8;
|
||||||
uint32 acb_info = ACB_WSTRUST;
|
uint32 acb_info = ACB_WSTRUST;
|
||||||
uchar pwbuf[516];
|
uint32 fields_present;
|
||||||
|
uchar pwbuf[532];
|
||||||
SAM_USERINFO_CTR ctr;
|
SAM_USERINFO_CTR ctr;
|
||||||
SAM_USER_INFO_24 p24;
|
SAM_USER_INFO_25 p25;
|
||||||
SAM_USER_INFO_16 p16;
|
const int infolevel = 25;
|
||||||
|
struct MD5Context md5ctx;
|
||||||
|
uchar md5buffer[16];
|
||||||
|
DATA_BLOB digested_session_key;
|
||||||
uchar md4_trust_password[16];
|
uchar md4_trust_password[16];
|
||||||
|
|
||||||
/* Open the domain */
|
/* 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,
|
status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
|
||||||
SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
|
SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
/* 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));
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create a random machine account password and generate the hash */
|
||||||
|
|
||||||
|
E_md4hash(clear_pw, md4_trust_password);
|
||||||
/* Why do we have to try to (re-)set the ACB to be the same as what
|
encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE);
|
||||||
we passed in the samr_create_dom_user() call? When a NT
|
|
||||||
workstation is joined to a domain by an administrator the
|
generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer));
|
||||||
acb_info is set to 0x80. For a normal user with "Add
|
digested_session_key = data_blob_talloc(mem_ctx, 0, 16);
|
||||||
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
|
MD5Init(&md5ctx);
|
||||||
seems to cope with either value so don't bomb out if the set
|
MD5Update(&md5ctx, md5buffer, sizeof(md5buffer));
|
||||||
userinfo2 level 0x10 fails. -tpot */
|
MD5Update(&md5ctx, cli->user_session_key.data, cli->user_session_key.length);
|
||||||
|
MD5Final(digested_session_key.data, &md5ctx);
|
||||||
ZERO_STRUCT(ctr);
|
|
||||||
ctr.switch_value = 16;
|
SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key);
|
||||||
ctr.info.id16 = &p16;
|
memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer));
|
||||||
|
|
||||||
/* Fill in the additional account flags now */
|
/* 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,
|
ZERO_STRUCT(ctr);
|
||||||
&cli->user_session_key, &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);
|
rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
|
||||||
cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
|
cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
|
||||||
|
|||||||
Reference in New Issue
Block a user