CVE-2015-5370: s3:rpc_server: don't allow auth3 if the authentication was already...
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob2926f06d5f89861bacd7c4684fb77f6f9f3817e2
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"
47 #include "lib/tsocket/tsocket.h"
48 #include "../librpc/gen_ndr/ndr_samr.h"
49 #include "../librpc/gen_ndr/ndr_lsa.h"
50 #include "../librpc/gen_ndr/ndr_netlogon.h"
51 #include "../librpc/gen_ndr/ndr_epmapper.h"
52 #include "../librpc/gen_ndr/ndr_echo.h"
54 #undef DBGC_CLASS
55 #define DBGC_CLASS DBGC_RPC_SRV
57 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p);
59 /**
60 * Dump everything from the start of the end up of the provided data
61 * into a file, but only at debug level >= 50
62 **/
63 static void dump_pdu_region(const char *name, int v,
64 DATA_BLOB *data, size_t start, size_t end)
66 int fd, i;
67 char *fname = NULL;
68 ssize_t sz;
70 if (DEBUGLEVEL < 50) return;
72 if (start > data->length || end > data->length || start > end) return;
74 for (i = 1; i < 100; i++) {
75 if (v != -1) {
76 fname = talloc_asprintf(talloc_tos(),
77 "/tmp/%s_%d.%d.prs",
78 name, v, i);
79 } else {
80 fname = talloc_asprintf(talloc_tos(),
81 "/tmp/%s_%d.prs",
82 name, i);
84 if (!fname) {
85 return;
87 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
88 if (fd != -1 || errno != EEXIST) break;
90 if (fd != -1) {
91 sz = write(fd, data->data + start, end - start);
92 i = close(fd);
93 if ((sz != end - start) || (i != 0) ) {
94 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
95 fname, (unsigned long)sz,
96 (unsigned long)end - start, i));
97 } else {
98 DEBUG(0,("created %s\n", fname));
101 TALLOC_FREE(fname);
104 static DATA_BLOB generic_session_key(void)
106 return data_blob_const("SystemLibraryDTC", 16);
109 /*******************************************************************
110 Generate the next PDU to be returned from the data.
111 ********************************************************************/
113 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
114 struct pipe_auth_data *auth,
115 uint32_t call_id,
116 DATA_BLOB *rdata,
117 size_t data_sent_length,
118 DATA_BLOB *frag,
119 size_t *pdu_size)
121 union dcerpc_payload u;
122 uint8_t pfc_flags;
123 size_t data_left;
124 size_t data_to_send;
125 size_t frag_len;
126 size_t pad_len = 0;
127 size_t auth_len = 0;
128 NTSTATUS status;
130 ZERO_STRUCT(u.response);
132 /* Set up rpc packet pfc flags. */
133 if (data_sent_length == 0) {
134 pfc_flags = DCERPC_PFC_FLAG_FIRST;
135 } else {
136 pfc_flags = 0;
139 /* Work out how much we can fit in a single PDU. */
140 data_left = rdata->length - data_sent_length;
142 /* Ensure there really is data left to send. */
143 if (!data_left) {
144 DEBUG(0, ("No data left to send !\n"));
145 return NT_STATUS_BUFFER_TOO_SMALL;
148 status = dcerpc_guess_sizes(auth,
149 DCERPC_RESPONSE_LENGTH,
150 data_left,
151 RPC_MAX_PDU_FRAG_LEN,
152 &data_to_send, &frag_len,
153 &auth_len, &pad_len);
154 if (!NT_STATUS_IS_OK(status)) {
155 return status;
158 /* Set up the alloc hint. This should be the data left to send. */
159 u.response.alloc_hint = data_left;
161 /* Work out if this PDU will be the last. */
162 if (data_sent_length + data_to_send >= rdata->length) {
163 pfc_flags |= DCERPC_PFC_FLAG_LAST;
166 /* Prepare data to be NDR encoded. */
167 u.response.stub_and_verifier =
168 data_blob_const(rdata->data + data_sent_length, data_to_send);
170 /* Store the packet in the data stream. */
171 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
172 pfc_flags, auth_len, call_id,
173 &u, frag);
174 if (!NT_STATUS_IS_OK(status)) {
175 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
176 return status;
179 if (auth_len) {
180 /* Set the proper length on the pdu, including padding.
181 * Only needed if an auth trailer will be appended. */
182 dcerpc_set_frag_length(frag, frag->length
183 + pad_len
184 + DCERPC_AUTH_TRAILER_LENGTH
185 + auth_len);
188 if (auth_len) {
189 status = dcerpc_add_auth_footer(auth, pad_len, frag);
190 if (!NT_STATUS_IS_OK(status)) {
191 data_blob_free(frag);
192 return status;
196 *pdu_size = data_to_send;
197 return NT_STATUS_OK;
200 /*******************************************************************
201 Generate the next PDU to be returned from the data in p->rdata.
202 ********************************************************************/
204 bool create_next_pdu(struct pipes_struct *p)
206 size_t pdu_size = 0;
207 NTSTATUS status;
210 * If we're in the fault state, keep returning fault PDU's until
211 * the pipe gets closed. JRA.
213 if (p->fault_state) {
214 setup_fault_pdu(p, NT_STATUS(p->fault_state));
215 return true;
218 status = create_next_packet(p->mem_ctx, &p->auth,
219 p->call_id, &p->out_data.rdata,
220 p->out_data.data_sent_length,
221 &p->out_data.frag, &pdu_size);
222 if (!NT_STATUS_IS_OK(status)) {
223 DEBUG(0, ("Failed to create packet with error %s, "
224 "(auth level %u / type %u)\n",
225 nt_errstr(status),
226 (unsigned int)p->auth.auth_level,
227 (unsigned int)p->auth.auth_type));
228 return false;
231 /* Setup the counts for this PDU. */
232 p->out_data.data_sent_length += pdu_size;
233 p->out_data.current_pdu_sent = 0;
234 return true;
238 static bool pipe_init_outgoing_data(struct pipes_struct *p);
240 /*******************************************************************
241 Marshall a bind_nak pdu.
242 *******************************************************************/
244 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
246 NTSTATUS status;
247 union dcerpc_payload u;
249 /* Free any memory in the current return data buffer. */
250 pipe_init_outgoing_data(p);
253 * Initialize a bind_nak header.
256 ZERO_STRUCT(u);
258 u.bind_nak.reject_reason = 0;
261 * Marshall directly into the outgoing PDU space. We
262 * must do this as we need to set to the bind response
263 * header and are never sending more than one PDU here.
266 status = dcerpc_push_ncacn_packet(p->mem_ctx,
267 DCERPC_PKT_BIND_NAK,
268 DCERPC_PFC_FLAG_FIRST |
269 DCERPC_PFC_FLAG_LAST,
271 pkt->call_id,
273 &p->out_data.frag);
274 if (!NT_STATUS_IS_OK(status)) {
275 return False;
278 p->out_data.data_sent_length = 0;
279 p->out_data.current_pdu_sent = 0;
281 TALLOC_FREE(p->auth.auth_ctx);
282 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
283 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
284 p->pipe_bound = False;
286 return True;
289 /*******************************************************************
290 Marshall a fault pdu.
291 *******************************************************************/
293 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
295 NTSTATUS status;
296 union dcerpc_payload u;
298 /* Free any memory in the current return data buffer. */
299 pipe_init_outgoing_data(p);
302 * Initialize a fault header.
305 ZERO_STRUCT(u);
307 u.fault.status = NT_STATUS_V(fault_status);
308 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
311 * Marshall directly into the outgoing PDU space. We
312 * must do this as we need to set to the bind response
313 * header and are never sending more than one PDU here.
316 status = dcerpc_push_ncacn_packet(p->mem_ctx,
317 DCERPC_PKT_FAULT,
318 DCERPC_PFC_FLAG_FIRST |
319 DCERPC_PFC_FLAG_LAST |
320 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
322 p->call_id,
324 &p->out_data.frag);
325 if (!NT_STATUS_IS_OK(status)) {
326 return False;
329 p->out_data.data_sent_length = 0;
330 p->out_data.current_pdu_sent = 0;
332 return True;
335 /*******************************************************************
336 Ensure a bind request has the correct abstract & transfer interface.
337 Used to reject unknown binds from Win2k.
338 *******************************************************************/
340 static bool check_bind_req(struct pipes_struct *p,
341 struct ndr_syntax_id* abstract,
342 struct ndr_syntax_id* transfer,
343 uint32_t context_id)
345 struct pipe_rpc_fns *context_fns;
346 bool ok;
347 const char *interface_name = NULL;
349 DEBUG(3,("check_bind_req for %s\n",
350 ndr_interface_name(&abstract->uuid,
351 abstract->if_version)));
353 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
354 if (rpc_srv_pipe_exists_by_id(abstract) &&
355 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
356 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
357 rpc_srv_get_pipe_cli_name(abstract),
358 rpc_srv_get_pipe_srv_name(abstract)));
359 } else {
360 return false;
363 ok = init_pipe_handles(p, abstract);
364 if (!ok) {
365 DEBUG(1, ("Failed to init pipe handles!\n"));
366 return false;
369 context_fns = talloc_zero(p, struct pipe_rpc_fns);
370 if (context_fns == NULL) {
371 DEBUG(0,("check_bind_req: talloc() failed!\n"));
372 return false;
375 interface_name = ndr_interface_name(&abstract->uuid,
376 abstract->if_version);
377 SMB_ASSERT(interface_name != NULL);
379 context_fns->next = context_fns->prev = NULL;
380 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
381 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
382 context_fns->context_id = context_id;
383 context_fns->syntax = *abstract;
385 context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
387 * for the samr, lsarpc and netlogon interfaces we don't allow "connect"
388 * auth_level by default.
390 ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id);
391 if (ok) {
392 context_fns->allow_connect = false;
394 ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
395 if (ok) {
396 context_fns->allow_connect = false;
398 ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
399 if (ok) {
400 context_fns->allow_connect = false;
403 * for the epmapper and echo interfaces we allow "connect"
404 * auth_level by default.
406 ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
407 if (ok) {
408 context_fns->allow_connect = true;
410 ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
411 if (ok) {
412 context_fns->allow_connect = true;
415 * every interface can be modified to allow "connect" auth_level by
416 * using a parametric option like:
417 * allow dcerpc auth level connect:<interface>
418 * e.g.
419 * allow dcerpc auth level connect:samr = yes
421 context_fns->allow_connect = lp_parm_bool(-1,
422 "allow dcerpc auth level connect",
423 interface_name, context_fns->allow_connect);
425 /* add to the list of open contexts */
427 DLIST_ADD( p->contexts, context_fns );
429 return True;
433 * Is a named pipe known?
434 * @param[in] pipename Just the filename
435 * @result Do we want to serve this?
437 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
439 NTSTATUS status;
441 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
442 DEBUG(10, ("refusing spoolss access\n"));
443 return false;
446 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
447 return true;
450 status = smb_probe_module("rpc", pipename);
451 if (!NT_STATUS_IS_OK(status)) {
452 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
453 return false;
455 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
458 * Scan the list again for the interface id
460 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
461 return true;
464 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
465 pipename));
467 return false;
470 /*******************************************************************
471 Handle an NTLMSSP bind auth.
472 *******************************************************************/
474 static bool pipe_auth_generic_bind(struct pipes_struct *p,
475 struct ncacn_packet *pkt,
476 struct dcerpc_auth *auth_info,
477 DATA_BLOB *response)
479 TALLOC_CTX *mem_ctx = pkt;
480 struct gensec_security *gensec_security = NULL;
481 NTSTATUS status;
483 status = auth_generic_server_authtype_start(p,
484 auth_info->auth_type,
485 auth_info->auth_level,
486 &auth_info->credentials,
487 response,
488 p->remote_address,
489 &gensec_security);
490 if (!NT_STATUS_IS_OK(status) &&
491 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
493 DEBUG(0, (__location__ ": auth_generic_server_authtype_start[%u/%u] failed: %s\n",
494 auth_info->auth_type, auth_info->auth_level, nt_errstr(status)));
495 return false;
498 /* Make sure data is bound to the memctx, to be freed the caller */
499 talloc_steal(mem_ctx, response->data);
501 p->auth.auth_ctx = gensec_security;
502 p->auth.auth_type = auth_info->auth_type;
503 p->auth.auth_level = auth_info->auth_level;
505 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
506 p->auth.client_hdr_signing = true;
507 p->auth.hdr_signing = gensec_have_feature(gensec_security,
508 GENSEC_FEATURE_SIGN_PKT_HEADER);
511 if (p->auth.hdr_signing) {
512 gensec_want_feature(gensec_security,
513 GENSEC_FEATURE_SIGN_PKT_HEADER);
516 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
517 return true;
520 status = pipe_auth_verify_final(p);
521 if (!NT_STATUS_IS_OK(status)) {
522 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
523 nt_errstr(status)));
524 return false;
527 return true;
530 /*******************************************************************
531 Process an NTLMSSP authentication response.
532 If this function succeeds, the user has been authenticated
533 and their domain, name and calling workstation stored in
534 the pipe struct.
535 *******************************************************************/
537 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
538 struct gensec_security *gensec_security,
539 enum dcerpc_AuthLevel auth_level,
540 struct auth_session_info **session_info)
542 NTSTATUS status;
543 bool ret;
545 DEBUG(5, (__location__ ": checking user details\n"));
547 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
548 ensure the underlying NTLMSSP flags are also set. If not we should
549 refuse the bind. */
551 status = auth_generic_server_check_flags(gensec_security,
552 (auth_level ==
553 DCERPC_AUTH_LEVEL_INTEGRITY),
554 (auth_level ==
555 DCERPC_AUTH_LEVEL_PRIVACY));
556 if (!NT_STATUS_IS_OK(status)) {
557 DEBUG(0, (__location__ ": Client failed to negotatie proper "
558 "security for rpc connection\n"));
559 return false;
562 TALLOC_FREE(*session_info);
564 status = auth_generic_server_get_user_info(gensec_security,
565 mem_ctx, session_info);
566 if (!NT_STATUS_IS_OK(status)) {
567 DEBUG(0, (__location__ ": failed to obtain the server info "
568 "for authenticated user: %s\n", nt_errstr(status)));
569 return false;
572 if ((*session_info)->security_token == NULL) {
573 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
574 return false;
577 if ((*session_info)->unix_token == NULL) {
578 DEBUG(1, ("Auth module failed to provide unix_token\n"));
579 return false;
583 * We're an authenticated bind over smb, so the session key needs to
584 * be set to "SystemLibraryDTC". Weird, but this is what Windows
585 * does. See the RPC-SAMBA3SESSIONKEY.
588 ret = session_info_set_session_key((*session_info), generic_session_key());
589 if (!ret) {
590 DEBUG(0, ("Failed to set session key!\n"));
591 return false;
594 return true;
597 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
599 struct gensec_security *gensec_security;
600 bool ok;
602 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
603 p->pipe_bound = true;
604 return NT_STATUS_OK;
607 gensec_security = p->auth.auth_ctx;
609 ok = pipe_auth_generic_verify_final(p, gensec_security,
610 p->auth.auth_level,
611 &p->session_info);
612 if (!ok) {
613 return NT_STATUS_ACCESS_DENIED;
616 p->pipe_bound = true;
618 return NT_STATUS_OK;
621 /*******************************************************************
622 Respond to a pipe bind request.
623 *******************************************************************/
625 static bool api_pipe_bind_req(struct pipes_struct *p,
626 struct ncacn_packet *pkt)
628 struct dcerpc_auth auth_info = {0};
629 uint16_t assoc_gid;
630 NTSTATUS status;
631 struct ndr_syntax_id id;
632 uint8_t pfc_flags = 0;
633 union dcerpc_payload u;
634 struct dcerpc_ack_ctx bind_ack_ctx;
635 DATA_BLOB auth_resp = data_blob_null;
636 DATA_BLOB auth_blob = data_blob_null;
637 const struct ndr_interface_table *table;
639 /* No rebinds on a bound pipe - use alter context. */
640 if (p->pipe_bound) {
641 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
642 return setup_bind_nak(p, pkt);
645 if (pkt->u.bind.num_contexts == 0) {
646 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
647 goto err_exit;
651 * Try and find the correct pipe name to ensure
652 * that this is a pipe name we support.
654 id = pkt->u.bind.ctx_list[0].abstract_syntax;
656 table = ndr_table_by_uuid(&id.uuid);
657 if (table == NULL) {
658 DEBUG(0,("unknown interface\n"));
659 return false;
662 if (rpc_srv_pipe_exists_by_id(&id)) {
663 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
664 rpc_srv_get_pipe_cli_name(&id),
665 rpc_srv_get_pipe_srv_name(&id)));
666 } else {
667 status = smb_probe_module(
668 "rpc", dcerpc_default_transport_endpoint(pkt,
669 NCACN_NP, table));
671 if (NT_STATUS_IS_ERR(status)) {
672 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
673 "%s in bind request.\n",
674 ndr_interface_name(&id.uuid,
675 id.if_version)));
677 return setup_bind_nak(p, pkt);
680 if (rpc_srv_get_pipe_interface_by_cli_name(
681 dcerpc_default_transport_endpoint(pkt,
682 NCACN_NP, table),
683 &id)) {
684 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
685 rpc_srv_get_pipe_cli_name(&id),
686 rpc_srv_get_pipe_srv_name(&id)));
687 } else {
688 DEBUG(0, ("module %s doesn't provide functions for "
689 "pipe %s!\n",
690 ndr_interface_name(&id.uuid,
691 id.if_version),
692 ndr_interface_name(&id.uuid,
693 id.if_version)));
694 return setup_bind_nak(p, pkt);
698 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
700 if (pkt->u.bind.assoc_group_id != 0) {
701 assoc_gid = pkt->u.bind.assoc_group_id;
702 } else {
703 assoc_gid = 0x53f0;
707 * Create the bind response struct.
710 /* If the requested abstract synt uuid doesn't match our client pipe,
711 reject the bind_ack & set the transfer interface synt to all 0's,
712 ver 0 (observed when NT5 attempts to bind to abstract interfaces
713 unknown to NT4)
714 Needed when adding entries to a DACL from NT5 - SK */
716 if (check_bind_req(p,
717 &pkt->u.bind.ctx_list[0].abstract_syntax,
718 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
719 pkt->u.bind.ctx_list[0].context_id)) {
721 bind_ack_ctx.result = 0;
722 bind_ack_ctx.reason.value = 0;
723 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
724 } else {
725 p->pipe_bound = False;
726 /* Rejection reason: abstract syntax not supported */
727 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
728 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
729 bind_ack_ctx.syntax = ndr_syntax_id_null;
733 * Check if this is an authenticated bind request.
735 if (pkt->auth_length) {
737 * Decode the authentication verifier.
739 status = dcerpc_pull_auth_trailer(pkt, pkt,
740 &pkt->u.bind.auth_info,
741 &auth_info, NULL, true);
742 if (!NT_STATUS_IS_OK(status)) {
743 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
744 goto err_exit;
747 if (!pipe_auth_generic_bind(p, pkt,
748 &auth_info, &auth_resp)) {
749 goto err_exit;
751 } else {
752 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
753 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
754 p->pipe_bound = True;
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)));
801 goto err_exit;
804 if (auth_resp.length) {
806 status = dcerpc_push_dcerpc_auth(pkt,
807 p->auth.auth_type,
808 p->auth.auth_level,
810 1, /* auth_context_id */
811 &auth_resp,
812 &auth_blob);
813 if (!NT_STATUS_IS_OK(status)) {
814 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
815 goto err_exit;
819 /* Now that we have the auth len store it into the right place in
820 * the dcerpc header */
821 dcerpc_set_frag_length(&p->out_data.frag,
822 p->out_data.frag.length + auth_blob.length);
824 if (auth_blob.length) {
826 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
827 auth_blob.data, auth_blob.length)) {
828 DEBUG(0, ("Append of auth info failed.\n"));
829 goto err_exit;
834 * Setup the lengths for the initial reply.
837 p->out_data.data_sent_length = 0;
838 p->out_data.current_pdu_sent = 0;
840 TALLOC_FREE(auth_blob.data);
841 return True;
843 err_exit:
845 data_blob_free(&p->out_data.frag);
846 TALLOC_FREE(auth_blob.data);
847 return setup_bind_nak(p, pkt);
850 /*******************************************************************
851 This is the "stage3" response after a bind request and reply.
852 *******************************************************************/
854 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
856 struct dcerpc_auth auth_info;
857 DATA_BLOB response = data_blob_null;
858 struct gensec_security *gensec_security;
859 NTSTATUS status;
861 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
863 /* We can only finish if the pipe is unbound for now */
864 if (p->pipe_bound) {
865 DEBUG(0, (__location__ ": Pipe already bound, "
866 "AUTH3 not supported!\n"));
867 goto err;
870 if (pkt->auth_length == 0) {
871 DEBUG(1, ("No auth field sent for auth3 request!\n"));
872 goto err;
876 * Decode the authentication verifier response.
879 status = dcerpc_pull_auth_trailer(pkt, pkt,
880 &pkt->u.auth3.auth_info,
881 &auth_info, NULL, true);
882 if (!NT_STATUS_IS_OK(status)) {
883 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
884 goto err;
887 /* We must NEVER look at auth_info->auth_pad_len here,
888 * as old Samba client code gets it wrong and sends it
889 * as zero. JRA.
892 if (auth_info.auth_type != p->auth.auth_type) {
893 DEBUG(1, ("Auth type mismatch! Client sent %d, "
894 "but auth was started as type %d!\n",
895 auth_info.auth_type, p->auth.auth_type));
896 goto err;
899 gensec_security = p->auth.auth_ctx;
901 status = auth_generic_server_step(gensec_security,
902 pkt, &auth_info.credentials,
903 &response);
905 if (NT_STATUS_EQUAL(status,
906 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
907 response.length) {
908 DEBUG(1, (__location__ ": This was supposed to be the final "
909 "leg, but crypto machinery claims a response is "
910 "needed, aborting auth!\n"));
911 data_blob_free(&response);
912 goto err;
914 if (!NT_STATUS_IS_OK(status)) {
915 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
916 goto err;
919 /* Now verify auth was indeed successful and extract server info */
920 status = pipe_auth_verify_final(p);
921 if (!NT_STATUS_IS_OK(status)) {
922 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
923 goto err;
926 return true;
928 err:
930 TALLOC_FREE(p->auth.auth_ctx);
931 return false;
934 /****************************************************************************
935 Deal with an alter context call. Can be third part of 3 leg auth request for
936 SPNEGO calls.
937 ****************************************************************************/
939 static bool api_pipe_alter_context(struct pipes_struct *p,
940 struct ncacn_packet *pkt)
942 struct dcerpc_auth auth_info = {0};
943 uint16_t assoc_gid;
944 NTSTATUS status;
945 union dcerpc_payload u;
946 struct dcerpc_ack_ctx bind_ack_ctx;
947 DATA_BLOB auth_resp = data_blob_null;
948 DATA_BLOB auth_blob = data_blob_null;
949 struct gensec_security *gensec_security;
951 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
953 if (pkt->u.bind.assoc_group_id != 0) {
954 assoc_gid = pkt->u.bind.assoc_group_id;
955 } else {
956 assoc_gid = 0x53f0;
960 * Create the bind response struct.
963 /* If the requested abstract synt uuid doesn't match our client pipe,
964 reject the bind_ack & set the transfer interface synt to all 0's,
965 ver 0 (observed when NT5 attempts to bind to abstract interfaces
966 unknown to NT4)
967 Needed when adding entries to a DACL from NT5 - SK */
969 if (check_bind_req(p,
970 &pkt->u.bind.ctx_list[0].abstract_syntax,
971 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
972 pkt->u.bind.ctx_list[0].context_id)) {
974 bind_ack_ctx.result = 0;
975 bind_ack_ctx.reason.value = 0;
976 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
977 } else {
978 p->pipe_bound = False;
979 /* Rejection reason: abstract syntax not supported */
980 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
981 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
982 bind_ack_ctx.syntax = ndr_syntax_id_null;
986 * Check if this is an authenticated alter context request.
988 if (pkt->auth_length) {
989 /* We can only finish if the pipe is unbound for now */
990 if (p->pipe_bound) {
991 DEBUG(0, (__location__ ": Pipe already bound, "
992 "Altering Context not yet supported!\n"));
993 goto err_exit;
996 status = dcerpc_pull_auth_trailer(pkt, pkt,
997 &pkt->u.bind.auth_info,
998 &auth_info, NULL, true);
999 if (!NT_STATUS_IS_OK(status)) {
1000 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1001 goto err_exit;
1004 if (auth_info.auth_type != p->auth.auth_type) {
1005 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1006 "but auth was started as type %d!\n",
1007 auth_info.auth_type, p->auth.auth_type));
1008 goto err_exit;
1011 gensec_security = p->auth.auth_ctx;
1012 status = auth_generic_server_step(gensec_security,
1013 pkt,
1014 &auth_info.credentials,
1015 &auth_resp);
1016 if (NT_STATUS_IS_OK(status)) {
1017 /* third leg of auth, verify auth info */
1018 status = pipe_auth_verify_final(p);
1019 if (!NT_STATUS_IS_OK(status)) {
1020 DEBUG(0, ("Auth Verify failed (%s)\n",
1021 nt_errstr(status)));
1022 goto err_exit;
1024 } else if (NT_STATUS_EQUAL(status,
1025 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1026 DEBUG(10, ("More auth legs required.\n"));
1027 } else {
1028 DEBUG(0, ("Auth step returned an error (%s)\n",
1029 nt_errstr(status)));
1030 goto err_exit;
1034 ZERO_STRUCT(u.alter_resp);
1035 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1036 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1037 u.alter_resp.assoc_group_id = assoc_gid;
1039 /* secondary address CAN be NULL
1040 * as the specs say it's ignored.
1041 * It MUST be NULL to have the spoolss working.
1043 u.alter_resp.secondary_address = "";
1044 u.alter_resp.secondary_address_size = 1;
1046 u.alter_resp.num_results = 1;
1047 u.alter_resp.ctx_list = &bind_ack_ctx;
1049 /* NOTE: We leave the auth_info empty so we can calculate the padding
1050 * later and then append the auth_info --simo */
1053 * Marshall directly into the outgoing PDU space. We
1054 * must do this as we need to set to the bind response
1055 * header and are never sending more than one PDU here.
1058 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1059 DCERPC_PKT_ALTER_RESP,
1060 DCERPC_PFC_FLAG_FIRST |
1061 DCERPC_PFC_FLAG_LAST,
1062 auth_resp.length,
1063 pkt->call_id,
1065 &p->out_data.frag);
1066 if (!NT_STATUS_IS_OK(status)) {
1067 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1068 nt_errstr(status)));
1069 goto err_exit;
1072 if (auth_resp.length) {
1073 status = dcerpc_push_dcerpc_auth(pkt,
1074 auth_info.auth_type,
1075 auth_info.auth_level,
1076 0, /* pad_len */
1077 1, /* auth_context_id */
1078 &auth_resp,
1079 &auth_blob);
1080 if (!NT_STATUS_IS_OK(status)) {
1081 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1082 goto err_exit;
1086 /* Now that we have the auth len store it into the right place in
1087 * the dcerpc header */
1088 dcerpc_set_frag_length(&p->out_data.frag,
1089 p->out_data.frag.length +
1090 auth_blob.length);
1092 if (auth_resp.length) {
1093 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1094 auth_blob.data, auth_blob.length)) {
1095 DEBUG(0, ("Append of auth info failed.\n"));
1096 goto err_exit;
1101 * Setup the lengths for the initial reply.
1104 p->out_data.data_sent_length = 0;
1105 p->out_data.current_pdu_sent = 0;
1107 TALLOC_FREE(auth_blob.data);
1108 return True;
1110 err_exit:
1112 data_blob_free(&p->out_data.frag);
1113 TALLOC_FREE(auth_blob.data);
1114 return setup_bind_nak(p, pkt);
1117 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1118 const struct api_struct *api_rpc_cmds, int n_cmds,
1119 const struct ndr_syntax_id *syntax);
1121 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1122 struct ncacn_packet *pkt,
1123 struct pipe_rpc_fns *pipe_fns)
1125 TALLOC_CTX *frame = talloc_stackframe();
1126 struct dcerpc_sec_verification_trailer *vt = NULL;
1127 const uint32_t bitmask1 =
1128 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1129 const struct dcerpc_sec_vt_pcontext pcontext = {
1130 .abstract_syntax = pipe_fns->syntax,
1131 .transfer_syntax = ndr_transfer_syntax_ndr,
1133 const struct dcerpc_sec_vt_header2 header2 =
1134 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1135 struct ndr_pull *ndr;
1136 enum ndr_err_code ndr_err;
1137 bool ret = false;
1139 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1140 if (ndr == NULL) {
1141 goto done;
1144 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1145 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1146 goto done;
1149 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1150 &pcontext, &header2);
1151 done:
1152 TALLOC_FREE(frame);
1153 return ret;
1156 /****************************************************************************
1157 Find the correct RPC function to call for this request.
1158 If the pipe is authenticated then become the correct UNIX user
1159 before doing the call.
1160 ****************************************************************************/
1162 static bool api_pipe_request(struct pipes_struct *p,
1163 struct ncacn_packet *pkt)
1165 TALLOC_CTX *frame = talloc_stackframe();
1166 bool ret = False;
1167 struct pipe_rpc_fns *pipe_fns;
1168 const char *interface_name = NULL;
1170 if (!p->pipe_bound) {
1171 DEBUG(1, ("Pipe not bound!\n"));
1172 data_blob_free(&p->out_data.rdata);
1173 TALLOC_FREE(frame);
1174 return false;
1177 /* get the set of RPC functions for this context */
1178 pipe_fns = find_pipe_fns_by_context(p->contexts,
1179 pkt->u.request.context_id);
1180 if (pipe_fns == NULL) {
1181 DEBUG(0, ("No rpc function table associated with context "
1182 "[%d]\n",
1183 pkt->u.request.context_id));
1184 data_blob_free(&p->out_data.rdata);
1185 TALLOC_FREE(frame);
1186 return false;
1189 interface_name = ndr_interface_name(&pipe_fns->syntax.uuid,
1190 pipe_fns->syntax.if_version);
1191 SMB_ASSERT(interface_name != NULL);
1193 switch (p->auth.auth_level) {
1194 case DCERPC_AUTH_LEVEL_NONE:
1195 case DCERPC_AUTH_LEVEL_INTEGRITY:
1196 case DCERPC_AUTH_LEVEL_PRIVACY:
1197 break;
1198 default:
1199 if (!pipe_fns->allow_connect) {
1200 char *addr;
1202 addr = tsocket_address_string(p->remote_address, frame);
1204 DEBUG(1, ("%s: restrict auth_level_connect access "
1205 "to [%s] with auth[type=0x%x,level=0x%x] "
1206 "on [%s] from [%s]\n",
1207 __func__, interface_name,
1208 p->auth.auth_type,
1209 p->auth.auth_level,
1210 derpc_transport_string_by_transport(p->transport),
1211 addr));
1213 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1214 TALLOC_FREE(frame);
1215 return true;
1217 break;
1220 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1221 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1222 set_incoming_fault(p);
1223 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1224 data_blob_free(&p->out_data.rdata);
1225 TALLOC_FREE(frame);
1226 return true;
1229 if (!become_authenticated_pipe_user(p->session_info)) {
1230 DEBUG(1, ("Failed to become pipe user!\n"));
1231 data_blob_free(&p->out_data.rdata);
1232 TALLOC_FREE(frame);
1233 return false;
1236 DEBUG(5, ("Requested %s rpc service\n", interface_name));
1238 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1239 &pipe_fns->syntax);
1240 unbecome_authenticated_pipe_user();
1242 TALLOC_FREE(frame);
1243 return ret;
1246 /*******************************************************************
1247 Calls the underlying RPC function for a named pipe.
1248 ********************************************************************/
1250 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1251 const struct api_struct *api_rpc_cmds, int n_cmds,
1252 const struct ndr_syntax_id *syntax)
1254 int fn_num;
1255 uint32_t offset1;
1256 const struct ndr_interface_table *table;
1258 /* interpret the command */
1259 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1260 ndr_interface_name(&syntax->uuid, syntax->if_version),
1261 pkt->u.request.opnum));
1263 table = ndr_table_by_uuid(&syntax->uuid);
1264 if (table == NULL) {
1265 DEBUG(0,("unknown interface\n"));
1266 return false;
1269 if (DEBUGLEVEL >= 50) {
1270 fstring name;
1271 slprintf(name, sizeof(name)-1, "in_%s",
1272 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1273 dump_pdu_region(name, pkt->u.request.opnum,
1274 &p->in_data.data, 0,
1275 p->in_data.data.length);
1278 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1279 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1280 api_rpc_cmds[fn_num].fn != NULL) {
1281 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1282 api_rpc_cmds[fn_num].name));
1283 break;
1287 if (fn_num == n_cmds) {
1289 * For an unknown RPC just return a fault PDU but
1290 * return True to allow RPC's on the pipe to continue
1291 * and not put the pipe into fault state. JRA.
1293 DEBUG(4, ("unknown\n"));
1294 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1295 return True;
1298 offset1 = p->out_data.rdata.length;
1300 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1301 fn_num, api_rpc_cmds[fn_num].fn));
1302 /* do the actual command */
1303 if(!api_rpc_cmds[fn_num].fn(p)) {
1304 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1305 ndr_interface_name(&syntax->uuid, syntax->if_version),
1306 api_rpc_cmds[fn_num].name));
1307 data_blob_free(&p->out_data.rdata);
1308 return False;
1311 if (p->fault_state) {
1312 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1313 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1314 p->fault_state = 0;
1315 return true;
1318 if (DEBUGLEVEL >= 50) {
1319 fstring name;
1320 slprintf(name, sizeof(name)-1, "out_%s",
1321 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1322 dump_pdu_region(name, pkt->u.request.opnum,
1323 &p->out_data.rdata, offset1,
1324 p->out_data.rdata.length);
1327 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1328 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1330 /* Check for buffer underflow in rpc parsing */
1331 if ((DEBUGLEVEL >= 10) &&
1332 (pkt->frag_length < p->in_data.data.length)) {
1333 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1334 dump_data(10, p->in_data.data.data + pkt->frag_length,
1335 p->in_data.data.length - pkt->frag_length);
1338 return True;
1341 /****************************************************************************
1342 Initialise an outgoing packet.
1343 ****************************************************************************/
1345 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1347 output_data *o_data = &p->out_data;
1349 /* Reset the offset counters. */
1350 o_data->data_sent_length = 0;
1351 o_data->current_pdu_sent = 0;
1353 data_blob_free(&o_data->frag);
1355 /* Free any memory in the current return data buffer. */
1356 data_blob_free(&o_data->rdata);
1358 return True;
1361 /****************************************************************************
1362 Sets the fault state on incoming packets.
1363 ****************************************************************************/
1365 void set_incoming_fault(struct pipes_struct *p)
1367 data_blob_free(&p->in_data.data);
1368 p->in_data.pdu_needed_len = 0;
1369 p->in_data.pdu.length = 0;
1370 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1372 DEBUG(10, ("Setting fault state\n"));
1375 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1376 struct ncacn_packet *pkt,
1377 DATA_BLOB *raw_pkt)
1379 NTSTATUS status;
1380 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1382 DEBUG(10, ("Checking request auth.\n"));
1384 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1385 hdr_size += 16;
1388 /* in case of sealing this function will unseal the data in place */
1389 status = dcerpc_check_auth(auth, pkt,
1390 &pkt->u.request.stub_and_verifier,
1391 hdr_size, raw_pkt);
1392 if (!NT_STATUS_IS_OK(status)) {
1393 return status;
1396 return NT_STATUS_OK;
1399 /****************************************************************************
1400 Processes a request pdu. This will do auth processing if needed, and
1401 appends the data into the complete stream if the LAST flag is not set.
1402 ****************************************************************************/
1404 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1406 NTSTATUS status;
1407 DATA_BLOB data;
1408 struct dcerpc_sec_vt_header2 hdr2;
1410 if (!p->pipe_bound) {
1411 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1412 set_incoming_fault(p);
1413 return False;
1416 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1417 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1418 p->header2 = hdr2;
1419 } else {
1420 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1421 set_incoming_fault(p);
1422 return false;
1426 /* Store the opnum */
1427 p->opnum = pkt->u.request.opnum;
1429 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1432 nt_errstr(status)));
1433 set_incoming_fault(p);
1434 return false;
1437 data = pkt->u.request.stub_and_verifier;
1440 * Check the data length doesn't go over the 15Mb limit.
1441 * increased after observing a bug in the Windows NT 4.0 SP6a
1442 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1443 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1446 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1447 DEBUG(0, ("process_request_pdu: "
1448 "rpc data buffer too large (%u) + (%u)\n",
1449 (unsigned int)p->in_data.data.length,
1450 (unsigned int)data.length));
1451 set_incoming_fault(p);
1452 return False;
1456 * Append the data portion into the buffer and return.
1459 if (data.length) {
1460 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1461 data.data, data.length)) {
1462 DEBUG(0, ("Unable to append data size %u "
1463 "to parse buffer of size %u.\n",
1464 (unsigned int)data.length,
1465 (unsigned int)p->in_data.data.length));
1466 set_incoming_fault(p);
1467 return False;
1471 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1472 return true;
1476 * Ok - we finally have a complete RPC stream.
1477 * Call the rpc command to process it.
1480 return api_pipe_request(p, pkt);
1483 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1485 bool reply = false;
1487 /* Store the call_id */
1488 p->call_id = pkt->call_id;
1490 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1492 if (!pipe_init_outgoing_data(p)) {
1493 goto done;
1496 switch (pkt->ptype) {
1497 case DCERPC_PKT_REQUEST:
1498 reply = process_request_pdu(p, pkt);
1499 break;
1501 case DCERPC_PKT_PING: /* CL request - ignore... */
1502 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1503 (unsigned int)pkt->ptype));
1504 break;
1506 case DCERPC_PKT_RESPONSE: /* No responses here. */
1507 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1508 break;
1510 case DCERPC_PKT_FAULT:
1511 case DCERPC_PKT_WORKING:
1512 /* CL request - reply to a ping when a call in process. */
1513 case DCERPC_PKT_NOCALL:
1514 /* CL - server reply to a ping call. */
1515 case DCERPC_PKT_REJECT:
1516 case DCERPC_PKT_ACK:
1517 case DCERPC_PKT_CL_CANCEL:
1518 case DCERPC_PKT_FACK:
1519 case DCERPC_PKT_CANCEL_ACK:
1520 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1521 (unsigned int)pkt->ptype));
1522 break;
1524 case DCERPC_PKT_BIND:
1526 * We assume that a pipe bind is only in one pdu.
1528 reply = api_pipe_bind_req(p, pkt);
1529 break;
1531 case DCERPC_PKT_BIND_ACK:
1532 case DCERPC_PKT_BIND_NAK:
1533 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1534 "packet type %u received.\n",
1535 (unsigned int)pkt->ptype));
1536 break;
1539 case DCERPC_PKT_ALTER:
1541 * We assume that a pipe bind is only in one pdu.
1543 reply = api_pipe_alter_context(p, pkt);
1544 break;
1546 case DCERPC_PKT_ALTER_RESP:
1547 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1548 "Should only be server -> client.\n"));
1549 break;
1551 case DCERPC_PKT_AUTH3:
1553 * The third packet in an auth exchange.
1555 reply = api_pipe_bind_auth3(p, pkt);
1556 break;
1558 case DCERPC_PKT_SHUTDOWN:
1559 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1560 "Should only be server -> client.\n"));
1561 break;
1563 case DCERPC_PKT_CO_CANCEL:
1564 /* For now just free all client data and continue
1565 * processing. */
1566 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1567 " Abandoning rpc call.\n"));
1568 /* As we never do asynchronous RPC serving, we can
1569 * never cancel a call (as far as I know).
1570 * If we ever did we'd have to send a cancel_ack reply.
1571 * For now, just free all client data and continue
1572 * processing. */
1573 reply = True;
1574 break;
1576 #if 0
1577 /* Enable this if we're doing async rpc. */
1578 /* We must check the outstanding callid matches. */
1579 if (pipe_init_outgoing_data(p)) {
1580 /* Send a cancel_ack PDU reply. */
1581 /* We should probably check the auth-verifier here. */
1582 reply = setup_cancel_ack_reply(p, pkt);
1584 break;
1585 #endif
1587 case DCERPC_PKT_ORPHANED:
1588 /* We should probably check the auth-verifier here.
1589 * For now just free all client data and continue
1590 * processing. */
1591 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1592 " Abandoning rpc call.\n"));
1593 reply = True;
1594 break;
1596 default:
1597 DEBUG(0, ("process_complete_pdu: "
1598 "Unknown rpc type = %u received.\n",
1599 (unsigned int)pkt->ptype));
1600 break;
1603 done:
1604 if (!reply) {
1605 DEBUG(3,("DCE/RPC fault sent!"));
1606 set_incoming_fault(p);
1607 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1609 /* pkt and p->in_data.pdu.data freed by caller */