X-Git-Url: http://git.samba.org/samba.git/?p=jra%2Fsamba%2F.git;a=blobdiff_plain;f=source3%2Flibnet%2Flibnet_join.c;h=51d979074b65ba99b8594bb004d6ca51bd01a735;hp=6935e000dc224b44c609bb6cdab61f4ad8227286;hb=aaea68791cfea45c6fa69abc93ad6d0e832d0283;hpb=694a579cb8d418a4feb441a77c0dc000023f2c6e diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 6935e000dc2..51d979074b6 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -762,7 +762,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, struct lsa_String lsa_acct_name; uint32_t user_rid; uint32_t acct_flags = ACB_WSTRUST; - uchar md4_trust_password[16]; struct samr_Ids user_rids; struct samr_Ids name_types; union samr_UserInfo user_info; @@ -898,14 +897,6 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, goto done; } - /* Create a random machine account password and generate the hash */ - - E_md4hash(r->in.machine_password, md4_trust_password); - - init_samr_CryptPasswordEx(r->in.machine_password, - &cli->user_session_key, - &crypt_pwd_ex); - /* Fill in the additional account flags now */ acct_flags |= ACB_PWNOEXP; @@ -916,23 +907,40 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, ;; } - /* Set password and account flags on machine account */ - - ZERO_STRUCT(user_info.info25); - - user_info.info25.info.fields_present = ACCT_NT_PWD_SET | - ACCT_LM_PWD_SET | - SAMR_FIELD_ACCT_FLAGS; - - user_info.info25.info.acct_flags = acct_flags; - memcpy(&user_info.info25.password.data, crypt_pwd_ex.data, - sizeof(crypt_pwd_ex.data)); + /* Set account flags on machine account */ + ZERO_STRUCT(user_info.info16); + user_info.info16.acct_flags = acct_flags; status = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, &user_pol, - 25, + 16, &user_info); + if (!NT_STATUS_IS_OK(status)) { + + rpccli_samr_DeleteUser(pipe_hnd, mem_ctx, + &user_pol); + + libnet_join_set_error_string(mem_ctx, r, + "Failed to set account flags for machine account (%s)\n", + nt_errstr(status)); + goto done; + } + + /* Set password on machine account - first try level 26 */ + + init_samr_CryptPasswordEx(r->in.machine_password, + &cli->user_session_key, + &crypt_pwd_ex); + + init_samr_user_info26(&user_info.info26, &crypt_pwd_ex, + PASS_DONT_CHANGE_AT_NEXT_LOGON); + + status = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, + &user_pol, + 26, + &user_info); + if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) { /* retry with level 24 */ @@ -941,7 +949,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, &cli->user_session_key, &crypt_pwd); - init_samr_user_info24(&user_info.info24, crypt_pwd.data, 24); + init_samr_user_info24(&user_info.info24, &crypt_pwd, + PASS_DONT_CHANGE_AT_NEXT_LOGON); status = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, &user_pol, @@ -1010,8 +1019,7 @@ NTSTATUS libnet_join_ok(const char *netbios_domain_name, return NT_STATUS_NO_TRUST_LSA_SECRET; } - asprintf(&machine_account, "%s$", machine_name); - if (!machine_account) { + if (asprintf(&machine_account, "%s$", machine_name) == -1) { SAFE_FREE(machine_password); return NT_STATUS_NO_MEMORY; } @@ -1512,7 +1520,10 @@ static WERROR libnet_join_post_processing(TALLOC_CTX *mem_ctx, return WERR_OK; } - saf_store(r->in.domain_name, r->in.dc_name); + saf_join_store(r->out.netbios_domain_name, r->in.dc_name); + if (r->out.dns_domain_name) { + saf_join_store(r->out.dns_domain_name, r->in.dc_name); + } #ifdef WITH_ADS if (r->out.domain_is_ad) { @@ -1638,24 +1649,31 @@ WERROR libnet_init_UnjoinCtx(TALLOC_CTX *mem_ctx, static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx, struct libnet_JoinCtx *r) { + bool valid_security = false; + bool valid_workgroup = false; + bool valid_realm = false; + /* check if configuration is already set correctly */ + valid_workgroup = strequal(lp_workgroup(), r->out.netbios_domain_name); + switch (r->out.domain_is_ad) { case false: - if ((strequal(lp_workgroup(), - r->out.netbios_domain_name)) && - (lp_security() == SEC_DOMAIN)) { + valid_security = (lp_security() == SEC_DOMAIN); + if (valid_workgroup && valid_security) { /* nothing to be done */ return WERR_OK; } break; case true: - if ((strequal(lp_workgroup(), - r->out.netbios_domain_name)) && - (strequal(lp_realm(), - r->out.dns_domain_name)) && - ((lp_security() == SEC_ADS) || - (lp_security() == SEC_DOMAIN))) { + valid_realm = strequal(lp_realm(), r->out.dns_domain_name); + switch (lp_security()) { + case SEC_DOMAIN: + case SEC_ADS: + valid_security = true; + } + + if (valid_workgroup && valid_realm && valid_security) { /* nothing to be done */ return WERR_OK; } @@ -1665,9 +1683,41 @@ static WERROR libnet_join_check_config(TALLOC_CTX *mem_ctx, /* check if we are supposed to manipulate configuration */ if (!r->in.modify_config) { + + char *wrong_conf = talloc_strdup(mem_ctx, ""); + + if (!valid_workgroup) { + wrong_conf = talloc_asprintf_append(wrong_conf, + "\"workgroup\" set to '%s', should be '%s'", + lp_workgroup(), r->out.netbios_domain_name); + W_ERROR_HAVE_NO_MEMORY(wrong_conf); + } + + if (!valid_realm) { + wrong_conf = talloc_asprintf_append(wrong_conf, + "\"realm\" set to '%s', should be '%s'", + lp_realm(), r->out.dns_domain_name); + W_ERROR_HAVE_NO_MEMORY(wrong_conf); + } + + if (!valid_security) { + const char *sec = NULL; + switch (lp_security()) { + case SEC_SHARE: sec = "share"; break; + case SEC_USER: sec = "user"; break; + case SEC_DOMAIN: sec = "domain"; break; + case SEC_ADS: sec = "ads"; break; + } + wrong_conf = talloc_asprintf_append(wrong_conf, + "\"security\" set to '%s', should be %s", + sec, r->out.domain_is_ad ? + "either 'domain' or 'ads'" : "'domain'"); + W_ERROR_HAVE_NO_MEMORY(wrong_conf); + } + libnet_join_set_error_string(mem_ctx, r, - "Invalid configuration and configuration modification " - "was not requested"); + "Invalid configuration (%s) and configuration modification " + "was not requested", wrong_conf); return WERR_CAN_NOT_COMPLETE; } @@ -1704,6 +1754,7 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, r->in.domain_name, NULL, NULL, + DS_FORCE_REDISCOVERY | DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED | DS_RETURN_DNS_NAME,