2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1998
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
6 * Copyright (C) Paul Ashton 1997-1998,
7 * Copyright (C) Jeremy Allison 1999,
8 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
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 #define DBGC_CLASS DBGC_RPC_SRV
46 /*************************************************************
48 We need to transfer the session key from one rpc bind to the
49 next. This is the way the netlogon schannel works.
50 **************************************************************/
51 struct dcinfo last_dcinfo;
53 static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
55 unsigned char *hash = p->ntlmssp_hash;
56 unsigned char index_i = hash[256];
57 unsigned char index_j = hash[257];
60 for( ind = 0; ind < len; ind++) {
65 index_j += hash[index_i];
68 hash[index_i] = hash[index_j];
71 t = hash[index_i] + hash[index_j];
72 data[ind] = data[ind] ^ hash[t];
79 /*******************************************************************
80 Generate the next PDU to be returned from the data in p->rdata.
81 We cheat here as this function doesn't handle the special auth
82 footers of the authenticated bind response reply.
83 ********************************************************************/
85 BOOL create_next_pdu(pipes_struct *p)
87 RPC_HDR_RESP hdr_resp;
88 BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
89 BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
91 uint32 data_space_available;
93 prs_struct outgoing_pdu;
97 * If we're in the fault state, keep returning fault PDU's until
98 * the pipe gets closed. JRA.
102 setup_fault_pdu(p, NT_STATUS(0x1c010002));
106 memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
108 /* Change the incoming request header to a response. */
109 p->hdr.pkt_type = RPC_RESPONSE;
111 /* Set up rpc header flags. */
112 if (p->out_data.data_sent_length == 0)
113 p->hdr.flags = RPC_FLG_FIRST;
118 * Work out how much we can fit in a single PDU.
121 data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
122 if(p->ntlmssp_auth_validated)
123 data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
125 if(p->netsec_auth_validated)
126 data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN);
129 * The amount we send is the minimum of the available
130 * space and the amount left to send.
133 data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
136 * Ensure there really is data left to send.
140 DEBUG(0,("create_next_pdu: no data left to send !\n"));
144 data_len = MIN(data_len_left, data_space_available);
147 * Set up the alloc hint. This should be the data left to
151 hdr_resp.alloc_hint = data_len_left;
154 * Set up the header lengths.
157 if (p->ntlmssp_auth_validated) {
158 p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
159 RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
160 p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
161 } else if (p->netsec_auth_validated) {
162 p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
163 RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN;
164 p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN;
166 p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
171 * Work out if this PDU will be the last.
174 if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata))
175 p->hdr.flags |= RPC_FLG_LAST;
178 * Init the parse struct to point at the outgoing
182 prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
183 prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
185 /* Store the header in the data stream. */
186 if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
187 DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
188 prs_mem_free(&outgoing_pdu);
192 if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
193 DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
194 prs_mem_free(&outgoing_pdu);
198 /* Store the current offset. */
199 data_pos = prs_offset(&outgoing_pdu);
201 /* Copy the data into the PDU. */
203 if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
204 DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
205 prs_mem_free(&outgoing_pdu);
209 if (p->ntlmssp_auth_validated) {
213 DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
214 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len));
217 * Set data to point to where we copied the data into.
220 data = prs_data_p(&outgoing_pdu) + data_pos;
223 crc32 = crc32_calc_buffer(data, data_len);
224 NTLMSSPcalc_p(p, (uchar*)data, data_len);
227 if (auth_seal || auth_verify) {
228 RPC_HDR_AUTH auth_info;
230 init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL,
231 (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0));
232 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
233 DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
234 prs_mem_free(&outgoing_pdu);
240 RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
241 char *auth_data = prs_data_p(&outgoing_pdu);
243 p->ntlmssp_seq_num++;
244 init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION,
245 crc32, p->ntlmssp_seq_num++);
246 auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
247 if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
248 DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
249 prs_mem_free(&outgoing_pdu);
252 NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
256 if (p->netsec_auth_validated) {
258 RPC_HDR_AUTH auth_info;
259 static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
260 static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 };
262 RPC_AUTH_NETSEC_CHK verf;
266 data = prs_data_p(&outgoing_pdu) + data_pos;
268 init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL,
269 RPC_HDR_AUTH_LEN, 1);
271 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
272 DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
273 prs_mem_free(&outgoing_pdu);
277 prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
278 prs_init(&rauth, 0, p->mem_ctx, MARSHALL);
280 init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, nullbytes, nullbytes);
282 netsec_encode(&p->netsec_auth,
283 AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL,
285 &verf, data, data_len);
287 smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0);
289 p->netsec_auth.seq_num++;
293 * Setup the counts for this PDU.
296 p->out_data.data_sent_length += data_len;
297 p->out_data.current_pdu_len = p->hdr.frag_len;
298 p->out_data.current_pdu_sent = 0;
300 prs_mem_free(&outgoing_pdu);
304 /*******************************************************************
305 Process an NTLMSSP authentication response.
306 If this function succeeds, the user has been authenticated
307 and their domain, name and calling workstation stored in
309 The initial challenge is stored in p->challenge.
310 *******************************************************************/
312 static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
324 struct auth_context *auth_context = NULL;
325 auth_usersupplied_info *user_info = NULL;
326 auth_serversupplied_info *server_info = NULL;
328 DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
330 memset(p->user_name, '\0', sizeof(p->user_name));
331 memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name));
332 memset(p->domain, '\0', sizeof(p->domain));
333 memset(p->wks, '\0', sizeof(p->wks));
335 /* Set up for non-authenticated user. */
336 delete_nt_token(&p->pipe_user.nt_user_token);
337 p->pipe_user.ngroups = 0;
338 SAFE_FREE( p->pipe_user.groups);
341 * Setup an empty password for a guest user.
345 * We always negotiate UNICODE.
348 if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) {
349 rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 );
350 rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0);
351 rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0);
353 pull_ascii_fstring(user_name, ntlmssp_resp->user);
354 pull_ascii_fstring(domain, ntlmssp_resp->domain);
355 pull_ascii_fstring(wks, ntlmssp_resp->wks);
358 DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));
360 nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len);
361 lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len);
363 memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
364 memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len);
366 #ifdef DEBUG_PASSWORD
367 DEBUG(100,("lm, nt owfs, chal\n"));
368 dump_data(100, (char *)lm_owf, sizeof(lm_owf));
369 dump_data(100, (char *)nt_owf, nt_pw_len);
370 dump_data(100, (char *)p->challenge, 8);
374 * Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
380 * Do the length checking only if user is not NULL.
383 if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0)
385 if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0)
387 if (ntlmssp_resp->hdr_usr.str_str_len == 0)
389 if (ntlmssp_resp->hdr_domain.str_str_len == 0)
391 if (ntlmssp_resp->hdr_wks.str_str_len == 0)
396 make_auth_context_fixed(&auth_context, (uchar*)p->challenge);
398 if (!make_user_info_netlogon_network(&user_info,
399 user_name, domain, wks,
401 nt_owf, nt_pw_len)) {
402 DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n"));
406 nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
408 (auth_context->free)(&auth_context);
409 free_user_info(&user_info);
411 p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
413 if (!p->ntlmssp_auth_validated) {
414 DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
415 failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
416 free_server_info(&server_info);
421 * Set up the sign/seal data.
426 NTLMSSPOWFencrypt(server_info->first_8_lm_hash, lm_owf, p24);
438 for (ind = 0; ind < 256; ind++)
439 p->ntlmssp_hash[ind] = (unsigned char)ind;
441 for( ind = 0; ind < 256; ind++) {
444 j += (p->ntlmssp_hash[ind] + k2[ind%8]);
446 tc = p->ntlmssp_hash[ind];
447 p->ntlmssp_hash[ind] = p->ntlmssp_hash[j];
448 p->ntlmssp_hash[j] = tc;
451 p->ntlmssp_hash[256] = 0;
452 p->ntlmssp_hash[257] = 0;
455 dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash,
456 sizeof(p->ntlmssp_hash));
458 /* NTLMSSPhash(p->ntlmssp_hash, p24); */
459 p->ntlmssp_seq_num = 0;
463 fstrcpy(p->user_name, user_name);
464 fstrcpy(p->pipe_user_name, server_info->unix_name);
465 fstrcpy(p->domain, domain);
466 fstrcpy(p->wks, wks);
469 * Store the UNIX credential data (uid/gid pair) in the pipe structure.
472 memcpy(p->session_key, server_info->session_key, sizeof(p->session_key));
474 p->pipe_user.uid = server_info->uid;
475 p->pipe_user.gid = server_info->gid;
477 p->pipe_user.ngroups = server_info->n_groups;
478 if (p->pipe_user.ngroups) {
479 if (!(p->pipe_user.groups = memdup(server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) {
480 DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n"));
481 free_server_info(&server_info);
486 if (server_info->ptok)
487 p->pipe_user.nt_user_token = dup_nt_token(server_info->ptok);
489 DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
490 p->pipe_user.nt_user_token = NULL;
491 free_server_info(&server_info);
495 p->ntlmssp_auth_validated = True;
497 free_server_info(&server_info);
501 /*******************************************************************
502 The switch table for the pipe names and the functions to handle them.
503 *******************************************************************/
512 struct api_struct *cmds;
516 static struct rpc_table *rpc_lookup;
517 static int rpc_lookup_size;
519 /*******************************************************************
520 This is the client reply to our challenge for an authenticated
521 bind request. The challenge we sent is in p->challenge.
522 *******************************************************************/
524 BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p)
526 RPC_HDR_AUTHA autha_info;
527 RPC_AUTH_VERIFIER auth_verifier;
528 RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
530 DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
532 if (p->hdr.auth_len == 0) {
533 DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n"));
538 * Decode the authentication verifier response.
541 if(!smb_io_rpc_hdr_autha("", &autha_info, rpc_in_p, 0)) {
542 DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n"));
546 if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) {
547 DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
548 (int)autha_info.auth_type, (int)autha_info.auth_level ));
552 if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
553 DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n"));
558 * Ensure this is a NTLMSSP_AUTH packet type.
561 if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) {
562 DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n"));
566 if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, rpc_in_p, 0)) {
567 DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n"));
572 * The following call actually checks the challenge/response data.
573 * for correctness against the given DOMAIN\user name.
576 if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp))
584 /*******************************************************************
585 Marshall a bind_nak pdu.
586 *******************************************************************/
588 static BOOL setup_bind_nak(pipes_struct *p)
590 prs_struct outgoing_rpc;
594 /* Free any memory in the current return data buffer. */
595 prs_mem_free(&p->out_data.rdata);
598 * Marshall directly into the outgoing PDU space. We
599 * must do this as we need to set to the bind response
600 * header and are never sending more than one PDU here.
603 prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
604 prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
608 * Initialize a bind_nak header.
611 init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST,
612 p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
615 * Marshall the header into the outgoing PDU.
618 if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) {
619 DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n"));
620 prs_mem_free(&outgoing_rpc);
625 * Now add the reject reason.
628 if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) {
629 prs_mem_free(&outgoing_rpc);
633 p->out_data.data_sent_length = 0;
634 p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
635 p->out_data.current_pdu_sent = 0;
637 p->pipe_bound = False;
642 /*******************************************************************
643 Marshall a fault pdu.
644 *******************************************************************/
646 BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
648 prs_struct outgoing_pdu;
650 RPC_HDR_RESP hdr_resp;
651 RPC_HDR_FAULT fault_resp;
653 /* Free any memory in the current return data buffer. */
654 prs_mem_free(&p->out_data.rdata);
657 * Marshall directly into the outgoing PDU space. We
658 * must do this as we need to set to the bind response
659 * header and are never sending more than one PDU here.
662 prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
663 prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
666 * Initialize a fault header.
669 init_rpc_hdr(&fault_hdr, RPC_FAULT, RPC_FLG_FIRST | RPC_FLG_LAST | RPC_FLG_NOCALL,
670 p->hdr.call_id, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_FAULT_LEN, 0);
673 * Initialize the HDR_RESP and FAULT parts of the PDU.
676 memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
678 fault_resp.status = status;
679 fault_resp.reserved = 0;
682 * Marshall the header into the outgoing PDU.
685 if(!smb_io_rpc_hdr("", &fault_hdr, &outgoing_pdu, 0)) {
686 DEBUG(0,("setup_fault_pdu: marshalling of RPC_HDR failed.\n"));
687 prs_mem_free(&outgoing_pdu);
691 if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
692 DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_RESP.\n"));
693 prs_mem_free(&outgoing_pdu);
697 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, &outgoing_pdu, 0)) {
698 DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_FAULT.\n"));
699 prs_mem_free(&outgoing_pdu);
703 p->out_data.data_sent_length = 0;
704 p->out_data.current_pdu_len = prs_offset(&outgoing_pdu);
705 p->out_data.current_pdu_sent = 0;
707 prs_mem_free(&outgoing_pdu);
711 /*******************************************************************
712 Ensure a bind request has the correct abstract & transfer interface.
713 Used to reject unknown binds from Win2k.
714 *******************************************************************/
716 BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
717 RPC_IFACE* transfer, uint32 context_id)
719 extern struct pipe_id_info pipe_names[];
720 char *pipe_name = p->name;
724 fstrcpy(pname,"\\PIPE\\");
725 fstrcat(pname,pipe_name);
727 DEBUG(3,("check_bind_req for %s\n", pname));
729 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
731 for ( i=0; pipe_names[i].client_pipe; i++ )
733 if ( strequal(pipe_names[i].client_pipe, pname)
734 && (abstract->version == pipe_names[i].abstr_syntax.version)
735 && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) == 0)
736 && (transfer->version == pipe_names[i].trans_syntax.version)
737 && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) )
739 struct api_struct *fns = NULL;
741 PIPE_RPC_FNS *context_fns;
743 if ( !(context_fns = malloc(sizeof(PIPE_RPC_FNS))) ) {
744 DEBUG(0,("check_bind_req: malloc() failed!\n"));
748 /* save the RPC function table associated with this bind */
750 get_pipe_fns(i, &fns, &n_fns);
752 context_fns->cmds = fns;
753 context_fns->n_cmds = n_fns;
754 context_fns->context_id = context_id;
756 /* add to the list of open contexts */
758 DLIST_ADD( p->contexts, context_fns );
764 if(pipe_names[i].client_pipe == NULL)
770 /*******************************************************************
771 Register commands to an RPC pipe
772 *******************************************************************/
773 NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size)
775 struct rpc_table *rpc_entry;
777 if (!clnt || !srv || !cmds) {
778 return NT_STATUS_INVALID_PARAMETER;
781 if (version != SMB_RPC_INTERFACE_VERSION) {
782 DEBUG(0,("Can't register rpc commands!\n"
783 "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
784 ", while this version of samba uses version %d!\n",
785 version,SMB_RPC_INTERFACE_VERSION));
786 return NT_STATUS_OBJECT_TYPE_MISMATCH;
791 * we still need to make sure that don't register the same commands twice!!!
796 /* We use a temporary variable because this call can fail and
797 rpc_lookup will still be valid afterwards. It could then succeed if
798 called again later */
799 rpc_entry = realloc(rpc_lookup,
800 ++rpc_lookup_size*sizeof(struct rpc_table));
801 if (NULL == rpc_entry) {
803 DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n"));
804 return NT_STATUS_NO_MEMORY;
806 rpc_lookup = rpc_entry;
809 rpc_entry = rpc_lookup + (rpc_lookup_size - 1);
810 ZERO_STRUCTP(rpc_entry);
811 rpc_entry->pipe.clnt = strdup(clnt);
812 rpc_entry->pipe.srv = strdup(srv);
813 rpc_entry->cmds = realloc(rpc_entry->cmds,
814 (rpc_entry->n_cmds + size) *
815 sizeof(struct api_struct));
816 memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds,
817 size * sizeof(struct api_struct));
818 rpc_entry->n_cmds += size;
823 /*******************************************************************
824 Respond to a pipe bind request.
825 *******************************************************************/
827 BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
831 RPC_HDR_AUTH auth_info;
833 fstring ack_pipe_name;
834 prs_struct out_hdr_ba;
836 prs_struct outgoing_rpc;
839 enum RPC_PKT_TYPE reply_pkt_type;
841 p->ntlmssp_auth_requested = False;
842 p->netsec_auth_validated = False;
844 DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
847 * Try and find the correct pipe name to ensure
848 * that this is a pipe name we support.
852 for (i = 0; i < rpc_lookup_size; i++) {
853 if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
854 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
855 rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
856 fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
861 if (i == rpc_lookup_size) {
862 if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
863 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
865 if(!setup_bind_nak(p))
870 for (i = 0; i < rpc_lookup_size; i++) {
871 if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
872 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
873 rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv));
874 fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv);
879 if (i == rpc_lookup_size) {
880 DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
885 /* decode the bind request */
886 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) {
887 DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n"));
892 * Check if this is an authenticated request.
895 if (p->hdr.auth_len != 0) {
896 RPC_AUTH_VERIFIER auth_verifier;
897 RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
900 * Decode the authentication verifier.
903 if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) {
904 DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
908 if(auth_info.auth_type == NTLMSSP_AUTH_TYPE) {
910 if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) {
911 DEBUG(0,("api_pipe_bind_req: unable to "
912 "unmarshall RPC_HDR_AUTH struct.\n"));
916 if(!strequal(auth_verifier.signature, "NTLMSSP")) {
917 DEBUG(0,("api_pipe_bind_req: "
918 "auth_verifier.signature != NTLMSSP\n"));
922 if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
923 DEBUG(0,("api_pipe_bind_req: "
924 "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
925 auth_verifier.msg_type));
929 if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) {
930 DEBUG(0,("api_pipe_bind_req: "
931 "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
935 p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
936 p->ntlmssp_auth_requested = True;
938 } else if (auth_info.auth_type == NETSEC_AUTH_TYPE) {
940 RPC_AUTH_NETSEC_NEG neg;
941 struct netsec_auth_struct *a = &(p->netsec_auth);
943 if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) {
944 DEBUG(0,("api_pipe_bind_req: "
945 "Could not unmarshal SCHANNEL auth neg\n"));
949 p->netsec_auth_validated = True;
951 memset(a->sess_key, 0, sizeof(a->sess_key));
952 memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
956 DEBUG(10,("schannel auth: domain [%s] myname [%s]\n",
957 neg.domain, neg.myname));
960 DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
961 auth_info.auth_type ));
966 switch(p->hdr.pkt_type) {
968 /* name has to be \PIPE\xxxxx */
969 fstrcpy(ack_pipe_name, "\\PIPE\\");
970 fstrcat(ack_pipe_name, p->pipe_srv_name);
971 reply_pkt_type = RPC_BINDACK;
974 /* secondary address CAN be NULL
975 * as the specs say it's ignored.
976 * It MUST NULL to have the spoolss working.
978 fstrcpy(ack_pipe_name,"");
979 reply_pkt_type = RPC_ALTCONTRESP;
985 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
988 * Marshall directly into the outgoing PDU space. We
989 * must do this as we need to set to the bind response
990 * header and are never sending more than one PDU here.
993 prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL);
994 prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
997 * Setup the memory to marshall the ba header, and the
1001 if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) {
1002 DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
1003 prs_mem_free(&outgoing_rpc);
1007 if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) {
1008 DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n"));
1009 prs_mem_free(&outgoing_rpc);
1010 prs_mem_free(&out_hdr_ba);
1014 if (p->ntlmssp_auth_requested)
1017 assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0;
1020 * Create the bind response struct.
1023 /* If the requested abstract synt uuid doesn't match our client pipe,
1024 reject the bind_ack & set the transfer interface synt to all 0's,
1025 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1027 Needed when adding entries to a DACL from NT5 - SK */
1029 if(check_bind_req(p, &hdr_rb.abstract, &hdr_rb.transfer, hdr_rb.context_id ))
1031 init_rpc_hdr_ba(&hdr_ba,
1039 RPC_IFACE null_interface;
1040 ZERO_STRUCT(null_interface);
1041 /* Rejection reason: abstract syntax not supported */
1042 init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN,
1043 MAX_PDU_FRAG_LEN, assoc_gid,
1044 ack_pipe_name, 0x1, 0x2, 0x1,
1052 if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
1053 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
1058 * Now the authentication.
1061 if (p->ntlmssp_auth_requested) {
1062 RPC_AUTH_VERIFIER auth_verifier;
1063 RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
1065 generate_random_buffer(p->challenge, 8, False);
1067 /*** Authentication info ***/
1069 init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1);
1070 if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
1071 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
1075 /*** NTLMSSP verifier ***/
1077 init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE);
1078 if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) {
1079 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
1083 /* NTLMSSP challenge ***/
1085 init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge);
1086 if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) {
1087 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n"));
1091 /* Auth len in the rpc header doesn't include auth_header. */
1092 auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
1095 if (p->netsec_auth_validated) {
1096 RPC_AUTH_VERIFIER auth_verifier;
1099 /* The client opens a second RPC NETLOGON pipe without
1100 doing a auth2. The credentials for the schannel are
1101 re-used from the auth2 the client did before. */
1102 p->dc = last_dcinfo;
1104 init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1);
1105 if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
1106 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
1110 /*** NETSEC verifier ***/
1112 init_rpc_auth_verifier(&auth_verifier, "\001", 0x0);
1113 if(!smb_io_rpc_netsec_verifier("", &auth_verifier, &out_auth, 0)) {
1114 DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
1118 prs_align(&out_auth);
1121 if(!prs_uint32("flags ", &out_auth, 0, &flags))
1124 auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
1128 * Create the header, now we know the length.
1131 init_rpc_hdr(&p->hdr, reply_pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
1133 RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
1137 * Marshall the header into the outgoing PDU.
1140 if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
1141 DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
1146 * Now add the RPC_HDR_BA and any auth needed.
1149 if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
1150 DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
1154 if((p->ntlmssp_auth_requested|p->netsec_auth_validated) &&
1155 !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
1156 DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
1160 if(!p->ntlmssp_auth_requested)
1161 p->pipe_bound = True;
1164 * Setup the lengths for the initial reply.
1167 p->out_data.data_sent_length = 0;
1168 p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
1169 p->out_data.current_pdu_sent = 0;
1171 prs_mem_free(&out_hdr_ba);
1172 prs_mem_free(&out_auth);
1178 prs_mem_free(&outgoing_rpc);
1179 prs_mem_free(&out_hdr_ba);
1180 prs_mem_free(&out_auth);
1184 /****************************************************************************
1185 Deal with sign & seal processing on an RPC request.
1186 ****************************************************************************/
1188 BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
1191 * We always negotiate the following two bits....
1193 BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
1194 BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
1200 auth_len = p->hdr.auth_len;
1202 if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) {
1203 DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len ));
1208 * The following is that length of the data we must verify or unseal.
1209 * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
1210 * preceeding the auth_data.
1213 data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1214 (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len;
1216 DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
1217 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
1221 * The data in rpc_in doesn't contain the RPC_HEADER as this
1222 * has already been consumed.
1224 char *data = prs_data_p(rpc_in) + RPC_HDR_REQ_LEN;
1225 dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash,
1226 sizeof(p->ntlmssp_hash));
1228 dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n",
1229 (const unsigned char *)data, data_len);
1230 NTLMSSPcalc_p(p, (uchar*)data, data_len);
1231 dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n",
1232 (const unsigned char *)data, data_len);
1233 crc32 = crc32_calc_buffer(data, data_len);
1236 old_offset = prs_offset(rpc_in);
1238 if (auth_seal || auth_verify) {
1239 RPC_HDR_AUTH auth_info;
1241 if(!prs_set_offset(rpc_in, old_offset + data_len)) {
1242 DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n",
1243 (unsigned int)old_offset + data_len ));
1247 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
1248 DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));
1254 RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
1255 char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4;
1257 DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4));
1260 * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the
1263 if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) {
1264 DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n",
1265 RPC_AUTH_NTLMSSP_CHK_LEN - 4 ));
1269 NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
1270 if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) {
1271 DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n"));
1275 if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) {
1276 DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n"));
1282 * Return the current pointer to the data offset.
1285 if(!prs_set_offset(rpc_in, old_offset)) {
1286 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1287 (unsigned int)old_offset ));
1294 /****************************************************************************
1295 Deal with schannel processing on an RPC request.
1296 ****************************************************************************/
1297 BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in)
1300 * We always negotiate the following two bits....
1305 RPC_HDR_AUTH auth_info;
1306 RPC_AUTH_NETSEC_CHK netsec_chk;
1309 auth_len = p->hdr.auth_len;
1311 if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) {
1312 DEBUG(0,("Incorrect auth_len %d.\n", auth_len ));
1317 * The following is that length of the data we must verify or unseal.
1318 * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
1319 * preceeding the auth_data.
1322 data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
1323 RPC_HDR_AUTH_LEN - auth_len;
1325 DEBUG(5,("data %d auth %d\n", data_len, auth_len));
1327 old_offset = prs_offset(rpc_in);
1329 if(!prs_set_offset(rpc_in, old_offset + data_len)) {
1330 DEBUG(0,("cannot move offset to %u.\n",
1331 (unsigned int)old_offset + data_len ));
1335 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
1336 DEBUG(0,("failed to unmarshall RPC_HDR_AUTH.\n"));
1340 if ((auth_info.auth_type != NETSEC_AUTH_TYPE) ||
1341 (auth_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL)) {
1342 DEBUG(0,("Invalid auth info %d or level %d on schannel\n",
1343 auth_info.auth_type, auth_info.auth_level));
1347 if(!smb_io_rpc_auth_netsec_chk("", &netsec_chk, rpc_in, 0)) {
1348 DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n"));
1352 if (!netsec_decode(&p->netsec_auth,
1353 AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL,
1354 SENDER_IS_INITIATOR,
1356 prs_data_p(rpc_in)+old_offset, data_len)) {
1357 DEBUG(0,("failed to decode PDU\n"));
1362 * Return the current pointer to the data offset.
1365 if(!prs_set_offset(rpc_in, old_offset)) {
1366 DEBUG(0,("failed to set offset back to %u\n",
1367 (unsigned int)old_offset ));
1371 /* The sequence number gets incremented on both send and receive. */
1372 p->netsec_auth.seq_num++;
1377 /****************************************************************************
1378 Return a user struct for a pipe user.
1379 ****************************************************************************/
1381 struct current_user *get_current_user(struct current_user *user, pipes_struct *p)
1383 if (p->ntlmssp_auth_validated) {
1384 memcpy(user, &p->pipe_user, sizeof(struct current_user));
1386 extern struct current_user current_user;
1387 memcpy(user, ¤t_user, sizeof(struct current_user));
1393 /****************************************************************************
1394 Find the set of RPC functions associated with this context_id
1395 ****************************************************************************/
1397 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1399 PIPE_RPC_FNS *fns = NULL;
1400 PIPE_RPC_FNS *tmp = NULL;
1403 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1407 for (tmp=list; tmp; tmp=tmp->next ) {
1408 if ( tmp->context_id == context_id )
1417 /****************************************************************************
1419 ****************************************************************************/
1421 void free_pipe_rpc_context( PIPE_RPC_FNS *list )
1423 PIPE_RPC_FNS *tmp = list;
1435 /****************************************************************************
1436 Find the correct RPC function to call for this request.
1437 If the pipe is authenticated then become the correct UNIX user
1438 before doing the call.
1439 ****************************************************************************/
1441 BOOL api_pipe_request(pipes_struct *p)
1444 PIPE_RPC_FNS *pipe_fns;
1446 if (p->ntlmssp_auth_validated) {
1448 if(!become_authenticated_pipe_user(p)) {
1449 prs_mem_free(&p->out_data.rdata);
1454 DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));
1456 /* get the set of RPC functions for this context */
1458 pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id);
1461 set_current_rpc_talloc(p->mem_ctx);
1462 ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds);
1463 set_current_rpc_talloc(NULL);
1466 DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n",
1467 p->hdr_req.context_id, p->name));
1470 if(p->ntlmssp_auth_validated)
1471 unbecome_authenticated_pipe_user();
1476 /*******************************************************************
1477 Calls the underlying RPC function for a named pipe.
1478 ********************************************************************/
1480 BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
1481 const struct api_struct *api_rpc_cmds, int n_cmds)
1485 uint32 offset1, offset2;
1487 /* interpret the command */
1488 DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
1490 slprintf(name, sizeof(name)-1, "in_%s", rpc_name);
1491 prs_dump(name, p->hdr_req.opnum, &p->in_data.data);
1493 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1494 if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
1495 DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name));
1500 if (fn_num == n_cmds) {
1502 * For an unknown RPC just return a fault PDU but
1503 * return True to allow RPC's on the pipe to continue
1504 * and not put the pipe into fault state. JRA.
1506 DEBUG(4, ("unknown\n"));
1507 setup_fault_pdu(p, NT_STATUS(0x1c010002));
1511 offset1 = prs_offset(&p->out_data.rdata);
1513 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1514 fn_num, api_rpc_cmds[fn_num].fn));
1515 /* do the actual command */
1516 if(!api_rpc_cmds[fn_num].fn(p)) {
1517 DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name));
1518 prs_mem_free(&p->out_data.rdata);
1522 if (p->bad_handle_fault_state) {
1523 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1524 p->bad_handle_fault_state = False;
1525 setup_fault_pdu(p, NT_STATUS(0x1C00001A));
1529 slprintf(name, sizeof(name)-1, "out_%s", rpc_name);
1530 offset2 = prs_offset(&p->out_data.rdata);
1531 prs_set_offset(&p->out_data.rdata, offset1);
1532 prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata);
1533 prs_set_offset(&p->out_data.rdata, offset2);
1535 DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));
1537 /* Check for buffer underflow in rpc parsing */
1539 if ((DEBUGLEVEL >= 10) &&
1540 (prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) {
1541 size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data);
1544 data = malloc(data_len);
1546 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1548 prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, (uint32)data_len);
1557 /*******************************************************************
1558 *******************************************************************/
1560 void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
1562 struct api_struct *cmds = NULL;
1567 lsa_get_pipe_fns( &cmds, &n_cmds );
1570 lsa_ds_get_pipe_fns( &cmds, &n_cmds );
1573 samr_get_pipe_fns( &cmds, &n_cmds );
1576 netlog_get_pipe_fns( &cmds, &n_cmds );
1579 srvsvc_get_pipe_fns( &cmds, &n_cmds );
1582 wkssvc_get_pipe_fns( &cmds, &n_cmds );
1585 reg_get_pipe_fns( &cmds, &n_cmds );
1588 spoolss_get_pipe_fns( &cmds, &n_cmds );
1591 netdfs_get_pipe_fns( &cmds, &n_cmds );
1595 echo_get_pipe_fns( &cmds, &n_cmds );
1599 DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx));