From 542729273c2356abe3637bd65463a20b87b11404 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 28 Nov 2006 17:30:43 +0000 Subject: r19934: - allow to pass a samr_UserInfo21 struct to be passed to libnet_SetPassword() - as the SetUserInfo2() levels 26/25 and 24/23 have the same encryption but 26 and 24 change only the password and 25 and 23 take a info21 and change the password, we now use 26 with fallback to 24 or 25 with fallback to 23. - use samr_SetUserInfo2() to match what w2k3 does (works also against nt4) - pass the info21 to libnet_SetPassword() to set acct_flags and full_name together with the password (to match what w2k3 does) metze (This used to be commit 1b86af32f3069cc75ae645698d3f92a0798e38f7) --- source4/libnet/libnet_join.c | 36 ++++++-------------- source4/libnet/libnet_passwd.c | 76 ++++++++++++++++++++++++++---------------- source4/libnet/libnet_passwd.h | 4 +++ 3 files changed, 63 insertions(+), 53 deletions(-) (limited to 'source4/libnet') diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index ed98699804..8e3753065e 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -408,9 +408,9 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J * - potentially delete and recreate the user * - assert the account is of the right type with samrQueryUserInfo * - * - call libnet_SetPassword_samr_handle to set the password + * - call libnet_SetPassword_samr_handle to set the password, + * and pass a samr_UserInfo21 struct to set full_name and the account flags * - * - do a samrSetUserInfo to set the account flags * - do some ADS specific things when we join as Domain Controller, * look at libnet_joinADSDomain() for the details */ @@ -432,8 +432,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct samr_CreateUser2 cu; struct policy_handle *u_handle = NULL; struct samr_QueryUserInfo qui; - struct samr_SetUserInfo sui; - union samr_UserInfo u_info; + struct samr_UserInfo21 u_info21; union libnet_SetPassword r2; struct samr_GetUserPwInfo pwp; struct lsa_String samr_account_name; @@ -756,7 +755,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru acct_flags = qui.out.info->info16.acct_flags; } - acct_flags = (acct_flags & ~ACB_DISABLED); + acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ)); /* Find out what password policy this user has */ pwp.in.user_handle = u_handle; @@ -770,11 +769,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru password_str = generate_random_str(tmp_ctx, MAX(8, policy_min_pw_len)); + /* set full_name and reset flags */ + ZERO_STRUCT(u_info21); + u_info21.full_name.string = r->in.account_name; + u_info21.acct_flags = acct_flags; + u_info21.fields_present = SAMR_FIELD_FULL_NAME | SAMR_FIELD_ACCT_FLAGS; + r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE; r2.samr_handle.in.account_name = r->in.account_name; r2.samr_handle.in.newpassword = password_str; r2.samr_handle.in.user_handle = u_handle; r2.samr_handle.in.dcerpc_pipe = samr_pipe; + r2.samr_handle.in.info21 = &u_info21; status = libnet_SetPassword(ctx, tmp_ctx, &r2); if (!NT_STATUS_IS_OK(status)) { @@ -783,26 +789,6 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - /* reset flags (if required) */ - if (acct_flags != qui.out.info->info16.acct_flags) { - ZERO_STRUCT(u_info); - u_info.info16.acct_flags = acct_flags; - - sui.in.user_handle = u_handle; - sui.in.info = &u_info; - sui.in.level = 16; - - dcerpc_samr_SetUserInfo(samr_pipe, tmp_ctx, &sui); - if (!NT_STATUS_IS_OK(status)) { - r->out.error_string = talloc_asprintf(mem_ctx, - "samr_SetUserInfo for [%s] failed to remove ACB_DISABLED flag: %s", - r->in.account_name, - nt_errstr(status)); - talloc_free(tmp_ctx); - return status; - } - } - account_sid = dom_sid_add_rid(mem_ctx, connect_with_info->out.domain_sid, rid); if (!account_sid) { r->out.error_string = NULL; diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c index 050299f68a..483be7502d 100644 --- a/source4/libnet/libnet_passwd.c +++ b/source4/libnet/libnet_passwd.c @@ -290,14 +290,18 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { NTSTATUS status; - struct samr_SetUserInfo sui; + struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; DATA_BLOB session_key; DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); uint8_t confounder[16]; struct MD5Context md5; - /* prepare samr_SetUserInfo level 26 */ + if (r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + /* prepare samr_SetUserInfo2 level 26 */ ZERO_STRUCT(u_info); encode_pw_buffer(u_info.info26.password.data, r->samr_handle.in.newpassword, STR_UNICODE); u_info.info26.pw_len = strlen(r->samr_handle.in.newpassword); @@ -324,13 +328,13 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA sui.in.info = &u_info; sui.in.level = 26; - /* 7. try samr_SetUserInfo level 26 to set the password */ - status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); - /* check result of samr_SetUserInfo level 26 */ + /* 7. try samr_SetUserInfo2 level 26 to set the password */ + status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); + /* check result of samr_SetUserInfo2 level 26 */ if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "SetUserInfo level 26 for [%s] failed: %s", + "SetUserInfo2 level 26 for [%s] failed: %s", r->samr_handle.in.account_name, nt_errstr(status)); } return status; @@ -339,16 +343,21 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { NTSTATUS status; - struct samr_SetUserInfo sui; + struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; DATA_BLOB session_key; DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); uint8_t confounder[16]; struct MD5Context md5; - /* prepare samr_SetUserInfo level 25 */ + if (!r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + /* prepare samr_SetUserInfo2 level 25 */ ZERO_STRUCT(u_info); - u_info.info25.info.fields_present = SAMR_FIELD_PASSWORD; + u_info.info25.info = *r->samr_handle.in.info21; + u_info.info25.info.fields_present |= SAMR_FIELD_PASSWORD; encode_pw_buffer(u_info.info25.password.data, r->samr_handle.in.newpassword, STR_UNICODE); status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); @@ -373,12 +382,12 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA sui.in.info = &u_info; sui.in.level = 25; - /* 8. try samr_SetUserInfo level 25 to set the password */ - status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); + /* 8. try samr_SetUserInfo2 level 25 to set the password */ + status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "SetUserInfo level 25 for [%s] failed: %s", + "SetUserInfo2 level 25 for [%s] failed: %s", r->samr_handle.in.account_name, nt_errstr(status)); } return status; @@ -387,11 +396,15 @@ static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TA static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { NTSTATUS status; - struct samr_SetUserInfo sui; + struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; DATA_BLOB session_key; - /* prepare samr_SetUserInfo level 24 */ + if (r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + /* prepare samr_SetUserInfo2 level 24 */ ZERO_STRUCT(u_info); encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE); /* w2k3 ignores this length */ @@ -411,12 +424,12 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA sui.in.info = &u_info; sui.in.level = 24; - /* 9. try samr_SetUserInfo level 24 to set the password */ - status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); + /* 9. try samr_SetUserInfo2 level 24 to set the password */ + status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "SetUserInfo level 24 for [%s] failed: %s", + "SetUserInfo2 level 24 for [%s] failed: %s", r->samr_handle.in.account_name, nt_errstr(status)); } return status; @@ -425,13 +438,18 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { NTSTATUS status; - struct samr_SetUserInfo sui; + struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; DATA_BLOB session_key; - /* prepare samr_SetUserInfo level 23 */ + if (!r->samr_handle.in.info21) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + /* prepare samr_SetUserInfo2 level 23 */ ZERO_STRUCT(u_info); - u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD; + u_info.info23.info = *r->samr_handle.in.info21; + u_info.info23.info.fields_present |= SAMR_FIELD_PASSWORD; encode_pw_buffer(u_info.info23.password.data, r->samr_handle.in.newpassword, STR_UNICODE); status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); @@ -449,25 +467,26 @@ static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TA sui.in.info = &u_info; sui.in.level = 23; - /* 10. try samr_SetUserInfo level 23 to set the password */ - status = dcerpc_samr_SetUserInfo(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); + /* 10. try samr_SetUserInfo2 level 23 to set the password */ + status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, - "SetUserInfo level 23 for [%s] failed: %s", + "SetUserInfo2 level 23 for [%s] failed: %s", r->samr_handle.in.account_name, nt_errstr(status)); } return status; } /* - * 1. try samr_SetUserInfo level 26 to set the password - * 2. try samr_SetUserInfo level 25 to set the password - * 3. try samr_SetUserInfo level 24 to set the password - * 4. try samr_SetUserInfo level 23 to set the password + * 1. try samr_SetUserInfo2 level 26 to set the password + * 2. try samr_SetUserInfo2 level 25 to set the password + * 3. try samr_SetUserInfo2 level 24 to set the password + * 4. try samr_SetUserInfo2 level 23 to set the password */ static NTSTATUS libnet_SetPassword_samr_handle(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r) { + NTSTATUS status; enum libnet_SetPassword_level levels[] = { LIBNET_SET_PASSWORD_SAMR_HANDLE_26, @@ -476,11 +495,12 @@ static NTSTATUS libnet_SetPassword_samr_handle(struct libnet_context *ctx, TALLO LIBNET_SET_PASSWORD_SAMR_HANDLE_23, }; int i; - + for (i=0; i < ARRAY_SIZE(levels); i++) { r->generic.level = levels[i]; status = libnet_SetPassword(ctx, mem_ctx, r); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) + || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER_MIX) || NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { /* Try another password set mechanism */ continue; diff --git a/source4/libnet/libnet_passwd.h b/source4/libnet/libnet_passwd.h index d7b284cb74..52a392f1d6 100644 --- a/source4/libnet/libnet_passwd.h +++ b/source4/libnet/libnet_passwd.h @@ -104,6 +104,10 @@ union libnet_SetPassword { struct policy_handle *user_handle; struct dcerpc_pipe *dcerpc_pipe; const char *newpassword; + struct samr_UserInfo21 *info21; /* can be NULL, + * for level 26,24 it must be NULL + * for level 25,23 it must be non-NULL + */ } in; struct _libnet_SetPassword_out out; } samr_handle; -- cgit