diff options
-rw-r--r-- | source3/libnet/libnet_join.c | 112 |
1 files changed, 100 insertions, 12 deletions
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 7c8b395cd3..1d52b81a75 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -155,6 +155,39 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + ADS_STATUS status; + LDAPMessage *res = NULL; + const char *attrs[] = { "dn", NULL }; + + status = ads_search_dn(r->in.ads, &res, r->in.account_ou, attrs); + if (!ADS_ERR_OK(status)) { + return status; + } + + if (ads_count_replies(r->in.ads, res) != 1) { + ads_msgfree(r->in.ads, res); + return ADS_ERROR_LDAP(LDAP_NO_SUCH_OBJECT); + } + + status = ads_create_machine_acct(r->in.ads, + r->in.machine_name, + r->in.account_ou); + ads_msgfree(r->in.ads, res); + + if ((status.error_type == ENUM_ADS_ERROR_LDAP) && + (status.err.rc == LDAP_ALREADY_EXISTS)) { + status = ADS_SUCCESS; + } + + return status; +} + +/**************************************************************** +****************************************************************/ + static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx, struct libnet_JoinCtx *r) { @@ -174,6 +207,9 @@ static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx, return true; } +/**************************************************************** +****************************************************************/ + static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, struct libnet_JoinCtx *r) { @@ -362,6 +398,9 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, return status; } +/**************************************************************** +****************************************************************/ + static bool libnet_join_unjoindomain_remove_secrets(TALLOC_CTX *mem_ctx, struct libnet_UnjoinCtx *r) { @@ -376,6 +415,9 @@ static bool libnet_join_unjoindomain_remove_secrets(TALLOC_CTX *mem_ctx, return true; } +/**************************************************************** +****************************************************************/ + static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, struct libnet_UnjoinCtx *r) { @@ -481,6 +523,9 @@ done: return status; } +/**************************************************************** +****************************************************************/ + static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r) { WERROR werr; @@ -519,6 +564,9 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r) return werr; } +/**************************************************************** +****************************************************************/ + static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r) { WERROR werr = WERR_OK; @@ -534,6 +582,8 @@ static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r) return werr; } +/**************************************************************** +****************************************************************/ static WERROR do_JoinConfig(struct libnet_JoinCtx *r) { @@ -558,6 +608,9 @@ static WERROR do_JoinConfig(struct libnet_JoinCtx *r) return werr; } +/**************************************************************** +****************************************************************/ + static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r) { WERROR werr; @@ -651,11 +704,54 @@ WERROR libnet_init_UnjoinCtx(TALLOC_CTX *mem_ctx, return WERR_OK; } +/**************************************************************** +****************************************************************/ + +static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + NTSTATUS status; + ADS_STATUS ads_status; + + if (r->in.account_ou) { + ads_status = libnet_join_connect_ads(mem_ctx, r); + if (!ADS_ERR_OK(ads_status)) { + return WERR_GENERAL_FAILURE; + } + ads_status = libnet_join_precreate_machine_acct(mem_ctx, r); + if (!ADS_ERR_OK(ads_status)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to precreate account in ou %s: %s\n", + r->in.account_ou, + ads_errstr(ads_status)); + return WERR_GENERAL_FAILURE; + } + + r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE; + } + + status = libnet_join_joindomain_rpc(mem_ctx, r); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { + return WERR_SETUP_ALREADY_JOINED; + } + return ntstatus_to_werror(status); + } + + if (!libnet_join_joindomain_store_secrets(mem_ctx, r)) { + return WERR_SETUP_NOT_JOINED; + } + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + WERROR libnet_Join(TALLOC_CTX *mem_ctx, struct libnet_JoinCtx *r) { WERROR werr; - NTSTATUS status; if (!r->in.domain_name) { return WERR_INVALID_PARAM; @@ -670,17 +766,9 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx, } if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { - - status = libnet_join_joindomain_rpc(mem_ctx, r); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { - return WERR_SETUP_ALREADY_JOINED; - } - return ntstatus_to_werror(status); - } - - if (!libnet_join_joindomain_store_secrets(mem_ctx, r)) { - return WERR_SETUP_NOT_JOINED; + werr = libnet_DomainJoin(mem_ctx, r); + if (!W_ERROR_IS_OK(werr)) { + return werr; } } |