s4-torture: add test for clusapi_QueryValue.
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob4ffaa0dbb036c3f5ad27f9aa52ff0f14395b3c17
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 /* this module apparently provides an implementation of DCE/RPC over a
21 * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
22 * documentation are available (in on-line form) from the X-Open group.
24 * this module should provide a level of abstraction between SMB
25 * and DCE/RPC, while minimising the amount of mallocs, unnecessary
26 * data copies, and network traffic.
30 #include "includes.h"
31 #include "system/filesys.h"
32 #include "srv_pipe_internal.h"
33 #include "../librpc/gen_ndr/dcerpc.h"
34 #include "../librpc/rpc/rpc_common.h"
35 #include "dcesrv_auth_generic.h"
36 #include "rpc_server.h"
37 #include "rpc_dce.h"
38 #include "smbd/smbd.h"
39 #include "auth.h"
40 #include "ntdomain.h"
41 #include "rpc_server/srv_pipe.h"
42 #include "rpc_server/rpc_contexts.h"
43 #include "lib/param/param.h"
44 #include "librpc/ndr/ndr_table.h"
45 #include "auth/gensec/gensec.h"
46 #include "librpc/ndr/ndr_dcerpc.h"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_RPC_SRV
51 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p);
53 /**
54 * Dump everything from the start of the end up of the provided data
55 * into a file, but only at debug level >= 50
56 **/
57 static void dump_pdu_region(const char *name, int v,
58 DATA_BLOB *data, size_t start, size_t end)
60 int fd, i;
61 char *fname = NULL;
62 ssize_t sz;
64 if (DEBUGLEVEL < 50) return;
66 if (start > data->length || end > data->length || start > end) return;
68 for (i = 1; i < 100; i++) {
69 if (v != -1) {
70 fname = talloc_asprintf(talloc_tos(),
71 "/tmp/%s_%d.%d.prs",
72 name, v, i);
73 } else {
74 fname = talloc_asprintf(talloc_tos(),
75 "/tmp/%s_%d.prs",
76 name, i);
78 if (!fname) {
79 return;
81 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
82 if (fd != -1 || errno != EEXIST) break;
84 if (fd != -1) {
85 sz = write(fd, data->data + start, end - start);
86 i = close(fd);
87 if ((sz != end - start) || (i != 0) ) {
88 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
89 fname, (unsigned long)sz,
90 (unsigned long)end - start, i));
91 } else {
92 DEBUG(0,("created %s\n", fname));
95 TALLOC_FREE(fname);
98 static DATA_BLOB generic_session_key(void)
100 return data_blob_const("SystemLibraryDTC", 16);
103 /*******************************************************************
104 Generate the next PDU to be returned from the data.
105 ********************************************************************/
107 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
108 struct pipe_auth_data *auth,
109 uint32_t call_id,
110 DATA_BLOB *rdata,
111 size_t data_sent_length,
112 DATA_BLOB *frag,
113 size_t *pdu_size)
115 union dcerpc_payload u;
116 uint8_t pfc_flags;
117 size_t data_left;
118 size_t data_to_send;
119 size_t frag_len;
120 size_t pad_len = 0;
121 size_t auth_len = 0;
122 NTSTATUS status;
124 ZERO_STRUCT(u.response);
126 /* Set up rpc packet pfc flags. */
127 if (data_sent_length == 0) {
128 pfc_flags = DCERPC_PFC_FLAG_FIRST;
129 } else {
130 pfc_flags = 0;
133 /* Work out how much we can fit in a single PDU. */
134 data_left = rdata->length - data_sent_length;
136 /* Ensure there really is data left to send. */
137 if (!data_left) {
138 DEBUG(0, ("No data left to send !\n"));
139 return NT_STATUS_BUFFER_TOO_SMALL;
142 status = dcerpc_guess_sizes(auth,
143 DCERPC_RESPONSE_LENGTH,
144 data_left,
145 RPC_MAX_PDU_FRAG_LEN,
146 &data_to_send, &frag_len,
147 &auth_len, &pad_len);
148 if (!NT_STATUS_IS_OK(status)) {
149 return status;
152 /* Set up the alloc hint. This should be the data left to send. */
153 u.response.alloc_hint = data_left;
155 /* Work out if this PDU will be the last. */
156 if (data_sent_length + data_to_send >= rdata->length) {
157 pfc_flags |= DCERPC_PFC_FLAG_LAST;
160 /* Prepare data to be NDR encoded. */
161 u.response.stub_and_verifier =
162 data_blob_const(rdata->data + data_sent_length, data_to_send);
164 /* Store the packet in the data stream. */
165 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
166 pfc_flags, auth_len, call_id,
167 &u, frag);
168 if (!NT_STATUS_IS_OK(status)) {
169 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
170 return status;
173 if (auth_len) {
174 /* Set the proper length on the pdu, including padding.
175 * Only needed if an auth trailer will be appended. */
176 dcerpc_set_frag_length(frag, frag->length
177 + pad_len
178 + DCERPC_AUTH_TRAILER_LENGTH
179 + auth_len);
182 if (auth_len) {
183 status = dcerpc_add_auth_footer(auth, pad_len, frag);
184 if (!NT_STATUS_IS_OK(status)) {
185 data_blob_free(frag);
186 return status;
190 *pdu_size = data_to_send;
191 return NT_STATUS_OK;
194 /*******************************************************************
195 Generate the next PDU to be returned from the data in p->rdata.
196 ********************************************************************/
198 bool create_next_pdu(struct pipes_struct *p)
200 size_t pdu_size = 0;
201 NTSTATUS status;
204 * If we're in the fault state, keep returning fault PDU's until
205 * the pipe gets closed. JRA.
207 if (p->fault_state) {
208 setup_fault_pdu(p, NT_STATUS(p->fault_state));
209 return true;
212 status = create_next_packet(p->mem_ctx, &p->auth,
213 p->call_id, &p->out_data.rdata,
214 p->out_data.data_sent_length,
215 &p->out_data.frag, &pdu_size);
216 if (!NT_STATUS_IS_OK(status)) {
217 DEBUG(0, ("Failed to create packet with error %s, "
218 "(auth level %u / type %u)\n",
219 nt_errstr(status),
220 (unsigned int)p->auth.auth_level,
221 (unsigned int)p->auth.auth_type));
222 return false;
225 /* Setup the counts for this PDU. */
226 p->out_data.data_sent_length += pdu_size;
227 p->out_data.current_pdu_sent = 0;
228 return true;
232 static bool pipe_init_outgoing_data(struct pipes_struct *p);
234 /*******************************************************************
235 Marshall a bind_nak pdu.
236 *******************************************************************/
238 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
240 NTSTATUS status;
241 union dcerpc_payload u;
243 /* Free any memory in the current return data buffer. */
244 pipe_init_outgoing_data(p);
247 * Initialize a bind_nak header.
250 ZERO_STRUCT(u);
252 u.bind_nak.reject_reason = 0;
255 * Marshall directly into the outgoing PDU space. We
256 * must do this as we need to set to the bind response
257 * header and are never sending more than one PDU here.
260 status = dcerpc_push_ncacn_packet(p->mem_ctx,
261 DCERPC_PKT_BIND_NAK,
262 DCERPC_PFC_FLAG_FIRST |
263 DCERPC_PFC_FLAG_LAST,
265 pkt->call_id,
267 &p->out_data.frag);
268 if (!NT_STATUS_IS_OK(status)) {
269 return False;
272 p->out_data.data_sent_length = 0;
273 p->out_data.current_pdu_sent = 0;
275 TALLOC_FREE(p->auth.auth_ctx);
276 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
277 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
278 p->pipe_bound = False;
280 return True;
283 /*******************************************************************
284 Marshall a fault pdu.
285 *******************************************************************/
287 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
289 NTSTATUS status;
290 union dcerpc_payload u;
292 /* Free any memory in the current return data buffer. */
293 pipe_init_outgoing_data(p);
296 * Initialize a fault header.
299 ZERO_STRUCT(u);
301 u.fault.status = NT_STATUS_V(fault_status);
302 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
305 * Marshall directly into the outgoing PDU space. We
306 * must do this as we need to set to the bind response
307 * header and are never sending more than one PDU here.
310 status = dcerpc_push_ncacn_packet(p->mem_ctx,
311 DCERPC_PKT_FAULT,
312 DCERPC_PFC_FLAG_FIRST |
313 DCERPC_PFC_FLAG_LAST |
314 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
316 p->call_id,
318 &p->out_data.frag);
319 if (!NT_STATUS_IS_OK(status)) {
320 return False;
323 p->out_data.data_sent_length = 0;
324 p->out_data.current_pdu_sent = 0;
326 return True;
329 /*******************************************************************
330 Ensure a bind request has the correct abstract & transfer interface.
331 Used to reject unknown binds from Win2k.
332 *******************************************************************/
334 static bool check_bind_req(struct pipes_struct *p,
335 struct ndr_syntax_id* abstract,
336 struct ndr_syntax_id* transfer,
337 uint32_t context_id)
339 struct pipe_rpc_fns *context_fns;
340 bool ok;
342 DEBUG(3,("check_bind_req for %s\n",
343 ndr_interface_name(&abstract->uuid,
344 abstract->if_version)));
346 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
347 if (rpc_srv_pipe_exists_by_id(abstract) &&
348 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
349 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
350 rpc_srv_get_pipe_cli_name(abstract),
351 rpc_srv_get_pipe_srv_name(abstract)));
352 } else {
353 return false;
356 ok = init_pipe_handles(p, abstract);
357 if (!ok) {
358 DEBUG(1, ("Failed to init pipe handles!\n"));
359 return false;
362 context_fns = talloc(p, struct pipe_rpc_fns);
363 if (context_fns == NULL) {
364 DEBUG(0,("check_bind_req: talloc() failed!\n"));
365 return false;
368 context_fns->next = context_fns->prev = NULL;
369 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
370 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
371 context_fns->context_id = context_id;
372 context_fns->syntax = *abstract;
374 /* add to the list of open contexts */
376 DLIST_ADD( p->contexts, context_fns );
378 return True;
382 * Is a named pipe known?
383 * @param[in] pipename Just the filename
384 * @result Do we want to serve this?
386 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
388 NTSTATUS status;
390 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
391 DEBUG(10, ("refusing spoolss access\n"));
392 return false;
395 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
396 return true;
399 status = smb_probe_module("rpc", pipename);
400 if (!NT_STATUS_IS_OK(status)) {
401 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
402 return false;
404 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
407 * Scan the list again for the interface id
409 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
410 return true;
413 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
414 pipename));
416 return false;
419 /*******************************************************************
420 Handle an NTLMSSP bind auth.
421 *******************************************************************/
423 static bool pipe_auth_generic_bind(struct pipes_struct *p,
424 struct ncacn_packet *pkt,
425 struct dcerpc_auth *auth_info,
426 DATA_BLOB *response)
428 TALLOC_CTX *mem_ctx = pkt;
429 struct gensec_security *gensec_security = NULL;
430 NTSTATUS status;
432 status = auth_generic_server_authtype_start(p,
433 auth_info->auth_type,
434 auth_info->auth_level,
435 &auth_info->credentials,
436 response,
437 p->remote_address,
438 &gensec_security);
439 if (!NT_STATUS_IS_OK(status) &&
440 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
442 DEBUG(0, (__location__ ": auth_generic_server_authtype_start[%u/%u] failed: %s\n",
443 auth_info->auth_type, auth_info->auth_level, nt_errstr(status)));
444 return false;
447 /* Make sure data is bound to the memctx, to be freed the caller */
448 talloc_steal(mem_ctx, response->data);
450 p->auth.auth_ctx = gensec_security;
451 p->auth.auth_type = auth_info->auth_type;
453 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
454 p->auth.client_hdr_signing = true;
455 p->auth.hdr_signing = gensec_have_feature(gensec_security,
456 GENSEC_FEATURE_SIGN_PKT_HEADER);
459 if (p->auth.hdr_signing) {
460 gensec_want_feature(gensec_security,
461 GENSEC_FEATURE_SIGN_PKT_HEADER);
464 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
465 return true;
468 status = pipe_auth_verify_final(p);
469 if (!NT_STATUS_IS_OK(status)) {
470 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
471 nt_errstr(status)));
472 return false;
475 return true;
478 /*******************************************************************
479 Process an NTLMSSP authentication response.
480 If this function succeeds, the user has been authenticated
481 and their domain, name and calling workstation stored in
482 the pipe struct.
483 *******************************************************************/
485 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
486 struct gensec_security *gensec_security,
487 enum dcerpc_AuthLevel auth_level,
488 struct auth_session_info **session_info)
490 NTSTATUS status;
491 bool ret;
493 DEBUG(5, (__location__ ": checking user details\n"));
495 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
496 ensure the underlying NTLMSSP flags are also set. If not we should
497 refuse the bind. */
499 status = auth_generic_server_check_flags(gensec_security,
500 (auth_level ==
501 DCERPC_AUTH_LEVEL_INTEGRITY),
502 (auth_level ==
503 DCERPC_AUTH_LEVEL_PRIVACY));
504 if (!NT_STATUS_IS_OK(status)) {
505 DEBUG(0, (__location__ ": Client failed to negotatie proper "
506 "security for rpc connection\n"));
507 return false;
510 TALLOC_FREE(*session_info);
512 status = auth_generic_server_get_user_info(gensec_security,
513 mem_ctx, session_info);
514 if (!NT_STATUS_IS_OK(status)) {
515 DEBUG(0, (__location__ ": failed to obtain the server info "
516 "for authenticated user: %s\n", nt_errstr(status)));
517 return false;
520 if ((*session_info)->security_token == NULL) {
521 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
522 return false;
525 if ((*session_info)->unix_token == NULL) {
526 DEBUG(1, ("Auth module failed to provide unix_token\n"));
527 return false;
531 * We're an authenticated bind over smb, so the session key needs to
532 * be set to "SystemLibraryDTC". Weird, but this is what Windows
533 * does. See the RPC-SAMBA3SESSIONKEY.
536 ret = session_info_set_session_key((*session_info), generic_session_key());
537 if (!ret) {
538 DEBUG(0, ("Failed to set session key!\n"));
539 return false;
542 return true;
545 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
547 struct gensec_security *gensec_security;
548 bool ok;
550 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
551 p->pipe_bound = true;
552 return NT_STATUS_OK;
555 gensec_security = p->auth.auth_ctx;
557 ok = pipe_auth_generic_verify_final(p, gensec_security,
558 p->auth.auth_level,
559 &p->session_info);
560 if (!ok) {
561 return NT_STATUS_ACCESS_DENIED;
564 p->pipe_bound = true;
566 return NT_STATUS_OK;
569 /*******************************************************************
570 Respond to a pipe bind request.
571 *******************************************************************/
573 static bool api_pipe_bind_req(struct pipes_struct *p,
574 struct ncacn_packet *pkt)
576 struct dcerpc_auth auth_info = {0};
577 uint16_t assoc_gid;
578 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
579 NTSTATUS status;
580 struct ndr_syntax_id id;
581 uint8_t pfc_flags = 0;
582 union dcerpc_payload u;
583 struct dcerpc_ack_ctx bind_ack_ctx;
584 DATA_BLOB auth_resp = data_blob_null;
585 DATA_BLOB auth_blob = data_blob_null;
586 const struct ndr_interface_table *table;
588 /* No rebinds on a bound pipe - use alter context. */
589 if (p->pipe_bound) {
590 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
591 return setup_bind_nak(p, pkt);
594 if (pkt->u.bind.num_contexts == 0) {
595 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
596 goto err_exit;
600 * Try and find the correct pipe name to ensure
601 * that this is a pipe name we support.
603 id = pkt->u.bind.ctx_list[0].abstract_syntax;
605 table = ndr_table_by_uuid(&id.uuid);
606 if (table == NULL) {
607 DEBUG(0,("unknown interface\n"));
608 return false;
611 if (rpc_srv_pipe_exists_by_id(&id)) {
612 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
613 rpc_srv_get_pipe_cli_name(&id),
614 rpc_srv_get_pipe_srv_name(&id)));
615 } else {
616 status = smb_probe_module(
617 "rpc", dcerpc_default_transport_endpoint(pkt,
618 NCACN_NP, table));
620 if (NT_STATUS_IS_ERR(status)) {
621 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
622 "%s in bind request.\n",
623 ndr_interface_name(&id.uuid,
624 id.if_version)));
626 return setup_bind_nak(p, pkt);
629 if (rpc_srv_get_pipe_interface_by_cli_name(
630 dcerpc_default_transport_endpoint(pkt,
631 NCACN_NP, table),
632 &id)) {
633 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
634 rpc_srv_get_pipe_cli_name(&id),
635 rpc_srv_get_pipe_srv_name(&id)));
636 } else {
637 DEBUG(0, ("module %s doesn't provide functions for "
638 "pipe %s!\n",
639 ndr_interface_name(&id.uuid,
640 id.if_version),
641 ndr_interface_name(&id.uuid,
642 id.if_version)));
643 return setup_bind_nak(p, pkt);
647 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
649 if (pkt->u.bind.assoc_group_id != 0) {
650 assoc_gid = pkt->u.bind.assoc_group_id;
651 } else {
652 assoc_gid = 0x53f0;
656 * Create the bind response struct.
659 /* If the requested abstract synt uuid doesn't match our client pipe,
660 reject the bind_ack & set the transfer interface synt to all 0's,
661 ver 0 (observed when NT5 attempts to bind to abstract interfaces
662 unknown to NT4)
663 Needed when adding entries to a DACL from NT5 - SK */
665 if (check_bind_req(p,
666 &pkt->u.bind.ctx_list[0].abstract_syntax,
667 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
668 pkt->u.bind.ctx_list[0].context_id)) {
670 bind_ack_ctx.result = 0;
671 bind_ack_ctx.reason.value = 0;
672 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
673 } else {
674 p->pipe_bound = False;
675 /* Rejection reason: abstract syntax not supported */
676 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
677 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
678 bind_ack_ctx.syntax = ndr_syntax_id_null;
682 * Check if this is an authenticated bind request.
684 if (pkt->auth_length) {
685 /* Quick length check. Won't catch a bad auth footer,
686 * prevents overrun. */
688 if (pkt->frag_length < RPC_HEADER_LEN +
689 DCERPC_AUTH_TRAILER_LENGTH +
690 pkt->auth_length) {
691 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
692 "too long for fragment %u.\n",
693 (unsigned int)pkt->auth_length,
694 (unsigned int)pkt->frag_length));
695 goto err_exit;
699 * Decode the authentication verifier.
701 status = dcerpc_pull_dcerpc_auth(pkt,
702 &pkt->u.bind.auth_info,
703 &auth_info, p->endian);
704 if (!NT_STATUS_IS_OK(status)) {
705 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
706 goto err_exit;
709 auth_type = auth_info.auth_type;
711 /* Work out if we have to sign or seal etc. */
712 switch (auth_info.auth_level) {
713 case DCERPC_AUTH_LEVEL_INTEGRITY:
714 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
715 break;
716 case DCERPC_AUTH_LEVEL_PRIVACY:
717 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
718 break;
719 case DCERPC_AUTH_LEVEL_CONNECT:
720 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
721 break;
722 default:
723 DEBUG(0, ("Unexpected auth level (%u).\n",
724 (unsigned int)auth_info.auth_level ));
725 goto err_exit;
728 switch (auth_type) {
729 case DCERPC_AUTH_TYPE_NONE:
730 break;
732 default:
733 if (!pipe_auth_generic_bind(p, pkt,
734 &auth_info, &auth_resp)) {
735 goto err_exit;
737 break;
741 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
742 /* Unauthenticated bind request. */
743 /* We're finished - no more packets. */
744 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
745 /* We must set the pipe auth_level here also. */
746 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
747 p->pipe_bound = True;
748 /* The session key was initialized from the SMB
749 * session in make_internal_rpc_pipe_p */
752 ZERO_STRUCT(u.bind_ack);
753 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
754 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
755 u.bind_ack.assoc_group_id = assoc_gid;
757 /* name has to be \PIPE\xxxxx */
758 u.bind_ack.secondary_address =
759 talloc_asprintf(pkt, "\\PIPE\\%s",
760 rpc_srv_get_pipe_srv_name(&id));
761 if (!u.bind_ack.secondary_address) {
762 DEBUG(0, ("Out of memory!\n"));
763 goto err_exit;
765 u.bind_ack.secondary_address_size =
766 strlen(u.bind_ack.secondary_address) + 1;
768 u.bind_ack.num_results = 1;
769 u.bind_ack.ctx_list = &bind_ack_ctx;
771 /* NOTE: We leave the auth_info empty so we can calculate the padding
772 * later and then append the auth_info --simo */
775 * Marshall directly into the outgoing PDU space. We
776 * must do this as we need to set to the bind response
777 * header and are never sending more than one PDU here.
780 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
782 if (p->auth.hdr_signing) {
783 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
786 status = dcerpc_push_ncacn_packet(p->mem_ctx,
787 DCERPC_PKT_BIND_ACK,
788 pfc_flags,
789 auth_resp.length,
790 pkt->call_id,
792 &p->out_data.frag);
793 if (!NT_STATUS_IS_OK(status)) {
794 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
795 nt_errstr(status)));
798 if (auth_resp.length) {
800 status = dcerpc_push_dcerpc_auth(pkt,
801 auth_type,
802 auth_info.auth_level,
804 1, /* auth_context_id */
805 &auth_resp,
806 &auth_blob);
807 if (!NT_STATUS_IS_OK(status)) {
808 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
809 goto err_exit;
813 /* Now that we have the auth len store it into the right place in
814 * the dcerpc header */
815 dcerpc_set_frag_length(&p->out_data.frag,
816 p->out_data.frag.length + auth_blob.length);
818 if (auth_blob.length) {
820 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
821 auth_blob.data, auth_blob.length)) {
822 DEBUG(0, ("Append of auth info failed.\n"));
823 goto err_exit;
828 * Setup the lengths for the initial reply.
831 p->out_data.data_sent_length = 0;
832 p->out_data.current_pdu_sent = 0;
834 TALLOC_FREE(auth_blob.data);
835 return True;
837 err_exit:
839 data_blob_free(&p->out_data.frag);
840 TALLOC_FREE(auth_blob.data);
841 return setup_bind_nak(p, pkt);
844 /*******************************************************************
845 This is the "stage3" response after a bind request and reply.
846 *******************************************************************/
848 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
850 struct dcerpc_auth auth_info;
851 DATA_BLOB response = data_blob_null;
852 struct gensec_security *gensec_security;
853 NTSTATUS status;
855 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
857 if (pkt->auth_length == 0) {
858 DEBUG(1, ("No auth field sent for bind request!\n"));
859 goto err;
862 /* Ensure there's enough data for an authenticated request. */
863 if (pkt->frag_length < RPC_HEADER_LEN
864 + DCERPC_AUTH_TRAILER_LENGTH
865 + pkt->auth_length) {
866 DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
867 "%u is too large.\n",
868 (unsigned int)pkt->auth_length));
869 goto err;
873 * Decode the authentication verifier response.
876 status = dcerpc_pull_dcerpc_auth(pkt,
877 &pkt->u.auth3.auth_info,
878 &auth_info, p->endian);
879 if (!NT_STATUS_IS_OK(status)) {
880 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
881 goto err;
884 /* We must NEVER look at auth_info->auth_pad_len here,
885 * as old Samba client code gets it wrong and sends it
886 * as zero. JRA.
889 if (auth_info.auth_type != p->auth.auth_type) {
890 DEBUG(1, ("Auth type mismatch! Client sent %d, "
891 "but auth was started as type %d!\n",
892 auth_info.auth_type, p->auth.auth_type));
893 goto err;
896 gensec_security = p->auth.auth_ctx;
898 status = auth_generic_server_step(gensec_security,
899 pkt, &auth_info.credentials,
900 &response);
902 if (NT_STATUS_EQUAL(status,
903 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
904 response.length) {
905 DEBUG(1, (__location__ ": This was supposed to be the final "
906 "leg, but crypto machinery claims a response is "
907 "needed, aborting auth!\n"));
908 data_blob_free(&response);
909 goto err;
911 if (!NT_STATUS_IS_OK(status)) {
912 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
913 goto err;
916 /* Now verify auth was indeed successful and extract server info */
917 status = pipe_auth_verify_final(p);
918 if (!NT_STATUS_IS_OK(status)) {
919 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
920 goto err;
923 return true;
925 err:
927 TALLOC_FREE(p->auth.auth_ctx);
928 return false;
931 /****************************************************************************
932 Deal with an alter context call. Can be third part of 3 leg auth request for
933 SPNEGO calls.
934 ****************************************************************************/
936 static bool api_pipe_alter_context(struct pipes_struct *p,
937 struct ncacn_packet *pkt)
939 struct dcerpc_auth auth_info = {0};
940 uint16_t assoc_gid;
941 NTSTATUS status;
942 union dcerpc_payload u;
943 struct dcerpc_ack_ctx bind_ack_ctx;
944 DATA_BLOB auth_resp = data_blob_null;
945 DATA_BLOB auth_blob = data_blob_null;
946 struct gensec_security *gensec_security;
948 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
950 if (pkt->u.bind.assoc_group_id != 0) {
951 assoc_gid = pkt->u.bind.assoc_group_id;
952 } else {
953 assoc_gid = 0x53f0;
957 * Create the bind response struct.
960 /* If the requested abstract synt uuid doesn't match our client pipe,
961 reject the bind_ack & set the transfer interface synt to all 0's,
962 ver 0 (observed when NT5 attempts to bind to abstract interfaces
963 unknown to NT4)
964 Needed when adding entries to a DACL from NT5 - SK */
966 if (check_bind_req(p,
967 &pkt->u.bind.ctx_list[0].abstract_syntax,
968 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
969 pkt->u.bind.ctx_list[0].context_id)) {
971 bind_ack_ctx.result = 0;
972 bind_ack_ctx.reason.value = 0;
973 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
974 } else {
975 p->pipe_bound = False;
976 /* Rejection reason: abstract syntax not supported */
977 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
978 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
979 bind_ack_ctx.syntax = ndr_syntax_id_null;
983 * Check if this is an authenticated alter context request.
985 if (pkt->auth_length) {
986 /* Quick length check. Won't catch a bad auth footer,
987 * prevents overrun. */
989 if (pkt->frag_length < RPC_HEADER_LEN +
990 DCERPC_AUTH_TRAILER_LENGTH +
991 pkt->auth_length) {
992 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
993 "too long for fragment %u.\n",
994 (unsigned int)pkt->auth_length,
995 (unsigned int)pkt->frag_length ));
996 goto err_exit;
999 status = dcerpc_pull_dcerpc_auth(pkt,
1000 &pkt->u.bind.auth_info,
1001 &auth_info, p->endian);
1002 if (!NT_STATUS_IS_OK(status)) {
1003 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1004 goto err_exit;
1007 /* We can only finish if the pipe is unbound for now */
1008 if (p->pipe_bound) {
1009 DEBUG(0, (__location__ ": Pipe already bound, "
1010 "Altering Context not yet supported!\n"));
1011 goto err_exit;
1014 if (auth_info.auth_type != p->auth.auth_type) {
1015 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1016 "but auth was started as type %d!\n",
1017 auth_info.auth_type, p->auth.auth_type));
1018 goto err_exit;
1021 gensec_security = p->auth.auth_ctx;
1022 status = auth_generic_server_step(gensec_security,
1023 pkt,
1024 &auth_info.credentials,
1025 &auth_resp);
1026 if (NT_STATUS_IS_OK(status)) {
1027 /* third leg of auth, verify auth info */
1028 status = pipe_auth_verify_final(p);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 DEBUG(0, ("Auth Verify failed (%s)\n",
1031 nt_errstr(status)));
1032 goto err_exit;
1034 } else if (NT_STATUS_EQUAL(status,
1035 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1036 DEBUG(10, ("More auth legs required.\n"));
1037 } else {
1038 DEBUG(0, ("Auth step returned an error (%s)\n",
1039 nt_errstr(status)));
1040 goto err_exit;
1044 ZERO_STRUCT(u.alter_resp);
1045 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1046 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1047 u.alter_resp.assoc_group_id = assoc_gid;
1049 /* secondary address CAN be NULL
1050 * as the specs say it's ignored.
1051 * It MUST be NULL to have the spoolss working.
1053 u.alter_resp.secondary_address = "";
1054 u.alter_resp.secondary_address_size = 1;
1056 u.alter_resp.num_results = 1;
1057 u.alter_resp.ctx_list = &bind_ack_ctx;
1059 /* NOTE: We leave the auth_info empty so we can calculate the padding
1060 * later and then append the auth_info --simo */
1063 * Marshall directly into the outgoing PDU space. We
1064 * must do this as we need to set to the bind response
1065 * header and are never sending more than one PDU here.
1068 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1069 DCERPC_PKT_ALTER_RESP,
1070 DCERPC_PFC_FLAG_FIRST |
1071 DCERPC_PFC_FLAG_LAST,
1072 auth_resp.length,
1073 pkt->call_id,
1075 &p->out_data.frag);
1076 if (!NT_STATUS_IS_OK(status)) {
1077 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1078 nt_errstr(status)));
1081 if (auth_resp.length) {
1082 status = dcerpc_push_dcerpc_auth(pkt,
1083 auth_info.auth_type,
1084 auth_info.auth_level,
1085 0, /* pad_len */
1086 1, /* auth_context_id */
1087 &auth_resp,
1088 &auth_blob);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1091 goto err_exit;
1095 /* Now that we have the auth len store it into the right place in
1096 * the dcerpc header */
1097 dcerpc_set_frag_length(&p->out_data.frag,
1098 p->out_data.frag.length +
1099 auth_blob.length);
1101 if (auth_resp.length) {
1102 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1103 auth_blob.data, auth_blob.length)) {
1104 DEBUG(0, ("Append of auth info failed.\n"));
1105 goto err_exit;
1110 * Setup the lengths for the initial reply.
1113 p->out_data.data_sent_length = 0;
1114 p->out_data.current_pdu_sent = 0;
1116 TALLOC_FREE(auth_blob.data);
1117 return True;
1119 err_exit:
1121 data_blob_free(&p->out_data.frag);
1122 TALLOC_FREE(auth_blob.data);
1123 return setup_bind_nak(p, pkt);
1126 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1127 const struct api_struct *api_rpc_cmds, int n_cmds,
1128 const struct ndr_syntax_id *syntax);
1130 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1131 struct ncacn_packet *pkt,
1132 struct pipe_rpc_fns *pipe_fns)
1134 TALLOC_CTX *frame = talloc_stackframe();
1135 struct dcerpc_sec_verification_trailer *vt = NULL;
1136 const uint32_t bitmask1 =
1137 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1138 const struct dcerpc_sec_vt_pcontext pcontext = {
1139 .abstract_syntax = pipe_fns->syntax,
1140 .transfer_syntax = ndr_transfer_syntax_ndr,
1142 const struct dcerpc_sec_vt_header2 header2 =
1143 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1144 struct ndr_pull *ndr;
1145 enum ndr_err_code ndr_err;
1146 bool ret = false;
1148 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1149 if (ndr == NULL) {
1150 goto done;
1153 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1154 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1155 goto done;
1158 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1159 &pcontext, &header2);
1160 done:
1161 TALLOC_FREE(frame);
1162 return ret;
1165 /****************************************************************************
1166 Find the correct RPC function to call for this request.
1167 If the pipe is authenticated then become the correct UNIX user
1168 before doing the call.
1169 ****************************************************************************/
1171 static bool api_pipe_request(struct pipes_struct *p,
1172 struct ncacn_packet *pkt)
1174 TALLOC_CTX *frame = talloc_stackframe();
1175 bool ret = False;
1176 struct pipe_rpc_fns *pipe_fns;
1178 if (!p->pipe_bound) {
1179 DEBUG(1, ("Pipe not bound!\n"));
1180 data_blob_free(&p->out_data.rdata);
1181 TALLOC_FREE(frame);
1182 return false;
1185 /* get the set of RPC functions for this context */
1186 pipe_fns = find_pipe_fns_by_context(p->contexts,
1187 pkt->u.request.context_id);
1188 if (pipe_fns == NULL) {
1189 DEBUG(0, ("No rpc function table associated with context "
1190 "[%d]\n",
1191 pkt->u.request.context_id));
1192 data_blob_free(&p->out_data.rdata);
1193 TALLOC_FREE(frame);
1194 return false;
1197 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1198 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1199 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1200 data_blob_free(&p->out_data.rdata);
1201 TALLOC_FREE(frame);
1202 return true;
1205 if (!become_authenticated_pipe_user(p->session_info)) {
1206 DEBUG(1, ("Failed to become pipe user!\n"));
1207 data_blob_free(&p->out_data.rdata);
1208 TALLOC_FREE(frame);
1209 return false;
1212 DEBUG(5, ("Requested %s rpc service\n",
1213 ndr_interface_name(&pipe_fns->syntax.uuid,
1214 pipe_fns->syntax.if_version)));
1216 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1217 &pipe_fns->syntax);
1218 unbecome_authenticated_pipe_user();
1220 TALLOC_FREE(frame);
1221 return ret;
1224 /*******************************************************************
1225 Calls the underlying RPC function for a named pipe.
1226 ********************************************************************/
1228 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1229 const struct api_struct *api_rpc_cmds, int n_cmds,
1230 const struct ndr_syntax_id *syntax)
1232 int fn_num;
1233 uint32_t offset1;
1234 const struct ndr_interface_table *table;
1236 /* interpret the command */
1237 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1238 ndr_interface_name(&syntax->uuid, syntax->if_version),
1239 pkt->u.request.opnum));
1241 table = ndr_table_by_uuid(&syntax->uuid);
1242 if (table == NULL) {
1243 DEBUG(0,("unknown interface\n"));
1244 return false;
1247 if (DEBUGLEVEL >= 50) {
1248 fstring name;
1249 slprintf(name, sizeof(name)-1, "in_%s",
1250 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1251 dump_pdu_region(name, pkt->u.request.opnum,
1252 &p->in_data.data, 0,
1253 p->in_data.data.length);
1256 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1257 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1258 api_rpc_cmds[fn_num].fn != NULL) {
1259 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1260 api_rpc_cmds[fn_num].name));
1261 break;
1265 if (fn_num == n_cmds) {
1267 * For an unknown RPC just return a fault PDU but
1268 * return True to allow RPC's on the pipe to continue
1269 * and not put the pipe into fault state. JRA.
1271 DEBUG(4, ("unknown\n"));
1272 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1273 return True;
1276 offset1 = p->out_data.rdata.length;
1278 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1279 fn_num, api_rpc_cmds[fn_num].fn));
1280 /* do the actual command */
1281 if(!api_rpc_cmds[fn_num].fn(p)) {
1282 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1283 ndr_interface_name(&syntax->uuid, syntax->if_version),
1284 api_rpc_cmds[fn_num].name));
1285 data_blob_free(&p->out_data.rdata);
1286 return False;
1289 if (p->fault_state) {
1290 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1291 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1292 p->fault_state = 0;
1293 return true;
1296 if (DEBUGLEVEL >= 50) {
1297 fstring name;
1298 slprintf(name, sizeof(name)-1, "out_%s",
1299 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1300 dump_pdu_region(name, pkt->u.request.opnum,
1301 &p->out_data.rdata, offset1,
1302 p->out_data.rdata.length);
1305 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1306 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1308 /* Check for buffer underflow in rpc parsing */
1309 if ((DEBUGLEVEL >= 10) &&
1310 (pkt->frag_length < p->in_data.data.length)) {
1311 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1312 dump_data(10, p->in_data.data.data + pkt->frag_length,
1313 p->in_data.data.length - pkt->frag_length);
1316 return True;
1319 /****************************************************************************
1320 Initialise an outgoing packet.
1321 ****************************************************************************/
1323 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1325 output_data *o_data = &p->out_data;
1327 /* Reset the offset counters. */
1328 o_data->data_sent_length = 0;
1329 o_data->current_pdu_sent = 0;
1331 data_blob_free(&o_data->frag);
1333 /* Free any memory in the current return data buffer. */
1334 data_blob_free(&o_data->rdata);
1336 return True;
1339 /****************************************************************************
1340 Sets the fault state on incoming packets.
1341 ****************************************************************************/
1343 void set_incoming_fault(struct pipes_struct *p)
1345 data_blob_free(&p->in_data.data);
1346 p->in_data.pdu_needed_len = 0;
1347 p->in_data.pdu.length = 0;
1348 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1350 DEBUG(10, ("Setting fault state\n"));
1353 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1354 struct ncacn_packet *pkt,
1355 DATA_BLOB *raw_pkt)
1357 NTSTATUS status;
1358 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1359 size_t pad_len;
1361 DEBUG(10, ("Checking request auth.\n"));
1363 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1364 hdr_size += 16;
1367 /* in case of sealing this function will unseal the data in place */
1368 status = dcerpc_check_auth(auth, pkt,
1369 &pkt->u.request.stub_and_verifier,
1370 hdr_size, raw_pkt,
1371 &pad_len);
1372 if (!NT_STATUS_IS_OK(status)) {
1373 return status;
1377 /* remove padding and auth trailer,
1378 * this way the caller will get just the data */
1379 if (pkt->auth_length) {
1380 size_t trail_len = pad_len
1381 + DCERPC_AUTH_TRAILER_LENGTH
1382 + pkt->auth_length;
1383 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1384 return NT_STATUS_INFO_LENGTH_MISMATCH;
1386 pkt->u.request.stub_and_verifier.length -= trail_len;
1389 return NT_STATUS_OK;
1392 /****************************************************************************
1393 Processes a request pdu. This will do auth processing if needed, and
1394 appends the data into the complete stream if the LAST flag is not set.
1395 ****************************************************************************/
1397 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1399 NTSTATUS status;
1400 DATA_BLOB data;
1401 struct dcerpc_sec_vt_header2 hdr2;
1403 if (!p->pipe_bound) {
1404 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1405 set_incoming_fault(p);
1406 return False;
1409 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1410 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1411 p->header2 = hdr2;
1412 } else {
1413 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1414 set_incoming_fault(p);
1415 return false;
1419 /* Store the opnum */
1420 p->opnum = pkt->u.request.opnum;
1422 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1423 if (!NT_STATUS_IS_OK(status)) {
1424 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1425 nt_errstr(status)));
1426 set_incoming_fault(p);
1427 return false;
1430 data = pkt->u.request.stub_and_verifier;
1433 * Check the data length doesn't go over the 15Mb limit.
1434 * increased after observing a bug in the Windows NT 4.0 SP6a
1435 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1436 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1439 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1440 DEBUG(0, ("process_request_pdu: "
1441 "rpc data buffer too large (%u) + (%u)\n",
1442 (unsigned int)p->in_data.data.length,
1443 (unsigned int)data.length));
1444 set_incoming_fault(p);
1445 return False;
1449 * Append the data portion into the buffer and return.
1452 if (data.length) {
1453 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1454 data.data, data.length)) {
1455 DEBUG(0, ("Unable to append data size %u "
1456 "to parse buffer of size %u.\n",
1457 (unsigned int)data.length,
1458 (unsigned int)p->in_data.data.length));
1459 set_incoming_fault(p);
1460 return False;
1464 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1465 return true;
1469 * Ok - we finally have a complete RPC stream.
1470 * Call the rpc command to process it.
1473 return api_pipe_request(p, pkt);
1476 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1478 bool reply = false;
1480 /* Store the call_id */
1481 p->call_id = pkt->call_id;
1483 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1485 if (!pipe_init_outgoing_data(p)) {
1486 goto done;
1489 switch (pkt->ptype) {
1490 case DCERPC_PKT_REQUEST:
1491 reply = process_request_pdu(p, pkt);
1492 break;
1494 case DCERPC_PKT_PING: /* CL request - ignore... */
1495 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1496 (unsigned int)pkt->ptype));
1497 break;
1499 case DCERPC_PKT_RESPONSE: /* No responses here. */
1500 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1501 break;
1503 case DCERPC_PKT_FAULT:
1504 case DCERPC_PKT_WORKING:
1505 /* CL request - reply to a ping when a call in process. */
1506 case DCERPC_PKT_NOCALL:
1507 /* CL - server reply to a ping call. */
1508 case DCERPC_PKT_REJECT:
1509 case DCERPC_PKT_ACK:
1510 case DCERPC_PKT_CL_CANCEL:
1511 case DCERPC_PKT_FACK:
1512 case DCERPC_PKT_CANCEL_ACK:
1513 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1514 (unsigned int)pkt->ptype));
1515 break;
1517 case DCERPC_PKT_BIND:
1519 * We assume that a pipe bind is only in one pdu.
1521 reply = api_pipe_bind_req(p, pkt);
1522 break;
1524 case DCERPC_PKT_BIND_ACK:
1525 case DCERPC_PKT_BIND_NAK:
1526 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1527 "packet type %u received.\n",
1528 (unsigned int)pkt->ptype));
1529 break;
1532 case DCERPC_PKT_ALTER:
1534 * We assume that a pipe bind is only in one pdu.
1536 reply = api_pipe_alter_context(p, pkt);
1537 break;
1539 case DCERPC_PKT_ALTER_RESP:
1540 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1541 "Should only be server -> client.\n"));
1542 break;
1544 case DCERPC_PKT_AUTH3:
1546 * The third packet in an auth exchange.
1548 reply = api_pipe_bind_auth3(p, pkt);
1549 break;
1551 case DCERPC_PKT_SHUTDOWN:
1552 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1553 "Should only be server -> client.\n"));
1554 break;
1556 case DCERPC_PKT_CO_CANCEL:
1557 /* For now just free all client data and continue
1558 * processing. */
1559 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1560 " Abandoning rpc call.\n"));
1561 /* As we never do asynchronous RPC serving, we can
1562 * never cancel a call (as far as I know).
1563 * If we ever did we'd have to send a cancel_ack reply.
1564 * For now, just free all client data and continue
1565 * processing. */
1566 reply = True;
1567 break;
1569 #if 0
1570 /* Enable this if we're doing async rpc. */
1571 /* We must check the outstanding callid matches. */
1572 if (pipe_init_outgoing_data(p)) {
1573 /* Send a cancel_ack PDU reply. */
1574 /* We should probably check the auth-verifier here. */
1575 reply = setup_cancel_ack_reply(p, pkt);
1577 break;
1578 #endif
1580 case DCERPC_PKT_ORPHANED:
1581 /* We should probably check the auth-verifier here.
1582 * For now just free all client data and continue
1583 * processing. */
1584 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1585 " Abandoning rpc call.\n"));
1586 reply = True;
1587 break;
1589 default:
1590 DEBUG(0, ("process_complete_pdu: "
1591 "Unknown rpc type = %u received.\n",
1592 (unsigned int)pkt->ptype));
1593 break;
1596 done:
1597 if (!reply) {
1598 DEBUG(3,("DCE/RPC fault sent!"));
1599 set_incoming_fault(p);
1600 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1602 /* pkt and p->in_data.pdu.data freed by caller */