s3-net: add "net dom renamecomputer" to rename machines in a domain.
[ira/wip.git] / source3 / rpc_server / srv_wkssvc_nt.c
index 849ec9c4eb8bc85cefc598510bb540407bab817f..b06818efb3092750e030a2ef91d97c027d149449 100644 (file)
@@ -4,7 +4,8 @@
  *
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Gerald (Jerry) Carter                2006.
- *  
+ *  Copyright (C) Guenther Deschner            2007-2008.
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 3 of the License, or
@@ -23,6 +24,7 @@
 
 #include "includes.h"
 #include "libnet/libnet.h"
+#include "../libcli/auth/libcli_auth.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
@@ -281,39 +283,43 @@ WERROR _wkssvc_NetrGetJoinableOus(pipes_struct *p, struct wkssvc_NetrGetJoinable
 }
 
 /********************************************************************
+ _wkssvc_NetrJoinDomain2
  ********************************************************************/
 
-WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r)
+WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p,
+                              struct wkssvc_NetrJoinDomain2 *r)
 {
-#if 0
        struct libnet_JoinCtx *j = NULL;
-       char *pwd = NULL;
+       char *cleartext_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;
+       struct nt_user_token *token = p->server_info->ptok;
 
        if (!r->in.domain_name) {
                return WERR_INVALID_PARAM;
        }
 
+       if (!r->in.admin_account || !r->in.encrypted_password) {
+               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)) {
+               DEBUG(5,("_wkssvc_NetrJoinDomain2: 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_key,
-                                                 &pwd);
-       if (!W_ERROR_IS_OK(werr)) {
-               return werr;
+       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 = libnet_init_JoinCtx(p->mem_ctx, &j);
+       werr = decode_wkssvc_join_password_buffer(
+               p->mem_ctx, r->in.encrypted_password,
+               &p->server_info->user_session_key, &cleartext_pwd);
        if (!W_ERROR_IS_OK(werr)) {
                return werr;
        }
@@ -323,46 +329,98 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r
                          &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);
+       werr = libnet_init_JoinCtx(p->mem_ctx, &j);
+       if (!W_ERROR_IS_OK(werr)) {
+               return werr;
        }
 
-       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;
+       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           = smbd_messaging_context();
 
        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;
-#endif
-       p->rng_fault_state = True;
-       return WERR_NOT_SUPPORTED;
 }
 
 /********************************************************************
+ _wkssvc_NetrUnjoinDomain2
  ********************************************************************/
 
-WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p, struct wkssvc_NetrUnjoinDomain2 *r)
+WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p,
+                                struct wkssvc_NetrUnjoinDomain2 *r)
 {
-       /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
-       return WERR_NOT_SUPPORTED;
+       struct libnet_UnjoinCtx *u = NULL;
+       char *cleartext_pwd = NULL;
+       char *admin_domain = NULL;
+       char *admin_account = NULL;
+       WERROR werr;
+       struct nt_user_token *token = p->server_info->ptok;
+
+       if (!r->in.account || !r->in.encrypted_password) {
+               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)) {
+               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->server_info->user_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           = smbd_messaging_context();
+
+       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;
 }
 
 /********************************************************************
@@ -370,8 +428,7 @@ WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p, struct wkssvc_NetrUnjoinDomain
 
 WERROR _wkssvc_NetrRenameMachineInDomain2(pipes_struct *p, struct wkssvc_NetrRenameMachineInDomain2 *r)
 {
-       /* FIXME: Add implementation code here */
-       p->rng_fault_state = True;
+       /* for now just return not supported */
        return WERR_NOT_SUPPORTED;
 }