s3-rpc_server: Fix handling of fragmented rpc requests.
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob67c9a68b98429ed8d44efa8939340ef469c5f408
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 /**
52 * Dump everything from the start of the end up of the provided data
53 * into a file, but only at debug level >= 50
54 **/
55 static void dump_pdu_region(const char *name, int v,
56 DATA_BLOB *data, size_t start, size_t end)
58 int fd, i;
59 char *fname = NULL;
60 ssize_t sz;
62 if (DEBUGLEVEL < 50) return;
64 if (start > data->length || end > data->length || start > end) return;
66 for (i = 1; i < 100; i++) {
67 if (v != -1) {
68 fname = talloc_asprintf(talloc_tos(),
69 "/tmp/%s_%d.%d.prs",
70 name, v, i);
71 } else {
72 fname = talloc_asprintf(talloc_tos(),
73 "/tmp/%s_%d.prs",
74 name, i);
76 if (!fname) {
77 return;
79 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
80 if (fd != -1 || errno != EEXIST) break;
82 if (fd != -1) {
83 sz = write(fd, data->data + start, end - start);
84 i = close(fd);
85 if ((sz != end - start) || (i != 0) ) {
86 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
87 fname, (unsigned long)sz,
88 (unsigned long)end - start, i));
89 } else {
90 DEBUG(0,("created %s\n", fname));
93 TALLOC_FREE(fname);
96 static DATA_BLOB generic_session_key(void)
98 return data_blob_const("SystemLibraryDTC", 16);
101 /*******************************************************************
102 Generate the next PDU to be returned from the data.
103 ********************************************************************/
105 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
106 struct pipe_auth_data *auth,
107 uint32_t call_id,
108 DATA_BLOB *rdata,
109 size_t data_sent_length,
110 DATA_BLOB *frag,
111 size_t *pdu_size)
113 union dcerpc_payload u;
114 uint8_t pfc_flags;
115 size_t data_left;
116 size_t data_to_send;
117 size_t frag_len;
118 size_t pad_len = 0;
119 size_t auth_len = 0;
120 NTSTATUS status;
122 ZERO_STRUCT(u.response);
124 /* Set up rpc packet pfc flags. */
125 if (data_sent_length == 0) {
126 pfc_flags = DCERPC_PFC_FLAG_FIRST;
127 } else {
128 pfc_flags = 0;
131 /* Work out how much we can fit in a single PDU. */
132 data_left = rdata->length - data_sent_length;
134 /* Ensure there really is data left to send. */
135 if (!data_left) {
136 DEBUG(0, ("No data left to send !\n"));
137 return NT_STATUS_BUFFER_TOO_SMALL;
140 status = dcerpc_guess_sizes(auth,
141 DCERPC_RESPONSE_LENGTH,
142 data_left,
143 RPC_MAX_PDU_FRAG_LEN,
144 SERVER_NDR_PADDING_SIZE,
145 &data_to_send, &frag_len,
146 &auth_len, &pad_len);
147 if (!NT_STATUS_IS_OK(status)) {
148 return status;
151 /* Set up the alloc hint. This should be the data left to send. */
152 u.response.alloc_hint = data_left;
154 /* Work out if this PDU will be the last. */
155 if (data_sent_length + data_to_send >= rdata->length) {
156 pfc_flags |= DCERPC_PFC_FLAG_LAST;
159 /* Prepare data to be NDR encoded. */
160 u.response.stub_and_verifier =
161 data_blob_const(rdata->data + data_sent_length, data_to_send);
163 /* Store the packet in the data stream. */
164 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
165 pfc_flags, auth_len, call_id,
166 &u, frag);
167 if (!NT_STATUS_IS_OK(status)) {
168 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
169 return status;
172 if (auth_len) {
173 /* Set the proper length on the pdu, including padding.
174 * Only needed if an auth trailer will be appended. */
175 dcerpc_set_frag_length(frag, frag->length
176 + pad_len
177 + DCERPC_AUTH_TRAILER_LENGTH
178 + auth_len);
181 if (auth_len) {
182 status = dcerpc_add_auth_footer(auth, pad_len, frag);
183 if (!NT_STATUS_IS_OK(status)) {
184 data_blob_free(frag);
185 return status;
189 *pdu_size = data_to_send;
190 return NT_STATUS_OK;
193 /*******************************************************************
194 Generate the next PDU to be returned from the data in p->rdata.
195 ********************************************************************/
197 bool create_next_pdu(struct pipes_struct *p)
199 size_t pdu_size = 0;
200 NTSTATUS status;
203 * If we're in the fault state, keep returning fault PDU's until
204 * the pipe gets closed. JRA.
206 if (p->fault_state) {
207 setup_fault_pdu(p, NT_STATUS(p->fault_state));
208 return true;
211 status = create_next_packet(p->mem_ctx, &p->auth,
212 p->call_id, &p->out_data.rdata,
213 p->out_data.data_sent_length,
214 &p->out_data.frag, &pdu_size);
215 if (!NT_STATUS_IS_OK(status)) {
216 DEBUG(0, ("Failed to create packet with error %s, "
217 "(auth level %u / type %u)\n",
218 nt_errstr(status),
219 (unsigned int)p->auth.auth_level,
220 (unsigned int)p->auth.auth_type));
221 return false;
224 /* Setup the counts for this PDU. */
225 p->out_data.data_sent_length += pdu_size;
226 p->out_data.current_pdu_sent = 0;
227 return true;
231 static bool pipe_init_outgoing_data(struct pipes_struct *p);
233 /*******************************************************************
234 Marshall a bind_nak pdu.
235 *******************************************************************/
237 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
239 NTSTATUS status;
240 union dcerpc_payload u;
242 /* Free any memory in the current return data buffer. */
243 pipe_init_outgoing_data(p);
246 * Initialize a bind_nak header.
249 ZERO_STRUCT(u);
251 u.bind_nak.reject_reason = 0;
254 * Marshall directly into the outgoing PDU space. We
255 * must do this as we need to set to the bind response
256 * header and are never sending more than one PDU here.
259 status = dcerpc_push_ncacn_packet(p->mem_ctx,
260 DCERPC_PKT_BIND_NAK,
261 DCERPC_PFC_FLAG_FIRST |
262 DCERPC_PFC_FLAG_LAST,
264 pkt->call_id,
266 &p->out_data.frag);
267 if (!NT_STATUS_IS_OK(status)) {
268 return False;
271 p->out_data.data_sent_length = 0;
272 p->out_data.current_pdu_sent = 0;
274 TALLOC_FREE(p->auth.auth_ctx);
275 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
276 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
277 p->pipe_bound = False;
279 return True;
282 /*******************************************************************
283 Marshall a fault pdu.
284 *******************************************************************/
286 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
288 NTSTATUS status;
289 union dcerpc_payload u;
291 /* Free any memory in the current return data buffer. */
292 pipe_init_outgoing_data(p);
295 * Initialize a fault header.
298 ZERO_STRUCT(u);
300 u.fault.status = NT_STATUS_V(fault_status);
301 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
304 * Marshall directly into the outgoing PDU space. We
305 * must do this as we need to set to the bind response
306 * header and are never sending more than one PDU here.
309 status = dcerpc_push_ncacn_packet(p->mem_ctx,
310 DCERPC_PKT_FAULT,
311 DCERPC_PFC_FLAG_FIRST |
312 DCERPC_PFC_FLAG_LAST |
313 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
315 p->call_id,
317 &p->out_data.frag);
318 if (!NT_STATUS_IS_OK(status)) {
319 return False;
322 p->out_data.data_sent_length = 0;
323 p->out_data.current_pdu_sent = 0;
325 return True;
328 /*******************************************************************
329 Ensure a bind request has the correct abstract & transfer interface.
330 Used to reject unknown binds from Win2k.
331 *******************************************************************/
333 static bool check_bind_req(struct pipes_struct *p,
334 struct ndr_syntax_id* abstract,
335 struct ndr_syntax_id* transfer,
336 uint32_t context_id)
338 struct pipe_rpc_fns *context_fns;
339 bool ok;
341 DEBUG(3,("check_bind_req for %s\n",
342 ndr_interface_name(&abstract->uuid,
343 abstract->if_version)));
345 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
346 if (rpc_srv_pipe_exists_by_id(abstract) &&
347 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
348 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
349 rpc_srv_get_pipe_cli_name(abstract),
350 rpc_srv_get_pipe_srv_name(abstract)));
351 } else {
352 return false;
355 ok = init_pipe_handles(p, abstract);
356 if (!ok) {
357 DEBUG(1, ("Failed to init pipe handles!\n"));
358 return false;
361 context_fns = talloc(p, struct pipe_rpc_fns);
362 if (context_fns == NULL) {
363 DEBUG(0,("check_bind_req: talloc() failed!\n"));
364 return false;
367 context_fns->next = context_fns->prev = NULL;
368 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
369 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
370 context_fns->context_id = context_id;
371 context_fns->syntax = *abstract;
373 /* add to the list of open contexts */
375 DLIST_ADD( p->contexts, context_fns );
377 return True;
381 * Is a named pipe known?
382 * @param[in] pipename Just the filename
383 * @result Do we want to serve this?
385 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
387 NTSTATUS status;
389 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
390 DEBUG(10, ("refusing spoolss access\n"));
391 return false;
394 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
395 return true;
398 status = smb_probe_module("rpc", pipename);
399 if (!NT_STATUS_IS_OK(status)) {
400 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
401 return false;
403 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
406 * Scan the list again for the interface id
408 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
409 return true;
412 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
413 pipename));
415 return false;
418 /*******************************************************************
419 Handle an NTLMSSP bind auth.
420 *******************************************************************/
422 static bool pipe_auth_generic_bind(struct pipes_struct *p,
423 struct ncacn_packet *pkt,
424 struct dcerpc_auth *auth_info,
425 DATA_BLOB *response)
427 TALLOC_CTX *mem_ctx = pkt;
428 struct gensec_security *gensec_security = NULL;
429 NTSTATUS status;
431 status = auth_generic_server_authtype_start(p,
432 auth_info->auth_type,
433 auth_info->auth_level,
434 &auth_info->credentials,
435 response,
436 p->remote_address,
437 &gensec_security);
438 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
439 DEBUG(0, (__location__ ": auth_generic_server_authtype_start failed: %s\n",
440 nt_errstr(status)));
441 return false;
444 /* Make sure data is bound to the memctx, to be freed the caller */
445 talloc_steal(mem_ctx, response->data);
447 p->auth.auth_ctx = gensec_security;
448 p->auth.auth_type = auth_info->auth_type;
450 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
451 p->auth.client_hdr_signing = true;
452 p->auth.hdr_signing = gensec_have_feature(gensec_security,
453 GENSEC_FEATURE_SIGN_PKT_HEADER);
456 if (p->auth.hdr_signing) {
457 gensec_want_feature(gensec_security,
458 GENSEC_FEATURE_SIGN_PKT_HEADER);
461 return true;
464 /*******************************************************************
465 Process an NTLMSSP authentication response.
466 If this function succeeds, the user has been authenticated
467 and their domain, name and calling workstation stored in
468 the pipe struct.
469 *******************************************************************/
471 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
472 struct gensec_security *gensec_security,
473 enum dcerpc_AuthLevel auth_level,
474 struct auth_session_info **session_info)
476 NTSTATUS status;
477 bool ret;
479 DEBUG(5, (__location__ ": checking user details\n"));
481 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
482 ensure the underlying NTLMSSP flags are also set. If not we should
483 refuse the bind. */
485 status = auth_generic_server_check_flags(gensec_security,
486 (auth_level ==
487 DCERPC_AUTH_LEVEL_INTEGRITY),
488 (auth_level ==
489 DCERPC_AUTH_LEVEL_PRIVACY));
490 if (!NT_STATUS_IS_OK(status)) {
491 DEBUG(0, (__location__ ": Client failed to negotatie proper "
492 "security for rpc connection\n"));
493 return false;
496 TALLOC_FREE(*session_info);
498 status = auth_generic_server_get_user_info(gensec_security,
499 mem_ctx, session_info);
500 if (!NT_STATUS_IS_OK(status)) {
501 DEBUG(0, (__location__ ": failed to obtain the server info "
502 "for authenticated user: %s\n", nt_errstr(status)));
503 return false;
506 if ((*session_info)->security_token == NULL) {
507 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
508 return false;
512 * We're an authenticated bind over smb, so the session key needs to
513 * be set to "SystemLibraryDTC". Weird, but this is what Windows
514 * does. See the RPC-SAMBA3SESSIONKEY.
517 ret = session_info_set_session_key((*session_info), generic_session_key());
518 if (!ret) {
519 DEBUG(0, ("Failed to set session key!\n"));
520 return false;
523 return true;
526 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
528 struct gensec_security *gensec_security;
530 switch (p->auth.auth_type) {
531 case DCERPC_AUTH_TYPE_NTLMSSP:
532 case DCERPC_AUTH_TYPE_KRB5:
533 case DCERPC_AUTH_TYPE_SPNEGO:
534 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
535 struct gensec_security);
536 if (!pipe_auth_generic_verify_final(p, gensec_security,
537 p->auth.auth_level,
538 &p->session_info)) {
539 return NT_STATUS_ACCESS_DENIED;
541 break;
542 default:
543 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
544 (unsigned int)p->auth.auth_type));
545 return NT_STATUS_ACCESS_DENIED;
548 p->pipe_bound = true;
550 return NT_STATUS_OK;
553 /*******************************************************************
554 Respond to a pipe bind request.
555 *******************************************************************/
557 static bool api_pipe_bind_req(struct pipes_struct *p,
558 struct ncacn_packet *pkt)
560 struct dcerpc_auth auth_info;
561 uint16 assoc_gid;
562 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
563 NTSTATUS status;
564 struct ndr_syntax_id id;
565 uint8_t pfc_flags = 0;
566 union dcerpc_payload u;
567 struct dcerpc_ack_ctx bind_ack_ctx;
568 DATA_BLOB auth_resp = data_blob_null;
569 DATA_BLOB auth_blob = data_blob_null;
570 const struct ndr_interface_table *table;
572 /* No rebinds on a bound pipe - use alter context. */
573 if (p->pipe_bound) {
574 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
575 return setup_bind_nak(p, pkt);
578 if (pkt->u.bind.num_contexts == 0) {
579 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
580 goto err_exit;
584 * Try and find the correct pipe name to ensure
585 * that this is a pipe name we support.
587 id = pkt->u.bind.ctx_list[0].abstract_syntax;
589 table = ndr_table_by_uuid(&id.uuid);
590 if (table == NULL) {
591 DEBUG(0,("unknown interface\n"));
592 return false;
595 if (rpc_srv_pipe_exists_by_id(&id)) {
596 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
597 rpc_srv_get_pipe_cli_name(&id),
598 rpc_srv_get_pipe_srv_name(&id)));
599 } else {
600 status = smb_probe_module(
601 "rpc", dcerpc_default_transport_endpoint(pkt,
602 NCACN_NP, table));
604 if (NT_STATUS_IS_ERR(status)) {
605 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
606 "%s in bind request.\n",
607 ndr_interface_name(&id.uuid,
608 id.if_version)));
610 return setup_bind_nak(p, pkt);
613 if (rpc_srv_get_pipe_interface_by_cli_name(
614 dcerpc_default_transport_endpoint(pkt,
615 NCACN_NP, table),
616 &id)) {
617 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
618 rpc_srv_get_pipe_cli_name(&id),
619 rpc_srv_get_pipe_srv_name(&id)));
620 } else {
621 DEBUG(0, ("module %s doesn't provide functions for "
622 "pipe %s!\n",
623 ndr_interface_name(&id.uuid,
624 id.if_version),
625 ndr_interface_name(&id.uuid,
626 id.if_version)));
627 return setup_bind_nak(p, pkt);
631 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
633 if (pkt->u.bind.assoc_group_id != 0) {
634 assoc_gid = pkt->u.bind.assoc_group_id;
635 } else {
636 assoc_gid = 0x53f0;
640 * Create the bind response struct.
643 /* If the requested abstract synt uuid doesn't match our client pipe,
644 reject the bind_ack & set the transfer interface synt to all 0's,
645 ver 0 (observed when NT5 attempts to bind to abstract interfaces
646 unknown to NT4)
647 Needed when adding entries to a DACL from NT5 - SK */
649 if (check_bind_req(p,
650 &pkt->u.bind.ctx_list[0].abstract_syntax,
651 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
652 pkt->u.bind.ctx_list[0].context_id)) {
654 bind_ack_ctx.result = 0;
655 bind_ack_ctx.reason.value = 0;
656 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
657 } else {
658 p->pipe_bound = False;
659 /* Rejection reason: abstract syntax not supported */
660 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
661 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
662 bind_ack_ctx.syntax = ndr_syntax_id_null;
666 * Check if this is an authenticated bind request.
668 if (pkt->auth_length) {
669 /* Quick length check. Won't catch a bad auth footer,
670 * prevents overrun. */
672 if (pkt->frag_length < RPC_HEADER_LEN +
673 DCERPC_AUTH_TRAILER_LENGTH +
674 pkt->auth_length) {
675 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
676 "too long for fragment %u.\n",
677 (unsigned int)pkt->auth_length,
678 (unsigned int)pkt->frag_length));
679 goto err_exit;
683 * Decode the authentication verifier.
685 status = dcerpc_pull_dcerpc_auth(pkt,
686 &pkt->u.bind.auth_info,
687 &auth_info, p->endian);
688 if (!NT_STATUS_IS_OK(status)) {
689 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
690 goto err_exit;
693 auth_type = auth_info.auth_type;
695 /* Work out if we have to sign or seal etc. */
696 switch (auth_info.auth_level) {
697 case DCERPC_AUTH_LEVEL_INTEGRITY:
698 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
699 break;
700 case DCERPC_AUTH_LEVEL_PRIVACY:
701 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
702 break;
703 case DCERPC_AUTH_LEVEL_CONNECT:
704 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
705 break;
706 default:
707 DEBUG(0, ("Unexpected auth level (%u).\n",
708 (unsigned int)auth_info.auth_level ));
709 goto err_exit;
712 switch (auth_type) {
713 case DCERPC_AUTH_TYPE_NTLMSSP:
714 if (!pipe_auth_generic_bind(p, pkt,
715 &auth_info, &auth_resp)) {
716 goto err_exit;
718 assoc_gid = 0x7a77;
719 break;
721 case DCERPC_AUTH_TYPE_SCHANNEL:
722 if (!pipe_auth_generic_bind(p, pkt,
723 &auth_info, &auth_resp)) {
724 goto err_exit;
726 if (!session_info_set_session_key(p->session_info, generic_session_key())) {
727 DEBUG(0, ("session_info_set_session_key failed\n"));
728 goto err_exit;
730 p->pipe_bound = true;
731 break;
733 case DCERPC_AUTH_TYPE_SPNEGO:
734 case DCERPC_AUTH_TYPE_KRB5:
735 if (!pipe_auth_generic_bind(p, pkt,
736 &auth_info, &auth_resp)) {
737 goto err_exit;
739 break;
741 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
742 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
743 TALLOC_FREE(p->session_info);
745 status = make_session_info_system(p,
746 &p->session_info);
747 if (!NT_STATUS_IS_OK(status)) {
748 goto err_exit;
751 auth_resp = data_blob_talloc(pkt,
752 "NCALRPC_AUTH_OK",
753 15);
755 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
756 p->pipe_bound = true;
757 } else {
758 goto err_exit;
760 break;
762 case DCERPC_AUTH_TYPE_NONE:
763 break;
765 default:
766 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
767 goto err_exit;
771 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
772 /* Unauthenticated bind request. */
773 /* We're finished - no more packets. */
774 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
775 /* We must set the pipe auth_level here also. */
776 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
777 p->pipe_bound = True;
778 /* The session key was initialized from the SMB
779 * session in make_internal_rpc_pipe_p */
782 ZERO_STRUCT(u.bind_ack);
783 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
784 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
785 u.bind_ack.assoc_group_id = assoc_gid;
787 /* name has to be \PIPE\xxxxx */
788 u.bind_ack.secondary_address =
789 talloc_asprintf(pkt, "\\PIPE\\%s",
790 rpc_srv_get_pipe_srv_name(&id));
791 if (!u.bind_ack.secondary_address) {
792 DEBUG(0, ("Out of memory!\n"));
793 goto err_exit;
795 u.bind_ack.secondary_address_size =
796 strlen(u.bind_ack.secondary_address) + 1;
798 u.bind_ack.num_results = 1;
799 u.bind_ack.ctx_list = &bind_ack_ctx;
801 /* NOTE: We leave the auth_info empty so we can calculate the padding
802 * later and then append the auth_info --simo */
805 * Marshall directly into the outgoing PDU space. We
806 * must do this as we need to set to the bind response
807 * header and are never sending more than one PDU here.
810 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
812 if (p->auth.hdr_signing) {
813 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
816 status = dcerpc_push_ncacn_packet(p->mem_ctx,
817 DCERPC_PKT_BIND_ACK,
818 pfc_flags,
819 auth_resp.length,
820 pkt->call_id,
822 &p->out_data.frag);
823 if (!NT_STATUS_IS_OK(status)) {
824 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
825 nt_errstr(status)));
828 if (auth_resp.length) {
830 status = dcerpc_push_dcerpc_auth(pkt,
831 auth_type,
832 auth_info.auth_level,
834 1, /* auth_context_id */
835 &auth_resp,
836 &auth_blob);
837 if (!NT_STATUS_IS_OK(status)) {
838 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
839 goto err_exit;
843 /* Now that we have the auth len store it into the right place in
844 * the dcerpc header */
845 dcerpc_set_frag_length(&p->out_data.frag,
846 p->out_data.frag.length + auth_blob.length);
848 if (auth_blob.length) {
850 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
851 auth_blob.data, auth_blob.length)) {
852 DEBUG(0, ("Append of auth info failed.\n"));
853 goto err_exit;
858 * Setup the lengths for the initial reply.
861 p->out_data.data_sent_length = 0;
862 p->out_data.current_pdu_sent = 0;
864 TALLOC_FREE(auth_blob.data);
865 return True;
867 err_exit:
869 data_blob_free(&p->out_data.frag);
870 TALLOC_FREE(auth_blob.data);
871 return setup_bind_nak(p, pkt);
874 /*******************************************************************
875 This is the "stage3" response after a bind request and reply.
876 *******************************************************************/
878 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
880 struct dcerpc_auth auth_info;
881 DATA_BLOB response = data_blob_null;
882 struct gensec_security *gensec_security;
883 NTSTATUS status;
885 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
887 if (pkt->auth_length == 0) {
888 DEBUG(1, ("No auth field sent for bind request!\n"));
889 goto err;
892 /* Ensure there's enough data for an authenticated request. */
893 if (pkt->frag_length < RPC_HEADER_LEN
894 + DCERPC_AUTH_TRAILER_LENGTH
895 + pkt->auth_length) {
896 DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
897 "%u is too large.\n",
898 (unsigned int)pkt->auth_length));
899 goto err;
903 * Decode the authentication verifier response.
906 status = dcerpc_pull_dcerpc_auth(pkt,
907 &pkt->u.auth3.auth_info,
908 &auth_info, p->endian);
909 if (!NT_STATUS_IS_OK(status)) {
910 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
911 goto err;
914 /* We must NEVER look at auth_info->auth_pad_len here,
915 * as old Samba client code gets it wrong and sends it
916 * as zero. JRA.
919 if (auth_info.auth_type != p->auth.auth_type) {
920 DEBUG(1, ("Auth type mismatch! Client sent %d, "
921 "but auth was started as type %d!\n",
922 auth_info.auth_type, p->auth.auth_type));
923 goto err;
926 switch (auth_info.auth_type) {
927 case DCERPC_AUTH_TYPE_NTLMSSP:
928 case DCERPC_AUTH_TYPE_KRB5:
929 case DCERPC_AUTH_TYPE_SPNEGO:
930 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
931 struct gensec_security);
932 status = auth_generic_server_step(gensec_security,
933 pkt, &auth_info.credentials,
934 &response);
935 break;
936 default:
937 DEBUG(1, (__location__ ": incorrect auth type (%u).\n",
938 (unsigned int)auth_info.auth_type));
939 return false;
942 if (NT_STATUS_EQUAL(status,
943 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
944 response.length) {
945 DEBUG(1, (__location__ ": This was supposed to be the final "
946 "leg, but crypto machinery claims a response is "
947 "needed, aborting auth!\n"));
948 data_blob_free(&response);
949 goto err;
951 if (!NT_STATUS_IS_OK(status)) {
952 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
953 goto err;
956 /* Now verify auth was indeed successful and extract server info */
957 status = pipe_auth_verify_final(p);
958 if (!NT_STATUS_IS_OK(status)) {
959 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
960 goto err;
963 return true;
965 err:
967 TALLOC_FREE(p->auth.auth_ctx);
968 return false;
971 /****************************************************************************
972 Deal with an alter context call. Can be third part of 3 leg auth request for
973 SPNEGO calls.
974 ****************************************************************************/
976 static bool api_pipe_alter_context(struct pipes_struct *p,
977 struct ncacn_packet *pkt)
979 struct dcerpc_auth auth_info;
980 uint16 assoc_gid;
981 NTSTATUS status;
982 union dcerpc_payload u;
983 struct dcerpc_ack_ctx bind_ack_ctx;
984 DATA_BLOB auth_resp = data_blob_null;
985 DATA_BLOB auth_blob = data_blob_null;
986 int pad_len = 0;
987 struct gensec_security *gensec_security;
989 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
991 if (pkt->u.bind.assoc_group_id != 0) {
992 assoc_gid = pkt->u.bind.assoc_group_id;
993 } else {
994 assoc_gid = 0x53f0;
998 * Create the bind response struct.
1001 /* If the requested abstract synt uuid doesn't match our client pipe,
1002 reject the bind_ack & set the transfer interface synt to all 0's,
1003 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1004 unknown to NT4)
1005 Needed when adding entries to a DACL from NT5 - SK */
1007 if (check_bind_req(p,
1008 &pkt->u.bind.ctx_list[0].abstract_syntax,
1009 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1010 pkt->u.bind.ctx_list[0].context_id)) {
1012 bind_ack_ctx.result = 0;
1013 bind_ack_ctx.reason.value = 0;
1014 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1015 } else {
1016 p->pipe_bound = False;
1017 /* Rejection reason: abstract syntax not supported */
1018 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1019 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
1020 bind_ack_ctx.syntax = ndr_syntax_id_null;
1024 * Check if this is an authenticated alter context request.
1026 if (pkt->auth_length) {
1027 /* Quick length check. Won't catch a bad auth footer,
1028 * prevents overrun. */
1030 if (pkt->frag_length < RPC_HEADER_LEN +
1031 DCERPC_AUTH_TRAILER_LENGTH +
1032 pkt->auth_length) {
1033 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1034 "too long for fragment %u.\n",
1035 (unsigned int)pkt->auth_length,
1036 (unsigned int)pkt->frag_length ));
1037 goto err_exit;
1040 status = dcerpc_pull_dcerpc_auth(pkt,
1041 &pkt->u.bind.auth_info,
1042 &auth_info, p->endian);
1043 if (!NT_STATUS_IS_OK(status)) {
1044 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1045 goto err_exit;
1048 /* We can only finish if the pipe is unbound for now */
1049 if (p->pipe_bound) {
1050 DEBUG(0, (__location__ ": Pipe already bound, "
1051 "Altering Context not yet supported!\n"));
1052 goto err_exit;
1055 if (auth_info.auth_type != p->auth.auth_type) {
1056 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1057 "but auth was started as type %d!\n",
1058 auth_info.auth_type, p->auth.auth_type));
1059 goto err_exit;
1063 switch (auth_info.auth_type) {
1064 case DCERPC_AUTH_TYPE_SPNEGO:
1065 case DCERPC_AUTH_TYPE_KRB5:
1066 case DCERPC_AUTH_TYPE_NTLMSSP:
1067 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1068 struct gensec_security);
1069 status = auth_generic_server_step(gensec_security,
1070 pkt,
1071 &auth_info.credentials,
1072 &auth_resp);
1073 break;
1075 default:
1076 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1077 "in alter-context call\n",
1078 auth_info.auth_type));
1079 goto err_exit;
1082 if (NT_STATUS_IS_OK(status)) {
1083 /* third leg of auth, verify auth info */
1084 status = pipe_auth_verify_final(p);
1085 if (!NT_STATUS_IS_OK(status)) {
1086 DEBUG(0, ("Auth Verify failed (%s)\n",
1087 nt_errstr(status)));
1088 goto err_exit;
1090 } else if (NT_STATUS_EQUAL(status,
1091 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1092 DEBUG(10, ("More auth legs required.\n"));
1093 } else {
1094 DEBUG(0, ("Auth step returned an error (%s)\n",
1095 nt_errstr(status)));
1096 goto err_exit;
1100 ZERO_STRUCT(u.alter_resp);
1101 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1102 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1103 u.alter_resp.assoc_group_id = assoc_gid;
1105 /* secondary address CAN be NULL
1106 * as the specs say it's ignored.
1107 * It MUST be NULL to have the spoolss working.
1109 u.alter_resp.secondary_address = "";
1110 u.alter_resp.secondary_address_size = 1;
1112 u.alter_resp.num_results = 1;
1113 u.alter_resp.ctx_list = &bind_ack_ctx;
1115 /* NOTE: We leave the auth_info empty so we can calculate the padding
1116 * later and then append the auth_info --simo */
1119 * Marshall directly into the outgoing PDU space. We
1120 * must do this as we need to set to the bind response
1121 * header and are never sending more than one PDU here.
1124 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1125 DCERPC_PKT_ALTER_RESP,
1126 DCERPC_PFC_FLAG_FIRST |
1127 DCERPC_PFC_FLAG_LAST,
1128 auth_resp.length,
1129 pkt->call_id,
1131 &p->out_data.frag);
1132 if (!NT_STATUS_IS_OK(status)) {
1133 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1134 nt_errstr(status)));
1137 if (auth_resp.length) {
1139 /* Work out any padding needed before the auth footer. */
1140 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1141 if (pad_len) {
1142 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1143 DEBUG(10, ("auth pad_len = %u\n",
1144 (unsigned int)pad_len));
1147 status = dcerpc_push_dcerpc_auth(pkt,
1148 auth_info.auth_type,
1149 auth_info.auth_level,
1150 pad_len,
1151 1, /* auth_context_id */
1152 &auth_resp,
1153 &auth_blob);
1154 if (!NT_STATUS_IS_OK(status)) {
1155 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1156 goto err_exit;
1160 /* Now that we have the auth len store it into the right place in
1161 * the dcerpc header */
1162 dcerpc_set_frag_length(&p->out_data.frag,
1163 p->out_data.frag.length +
1164 pad_len + auth_blob.length);
1166 if (auth_resp.length) {
1167 if (pad_len) {
1168 char pad[SERVER_NDR_PADDING_SIZE];
1169 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1170 if (!data_blob_append(p->mem_ctx,
1171 &p->out_data.frag,
1172 pad, pad_len)) {
1173 DEBUG(0, ("api_pipe_bind_req: failed to add "
1174 "%u bytes of pad data.\n",
1175 (unsigned int)pad_len));
1176 goto err_exit;
1180 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1181 auth_blob.data, auth_blob.length)) {
1182 DEBUG(0, ("Append of auth info failed.\n"));
1183 goto err_exit;
1188 * Setup the lengths for the initial reply.
1191 p->out_data.data_sent_length = 0;
1192 p->out_data.current_pdu_sent = 0;
1194 TALLOC_FREE(auth_blob.data);
1195 return True;
1197 err_exit:
1199 data_blob_free(&p->out_data.frag);
1200 TALLOC_FREE(auth_blob.data);
1201 return setup_bind_nak(p, pkt);
1204 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1205 const struct api_struct *api_rpc_cmds, int n_cmds,
1206 const struct ndr_syntax_id *syntax);
1208 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1209 struct ncacn_packet *pkt,
1210 struct pipe_rpc_fns *pipe_fns)
1212 TALLOC_CTX *frame = talloc_stackframe();
1213 struct dcerpc_sec_verification_trailer *vt = NULL;
1214 const uint32_t bitmask1 =
1215 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1216 const struct dcerpc_sec_vt_pcontext pcontext = {
1217 .abstract_syntax = pipe_fns->syntax,
1218 .transfer_syntax = ndr_transfer_syntax_ndr,
1220 const struct dcerpc_sec_vt_header2 header2 =
1221 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1222 struct ndr_pull *ndr;
1223 enum ndr_err_code ndr_err;
1224 bool ret = false;
1226 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1227 if (ndr == NULL) {
1228 goto done;
1231 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1232 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1233 goto done;
1236 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1237 &pcontext, &header2);
1238 done:
1239 TALLOC_FREE(frame);
1240 return ret;
1243 /****************************************************************************
1244 Find the correct RPC function to call for this request.
1245 If the pipe is authenticated then become the correct UNIX user
1246 before doing the call.
1247 ****************************************************************************/
1249 static bool api_pipe_request(struct pipes_struct *p,
1250 struct ncacn_packet *pkt)
1252 TALLOC_CTX *frame = talloc_stackframe();
1253 bool ret = False;
1254 struct pipe_rpc_fns *pipe_fns;
1256 if (!p->pipe_bound) {
1257 DEBUG(1, ("Pipe not bound!\n"));
1258 data_blob_free(&p->out_data.rdata);
1259 TALLOC_FREE(frame);
1260 return false;
1263 /* get the set of RPC functions for this context */
1264 pipe_fns = find_pipe_fns_by_context(p->contexts,
1265 pkt->u.request.context_id);
1266 if (pipe_fns == NULL) {
1267 DEBUG(0, ("No rpc function table associated with context "
1268 "[%d]\n",
1269 pkt->u.request.context_id));
1270 data_blob_free(&p->out_data.rdata);
1271 TALLOC_FREE(frame);
1272 return false;
1275 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1276 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1277 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1278 data_blob_free(&p->out_data.rdata);
1279 TALLOC_FREE(frame);
1280 return true;
1283 if (!become_authenticated_pipe_user(p->session_info)) {
1284 DEBUG(1, ("Failed to become pipe user!\n"));
1285 data_blob_free(&p->out_data.rdata);
1286 TALLOC_FREE(frame);
1287 return false;
1290 DEBUG(5, ("Requested %s rpc service\n",
1291 ndr_interface_name(&pipe_fns->syntax.uuid,
1292 pipe_fns->syntax.if_version)));
1294 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1295 &pipe_fns->syntax);
1296 unbecome_authenticated_pipe_user();
1298 TALLOC_FREE(frame);
1299 return ret;
1302 /*******************************************************************
1303 Calls the underlying RPC function for a named pipe.
1304 ********************************************************************/
1306 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1307 const struct api_struct *api_rpc_cmds, int n_cmds,
1308 const struct ndr_syntax_id *syntax)
1310 int fn_num;
1311 uint32_t offset1;
1312 const struct ndr_interface_table *table;
1314 /* interpret the command */
1315 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1316 ndr_interface_name(&syntax->uuid, syntax->if_version),
1317 pkt->u.request.opnum));
1319 table = ndr_table_by_uuid(&syntax->uuid);
1320 if (table == NULL) {
1321 DEBUG(0,("unknown interface\n"));
1322 return false;
1325 if (DEBUGLEVEL >= 50) {
1326 fstring name;
1327 slprintf(name, sizeof(name)-1, "in_%s",
1328 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1329 dump_pdu_region(name, pkt->u.request.opnum,
1330 &p->in_data.data, 0,
1331 p->in_data.data.length);
1334 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1335 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1336 api_rpc_cmds[fn_num].fn != NULL) {
1337 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1338 api_rpc_cmds[fn_num].name));
1339 break;
1343 if (fn_num == n_cmds) {
1345 * For an unknown RPC just return a fault PDU but
1346 * return True to allow RPC's on the pipe to continue
1347 * and not put the pipe into fault state. JRA.
1349 DEBUG(4, ("unknown\n"));
1350 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1351 return True;
1354 offset1 = p->out_data.rdata.length;
1356 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1357 fn_num, api_rpc_cmds[fn_num].fn));
1358 /* do the actual command */
1359 if(!api_rpc_cmds[fn_num].fn(p)) {
1360 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1361 ndr_interface_name(&syntax->uuid, syntax->if_version),
1362 api_rpc_cmds[fn_num].name));
1363 data_blob_free(&p->out_data.rdata);
1364 return False;
1367 if (p->fault_state) {
1368 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1369 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1370 p->fault_state = 0;
1371 return true;
1374 if (DEBUGLEVEL >= 50) {
1375 fstring name;
1376 slprintf(name, sizeof(name)-1, "out_%s",
1377 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1378 dump_pdu_region(name, pkt->u.request.opnum,
1379 &p->out_data.rdata, offset1,
1380 p->out_data.rdata.length);
1383 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1384 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1386 /* Check for buffer underflow in rpc parsing */
1387 if ((DEBUGLEVEL >= 10) &&
1388 (pkt->frag_length < p->in_data.data.length)) {
1389 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1390 dump_data(10, p->in_data.data.data + pkt->frag_length,
1391 p->in_data.data.length - pkt->frag_length);
1394 return True;
1397 /****************************************************************************
1398 Initialise an outgoing packet.
1399 ****************************************************************************/
1401 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1403 output_data *o_data = &p->out_data;
1405 /* Reset the offset counters. */
1406 o_data->data_sent_length = 0;
1407 o_data->current_pdu_sent = 0;
1409 data_blob_free(&o_data->frag);
1411 /* Free any memory in the current return data buffer. */
1412 data_blob_free(&o_data->rdata);
1414 return True;
1417 /****************************************************************************
1418 Sets the fault state on incoming packets.
1419 ****************************************************************************/
1421 void set_incoming_fault(struct pipes_struct *p)
1423 data_blob_free(&p->in_data.data);
1424 p->in_data.pdu_needed_len = 0;
1425 p->in_data.pdu.length = 0;
1426 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1428 DEBUG(10, ("Setting fault state\n"));
1431 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1432 struct ncacn_packet *pkt,
1433 DATA_BLOB *raw_pkt)
1435 NTSTATUS status;
1436 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1437 size_t pad_len;
1439 DEBUG(10, ("Checking request auth.\n"));
1441 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1442 hdr_size += 16;
1445 /* in case of sealing this function will unseal the data in place */
1446 status = dcerpc_check_auth(auth, pkt,
1447 &pkt->u.request.stub_and_verifier,
1448 hdr_size, raw_pkt,
1449 &pad_len);
1450 if (!NT_STATUS_IS_OK(status)) {
1451 return status;
1455 /* remove padding and auth trailer,
1456 * this way the caller will get just the data */
1457 if (pkt->auth_length) {
1458 size_t trail_len = pad_len
1459 + DCERPC_AUTH_TRAILER_LENGTH
1460 + pkt->auth_length;
1461 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1462 return NT_STATUS_INFO_LENGTH_MISMATCH;
1464 pkt->u.request.stub_and_verifier.length -= trail_len;
1467 return NT_STATUS_OK;
1470 /****************************************************************************
1471 Processes a request pdu. This will do auth processing if needed, and
1472 appends the data into the complete stream if the LAST flag is not set.
1473 ****************************************************************************/
1475 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1477 NTSTATUS status;
1478 DATA_BLOB data;
1479 struct dcerpc_sec_vt_header2 hdr2;
1481 if (!p->pipe_bound) {
1482 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1483 set_incoming_fault(p);
1484 return False;
1487 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1488 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1489 p->header2 = hdr2;
1490 } else {
1491 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1492 set_incoming_fault(p);
1493 return false;
1497 /* Store the opnum */
1498 p->opnum = pkt->u.request.opnum;
1500 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1501 if (!NT_STATUS_IS_OK(status)) {
1502 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1503 nt_errstr(status)));
1504 set_incoming_fault(p);
1505 return false;
1508 data = pkt->u.request.stub_and_verifier;
1511 * Check the data length doesn't go over the 15Mb limit.
1512 * increased after observing a bug in the Windows NT 4.0 SP6a
1513 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1514 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1517 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1518 DEBUG(0, ("process_request_pdu: "
1519 "rpc data buffer too large (%u) + (%u)\n",
1520 (unsigned int)p->in_data.data.length,
1521 (unsigned int)data.length));
1522 set_incoming_fault(p);
1523 return False;
1527 * Append the data portion into the buffer and return.
1530 if (data.length) {
1531 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1532 data.data, data.length)) {
1533 DEBUG(0, ("Unable to append data size %u "
1534 "to parse buffer of size %u.\n",
1535 (unsigned int)data.length,
1536 (unsigned int)p->in_data.data.length));
1537 set_incoming_fault(p);
1538 return False;
1542 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1543 return true;
1547 * Ok - we finally have a complete RPC stream.
1548 * Call the rpc command to process it.
1551 return api_pipe_request(p, pkt);
1554 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1556 bool reply = false;
1558 /* Store the call_id */
1559 p->call_id = pkt->call_id;
1561 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1563 if (!pipe_init_outgoing_data(p)) {
1564 goto done;
1567 switch (pkt->ptype) {
1568 case DCERPC_PKT_REQUEST:
1569 reply = process_request_pdu(p, pkt);
1570 break;
1572 case DCERPC_PKT_PING: /* CL request - ignore... */
1573 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1574 (unsigned int)pkt->ptype));
1575 break;
1577 case DCERPC_PKT_RESPONSE: /* No responses here. */
1578 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1579 break;
1581 case DCERPC_PKT_FAULT:
1582 case DCERPC_PKT_WORKING:
1583 /* CL request - reply to a ping when a call in process. */
1584 case DCERPC_PKT_NOCALL:
1585 /* CL - server reply to a ping call. */
1586 case DCERPC_PKT_REJECT:
1587 case DCERPC_PKT_ACK:
1588 case DCERPC_PKT_CL_CANCEL:
1589 case DCERPC_PKT_FACK:
1590 case DCERPC_PKT_CANCEL_ACK:
1591 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1592 (unsigned int)pkt->ptype));
1593 break;
1595 case DCERPC_PKT_BIND:
1597 * We assume that a pipe bind is only in one pdu.
1599 reply = api_pipe_bind_req(p, pkt);
1600 break;
1602 case DCERPC_PKT_BIND_ACK:
1603 case DCERPC_PKT_BIND_NAK:
1604 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1605 "packet type %u received.\n",
1606 (unsigned int)pkt->ptype));
1607 break;
1610 case DCERPC_PKT_ALTER:
1612 * We assume that a pipe bind is only in one pdu.
1614 reply = api_pipe_alter_context(p, pkt);
1615 break;
1617 case DCERPC_PKT_ALTER_RESP:
1618 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1619 "Should only be server -> client.\n"));
1620 break;
1622 case DCERPC_PKT_AUTH3:
1624 * The third packet in an auth exchange.
1626 reply = api_pipe_bind_auth3(p, pkt);
1627 break;
1629 case DCERPC_PKT_SHUTDOWN:
1630 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1631 "Should only be server -> client.\n"));
1632 break;
1634 case DCERPC_PKT_CO_CANCEL:
1635 /* For now just free all client data and continue
1636 * processing. */
1637 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1638 " Abandoning rpc call.\n"));
1639 /* As we never do asynchronous RPC serving, we can
1640 * never cancel a call (as far as I know).
1641 * If we ever did we'd have to send a cancel_ack reply.
1642 * For now, just free all client data and continue
1643 * processing. */
1644 reply = True;
1645 break;
1647 #if 0
1648 /* Enable this if we're doing async rpc. */
1649 /* We must check the outstanding callid matches. */
1650 if (pipe_init_outgoing_data(p)) {
1651 /* Send a cancel_ack PDU reply. */
1652 /* We should probably check the auth-verifier here. */
1653 reply = setup_cancel_ack_reply(p, pkt);
1655 break;
1656 #endif
1658 case DCERPC_PKT_ORPHANED:
1659 /* We should probably check the auth-verifier here.
1660 * For now just free all client data and continue
1661 * processing. */
1662 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1663 " Abandoning rpc call.\n"));
1664 reply = True;
1665 break;
1667 default:
1668 DEBUG(0, ("process_complete_pdu: "
1669 "Unknown rpc type = %u received.\n",
1670 (unsigned int)pkt->ptype));
1671 break;
1674 done:
1675 if (!reply) {
1676 DEBUG(3,("DCE/RPC fault sent!"));
1677 set_incoming_fault(p);
1678 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1680 /* pkt and p->in_data.pdu.data freed by caller */