s3:rpc_server: add support for DCERPC_AUTH_LEVEL_PACKET
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob0633b5fa78cecb9b4f4b7a73144fc9463790fb76
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"
54 #undef DBGC_CLASS
55 #define DBGC_CLASS DBGC_RPC_SRV
57 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p);
59 /**
60 * Dump everything from the start of the end up of the provided data
61 * into a file, but only at debug level >= 50
62 **/
63 static void dump_pdu_region(const char *name, int v,
64 DATA_BLOB *data, size_t start, size_t end)
66 int fd, i;
67 char *fname = NULL;
68 ssize_t sz;
70 if (DEBUGLEVEL < 50) return;
72 if (start > data->length || end > data->length || start > end) return;
74 for (i = 1; i < 100; i++) {
75 if (v != -1) {
76 fname = talloc_asprintf(talloc_tos(),
77 "/tmp/%s_%d.%d.prs",
78 name, v, i);
79 } else {
80 fname = talloc_asprintf(talloc_tos(),
81 "/tmp/%s_%d.prs",
82 name, i);
84 if (!fname) {
85 return;
87 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
88 if (fd != -1 || errno != EEXIST) break;
90 if (fd != -1) {
91 sz = write(fd, data->data + start, end - start);
92 i = close(fd);
93 if ((sz != end - start) || (i != 0) ) {
94 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
95 fname, (unsigned long)sz,
96 (unsigned long)end - start, i));
97 } else {
98 DEBUG(0,("created %s\n", fname));
101 TALLOC_FREE(fname);
104 static DATA_BLOB generic_session_key(void)
106 return data_blob_const("SystemLibraryDTC", 16);
109 /*******************************************************************
110 Generate the next PDU to be returned from the data.
111 ********************************************************************/
113 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
114 struct pipe_auth_data *auth,
115 uint32_t call_id,
116 DATA_BLOB *rdata,
117 size_t data_sent_length,
118 DATA_BLOB *frag,
119 size_t *pdu_size)
121 union dcerpc_payload u;
122 uint8_t pfc_flags;
123 size_t data_left;
124 size_t data_to_send;
125 size_t frag_len;
126 size_t pad_len = 0;
127 size_t auth_len = 0;
128 NTSTATUS status;
130 ZERO_STRUCT(u.response);
132 /* Set up rpc packet pfc flags. */
133 if (data_sent_length == 0) {
134 pfc_flags = DCERPC_PFC_FLAG_FIRST;
135 } else {
136 pfc_flags = 0;
139 /* Work out how much we can fit in a single PDU. */
140 data_left = rdata->length - data_sent_length;
142 /* Ensure there really is data left to send. */
143 if (!data_left) {
144 DEBUG(0, ("No data left to send !\n"));
145 return NT_STATUS_BUFFER_TOO_SMALL;
148 status = dcerpc_guess_sizes(auth,
149 DCERPC_RESPONSE_LENGTH,
150 data_left,
151 RPC_MAX_PDU_FRAG_LEN,
152 &data_to_send, &frag_len,
153 &auth_len, &pad_len);
154 if (!NT_STATUS_IS_OK(status)) {
155 return status;
158 /* Set up the alloc hint. This should be the data left to send. */
159 u.response.alloc_hint = data_left;
161 /* Work out if this PDU will be the last. */
162 if (data_sent_length + data_to_send >= rdata->length) {
163 pfc_flags |= DCERPC_PFC_FLAG_LAST;
166 /* Prepare data to be NDR encoded. */
167 u.response.stub_and_verifier =
168 data_blob_const(rdata->data + data_sent_length, data_to_send);
170 /* Store the packet in the data stream. */
171 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
172 pfc_flags, auth_len, call_id,
173 &u, frag);
174 if (!NT_STATUS_IS_OK(status)) {
175 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
176 return status;
179 if (auth_len) {
180 /* Set the proper length on the pdu, including padding.
181 * Only needed if an auth trailer will be appended. */
182 dcerpc_set_frag_length(frag, frag->length
183 + pad_len
184 + DCERPC_AUTH_TRAILER_LENGTH
185 + auth_len);
188 if (auth_len) {
189 status = dcerpc_add_auth_footer(auth, pad_len, frag);
190 if (!NT_STATUS_IS_OK(status)) {
191 data_blob_free(frag);
192 return status;
196 *pdu_size = data_to_send;
197 return NT_STATUS_OK;
200 /*******************************************************************
201 Generate the next PDU to be returned from the data in p->rdata.
202 ********************************************************************/
204 bool create_next_pdu(struct pipes_struct *p)
206 size_t pdu_size = 0;
207 NTSTATUS status;
210 * If we're in the fault state, keep returning fault PDU's until
211 * the pipe gets closed. JRA.
213 if (p->fault_state) {
214 setup_fault_pdu(p, NT_STATUS(p->fault_state));
215 return true;
218 status = create_next_packet(p->mem_ctx, &p->auth,
219 p->call_id, &p->out_data.rdata,
220 p->out_data.data_sent_length,
221 &p->out_data.frag, &pdu_size);
222 if (!NT_STATUS_IS_OK(status)) {
223 DEBUG(0, ("Failed to create packet with error %s, "
224 "(auth level %u / type %u)\n",
225 nt_errstr(status),
226 (unsigned int)p->auth.auth_level,
227 (unsigned int)p->auth.auth_type));
228 return false;
231 /* Setup the counts for this PDU. */
232 p->out_data.data_sent_length += pdu_size;
233 p->out_data.current_pdu_sent = 0;
234 return true;
238 static bool pipe_init_outgoing_data(struct pipes_struct *p);
240 /*******************************************************************
241 Marshall a bind_nak pdu.
242 *******************************************************************/
244 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
246 NTSTATUS status;
247 union dcerpc_payload u;
249 /* Free any memory in the current return data buffer. */
250 pipe_init_outgoing_data(p);
253 * Initialize a bind_nak header.
256 ZERO_STRUCT(u);
258 u.bind_nak.reject_reason = 0;
261 * Marshall directly into the outgoing PDU space. We
262 * must do this as we need to set to the bind response
263 * header and are never sending more than one PDU here.
266 status = dcerpc_push_ncacn_packet(p->mem_ctx,
267 DCERPC_PKT_BIND_NAK,
268 DCERPC_PFC_FLAG_FIRST |
269 DCERPC_PFC_FLAG_LAST,
271 pkt->call_id,
273 &p->out_data.frag);
274 if (!NT_STATUS_IS_OK(status)) {
275 return False;
278 p->out_data.data_sent_length = 0;
279 p->out_data.current_pdu_sent = 0;
281 set_incoming_fault(p);
282 TALLOC_FREE(p->auth.auth_ctx);
283 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
284 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
285 p->pipe_bound = False;
286 p->allow_bind = false;
287 p->allow_alter = false;
288 p->allow_auth3 = false;
290 return True;
293 /*******************************************************************
294 Marshall a fault pdu.
295 *******************************************************************/
297 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
299 NTSTATUS status;
300 union dcerpc_payload u;
302 /* Free any memory in the current return data buffer. */
303 pipe_init_outgoing_data(p);
306 * Initialize a fault header.
309 ZERO_STRUCT(u);
311 u.fault.status = NT_STATUS_V(fault_status);
314 * Marshall directly into the outgoing PDU space. We
315 * must do this as we need to set to the bind response
316 * header and are never sending more than one PDU here.
319 status = dcerpc_push_ncacn_packet(p->mem_ctx,
320 DCERPC_PKT_FAULT,
321 DCERPC_PFC_FLAG_FIRST |
322 DCERPC_PFC_FLAG_LAST |
323 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
325 p->call_id,
327 &p->out_data.frag);
328 if (!NT_STATUS_IS_OK(status)) {
329 return False;
332 p->out_data.data_sent_length = 0;
333 p->out_data.current_pdu_sent = 0;
335 return True;
338 /*******************************************************************
339 Ensure a bind request has the correct abstract & transfer interface.
340 Used to reject unknown binds from Win2k.
341 *******************************************************************/
343 static bool check_bind_req(struct pipes_struct *p,
344 struct ndr_syntax_id* abstract,
345 struct ndr_syntax_id* transfer,
346 uint32_t context_id)
348 struct pipe_rpc_fns *context_fns;
349 bool ok;
350 const char *interface_name = NULL;
352 DEBUG(3,("check_bind_req for %s context_id=%u\n",
353 ndr_interface_name(&abstract->uuid,
354 abstract->if_version),
355 (unsigned)context_id));
357 ok = ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr);
358 if (!ok) {
359 DEBUG(1,("check_bind_req unknown transfer syntax for "
360 "%s context_id=%u\n",
361 ndr_interface_name(&abstract->uuid,
362 abstract->if_version),
363 (unsigned)context_id));
364 return false;
367 for (context_fns = p->contexts;
368 context_fns != NULL;
369 context_fns = context_fns->next)
371 if (context_fns->context_id != context_id) {
372 continue;
375 ok = ndr_syntax_id_equal(&context_fns->syntax,
376 abstract);
377 if (ok) {
378 return true;
381 DEBUG(1,("check_bind_req: changing abstract syntax for "
382 "%s context_id=%u into %s not supported\n",
383 ndr_interface_name(&context_fns->syntax.uuid,
384 context_fns->syntax.if_version),
385 (unsigned)context_id,
386 ndr_interface_name(&abstract->uuid,
387 abstract->if_version)));
388 return false;
391 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
392 if (!rpc_srv_pipe_exists_by_id(abstract)) {
393 return false;
396 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
397 rpc_srv_get_pipe_cli_name(abstract),
398 rpc_srv_get_pipe_srv_name(abstract)));
400 ok = init_pipe_handles(p, abstract);
401 if (!ok) {
402 DEBUG(1, ("Failed to init pipe handles!\n"));
403 return false;
406 context_fns = talloc_zero(p, struct pipe_rpc_fns);
407 if (context_fns == NULL) {
408 DEBUG(0,("check_bind_req: talloc() failed!\n"));
409 return false;
412 interface_name = ndr_interface_name(&abstract->uuid,
413 abstract->if_version);
414 SMB_ASSERT(interface_name != NULL);
416 context_fns->next = context_fns->prev = NULL;
417 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
418 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
419 context_fns->context_id = context_id;
420 context_fns->syntax = *abstract;
422 context_fns->allow_connect = lp_allow_dcerpc_auth_level_connect();
424 * for the samr, lsarpc and netlogon interfaces we don't allow "connect"
425 * auth_level by default.
427 ok = ndr_syntax_id_equal(abstract, &ndr_table_samr.syntax_id);
428 if (ok) {
429 context_fns->allow_connect = false;
431 ok = ndr_syntax_id_equal(abstract, &ndr_table_lsarpc.syntax_id);
432 if (ok) {
433 context_fns->allow_connect = false;
435 ok = ndr_syntax_id_equal(abstract, &ndr_table_netlogon.syntax_id);
436 if (ok) {
437 context_fns->allow_connect = false;
440 * for the epmapper and echo interfaces we allow "connect"
441 * auth_level by default.
443 ok = ndr_syntax_id_equal(abstract, &ndr_table_epmapper.syntax_id);
444 if (ok) {
445 context_fns->allow_connect = true;
447 ok = ndr_syntax_id_equal(abstract, &ndr_table_rpcecho.syntax_id);
448 if (ok) {
449 context_fns->allow_connect = true;
452 * every interface can be modified to allow "connect" auth_level by
453 * using a parametric option like:
454 * allow dcerpc auth level connect:<interface>
455 * e.g.
456 * allow dcerpc auth level connect:samr = yes
458 context_fns->allow_connect = lp_parm_bool(-1,
459 "allow dcerpc auth level connect",
460 interface_name, context_fns->allow_connect);
462 /* add to the list of open contexts */
464 DLIST_ADD( p->contexts, context_fns );
466 return True;
470 * Is a named pipe known?
471 * @param[in] pipename Just the filename
472 * @result Do we want to serve this?
474 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
476 NTSTATUS status;
478 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
479 DEBUG(10, ("refusing spoolss access\n"));
480 return false;
483 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
484 return true;
487 status = smb_probe_module("rpc", pipename);
488 if (!NT_STATUS_IS_OK(status)) {
489 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
490 return false;
492 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
495 * Scan the list again for the interface id
497 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
498 return true;
501 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
502 pipename));
504 return false;
507 /*******************************************************************
508 Handle an NTLMSSP bind auth.
509 *******************************************************************/
511 static bool pipe_auth_generic_bind(struct pipes_struct *p,
512 struct ncacn_packet *pkt,
513 struct dcerpc_auth *auth_info,
514 DATA_BLOB *response)
516 TALLOC_CTX *mem_ctx = pkt;
517 struct gensec_security *gensec_security = NULL;
518 NTSTATUS status;
520 status = auth_generic_server_authtype_start(p,
521 auth_info->auth_type,
522 auth_info->auth_level,
523 &auth_info->credentials,
524 response,
525 p->remote_address,
526 &gensec_security);
527 if (!NT_STATUS_IS_OK(status) &&
528 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
530 DEBUG(0, (__location__ ": auth_generic_server_authtype_start[%u/%u] failed: %s\n",
531 auth_info->auth_type, auth_info->auth_level, nt_errstr(status)));
532 return false;
535 /* Make sure data is bound to the memctx, to be freed the caller */
536 talloc_steal(mem_ctx, response->data);
538 p->auth.auth_ctx = gensec_security;
539 p->auth.auth_type = auth_info->auth_type;
540 p->auth.auth_level = auth_info->auth_level;
541 p->auth.auth_context_id = auth_info->auth_context_id;
543 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
544 p->auth.client_hdr_signing = true;
545 p->auth.hdr_signing = gensec_have_feature(gensec_security,
546 GENSEC_FEATURE_SIGN_PKT_HEADER);
549 if (p->auth.hdr_signing) {
550 gensec_want_feature(gensec_security,
551 GENSEC_FEATURE_SIGN_PKT_HEADER);
554 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
555 return true;
558 status = pipe_auth_verify_final(p);
559 if (!NT_STATUS_IS_OK(status)) {
560 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
561 nt_errstr(status)));
562 return false;
565 return true;
568 /*******************************************************************
569 Process an NTLMSSP authentication response.
570 If this function succeeds, the user has been authenticated
571 and their domain, name and calling workstation stored in
572 the pipe struct.
573 *******************************************************************/
575 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
576 struct gensec_security *gensec_security,
577 enum dcerpc_AuthLevel auth_level,
578 struct auth_session_info **session_info)
580 NTSTATUS status;
581 bool ret;
583 DEBUG(5, (__location__ ": checking user details\n"));
585 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
586 ensure the underlying NTLMSSP flags are also set. If not we should
587 refuse the bind. */
589 status = auth_generic_server_check_flags(gensec_security,
590 (auth_level >=
591 DCERPC_AUTH_LEVEL_PACKET),
592 (auth_level ==
593 DCERPC_AUTH_LEVEL_PRIVACY));
594 if (!NT_STATUS_IS_OK(status)) {
595 DEBUG(0, (__location__ ": Client failed to negotatie proper "
596 "security for rpc connection\n"));
597 return false;
600 TALLOC_FREE(*session_info);
602 status = auth_generic_server_get_user_info(gensec_security,
603 mem_ctx, session_info);
604 if (!NT_STATUS_IS_OK(status)) {
605 DEBUG(0, (__location__ ": failed to obtain the server info "
606 "for authenticated user: %s\n", nt_errstr(status)));
607 return false;
610 if ((*session_info)->security_token == NULL) {
611 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
612 return false;
615 if ((*session_info)->unix_token == NULL) {
616 DEBUG(1, ("Auth module failed to provide unix_token\n"));
617 return false;
621 * We're an authenticated bind over smb, so the session key needs to
622 * be set to "SystemLibraryDTC". Weird, but this is what Windows
623 * does. See the RPC-SAMBA3SESSIONKEY.
626 ret = session_info_set_session_key((*session_info), generic_session_key());
627 if (!ret) {
628 DEBUG(0, ("Failed to set session key!\n"));
629 return false;
632 return true;
635 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
637 struct gensec_security *gensec_security;
638 bool ok;
640 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
641 p->pipe_bound = true;
642 return NT_STATUS_OK;
645 gensec_security = p->auth.auth_ctx;
647 ok = pipe_auth_generic_verify_final(p, gensec_security,
648 p->auth.auth_level,
649 &p->session_info);
650 if (!ok) {
651 return NT_STATUS_ACCESS_DENIED;
654 p->pipe_bound = true;
656 return NT_STATUS_OK;
659 /*******************************************************************
660 Respond to a pipe bind request.
661 *******************************************************************/
663 static bool api_pipe_bind_req(struct pipes_struct *p,
664 struct ncacn_packet *pkt)
666 struct dcerpc_auth auth_info = {0};
667 uint16_t assoc_gid;
668 NTSTATUS status;
669 struct ndr_syntax_id id;
670 uint8_t pfc_flags = 0;
671 union dcerpc_payload u;
672 struct dcerpc_ack_ctx bind_ack_ctx;
673 DATA_BLOB auth_resp = data_blob_null;
674 DATA_BLOB auth_blob = data_blob_null;
675 const struct ndr_interface_table *table;
677 if (!p->allow_bind) {
678 DEBUG(2,("Pipe not in allow bind state\n"));
679 return setup_bind_nak(p, pkt);
681 p->allow_bind = false;
683 status = dcerpc_verify_ncacn_packet_header(pkt,
684 DCERPC_PKT_BIND,
685 pkt->u.bind.auth_info.length,
686 0, /* required flags */
687 DCERPC_PFC_FLAG_FIRST |
688 DCERPC_PFC_FLAG_LAST |
689 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
690 0x08 | /* this is not defined, but should be ignored */
691 DCERPC_PFC_FLAG_CONC_MPX |
692 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
693 DCERPC_PFC_FLAG_MAYBE |
694 DCERPC_PFC_FLAG_OBJECT_UUID);
695 if (!NT_STATUS_IS_OK(status)) {
696 DEBUG(1, ("api_pipe_bind_req: invalid pdu: %s\n",
697 nt_errstr(status)));
698 NDR_PRINT_DEBUG(ncacn_packet, pkt);
699 goto err_exit;
702 if (pkt->u.bind.num_contexts == 0) {
703 DEBUG(1, ("api_pipe_bind_req: no rpc contexts around\n"));
704 goto err_exit;
707 if (pkt->u.bind.ctx_list[0].num_transfer_syntaxes == 0) {
708 DEBUG(1, ("api_pipe_bind_req: no transfer syntaxes around\n"));
709 goto err_exit;
713 * Try and find the correct pipe name to ensure
714 * that this is a pipe name we support.
716 id = pkt->u.bind.ctx_list[0].abstract_syntax;
718 table = ndr_table_by_uuid(&id.uuid);
719 if (table == NULL) {
720 DEBUG(0,("unknown interface\n"));
721 return false;
724 if (rpc_srv_pipe_exists_by_id(&id)) {
725 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
726 rpc_srv_get_pipe_cli_name(&id),
727 rpc_srv_get_pipe_srv_name(&id)));
728 } else {
729 status = smb_probe_module(
730 "rpc", dcerpc_default_transport_endpoint(pkt,
731 NCACN_NP, table));
733 if (NT_STATUS_IS_ERR(status)) {
734 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
735 "%s in bind request.\n",
736 ndr_interface_name(&id.uuid,
737 id.if_version)));
739 return setup_bind_nak(p, pkt);
742 if (rpc_srv_get_pipe_interface_by_cli_name(
743 dcerpc_default_transport_endpoint(pkt,
744 NCACN_NP, table),
745 &id)) {
746 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
747 rpc_srv_get_pipe_cli_name(&id),
748 rpc_srv_get_pipe_srv_name(&id)));
749 } else {
750 DEBUG(0, ("module %s doesn't provide functions for "
751 "pipe %s!\n",
752 ndr_interface_name(&id.uuid,
753 id.if_version),
754 ndr_interface_name(&id.uuid,
755 id.if_version)));
756 return setup_bind_nak(p, pkt);
760 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
762 if (pkt->u.bind.assoc_group_id != 0) {
763 assoc_gid = pkt->u.bind.assoc_group_id;
764 } else {
765 assoc_gid = 0x53f0;
769 * Create the bind response struct.
772 /* If the requested abstract synt uuid doesn't match our client pipe,
773 reject the bind_ack & set the transfer interface synt to all 0's,
774 ver 0 (observed when NT5 attempts to bind to abstract interfaces
775 unknown to NT4)
776 Needed when adding entries to a DACL from NT5 - SK */
778 if (check_bind_req(p,
779 &pkt->u.bind.ctx_list[0].abstract_syntax,
780 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
781 pkt->u.bind.ctx_list[0].context_id)) {
783 bind_ack_ctx.result = 0;
784 bind_ack_ctx.reason.value = 0;
785 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
786 } else {
787 /* Rejection reason: abstract syntax not supported */
788 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
789 bind_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
790 bind_ack_ctx.syntax = ndr_syntax_id_null;
794 * Check if this is an authenticated bind request.
796 if (pkt->auth_length) {
798 * Decode the authentication verifier.
800 status = dcerpc_pull_auth_trailer(pkt, pkt,
801 &pkt->u.bind.auth_info,
802 &auth_info, NULL, true);
803 if (!NT_STATUS_IS_OK(status)) {
804 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
805 goto err_exit;
808 if (!pipe_auth_generic_bind(p, pkt,
809 &auth_info, &auth_resp)) {
810 goto err_exit;
812 } else {
813 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
814 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
815 p->auth.auth_context_id = 0;
818 ZERO_STRUCT(u.bind_ack);
819 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
820 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
821 u.bind_ack.assoc_group_id = assoc_gid;
823 /* name has to be \PIPE\xxxxx */
824 u.bind_ack.secondary_address =
825 talloc_asprintf(pkt, "\\PIPE\\%s",
826 rpc_srv_get_pipe_srv_name(&id));
827 if (!u.bind_ack.secondary_address) {
828 DEBUG(0, ("Out of memory!\n"));
829 goto err_exit;
831 u.bind_ack.secondary_address_size =
832 strlen(u.bind_ack.secondary_address) + 1;
834 u.bind_ack.num_results = 1;
835 u.bind_ack.ctx_list = &bind_ack_ctx;
837 /* NOTE: We leave the auth_info empty so we can calculate the padding
838 * later and then append the auth_info --simo */
841 * Marshall directly into the outgoing PDU space. We
842 * must do this as we need to set to the bind response
843 * header and are never sending more than one PDU here.
846 pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
848 if (p->auth.hdr_signing) {
849 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
852 status = dcerpc_push_ncacn_packet(p->mem_ctx,
853 DCERPC_PKT_BIND_ACK,
854 pfc_flags,
855 auth_resp.length,
856 pkt->call_id,
858 &p->out_data.frag);
859 if (!NT_STATUS_IS_OK(status)) {
860 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
861 nt_errstr(status)));
862 goto err_exit;
865 if (auth_resp.length) {
866 status = dcerpc_push_dcerpc_auth(pkt,
867 p->auth.auth_type,
868 p->auth.auth_level,
869 0, /* pad_len */
870 p->auth.auth_context_id,
871 &auth_resp,
872 &auth_blob);
873 if (!NT_STATUS_IS_OK(status)) {
874 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
875 goto err_exit;
879 /* Now that we have the auth len store it into the right place in
880 * the dcerpc header */
881 dcerpc_set_frag_length(&p->out_data.frag,
882 p->out_data.frag.length + auth_blob.length);
884 if (auth_blob.length) {
886 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
887 auth_blob.data, auth_blob.length)) {
888 DEBUG(0, ("Append of auth info failed.\n"));
889 goto err_exit;
894 * Setup the lengths for the initial reply.
897 p->out_data.data_sent_length = 0;
898 p->out_data.current_pdu_sent = 0;
900 TALLOC_FREE(auth_blob.data);
902 if (bind_ack_ctx.result == 0) {
903 p->allow_alter = true;
904 p->allow_auth3 = true;
905 if (p->auth.auth_type == DCERPC_AUTH_TYPE_NONE) {
906 status = pipe_auth_verify_final(p);
907 if (!NT_STATUS_IS_OK(status)) {
908 DEBUG(0, ("pipe_auth_verify_final failed: %s\n",
909 nt_errstr(status)));
910 goto err_exit;
913 } else {
914 goto err_exit;
917 return True;
919 err_exit:
921 data_blob_free(&p->out_data.frag);
922 TALLOC_FREE(auth_blob.data);
923 return setup_bind_nak(p, pkt);
926 /*******************************************************************
927 This is the "stage3" response after a bind request and reply.
928 *******************************************************************/
930 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
932 struct dcerpc_auth auth_info;
933 DATA_BLOB response = data_blob_null;
934 struct gensec_security *gensec_security;
935 NTSTATUS status;
937 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
939 if (!p->allow_auth3) {
940 DEBUG(1, ("Pipe not in allow auth3 state.\n"));
941 goto err;
944 status = dcerpc_verify_ncacn_packet_header(pkt,
945 DCERPC_PKT_AUTH3,
946 pkt->u.auth3.auth_info.length,
947 0, /* required flags */
948 DCERPC_PFC_FLAG_FIRST |
949 DCERPC_PFC_FLAG_LAST |
950 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
951 0x08 | /* this is not defined, but should be ignored */
952 DCERPC_PFC_FLAG_CONC_MPX |
953 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
954 DCERPC_PFC_FLAG_MAYBE |
955 DCERPC_PFC_FLAG_OBJECT_UUID);
956 if (!NT_STATUS_IS_OK(status)) {
957 DEBUG(1, ("api_pipe_bind_auth3: invalid pdu: %s\n",
958 nt_errstr(status)));
959 NDR_PRINT_DEBUG(ncacn_packet, pkt);
960 goto err;
963 /* We can only finish if the pipe is unbound for now */
964 if (p->pipe_bound) {
965 DEBUG(0, (__location__ ": Pipe already bound, "
966 "AUTH3 not supported!\n"));
967 goto err;
970 if (pkt->auth_length == 0) {
971 DEBUG(1, ("No auth field sent for auth3 request!\n"));
972 goto err;
976 * Decode the authentication verifier response.
979 status = dcerpc_pull_auth_trailer(pkt, pkt,
980 &pkt->u.auth3.auth_info,
981 &auth_info, NULL, true);
982 if (!NT_STATUS_IS_OK(status)) {
983 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
984 goto err;
987 /* We must NEVER look at auth_info->auth_pad_len here,
988 * as old Samba client code gets it wrong and sends it
989 * as zero. JRA.
992 if (auth_info.auth_type != p->auth.auth_type) {
993 DEBUG(1, ("Auth type mismatch! Client sent %d, "
994 "but auth was started as type %d!\n",
995 auth_info.auth_type, p->auth.auth_type));
996 goto err;
999 if (auth_info.auth_level != p->auth.auth_level) {
1000 DEBUG(1, ("Auth level mismatch! Client sent %d, "
1001 "but auth was started as level %d!\n",
1002 auth_info.auth_level, p->auth.auth_level));
1003 goto err;
1006 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1007 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1008 "but auth was started as level %u!\n",
1009 (unsigned)auth_info.auth_context_id,
1010 (unsigned)p->auth.auth_context_id));
1011 goto err;
1014 gensec_security = p->auth.auth_ctx;
1016 status = auth_generic_server_step(gensec_security,
1017 pkt, &auth_info.credentials,
1018 &response);
1020 if (NT_STATUS_EQUAL(status,
1021 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1022 response.length) {
1023 DEBUG(1, (__location__ ": This was supposed to be the final "
1024 "leg, but crypto machinery claims a response is "
1025 "needed, aborting auth!\n"));
1026 data_blob_free(&response);
1027 goto err;
1029 if (!NT_STATUS_IS_OK(status)) {
1030 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
1031 goto err;
1034 /* Now verify auth was indeed successful and extract server info */
1035 status = pipe_auth_verify_final(p);
1036 if (!NT_STATUS_IS_OK(status)) {
1037 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1038 goto err;
1041 return true;
1043 err:
1044 p->pipe_bound = false;
1045 p->allow_bind = false;
1046 p->allow_alter = false;
1047 p->allow_auth3 = false;
1049 TALLOC_FREE(p->auth.auth_ctx);
1050 return false;
1053 /****************************************************************************
1054 Deal with an alter context call. Can be third part of 3 leg auth request for
1055 SPNEGO calls.
1056 ****************************************************************************/
1058 static bool api_pipe_alter_context(struct pipes_struct *p,
1059 struct ncacn_packet *pkt)
1061 struct dcerpc_auth auth_info = {0};
1062 uint16_t assoc_gid;
1063 NTSTATUS status;
1064 union dcerpc_payload u;
1065 struct dcerpc_ack_ctx alter_ack_ctx;
1066 DATA_BLOB auth_resp = data_blob_null;
1067 DATA_BLOB auth_blob = data_blob_null;
1068 struct gensec_security *gensec_security;
1070 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1072 if (!p->allow_alter) {
1073 DEBUG(1, ("Pipe not in allow alter state.\n"));
1074 goto err_exit;
1077 status = dcerpc_verify_ncacn_packet_header(pkt,
1078 DCERPC_PKT_ALTER,
1079 pkt->u.alter.auth_info.length,
1080 0, /* required flags */
1081 DCERPC_PFC_FLAG_FIRST |
1082 DCERPC_PFC_FLAG_LAST |
1083 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1084 0x08 | /* this is not defined, but should be ignored */
1085 DCERPC_PFC_FLAG_CONC_MPX |
1086 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1087 DCERPC_PFC_FLAG_MAYBE |
1088 DCERPC_PFC_FLAG_OBJECT_UUID);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 DEBUG(1, ("api_pipe_alter_context: invalid pdu: %s\n",
1091 nt_errstr(status)));
1092 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1093 goto err_exit;
1096 if (pkt->u.alter.num_contexts == 0) {
1097 DEBUG(1, ("api_pipe_alter_context: no rpc contexts around\n"));
1098 goto err_exit;
1101 if (pkt->u.alter.ctx_list[0].num_transfer_syntaxes == 0) {
1102 DEBUG(1, ("api_pipe_alter_context: no transfer syntaxes around\n"));
1103 goto err_exit;
1106 if (pkt->u.alter.assoc_group_id != 0) {
1107 assoc_gid = pkt->u.alter.assoc_group_id;
1108 } else {
1109 assoc_gid = 0x53f0;
1113 * Create the bind response struct.
1116 /* If the requested abstract synt uuid doesn't match our client pipe,
1117 reject the alter_ack & set the transfer interface synt to all 0's,
1118 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1119 unknown to NT4)
1120 Needed when adding entries to a DACL from NT5 - SK */
1122 if (check_bind_req(p,
1123 &pkt->u.alter.ctx_list[0].abstract_syntax,
1124 &pkt->u.alter.ctx_list[0].transfer_syntaxes[0],
1125 pkt->u.alter.ctx_list[0].context_id)) {
1127 alter_ack_ctx.result = 0;
1128 alter_ack_ctx.reason.value = 0;
1129 alter_ack_ctx.syntax = pkt->u.alter.ctx_list[0].transfer_syntaxes[0];
1130 } else {
1131 /* Rejection reason: abstract syntax not supported */
1132 alter_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1133 alter_ack_ctx.reason.value = DCERPC_BIND_REASON_ASYNTAX;
1134 alter_ack_ctx.syntax = ndr_syntax_id_null;
1138 * Check if this is an authenticated alter context request.
1140 if (pkt->auth_length) {
1141 /* We can only finish if the pipe is unbound for now */
1142 if (p->pipe_bound) {
1143 DEBUG(0, (__location__ ": Pipe already bound, "
1144 "Altering Context not yet supported!\n"));
1145 goto err_exit;
1148 status = dcerpc_pull_auth_trailer(pkt, pkt,
1149 &pkt->u.alter.auth_info,
1150 &auth_info, NULL, true);
1151 if (!NT_STATUS_IS_OK(status)) {
1152 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1153 goto err_exit;
1156 if (auth_info.auth_type != p->auth.auth_type) {
1157 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1158 "but auth was started as type %d!\n",
1159 auth_info.auth_type, p->auth.auth_type));
1160 goto err_exit;
1163 if (auth_info.auth_level != p->auth.auth_level) {
1164 DEBUG(0, ("Auth level mismatch! Client sent %d, "
1165 "but auth was started as level %d!\n",
1166 auth_info.auth_level, p->auth.auth_level));
1167 goto err_exit;
1170 if (auth_info.auth_context_id != p->auth.auth_context_id) {
1171 DEBUG(0, ("Auth context id mismatch! Client sent %u, "
1172 "but auth was started as level %u!\n",
1173 (unsigned)auth_info.auth_context_id,
1174 (unsigned)p->auth.auth_context_id));
1175 goto err_exit;
1178 gensec_security = p->auth.auth_ctx;
1179 status = auth_generic_server_step(gensec_security,
1180 pkt,
1181 &auth_info.credentials,
1182 &auth_resp);
1183 if (NT_STATUS_IS_OK(status)) {
1184 /* third leg of auth, verify auth info */
1185 status = pipe_auth_verify_final(p);
1186 if (!NT_STATUS_IS_OK(status)) {
1187 DEBUG(0, ("Auth Verify failed (%s)\n",
1188 nt_errstr(status)));
1189 goto err_exit;
1191 } else if (NT_STATUS_EQUAL(status,
1192 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1193 DEBUG(10, ("More auth legs required.\n"));
1194 } else {
1195 DEBUG(0, ("Auth step returned an error (%s)\n",
1196 nt_errstr(status)));
1197 goto err_exit;
1201 ZERO_STRUCT(u.alter_resp);
1202 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1203 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1204 u.alter_resp.assoc_group_id = assoc_gid;
1206 /* secondary address CAN be NULL
1207 * as the specs say it's ignored.
1208 * It MUST be NULL to have the spoolss working.
1210 u.alter_resp.secondary_address = "";
1211 u.alter_resp.secondary_address_size = 1;
1213 u.alter_resp.num_results = 1;
1214 u.alter_resp.ctx_list = &alter_ack_ctx;
1216 /* NOTE: We leave the auth_info empty so we can calculate the padding
1217 * later and then append the auth_info --simo */
1220 * Marshall directly into the outgoing PDU space. We
1221 * must do this as we need to set to the bind response
1222 * header and are never sending more than one PDU here.
1225 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1226 DCERPC_PKT_ALTER_RESP,
1227 DCERPC_PFC_FLAG_FIRST |
1228 DCERPC_PFC_FLAG_LAST,
1229 auth_resp.length,
1230 pkt->call_id,
1232 &p->out_data.frag);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 DEBUG(0, ("Failed to marshall alter_resp packet. (%s)\n",
1235 nt_errstr(status)));
1236 goto err_exit;
1239 if (auth_resp.length) {
1240 status = dcerpc_push_dcerpc_auth(pkt,
1241 p->auth.auth_type,
1242 p->auth.auth_level,
1243 0, /* pad_len */
1244 p->auth.auth_context_id,
1245 &auth_resp,
1246 &auth_blob);
1247 if (!NT_STATUS_IS_OK(status)) {
1248 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1249 goto err_exit;
1253 /* Now that we have the auth len store it into the right place in
1254 * the dcerpc header */
1255 dcerpc_set_frag_length(&p->out_data.frag,
1256 p->out_data.frag.length +
1257 auth_blob.length);
1259 if (auth_resp.length) {
1260 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1261 auth_blob.data, auth_blob.length)) {
1262 DEBUG(0, ("Append of auth info failed.\n"));
1263 goto err_exit;
1268 * Setup the lengths for the initial reply.
1271 p->out_data.data_sent_length = 0;
1272 p->out_data.current_pdu_sent = 0;
1274 TALLOC_FREE(auth_blob.data);
1275 return True;
1277 err_exit:
1279 data_blob_free(&p->out_data.frag);
1280 TALLOC_FREE(auth_blob.data);
1281 return setup_bind_nak(p, pkt);
1284 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1285 const struct api_struct *api_rpc_cmds, int n_cmds,
1286 const struct ndr_syntax_id *syntax);
1288 static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
1289 struct ncacn_packet *pkt,
1290 struct pipe_rpc_fns *pipe_fns)
1292 TALLOC_CTX *frame = talloc_stackframe();
1293 struct dcerpc_sec_verification_trailer *vt = NULL;
1294 const uint32_t bitmask1 =
1295 p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1296 const struct dcerpc_sec_vt_pcontext pcontext = {
1297 .abstract_syntax = pipe_fns->syntax,
1298 .transfer_syntax = ndr_transfer_syntax_ndr,
1300 const struct dcerpc_sec_vt_header2 header2 =
1301 dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1302 struct ndr_pull *ndr;
1303 enum ndr_err_code ndr_err;
1304 bool ret = false;
1306 ndr = ndr_pull_init_blob(&p->in_data.data, frame);
1307 if (ndr == NULL) {
1308 goto done;
1311 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
1312 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1313 goto done;
1316 ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1317 &pcontext, &header2);
1318 done:
1319 TALLOC_FREE(frame);
1320 return ret;
1323 /****************************************************************************
1324 Find the correct RPC function to call for this request.
1325 If the pipe is authenticated then become the correct UNIX user
1326 before doing the call.
1327 ****************************************************************************/
1329 static bool api_pipe_request(struct pipes_struct *p,
1330 struct ncacn_packet *pkt)
1332 TALLOC_CTX *frame = talloc_stackframe();
1333 bool ret = False;
1334 struct pipe_rpc_fns *pipe_fns;
1335 const char *interface_name = NULL;
1337 if (!p->pipe_bound) {
1338 DEBUG(1, ("Pipe not bound!\n"));
1339 data_blob_free(&p->out_data.rdata);
1340 TALLOC_FREE(frame);
1341 return false;
1344 /* get the set of RPC functions for this context */
1345 pipe_fns = find_pipe_fns_by_context(p->contexts,
1346 pkt->u.request.context_id);
1347 if (pipe_fns == NULL) {
1348 DEBUG(0, ("No rpc function table associated with context "
1349 "[%d]\n",
1350 pkt->u.request.context_id));
1351 data_blob_free(&p->out_data.rdata);
1352 TALLOC_FREE(frame);
1353 return false;
1356 interface_name = ndr_interface_name(&pipe_fns->syntax.uuid,
1357 pipe_fns->syntax.if_version);
1358 SMB_ASSERT(interface_name != NULL);
1360 switch (p->auth.auth_level) {
1361 case DCERPC_AUTH_LEVEL_NONE:
1362 case DCERPC_AUTH_LEVEL_PACKET:
1363 case DCERPC_AUTH_LEVEL_INTEGRITY:
1364 case DCERPC_AUTH_LEVEL_PRIVACY:
1365 break;
1366 default:
1367 if (!pipe_fns->allow_connect) {
1368 char *addr;
1370 addr = tsocket_address_string(p->remote_address, frame);
1372 DEBUG(1, ("%s: restrict auth_level_connect access "
1373 "to [%s] with auth[type=0x%x,level=0x%x] "
1374 "on [%s] from [%s]\n",
1375 __func__, interface_name,
1376 p->auth.auth_type,
1377 p->auth.auth_level,
1378 derpc_transport_string_by_transport(p->transport),
1379 addr));
1381 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1382 TALLOC_FREE(frame);
1383 return true;
1385 break;
1388 if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
1389 DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
1390 set_incoming_fault(p);
1391 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
1392 data_blob_free(&p->out_data.rdata);
1393 TALLOC_FREE(frame);
1394 return true;
1397 if (!become_authenticated_pipe_user(p->session_info)) {
1398 DEBUG(1, ("Failed to become pipe user!\n"));
1399 data_blob_free(&p->out_data.rdata);
1400 TALLOC_FREE(frame);
1401 return false;
1404 DEBUG(5, ("Requested %s rpc service\n", interface_name));
1406 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1407 &pipe_fns->syntax);
1408 unbecome_authenticated_pipe_user();
1410 TALLOC_FREE(frame);
1411 return ret;
1414 /*******************************************************************
1415 Calls the underlying RPC function for a named pipe.
1416 ********************************************************************/
1418 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1419 const struct api_struct *api_rpc_cmds, int n_cmds,
1420 const struct ndr_syntax_id *syntax)
1422 int fn_num;
1423 uint32_t offset1;
1424 const struct ndr_interface_table *table;
1426 /* interpret the command */
1427 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1428 ndr_interface_name(&syntax->uuid, syntax->if_version),
1429 pkt->u.request.opnum));
1431 table = ndr_table_by_uuid(&syntax->uuid);
1432 if (table == NULL) {
1433 DEBUG(0,("unknown interface\n"));
1434 return false;
1437 if (DEBUGLEVEL >= 50) {
1438 fstring name;
1439 slprintf(name, sizeof(name)-1, "in_%s",
1440 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1441 dump_pdu_region(name, pkt->u.request.opnum,
1442 &p->in_data.data, 0,
1443 p->in_data.data.length);
1446 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1447 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1448 api_rpc_cmds[fn_num].fn != NULL) {
1449 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1450 api_rpc_cmds[fn_num].name));
1451 break;
1455 if (fn_num == n_cmds) {
1457 * For an unknown RPC just return a fault PDU but
1458 * return True to allow RPC's on the pipe to continue
1459 * and not put the pipe into fault state. JRA.
1461 DEBUG(4, ("unknown\n"));
1462 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1463 return True;
1466 offset1 = p->out_data.rdata.length;
1468 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1469 fn_num, api_rpc_cmds[fn_num].fn));
1470 /* do the actual command */
1471 if(!api_rpc_cmds[fn_num].fn(p)) {
1472 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1473 ndr_interface_name(&syntax->uuid, syntax->if_version),
1474 api_rpc_cmds[fn_num].name));
1475 data_blob_free(&p->out_data.rdata);
1476 return False;
1479 if (p->fault_state) {
1480 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1481 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1482 p->fault_state = 0;
1483 return true;
1486 if (DEBUGLEVEL >= 50) {
1487 fstring name;
1488 slprintf(name, sizeof(name)-1, "out_%s",
1489 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
1490 dump_pdu_region(name, pkt->u.request.opnum,
1491 &p->out_data.rdata, offset1,
1492 p->out_data.rdata.length);
1495 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1496 ndr_interface_name(&syntax->uuid, syntax->if_version)));
1498 /* Check for buffer underflow in rpc parsing */
1499 if ((DEBUGLEVEL >= 10) &&
1500 (pkt->frag_length < p->in_data.data.length)) {
1501 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1502 dump_data(10, p->in_data.data.data + pkt->frag_length,
1503 p->in_data.data.length - pkt->frag_length);
1506 return True;
1509 /****************************************************************************
1510 Initialise an outgoing packet.
1511 ****************************************************************************/
1513 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1515 output_data *o_data = &p->out_data;
1517 /* Reset the offset counters. */
1518 o_data->data_sent_length = 0;
1519 o_data->current_pdu_sent = 0;
1521 data_blob_free(&o_data->frag);
1523 /* Free any memory in the current return data buffer. */
1524 data_blob_free(&o_data->rdata);
1526 return True;
1529 /****************************************************************************
1530 Sets the fault state on incoming packets.
1531 ****************************************************************************/
1533 void set_incoming_fault(struct pipes_struct *p)
1535 data_blob_free(&p->in_data.data);
1536 p->in_data.pdu_needed_len = 0;
1537 p->in_data.pdu.length = 0;
1538 p->fault_state = DCERPC_NCA_S_PROTO_ERROR;
1540 p->allow_alter = false;
1541 p->allow_auth3 = false;
1542 p->pipe_bound = false;
1544 DEBUG(10, ("Setting fault state\n"));
1547 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1548 struct ncacn_packet *pkt,
1549 DATA_BLOB *raw_pkt)
1551 NTSTATUS status;
1552 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1554 DEBUG(10, ("Checking request auth.\n"));
1556 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1557 hdr_size += 16;
1560 /* in case of sealing this function will unseal the data in place */
1561 status = dcerpc_check_auth(auth, pkt,
1562 &pkt->u.request.stub_and_verifier,
1563 hdr_size, raw_pkt);
1564 if (!NT_STATUS_IS_OK(status)) {
1565 return status;
1568 return NT_STATUS_OK;
1571 /****************************************************************************
1572 Processes a request pdu. This will do auth processing if needed, and
1573 appends the data into the complete stream if the LAST flag is not set.
1574 ****************************************************************************/
1576 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1578 NTSTATUS status;
1579 DATA_BLOB data;
1580 struct dcerpc_sec_vt_header2 hdr2;
1582 if (!p->pipe_bound) {
1583 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1584 set_incoming_fault(p);
1585 return False;
1589 * We don't ignore DCERPC_PFC_FLAG_PENDING_CANCEL.
1590 * TODO: we can reject it with DCERPC_FAULT_NO_CALL_ACTIVE later.
1592 status = dcerpc_verify_ncacn_packet_header(pkt,
1593 DCERPC_PKT_REQUEST,
1594 pkt->u.request.stub_and_verifier.length,
1595 0, /* required_flags */
1596 DCERPC_PFC_FLAG_FIRST |
1597 DCERPC_PFC_FLAG_LAST |
1598 0x08 | /* this is not defined, but should be ignored */
1599 DCERPC_PFC_FLAG_CONC_MPX |
1600 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1601 DCERPC_PFC_FLAG_MAYBE |
1602 DCERPC_PFC_FLAG_OBJECT_UUID);
1603 if (!NT_STATUS_IS_OK(status)) {
1604 DEBUG(1, ("process_request_pdu: invalid pdu: %s\n",
1605 nt_errstr(status)));
1606 NDR_PRINT_DEBUG(ncacn_packet, pkt);
1607 set_incoming_fault(p);
1608 return false;
1611 hdr2 = dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
1612 if (pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1613 p->header2 = hdr2;
1614 } else {
1615 if (!dcerpc_sec_vt_header2_equal(&hdr2, &p->header2)) {
1616 set_incoming_fault(p);
1617 return false;
1621 /* Store the opnum */
1622 p->opnum = pkt->u.request.opnum;
1624 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1625 if (!NT_STATUS_IS_OK(status)) {
1626 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1627 nt_errstr(status)));
1628 set_incoming_fault(p);
1629 return false;
1632 data = pkt->u.request.stub_and_verifier;
1635 * Check the data length doesn't go over the 15Mb limit.
1636 * increased after observing a bug in the Windows NT 4.0 SP6a
1637 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1638 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1641 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1642 DEBUG(0, ("process_request_pdu: "
1643 "rpc data buffer too large (%u) + (%u)\n",
1644 (unsigned int)p->in_data.data.length,
1645 (unsigned int)data.length));
1646 set_incoming_fault(p);
1647 return False;
1651 * Append the data portion into the buffer and return.
1654 if (data.length) {
1655 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1656 data.data, data.length)) {
1657 DEBUG(0, ("Unable to append data size %u "
1658 "to parse buffer of size %u.\n",
1659 (unsigned int)data.length,
1660 (unsigned int)p->in_data.data.length));
1661 set_incoming_fault(p);
1662 return False;
1666 if (!(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1667 return true;
1671 * Ok - we finally have a complete RPC stream.
1672 * Call the rpc command to process it.
1675 return api_pipe_request(p, pkt);
1678 void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1680 bool reply = false;
1682 /* Store the call_id */
1683 p->call_id = pkt->call_id;
1685 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1687 if (!pipe_init_outgoing_data(p)) {
1688 goto done;
1691 switch (pkt->ptype) {
1692 case DCERPC_PKT_REQUEST:
1693 reply = process_request_pdu(p, pkt);
1694 break;
1696 case DCERPC_PKT_PING: /* CL request - ignore... */
1697 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1698 (unsigned int)pkt->ptype));
1699 break;
1701 case DCERPC_PKT_RESPONSE: /* No responses here. */
1702 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1703 break;
1705 case DCERPC_PKT_FAULT:
1706 case DCERPC_PKT_WORKING:
1707 /* CL request - reply to a ping when a call in process. */
1708 case DCERPC_PKT_NOCALL:
1709 /* CL - server reply to a ping call. */
1710 case DCERPC_PKT_REJECT:
1711 case DCERPC_PKT_ACK:
1712 case DCERPC_PKT_CL_CANCEL:
1713 case DCERPC_PKT_FACK:
1714 case DCERPC_PKT_CANCEL_ACK:
1715 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1716 (unsigned int)pkt->ptype));
1717 break;
1719 case DCERPC_PKT_BIND:
1721 * We assume that a pipe bind is only in one pdu.
1723 reply = api_pipe_bind_req(p, pkt);
1724 break;
1726 case DCERPC_PKT_BIND_ACK:
1727 case DCERPC_PKT_BIND_NAK:
1728 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1729 "packet type %u received.\n",
1730 (unsigned int)pkt->ptype));
1731 break;
1734 case DCERPC_PKT_ALTER:
1736 * We assume that a pipe bind is only in one pdu.
1738 reply = api_pipe_alter_context(p, pkt);
1739 break;
1741 case DCERPC_PKT_ALTER_RESP:
1742 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1743 "Should only be server -> client.\n"));
1744 break;
1746 case DCERPC_PKT_AUTH3:
1748 * The third packet in an auth exchange.
1750 reply = api_pipe_bind_auth3(p, pkt);
1751 break;
1753 case DCERPC_PKT_SHUTDOWN:
1754 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1755 "Should only be server -> client.\n"));
1756 break;
1758 case DCERPC_PKT_CO_CANCEL:
1759 /* For now just free all client data and continue
1760 * processing. */
1761 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1762 " Abandoning rpc call.\n"));
1763 /* As we never do asynchronous RPC serving, we can
1764 * never cancel a call (as far as I know).
1765 * If we ever did we'd have to send a cancel_ack reply.
1766 * For now, just free all client data and continue
1767 * processing. */
1768 reply = True;
1769 break;
1771 #if 0
1772 /* Enable this if we're doing async rpc. */
1773 /* We must check the outstanding callid matches. */
1774 if (pipe_init_outgoing_data(p)) {
1775 /* Send a cancel_ack PDU reply. */
1776 /* We should probably check the auth-verifier here. */
1777 reply = setup_cancel_ack_reply(p, pkt);
1779 break;
1780 #endif
1782 case DCERPC_PKT_ORPHANED:
1783 /* We should probably check the auth-verifier here.
1784 * For now just free all client data and continue
1785 * processing. */
1786 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1787 " Abandoning rpc call.\n"));
1788 reply = True;
1789 break;
1791 default:
1792 DEBUG(0, ("process_complete_pdu: "
1793 "Unknown rpc type = %u received.\n",
1794 (unsigned int)pkt->ptype));
1795 break;
1798 done:
1799 if (!reply) {
1800 DEBUG(3,("DCE/RPC fault sent!"));
1801 set_incoming_fault(p);
1802 setup_fault_pdu(p, NT_STATUS(DCERPC_NCA_S_PROTO_ERROR));
1804 /* pkt and p->in_data.pdu.data freed by caller */