port latest changes from SAMBA_3_0 tree
[samba.git] / source3 / rpc_client / cli_pipe.c
index d6307ddb46e579f2dcd9de7049653325de7faaf8..ebe54c2c06f7918fe08f768f2952ea956a5c37fb 100644 (file)
@@ -5,6 +5,7 @@
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
  *  Copyright (C) Paul Ashton                       1998.
  *  Copyright (C) Jeremy Allison                    1999.
+ *  Copyright (C) Andrew Bartlett                   2003.
  *  
  *  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
@@ -637,7 +638,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
        RPC_HDR_AUTH hdr_auth;
        int auth_len = 0;
        int auth_type, auth_level;
-       size_t saved_hdr_offset;
+       size_t saved_hdr_offset = 0;
 
        prs_struct auth_info;
        prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */
@@ -690,14 +691,15 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
 
                data_blob_free(&request);
 
-       } 
-       else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
+       } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
                RPC_AUTH_NETSEC_NEG netsec_neg;
 
                /* Use lp_workgroup() if domain not specified */
 
-               if (!domain || !domain[0])
+               if (!domain || !domain[0]) {
+                       DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n"));
                        domain = lp_workgroup();
+               }
 
                init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name);
 
@@ -715,7 +717,8 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
                /* Auth len in the rpc header doesn't include auth_header. */
                auth_len = prs_offset(&auth_info) - saved_hdr_offset;
        }
-       /* create the request RPC_HDR */
+
+       /* Create the request RPC_HDR */
        init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id, 
                RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info),
                auth_len);
@@ -1021,11 +1024,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                                static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
                                static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 };
                                size_t parse_offset_marker;
-                               if ((cli->auth_info.seq_num & 1) != 0) {
-                                       DEBUG(0,("SCHANNEL ERROR: seq_num must be even in client (seq_num=%d)\n",
-                                                cli->auth_info.seq_num));
-                               }
-                               
                                DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num));
                                
                                init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes,
@@ -1573,9 +1571,6 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
                }
        }
        
-       /* doing schannel, not per-user auth */
-       cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
-       
        if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) {
                DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
                cli_close(cli, cli->nt_pipe_fnum);
@@ -1586,6 +1581,57 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
 }
 
 
+NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan,
+                            const uchar trust_password[16])
+{
+       NTSTATUS result;        
+       uint32 neg_flags = 0x000001ff;
+       cli->pipe_auth_flags = 0;
+
+       if (lp_client_schannel() == False) {
+               return NT_STATUS_OK;
+       }
+
+       if (!cli_nt_session_open(cli, PI_NETLOGON)) {
+               DEBUG(0, ("Could not initialise %s\n",
+                         get_pipe_name_from_index(PI_NETLOGON)));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (lp_client_schannel() != False)
+               neg_flags |= NETLOGON_NEG_SCHANNEL;
+
+       neg_flags |= NETLOGON_NEG_SCHANNEL;
+
+       result = cli_nt_setup_creds(cli, sec_chan, trust_password,
+                                   &neg_flags, 2);
+
+       if (!(neg_flags & NETLOGON_NEG_SCHANNEL) 
+           && lp_client_schannel() == True) {
+               DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n"));
+               result = NT_STATUS_UNSUCCESSFUL;
+       }
+
+       if (!NT_STATUS_IS_OK(result)) {
+               ZERO_STRUCT(cli->auth_info.sess_key);
+               ZERO_STRUCT(cli->sess_key);
+               cli->pipe_auth_flags = 0;
+               cli_nt_session_close(cli);
+               return result;
+       }
+
+       memcpy(cli->auth_info.sess_key, cli->sess_key,
+              sizeof(cli->auth_info.sess_key));
+
+       cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
+       cli->nt_pipe_fnum = 0;
+
+       /* doing schannel, not per-user auth */
+       cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
+
+       return NT_STATUS_OK;
+}
+
 const char *cli_pipe_get_name(struct cli_state *cli)
 {
        return cli->pipe_name;