rpc_server: Fix CID 1035535 Uninitialized scalar variable
[Samba.git] / source3 / rpc_server / srv_pipe.c
blobb2b7271cbeb8b28213885c58051f8a7b9c04a1e9
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 SERVER_NDR_PADDING_SIZE,
147 &data_to_send, &frag_len,
148 &auth_len, &pad_len);
149 if (!NT_STATUS_IS_OK(status)) {
150 return status;
153 /* Set up the alloc hint. This should be the data left to send. */
154 u.response.alloc_hint = data_left;
156 /* Work out if this PDU will be the last. */
157 if (data_sent_length + data_to_send >= rdata->length) {
158 pfc_flags |= DCERPC_PFC_FLAG_LAST;
161 /* Prepare data to be NDR encoded. */
162 u.response.stub_and_verifier =
163 data_blob_const(rdata->data + data_sent_length, data_to_send);
165 /* Store the packet in the data stream. */
166 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
167 pfc_flags, auth_len, call_id,
168 &u, frag);
169 if (!NT_STATUS_IS_OK(status)) {
170 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
171 return status;
174 if (auth_len) {
175 /* Set the proper length on the pdu, including padding.
176 * Only needed if an auth trailer will be appended. */
177 dcerpc_set_frag_length(frag, frag->length
178 + pad_len
179 + DCERPC_AUTH_TRAILER_LENGTH
180 + auth_len);
183 if (auth_len) {
184 status = dcerpc_add_auth_footer(auth, pad_len, frag);
185 if (!NT_STATUS_IS_OK(status)) {
186 data_blob_free(frag);
187 return status;
191 *pdu_size = data_to_send;
192 return NT_STATUS_OK;
195 /*******************************************************************
196 Generate the next PDU to be returned from the data in p->rdata.
197 ********************************************************************/
199 bool create_next_pdu(struct pipes_struct *p)
201 size_t pdu_size = 0;
202 NTSTATUS status;
205 * If we're in the fault state, keep returning fault PDU's until
206 * the pipe gets closed. JRA.
208 if (p->fault_state) {
209 setup_fault_pdu(p, NT_STATUS(p->fault_state));
210 return true;
213 status = create_next_packet(p->mem_ctx, &p->auth,
214 p->call_id, &p->out_data.rdata,
215 p->out_data.data_sent_length,
216 &p->out_data.frag, &pdu_size);
217 if (!NT_STATUS_IS_OK(status)) {
218 DEBUG(0, ("Failed to create packet with error %s, "
219 "(auth level %u / type %u)\n",
220 nt_errstr(status),
221 (unsigned int)p->auth.auth_level,
222 (unsigned int)p->auth.auth_type));
223 return false;
226 /* Setup the counts for this PDU. */
227 p->out_data.data_sent_length += pdu_size;
228 p->out_data.current_pdu_sent = 0;
229 return true;
233 static bool pipe_init_outgoing_data(struct pipes_struct *p);
235 /*******************************************************************
236 Marshall a bind_nak pdu.
237 *******************************************************************/
239 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
241 NTSTATUS status;
242 union dcerpc_payload u;
244 /* Free any memory in the current return data buffer. */
245 pipe_init_outgoing_data(p);
248 * Initialize a bind_nak header.
251 ZERO_STRUCT(u);
253 u.bind_nak.reject_reason = 0;
256 * Marshall directly into the outgoing PDU space. We
257 * must do this as we need to set to the bind response
258 * header and are never sending more than one PDU here.
261 status = dcerpc_push_ncacn_packet(p->mem_ctx,
262 DCERPC_PKT_BIND_NAK,
263 DCERPC_PFC_FLAG_FIRST |
264 DCERPC_PFC_FLAG_LAST,
266 pkt->call_id,
268 &p->out_data.frag);
269 if (!NT_STATUS_IS_OK(status)) {
270 return False;
273 p->out_data.data_sent_length = 0;
274 p->out_data.current_pdu_sent = 0;
276 TALLOC_FREE(p->auth.auth_ctx);
277 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
278 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
279 p->pipe_bound = False;
281 return True;
284 /*******************************************************************
285 Marshall a fault pdu.
286 *******************************************************************/
288 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
290 NTSTATUS status;
291 union dcerpc_payload u;
293 /* Free any memory in the current return data buffer. */
294 pipe_init_outgoing_data(p);
297 * Initialize a fault header.
300 ZERO_STRUCT(u);
302 u.fault.status = NT_STATUS_V(fault_status);
303 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
306 * Marshall directly into the outgoing PDU space. We
307 * must do this as we need to set to the bind response
308 * header and are never sending more than one PDU here.
311 status = dcerpc_push_ncacn_packet(p->mem_ctx,
312 DCERPC_PKT_FAULT,
313 DCERPC_PFC_FLAG_FIRST |
314 DCERPC_PFC_FLAG_LAST |
315 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
317 p->call_id,
319 &p->out_data.frag);
320 if (!NT_STATUS_IS_OK(status)) {
321 return False;
324 p->out_data.data_sent_length = 0;
325 p->out_data.current_pdu_sent = 0;
327 return True;
330 /*******************************************************************
331 Ensure a bind request has the correct abstract & transfer interface.
332 Used to reject unknown binds from Win2k.
333 *******************************************************************/
335 static bool check_bind_req(struct pipes_struct *p,
336 struct ndr_syntax_id* abstract,
337 struct ndr_syntax_id* transfer,
338 uint32_t context_id)
340 struct pipe_rpc_fns *context_fns;
341 bool ok;
343 DEBUG(3,("check_bind_req for %s\n",
344 ndr_interface_name(&abstract->uuid,
345 abstract->if_version)));
347 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
348 if (rpc_srv_pipe_exists_by_id(abstract) &&
349 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
350 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
351 rpc_srv_get_pipe_cli_name(abstract),
352 rpc_srv_get_pipe_srv_name(abstract)));
353 } else {
354 return false;
357 ok = init_pipe_handles(p, abstract);
358 if (!ok) {
359 DEBUG(1, ("Failed to init pipe handles!\n"));
360 return false;
363 context_fns = talloc(p, struct pipe_rpc_fns);
364 if (context_fns == NULL) {
365 DEBUG(0,("check_bind_req: talloc() failed!\n"));
366 return false;
369 context_fns->next = context_fns->prev = NULL;
370 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
371 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
372 context_fns->context_id = context_id;
373 context_fns->syntax = *abstract;
375 /* add to the list of open contexts */
377 DLIST_ADD( p->contexts, context_fns );
379 return True;
383 * Is a named pipe known?
384 * @param[in] pipename Just the filename
385 * @result Do we want to serve this?
387 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
389 NTSTATUS status;
391 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
392 DEBUG(10, ("refusing spoolss access\n"));
393 return false;
396 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
397 return true;
400 status = smb_probe_module("rpc", pipename);
401 if (!NT_STATUS_IS_OK(status)) {
402 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
403 return false;
405 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
408 * Scan the list again for the interface id
410 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
411 return true;
414 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
415 pipename));
417 return false;
420 /*******************************************************************
421 Handle an NTLMSSP bind auth.
422 *******************************************************************/
424 static bool pipe_auth_generic_bind(struct pipes_struct *p,
425 struct ncacn_packet *pkt,
426 struct dcerpc_auth *auth_info,
427 DATA_BLOB *response)
429 TALLOC_CTX *mem_ctx = pkt;
430 struct gensec_security *gensec_security = NULL;
431 NTSTATUS status;
433 status = auth_generic_server_authtype_start(p,
434 auth_info->auth_type,
435 auth_info->auth_level,
436 &auth_info->credentials,
437 response,
438 p->remote_address,
439 &gensec_security);
440 if (!NT_STATUS_IS_OK(status) &&
441 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
443 DEBUG(0, (__location__ ": auth_generic_server_authtype_start[%u/%u] failed: %s\n",
444 auth_info->auth_type, auth_info->auth_level, nt_errstr(status)));
445 return false;
448 /* Make sure data is bound to the memctx, to be freed the caller */
449 talloc_steal(mem_ctx, response->data);
451 p->auth.auth_ctx = gensec_security;
452 p->auth.auth_type = auth_info->auth_type;
454 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
455 p->auth.client_hdr_signing = true;
456 p->auth.hdr_signing = gensec_have_feature(gensec_security,
457 GENSEC_FEATURE_SIGN_PKT_HEADER);
460 if (p->auth.hdr_signing) {
461 gensec_want_feature(gensec_security,
462 GENSEC_FEATURE_SIGN_PKT_HEADER);
465 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
466 return true;
469 status = pipe_auth_verify_final(p);
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
472 nt_errstr(status)));
473 return false;
476 return true;
479 /*******************************************************************
480 Process an NTLMSSP authentication response.
481 If this function succeeds, the user has been authenticated
482 and their domain, name and calling workstation stored in
483 the pipe struct.
484 *******************************************************************/
486 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
487 struct gensec_security *gensec_security,
488 enum dcerpc_AuthLevel auth_level,
489 struct auth_session_info **session_info)
491 NTSTATUS status;
492 bool ret;
494 DEBUG(5, (__location__ ": checking user details\n"));
496 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
497 ensure the underlying NTLMSSP flags are also set. If not we should
498 refuse the bind. */
500 status = auth_generic_server_check_flags(gensec_security,
501 (auth_level ==
502 DCERPC_AUTH_LEVEL_INTEGRITY),
503 (auth_level ==
504 DCERPC_AUTH_LEVEL_PRIVACY));
505 if (!NT_STATUS_IS_OK(status)) {
506 DEBUG(0, (__location__ ": Client failed to negotatie proper "
507 "security for rpc connection\n"));
508 return false;
511 TALLOC_FREE(*session_info);
513 status = auth_generic_server_get_user_info(gensec_security,
514 mem_ctx, session_info);
515 if (!NT_STATUS_IS_OK(status)) {
516 DEBUG(0, (__location__ ": failed to obtain the server info "
517 "for authenticated user: %s\n", nt_errstr(status)));
518 return false;
521 if ((*session_info)->security_token == NULL) {
522 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
523 return false;
526 if ((*session_info)->unix_token == NULL) {
527 DEBUG(1, ("Auth module failed to provide unix_token\n"));
528 return false;
532 * We're an authenticated bind over smb, so the session key needs to
533 * be set to "SystemLibraryDTC". Weird, but this is what Windows
534 * does. See the RPC-SAMBA3SESSIONKEY.
537 ret = session_info_set_session_key((*session_info), generic_session_key());
538 if (!ret) {
539 DEBUG(0, ("Failed to set session key!\n"));
540 return false;
543 return true;
546 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
548 struct gensec_security *gensec_security;
549 bool ok;
551 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
552 p->pipe_bound = true;
553 return NT_STATUS_OK;
556 gensec_security = p->auth.auth_ctx;
558 ok = pipe_auth_generic_verify_final(p, gensec_security,
559 p->auth.auth_level,
560 &p->session_info);
561 if (!ok) {
562 return NT_STATUS_ACCESS_DENIED;
565 p->pipe_bound = true;
567 return NT_STATUS_OK;
570 /*******************************************************************
571 Respond to a pipe bind request.
572 *******************************************************************/
574 static bool api_pipe_bind_req(struct pipes_struct *p,
575 struct ncacn_packet *pkt)
577 struct dcerpc_auth auth_info = {0};
578 uint16 assoc_gid;
579 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
580 NTSTATUS status;
581 struct ndr_syntax_id id;
582 uint8_t pfc_flags = 0;
583 union dcerpc_payload u;
584 struct dcerpc_ack_ctx bind_ack_ctx;
585 DATA_BLOB auth_resp = data_blob_null;
586 DATA_BLOB auth_blob = data_blob_null;
587 const struct ndr_interface_table *table;
589 /* No rebinds on a bound pipe - use alter context. */
590 if (p->pipe_bound) {
591 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
592 return setup_bind_nak(p, pkt);
595 if (pkt->u.bind.num_contexts == 0) {
596 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
597 goto err_exit;
601 * Try and find the correct pipe name to ensure
602 * that this is a pipe name we support.
604 id = pkt->u.bind.ctx_list[0].abstract_syntax;
606 table = ndr_table_by_uuid(&id.uuid);
607 if (table == NULL) {
608 DEBUG(0,("unknown interface\n"));
609 return false;
612 if (rpc_srv_pipe_exists_by_id(&id)) {
613 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
614 rpc_srv_get_pipe_cli_name(&id),
615 rpc_srv_get_pipe_srv_name(&id)));
616 } else {
617 status = smb_probe_module(
618 "rpc", dcerpc_default_transport_endpoint(pkt,
619 NCACN_NP, table));
621 if (NT_STATUS_IS_ERR(status)) {
622 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
623 "%s in bind request.\n",
624 ndr_interface_name(&id.uuid,
625 id.if_version)));
627 return setup_bind_nak(p, pkt);
630 if (rpc_srv_get_pipe_interface_by_cli_name(
631 dcerpc_default_transport_endpoint(pkt,
632 NCACN_NP, table),
633 &id)) {
634 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
635 rpc_srv_get_pipe_cli_name(&id),
636 rpc_srv_get_pipe_srv_name(&id)));
637 } else {
638 DEBUG(0, ("module %s doesn't provide functions for "
639 "pipe %s!\n",
640 ndr_interface_name(&id.uuid,
641 id.if_version),
642 ndr_interface_name(&id.uuid,
643 id.if_version)));
644 return setup_bind_nak(p, pkt);
648 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
650 if (pkt->u.bind.assoc_group_id != 0) {
651 assoc_gid = pkt->u.bind.assoc_group_id;
652 } else {
653 assoc_gid = 0x53f0;
657 * Create the bind response struct.
660 /* If the requested abstract synt uuid doesn't match our client pipe,
661 reject the bind_ack & set the transfer interface synt to all 0's,
662 ver 0 (observed when NT5 attempts to bind to abstract interfaces
663 unknown to NT4)
664 Needed when adding entries to a DACL from NT5 - SK */
666 if (check_bind_req(p,
667 &pkt->u.bind.ctx_list[0].abstract_syntax,
668 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
669 pkt->u.bind.ctx_list[0].context_id)) {
671 bind_ack_ctx.result = 0;
672 bind_ack_ctx.reason.value = 0;
673 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
674 } else {
675 p->pipe_bound = False;
676 /* Rejection reason: abstract syntax not supported */
677 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
678 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
679 bind_ack_ctx.syntax = ndr_syntax_id_null;
683 * Check if this is an authenticated bind request.
685 if (pkt->auth_length) {
686 /* Quick length check. Won't catch a bad auth footer,
687 * prevents overrun. */
689 if (pkt->frag_length < RPC_HEADER_LEN +
690 DCERPC_AUTH_TRAILER_LENGTH +
691 pkt->auth_length) {
692 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
693 "too long for fragment %u.\n",
694 (unsigned int)pkt->auth_length,
695 (unsigned int)pkt->frag_length));
696 goto err_exit;
700 * Decode the authentication verifier.
702 status = dcerpc_pull_dcerpc_auth(pkt,
703 &pkt->u.bind.auth_info,
704 &auth_info, p->endian);
705 if (!NT_STATUS_IS_OK(status)) {
706 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
707 goto err_exit;
710 auth_type = auth_info.auth_type;
712 /* Work out if we have to sign or seal etc. */
713 switch (auth_info.auth_level) {
714 case DCERPC_AUTH_LEVEL_INTEGRITY:
715 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
716 break;
717 case DCERPC_AUTH_LEVEL_PRIVACY:
718 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
719 break;
720 case DCERPC_AUTH_LEVEL_CONNECT:
721 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
722 break;
723 default:
724 DEBUG(0, ("Unexpected auth level (%u).\n",
725 (unsigned int)auth_info.auth_level ));
726 goto err_exit;
729 switch (auth_type) {
730 case DCERPC_AUTH_TYPE_NONE:
731 break;
733 default:
734 if (!pipe_auth_generic_bind(p, pkt,
735 &auth_info, &auth_resp)) {
736 goto err_exit;
738 break;
742 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
743 /* Unauthenticated bind request. */
744 /* We're finished - no more packets. */
745 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
746 /* We must set the pipe auth_level here also. */
747 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
748 p->pipe_bound = True;
749 /* The session key was initialized from the SMB
750 * session in make_internal_rpc_pipe_p */
753 ZERO_STRUCT(u.bind_ack);
754 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
755 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
756 u.bind_ack.assoc_group_id = assoc_gid;
758 /* name has to be \PIPE\xxxxx */
759 u.bind_ack.secondary_address =
760 talloc_asprintf(pkt, "\\PIPE\\%s",
761 rpc_srv_get_pipe_srv_name(&id));
762 if (!u.bind_ack.secondary_address) {
763 DEBUG(0, ("Out of memory!\n"));
764 goto err_exit;
766 u.bind_ack.secondary_address_size =
767 strlen(u.bind_ack.secondary_address) + 1;
769 u.bind_ack.num_results = 1;
770 u.bind_ack.ctx_list = &bind_ack_ctx;
772 /* NOTE: We leave the auth_info empty so we can calculate the padding
773 * later and then append the auth_info --simo */
776 * Marshall directly into the outgoing PDU space. We
777 * must do this as we need to set to the bind response
778 * header and are never sending more than one PDU here.
781 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
783 if (p->auth.hdr_signing) {
784 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
787 status = dcerpc_push_ncacn_packet(p->mem_ctx,
788 DCERPC_PKT_BIND_ACK,
789 pfc_flags,
790 auth_resp.length,
791 pkt->call_id,
793 &p->out_data.frag);
794 if (!NT_STATUS_IS_OK(status)) {
795 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
796 nt_errstr(status)));
799 if (auth_resp.length) {
801 status = dcerpc_push_dcerpc_auth(pkt,
802 auth_type,
803 auth_info.auth_level,
805 1, /* auth_context_id */
806 &auth_resp,
807 &auth_blob);
808 if (!NT_STATUS_IS_OK(status)) {
809 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
810 goto err_exit;
814 /* Now that we have the auth len store it into the right place in
815 * the dcerpc header */
816 dcerpc_set_frag_length(&p->out_data.frag,
817 p->out_data.frag.length + auth_blob.length);
819 if (auth_blob.length) {
821 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
822 auth_blob.data, auth_blob.length)) {
823 DEBUG(0, ("Append of auth info failed.\n"));
824 goto err_exit;
829 * Setup the lengths for the initial reply.
832 p->out_data.data_sent_length = 0;
833 p->out_data.current_pdu_sent = 0;
835 TALLOC_FREE(auth_blob.data);
836 return True;
838 err_exit:
840 data_blob_free(&p->out_data.frag);
841 TALLOC_FREE(auth_blob.data);
842 return setup_bind_nak(p, pkt);
845 /*******************************************************************
846 This is the "stage3" response after a bind request and reply.
847 *******************************************************************/
849 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
851 struct dcerpc_auth auth_info;
852 DATA_BLOB response = data_blob_null;
853 struct gensec_security *gensec_security;
854 NTSTATUS status;
856 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
858 if (pkt->auth_length == 0) {
859 DEBUG(1, ("No auth field sent for bind request!\n"));
860 goto err;
863 /* Ensure there's enough data for an authenticated request. */
864 if (pkt->frag_length < RPC_HEADER_LEN
865 + DCERPC_AUTH_TRAILER_LENGTH
866 + pkt->auth_length) {
867 DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
868 "%u is too large.\n",
869 (unsigned int)pkt->auth_length));
870 goto err;
874 * Decode the authentication verifier response.
877 status = dcerpc_pull_dcerpc_auth(pkt,
878 &pkt->u.auth3.auth_info,
879 &auth_info, p->endian);
880 if (!NT_STATUS_IS_OK(status)) {
881 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
882 goto err;
885 /* We must NEVER look at auth_info->auth_pad_len here,
886 * as old Samba client code gets it wrong and sends it
887 * as zero. JRA.
890 if (auth_info.auth_type != p->auth.auth_type) {
891 DEBUG(1, ("Auth type mismatch! Client sent %d, "
892 "but auth was started as type %d!\n",
893 auth_info.auth_type, p->auth.auth_type));
894 goto err;
897 gensec_security = p->auth.auth_ctx;
899 status = auth_generic_server_step(gensec_security,
900 pkt, &auth_info.credentials,
901 &response);
903 if (NT_STATUS_EQUAL(status,
904 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
905 response.length) {
906 DEBUG(1, (__location__ ": This was supposed to be the final "
907 "leg, but crypto machinery claims a response is "
908 "needed, aborting auth!\n"));
909 data_blob_free(&response);
910 goto err;
912 if (!NT_STATUS_IS_OK(status)) {
913 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
914 goto err;
917 /* Now verify auth was indeed successful and extract server info */
918 status = pipe_auth_verify_final(p);
919 if (!NT_STATUS_IS_OK(status)) {
920 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
921 goto err;
924 return true;
926 err:
928 TALLOC_FREE(p->auth.auth_ctx);
929 return false;
932 /****************************************************************************
933 Deal with an alter context call. Can be third part of 3 leg auth request for
934 SPNEGO calls.
935 ****************************************************************************/
937 static bool api_pipe_alter_context(struct pipes_struct *p,
938 struct ncacn_packet *pkt)
940 struct dcerpc_auth auth_info = {0};
941 uint16 assoc_gid;
942 NTSTATUS status;
943 union dcerpc_payload u;
944 struct dcerpc_ack_ctx bind_ack_ctx;
945 DATA_BLOB auth_resp = data_blob_null;
946 DATA_BLOB auth_blob = data_blob_null;
947 int pad_len = 0;
948 struct gensec_security *gensec_security;
950 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
952 if (pkt->u.bind.assoc_group_id != 0) {
953 assoc_gid = pkt->u.bind.assoc_group_id;
954 } else {
955 assoc_gid = 0x53f0;
959 * Create the bind response struct.
962 /* If the requested abstract synt uuid doesn't match our client pipe,
963 reject the bind_ack & set the transfer interface synt to all 0's,
964 ver 0 (observed when NT5 attempts to bind to abstract interfaces
965 unknown to NT4)
966 Needed when adding entries to a DACL from NT5 - SK */
968 if (check_bind_req(p,
969 &pkt->u.bind.ctx_list[0].abstract_syntax,
970 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
971 pkt->u.bind.ctx_list[0].context_id)) {
973 bind_ack_ctx.result = 0;
974 bind_ack_ctx.reason.value = 0;
975 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
976 } else {
977 p->pipe_bound = False;
978 /* Rejection reason: abstract syntax not supported */
979 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
980 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
981 bind_ack_ctx.syntax = ndr_syntax_id_null;
985 * Check if this is an authenticated alter context request.
987 if (pkt->auth_length) {
988 /* Quick length check. Won't catch a bad auth footer,
989 * prevents overrun. */
991 if (pkt->frag_length < RPC_HEADER_LEN +
992 DCERPC_AUTH_TRAILER_LENGTH +
993 pkt->auth_length) {
994 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
995 "too long for fragment %u.\n",
996 (unsigned int)pkt->auth_length,
997 (unsigned int)pkt->frag_length ));
998 goto err_exit;
1001 status = dcerpc_pull_dcerpc_auth(pkt,
1002 &pkt->u.bind.auth_info,
1003 &auth_info, p->endian);
1004 if (!NT_STATUS_IS_OK(status)) {
1005 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1006 goto err_exit;
1009 /* We can only finish if the pipe is unbound for now */
1010 if (p->pipe_bound) {
1011 DEBUG(0, (__location__ ": Pipe already bound, "
1012 "Altering Context not yet supported!\n"));
1013 goto err_exit;
1016 if (auth_info.auth_type != p->auth.auth_type) {
1017 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1018 "but auth was started as type %d!\n",
1019 auth_info.auth_type, p->auth.auth_type));
1020 goto err_exit;
1023 gensec_security = p->auth.auth_ctx;
1024 status = auth_generic_server_step(gensec_security,
1025 pkt,
1026 &auth_info.credentials,
1027 &auth_resp);
1028 if (NT_STATUS_IS_OK(status)) {
1029 /* third leg of auth, verify auth info */
1030 status = pipe_auth_verify_final(p);
1031 if (!NT_STATUS_IS_OK(status)) {
1032 DEBUG(0, ("Auth Verify failed (%s)\n",
1033 nt_errstr(status)));
1034 goto err_exit;
1036 } else if (NT_STATUS_EQUAL(status,
1037 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1038 DEBUG(10, ("More auth legs required.\n"));
1039 } else {
1040 DEBUG(0, ("Auth step returned an error (%s)\n",
1041 nt_errstr(status)));
1042 goto err_exit;
1046 ZERO_STRUCT(u.alter_resp);
1047 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1048 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1049 u.alter_resp.assoc_group_id = assoc_gid;
1051 /* secondary address CAN be NULL
1052 * as the specs say it's ignored.
1053 * It MUST be NULL to have the spoolss working.
1055 u.alter_resp.secondary_address = "";
1056 u.alter_resp.secondary_address_size = 1;
1058 u.alter_resp.num_results = 1;
1059 u.alter_resp.ctx_list = &bind_ack_ctx;
1061 /* NOTE: We leave the auth_info empty so we can calculate the padding
1062 * later and then append the auth_info --simo */
1065 * Marshall directly into the outgoing PDU space. We
1066 * must do this as we need to set to the bind response
1067 * header and are never sending more than one PDU here.
1070 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1071 DCERPC_PKT_ALTER_RESP,
1072 DCERPC_PFC_FLAG_FIRST |
1073 DCERPC_PFC_FLAG_LAST,
1074 auth_resp.length,
1075 pkt->call_id,
1077 &p->out_data.frag);
1078 if (!NT_STATUS_IS_OK(status)) {
1079 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1080 nt_errstr(status)));
1083 if (auth_resp.length) {
1085 /* Work out any padding needed before the auth footer. */
1086 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1087 if (pad_len) {
1088 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1089 DEBUG(10, ("auth pad_len = %u\n",
1090 (unsigned int)pad_len));
1093 status = dcerpc_push_dcerpc_auth(pkt,
1094 auth_info.auth_type,
1095 auth_info.auth_level,
1096 pad_len,
1097 1, /* auth_context_id */
1098 &auth_resp,
1099 &auth_blob);
1100 if (!NT_STATUS_IS_OK(status)) {
1101 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1102 goto err_exit;
1106 /* Now that we have the auth len store it into the right place in
1107 * the dcerpc header */
1108 dcerpc_set_frag_length(&p->out_data.frag,
1109 p->out_data.frag.length +
1110 pad_len + auth_blob.length);
1112 if (auth_resp.length) {
1113 if (pad_len) {
1114 char pad[SERVER_NDR_PADDING_SIZE];
1115 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1116 if (!data_blob_append(p->mem_ctx,
1117 &p->out_data.frag,
1118 pad, pad_len)) {
1119 DEBUG(0, ("api_pipe_bind_req: failed to add "
1120 "%u bytes of pad data.\n",
1121 (unsigned int)pad_len));
1122 goto err_exit;
1126 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1127 auth_blob.data, auth_blob.length)) {
1128 DEBUG(0, ("Append of auth info failed.\n"));
1129 goto err_exit;
1134 * Setup the lengths for the initial reply.
1137 p->out_data.data_sent_length = 0;
1138 p->out_data.current_pdu_sent = 0;
1140 TALLOC_FREE(auth_blob.data);
1141 return True;
1143 err_exit:
1145 data_blob_free(&p->out_data.frag);
1146 TALLOC_FREE(auth_blob.data);
1147 return setup_bind_nak(p, pkt);
1150 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1151 const struct api_struct *api_rpc_cmds, int n_cmds,
1152 const struct ndr_syntax_id *syntax);
1154 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1155 struct ncacn_packet *pkt,
1156 struct pipe_rpc_fns *pipe_fns)
1158 TALLOC_CTX *frame = talloc_stackframe();
1159 struct dcerpc_sec_verification_trailer *vt = NULL;
1160 const uint32_t bitmask1 =
1161 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1162 const struct dcerpc_sec_vt_pcontext pcontext = {
1163 .abstract_syntax = pipe_fns->syntax,
1164 .transfer_syntax = ndr_transfer_syntax_ndr,
1166 const struct dcerpc_sec_vt_header2 header2 =
1167 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1168 struct ndr_pull *ndr;
1169 enum ndr_err_code ndr_err;
1170 bool ret = false;
1172 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1173 if (ndr == NULL) {
1174 goto done;
1177 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1178 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1179 goto done;
1182 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1183 &pcontext, &header2);
1184 done:
1185 TALLOC_FREE(frame);
1186 return ret;
1189 /****************************************************************************
1190 Find the correct RPC function to call for this request.
1191 If the pipe is authenticated then become the correct UNIX user
1192 before doing the call.
1193 ****************************************************************************/
1195 static bool api_pipe_request(struct pipes_struct *p,
1196 struct ncacn_packet *pkt)
1198 TALLOC_CTX *frame = talloc_stackframe();
1199 bool ret = False;
1200 struct pipe_rpc_fns *pipe_fns;
1202 if (!p->pipe_bound) {
1203 DEBUG(1, ("Pipe not bound!\n"));
1204 data_blob_free(&p->out_data.rdata);
1205 TALLOC_FREE(frame);
1206 return false;
1209 /* get the set of RPC functions for this context */
1210 pipe_fns = find_pipe_fns_by_context(p->contexts,
1211 pkt->u.request.context_id);
1212 if (pipe_fns == NULL) {
1213 DEBUG(0, ("No rpc function table associated with context "
1214 "[%d]\n",
1215 pkt->u.request.context_id));
1216 data_blob_free(&p->out_data.rdata);
1217 TALLOC_FREE(frame);
1218 return false;
1221 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1222 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1223 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1224 data_blob_free(&p->out_data.rdata);
1225 TALLOC_FREE(frame);
1226 return true;
1229 if (!become_authenticated_pipe_user(p->session_info)) {
1230 DEBUG(1, ("Failed to become pipe user!\n"));
1231 data_blob_free(&p->out_data.rdata);
1232 TALLOC_FREE(frame);
1233 return false;
1236 DEBUG(5, ("Requested %s rpc service\n",
1237 ndr_interface_name(&pipe_fns->syntax.uuid,
1238 pipe_fns->syntax.if_version)));
1240 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1241 &pipe_fns->syntax);
1242 unbecome_authenticated_pipe_user();
1244 TALLOC_FREE(frame);
1245 return ret;
1248 /*******************************************************************
1249 Calls the underlying RPC function for a named pipe.
1250 ********************************************************************/
1252 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1253 const struct api_struct *api_rpc_cmds, int n_cmds,
1254 const struct ndr_syntax_id *syntax)
1256 int fn_num;
1257 uint32_t offset1;
1258 const struct ndr_interface_table *table;
1260 /* interpret the command */
1261 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1262 ndr_interface_name(&syntax->uuid, syntax->if_version),
1263 pkt->u.request.opnum));
1265 table = ndr_table_by_uuid(&syntax->uuid);
1266 if (table == NULL) {
1267 DEBUG(0,("unknown interface\n"));
1268 return false;
1271 if (DEBUGLEVEL >= 50) {
1272 fstring name;
1273 slprintf(name, sizeof(name)-1, "in_%s",
1274 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1275 dump_pdu_region(name, pkt->u.request.opnum,
1276 &p->in_data.data, 0,
1277 p->in_data.data.length);
1280 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1281 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1282 api_rpc_cmds[fn_num].fn != NULL) {
1283 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1284 api_rpc_cmds[fn_num].name));
1285 break;
1289 if (fn_num == n_cmds) {
1291 * For an unknown RPC just return a fault PDU but
1292 * return True to allow RPC's on the pipe to continue
1293 * and not put the pipe into fault state. JRA.
1295 DEBUG(4, ("unknown\n"));
1296 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1297 return True;
1300 offset1 = p->out_data.rdata.length;
1302 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1303 fn_num, api_rpc_cmds[fn_num].fn));
1304 /* do the actual command */
1305 if(!api_rpc_cmds[fn_num].fn(p)) {
1306 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1307 ndr_interface_name(&syntax->uuid, syntax->if_version),
1308 api_rpc_cmds[fn_num].name));
1309 data_blob_free(&p->out_data.rdata);
1310 return False;
1313 if (p->fault_state) {
1314 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1315 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1316 p->fault_state = 0;
1317 return true;
1320 if (DEBUGLEVEL >= 50) {
1321 fstring name;
1322 slprintf(name, sizeof(name)-1, "out_%s",
1323 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1324 dump_pdu_region(name, pkt->u.request.opnum,
1325 &p->out_data.rdata, offset1,
1326 p->out_data.rdata.length);
1329 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1330 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1332 /* Check for buffer underflow in rpc parsing */
1333 if ((DEBUGLEVEL >= 10) &&
1334 (pkt->frag_length < p->in_data.data.length)) {
1335 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1336 dump_data(10, p->in_data.data.data + pkt->frag_length,
1337 p->in_data.data.length - pkt->frag_length);
1340 return True;
1343 /****************************************************************************
1344 Initialise an outgoing packet.
1345 ****************************************************************************/
1347 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1349 output_data *o_data = &p->out_data;
1351 /* Reset the offset counters. */
1352 o_data->data_sent_length = 0;
1353 o_data->current_pdu_sent = 0;
1355 data_blob_free(&o_data->frag);
1357 /* Free any memory in the current return data buffer. */
1358 data_blob_free(&o_data->rdata);
1360 return True;
1363 /****************************************************************************
1364 Sets the fault state on incoming packets.
1365 ****************************************************************************/
1367 void set_incoming_fault(struct pipes_struct *p)
1369 data_blob_free(&p->in_data.data);
1370 p->in_data.pdu_needed_len = 0;
1371 p->in_data.pdu.length = 0;
1372 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1374 DEBUG(10, ("Setting fault state\n"));
1377 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1378 struct ncacn_packet *pkt,
1379 DATA_BLOB *raw_pkt)
1381 NTSTATUS status;
1382 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1383 size_t pad_len;
1385 DEBUG(10, ("Checking request auth.\n"));
1387 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1388 hdr_size += 16;
1391 /* in case of sealing this function will unseal the data in place */
1392 status = dcerpc_check_auth(auth, pkt,
1393 &pkt->u.request.stub_and_verifier,
1394 hdr_size, raw_pkt,
1395 &pad_len);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 return status;
1401 /* remove padding and auth trailer,
1402 * this way the caller will get just the data */
1403 if (pkt->auth_length) {
1404 size_t trail_len = pad_len
1405 + DCERPC_AUTH_TRAILER_LENGTH
1406 + pkt->auth_length;
1407 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1408 return NT_STATUS_INFO_LENGTH_MISMATCH;
1410 pkt->u.request.stub_and_verifier.length -= trail_len;
1413 return NT_STATUS_OK;
1416 /****************************************************************************
1417 Processes a request pdu. This will do auth processing if needed, and
1418 appends the data into the complete stream if the LAST flag is not set.
1419 ****************************************************************************/
1421 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1423 NTSTATUS status;
1424 DATA_BLOB data;
1425 struct dcerpc_sec_vt_header2 hdr2;
1427 if (!p->pipe_bound) {
1428 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1429 set_incoming_fault(p);
1430 return False;
1433 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1434 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1435 p->header2 = hdr2;
1436 } else {
1437 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1438 set_incoming_fault(p);
1439 return false;
1443 /* Store the opnum */
1444 p->opnum = pkt->u.request.opnum;
1446 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1447 if (!NT_STATUS_IS_OK(status)) {
1448 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1449 nt_errstr(status)));
1450 set_incoming_fault(p);
1451 return false;
1454 data = pkt->u.request.stub_and_verifier;
1457 * Check the data length doesn't go over the 15Mb limit.
1458 * increased after observing a bug in the Windows NT 4.0 SP6a
1459 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1460 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1463 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1464 DEBUG(0, ("process_request_pdu: "
1465 "rpc data buffer too large (%u) + (%u)\n",
1466 (unsigned int)p->in_data.data.length,
1467 (unsigned int)data.length));
1468 set_incoming_fault(p);
1469 return False;
1473 * Append the data portion into the buffer and return.
1476 if (data.length) {
1477 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1478 data.data, data.length)) {
1479 DEBUG(0, ("Unable to append data size %u "
1480 "to parse buffer of size %u.\n",
1481 (unsigned int)data.length,
1482 (unsigned int)p->in_data.data.length));
1483 set_incoming_fault(p);
1484 return False;
1488 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1489 return true;
1493 * Ok - we finally have a complete RPC stream.
1494 * Call the rpc command to process it.
1497 return api_pipe_request(p, pkt);
1500 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1502 bool reply = false;
1504 /* Store the call_id */
1505 p->call_id = pkt->call_id;
1507 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1509 if (!pipe_init_outgoing_data(p)) {
1510 goto done;
1513 switch (pkt->ptype) {
1514 case DCERPC_PKT_REQUEST:
1515 reply = process_request_pdu(p, pkt);
1516 break;
1518 case DCERPC_PKT_PING: /* CL request - ignore... */
1519 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1520 (unsigned int)pkt->ptype));
1521 break;
1523 case DCERPC_PKT_RESPONSE: /* No responses here. */
1524 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1525 break;
1527 case DCERPC_PKT_FAULT:
1528 case DCERPC_PKT_WORKING:
1529 /* CL request - reply to a ping when a call in process. */
1530 case DCERPC_PKT_NOCALL:
1531 /* CL - server reply to a ping call. */
1532 case DCERPC_PKT_REJECT:
1533 case DCERPC_PKT_ACK:
1534 case DCERPC_PKT_CL_CANCEL:
1535 case DCERPC_PKT_FACK:
1536 case DCERPC_PKT_CANCEL_ACK:
1537 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1538 (unsigned int)pkt->ptype));
1539 break;
1541 case DCERPC_PKT_BIND:
1543 * We assume that a pipe bind is only in one pdu.
1545 reply = api_pipe_bind_req(p, pkt);
1546 break;
1548 case DCERPC_PKT_BIND_ACK:
1549 case DCERPC_PKT_BIND_NAK:
1550 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1551 "packet type %u received.\n",
1552 (unsigned int)pkt->ptype));
1553 break;
1556 case DCERPC_PKT_ALTER:
1558 * We assume that a pipe bind is only in one pdu.
1560 reply = api_pipe_alter_context(p, pkt);
1561 break;
1563 case DCERPC_PKT_ALTER_RESP:
1564 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1565 "Should only be server -> client.\n"));
1566 break;
1568 case DCERPC_PKT_AUTH3:
1570 * The third packet in an auth exchange.
1572 reply = api_pipe_bind_auth3(p, pkt);
1573 break;
1575 case DCERPC_PKT_SHUTDOWN:
1576 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1577 "Should only be server -> client.\n"));
1578 break;
1580 case DCERPC_PKT_CO_CANCEL:
1581 /* For now just free all client data and continue
1582 * processing. */
1583 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1584 " Abandoning rpc call.\n"));
1585 /* As we never do asynchronous RPC serving, we can
1586 * never cancel a call (as far as I know).
1587 * If we ever did we'd have to send a cancel_ack reply.
1588 * For now, just free all client data and continue
1589 * processing. */
1590 reply = True;
1591 break;
1593 #if 0
1594 /* Enable this if we're doing async rpc. */
1595 /* We must check the outstanding callid matches. */
1596 if (pipe_init_outgoing_data(p)) {
1597 /* Send a cancel_ack PDU reply. */
1598 /* We should probably check the auth-verifier here. */
1599 reply = setup_cancel_ack_reply(p, pkt);
1601 break;
1602 #endif
1604 case DCERPC_PKT_ORPHANED:
1605 /* We should probably check the auth-verifier here.
1606 * For now just free all client data and continue
1607 * processing. */
1608 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1609 " Abandoning rpc call.\n"));
1610 reply = True;
1611 break;
1613 default:
1614 DEBUG(0, ("process_complete_pdu: "
1615 "Unknown rpc type = %u received.\n",
1616 (unsigned int)pkt->ptype));
1617 break;
1620 done:
1621 if (!reply) {
1622 DEBUG(3,("DCE/RPC fault sent!"));
1623 set_incoming_fault(p);
1624 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1626 /* pkt and p->in_data.pdu.data freed by caller */