smbd: Rename lck2->rw_probe in brl_conflict_other
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob948abf31426abf67e21b19096b3a0f305266bb74
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 default:
738 if (!pipe_auth_generic_bind(p, pkt,
739 &auth_info, &auth_resp)) {
740 goto err_exit;
742 break;
746 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
747 /* Unauthenticated bind request. */
748 /* We're finished - no more packets. */
749 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
750 /* We must set the pipe auth_level here also. */
751 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
752 p->pipe_bound = True;
753 /* The session key was initialized from the SMB
754 * session in make_internal_rpc_pipe_p */
757 ZERO_STRUCT(u.bind_ack);
758 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
759 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
760 u.bind_ack.assoc_group_id = assoc_gid;
762 /* name has to be \PIPE\xxxxx */
763 u.bind_ack.secondary_address =
764 talloc_asprintf(pkt, "\\PIPE\\%s",
765 rpc_srv_get_pipe_srv_name(&id));
766 if (!u.bind_ack.secondary_address) {
767 DEBUG(0, ("Out of memory!\n"));
768 goto err_exit;
770 u.bind_ack.secondary_address_size =
771 strlen(u.bind_ack.secondary_address) + 1;
773 u.bind_ack.num_results = 1;
774 u.bind_ack.ctx_list = &bind_ack_ctx;
776 /* NOTE: We leave the auth_info empty so we can calculate the padding
777 * later and then append the auth_info --simo */
780 * Marshall directly into the outgoing PDU space. We
781 * must do this as we need to set to the bind response
782 * header and are never sending more than one PDU here.
785 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
787 if (p->auth.hdr_signing) {
788 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
791 status = dcerpc_push_ncacn_packet(p->mem_ctx,
792 DCERPC_PKT_BIND_ACK,
793 pfc_flags,
794 auth_resp.length,
795 pkt->call_id,
797 &p->out_data.frag);
798 if (!NT_STATUS_IS_OK(status)) {
799 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
800 nt_errstr(status)));
803 if (auth_resp.length) {
805 status = dcerpc_push_dcerpc_auth(pkt,
806 auth_type,
807 auth_info.auth_level,
809 1, /* auth_context_id */
810 &auth_resp,
811 &auth_blob);
812 if (!NT_STATUS_IS_OK(status)) {
813 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
814 goto err_exit;
818 /* Now that we have the auth len store it into the right place in
819 * the dcerpc header */
820 dcerpc_set_frag_length(&p->out_data.frag,
821 p->out_data.frag.length + auth_blob.length);
823 if (auth_blob.length) {
825 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
826 auth_blob.data, auth_blob.length)) {
827 DEBUG(0, ("Append of auth info failed.\n"));
828 goto err_exit;
833 * Setup the lengths for the initial reply.
836 p->out_data.data_sent_length = 0;
837 p->out_data.current_pdu_sent = 0;
839 TALLOC_FREE(auth_blob.data);
840 return True;
842 err_exit:
844 data_blob_free(&p->out_data.frag);
845 TALLOC_FREE(auth_blob.data);
846 return setup_bind_nak(p, pkt);
849 /*******************************************************************
850 This is the "stage3" response after a bind request and reply.
851 *******************************************************************/
853 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
855 struct dcerpc_auth auth_info;
856 DATA_BLOB response = data_blob_null;
857 struct gensec_security *gensec_security;
858 NTSTATUS status;
860 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
862 if (pkt->auth_length == 0) {
863 DEBUG(1, ("No auth field sent for bind request!\n"));
864 goto err;
867 /* Ensure there's enough data for an authenticated request. */
868 if (pkt->frag_length < RPC_HEADER_LEN
869 + DCERPC_AUTH_TRAILER_LENGTH
870 + pkt->auth_length) {
871 DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
872 "%u is too large.\n",
873 (unsigned int)pkt->auth_length));
874 goto err;
878 * Decode the authentication verifier response.
881 status = dcerpc_pull_dcerpc_auth(pkt,
882 &pkt->u.auth3.auth_info,
883 &auth_info, p->endian);
884 if (!NT_STATUS_IS_OK(status)) {
885 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
886 goto err;
889 /* We must NEVER look at auth_info->auth_pad_len here,
890 * as old Samba client code gets it wrong and sends it
891 * as zero. JRA.
894 if (auth_info.auth_type != p->auth.auth_type) {
895 DEBUG(1, ("Auth type mismatch! Client sent %d, "
896 "but auth was started as type %d!\n",
897 auth_info.auth_type, p->auth.auth_type));
898 goto err;
901 gensec_security = talloc_get_type(p->auth.auth_ctx,
902 struct gensec_security);
904 status = auth_generic_server_step(gensec_security,
905 pkt, &auth_info.credentials,
906 &response);
908 if (NT_STATUS_EQUAL(status,
909 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
910 response.length) {
911 DEBUG(1, (__location__ ": This was supposed to be the final "
912 "leg, but crypto machinery claims a response is "
913 "needed, aborting auth!\n"));
914 data_blob_free(&response);
915 goto err;
917 if (!NT_STATUS_IS_OK(status)) {
918 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
919 goto err;
922 /* Now verify auth was indeed successful and extract server info */
923 status = pipe_auth_verify_final(p);
924 if (!NT_STATUS_IS_OK(status)) {
925 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
926 goto err;
929 return true;
931 err:
933 TALLOC_FREE(p->auth.auth_ctx);
934 return false;
937 /****************************************************************************
938 Deal with an alter context call. Can be third part of 3 leg auth request for
939 SPNEGO calls.
940 ****************************************************************************/
942 static bool api_pipe_alter_context(struct pipes_struct *p,
943 struct ncacn_packet *pkt)
945 struct dcerpc_auth auth_info;
946 uint16 assoc_gid;
947 NTSTATUS status;
948 union dcerpc_payload u;
949 struct dcerpc_ack_ctx bind_ack_ctx;
950 DATA_BLOB auth_resp = data_blob_null;
951 DATA_BLOB auth_blob = data_blob_null;
952 int pad_len = 0;
953 struct gensec_security *gensec_security;
955 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
957 if (pkt->u.bind.assoc_group_id != 0) {
958 assoc_gid = pkt->u.bind.assoc_group_id;
959 } else {
960 assoc_gid = 0x53f0;
964 * Create the bind response struct.
967 /* If the requested abstract synt uuid doesn't match our client pipe,
968 reject the bind_ack & set the transfer interface synt to all 0's,
969 ver 0 (observed when NT5 attempts to bind to abstract interfaces
970 unknown to NT4)
971 Needed when adding entries to a DACL from NT5 - SK */
973 if (check_bind_req(p,
974 &pkt->u.bind.ctx_list[0].abstract_syntax,
975 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
976 pkt->u.bind.ctx_list[0].context_id)) {
978 bind_ack_ctx.result = 0;
979 bind_ack_ctx.reason.value = 0;
980 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
981 } else {
982 p->pipe_bound = False;
983 /* Rejection reason: abstract syntax not supported */
984 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
985 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
986 bind_ack_ctx.syntax = ndr_syntax_id_null;
990 * Check if this is an authenticated alter context request.
992 if (pkt->auth_length) {
993 /* Quick length check. Won't catch a bad auth footer,
994 * prevents overrun. */
996 if (pkt->frag_length < RPC_HEADER_LEN +
997 DCERPC_AUTH_TRAILER_LENGTH +
998 pkt->auth_length) {
999 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1000 "too long for fragment %u.\n",
1001 (unsigned int)pkt->auth_length,
1002 (unsigned int)pkt->frag_length ));
1003 goto err_exit;
1006 status = dcerpc_pull_dcerpc_auth(pkt,
1007 &pkt->u.bind.auth_info,
1008 &auth_info, p->endian);
1009 if (!NT_STATUS_IS_OK(status)) {
1010 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1011 goto err_exit;
1014 /* We can only finish if the pipe is unbound for now */
1015 if (p->pipe_bound) {
1016 DEBUG(0, (__location__ ": Pipe already bound, "
1017 "Altering Context not yet supported!\n"));
1018 goto err_exit;
1021 if (auth_info.auth_type != p->auth.auth_type) {
1022 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1023 "but auth was started as type %d!\n",
1024 auth_info.auth_type, p->auth.auth_type));
1025 goto err_exit;
1028 gensec_security = talloc_get_type(p->auth.auth_ctx,
1029 struct gensec_security);
1030 status = auth_generic_server_step(gensec_security,
1031 pkt,
1032 &auth_info.credentials,
1033 &auth_resp);
1034 if (NT_STATUS_IS_OK(status)) {
1035 /* third leg of auth, verify auth info */
1036 status = pipe_auth_verify_final(p);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 DEBUG(0, ("Auth Verify failed (%s)\n",
1039 nt_errstr(status)));
1040 goto err_exit;
1042 } else if (NT_STATUS_EQUAL(status,
1043 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1044 DEBUG(10, ("More auth legs required.\n"));
1045 } else {
1046 DEBUG(0, ("Auth step returned an error (%s)\n",
1047 nt_errstr(status)));
1048 goto err_exit;
1052 ZERO_STRUCT(u.alter_resp);
1053 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1054 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1055 u.alter_resp.assoc_group_id = assoc_gid;
1057 /* secondary address CAN be NULL
1058 * as the specs say it's ignored.
1059 * It MUST be NULL to have the spoolss working.
1061 u.alter_resp.secondary_address = "";
1062 u.alter_resp.secondary_address_size = 1;
1064 u.alter_resp.num_results = 1;
1065 u.alter_resp.ctx_list = &bind_ack_ctx;
1067 /* NOTE: We leave the auth_info empty so we can calculate the padding
1068 * later and then append the auth_info --simo */
1071 * Marshall directly into the outgoing PDU space. We
1072 * must do this as we need to set to the bind response
1073 * header and are never sending more than one PDU here.
1076 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1077 DCERPC_PKT_ALTER_RESP,
1078 DCERPC_PFC_FLAG_FIRST |
1079 DCERPC_PFC_FLAG_LAST,
1080 auth_resp.length,
1081 pkt->call_id,
1083 &p->out_data.frag);
1084 if (!NT_STATUS_IS_OK(status)) {
1085 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1086 nt_errstr(status)));
1089 if (auth_resp.length) {
1091 /* Work out any padding needed before the auth footer. */
1092 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1093 if (pad_len) {
1094 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1095 DEBUG(10, ("auth pad_len = %u\n",
1096 (unsigned int)pad_len));
1099 status = dcerpc_push_dcerpc_auth(pkt,
1100 auth_info.auth_type,
1101 auth_info.auth_level,
1102 pad_len,
1103 1, /* auth_context_id */
1104 &auth_resp,
1105 &auth_blob);
1106 if (!NT_STATUS_IS_OK(status)) {
1107 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1108 goto err_exit;
1112 /* Now that we have the auth len store it into the right place in
1113 * the dcerpc header */
1114 dcerpc_set_frag_length(&p->out_data.frag,
1115 p->out_data.frag.length +
1116 pad_len + auth_blob.length);
1118 if (auth_resp.length) {
1119 if (pad_len) {
1120 char pad[SERVER_NDR_PADDING_SIZE];
1121 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1122 if (!data_blob_append(p->mem_ctx,
1123 &p->out_data.frag,
1124 pad, pad_len)) {
1125 DEBUG(0, ("api_pipe_bind_req: failed to add "
1126 "%u bytes of pad data.\n",
1127 (unsigned int)pad_len));
1128 goto err_exit;
1132 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1133 auth_blob.data, auth_blob.length)) {
1134 DEBUG(0, ("Append of auth info failed.\n"));
1135 goto err_exit;
1140 * Setup the lengths for the initial reply.
1143 p->out_data.data_sent_length = 0;
1144 p->out_data.current_pdu_sent = 0;
1146 TALLOC_FREE(auth_blob.data);
1147 return True;
1149 err_exit:
1151 data_blob_free(&p->out_data.frag);
1152 TALLOC_FREE(auth_blob.data);
1153 return setup_bind_nak(p, pkt);
1156 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1157 const struct api_struct *api_rpc_cmds, int n_cmds,
1158 const struct ndr_syntax_id *syntax);
1160 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1161 struct ncacn_packet *pkt,
1162 struct pipe_rpc_fns *pipe_fns)
1164 TALLOC_CTX *frame = talloc_stackframe();
1165 struct dcerpc_sec_verification_trailer *vt = NULL;
1166 const uint32_t bitmask1 =
1167 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1168 const struct dcerpc_sec_vt_pcontext pcontext = {
1169 .abstract_syntax = pipe_fns->syntax,
1170 .transfer_syntax = ndr_transfer_syntax_ndr,
1172 const struct dcerpc_sec_vt_header2 header2 =
1173 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1174 struct ndr_pull *ndr;
1175 enum ndr_err_code ndr_err;
1176 bool ret = false;
1178 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1179 if (ndr == NULL) {
1180 goto done;
1183 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1184 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1185 goto done;
1188 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1189 &pcontext, &header2);
1190 done:
1191 TALLOC_FREE(frame);
1192 return ret;
1195 /****************************************************************************
1196 Find the correct RPC function to call for this request.
1197 If the pipe is authenticated then become the correct UNIX user
1198 before doing the call.
1199 ****************************************************************************/
1201 static bool api_pipe_request(struct pipes_struct *p,
1202 struct ncacn_packet *pkt)
1204 TALLOC_CTX *frame = talloc_stackframe();
1205 bool ret = False;
1206 struct pipe_rpc_fns *pipe_fns;
1208 if (!p->pipe_bound) {
1209 DEBUG(1, ("Pipe not bound!\n"));
1210 data_blob_free(&p->out_data.rdata);
1211 TALLOC_FREE(frame);
1212 return false;
1215 /* get the set of RPC functions for this context */
1216 pipe_fns = find_pipe_fns_by_context(p->contexts,
1217 pkt->u.request.context_id);
1218 if (pipe_fns == NULL) {
1219 DEBUG(0, ("No rpc function table associated with context "
1220 "[%d]\n",
1221 pkt->u.request.context_id));
1222 data_blob_free(&p->out_data.rdata);
1223 TALLOC_FREE(frame);
1224 return false;
1227 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1228 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1229 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1230 data_blob_free(&p->out_data.rdata);
1231 TALLOC_FREE(frame);
1232 return true;
1235 if (!become_authenticated_pipe_user(p->session_info)) {
1236 DEBUG(1, ("Failed to become pipe user!\n"));
1237 data_blob_free(&p->out_data.rdata);
1238 TALLOC_FREE(frame);
1239 return false;
1242 DEBUG(5, ("Requested %s rpc service\n",
1243 ndr_interface_name(&pipe_fns->syntax.uuid,
1244 pipe_fns->syntax.if_version)));
1246 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1247 &pipe_fns->syntax);
1248 unbecome_authenticated_pipe_user();
1250 TALLOC_FREE(frame);
1251 return ret;
1254 /*******************************************************************
1255 Calls the underlying RPC function for a named pipe.
1256 ********************************************************************/
1258 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1259 const struct api_struct *api_rpc_cmds, int n_cmds,
1260 const struct ndr_syntax_id *syntax)
1262 int fn_num;
1263 uint32_t offset1;
1264 const struct ndr_interface_table *table;
1266 /* interpret the command */
1267 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1268 ndr_interface_name(&syntax->uuid, syntax->if_version),
1269 pkt->u.request.opnum));
1271 table = ndr_table_by_uuid(&syntax->uuid);
1272 if (table == NULL) {
1273 DEBUG(0,("unknown interface\n"));
1274 return false;
1277 if (DEBUGLEVEL >= 50) {
1278 fstring name;
1279 slprintf(name, sizeof(name)-1, "in_%s",
1280 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1281 dump_pdu_region(name, pkt->u.request.opnum,
1282 &p->in_data.data, 0,
1283 p->in_data.data.length);
1286 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1287 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1288 api_rpc_cmds[fn_num].fn != NULL) {
1289 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1290 api_rpc_cmds[fn_num].name));
1291 break;
1295 if (fn_num == n_cmds) {
1297 * For an unknown RPC just return a fault PDU but
1298 * return True to allow RPC's on the pipe to continue
1299 * and not put the pipe into fault state. JRA.
1301 DEBUG(4, ("unknown\n"));
1302 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1303 return True;
1306 offset1 = p->out_data.rdata.length;
1308 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1309 fn_num, api_rpc_cmds[fn_num].fn));
1310 /* do the actual command */
1311 if(!api_rpc_cmds[fn_num].fn(p)) {
1312 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1313 ndr_interface_name(&syntax->uuid, syntax->if_version),
1314 api_rpc_cmds[fn_num].name));
1315 data_blob_free(&p->out_data.rdata);
1316 return False;
1319 if (p->fault_state) {
1320 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1321 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1322 p->fault_state = 0;
1323 return true;
1326 if (DEBUGLEVEL >= 50) {
1327 fstring name;
1328 slprintf(name, sizeof(name)-1, "out_%s",
1329 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1330 dump_pdu_region(name, pkt->u.request.opnum,
1331 &p->out_data.rdata, offset1,
1332 p->out_data.rdata.length);
1335 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1336 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1338 /* Check for buffer underflow in rpc parsing */
1339 if ((DEBUGLEVEL >= 10) &&
1340 (pkt->frag_length < p->in_data.data.length)) {
1341 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1342 dump_data(10, p->in_data.data.data + pkt->frag_length,
1343 p->in_data.data.length - pkt->frag_length);
1346 return True;
1349 /****************************************************************************
1350 Initialise an outgoing packet.
1351 ****************************************************************************/
1353 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1355 output_data *o_data = &p->out_data;
1357 /* Reset the offset counters. */
1358 o_data->data_sent_length = 0;
1359 o_data->current_pdu_sent = 0;
1361 data_blob_free(&o_data->frag);
1363 /* Free any memory in the current return data buffer. */
1364 data_blob_free(&o_data->rdata);
1366 return True;
1369 /****************************************************************************
1370 Sets the fault state on incoming packets.
1371 ****************************************************************************/
1373 void set_incoming_fault(struct pipes_struct *p)
1375 data_blob_free(&p->in_data.data);
1376 p->in_data.pdu_needed_len = 0;
1377 p->in_data.pdu.length = 0;
1378 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1380 DEBUG(10, ("Setting fault state\n"));
1383 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1384 struct ncacn_packet *pkt,
1385 DATA_BLOB *raw_pkt)
1387 NTSTATUS status;
1388 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1389 size_t pad_len;
1391 DEBUG(10, ("Checking request auth.\n"));
1393 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1394 hdr_size += 16;
1397 /* in case of sealing this function will unseal the data in place */
1398 status = dcerpc_check_auth(auth, pkt,
1399 &pkt->u.request.stub_and_verifier,
1400 hdr_size, raw_pkt,
1401 &pad_len);
1402 if (!NT_STATUS_IS_OK(status)) {
1403 return status;
1407 /* remove padding and auth trailer,
1408 * this way the caller will get just the data */
1409 if (pkt->auth_length) {
1410 size_t trail_len = pad_len
1411 + DCERPC_AUTH_TRAILER_LENGTH
1412 + pkt->auth_length;
1413 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1414 return NT_STATUS_INFO_LENGTH_MISMATCH;
1416 pkt->u.request.stub_and_verifier.length -= trail_len;
1419 return NT_STATUS_OK;
1422 /****************************************************************************
1423 Processes a request pdu. This will do auth processing if needed, and
1424 appends the data into the complete stream if the LAST flag is not set.
1425 ****************************************************************************/
1427 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1429 NTSTATUS status;
1430 DATA_BLOB data;
1431 struct dcerpc_sec_vt_header2 hdr2;
1433 if (!p->pipe_bound) {
1434 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1435 set_incoming_fault(p);
1436 return False;
1439 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1440 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1441 p->header2 = hdr2;
1442 } else {
1443 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1444 set_incoming_fault(p);
1445 return false;
1449 /* Store the opnum */
1450 p->opnum = pkt->u.request.opnum;
1452 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1453 if (!NT_STATUS_IS_OK(status)) {
1454 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1455 nt_errstr(status)));
1456 set_incoming_fault(p);
1457 return false;
1460 data = pkt->u.request.stub_and_verifier;
1463 * Check the data length doesn't go over the 15Mb limit.
1464 * increased after observing a bug in the Windows NT 4.0 SP6a
1465 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1466 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1469 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1470 DEBUG(0, ("process_request_pdu: "
1471 "rpc data buffer too large (%u) + (%u)\n",
1472 (unsigned int)p->in_data.data.length,
1473 (unsigned int)data.length));
1474 set_incoming_fault(p);
1475 return False;
1479 * Append the data portion into the buffer and return.
1482 if (data.length) {
1483 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1484 data.data, data.length)) {
1485 DEBUG(0, ("Unable to append data size %u "
1486 "to parse buffer of size %u.\n",
1487 (unsigned int)data.length,
1488 (unsigned int)p->in_data.data.length));
1489 set_incoming_fault(p);
1490 return False;
1494 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1495 return true;
1499 * Ok - we finally have a complete RPC stream.
1500 * Call the rpc command to process it.
1503 return api_pipe_request(p, pkt);
1506 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1508 bool reply = false;
1510 /* Store the call_id */
1511 p->call_id = pkt->call_id;
1513 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1515 if (!pipe_init_outgoing_data(p)) {
1516 goto done;
1519 switch (pkt->ptype) {
1520 case DCERPC_PKT_REQUEST:
1521 reply = process_request_pdu(p, pkt);
1522 break;
1524 case DCERPC_PKT_PING: /* CL request - ignore... */
1525 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1526 (unsigned int)pkt->ptype));
1527 break;
1529 case DCERPC_PKT_RESPONSE: /* No responses here. */
1530 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1531 break;
1533 case DCERPC_PKT_FAULT:
1534 case DCERPC_PKT_WORKING:
1535 /* CL request - reply to a ping when a call in process. */
1536 case DCERPC_PKT_NOCALL:
1537 /* CL - server reply to a ping call. */
1538 case DCERPC_PKT_REJECT:
1539 case DCERPC_PKT_ACK:
1540 case DCERPC_PKT_CL_CANCEL:
1541 case DCERPC_PKT_FACK:
1542 case DCERPC_PKT_CANCEL_ACK:
1543 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1544 (unsigned int)pkt->ptype));
1545 break;
1547 case DCERPC_PKT_BIND:
1549 * We assume that a pipe bind is only in one pdu.
1551 reply = api_pipe_bind_req(p, pkt);
1552 break;
1554 case DCERPC_PKT_BIND_ACK:
1555 case DCERPC_PKT_BIND_NAK:
1556 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1557 "packet type %u received.\n",
1558 (unsigned int)pkt->ptype));
1559 break;
1562 case DCERPC_PKT_ALTER:
1564 * We assume that a pipe bind is only in one pdu.
1566 reply = api_pipe_alter_context(p, pkt);
1567 break;
1569 case DCERPC_PKT_ALTER_RESP:
1570 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1571 "Should only be server -> client.\n"));
1572 break;
1574 case DCERPC_PKT_AUTH3:
1576 * The third packet in an auth exchange.
1578 reply = api_pipe_bind_auth3(p, pkt);
1579 break;
1581 case DCERPC_PKT_SHUTDOWN:
1582 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1583 "Should only be server -> client.\n"));
1584 break;
1586 case DCERPC_PKT_CO_CANCEL:
1587 /* For now just free all client data and continue
1588 * processing. */
1589 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1590 " Abandoning rpc call.\n"));
1591 /* As we never do asynchronous RPC serving, we can
1592 * never cancel a call (as far as I know).
1593 * If we ever did we'd have to send a cancel_ack reply.
1594 * For now, just free all client data and continue
1595 * processing. */
1596 reply = True;
1597 break;
1599 #if 0
1600 /* Enable this if we're doing async rpc. */
1601 /* We must check the outstanding callid matches. */
1602 if (pipe_init_outgoing_data(p)) {
1603 /* Send a cancel_ack PDU reply. */
1604 /* We should probably check the auth-verifier here. */
1605 reply = setup_cancel_ack_reply(p, pkt);
1607 break;
1608 #endif
1610 case DCERPC_PKT_ORPHANED:
1611 /* We should probably check the auth-verifier here.
1612 * For now just free all client data and continue
1613 * processing. */
1614 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1615 " Abandoning rpc call.\n"));
1616 reply = True;
1617 break;
1619 default:
1620 DEBUG(0, ("process_complete_pdu: "
1621 "Unknown rpc type = %u received.\n",
1622 (unsigned int)pkt->ptype));
1623 break;
1626 done:
1627 if (!reply) {
1628 DEBUG(3,("DCE/RPC fault sent!"));
1629 set_incoming_fault(p);
1630 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1632 /* pkt and p->in_data.pdu.data freed by caller */