3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1998,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8 * Copyright (C) Paul Ashton 1998.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 extern int DEBUGLEVEL;
33 extern struct pipe_id_info pipe_names[];
34 extern fstring global_myworkgroup;
35 extern pstring global_myname;
37 /********************************************************************
39 ********************************************************************/
40 static uint32 get_rpc_call_id(void)
42 static uint32 call_id = 0;
46 /*******************************************************************
47 uses SMBreadX to get rest of rpc data
48 ********************************************************************/
50 static BOOL rpc_read(struct cli_state *cli,
51 prs_struct *rdata, uint32 data_to_read,
54 int size = cli->max_recv_frag;
55 int file_offset = rdata_offset;
59 uint32 new_data_size = rdata->data->data_used + data_to_read;
61 file_offset -= rdata_offset;
63 DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
64 data_to_read, rdata_offset, file_offset));
66 if (new_data_size > rdata->data->data_size)
68 mem_grow_data(&rdata->data, True, new_data_size, True);
69 DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
72 data = rdata->data->data + rdata_offset;
74 do /* read data using SMBreadX */
76 if (size > data_to_read)
79 new_data_size = rdata->data->data_used + size;
81 if (new_data_size > rdata->data->data_size)
83 mem_grow_data(&rdata->data, True, new_data_size, True);
84 DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
87 num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset, size);
89 DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
90 file_offset, num_read, data_to_read));
92 data_to_read -= num_read;
93 file_offset += num_read;
96 if (cli_error(cli, NULL, &err)) return False;
98 } while (num_read > 0 && data_to_read > 0);
99 /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
101 mem_realloc_data(rdata->data, file_offset + rdata_offset);
102 rdata->data->offset.end = file_offset + rdata_offset;
104 DEBUG(5,("rpc_read: offset end: 0x%x. data left to read:0x%x\n",
105 rdata->data->offset.end, data_to_read));
110 /****************************************************************************
112 ****************************************************************************/
113 static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr,
114 BOOL *first, BOOL *last, int *len)
116 DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used));
118 smb_io_rpc_hdr ("rpc_hdr ", rhdr , rdata, 0);
120 if (!rdata->offset || rdata->offset != 0x10)
122 DEBUG(0,("cli_pipe: error in rpc header\n"));
126 DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n",
127 rdata->data->data_used));
129 (*first ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST);
130 (*last ) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST );
131 (*len ) = rhdr->frag_len - rdata->data->data_used;
133 return rhdr->pkt_type != RPC_FAULT;
136 static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, int len)
138 unsigned char *hash = cli->ntlmssp_hash;
139 unsigned char index_i = hash[256];
140 unsigned char index_j = hash[257];
143 for( ind = 0; ind < len; ind++)
149 index_j += hash[index_i];
152 hash[index_i] = hash[index_j];
155 t = hash[index_i] + hash[index_j];
156 data[ind] = data[ind] ^ hash[t];
163 /****************************************************************************
164 decrypt data on an rpc pipe
165 ****************************************************************************/
167 static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
168 int len, int auth_len)
170 RPC_AUTH_NTLMSSP_CHK chk;
172 int data_len = len - 0x18 - auth_len - 8;
173 char *reply_data = mem_data(&rdata->data, 0x18);
175 BOOL auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
176 BOOL auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
178 DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
179 len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
181 if (reply_data == NULL) return False;
185 DEBUG(10,("rpc_auth_pipe: seal\n"));
186 dump_data(100, reply_data, data_len);
187 NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len);
188 dump_data(100, reply_data, data_len);
191 if (auth_verify || auth_seal)
193 RPC_HDR_AUTH rhdr_auth;
195 char *data = mem_data(&rdata->data, len - auth_len - 8);
196 prs_init(&auth_req , 0x08, 4, 0, True);
197 memcpy(auth_req.data->data, data, 8);
198 smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0);
199 prs_mem_free(&auth_req);
201 if (!rpc_hdr_auth_chk(&rhdr_auth))
209 prs_struct auth_verf;
210 char *data = mem_data(&rdata->data, len - auth_len);
211 if (data == NULL) return False;
213 DEBUG(10,("rpc_auth_pipe: verify\n"));
214 dump_data(100, data, auth_len);
215 NTLMSSPcalc_ap(cli, (uchar*)(data+4), auth_len - 4);
216 prs_init(&auth_verf, 0x08, 4, 0, True);
217 memcpy(auth_verf.data->data, data, 16);
218 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
219 dump_data(100, data, auth_len);
220 prs_mem_free(&auth_verf);
225 crc32 = crc32_calc_buffer(data_len, reply_data);
226 if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num))
230 cli->ntlmssp_seq_num++;
236 /****************************************************************************
237 send data on an rpc pipe, which *must* be in one fragment.
238 receive response data from an rpc pipe, which may be large...
240 read the first fragment: unfortunately have to use SMBtrans for the first
241 bit, then SMBreadX for subsequent bits.
243 if first fragment received also wasn't the last fragment, continue
244 getting fragments until we _do_ receive the last fragment.
246 [note: from a data abstraction viewpoint, this function is marginally
247 complicated by the return side of cli_api_pipe getting in the way
248 (i.e, the SMB header stuff). the proper way to do this is to split
249 cli_api_pipe down into receive / transmit. oh, and split cli_readx
250 down. in other words, state-based (kernel) techniques...]
252 ****************************************************************************/
254 static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd,
255 prs_struct *param , prs_struct *data,
256 prs_struct *rparam, prs_struct *rdata)
260 uint16 setup[2]; /* only need 2 uint16 setup parameters */
267 * Setup the pointers from the incoming.
269 char *pparams = param ? param->data->data : NULL;
270 int params_len = param ? param->data->data_used : 0;
271 char *pdata = data ? data->data->data : NULL;
272 int data_len = data ? data->data->data_used : 0;
275 * Setup the pointers to the outgoing.
277 char **pp_ret_params = rparam ? &rparam->data->data : NULL;
278 uint32 *p_ret_params_len = rparam ? &rparam->data->data_used : NULL;
280 char **pp_ret_data = rdata ? &rdata->data->data : NULL;
281 uint32 *p_ret_data_len = rdata ? &rdata->data->data_used : NULL;
283 /* create setup parameters. */
285 setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */
287 DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", cmd, cli->nt_pipe_fnum));
289 /* send the data: receive a response. */
290 if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
291 setup, 2, 0, /* Setup, length, max */
292 pparams, params_len, 0, /* Params, length, max */
293 pdata, data_len, 1024, /* data, length, max */
294 pp_ret_params, p_ret_params_len, /* return params, len */
295 pp_ret_data, p_ret_data_len)) /* return data, len */
297 DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli)));
301 if (rdata->data->data == NULL) return False;
303 /**** parse the header: check it's a response record */
305 rdata->data->offset.start = 0;
306 rdata->data->offset.end = rdata->data->data_used;
309 /* cli_api_pipe does an ordinary Realloc - we have no margins now. */
310 rdata->data->margin = 0;
311 if (rparam) rparam->data->margin = 0;
313 if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len))
318 if (rhdr.pkt_type == RPC_BINDACK)
322 DEBUG(5,("rpc_api_pipe: bug in AS/U, setting fragment first/last ON\n"));
328 if (rhdr.pkt_type == RPC_RESPONSE)
330 RPC_HDR_RESP rhdr_resp;
331 smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
334 DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n",
335 len, rdata->data->data_used));
337 /* check if data to be sent back was too large for one SMB. */
338 /* err status is only informational: the _real_ check is on the length */
339 if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
341 if (!rpc_read(cli, rdata, len, rdata->data->data_used))
347 if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
352 /* only one rpc fragment, and it has been read */
355 DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
359 while (!last) /* read more fragments until we get the last one */
361 RPC_HDR_RESP rhdr_resp;
365 prs_init(&hps, 0x8, 4, 0, True);
367 num_read = cli_read(cli, cli->nt_pipe_fnum, hps.data->data, 0, 0x18);
368 DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
370 if (num_read != 0x18) return False;
372 if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
377 smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0);
381 if (cli_error(cli, NULL, &err)) return False;
385 DEBUG(0,("rpc_api_pipe: wierd rpc header received\n"));
389 if (!rpc_read(cli, rdata, len, rdata->data->data_used))
394 if (rhdr.auth_len != 0 && !rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
403 /*******************************************************************
404 creates a DCE/RPC bind request
406 - initialises the parse structure.
407 - dynamically allocates the header data structure
408 - caller is expected to free the header data structure once used.
410 ********************************************************************/
411 static BOOL create_rpc_bind_req(prs_struct *rhdr,
413 prs_struct *rhdr_auth,
414 prs_struct *auth_req,
415 prs_struct *auth_ntlm,
417 RPC_IFACE *abstract, RPC_IFACE *transfer,
418 char *my_name, char *domain, uint32 neg_flags)
422 RPC_HDR_AUTH hdr_auth;
423 RPC_AUTH_VERIFIER auth_verifier;
424 RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
426 /* create the bind request RPC_HDR_RB */
427 make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0,
428 0x1, 0x0, 0x1, abstract, transfer);
430 /* stream the bind request data */
431 smb_io_rpc_hdr_rb("", &hdr_rb, rhdr_rb, 0);
432 mem_realloc_data(rhdr_rb->data, rhdr_rb->offset);
434 if (auth_req != NULL && rhdr_auth != NULL && auth_ntlm != NULL)
436 make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00, 1);
437 smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rhdr_auth, 0);
438 mem_realloc_data(rhdr_auth->data, rhdr_auth->offset);
440 make_rpc_auth_verifier(&auth_verifier,
441 "NTLMSSP", NTLMSSP_NEGOTIATE);
443 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0);
444 mem_realloc_data(auth_req->data, auth_req->offset);
446 make_rpc_auth_ntlmssp_neg(&ntlmssp_neg,
447 neg_flags, my_name, domain);
449 smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0);
450 mem_realloc_data(auth_req->data, auth_req->offset);
453 /* create the request RPC_HDR */
454 make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
455 (auth_req != NULL ? auth_req ->offset : 0) +
456 (auth_ntlm != NULL ? auth_ntlm->offset : 0) +
457 (rhdr_auth != NULL ? rhdr_auth->offset : 0) +
458 rhdr_rb->offset + 0x10,
459 (auth_req != NULL ? auth_req ->offset : 0) +
460 (auth_ntlm != NULL ? auth_ntlm->offset : 0));
462 smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0);
463 mem_realloc_data(rhdr->data, rhdr->offset);
465 if (rhdr->data == NULL || rhdr_rb->data == NULL) return False;
468 /*** link rpc header, bind acknowledgment and authentication responses ***/
471 if (auth_req != NULL)
473 prs_link(NULL , rhdr , rhdr_rb );
474 prs_link(rhdr , rhdr_rb , rhdr_auth);
475 prs_link(rhdr_rb , rhdr_auth , auth_req );
476 prs_link(rhdr_auth, auth_req , auth_ntlm);
477 prs_link(auth_req , auth_ntlm , NULL );
481 prs_link(NULL, rhdr , rhdr_rb);
482 prs_link(rhdr, rhdr_rb, NULL );
489 /*******************************************************************
490 creates a DCE/RPC bind authentication response
492 - initialises the parse structure.
493 - dynamically allocates the header data structure
494 - caller is expected to free the header data structure once used.
496 ********************************************************************/
497 static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
498 char *domain, char *user_name, char *my_name,
499 uint32 ntlmssp_cli_flgs,
502 prs_struct *rhdr_autha,
503 prs_struct *auth_resp)
505 unsigned char lm_owf[24];
506 unsigned char nt_owf[24];
508 RPC_HDR_AUTHA hdr_autha;
509 RPC_AUTH_VERIFIER auth_verifier;
510 RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
512 make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00);
513 smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0);
514 mem_realloc_data(rhdr_autha->data, rhdr_autha->offset);
516 make_rpc_auth_verifier(&auth_verifier,
517 "NTLMSSP", NTLMSSP_AUTH);
519 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0);
520 mem_realloc_data(auth_resp->data, auth_resp->offset);
522 pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf);
524 make_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
526 domain, user_name, my_name,
529 smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0);
530 mem_realloc_data(auth_resp->data, auth_resp->offset);
532 /* create the request RPC_HDR */
533 make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
534 auth_resp->offset + rhdr_autha->offset + 0x10,
537 smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0);
538 mem_realloc_data(rhdr->data, rhdr->offset);
540 if (rhdr->data == NULL || rhdr_autha->data == NULL) return False;
543 /*** link rpc header and authentication responses ***/
546 prs_link(NULL , rhdr , rhdr_autha);
547 prs_link(rhdr , rhdr_autha , auth_resp );
548 prs_link(rhdr_autha, auth_resp , NULL );
554 /*******************************************************************
555 creates a DCE/RPC bind request
557 - initialises the parse structure.
558 - dynamically allocates the header data structure
559 - caller is expected to free the header data structure once used.
561 ********************************************************************/
563 static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len,
570 DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
573 /* create the rpc header RPC_HDR */
574 make_rpc_hdr(&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
575 get_rpc_call_id(), data_len, auth_len);
579 alloc_hint = data_len - 0x18 - auth_len - 16;
583 alloc_hint = data_len - 0x18;
586 DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
587 data_len, auth_len, alloc_hint));
589 /* create the rpc request RPC_HDR_REQ */
590 make_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
593 smb_io_rpc_hdr ("hdr ", &hdr , rhdr, 0);
594 smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0);
596 if (rhdr->data == NULL || rhdr->offset != 0x18) return False;
598 rhdr->data->offset.start = 0;
599 rhdr->data->offset.end = rhdr->offset;
605 /****************************************************************************
606 send a request on an rpc pipe.
607 ****************************************************************************/
608 BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
609 prs_struct *data, prs_struct *rdata)
611 /* fudge this, at the moment: create the header; memcpy the data. oops. */
616 prs_struct auth_verf;
624 auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
625 auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
627 /* happen to know that NTLMSSP authentication verifier is 16 bytes */
628 auth_len = (auth_verify ? 16 : 0);
629 data_len = data->offset + auth_len + (auth_verify ? 8 : 0) + 0x18;
630 data->data->offset.end = data->offset;
632 prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False);
633 prs_init(&hdr_auth , 8 , 4, SAFETY_MARGIN, False);
634 prs_init(&auth_verf, auth_len, 4, SAFETY_MARGIN, False);
635 prs_init(&rparam , 0 , 4, 0 , True );
637 create_rpc_request(&hdr, op_num, data_len, auth_len);
641 crc32 = crc32_calc_buffer(data->offset, mem_data(&data->data, 0));
642 NTLMSSPcalc_ap(cli, (uchar*)mem_data(&data->data, 0), data->offset);
645 if (auth_seal || auth_verify)
647 RPC_HDR_AUTH rhdr_auth;
649 make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
650 smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
655 RPC_AUTH_NTLMSSP_CHK chk;
657 make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++);
658 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
659 NTLMSSPcalc_ap(cli, (uchar*)mem_data(&auth_verf.data, 4), 12);
662 if (auth_seal || auth_verify)
664 prs_link(NULL , &hdr , data );
665 prs_link(&hdr , data , &hdr_auth );
666 prs_link(data , &hdr_auth , &auth_verf);
667 prs_link(&hdr_auth, &auth_verf, NULL );
671 prs_link(NULL, &hdr, data);
672 prs_link(&hdr, data, NULL);
675 mem_realloc_data(hdr.data, data_len);
677 DEBUG(100,("data_len: %x data_calc_len: %x\n",
678 data_len, mem_buf_len(data->data)));
680 /* this is a hack due to limitations in rpc_api_pipe */
681 prs_init(&dataa, mem_buf_len(hdr.data), 4, 0x0, False);
682 mem_buf_copy(dataa.data->data, hdr.data, 0, mem_buf_len(hdr.data));
684 ret = rpc_api_pipe(cli, 0x0026, NULL, &dataa, &rparam, rdata);
686 prs_mem_free(&hdr_auth );
687 prs_mem_free(&auth_verf);
688 prs_mem_free(&rparam );
690 prs_mem_free(&dataa );
695 /****************************************************************************
697 ****************************************************************************/
699 static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state)
701 BOOL state_set = False;
703 uint16 setup[2]; /* only need 2 uint16 setup parameters */
706 uint32 rparam_len, rdata_len;
708 if (pipe_name == NULL) return False;
710 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
711 cli->nt_pipe_fnum, pipe_name, device_state));
713 /* create parameters: device state */
714 SSVAL(param, 0, device_state);
716 /* create setup parameters. */
718 setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */
720 /* send the data on \PIPE\ */
721 if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
722 setup, 2, 0, /* setup, length, max */
723 param, 2, 0, /* param, length, max */
724 NULL, 0, 1024, /* data, length, max */
725 &rparam, &rparam_len, /* return param, length */
726 &rdata, &rdata_len)) /* return data, length */
728 DEBUG(5, ("Set Handle state: return OK\n"));
732 if (rparam) free(rparam);
733 if (rdata ) free(rdata );
738 /****************************************************************************
739 check the rpc bind acknowledge response
740 ****************************************************************************/
742 static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
746 while (pipe_names[pipe_idx].client_pipe != NULL)
748 if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe ))
750 DEBUG(5,("Bind Abstract Syntax: "));
751 dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax),
752 sizeof(pipe_names[pipe_idx].abstr_syntax));
753 DEBUG(5,("Bind Transfer Syntax: "));
754 dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
755 sizeof(pipe_names[pipe_idx].trans_syntax));
757 /* copy the required syntaxes out so we can do the right bind */
758 memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax),
759 sizeof(pipe_names[pipe_idx].trans_syntax));
760 memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax),
761 sizeof(pipe_names[pipe_idx].abstr_syntax));
768 DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
772 /****************************************************************************
773 check the rpc bind acknowledge response
774 ****************************************************************************/
776 static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
780 while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0)
782 DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
783 pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
785 if ((strequal(pipe_name, pipe_names[i].client_pipe )))
787 if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe ))
789 DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
790 pipe_names[i].server_pipe ));
795 DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
796 pipe_names[i].server_pipe ,
807 if (pipe_names[i].server_pipe == NULL)
809 DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
813 /* check the transfer syntax */
814 if (!((hdr_ba->transfer.version == transfer->version) &&
815 (memcmp(hdr_ba->transfer.data, transfer->data,
816 sizeof(transfer->version)) ==0)))
818 DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
822 /* lkclXXXX only accept one result: check the result(s) */
823 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
825 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
826 hdr_ba->res.num_results, hdr_ba->res.reason));
829 DEBUG(5,("bind_rpc_pipe: accepted!\n"));
833 /****************************************************************************
835 ****************************************************************************/
837 static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name,
838 RPC_IFACE *abstract, RPC_IFACE *transfer,
845 prs_struct auth_ntlm;
850 BOOL valid_ack = False;
851 BOOL ntlmssp_auth = cli->ntlmssp_cli_flgs != 0;
854 if (pipe_name == NULL || abstract == NULL || transfer == NULL)
859 DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
861 if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
863 prs_init(&hdr , 0x10 , 4, 0x0 , False);
864 prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False);
865 prs_init(&hdr_auth , (ntlmssp_auth ? 8 : 0), 4, SAFETY_MARGIN, False);
866 prs_init(&auth_req , (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
867 prs_init(&auth_ntlm, (ntlmssp_auth ? 1024 : 0), 4, SAFETY_MARGIN, False);
869 prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True);
870 prs_init(&rparam , 0 , 4, SAFETY_MARGIN, True);
872 rpc_call_id = get_rpc_call_id();
873 create_rpc_bind_req(&hdr, &hdr_rb,
874 ntlmssp_auth ? &hdr_auth : NULL,
875 ntlmssp_auth ? &auth_req : NULL,
876 ntlmssp_auth ? &auth_ntlm : NULL,
879 global_myname, cli->domain, cli->ntlmssp_cli_flgs);
881 /* this is a hack due to limitations in rpc_api_pipe */
882 prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
883 mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
885 /* send data on \PIPE\. receive a response */
886 if (rpc_api_pipe(cli, 0x0026, NULL, &data, &rparam, &rdata))
889 RPC_HDR_AUTH rhdr_auth;
890 RPC_AUTH_VERIFIER rhdr_verf;
891 RPC_AUTH_NTLMSSP_CHAL rhdr_chal;
893 DEBUG(5, ("rpc_api_pipe: return OK\n"));
895 smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
897 if (rdata.offset != 0)
899 valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
904 cli->max_xmit_frag = hdr_ba.bba.max_tsize;
905 cli->max_recv_frag = hdr_ba.bba.max_rsize;
908 if (valid_ack && ntlmssp_auth)
910 smb_io_rpc_hdr_auth("", &rhdr_auth, &rdata, 0);
911 if (rdata.offset == 0) valid_ack = False;
914 if (valid_ack && ntlmssp_auth)
916 smb_io_rpc_auth_verifier("", &rhdr_verf, &rdata, 0);
917 if (rdata.offset == 0) valid_ack = False;
919 if (valid_ack && ntlmssp_auth)
921 smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, &rdata, 0);
922 if (rdata.offset == 0) valid_ack = False;
924 if (valid_ack && ntlmssp_auth)
926 unsigned char p24[24];
927 unsigned char lm_owf[24];
928 unsigned char lm_hash[16];
931 prs_struct hdr_autha;
932 prs_struct auth_resp;
935 cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
937 prs_init(&hdra , 0x10, 4, 0x0 , False);
938 prs_init(&hdr_autha, 1024, 4, SAFETY_MARGIN, False);
939 prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
941 pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge);
943 create_rpc_bind_resp(&cli->pwd, cli->domain,
944 cli->user_name, global_myname,
945 cli->ntlmssp_cli_flgs,
947 &hdra, &hdr_autha, &auth_resp);
949 pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
950 pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
951 NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
962 for (ind = 0; ind < 256; ind++)
964 cli->ntlmssp_hash[ind] = (unsigned char)ind;
967 for( ind = 0; ind < 256; ind++)
971 j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
973 tc = cli->ntlmssp_hash[ind];
974 cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
975 cli->ntlmssp_hash[j] = tc;
978 cli->ntlmssp_hash[256] = 0;
979 cli->ntlmssp_hash[257] = 0;
981 /* NTLMSSPhash(cli->ntlmssp_hash, p24); */
982 bzero(lm_hash, sizeof(lm_hash));
984 /* this is a hack due to limitations in rpc_api_pipe */
985 prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
986 mem_buf_copy(dataa.data->data, hdra.data, 0, mem_buf_len(hdra.data));
988 if (cli_write(cli, cli->nt_pipe_fnum, 0x0008,
990 dataa.data->data_used) < 0)
997 cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
1000 prs_mem_free(&hdra);
1001 prs_mem_free(&dataa);
1002 prs_mem_free(&hdr_autha);
1003 prs_mem_free(&auth_resp);
1007 prs_mem_free(&data );
1008 prs_mem_free(&hdr );
1009 prs_mem_free(&hdr_rb );
1010 prs_mem_free(&hdr_auth );
1011 prs_mem_free(&auth_req );
1012 prs_mem_free(&auth_ntlm);
1013 prs_mem_free(&rdata );
1014 prs_mem_free(&rparam );
1019 /****************************************************************************
1020 set ntlmssp negotiation flags
1021 ****************************************************************************/
1023 void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
1025 cli->ntlmssp_cli_flgs = ntlmssp_flgs;
1029 /****************************************************************************
1031 ****************************************************************************/
1033 BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
1039 /******************* open the pipe *****************/
1040 if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS))
1042 if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1)
1044 DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n",
1045 &(pipe_name[5]), cli->desthost, cli_errstr(cli)));
1049 cli->nt_pipe_fnum = (uint16)fnum;
1053 if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1)
1055 DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n",
1056 pipe_name, cli->desthost, cli_errstr(cli)));
1060 cli->nt_pipe_fnum = (uint16)fnum;
1062 /**************** Set Named Pipe State ***************/
1063 if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300))
1065 DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n",
1067 cli_close(cli, cli->nt_pipe_fnum);
1073 /******************* bind request on pipe *****************/
1075 if (!rpc_pipe_bind(cli, pipe_name,
1076 &abstract, &transfer,
1079 DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
1081 cli_close(cli, cli->nt_pipe_fnum);
1086 * Setup the remote server name prefixed by \ and the machine account name.
1089 fstrcpy(cli->srv_name_slash, "\\\\");
1090 fstrcat(cli->srv_name_slash, cli->desthost);
1091 strupper(cli->srv_name_slash);
1093 fstrcpy(cli->clnt_name_slash, "\\\\");
1094 fstrcat(cli->clnt_name_slash, global_myname);
1095 strupper(cli->clnt_name_slash);
1097 fstrcpy(cli->mach_acct, global_myname);
1098 fstrcat(cli->mach_acct, "$");
1099 strupper(cli->mach_acct);
1104 /****************************************************************************
1106 ****************************************************************************/
1108 void cli_nt_session_close(struct cli_state *cli)
1110 cli_close(cli, cli->nt_pipe_fnum);