cleaning up conflicts between group code not yet committed and
[samba.git] / source / rpc_client / cli_pipe.c
index 732161ad82270398537566698e5794c52ee946d4..cb93f61b2de142de0745594ae2702ec69377b1f0 100644 (file)
@@ -37,17 +37,12 @@ extern pstring global_myname;
 /********************************************************************
  rpc pipe call id 
  ********************************************************************/
-static uint32 call_id = 0;
 static uint32 get_rpc_call_id(void)
 {
+  static uint32 call_id = 0;
   return ++call_id;
 }
 
-static uint32 reset_rpc_call_id(void)
-{
-       call_id = 0;
-}
-
 /*******************************************************************
  uses SMBreadX to get rest of rpc data
  ********************************************************************/
@@ -56,15 +51,13 @@ static BOOL rpc_read(struct cli_state *cli,
                      prs_struct *rdata, uint32 data_to_read,
                      uint32 rdata_offset)
 {
-       int size = 0x1630;
+       int size = cli->max_recv_frag;
        int file_offset = rdata_offset;
        int num_read;
-       char *data = rdata->data->data;
+       char *data;
        uint32 err;
        uint32 new_data_size = rdata->data->data_used + data_to_read;
 
-       data += rdata_offset;
-
        file_offset -= rdata_offset;
 
        DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
@@ -76,6 +69,8 @@ static BOOL rpc_read(struct cli_state *cli,
                DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
        }
 
+       data = rdata->data->data + rdata_offset;
+
        do /* read data using SMBreadX */
        {
                if (size > data_to_read)
@@ -89,7 +84,7 @@ static BOOL rpc_read(struct cli_state *cli,
                        DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
                }
 
-               num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, size);
+               num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset, size);
 
                DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
                          file_offset, num_read, data_to_read));
@@ -106,22 +101,21 @@ static BOOL rpc_read(struct cli_state *cli,
        mem_realloc_data(rdata->data, file_offset + rdata_offset);
        rdata->data->offset.end = file_offset + rdata_offset;
 
-       DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read));
+       DEBUG(5,("rpc_read: offset end: 0x%x.  data left to read:0x%x\n",
+                 rdata->data->offset.end, data_to_read));
 
-       return data_to_read == 0;
+       return True;
 }
 
 /****************************************************************************
  checks the header
  ****************************************************************************/
-static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type,
+static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr, 
                           BOOL *first, BOOL *last, int *len)
 {
-       RPC_HDR    rhdr;
-
        DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used));
 
-       smb_io_rpc_hdr   ("rpc_hdr   ", &rhdr   , rdata, 0);
+       smb_io_rpc_hdr   ("rpc_hdr   ", rhdr   , rdata, 0);
 
        if (!rdata->offset || rdata->offset != 0x10)
        {
@@ -132,14 +126,113 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type,
        DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n",
                  rdata->data->data_used));
 
-       (*first   ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
-       (*last    ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
-       (*len     ) = rhdr.frag_len - rdata->data->data_used;
-       (*pkt_type) = rhdr.pkt_type;
+       (*first   ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST);
+       (*last    ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST );
+       (*len     ) = rhdr->frag_len - rdata->data->data_used;
+
+       return rhdr->pkt_type != RPC_FAULT;
+}
+
+static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, int len)
+{
+       unsigned char *hash = cli->ntlmssp_hash;
+    unsigned char index_i = hash[256];
+    unsigned char index_j = hash[257];
+    int ind;
+
+    for( ind = 0; ind < len; ind++)
+    {
+        unsigned char tc;
+        unsigned char t;
+
+        index_i++;
+        index_j += hash[index_i];
+
+        tc = hash[index_i];
+        hash[index_i] = hash[index_j];
+        hash[index_j] = tc;
+
+        t = hash[index_i] + hash[index_j];
+        data[ind] = data[ind] ^ hash[t];
+    }
+
+    hash[256] = index_i;
+    hash[257] = index_j;
+}
+
+/****************************************************************************
+ decrypt data on an rpc pipe
+ ****************************************************************************/
+
+static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
+                               int len, int auth_len)
+{
+       RPC_AUTH_NTLMSSP_CHK chk;
+       uint32 crc32;
+       int data_len = len - 0x18 - auth_len - 8;
+       char *reply_data = mem_data(&rdata->data, 0x18);
+
+       BOOL auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
+       BOOL auth_seal   = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
+
+       DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
+                 len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
+
+       if (reply_data == NULL) return False;
+
+       if (auth_seal)
+       {
+               DEBUG(10,("rpc_auth_pipe: seal\n"));
+               dump_data(100, reply_data, data_len);
+               NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len);
+               dump_data(100, reply_data, data_len);
+       }
+
+       if (auth_verify || auth_seal)
+       {
+               RPC_HDR_AUTH         rhdr_auth; 
+               prs_struct auth_req;
+               char *data = mem_data(&rdata->data, len - auth_len - 8);
+               prs_init(&auth_req , 0x08, 4, 0, True);
+               memcpy(auth_req.data->data, data, 8);
+               smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0);
+               prs_mem_free(&auth_req);
+
+               if (!rpc_hdr_auth_chk(&rhdr_auth))
+               {
+                       return False;
+               }
+       }
 
+       if (auth_verify)
+       {
+               prs_struct auth_verf;
+               char *data = mem_data(&rdata->data, len - auth_len);
+               if (data == NULL) return False;
+
+               DEBUG(10,("rpc_auth_pipe: verify\n"));
+               dump_data(100, data, auth_len);
+               NTLMSSPcalc_ap(cli, (uchar*)(data+4), auth_len - 4);
+               prs_init(&auth_verf, 0x08, 4, 0, True);
+               memcpy(auth_verf.data->data, data, 16);
+               smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
+               dump_data(100, data, auth_len);
+               prs_mem_free(&auth_verf);
+       }
+
+       if (auth_verify)
+       {
+               crc32 = crc32_calc_buffer(data_len, reply_data);
+               if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num))
+               {
+                       return False;
+               }
+               cli->ntlmssp_seq_num++;
+       }
        return True;
 }
 
+
 /****************************************************************************
  send data on an rpc pipe, which *must* be in one fragment.
  receive response data from an rpc pipe, which may be large...
@@ -166,9 +259,9 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd,
 
        uint16 setup[2]; /* only need 2 uint16 setup parameters */
        uint32 err;
-       uint8 pkt_type = 0xff;
        BOOL first = True;
        BOOL last  = True;
+       RPC_HDR    rhdr;
 
        /*
        * Setup the pointers from the incoming.
@@ -191,6 +284,8 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd,
        setup[0] = cmd; 
        setup[1] = cli->nt_pipe_fnum; /* pipe file handle.  got this from an SMBOpenX. */
 
+       DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, cli->nt_pipe_fnum));
+
        /* send the data: receive a response. */
        if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
                  setup, 2, 0,                     /* Setup, length, max */
@@ -215,9 +310,22 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd,
        rdata->data->margin = 0;
        if (rparam) rparam->data->margin = 0;
 
-       if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len)) return False;
+       if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len))
+       {
+               return False;
+       }
 
-       if (pkt_type == RPC_RESPONSE)
+       if (rhdr.pkt_type == RPC_BINDACK)
+       {
+               if (!last && !first)
+               {
+                       DEBUG(5,("rpc_api_pipe: bug in AS/U, setting fragment first/last ON\n"));
+                       first = True;
+                       last = True;
+               }
+       }
+
+       if (rhdr.pkt_type == RPC_RESPONSE)
        {
                RPC_HDR_RESP rhdr_resp;
                smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
@@ -236,6 +344,11 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd,
                }
        }
 
+       if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
+       {
+               return False;
+       }
+
        /* only one rpc fragment, and it has been read */
        if (first && last)
        {
@@ -245,39 +358,43 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd,
 
        while (!last) /* read more fragments until we get the last one */
        {
-               RPC_HDR      rhdr;
                RPC_HDR_RESP rhdr_resp;
                int num_read;
                prs_struct hps;
 
-               prs_init(&hps, 0x18, 4, 0, True);
+               prs_init(&hps, 0x8, 4, 0, True);
 
                num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18);
                DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
 
                if (num_read != 0x18) return False;
 
-               smb_io_rpc_hdr     ("rpc_hdr     ", &rhdr     , &hps, 0);
+               if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
+               {
+                       return False;
+               }
+
                smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0);
 
                prs_mem_free(&hps);
 
                if (cli_error(cli, NULL, &err)) return False;
 
-               first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
-               last  = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
-
                if (first)
                {
                        DEBUG(0,("rpc_api_pipe: wierd rpc header received\n"));
                        return False;
                }
 
-               len = rhdr.frag_len - hps.offset;
                if (!rpc_read(cli, rdata, len, rdata->data->data_used))
                {
                        return False;
                }
+
+               if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
+               {
+                       return False;
+               }
        }
 
        return True;
@@ -296,7 +413,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr,
                                 prs_struct *rhdr_auth,
                                 prs_struct *auth_req,
                                 prs_struct *auth_ntlm,
-                               uint32 call_id,
+                               uint32 rpc_call_id,
                                 RPC_IFACE *abstract, RPC_IFACE *transfer,
                                 char *my_name, char *domain, uint32 neg_flags)
 {
@@ -316,7 +433,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr,
 
        if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL)
        {
-               make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00);
+               make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00, 1);
                smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0);
                mem_realloc_data(rhdr_auth->data, rhdr_auth->offset);
 
@@ -334,10 +451,13 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr,
        }
 
        /* create the request RPC_HDR */
-       make_rpc_hdr(&hdr, RPC_BIND, 0x0, call_id,
+       make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
+                    (auth_req  != NULL ? auth_req ->offset : 0) +
+                    (auth_ntlm != NULL ? auth_ntlm->offset : 0) +
+                    (rhdr_auth != NULL ? rhdr_auth->offset : 0) +
                     rhdr_rb->offset + 0x10,
-                    auth_req  != NULL ? auth_req ->offset : 0 +
-                    auth_ntlm != NULL ? auth_ntlm->offset : 0);
+                    (auth_req  != NULL ? auth_req ->offset : 0) +
+                    (auth_ntlm != NULL ? auth_ntlm->offset : 0));
 
        smb_io_rpc_hdr("hdr"   , &hdr   , rhdr, 0);
        mem_realloc_data(rhdr->data, rhdr->offset);
@@ -377,7 +497,7 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr,
 static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
                                char *domain, char *user_name, char *my_name,
                                uint32 ntlmssp_cli_flgs,
-                               uint32 call_id,
+                               uint32 rpc_call_id,
                                prs_struct *rhdr,
                                 prs_struct *rhdr_autha,
                                 prs_struct *auth_resp)
@@ -410,7 +530,7 @@ static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
        mem_realloc_data(auth_resp->data, auth_resp->offset);
 
        /* create the request RPC_HDR */
-       make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, call_id,
+       make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
                     auth_resp->offset + rhdr_autha->offset + 0x10,
                     auth_resp->offset);
 
@@ -505,7 +625,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
        auth_seal   = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
 
        /* happen to know that NTLMSSP authentication verifier is 16 bytes */
-       auth_len               = auth_verify ? 16 : 0;
+       auth_len               = (auth_verify ? 16 : 0);
        data_len               = data->offset + auth_len + (auth_verify ? 8 : 0) + 0x18;
        data->data->offset.end = data->offset;
 
@@ -519,20 +639,24 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
        if (auth_seal)
        {
                crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0));
-               NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&data->data, 0), data->offset);
+               NTLMSSPcalc_ap(cli, (uchar*)mem_data(&data->data, 0), data->offset);
        }
 
-       if (auth_verify)
+       if (auth_seal || auth_verify)
        {
-               RPC_AUTH_NTLMSSP_CHK chk;
                RPC_HDR_AUTH         rhdr_auth;
 
-               make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08);
+               make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
                smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
+       }
+
+       if (auth_verify)
+       {
+               RPC_AUTH_NTLMSSP_CHK chk;
 
-               make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, 0);
+               make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++);
                smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
-               NTLMSSPcalc(cli->ntlmssp_hash, mem_data(&auth_verf.data, 4), 12);
+               NTLMSSPcalc_ap(cli, (uchar*)mem_data(&auth_verf.data, 4), 12);
        }
 
        if (auth_seal || auth_verify)
@@ -653,7 +777,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *
 {
        int i = 0;
 
-       while ((pipe_names[i].client_pipe != NULL))
+       while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0)
        {
                DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
                pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
@@ -668,10 +792,10 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *
                        }
                        else
                        {
-                               DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n",
+                               DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
                                         pipe_names[i].server_pipe ,
                                         hdr_ba->addr.str));
-                               return False;
+                               break;
                        }
                }
                else
@@ -717,7 +841,6 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
        prs_struct hdr;
        prs_struct hdr_rb;
        prs_struct hdr_auth;
-       prs_struct hdr_autha;
        prs_struct auth_req;
        prs_struct auth_ntlm;
        prs_struct data;
@@ -726,7 +849,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
 
        BOOL valid_ack = False;
        BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0;
-       uint32 call_id;
+       uint32 rpc_call_id;
 
        if (pipe_name == NULL || abstract == NULL || transfer == NULL)
        {
@@ -737,21 +860,21 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
 
        if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
 
-       prs_init(&hdr      , 0x10                   , 4, 0x0          , False);
-       prs_init(&hdr_rb   , 1024                   , 4, SAFETY_MARGIN, False);
-       prs_init(&hdr_auth , ntlmssp_auth ?    8 : 0, 4, SAFETY_MARGIN, False);
-       prs_init(&auth_req , ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
-       prs_init(&auth_ntlm, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
+       prs_init(&hdr      , 0x10                     , 4, 0x0          , False);
+       prs_init(&hdr_rb   , 1024                     , 4, SAFETY_MARGIN, False);
+       prs_init(&hdr_auth , (ntlmssp_auth ?    8 : 0), 4, SAFETY_MARGIN, False);
+       prs_init(&auth_req , (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
+       prs_init(&auth_ntlm, (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
 
        prs_init(&rdata    , 0   , 4, SAFETY_MARGIN, True);
        prs_init(&rparam   , 0   , 4, SAFETY_MARGIN, True);
 
-       call_id = get_rpc_call_id();
+       rpc_call_id = get_rpc_call_id();
        create_rpc_bind_req(&hdr, &hdr_rb,
                            ntlmssp_auth ? &hdr_auth : NULL,
                            ntlmssp_auth ? &auth_req : NULL,
                            ntlmssp_auth ? &auth_ntlm : NULL,
-                           call_id,
+                           rpc_call_id,
                            abstract, transfer,
                            global_myname, cli->domain, cli->ntlmssp_cli_flgs);
 
@@ -776,6 +899,12 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
                        valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
                }
 
+               if (valid_ack)
+               {
+                       cli->max_xmit_frag = hdr_ba.bba.max_tsize;
+                       cli->max_recv_frag = hdr_ba.bba.max_rsize;
+               }
+
                if (valid_ack && ntlmssp_auth)
                {
                        smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0);
@@ -810,18 +939,48 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
                        prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
 
                        pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge);
-                       pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
-                       pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
-                       NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
-                       bzero(lm_hash, sizeof(lm_hash));
-                       NTLMSSPhash(cli->ntlmssp_hash, p24);
 
                        create_rpc_bind_resp(&cli->pwd, cli->domain,
                                             cli->user_name, global_myname, 
                                             cli->ntlmssp_cli_flgs,
-                                            call_id,
+                                            rpc_call_id,
                                             &hdra, &hdr_autha, &auth_resp);
                                            
+                       pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
+                       pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
+                       NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
+                       {
+                               unsigned char j = 0;
+                               int ind;
+                               unsigned char k2[8];
+
+                               memcpy(k2, p24, 5);
+                               k2[5] = 0xe5;
+                               k2[6] = 0x38;
+                               k2[7] = 0xb0;
+
+                               for (ind = 0; ind < 256; ind++)
+                               {
+                                       cli->ntlmssp_hash[ind] = (unsigned char)ind;
+                               }
+
+                               for( ind = 0; ind < 256; ind++)
+                               {
+                                       unsigned char tc;
+
+                                       j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
+
+                                       tc = cli->ntlmssp_hash[ind];
+                                       cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
+                                       cli->ntlmssp_hash[j] = tc;
+                               }
+
+                               cli->ntlmssp_hash[256] = 0;
+                               cli->ntlmssp_hash[257] = 0;
+                       }
+/*                     NTLMSSPhash(cli->ntlmssp_hash, p24); */
+                       bzero(lm_hash, sizeof(lm_hash));
+
                        /* this is a hack due to limitations in rpc_api_pipe */
                        prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
                        mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data));
@@ -854,23 +1013,29 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
        prs_mem_free(&rdata    );
        prs_mem_free(&rparam   );
 
-       reset_rpc_call_id();
-
        return valid_ack;
 }
 
+/****************************************************************************
+ set ntlmssp negotiation flags
+ ****************************************************************************/
+
+void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
+{
+       cli->ntlmssp_cli_flgs = ntlmssp_flgs;
+}
+
+
 /****************************************************************************
  open a session
  ****************************************************************************/
 
-BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted)
+BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
 {
        RPC_IFACE abstract;
        RPC_IFACE transfer;
        int fnum;
 
-       reset_rpc_call_id();
-
        /******************* open the pipe *****************/
        if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS))
        {
@@ -907,25 +1072,6 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name, BOOL encrypted)
 
        /******************* bind request on pipe *****************/
 
-       if (encrypted)
-       {
-               cli->ntlmssp_cli_flgs = 
-                                   NTLMSSP_NEGOTIATE_UNICODE |
-/*                                 NTLMSSP_NEGOTIATE_OEM |
- */
-                                   NTLMSSP_NEGOTIATE_SIGN |
-                                   NTLMSSP_NEGOTIATE_SEAL |
-                                   NTLMSSP_NEGOTIATE_LM_KEY |
-                                   NTLMSSP_NEGOTIATE_NTLM |
-                                   NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
-/*
-                                   NTLMSSP_NEGOTIATE_00001000 |
-                                   NTLMSSP_NEGOTIATE_00002000;
- */
-               DEBUG(5,("cli_nt_session_open: neg_flags: %lx\n",
-                        cli->ntlmssp_cli_flgs));
-       }
-
        if (!rpc_pipe_bind(cli, pipe_name,
                           &abstract, &transfer,
                           global_myname))