static int ejs_net_join_domain(MprVarHandle eid, int argc, struct MprVar **argv) { TALLOC_CTX *mem_ctx; struct libnet_context *ctx; struct libnet_Join *join; NTSTATUS status; ctx = mprGetThisPtr(eid, "ctx"); mem_ctx = talloc_new(mprMemCtx()); join = talloc(mem_ctx, struct libnet_Join); if (!join) { talloc_free(mem_ctx); return -1; } /* prepare parameters for the join */ join->in.netbios_name = NULL; join->in.join_type = SEC_CHAN_WKSTA; join->in.domain_name = cli_credentials_get_domain(ctx->cred); join->in.level = LIBNET_JOIN_AUTOMATIC; join->out.error_string = NULL; if (argc == 1 && argv[0]->type == MPR_TYPE_OBJECT) { MprVar *netbios_name = mprGetProperty(argv[0], "netbios_name", NULL); MprVar *domain_name = mprGetProperty(argv[0], "domain_name", NULL); MprVar *join_type = mprGetProperty(argv[0], "join_type", NULL); if (netbios_name) { join->in.netbios_name = mprToString(netbios_name); } if (domain_name) { join->in.domain_name = mprToString(domain_name); } if (join_type) { join->in.join_type = mprToInt(join_type); } } if (!join->in.domain_name) { ejsSetErrorMsg(eid, "a domain must be specified for to join"); talloc_free(mem_ctx); return -1; } /* do the domain join */ status = libnet_Join(ctx, join, join); if (!NT_STATUS_IS_OK(status)) { MprVar error_string = mprString(join->out.error_string); mprSetPropertyValue(argv[0], "error_string", error_string); mpr_Return(eid, mprCreateBoolVar(False)); } else { mpr_Return(eid, mprCreateBoolVar(True)); } talloc_free(mem_ctx); return 0; }
WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r) { struct libnet_JoinCtx *j = 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.domain_name) { return WERR_INVALID_PARAM; } if (!r->in.admin_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_NetrJoinDomain2: account doesn't have " "sufficient privileges\n")); return WERR_ACCESS_DENIED; } if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED) || (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) { return WERR_NOT_SUPPORTED; } 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.admin_account, &admin_domain, &admin_account); werr = libnet_init_JoinCtx(p->mem_ctx, &j); if (!W_ERROR_IS_OK(werr)) { return werr; } j->in.domain_name = r->in.domain_name; j->in.account_ou = r->in.account_ou; j->in.join_flags = r->in.join_flags; j->in.admin_account = admin_account; j->in.admin_password = cleartext_pwd; j->in.debug = true; j->in.modify_config = lp_config_backend_is_registry(); j->in.msg_ctx = p->msg_ctx; become_root(); werr = libnet_Join(p->mem_ctx, j); unbecome_root(); if (!W_ERROR_IS_OK(werr)) { DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n", j->out.error_string ? j->out.error_string : win_errstr(werr))); } TALLOC_FREE(j); return werr; }
WERROR NetJoinDomain_l(struct libnetapi_ctx *mem_ctx, struct NetJoinDomain *r) { struct libnet_JoinCtx *j = NULL; WERROR werr; if (!r->in.domain) { return WERR_INVALID_PARAM; } werr = libnet_init_JoinCtx(mem_ctx, &j); W_ERROR_NOT_OK_RETURN(werr); j->in.domain_name = talloc_strdup(mem_ctx, r->in.domain); W_ERROR_HAVE_NO_MEMORY(j->in.domain_name); if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { 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, r->in.domain, NULL, NULL, flags, &info); if (!NT_STATUS_IS_OK(status)) { libnetapi_set_error_string(mem_ctx, "%s", get_friendly_nt_error_msg(status)); return ntstatus_to_werror(status); } dc = strip_hostname(info->dc_unc); j->in.dc_name = talloc_strdup(mem_ctx, dc); W_ERROR_HAVE_NO_MEMORY(j->in.dc_name); } if (r->in.account_ou) { j->in.account_ou = talloc_strdup(mem_ctx, r->in.account_ou); W_ERROR_HAVE_NO_MEMORY(j->in.account_ou); } if (r->in.account) { j->in.admin_account = talloc_strdup(mem_ctx, r->in.account); W_ERROR_HAVE_NO_MEMORY(j->in.admin_account); } if (r->in.password) { j->in.admin_password = talloc_strdup(mem_ctx, r->in.password); W_ERROR_HAVE_NO_MEMORY(j->in.admin_password); } j->in.join_flags = r->in.join_flags; j->in.modify_config = true; j->in.debug = true; werr = libnet_Join(mem_ctx, j); if (!W_ERROR_IS_OK(werr) && j->out.error_string) { libnetapi_set_error_string(mem_ctx, "%s", j->out.error_string); } TALLOC_FREE(j); return werr; }