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 struct smb_passwd *smb_pass = NULL;
236 memset(null_pwd, 0, sizeof(null_pwd));
238 DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
240 lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len;
241 nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len;
242 usr_len = l->ntlmssp_resp.hdr_usr .str_str_len;
243 dom_len = l->ntlmssp_resp.hdr_domain .str_str_len;
244 wks_len = l->ntlmssp_resp.hdr_wks .str_str_len;
246 if (lm_owf_len == 0 && nt_owf_len == 0 &&
247 usr_len == 0 && dom_len == 0 && wks_len == 0)
253 if (lm_owf_len == 0) return False;
254 if (nt_owf_len == 0) return False;
255 if (l->ntlmssp_resp.hdr_usr .str_str_len == 0) return False;
256 if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False;
257 if (l->ntlmssp_resp.hdr_wks .str_str_len == 0) return False;
260 if (lm_owf_len > sizeof(lm_owf)) return False;
261 if (nt_owf_len > sizeof(nt_owf)) return False;
263 memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf));
264 memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf));
266 #ifdef DEBUG_PASSWORD
267 DEBUG(100,("lm, nt owfs, chal\n"));
268 dump_data(100, lm_owf, sizeof(lm_owf));
269 dump_data(100, nt_owf, sizeof(nt_owf));
270 dump_data(100, l->ntlmssp_chal.challenge, 8);
273 memset(l->user_name, 0, sizeof(l->user_name));
274 memset(l->domain , 0, sizeof(l->domain ));
275 memset(l->wks , 0, sizeof(l->wks ));
277 if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
279 unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user,
280 MIN(l->ntlmssp_resp.hdr_usr .str_str_len/2,
281 sizeof(l->user_name)-1));
282 unibuf_to_ascii(l->domain , l->ntlmssp_resp.domain,
283 MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2,
284 sizeof(l->domain )-1));
285 unibuf_to_ascii(l->wks , l->ntlmssp_resp.wks,
286 MIN(l->ntlmssp_resp.hdr_wks .str_str_len/2,
291 fstrcpy(l->user_name, l->ntlmssp_resp.user );
292 fstrcpy(l->domain , l->ntlmssp_resp.domain);
293 fstrcpy(l->wks , l->ntlmssp_resp.wks );
299 DEBUG(5,("anonymous user session\n"));
300 mdfour(l->user_sess_key, null_pwd, 16);
302 l->ntlmssp_validated = True;
306 DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks));
308 smb_pass = getsmbpwnam(l->user_name);
309 l->ntlmssp_validated = pass_check_smb(smb_pass, l->domain,
310 (uchar*)l->ntlmssp_chal.challenge,
313 NULL, l->user_sess_key);
316 if (smb_pass != NULL)
318 pwd = smb_pass->smb_passwd;
322 if (l->ntlmssp_validated && pwd != NULL)
325 NTLMSSPOWFencrypt(pwd, lm_owf, p24);
337 for (ind = 0; ind < 256; ind++)
339 l->ntlmssp_hash[ind] = (unsigned char)ind;
342 for( ind = 0; ind < 256; ind++)
346 j += (l->ntlmssp_hash[ind] + k2[ind%8]);
348 tc = l->ntlmssp_hash[ind];
349 l->ntlmssp_hash[ind] = l->ntlmssp_hash[j];
350 l->ntlmssp_hash[j] = tc;
353 l->ntlmssp_hash[256] = 0;
354 l->ntlmssp_hash[257] = 0;
356 l->ntlmssp_seq_num = 0;
360 l->ntlmssp_validated = False;
363 return l->ntlmssp_validated;
366 static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd)
368 /* receive a negotiate; send a challenge; receive a response */
369 switch (l->auth_verifier.msg_type)
371 case NTLMSSP_NEGOTIATE:
373 smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0);
378 smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0);
379 if (!api_pipe_ntlmssp_verify(l))
387 /* NTLMSSP expected: unexpected message type */
388 DEBUG(3,("unexpected message type in NTLMSSP %d\n",
389 l->auth_verifier.msg_type));
394 return (pd->offset != 0);
399 char * pipe_clnt_name;
400 char * pipe_srv_name;
401 BOOL (*fn) (rpcsrv_struct *, prs_struct *);
404 static struct api_cmd **api_fd_commands = NULL;
407 static void api_cmd_free(struct api_cmd *item)
411 if (item->pipe_clnt_name != NULL)
413 free(item->pipe_clnt_name);
415 if (item->pipe_srv_name != NULL)
417 free(item->pipe_srv_name);
423 static struct api_cmd *api_cmd_dup(const struct api_cmd *from)
425 struct api_cmd *copy = NULL;
430 copy = (struct api_cmd *) malloc(sizeof(struct api_cmd));
434 if (from->pipe_clnt_name != NULL)
436 copy->pipe_clnt_name = strdup(from->pipe_clnt_name );
438 if (from->pipe_srv_name != NULL)
440 copy->pipe_srv_name = strdup(from->pipe_srv_name);
442 if (from->fn != NULL)
450 static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries)
452 void(*fn)(void*) = (void(*)(void*))&api_cmd_free;
453 free_void_array(num_entries, (void**)entries, *fn);
456 static struct api_cmd* add_api_cmd_to_array(uint32 *len,
457 struct api_cmd ***array,
458 const struct api_cmd *name)
460 void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup;
461 return (struct api_cmd*)add_copy_to_array(len,
462 (void***)array, (const void*)name, *fn, False);
468 { "lsarpc", "lsass", api_ntlsa_rpc },
469 { "samr", "lsass", api_samr_rpc },
470 { "srvsvc", "ntsvcs", api_srvsvc_rpc },
471 { "wkssvc", "ntsvcs", api_wkssvc_rpc },
472 { "browser", "ntsvcs", api_brs_rpc },
473 { "svcctl", "ntsvcs", api_svcctl_rpc },
474 { "NETLOGON", "lsass", api_netlog_rpc },
475 { "winreg", "winreg", api_reg_rpc },
476 { "spoolss", "spoolss", api_spoolss_rpc },
481 void close_msrpc_command_processor(void)
483 free_api_cmd_array(num_cmds, api_fd_commands);
486 void add_msrpc_command_processor(char* pipe_name,
488 BOOL (*fn) (rpcsrv_struct *, prs_struct *))
491 cmd.pipe_clnt_name = pipe_name;
492 cmd.pipe_srv_name = process_name;
495 add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
498 static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd)
500 DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
502 if (l->hdr.auth_len == 0) return False;
504 /* decode the authentication verifier response */
505 smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0);
506 if (pd->offset == 0) return False;
508 if (!rpc_hdr_auth_chk(&(l->auth_info))) return False;
510 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
511 if (pd->offset == 0) return False;
513 if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
515 return api_pipe_ntlmssp(l, pd);
518 static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status)
520 DEBUG(5,("api_pipe_fault_resp: make response\n"));
522 prs_init(&(l->rhdr ), 0x18, 4, 0, False);
523 prs_init(&(l->rfault ), 0x8 , 4, 0, False);
526 /*** set up the header, response header and fault status ***/
529 l->hdr_fault.status = status;
530 l->hdr_fault.reserved = 0x0;
532 l->hdr_resp.alloc_hint = 0x0;
533 l->hdr_resp.cancel_count = 0x0;
534 l->hdr_resp.reserved = 0x0;
536 make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
541 smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0);
542 smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0);
543 smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0);
544 mem_realloc_data(l->rhdr.data, l->rhdr.offset);
545 mem_realloc_data(l->rfault.data, l->rfault.offset);
548 /*** link rpc header and fault together ***/
551 prs_link(NULL , &l->rhdr , &l->rfault);
552 prs_link(&l->rhdr, &l->rfault, NULL );
557 static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
558 const char* ack_pipe_name,
559 enum RPC_PKT_TYPE pkt_type)
563 l->ntlmssp_auth = False;
565 /* decode the bind request */
566 smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0);
568 if (pd->offset == 0) return False;
570 if (l->hdr.auth_len != 0)
572 /* decode the authentication verifier */
573 smb_io_rpc_hdr_auth ("", &l->auth_info , pd, 0);
574 if (pd->offset == 0) return False;
576 l->ntlmssp_auth = l->auth_info.auth_type = 0x0a;
580 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0);
581 if (pd->offset == 0) return False;
583 l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP");
588 if (!api_pipe_ntlmssp(l, pd)) return False;
592 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
594 prs_init(&(l->rdata), 1024, 4, 0, False);
595 prs_init(&(l->rhdr ), 0x18, 4, 0, False);
596 prs_init(&(l->rauth), 1024, 4, 0, False);
597 prs_init(&(l->rverf), 0x08, 4, 0, False);
598 prs_init(&(l->rntlm), 1024, 4, 0, False);
601 /*** do the bind ack first ***/
610 assoc_gid = l->hdr_rb.bba.assoc_gid;
613 make_rpc_hdr_ba(&l->hdr_ba,
614 l->hdr_rb.bba.max_tsize,
615 l->hdr_rb.bba.max_rsize,
619 &(l->hdr_rb.transfer));
621 smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0);
622 mem_realloc_data(l->rdata.data, l->rdata.offset);
625 /*** now the authentication ***/
631 generate_random_buffer(challenge, 8, False);
633 /*** authentication info ***/
635 make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1);
636 smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0);
637 mem_realloc_data(l->rverf.data, l->rverf.offset);
639 /*** NTLMSSP verifier ***/
641 make_rpc_auth_ntlmssp_verifier(&l->auth_verifier,
642 "NTLMSSP", NTLMSSP_CHALLENGE);
643 smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0);
644 mem_realloc_data(l->rauth.data, l->rauth.offset);
646 /* NTLMSSP challenge ***/
648 make_rpc_auth_ntlmssp_chal(&l->ntlmssp_chal,
649 0x000082b1, challenge);
650 smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0);
651 mem_realloc_data(l->rntlm.data, l->rntlm.offset);
655 /*** then do the header, now we know the length ***/
658 make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
660 l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10,
661 l->rauth.offset + l->rntlm.offset);
663 smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0);
664 mem_realloc_data(l->rhdr.data, l->rdata.offset);
667 /*** link rpc header, bind acknowledgment and authentication responses ***/
672 prs_link(NULL , &l->rhdr , &l->rdata);
673 prs_link(&l->rhdr , &l->rdata, &l->rverf);
674 prs_link(&l->rdata, &l->rverf, &l->rauth);
675 prs_link(&l->rverf, &l->rauth, &l->rntlm);
676 prs_link(&l->rauth, &l->rntlm, NULL );
680 prs_link(NULL , &l->rhdr , &l->rdata);
681 prs_link(&l->rhdr, &l->rdata, NULL );
687 static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd,
689 enum RPC_PKT_TYPE pkt_type)
691 fstring ack_pipe_name;
692 fstring pipe_srv_name;
695 DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
697 for (i = 0; i < num_cmds; i++)
699 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
700 api_fd_commands[i]->fn != NULL)
702 DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
703 api_fd_commands[i]->pipe_clnt_name,
704 api_fd_commands[i]->pipe_srv_name));
705 fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name);
710 if (api_fd_commands[i]->fn == NULL) return False;
716 /* name has to be \PIPE\xxxxx */
717 fstrcpy(ack_pipe_name, "\\PIPE\\");
718 fstrcat(ack_pipe_name, pipe_srv_name);
721 case RPC_ALTCONTRESP:
723 /* secondary address CAN be NULL
724 * as the specs says it's ignored.
725 * It MUST NULL to have the spoolss working.
727 fstrcpy(ack_pipe_name, "");
735 return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type);
739 * The RPC Alter-Context call is used only by the spoolss pipe
740 * simply because there is a bug (?) in the MS unmarshalling code
741 * or in the marshalling code. If it's in the later, then Samba
744 static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd,
747 return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK);
750 static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd,
753 return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP);
756 static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd)
758 BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
759 BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
765 auth_len = l->hdr.auth_len;
767 if (auth_len != 16 && auth_verify)
772 data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
774 DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
775 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
779 char *data = mem_data(&pd->data, pd->offset);
780 DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
781 NTLMSSPcalc_p(l, (uchar*)data, data_len);
782 crc32 = crc32_calc_buffer(data_len, data);
785 /*** skip the data, record the offset so we can restore it again */
786 old_offset = pd->offset;
788 if (auth_seal || auth_verify)
790 pd->offset += data_len;
791 smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0);
796 char *req_data = mem_data(&pd->data, pd->offset + 4);
797 DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
798 NTLMSSPcalc_p(l, (uchar*)req_data, 12);
799 smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0);
801 if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32,
808 pd->offset = old_offset;
813 static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name)
817 if (l->ntlmssp_auth && l->ntlmssp_validated)
819 if (!api_pipe_auth_process(l, pd)) return False;
821 DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n"));
827 for (i = 0; i < num_cmds; i++)
829 if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
830 api_fd_commands[i]->fn != NULL)
832 DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name));
833 return api_fd_commands[i]->fn(l, pd);
839 BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len)
847 if (ps->data == NULL)
849 DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len));
850 prs_init(ps, len, 4, 0, True);
853 if (ps->data == NULL)
860 prev_size = ps->data->data_used;
861 new_size = prev_size + len;
862 DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n",
863 prev_size, new_size));
864 if (!mem_realloc_data(ps->data, new_size))
870 DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start));
871 ps->data->offset.start = 0x0;
873 to = mem_data(&ps->data, prev_size);
876 DEBUG(10,("rpc_add_to_pdu: data could not be found\n"));
879 if (ps->data->data_used != new_size)
881 DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n",
882 ps->data->data_used, new_size));
885 memcpy(to, data, len);
889 static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp)
891 DEBUG(10,("rpc_redirect\n"));
893 if (!msrpc_send_prs(p->m, req))
895 DEBUG(2,("msrpc redirect send failed\n"));
898 if (!msrpc_receive_prs(p->m, resp))
900 DEBUG(2,("msrpc redirect receive failed\n"));
903 prs_link(NULL, resp, NULL);
904 prs_debug_out(resp, "redirect", 100);
908 static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp,
913 if (req->data == NULL) return False;
915 /* lkclXXXX still assume that the first complete PDU is always
916 in a single request!!!
918 /* process the rpc header */
920 smb_io_rpc_hdr("", &l->hdr, req, 0);
922 if (req->offset == 0) return False;
924 switch (l->hdr.pkt_type)
928 reply = api_pipe_bind_req(l, req, name);
933 reply = api_pipe_alt_req(l, req, name);
938 if (l->ntlmssp_auth && !l->ntlmssp_validated)
940 /* authentication _was_ requested
941 and it failed. sorry, no deal!
947 /* read the rpc header */
948 smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0);
949 reply = api_pipe_request(l, req, name);
953 case RPC_BINDRESP: /* not the real name! */
955 reply = api_pipe_bind_auth_resp(l, req);
956 l->ntlmssp_auth = reply;
963 reply = api_pipe_fault_resp(l, req, 0x1c010002);
968 /* flatten the data into a single pdu */
969 reply = prs_copy(resp, &l->rhdr);
972 /* delete intermediate data used to set up the pdu. leave
973 rdata alone because that's got the rest of the data in it */
979 BOOL rpc_send_and_rcv_pdu(pipes_struct *p)
981 DEBUG(10,("rpc_send_and_rcv_pdu\n"));
985 return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu);
987 else if (p->l != NULL)
989 return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu,
995 /*******************************************************************
996 entry point from msrpc to smb. adds data received to pdu; checks
997 pdu; hands pdu off to msrpc, which gets a pdu back (except in the
998 case of the RPC_BINDCONT pdu).
999 ********************************************************************/
1000 BOOL rpc_to_smb(pipes_struct *p, char *data, int len)
1002 BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len);
1004 if (reply && is_complete_pdu(&p->smb_pdu))
1006 p->smb_pdu.offset = p->smb_pdu.data->data_size;
1007 prs_link(NULL, &p->smb_pdu, NULL);
1008 reply = rpc_send_and_rcv_pdu(p);
1009 mem_free_data(p->smb_pdu.data);
1010 prs_init(&p->smb_pdu, 0, 4, 0, True);
1016 /*******************************************************************
1017 receives a netlogon pipe and responds.
1018 ********************************************************************/
1019 static BOOL api_rpc_command(rpcsrv_struct *l,
1020 char *rpc_name, struct api_struct *api_rpc_cmds,
1024 DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum));
1026 for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
1028 if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL)
1030 DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
1035 if (api_rpc_cmds[fn_num].name == NULL)
1037 DEBUG(4, ("unknown\n"));
1041 /* start off with 1024 bytes, and a large safety margin too */
1042 prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False);
1044 /* do the actual command */
1045 api_rpc_cmds[fn_num].fn(l, data, &(l->rdata));
1047 if (l->rdata.data == NULL || l->rdata.offset == 0)
1049 mem_free_data(l->rdata.data);
1053 mem_realloc_data(l->rdata.data, l->rdata.offset);
1055 DEBUG(10,("called %s\n", rpc_name));
1061 /*******************************************************************
1062 receives a netlogon pipe and responds.
1063 ********************************************************************/
1064 BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds,
1067 if (data == NULL || data->data == NULL)
1069 DEBUG(2,("%s: NULL data received\n", rpc_name));
1073 /* interpret the command */
1074 if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data))
1079 /* create the rpc header */
1080 if (!create_rpc_reply(l, 0))
1088 BOOL is_complete_pdu(prs_struct *ps)
1091 int len = ps->data->data_size;
1093 DEBUG(10,("is_complete_pdu - len %d\n", len));
1098 /* writing. oops!! */
1099 DEBUG(4,("is_complete_pdu: write set, not read!\n"));
1103 if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0))
1107 /* check that the fragment length is equal to the data length so far */
1108 return hdr.frag_len == len;