test:dnsserver: Add zone creation and deletion test
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob61e306c1996bce331f67eb9acae828a23fbeefb1
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 /*******************************************************************
680 Handle a GSSAPI bind auth.
681 *******************************************************************/
683 static bool pipe_gssapi_auth_bind(struct pipes_struct *p,
684 TALLOC_CTX *mem_ctx,
685 struct dcerpc_auth *auth_info,
686 DATA_BLOB *response)
688 NTSTATUS status;
689 struct gse_context *gse_ctx = NULL;
691 status = gssapi_server_auth_start(p,
692 (auth_info->auth_level ==
693 DCERPC_AUTH_LEVEL_INTEGRITY),
694 (auth_info->auth_level ==
695 DCERPC_AUTH_LEVEL_PRIVACY),
696 true,
697 &auth_info->credentials,
698 response,
699 &gse_ctx);
700 if (!NT_STATUS_IS_OK(status)) {
701 DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
702 nt_errstr(status)));
703 goto err;
706 /* Make sure data is bound to the memctx, to be freed the caller */
707 talloc_steal(mem_ctx, response->data);
709 p->auth.auth_ctx = gse_ctx;
710 p->auth.auth_type = DCERPC_AUTH_TYPE_KRB5;
712 DEBUG(10, ("KRB5 auth started\n"));
714 return true;
716 err:
717 TALLOC_FREE(gse_ctx);
718 return false;
721 static NTSTATUS pipe_gssapi_verify_final(TALLOC_CTX *mem_ctx,
722 struct gse_context *gse_ctx,
723 const struct tsocket_address *remote_address,
724 struct auth_session_info **session_info)
726 NTSTATUS status;
727 bool bret;
729 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
730 ensure the underlying flags are also set. If not we should
731 refuse the bind. */
733 status = gssapi_server_check_flags(gse_ctx);
734 if (!NT_STATUS_IS_OK(status)) {
735 DEBUG(0, ("Requested Security Layers not honored!\n"));
736 return status;
739 status = gssapi_server_get_user_info(gse_ctx, mem_ctx,
740 remote_address, session_info);
741 if (!NT_STATUS_IS_OK(status)) {
742 DEBUG(0, (__location__ ": failed to obtain the server info "
743 "for authenticated user: %s\n", nt_errstr(status)));
744 return status;
748 * We're an authenticated bind over smb, so the session key needs to
749 * be set to "SystemLibraryDTC". Weird, but this is what Windows
750 * does. See the RPC-SAMBA3SESSIONKEY.
753 bret = session_info_set_session_key((*session_info), generic_session_key());
754 if (!bret) {
755 return NT_STATUS_ACCESS_DENIED;
758 return NT_STATUS_OK;
761 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
763 enum spnego_mech auth_type;
764 struct gensec_security *gensec_security;
765 struct spnego_context *spnego_ctx;
766 struct gse_context *gse_ctx;
767 void *mech_ctx;
768 NTSTATUS status;
770 switch (p->auth.auth_type) {
771 case DCERPC_AUTH_TYPE_NTLMSSP:
772 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
773 struct gensec_security);
774 if (!pipe_auth_generic_verify_final(p, gensec_security,
775 p->auth.auth_level,
776 &p->session_info)) {
777 return NT_STATUS_ACCESS_DENIED;
779 break;
780 case DCERPC_AUTH_TYPE_KRB5:
781 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
782 struct gse_context);
783 status = pipe_gssapi_verify_final(p, gse_ctx,
784 p->remote_address,
785 &p->session_info);
786 if (!NT_STATUS_IS_OK(status)) {
787 DEBUG(1, ("gssapi bind failed with: %s",
788 nt_errstr(status)));
789 return status;
791 break;
792 case DCERPC_AUTH_TYPE_SPNEGO:
793 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
794 struct spnego_context);
795 status = spnego_get_negotiated_mech(spnego_ctx,
796 &auth_type, &mech_ctx);
797 if (!NT_STATUS_IS_OK(status)) {
798 DEBUG(0, ("Bad SPNEGO state (%s)\n",
799 nt_errstr(status)));
800 return status;
802 switch(auth_type) {
803 case SPNEGO_KRB5:
804 gse_ctx = talloc_get_type_abort(mech_ctx,
805 struct gse_context);
806 status = pipe_gssapi_verify_final(p, gse_ctx,
807 p->remote_address,
808 &p->session_info);
809 if (!NT_STATUS_IS_OK(status)) {
810 DEBUG(1, ("gssapi bind failed with: %s",
811 nt_errstr(status)));
812 return status;
814 break;
815 case SPNEGO_NTLMSSP:
816 gensec_security = talloc_get_type_abort(mech_ctx,
817 struct gensec_security);
818 if (!pipe_auth_generic_verify_final(p, gensec_security,
819 p->auth.auth_level,
820 &p->session_info)) {
821 return NT_STATUS_ACCESS_DENIED;
823 break;
824 default:
825 DEBUG(0, (__location__ ": incorrect spnego type "
826 "(%d).\n", auth_type));
827 return NT_STATUS_ACCESS_DENIED;
829 break;
830 default:
831 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
832 (unsigned int)p->auth.auth_type));
833 return NT_STATUS_ACCESS_DENIED;
836 p->pipe_bound = true;
838 return NT_STATUS_OK;
841 /*******************************************************************
842 Respond to a pipe bind request.
843 *******************************************************************/
845 static bool api_pipe_bind_req(struct pipes_struct *p,
846 struct ncacn_packet *pkt)
848 struct dcerpc_auth auth_info;
849 uint16 assoc_gid;
850 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
851 NTSTATUS status;
852 struct ndr_syntax_id id;
853 union dcerpc_payload u;
854 struct dcerpc_ack_ctx bind_ack_ctx;
855 DATA_BLOB auth_resp = data_blob_null;
856 DATA_BLOB auth_blob = data_blob_null;
858 /* No rebinds on a bound pipe - use alter context. */
859 if (p->pipe_bound) {
860 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
861 return setup_bind_nak(p, pkt);
864 if (pkt->u.bind.num_contexts == 0) {
865 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
866 goto err_exit;
870 * Try and find the correct pipe name to ensure
871 * that this is a pipe name we support.
873 id = pkt->u.bind.ctx_list[0].abstract_syntax;
874 if (rpc_srv_pipe_exists_by_id(&id)) {
875 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
876 rpc_srv_get_pipe_cli_name(&id),
877 rpc_srv_get_pipe_srv_name(&id)));
878 } else {
879 status = smb_probe_module(
880 "rpc", get_pipe_name_from_syntax(
881 talloc_tos(),
882 &id));
884 if (NT_STATUS_IS_ERR(status)) {
885 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
886 "%s in bind request.\n",
887 get_pipe_name_from_syntax(talloc_tos(), &id)));
889 return setup_bind_nak(p, pkt);
892 if (rpc_srv_get_pipe_interface_by_cli_name(
893 get_pipe_name_from_syntax(talloc_tos(),
894 &id),
895 &id)) {
896 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
897 rpc_srv_get_pipe_cli_name(&id),
898 rpc_srv_get_pipe_srv_name(&id)));
899 } else {
900 DEBUG(0, ("module %s doesn't provide functions for "
901 "pipe %s!\n",
902 get_pipe_name_from_syntax(talloc_tos(), &id),
903 get_pipe_name_from_syntax(talloc_tos(), &id)));
904 return setup_bind_nak(p, pkt);
908 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
910 if (pkt->u.bind.assoc_group_id != 0) {
911 assoc_gid = pkt->u.bind.assoc_group_id;
912 } else {
913 assoc_gid = 0x53f0;
917 * Create the bind response struct.
920 /* If the requested abstract synt uuid doesn't match our client pipe,
921 reject the bind_ack & set the transfer interface synt to all 0's,
922 ver 0 (observed when NT5 attempts to bind to abstract interfaces
923 unknown to NT4)
924 Needed when adding entries to a DACL from NT5 - SK */
926 if (check_bind_req(p,
927 &pkt->u.bind.ctx_list[0].abstract_syntax,
928 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
929 pkt->u.bind.ctx_list[0].context_id)) {
931 bind_ack_ctx.result = 0;
932 bind_ack_ctx.reason = 0;
933 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
934 } else {
935 p->pipe_bound = False;
936 /* Rejection reason: abstract syntax not supported */
937 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
938 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
939 bind_ack_ctx.syntax = null_ndr_syntax_id;
943 * Check if this is an authenticated bind request.
945 if (pkt->auth_length) {
946 /* Quick length check. Won't catch a bad auth footer,
947 * prevents overrun. */
949 if (pkt->frag_length < RPC_HEADER_LEN +
950 DCERPC_AUTH_TRAILER_LENGTH +
951 pkt->auth_length) {
952 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
953 "too long for fragment %u.\n",
954 (unsigned int)pkt->auth_length,
955 (unsigned int)pkt->frag_length));
956 goto err_exit;
960 * Decode the authentication verifier.
962 status = dcerpc_pull_dcerpc_auth(pkt,
963 &pkt->u.bind.auth_info,
964 &auth_info, p->endian);
965 if (!NT_STATUS_IS_OK(status)) {
966 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
967 goto err_exit;
970 auth_type = auth_info.auth_type;
972 /* Work out if we have to sign or seal etc. */
973 switch (auth_info.auth_level) {
974 case DCERPC_AUTH_LEVEL_INTEGRITY:
975 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
976 break;
977 case DCERPC_AUTH_LEVEL_PRIVACY:
978 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
979 break;
980 case DCERPC_AUTH_LEVEL_CONNECT:
981 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
982 break;
983 default:
984 DEBUG(0, ("Unexpected auth level (%u).\n",
985 (unsigned int)auth_info.auth_level ));
986 goto err_exit;
989 switch (auth_type) {
990 case DCERPC_AUTH_TYPE_NTLMSSP:
991 if (!pipe_auth_generic_bind(p, pkt,
992 &auth_info, &auth_resp)) {
993 goto err_exit;
995 assoc_gid = 0x7a77;
996 break;
998 case DCERPC_AUTH_TYPE_SCHANNEL:
999 if (!pipe_schannel_auth_bind(p, pkt,
1000 &auth_info, &auth_resp)) {
1001 goto err_exit;
1003 break;
1005 case DCERPC_AUTH_TYPE_SPNEGO:
1006 if (!pipe_spnego_auth_bind(p, pkt,
1007 &auth_info, &auth_resp)) {
1008 goto err_exit;
1010 break;
1012 case DCERPC_AUTH_TYPE_KRB5:
1013 if (!pipe_gssapi_auth_bind(p, pkt,
1014 &auth_info, &auth_resp)) {
1015 goto err_exit;
1017 break;
1019 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1020 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
1021 TALLOC_FREE(p->session_info);
1023 status = make_session_info_system(p,
1024 &p->session_info);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 goto err_exit;
1029 auth_resp = data_blob_talloc(pkt,
1030 "NCALRPC_AUTH_OK",
1031 15);
1033 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
1034 p->pipe_bound = true;
1035 } else {
1036 goto err_exit;
1038 break;
1040 case DCERPC_AUTH_TYPE_NONE:
1041 break;
1043 default:
1044 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1045 goto err_exit;
1049 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1050 /* Unauthenticated bind request. */
1051 /* We're finished - no more packets. */
1052 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1053 /* We must set the pipe auth_level here also. */
1054 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1055 p->pipe_bound = True;
1056 /* The session key was initialized from the SMB
1057 * session in make_internal_rpc_pipe_p */
1060 ZERO_STRUCT(u.bind_ack);
1061 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1062 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1063 u.bind_ack.assoc_group_id = assoc_gid;
1065 /* name has to be \PIPE\xxxxx */
1066 u.bind_ack.secondary_address =
1067 talloc_asprintf(pkt, "\\PIPE\\%s",
1068 rpc_srv_get_pipe_srv_name(&id));
1069 if (!u.bind_ack.secondary_address) {
1070 DEBUG(0, ("Out of memory!\n"));
1071 goto err_exit;
1073 u.bind_ack.secondary_address_size =
1074 strlen(u.bind_ack.secondary_address) + 1;
1076 u.bind_ack.num_results = 1;
1077 u.bind_ack.ctx_list = &bind_ack_ctx;
1079 /* NOTE: We leave the auth_info empty so we can calculate the padding
1080 * later and then append the auth_info --simo */
1083 * Marshall directly into the outgoing PDU space. We
1084 * must do this as we need to set to the bind response
1085 * header and are never sending more than one PDU here.
1088 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1089 DCERPC_PKT_BIND_ACK,
1090 DCERPC_PFC_FLAG_FIRST |
1091 DCERPC_PFC_FLAG_LAST,
1092 auth_resp.length,
1093 pkt->call_id,
1095 &p->out_data.frag);
1096 if (!NT_STATUS_IS_OK(status)) {
1097 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1098 nt_errstr(status)));
1101 if (auth_resp.length) {
1103 status = dcerpc_push_dcerpc_auth(pkt,
1104 auth_type,
1105 auth_info.auth_level,
1107 1, /* auth_context_id */
1108 &auth_resp,
1109 &auth_blob);
1110 if (!NT_STATUS_IS_OK(status)) {
1111 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1112 goto err_exit;
1116 /* Now that we have the auth len store it into the right place in
1117 * the dcerpc header */
1118 dcerpc_set_frag_length(&p->out_data.frag,
1119 p->out_data.frag.length + auth_blob.length);
1121 if (auth_blob.length) {
1123 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1124 auth_blob.data, auth_blob.length)) {
1125 DEBUG(0, ("Append of auth info failed.\n"));
1126 goto err_exit;
1131 * Setup the lengths for the initial reply.
1134 p->out_data.data_sent_length = 0;
1135 p->out_data.current_pdu_sent = 0;
1137 TALLOC_FREE(auth_blob.data);
1138 return True;
1140 err_exit:
1142 data_blob_free(&p->out_data.frag);
1143 TALLOC_FREE(auth_blob.data);
1144 return setup_bind_nak(p, pkt);
1147 /*******************************************************************
1148 This is the "stage3" response after a bind request and reply.
1149 *******************************************************************/
1151 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1153 struct dcerpc_auth auth_info;
1154 DATA_BLOB response = data_blob_null;
1155 struct gensec_security *gensec_security;
1156 struct spnego_context *spnego_ctx;
1157 struct gse_context *gse_ctx;
1158 NTSTATUS status;
1160 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1162 if (pkt->auth_length == 0) {
1163 DEBUG(0, ("No auth field sent for bind request!\n"));
1164 goto err;
1167 /* Ensure there's enough data for an authenticated request. */
1168 if (pkt->frag_length < RPC_HEADER_LEN
1169 + DCERPC_AUTH_TRAILER_LENGTH
1170 + pkt->auth_length) {
1171 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
1172 "%u is too large.\n",
1173 (unsigned int)pkt->auth_length));
1174 goto err;
1178 * Decode the authentication verifier response.
1181 status = dcerpc_pull_dcerpc_auth(pkt,
1182 &pkt->u.auth3.auth_info,
1183 &auth_info, p->endian);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1186 goto err;
1189 /* We must NEVER look at auth_info->auth_pad_len here,
1190 * as old Samba client code gets it wrong and sends it
1191 * as zero. JRA.
1194 if (auth_info.auth_type != p->auth.auth_type) {
1195 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1196 "but auth was started as type %d!\n",
1197 auth_info.auth_type, p->auth.auth_type));
1198 goto err;
1201 switch (auth_info.auth_type) {
1202 case DCERPC_AUTH_TYPE_NTLMSSP:
1203 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1204 struct gensec_security);
1205 status = auth_generic_server_step(gensec_security,
1206 pkt, &auth_info.credentials,
1207 &response);
1208 break;
1209 case DCERPC_AUTH_TYPE_KRB5:
1210 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1211 struct gse_context);
1212 status = gssapi_server_step(gse_ctx,
1213 pkt, &auth_info.credentials,
1214 &response);
1215 break;
1216 case DCERPC_AUTH_TYPE_SPNEGO:
1217 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1218 struct spnego_context);
1219 status = spnego_server_step(spnego_ctx,
1220 pkt, &auth_info.credentials,
1221 &response);
1222 break;
1223 default:
1224 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1225 (unsigned int)auth_info.auth_type));
1226 return false;
1229 if (NT_STATUS_EQUAL(status,
1230 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1231 response.length) {
1232 DEBUG(0, (__location__ ": This was supposed to be the final "
1233 "leg, but crypto machinery claims a response is "
1234 "needed, aborting auth!\n"));
1235 data_blob_free(&response);
1236 goto err;
1238 if (!NT_STATUS_IS_OK(status)) {
1239 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1240 goto err;
1243 /* Now verify auth was indeed successful and extract server info */
1244 status = pipe_auth_verify_final(p);
1245 if (!NT_STATUS_IS_OK(status)) {
1246 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1247 goto err;
1250 return true;
1252 err:
1254 TALLOC_FREE(p->auth.auth_ctx);
1255 return false;
1258 /****************************************************************************
1259 Deal with an alter context call. Can be third part of 3 leg auth request for
1260 SPNEGO calls.
1261 ****************************************************************************/
1263 static bool api_pipe_alter_context(struct pipes_struct *p,
1264 struct ncacn_packet *pkt)
1266 struct dcerpc_auth auth_info;
1267 uint16 assoc_gid;
1268 NTSTATUS status;
1269 union dcerpc_payload u;
1270 struct dcerpc_ack_ctx bind_ack_ctx;
1271 DATA_BLOB auth_resp = data_blob_null;
1272 DATA_BLOB auth_blob = data_blob_null;
1273 int pad_len = 0;
1274 struct gensec_security *gensec_security;
1275 struct spnego_context *spnego_ctx;
1276 struct gse_context *gse_ctx;
1278 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1280 if (pkt->u.bind.assoc_group_id != 0) {
1281 assoc_gid = pkt->u.bind.assoc_group_id;
1282 } else {
1283 assoc_gid = 0x53f0;
1287 * Create the bind response struct.
1290 /* If the requested abstract synt uuid doesn't match our client pipe,
1291 reject the bind_ack & set the transfer interface synt to all 0's,
1292 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1293 unknown to NT4)
1294 Needed when adding entries to a DACL from NT5 - SK */
1296 if (check_bind_req(p,
1297 &pkt->u.bind.ctx_list[0].abstract_syntax,
1298 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1299 pkt->u.bind.ctx_list[0].context_id)) {
1301 bind_ack_ctx.result = 0;
1302 bind_ack_ctx.reason = 0;
1303 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1304 } else {
1305 p->pipe_bound = False;
1306 /* Rejection reason: abstract syntax not supported */
1307 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1308 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1309 bind_ack_ctx.syntax = null_ndr_syntax_id;
1313 * Check if this is an authenticated alter context request.
1315 if (pkt->auth_length) {
1316 /* Quick length check. Won't catch a bad auth footer,
1317 * prevents overrun. */
1319 if (pkt->frag_length < RPC_HEADER_LEN +
1320 DCERPC_AUTH_TRAILER_LENGTH +
1321 pkt->auth_length) {
1322 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1323 "too long for fragment %u.\n",
1324 (unsigned int)pkt->auth_length,
1325 (unsigned int)pkt->frag_length ));
1326 goto err_exit;
1329 status = dcerpc_pull_dcerpc_auth(pkt,
1330 &pkt->u.bind.auth_info,
1331 &auth_info, p->endian);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1334 goto err_exit;
1337 /* We can only finish if the pipe is unbound for now */
1338 if (p->pipe_bound) {
1339 DEBUG(0, (__location__ ": Pipe already bound, "
1340 "Altering Context not yet supported!\n"));
1341 goto err_exit;
1344 if (auth_info.auth_type != p->auth.auth_type) {
1345 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1346 "but auth was started as type %d!\n",
1347 auth_info.auth_type, p->auth.auth_type));
1348 goto err_exit;
1352 switch (auth_info.auth_type) {
1353 case DCERPC_AUTH_TYPE_SPNEGO:
1354 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1355 struct spnego_context);
1356 status = spnego_server_step(spnego_ctx,
1357 pkt,
1358 &auth_info.credentials,
1359 &auth_resp);
1360 break;
1362 case DCERPC_AUTH_TYPE_KRB5:
1363 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1364 struct gse_context);
1365 status = gssapi_server_step(gse_ctx,
1366 pkt,
1367 &auth_info.credentials,
1368 &auth_resp);
1369 break;
1370 case DCERPC_AUTH_TYPE_NTLMSSP:
1371 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1372 struct gensec_security);
1373 status = auth_generic_server_step(gensec_security,
1374 pkt,
1375 &auth_info.credentials,
1376 &auth_resp);
1377 break;
1379 default:
1380 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1381 "in alter-context call\n",
1382 auth_info.auth_type));
1383 goto err_exit;
1386 if (NT_STATUS_IS_OK(status)) {
1387 /* third leg of auth, verify auth info */
1388 status = pipe_auth_verify_final(p);
1389 if (!NT_STATUS_IS_OK(status)) {
1390 DEBUG(0, ("Auth Verify failed (%s)\n",
1391 nt_errstr(status)));
1392 goto err_exit;
1394 } else if (NT_STATUS_EQUAL(status,
1395 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1396 DEBUG(10, ("More auth legs required.\n"));
1397 } else {
1398 DEBUG(0, ("Auth step returned an error (%s)\n",
1399 nt_errstr(status)));
1400 goto err_exit;
1404 ZERO_STRUCT(u.alter_resp);
1405 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1406 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1407 u.alter_resp.assoc_group_id = assoc_gid;
1409 /* secondary address CAN be NULL
1410 * as the specs say it's ignored.
1411 * It MUST be NULL to have the spoolss working.
1413 u.alter_resp.secondary_address = "";
1414 u.alter_resp.secondary_address_size = 1;
1416 u.alter_resp.num_results = 1;
1417 u.alter_resp.ctx_list = &bind_ack_ctx;
1419 /* NOTE: We leave the auth_info empty so we can calculate the padding
1420 * later and then append the auth_info --simo */
1423 * Marshall directly into the outgoing PDU space. We
1424 * must do this as we need to set to the bind response
1425 * header and are never sending more than one PDU here.
1428 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1429 DCERPC_PKT_ALTER_RESP,
1430 DCERPC_PFC_FLAG_FIRST |
1431 DCERPC_PFC_FLAG_LAST,
1432 auth_resp.length,
1433 pkt->call_id,
1435 &p->out_data.frag);
1436 if (!NT_STATUS_IS_OK(status)) {
1437 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1438 nt_errstr(status)));
1441 if (auth_resp.length) {
1443 /* Work out any padding needed before the auth footer. */
1444 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1445 if (pad_len) {
1446 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1447 DEBUG(10, ("auth pad_len = %u\n",
1448 (unsigned int)pad_len));
1451 status = dcerpc_push_dcerpc_auth(pkt,
1452 auth_info.auth_type,
1453 auth_info.auth_level,
1454 pad_len,
1455 1, /* auth_context_id */
1456 &auth_resp,
1457 &auth_blob);
1458 if (!NT_STATUS_IS_OK(status)) {
1459 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1460 goto err_exit;
1464 /* Now that we have the auth len store it into the right place in
1465 * the dcerpc header */
1466 dcerpc_set_frag_length(&p->out_data.frag,
1467 p->out_data.frag.length +
1468 pad_len + auth_blob.length);
1470 if (auth_resp.length) {
1471 if (pad_len) {
1472 char pad[SERVER_NDR_PADDING_SIZE];
1473 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1474 if (!data_blob_append(p->mem_ctx,
1475 &p->out_data.frag,
1476 pad, pad_len)) {
1477 DEBUG(0, ("api_pipe_bind_req: failed to add "
1478 "%u bytes of pad data.\n",
1479 (unsigned int)pad_len));
1480 goto err_exit;
1484 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1485 auth_blob.data, auth_blob.length)) {
1486 DEBUG(0, ("Append of auth info failed.\n"));
1487 goto err_exit;
1492 * Setup the lengths for the initial reply.
1495 p->out_data.data_sent_length = 0;
1496 p->out_data.current_pdu_sent = 0;
1498 TALLOC_FREE(auth_blob.data);
1499 return True;
1501 err_exit:
1503 data_blob_free(&p->out_data.frag);
1504 TALLOC_FREE(auth_blob.data);
1505 return setup_bind_nak(p, pkt);
1508 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1509 const struct api_struct *api_rpc_cmds, int n_cmds,
1510 const struct ndr_syntax_id *syntax);
1512 /****************************************************************************
1513 Find the correct RPC function to call for this request.
1514 If the pipe is authenticated then become the correct UNIX user
1515 before doing the call.
1516 ****************************************************************************/
1518 static bool api_pipe_request(struct pipes_struct *p,
1519 struct ncacn_packet *pkt)
1521 bool ret = False;
1522 struct pipe_rpc_fns *pipe_fns;
1524 if (!p->pipe_bound) {
1525 DEBUG(1, ("Pipe not bound!\n"));
1526 data_blob_free(&p->out_data.rdata);
1527 return false;
1530 if (!become_authenticated_pipe_user(p->session_info)) {
1531 DEBUG(1, ("Failed to become pipe user!\n"));
1532 data_blob_free(&p->out_data.rdata);
1533 return false;
1536 /* get the set of RPC functions for this context */
1538 pipe_fns = find_pipe_fns_by_context(p->contexts,
1539 pkt->u.request.context_id);
1541 if ( pipe_fns ) {
1542 TALLOC_CTX *frame = talloc_stackframe();
1544 DEBUG(5, ("Requested %s rpc service\n",
1545 get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
1547 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1548 &pipe_fns->syntax);
1550 TALLOC_FREE(frame);
1552 else {
1553 DEBUG(0, ("No rpc function table associated with context "
1554 "[%d]\n",
1555 pkt->u.request.context_id));
1558 unbecome_authenticated_pipe_user();
1560 return ret;
1563 /*******************************************************************
1564 Calls the underlying RPC function for a named pipe.
1565 ********************************************************************/
1567 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1568 const struct api_struct *api_rpc_cmds, int n_cmds,
1569 const struct ndr_syntax_id *syntax)
1571 int fn_num;
1572 uint32_t offset1;
1574 /* interpret the command */
1575 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1576 get_pipe_name_from_syntax(talloc_tos(), syntax),
1577 pkt->u.request.opnum));
1579 if (DEBUGLEVEL >= 50) {
1580 fstring name;
1581 slprintf(name, sizeof(name)-1, "in_%s",
1582 get_pipe_name_from_syntax(talloc_tos(), syntax));
1583 dump_pdu_region(name, pkt->u.request.opnum,
1584 &p->in_data.data, 0,
1585 p->in_data.data.length);
1588 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1589 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1590 api_rpc_cmds[fn_num].fn != NULL) {
1591 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1592 api_rpc_cmds[fn_num].name));
1593 break;
1597 if (fn_num == n_cmds) {
1599 * For an unknown RPC just return a fault PDU but
1600 * return True to allow RPC's on the pipe to continue
1601 * and not put the pipe into fault state. JRA.
1603 DEBUG(4, ("unknown\n"));
1604 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1605 return True;
1608 offset1 = p->out_data.rdata.length;
1610 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1611 fn_num, api_rpc_cmds[fn_num].fn));
1612 /* do the actual command */
1613 if(!api_rpc_cmds[fn_num].fn(p)) {
1614 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1615 get_pipe_name_from_syntax(talloc_tos(), syntax),
1616 api_rpc_cmds[fn_num].name));
1617 data_blob_free(&p->out_data.rdata);
1618 return False;
1621 if (p->bad_handle_fault_state) {
1622 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1623 p->bad_handle_fault_state = False;
1624 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1625 return True;
1628 if (p->rng_fault_state) {
1629 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1630 p->rng_fault_state = False;
1631 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1632 return True;
1635 if (DEBUGLEVEL >= 50) {
1636 fstring name;
1637 slprintf(name, sizeof(name)-1, "out_%s",
1638 get_pipe_name_from_syntax(talloc_tos(), syntax));
1639 dump_pdu_region(name, pkt->u.request.opnum,
1640 &p->out_data.rdata, offset1,
1641 p->out_data.rdata.length);
1644 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1645 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1647 /* Check for buffer underflow in rpc parsing */
1648 if ((DEBUGLEVEL >= 10) &&
1649 (pkt->frag_length < p->in_data.data.length)) {
1650 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1651 dump_data(10, p->in_data.data.data + pkt->frag_length,
1652 p->in_data.data.length - pkt->frag_length);
1655 return True;
1658 /****************************************************************************
1659 Initialise an outgoing packet.
1660 ****************************************************************************/
1662 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1664 output_data *o_data = &p->out_data;
1666 /* Reset the offset counters. */
1667 o_data->data_sent_length = 0;
1668 o_data->current_pdu_sent = 0;
1670 data_blob_free(&o_data->frag);
1672 /* Free any memory in the current return data buffer. */
1673 data_blob_free(&o_data->rdata);
1675 return True;
1678 /****************************************************************************
1679 Sets the fault state on incoming packets.
1680 ****************************************************************************/
1682 void set_incoming_fault(struct pipes_struct *p)
1684 data_blob_free(&p->in_data.data);
1685 p->in_data.pdu_needed_len = 0;
1686 p->in_data.pdu.length = 0;
1687 p->fault_state = True;
1689 DEBUG(10, ("Setting fault state\n"));
1692 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1693 struct ncacn_packet *pkt,
1694 DATA_BLOB *raw_pkt)
1696 NTSTATUS status;
1697 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1698 size_t pad_len;
1700 DEBUG(10, ("Checking request auth.\n"));
1702 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1703 hdr_size += 16;
1706 /* in case of sealing this function will unseal the data in place */
1707 status = dcerpc_check_auth(auth, pkt,
1708 &pkt->u.request.stub_and_verifier,
1709 hdr_size, raw_pkt,
1710 &pad_len);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 return status;
1716 /* remove padding and auth trailer,
1717 * this way the caller will get just the data */
1718 if (pkt->auth_length) {
1719 size_t trail_len = pad_len
1720 + DCERPC_AUTH_TRAILER_LENGTH
1721 + pkt->auth_length;
1722 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1723 return NT_STATUS_INFO_LENGTH_MISMATCH;
1725 pkt->u.request.stub_and_verifier.length -= trail_len;
1728 return NT_STATUS_OK;
1731 /****************************************************************************
1732 Processes a request pdu. This will do auth processing if needed, and
1733 appends the data into the complete stream if the LAST flag is not set.
1734 ****************************************************************************/
1736 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1738 NTSTATUS status;
1739 DATA_BLOB data;
1741 if (!p->pipe_bound) {
1742 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1743 set_incoming_fault(p);
1744 return False;
1747 /* Store the opnum */
1748 p->opnum = pkt->u.request.opnum;
1750 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1751 if (!NT_STATUS_IS_OK(status)) {
1752 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1753 nt_errstr(status)));
1754 set_incoming_fault(p);
1755 return false;
1758 data = pkt->u.request.stub_and_verifier;
1761 * Check the data length doesn't go over the 15Mb limit.
1762 * increased after observing a bug in the Windows NT 4.0 SP6a
1763 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1764 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1767 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1768 DEBUG(0, ("process_request_pdu: "
1769 "rpc data buffer too large (%u) + (%u)\n",
1770 (unsigned int)p->in_data.data.length,
1771 (unsigned int)data.length));
1772 set_incoming_fault(p);
1773 return False;
1777 * Append the data portion into the buffer and return.
1780 if (data.length) {
1781 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1782 data.data, data.length)) {
1783 DEBUG(0, ("Unable to append data size %u "
1784 "to parse buffer of size %u.\n",
1785 (unsigned int)data.length,
1786 (unsigned int)p->in_data.data.length));
1787 set_incoming_fault(p);
1788 return False;
1792 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1793 bool ret = False;
1795 * Ok - we finally have a complete RPC stream.
1796 * Call the rpc command to process it.
1800 * Process the complete data stream here.
1802 if (pipe_init_outgoing_data(p)) {
1803 ret = api_pipe_request(p, pkt);
1806 return ret;
1809 return True;
1812 /****************************************************************************
1813 Processes a finished PDU stored in p->in_data.pdu.
1814 ****************************************************************************/
1816 void process_complete_pdu(struct pipes_struct *p)
1818 struct ncacn_packet *pkt = NULL;
1819 NTSTATUS status;
1820 bool reply = False;
1822 if(p->fault_state) {
1823 DEBUG(10,("RPC connection in fault state.\n"));
1824 goto done;
1827 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1828 if (!pkt) {
1829 DEBUG(0, ("Out of memory!\n"));
1830 goto done;
1834 * Ensure we're using the corrent endianness for both the
1835 * RPC header flags and the raw data we will be reading from.
1837 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1838 p->endian = RPC_LITTLE_ENDIAN;
1839 } else {
1840 p->endian = RPC_BIG_ENDIAN;
1842 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1844 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1845 pkt, p->endian);
1846 if (!NT_STATUS_IS_OK(status)) {
1847 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1848 nt_errstr(status)));
1849 goto done;
1852 /* Store the call_id */
1853 p->call_id = pkt->call_id;
1855 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1857 switch (pkt->ptype) {
1858 case DCERPC_PKT_REQUEST:
1859 reply = process_request_pdu(p, pkt);
1860 break;
1862 case DCERPC_PKT_PING: /* CL request - ignore... */
1863 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1864 (unsigned int)pkt->ptype));
1865 break;
1867 case DCERPC_PKT_RESPONSE: /* No responses here. */
1868 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1869 break;
1871 case DCERPC_PKT_FAULT:
1872 case DCERPC_PKT_WORKING:
1873 /* CL request - reply to a ping when a call in process. */
1874 case DCERPC_PKT_NOCALL:
1875 /* CL - server reply to a ping call. */
1876 case DCERPC_PKT_REJECT:
1877 case DCERPC_PKT_ACK:
1878 case DCERPC_PKT_CL_CANCEL:
1879 case DCERPC_PKT_FACK:
1880 case DCERPC_PKT_CANCEL_ACK:
1881 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1882 (unsigned int)pkt->ptype));
1883 break;
1885 case DCERPC_PKT_BIND:
1887 * We assume that a pipe bind is only in one pdu.
1889 if (pipe_init_outgoing_data(p)) {
1890 reply = api_pipe_bind_req(p, pkt);
1892 break;
1894 case DCERPC_PKT_BIND_ACK:
1895 case DCERPC_PKT_BIND_NAK:
1896 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1897 "packet type %u received.\n",
1898 (unsigned int)pkt->ptype));
1899 break;
1902 case DCERPC_PKT_ALTER:
1904 * We assume that a pipe bind is only in one pdu.
1906 if (pipe_init_outgoing_data(p)) {
1907 reply = api_pipe_alter_context(p, pkt);
1909 break;
1911 case DCERPC_PKT_ALTER_RESP:
1912 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1913 "Should only be server -> client.\n"));
1914 break;
1916 case DCERPC_PKT_AUTH3:
1918 * The third packet in an auth exchange.
1920 if (pipe_init_outgoing_data(p)) {
1921 reply = api_pipe_bind_auth3(p, pkt);
1923 break;
1925 case DCERPC_PKT_SHUTDOWN:
1926 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1927 "Should only be server -> client.\n"));
1928 break;
1930 case DCERPC_PKT_CO_CANCEL:
1931 /* For now just free all client data and continue
1932 * processing. */
1933 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1934 " Abandoning rpc call.\n"));
1935 /* As we never do asynchronous RPC serving, we can
1936 * never cancel a call (as far as I know).
1937 * If we ever did we'd have to send a cancel_ack reply.
1938 * For now, just free all client data and continue
1939 * processing. */
1940 reply = True;
1941 break;
1943 #if 0
1944 /* Enable this if we're doing async rpc. */
1945 /* We must check the outstanding callid matches. */
1946 if (pipe_init_outgoing_data(p)) {
1947 /* Send a cancel_ack PDU reply. */
1948 /* We should probably check the auth-verifier here. */
1949 reply = setup_cancel_ack_reply(p, pkt);
1951 break;
1952 #endif
1954 case DCERPC_PKT_ORPHANED:
1955 /* We should probably check the auth-verifier here.
1956 * For now just free all client data and continue
1957 * processing. */
1958 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1959 " Abandoning rpc call.\n"));
1960 reply = True;
1961 break;
1963 default:
1964 DEBUG(0, ("process_complete_pdu: "
1965 "Unknown rpc type = %u received.\n",
1966 (unsigned int)pkt->ptype));
1967 break;
1970 done:
1971 if (!reply) {
1972 DEBUG(3,("DCE/RPC fault sent!"));
1973 set_incoming_fault(p);
1974 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1975 TALLOC_FREE(pkt);
1976 } else {
1978 * Reset the lengths. We're ready for a new pdu.
1980 TALLOC_FREE(p->in_data.pdu.data);
1981 p->in_data.pdu_needed_len = 0;
1982 p->in_data.pdu.length = 0;
1985 TALLOC_FREE(pkt);