s3:rpc_server: make use of netsec_create_state()
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob49a27b9b0bc0df8e75166983ade0ae4ca4b76e26
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_schannel.h"
34 #include "../librpc/gen_ndr/dcerpc.h"
35 #include "../librpc/rpc/rpc_common.h"
36 #include "../libcli/auth/schannel.h"
37 #include "../libcli/auth/spnego.h"
38 #include "dcesrv_auth_generic.h"
39 #include "rpc_server.h"
40 #include "rpc_dce.h"
41 #include "smbd/smbd.h"
42 #include "auth.h"
43 #include "ntdomain.h"
44 #include "rpc_server/srv_pipe.h"
45 #include "rpc_server/rpc_contexts.h"
46 #include "lib/param/param.h"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_RPC_SRV
51 /**
52 * Dump everything from the start of the end up of the provided data
53 * into a file, but only at debug level >= 50
54 **/
55 static void dump_pdu_region(const char *name, int v,
56 DATA_BLOB *data, size_t start, size_t end)
58 int fd, i;
59 char *fname = NULL;
60 ssize_t sz;
62 if (DEBUGLEVEL < 50) return;
64 if (start > data->length || end > data->length || start > end) return;
66 for (i = 1; i < 100; i++) {
67 if (v != -1) {
68 fname = talloc_asprintf(talloc_tos(),
69 "/tmp/%s_%d.%d.prs",
70 name, v, i);
71 } else {
72 fname = talloc_asprintf(talloc_tos(),
73 "/tmp/%s_%d.prs",
74 name, i);
76 if (!fname) {
77 return;
79 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
80 if (fd != -1 || errno != EEXIST) break;
82 if (fd != -1) {
83 sz = write(fd, data->data + start, end - start);
84 i = close(fd);
85 if ((sz != end - start) || (i != 0) ) {
86 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
87 fname, (unsigned long)sz,
88 (unsigned long)end - start, i));
89 } else {
90 DEBUG(0,("created %s\n", fname));
93 TALLOC_FREE(fname);
96 static DATA_BLOB generic_session_key(void)
98 return data_blob_const("SystemLibraryDTC", 16);
101 /*******************************************************************
102 Generate the next PDU to be returned from the data.
103 ********************************************************************/
105 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
106 struct pipe_auth_data *auth,
107 uint32_t call_id,
108 DATA_BLOB *rdata,
109 size_t data_sent_length,
110 DATA_BLOB *frag,
111 size_t *pdu_size)
113 union dcerpc_payload u;
114 uint8_t pfc_flags;
115 size_t data_left;
116 size_t data_to_send;
117 size_t frag_len;
118 size_t pad_len = 0;
119 size_t auth_len = 0;
120 NTSTATUS status;
122 ZERO_STRUCT(u.response);
124 /* Set up rpc packet pfc flags. */
125 if (data_sent_length == 0) {
126 pfc_flags = DCERPC_PFC_FLAG_FIRST;
127 } else {
128 pfc_flags = 0;
131 /* Work out how much we can fit in a single PDU. */
132 data_left = rdata->length - data_sent_length;
134 /* Ensure there really is data left to send. */
135 if (!data_left) {
136 DEBUG(0, ("No data left to send !\n"));
137 return NT_STATUS_BUFFER_TOO_SMALL;
140 status = dcerpc_guess_sizes(auth,
141 DCERPC_RESPONSE_LENGTH,
142 data_left,
143 RPC_MAX_PDU_FRAG_LEN,
144 SERVER_NDR_PADDING_SIZE,
145 &data_to_send, &frag_len,
146 &auth_len, &pad_len);
147 if (!NT_STATUS_IS_OK(status)) {
148 return status;
151 /* Set up the alloc hint. This should be the data left to send. */
152 u.response.alloc_hint = data_left;
154 /* Work out if this PDU will be the last. */
155 if (data_sent_length + data_to_send >= rdata->length) {
156 pfc_flags |= DCERPC_PFC_FLAG_LAST;
159 /* Prepare data to be NDR encoded. */
160 u.response.stub_and_verifier =
161 data_blob_const(rdata->data + data_sent_length, data_to_send);
163 /* Store the packet in the data stream. */
164 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
165 pfc_flags, auth_len, call_id,
166 &u, frag);
167 if (!NT_STATUS_IS_OK(status)) {
168 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
169 return status;
172 if (auth_len) {
173 /* Set the proper length on the pdu, including padding.
174 * Only needed if an auth trailer will be appended. */
175 dcerpc_set_frag_length(frag, frag->length
176 + pad_len
177 + DCERPC_AUTH_TRAILER_LENGTH
178 + auth_len);
181 if (auth_len) {
182 status = dcerpc_add_auth_footer(auth, pad_len, frag);
183 if (!NT_STATUS_IS_OK(status)) {
184 data_blob_free(frag);
185 return status;
189 *pdu_size = data_to_send;
190 return NT_STATUS_OK;
193 /*******************************************************************
194 Generate the next PDU to be returned from the data in p->rdata.
195 ********************************************************************/
197 bool create_next_pdu(struct pipes_struct *p)
199 size_t pdu_size = 0;
200 NTSTATUS status;
203 * If we're in the fault state, keep returning fault PDU's until
204 * the pipe gets closed. JRA.
206 if (p->fault_state) {
207 setup_fault_pdu(p, NT_STATUS(p->fault_state));
208 return true;
211 status = create_next_packet(p->mem_ctx, &p->auth,
212 p->call_id, &p->out_data.rdata,
213 p->out_data.data_sent_length,
214 &p->out_data.frag, &pdu_size);
215 if (!NT_STATUS_IS_OK(status)) {
216 DEBUG(0, ("Failed to create packet with error %s, "
217 "(auth level %u / type %u)\n",
218 nt_errstr(status),
219 (unsigned int)p->auth.auth_level,
220 (unsigned int)p->auth.auth_type));
221 return false;
224 /* Setup the counts for this PDU. */
225 p->out_data.data_sent_length += pdu_size;
226 p->out_data.current_pdu_sent = 0;
227 return true;
231 static bool pipe_init_outgoing_data(struct pipes_struct *p);
233 /*******************************************************************
234 Marshall a bind_nak pdu.
235 *******************************************************************/
237 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
239 NTSTATUS status;
240 union dcerpc_payload u;
242 /* Free any memory in the current return data buffer. */
243 pipe_init_outgoing_data(p);
246 * Initialize a bind_nak header.
249 ZERO_STRUCT(u);
251 u.bind_nak.reject_reason = 0;
254 * Marshall directly into the outgoing PDU space. We
255 * must do this as we need to set to the bind response
256 * header and are never sending more than one PDU here.
259 status = dcerpc_push_ncacn_packet(p->mem_ctx,
260 DCERPC_PKT_BIND_NAK,
261 DCERPC_PFC_FLAG_FIRST |
262 DCERPC_PFC_FLAG_LAST,
264 pkt->call_id,
266 &p->out_data.frag);
267 if (!NT_STATUS_IS_OK(status)) {
268 return False;
271 p->out_data.data_sent_length = 0;
272 p->out_data.current_pdu_sent = 0;
274 TALLOC_FREE(p->auth.auth_ctx);
275 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
276 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
277 p->pipe_bound = False;
279 return True;
282 /*******************************************************************
283 Marshall a fault pdu.
284 *******************************************************************/
286 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
288 NTSTATUS status;
289 union dcerpc_payload u;
291 /* Free any memory in the current return data buffer. */
292 pipe_init_outgoing_data(p);
295 * Initialize a fault header.
298 ZERO_STRUCT(u);
300 u.fault.status = NT_STATUS_V(fault_status);
301 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
304 * Marshall directly into the outgoing PDU space. We
305 * must do this as we need to set to the bind response
306 * header and are never sending more than one PDU here.
309 status = dcerpc_push_ncacn_packet(p->mem_ctx,
310 DCERPC_PKT_FAULT,
311 DCERPC_PFC_FLAG_FIRST |
312 DCERPC_PFC_FLAG_LAST |
313 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
315 p->call_id,
317 &p->out_data.frag);
318 if (!NT_STATUS_IS_OK(status)) {
319 return False;
322 p->out_data.data_sent_length = 0;
323 p->out_data.current_pdu_sent = 0;
325 return True;
328 /*******************************************************************
329 Ensure a bind request has the correct abstract & transfer interface.
330 Used to reject unknown binds from Win2k.
331 *******************************************************************/
333 static bool check_bind_req(struct pipes_struct *p,
334 struct ndr_syntax_id* abstract,
335 struct ndr_syntax_id* transfer,
336 uint32_t context_id)
338 struct pipe_rpc_fns *context_fns;
339 bool ok;
341 DEBUG(3,("check_bind_req for %s\n",
342 get_pipe_name_from_syntax(talloc_tos(), abstract)));
344 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
345 if (rpc_srv_pipe_exists_by_id(abstract) &&
346 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
347 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
348 rpc_srv_get_pipe_cli_name(abstract),
349 rpc_srv_get_pipe_srv_name(abstract)));
350 } else {
351 return false;
354 ok = init_pipe_handles(p, abstract);
355 if (!ok) {
356 DEBUG(1, ("Failed to init pipe handles!\n"));
357 return false;
360 context_fns = talloc(p, struct pipe_rpc_fns);
361 if (context_fns == NULL) {
362 DEBUG(0,("check_bind_req: talloc() failed!\n"));
363 return false;
366 context_fns->next = context_fns->prev = NULL;
367 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
368 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
369 context_fns->context_id = context_id;
370 context_fns->syntax = *abstract;
372 /* add to the list of open contexts */
374 DLIST_ADD( p->contexts, context_fns );
376 return True;
380 * Is a named pipe known?
381 * @param[in] pipename Just the filename
382 * @result Do we want to serve this?
384 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
386 NTSTATUS status;
388 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
389 DEBUG(10, ("refusing spoolss access\n"));
390 return false;
393 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
394 return true;
397 status = smb_probe_module("rpc", pipename);
398 if (!NT_STATUS_IS_OK(status)) {
399 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
400 return false;
402 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
405 * Scan the list again for the interface id
407 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
408 return true;
411 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
412 pipename));
414 return false;
417 /*******************************************************************
418 Handle an schannel bind auth.
419 *******************************************************************/
421 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
422 TALLOC_CTX *mem_ctx,
423 struct dcerpc_auth *auth_info,
424 DATA_BLOB *response)
426 struct NL_AUTH_MESSAGE neg;
427 struct NL_AUTH_MESSAGE reply;
428 bool ret;
429 NTSTATUS status;
430 struct netlogon_creds_CredentialState *creds;
431 enum ndr_err_code ndr_err;
432 struct schannel_state *schannel_auth;
433 struct loadparm_context *lp_ctx;
435 ndr_err = ndr_pull_struct_blob(
436 &auth_info->credentials, mem_ctx, &neg,
437 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
438 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
439 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
440 return false;
443 if (DEBUGLEVEL >= 10) {
444 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
447 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
448 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
449 return false;
452 lp_ctx = loadparm_init_s3(p, loadparm_s3_helpers());
453 if (!lp_ctx) {
454 DEBUG(0,("pipe_schannel_auth_bind: loadparm_init_s3() failed!\n"));
455 return false;
459 * The neg.oem_netbios_computer.a key here must match the remote computer name
460 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
461 * operations that use credentials.
464 become_root();
465 status = schannel_get_creds_state(p->mem_ctx, lp_ctx,
466 neg.oem_netbios_computer.a, &creds);
467 unbecome_root();
469 talloc_unlink(p, lp_ctx);
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
472 return False;
475 schannel_auth = netsec_create_state(p, creds, false /* not initiator */);
476 TALLOC_FREE(creds);
477 if (!schannel_auth) {
478 return False;
482 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
483 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
484 * struct of the person who opened the pipe. I need to test this further. JRA.
486 * VL. As we are mapping this to guest set the generic key
487 * "SystemLibraryDTC" key here. It's a bit difficult to test against
488 * W2k3, as it does not allow schannel binds against SAMR and LSA
489 * anymore.
492 ret = session_info_set_session_key(p->session_info, generic_session_key());
494 if (!ret) {
495 DEBUG(0, ("session_info_set_session_key failed\n"));
496 return false;
499 /*** SCHANNEL verifier ***/
501 reply.MessageType = NL_NEGOTIATE_RESPONSE;
502 reply.Flags = 0;
503 reply.Buffer.dummy = 5; /* ??? actually I don't think
504 * this has any meaning
505 * here - gd */
507 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
508 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
509 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
510 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
511 return false;
514 if (DEBUGLEVEL >= 10) {
515 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
518 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
519 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
521 /* We're finished with this bind - no more packets. */
522 p->auth.auth_ctx = schannel_auth;
523 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
525 p->pipe_bound = True;
527 return True;
530 /*******************************************************************
531 Handle an NTLMSSP bind auth.
532 *******************************************************************/
534 static bool pipe_auth_generic_bind(struct pipes_struct *p,
535 TALLOC_CTX *mem_ctx,
536 struct dcerpc_auth *auth_info,
537 DATA_BLOB *response)
539 struct gensec_security *gensec_security = NULL;
540 NTSTATUS status;
542 status = auth_generic_server_authtype_start(p,
543 auth_info->auth_type,
544 auth_info->auth_level,
545 &auth_info->credentials,
546 response,
547 p->remote_address,
548 &gensec_security);
549 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
550 DEBUG(0, (__location__ ": auth_generic_server_authtype_start failed: %s\n",
551 nt_errstr(status)));
552 return false;
555 /* Make sure data is bound to the memctx, to be freed the caller */
556 talloc_steal(mem_ctx, response->data);
558 p->auth.auth_ctx = gensec_security;
559 p->auth.auth_type = auth_info->auth_type;
561 return true;
564 /*******************************************************************
565 Process an NTLMSSP authentication response.
566 If this function succeeds, the user has been authenticated
567 and their domain, name and calling workstation stored in
568 the pipe struct.
569 *******************************************************************/
571 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
572 struct gensec_security *gensec_security,
573 enum dcerpc_AuthLevel auth_level,
574 struct auth_session_info **session_info)
576 NTSTATUS status;
577 bool ret;
579 DEBUG(5, (__location__ ": checking user details\n"));
581 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
582 ensure the underlying NTLMSSP flags are also set. If not we should
583 refuse the bind. */
585 status = auth_generic_server_check_flags(gensec_security,
586 (auth_level ==
587 DCERPC_AUTH_LEVEL_INTEGRITY),
588 (auth_level ==
589 DCERPC_AUTH_LEVEL_PRIVACY));
590 if (!NT_STATUS_IS_OK(status)) {
591 DEBUG(0, (__location__ ": Client failed to negotatie proper "
592 "security for rpc connection\n"));
593 return false;
596 TALLOC_FREE(*session_info);
598 status = auth_generic_server_get_user_info(gensec_security,
599 mem_ctx, session_info);
600 if (!NT_STATUS_IS_OK(status)) {
601 DEBUG(0, (__location__ ": failed to obtain the server info "
602 "for authenticated user: %s\n", nt_errstr(status)));
603 return false;
606 if ((*session_info)->security_token == NULL) {
607 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
608 return false;
612 * We're an authenticated bind over smb, so the session key needs to
613 * be set to "SystemLibraryDTC". Weird, but this is what Windows
614 * does. See the RPC-SAMBA3SESSIONKEY.
617 ret = session_info_set_session_key((*session_info), generic_session_key());
618 if (!ret) {
619 DEBUG(0, ("Failed to set session key!\n"));
620 return false;
623 return true;
626 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
628 struct gensec_security *gensec_security;
630 switch (p->auth.auth_type) {
631 case DCERPC_AUTH_TYPE_NTLMSSP:
632 case DCERPC_AUTH_TYPE_KRB5:
633 case DCERPC_AUTH_TYPE_SPNEGO:
634 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
635 struct gensec_security);
636 if (!pipe_auth_generic_verify_final(p, gensec_security,
637 p->auth.auth_level,
638 &p->session_info)) {
639 return NT_STATUS_ACCESS_DENIED;
641 break;
642 default:
643 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
644 (unsigned int)p->auth.auth_type));
645 return NT_STATUS_ACCESS_DENIED;
648 p->pipe_bound = true;
650 return NT_STATUS_OK;
653 /*******************************************************************
654 Respond to a pipe bind request.
655 *******************************************************************/
657 static bool api_pipe_bind_req(struct pipes_struct *p,
658 struct ncacn_packet *pkt)
660 struct dcerpc_auth auth_info;
661 uint16 assoc_gid;
662 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
663 NTSTATUS status;
664 struct ndr_syntax_id id;
665 union dcerpc_payload u;
666 struct dcerpc_ack_ctx bind_ack_ctx;
667 DATA_BLOB auth_resp = data_blob_null;
668 DATA_BLOB auth_blob = data_blob_null;
670 /* No rebinds on a bound pipe - use alter context. */
671 if (p->pipe_bound) {
672 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
673 return setup_bind_nak(p, pkt);
676 if (pkt->u.bind.num_contexts == 0) {
677 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
678 goto err_exit;
682 * Try and find the correct pipe name to ensure
683 * that this is a pipe name we support.
685 id = pkt->u.bind.ctx_list[0].abstract_syntax;
686 if (rpc_srv_pipe_exists_by_id(&id)) {
687 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
688 rpc_srv_get_pipe_cli_name(&id),
689 rpc_srv_get_pipe_srv_name(&id)));
690 } else {
691 status = smb_probe_module(
692 "rpc", get_pipe_name_from_syntax(
693 talloc_tos(),
694 &id));
696 if (NT_STATUS_IS_ERR(status)) {
697 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
698 "%s in bind request.\n",
699 get_pipe_name_from_syntax(talloc_tos(), &id)));
701 return setup_bind_nak(p, pkt);
704 if (rpc_srv_get_pipe_interface_by_cli_name(
705 get_pipe_name_from_syntax(talloc_tos(),
706 &id),
707 &id)) {
708 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
709 rpc_srv_get_pipe_cli_name(&id),
710 rpc_srv_get_pipe_srv_name(&id)));
711 } else {
712 DEBUG(0, ("module %s doesn't provide functions for "
713 "pipe %s!\n",
714 get_pipe_name_from_syntax(talloc_tos(), &id),
715 get_pipe_name_from_syntax(talloc_tos(), &id)));
716 return setup_bind_nak(p, pkt);
720 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
722 if (pkt->u.bind.assoc_group_id != 0) {
723 assoc_gid = pkt->u.bind.assoc_group_id;
724 } else {
725 assoc_gid = 0x53f0;
729 * Create the bind response struct.
732 /* If the requested abstract synt uuid doesn't match our client pipe,
733 reject the bind_ack & set the transfer interface synt to all 0's,
734 ver 0 (observed when NT5 attempts to bind to abstract interfaces
735 unknown to NT4)
736 Needed when adding entries to a DACL from NT5 - SK */
738 if (check_bind_req(p,
739 &pkt->u.bind.ctx_list[0].abstract_syntax,
740 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
741 pkt->u.bind.ctx_list[0].context_id)) {
743 bind_ack_ctx.result = 0;
744 bind_ack_ctx.reason = 0;
745 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
746 } else {
747 p->pipe_bound = False;
748 /* Rejection reason: abstract syntax not supported */
749 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
750 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
751 bind_ack_ctx.syntax = ndr_syntax_id_null;
755 * Check if this is an authenticated bind request.
757 if (pkt->auth_length) {
758 /* Quick length check. Won't catch a bad auth footer,
759 * prevents overrun. */
761 if (pkt->frag_length < RPC_HEADER_LEN +
762 DCERPC_AUTH_TRAILER_LENGTH +
763 pkt->auth_length) {
764 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
765 "too long for fragment %u.\n",
766 (unsigned int)pkt->auth_length,
767 (unsigned int)pkt->frag_length));
768 goto err_exit;
772 * Decode the authentication verifier.
774 status = dcerpc_pull_dcerpc_auth(pkt,
775 &pkt->u.bind.auth_info,
776 &auth_info, p->endian);
777 if (!NT_STATUS_IS_OK(status)) {
778 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
779 goto err_exit;
782 auth_type = auth_info.auth_type;
784 /* Work out if we have to sign or seal etc. */
785 switch (auth_info.auth_level) {
786 case DCERPC_AUTH_LEVEL_INTEGRITY:
787 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
788 break;
789 case DCERPC_AUTH_LEVEL_PRIVACY:
790 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
791 break;
792 case DCERPC_AUTH_LEVEL_CONNECT:
793 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
794 break;
795 default:
796 DEBUG(0, ("Unexpected auth level (%u).\n",
797 (unsigned int)auth_info.auth_level ));
798 goto err_exit;
801 switch (auth_type) {
802 case DCERPC_AUTH_TYPE_NTLMSSP:
803 if (!pipe_auth_generic_bind(p, pkt,
804 &auth_info, &auth_resp)) {
805 goto err_exit;
807 assoc_gid = 0x7a77;
808 break;
810 case DCERPC_AUTH_TYPE_SCHANNEL:
811 if (!pipe_schannel_auth_bind(p, pkt,
812 &auth_info, &auth_resp)) {
813 goto err_exit;
815 break;
817 case DCERPC_AUTH_TYPE_SPNEGO:
818 case DCERPC_AUTH_TYPE_KRB5:
819 if (!pipe_auth_generic_bind(p, pkt,
820 &auth_info, &auth_resp)) {
821 goto err_exit;
823 break;
825 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
826 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
827 TALLOC_FREE(p->session_info);
829 status = make_session_info_system(p,
830 &p->session_info);
831 if (!NT_STATUS_IS_OK(status)) {
832 goto err_exit;
835 auth_resp = data_blob_talloc(pkt,
836 "NCALRPC_AUTH_OK",
837 15);
839 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
840 p->pipe_bound = true;
841 } else {
842 goto err_exit;
844 break;
846 case DCERPC_AUTH_TYPE_NONE:
847 break;
849 default:
850 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
851 goto err_exit;
855 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
856 /* Unauthenticated bind request. */
857 /* We're finished - no more packets. */
858 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
859 /* We must set the pipe auth_level here also. */
860 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
861 p->pipe_bound = True;
862 /* The session key was initialized from the SMB
863 * session in make_internal_rpc_pipe_p */
866 ZERO_STRUCT(u.bind_ack);
867 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
868 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
869 u.bind_ack.assoc_group_id = assoc_gid;
871 /* name has to be \PIPE\xxxxx */
872 u.bind_ack.secondary_address =
873 talloc_asprintf(pkt, "\\PIPE\\%s",
874 rpc_srv_get_pipe_srv_name(&id));
875 if (!u.bind_ack.secondary_address) {
876 DEBUG(0, ("Out of memory!\n"));
877 goto err_exit;
879 u.bind_ack.secondary_address_size =
880 strlen(u.bind_ack.secondary_address) + 1;
882 u.bind_ack.num_results = 1;
883 u.bind_ack.ctx_list = &bind_ack_ctx;
885 /* NOTE: We leave the auth_info empty so we can calculate the padding
886 * later and then append the auth_info --simo */
889 * Marshall directly into the outgoing PDU space. We
890 * must do this as we need to set to the bind response
891 * header and are never sending more than one PDU here.
894 status = dcerpc_push_ncacn_packet(p->mem_ctx,
895 DCERPC_PKT_BIND_ACK,
896 DCERPC_PFC_FLAG_FIRST |
897 DCERPC_PFC_FLAG_LAST,
898 auth_resp.length,
899 pkt->call_id,
901 &p->out_data.frag);
902 if (!NT_STATUS_IS_OK(status)) {
903 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
904 nt_errstr(status)));
907 if (auth_resp.length) {
909 status = dcerpc_push_dcerpc_auth(pkt,
910 auth_type,
911 auth_info.auth_level,
913 1, /* auth_context_id */
914 &auth_resp,
915 &auth_blob);
916 if (!NT_STATUS_IS_OK(status)) {
917 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
918 goto err_exit;
922 /* Now that we have the auth len store it into the right place in
923 * the dcerpc header */
924 dcerpc_set_frag_length(&p->out_data.frag,
925 p->out_data.frag.length + auth_blob.length);
927 if (auth_blob.length) {
929 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
930 auth_blob.data, auth_blob.length)) {
931 DEBUG(0, ("Append of auth info failed.\n"));
932 goto err_exit;
937 * Setup the lengths for the initial reply.
940 p->out_data.data_sent_length = 0;
941 p->out_data.current_pdu_sent = 0;
943 TALLOC_FREE(auth_blob.data);
944 return True;
946 err_exit:
948 data_blob_free(&p->out_data.frag);
949 TALLOC_FREE(auth_blob.data);
950 return setup_bind_nak(p, pkt);
953 /*******************************************************************
954 This is the "stage3" response after a bind request and reply.
955 *******************************************************************/
957 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
959 struct dcerpc_auth auth_info;
960 DATA_BLOB response = data_blob_null;
961 struct gensec_security *gensec_security;
962 NTSTATUS status;
964 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
966 if (pkt->auth_length == 0) {
967 DEBUG(1, ("No auth field sent for bind request!\n"));
968 goto err;
971 /* Ensure there's enough data for an authenticated request. */
972 if (pkt->frag_length < RPC_HEADER_LEN
973 + DCERPC_AUTH_TRAILER_LENGTH
974 + pkt->auth_length) {
975 DEBUG(1,("api_pipe_ntlmssp_auth_process: auth_len "
976 "%u is too large.\n",
977 (unsigned int)pkt->auth_length));
978 goto err;
982 * Decode the authentication verifier response.
985 status = dcerpc_pull_dcerpc_auth(pkt,
986 &pkt->u.auth3.auth_info,
987 &auth_info, p->endian);
988 if (!NT_STATUS_IS_OK(status)) {
989 DEBUG(1, ("Failed to unmarshall dcerpc_auth.\n"));
990 goto err;
993 /* We must NEVER look at auth_info->auth_pad_len here,
994 * as old Samba client code gets it wrong and sends it
995 * as zero. JRA.
998 if (auth_info.auth_type != p->auth.auth_type) {
999 DEBUG(1, ("Auth type mismatch! Client sent %d, "
1000 "but auth was started as type %d!\n",
1001 auth_info.auth_type, p->auth.auth_type));
1002 goto err;
1005 switch (auth_info.auth_type) {
1006 case DCERPC_AUTH_TYPE_NTLMSSP:
1007 case DCERPC_AUTH_TYPE_KRB5:
1008 case DCERPC_AUTH_TYPE_SPNEGO:
1009 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1010 struct gensec_security);
1011 status = auth_generic_server_step(gensec_security,
1012 pkt, &auth_info.credentials,
1013 &response);
1014 break;
1015 default:
1016 DEBUG(1, (__location__ ": incorrect auth type (%u).\n",
1017 (unsigned int)auth_info.auth_type));
1018 return false;
1021 if (NT_STATUS_EQUAL(status,
1022 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1023 response.length) {
1024 DEBUG(1, (__location__ ": This was supposed to be the final "
1025 "leg, but crypto machinery claims a response is "
1026 "needed, aborting auth!\n"));
1027 data_blob_free(&response);
1028 goto err;
1030 if (!NT_STATUS_IS_OK(status)) {
1031 DEBUG(2, ("Auth failed (%s)\n", nt_errstr(status)));
1032 goto err;
1035 /* Now verify auth was indeed successful and extract server info */
1036 status = pipe_auth_verify_final(p);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 DEBUG(2, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1039 goto err;
1042 return true;
1044 err:
1046 TALLOC_FREE(p->auth.auth_ctx);
1047 return false;
1050 /****************************************************************************
1051 Deal with an alter context call. Can be third part of 3 leg auth request for
1052 SPNEGO calls.
1053 ****************************************************************************/
1055 static bool api_pipe_alter_context(struct pipes_struct *p,
1056 struct ncacn_packet *pkt)
1058 struct dcerpc_auth auth_info;
1059 uint16 assoc_gid;
1060 NTSTATUS status;
1061 union dcerpc_payload u;
1062 struct dcerpc_ack_ctx bind_ack_ctx;
1063 DATA_BLOB auth_resp = data_blob_null;
1064 DATA_BLOB auth_blob = data_blob_null;
1065 int pad_len = 0;
1066 struct gensec_security *gensec_security;
1068 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1070 if (pkt->u.bind.assoc_group_id != 0) {
1071 assoc_gid = pkt->u.bind.assoc_group_id;
1072 } else {
1073 assoc_gid = 0x53f0;
1077 * Create the bind response struct.
1080 /* If the requested abstract synt uuid doesn't match our client pipe,
1081 reject the bind_ack & set the transfer interface synt to all 0's,
1082 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1083 unknown to NT4)
1084 Needed when adding entries to a DACL from NT5 - SK */
1086 if (check_bind_req(p,
1087 &pkt->u.bind.ctx_list[0].abstract_syntax,
1088 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1089 pkt->u.bind.ctx_list[0].context_id)) {
1091 bind_ack_ctx.result = 0;
1092 bind_ack_ctx.reason = 0;
1093 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1094 } else {
1095 p->pipe_bound = False;
1096 /* Rejection reason: abstract syntax not supported */
1097 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1098 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1099 bind_ack_ctx.syntax = ndr_syntax_id_null;
1103 * Check if this is an authenticated alter context request.
1105 if (pkt->auth_length) {
1106 /* Quick length check. Won't catch a bad auth footer,
1107 * prevents overrun. */
1109 if (pkt->frag_length < RPC_HEADER_LEN +
1110 DCERPC_AUTH_TRAILER_LENGTH +
1111 pkt->auth_length) {
1112 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1113 "too long for fragment %u.\n",
1114 (unsigned int)pkt->auth_length,
1115 (unsigned int)pkt->frag_length ));
1116 goto err_exit;
1119 status = dcerpc_pull_dcerpc_auth(pkt,
1120 &pkt->u.bind.auth_info,
1121 &auth_info, p->endian);
1122 if (!NT_STATUS_IS_OK(status)) {
1123 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1124 goto err_exit;
1127 /* We can only finish if the pipe is unbound for now */
1128 if (p->pipe_bound) {
1129 DEBUG(0, (__location__ ": Pipe already bound, "
1130 "Altering Context not yet supported!\n"));
1131 goto err_exit;
1134 if (auth_info.auth_type != p->auth.auth_type) {
1135 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1136 "but auth was started as type %d!\n",
1137 auth_info.auth_type, p->auth.auth_type));
1138 goto err_exit;
1142 switch (auth_info.auth_type) {
1143 case DCERPC_AUTH_TYPE_SPNEGO:
1144 case DCERPC_AUTH_TYPE_KRB5:
1145 case DCERPC_AUTH_TYPE_NTLMSSP:
1146 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1147 struct gensec_security);
1148 status = auth_generic_server_step(gensec_security,
1149 pkt,
1150 &auth_info.credentials,
1151 &auth_resp);
1152 break;
1154 default:
1155 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1156 "in alter-context call\n",
1157 auth_info.auth_type));
1158 goto err_exit;
1161 if (NT_STATUS_IS_OK(status)) {
1162 /* third leg of auth, verify auth info */
1163 status = pipe_auth_verify_final(p);
1164 if (!NT_STATUS_IS_OK(status)) {
1165 DEBUG(0, ("Auth Verify failed (%s)\n",
1166 nt_errstr(status)));
1167 goto err_exit;
1169 } else if (NT_STATUS_EQUAL(status,
1170 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1171 DEBUG(10, ("More auth legs required.\n"));
1172 } else {
1173 DEBUG(0, ("Auth step returned an error (%s)\n",
1174 nt_errstr(status)));
1175 goto err_exit;
1179 ZERO_STRUCT(u.alter_resp);
1180 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1181 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1182 u.alter_resp.assoc_group_id = assoc_gid;
1184 /* secondary address CAN be NULL
1185 * as the specs say it's ignored.
1186 * It MUST be NULL to have the spoolss working.
1188 u.alter_resp.secondary_address = "";
1189 u.alter_resp.secondary_address_size = 1;
1191 u.alter_resp.num_results = 1;
1192 u.alter_resp.ctx_list = &bind_ack_ctx;
1194 /* NOTE: We leave the auth_info empty so we can calculate the padding
1195 * later and then append the auth_info --simo */
1198 * Marshall directly into the outgoing PDU space. We
1199 * must do this as we need to set to the bind response
1200 * header and are never sending more than one PDU here.
1203 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1204 DCERPC_PKT_ALTER_RESP,
1205 DCERPC_PFC_FLAG_FIRST |
1206 DCERPC_PFC_FLAG_LAST,
1207 auth_resp.length,
1208 pkt->call_id,
1210 &p->out_data.frag);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1213 nt_errstr(status)));
1216 if (auth_resp.length) {
1218 /* Work out any padding needed before the auth footer. */
1219 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1220 if (pad_len) {
1221 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1222 DEBUG(10, ("auth pad_len = %u\n",
1223 (unsigned int)pad_len));
1226 status = dcerpc_push_dcerpc_auth(pkt,
1227 auth_info.auth_type,
1228 auth_info.auth_level,
1229 pad_len,
1230 1, /* auth_context_id */
1231 &auth_resp,
1232 &auth_blob);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1235 goto err_exit;
1239 /* Now that we have the auth len store it into the right place in
1240 * the dcerpc header */
1241 dcerpc_set_frag_length(&p->out_data.frag,
1242 p->out_data.frag.length +
1243 pad_len + auth_blob.length);
1245 if (auth_resp.length) {
1246 if (pad_len) {
1247 char pad[SERVER_NDR_PADDING_SIZE];
1248 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1249 if (!data_blob_append(p->mem_ctx,
1250 &p->out_data.frag,
1251 pad, pad_len)) {
1252 DEBUG(0, ("api_pipe_bind_req: failed to add "
1253 "%u bytes of pad data.\n",
1254 (unsigned int)pad_len));
1255 goto err_exit;
1259 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1260 auth_blob.data, auth_blob.length)) {
1261 DEBUG(0, ("Append of auth info failed.\n"));
1262 goto err_exit;
1267 * Setup the lengths for the initial reply.
1270 p->out_data.data_sent_length = 0;
1271 p->out_data.current_pdu_sent = 0;
1273 TALLOC_FREE(auth_blob.data);
1274 return True;
1276 err_exit:
1278 data_blob_free(&p->out_data.frag);
1279 TALLOC_FREE(auth_blob.data);
1280 return setup_bind_nak(p, pkt);
1283 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1284 const struct api_struct *api_rpc_cmds, int n_cmds,
1285 const struct ndr_syntax_id *syntax);
1287 /****************************************************************************
1288 Find the correct RPC function to call for this request.
1289 If the pipe is authenticated then become the correct UNIX user
1290 before doing the call.
1291 ****************************************************************************/
1293 static bool api_pipe_request(struct pipes_struct *p,
1294 struct ncacn_packet *pkt)
1296 bool ret = False;
1297 struct pipe_rpc_fns *pipe_fns;
1299 if (!p->pipe_bound) {
1300 DEBUG(1, ("Pipe not bound!\n"));
1301 data_blob_free(&p->out_data.rdata);
1302 return false;
1305 if (!become_authenticated_pipe_user(p->session_info)) {
1306 DEBUG(1, ("Failed to become pipe user!\n"));
1307 data_blob_free(&p->out_data.rdata);
1308 return false;
1311 /* get the set of RPC functions for this context */
1313 pipe_fns = find_pipe_fns_by_context(p->contexts,
1314 pkt->u.request.context_id);
1316 if ( pipe_fns ) {
1317 TALLOC_CTX *frame = talloc_stackframe();
1319 DEBUG(5, ("Requested %s rpc service\n",
1320 get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
1322 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1323 &pipe_fns->syntax);
1325 TALLOC_FREE(frame);
1327 else {
1328 DEBUG(0, ("No rpc function table associated with context "
1329 "[%d]\n",
1330 pkt->u.request.context_id));
1333 unbecome_authenticated_pipe_user();
1335 return ret;
1338 /*******************************************************************
1339 Calls the underlying RPC function for a named pipe.
1340 ********************************************************************/
1342 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1343 const struct api_struct *api_rpc_cmds, int n_cmds,
1344 const struct ndr_syntax_id *syntax)
1346 int fn_num;
1347 uint32_t offset1;
1349 /* interpret the command */
1350 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1351 get_pipe_name_from_syntax(talloc_tos(), syntax),
1352 pkt->u.request.opnum));
1354 if (DEBUGLEVEL >= 50) {
1355 fstring name;
1356 slprintf(name, sizeof(name)-1, "in_%s",
1357 get_pipe_name_from_syntax(talloc_tos(), syntax));
1358 dump_pdu_region(name, pkt->u.request.opnum,
1359 &p->in_data.data, 0,
1360 p->in_data.data.length);
1363 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1364 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1365 api_rpc_cmds[fn_num].fn != NULL) {
1366 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1367 api_rpc_cmds[fn_num].name));
1368 break;
1372 if (fn_num == n_cmds) {
1374 * For an unknown RPC just return a fault PDU but
1375 * return True to allow RPC's on the pipe to continue
1376 * and not put the pipe into fault state. JRA.
1378 DEBUG(4, ("unknown\n"));
1379 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1380 return True;
1383 offset1 = p->out_data.rdata.length;
1385 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1386 fn_num, api_rpc_cmds[fn_num].fn));
1387 /* do the actual command */
1388 if(!api_rpc_cmds[fn_num].fn(p)) {
1389 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1390 get_pipe_name_from_syntax(talloc_tos(), syntax),
1391 api_rpc_cmds[fn_num].name));
1392 data_blob_free(&p->out_data.rdata);
1393 return False;
1396 if (p->fault_state) {
1397 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1398 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1399 p->fault_state = 0;
1400 return true;
1403 if (DEBUGLEVEL >= 50) {
1404 fstring name;
1405 slprintf(name, sizeof(name)-1, "out_%s",
1406 get_pipe_name_from_syntax(talloc_tos(), syntax));
1407 dump_pdu_region(name, pkt->u.request.opnum,
1408 &p->out_data.rdata, offset1,
1409 p->out_data.rdata.length);
1412 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1413 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1415 /* Check for buffer underflow in rpc parsing */
1416 if ((DEBUGLEVEL >= 10) &&
1417 (pkt->frag_length < p->in_data.data.length)) {
1418 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1419 dump_data(10, p->in_data.data.data + pkt->frag_length,
1420 p->in_data.data.length - pkt->frag_length);
1423 return True;
1426 /****************************************************************************
1427 Initialise an outgoing packet.
1428 ****************************************************************************/
1430 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1432 output_data *o_data = &p->out_data;
1434 /* Reset the offset counters. */
1435 o_data->data_sent_length = 0;
1436 o_data->current_pdu_sent = 0;
1438 data_blob_free(&o_data->frag);
1440 /* Free any memory in the current return data buffer. */
1441 data_blob_free(&o_data->rdata);
1443 return True;
1446 /****************************************************************************
1447 Sets the fault state on incoming packets.
1448 ****************************************************************************/
1450 void set_incoming_fault(struct pipes_struct *p)
1452 data_blob_free(&p->in_data.data);
1453 p->in_data.pdu_needed_len = 0;
1454 p->in_data.pdu.length = 0;
1455 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1457 DEBUG(10, ("Setting fault state\n"));
1460 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1461 struct ncacn_packet *pkt,
1462 DATA_BLOB *raw_pkt)
1464 NTSTATUS status;
1465 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1466 size_t pad_len;
1468 DEBUG(10, ("Checking request auth.\n"));
1470 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1471 hdr_size += 16;
1474 /* in case of sealing this function will unseal the data in place */
1475 status = dcerpc_check_auth(auth, pkt,
1476 &pkt->u.request.stub_and_verifier,
1477 hdr_size, raw_pkt,
1478 &pad_len);
1479 if (!NT_STATUS_IS_OK(status)) {
1480 return status;
1484 /* remove padding and auth trailer,
1485 * this way the caller will get just the data */
1486 if (pkt->auth_length) {
1487 size_t trail_len = pad_len
1488 + DCERPC_AUTH_TRAILER_LENGTH
1489 + pkt->auth_length;
1490 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1491 return NT_STATUS_INFO_LENGTH_MISMATCH;
1493 pkt->u.request.stub_and_verifier.length -= trail_len;
1496 return NT_STATUS_OK;
1499 /****************************************************************************
1500 Processes a request pdu. This will do auth processing if needed, and
1501 appends the data into the complete stream if the LAST flag is not set.
1502 ****************************************************************************/
1504 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1506 NTSTATUS status;
1507 DATA_BLOB data;
1509 if (!p->pipe_bound) {
1510 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1511 set_incoming_fault(p);
1512 return False;
1515 /* Store the opnum */
1516 p->opnum = pkt->u.request.opnum;
1518 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1521 nt_errstr(status)));
1522 set_incoming_fault(p);
1523 return false;
1526 data = pkt->u.request.stub_and_verifier;
1529 * Check the data length doesn't go over the 15Mb limit.
1530 * increased after observing a bug in the Windows NT 4.0 SP6a
1531 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1532 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1535 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1536 DEBUG(0, ("process_request_pdu: "
1537 "rpc data buffer too large (%u) + (%u)\n",
1538 (unsigned int)p->in_data.data.length,
1539 (unsigned int)data.length));
1540 set_incoming_fault(p);
1541 return False;
1545 * Append the data portion into the buffer and return.
1548 if (data.length) {
1549 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1550 data.data, data.length)) {
1551 DEBUG(0, ("Unable to append data size %u "
1552 "to parse buffer of size %u.\n",
1553 (unsigned int)data.length,
1554 (unsigned int)p->in_data.data.length));
1555 set_incoming_fault(p);
1556 return False;
1560 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1561 bool ret = False;
1563 * Ok - we finally have a complete RPC stream.
1564 * Call the rpc command to process it.
1568 * Process the complete data stream here.
1570 if (pipe_init_outgoing_data(p)) {
1571 ret = api_pipe_request(p, pkt);
1574 return ret;
1577 return True;
1580 /****************************************************************************
1581 Processes a finished PDU stored in p->in_data.pdu.
1582 ****************************************************************************/
1584 void process_complete_pdu(struct pipes_struct *p)
1586 struct ncacn_packet *pkt = NULL;
1587 NTSTATUS status;
1588 bool reply = False;
1590 if(p->fault_state) {
1591 DEBUG(10,("RPC connection in fault state.\n"));
1592 goto done;
1595 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1596 if (!pkt) {
1597 DEBUG(0, ("Out of memory!\n"));
1598 goto done;
1602 * Ensure we're using the corrent endianness for both the
1603 * RPC header flags and the raw data we will be reading from.
1605 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1606 p->endian = RPC_LITTLE_ENDIAN;
1607 } else {
1608 p->endian = RPC_BIG_ENDIAN;
1610 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1612 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1613 pkt, p->endian);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1616 nt_errstr(status)));
1617 goto done;
1620 /* Store the call_id */
1621 p->call_id = pkt->call_id;
1623 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1625 switch (pkt->ptype) {
1626 case DCERPC_PKT_REQUEST:
1627 reply = process_request_pdu(p, pkt);
1628 break;
1630 case DCERPC_PKT_PING: /* CL request - ignore... */
1631 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1632 (unsigned int)pkt->ptype));
1633 break;
1635 case DCERPC_PKT_RESPONSE: /* No responses here. */
1636 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1637 break;
1639 case DCERPC_PKT_FAULT:
1640 case DCERPC_PKT_WORKING:
1641 /* CL request - reply to a ping when a call in process. */
1642 case DCERPC_PKT_NOCALL:
1643 /* CL - server reply to a ping call. */
1644 case DCERPC_PKT_REJECT:
1645 case DCERPC_PKT_ACK:
1646 case DCERPC_PKT_CL_CANCEL:
1647 case DCERPC_PKT_FACK:
1648 case DCERPC_PKT_CANCEL_ACK:
1649 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1650 (unsigned int)pkt->ptype));
1651 break;
1653 case DCERPC_PKT_BIND:
1655 * We assume that a pipe bind is only in one pdu.
1657 if (pipe_init_outgoing_data(p)) {
1658 reply = api_pipe_bind_req(p, pkt);
1660 break;
1662 case DCERPC_PKT_BIND_ACK:
1663 case DCERPC_PKT_BIND_NAK:
1664 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1665 "packet type %u received.\n",
1666 (unsigned int)pkt->ptype));
1667 break;
1670 case DCERPC_PKT_ALTER:
1672 * We assume that a pipe bind is only in one pdu.
1674 if (pipe_init_outgoing_data(p)) {
1675 reply = api_pipe_alter_context(p, pkt);
1677 break;
1679 case DCERPC_PKT_ALTER_RESP:
1680 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1681 "Should only be server -> client.\n"));
1682 break;
1684 case DCERPC_PKT_AUTH3:
1686 * The third packet in an auth exchange.
1688 if (pipe_init_outgoing_data(p)) {
1689 reply = api_pipe_bind_auth3(p, pkt);
1691 break;
1693 case DCERPC_PKT_SHUTDOWN:
1694 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1695 "Should only be server -> client.\n"));
1696 break;
1698 case DCERPC_PKT_CO_CANCEL:
1699 /* For now just free all client data and continue
1700 * processing. */
1701 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1702 " Abandoning rpc call.\n"));
1703 /* As we never do asynchronous RPC serving, we can
1704 * never cancel a call (as far as I know).
1705 * If we ever did we'd have to send a cancel_ack reply.
1706 * For now, just free all client data and continue
1707 * processing. */
1708 reply = True;
1709 break;
1711 #if 0
1712 /* Enable this if we're doing async rpc. */
1713 /* We must check the outstanding callid matches. */
1714 if (pipe_init_outgoing_data(p)) {
1715 /* Send a cancel_ack PDU reply. */
1716 /* We should probably check the auth-verifier here. */
1717 reply = setup_cancel_ack_reply(p, pkt);
1719 break;
1720 #endif
1722 case DCERPC_PKT_ORPHANED:
1723 /* We should probably check the auth-verifier here.
1724 * For now just free all client data and continue
1725 * processing. */
1726 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1727 " Abandoning rpc call.\n"));
1728 reply = True;
1729 break;
1731 default:
1732 DEBUG(0, ("process_complete_pdu: "
1733 "Unknown rpc type = %u received.\n",
1734 (unsigned int)pkt->ptype));
1735 break;
1738 done:
1739 if (!reply) {
1740 DEBUG(3,("DCE/RPC fault sent!"));
1741 set_incoming_fault(p);
1742 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1743 TALLOC_FREE(pkt);
1744 } else {
1746 * Reset the lengths. We're ready for a new pdu.
1748 TALLOC_FREE(p->in_data.pdu.data);
1749 p->in_data.pdu_needed_len = 0;
1750 p->in_data.pdu.length = 0;
1753 TALLOC_FREE(pkt);