diff options
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/rpc_server/srv_wkssvc_nt.c | 69 |
2 files changed, 67 insertions, 4 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 1b482c1d46..765c705d86 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -558,7 +558,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ - $(BUILDOPT_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ) + $(BUILDOPT_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \ printing/print_cups.o printing/print_generic.o \ diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c index d9d2df344a..e60dca61c7 100644 --- a/source3/rpc_server/srv_wkssvc_nt.c +++ b/source3/rpc_server/srv_wkssvc_nt.c @@ -22,6 +22,8 @@ /* This is the implementation of the wks interface. */ #include "includes.h" +#include "libnet/libnet_join.h" +#include "libnet/libnet_proto.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -284,9 +286,70 @@ WERROR _wkssvc_NetrGetJoinableOus(pipes_struct *p, struct wkssvc_NetrGetJoinable WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r) { - /* FIXME: Add implementation code here */ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + struct libnet_JoinCtx *j = NULL; + char *pwd = NULL; + char *admin_domain = NULL; + char *admin_account = NULL; + WERROR werr; + NTSTATUS status; + struct nt_user_token *token = p->pipe_user.nt_user_token; + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + + if (!r->in.domain_name) { + return WERR_INVALID_PARAM; + } + + if (!user_has_privileges(token, &se_machine_account) && + !nt_token_check_domain_rid(token, DOMAIN_GROUP_RID_ADMINS) && + !nt_token_check_domain_rid(token, BUILTIN_ALIAS_RID_ADMINS)) { + return WERR_ACCESS_DENIED; + } + + werr = decode_wkssvc_join_password_buffer(p->mem_ctx, + r->in.encrypted_password, + &p->session_key, + &pwd); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + werr = libnet_init_JoinCtx(p->mem_ctx, &j); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + split_domain_user(p->mem_ctx, + r->in.admin_account, + &admin_domain, + &admin_account); + + status = DsGetDcName(p->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)) { + return ntstatus_to_werror(status); + } + + j->in.server_name = info->domain_controller_name; + 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.password = pwd; + j->in.modify_config = true; + + become_root(); + werr = libnet_Join(p->mem_ctx, j); + unbecome_root(); + + return werr; } /******************************************************************** |