WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p, struct wkssvc_NetrUnjoinDomain2 *r) { struct libnet_UnjoinCtx *u = NULL; char *cleartext_pwd = NULL; char *admin_domain = NULL; char *admin_account = NULL; WERROR werr; struct security_token *token = p->session_info->security_token; if (!r->in.account || !r->in.encrypted_password) { return WERR_INVALID_PARAM; } if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) && !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) && !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) { DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have " "sufficient privileges\n")); return WERR_ACCESS_DENIED; } werr = decode_wkssvc_join_password_buffer( p->mem_ctx, r->in.encrypted_password, &p->session_info->session_key, &cleartext_pwd); if (!W_ERROR_IS_OK(werr)) { return werr; } split_domain_user(p->mem_ctx, r->in.account, &admin_domain, &admin_account); werr = libnet_init_UnjoinCtx(p->mem_ctx, &u); if (!W_ERROR_IS_OK(werr)) { return werr; } u->in.domain_name = lp_realm(); u->in.unjoin_flags = r->in.unjoin_flags | WKSSVC_JOIN_FLAGS_JOIN_TYPE; u->in.admin_account = admin_account; u->in.admin_password = cleartext_pwd; u->in.debug = true; u->in.modify_config = lp_config_backend_is_registry(); u->in.msg_ctx = p->msg_ctx; become_root(); werr = libnet_Unjoin(p->mem_ctx, u); unbecome_root(); if (!W_ERROR_IS_OK(werr)) { DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n", u->out.error_string ? u->out.error_string : win_errstr(werr))); } TALLOC_FREE(u); return werr; }
WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx, struct NetUnjoinDomain *r) { struct libnet_UnjoinCtx *u = NULL; struct dom_sid domain_sid; const char *domain = NULL; WERROR werr; if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { return WERR_SETUP_NOT_JOINED; } werr = libnet_init_UnjoinCtx(mem_ctx, &u); W_ERROR_NOT_OK_RETURN(werr); if (lp_realm()) { domain = lp_realm(); } else { domain = lp_workgroup(); } if (r->in.server_name) { u->in.dc_name = talloc_strdup(mem_ctx, r->in.server_name); W_ERROR_HAVE_NO_MEMORY(u->in.dc_name); } else { NTSTATUS status; struct netr_DsRGetDCNameInfo *info = NULL; const char *dc = NULL; uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED | DS_RETURN_DNS_NAME; status = dsgetdcname(mem_ctx, NULL, domain, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { libnetapi_set_error_string(mem_ctx, "failed to find DC for domain %s: %s", domain, get_friendly_nt_error_msg(status)); return ntstatus_to_werror(status); } dc = strip_hostname(info->dc_unc); u->in.dc_name = talloc_strdup(mem_ctx, dc); W_ERROR_HAVE_NO_MEMORY(u->in.dc_name); u->in.domain_name = domain; } if (r->in.account) { u->in.admin_account = talloc_strdup(mem_ctx, r->in.account); W_ERROR_HAVE_NO_MEMORY(u->in.admin_account); } if (r->in.password) { u->in.admin_password = talloc_strdup(mem_ctx, r->in.password); W_ERROR_HAVE_NO_MEMORY(u->in.admin_password); } 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; u->in.domain_sid = &domain_sid; werr = libnet_Unjoin(mem_ctx, u); if (!W_ERROR_IS_OK(werr) && u->out.error_string) { libnetapi_set_error_string(mem_ctx, "%s", u->out.error_string); } TALLOC_FREE(u); return werr; }