s3-librpc Call GSSAPI via the auth_generic layer and gensec
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_pipe.c
blob605ed5420cd0e59e9ed9c89636cb4e4abb660d40
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_gssapi_verify_final(TALLOC_CTX *mem_ctx,
680 struct gse_context *gse_ctx,
681 const struct tsocket_address *remote_address,
682 struct auth_session_info **session_info)
684 NTSTATUS status;
685 bool bret;
687 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
688 ensure the underlying flags are also set. If not we should
689 refuse the bind. */
691 status = gssapi_server_check_flags(gse_ctx);
692 if (!NT_STATUS_IS_OK(status)) {
693 DEBUG(0, ("Requested Security Layers not honored!\n"));
694 return status;
697 status = gssapi_server_get_user_info(gse_ctx, mem_ctx,
698 remote_address, session_info);
699 if (!NT_STATUS_IS_OK(status)) {
700 DEBUG(0, (__location__ ": failed to obtain the server info "
701 "for authenticated user: %s\n", nt_errstr(status)));
702 return status;
706 * We're an authenticated bind over smb, so the session key needs to
707 * be set to "SystemLibraryDTC". Weird, but this is what Windows
708 * does. See the RPC-SAMBA3SESSIONKEY.
711 bret = session_info_set_session_key((*session_info), generic_session_key());
712 if (!bret) {
713 return NT_STATUS_ACCESS_DENIED;
716 return NT_STATUS_OK;
719 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
721 enum spnego_mech auth_type;
722 struct gensec_security *gensec_security;
723 struct spnego_context *spnego_ctx;
724 struct gse_context *gse_ctx;
725 void *mech_ctx;
726 NTSTATUS status;
728 switch (p->auth.auth_type) {
729 case DCERPC_AUTH_TYPE_NTLMSSP:
730 case DCERPC_AUTH_TYPE_KRB5:
731 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
732 struct gensec_security);
733 if (!pipe_auth_generic_verify_final(p, gensec_security,
734 p->auth.auth_level,
735 &p->session_info)) {
736 return NT_STATUS_ACCESS_DENIED;
738 break;
739 case DCERPC_AUTH_TYPE_SPNEGO:
740 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
741 struct spnego_context);
742 status = spnego_get_negotiated_mech(spnego_ctx,
743 &auth_type, &mech_ctx);
744 if (!NT_STATUS_IS_OK(status)) {
745 DEBUG(0, ("Bad SPNEGO state (%s)\n",
746 nt_errstr(status)));
747 return status;
749 switch(auth_type) {
750 case SPNEGO_KRB5:
751 gse_ctx = talloc_get_type_abort(mech_ctx,
752 struct gse_context);
753 status = pipe_gssapi_verify_final(p, gse_ctx,
754 p->remote_address,
755 &p->session_info);
756 if (!NT_STATUS_IS_OK(status)) {
757 DEBUG(1, ("gssapi bind failed with: %s",
758 nt_errstr(status)));
759 return status;
761 break;
762 case SPNEGO_NTLMSSP:
763 gensec_security = talloc_get_type_abort(mech_ctx,
764 struct gensec_security);
765 if (!pipe_auth_generic_verify_final(p, gensec_security,
766 p->auth.auth_level,
767 &p->session_info)) {
768 return NT_STATUS_ACCESS_DENIED;
770 break;
771 default:
772 DEBUG(0, (__location__ ": incorrect spnego type "
773 "(%d).\n", auth_type));
774 return NT_STATUS_ACCESS_DENIED;
776 break;
777 default:
778 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
779 (unsigned int)p->auth.auth_type));
780 return NT_STATUS_ACCESS_DENIED;
783 p->pipe_bound = true;
785 return NT_STATUS_OK;
788 /*******************************************************************
789 Respond to a pipe bind request.
790 *******************************************************************/
792 static bool api_pipe_bind_req(struct pipes_struct *p,
793 struct ncacn_packet *pkt)
795 struct dcerpc_auth auth_info;
796 uint16 assoc_gid;
797 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
798 NTSTATUS status;
799 struct ndr_syntax_id id;
800 union dcerpc_payload u;
801 struct dcerpc_ack_ctx bind_ack_ctx;
802 DATA_BLOB auth_resp = data_blob_null;
803 DATA_BLOB auth_blob = data_blob_null;
805 /* No rebinds on a bound pipe - use alter context. */
806 if (p->pipe_bound) {
807 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
808 return setup_bind_nak(p, pkt);
811 if (pkt->u.bind.num_contexts == 0) {
812 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
813 goto err_exit;
817 * Try and find the correct pipe name to ensure
818 * that this is a pipe name we support.
820 id = pkt->u.bind.ctx_list[0].abstract_syntax;
821 if (rpc_srv_pipe_exists_by_id(&id)) {
822 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
823 rpc_srv_get_pipe_cli_name(&id),
824 rpc_srv_get_pipe_srv_name(&id)));
825 } else {
826 status = smb_probe_module(
827 "rpc", get_pipe_name_from_syntax(
828 talloc_tos(),
829 &id));
831 if (NT_STATUS_IS_ERR(status)) {
832 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
833 "%s in bind request.\n",
834 get_pipe_name_from_syntax(talloc_tos(), &id)));
836 return setup_bind_nak(p, pkt);
839 if (rpc_srv_get_pipe_interface_by_cli_name(
840 get_pipe_name_from_syntax(talloc_tos(),
841 &id),
842 &id)) {
843 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
844 rpc_srv_get_pipe_cli_name(&id),
845 rpc_srv_get_pipe_srv_name(&id)));
846 } else {
847 DEBUG(0, ("module %s doesn't provide functions for "
848 "pipe %s!\n",
849 get_pipe_name_from_syntax(talloc_tos(), &id),
850 get_pipe_name_from_syntax(talloc_tos(), &id)));
851 return setup_bind_nak(p, pkt);
855 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
857 if (pkt->u.bind.assoc_group_id != 0) {
858 assoc_gid = pkt->u.bind.assoc_group_id;
859 } else {
860 assoc_gid = 0x53f0;
864 * Create the bind response struct.
867 /* If the requested abstract synt uuid doesn't match our client pipe,
868 reject the bind_ack & set the transfer interface synt to all 0's,
869 ver 0 (observed when NT5 attempts to bind to abstract interfaces
870 unknown to NT4)
871 Needed when adding entries to a DACL from NT5 - SK */
873 if (check_bind_req(p,
874 &pkt->u.bind.ctx_list[0].abstract_syntax,
875 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
876 pkt->u.bind.ctx_list[0].context_id)) {
878 bind_ack_ctx.result = 0;
879 bind_ack_ctx.reason = 0;
880 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
881 } else {
882 p->pipe_bound = False;
883 /* Rejection reason: abstract syntax not supported */
884 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
885 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
886 bind_ack_ctx.syntax = null_ndr_syntax_id;
890 * Check if this is an authenticated bind request.
892 if (pkt->auth_length) {
893 /* Quick length check. Won't catch a bad auth footer,
894 * prevents overrun. */
896 if (pkt->frag_length < RPC_HEADER_LEN +
897 DCERPC_AUTH_TRAILER_LENGTH +
898 pkt->auth_length) {
899 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
900 "too long for fragment %u.\n",
901 (unsigned int)pkt->auth_length,
902 (unsigned int)pkt->frag_length));
903 goto err_exit;
907 * Decode the authentication verifier.
909 status = dcerpc_pull_dcerpc_auth(pkt,
910 &pkt->u.bind.auth_info,
911 &auth_info, p->endian);
912 if (!NT_STATUS_IS_OK(status)) {
913 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
914 goto err_exit;
917 auth_type = auth_info.auth_type;
919 /* Work out if we have to sign or seal etc. */
920 switch (auth_info.auth_level) {
921 case DCERPC_AUTH_LEVEL_INTEGRITY:
922 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
923 break;
924 case DCERPC_AUTH_LEVEL_PRIVACY:
925 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
926 break;
927 case DCERPC_AUTH_LEVEL_CONNECT:
928 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
929 break;
930 default:
931 DEBUG(0, ("Unexpected auth level (%u).\n",
932 (unsigned int)auth_info.auth_level ));
933 goto err_exit;
936 switch (auth_type) {
937 case DCERPC_AUTH_TYPE_NTLMSSP:
938 if (!pipe_auth_generic_bind(p, pkt,
939 &auth_info, &auth_resp)) {
940 goto err_exit;
942 assoc_gid = 0x7a77;
943 break;
945 case DCERPC_AUTH_TYPE_SCHANNEL:
946 if (!pipe_schannel_auth_bind(p, pkt,
947 &auth_info, &auth_resp)) {
948 goto err_exit;
950 break;
952 case DCERPC_AUTH_TYPE_SPNEGO:
953 if (!pipe_spnego_auth_bind(p, pkt,
954 &auth_info, &auth_resp)) {
955 goto err_exit;
957 break;
959 case DCERPC_AUTH_TYPE_KRB5:
960 if (!pipe_auth_generic_bind(p, pkt,
961 &auth_info, &auth_resp)) {
962 goto err_exit;
964 break;
966 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
967 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
968 TALLOC_FREE(p->session_info);
970 status = make_session_info_system(p,
971 &p->session_info);
972 if (!NT_STATUS_IS_OK(status)) {
973 goto err_exit;
976 auth_resp = data_blob_talloc(pkt,
977 "NCALRPC_AUTH_OK",
978 15);
980 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
981 p->pipe_bound = true;
982 } else {
983 goto err_exit;
985 break;
987 case DCERPC_AUTH_TYPE_NONE:
988 break;
990 default:
991 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
992 goto err_exit;
996 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
997 /* Unauthenticated bind request. */
998 /* We're finished - no more packets. */
999 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1000 /* We must set the pipe auth_level here also. */
1001 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1002 p->pipe_bound = True;
1003 /* The session key was initialized from the SMB
1004 * session in make_internal_rpc_pipe_p */
1007 ZERO_STRUCT(u.bind_ack);
1008 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1009 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1010 u.bind_ack.assoc_group_id = assoc_gid;
1012 /* name has to be \PIPE\xxxxx */
1013 u.bind_ack.secondary_address =
1014 talloc_asprintf(pkt, "\\PIPE\\%s",
1015 rpc_srv_get_pipe_srv_name(&id));
1016 if (!u.bind_ack.secondary_address) {
1017 DEBUG(0, ("Out of memory!\n"));
1018 goto err_exit;
1020 u.bind_ack.secondary_address_size =
1021 strlen(u.bind_ack.secondary_address) + 1;
1023 u.bind_ack.num_results = 1;
1024 u.bind_ack.ctx_list = &bind_ack_ctx;
1026 /* NOTE: We leave the auth_info empty so we can calculate the padding
1027 * later and then append the auth_info --simo */
1030 * Marshall directly into the outgoing PDU space. We
1031 * must do this as we need to set to the bind response
1032 * header and are never sending more than one PDU here.
1035 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1036 DCERPC_PKT_BIND_ACK,
1037 DCERPC_PFC_FLAG_FIRST |
1038 DCERPC_PFC_FLAG_LAST,
1039 auth_resp.length,
1040 pkt->call_id,
1042 &p->out_data.frag);
1043 if (!NT_STATUS_IS_OK(status)) {
1044 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1045 nt_errstr(status)));
1048 if (auth_resp.length) {
1050 status = dcerpc_push_dcerpc_auth(pkt,
1051 auth_type,
1052 auth_info.auth_level,
1054 1, /* auth_context_id */
1055 &auth_resp,
1056 &auth_blob);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1059 goto err_exit;
1063 /* Now that we have the auth len store it into the right place in
1064 * the dcerpc header */
1065 dcerpc_set_frag_length(&p->out_data.frag,
1066 p->out_data.frag.length + auth_blob.length);
1068 if (auth_blob.length) {
1070 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1071 auth_blob.data, auth_blob.length)) {
1072 DEBUG(0, ("Append of auth info failed.\n"));
1073 goto err_exit;
1078 * Setup the lengths for the initial reply.
1081 p->out_data.data_sent_length = 0;
1082 p->out_data.current_pdu_sent = 0;
1084 TALLOC_FREE(auth_blob.data);
1085 return True;
1087 err_exit:
1089 data_blob_free(&p->out_data.frag);
1090 TALLOC_FREE(auth_blob.data);
1091 return setup_bind_nak(p, pkt);
1094 /*******************************************************************
1095 This is the "stage3" response after a bind request and reply.
1096 *******************************************************************/
1098 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1100 struct dcerpc_auth auth_info;
1101 DATA_BLOB response = data_blob_null;
1102 struct gensec_security *gensec_security;
1103 struct spnego_context *spnego_ctx;
1104 NTSTATUS status;
1106 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1108 if (pkt->auth_length == 0) {
1109 DEBUG(0, ("No auth field sent for bind request!\n"));
1110 goto err;
1113 /* Ensure there's enough data for an authenticated request. */
1114 if (pkt->frag_length < RPC_HEADER_LEN
1115 + DCERPC_AUTH_TRAILER_LENGTH
1116 + pkt->auth_length) {
1117 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
1118 "%u is too large.\n",
1119 (unsigned int)pkt->auth_length));
1120 goto err;
1124 * Decode the authentication verifier response.
1127 status = dcerpc_pull_dcerpc_auth(pkt,
1128 &pkt->u.auth3.auth_info,
1129 &auth_info, p->endian);
1130 if (!NT_STATUS_IS_OK(status)) {
1131 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1132 goto err;
1135 /* We must NEVER look at auth_info->auth_pad_len here,
1136 * as old Samba client code gets it wrong and sends it
1137 * as zero. JRA.
1140 if (auth_info.auth_type != p->auth.auth_type) {
1141 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1142 "but auth was started as type %d!\n",
1143 auth_info.auth_type, p->auth.auth_type));
1144 goto err;
1147 switch (auth_info.auth_type) {
1148 case DCERPC_AUTH_TYPE_NTLMSSP:
1149 case DCERPC_AUTH_TYPE_KRB5:
1150 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1151 struct gensec_security);
1152 status = auth_generic_server_step(gensec_security,
1153 pkt, &auth_info.credentials,
1154 &response);
1155 break;
1156 case DCERPC_AUTH_TYPE_SPNEGO:
1157 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1158 struct spnego_context);
1159 status = spnego_server_step(spnego_ctx,
1160 pkt, &auth_info.credentials,
1161 &response);
1162 break;
1163 default:
1164 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1165 (unsigned int)auth_info.auth_type));
1166 return false;
1169 if (NT_STATUS_EQUAL(status,
1170 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1171 response.length) {
1172 DEBUG(0, (__location__ ": This was supposed to be the final "
1173 "leg, but crypto machinery claims a response is "
1174 "needed, aborting auth!\n"));
1175 data_blob_free(&response);
1176 goto err;
1178 if (!NT_STATUS_IS_OK(status)) {
1179 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1180 goto err;
1183 /* Now verify auth was indeed successful and extract server info */
1184 status = pipe_auth_verify_final(p);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1187 goto err;
1190 return true;
1192 err:
1194 TALLOC_FREE(p->auth.auth_ctx);
1195 return false;
1198 /****************************************************************************
1199 Deal with an alter context call. Can be third part of 3 leg auth request for
1200 SPNEGO calls.
1201 ****************************************************************************/
1203 static bool api_pipe_alter_context(struct pipes_struct *p,
1204 struct ncacn_packet *pkt)
1206 struct dcerpc_auth auth_info;
1207 uint16 assoc_gid;
1208 NTSTATUS status;
1209 union dcerpc_payload u;
1210 struct dcerpc_ack_ctx bind_ack_ctx;
1211 DATA_BLOB auth_resp = data_blob_null;
1212 DATA_BLOB auth_blob = data_blob_null;
1213 int pad_len = 0;
1214 struct gensec_security *gensec_security;
1215 struct spnego_context *spnego_ctx;
1217 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1219 if (pkt->u.bind.assoc_group_id != 0) {
1220 assoc_gid = pkt->u.bind.assoc_group_id;
1221 } else {
1222 assoc_gid = 0x53f0;
1226 * Create the bind response struct.
1229 /* If the requested abstract synt uuid doesn't match our client pipe,
1230 reject the bind_ack & set the transfer interface synt to all 0's,
1231 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1232 unknown to NT4)
1233 Needed when adding entries to a DACL from NT5 - SK */
1235 if (check_bind_req(p,
1236 &pkt->u.bind.ctx_list[0].abstract_syntax,
1237 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1238 pkt->u.bind.ctx_list[0].context_id)) {
1240 bind_ack_ctx.result = 0;
1241 bind_ack_ctx.reason = 0;
1242 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1243 } else {
1244 p->pipe_bound = False;
1245 /* Rejection reason: abstract syntax not supported */
1246 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1247 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1248 bind_ack_ctx.syntax = null_ndr_syntax_id;
1252 * Check if this is an authenticated alter context request.
1254 if (pkt->auth_length) {
1255 /* Quick length check. Won't catch a bad auth footer,
1256 * prevents overrun. */
1258 if (pkt->frag_length < RPC_HEADER_LEN +
1259 DCERPC_AUTH_TRAILER_LENGTH +
1260 pkt->auth_length) {
1261 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1262 "too long for fragment %u.\n",
1263 (unsigned int)pkt->auth_length,
1264 (unsigned int)pkt->frag_length ));
1265 goto err_exit;
1268 status = dcerpc_pull_dcerpc_auth(pkt,
1269 &pkt->u.bind.auth_info,
1270 &auth_info, p->endian);
1271 if (!NT_STATUS_IS_OK(status)) {
1272 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1273 goto err_exit;
1276 /* We can only finish if the pipe is unbound for now */
1277 if (p->pipe_bound) {
1278 DEBUG(0, (__location__ ": Pipe already bound, "
1279 "Altering Context not yet supported!\n"));
1280 goto err_exit;
1283 if (auth_info.auth_type != p->auth.auth_type) {
1284 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1285 "but auth was started as type %d!\n",
1286 auth_info.auth_type, p->auth.auth_type));
1287 goto err_exit;
1291 switch (auth_info.auth_type) {
1292 case DCERPC_AUTH_TYPE_SPNEGO:
1293 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1294 struct spnego_context);
1295 status = spnego_server_step(spnego_ctx,
1296 pkt,
1297 &auth_info.credentials,
1298 &auth_resp);
1299 break;
1301 case DCERPC_AUTH_TYPE_KRB5:
1302 case DCERPC_AUTH_TYPE_NTLMSSP:
1303 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1304 struct gensec_security);
1305 status = auth_generic_server_step(gensec_security,
1306 pkt,
1307 &auth_info.credentials,
1308 &auth_resp);
1309 break;
1311 default:
1312 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1313 "in alter-context call\n",
1314 auth_info.auth_type));
1315 goto err_exit;
1318 if (NT_STATUS_IS_OK(status)) {
1319 /* third leg of auth, verify auth info */
1320 status = pipe_auth_verify_final(p);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 DEBUG(0, ("Auth Verify failed (%s)\n",
1323 nt_errstr(status)));
1324 goto err_exit;
1326 } else if (NT_STATUS_EQUAL(status,
1327 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1328 DEBUG(10, ("More auth legs required.\n"));
1329 } else {
1330 DEBUG(0, ("Auth step returned an error (%s)\n",
1331 nt_errstr(status)));
1332 goto err_exit;
1336 ZERO_STRUCT(u.alter_resp);
1337 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1338 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1339 u.alter_resp.assoc_group_id = assoc_gid;
1341 /* secondary address CAN be NULL
1342 * as the specs say it's ignored.
1343 * It MUST be NULL to have the spoolss working.
1345 u.alter_resp.secondary_address = "";
1346 u.alter_resp.secondary_address_size = 1;
1348 u.alter_resp.num_results = 1;
1349 u.alter_resp.ctx_list = &bind_ack_ctx;
1351 /* NOTE: We leave the auth_info empty so we can calculate the padding
1352 * later and then append the auth_info --simo */
1355 * Marshall directly into the outgoing PDU space. We
1356 * must do this as we need to set to the bind response
1357 * header and are never sending more than one PDU here.
1360 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1361 DCERPC_PKT_ALTER_RESP,
1362 DCERPC_PFC_FLAG_FIRST |
1363 DCERPC_PFC_FLAG_LAST,
1364 auth_resp.length,
1365 pkt->call_id,
1367 &p->out_data.frag);
1368 if (!NT_STATUS_IS_OK(status)) {
1369 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1370 nt_errstr(status)));
1373 if (auth_resp.length) {
1375 /* Work out any padding needed before the auth footer. */
1376 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1377 if (pad_len) {
1378 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1379 DEBUG(10, ("auth pad_len = %u\n",
1380 (unsigned int)pad_len));
1383 status = dcerpc_push_dcerpc_auth(pkt,
1384 auth_info.auth_type,
1385 auth_info.auth_level,
1386 pad_len,
1387 1, /* auth_context_id */
1388 &auth_resp,
1389 &auth_blob);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1392 goto err_exit;
1396 /* Now that we have the auth len store it into the right place in
1397 * the dcerpc header */
1398 dcerpc_set_frag_length(&p->out_data.frag,
1399 p->out_data.frag.length +
1400 pad_len + auth_blob.length);
1402 if (auth_resp.length) {
1403 if (pad_len) {
1404 char pad[SERVER_NDR_PADDING_SIZE];
1405 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1406 if (!data_blob_append(p->mem_ctx,
1407 &p->out_data.frag,
1408 pad, pad_len)) {
1409 DEBUG(0, ("api_pipe_bind_req: failed to add "
1410 "%u bytes of pad data.\n",
1411 (unsigned int)pad_len));
1412 goto err_exit;
1416 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1417 auth_blob.data, auth_blob.length)) {
1418 DEBUG(0, ("Append of auth info failed.\n"));
1419 goto err_exit;
1424 * Setup the lengths for the initial reply.
1427 p->out_data.data_sent_length = 0;
1428 p->out_data.current_pdu_sent = 0;
1430 TALLOC_FREE(auth_blob.data);
1431 return True;
1433 err_exit:
1435 data_blob_free(&p->out_data.frag);
1436 TALLOC_FREE(auth_blob.data);
1437 return setup_bind_nak(p, pkt);
1440 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1441 const struct api_struct *api_rpc_cmds, int n_cmds,
1442 const struct ndr_syntax_id *syntax);
1444 /****************************************************************************
1445 Find the correct RPC function to call for this request.
1446 If the pipe is authenticated then become the correct UNIX user
1447 before doing the call.
1448 ****************************************************************************/
1450 static bool api_pipe_request(struct pipes_struct *p,
1451 struct ncacn_packet *pkt)
1453 bool ret = False;
1454 struct pipe_rpc_fns *pipe_fns;
1456 if (!p->pipe_bound) {
1457 DEBUG(1, ("Pipe not bound!\n"));
1458 data_blob_free(&p->out_data.rdata);
1459 return false;
1462 if (!become_authenticated_pipe_user(p->session_info)) {
1463 DEBUG(1, ("Failed to become pipe user!\n"));
1464 data_blob_free(&p->out_data.rdata);
1465 return false;
1468 /* get the set of RPC functions for this context */
1470 pipe_fns = find_pipe_fns_by_context(p->contexts,
1471 pkt->u.request.context_id);
1473 if ( pipe_fns ) {
1474 TALLOC_CTX *frame = talloc_stackframe();
1476 DEBUG(5, ("Requested %s rpc service\n",
1477 get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
1479 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1480 &pipe_fns->syntax);
1482 TALLOC_FREE(frame);
1484 else {
1485 DEBUG(0, ("No rpc function table associated with context "
1486 "[%d]\n",
1487 pkt->u.request.context_id));
1490 unbecome_authenticated_pipe_user();
1492 return ret;
1495 /*******************************************************************
1496 Calls the underlying RPC function for a named pipe.
1497 ********************************************************************/
1499 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1500 const struct api_struct *api_rpc_cmds, int n_cmds,
1501 const struct ndr_syntax_id *syntax)
1503 int fn_num;
1504 uint32_t offset1;
1506 /* interpret the command */
1507 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1508 get_pipe_name_from_syntax(talloc_tos(), syntax),
1509 pkt->u.request.opnum));
1511 if (DEBUGLEVEL >= 50) {
1512 fstring name;
1513 slprintf(name, sizeof(name)-1, "in_%s",
1514 get_pipe_name_from_syntax(talloc_tos(), syntax));
1515 dump_pdu_region(name, pkt->u.request.opnum,
1516 &p->in_data.data, 0,
1517 p->in_data.data.length);
1520 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1521 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1522 api_rpc_cmds[fn_num].fn != NULL) {
1523 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1524 api_rpc_cmds[fn_num].name));
1525 break;
1529 if (fn_num == n_cmds) {
1531 * For an unknown RPC just return a fault PDU but
1532 * return True to allow RPC's on the pipe to continue
1533 * and not put the pipe into fault state. JRA.
1535 DEBUG(4, ("unknown\n"));
1536 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1537 return True;
1540 offset1 = p->out_data.rdata.length;
1542 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1543 fn_num, api_rpc_cmds[fn_num].fn));
1544 /* do the actual command */
1545 if(!api_rpc_cmds[fn_num].fn(p)) {
1546 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1547 get_pipe_name_from_syntax(talloc_tos(), syntax),
1548 api_rpc_cmds[fn_num].name));
1549 data_blob_free(&p->out_data.rdata);
1550 return False;
1553 if (p->bad_handle_fault_state) {
1554 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1555 p->bad_handle_fault_state = False;
1556 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1557 return True;
1560 if (p->rng_fault_state) {
1561 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1562 p->rng_fault_state = False;
1563 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1564 return True;
1567 if (DEBUGLEVEL >= 50) {
1568 fstring name;
1569 slprintf(name, sizeof(name)-1, "out_%s",
1570 get_pipe_name_from_syntax(talloc_tos(), syntax));
1571 dump_pdu_region(name, pkt->u.request.opnum,
1572 &p->out_data.rdata, offset1,
1573 p->out_data.rdata.length);
1576 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1577 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1579 /* Check for buffer underflow in rpc parsing */
1580 if ((DEBUGLEVEL >= 10) &&
1581 (pkt->frag_length < p->in_data.data.length)) {
1582 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1583 dump_data(10, p->in_data.data.data + pkt->frag_length,
1584 p->in_data.data.length - pkt->frag_length);
1587 return True;
1590 /****************************************************************************
1591 Initialise an outgoing packet.
1592 ****************************************************************************/
1594 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1596 output_data *o_data = &p->out_data;
1598 /* Reset the offset counters. */
1599 o_data->data_sent_length = 0;
1600 o_data->current_pdu_sent = 0;
1602 data_blob_free(&o_data->frag);
1604 /* Free any memory in the current return data buffer. */
1605 data_blob_free(&o_data->rdata);
1607 return True;
1610 /****************************************************************************
1611 Sets the fault state on incoming packets.
1612 ****************************************************************************/
1614 void set_incoming_fault(struct pipes_struct *p)
1616 data_blob_free(&p->in_data.data);
1617 p->in_data.pdu_needed_len = 0;
1618 p->in_data.pdu.length = 0;
1619 p->fault_state = True;
1621 DEBUG(10, ("Setting fault state\n"));
1624 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1625 struct ncacn_packet *pkt,
1626 DATA_BLOB *raw_pkt)
1628 NTSTATUS status;
1629 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1630 size_t pad_len;
1632 DEBUG(10, ("Checking request auth.\n"));
1634 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1635 hdr_size += 16;
1638 /* in case of sealing this function will unseal the data in place */
1639 status = dcerpc_check_auth(auth, pkt,
1640 &pkt->u.request.stub_and_verifier,
1641 hdr_size, raw_pkt,
1642 &pad_len);
1643 if (!NT_STATUS_IS_OK(status)) {
1644 return status;
1648 /* remove padding and auth trailer,
1649 * this way the caller will get just the data */
1650 if (pkt->auth_length) {
1651 size_t trail_len = pad_len
1652 + DCERPC_AUTH_TRAILER_LENGTH
1653 + pkt->auth_length;
1654 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1655 return NT_STATUS_INFO_LENGTH_MISMATCH;
1657 pkt->u.request.stub_and_verifier.length -= trail_len;
1660 return NT_STATUS_OK;
1663 /****************************************************************************
1664 Processes a request pdu. This will do auth processing if needed, and
1665 appends the data into the complete stream if the LAST flag is not set.
1666 ****************************************************************************/
1668 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1670 NTSTATUS status;
1671 DATA_BLOB data;
1673 if (!p->pipe_bound) {
1674 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1675 set_incoming_fault(p);
1676 return False;
1679 /* Store the opnum */
1680 p->opnum = pkt->u.request.opnum;
1682 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1683 if (!NT_STATUS_IS_OK(status)) {
1684 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1685 nt_errstr(status)));
1686 set_incoming_fault(p);
1687 return false;
1690 data = pkt->u.request.stub_and_verifier;
1693 * Check the data length doesn't go over the 15Mb limit.
1694 * increased after observing a bug in the Windows NT 4.0 SP6a
1695 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1696 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1699 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1700 DEBUG(0, ("process_request_pdu: "
1701 "rpc data buffer too large (%u) + (%u)\n",
1702 (unsigned int)p->in_data.data.length,
1703 (unsigned int)data.length));
1704 set_incoming_fault(p);
1705 return False;
1709 * Append the data portion into the buffer and return.
1712 if (data.length) {
1713 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1714 data.data, data.length)) {
1715 DEBUG(0, ("Unable to append data size %u "
1716 "to parse buffer of size %u.\n",
1717 (unsigned int)data.length,
1718 (unsigned int)p->in_data.data.length));
1719 set_incoming_fault(p);
1720 return False;
1724 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1725 bool ret = False;
1727 * Ok - we finally have a complete RPC stream.
1728 * Call the rpc command to process it.
1732 * Process the complete data stream here.
1734 if (pipe_init_outgoing_data(p)) {
1735 ret = api_pipe_request(p, pkt);
1738 return ret;
1741 return True;
1744 /****************************************************************************
1745 Processes a finished PDU stored in p->in_data.pdu.
1746 ****************************************************************************/
1748 void process_complete_pdu(struct pipes_struct *p)
1750 struct ncacn_packet *pkt = NULL;
1751 NTSTATUS status;
1752 bool reply = False;
1754 if(p->fault_state) {
1755 DEBUG(10,("RPC connection in fault state.\n"));
1756 goto done;
1759 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1760 if (!pkt) {
1761 DEBUG(0, ("Out of memory!\n"));
1762 goto done;
1766 * Ensure we're using the corrent endianness for both the
1767 * RPC header flags and the raw data we will be reading from.
1769 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1770 p->endian = RPC_LITTLE_ENDIAN;
1771 } else {
1772 p->endian = RPC_BIG_ENDIAN;
1774 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1776 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1777 pkt, p->endian);
1778 if (!NT_STATUS_IS_OK(status)) {
1779 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1780 nt_errstr(status)));
1781 goto done;
1784 /* Store the call_id */
1785 p->call_id = pkt->call_id;
1787 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1789 switch (pkt->ptype) {
1790 case DCERPC_PKT_REQUEST:
1791 reply = process_request_pdu(p, pkt);
1792 break;
1794 case DCERPC_PKT_PING: /* CL request - ignore... */
1795 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1796 (unsigned int)pkt->ptype));
1797 break;
1799 case DCERPC_PKT_RESPONSE: /* No responses here. */
1800 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1801 break;
1803 case DCERPC_PKT_FAULT:
1804 case DCERPC_PKT_WORKING:
1805 /* CL request - reply to a ping when a call in process. */
1806 case DCERPC_PKT_NOCALL:
1807 /* CL - server reply to a ping call. */
1808 case DCERPC_PKT_REJECT:
1809 case DCERPC_PKT_ACK:
1810 case DCERPC_PKT_CL_CANCEL:
1811 case DCERPC_PKT_FACK:
1812 case DCERPC_PKT_CANCEL_ACK:
1813 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1814 (unsigned int)pkt->ptype));
1815 break;
1817 case DCERPC_PKT_BIND:
1819 * We assume that a pipe bind is only in one pdu.
1821 if (pipe_init_outgoing_data(p)) {
1822 reply = api_pipe_bind_req(p, pkt);
1824 break;
1826 case DCERPC_PKT_BIND_ACK:
1827 case DCERPC_PKT_BIND_NAK:
1828 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1829 "packet type %u received.\n",
1830 (unsigned int)pkt->ptype));
1831 break;
1834 case DCERPC_PKT_ALTER:
1836 * We assume that a pipe bind is only in one pdu.
1838 if (pipe_init_outgoing_data(p)) {
1839 reply = api_pipe_alter_context(p, pkt);
1841 break;
1843 case DCERPC_PKT_ALTER_RESP:
1844 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1845 "Should only be server -> client.\n"));
1846 break;
1848 case DCERPC_PKT_AUTH3:
1850 * The third packet in an auth exchange.
1852 if (pipe_init_outgoing_data(p)) {
1853 reply = api_pipe_bind_auth3(p, pkt);
1855 break;
1857 case DCERPC_PKT_SHUTDOWN:
1858 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1859 "Should only be server -> client.\n"));
1860 break;
1862 case DCERPC_PKT_CO_CANCEL:
1863 /* For now just free all client data and continue
1864 * processing. */
1865 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1866 " Abandoning rpc call.\n"));
1867 /* As we never do asynchronous RPC serving, we can
1868 * never cancel a call (as far as I know).
1869 * If we ever did we'd have to send a cancel_ack reply.
1870 * For now, just free all client data and continue
1871 * processing. */
1872 reply = True;
1873 break;
1875 #if 0
1876 /* Enable this if we're doing async rpc. */
1877 /* We must check the outstanding callid matches. */
1878 if (pipe_init_outgoing_data(p)) {
1879 /* Send a cancel_ack PDU reply. */
1880 /* We should probably check the auth-verifier here. */
1881 reply = setup_cancel_ack_reply(p, pkt);
1883 break;
1884 #endif
1886 case DCERPC_PKT_ORPHANED:
1887 /* We should probably check the auth-verifier here.
1888 * For now just free all client data and continue
1889 * processing. */
1890 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1891 " Abandoning rpc call.\n"));
1892 reply = True;
1893 break;
1895 default:
1896 DEBUG(0, ("process_complete_pdu: "
1897 "Unknown rpc type = %u received.\n",
1898 (unsigned int)pkt->ptype));
1899 break;
1902 done:
1903 if (!reply) {
1904 DEBUG(3,("DCE/RPC fault sent!"));
1905 set_incoming_fault(p);
1906 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1907 TALLOC_FREE(pkt);
1908 } else {
1910 * Reset the lengths. We're ready for a new pdu.
1912 TALLOC_FREE(p->in_data.pdu.data);
1913 p->in_data.pdu_needed_len = 0;
1914 p->in_data.pdu.length = 0;
1917 TALLOC_FREE(pkt);