s3:rpc_server: move gensec_update() out of auth_generic_server_authtype_start*()
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob39f5fb49ec3c0e011a5c6ad4b7ac60bcf49af05a
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 (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
485 DEBUG(10, ("refusing spoolss access\n"));
486 return false;
489 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
490 return true;
493 status = smb_probe_module("rpc", pipename);
494 if (!NT_STATUS_IS_OK(status)) {
495 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
496 return false;
498 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
501 * Scan the list again for the interface id
503 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
504 return true;
507 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
508 pipename));
510 return false;
513 /*******************************************************************
514 Handle an NTLMSSP bind auth.
515 *******************************************************************/
517 static bool pipe_auth_generic_bind(struct pipes_struct *p,
518 struct ncacn_packet *pkt,
519 struct dcerpc_auth *auth_info,
520 const char *service_description,
521 DATA_BLOB *response)
523 TALLOC_CTX *mem_ctx = pkt;
524 struct gensec_security *gensec_security = NULL;
525 NTSTATUS status;
527 status = auth_generic_server_authtype_start(p,
528 auth_info->auth_type,
529 auth_info->auth_level,
530 p->remote_address,
531 p->local_address,
532 service_description,
533 &gensec_security);
534 if (!NT_STATUS_IS_OK(status)) {
535 DEBUG(0, (__location__ ": auth_generic_server_authtype_start[%u/%u] failed: %s\n",
536 auth_info->auth_type, auth_info->auth_level, nt_errstr(status)));
537 return false;
540 p->auth.auth_ctx = gensec_security;
541 p->auth.auth_type = auth_info->auth_type;
542 p->auth.auth_level = auth_info->auth_level;
543 p->auth.auth_context_id = auth_info->auth_context_id;
545 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
546 p->auth.client_hdr_signing = true;
547 p->auth.hdr_signing = gensec_have_feature(gensec_security,
548 GENSEC_FEATURE_SIGN_PKT_HEADER);
551 if (p->auth.hdr_signing) {
552 gensec_want_feature(gensec_security,
553 GENSEC_FEATURE_SIGN_PKT_HEADER);
556 status = auth_generic_server_step(gensec_security, mem_ctx,
557 &auth_info->credentials,
558 response);
559 if (!NT_STATUS_IS_OK(status) &&
560 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
562 DEBUG(2, (__location__ ": "
563 "auth_generic_server_step[%u/%u] failed: %s\n",
564 auth_info->auth_type, auth_info->auth_level,
565 nt_errstr(status)));
566 return false;
569 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
570 return true;
573 status = pipe_auth_verify_final(p);
574 if (!NT_STATUS_IS_OK(status)) {
575 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
576 nt_errstr(status)));
577 return false;
580 return true;
583 /*******************************************************************
584 Process an NTLMSSP authentication response.
585 If this function succeeds, the user has been authenticated
586 and their domain, name and calling workstation stored in
587 the pipe struct.
588 *******************************************************************/
590 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
591 struct gensec_security *gensec_security,
592 enum dcerpc_AuthLevel auth_level,
593 struct auth_session_info **session_info)
595 NTSTATUS status;
596 bool ret;
598 DEBUG(5, (__location__ ": checking user details\n"));
600 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
601 ensure the underlying NTLMSSP flags are also set. If not we should
602 refuse the bind. */
604 status = auth_generic_server_check_flags(gensec_security,
605 (auth_level >=
606 DCERPC_AUTH_LEVEL_PACKET),
607 (auth_level ==
608 DCERPC_AUTH_LEVEL_PRIVACY));
609 if (!NT_STATUS_IS_OK(status)) {
610 DEBUG(0, (__location__ ": Client failed to negotatie proper "
611 "security for rpc connection\n"));
612 return false;
615 TALLOC_FREE(*session_info);
617 status = auth_generic_server_get_user_info(gensec_security,
618 mem_ctx, session_info);
619 if (!NT_STATUS_IS_OK(status)) {
620 DEBUG(0, (__location__ ": failed to obtain the server info "
621 "for authenticated user: %s\n", nt_errstr(status)));
622 return false;
625 if ((*session_info)->security_token == NULL) {
626 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
627 return false;
630 if ((*session_info)->unix_token == NULL) {
631 DEBUG(1, ("Auth module failed to provide unix_token\n"));
632 return false;
636 * We're an authenticated bind over smb, so the session key needs to
637 * be set to "SystemLibraryDTC". Weird, but this is what Windows
638 * does. See the RPC-SAMBA3SESSIONKEY.
641 ret = session_info_set_session_key((*session_info), generic_session_key());
642 if (!ret) {
643 DEBUG(0, ("Failed to set session key!\n"));
644 return false;
647 return true;
650 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
652 struct gensec_security *gensec_security;
653 bool ok;
655 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
656 p->pipe_bound = true;
657 return NT_STATUS_OK;
660 gensec_security = p->auth.auth_ctx;
662 ok = pipe_auth_generic_verify_final(p, gensec_security,
663 p->auth.auth_level,
664 &p->session_info);
665 if (!ok) {
666 return NT_STATUS_ACCESS_DENIED;
669 p->pipe_bound = true;
671 return NT_STATUS_OK;
674 /*******************************************************************
675 Respond to a pipe bind request.
676 *******************************************************************/
678 static bool api_pipe_bind_req(struct pipes_struct *p,
679 struct ncacn_packet *pkt)
681 struct dcerpc_auth auth_info = {0};
682 uint16_t assoc_gid;
683 NTSTATUS status;
684 struct ndr_syntax_id id;
685 uint8_t pfc_flags = 0;
686 union dcerpc_payload u;
687 struct dcerpc_ack_ctx bind_ack_ctx;
688 DATA_BLOB auth_resp = data_blob_null;
689 DATA_BLOB auth_blob = data_blob_null;
690 const struct ndr_interface_table *table;
691 const char *secondary_address = NULL;
693 if (!p->allow_bind) {
694 DEBUG(2,("Pipe not in allow bind state\n"));
695 return setup_bind_nak(p, pkt);
697 p->allow_bind = false;
699 status = dcerpc_verify_ncacn_packet_header(pkt,
700 DCERPC_PKT_BIND,
701 pkt->u.bind.auth_info.length,
702 0, /* required flags */
703 DCERPC_PFC_FLAG_FIRST |
704 DCERPC_PFC_FLAG_LAST |
705 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
706 0x08 | /* this is not defined, but should be ignored */
707 DCERPC_PFC_FLAG_CONC_MPX |
708 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
709 DCERPC_PFC_FLAG_MAYBE |
710 DCERPC_PFC_FLAG_OBJECT_UUID);
711 if (!NT_STATUS_IS_OK(status)) {
712 DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n",
713 nt_errstr(status)));
714 NDR_PRINT_DEBUG(ncacn_packet, pkt);
715 goto err_exit;
718 if (pkt->u.bind.num_contexts == 0) {
719 DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n"));
720 goto err_exit;
723 if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) {
724 DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n"));
725 goto err_exit;
729 * Try and find the correct pipe name to ensure
730 * that this is a pipe name we support.
732 id = pkt->u.bind.ctx_list[0].abstract_syntax;
734 table = ndr_table_by_uuid(&id.uuid);
735 if (table == NULL) {
736 DEBUG(0,("unknown interface\n"));
737 return false;
740 if (rpc_srv_pipe_exists_by_id(&id)) {
741 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
742 rpc_srv_get_pipe_cli_name(&id),
743 rpc_srv_get_pipe_srv_name(&id)));
744 } else {
745 status = smb_probe_module(
746 "rpc", dcerpc_default_transport_endpoint(pkt,
747 NCACN_NP, table));
749 if (NT_STATUS_IS_ERR(status)) {
750 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
751 "%s in bind request.\n",
752 ndr_interface_name(&id.uuid,
753 id.if_version)));
755 return setup_bind_nak(p, pkt);
758 if (rpc_srv_get_pipe_interface_by_cli_name(
759 dcerpc_default_transport_endpoint(pkt,
760 NCACN_NP, table),
761 &id)) {
762 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
763 rpc_srv_get_pipe_cli_name(&id),
764 rpc_srv_get_pipe_srv_name(&id)));
765 } else {
766 DEBUG(0, ("module %s doesn't provide functions for "
767 "pipe %s!\n",
768 ndr_interface_name(&id.uuid,
769 id.if_version),
770 ndr_interface_name(&id.uuid,
771 id.if_version)));
772 return setup_bind_nak(p, pkt);
776 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
778 if (pkt->u.bind.assoc_group_id != 0) {
779 assoc_gid = pkt->u.bind.assoc_group_id;
780 } else {
781 assoc_gid = 0x53f0;
785 * Create the bind response struct.
788 /* If the requested abstract synt uuid doesn't match our client pipe,
789 reject the bind_ack & set the transfer interface synt to all 0's,
790 ver 0 (observed when NT5 attempts to bind to abstract interfaces
791 unknown to NT4)
792 Needed when adding entries to a DACL from NT5 - SK */
794 if (check_bind_req(p,
795 &pkt->u.bind.ctx_list[0].abstract_syntax,
796 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
797 pkt->u.bind.ctx_list[0].context_id)) {
799 bind_ack_ctx.result = 0;
800 bind_ack_ctx.reason.value = 0;
801 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
802 } else {
803 /* Rejection reason: abstract syntax not supported */
804 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
805 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
806 bind_ack_ctx.syntax = ndr_syntax_id_null;
810 * Check if this is an authenticated bind request.
812 if (pkt->auth_length) {
814 * Decode the authentication verifier.
816 status = dcerpc_pull_auth_trailer(pkt, pkt,
817 &pkt->u.bind.auth_info,
818 &auth_info, NULL, true);
819 if (!NT_STATUS_IS_OK(status)) {
820 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
821 goto err_exit;
824 if (!pipe_auth_generic_bind(p, pkt,
825 &auth_info,
826 table->name,
827 &auth_resp)) {
828 goto err_exit;
830 } else {
831 TALLOC_CTX *frame = talloc_stackframe();
832 struct auth4_context *auth4_context;
833 const char *transport_protection = AUTHZ_TRANSPORT_PROTECTION_NONE;
834 if (p->transport == NCACN_NP) {
835 transport_protection = AUTHZ_TRANSPORT_PROTECTION_SMB;
838 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
839 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
840 p->auth.auth_context_id = 0;
842 status = make_auth4_context(frame, &auth4_context);
843 if (!NT_STATUS_IS_OK(status)) {
844 DEBUG(0, ("Unable to make auth context for authz log.\n"));
845 TALLOC_FREE(frame);
846 goto err_exit;
850 * Log the authorization to this RPC interface. This
851 * covered ncacn_np pass-through auth, and anonymous
852 * DCE/RPC (eg epmapper, netlogon etc)
854 log_successful_authz_event(auth4_context->msg_ctx,
855 auth4_context->lp_ctx,
856 p->remote_address,
857 p->local_address,
858 table->name,
859 derpc_transport_string_by_transport(p->transport),
860 transport_protection,
861 p->session_info);
862 TALLOC_FREE(frame);
865 ZERO_STRUCT(u.bind_ack);
866 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
867 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
868 u.bind_ack.assoc_group_id = assoc_gid;
870 switch (p->transport) {
871 case NCACN_IP_TCP:
872 secondary_address = talloc_asprintf(pkt, "%d",
873 tsocket_address_inet_port(p->local_address));
874 break;
875 case NCACN_NP:
876 default:
877 /* name has to be \PIPE\xxxxx */
878 secondary_address =
879 talloc_asprintf(pkt, "\\PIPE\\%s",
880 rpc_srv_get_pipe_srv_name(&id));
881 break;
884 if (secondary_address == NULL) {
885 DEBUG(0, ("Out of memory!\n"));
886 goto err_exit;
889 u.bind_ack.secondary_address = secondary_address;
890 u.bind_ack.secondary_address_size =
891 strlen(u.bind_ack.secondary_address) + 1;
893 u.bind_ack.num_results = 1;
894 u.bind_ack.ctx_list = &bind_ack_ctx;
896 /* NOTE: We leave the auth_info empty so we can calculate the padding
897 * later and then append the auth_info --simo */
900 * Marshall directly into the outgoing PDU space. We
901 * must do this as we need to set to the bind response
902 * header and are never sending more than one PDU here.
905 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
907 if (p->auth.hdr_signing) {
908 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
911 status = dcerpc_push_ncacn_packet(p->mem_ctx,
912 DCERPC_PKT_BIND_ACK,
913 pfc_flags,
914 auth_resp.length,
915 pkt->call_id,
917 &p->out_data.frag);
918 if (!NT_STATUS_IS_OK(status)) {
919 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
920 nt_errstr(status)));
921 goto err_exit;
924 if (auth_resp.length) {
925 status = dcerpc_push_dcerpc_auth(pkt,
926 p->auth.auth_type,
927 p->auth.auth_level,
928 0, /* pad_len */
929 p->auth.auth_context_id,
930 &auth_resp,
931 &auth_blob);
932 if (!NT_STATUS_IS_OK(status)) {
933 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
934 goto err_exit;
938 /* Now that we have the auth len store it into the right place in
939 * the dcerpc header */
940 dcerpc_set_frag_length(&p->out_data.frag,
941 p->out_data.frag.length + auth_blob.length);
943 if (auth_blob.length) {
945 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
946 auth_blob.data, auth_blob.length)) {
947 DEBUG(0, ("Append of auth info failed.\n"));
948 goto err_exit;
953 * Setup the lengths for the initial reply.
956 p->out_data.data_sent_length = 0;
957 p->out_data.current_pdu_sent = 0;
959 TALLOC_FREE(auth_blob.data);
961 if (bind_ack_ctx.result == 0) {
962 p->allow_alter = true;
963 p->allow_auth3 = true;
964 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
965 status = pipe_auth_verify_final(p);
966 if (!NT_STATUS_IS_OK(status)) {
967 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
968 nt_errstr(status)));
969 goto err_exit;
972 } else {
973 goto err_exit;
976 return True;
978 err_exit:
980 data_blob_free(&p->out_data.frag);
981 TALLOC_FREE(auth_blob.data);
982 return setup_bind_nak(p, pkt);
985 /*******************************************************************
986 This is the "stage3" response after a bind request and reply.
987 *******************************************************************/
989 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
991 struct dcerpc_auth auth_info;
992 DATA_BLOB response = data_blob_null;
993 struct gensec_security *gensec_security;
994 NTSTATUS status;
996 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
998 if (!p->allow_auth3) {
999 DEBUG(1, ("Pipe not in allow auth3 state.\n"));
1000 goto err;
1003 status = dcerpc_verify_ncacn_packet_header(pkt,
1004 DCERPC_PKT_AUTH3,
1005 pkt->u.auth3.auth_info.length,
1006 0, /* required flags */
1007 DCERPC_PFC_FLAG_FIRST |
1008 DCERPC_PFC_FLAG_LAST |
1009 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1010 0x08 | /* this is not defined, but should be ignored */
1011 DCERPC_PFC_FLAG_CONC_MPX |
1012 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1013 DCERPC_PFC_FLAG_MAYBE |
1014 DCERPC_PFC_FLAG_OBJECT_UUID);
1015 if (!NT_STATUS_IS_OK(status)) {
1016 DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n",
1017 nt_errstr(status)));
1018 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1019 goto err;
1022 /* We can only finish if the pipe is unbound for now */
1023 if (p->pipe_bound) {
1024 DEBUG(0, (__location__ ": Pipe already bound, "
1025 "AUTH3 not supported!\n"));
1026 goto err;
1029 if (pkt->auth_length == 0) {
1030 DEBUG(1, ("No auth field sent for auth3 request!\n"));
1031 goto err;
1035 * Decode the authentication verifier response.
1038 status = dcerpc_pull_auth_trailer(pkt, pkt,
1039 &pkt->u.auth3.auth_info,
1040 &auth_info, NULL, true);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
1043 goto err;
1046 /* We must NEVER look at auth_info->auth_pad_len here,
1047 * as old Samba client code gets it wrong and sends it
1048 * as zero. JRA.
1051 if (auth_info.auth_type != p->auth.auth_type) {
1052 DEBUG(1, ("Auth type mismatch! Client sent %d, "
1053 "but auth was started as type %d!\n",
1054 auth_info.auth_type, p->auth.auth_type));
1055 goto err;
1058 if (auth_info.auth_level != p->auth.auth_level) {
1059 DEBUG(1, ("Auth level mismatch! Client sent %d, "
1060 "but auth was started as level %d!\n",
1061 auth_info.auth_level, p->auth.auth_level));
1062 goto err;
1065 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1066 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1067 "but auth was started as level %u!\n",
1068 (unsigned)auth_info.auth_context_id,
1069 (unsigned)p->auth.auth_context_id));
1070 goto err;
1073 gensec_security = p->auth.auth_ctx;
1075 status = auth_generic_server_step(gensec_security,
1076 pkt, &auth_info.credentials,
1077 &response);
1079 if (NT_STATUS_EQUAL(status,
1080 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1081 response.length) {
1082 DEBUG(1, (__location__ ": This was supposed to be the final "
1083 "leg, but crypto machinery claims a response is "
1084 "needed, aborting auth!\n"));
1085 data_blob_free(&response);
1086 goto err;
1088 if (!NT_STATUS_IS_OK(status)) {
1089 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
1090 goto err;
1093 /* Now verify auth was indeed successful and extract server info */
1094 status = pipe_auth_verify_final(p);
1095 if (!NT_STATUS_IS_OK(status)) {
1096 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1097 goto err;
1100 return true;
1102 err:
1103 p->pipe_bound = false;
1104 p->allow_bind = false;
1105 p->allow_alter = false;
1106 p->allow_auth3 = false;
1108 TALLOC_FREE(p->auth.auth_ctx);
1109 return false;
1112 /****************************************************************************
1113 Deal with an alter context call. Can be third part of 3 leg auth request for
1114 SPNEGO calls.
1115 ****************************************************************************/
1117 static bool api_pipe_alter_context(struct pipes_struct *p,
1118 struct ncacn_packet *pkt)
1120 struct dcerpc_auth auth_info = {0};
1121 uint16_t assoc_gid;
1122 NTSTATUS status;
1123 union dcerpc_payload u;
1124 struct dcerpc_ack_ctx alter_ack_ctx;
1125 DATA_BLOB auth_resp = data_blob_null;
1126 DATA_BLOB auth_blob = data_blob_null;
1127 struct gensec_security *gensec_security;
1129 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1131 if (!p->allow_alter) {
1132 DEBUG(1, ("Pipe not in allow alter state.\n"));
1133 goto err_exit;
1136 status = dcerpc_verify_ncacn_packet_header(pkt,
1137 DCERPC_PKT_ALTER,
1138 pkt->u.alter.auth_info.length,
1139 0, /* required flags */
1140 DCERPC_PFC_FLAG_FIRST |
1141 DCERPC_PFC_FLAG_LAST |
1142 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1143 0x08 | /* this is not defined, but should be ignored */
1144 DCERPC_PFC_FLAG_CONC_MPX |
1145 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1146 DCERPC_PFC_FLAG_MAYBE |
1147 DCERPC_PFC_FLAG_OBJECT_UUID);
1148 if (!NT_STATUS_IS_OK(status)) {
1149 DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n",
1150 nt_errstr(status)));
1151 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1152 goto err_exit;
1155 if (pkt->u.alter.num_contexts == 0) {
1156 DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n"));
1157 goto err_exit;
1160 if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) {
1161 DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n"));
1162 goto err_exit;
1165 if (pkt->u.alter.assoc_group_id != 0) {
1166 assoc_gid = pkt->u.alter.assoc_group_id;
1167 } else {
1168 assoc_gid = 0x53f0;
1172 * Create the bind response struct.
1175 /* If the requested abstract synt uuid doesn't match our client pipe,
1176 reject the alter_ack & set the transfer interface synt to all 0's,
1177 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1178 unknown to NT4)
1179 Needed when adding entries to a DACL from NT5 - SK */
1181 if (check_bind_req(p,
1182 &pkt->u.alter.ctx_list[0].abstract_syntax,
1183 &pkt->u.alter.ctx_list[0].transfer_syntaxes[0],
1184 pkt->u.alter.ctx_list[0].context_id)) {
1186 alter_ack_ctx.result = 0;
1187 alter_ack_ctx.reason.value = 0;
1188 alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0];
1189 } else {
1190 /* Rejection reason: abstract syntax not supported */
1191 alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1192 alter_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
1193 alter_ack_ctx.syntax = ndr_syntax_id_null;
1197 * Check if this is an authenticated alter context request.
1199 if (pkt->auth_length) {
1200 /* We can only finish if the pipe is unbound for now */
1201 if (p->pipe_bound) {
1202 DEBUG(0, (__location__ ": Pipe already bound, "
1203 "Altering Context not yet supported!\n"));
1204 goto err_exit;
1207 status = dcerpc_pull_auth_trailer(pkt, pkt,
1208 &pkt->u.alter.auth_info,
1209 &auth_info, NULL, true);
1210 if (!NT_STATUS_IS_OK(status)) {
1211 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1212 goto err_exit;
1215 if (auth_info.auth_type != p->auth.auth_type) {
1216 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1217 "but auth was started as type %d!\n",
1218 auth_info.auth_type, p->auth.auth_type));
1219 goto err_exit;
1222 if (auth_info.auth_level != p->auth.auth_level) {
1223 DEBUG(0, ("Auth level mismatch! Client sent %d, "
1224 "but auth was started as level %d!\n",
1225 auth_info.auth_level, p->auth.auth_level));
1226 goto err_exit;
1229 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1230 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1231 "but auth was started as level %u!\n",
1232 (unsigned)auth_info.auth_context_id,
1233 (unsigned)p->auth.auth_context_id));
1234 goto err_exit;
1237 gensec_security = p->auth.auth_ctx;
1238 status = auth_generic_server_step(gensec_security,
1239 pkt,
1240 &auth_info.credentials,
1241 &auth_resp);
1242 if (NT_STATUS_IS_OK(status)) {
1243 /* third leg of auth, verify auth info */
1244 status = pipe_auth_verify_final(p);
1245 if (!NT_STATUS_IS_OK(status)) {
1246 DEBUG(0, ("Auth Verify failed (%s)\n",
1247 nt_errstr(status)));
1248 goto err_exit;
1250 } else if (NT_STATUS_EQUAL(status,
1251 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1252 DEBUG(10, ("More auth legs required.\n"));
1253 } else {
1254 DEBUG(0, ("Auth step returned an error (%s)\n",
1255 nt_errstr(status)));
1256 goto err_exit;
1260 ZERO_STRUCT(u.alter_resp);
1261 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1262 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1263 u.alter_resp.assoc_group_id = assoc_gid;
1265 /* secondary address CAN be NULL
1266 * as the specs say it's ignored.
1267 * It MUST be NULL to have the spoolss working.
1269 u.alter_resp.secondary_address = "";
1270 u.alter_resp.secondary_address_size = 1;
1272 u.alter_resp.num_results = 1;
1273 u.alter_resp.ctx_list = &alter_ack_ctx;
1275 /* NOTE: We leave the auth_info empty so we can calculate the padding
1276 * later and then append the auth_info --simo */
1279 * Marshall directly into the outgoing PDU space. We
1280 * must do this as we need to set to the bind response
1281 * header and are never sending more than one PDU here.
1284 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1285 DCERPC_PKT_ALTER_RESP,
1286 DCERPC_PFC_FLAG_FIRST |
1287 DCERPC_PFC_FLAG_LAST,
1288 auth_resp.length,
1289 pkt->call_id,
1291 &p->out_data.frag);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n",
1294 nt_errstr(status)));
1295 goto err_exit;
1298 if (auth_resp.length) {
1299 status = dcerpc_push_dcerpc_auth(pkt,
1300 p->auth.auth_type,
1301 p->auth.auth_level,
1302 0, /* pad_len */
1303 p->auth.auth_context_id,
1304 &auth_resp,
1305 &auth_blob);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1308 goto err_exit;
1312 /* Now that we have the auth len store it into the right place in
1313 * the dcerpc header */
1314 dcerpc_set_frag_length(&p->out_data.frag,
1315 p->out_data.frag.length +
1316 auth_blob.length);
1318 if (auth_resp.length) {
1319 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1320 auth_blob.data, auth_blob.length)) {
1321 DEBUG(0, ("Append of auth info failed.\n"));
1322 goto err_exit;
1327 * Setup the lengths for the initial reply.
1330 p->out_data.data_sent_length = 0;
1331 p->out_data.current_pdu_sent = 0;
1333 TALLOC_FREE(auth_blob.data);
1334 return True;
1336 err_exit:
1338 data_blob_free(&p->out_data.frag);
1339 TALLOC_FREE(auth_blob.data);
1340 return setup_bind_nak(p, pkt);
1343 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1344 const struct api_struct *api_rpc_cmds, int n_cmds,
1345 const struct ndr_syntax_id *syntax);
1347 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1348 struct ncacn_packet *pkt,
1349 struct pipe_rpc_fns *pipe_fns)
1351 TALLOC_CTX *frame = talloc_stackframe();
1352 struct dcerpc_sec_verification_trailer *vt = NULL;
1353 const uint32_t bitmask1 =
1354 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1355 const struct dcerpc_sec_vt_pcontext pcontext = {
1356 .abstract_syntax = pipe_fns->syntax,
1357 .transfer_syntax = ndr_transfer_syntax_ndr,
1359 const struct dcerpc_sec_vt_header2 header2 =
1360 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1361 struct ndr_pull *ndr;
1362 enum ndr_err_code ndr_err;
1363 bool ret = false;
1365 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1366 if (ndr == NULL) {
1367 goto done;
1370 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1371 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1372 goto done;
1375 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1376 &pcontext, &header2);
1377 done:
1378 TALLOC_FREE(frame);
1379 return ret;
1382 /****************************************************************************
1383 Find the correct RPC function to call for this request.
1384 If the pipe is authenticated then become the correct UNIX user
1385 before doing the call.
1386 ****************************************************************************/
1388 static bool api_pipe_request(struct pipes_struct *p,
1389 struct ncacn_packet *pkt)
1391 TALLOC_CTX *frame = talloc_stackframe();
1392 bool ret = False;
1393 struct pipe_rpc_fns *pipe_fns;
1394 const char *interface_name = NULL;
1396 if (!p->pipe_bound) {
1397 DEBUG(1, ("Pipe not bound!\n"));
1398 data_blob_free(&p->out_data.rdata);
1399 TALLOC_FREE(frame);
1400 return false;
1403 /* get the set of RPC functions for this context */
1404 pipe_fns = find_pipe_fns_by_context(p->contexts,
1405 pkt->u.request.context_id);
1406 if (pipe_fns == NULL) {
1407 DEBUG(0, ("No rpc function table associated with context "
1408 "[%d]\n",
1409 pkt->u.request.context_id));
1410 data_blob_free(&p->out_data.rdata);
1411 TALLOC_FREE(frame);
1412 return false;
1415 interface_name = ndr_interface_name(&pipe_fns->syntax.uuid,
1416 pipe_fns->syntax.if_version);
1417 SMB_ASSERT(interface_name != NULL);
1419 if (p->auth.auth_level < pipe_fns->min_auth_level) {
1421 DEBUG(1, ("%s: auth level required for %s: 0x%x, got: 0x%0x\n",
1422 __func__, interface_name,
1423 pipe_fns->min_auth_level,
1424 p->auth.auth_level));
1426 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1427 TALLOC_FREE(frame);
1428 return true;
1431 switch (p->auth.auth_level) {
1432 case DCERPC_AUTH_LEVEL_NONE:
1433 case DCERPC_AUTH_LEVEL_PACKET:
1434 case DCERPC_AUTH_LEVEL_INTEGRITY:
1435 case DCERPC_AUTH_LEVEL_PRIVACY:
1436 break;
1437 default:
1438 if (!pipe_fns->allow_connect) {
1439 char *addr;
1441 addr = tsocket_address_string(p->remote_address, frame);
1443 DEBUG(1, ("%s: restrict auth_level_connect access "
1444 "to [%s] with auth[type=0x%x,level=0x%x] "
1445 "on [%s] from [%s]\n",
1446 __func__, interface_name,
1447 p->auth.auth_type,
1448 p->auth.auth_level,
1449 derpc_transport_string_by_transport(p->transport),
1450 addr));
1452 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1453 TALLOC_FREE(frame);
1454 return true;
1456 break;
1459 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1460 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1461 set_incoming_fault(p);
1462 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1463 data_blob_free(&p->out_data.rdata);
1464 TALLOC_FREE(frame);
1465 return true;
1468 if (!become_authenticated_pipe_user(p->session_info)) {
1469 DEBUG(1, ("Failed to become pipe user!\n"));
1470 data_blob_free(&p->out_data.rdata);
1471 TALLOC_FREE(frame);
1472 return false;
1475 DEBUG(5, ("Requested %s rpc service\n", interface_name));
1477 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1478 &pipe_fns->syntax);
1479 unbecome_authenticated_pipe_user();
1481 TALLOC_FREE(frame);
1482 return ret;
1485 /*******************************************************************
1486 Calls the underlying RPC function for a named pipe.
1487 ********************************************************************/
1489 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1490 const struct api_struct *api_rpc_cmds, int n_cmds,
1491 const struct ndr_syntax_id *syntax)
1493 int fn_num;
1494 uint32_t offset1;
1495 const struct ndr_interface_table *table;
1497 /* interpret the command */
1498 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1499 ndr_interface_name(&syntax->uuid, syntax->if_version),
1500 pkt->u.request.opnum));
1502 table = ndr_table_by_uuid(&syntax->uuid);
1503 if (table == NULL) {
1504 DEBUG(0,("unknown interface\n"));
1505 return false;
1508 if (DEBUGLEVEL >= 50) {
1509 fstring name;
1510 slprintf(name, sizeof(name)-1, "in_%s",
1511 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1512 dump_pdu_region(name, pkt->u.request.opnum,
1513 &p->in_data.data, 0,
1514 p->in_data.data.length);
1517 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1518 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1519 api_rpc_cmds[fn_num].fn != NULL) {
1520 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1521 api_rpc_cmds[fn_num].name));
1522 break;
1526 if (fn_num == n_cmds) {
1528 * For an unknown RPC just return a fault PDU but
1529 * return True to allow RPC's on the pipe to continue
1530 * and not put the pipe into fault state. JRA.
1532 DEBUG(4, ("unknown\n"));
1533 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1534 return True;
1537 offset1 = p->out_data.rdata.length;
1539 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1540 fn_num, api_rpc_cmds[fn_num].fn));
1541 /* do the actual command */
1542 if(!api_rpc_cmds[fn_num].fn(p)) {
1543 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1544 ndr_interface_name(&syntax->uuid, syntax->if_version),
1545 api_rpc_cmds[fn_num].name));
1546 data_blob_free(&p->out_data.rdata);
1547 return False;
1550 if (p->fault_state) {
1551 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1552 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1553 p->fault_state = 0;
1554 return true;
1557 if (DEBUGLEVEL >= 50) {
1558 fstring name;
1559 slprintf(name, sizeof(name)-1, "out_%s",
1560 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1561 dump_pdu_region(name, pkt->u.request.opnum,
1562 &p->out_data.rdata, offset1,
1563 p->out_data.rdata.length);
1566 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1567 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1569 /* Check for buffer underflow in rpc parsing */
1570 if ((DEBUGLEVEL >= 10) &&
1571 (pkt->frag_length < p->in_data.data.length)) {
1572 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1573 dump_data(10, p->in_data.data.data + pkt->frag_length,
1574 p->in_data.data.length - pkt->frag_length);
1577 return True;
1580 /****************************************************************************
1581 Initialise an outgoing packet.
1582 ****************************************************************************/
1584 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1586 output_data *o_data = &p->out_data;
1588 /* Reset the offset counters. */
1589 o_data->data_sent_length = 0;
1590 o_data->current_pdu_sent = 0;
1592 data_blob_free(&o_data->frag);
1594 /* Free any memory in the current return data buffer. */
1595 data_blob_free(&o_data->rdata);
1597 return True;
1600 /****************************************************************************
1601 Sets the fault state on incoming packets.
1602 ****************************************************************************/
1604 void set_incoming_fault(struct pipes_struct *p)
1606 data_blob_free(&p->in_data.data);
1607 p->in_data.pdu_needed_len = 0;
1608 p->in_data.pdu.length = 0;
1609 p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
1611 p->allow_alter = false;
1612 p->allow_auth3 = false;
1613 p->pipe_bound = false;
1615 DEBUG(10, ("Setting fault state\n"));
1618 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1619 struct ncacn_packet *pkt,
1620 DATA_BLOB *raw_pkt)
1622 NTSTATUS status;
1623 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1625 DEBUG(10, ("Checking request auth.\n"));
1627 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1628 hdr_size += 16;
1631 /* in case of sealing this function will unseal the data in place */
1632 status = dcerpc_check_auth(auth, pkt,
1633 &pkt->u.request.stub_and_verifier,
1634 hdr_size, raw_pkt);
1635 if (!NT_STATUS_IS_OK(status)) {
1636 return status;
1639 return NT_STATUS_OK;
1642 /****************************************************************************
1643 Processes a request pdu. This will do auth processing if needed, and
1644 appends the data into the complete stream if the LAST flag is not set.
1645 ****************************************************************************/
1647 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1649 NTSTATUS status;
1650 DATA_BLOB data;
1651 struct dcerpc_sec_vt_header2 hdr2;
1653 if (!p->pipe_bound) {
1654 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1655 set_incoming_fault(p);
1656 return False;
1660 * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL.
1661 * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later.
1663 status = dcerpc_verify_ncacn_packet_header(pkt,
1664 DCERPC_PKT_REQUEST,
1665 pkt->u.request.stub_and_verifier.length,
1666 0, /* required_flags */
1667 DCERPC_PFC_FLAG_FIRST |
1668 DCERPC_PFC_FLAG_LAST |
1669 0x08 | /* this is not defined, but should be ignored */
1670 DCERPC_PFC_FLAG_CONC_MPX |
1671 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1672 DCERPC_PFC_FLAG_MAYBE |
1673 DCERPC_PFC_FLAG_OBJECT_UUID);
1674 if (!NT_STATUS_IS_OK(status)) {
1675 DEBUG(1, ("process_request_pdu: invalid pdu: %s\n",
1676 nt_errstr(status)));
1677 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1678 set_incoming_fault(p);
1679 return false;
1682 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1683 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1684 p->header2 = hdr2;
1685 } else {
1686 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1687 set_incoming_fault(p);
1688 return false;
1692 /* Store the opnum */
1693 p->opnum = pkt->u.request.opnum;
1695 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1696 if (!NT_STATUS_IS_OK(status)) {
1697 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1698 nt_errstr(status)));
1699 set_incoming_fault(p);
1700 return false;
1703 data = pkt->u.request.stub_and_verifier;
1706 * Check the data length doesn't go over the 15Mb limit.
1707 * increased after observing a bug in the Windows NT 4.0 SP6a
1708 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1709 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1712 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1713 DEBUG(0, ("process_request_pdu: "
1714 "rpc data buffer too large (%u) + (%u)\n",
1715 (unsigned int)p->in_data.data.length,
1716 (unsigned int)data.length));
1717 set_incoming_fault(p);
1718 return False;
1722 * Append the data portion into the buffer and return.
1725 if (data.length) {
1726 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1727 data.data, data.length)) {
1728 DEBUG(0, ("Unable to append data size %u "
1729 "to parse buffer of size %u.\n",
1730 (unsigned int)data.length,
1731 (unsigned int)p->in_data.data.length));
1732 set_incoming_fault(p);
1733 return False;
1737 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1738 return true;
1742 * Ok - we finally have a complete RPC stream.
1743 * Call the rpc command to process it.
1746 return api_pipe_request(p, pkt);
1749 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1751 bool reply = false;
1753 /* Store the call_id */
1754 p->call_id = pkt->call_id;
1756 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1758 if (!pipe_init_outgoing_data(p)) {
1759 goto done;
1762 switch (pkt->ptype) {
1763 case DCERPC_PKT_REQUEST:
1764 reply = process_request_pdu(p, pkt);
1765 break;
1767 case DCERPC_PKT_PING: /* CL request - ignore... */
1768 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1769 (unsigned int)pkt->ptype));
1770 break;
1772 case DCERPC_PKT_RESPONSE: /* No responses here. */
1773 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1774 break;
1776 case DCERPC_PKT_FAULT:
1777 case DCERPC_PKT_WORKING:
1778 /* CL request - reply to a ping when a call in process. */
1779 case DCERPC_PKT_NOCALL:
1780 /* CL - server reply to a ping call. */
1781 case DCERPC_PKT_REJECT:
1782 case DCERPC_PKT_ACK:
1783 case DCERPC_PKT_CL_CANCEL:
1784 case DCERPC_PKT_FACK:
1785 case DCERPC_PKT_CANCEL_ACK:
1786 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1787 (unsigned int)pkt->ptype));
1788 break;
1790 case DCERPC_PKT_BIND:
1792 * We assume that a pipe bind is only in one pdu.
1794 reply = api_pipe_bind_req(p, pkt);
1795 break;
1797 case DCERPC_PKT_BIND_ACK:
1798 case DCERPC_PKT_BIND_NAK:
1799 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1800 "packet type %u received.\n",
1801 (unsigned int)pkt->ptype));
1802 break;
1805 case DCERPC_PKT_ALTER:
1807 * We assume that a pipe bind is only in one pdu.
1809 reply = api_pipe_alter_context(p, pkt);
1810 break;
1812 case DCERPC_PKT_ALTER_RESP:
1813 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1814 "Should only be server -> client.\n"));
1815 break;
1817 case DCERPC_PKT_AUTH3:
1819 * The third packet in an auth exchange.
1821 reply = api_pipe_bind_auth3(p, pkt);
1822 break;
1824 case DCERPC_PKT_SHUTDOWN:
1825 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1826 "Should only be server -> client.\n"));
1827 break;
1829 case DCERPC_PKT_CO_CANCEL:
1830 /* For now just free all client data and continue
1831 * processing. */
1832 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1833 " Abandoning rpc call.\n"));
1834 /* As we never do asynchronous RPC serving, we can
1835 * never cancel a call (as far as I know).
1836 * If we ever did we'd have to send a cancel_ack reply.
1837 * For now, just free all client data and continue
1838 * processing. */
1839 reply = True;
1840 break;
1842 #if 0
1843 /* Enable this if we're doing async rpc. */
1844 /* We must check the outstanding callid matches. */
1845 if (pipe_init_outgoing_data(p)) {
1846 /* Send a cancel_ack PDU reply. */
1847 /* We should probably check the auth-verifier here. */
1848 reply = setup_cancel_ack_reply(p, pkt);
1850 break;
1851 #endif
1853 case DCERPC_PKT_ORPHANED:
1854 /* We should probably check the auth-verifier here.
1855 * For now just free all client data and continue
1856 * processing. */
1857 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1858 " Abandoning rpc call.\n"));
1859 reply = True;
1860 break;
1862 default:
1863 DEBUG(0, ("process_complete_pdu: "
1864 "Unknown rpc type = %u received.\n",
1865 (unsigned int)pkt->ptype));
1866 break;
1869 done:
1870 if (!reply) {
1871 DEBUG(3,("DCE/RPC fault sent!"));
1872 set_incoming_fault(p);
1873 setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR));
1875 /* pkt and p->in_data.pdu.data freed by caller */