diff options
-rw-r--r-- | source/lib/netapi/joindomain.c | 1 | ||||
-rw-r--r-- | source/libnet/libnet_join.c | 61 | ||||
-rw-r--r-- | source/librpc/gen_ndr/libnet_join.h | 1 | ||||
-rw-r--r-- | source/librpc/gen_ndr/ndr_libnet_join.c | 1 | ||||
-rw-r--r-- | source/librpc/idl/libnet_join.idl | 1 | ||||
-rw-r--r-- | source/utils/net_ads.c | 11 |
6 files changed, 55 insertions, 21 deletions
diff --git a/source/lib/netapi/joindomain.c b/source/lib/netapi/joindomain.c index 66f7cfb13ff..c204a809716 100644 --- a/source/lib/netapi/joindomain.c +++ b/source/lib/netapi/joindomain.c @@ -209,6 +209,7 @@ WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx, u->in.domain_name = domain; u->in.unjoin_flags = r->in.unjoin_flags; + u->in.delete_machine_account = false; u->in.modify_config = true; u->in.debug = true; diff --git a/source/libnet/libnet_join.c b/source/libnet/libnet_join.c index c13ac9b769e..face9d3a35b 100644 --- a/source/libnet/libnet_join.c +++ b/source/libnet/libnet_join.c @@ -1835,6 +1835,12 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, W_ERROR_HAVE_NO_MEMORY(r->in.domain_sid); } + if (!(r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) && + !r->in.delete_machine_account) { + libnet_join_unjoindomain_remove_secrets(mem_ctx, r); + return WERR_OK; + } + if (!r->in.dc_name) { struct netr_DsRGetDCNameInfo *info; const char *dc; @@ -1860,38 +1866,55 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, 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 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; - } - return ntstatus_to_werror(status); - } - - r->out.disabled_machine_account = true; - #ifdef WITH_ADS - if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) { + /* for net ads leave, try to delete the account. If it works, + no sense in disabling. If it fails, we can still try to + disable it. jmcd */ + + if (r->in.delete_machine_account) { ADS_STATUS ads_status; - libnet_unjoin_connect_ads(mem_ctx, r); - ads_status = libnet_unjoin_remove_machine_acct(mem_ctx, r); + ads_status = libnet_unjoin_connect_ads(mem_ctx, r); + if (ADS_ERR_OK(ads_status)) { + /* dirty hack */ + r->out.dns_domain_name = + talloc_strdup(mem_ctx, + r->in.ads->server.realm); + ads_status = + libnet_unjoin_remove_machine_acct(mem_ctx, r); + } if (!ADS_ERR_OK(ads_status)) { libnet_unjoin_set_error_string(mem_ctx, r, "failed to remove machine account from AD: %s", ads_errstr(ads_status)); } else { r->out.deleted_machine_account = true; - /* dirty hack */ - r->out.dns_domain_name = talloc_strdup(mem_ctx, - r->in.ads->server.realm); W_ERROR_HAVE_NO_MEMORY(r->out.dns_domain_name); + libnet_join_unjoindomain_remove_secrets(mem_ctx, r); + return WERR_OK; } } #endif /* WITH_ADS */ + /* The WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE flag really means + "disable". */ + if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) { + status = libnet_join_unjoindomain_rpc(mem_ctx, r); + if (!NT_STATUS_IS_OK(status)) { + libnet_unjoin_set_error_string(mem_ctx, r, + "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; + } + return ntstatus_to_werror(status); + } + + r->out.disabled_machine_account = true; + } + + /* If disable succeeded or was not requested at all, we + should be getting rid of our end of things */ + libnet_join_unjoindomain_remove_secrets(mem_ctx, r); return WERR_OK; diff --git a/source/librpc/gen_ndr/libnet_join.h b/source/librpc/gen_ndr/libnet_join.h index e5ec438bb58..0de71323248 100644 --- a/source/librpc/gen_ndr/libnet_join.h +++ b/source/librpc/gen_ndr/libnet_join.h @@ -56,6 +56,7 @@ struct libnet_UnjoinCtx { const char * admin_password; const char * machine_password; uint32_t unjoin_flags; + uint8_t delete_machine_account; uint8_t modify_config; struct dom_sid *domain_sid;/* [ref] */ struct ads_struct *ads;/* [ref] */ diff --git a/source/librpc/gen_ndr/ndr_libnet_join.c b/source/librpc/gen_ndr/ndr_libnet_join.c index 753859f0ed7..a550cd61104 100644 --- a/source/librpc/gen_ndr/ndr_libnet_join.c +++ b/source/librpc/gen_ndr/ndr_libnet_join.c @@ -87,6 +87,7 @@ _PUBLIC_ void ndr_print_libnet_UnjoinCtx(struct ndr_print *ndr, const char *name ndr_print_ptr(ndr, "machine_password", r->in.machine_password); #endif ndr_print_wkssvc_joinflags(ndr, "unjoin_flags", r->in.unjoin_flags); + ndr_print_uint8(ndr, "delete_machine_account", r->in.delete_machine_account); ndr_print_uint8(ndr, "modify_config", r->in.modify_config); ndr_print_ptr(ndr, "domain_sid", r->in.domain_sid); ndr->depth++; diff --git a/source/librpc/idl/libnet_join.idl b/source/librpc/idl/libnet_join.idl index 7f6e3464556..93b1f0989f7 100644 --- a/source/librpc/idl/libnet_join.idl +++ b/source/librpc/idl/libnet_join.idl @@ -51,6 +51,7 @@ interface libnetjoin [in] string admin_password, [in] string machine_password, [in] wkssvc_joinflags unjoin_flags, + [in] boolean8 delete_machine_account, [in] boolean8 modify_config, [in] dom_sid *domain_sid, [in] ads_struct *ads, diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c index a023a11a066..3c27b4ccb2a 100644 --- a/source/utils/net_ads.c +++ b/source/utils/net_ads.c @@ -835,8 +835,12 @@ static int net_ads_leave(int argc, const char **argv) r->in.admin_account = opt_user_name; r->in.admin_password = net_prompt_pass(opt_user_name); r->in.modify_config = lp_config_backend_is_registry(); + + /* Try to delete it, but if that fails, disable it. The + WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE really means "disable */ r->in.unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; + r->in.delete_machine_account = true; werr = libnet_Unjoin(ctx, r); if (!W_ERROR_IS_OK(werr)) { @@ -846,7 +850,7 @@ static int net_ads_leave(int argc, const char **argv) goto done; } - if (W_ERROR_IS_OK(werr)) { + if (r->out.deleted_machine_account) { d_printf("Deleted account for '%s' in realm '%s'\n", r->in.machine_name, r->out.dns_domain_name); goto done; @@ -860,7 +864,10 @@ static int net_ads_leave(int argc, const char **argv) goto done; } - d_fprintf(stderr, "Failed to disable machine account for '%s' in realm '%s'\n", + /* Based on what we requseted, we shouldn't get here, but if + we did, it means the secrets were removed, and therefore + we have left the domain */ + d_fprintf(stderr, "Machine '%s' Left domain '%s'\n", r->in.machine_name, r->out.dns_domain_name); done: |