diff options
Diffstat (limited to 'source3/libnet/libnet_join.c')
-rw-r--r-- | source3/libnet/libnet_join.c | 201 |
1 files changed, 171 insertions, 30 deletions
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index eaf851ccec..a9978ba4b8 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -24,6 +24,35 @@ /**************************************************************** ****************************************************************/ +#define LIBNET_JOIN_DUMP_CTX(ctx, r, f) \ + do { \ + char *str = NULL; \ + str = NDR_PRINT_FUNCTION_STRING(ctx, libnet_JoinCtx, f, r); \ + DEBUG(1,("libnet_Join:\n%s", str)); \ + talloc_free(str); \ + } while (0) + +#define LIBNET_JOIN_IN_DUMP_CTX(ctx, r) \ + LIBNET_JOIN_DUMP_CTX(ctx, r, NDR_IN | NDR_SET_VALUES) +#define LIBNET_JOIN_OUT_DUMP_CTX(ctx, r) \ + LIBNET_JOIN_DUMP_CTX(ctx, r, NDR_OUT) + +#define LIBNET_UNJOIN_DUMP_CTX(ctx, r, f) \ + do { \ + char *str = NULL; \ + str = NDR_PRINT_FUNCTION_STRING(ctx, libnet_UnjoinCtx, f, r); \ + DEBUG(1,("libnet_Unjoin:\n%s", str)); \ + talloc_free(str); \ + } while (0) + +#define LIBNET_UNJOIN_IN_DUMP_CTX(ctx, r) \ + LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_IN | NDR_SET_VALUES) +#define LIBNET_UNJOIN_OUT_DUMP_CTX(ctx, r) \ + LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_OUT) + +/**************************************************************** +****************************************************************/ + static void libnet_join_set_error_string(TALLOC_CTX *mem_ctx, struct libnet_JoinCtx *r, const char *format, ...) @@ -107,10 +136,6 @@ static ADS_STATUS libnet_join_connect_ads(TALLOC_CTX *mem_ctx, { ADS_STATUS status; - if (r->in.ads) { - ads_destroy(&r->in.ads); - } - status = libnet_connect_ads(r->in.domain_name, r->in.domain_name, r->in.dc_name, @@ -134,10 +159,6 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx, { ADS_STATUS status; - if (r->in.ads) { - ads_destroy(&r->in.ads); - } - status = libnet_connect_ads(r->in.domain_name, r->in.domain_name, r->in.dc_name, @@ -244,7 +265,6 @@ static ADS_STATUS libnet_join_find_machine_acct(TALLOC_CTX *mem_ctx, goto done; } - TALLOC_FREE(r->out.dn); r->out.dn = talloc_strdup(mem_ctx, dn); if (!r->out.dn) { status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); @@ -1013,6 +1033,58 @@ static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r) /**************************************************************** ****************************************************************/ +static WERROR libnet_join_pre_processing(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + + if (!r->in.domain_name) { + return WERR_INVALID_PARAM; + } + + if (r->in.modify_config && !lp_config_backend_is_registry()) { + return WERR_NOT_SUPPORTED; + } + + if (IS_DC) { + return WERR_SETUP_DOMAIN_CONTROLLER; + } + + if (!secrets_init()) { + libnet_join_set_error_string(mem_ctx, r, + "Unable to open secrets database"); + return WERR_CAN_NOT_COMPLETE; + } + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +static WERROR libnet_join_post_processing(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + WERROR werr; + + if (!W_ERROR_IS_OK(r->out.result)) { + return r->out.result; + } + + werr = do_JoinConfig(r); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { + saf_store(r->in.domain_name, r->in.dc_name); + } + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + static int libnet_destroy_JoinCtx(struct libnet_JoinCtx *r) { if (r->in.ads) { @@ -1104,8 +1176,9 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, &info); if (!NT_STATUS_IS_OK(status)) { libnet_join_set_error_string(mem_ctx, r, - "failed to find DC: %s", - nt_errstr(status)); + "failed to find DC for domain %s", + r->in.domain_name, + get_friendly_nt_error_msg(status)); return WERR_DOMAIN_CONTROLLER_NOT_FOUND; } @@ -1139,7 +1212,7 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { libnet_join_set_error_string(mem_ctx, r, "failed to join domain over rpc: %s", - nt_errstr(status)); + get_friendly_nt_error_msg(status)); if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { return WERR_SETUP_ALREADY_JOINED; } @@ -1170,30 +1243,32 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx, { WERROR werr; - if (!r->in.domain_name) { - return WERR_INVALID_PARAM; + if (r->in.debug) { + LIBNET_JOIN_IN_DUMP_CTX(mem_ctx, r); } - if (r->in.modify_config && !lp_include_registry_globals()) { - return WERR_NOT_SUPPORTED; - } - - if (IS_DC) { - return WERR_SETUP_DOMAIN_CONTROLLER; + werr = libnet_join_pre_processing(mem_ctx, r); + if (!W_ERROR_IS_OK(werr)) { + goto done; } if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { werr = libnet_DomainJoin(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { - return werr; + goto done; } } - werr = do_JoinConfig(r); + werr = libnet_join_post_processing(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { - return werr; + goto done; } + done: + r->out.result = werr; + if (r->in.debug) { + LIBNET_JOIN_OUT_DUMP_CTX(mem_ctx, r); + } return werr; } @@ -1205,11 +1280,46 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, { NTSTATUS status; + if (!r->in.domain_sid) { + struct dom_sid sid; + if (!secrets_fetch_domain_sid(lp_workgroup(), &sid)) { + libnet_unjoin_set_error_string(mem_ctx, r, + "Unable to fetch domain sid: are we joined?"); + return WERR_SETUP_NOT_JOINED; + } + r->in.domain_sid = sid_dup_talloc(mem_ctx, &sid); + W_ERROR_HAVE_NO_MEMORY(r->in.domain_sid); + } + + if (!r->in.dc_name) { + struct DS_DOMAIN_CONTROLLER_INFO *info; + status = dsgetdcname(mem_ctx, + NULL, + r->in.domain_name, + NULL, + NULL, + DS_DIRECTORY_SERVICE_REQUIRED | + DS_WRITABLE_REQUIRED | + DS_RETURN_DNS_NAME, + &info); + if (!NT_STATUS_IS_OK(status)) { + libnet_unjoin_set_error_string(mem_ctx, r, + "failed to find DC for domain %s", + r->in.domain_name, + get_friendly_nt_error_msg(status)); + return WERR_DOMAIN_CONTROLLER_NOT_FOUND; + } + + r->in.dc_name = talloc_strdup(mem_ctx, + info->domain_controller_name); + W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); + } + status = libnet_join_unjoindomain_rpc(mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { libnet_unjoin_set_error_string(mem_ctx, r, - "failed to unjoin domain: %s", - nt_errstr(status)); + "failed to disable machine account via rpc: %s", + get_friendly_nt_error_msg(status)); if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) { return WERR_SETUP_NOT_JOINED; } @@ -1237,26 +1347,57 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static WERROR libnet_unjoin_pre_processing(TALLOC_CTX *mem_ctx, + struct libnet_UnjoinCtx *r) +{ + if (r->in.modify_config && !lp_config_backend_is_registry()) { + return WERR_NOT_SUPPORTED; + } + + if (!secrets_init()) { + libnet_unjoin_set_error_string(mem_ctx, r, + "Unable to open secrets database"); + return WERR_CAN_NOT_COMPLETE; + } + + return WERR_OK; +} + + +/**************************************************************** +****************************************************************/ + WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx, struct libnet_UnjoinCtx *r) { WERROR werr; - if (r->in.modify_config && !lp_include_registry_globals()) { - return WERR_NOT_SUPPORTED; + if (r->in.debug) { + LIBNET_UNJOIN_IN_DUMP_CTX(mem_ctx, r); + } + + werr = libnet_unjoin_pre_processing(mem_ctx, r); + if (!W_ERROR_IS_OK(werr)) { + goto done; } if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { werr = libnet_DomainUnjoin(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { - do_UnjoinConfig(r); - return werr; + goto done; } } werr = do_UnjoinConfig(r); if (!W_ERROR_IS_OK(werr)) { - return werr; + goto done; + } + + done: + r->out.result = werr; + + if (r->in.debug) { + LIBNET_UNJOIN_OUT_DUMP_CTX(mem_ctx, r); } return werr; |