s3:rpc_server: pass everything but AUTH_TYPE_{NONE,NCALRPC_AS_SYSTEM} to gensec
[Samba.git] / source3 / rpc_server / srv_pipe.c
blobd85751d84680ee299665dbf8386af08eff212c57
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 /* this module apparently provides an implementation of DCE/RPC over a
21 * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
22 * documentation are available (in on-line form) from the X-Open group.
24 * this module should provide a level of abstraction between SMB
25 * and DCE/RPC, while minimising the amount of mallocs, unnecessary
26 * data copies, and network traffic.
30 #include "includes.h"
31 #include "system/filesys.h"
32 #include "srv_pipe_internal.h"
33 #include "../librpc/gen_ndr/dcerpc.h"
34 #include "../librpc/rpc/rpc_common.h"
35 #include "dcesrv_auth_generic.h"
36 #include "rpc_server.h"
37 #include "rpc_dce.h"
38 #include "smbd/smbd.h"
39 #include "auth.h"
40 #include "ntdomain.h"
41 #include "rpc_server/srv_pipe.h"
42 #include "rpc_server/rpc_contexts.h"
43 #include "lib/param/param.h"
44 #include "librpc/ndr/ndr_table.h"
45 #include "auth/gensec/gensec.h"
46 #include "librpc/ndr/ndr_dcerpc.h"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_RPC_SRV
51 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p);
53 /**
54 * Dump everything from the start of the end up of the provided data
55 * into a file, but only at debug level >= 50
56 **/
57 static void dump_pdu_region(const char *name, int v,
58 DATA_BLOB *data, size_t start, size_t end)
60 int fd, i;
61 char *fname = NULL;
62 ssize_t sz;
64 if (DEBUGLEVEL < 50) return;
66 if (start > data->length || end > data->length || start > end) return;
68 for (i = 1; i < 100; i++) {
69 if (v != -1) {
70 fname = talloc_asprintf(talloc_tos(),
71 "/tmp/%s_%d.%d.prs",
72 name, v, i);
73 } else {
74 fname = talloc_asprintf(talloc_tos(),
75 "/tmp/%s_%d.prs",
76 name, i);
78 if (!fname) {
79 return;
81 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
82 if (fd != -1 || errno != EEXIST) break;
84 if (fd != -1) {
85 sz = write(fd, data->data + start, end - start);
86 i = close(fd);
87 if ((sz != end - start) || (i != 0) ) {
88 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
89 fname, (unsigned long)sz,
90 (unsigned long)end - start, i));
91 } else {
92 DEBUG(0,("created %s\n", fname));
95 TALLOC_FREE(fname);
98 static DATA_BLOB generic_session_key(void)
100 return data_blob_const("SystemLibraryDTC", 16);
103 /*******************************************************************
104 Generate the next PDU to be returned from the data.
105 ********************************************************************/
107 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
108 struct pipe_auth_data *auth,
109 uint32_t call_id,
110 DATA_BLOB *rdata,
111 size_t data_sent_length,
112 DATA_BLOB *frag,
113 size_t *pdu_size)
115 union dcerpc_payload u;
116 uint8_t pfc_flags;
117 size_t data_left;
118 size_t data_to_send;
119 size_t frag_len;
120 size_t pad_len = 0;
121 size_t auth_len = 0;
122 NTSTATUS status;
124 ZERO_STRUCT(u.response);
126 /* Set up rpc packet pfc flags. */
127 if (data_sent_length == 0) {
128 pfc_flags = DCERPC_PFC_FLAG_FIRST;
129 } else {
130 pfc_flags = 0;
133 /* Work out how much we can fit in a single PDU. */
134 data_left = rdata->length - data_sent_length;
136 /* Ensure there really is data left to send. */
137 if (!data_left) {
138 DEBUG(0, ("No data left to send !\n"));
139 return NT_STATUS_BUFFER_TOO_SMALL;
142 status = dcerpc_guess_sizes(auth,
143 DCERPC_RESPONSE_LENGTH,
144 data_left,
145 RPC_MAX_PDU_FRAG_LEN,
146 SERVER_NDR_PADDING_SIZE,
147 &data_to_send, &frag_len,
148 &auth_len, &pad_len);
149 if (!NT_STATUS_IS_OK(status)) {
150 return status;
153 /* Set up the alloc hint. This should be the data left to send. */
154 u.response.alloc_hint = data_left;
156 /* Work out if this PDU will be the last. */
157 if (data_sent_length + data_to_send >= rdata->length) {
158 pfc_flags |= DCERPC_PFC_FLAG_LAST;
161 /* Prepare data to be NDR encoded. */
162 u.response.stub_and_verifier =
163 data_blob_const(rdata->data + data_sent_length, data_to_send);
165 /* Store the packet in the data stream. */
166 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
167 pfc_flags, auth_len, call_id,
168 &u, frag);
169 if (!NT_STATUS_IS_OK(status)) {
170 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
171 return status;
174 if (auth_len) {
175 /* Set the proper length on the pdu, including padding.
176 * Only needed if an auth trailer will be appended. */
177 dcerpc_set_frag_length(frag, frag->length
178 + pad_len
179 + DCERPC_AUTH_TRAILER_LENGTH
180 + auth_len);
183 if (auth_len) {
184 status = dcerpc_add_auth_footer(auth, pad_len, frag);
185 if (!NT_STATUS_IS_OK(status)) {
186 data_blob_free(frag);
187 return status;
191 *pdu_size = data_to_send;
192 return NT_STATUS_OK;
195 /*******************************************************************
196 Generate the next PDU to be returned from the data in p->rdata.
197 ********************************************************************/
199 bool create_next_pdu(struct pipes_struct *p)
201 size_t pdu_size = 0;
202 NTSTATUS status;
205 * If we're in the fault state, keep returning fault PDU's until
206 * the pipe gets closed. JRA.
208 if (p->fault_state) {
209 setup_fault_pdu(p, NT_STATUS(p->fault_state));
210 return true;
213 status = create_next_packet(p->mem_ctx, &p->auth,
214 p->call_id, &p->out_data.rdata,
215 p->out_data.data_sent_length,
216 &p->out_data.frag, &pdu_size);
217 if (!NT_STATUS_IS_OK(status)) {
218 DEBUG(0, ("Failed to create packet with error %s, "
219 "(auth level %u / type %u)\n",
220 nt_errstr(status),
221 (unsigned int)p->auth.auth_level,
222 (unsigned int)p->auth.auth_type));
223 return false;
226 /* Setup the counts for this PDU. */
227 p->out_data.data_sent_length += pdu_size;
228 p->out_data.current_pdu_sent = 0;
229 return true;
233 static bool pipe_init_outgoing_data(struct pipes_struct *p);
235 /*******************************************************************
236 Marshall a bind_nak pdu.
237 *******************************************************************/
239 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
241 NTSTATUS status;
242 union dcerpc_payload u;
244 /* Free any memory in the current return data buffer. */
245 pipe_init_outgoing_data(p);
248 * Initialize a bind_nak header.
251 ZERO_STRUCT(u);
253 u.bind_nak.reject_reason = 0;
256 * Marshall directly into the outgoing PDU space. We
257 * must do this as we need to set to the bind response
258 * header and are never sending more than one PDU here.
261 status = dcerpc_push_ncacn_packet(p->mem_ctx,
262 DCERPC_PKT_BIND_NAK,
263 DCERPC_PFC_FLAG_FIRST |
264 DCERPC_PFC_FLAG_LAST,
266 pkt->call_id,
268 &p->out_data.frag);
269 if (!NT_STATUS_IS_OK(status)) {
270 return False;
273 p->out_data.data_sent_length = 0;
274 p->out_data.current_pdu_sent = 0;
276 TALLOC_FREE(p->auth.auth_ctx);
277 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
278 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
279 p->pipe_bound = False;
281 return True;
284 /*******************************************************************
285 Marshall a fault pdu.
286 *******************************************************************/
288 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
290 NTSTATUS status;
291 union dcerpc_payload u;
293 /* Free any memory in the current return data buffer. */
294 pipe_init_outgoing_data(p);
297 * Initialize a fault header.
300 ZERO_STRUCT(u);
302 u.fault.status = NT_STATUS_V(fault_status);
303 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
306 * Marshall directly into the outgoing PDU space. We
307 * must do this as we need to set to the bind response
308 * header and are never sending more than one PDU here.
311 status = dcerpc_push_ncacn_packet(p->mem_ctx,
312 DCERPC_PKT_FAULT,
313 DCERPC_PFC_FLAG_FIRST |
314 DCERPC_PFC_FLAG_LAST |
315 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
317 p->call_id,
319 &p->out_data.frag);
320 if (!NT_STATUS_IS_OK(status)) {
321 return False;
324 p->out_data.data_sent_length = 0;
325 p->out_data.current_pdu_sent = 0;
327 return True;
330 /*******************************************************************
331 Ensure a bind request has the correct abstract & transfer interface.
332 Used to reject unknown binds from Win2k.
333 *******************************************************************/
335 static bool check_bind_req(struct pipes_struct *p,
336 struct ndr_syntax_id* abstract,
337 struct ndr_syntax_id* transfer,
338 uint32_t context_id)
340 struct pipe_rpc_fns *context_fns;
341 bool ok;
343 DEBUG(3,("check_bind_req for %s\n",
344 ndr_interface_name(&abstract->uuid,
345 abstract->if_version)));
347 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
348 if (rpc_srv_pipe_exists_by_id(abstract) &&
349 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
350 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
351 rpc_srv_get_pipe_cli_name(abstract),
352 rpc_srv_get_pipe_srv_name(abstract)));
353 } else {
354 return false;
357 ok = init_pipe_handles(p, abstract);
358 if (!ok) {
359 DEBUG(1, ("Failed to init pipe handles!\n"));
360 return false;
363 context_fns = talloc(p, struct pipe_rpc_fns);
364 if (context_fns == NULL) {
365 DEBUG(0,("check_bind_req: talloc() failed!\n"));
366 return false;
369 context_fns->next = context_fns->prev = NULL;
370 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
371 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
372 context_fns->context_id = context_id;
373 context_fns->syntax = *abstract;
375 /* add to the list of open contexts */
377 DLIST_ADD( p->contexts, context_fns );
379 return True;
383 * Is a named pipe known?
384 * @param[in] pipename Just the filename
385 * @result Do we want to serve this?
387 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
389 NTSTATUS status;
391 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
392 DEBUG(10, ("refusing spoolss access\n"));
393 return false;
396 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
397 return true;
400 status = smb_probe_module("rpc", pipename);
401 if (!NT_STATUS_IS_OK(status)) {
402 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
403 return false;
405 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
408 * Scan the list again for the interface id
410 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
411 return true;
414 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
415 pipename));
417 return false;
420 /*******************************************************************
421 Handle an NTLMSSP bind auth.
422 *******************************************************************/
424 static bool pipe_auth_generic_bind(struct pipes_struct *p,
425 struct ncacn_packet *pkt,
426 struct dcerpc_auth *auth_info,
427 DATA_BLOB *response)
429 TALLOC_CTX *mem_ctx = pkt;
430 struct gensec_security *gensec_security = NULL;
431 NTSTATUS status;
433 status = auth_generic_server_authtype_start(p,
434 auth_info->auth_type,
435 auth_info->auth_level,
436 &auth_info->credentials,
437 response,
438 p->remote_address,
439 &gensec_security);
440 if (!NT_STATUS_IS_OK(status) &&
441 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
443 DEBUG(0, (__location__ ": auth_generic_server_authtype_start[%u/%u] failed: %s\n",
444 auth_info->auth_type, auth_info->auth_level, nt_errstr(status)));
445 return false;
448 /* Make sure data is bound to the memctx, to be freed the caller */
449 talloc_steal(mem_ctx, response->data);
451 p->auth.auth_ctx = gensec_security;
452 p->auth.auth_type = auth_info->auth_type;
454 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
455 p->auth.client_hdr_signing = true;
456 p->auth.hdr_signing = gensec_have_feature(gensec_security,
457 GENSEC_FEATURE_SIGN_PKT_HEADER);
460 if (p->auth.hdr_signing) {
461 gensec_want_feature(gensec_security,
462 GENSEC_FEATURE_SIGN_PKT_HEADER);
465 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
466 return true;
469 status = pipe_auth_verify_final(p);
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
472 nt_errstr(status)));
473 return false;
476 return true;
479 /*******************************************************************
480 Process an NTLMSSP authentication response.
481 If this function succeeds, the user has been authenticated
482 and their domain, name and calling workstation stored in
483 the pipe struct.
484 *******************************************************************/
486 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
487 struct gensec_security *gensec_security,
488 enum dcerpc_AuthLevel auth_level,
489 struct auth_session_info **session_info)
491 NTSTATUS status;
492 bool ret;
494 DEBUG(5, (__location__ ": checking user details\n"));
496 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
497 ensure the underlying NTLMSSP flags are also set. If not we should
498 refuse the bind. */
500 status = auth_generic_server_check_flags(gensec_security,
501 (auth_level ==
502 DCERPC_AUTH_LEVEL_INTEGRITY),
503 (auth_level ==
504 DCERPC_AUTH_LEVEL_PRIVACY));
505 if (!NT_STATUS_IS_OK(status)) {
506 DEBUG(0, (__location__ ": Client failed to negotatie proper "
507 "security for rpc connection\n"));
508 return false;
511 TALLOC_FREE(*session_info);
513 status = auth_generic_server_get_user_info(gensec_security,
514 mem_ctx, session_info);
515 if (!NT_STATUS_IS_OK(status)) {
516 DEBUG(0, (__location__ ": failed to obtain the server info "
517 "for authenticated user: %s\n", nt_errstr(status)));
518 return false;
521 if ((*session_info)->security_token == NULL) {
522 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
523 return false;
526 if ((*session_info)->unix_token == NULL) {
527 DEBUG(1, ("Auth module failed to provide unix_token\n"));
528 return false;
532 * We're an authenticated bind over smb, so the session key needs to
533 * be set to "SystemLibraryDTC". Weird, but this is what Windows
534 * does. See the RPC-SAMBA3SESSIONKEY.
537 ret = session_info_set_session_key((*session_info), generic_session_key());
538 if (!ret) {
539 DEBUG(0, ("Failed to set session key!\n"));
540 return false;
543 return true;
546 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
548 struct gensec_security *gensec_security;
549 bool ok;
551 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
552 p->pipe_bound = true;
553 return NT_STATUS_OK;
556 gensec_security = talloc_get_type(p->auth.auth_ctx,
557 struct gensec_security);
558 if (gensec_security == NULL) {
559 return NT_STATUS_INTERNAL_ERROR;
562 ok = pipe_auth_generic_verify_final(p, gensec_security,
563 p->auth.auth_level,
564 &p->session_info);
565 if (!ok) {
566 return NT_STATUS_ACCESS_DENIED;
569 p->pipe_bound = true;
571 return NT_STATUS_OK;
574 /*******************************************************************
575 Respond to a pipe bind request.
576 *******************************************************************/
578 static bool api_pipe_bind_req(struct pipes_struct *p,
579 struct ncacn_packet *pkt)
581 struct dcerpc_auth auth_info;
582 uint16 assoc_gid;
583 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
584 NTSTATUS status;
585 struct ndr_syntax_id id;
586 uint8_t pfc_flags = 0;
587 union dcerpc_payload u;
588 struct dcerpc_ack_ctx bind_ack_ctx;
589 DATA_BLOB auth_resp = data_blob_null;
590 DATA_BLOB auth_blob = data_blob_null;
591 const struct ndr_interface_table *table;
593 /* No rebinds on a bound pipe - use alter context. */
594 if (p->pipe_bound) {
595 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
596 return setup_bind_nak(p, pkt);
599 if (pkt->u.bind.num_contexts == 0) {
600 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
601 goto err_exit;
605 * Try and find the correct pipe name to ensure
606 * that this is a pipe name we support.
608 id = pkt->u.bind.ctx_list[0].abstract_syntax;
610 table = ndr_table_by_uuid(&id.uuid);
611 if (table == NULL) {
612 DEBUG(0,("unknown interface\n"));
613 return false;
616 if (rpc_srv_pipe_exists_by_id(&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 status = smb_probe_module(
622 "rpc", dcerpc_default_transport_endpoint(pkt,
623 NCACN_NP, table));
625 if (NT_STATUS_IS_ERR(status)) {
626 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
627 "%s in bind request.\n",
628 ndr_interface_name(&id.uuid,
629 id.if_version)));
631 return setup_bind_nak(p, pkt);
634 if (rpc_srv_get_pipe_interface_by_cli_name(
635 dcerpc_default_transport_endpoint(pkt,
636 NCACN_NP, table),
637 &id)) {
638 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
639 rpc_srv_get_pipe_cli_name(&id),
640 rpc_srv_get_pipe_srv_name(&id)));
641 } else {
642 DEBUG(0, ("module %s doesn't provide functions for "
643 "pipe %s!\n",
644 ndr_interface_name(&id.uuid,
645 id.if_version),
646 ndr_interface_name(&id.uuid,
647 id.if_version)));
648 return setup_bind_nak(p, pkt);
652 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
654 if (pkt->u.bind.assoc_group_id != 0) {
655 assoc_gid = pkt->u.bind.assoc_group_id;
656 } else {
657 assoc_gid = 0x53f0;
661 * Create the bind response struct.
664 /* If the requested abstract synt uuid doesn't match our client pipe,
665 reject the bind_ack & set the transfer interface synt to all 0's,
666 ver 0 (observed when NT5 attempts to bind to abstract interfaces
667 unknown to NT4)
668 Needed when adding entries to a DACL from NT5 - SK */
670 if (check_bind_req(p,
671 &pkt->u.bind.ctx_list[0].abstract_syntax,
672 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
673 pkt->u.bind.ctx_list[0].context_id)) {
675 bind_ack_ctx.result = 0;
676 bind_ack_ctx.reason.value = 0;
677 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
678 } else {
679 p->pipe_bound = False;
680 /* Rejection reason: abstract syntax not supported */
681 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
682 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
683 bind_ack_ctx.syntax = ndr_syntax_id_null;
687 * Check if this is an authenticated bind request.
689 if (pkt->auth_length) {
690 /* Quick length check. Won't catch a bad auth footer,
691 * prevents overrun. */
693 if (pkt->frag_length < RPC_HEADER_LEN +
694 DCERPC_AUTH_TRAILER_LENGTH +
695 pkt->auth_length) {
696 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
697 "too long for fragment %u.\n",
698 (unsigned int)pkt->auth_length,
699 (unsigned int)pkt->frag_length));
700 goto err_exit;
704 * Decode the authentication verifier.
706 status = dcerpc_pull_dcerpc_auth(pkt,
707 &pkt->u.bind.auth_info,
708 &auth_info, p->endian);
709 if (!NT_STATUS_IS_OK(status)) {
710 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
711 goto err_exit;
714 auth_type = auth_info.auth_type;
716 /* Work out if we have to sign or seal etc. */
717 switch (auth_info.auth_level) {
718 case DCERPC_AUTH_LEVEL_INTEGRITY:
719 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
720 break;
721 case DCERPC_AUTH_LEVEL_PRIVACY:
722 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
723 break;
724 case DCERPC_AUTH_LEVEL_CONNECT:
725 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
726 break;
727 default:
728 DEBUG(0, ("Unexpected auth level (%u).\n",
729 (unsigned int)auth_info.auth_level ));
730 goto err_exit;
733 switch (auth_type) {
734 case DCERPC_AUTH_TYPE_NONE:
735 break;
737 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
738 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
739 TALLOC_FREE(p->session_info);
741 status = make_session_info_system(p,
742 &p->session_info);
743 if (!NT_STATUS_IS_OK(status)) {
744 goto err_exit;
747 auth_resp = data_blob_talloc(pkt,
748 "NCALRPC_AUTH_OK",
749 15);
751 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
752 p->pipe_bound = true;
753 } else {
754 goto err_exit;
756 break;
758 default:
759 if (!pipe_auth_generic_bind(p, pkt,
760 &auth_info, &auth_resp)) {
761 goto err_exit;
763 break;
767 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
768 /* Unauthenticated bind request. */
769 /* We're finished - no more packets. */
770 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
771 /* We must set the pipe auth_level here also. */
772 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
773 p->pipe_bound = True;
774 /* The session key was initialized from the SMB
775 * session in make_internal_rpc_pipe_p */
778 ZERO_STRUCT(u.bind_ack);
779 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
780 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
781 u.bind_ack.assoc_group_id = assoc_gid;
783 /* name has to be \PIPE\xxxxx */
784 u.bind_ack.secondary_address =
785 talloc_asprintf(pkt, "\\PIPE\\%s",
786 rpc_srv_get_pipe_srv_name(&id));
787 if (!u.bind_ack.secondary_address) {
788 DEBUG(0, ("Out of memory!\n"));
789 goto err_exit;
791 u.bind_ack.secondary_address_size =
792 strlen(u.bind_ack.secondary_address) + 1;
794 u.bind_ack.num_results = 1;
795 u.bind_ack.ctx_list = &bind_ack_ctx;
797 /* NOTE: We leave the auth_info empty so we can calculate the padding
798 * later and then append the auth_info --simo */
801 * Marshall directly into the outgoing PDU space. We
802 * must do this as we need to set to the bind response
803 * header and are never sending more than one PDU here.
806 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
808 if (p->auth.hdr_signing) {
809 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
812 status = dcerpc_push_ncacn_packet(p->mem_ctx,
813 DCERPC_PKT_BIND_ACK,
814 pfc_flags,
815 auth_resp.length,
816 pkt->call_id,
818 &p->out_data.frag);
819 if (!NT_STATUS_IS_OK(status)) {
820 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
821 nt_errstr(status)));
824 if (auth_resp.length) {
826 status = dcerpc_push_dcerpc_auth(pkt,
827 auth_type,
828 auth_info.auth_level,
830 1, /* auth_context_id */
831 &auth_resp,
832 &auth_blob);
833 if (!NT_STATUS_IS_OK(status)) {
834 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
835 goto err_exit;
839 /* Now that we have the auth len store it into the right place in
840 * the dcerpc header */
841 dcerpc_set_frag_length(&p->out_data.frag,
842 p->out_data.frag.length + auth_blob.length);
844 if (auth_blob.length) {
846 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
847 auth_blob.data, auth_blob.length)) {
848 DEBUG(0, ("Append of auth info failed.\n"));
849 goto err_exit;
854 * Setup the lengths for the initial reply.
857 p->out_data.data_sent_length = 0;
858 p->out_data.current_pdu_sent = 0;
860 TALLOC_FREE(auth_blob.data);
861 return True;
863 err_exit:
865 data_blob_free(&p->out_data.frag);
866 TALLOC_FREE(auth_blob.data);
867 return setup_bind_nak(p, pkt);
870 /*******************************************************************
871 This is the "stage3" response after a bind request and reply.
872 *******************************************************************/
874 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
876 struct dcerpc_auth auth_info;
877 DATA_BLOB response = data_blob_null;
878 struct gensec_security *gensec_security;
879 NTSTATUS status;
881 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
883 if (pkt->auth_length == 0) {
884 DEBUG(1, ("No auth field sent for bind request!\n"));
885 goto err;
888 /* Ensure there's enough data for an authenticated request. */
889 if (pkt->frag_length < RPC_HEADER_LEN
890 + DCERPC_AUTH_TRAILER_LENGTH
891 + pkt->auth_length) {
892 DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
893 "%u is too large.\n",
894 (unsigned int)pkt->auth_length));
895 goto err;
899 * Decode the authentication verifier response.
902 status = dcerpc_pull_dcerpc_auth(pkt,
903 &pkt->u.auth3.auth_info,
904 &auth_info, p->endian);
905 if (!NT_STATUS_IS_OK(status)) {
906 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
907 goto err;
910 /* We must NEVER look at auth_info->auth_pad_len here,
911 * as old Samba client code gets it wrong and sends it
912 * as zero. JRA.
915 if (auth_info.auth_type != p->auth.auth_type) {
916 DEBUG(1, ("Auth type mismatch! Client sent %d, "
917 "but auth was started as type %d!\n",
918 auth_info.auth_type, p->auth.auth_type));
919 goto err;
922 gensec_security = talloc_get_type(p->auth.auth_ctx,
923 struct gensec_security);
925 status = auth_generic_server_step(gensec_security,
926 pkt, &auth_info.credentials,
927 &response);
929 if (NT_STATUS_EQUAL(status,
930 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
931 response.length) {
932 DEBUG(1, (__location__ ": This was supposed to be the final "
933 "leg, but crypto machinery claims a response is "
934 "needed, aborting auth!\n"));
935 data_blob_free(&response);
936 goto err;
938 if (!NT_STATUS_IS_OK(status)) {
939 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
940 goto err;
943 /* Now verify auth was indeed successful and extract server info */
944 status = pipe_auth_verify_final(p);
945 if (!NT_STATUS_IS_OK(status)) {
946 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
947 goto err;
950 return true;
952 err:
954 TALLOC_FREE(p->auth.auth_ctx);
955 return false;
958 /****************************************************************************
959 Deal with an alter context call. Can be third part of 3 leg auth request for
960 SPNEGO calls.
961 ****************************************************************************/
963 static bool api_pipe_alter_context(struct pipes_struct *p,
964 struct ncacn_packet *pkt)
966 struct dcerpc_auth auth_info;
967 uint16 assoc_gid;
968 NTSTATUS status;
969 union dcerpc_payload u;
970 struct dcerpc_ack_ctx bind_ack_ctx;
971 DATA_BLOB auth_resp = data_blob_null;
972 DATA_BLOB auth_blob = data_blob_null;
973 int pad_len = 0;
974 struct gensec_security *gensec_security;
976 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
978 if (pkt->u.bind.assoc_group_id != 0) {
979 assoc_gid = pkt->u.bind.assoc_group_id;
980 } else {
981 assoc_gid = 0x53f0;
985 * Create the bind response struct.
988 /* If the requested abstract synt uuid doesn't match our client pipe,
989 reject the bind_ack & set the transfer interface synt to all 0's,
990 ver 0 (observed when NT5 attempts to bind to abstract interfaces
991 unknown to NT4)
992 Needed when adding entries to a DACL from NT5 - SK */
994 if (check_bind_req(p,
995 &pkt->u.bind.ctx_list[0].abstract_syntax,
996 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
997 pkt->u.bind.ctx_list[0].context_id)) {
999 bind_ack_ctx.result = 0;
1000 bind_ack_ctx.reason.value = 0;
1001 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1002 } else {
1003 p->pipe_bound = False;
1004 /* Rejection reason: abstract syntax not supported */
1005 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1006 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
1007 bind_ack_ctx.syntax = ndr_syntax_id_null;
1011 * Check if this is an authenticated alter context request.
1013 if (pkt->auth_length) {
1014 /* Quick length check. Won't catch a bad auth footer,
1015 * prevents overrun. */
1017 if (pkt->frag_length < RPC_HEADER_LEN +
1018 DCERPC_AUTH_TRAILER_LENGTH +
1019 pkt->auth_length) {
1020 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1021 "too long for fragment %u.\n",
1022 (unsigned int)pkt->auth_length,
1023 (unsigned int)pkt->frag_length ));
1024 goto err_exit;
1027 status = dcerpc_pull_dcerpc_auth(pkt,
1028 &pkt->u.bind.auth_info,
1029 &auth_info, p->endian);
1030 if (!NT_STATUS_IS_OK(status)) {
1031 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1032 goto err_exit;
1035 /* We can only finish if the pipe is unbound for now */
1036 if (p->pipe_bound) {
1037 DEBUG(0, (__location__ ": Pipe already bound, "
1038 "Altering Context not yet supported!\n"));
1039 goto err_exit;
1042 if (auth_info.auth_type != p->auth.auth_type) {
1043 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1044 "but auth was started as type %d!\n",
1045 auth_info.auth_type, p->auth.auth_type));
1046 goto err_exit;
1049 gensec_security = talloc_get_type(p->auth.auth_ctx,
1050 struct gensec_security);
1051 status = auth_generic_server_step(gensec_security,
1052 pkt,
1053 &auth_info.credentials,
1054 &auth_resp);
1055 if (NT_STATUS_IS_OK(status)) {
1056 /* third leg of auth, verify auth info */
1057 status = pipe_auth_verify_final(p);
1058 if (!NT_STATUS_IS_OK(status)) {
1059 DEBUG(0, ("Auth Verify failed (%s)\n",
1060 nt_errstr(status)));
1061 goto err_exit;
1063 } else if (NT_STATUS_EQUAL(status,
1064 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1065 DEBUG(10, ("More auth legs required.\n"));
1066 } else {
1067 DEBUG(0, ("Auth step returned an error (%s)\n",
1068 nt_errstr(status)));
1069 goto err_exit;
1073 ZERO_STRUCT(u.alter_resp);
1074 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1075 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1076 u.alter_resp.assoc_group_id = assoc_gid;
1078 /* secondary address CAN be NULL
1079 * as the specs say it's ignored.
1080 * It MUST be NULL to have the spoolss working.
1082 u.alter_resp.secondary_address = "";
1083 u.alter_resp.secondary_address_size = 1;
1085 u.alter_resp.num_results = 1;
1086 u.alter_resp.ctx_list = &bind_ack_ctx;
1088 /* NOTE: We leave the auth_info empty so we can calculate the padding
1089 * later and then append the auth_info --simo */
1092 * Marshall directly into the outgoing PDU space. We
1093 * must do this as we need to set to the bind response
1094 * header and are never sending more than one PDU here.
1097 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1098 DCERPC_PKT_ALTER_RESP,
1099 DCERPC_PFC_FLAG_FIRST |
1100 DCERPC_PFC_FLAG_LAST,
1101 auth_resp.length,
1102 pkt->call_id,
1104 &p->out_data.frag);
1105 if (!NT_STATUS_IS_OK(status)) {
1106 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1107 nt_errstr(status)));
1110 if (auth_resp.length) {
1112 /* Work out any padding needed before the auth footer. */
1113 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1114 if (pad_len) {
1115 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1116 DEBUG(10, ("auth pad_len = %u\n",
1117 (unsigned int)pad_len));
1120 status = dcerpc_push_dcerpc_auth(pkt,
1121 auth_info.auth_type,
1122 auth_info.auth_level,
1123 pad_len,
1124 1, /* auth_context_id */
1125 &auth_resp,
1126 &auth_blob);
1127 if (!NT_STATUS_IS_OK(status)) {
1128 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1129 goto err_exit;
1133 /* Now that we have the auth len store it into the right place in
1134 * the dcerpc header */
1135 dcerpc_set_frag_length(&p->out_data.frag,
1136 p->out_data.frag.length +
1137 pad_len + auth_blob.length);
1139 if (auth_resp.length) {
1140 if (pad_len) {
1141 char pad[SERVER_NDR_PADDING_SIZE];
1142 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1143 if (!data_blob_append(p->mem_ctx,
1144 &p->out_data.frag,
1145 pad, pad_len)) {
1146 DEBUG(0, ("api_pipe_bind_req: failed to add "
1147 "%u bytes of pad data.\n",
1148 (unsigned int)pad_len));
1149 goto err_exit;
1153 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1154 auth_blob.data, auth_blob.length)) {
1155 DEBUG(0, ("Append of auth info failed.\n"));
1156 goto err_exit;
1161 * Setup the lengths for the initial reply.
1164 p->out_data.data_sent_length = 0;
1165 p->out_data.current_pdu_sent = 0;
1167 TALLOC_FREE(auth_blob.data);
1168 return True;
1170 err_exit:
1172 data_blob_free(&p->out_data.frag);
1173 TALLOC_FREE(auth_blob.data);
1174 return setup_bind_nak(p, pkt);
1177 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1178 const struct api_struct *api_rpc_cmds, int n_cmds,
1179 const struct ndr_syntax_id *syntax);
1181 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1182 struct ncacn_packet *pkt,
1183 struct pipe_rpc_fns *pipe_fns)
1185 TALLOC_CTX *frame = talloc_stackframe();
1186 struct dcerpc_sec_verification_trailer *vt = NULL;
1187 const uint32_t bitmask1 =
1188 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1189 const struct dcerpc_sec_vt_pcontext pcontext = {
1190 .abstract_syntax = pipe_fns->syntax,
1191 .transfer_syntax = ndr_transfer_syntax_ndr,
1193 const struct dcerpc_sec_vt_header2 header2 =
1194 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1195 struct ndr_pull *ndr;
1196 enum ndr_err_code ndr_err;
1197 bool ret = false;
1199 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1200 if (ndr == NULL) {
1201 goto done;
1204 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1205 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1206 goto done;
1209 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1210 &pcontext, &header2);
1211 done:
1212 TALLOC_FREE(frame);
1213 return ret;
1216 /****************************************************************************
1217 Find the correct RPC function to call for this request.
1218 If the pipe is authenticated then become the correct UNIX user
1219 before doing the call.
1220 ****************************************************************************/
1222 static bool api_pipe_request(struct pipes_struct *p,
1223 struct ncacn_packet *pkt)
1225 TALLOC_CTX *frame = talloc_stackframe();
1226 bool ret = False;
1227 struct pipe_rpc_fns *pipe_fns;
1229 if (!p->pipe_bound) {
1230 DEBUG(1, ("Pipe not bound!\n"));
1231 data_blob_free(&p->out_data.rdata);
1232 TALLOC_FREE(frame);
1233 return false;
1236 /* get the set of RPC functions for this context */
1237 pipe_fns = find_pipe_fns_by_context(p->contexts,
1238 pkt->u.request.context_id);
1239 if (pipe_fns == NULL) {
1240 DEBUG(0, ("No rpc function table associated with context "
1241 "[%d]\n",
1242 pkt->u.request.context_id));
1243 data_blob_free(&p->out_data.rdata);
1244 TALLOC_FREE(frame);
1245 return false;
1248 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1249 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1250 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1251 data_blob_free(&p->out_data.rdata);
1252 TALLOC_FREE(frame);
1253 return true;
1256 if (!become_authenticated_pipe_user(p->session_info)) {
1257 DEBUG(1, ("Failed to become pipe user!\n"));
1258 data_blob_free(&p->out_data.rdata);
1259 TALLOC_FREE(frame);
1260 return false;
1263 DEBUG(5, ("Requested %s rpc service\n",
1264 ndr_interface_name(&pipe_fns->syntax.uuid,
1265 pipe_fns->syntax.if_version)));
1267 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1268 &pipe_fns->syntax);
1269 unbecome_authenticated_pipe_user();
1271 TALLOC_FREE(frame);
1272 return ret;
1275 /*******************************************************************
1276 Calls the underlying RPC function for a named pipe.
1277 ********************************************************************/
1279 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1280 const struct api_struct *api_rpc_cmds, int n_cmds,
1281 const struct ndr_syntax_id *syntax)
1283 int fn_num;
1284 uint32_t offset1;
1285 const struct ndr_interface_table *table;
1287 /* interpret the command */
1288 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1289 ndr_interface_name(&syntax->uuid, syntax->if_version),
1290 pkt->u.request.opnum));
1292 table = ndr_table_by_uuid(&syntax->uuid);
1293 if (table == NULL) {
1294 DEBUG(0,("unknown interface\n"));
1295 return false;
1298 if (DEBUGLEVEL >= 50) {
1299 fstring name;
1300 slprintf(name, sizeof(name)-1, "in_%s",
1301 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1302 dump_pdu_region(name, pkt->u.request.opnum,
1303 &p->in_data.data, 0,
1304 p->in_data.data.length);
1307 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1308 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1309 api_rpc_cmds[fn_num].fn != NULL) {
1310 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1311 api_rpc_cmds[fn_num].name));
1312 break;
1316 if (fn_num == n_cmds) {
1318 * For an unknown RPC just return a fault PDU but
1319 * return True to allow RPC's on the pipe to continue
1320 * and not put the pipe into fault state. JRA.
1322 DEBUG(4, ("unknown\n"));
1323 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1324 return True;
1327 offset1 = p->out_data.rdata.length;
1329 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1330 fn_num, api_rpc_cmds[fn_num].fn));
1331 /* do the actual command */
1332 if(!api_rpc_cmds[fn_num].fn(p)) {
1333 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1334 ndr_interface_name(&syntax->uuid, syntax->if_version),
1335 api_rpc_cmds[fn_num].name));
1336 data_blob_free(&p->out_data.rdata);
1337 return False;
1340 if (p->fault_state) {
1341 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1342 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1343 p->fault_state = 0;
1344 return true;
1347 if (DEBUGLEVEL >= 50) {
1348 fstring name;
1349 slprintf(name, sizeof(name)-1, "out_%s",
1350 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1351 dump_pdu_region(name, pkt->u.request.opnum,
1352 &p->out_data.rdata, offset1,
1353 p->out_data.rdata.length);
1356 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1357 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1359 /* Check for buffer underflow in rpc parsing */
1360 if ((DEBUGLEVEL >= 10) &&
1361 (pkt->frag_length < p->in_data.data.length)) {
1362 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1363 dump_data(10, p->in_data.data.data + pkt->frag_length,
1364 p->in_data.data.length - pkt->frag_length);
1367 return True;
1370 /****************************************************************************
1371 Initialise an outgoing packet.
1372 ****************************************************************************/
1374 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1376 output_data *o_data = &p->out_data;
1378 /* Reset the offset counters. */
1379 o_data->data_sent_length = 0;
1380 o_data->current_pdu_sent = 0;
1382 data_blob_free(&o_data->frag);
1384 /* Free any memory in the current return data buffer. */
1385 data_blob_free(&o_data->rdata);
1387 return True;
1390 /****************************************************************************
1391 Sets the fault state on incoming packets.
1392 ****************************************************************************/
1394 void set_incoming_fault(struct pipes_struct *p)
1396 data_blob_free(&p->in_data.data);
1397 p->in_data.pdu_needed_len = 0;
1398 p->in_data.pdu.length = 0;
1399 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1401 DEBUG(10, ("Setting fault state\n"));
1404 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1405 struct ncacn_packet *pkt,
1406 DATA_BLOB *raw_pkt)
1408 NTSTATUS status;
1409 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1410 size_t pad_len;
1412 DEBUG(10, ("Checking request auth.\n"));
1414 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1415 hdr_size += 16;
1418 /* in case of sealing this function will unseal the data in place */
1419 status = dcerpc_check_auth(auth, pkt,
1420 &pkt->u.request.stub_and_verifier,
1421 hdr_size, raw_pkt,
1422 &pad_len);
1423 if (!NT_STATUS_IS_OK(status)) {
1424 return status;
1428 /* remove padding and auth trailer,
1429 * this way the caller will get just the data */
1430 if (pkt->auth_length) {
1431 size_t trail_len = pad_len
1432 + DCERPC_AUTH_TRAILER_LENGTH
1433 + pkt->auth_length;
1434 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1435 return NT_STATUS_INFO_LENGTH_MISMATCH;
1437 pkt->u.request.stub_and_verifier.length -= trail_len;
1440 return NT_STATUS_OK;
1443 /****************************************************************************
1444 Processes a request pdu. This will do auth processing if needed, and
1445 appends the data into the complete stream if the LAST flag is not set.
1446 ****************************************************************************/
1448 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1450 NTSTATUS status;
1451 DATA_BLOB data;
1452 struct dcerpc_sec_vt_header2 hdr2;
1454 if (!p->pipe_bound) {
1455 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1456 set_incoming_fault(p);
1457 return False;
1460 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1461 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1462 p->header2 = hdr2;
1463 } else {
1464 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1465 set_incoming_fault(p);
1466 return false;
1470 /* Store the opnum */
1471 p->opnum = pkt->u.request.opnum;
1473 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1474 if (!NT_STATUS_IS_OK(status)) {
1475 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1476 nt_errstr(status)));
1477 set_incoming_fault(p);
1478 return false;
1481 data = pkt->u.request.stub_and_verifier;
1484 * Check the data length doesn't go over the 15Mb limit.
1485 * increased after observing a bug in the Windows NT 4.0 SP6a
1486 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1487 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1490 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1491 DEBUG(0, ("process_request_pdu: "
1492 "rpc data buffer too large (%u) + (%u)\n",
1493 (unsigned int)p->in_data.data.length,
1494 (unsigned int)data.length));
1495 set_incoming_fault(p);
1496 return False;
1500 * Append the data portion into the buffer and return.
1503 if (data.length) {
1504 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1505 data.data, data.length)) {
1506 DEBUG(0, ("Unable to append data size %u "
1507 "to parse buffer of size %u.\n",
1508 (unsigned int)data.length,
1509 (unsigned int)p->in_data.data.length));
1510 set_incoming_fault(p);
1511 return False;
1515 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1516 return true;
1520 * Ok - we finally have a complete RPC stream.
1521 * Call the rpc command to process it.
1524 return api_pipe_request(p, pkt);
1527 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1529 bool reply = false;
1531 /* Store the call_id */
1532 p->call_id = pkt->call_id;
1534 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1536 if (!pipe_init_outgoing_data(p)) {
1537 goto done;
1540 switch (pkt->ptype) {
1541 case DCERPC_PKT_REQUEST:
1542 reply = process_request_pdu(p, pkt);
1543 break;
1545 case DCERPC_PKT_PING: /* CL request - ignore... */
1546 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1547 (unsigned int)pkt->ptype));
1548 break;
1550 case DCERPC_PKT_RESPONSE: /* No responses here. */
1551 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1552 break;
1554 case DCERPC_PKT_FAULT:
1555 case DCERPC_PKT_WORKING:
1556 /* CL request - reply to a ping when a call in process. */
1557 case DCERPC_PKT_NOCALL:
1558 /* CL - server reply to a ping call. */
1559 case DCERPC_PKT_REJECT:
1560 case DCERPC_PKT_ACK:
1561 case DCERPC_PKT_CL_CANCEL:
1562 case DCERPC_PKT_FACK:
1563 case DCERPC_PKT_CANCEL_ACK:
1564 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1565 (unsigned int)pkt->ptype));
1566 break;
1568 case DCERPC_PKT_BIND:
1570 * We assume that a pipe bind is only in one pdu.
1572 reply = api_pipe_bind_req(p, pkt);
1573 break;
1575 case DCERPC_PKT_BIND_ACK:
1576 case DCERPC_PKT_BIND_NAK:
1577 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1578 "packet type %u received.\n",
1579 (unsigned int)pkt->ptype));
1580 break;
1583 case DCERPC_PKT_ALTER:
1585 * We assume that a pipe bind is only in one pdu.
1587 reply = api_pipe_alter_context(p, pkt);
1588 break;
1590 case DCERPC_PKT_ALTER_RESP:
1591 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1592 "Should only be server -> client.\n"));
1593 break;
1595 case DCERPC_PKT_AUTH3:
1597 * The third packet in an auth exchange.
1599 reply = api_pipe_bind_auth3(p, pkt);
1600 break;
1602 case DCERPC_PKT_SHUTDOWN:
1603 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1604 "Should only be server -> client.\n"));
1605 break;
1607 case DCERPC_PKT_CO_CANCEL:
1608 /* For now just free all client data and continue
1609 * processing. */
1610 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1611 " Abandoning rpc call.\n"));
1612 /* As we never do asynchronous RPC serving, we can
1613 * never cancel a call (as far as I know).
1614 * If we ever did we'd have to send a cancel_ack reply.
1615 * For now, just free all client data and continue
1616 * processing. */
1617 reply = True;
1618 break;
1620 #if 0
1621 /* Enable this if we're doing async rpc. */
1622 /* We must check the outstanding callid matches. */
1623 if (pipe_init_outgoing_data(p)) {
1624 /* Send a cancel_ack PDU reply. */
1625 /* We should probably check the auth-verifier here. */
1626 reply = setup_cancel_ack_reply(p, pkt);
1628 break;
1629 #endif
1631 case DCERPC_PKT_ORPHANED:
1632 /* We should probably check the auth-verifier here.
1633 * For now just free all client data and continue
1634 * processing. */
1635 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1636 " Abandoning rpc call.\n"));
1637 reply = True;
1638 break;
1640 default:
1641 DEBUG(0, ("process_complete_pdu: "
1642 "Unknown rpc type = %u received.\n",
1643 (unsigned int)pkt->ptype));
1644 break;
1647 done:
1648 if (!reply) {
1649 DEBUG(3,("DCE/RPC fault sent!"));
1650 set_incoming_fault(p);
1651 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1653 /* pkt and p->in_data.pdu.data freed by caller */