Fix bug #6089 - Winbind samr_OpenDomain not possible with Samba 3.2.6+
[samba.git] / source / utils / net_rpc_join.c
index 2777324e81f3bdfb3ff3057b7c9519bc73bb7aa9..e663cc89e3f1584ad602110fcbb75d2b932a7c40 100644 (file)
@@ -1,6 +1,6 @@
-/* 
-   Samba Unix/Linux SMB client library 
-   Distributed SMB/CIFS Server Management Utility 
+/*
+   Samba Unix/Linux SMB client library
+   Distributed SMB/CIFS Server Management Utility
    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
    Copyright (C) Tim Potter     2001
    Copyright (C) 2008 Guenther Deschner
@@ -9,15 +9,15 @@
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
 #include "includes.h"
 #include "utils/net.h"
 
@@ -73,12 +73,13 @@ NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain,
        }
 
        /* Setup the creds as though we're going to do schannel... */
-        netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, &ntret);
+       ntret = get_schannel_session_key(cli, domain, &neg_flags,
+                                        &netlogon_pipe);
 
        /* We return NT_STATUS_INVALID_NETWORK_RESPONSE if the server is refusing
           to negotiate schannel, but the creds were set up ok. That'll have to do. */
 
-        if (!netlogon_pipe) {
+        if (!NT_STATUS_IS_OK(ntret)) {
                if (NT_STATUS_EQUAL(ntret, NT_STATUS_INVALID_NETWORK_RESPONSE)) {
                        cli_shutdown(cli);
                        return NT_STATUS_OK;
@@ -98,11 +99,11 @@ NTSTATUS net_rpc_join_ok(struct net_context *c, const char *domain,
                return ntret;
        }
 
-       pipe_hnd = cli_rpc_pipe_open_schannel_with_key(cli, PI_NETLOGON,
-                               PIPE_AUTH_LEVEL_PRIVACY,
-                               domain, netlogon_pipe->dc, &ntret);
+       ntret = cli_rpc_pipe_open_schannel_with_key(
+               cli, &ndr_table_netlogon.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
+               domain, netlogon_pipe->dc, &pipe_hnd);
 
-       if (!pipe_hnd) {
+       if (!NT_STATUS_IS_OK(ntret)) {
                DEBUG(0,("net_rpc_join_ok: failed to open schannel session "
                                "on netlogon pipe to server %s for domain %s. Error was %s\n",
                        cli->desthost, domain, nt_errstr(ntret) ));
@@ -147,7 +148,7 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
        /* Password stuff */
 
        char *clear_trust_password = NULL;
-       uchar pwbuf[516];
+       struct samr_CryptPassword crypt_pwd;
        uchar md4_trust_password[16];
        union samr_UserInfo set_info;
 
@@ -199,15 +200,16 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
 
        /* Fetch domain sid */
 
-       pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &result);
-       if (!pipe_hnd) {
+       result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+                                         &pipe_hnd);
+       if (!NT_STATUS_IS_OK(result)) {
                DEBUG(0, ("Error connecting to LSA pipe. Error was %s\n",
                        nt_errstr(result) ));
                goto done;
        }
 
 
-       CHECK_RPC_ERR(rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
+       CHECK_RPC_ERR(rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true,
                                          SEC_RIGHTS_MAXIMUM_ALLOWED,
                                          &lsa_pol),
                      "error opening lsa policy handle");
@@ -231,8 +233,9 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
        }
 
        /* Create domain user */
-       pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result);
-       if (!pipe_hnd) {
+       result = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
+                                         &pipe_hnd);
+       if (!NT_STATUS_IS_OK(result)) {
                DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n",
                        nt_errstr(result) ));
                goto done;
@@ -240,14 +243,17 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
 
        CHECK_RPC_ERR(rpccli_samr_Connect2(pipe_hnd, mem_ctx,
                                           pipe_hnd->desthost,
-                                          SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                          SAMR_ACCESS_ENUM_DOMAINS
+                                          | SAMR_ACCESS_LOOKUP_DOMAIN,
                                           &sam_pol),
                      "could not connect to SAM database");
 
 
        CHECK_RPC_ERR(rpccli_samr_OpenDomain(pipe_hnd, mem_ctx,
                                             &sam_pol,
-                                            SEC_RIGHTS_MAXIMUM_ALLOWED,
+                                            SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1
+                                            | SAMR_DOMAIN_ACCESS_CREATE_USER
+                                            | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
                                             domain_sid,
                                             &domain_pol),
                      "could not open domain");
@@ -334,14 +340,14 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
                E_md4hash(clear_trust_password, md4_trust_password);
        }
 
-       encode_pw_buffer(pwbuf, clear_trust_password, STR_UNICODE);
-
        /* Set password on machine account */
 
-       init_samr_user_info24(&set_info.info24, pwbuf, 24);
+       init_samr_CryptPassword(clear_trust_password,
+                               &cli->user_session_key,
+                               &crypt_pwd);
 
-       SamOEMhashBlob(set_info.info24.password.data, 516,
-                      &cli->user_session_key);
+       init_samr_user_info24(&set_info.info24, &crypt_pwd,
+                             PASS_DONT_CHANGE_AT_NEXT_LOGON);
 
        CHECK_RPC_ERR(rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx,
                                               &user_pol,
@@ -373,8 +379,9 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
 
        /* Now check the whole process from top-to-bottom */
 
-       pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, &result);
-       if (!pipe_hnd) {
+       result = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
+                                         &pipe_hnd);
+       if (!NT_STATUS_IS_OK(result)) {
                DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n",
                        nt_errstr(result) ));
                goto done;
@@ -409,13 +416,12 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
           do the same again (setup creds) in net_rpc_join_ok(). JRA. */
 
        if (lp_client_schannel() && (neg_flags & NETLOGON_NEG_SCHANNEL)) {
-               struct rpc_pipe_client *netlogon_schannel_pipe = 
-                                               cli_rpc_pipe_open_schannel_with_key(cli,
-                                                       PI_NETLOGON,
-                                                       PIPE_AUTH_LEVEL_PRIVACY,
-                                                       domain,
-                                                       pipe_hnd->dc,
-                                                       &result);
+               struct rpc_pipe_client *netlogon_schannel_pipe;
+
+               result = cli_rpc_pipe_open_schannel_with_key(
+                       cli, &ndr_table_netlogon.syntax_id,
+                       PIPE_AUTH_LEVEL_PRIVACY, domain, pipe_hnd->dc,
+                       &netlogon_schannel_pipe);
 
                if (!NT_STATUS_IS_OK(result)) {
                        DEBUG(0, ("Error in domain join verification (schannel setup failed): %s\n\n",
@@ -463,7 +469,7 @@ done:
                        printf("Joined domain %s.\n",domain);
                }
        }
-       
+
        cli_shutdown(cli);
 
        SAFE_FREE(clear_trust_password);
@@ -479,19 +485,23 @@ done:
  **/
 int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
 {
-       char *domain = smb_xstrdup(c->opt_target_workgroup);
        NTSTATUS nt_status;
 
+       if (c->display_usage) {
+               d_printf("Usage\n"
+                        "net rpc testjoin\n"
+                        "    Test if a join is OK\n");
+               return 0;
+       }
+
        /* Display success or failure */
-       nt_status = net_rpc_join_ok(c, domain, NULL, NULL);
+       nt_status = net_rpc_join_ok(c, c->opt_target_workgroup, NULL, NULL);
        if (!NT_STATUS_IS_OK(nt_status)) {
                fprintf(stderr,"Join to domain '%s' is not valid: %s\n",
-                       domain, nt_errstr(nt_status));
-               free(domain);
+                       c->opt_target_workgroup, nt_errstr(nt_status));
                return -1;
        }
 
-       printf("Join to '%s' is OK\n",domain);
-       free(domain);
+       printf("Join to '%s' is OK\n", c->opt_target_workgroup);
        return 0;
 }