missed some of Derrel's changes
[samba.git] / source3 / rpc_client / cli_pipe.c
index 2229a9f2cfa3093326cfe5796e37b37416507599..82a4b21754e63e0ccffb76b9cd9e7137aff816a0 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
@@ -28,7 +29,9 @@
 
 extern struct pipe_id_info pipe_names[];
 
-static void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) 
+/* convert pipe auth flags into the RPC auth type and level */
+
+void get_auth_type_level(int pipe_auth_flags, int *auth_type, int *auth_level) 
 {
        *auth_type = 0;
        *auth_level = 0;
@@ -185,6 +188,10 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
 
        RPC_HDR_AUTH rhdr_auth; 
 
+       char *dp = prs_data_p(rdata) + fragment_start + len -
+               RPC_HDR_AUTH_LEN - auth_len;
+       prs_struct auth_verf;
+
        *pauth_padding_len = 0;
 
        if (auth_len == 0) {
@@ -204,30 +211,29 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
                 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), 
                 BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL)));
 
-       {
-               int auth_type;
-               int auth_level;
-               char *dp = prs_data_p(rdata) + fragment_start + len -
-                                       RPC_HDR_AUTH_LEN - auth_len;
-               prs_struct auth_verf;
-
-               if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-                       DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
-                       return False;
-               }
-
-               DEBUG(10,("rpc_auth_pipe: packet:\n"));
-               dump_data(100, dp, auth_len);
-
-               prs_init(&auth_verf, RPC_HDR_AUTH_LEN, cli->mem_ctx, UNMARSHALL);
-
-               /* The endinness must be preserved. JRA. */
-               prs_set_endian_data( &auth_verf, rdata->bigendian_data);
+       if (dp - prs_data_p(rdata) > prs_data_size(rdata)) {
+               DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n"));
+               return False;
+       }
 
-               prs_copy_data_in(&auth_verf, dp, RPC_HDR_AUTH_LEN);
-               prs_set_offset(&auth_verf, 0);
+       DEBUG(10,("rpc_auth_pipe: packet:\n"));
+       dump_data(100, dp, auth_len);
 
+       prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL);
+       
+       /* The endinness must be preserved. JRA. */
+       prs_set_endian_data( &auth_verf, rdata->bigendian_data);
+       
+       /* Point this new parse struct at the auth section of the main 
+          parse struct - rather than copying it.  Avoids needing to
+          free it on every error
+       */
+       prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */);
+       prs_set_offset(&auth_verf, 0);
 
+       {
+               int auth_type;
+               int auth_level;
                if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) {
                        DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n"));
                        return False;
@@ -254,20 +260,24 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
 
        if (pkt_type == RPC_BINDACK) {
                if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
-                       char *dp = prs_data_p(rdata) + len - auth_len;
-                       
-                       if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-                               DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
-                               return False;
-                       }
-                       
+                       /* copy the next auth_len bytes into a buffer for 
+                          later use */
+
+                       DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
+                       BOOL store_ok;
+
                        /* save the reply away, for use a little later */
-                       return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, 
-                                                                             data_blob(dp, auth_len))));
-               }
-               if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
-                       /* nothing to do here - we don't seem to be able to validate the
-                          bindack based on VL's comments */
+                       prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len);
+
+                       store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, 
+                                                                          ntlmssp_verf)));
+
+                       data_blob_free(&ntlmssp_verf);
+                       return store_ok;
+               } 
+               else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
+                       /* nothing to do here - we don't seem to be able to 
+                          validate the bindack based on VL's comments */
                        return True;
                }
        }
@@ -277,19 +287,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
                DATA_BLOB sig;
                if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) ||
                    (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) {
-                       char *dp = prs_data_p(rdata) + len - auth_len;
-                       
-                       if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-                               DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
-                               return False;
-                       }
-                       
                        if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) {
                                DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len));
                                return False;
                        }
-                       
-                       sig = data_blob(dp, auth_len);
+                       sig = data_blob(NULL, auth_len);
+                       prs_copy_data_out((char *)sig.data, &auth_verf, auth_len);
                }
        
                /*
@@ -307,13 +310,13 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
                                DEBUG(1, ("Can't unseal - data_len < 0!!\n"));
                                return False;
                        }
-                       nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, 
-                                                    reply_data, data_len,
-                                                    &sig);
+                       nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state, 
+                                                                (unsigned char *)reply_data, data_len,
+                                                                &sig);
                } 
                else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
-                       nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, 
-                                                               reply_data, data_len,
+                       nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state, 
+                                                               (const unsigned char *)reply_data, data_len,
                                                                &sig);
                }
 
@@ -328,34 +331,16 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
 
        if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
                RPC_AUTH_NETSEC_CHK chk;
-               prs_struct netsec_verf;
-
-               char *dp = prs_data_p(rdata) + len - auth_len;
-               
-               if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
-                       DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
-                       return False;
-               }
 
                if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
                        DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len));
                        return False;
                }
 
-               prs_init(&netsec_verf, RPC_AUTH_NETSEC_CHK_LEN, 
-                        cli->mem_ctx, UNMARSHALL);
-
-               /* The endinness must be preserved. JRA. */
-               prs_set_endian_data( &netsec_verf, rdata->bigendian_data);
-
-               prs_copy_data_in(&netsec_verf, dp, auth_len);
-               prs_set_offset(&netsec_verf, 0);
-
                if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", 
-                                               &chk, &netsec_verf, 0)) {
+                                               &chk, &auth_verf, 0)) {
                        DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling "
                                  "RPC_AUTH_NETSECK_CHK failed\n"));
-                       prs_mem_free(&netsec_verf);
                        return False;
                }
 
@@ -364,13 +349,11 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
                                   SENDER_IS_ACCEPTOR,
                                   &chk, reply_data, data_len)) {
                        DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n"));
-                       prs_mem_free(&netsec_verf);
                        return False;
                }
 
                cli->auth_info.seq_num++;
 
-               prs_mem_free(&netsec_verf);
        }
        return True;
 }
@@ -660,7 +643,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 */
@@ -694,9 +677,9 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
                DATA_BLOB request;
 
                DEBUG(5, ("Processing NTLMSSP Negotiate\n"));
-               nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state,
-                                                 null_blob,
-                                                 &request);
+               nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
+                                          null_blob,
+                                          &request);
 
                if (!NT_STATUS_EQUAL(nt_status, 
                                     NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -706,21 +689,22 @@ 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 = request.length;
-               prs_copy_data_in(&auth_info, request.data, request.length);
+               prs_copy_data_in(&auth_info, (char *)request.data, request.length);
 
                DEBUG(5, ("NTLMSSP Negotiate:\n"));
-               dump_data(5, request.data, request.length);
+               dump_data(5, (const char *)request.data, request.length);
 
                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);
 
@@ -738,7 +722,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);
@@ -771,6 +756,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
                        return NT_STATUS_NO_MEMORY;
                }
        }
+       prs_mem_free(&auth_info);
        return NT_STATUS_OK;
 }
 
@@ -794,9 +780,9 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli,
 
        /* The response is picked up from the internal cache,
           where it was placed by the rpc_auth_pipe() code */
-       nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state,
-                                         ntlmssp_null_response,
-                                         &ntlmssp_reply);
+       nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
+                                  ntlmssp_null_response,
+                                  &ntlmssp_reply);
        
        if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                return nt_status;
@@ -830,20 +816,12 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli,
         * Append the auth data to the outgoing buffer.
         */
 
-       if(!prs_copy_data_in(rpc_out, ntlmssp_reply.data, ntlmssp_reply.length)) {
+       if(!prs_copy_data_in(rpc_out, (char *)ntlmssp_reply.data, ntlmssp_reply.length)) {
                DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
                data_blob_free(&ntlmssp_reply);
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
-               nt_status = ntlmssp_client_sign_init(cli->ntlmssp_pipe_state);
-               
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       return nt_status;
-               }
-       }
-
        data_blob_free(&ntlmssp_reply);
        return NT_STATUS_OK;
 }
@@ -957,7 +935,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                uint32 data_len, send_size;
                uint8 flags = 0;
                uint32 auth_padding = 0;
-               RPC_AUTH_NETSEC_CHK verf;
                DATA_BLOB sign_blob;
 
                /*
@@ -1012,7 +989,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                                 */
                                if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
                                        
-                                       nt_status = ntlmssp_client_seal_packet(cli->ntlmssp_pipe_state,
+                                       nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state,
                                                                               (unsigned char*)prs_data_p(&sec_blob),
                                                                               data_and_padding_size,
                                                                               &sign_blob);
@@ -1023,7 +1000,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                                } 
                                else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
                                        
-                                       nt_status = ntlmssp_client_sign_packet(cli->ntlmssp_pipe_state,
+                                       nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state,
                                                                               (unsigned char*)prs_data_p(&sec_blob),
                                                                               data_and_padding_size, &sign_blob);
                                        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1036,24 +1013,15 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                                /* write auth footer onto the packet */
                                real_auth_len = sign_blob.length;
                                
-                               prs_copy_data_in(&sec_blob, sign_blob.data, sign_blob.length);
+                               prs_copy_data_in(&sec_blob, (char *)sign_blob.data, sign_blob.length);
                                data_blob_free(&sign_blob);
 
                        }
                        else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {     
-                               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));
-                               }
-                               
+                               RPC_AUTH_NETSEC_CHK verf;
                                DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num));
                                
-                               init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes,
-                                                        nullbytes, nullbytes);
-                               
                                netsec_encode(&cli->auth_info, 
                                              cli->pipe_auth_flags,
                                              SENDER_IS_INITIATOR,
@@ -1255,10 +1223,12 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC
 {
        int i = 0;
 
+# if 0 /* JERRY -- apparently ASU forgets to fill in the server pipe name sometimes */
        if ( hdr_ba->addr.len <= 0)
                return False;
                
-       if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe )) 
+       if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
+            !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
        {
                DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
                         pipe_names[i].server_pipe ,hdr_ba->addr.str));
@@ -1271,6 +1241,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC
                DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
                return False;
        }
+#endif         /* JERRY */
 
        /* check the transfer syntax */
        if ((hdr_ba->transfer.version != transfer->version) ||
@@ -1301,8 +1272,10 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
        prs_init(&rpc_out, RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN, /* need at least this much */ 
                 cli->mem_ctx, MARSHALL);
 
-       create_rpc_bind_resp(cli, rpc_call_id,
-                            &rpc_out);
+       if (!NT_STATUS_IS_OK(create_rpc_bind_resp(cli, rpc_call_id,
+                                                 &rpc_out))) {
+               return False;
+       }
 
        if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out), 
                        0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
@@ -1357,6 +1330,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
                if (!NT_STATUS_IS_OK(nt_status))
                        return False;
 
+               /* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */
+
+               cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
+
                nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state, 
                                                 cli->user_name);
                if (!NT_STATUS_IS_OK(nt_status))
@@ -1367,11 +1344,18 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
                if (!NT_STATUS_IS_OK(nt_status))
                        return False;
 
-               pwd_get_cleartext(&cli->pwd, password);
-               nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, 
-                                                password);
-               if (!NT_STATUS_IS_OK(nt_status))
-                       return False;
+               if (cli->pwd.null_pwd) {
+                       nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, 
+                                                        NULL);
+                       if (!NT_STATUS_IS_OK(nt_status))
+                               return False;
+               } else {
+                       pwd_get_cleartext(&cli->pwd, password);
+                       nt_status = ntlmssp_set_password(cli->ntlmssp_pipe_state, 
+                                                        password);
+                       if (!NT_STATUS_IS_OK(nt_status))
+                               return False;
+               }
 
                if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
                        cli->ntlmssp_pipe_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -1459,7 +1443,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
                cli->nt_pipe_fnum = (uint16)fnum;
        } else {
                if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
-                       DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
+                       DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s.  Error was %s\n",
                                 pipe_names[pipe_idx].client_pipe, cli->desthost, cli_errstr(cli)));
                        return False;
                }
@@ -1484,6 +1468,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
                return False;
        }
 
+       cli->pipe_idx = pipe_idx;
+
        /* 
         * Setup the remote server name prefixed by \ and the machine account name.
         */
@@ -1517,7 +1503,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
                                   const uchar trust_password[16])
 {
        NTSTATUS result;        
-       uint32 neg_flags = 0x000001ff;
+       uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
        int fnum;
 
        cli_nt_netlogon_netsec_session_close(cli);
@@ -1596,9 +1582,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);
@@ -1609,6 +1592,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, int auth_flags,
+                            const uchar trust_password[16])
+{
+       NTSTATUS result;        
+       uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+       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_flags;
+
+       return NT_STATUS_OK;
+}
+
 const char *cli_pipe_get_name(struct cli_state *cli)
 {
        return cli->pipe_name;