s4:torture: test setting EOF of a stream to 0 with enabled AAPL extensions
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob7a1c61594678e9814bd9bfe9d1e292a893ba6bc7
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/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"
53 #include "../librpc/gen_ndr/ndr_winspool.h"
55 #undef DBGC_CLASS
56 #define DBGC_CLASS DBGC_RPC_SRV
58 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p);
60 /**
61 * Dump everything from the start of the end up of the provided data
62 * into a file, but only at debug level >= 50
63 **/
64 static void dump_pdu_region(const char *name, int v,
65 DATA_BLOB *data, size_t start, size_t end)
67 int fd, i;
68 char *fname = NULL;
69 ssize_t sz;
71 if (DEBUGLEVEL < 50) return;
73 if (start > data->length || end > data->length || start > end) return;
75 for (i = 1; i < 100; i++) {
76 if (v != -1) {
77 fname = talloc_asprintf(talloc_tos(),
78 "/tmp/%s_%d.%d.prs",
79 name, v, i);
80 } else {
81 fname = talloc_asprintf(talloc_tos(),
82 "/tmp/%s_%d.prs",
83 name, i);
85 if (!fname) {
86 return;
88 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
89 if (fd != -1 || errno != EEXIST) break;
91 if (fd != -1) {
92 sz = write(fd, data->data + start, end - start);
93 i = close(fd);
94 if ((sz != end - start) || (i != 0) ) {
95 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
96 fname, (unsigned long)sz,
97 (unsigned long)end - start, i));
98 } else {
99 DEBUG(0,("created %s\n", fname));
102 TALLOC_FREE(fname);
105 static DATA_BLOB generic_session_key(void)
107 return data_blob_const("SystemLibraryDTC", 16);
110 /*******************************************************************
111 Generate the next PDU to be returned from the data.
112 ********************************************************************/
114 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
115 struct pipe_auth_data *auth,
116 uint32_t call_id,
117 DATA_BLOB *rdata,
118 size_t data_sent_length,
119 DATA_BLOB *frag,
120 size_t *pdu_size)
122 union dcerpc_payload u;
123 uint8_t pfc_flags;
124 size_t data_left;
125 size_t data_to_send;
126 size_t frag_len;
127 size_t pad_len = 0;
128 size_t auth_len = 0;
129 NTSTATUS status;
131 ZERO_STRUCT(u.response);
133 /* Set up rpc packet pfc flags. */
134 if (data_sent_length == 0) {
135 pfc_flags = DCERPC_PFC_FLAG_FIRST;
136 } else {
137 pfc_flags = 0;
140 /* Work out how much we can fit in a single PDU. */
141 data_left = rdata->length - data_sent_length;
143 /* Ensure there really is data left to send. */
144 if (!data_left) {
145 DEBUG(0, ("No data left to send !\n"));
146 return NT_STATUS_BUFFER_TOO_SMALL;
149 status = dcerpc_guess_sizes(auth,
150 DCERPC_RESPONSE_LENGTH,
151 data_left,
152 RPC_MAX_PDU_FRAG_LEN,
153 &data_to_send, &frag_len,
154 &auth_len, &pad_len);
155 if (!NT_STATUS_IS_OK(status)) {
156 return status;
159 /* Set up the alloc hint. This should be the data left to send. */
160 u.response.alloc_hint = data_left;
162 /* Work out if this PDU will be the last. */
163 if (data_sent_length + data_to_send >= rdata->length) {
164 pfc_flags |= DCERPC_PFC_FLAG_LAST;
167 /* Prepare data to be NDR encoded. */
168 u.response.stub_and_verifier =
169 data_blob_const(rdata->data + data_sent_length, data_to_send);
171 /* Store the packet in the data stream. */
172 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
173 pfc_flags, auth_len, call_id,
174 &u, frag);
175 if (!NT_STATUS_IS_OK(status)) {
176 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
177 return status;
180 if (auth_len) {
181 /* Set the proper length on the pdu, including padding.
182 * Only needed if an auth trailer will be appended. */
183 dcerpc_set_frag_length(frag, frag->length
184 + pad_len
185 + DCERPC_AUTH_TRAILER_LENGTH
186 + auth_len);
189 if (auth_len) {
190 status = dcerpc_add_auth_footer(auth, pad_len, frag);
191 if (!NT_STATUS_IS_OK(status)) {
192 data_blob_free(frag);
193 return status;
197 *pdu_size = data_to_send;
198 return NT_STATUS_OK;
201 /*******************************************************************
202 Generate the next PDU to be returned from the data in p->rdata.
203 ********************************************************************/
205 bool create_next_pdu(struct pipes_struct *p)
207 size_t pdu_size = 0;
208 NTSTATUS status;
211 * If we're in the fault state, keep returning fault PDU's until
212 * the pipe gets closed. JRA.
214 if (p->fault_state) {
215 setup_fault_pdu(p, NT_STATUS(p->fault_state));
216 return true;
219 status = create_next_packet(p->mem_ctx, &p->auth,
220 p->call_id, &p->out_data.rdata,
221 p->out_data.data_sent_length,
222 &p->out_data.frag, &pdu_size);
223 if (!NT_STATUS_IS_OK(status)) {
224 DEBUG(0, ("Failed to create packet with error %s, "
225 "(auth level %u / type %u)\n",
226 nt_errstr(status),
227 (unsigned int)p->auth.auth_level,
228 (unsigned int)p->auth.auth_type));
229 return false;
232 /* Setup the counts for this PDU. */
233 p->out_data.data_sent_length += pdu_size;
234 p->out_data.current_pdu_sent = 0;
235 return true;
239 static bool pipe_init_outgoing_data(struct pipes_struct *p);
241 /*******************************************************************
242 Marshall a bind_nak pdu.
243 *******************************************************************/
245 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
247 NTSTATUS status;
248 union dcerpc_payload u;
250 /* Free any memory in the current return data buffer. */
251 pipe_init_outgoing_data(p);
254 * Initialize a bind_nak header.
257 ZERO_STRUCT(u);
259 u.bind_nak.reject_reason = 0;
262 * Marshall directly into the outgoing PDU space. We
263 * must do this as we need to set to the bind response
264 * header and are never sending more than one PDU here.
267 status = dcerpc_push_ncacn_packet(p->mem_ctx,
268 DCERPC_PKT_BIND_NAK,
269 DCERPC_PFC_FLAG_FIRST |
270 DCERPC_PFC_FLAG_LAST,
272 pkt->call_id,
274 &p->out_data.frag);
275 if (!NT_STATUS_IS_OK(status)) {
276 return False;
279 p->out_data.data_sent_length = 0;
280 p->out_data.current_pdu_sent = 0;
282 set_incoming_fault(p);
283 TALLOC_FREE(p->auth.auth_ctx);
284 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
285 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
286 p->pipe_bound = False;
287 p->allow_bind = false;
288 p->allow_alter = false;
289 p->allow_auth3 = false;
291 return True;
294 /*******************************************************************
295 Marshall a fault pdu.
296 *******************************************************************/
298 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
300 NTSTATUS status;
301 union dcerpc_payload u;
303 /* Free any memory in the current return data buffer. */
304 pipe_init_outgoing_data(p);
307 * Initialize a fault header.
310 ZERO_STRUCT(u);
312 u.fault.status = NT_STATUS_V(fault_status);
315 * Marshall directly into the outgoing PDU space. We
316 * must do this as we need to set to the bind response
317 * header and are never sending more than one PDU here.
320 status = dcerpc_push_ncacn_packet(p->mem_ctx,
321 DCERPC_PKT_FAULT,
322 DCERPC_PFC_FLAG_FIRST |
323 DCERPC_PFC_FLAG_LAST |
324 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
326 p->call_id,
328 &p->out_data.frag);
329 if (!NT_STATUS_IS_OK(status)) {
330 return False;
333 p->out_data.data_sent_length = 0;
334 p->out_data.current_pdu_sent = 0;
336 return True;
339 /*******************************************************************
340 Ensure a bind request has the correct abstract & transfer interface.
341 Used to reject unknown binds from Win2k.
342 *******************************************************************/
344 static bool check_bind_req(struct pipes_struct *p,
345 struct ndr_syntax_id* abstract,
346 struct ndr_syntax_id* transfer,
347 uint32_t context_id)
349 struct pipe_rpc_fns *context_fns;
350 bool ok;
351 const char *interface_name = NULL;
353 DEBUG(3,("check_bind_req for %s context_id=%u\n",
354 ndr_interface_name(&abstract->uuid,
355 abstract->if_version),
356 (unsigned)context_id));
358 ok = ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr);
359 if (!ok) {
360 DEBUG(1,("check_bind_req unknown transfer syntax for "
361 "%s context_id=%u\n",
362 ndr_interface_name(&abstract->uuid,
363 abstract->if_version),
364 (unsigned)context_id));
365 return false;
368 for (context_fns = p->contexts;
369 context_fns != NULL;
370 context_fns = context_fns->next)
372 if (context_fns->context_id != context_id) {
373 continue;
376 ok = ndr_syntax_id_equal(&context_fns->syntax,
377 abstract);
378 if (ok) {
379 return true;
382 DEBUG(1,("check_bind_req: changing abstract syntax for "
383 "%s context_id=%u into %s not supported\n",
384 ndr_interface_name(&context_fns->syntax.uuid,
385 context_fns->syntax.if_version),
386 (unsigned)context_id,
387 ndr_interface_name(&abstract->uuid,
388 abstract->if_version)));
389 return false;
392 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
393 if (!rpc_srv_pipe_exists_by_id(abstract)) {
394 return false;
397 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
398 rpc_srv_get_pipe_cli_name(abstract),
399 rpc_srv_get_pipe_srv_name(abstract)));
401 ok = init_pipe_handles(p, abstract);
402 if (!ok) {
403 DEBUG(1, ("Failed to init pipe handles!\n"));
404 return false;
407 context_fns = talloc_zero(p, struct pipe_rpc_fns);
408 if (context_fns == NULL) {
409 DEBUG(0,("check_bind_req: talloc() failed!\n"));
410 return false;
413 interface_name = ndr_interface_name(&abstract->uuid,
414 abstract->if_version);
415 SMB_ASSERT(interface_name != NULL);
417 context_fns->next = context_fns->prev = NULL;
418 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
419 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
420 context_fns->context_id = context_id;
421 context_fns->syntax = *abstract;
423 context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
425 * for the samr, lsarpc and netlogon interfaces we don't allow "connect"
426 * auth_level by default.
428 ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id);
429 if (ok) {
430 context_fns->allow_connect = false;
432 ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
433 if (ok) {
434 context_fns->allow_connect = false;
436 ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
437 if (ok) {
438 context_fns->allow_connect = false;
441 * for the epmapper and echo interfaces we allow "connect"
442 * auth_level by default.
444 ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
445 if (ok) {
446 context_fns->allow_connect = true;
448 ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
449 if (ok) {
450 context_fns->allow_connect = true;
453 * every interface can be modified to allow "connect" auth_level by
454 * using a parametric option like:
455 * allow dcerpc auth level connect:<interface>
456 * e.g.
457 * allow dcerpc auth level connect:samr = yes
459 context_fns->allow_connect = lp_parm_bool(-1,
460 "allow dcerpc auth level connect",
461 interface_name, context_fns->allow_connect);
463 ok = ndr_syntax_id_equal(abstract, &ndr_table_iremotewinspool.syntax_id);
464 if (ok) {
465 context_fns->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
468 /* add to the list of open contexts */
470 DLIST_ADD( p->contexts, context_fns );
472 return True;
476 * Is a named pipe known?
477 * @param[in] pipename Just the filename
478 * @result Do we want to serve this?
480 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
482 NTSTATUS status;
484 if (strchr(pipename, '/')) {
485 DEBUG(1, ("Refusing open on pipe %s\n", pipename));
486 return false;
489 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
490 DEBUG(10, ("refusing spoolss access\n"));
491 return false;
494 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
495 return true;
498 status = smb_probe_module("rpc", pipename);
499 if (!NT_STATUS_IS_OK(status)) {
500 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
501 return false;
503 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
506 * Scan the list again for the interface id
508 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
509 return true;
512 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
513 pipename));
515 return false;
518 /*******************************************************************
519 Handle an NTLMSSP bind auth.
520 *******************************************************************/
522 static bool pipe_auth_generic_bind(struct pipes_struct *p,
523 struct ncacn_packet *pkt,
524 struct dcerpc_auth *auth_info,
525 const char *service_description,
526 DATA_BLOB *response)
528 TALLOC_CTX *mem_ctx = pkt;
529 struct gensec_security *gensec_security = NULL;
530 NTSTATUS status;
532 status = auth_generic_server_authtype_start(p,
533 auth_info->auth_type,
534 auth_info->auth_level,
535 p->remote_address,
536 p->local_address,
537 service_description,
538 &gensec_security);
539 if (!NT_STATUS_IS_OK(status)) {
540 DEBUG(0, (__location__ ": auth_generic_server_authtype_start[%u/%u] failed: %s\n",
541 auth_info->auth_type, auth_info->auth_level, nt_errstr(status)));
542 return false;
545 p->auth.auth_ctx = gensec_security;
546 p->auth.auth_type = auth_info->auth_type;
547 p->auth.auth_level = auth_info->auth_level;
548 p->auth.auth_context_id = auth_info->auth_context_id;
550 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
551 p->auth.client_hdr_signing = true;
552 p->auth.hdr_signing = gensec_have_feature(gensec_security,
553 GENSEC_FEATURE_SIGN_PKT_HEADER);
556 if (p->auth.hdr_signing) {
557 gensec_want_feature(gensec_security,
558 GENSEC_FEATURE_SIGN_PKT_HEADER);
561 status = auth_generic_server_step(gensec_security, mem_ctx,
562 &auth_info->credentials,
563 response);
564 if (!NT_STATUS_IS_OK(status) &&
565 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
567 DEBUG(2, (__location__ ": "
568 "auth_generic_server_step[%u/%u] failed: %s\n",
569 auth_info->auth_type, auth_info->auth_level,
570 nt_errstr(status)));
571 return false;
574 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
575 return true;
578 status = pipe_auth_verify_final(p);
579 if (!NT_STATUS_IS_OK(status)) {
580 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
581 nt_errstr(status)));
582 return false;
585 return true;
588 /*******************************************************************
589 Process an NTLMSSP authentication response.
590 If this function succeeds, the user has been authenticated
591 and their domain, name and calling workstation stored in
592 the pipe struct.
593 *******************************************************************/
595 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
596 struct gensec_security *gensec_security,
597 enum dcerpc_AuthLevel auth_level,
598 struct auth_session_info **session_info)
600 NTSTATUS status;
601 bool ret;
603 DEBUG(5, (__location__ ": checking user details\n"));
605 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
606 ensure the underlying NTLMSSP flags are also set. If not we should
607 refuse the bind. */
609 status = auth_generic_server_check_flags(gensec_security,
610 (auth_level >=
611 DCERPC_AUTH_LEVEL_PACKET),
612 (auth_level ==
613 DCERPC_AUTH_LEVEL_PRIVACY));
614 if (!NT_STATUS_IS_OK(status)) {
615 DEBUG(0, (__location__ ": Client failed to negotatie proper "
616 "security for rpc connection\n"));
617 return false;
620 TALLOC_FREE(*session_info);
622 status = auth_generic_server_get_user_info(gensec_security,
623 mem_ctx, session_info);
624 if (!NT_STATUS_IS_OK(status)) {
625 DEBUG(0, (__location__ ": failed to obtain the server info "
626 "for authenticated user: %s\n", nt_errstr(status)));
627 return false;
630 if ((*session_info)->security_token == NULL) {
631 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
632 return false;
635 if ((*session_info)->unix_token == NULL) {
636 DEBUG(1, ("Auth module failed to provide unix_token\n"));
637 return false;
641 * We're an authenticated bind over smb, so the session key needs to
642 * be set to "SystemLibraryDTC". Weird, but this is what Windows
643 * does. See the RPC-SAMBA3SESSIONKEY.
646 ret = session_info_set_session_key((*session_info), generic_session_key());
647 if (!ret) {
648 DEBUG(0, ("Failed to set session key!\n"));
649 return false;
652 return true;
655 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
657 struct gensec_security *gensec_security;
658 bool ok;
660 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
661 p->pipe_bound = true;
662 return NT_STATUS_OK;
665 gensec_security = p->auth.auth_ctx;
667 ok = pipe_auth_generic_verify_final(p, gensec_security,
668 p->auth.auth_level,
669 &p->session_info);
670 if (!ok) {
671 return NT_STATUS_ACCESS_DENIED;
674 p->pipe_bound = true;
676 return NT_STATUS_OK;
679 /*******************************************************************
680 Respond to a pipe bind request.
681 *******************************************************************/
683 static bool api_pipe_bind_req(struct pipes_struct *p,
684 struct ncacn_packet *pkt)
686 struct dcerpc_auth auth_info = {0};
687 uint16_t assoc_gid;
688 NTSTATUS status;
689 struct ndr_syntax_id id;
690 uint8_t pfc_flags = 0;
691 union dcerpc_payload u;
692 struct dcerpc_ack_ctx bind_ack_ctx;
693 DATA_BLOB auth_resp = data_blob_null;
694 DATA_BLOB auth_blob = data_blob_null;
695 const struct ndr_interface_table *table;
696 const char *secondary_address = NULL;
698 if (!p->allow_bind) {
699 DEBUG(2,("Pipe not in allow bind state\n"));
700 return setup_bind_nak(p, pkt);
702 p->allow_bind = false;
704 status = dcerpc_verify_ncacn_packet_header(pkt,
705 DCERPC_PKT_BIND,
706 pkt->u.bind.auth_info.length,
707 0, /* required flags */
708 DCERPC_PFC_FLAG_FIRST |
709 DCERPC_PFC_FLAG_LAST |
710 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
711 0x08 | /* this is not defined, but should be ignored */
712 DCERPC_PFC_FLAG_CONC_MPX |
713 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
714 DCERPC_PFC_FLAG_MAYBE |
715 DCERPC_PFC_FLAG_OBJECT_UUID);
716 if (!NT_STATUS_IS_OK(status)) {
717 DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n",
718 nt_errstr(status)));
719 NDR_PRINT_DEBUG(ncacn_packet, pkt);
720 goto err_exit;
723 if (pkt->u.bind.num_contexts == 0) {
724 DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n"));
725 goto err_exit;
728 if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) {
729 DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n"));
730 goto err_exit;
734 * Try and find the correct pipe name to ensure
735 * that this is a pipe name we support.
737 id = pkt->u.bind.ctx_list[0].abstract_syntax;
739 table = ndr_table_by_uuid(&id.uuid);
740 if (table == NULL) {
741 char *iface = ndr_syntax_id_to_string(talloc_tos(), &id);
742 DBG_NOTICE("unknown interface %s\n",
743 iface ? iface : "<null>");
744 TALLOC_FREE(iface);
745 return false;
748 if (rpc_srv_pipe_exists_by_id(&id)) {
749 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
750 rpc_srv_get_pipe_cli_name(&id),
751 rpc_srv_get_pipe_srv_name(&id)));
752 } else {
753 status = smb_probe_module(
754 "rpc", dcerpc_default_transport_endpoint(pkt,
755 NCACN_NP, table));
757 if (NT_STATUS_IS_ERR(status)) {
758 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
759 "%s in bind request.\n",
760 ndr_interface_name(&id.uuid,
761 id.if_version)));
763 return setup_bind_nak(p, pkt);
766 if (rpc_srv_get_pipe_interface_by_cli_name(
767 dcerpc_default_transport_endpoint(pkt,
768 NCACN_NP, table),
769 &id)) {
770 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
771 rpc_srv_get_pipe_cli_name(&id),
772 rpc_srv_get_pipe_srv_name(&id)));
773 } else {
774 DEBUG(0, ("module %s doesn't provide functions for "
775 "pipe %s!\n",
776 ndr_interface_name(&id.uuid,
777 id.if_version),
778 ndr_interface_name(&id.uuid,
779 id.if_version)));
780 return setup_bind_nak(p, pkt);
784 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
786 if (pkt->u.bind.assoc_group_id != 0) {
787 assoc_gid = pkt->u.bind.assoc_group_id;
788 } else {
789 assoc_gid = 0x53f0;
793 * Create the bind response struct.
796 /* If the requested abstract synt uuid doesn't match our client pipe,
797 reject the bind_ack & set the transfer interface synt to all 0's,
798 ver 0 (observed when NT5 attempts to bind to abstract interfaces
799 unknown to NT4)
800 Needed when adding entries to a DACL from NT5 - SK */
802 if (check_bind_req(p,
803 &pkt->u.bind.ctx_list[0].abstract_syntax,
804 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
805 pkt->u.bind.ctx_list[0].context_id)) {
807 bind_ack_ctx.result = 0;
808 bind_ack_ctx.reason.value = 0;
809 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
810 } else {
811 /* Rejection reason: abstract syntax not supported */
812 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
813 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
814 bind_ack_ctx.syntax = ndr_syntax_id_null;
818 * Check if this is an authenticated bind request.
820 if (pkt->auth_length) {
822 * Decode the authentication verifier.
824 status = dcerpc_pull_auth_trailer(pkt, pkt,
825 &pkt->u.bind.auth_info,
826 &auth_info, NULL, true);
827 if (!NT_STATUS_IS_OK(status)) {
828 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
829 goto err_exit;
832 if (!pipe_auth_generic_bind(p, pkt,
833 &auth_info,
834 table->name,
835 &auth_resp)) {
836 goto err_exit;
838 } else {
839 TALLOC_CTX *frame = talloc_stackframe();
840 struct auth4_context *auth4_context;
841 const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
842 if (p->transport == NCACN_NP) {
843 transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB;
846 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
847 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
848 p->auth.auth_context_id = 0;
850 become_root();
851 status = make_auth4_context(frame, &auth4_context);
852 unbecome_root();
853 if (!NT_STATUS_IS_OK(status)) {
854 DEBUG(0, ("Unable to make auth context for authz log.\n"));
855 TALLOC_FREE(frame);
856 goto err_exit;
860 * Log the authorization to this RPC interface. This
861 * covered ncacn_np pass-through auth, and anonymous
862 * DCE/RPC (eg epmapper, netlogon etc)
864 log_successful_authz_event(auth4_context->msg_ctx,
865 auth4_context->lp_ctx,
866 p->remote_address,
867 p->local_address,
868 table->name,
869 derpc_transport_string_by_transport(p->transport),
870 transport_protection,
871 p->session_info);
872 TALLOC_FREE(frame);
875 ZERO_STRUCT(u.bind_ack);
876 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
877 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
878 u.bind_ack.assoc_group_id = assoc_gid;
880 switch (p->transport) {
881 case NCACN_IP_TCP:
882 secondary_address = talloc_asprintf(pkt, "%d",
883 tsocket_address_inet_port(p->local_address));
884 break;
885 case NCACN_NP:
886 default:
887 /* name has to be \PIPE\xxxxx */
888 secondary_address =
889 talloc_asprintf(pkt, "\\PIPE\\%s",
890 rpc_srv_get_pipe_srv_name(&id));
891 break;
894 if (secondary_address == NULL) {
895 DEBUG(0, ("Out of memory!\n"));
896 goto err_exit;
899 u.bind_ack.secondary_address = secondary_address;
900 u.bind_ack.secondary_address_size =
901 strlen(u.bind_ack.secondary_address) + 1;
903 u.bind_ack.num_results = 1;
904 u.bind_ack.ctx_list = &bind_ack_ctx;
906 /* NOTE: We leave the auth_info empty so we can calculate the padding
907 * later and then append the auth_info --simo */
910 * Marshall directly into the outgoing PDU space. We
911 * must do this as we need to set to the bind response
912 * header and are never sending more than one PDU here.
915 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
917 if (p->auth.hdr_signing) {
918 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
921 status = dcerpc_push_ncacn_packet(p->mem_ctx,
922 DCERPC_PKT_BIND_ACK,
923 pfc_flags,
924 auth_resp.length,
925 pkt->call_id,
927 &p->out_data.frag);
928 if (!NT_STATUS_IS_OK(status)) {
929 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
930 nt_errstr(status)));
931 goto err_exit;
934 if (auth_resp.length) {
935 status = dcerpc_push_dcerpc_auth(pkt,
936 p->auth.auth_type,
937 p->auth.auth_level,
938 0, /* pad_len */
939 p->auth.auth_context_id,
940 &auth_resp,
941 &auth_blob);
942 if (!NT_STATUS_IS_OK(status)) {
943 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
944 goto err_exit;
948 /* Now that we have the auth len store it into the right place in
949 * the dcerpc header */
950 dcerpc_set_frag_length(&p->out_data.frag,
951 p->out_data.frag.length + auth_blob.length);
953 if (auth_blob.length) {
955 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
956 auth_blob.data, auth_blob.length)) {
957 DEBUG(0, ("Append of auth info failed.\n"));
958 goto err_exit;
963 * Setup the lengths for the initial reply.
966 p->out_data.data_sent_length = 0;
967 p->out_data.current_pdu_sent = 0;
969 TALLOC_FREE(auth_blob.data);
971 if (bind_ack_ctx.result == 0) {
972 p->allow_alter = true;
973 p->allow_auth3 = true;
974 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
975 status = pipe_auth_verify_final(p);
976 if (!NT_STATUS_IS_OK(status)) {
977 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
978 nt_errstr(status)));
979 goto err_exit;
982 } else {
983 goto err_exit;
986 return True;
988 err_exit:
990 data_blob_free(&p->out_data.frag);
991 TALLOC_FREE(auth_blob.data);
992 return setup_bind_nak(p, pkt);
995 /*******************************************************************
996 This is the "stage3" response after a bind request and reply.
997 *******************************************************************/
999 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1001 struct dcerpc_auth auth_info;
1002 DATA_BLOB response = data_blob_null;
1003 struct gensec_security *gensec_security;
1004 NTSTATUS status;
1006 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1008 if (!p->allow_auth3) {
1009 DEBUG(1, ("Pipe not in allow auth3 state.\n"));
1010 goto err;
1013 status = dcerpc_verify_ncacn_packet_header(pkt,
1014 DCERPC_PKT_AUTH3,
1015 pkt->u.auth3.auth_info.length,
1016 0, /* required flags */
1017 DCERPC_PFC_FLAG_FIRST |
1018 DCERPC_PFC_FLAG_LAST |
1019 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1020 0x08 | /* this is not defined, but should be ignored */
1021 DCERPC_PFC_FLAG_CONC_MPX |
1022 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1023 DCERPC_PFC_FLAG_MAYBE |
1024 DCERPC_PFC_FLAG_OBJECT_UUID);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n",
1027 nt_errstr(status)));
1028 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1029 goto err;
1032 /* We can only finish if the pipe is unbound for now */
1033 if (p->pipe_bound) {
1034 DEBUG(0, (__location__ ": Pipe already bound, "
1035 "AUTH3 not supported!\n"));
1036 goto err;
1039 if (pkt->auth_length == 0) {
1040 DEBUG(1, ("No auth field sent for auth3 request!\n"));
1041 goto err;
1045 * Decode the authentication verifier response.
1048 status = dcerpc_pull_auth_trailer(pkt, pkt,
1049 &pkt->u.auth3.auth_info,
1050 &auth_info, NULL, true);
1051 if (!NT_STATUS_IS_OK(status)) {
1052 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
1053 goto err;
1056 /* We must NEVER look at auth_info->auth_pad_len here,
1057 * as old Samba client code gets it wrong and sends it
1058 * as zero. JRA.
1061 if (auth_info.auth_type != p->auth.auth_type) {
1062 DEBUG(1, ("Auth type mismatch! Client sent %d, "
1063 "but auth was started as type %d!\n",
1064 auth_info.auth_type, p->auth.auth_type));
1065 goto err;
1068 if (auth_info.auth_level != p->auth.auth_level) {
1069 DEBUG(1, ("Auth level mismatch! Client sent %d, "
1070 "but auth was started as level %d!\n",
1071 auth_info.auth_level, p->auth.auth_level));
1072 goto err;
1075 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1076 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1077 "but auth was started as level %u!\n",
1078 (unsigned)auth_info.auth_context_id,
1079 (unsigned)p->auth.auth_context_id));
1080 goto err;
1083 gensec_security = p->auth.auth_ctx;
1085 status = auth_generic_server_step(gensec_security,
1086 pkt, &auth_info.credentials,
1087 &response);
1089 if (NT_STATUS_EQUAL(status,
1090 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1091 response.length) {
1092 DEBUG(1, (__location__ ": This was supposed to be the final "
1093 "leg, but crypto machinery claims a response is "
1094 "needed, aborting auth!\n"));
1095 data_blob_free(&response);
1096 goto err;
1098 if (!NT_STATUS_IS_OK(status)) {
1099 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
1100 goto err;
1103 /* Now verify auth was indeed successful and extract server info */
1104 status = pipe_auth_verify_final(p);
1105 if (!NT_STATUS_IS_OK(status)) {
1106 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1107 goto err;
1110 return true;
1112 err:
1113 p->pipe_bound = false;
1114 p->allow_bind = false;
1115 p->allow_alter = false;
1116 p->allow_auth3 = false;
1118 TALLOC_FREE(p->auth.auth_ctx);
1119 return false;
1122 /****************************************************************************
1123 Deal with an alter context call. Can be third part of 3 leg auth request for
1124 SPNEGO calls.
1125 ****************************************************************************/
1127 static bool api_pipe_alter_context(struct pipes_struct *p,
1128 struct ncacn_packet *pkt)
1130 struct dcerpc_auth auth_info = {0};
1131 uint16_t assoc_gid;
1132 NTSTATUS status;
1133 union dcerpc_payload u;
1134 struct dcerpc_ack_ctx alter_ack_ctx;
1135 DATA_BLOB auth_resp = data_blob_null;
1136 DATA_BLOB auth_blob = data_blob_null;
1137 struct gensec_security *gensec_security;
1139 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1141 if (!p->allow_alter) {
1142 DEBUG(1, ("Pipe not in allow alter state.\n"));
1143 goto err_exit;
1146 status = dcerpc_verify_ncacn_packet_header(pkt,
1147 DCERPC_PKT_ALTER,
1148 pkt->u.alter.auth_info.length,
1149 0, /* required flags */
1150 DCERPC_PFC_FLAG_FIRST |
1151 DCERPC_PFC_FLAG_LAST |
1152 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1153 0x08 | /* this is not defined, but should be ignored */
1154 DCERPC_PFC_FLAG_CONC_MPX |
1155 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1156 DCERPC_PFC_FLAG_MAYBE |
1157 DCERPC_PFC_FLAG_OBJECT_UUID);
1158 if (!NT_STATUS_IS_OK(status)) {
1159 DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n",
1160 nt_errstr(status)));
1161 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1162 goto err_exit;
1165 if (pkt->u.alter.num_contexts == 0) {
1166 DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n"));
1167 goto err_exit;
1170 if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) {
1171 DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n"));
1172 goto err_exit;
1175 if (pkt->u.alter.assoc_group_id != 0) {
1176 assoc_gid = pkt->u.alter.assoc_group_id;
1177 } else {
1178 assoc_gid = 0x53f0;
1182 * Create the bind response struct.
1185 /* If the requested abstract synt uuid doesn't match our client pipe,
1186 reject the alter_ack & set the transfer interface synt to all 0's,
1187 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1188 unknown to NT4)
1189 Needed when adding entries to a DACL from NT5 - SK */
1191 if (check_bind_req(p,
1192 &pkt->u.alter.ctx_list[0].abstract_syntax,
1193 &pkt->u.alter.ctx_list[0].transfer_syntaxes[0],
1194 pkt->u.alter.ctx_list[0].context_id)) {
1196 alter_ack_ctx.result = 0;
1197 alter_ack_ctx.reason.value = 0;
1198 alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0];
1199 } else {
1200 /* Rejection reason: abstract syntax not supported */
1201 alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1202 alter_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
1203 alter_ack_ctx.syntax = ndr_syntax_id_null;
1207 * Check if this is an authenticated alter context request.
1209 if (pkt->auth_length) {
1210 /* We can only finish if the pipe is unbound for now */
1211 if (p->pipe_bound) {
1212 DEBUG(0, (__location__ ": Pipe already bound, "
1213 "Altering Context not yet supported!\n"));
1214 goto err_exit;
1217 status = dcerpc_pull_auth_trailer(pkt, pkt,
1218 &pkt->u.alter.auth_info,
1219 &auth_info, NULL, true);
1220 if (!NT_STATUS_IS_OK(status)) {
1221 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1222 goto err_exit;
1225 if (auth_info.auth_type != p->auth.auth_type) {
1226 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1227 "but auth was started as type %d!\n",
1228 auth_info.auth_type, p->auth.auth_type));
1229 goto err_exit;
1232 if (auth_info.auth_level != p->auth.auth_level) {
1233 DEBUG(0, ("Auth level mismatch! Client sent %d, "
1234 "but auth was started as level %d!\n",
1235 auth_info.auth_level, p->auth.auth_level));
1236 goto err_exit;
1239 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1240 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1241 "but auth was started as level %u!\n",
1242 (unsigned)auth_info.auth_context_id,
1243 (unsigned)p->auth.auth_context_id));
1244 goto err_exit;
1247 gensec_security = p->auth.auth_ctx;
1248 status = auth_generic_server_step(gensec_security,
1249 pkt,
1250 &auth_info.credentials,
1251 &auth_resp);
1252 if (NT_STATUS_IS_OK(status)) {
1253 /* third leg of auth, verify auth info */
1254 status = pipe_auth_verify_final(p);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 DEBUG(0, ("Auth Verify failed (%s)\n",
1257 nt_errstr(status)));
1258 goto err_exit;
1260 } else if (NT_STATUS_EQUAL(status,
1261 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1262 DEBUG(10, ("More auth legs required.\n"));
1263 } else {
1264 DEBUG(0, ("Auth step returned an error (%s)\n",
1265 nt_errstr(status)));
1266 goto err_exit;
1270 ZERO_STRUCT(u.alter_resp);
1271 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1272 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1273 u.alter_resp.assoc_group_id = assoc_gid;
1275 /* secondary address CAN be NULL
1276 * as the specs say it's ignored.
1277 * It MUST be NULL to have the spoolss working.
1279 u.alter_resp.secondary_address = "";
1280 u.alter_resp.secondary_address_size = 1;
1282 u.alter_resp.num_results = 1;
1283 u.alter_resp.ctx_list = &alter_ack_ctx;
1285 /* NOTE: We leave the auth_info empty so we can calculate the padding
1286 * later and then append the auth_info --simo */
1289 * Marshall directly into the outgoing PDU space. We
1290 * must do this as we need to set to the bind response
1291 * header and are never sending more than one PDU here.
1294 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1295 DCERPC_PKT_ALTER_RESP,
1296 DCERPC_PFC_FLAG_FIRST |
1297 DCERPC_PFC_FLAG_LAST,
1298 auth_resp.length,
1299 pkt->call_id,
1301 &p->out_data.frag);
1302 if (!NT_STATUS_IS_OK(status)) {
1303 DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n",
1304 nt_errstr(status)));
1305 goto err_exit;
1308 if (auth_resp.length) {
1309 status = dcerpc_push_dcerpc_auth(pkt,
1310 p->auth.auth_type,
1311 p->auth.auth_level,
1312 0, /* pad_len */
1313 p->auth.auth_context_id,
1314 &auth_resp,
1315 &auth_blob);
1316 if (!NT_STATUS_IS_OK(status)) {
1317 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1318 goto err_exit;
1322 /* Now that we have the auth len store it into the right place in
1323 * the dcerpc header */
1324 dcerpc_set_frag_length(&p->out_data.frag,
1325 p->out_data.frag.length +
1326 auth_blob.length);
1328 if (auth_resp.length) {
1329 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1330 auth_blob.data, auth_blob.length)) {
1331 DEBUG(0, ("Append of auth info failed.\n"));
1332 goto err_exit;
1337 * Setup the lengths for the initial reply.
1340 p->out_data.data_sent_length = 0;
1341 p->out_data.current_pdu_sent = 0;
1343 TALLOC_FREE(auth_blob.data);
1344 return True;
1346 err_exit:
1348 data_blob_free(&p->out_data.frag);
1349 TALLOC_FREE(auth_blob.data);
1350 return setup_bind_nak(p, pkt);
1353 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1354 const struct api_struct *api_rpc_cmds, int n_cmds,
1355 const struct ndr_syntax_id *syntax);
1357 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1358 struct ncacn_packet *pkt,
1359 struct pipe_rpc_fns *pipe_fns)
1361 TALLOC_CTX *frame = talloc_stackframe();
1362 struct dcerpc_sec_verification_trailer *vt = NULL;
1363 const uint32_t bitmask1 =
1364 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1365 const struct dcerpc_sec_vt_pcontext pcontext = {
1366 .abstract_syntax = pipe_fns->syntax,
1367 .transfer_syntax = ndr_transfer_syntax_ndr,
1369 const struct dcerpc_sec_vt_header2 header2 =
1370 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1371 struct ndr_pull *ndr;
1372 enum ndr_err_code ndr_err;
1373 bool ret = false;
1375 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1376 if (ndr == NULL) {
1377 goto done;
1380 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1381 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1382 goto done;
1385 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1386 &pcontext, &header2);
1387 done:
1388 TALLOC_FREE(frame);
1389 return ret;
1392 /****************************************************************************
1393 Find the correct RPC function to call for this request.
1394 If the pipe is authenticated then become the correct UNIX user
1395 before doing the call.
1396 ****************************************************************************/
1398 static bool api_pipe_request(struct pipes_struct *p,
1399 struct ncacn_packet *pkt)
1401 TALLOC_CTX *frame = talloc_stackframe();
1402 bool ret = False;
1403 struct pipe_rpc_fns *pipe_fns;
1404 const char *interface_name = NULL;
1406 if (!p->pipe_bound) {
1407 DEBUG(1, ("Pipe not bound!\n"));
1408 data_blob_free(&p->out_data.rdata);
1409 TALLOC_FREE(frame);
1410 return false;
1413 /* get the set of RPC functions for this context */
1414 pipe_fns = find_pipe_fns_by_context(p->contexts,
1415 pkt->u.request.context_id);
1416 if (pipe_fns == NULL) {
1417 DEBUG(0, ("No rpc function table associated with context "
1418 "[%d]\n",
1419 pkt->u.request.context_id));
1420 data_blob_free(&p->out_data.rdata);
1421 TALLOC_FREE(frame);
1422 return false;
1425 interface_name = ndr_interface_name(&pipe_fns->syntax.uuid,
1426 pipe_fns->syntax.if_version);
1427 SMB_ASSERT(interface_name != NULL);
1429 if (p->auth.auth_level < pipe_fns->min_auth_level) {
1431 DEBUG(1, ("%s: auth level required for %s: 0x%x, got: 0x%0x\n",
1432 __func__, interface_name,
1433 pipe_fns->min_auth_level,
1434 p->auth.auth_level));
1436 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1437 TALLOC_FREE(frame);
1438 return true;
1441 switch (p->auth.auth_level) {
1442 case DCERPC_AUTH_LEVEL_NONE:
1443 case DCERPC_AUTH_LEVEL_PACKET:
1444 case DCERPC_AUTH_LEVEL_INTEGRITY:
1445 case DCERPC_AUTH_LEVEL_PRIVACY:
1446 break;
1447 default:
1448 if (!pipe_fns->allow_connect) {
1449 char *addr;
1451 addr = tsocket_address_string(p->remote_address, frame);
1453 DEBUG(1, ("%s: restrict auth_level_connect access "
1454 "to [%s] with auth[type=0x%x,level=0x%x] "
1455 "on [%s] from [%s]\n",
1456 __func__, interface_name,
1457 p->auth.auth_type,
1458 p->auth.auth_level,
1459 derpc_transport_string_by_transport(p->transport),
1460 addr));
1462 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1463 TALLOC_FREE(frame);
1464 return true;
1466 break;
1469 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1470 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1471 set_incoming_fault(p);
1472 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1473 data_blob_free(&p->out_data.rdata);
1474 TALLOC_FREE(frame);
1475 return true;
1478 if (!become_authenticated_pipe_user(p->session_info)) {
1479 DEBUG(1, ("Failed to become pipe user!\n"));
1480 data_blob_free(&p->out_data.rdata);
1481 TALLOC_FREE(frame);
1482 return false;
1485 DEBUG(5, ("Requested %s rpc service\n", interface_name));
1487 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1488 &pipe_fns->syntax);
1489 unbecome_authenticated_pipe_user();
1491 TALLOC_FREE(frame);
1492 return ret;
1495 /*******************************************************************
1496 Calls the underlying RPC function for a named pipe.
1497 ********************************************************************/
1499 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1500 const struct api_struct *api_rpc_cmds, int n_cmds,
1501 const struct ndr_syntax_id *syntax)
1503 int fn_num;
1504 uint32_t offset1;
1505 const struct ndr_interface_table *table;
1507 /* interpret the command */
1508 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1509 ndr_interface_name(&syntax->uuid, syntax->if_version),
1510 pkt->u.request.opnum));
1512 table = ndr_table_by_uuid(&syntax->uuid);
1513 if (table == NULL) {
1514 DEBUG(0,("unknown interface\n"));
1515 return false;
1518 if (DEBUGLEVEL >= 50) {
1519 fstring name;
1520 slprintf(name, sizeof(name)-1, "in_%s",
1521 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1522 dump_pdu_region(name, pkt->u.request.opnum,
1523 &p->in_data.data, 0,
1524 p->in_data.data.length);
1527 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1528 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1529 api_rpc_cmds[fn_num].fn != NULL) {
1530 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1531 api_rpc_cmds[fn_num].name));
1532 break;
1536 if (fn_num == n_cmds) {
1538 * For an unknown RPC just return a fault PDU but
1539 * return True to allow RPC's on the pipe to continue
1540 * and not put the pipe into fault state. JRA.
1542 DEBUG(4, ("unknown\n"));
1543 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1544 return True;
1547 offset1 = p->out_data.rdata.length;
1549 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1550 fn_num, api_rpc_cmds[fn_num].fn));
1551 /* do the actual command */
1552 if(!api_rpc_cmds[fn_num].fn(p)) {
1553 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1554 ndr_interface_name(&syntax->uuid, syntax->if_version),
1555 api_rpc_cmds[fn_num].name));
1556 data_blob_free(&p->out_data.rdata);
1557 return False;
1560 if (p->fault_state) {
1561 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1562 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1563 p->fault_state = 0;
1564 return true;
1567 if (DEBUGLEVEL >= 50) {
1568 fstring name;
1569 slprintf(name, sizeof(name)-1, "out_%s",
1570 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1571 dump_pdu_region(name, pkt->u.request.opnum,
1572 &p->out_data.rdata, offset1,
1573 p->out_data.rdata.length);
1576 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1577 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1579 /* Check for buffer underflow in rpc parsing */
1580 if ((DEBUGLEVEL >= 10) &&
1581 (pkt->frag_length < p->in_data.data.length)) {
1582 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1583 dump_data(10, p->in_data.data.data + pkt->frag_length,
1584 p->in_data.data.length - pkt->frag_length);
1587 return True;
1590 /****************************************************************************
1591 Initialise an outgoing packet.
1592 ****************************************************************************/
1594 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1596 output_data *o_data = &p->out_data;
1598 /* Reset the offset counters. */
1599 o_data->data_sent_length = 0;
1600 o_data->current_pdu_sent = 0;
1602 data_blob_free(&o_data->frag);
1604 /* Free any memory in the current return data buffer. */
1605 data_blob_free(&o_data->rdata);
1607 return True;
1610 /****************************************************************************
1611 Sets the fault state on incoming packets.
1612 ****************************************************************************/
1614 void set_incoming_fault(struct pipes_struct *p)
1616 data_blob_free(&p->in_data.data);
1617 p->in_data.pdu_needed_len = 0;
1618 p->in_data.pdu.length = 0;
1619 p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
1621 p->allow_alter = false;
1622 p->allow_auth3 = false;
1623 p->pipe_bound = false;
1625 DEBUG(10, ("Setting fault state\n"));
1628 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1629 struct ncacn_packet *pkt,
1630 DATA_BLOB *raw_pkt)
1632 NTSTATUS status;
1633 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1635 DEBUG(10, ("Checking request auth.\n"));
1637 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1638 hdr_size += 16;
1641 /* in case of sealing this function will unseal the data in place */
1642 status = dcerpc_check_auth(auth, pkt,
1643 &pkt->u.request.stub_and_verifier,
1644 hdr_size, raw_pkt);
1645 if (!NT_STATUS_IS_OK(status)) {
1646 return status;
1649 return NT_STATUS_OK;
1652 /****************************************************************************
1653 Processes a request pdu. This will do auth processing if needed, and
1654 appends the data into the complete stream if the LAST flag is not set.
1655 ****************************************************************************/
1657 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1659 NTSTATUS status;
1660 DATA_BLOB data;
1661 struct dcerpc_sec_vt_header2 hdr2;
1663 if (!p->pipe_bound) {
1664 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1665 set_incoming_fault(p);
1666 return False;
1670 * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL.
1671 * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later.
1673 status = dcerpc_verify_ncacn_packet_header(pkt,
1674 DCERPC_PKT_REQUEST,
1675 pkt->u.request.stub_and_verifier.length,
1676 0, /* required_flags */
1677 DCERPC_PFC_FLAG_FIRST |
1678 DCERPC_PFC_FLAG_LAST |
1679 0x08 | /* this is not defined, but should be ignored */
1680 DCERPC_PFC_FLAG_CONC_MPX |
1681 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1682 DCERPC_PFC_FLAG_MAYBE |
1683 DCERPC_PFC_FLAG_OBJECT_UUID);
1684 if (!NT_STATUS_IS_OK(status)) {
1685 DEBUG(1, ("process_request_pdu: invalid pdu: %s\n",
1686 nt_errstr(status)));
1687 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1688 set_incoming_fault(p);
1689 return false;
1692 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1693 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1694 p->header2 = hdr2;
1695 } else {
1696 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1697 set_incoming_fault(p);
1698 return false;
1702 /* Store the opnum */
1703 p->opnum = pkt->u.request.opnum;
1705 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1708 nt_errstr(status)));
1709 set_incoming_fault(p);
1710 return false;
1713 data = pkt->u.request.stub_and_verifier;
1716 * Check the data length doesn't go over the 15Mb limit.
1717 * increased after observing a bug in the Windows NT 4.0 SP6a
1718 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1719 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1722 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1723 DEBUG(0, ("process_request_pdu: "
1724 "rpc data buffer too large (%u) + (%u)\n",
1725 (unsigned int)p->in_data.data.length,
1726 (unsigned int)data.length));
1727 set_incoming_fault(p);
1728 return False;
1732 * Append the data portion into the buffer and return.
1735 if (data.length) {
1736 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1737 data.data, data.length)) {
1738 DEBUG(0, ("Unable to append data size %u "
1739 "to parse buffer of size %u.\n",
1740 (unsigned int)data.length,
1741 (unsigned int)p->in_data.data.length));
1742 set_incoming_fault(p);
1743 return False;
1747 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1748 return true;
1752 * Ok - we finally have a complete RPC stream.
1753 * Call the rpc command to process it.
1756 return api_pipe_request(p, pkt);
1759 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1761 bool reply = false;
1763 /* Store the call_id */
1764 p->call_id = pkt->call_id;
1766 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1768 if (!pipe_init_outgoing_data(p)) {
1769 goto done;
1772 switch (pkt->ptype) {
1773 case DCERPC_PKT_REQUEST:
1774 reply = process_request_pdu(p, pkt);
1775 break;
1777 case DCERPC_PKT_PING: /* CL request - ignore... */
1778 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1779 (unsigned int)pkt->ptype));
1780 break;
1782 case DCERPC_PKT_RESPONSE: /* No responses here. */
1783 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1784 break;
1786 case DCERPC_PKT_FAULT:
1787 case DCERPC_PKT_WORKING:
1788 /* CL request - reply to a ping when a call in process. */
1789 case DCERPC_PKT_NOCALL:
1790 /* CL - server reply to a ping call. */
1791 case DCERPC_PKT_REJECT:
1792 case DCERPC_PKT_ACK:
1793 case DCERPC_PKT_CL_CANCEL:
1794 case DCERPC_PKT_FACK:
1795 case DCERPC_PKT_CANCEL_ACK:
1796 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1797 (unsigned int)pkt->ptype));
1798 break;
1800 case DCERPC_PKT_BIND:
1802 * We assume that a pipe bind is only in one pdu.
1804 reply = api_pipe_bind_req(p, pkt);
1805 break;
1807 case DCERPC_PKT_BIND_ACK:
1808 case DCERPC_PKT_BIND_NAK:
1809 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1810 "packet type %u received.\n",
1811 (unsigned int)pkt->ptype));
1812 break;
1815 case DCERPC_PKT_ALTER:
1817 * We assume that a pipe bind is only in one pdu.
1819 reply = api_pipe_alter_context(p, pkt);
1820 break;
1822 case DCERPC_PKT_ALTER_RESP:
1823 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1824 "Should only be server -> client.\n"));
1825 break;
1827 case DCERPC_PKT_AUTH3:
1829 * The third packet in an auth exchange.
1831 reply = api_pipe_bind_auth3(p, pkt);
1832 break;
1834 case DCERPC_PKT_SHUTDOWN:
1835 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1836 "Should only be server -> client.\n"));
1837 break;
1839 case DCERPC_PKT_CO_CANCEL:
1840 /* For now just free all client data and continue
1841 * processing. */
1842 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1843 " Abandoning rpc call.\n"));
1844 /* As we never do asynchronous RPC serving, we can
1845 * never cancel a call (as far as I know).
1846 * If we ever did we'd have to send a cancel_ack reply.
1847 * For now, just free all client data and continue
1848 * processing. */
1849 reply = True;
1850 break;
1852 #if 0
1853 /* Enable this if we're doing async rpc. */
1854 /* We must check the outstanding callid matches. */
1855 if (pipe_init_outgoing_data(p)) {
1856 /* Send a cancel_ack PDU reply. */
1857 /* We should probably check the auth-verifier here. */
1858 reply = setup_cancel_ack_reply(p, pkt);
1860 break;
1861 #endif
1863 case DCERPC_PKT_ORPHANED:
1864 /* We should probably check the auth-verifier here.
1865 * For now just free all client data and continue
1866 * processing. */
1867 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1868 " Abandoning rpc call.\n"));
1869 reply = True;
1870 break;
1872 default:
1873 DEBUG(0, ("process_complete_pdu: "
1874 "Unknown rpc type = %u received.\n",
1875 (unsigned int)pkt->ptype));
1876 break;
1879 done:
1880 if (!reply) {
1881 DEBUG(3,("DCE/RPC fault sent!"));
1882 set_incoming_fault(p);
1883 setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR));
1885 /* pkt and p->in_data.pdu.data freed by caller */