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 1997-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.
25 /* this module apparently provides an implementation of DCE/RPC over a
26 * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
27 * documentation are available (in on-line form) from the X-Open group.
29 * this module should provide a level of abstraction between SMB
30 * and DCE/RPC, while minimising the amount of mallocs, unnecessary
31 * data copies, and network traffic.
33 * in this version, which takes a "let's learn what's going on and
34 * get something running" approach, there is additional network
35 * traffic generated, but the code should be easier to understand...
37 * ... if you read the docs. or stare at packets for weeks on end.
44 extern int DEBUGLEVEL;
46 static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len)
48 unsigned char *hash = p->ntlmssp_hash;
49 unsigned char index_i = hash[256];
50 unsigned char index_j = hash[257];
53 for( ind = 0; ind < len; ind++)
59 index_j += hash[index_i];
62 hash[index_i] = hash[index_j];
65 t = hash[index_i] + hash[index_j];
66 data[ind] = data[ind] ^ hash[t];
73 /*******************************************************************
74 frees all temporary data used in construction of pdu
75 ********************************************************************/
76 void rpcsrv_free_temp(rpcsrv_struct *l)
78 mem_free_data(l->rhdr .data);
79 mem_free_data(l->rfault .data);
80 mem_free_data(l->rdata_i.data);
81 mem_free_data(l->rauth .data);
82 mem_free_data(l->rverf .data);
83 mem_free_data(l->rntlm .data);
86 /*******************************************************************
87 turns a DCE/RPC request into a DCE/RPC reply
89 this is where the data really should be split up into an array of
90 headers and data sections.
92 ********************************************************************/
93 BOOL create_rpc_reply(rpcsrv_struct *l, uint32 data_start)
96 BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
97 BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
100 uint32 data_end = l->rdata.offset + (l->ntlmssp_auth ? (8 + 16) : 0);
102 DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
103 data_start, data_end, l->hdr_ba.bba.max_tsize));
105 auth_len = l->hdr.auth_len;
109 DEBUG(10,("create_rpc_reply: auth\n"));
116 prs_init(&l->rhdr , 0x18, 4, 0, False);
117 prs_init(&l->rauth, 1024, 4, 0, False);
118 prs_init(&l->rverf, 0x10, 4, 0, False);
120 l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
122 /* set up rpc header (fragmentation issues) */
125 l->hdr.flags = RPC_FLG_FIRST;
132 l->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
134 if (l->hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
136 l->hdr.flags |= RPC_FLG_LAST;
137 l->hdr.frag_len = l->hdr_resp.alloc_hint + 0x18;
141 l->hdr.frag_len = l->hdr_ba.bba.max_tsize;
146 l->hdr_resp.alloc_hint -= auth_len + 8;
151 data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
155 data_len = l->hdr.frag_len - 0x18;
158 l->rhdr.data->offset.start = 0;
159 l->rhdr.data->offset.end = 0x18;
161 /* store the header in the data stream */
162 smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0);
163 smb_io_rpc_hdr_resp("resp", &(l->hdr_resp), &(l->rhdr), 0);
165 /* don't use rdata: use rdata_i instead, which moves... */
166 /* make a pointer to the rdata data, NOT A COPY */
168 l->rdata_i.data = NULL;
169 prs_init(&l->rdata_i, 0, l->rdata.align, l->rdata.data->margin, l->rdata.io);
170 data = mem_data(&(l->rdata.data), data_start);
171 mem_create(l->rdata_i.data, data, 0, data_len, 0, False);
172 l->rdata_i.offset = data_len;
178 DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n",
179 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
183 crc32 = crc32_calc_buffer(data_len, data);
184 NTLMSSPcalc_p(l, (uchar*)data, data_len);
187 if (auth_seal || auth_verify)
189 make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
190 smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, &l->rauth, 0);
196 l->ntlmssp_seq_num++;
197 make_rpc_auth_ntlmssp_chk(&l->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, l->ntlmssp_seq_num++);
198 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), &l->rverf, 0);
199 auth_data = mem_data(&l->rverf.data, 4);
200 NTLMSSPcalc_p(l, (uchar*)auth_data, 12);
204 /* set up the data chain */
207 prs_link(NULL , &l->rhdr , &l->rdata_i);
208 prs_link(&l->rhdr , &l->rdata_i, &l->rauth );
209 prs_link(&l->rdata_i, &l->rauth , &l->rverf );
210 prs_link(&l->rauth , &l->rverf , NULL );
214 prs_link(NULL , &l->rhdr , &l->rdata_i);
215 prs_link(&l->rhdr, &l->rdata_i, NULL );
218 return l->rhdr.data != NULL && l->rhdr.offset == 0x18;
221 static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l)
232 BOOL anonymous = False;
234 memset(null_pwd, 0, sizeof(null_pwd));
236 DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
238 lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len;
239 nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len;
240 usr_len = l->ntlmssp_resp.hdr_usr .str_str_len;
241 dom_len = l->ntlmssp_resp.hdr_domain .str_str_len;
242 wks_len = l->ntlmssp_resp.hdr_wks .str_str_len;
244 if (lm_owf_len == 0 && nt_owf_len == 0 &&
245 usr_len == 0 && dom_len == 0 && wks_len == 0)
251 if (lm_owf_len == 0) return False;
252 if (nt_owf_len == 0) return False;
253 if (l->ntlmssp_resp.hdr_usr .str_str_len == 0) return False;
254 if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False;
255 if (l->ntlmssp_resp.hdr_wks .str_str_len == 0) return False;
258 if (lm_owf_len > sizeof(lm_owf)) return False;
259 if (nt_owf_len > sizeof(nt_owf)) return False;
261 memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf));
262 memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf));
264 #ifdef DEBUG_PASSWORD
265 DEBUG(100,("lm, nt owfs, chal\n"));
266 dump_data(100, lm_owf, sizeof(lm_owf));
267 dump_data(100, nt_owf, sizeof(nt_owf));
268 dump_data(100, l->ntlmssp_chal.challenge, 8);
271 memset(l->user_name, 0, sizeof(l->user_name));
272 memset(l->domain , 0, sizeof(l->domain ));
273 memset(l->wks , 0, sizeof(l->wks ));
275 if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
277 unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user,
278 MIN(l->ntlmssp_resp.hdr_usr .str_str_len/2,
279 sizeof(l->user_name)-1));
280 unibuf_to_ascii(l->domain , l->ntlmssp_resp.domain,
281 MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2,
282 sizeof(l->domain )-1));
283 unibuf_to_ascii(l->wks , l->ntlmssp_resp.wks,
284 MIN(l->ntlmssp_resp.hdr_wks .str_str_len/2,
289 fstrcpy(l->user_name, l->ntlmssp_resp.user );
290 fstrcpy(l->domain , l->ntlmssp_resp.domain);
291 fstrcpy(l->wks , l->ntlmssp_resp.wks );
297 DEBUG(5,("anonymous user session\n"));
298 mdfour(l->user_sess_key, null_pwd, 16);
300 l->ntlmssp_validated = True;
304 DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks));
306 l->ntlmssp_validated = check_domain_security(l->user_name, l->domain,
307 (uchar*)l->ntlmssp_chal.challenge,
311 unbecome_root(False);
314 if (l->ntlmssp_validated && pwd != NULL)
317 NTLMSSPOWFencrypt(pwd, lm_owf, p24);
329 for (ind = 0; ind < 256; ind++)
331 l->ntlmssp_hash[ind] = (unsigned char)ind;
334 for( ind = 0; ind < 256; ind++)
338 j += (l->ntlmssp_hash[ind] + k2[ind%8]);
340 tc = l->ntlmssp_hash[ind];
341 l->ntlmssp_hash[ind] = l->ntlmssp_hash[j];
342 l->ntlmssp_hash[j] = tc;
345 l->ntlmssp_hash[256] = 0;
346 l->ntlmssp_hash[257] = 0;
348 l->ntlmssp_seq_num = 0;
352 l->ntlmssp_validated = False;
355 return l->ntlmssp_validated;
358 static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd)
360 /* receive a negotiate; send a challenge; receive a response */
361 switch (l->auth_verifier.msg_type)
363 case NTLMSSP_NEGOTIATE:
365 smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0);
370 smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0);
371 if (!api_pipe_ntlmssp_verify(l))
379 /* NTLMSSP expected: unexpected message type */
380 DEBUG(3,("unexpected message type in NTLMSSP %d\n",
381 l->auth_verifier.msg_type));
386 return (pd->offset != 0);
391 char * pipe_clnt_name;
392 char * pipe_srv_name;
393 BOOL (*fn) (rpcsrv_struct *, prs_struct *);
396 static struct api_cmd **api_fd_commands = NULL;
399 static void api_cmd_free(struct api_cmd *item)
403 if (item->pipe_clnt_name != NULL)
405 free(item->pipe_clnt_name);
407 if (item->pipe_srv_name != NULL)
409 free(item->pipe_srv_name);
415 static struct api_cmd *api_cmd_dup(const struct api_cmd *from)
417 struct api_cmd *copy = NULL;
422 copy = (struct api_cmd *) malloc(sizeof(struct api_cmd));
426 if (from->pipe_clnt_name != NULL)
428 copy->pipe_clnt_name = strdup(from->pipe_clnt_name );
430 if (from->pipe_srv_name != NULL)
432 copy->pipe_srv_name = strdup(from->pipe_srv_name);
434 if (from->fn != NULL)
442 static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries)
444 void(*fn)(void*) = (void(*)(void*))&api_cmd_free;
445 free_void_array(num_entries, (void**)entries, *fn);
448 static struct api_cmd* add_api_cmd_to_array(uint32 *len,
449 struct api_cmd ***array,
450 const struct api_cmd *name)
452 void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup;
453 return (struct api_cmd*)add_copy_to_array(len,
454 (void***)array, (const void*)name, *fn, False);
459 void close_msrpc_command_processor(void)
461 free_api_cmd_array(num_cmds, api_fd_commands);
464 void add_msrpc_command_processor(char* pipe_name,
466 BOOL (*fn) (rpcsrv_struct *, prs_struct *))
469 cmd.pipe_clnt_name = pipe_name;
470 cmd.pipe_srv_name = process_name;
473 add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
476 static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd)
478 DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
480 if (l->hdr.auth_len == 0) return False;
482 /* decode the authentication verifier response */
483 smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0);
484 if (pd->offset == 0) return False;
486 if (!rpc_hdr_auth_chk(&(l->auth_info))) return False;
488 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
489 if (pd->offset == 0) return False;
491 if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
493 return api_pipe_ntlmssp(l, pd);
496 static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status)
498 DEBUG(5,("api_pipe_fault_resp: make response\n"));
500 prs_init(&(l->rhdr ), 0x18, 4, 0, False);
501 prs_init(&(l->rfault ), 0x8 , 4, 0, False);
504 /*** set up the header, response header and fault status ***/
507 l->hdr_fault.status = status;
508 l->hdr_fault.reserved = 0x0;
510 l->hdr_resp.alloc_hint = 0x0;
511 l->hdr_resp.cancel_count = 0x0;
512 l->hdr_resp.reserved = 0x0;
514 make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
519 smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0);
520 smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0);
521 smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0);
522 mem_realloc_data(l->rhdr.data, l->rhdr.offset);
523 mem_realloc_data(l->rfault.data, l->rfault.offset);
526 /*** link rpc header and fault together ***/
529 prs_link(NULL , &l->rhdr , &l->rfault);
530 prs_link(&l->rhdr, &l->rfault, NULL );
535 static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
536 const char* ack_pipe_name,
537 enum RPC_PKT_TYPE pkt_type)
541 l->ntlmssp_auth = False;
543 /* decode the bind request */
544 smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0);
546 if (pd->offset == 0) return False;
548 if (l->hdr.auth_len != 0)
550 /* decode the authentication verifier */
551 smb_io_rpc_hdr_auth ("", &l->auth_info , pd, 0);
552 if (pd->offset == 0) return False;
554 l->ntlmssp_auth = l->auth_info.auth_type = 0x0a;
558 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
559 if (pd->offset == 0) return False;
561 l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP");
566 if (!api_pipe_ntlmssp(l, pd)) return False;
570 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
572 prs_init(&(l->rdata), 1024, 4, 0, False);
573 prs_init(&(l->rhdr ), 0x18, 4, 0, False);
574 prs_init(&(l->rauth), 1024, 4, 0, False);
575 prs_init(&(l->rverf), 0x08, 4, 0, False);
576 prs_init(&(l->rntlm), 1024, 4, 0, False);
579 /*** do the bind ack first ***/
588 assoc_gid = l->hdr_rb.bba.assoc_gid;
591 make_rpc_hdr_ba(&l->hdr_ba,
592 l->hdr_rb.bba.max_tsize,
593 l->hdr_rb.bba.max_rsize,
597 &(l->hdr_rb.transfer));
599 smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0);
600 mem_realloc_data(l->rdata.data, l->rdata.offset);
603 /*** now the authentication ***/
609 generate_random_buffer(challenge, 8, False);
611 /*** authentication info ***/
613 make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1);
614 smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0);
615 mem_realloc_data(l->rverf.data, l->rverf.offset);
617 /*** NTLMSSP verifier ***/
619 make_rpc_auth_ntlmssp_verifier(&l->auth_verifier,
620 "NTLMSSP", NTLMSSP_CHALLENGE);
621 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0);
622 mem_realloc_data(l->rauth.data, l->rauth.offset);
624 /* NTLMSSP challenge ***/
626 make_rpc_auth_ntlmssp_chal(&l->ntlmssp_chal,
627 0x000082b1, challenge);
628 smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0);
629 mem_realloc_data(l->rntlm.data, l->rntlm.offset);
633 /*** then do the header, now we know the length ***/
636 make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
638 l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10,
639 l->rauth.offset + l->rntlm.offset);
641 smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0);
642 mem_realloc_data(l->rhdr.data, l->rdata.offset);
645 /*** link rpc header, bind acknowledgment and authentication responses ***/
650 prs_link(NULL , &l->rhdr , &l->rdata);
651 prs_link(&l->rhdr , &l->rdata, &l->rverf);
652 prs_link(&l->rdata, &l->rverf, &l->rauth);
653 prs_link(&l->rverf, &l->rauth, &l->rntlm);
654 prs_link(&l->rauth, &l->rntlm, NULL );
658 prs_link(NULL , &l->rhdr , &l->rdata);
659 prs_link(&l->rhdr, &l->rdata, NULL );
665 static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
667 enum RPC_PKT_TYPE pkt_type)
669 fstring ack_pipe_name;
670 fstring pipe_srv_name;
673 DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
675 for (i = 0; i < num_cmds; i++)
677 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
678 api_fd_commands[i]->fn != NULL)
680 DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
681 api_fd_commands[i]->pipe_clnt_name,
682 api_fd_commands[i]->pipe_srv_name));
683 fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name);
688 if (api_fd_commands[i]->fn == NULL) return False;
694 /* name has to be \PIPE\xxxxx */
695 fstrcpy(ack_pipe_name, "\\PIPE\\");
696 fstrcat(ack_pipe_name, pipe_srv_name);
699 case RPC_ALTCONTRESP:
701 /* secondary address CAN be NULL
702 * as the specs says it's ignored.
703 * It MUST NULL to have the spoolss working.
705 fstrcpy(ack_pipe_name, "");
713 return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type);
717 * The RPC Alter-Context call is used only by the spoolss pipe
718 * simply because there is a bug (?) in the MS unmarshalling code
719 * or in the marshalling code. If it's in the later, then Samba
722 static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd,
725 return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK);
728 static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd,
731 return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP);
734 static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd)
736 BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
737 BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
743 auth_len = l->hdr.auth_len;
745 if (auth_len != 16 && auth_verify)
750 data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
752 DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
753 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
757 char *data = mem_data(&pd->data, pd->offset);
758 DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
759 NTLMSSPcalc_p(l, (uchar*)data, data_len);
760 crc32 = crc32_calc_buffer(data_len, data);
763 /*** skip the data, record the offset so we can restore it again */
764 old_offset = pd->offset;
766 if (auth_seal || auth_verify)
768 pd->offset += data_len;
769 smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0);
774 char *req_data = mem_data(&pd->data, pd->offset + 4);
775 DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
776 NTLMSSPcalc_p(l, (uchar*)req_data, 12);
777 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0);
779 if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32,
786 pd->offset = old_offset;
791 static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name)
795 if (l->ntlmssp_auth && l->ntlmssp_validated)
797 if (!api_pipe_auth_process(l, pd)) return False;
799 DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
805 for (i = 0; i < num_cmds; i++)
807 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
808 api_fd_commands[i]->fn != NULL)
810 DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name));
811 return api_fd_commands[i]->fn(l, pd);
817 BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len)
825 if (ps->data == NULL)
827 DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len));
828 prs_init(ps, len, 4, 0, True);
831 if (ps->data == NULL)
838 prev_size = ps->data->data_used;
839 new_size = prev_size + len;
840 DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n",
841 prev_size, new_size));
842 if (!mem_realloc_data(ps->data, new_size))
848 DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start));
849 ps->data->offset.start = 0x0;
851 to = mem_data(&ps->data, prev_size);
854 DEBUG(10,("rpc_add_to_pdu: data could not be found\n"));
857 if (ps->data->data_used != new_size)
859 DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n",
860 ps->data->data_used, new_size));
863 memcpy(to, data, len);
867 static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp)
869 DEBUG(10,("rpc_redirect\n"));
871 if (!msrpc_send_prs(p->m, req))
873 DEBUG(2,("msrpc redirect send failed\n"));
876 if (!msrpc_receive_prs(p->m, resp))
878 DEBUG(2,("msrpc redirect receive failed\n"));
881 prs_link(NULL, resp, NULL);
882 prs_debug_out(resp, "redirect", 100);
886 static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp,
891 if (req->data == NULL) return False;
893 /* lkclXXXX still assume that the first complete PDU is always
894 in a single request!!!
896 /* process the rpc header */
898 smb_io_rpc_hdr("", &l->hdr, req, 0);
900 if (req->offset == 0) return False;
902 switch (l->hdr.pkt_type)
906 reply = api_pipe_bind_req(l, req, name);
911 reply = api_pipe_alt_req(l, req, name);
916 if (l->ntlmssp_auth && !l->ntlmssp_validated)
918 /* authentication _was_ requested
919 and it failed. sorry, no deal!
925 /* read the rpc header */
926 smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0);
927 reply = api_pipe_request(l, req, name);
931 case RPC_BINDRESP: /* not the real name! */
933 reply = api_pipe_bind_auth_resp(l, req);
934 l->ntlmssp_auth = reply;
941 reply = api_pipe_fault_resp(l, req, 0x1c010002);
946 /* flatten the data into a single pdu */
947 reply = prs_copy(resp, &l->rhdr);
950 /* delete intermediate data used to set up the pdu. leave
951 rdata alone because that's got the rest of the data in it */
957 BOOL rpc_send_and_rcv_pdu(pipes_struct *p)
959 DEBUG(10,("rpc_send_and_rcv_pdu\n"));
963 return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu);
965 else if (p->l != NULL)
967 return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu,
973 /*******************************************************************
974 entry point from msrpc to smb. adds data received to pdu; checks
975 pdu; hands pdu off to msrpc, which gets a pdu back (except in the
976 case of the RPC_BINDCONT pdu).
977 ********************************************************************/
978 BOOL rpc_to_smb(pipes_struct *p, char *data, int len)
980 BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len);
982 if (reply && is_complete_pdu(&p->smb_pdu))
984 p->smb_pdu.offset = p->smb_pdu.data->data_size;
985 prs_link(NULL, &p->smb_pdu, NULL);
986 reply = rpc_send_and_rcv_pdu(p);
987 mem_free_data(p->smb_pdu.data);
988 prs_init(&p->smb_pdu, 0, 4, 0, True);
994 /*******************************************************************
995 receives a netlogon pipe and responds.
996 ********************************************************************/
997 static BOOL api_rpc_command(rpcsrv_struct *l,
998 char *rpc_name, struct api_struct *api_rpc_cmds,
1002 DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum));
1004 for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
1006 if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL)
1008 DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
1013 if (api_rpc_cmds[fn_num].name == NULL)
1015 DEBUG(4, ("unknown\n"));
1019 /* start off with 1024 bytes, and a large safety margin too */
1020 prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False);
1022 /* do the actual command */
1023 api_rpc_cmds[fn_num].fn(l, data, &(l->rdata));
1025 if (l->rdata.data == NULL || l->rdata.offset == 0)
1027 mem_free_data(l->rdata.data);
1031 mem_realloc_data(l->rdata.data, l->rdata.offset);
1033 DEBUG(10,("called %s\n", rpc_name));
1039 /*******************************************************************
1040 receives a netlogon pipe and responds.
1041 ********************************************************************/
1042 BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds,
1045 if (data == NULL || data->data == NULL)
1047 DEBUG(2,("%s: NULL data received\n", rpc_name));
1051 /* interpret the command */
1052 if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data))
1057 /* create the rpc header */
1058 if (!create_rpc_reply(l, 0))
1066 BOOL is_complete_pdu(prs_struct *ps)
1069 int len = ps->data->data_size;
1071 DEBUG(10,("is_complete_pdu - len %d\n", len));
1076 /* writing. oops!! */
1077 DEBUG(4,("is_complete_pdu: write set, not read!\n"));
1081 if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0))
1085 /* check that the fragment length is equal to the data length so far */
1086 return hdr.frag_len == len;