s3-librpc Call SPENGO/GSSAPI via the auth_generic layer and gensec
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob18389b42e0f99c1adf48060e3714c332ac7fcdbd
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 "../libcli/auth/schannel.h"
35 #include "../libcli/auth/spnego.h"
36 #include "dcesrv_auth_generic.h"
37 #include "dcesrv_gssapi.h"
38 #include "dcesrv_spnego.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(DCERPC_FAULT_OP_RNG_ERROR));
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)) {
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] cli_filename The pipe name requested by the client
382 * @result Do we want to serve this?
384 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
386 const char *pipename = cli_filename;
387 NTSTATUS status;
389 if (strnequal(pipename, "\\PIPE\\", 6)) {
390 pipename += 5;
393 if (*pipename == '\\') {
394 pipename += 1;
397 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
398 DEBUG(10, ("refusing spoolss access\n"));
399 return false;
402 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
403 return true;
406 status = smb_probe_module("rpc", pipename);
407 if (!NT_STATUS_IS_OK(status)) {
408 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
409 return false;
411 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
414 * Scan the list again for the interface id
416 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
417 return true;
420 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
421 pipename));
423 return false;
426 /*******************************************************************
427 Handle the first part of a SPNEGO bind auth.
428 *******************************************************************/
430 static bool pipe_spnego_auth_bind(struct pipes_struct *p,
431 TALLOC_CTX *mem_ctx,
432 struct dcerpc_auth *auth_info,
433 DATA_BLOB *response)
435 struct spnego_context *spnego_ctx;
436 NTSTATUS status;
438 status = spnego_server_auth_start(p,
439 (auth_info->auth_level ==
440 DCERPC_AUTH_LEVEL_INTEGRITY),
441 (auth_info->auth_level ==
442 DCERPC_AUTH_LEVEL_PRIVACY),
443 true,
444 &auth_info->credentials,
445 response,
446 p->remote_address,
447 &spnego_ctx);
448 if (!NT_STATUS_IS_OK(status)) {
449 DEBUG(0, ("Failed SPNEGO negotiate (%s)\n",
450 nt_errstr(status)));
451 return false;
454 /* Make sure data is bound to the memctx, to be freed the caller */
455 talloc_steal(mem_ctx, response->data);
457 p->auth.auth_ctx = spnego_ctx;
458 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
460 DEBUG(10, ("SPNEGO auth started\n"));
462 return true;
465 /*******************************************************************
466 Handle an schannel bind auth.
467 *******************************************************************/
469 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
470 TALLOC_CTX *mem_ctx,
471 struct dcerpc_auth *auth_info,
472 DATA_BLOB *response)
474 struct NL_AUTH_MESSAGE neg;
475 struct NL_AUTH_MESSAGE reply;
476 bool ret;
477 NTSTATUS status;
478 struct netlogon_creds_CredentialState *creds;
479 enum ndr_err_code ndr_err;
480 struct schannel_state *schannel_auth;
481 struct loadparm_context *lp_ctx;
483 ndr_err = ndr_pull_struct_blob(
484 &auth_info->credentials, mem_ctx, &neg,
485 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
486 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
487 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
488 return false;
491 if (DEBUGLEVEL >= 10) {
492 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
495 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
496 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
497 return false;
500 lp_ctx = loadparm_init_s3(p, loadparm_s3_context());
501 if (!lp_ctx) {
502 DEBUG(0,("pipe_schannel_auth_bind: loadparm_init_s3() failed!\n"));
503 return false;
507 * The neg.oem_netbios_computer.a key here must match the remote computer name
508 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
509 * operations that use credentials.
512 become_root();
513 status = schannel_get_creds_state(p, lp_ctx,
514 neg.oem_netbios_computer.a, &creds);
515 unbecome_root();
517 talloc_unlink(p, lp_ctx);
518 if (!NT_STATUS_IS_OK(status)) {
519 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
520 return False;
523 schannel_auth = talloc(p, struct schannel_state);
524 if (!schannel_auth) {
525 TALLOC_FREE(creds);
526 return False;
529 schannel_auth->state = SCHANNEL_STATE_START;
530 schannel_auth->seq_num = 0;
531 schannel_auth->initiator = false;
532 schannel_auth->creds = creds;
535 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
536 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
537 * struct of the person who opened the pipe. I need to test this further. JRA.
539 * VL. As we are mapping this to guest set the generic key
540 * "SystemLibraryDTC" key here. It's a bit difficult to test against
541 * W2k3, as it does not allow schannel binds against SAMR and LSA
542 * anymore.
545 ret = session_info_set_session_key(p->session_info, generic_session_key());
547 if (!ret) {
548 DEBUG(0, ("session_info_set_session_key failed\n"));
549 return false;
552 /*** SCHANNEL verifier ***/
554 reply.MessageType = NL_NEGOTIATE_RESPONSE;
555 reply.Flags = 0;
556 reply.Buffer.dummy = 5; /* ??? actually I don't think
557 * this has any meaning
558 * here - gd */
560 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
561 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
562 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
563 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
564 return false;
567 if (DEBUGLEVEL >= 10) {
568 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
571 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
572 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
574 /* We're finished with this bind - no more packets. */
575 p->auth.auth_ctx = schannel_auth;
576 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
578 p->pipe_bound = True;
580 return True;
583 /*******************************************************************
584 Handle an NTLMSSP bind auth.
585 *******************************************************************/
587 static bool pipe_auth_generic_bind(struct pipes_struct *p,
588 TALLOC_CTX *mem_ctx,
589 struct dcerpc_auth *auth_info,
590 DATA_BLOB *response)
592 struct gensec_security *gensec_security = NULL;
593 NTSTATUS status;
595 status = auth_generic_server_authtype_start(p,
596 auth_info->auth_type,
597 auth_info->auth_level,
598 &auth_info->credentials,
599 response,
600 p->remote_address,
601 &gensec_security);
602 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
603 DEBUG(0, (__location__ ": auth_generic_server_authtype_start failed: %s\n",
604 nt_errstr(status)));
605 return false;
608 /* Make sure data is bound to the memctx, to be freed the caller */
609 talloc_steal(mem_ctx, response->data);
611 p->auth.auth_ctx = gensec_security;
612 p->auth.auth_type = auth_info->auth_type;
614 return true;
617 /*******************************************************************
618 Process an NTLMSSP authentication response.
619 If this function succeeds, the user has been authenticated
620 and their domain, name and calling workstation stored in
621 the pipe struct.
622 *******************************************************************/
624 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
625 struct gensec_security *gensec_security,
626 enum dcerpc_AuthLevel auth_level,
627 struct auth_session_info **session_info)
629 NTSTATUS status;
630 bool ret;
632 DEBUG(5, (__location__ ": checking user details\n"));
634 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
635 ensure the underlying NTLMSSP flags are also set. If not we should
636 refuse the bind. */
638 status = auth_generic_server_check_flags(gensec_security,
639 (auth_level ==
640 DCERPC_AUTH_LEVEL_INTEGRITY),
641 (auth_level ==
642 DCERPC_AUTH_LEVEL_PRIVACY));
643 if (!NT_STATUS_IS_OK(status)) {
644 DEBUG(0, (__location__ ": Client failed to negotatie proper "
645 "security for rpc connection\n"));
646 return false;
649 TALLOC_FREE(*session_info);
651 status = auth_generic_server_get_user_info(gensec_security,
652 mem_ctx, session_info);
653 if (!NT_STATUS_IS_OK(status)) {
654 DEBUG(0, (__location__ ": failed to obtain the server info "
655 "for authenticated user: %s\n", nt_errstr(status)));
656 return false;
659 if ((*session_info)->security_token == NULL) {
660 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
661 return false;
665 * We're an authenticated bind over smb, so the session key needs to
666 * be set to "SystemLibraryDTC". Weird, but this is what Windows
667 * does. See the RPC-SAMBA3SESSIONKEY.
670 ret = session_info_set_session_key((*session_info), generic_session_key());
671 if (!ret) {
672 DEBUG(0, ("Failed to set session key!\n"));
673 return false;
676 return true;
679 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
681 enum spnego_mech auth_type;
682 struct gensec_security *gensec_security;
683 struct spnego_context *spnego_ctx;
684 void *mech_ctx;
685 NTSTATUS status;
687 switch (p->auth.auth_type) {
688 case DCERPC_AUTH_TYPE_NTLMSSP:
689 case DCERPC_AUTH_TYPE_KRB5:
690 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
691 struct gensec_security);
692 if (!pipe_auth_generic_verify_final(p, gensec_security,
693 p->auth.auth_level,
694 &p->session_info)) {
695 return NT_STATUS_ACCESS_DENIED;
697 break;
698 case DCERPC_AUTH_TYPE_SPNEGO:
699 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
700 struct spnego_context);
701 status = spnego_get_negotiated_mech(spnego_ctx,
702 &auth_type, &gensec_security);
703 if (!NT_STATUS_IS_OK(status)) {
704 DEBUG(0, ("Bad SPNEGO state (%s)\n",
705 nt_errstr(status)));
706 return status;
708 if (!pipe_auth_generic_verify_final(p, gensec_security,
709 p->auth.auth_level,
710 &p->session_info)) {
711 return NT_STATUS_ACCESS_DENIED;
713 break;
714 default:
715 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
716 (unsigned int)p->auth.auth_type));
717 return NT_STATUS_ACCESS_DENIED;
720 p->pipe_bound = true;
722 return NT_STATUS_OK;
725 /*******************************************************************
726 Respond to a pipe bind request.
727 *******************************************************************/
729 static bool api_pipe_bind_req(struct pipes_struct *p,
730 struct ncacn_packet *pkt)
732 struct dcerpc_auth auth_info;
733 uint16 assoc_gid;
734 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
735 NTSTATUS status;
736 struct ndr_syntax_id id;
737 union dcerpc_payload u;
738 struct dcerpc_ack_ctx bind_ack_ctx;
739 DATA_BLOB auth_resp = data_blob_null;
740 DATA_BLOB auth_blob = data_blob_null;
742 /* No rebinds on a bound pipe - use alter context. */
743 if (p->pipe_bound) {
744 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
745 return setup_bind_nak(p, pkt);
748 if (pkt->u.bind.num_contexts == 0) {
749 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
750 goto err_exit;
754 * Try and find the correct pipe name to ensure
755 * that this is a pipe name we support.
757 id = pkt->u.bind.ctx_list[0].abstract_syntax;
758 if (rpc_srv_pipe_exists_by_id(&id)) {
759 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
760 rpc_srv_get_pipe_cli_name(&id),
761 rpc_srv_get_pipe_srv_name(&id)));
762 } else {
763 status = smb_probe_module(
764 "rpc", get_pipe_name_from_syntax(
765 talloc_tos(),
766 &id));
768 if (NT_STATUS_IS_ERR(status)) {
769 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
770 "%s in bind request.\n",
771 get_pipe_name_from_syntax(talloc_tos(), &id)));
773 return setup_bind_nak(p, pkt);
776 if (rpc_srv_get_pipe_interface_by_cli_name(
777 get_pipe_name_from_syntax(talloc_tos(),
778 &id),
779 &id)) {
780 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
781 rpc_srv_get_pipe_cli_name(&id),
782 rpc_srv_get_pipe_srv_name(&id)));
783 } else {
784 DEBUG(0, ("module %s doesn't provide functions for "
785 "pipe %s!\n",
786 get_pipe_name_from_syntax(talloc_tos(), &id),
787 get_pipe_name_from_syntax(talloc_tos(), &id)));
788 return setup_bind_nak(p, pkt);
792 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
794 if (pkt->u.bind.assoc_group_id != 0) {
795 assoc_gid = pkt->u.bind.assoc_group_id;
796 } else {
797 assoc_gid = 0x53f0;
801 * Create the bind response struct.
804 /* If the requested abstract synt uuid doesn't match our client pipe,
805 reject the bind_ack & set the transfer interface synt to all 0's,
806 ver 0 (observed when NT5 attempts to bind to abstract interfaces
807 unknown to NT4)
808 Needed when adding entries to a DACL from NT5 - SK */
810 if (check_bind_req(p,
811 &pkt->u.bind.ctx_list[0].abstract_syntax,
812 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
813 pkt->u.bind.ctx_list[0].context_id)) {
815 bind_ack_ctx.result = 0;
816 bind_ack_ctx.reason = 0;
817 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
818 } else {
819 p->pipe_bound = False;
820 /* Rejection reason: abstract syntax not supported */
821 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
822 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
823 bind_ack_ctx.syntax = null_ndr_syntax_id;
827 * Check if this is an authenticated bind request.
829 if (pkt->auth_length) {
830 /* Quick length check. Won't catch a bad auth footer,
831 * prevents overrun. */
833 if (pkt->frag_length < RPC_HEADER_LEN +
834 DCERPC_AUTH_TRAILER_LENGTH +
835 pkt->auth_length) {
836 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
837 "too long for fragment %u.\n",
838 (unsigned int)pkt->auth_length,
839 (unsigned int)pkt->frag_length));
840 goto err_exit;
844 * Decode the authentication verifier.
846 status = dcerpc_pull_dcerpc_auth(pkt,
847 &pkt->u.bind.auth_info,
848 &auth_info, p->endian);
849 if (!NT_STATUS_IS_OK(status)) {
850 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
851 goto err_exit;
854 auth_type = auth_info.auth_type;
856 /* Work out if we have to sign or seal etc. */
857 switch (auth_info.auth_level) {
858 case DCERPC_AUTH_LEVEL_INTEGRITY:
859 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
860 break;
861 case DCERPC_AUTH_LEVEL_PRIVACY:
862 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
863 break;
864 case DCERPC_AUTH_LEVEL_CONNECT:
865 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
866 break;
867 default:
868 DEBUG(0, ("Unexpected auth level (%u).\n",
869 (unsigned int)auth_info.auth_level ));
870 goto err_exit;
873 switch (auth_type) {
874 case DCERPC_AUTH_TYPE_NTLMSSP:
875 if (!pipe_auth_generic_bind(p, pkt,
876 &auth_info, &auth_resp)) {
877 goto err_exit;
879 assoc_gid = 0x7a77;
880 break;
882 case DCERPC_AUTH_TYPE_SCHANNEL:
883 if (!pipe_schannel_auth_bind(p, pkt,
884 &auth_info, &auth_resp)) {
885 goto err_exit;
887 break;
889 case DCERPC_AUTH_TYPE_SPNEGO:
890 if (!pipe_spnego_auth_bind(p, pkt,
891 &auth_info, &auth_resp)) {
892 goto err_exit;
894 break;
896 case DCERPC_AUTH_TYPE_KRB5:
897 if (!pipe_auth_generic_bind(p, pkt,
898 &auth_info, &auth_resp)) {
899 goto err_exit;
901 break;
903 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
904 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
905 TALLOC_FREE(p->session_info);
907 status = make_session_info_system(p,
908 &p->session_info);
909 if (!NT_STATUS_IS_OK(status)) {
910 goto err_exit;
913 auth_resp = data_blob_talloc(pkt,
914 "NCALRPC_AUTH_OK",
915 15);
917 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
918 p->pipe_bound = true;
919 } else {
920 goto err_exit;
922 break;
924 case DCERPC_AUTH_TYPE_NONE:
925 break;
927 default:
928 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
929 goto err_exit;
933 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
934 /* Unauthenticated bind request. */
935 /* We're finished - no more packets. */
936 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
937 /* We must set the pipe auth_level here also. */
938 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
939 p->pipe_bound = True;
940 /* The session key was initialized from the SMB
941 * session in make_internal_rpc_pipe_p */
944 ZERO_STRUCT(u.bind_ack);
945 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
946 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
947 u.bind_ack.assoc_group_id = assoc_gid;
949 /* name has to be \PIPE\xxxxx */
950 u.bind_ack.secondary_address =
951 talloc_asprintf(pkt, "\\PIPE\\%s",
952 rpc_srv_get_pipe_srv_name(&id));
953 if (!u.bind_ack.secondary_address) {
954 DEBUG(0, ("Out of memory!\n"));
955 goto err_exit;
957 u.bind_ack.secondary_address_size =
958 strlen(u.bind_ack.secondary_address) + 1;
960 u.bind_ack.num_results = 1;
961 u.bind_ack.ctx_list = &bind_ack_ctx;
963 /* NOTE: We leave the auth_info empty so we can calculate the padding
964 * later and then append the auth_info --simo */
967 * Marshall directly into the outgoing PDU space. We
968 * must do this as we need to set to the bind response
969 * header and are never sending more than one PDU here.
972 status = dcerpc_push_ncacn_packet(p->mem_ctx,
973 DCERPC_PKT_BIND_ACK,
974 DCERPC_PFC_FLAG_FIRST |
975 DCERPC_PFC_FLAG_LAST,
976 auth_resp.length,
977 pkt->call_id,
979 &p->out_data.frag);
980 if (!NT_STATUS_IS_OK(status)) {
981 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
982 nt_errstr(status)));
985 if (auth_resp.length) {
987 status = dcerpc_push_dcerpc_auth(pkt,
988 auth_type,
989 auth_info.auth_level,
991 1, /* auth_context_id */
992 &auth_resp,
993 &auth_blob);
994 if (!NT_STATUS_IS_OK(status)) {
995 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
996 goto err_exit;
1000 /* Now that we have the auth len store it into the right place in
1001 * the dcerpc header */
1002 dcerpc_set_frag_length(&p->out_data.frag,
1003 p->out_data.frag.length + auth_blob.length);
1005 if (auth_blob.length) {
1007 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1008 auth_blob.data, auth_blob.length)) {
1009 DEBUG(0, ("Append of auth info failed.\n"));
1010 goto err_exit;
1015 * Setup the lengths for the initial reply.
1018 p->out_data.data_sent_length = 0;
1019 p->out_data.current_pdu_sent = 0;
1021 TALLOC_FREE(auth_blob.data);
1022 return True;
1024 err_exit:
1026 data_blob_free(&p->out_data.frag);
1027 TALLOC_FREE(auth_blob.data);
1028 return setup_bind_nak(p, pkt);
1031 /*******************************************************************
1032 This is the "stage3" response after a bind request and reply.
1033 *******************************************************************/
1035 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1037 struct dcerpc_auth auth_info;
1038 DATA_BLOB response = data_blob_null;
1039 struct gensec_security *gensec_security;
1040 struct spnego_context *spnego_ctx;
1041 NTSTATUS status;
1043 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1045 if (pkt->auth_length == 0) {
1046 DEBUG(0, ("No auth field sent for bind request!\n"));
1047 goto err;
1050 /* Ensure there's enough data for an authenticated request. */
1051 if (pkt->frag_length < RPC_HEADER_LEN
1052 + DCERPC_AUTH_TRAILER_LENGTH
1053 + pkt->auth_length) {
1054 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
1055 "%u is too large.\n",
1056 (unsigned int)pkt->auth_length));
1057 goto err;
1061 * Decode the authentication verifier response.
1064 status = dcerpc_pull_dcerpc_auth(pkt,
1065 &pkt->u.auth3.auth_info,
1066 &auth_info, p->endian);
1067 if (!NT_STATUS_IS_OK(status)) {
1068 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1069 goto err;
1072 /* We must NEVER look at auth_info->auth_pad_len here,
1073 * as old Samba client code gets it wrong and sends it
1074 * as zero. JRA.
1077 if (auth_info.auth_type != p->auth.auth_type) {
1078 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1079 "but auth was started as type %d!\n",
1080 auth_info.auth_type, p->auth.auth_type));
1081 goto err;
1084 switch (auth_info.auth_type) {
1085 case DCERPC_AUTH_TYPE_NTLMSSP:
1086 case DCERPC_AUTH_TYPE_KRB5:
1087 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1088 struct gensec_security);
1089 status = auth_generic_server_step(gensec_security,
1090 pkt, &auth_info.credentials,
1091 &response);
1092 break;
1093 case DCERPC_AUTH_TYPE_SPNEGO:
1094 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1095 struct spnego_context);
1096 status = spnego_server_step(spnego_ctx,
1097 pkt, &auth_info.credentials,
1098 &response);
1099 break;
1100 default:
1101 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1102 (unsigned int)auth_info.auth_type));
1103 return false;
1106 if (NT_STATUS_EQUAL(status,
1107 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1108 response.length) {
1109 DEBUG(0, (__location__ ": This was supposed to be the final "
1110 "leg, but crypto machinery claims a response is "
1111 "needed, aborting auth!\n"));
1112 data_blob_free(&response);
1113 goto err;
1115 if (!NT_STATUS_IS_OK(status)) {
1116 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1117 goto err;
1120 /* Now verify auth was indeed successful and extract server info */
1121 status = pipe_auth_verify_final(p);
1122 if (!NT_STATUS_IS_OK(status)) {
1123 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1124 goto err;
1127 return true;
1129 err:
1131 TALLOC_FREE(p->auth.auth_ctx);
1132 return false;
1135 /****************************************************************************
1136 Deal with an alter context call. Can be third part of 3 leg auth request for
1137 SPNEGO calls.
1138 ****************************************************************************/
1140 static bool api_pipe_alter_context(struct pipes_struct *p,
1141 struct ncacn_packet *pkt)
1143 struct dcerpc_auth auth_info;
1144 uint16 assoc_gid;
1145 NTSTATUS status;
1146 union dcerpc_payload u;
1147 struct dcerpc_ack_ctx bind_ack_ctx;
1148 DATA_BLOB auth_resp = data_blob_null;
1149 DATA_BLOB auth_blob = data_blob_null;
1150 int pad_len = 0;
1151 struct gensec_security *gensec_security;
1152 struct spnego_context *spnego_ctx;
1154 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1156 if (pkt->u.bind.assoc_group_id != 0) {
1157 assoc_gid = pkt->u.bind.assoc_group_id;
1158 } else {
1159 assoc_gid = 0x53f0;
1163 * Create the bind response struct.
1166 /* If the requested abstract synt uuid doesn't match our client pipe,
1167 reject the bind_ack & set the transfer interface synt to all 0's,
1168 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1169 unknown to NT4)
1170 Needed when adding entries to a DACL from NT5 - SK */
1172 if (check_bind_req(p,
1173 &pkt->u.bind.ctx_list[0].abstract_syntax,
1174 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1175 pkt->u.bind.ctx_list[0].context_id)) {
1177 bind_ack_ctx.result = 0;
1178 bind_ack_ctx.reason = 0;
1179 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1180 } else {
1181 p->pipe_bound = False;
1182 /* Rejection reason: abstract syntax not supported */
1183 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1184 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1185 bind_ack_ctx.syntax = null_ndr_syntax_id;
1189 * Check if this is an authenticated alter context request.
1191 if (pkt->auth_length) {
1192 /* Quick length check. Won't catch a bad auth footer,
1193 * prevents overrun. */
1195 if (pkt->frag_length < RPC_HEADER_LEN +
1196 DCERPC_AUTH_TRAILER_LENGTH +
1197 pkt->auth_length) {
1198 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1199 "too long for fragment %u.\n",
1200 (unsigned int)pkt->auth_length,
1201 (unsigned int)pkt->frag_length ));
1202 goto err_exit;
1205 status = dcerpc_pull_dcerpc_auth(pkt,
1206 &pkt->u.bind.auth_info,
1207 &auth_info, p->endian);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1210 goto err_exit;
1213 /* We can only finish if the pipe is unbound for now */
1214 if (p->pipe_bound) {
1215 DEBUG(0, (__location__ ": Pipe already bound, "
1216 "Altering Context not yet supported!\n"));
1217 goto err_exit;
1220 if (auth_info.auth_type != p->auth.auth_type) {
1221 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1222 "but auth was started as type %d!\n",
1223 auth_info.auth_type, p->auth.auth_type));
1224 goto err_exit;
1228 switch (auth_info.auth_type) {
1229 case DCERPC_AUTH_TYPE_SPNEGO:
1230 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1231 struct spnego_context);
1232 status = spnego_server_step(spnego_ctx,
1233 pkt,
1234 &auth_info.credentials,
1235 &auth_resp);
1236 break;
1238 case DCERPC_AUTH_TYPE_KRB5:
1239 case DCERPC_AUTH_TYPE_NTLMSSP:
1240 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1241 struct gensec_security);
1242 status = auth_generic_server_step(gensec_security,
1243 pkt,
1244 &auth_info.credentials,
1245 &auth_resp);
1246 break;
1248 default:
1249 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1250 "in alter-context call\n",
1251 auth_info.auth_type));
1252 goto err_exit;
1255 if (NT_STATUS_IS_OK(status)) {
1256 /* third leg of auth, verify auth info */
1257 status = pipe_auth_verify_final(p);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 DEBUG(0, ("Auth Verify failed (%s)\n",
1260 nt_errstr(status)));
1261 goto err_exit;
1263 } else if (NT_STATUS_EQUAL(status,
1264 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1265 DEBUG(10, ("More auth legs required.\n"));
1266 } else {
1267 DEBUG(0, ("Auth step returned an error (%s)\n",
1268 nt_errstr(status)));
1269 goto err_exit;
1273 ZERO_STRUCT(u.alter_resp);
1274 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1275 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1276 u.alter_resp.assoc_group_id = assoc_gid;
1278 /* secondary address CAN be NULL
1279 * as the specs say it's ignored.
1280 * It MUST be NULL to have the spoolss working.
1282 u.alter_resp.secondary_address = "";
1283 u.alter_resp.secondary_address_size = 1;
1285 u.alter_resp.num_results = 1;
1286 u.alter_resp.ctx_list = &bind_ack_ctx;
1288 /* NOTE: We leave the auth_info empty so we can calculate the padding
1289 * later and then append the auth_info --simo */
1292 * Marshall directly into the outgoing PDU space. We
1293 * must do this as we need to set to the bind response
1294 * header and are never sending more than one PDU here.
1297 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1298 DCERPC_PKT_ALTER_RESP,
1299 DCERPC_PFC_FLAG_FIRST |
1300 DCERPC_PFC_FLAG_LAST,
1301 auth_resp.length,
1302 pkt->call_id,
1304 &p->out_data.frag);
1305 if (!NT_STATUS_IS_OK(status)) {
1306 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1307 nt_errstr(status)));
1310 if (auth_resp.length) {
1312 /* Work out any padding needed before the auth footer. */
1313 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1314 if (pad_len) {
1315 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1316 DEBUG(10, ("auth pad_len = %u\n",
1317 (unsigned int)pad_len));
1320 status = dcerpc_push_dcerpc_auth(pkt,
1321 auth_info.auth_type,
1322 auth_info.auth_level,
1323 pad_len,
1324 1, /* auth_context_id */
1325 &auth_resp,
1326 &auth_blob);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1329 goto err_exit;
1333 /* Now that we have the auth len store it into the right place in
1334 * the dcerpc header */
1335 dcerpc_set_frag_length(&p->out_data.frag,
1336 p->out_data.frag.length +
1337 pad_len + auth_blob.length);
1339 if (auth_resp.length) {
1340 if (pad_len) {
1341 char pad[SERVER_NDR_PADDING_SIZE];
1342 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1343 if (!data_blob_append(p->mem_ctx,
1344 &p->out_data.frag,
1345 pad, pad_len)) {
1346 DEBUG(0, ("api_pipe_bind_req: failed to add "
1347 "%u bytes of pad data.\n",
1348 (unsigned int)pad_len));
1349 goto err_exit;
1353 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1354 auth_blob.data, auth_blob.length)) {
1355 DEBUG(0, ("Append of auth info failed.\n"));
1356 goto err_exit;
1361 * Setup the lengths for the initial reply.
1364 p->out_data.data_sent_length = 0;
1365 p->out_data.current_pdu_sent = 0;
1367 TALLOC_FREE(auth_blob.data);
1368 return True;
1370 err_exit:
1372 data_blob_free(&p->out_data.frag);
1373 TALLOC_FREE(auth_blob.data);
1374 return setup_bind_nak(p, pkt);
1377 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1378 const struct api_struct *api_rpc_cmds, int n_cmds,
1379 const struct ndr_syntax_id *syntax);
1381 /****************************************************************************
1382 Find the correct RPC function to call for this request.
1383 If the pipe is authenticated then become the correct UNIX user
1384 before doing the call.
1385 ****************************************************************************/
1387 static bool api_pipe_request(struct pipes_struct *p,
1388 struct ncacn_packet *pkt)
1390 bool ret = False;
1391 struct pipe_rpc_fns *pipe_fns;
1393 if (!p->pipe_bound) {
1394 DEBUG(1, ("Pipe not bound!\n"));
1395 data_blob_free(&p->out_data.rdata);
1396 return false;
1399 if (!become_authenticated_pipe_user(p->session_info)) {
1400 DEBUG(1, ("Failed to become pipe user!\n"));
1401 data_blob_free(&p->out_data.rdata);
1402 return false;
1405 /* get the set of RPC functions for this context */
1407 pipe_fns = find_pipe_fns_by_context(p->contexts,
1408 pkt->u.request.context_id);
1410 if ( pipe_fns ) {
1411 TALLOC_CTX *frame = talloc_stackframe();
1413 DEBUG(5, ("Requested %s rpc service\n",
1414 get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
1416 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1417 &pipe_fns->syntax);
1419 TALLOC_FREE(frame);
1421 else {
1422 DEBUG(0, ("No rpc function table associated with context "
1423 "[%d]\n",
1424 pkt->u.request.context_id));
1427 unbecome_authenticated_pipe_user();
1429 return ret;
1432 /*******************************************************************
1433 Calls the underlying RPC function for a named pipe.
1434 ********************************************************************/
1436 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1437 const struct api_struct *api_rpc_cmds, int n_cmds,
1438 const struct ndr_syntax_id *syntax)
1440 int fn_num;
1441 uint32_t offset1;
1443 /* interpret the command */
1444 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1445 get_pipe_name_from_syntax(talloc_tos(), syntax),
1446 pkt->u.request.opnum));
1448 if (DEBUGLEVEL >= 50) {
1449 fstring name;
1450 slprintf(name, sizeof(name)-1, "in_%s",
1451 get_pipe_name_from_syntax(talloc_tos(), syntax));
1452 dump_pdu_region(name, pkt->u.request.opnum,
1453 &p->in_data.data, 0,
1454 p->in_data.data.length);
1457 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1458 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1459 api_rpc_cmds[fn_num].fn != NULL) {
1460 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1461 api_rpc_cmds[fn_num].name));
1462 break;
1466 if (fn_num == n_cmds) {
1468 * For an unknown RPC just return a fault PDU but
1469 * return True to allow RPC's on the pipe to continue
1470 * and not put the pipe into fault state. JRA.
1472 DEBUG(4, ("unknown\n"));
1473 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1474 return True;
1477 offset1 = p->out_data.rdata.length;
1479 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1480 fn_num, api_rpc_cmds[fn_num].fn));
1481 /* do the actual command */
1482 if(!api_rpc_cmds[fn_num].fn(p)) {
1483 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1484 get_pipe_name_from_syntax(talloc_tos(), syntax),
1485 api_rpc_cmds[fn_num].name));
1486 data_blob_free(&p->out_data.rdata);
1487 return False;
1490 if (p->bad_handle_fault_state) {
1491 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1492 p->bad_handle_fault_state = False;
1493 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1494 return True;
1497 if (p->rng_fault_state) {
1498 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1499 p->rng_fault_state = False;
1500 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1501 return True;
1504 if (DEBUGLEVEL >= 50) {
1505 fstring name;
1506 slprintf(name, sizeof(name)-1, "out_%s",
1507 get_pipe_name_from_syntax(talloc_tos(), syntax));
1508 dump_pdu_region(name, pkt->u.request.opnum,
1509 &p->out_data.rdata, offset1,
1510 p->out_data.rdata.length);
1513 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1514 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1516 /* Check for buffer underflow in rpc parsing */
1517 if ((DEBUGLEVEL >= 10) &&
1518 (pkt->frag_length < p->in_data.data.length)) {
1519 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1520 dump_data(10, p->in_data.data.data + pkt->frag_length,
1521 p->in_data.data.length - pkt->frag_length);
1524 return True;
1527 /****************************************************************************
1528 Initialise an outgoing packet.
1529 ****************************************************************************/
1531 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1533 output_data *o_data = &p->out_data;
1535 /* Reset the offset counters. */
1536 o_data->data_sent_length = 0;
1537 o_data->current_pdu_sent = 0;
1539 data_blob_free(&o_data->frag);
1541 /* Free any memory in the current return data buffer. */
1542 data_blob_free(&o_data->rdata);
1544 return True;
1547 /****************************************************************************
1548 Sets the fault state on incoming packets.
1549 ****************************************************************************/
1551 void set_incoming_fault(struct pipes_struct *p)
1553 data_blob_free(&p->in_data.data);
1554 p->in_data.pdu_needed_len = 0;
1555 p->in_data.pdu.length = 0;
1556 p->fault_state = True;
1558 DEBUG(10, ("Setting fault state\n"));
1561 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1562 struct ncacn_packet *pkt,
1563 DATA_BLOB *raw_pkt)
1565 NTSTATUS status;
1566 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1567 size_t pad_len;
1569 DEBUG(10, ("Checking request auth.\n"));
1571 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1572 hdr_size += 16;
1575 /* in case of sealing this function will unseal the data in place */
1576 status = dcerpc_check_auth(auth, pkt,
1577 &pkt->u.request.stub_and_verifier,
1578 hdr_size, raw_pkt,
1579 &pad_len);
1580 if (!NT_STATUS_IS_OK(status)) {
1581 return status;
1585 /* remove padding and auth trailer,
1586 * this way the caller will get just the data */
1587 if (pkt->auth_length) {
1588 size_t trail_len = pad_len
1589 + DCERPC_AUTH_TRAILER_LENGTH
1590 + pkt->auth_length;
1591 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1592 return NT_STATUS_INFO_LENGTH_MISMATCH;
1594 pkt->u.request.stub_and_verifier.length -= trail_len;
1597 return NT_STATUS_OK;
1600 /****************************************************************************
1601 Processes a request pdu. This will do auth processing if needed, and
1602 appends the data into the complete stream if the LAST flag is not set.
1603 ****************************************************************************/
1605 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1607 NTSTATUS status;
1608 DATA_BLOB data;
1610 if (!p->pipe_bound) {
1611 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1612 set_incoming_fault(p);
1613 return False;
1616 /* Store the opnum */
1617 p->opnum = pkt->u.request.opnum;
1619 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1620 if (!NT_STATUS_IS_OK(status)) {
1621 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1622 nt_errstr(status)));
1623 set_incoming_fault(p);
1624 return false;
1627 data = pkt->u.request.stub_and_verifier;
1630 * Check the data length doesn't go over the 15Mb limit.
1631 * increased after observing a bug in the Windows NT 4.0 SP6a
1632 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1633 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1636 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1637 DEBUG(0, ("process_request_pdu: "
1638 "rpc data buffer too large (%u) + (%u)\n",
1639 (unsigned int)p->in_data.data.length,
1640 (unsigned int)data.length));
1641 set_incoming_fault(p);
1642 return False;
1646 * Append the data portion into the buffer and return.
1649 if (data.length) {
1650 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1651 data.data, data.length)) {
1652 DEBUG(0, ("Unable to append data size %u "
1653 "to parse buffer of size %u.\n",
1654 (unsigned int)data.length,
1655 (unsigned int)p->in_data.data.length));
1656 set_incoming_fault(p);
1657 return False;
1661 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1662 bool ret = False;
1664 * Ok - we finally have a complete RPC stream.
1665 * Call the rpc command to process it.
1669 * Process the complete data stream here.
1671 if (pipe_init_outgoing_data(p)) {
1672 ret = api_pipe_request(p, pkt);
1675 return ret;
1678 return True;
1681 /****************************************************************************
1682 Processes a finished PDU stored in p->in_data.pdu.
1683 ****************************************************************************/
1685 void process_complete_pdu(struct pipes_struct *p)
1687 struct ncacn_packet *pkt = NULL;
1688 NTSTATUS status;
1689 bool reply = False;
1691 if(p->fault_state) {
1692 DEBUG(10,("RPC connection in fault state.\n"));
1693 goto done;
1696 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1697 if (!pkt) {
1698 DEBUG(0, ("Out of memory!\n"));
1699 goto done;
1703 * Ensure we're using the corrent endianness for both the
1704 * RPC header flags and the raw data we will be reading from.
1706 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1707 p->endian = RPC_LITTLE_ENDIAN;
1708 } else {
1709 p->endian = RPC_BIG_ENDIAN;
1711 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1713 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1714 pkt, p->endian);
1715 if (!NT_STATUS_IS_OK(status)) {
1716 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1717 nt_errstr(status)));
1718 goto done;
1721 /* Store the call_id */
1722 p->call_id = pkt->call_id;
1724 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1726 switch (pkt->ptype) {
1727 case DCERPC_PKT_REQUEST:
1728 reply = process_request_pdu(p, pkt);
1729 break;
1731 case DCERPC_PKT_PING: /* CL request - ignore... */
1732 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1733 (unsigned int)pkt->ptype));
1734 break;
1736 case DCERPC_PKT_RESPONSE: /* No responses here. */
1737 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1738 break;
1740 case DCERPC_PKT_FAULT:
1741 case DCERPC_PKT_WORKING:
1742 /* CL request - reply to a ping when a call in process. */
1743 case DCERPC_PKT_NOCALL:
1744 /* CL - server reply to a ping call. */
1745 case DCERPC_PKT_REJECT:
1746 case DCERPC_PKT_ACK:
1747 case DCERPC_PKT_CL_CANCEL:
1748 case DCERPC_PKT_FACK:
1749 case DCERPC_PKT_CANCEL_ACK:
1750 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1751 (unsigned int)pkt->ptype));
1752 break;
1754 case DCERPC_PKT_BIND:
1756 * We assume that a pipe bind is only in one pdu.
1758 if (pipe_init_outgoing_data(p)) {
1759 reply = api_pipe_bind_req(p, pkt);
1761 break;
1763 case DCERPC_PKT_BIND_ACK:
1764 case DCERPC_PKT_BIND_NAK:
1765 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1766 "packet type %u received.\n",
1767 (unsigned int)pkt->ptype));
1768 break;
1771 case DCERPC_PKT_ALTER:
1773 * We assume that a pipe bind is only in one pdu.
1775 if (pipe_init_outgoing_data(p)) {
1776 reply = api_pipe_alter_context(p, pkt);
1778 break;
1780 case DCERPC_PKT_ALTER_RESP:
1781 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1782 "Should only be server -> client.\n"));
1783 break;
1785 case DCERPC_PKT_AUTH3:
1787 * The third packet in an auth exchange.
1789 if (pipe_init_outgoing_data(p)) {
1790 reply = api_pipe_bind_auth3(p, pkt);
1792 break;
1794 case DCERPC_PKT_SHUTDOWN:
1795 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1796 "Should only be server -> client.\n"));
1797 break;
1799 case DCERPC_PKT_CO_CANCEL:
1800 /* For now just free all client data and continue
1801 * processing. */
1802 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1803 " Abandoning rpc call.\n"));
1804 /* As we never do asynchronous RPC serving, we can
1805 * never cancel a call (as far as I know).
1806 * If we ever did we'd have to send a cancel_ack reply.
1807 * For now, just free all client data and continue
1808 * processing. */
1809 reply = True;
1810 break;
1812 #if 0
1813 /* Enable this if we're doing async rpc. */
1814 /* We must check the outstanding callid matches. */
1815 if (pipe_init_outgoing_data(p)) {
1816 /* Send a cancel_ack PDU reply. */
1817 /* We should probably check the auth-verifier here. */
1818 reply = setup_cancel_ack_reply(p, pkt);
1820 break;
1821 #endif
1823 case DCERPC_PKT_ORPHANED:
1824 /* We should probably check the auth-verifier here.
1825 * For now just free all client data and continue
1826 * processing. */
1827 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1828 " Abandoning rpc call.\n"));
1829 reply = True;
1830 break;
1832 default:
1833 DEBUG(0, ("process_complete_pdu: "
1834 "Unknown rpc type = %u received.\n",
1835 (unsigned int)pkt->ptype));
1836 break;
1839 done:
1840 if (!reply) {
1841 DEBUG(3,("DCE/RPC fault sent!"));
1842 set_incoming_fault(p);
1843 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1844 TALLOC_FREE(pkt);
1845 } else {
1847 * Reset the lengths. We're ready for a new pdu.
1849 TALLOC_FREE(p->in_data.pdu.data);
1850 p->in_data.pdu_needed_len = 0;
1851 p->in_data.pdu.length = 0;
1854 TALLOC_FREE(pkt);