s3:rpc_server: let auth_generic_server_step() handle gensec_security == NULL
[Samba.git] / source3 / rpc_server / srv_pipe.c
blobcdbe5faf5733c352d2958c34d3e3c563f4d6f224
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;
511 if ((*session_info)->unix_token == NULL) {
512 DEBUG(1, ("Auth module failed to provide unix_token\n"));
513 return false;
517 * We're an authenticated bind over smb, so the session key needs to
518 * be set to "SystemLibraryDTC". Weird, but this is what Windows
519 * does. See the RPC-SAMBA3SESSIONKEY.
522 ret = session_info_set_session_key((*session_info), generic_session_key());
523 if (!ret) {
524 DEBUG(0, ("Failed to set session key!\n"));
525 return false;
528 return true;
531 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
533 struct gensec_security *gensec_security;
534 bool ok;
536 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
537 p->pipe_bound = true;
538 return NT_STATUS_OK;
541 gensec_security = talloc_get_type(p->auth.auth_ctx,
542 struct gensec_security);
543 if (gensec_security == NULL) {
544 return NT_STATUS_INTERNAL_ERROR;
547 ok = pipe_auth_generic_verify_final(p, gensec_security,
548 p->auth.auth_level,
549 &p->session_info);
550 if (!ok) {
551 return NT_STATUS_ACCESS_DENIED;
554 p->pipe_bound = true;
556 return NT_STATUS_OK;
559 /*******************************************************************
560 Respond to a pipe bind request.
561 *******************************************************************/
563 static bool api_pipe_bind_req(struct pipes_struct *p,
564 struct ncacn_packet *pkt)
566 struct dcerpc_auth auth_info;
567 uint16 assoc_gid;
568 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
569 NTSTATUS status;
570 struct ndr_syntax_id id;
571 uint8_t pfc_flags = 0;
572 union dcerpc_payload u;
573 struct dcerpc_ack_ctx bind_ack_ctx;
574 DATA_BLOB auth_resp = data_blob_null;
575 DATA_BLOB auth_blob = data_blob_null;
576 const struct ndr_interface_table *table;
578 /* No rebinds on a bound pipe - use alter context. */
579 if (p->pipe_bound) {
580 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
581 return setup_bind_nak(p, pkt);
584 if (pkt->u.bind.num_contexts == 0) {
585 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
586 goto err_exit;
590 * Try and find the correct pipe name to ensure
591 * that this is a pipe name we support.
593 id = pkt->u.bind.ctx_list[0].abstract_syntax;
595 table = ndr_table_by_uuid(&id.uuid);
596 if (table == NULL) {
597 DEBUG(0,("unknown interface\n"));
598 return false;
601 if (rpc_srv_pipe_exists_by_id(&id)) {
602 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
603 rpc_srv_get_pipe_cli_name(&id),
604 rpc_srv_get_pipe_srv_name(&id)));
605 } else {
606 status = smb_probe_module(
607 "rpc", dcerpc_default_transport_endpoint(pkt,
608 NCACN_NP, table));
610 if (NT_STATUS_IS_ERR(status)) {
611 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
612 "%s in bind request.\n",
613 ndr_interface_name(&id.uuid,
614 id.if_version)));
616 return setup_bind_nak(p, pkt);
619 if (rpc_srv_get_pipe_interface_by_cli_name(
620 dcerpc_default_transport_endpoint(pkt,
621 NCACN_NP, table),
622 &id)) {
623 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
624 rpc_srv_get_pipe_cli_name(&id),
625 rpc_srv_get_pipe_srv_name(&id)));
626 } else {
627 DEBUG(0, ("module %s doesn't provide functions for "
628 "pipe %s!\n",
629 ndr_interface_name(&id.uuid,
630 id.if_version),
631 ndr_interface_name(&id.uuid,
632 id.if_version)));
633 return setup_bind_nak(p, pkt);
637 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
639 if (pkt->u.bind.assoc_group_id != 0) {
640 assoc_gid = pkt->u.bind.assoc_group_id;
641 } else {
642 assoc_gid = 0x53f0;
646 * Create the bind response struct.
649 /* If the requested abstract synt uuid doesn't match our client pipe,
650 reject the bind_ack & set the transfer interface synt to all 0's,
651 ver 0 (observed when NT5 attempts to bind to abstract interfaces
652 unknown to NT4)
653 Needed when adding entries to a DACL from NT5 - SK */
655 if (check_bind_req(p,
656 &pkt->u.bind.ctx_list[0].abstract_syntax,
657 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
658 pkt->u.bind.ctx_list[0].context_id)) {
660 bind_ack_ctx.result = 0;
661 bind_ack_ctx.reason.value = 0;
662 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
663 } else {
664 p->pipe_bound = False;
665 /* Rejection reason: abstract syntax not supported */
666 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
667 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
668 bind_ack_ctx.syntax = ndr_syntax_id_null;
672 * Check if this is an authenticated bind request.
674 if (pkt->auth_length) {
675 /* Quick length check. Won't catch a bad auth footer,
676 * prevents overrun. */
678 if (pkt->frag_length < RPC_HEADER_LEN +
679 DCERPC_AUTH_TRAILER_LENGTH +
680 pkt->auth_length) {
681 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
682 "too long for fragment %u.\n",
683 (unsigned int)pkt->auth_length,
684 (unsigned int)pkt->frag_length));
685 goto err_exit;
689 * Decode the authentication verifier.
691 status = dcerpc_pull_dcerpc_auth(pkt,
692 &pkt->u.bind.auth_info,
693 &auth_info, p->endian);
694 if (!NT_STATUS_IS_OK(status)) {
695 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
696 goto err_exit;
699 auth_type = auth_info.auth_type;
701 /* Work out if we have to sign or seal etc. */
702 switch (auth_info.auth_level) {
703 case DCERPC_AUTH_LEVEL_INTEGRITY:
704 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
705 break;
706 case DCERPC_AUTH_LEVEL_PRIVACY:
707 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
708 break;
709 case DCERPC_AUTH_LEVEL_CONNECT:
710 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
711 break;
712 default:
713 DEBUG(0, ("Unexpected auth level (%u).\n",
714 (unsigned int)auth_info.auth_level ));
715 goto err_exit;
718 switch (auth_type) {
719 case DCERPC_AUTH_TYPE_NTLMSSP:
720 if (!pipe_auth_generic_bind(p, pkt,
721 &auth_info, &auth_resp)) {
722 goto err_exit;
724 assoc_gid = 0x7a77;
725 break;
727 case DCERPC_AUTH_TYPE_SCHANNEL:
728 if (!pipe_auth_generic_bind(p, pkt,
729 &auth_info, &auth_resp)) {
730 goto err_exit;
732 if (!session_info_set_session_key(p->session_info, generic_session_key())) {
733 DEBUG(0, ("session_info_set_session_key failed\n"));
734 goto err_exit;
736 p->pipe_bound = true;
737 break;
739 case DCERPC_AUTH_TYPE_SPNEGO:
740 case DCERPC_AUTH_TYPE_KRB5:
741 if (!pipe_auth_generic_bind(p, pkt,
742 &auth_info, &auth_resp)) {
743 goto err_exit;
745 break;
747 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
748 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
749 TALLOC_FREE(p->session_info);
751 status = make_session_info_system(p,
752 &p->session_info);
753 if (!NT_STATUS_IS_OK(status)) {
754 goto err_exit;
757 auth_resp = data_blob_talloc(pkt,
758 "NCALRPC_AUTH_OK",
759 15);
761 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
762 p->pipe_bound = true;
763 } else {
764 goto err_exit;
766 break;
768 case DCERPC_AUTH_TYPE_NONE:
769 break;
771 default:
772 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
773 goto err_exit;
777 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
778 /* Unauthenticated bind request. */
779 /* We're finished - no more packets. */
780 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
781 /* We must set the pipe auth_level here also. */
782 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
783 p->pipe_bound = True;
784 /* The session key was initialized from the SMB
785 * session in make_internal_rpc_pipe_p */
788 ZERO_STRUCT(u.bind_ack);
789 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
790 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
791 u.bind_ack.assoc_group_id = assoc_gid;
793 /* name has to be \PIPE\xxxxx */
794 u.bind_ack.secondary_address =
795 talloc_asprintf(pkt, "\\PIPE\\%s",
796 rpc_srv_get_pipe_srv_name(&id));
797 if (!u.bind_ack.secondary_address) {
798 DEBUG(0, ("Out of memory!\n"));
799 goto err_exit;
801 u.bind_ack.secondary_address_size =
802 strlen(u.bind_ack.secondary_address) + 1;
804 u.bind_ack.num_results = 1;
805 u.bind_ack.ctx_list = &bind_ack_ctx;
807 /* NOTE: We leave the auth_info empty so we can calculate the padding
808 * later and then append the auth_info --simo */
811 * Marshall directly into the outgoing PDU space. We
812 * must do this as we need to set to the bind response
813 * header and are never sending more than one PDU here.
816 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
818 if (p->auth.hdr_signing) {
819 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
822 status = dcerpc_push_ncacn_packet(p->mem_ctx,
823 DCERPC_PKT_BIND_ACK,
824 pfc_flags,
825 auth_resp.length,
826 pkt->call_id,
828 &p->out_data.frag);
829 if (!NT_STATUS_IS_OK(status)) {
830 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
831 nt_errstr(status)));
834 if (auth_resp.length) {
836 status = dcerpc_push_dcerpc_auth(pkt,
837 auth_type,
838 auth_info.auth_level,
840 1, /* auth_context_id */
841 &auth_resp,
842 &auth_blob);
843 if (!NT_STATUS_IS_OK(status)) {
844 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
845 goto err_exit;
849 /* Now that we have the auth len store it into the right place in
850 * the dcerpc header */
851 dcerpc_set_frag_length(&p->out_data.frag,
852 p->out_data.frag.length + auth_blob.length);
854 if (auth_blob.length) {
856 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
857 auth_blob.data, auth_blob.length)) {
858 DEBUG(0, ("Append of auth info failed.\n"));
859 goto err_exit;
864 * Setup the lengths for the initial reply.
867 p->out_data.data_sent_length = 0;
868 p->out_data.current_pdu_sent = 0;
870 TALLOC_FREE(auth_blob.data);
871 return True;
873 err_exit:
875 data_blob_free(&p->out_data.frag);
876 TALLOC_FREE(auth_blob.data);
877 return setup_bind_nak(p, pkt);
880 /*******************************************************************
881 This is the "stage3" response after a bind request and reply.
882 *******************************************************************/
884 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
886 struct dcerpc_auth auth_info;
887 DATA_BLOB response = data_blob_null;
888 struct gensec_security *gensec_security;
889 NTSTATUS status;
891 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
893 if (pkt->auth_length == 0) {
894 DEBUG(1, ("No auth field sent for bind request!\n"));
895 goto err;
898 /* Ensure there's enough data for an authenticated request. */
899 if (pkt->frag_length < RPC_HEADER_LEN
900 + DCERPC_AUTH_TRAILER_LENGTH
901 + pkt->auth_length) {
902 DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
903 "%u is too large.\n",
904 (unsigned int)pkt->auth_length));
905 goto err;
909 * Decode the authentication verifier response.
912 status = dcerpc_pull_dcerpc_auth(pkt,
913 &pkt->u.auth3.auth_info,
914 &auth_info, p->endian);
915 if (!NT_STATUS_IS_OK(status)) {
916 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
917 goto err;
920 /* We must NEVER look at auth_info->auth_pad_len here,
921 * as old Samba client code gets it wrong and sends it
922 * as zero. JRA.
925 if (auth_info.auth_type != p->auth.auth_type) {
926 DEBUG(1, ("Auth type mismatch! Client sent %d, "
927 "but auth was started as type %d!\n",
928 auth_info.auth_type, p->auth.auth_type));
929 goto err;
932 gensec_security = talloc_get_type(p->auth.auth_ctx,
933 struct gensec_security);
935 status = auth_generic_server_step(gensec_security,
936 pkt, &auth_info.credentials,
937 &response);
939 if (NT_STATUS_EQUAL(status,
940 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
941 response.length) {
942 DEBUG(1, (__location__ ": This was supposed to be the final "
943 "leg, but crypto machinery claims a response is "
944 "needed, aborting auth!\n"));
945 data_blob_free(&response);
946 goto err;
948 if (!NT_STATUS_IS_OK(status)) {
949 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
950 goto err;
953 /* Now verify auth was indeed successful and extract server info */
954 status = pipe_auth_verify_final(p);
955 if (!NT_STATUS_IS_OK(status)) {
956 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
957 goto err;
960 return true;
962 err:
964 TALLOC_FREE(p->auth.auth_ctx);
965 return false;
968 /****************************************************************************
969 Deal with an alter context call. Can be third part of 3 leg auth request for
970 SPNEGO calls.
971 ****************************************************************************/
973 static bool api_pipe_alter_context(struct pipes_struct *p,
974 struct ncacn_packet *pkt)
976 struct dcerpc_auth auth_info;
977 uint16 assoc_gid;
978 NTSTATUS status;
979 union dcerpc_payload u;
980 struct dcerpc_ack_ctx bind_ack_ctx;
981 DATA_BLOB auth_resp = data_blob_null;
982 DATA_BLOB auth_blob = data_blob_null;
983 int pad_len = 0;
984 struct gensec_security *gensec_security;
986 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
988 if (pkt->u.bind.assoc_group_id != 0) {
989 assoc_gid = pkt->u.bind.assoc_group_id;
990 } else {
991 assoc_gid = 0x53f0;
995 * Create the bind response struct.
998 /* If the requested abstract synt uuid doesn't match our client pipe,
999 reject the bind_ack & set the transfer interface synt to all 0's,
1000 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1001 unknown to NT4)
1002 Needed when adding entries to a DACL from NT5 - SK */
1004 if (check_bind_req(p,
1005 &pkt->u.bind.ctx_list[0].abstract_syntax,
1006 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1007 pkt->u.bind.ctx_list[0].context_id)) {
1009 bind_ack_ctx.result = 0;
1010 bind_ack_ctx.reason.value = 0;
1011 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1012 } else {
1013 p->pipe_bound = False;
1014 /* Rejection reason: abstract syntax not supported */
1015 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1016 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
1017 bind_ack_ctx.syntax = ndr_syntax_id_null;
1021 * Check if this is an authenticated alter context request.
1023 if (pkt->auth_length) {
1024 /* Quick length check. Won't catch a bad auth footer,
1025 * prevents overrun. */
1027 if (pkt->frag_length < RPC_HEADER_LEN +
1028 DCERPC_AUTH_TRAILER_LENGTH +
1029 pkt->auth_length) {
1030 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1031 "too long for fragment %u.\n",
1032 (unsigned int)pkt->auth_length,
1033 (unsigned int)pkt->frag_length ));
1034 goto err_exit;
1037 status = dcerpc_pull_dcerpc_auth(pkt,
1038 &pkt->u.bind.auth_info,
1039 &auth_info, p->endian);
1040 if (!NT_STATUS_IS_OK(status)) {
1041 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1042 goto err_exit;
1045 /* We can only finish if the pipe is unbound for now */
1046 if (p->pipe_bound) {
1047 DEBUG(0, (__location__ ": Pipe already bound, "
1048 "Altering Context not yet supported!\n"));
1049 goto err_exit;
1052 if (auth_info.auth_type != p->auth.auth_type) {
1053 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1054 "but auth was started as type %d!\n",
1055 auth_info.auth_type, p->auth.auth_type));
1056 goto err_exit;
1059 gensec_security = talloc_get_type(p->auth.auth_ctx,
1060 struct gensec_security);
1061 status = auth_generic_server_step(gensec_security,
1062 pkt,
1063 &auth_info.credentials,
1064 &auth_resp);
1065 if (NT_STATUS_IS_OK(status)) {
1066 /* third leg of auth, verify auth info */
1067 status = pipe_auth_verify_final(p);
1068 if (!NT_STATUS_IS_OK(status)) {
1069 DEBUG(0, ("Auth Verify failed (%s)\n",
1070 nt_errstr(status)));
1071 goto err_exit;
1073 } else if (NT_STATUS_EQUAL(status,
1074 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1075 DEBUG(10, ("More auth legs required.\n"));
1076 } else {
1077 DEBUG(0, ("Auth step returned an error (%s)\n",
1078 nt_errstr(status)));
1079 goto err_exit;
1083 ZERO_STRUCT(u.alter_resp);
1084 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1085 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1086 u.alter_resp.assoc_group_id = assoc_gid;
1088 /* secondary address CAN be NULL
1089 * as the specs say it's ignored.
1090 * It MUST be NULL to have the spoolss working.
1092 u.alter_resp.secondary_address = "";
1093 u.alter_resp.secondary_address_size = 1;
1095 u.alter_resp.num_results = 1;
1096 u.alter_resp.ctx_list = &bind_ack_ctx;
1098 /* NOTE: We leave the auth_info empty so we can calculate the padding
1099 * later and then append the auth_info --simo */
1102 * Marshall directly into the outgoing PDU space. We
1103 * must do this as we need to set to the bind response
1104 * header and are never sending more than one PDU here.
1107 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1108 DCERPC_PKT_ALTER_RESP,
1109 DCERPC_PFC_FLAG_FIRST |
1110 DCERPC_PFC_FLAG_LAST,
1111 auth_resp.length,
1112 pkt->call_id,
1114 &p->out_data.frag);
1115 if (!NT_STATUS_IS_OK(status)) {
1116 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1117 nt_errstr(status)));
1120 if (auth_resp.length) {
1122 /* Work out any padding needed before the auth footer. */
1123 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1124 if (pad_len) {
1125 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1126 DEBUG(10, ("auth pad_len = %u\n",
1127 (unsigned int)pad_len));
1130 status = dcerpc_push_dcerpc_auth(pkt,
1131 auth_info.auth_type,
1132 auth_info.auth_level,
1133 pad_len,
1134 1, /* auth_context_id */
1135 &auth_resp,
1136 &auth_blob);
1137 if (!NT_STATUS_IS_OK(status)) {
1138 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1139 goto err_exit;
1143 /* Now that we have the auth len store it into the right place in
1144 * the dcerpc header */
1145 dcerpc_set_frag_length(&p->out_data.frag,
1146 p->out_data.frag.length +
1147 pad_len + auth_blob.length);
1149 if (auth_resp.length) {
1150 if (pad_len) {
1151 char pad[SERVER_NDR_PADDING_SIZE];
1152 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1153 if (!data_blob_append(p->mem_ctx,
1154 &p->out_data.frag,
1155 pad, pad_len)) {
1156 DEBUG(0, ("api_pipe_bind_req: failed to add "
1157 "%u bytes of pad data.\n",
1158 (unsigned int)pad_len));
1159 goto err_exit;
1163 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1164 auth_blob.data, auth_blob.length)) {
1165 DEBUG(0, ("Append of auth info failed.\n"));
1166 goto err_exit;
1171 * Setup the lengths for the initial reply.
1174 p->out_data.data_sent_length = 0;
1175 p->out_data.current_pdu_sent = 0;
1177 TALLOC_FREE(auth_blob.data);
1178 return True;
1180 err_exit:
1182 data_blob_free(&p->out_data.frag);
1183 TALLOC_FREE(auth_blob.data);
1184 return setup_bind_nak(p, pkt);
1187 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1188 const struct api_struct *api_rpc_cmds, int n_cmds,
1189 const struct ndr_syntax_id *syntax);
1191 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1192 struct ncacn_packet *pkt,
1193 struct pipe_rpc_fns *pipe_fns)
1195 TALLOC_CTX *frame = talloc_stackframe();
1196 struct dcerpc_sec_verification_trailer *vt = NULL;
1197 const uint32_t bitmask1 =
1198 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1199 const struct dcerpc_sec_vt_pcontext pcontext = {
1200 .abstract_syntax = pipe_fns->syntax,
1201 .transfer_syntax = ndr_transfer_syntax_ndr,
1203 const struct dcerpc_sec_vt_header2 header2 =
1204 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1205 struct ndr_pull *ndr;
1206 enum ndr_err_code ndr_err;
1207 bool ret = false;
1209 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1210 if (ndr == NULL) {
1211 goto done;
1214 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1215 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1216 goto done;
1219 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1220 &pcontext, &header2);
1221 done:
1222 TALLOC_FREE(frame);
1223 return ret;
1226 /****************************************************************************
1227 Find the correct RPC function to call for this request.
1228 If the pipe is authenticated then become the correct UNIX user
1229 before doing the call.
1230 ****************************************************************************/
1232 static bool api_pipe_request(struct pipes_struct *p,
1233 struct ncacn_packet *pkt)
1235 TALLOC_CTX *frame = talloc_stackframe();
1236 bool ret = False;
1237 struct pipe_rpc_fns *pipe_fns;
1239 if (!p->pipe_bound) {
1240 DEBUG(1, ("Pipe not bound!\n"));
1241 data_blob_free(&p->out_data.rdata);
1242 TALLOC_FREE(frame);
1243 return false;
1246 /* get the set of RPC functions for this context */
1247 pipe_fns = find_pipe_fns_by_context(p->contexts,
1248 pkt->u.request.context_id);
1249 if (pipe_fns == NULL) {
1250 DEBUG(0, ("No rpc function table associated with context "
1251 "[%d]\n",
1252 pkt->u.request.context_id));
1253 data_blob_free(&p->out_data.rdata);
1254 TALLOC_FREE(frame);
1255 return false;
1258 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1259 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1260 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1261 data_blob_free(&p->out_data.rdata);
1262 TALLOC_FREE(frame);
1263 return true;
1266 if (!become_authenticated_pipe_user(p->session_info)) {
1267 DEBUG(1, ("Failed to become pipe user!\n"));
1268 data_blob_free(&p->out_data.rdata);
1269 TALLOC_FREE(frame);
1270 return false;
1273 DEBUG(5, ("Requested %s rpc service\n",
1274 ndr_interface_name(&pipe_fns->syntax.uuid,
1275 pipe_fns->syntax.if_version)));
1277 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1278 &pipe_fns->syntax);
1279 unbecome_authenticated_pipe_user();
1281 TALLOC_FREE(frame);
1282 return ret;
1285 /*******************************************************************
1286 Calls the underlying RPC function for a named pipe.
1287 ********************************************************************/
1289 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1290 const struct api_struct *api_rpc_cmds, int n_cmds,
1291 const struct ndr_syntax_id *syntax)
1293 int fn_num;
1294 uint32_t offset1;
1295 const struct ndr_interface_table *table;
1297 /* interpret the command */
1298 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1299 ndr_interface_name(&syntax->uuid, syntax->if_version),
1300 pkt->u.request.opnum));
1302 table = ndr_table_by_uuid(&syntax->uuid);
1303 if (table == NULL) {
1304 DEBUG(0,("unknown interface\n"));
1305 return false;
1308 if (DEBUGLEVEL >= 50) {
1309 fstring name;
1310 slprintf(name, sizeof(name)-1, "in_%s",
1311 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1312 dump_pdu_region(name, pkt->u.request.opnum,
1313 &p->in_data.data, 0,
1314 p->in_data.data.length);
1317 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1318 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1319 api_rpc_cmds[fn_num].fn != NULL) {
1320 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1321 api_rpc_cmds[fn_num].name));
1322 break;
1326 if (fn_num == n_cmds) {
1328 * For an unknown RPC just return a fault PDU but
1329 * return True to allow RPC's on the pipe to continue
1330 * and not put the pipe into fault state. JRA.
1332 DEBUG(4, ("unknown\n"));
1333 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1334 return True;
1337 offset1 = p->out_data.rdata.length;
1339 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1340 fn_num, api_rpc_cmds[fn_num].fn));
1341 /* do the actual command */
1342 if(!api_rpc_cmds[fn_num].fn(p)) {
1343 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1344 ndr_interface_name(&syntax->uuid, syntax->if_version),
1345 api_rpc_cmds[fn_num].name));
1346 data_blob_free(&p->out_data.rdata);
1347 return False;
1350 if (p->fault_state) {
1351 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1352 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1353 p->fault_state = 0;
1354 return true;
1357 if (DEBUGLEVEL >= 50) {
1358 fstring name;
1359 slprintf(name, sizeof(name)-1, "out_%s",
1360 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1361 dump_pdu_region(name, pkt->u.request.opnum,
1362 &p->out_data.rdata, offset1,
1363 p->out_data.rdata.length);
1366 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1367 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1369 /* Check for buffer underflow in rpc parsing */
1370 if ((DEBUGLEVEL >= 10) &&
1371 (pkt->frag_length < p->in_data.data.length)) {
1372 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1373 dump_data(10, p->in_data.data.data + pkt->frag_length,
1374 p->in_data.data.length - pkt->frag_length);
1377 return True;
1380 /****************************************************************************
1381 Initialise an outgoing packet.
1382 ****************************************************************************/
1384 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1386 output_data *o_data = &p->out_data;
1388 /* Reset the offset counters. */
1389 o_data->data_sent_length = 0;
1390 o_data->current_pdu_sent = 0;
1392 data_blob_free(&o_data->frag);
1394 /* Free any memory in the current return data buffer. */
1395 data_blob_free(&o_data->rdata);
1397 return True;
1400 /****************************************************************************
1401 Sets the fault state on incoming packets.
1402 ****************************************************************************/
1404 void set_incoming_fault(struct pipes_struct *p)
1406 data_blob_free(&p->in_data.data);
1407 p->in_data.pdu_needed_len = 0;
1408 p->in_data.pdu.length = 0;
1409 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1411 DEBUG(10, ("Setting fault state\n"));
1414 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1415 struct ncacn_packet *pkt,
1416 DATA_BLOB *raw_pkt)
1418 NTSTATUS status;
1419 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1420 size_t pad_len;
1422 DEBUG(10, ("Checking request auth.\n"));
1424 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1425 hdr_size += 16;
1428 /* in case of sealing this function will unseal the data in place */
1429 status = dcerpc_check_auth(auth, pkt,
1430 &pkt->u.request.stub_and_verifier,
1431 hdr_size, raw_pkt,
1432 &pad_len);
1433 if (!NT_STATUS_IS_OK(status)) {
1434 return status;
1438 /* remove padding and auth trailer,
1439 * this way the caller will get just the data */
1440 if (pkt->auth_length) {
1441 size_t trail_len = pad_len
1442 + DCERPC_AUTH_TRAILER_LENGTH
1443 + pkt->auth_length;
1444 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1445 return NT_STATUS_INFO_LENGTH_MISMATCH;
1447 pkt->u.request.stub_and_verifier.length -= trail_len;
1450 return NT_STATUS_OK;
1453 /****************************************************************************
1454 Processes a request pdu. This will do auth processing if needed, and
1455 appends the data into the complete stream if the LAST flag is not set.
1456 ****************************************************************************/
1458 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1460 NTSTATUS status;
1461 DATA_BLOB data;
1462 struct dcerpc_sec_vt_header2 hdr2;
1464 if (!p->pipe_bound) {
1465 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1466 set_incoming_fault(p);
1467 return False;
1470 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1471 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1472 p->header2 = hdr2;
1473 } else {
1474 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1475 set_incoming_fault(p);
1476 return false;
1480 /* Store the opnum */
1481 p->opnum = pkt->u.request.opnum;
1483 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1484 if (!NT_STATUS_IS_OK(status)) {
1485 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1486 nt_errstr(status)));
1487 set_incoming_fault(p);
1488 return false;
1491 data = pkt->u.request.stub_and_verifier;
1494 * Check the data length doesn't go over the 15Mb limit.
1495 * increased after observing a bug in the Windows NT 4.0 SP6a
1496 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1497 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1500 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1501 DEBUG(0, ("process_request_pdu: "
1502 "rpc data buffer too large (%u) + (%u)\n",
1503 (unsigned int)p->in_data.data.length,
1504 (unsigned int)data.length));
1505 set_incoming_fault(p);
1506 return False;
1510 * Append the data portion into the buffer and return.
1513 if (data.length) {
1514 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1515 data.data, data.length)) {
1516 DEBUG(0, ("Unable to append data size %u "
1517 "to parse buffer of size %u.\n",
1518 (unsigned int)data.length,
1519 (unsigned int)p->in_data.data.length));
1520 set_incoming_fault(p);
1521 return False;
1525 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1526 return true;
1530 * Ok - we finally have a complete RPC stream.
1531 * Call the rpc command to process it.
1534 return api_pipe_request(p, pkt);
1537 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1539 bool reply = false;
1541 /* Store the call_id */
1542 p->call_id = pkt->call_id;
1544 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1546 if (!pipe_init_outgoing_data(p)) {
1547 goto done;
1550 switch (pkt->ptype) {
1551 case DCERPC_PKT_REQUEST:
1552 reply = process_request_pdu(p, pkt);
1553 break;
1555 case DCERPC_PKT_PING: /* CL request - ignore... */
1556 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1557 (unsigned int)pkt->ptype));
1558 break;
1560 case DCERPC_PKT_RESPONSE: /* No responses here. */
1561 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1562 break;
1564 case DCERPC_PKT_FAULT:
1565 case DCERPC_PKT_WORKING:
1566 /* CL request - reply to a ping when a call in process. */
1567 case DCERPC_PKT_NOCALL:
1568 /* CL - server reply to a ping call. */
1569 case DCERPC_PKT_REJECT:
1570 case DCERPC_PKT_ACK:
1571 case DCERPC_PKT_CL_CANCEL:
1572 case DCERPC_PKT_FACK:
1573 case DCERPC_PKT_CANCEL_ACK:
1574 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1575 (unsigned int)pkt->ptype));
1576 break;
1578 case DCERPC_PKT_BIND:
1580 * We assume that a pipe bind is only in one pdu.
1582 reply = api_pipe_bind_req(p, pkt);
1583 break;
1585 case DCERPC_PKT_BIND_ACK:
1586 case DCERPC_PKT_BIND_NAK:
1587 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1588 "packet type %u received.\n",
1589 (unsigned int)pkt->ptype));
1590 break;
1593 case DCERPC_PKT_ALTER:
1595 * We assume that a pipe bind is only in one pdu.
1597 reply = api_pipe_alter_context(p, pkt);
1598 break;
1600 case DCERPC_PKT_ALTER_RESP:
1601 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1602 "Should only be server -> client.\n"));
1603 break;
1605 case DCERPC_PKT_AUTH3:
1607 * The third packet in an auth exchange.
1609 reply = api_pipe_bind_auth3(p, pkt);
1610 break;
1612 case DCERPC_PKT_SHUTDOWN:
1613 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1614 "Should only be server -> client.\n"));
1615 break;
1617 case DCERPC_PKT_CO_CANCEL:
1618 /* For now just free all client data and continue
1619 * processing. */
1620 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1621 " Abandoning rpc call.\n"));
1622 /* As we never do asynchronous RPC serving, we can
1623 * never cancel a call (as far as I know).
1624 * If we ever did we'd have to send a cancel_ack reply.
1625 * For now, just free all client data and continue
1626 * processing. */
1627 reply = True;
1628 break;
1630 #if 0
1631 /* Enable this if we're doing async rpc. */
1632 /* We must check the outstanding callid matches. */
1633 if (pipe_init_outgoing_data(p)) {
1634 /* Send a cancel_ack PDU reply. */
1635 /* We should probably check the auth-verifier here. */
1636 reply = setup_cancel_ack_reply(p, pkt);
1638 break;
1639 #endif
1641 case DCERPC_PKT_ORPHANED:
1642 /* We should probably check the auth-verifier here.
1643 * For now just free all client data and continue
1644 * processing. */
1645 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1646 " Abandoning rpc call.\n"));
1647 reply = True;
1648 break;
1650 default:
1651 DEBUG(0, ("process_complete_pdu: "
1652 "Unknown rpc type = %u received.\n",
1653 (unsigned int)pkt->ptype));
1654 break;
1657 done:
1658 if (!reply) {
1659 DEBUG(3,("DCE/RPC fault sent!"));
1660 set_incoming_fault(p);
1661 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1663 /* pkt and p->in_data.pdu.data freed by caller */