summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/rpc_server/srv_wkssvc_nt.c69
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;
}
/********************************************************************