s3-auth: On successful user mapping set mapped_to_guest to false.
[Samba/vl.git] / source3 / rpc_server / srv_pipe.c
blob879b6deabd01716a9c1bb981941e20cef0d3f799
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_spnego.h"
38 #include "rpc_server.h"
39 #include "rpc_dce.h"
40 #include "smbd/smbd.h"
41 #include "auth.h"
42 #include "ntdomain.h"
43 #include "rpc_server/srv_pipe.h"
44 #include "rpc_server/rpc_contexts.h"
45 #include "lib/param/param.h"
47 #undef DBGC_CLASS
48 #define DBGC_CLASS DBGC_RPC_SRV
50 /**
51 * Dump everything from the start of the end up of the provided data
52 * into a file, but only at debug level >= 50
53 **/
54 static void dump_pdu_region(const char *name, int v,
55 DATA_BLOB *data, size_t start, size_t end)
57 int fd, i;
58 char *fname = NULL;
59 ssize_t sz;
61 if (DEBUGLEVEL < 50) return;
63 if (start > data->length || end > data->length || start > end) return;
65 for (i = 1; i < 100; i++) {
66 if (v != -1) {
67 fname = talloc_asprintf(talloc_tos(),
68 "/tmp/%s_%d.%d.prs",
69 name, v, i);
70 } else {
71 fname = talloc_asprintf(talloc_tos(),
72 "/tmp/%s_%d.prs",
73 name, i);
75 if (!fname) {
76 return;
78 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
79 if (fd != -1 || errno != EEXIST) break;
81 if (fd != -1) {
82 sz = write(fd, data->data + start, end - start);
83 i = close(fd);
84 if ((sz != end - start) || (i != 0) ) {
85 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
86 fname, (unsigned long)sz,
87 (unsigned long)end - start, i));
88 } else {
89 DEBUG(0,("created %s\n", fname));
92 TALLOC_FREE(fname);
95 static DATA_BLOB generic_session_key(void)
97 return data_blob_const("SystemLibraryDTC", 16);
100 /*******************************************************************
101 Generate the next PDU to be returned from the data.
102 ********************************************************************/
104 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
105 struct pipe_auth_data *auth,
106 uint32_t call_id,
107 DATA_BLOB *rdata,
108 size_t data_sent_length,
109 DATA_BLOB *frag,
110 size_t *pdu_size)
112 union dcerpc_payload u;
113 uint8_t pfc_flags;
114 size_t data_left;
115 size_t data_to_send;
116 size_t frag_len;
117 size_t pad_len = 0;
118 size_t auth_len = 0;
119 NTSTATUS status;
121 ZERO_STRUCT(u.response);
123 /* Set up rpc packet pfc flags. */
124 if (data_sent_length == 0) {
125 pfc_flags = DCERPC_PFC_FLAG_FIRST;
126 } else {
127 pfc_flags = 0;
130 /* Work out how much we can fit in a single PDU. */
131 data_left = rdata->length - data_sent_length;
133 /* Ensure there really is data left to send. */
134 if (!data_left) {
135 DEBUG(0, ("No data left to send !\n"));
136 return NT_STATUS_BUFFER_TOO_SMALL;
139 status = dcerpc_guess_sizes(auth,
140 DCERPC_RESPONSE_LENGTH,
141 data_left,
142 RPC_MAX_PDU_FRAG_LEN,
143 SERVER_NDR_PADDING_SIZE,
144 &data_to_send, &frag_len,
145 &auth_len, &pad_len);
146 if (!NT_STATUS_IS_OK(status)) {
147 return status;
150 /* Set up the alloc hint. This should be the data left to send. */
151 u.response.alloc_hint = data_left;
153 /* Work out if this PDU will be the last. */
154 if (data_sent_length + data_to_send >= rdata->length) {
155 pfc_flags |= DCERPC_PFC_FLAG_LAST;
158 /* Prepare data to be NDR encoded. */
159 u.response.stub_and_verifier =
160 data_blob_const(rdata->data + data_sent_length, data_to_send);
162 /* Store the packet in the data stream. */
163 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
164 pfc_flags, auth_len, call_id,
165 &u, frag);
166 if (!NT_STATUS_IS_OK(status)) {
167 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
168 return status;
171 if (auth_len) {
172 /* Set the proper length on the pdu, including padding.
173 * Only needed if an auth trailer will be appended. */
174 dcerpc_set_frag_length(frag, frag->length
175 + pad_len
176 + DCERPC_AUTH_TRAILER_LENGTH
177 + auth_len);
180 if (auth_len) {
181 status = dcerpc_add_auth_footer(auth, pad_len, frag);
182 if (!NT_STATUS_IS_OK(status)) {
183 data_blob_free(frag);
184 return status;
188 *pdu_size = data_to_send;
189 return NT_STATUS_OK;
192 /*******************************************************************
193 Generate the next PDU to be returned from the data in p->rdata.
194 ********************************************************************/
196 bool create_next_pdu(struct pipes_struct *p)
198 size_t pdu_size = 0;
199 NTSTATUS status;
202 * If we're in the fault state, keep returning fault PDU's until
203 * the pipe gets closed. JRA.
205 if (p->fault_state) {
206 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
207 return true;
210 status = create_next_packet(p->mem_ctx, &p->auth,
211 p->call_id, &p->out_data.rdata,
212 p->out_data.data_sent_length,
213 &p->out_data.frag, &pdu_size);
214 if (!NT_STATUS_IS_OK(status)) {
215 DEBUG(0, ("Failed to create packet with error %s, "
216 "(auth level %u / type %u)\n",
217 nt_errstr(status),
218 (unsigned int)p->auth.auth_level,
219 (unsigned int)p->auth.auth_type));
220 return false;
223 /* Setup the counts for this PDU. */
224 p->out_data.data_sent_length += pdu_size;
225 p->out_data.current_pdu_sent = 0;
226 return true;
230 static bool pipe_init_outgoing_data(struct pipes_struct *p);
232 /*******************************************************************
233 Marshall a bind_nak pdu.
234 *******************************************************************/
236 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
238 NTSTATUS status;
239 union dcerpc_payload u;
241 /* Free any memory in the current return data buffer. */
242 pipe_init_outgoing_data(p);
245 * Initialize a bind_nak header.
248 ZERO_STRUCT(u);
250 u.bind_nak.reject_reason = 0;
253 * Marshall directly into the outgoing PDU space. We
254 * must do this as we need to set to the bind response
255 * header and are never sending more than one PDU here.
258 status = dcerpc_push_ncacn_packet(p->mem_ctx,
259 DCERPC_PKT_BIND_NAK,
260 DCERPC_PFC_FLAG_FIRST |
261 DCERPC_PFC_FLAG_LAST,
263 pkt->call_id,
265 &p->out_data.frag);
266 if (!NT_STATUS_IS_OK(status)) {
267 return False;
270 p->out_data.data_sent_length = 0;
271 p->out_data.current_pdu_sent = 0;
273 TALLOC_FREE(p->auth.auth_ctx);
274 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
275 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
276 p->pipe_bound = False;
278 return True;
281 /*******************************************************************
282 Marshall a fault pdu.
283 *******************************************************************/
285 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
287 NTSTATUS status;
288 union dcerpc_payload u;
290 /* Free any memory in the current return data buffer. */
291 pipe_init_outgoing_data(p);
294 * Initialize a fault header.
297 ZERO_STRUCT(u);
299 u.fault.status = NT_STATUS_V(fault_status);
300 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
303 * Marshall directly into the outgoing PDU space. We
304 * must do this as we need to set to the bind response
305 * header and are never sending more than one PDU here.
308 status = dcerpc_push_ncacn_packet(p->mem_ctx,
309 DCERPC_PKT_FAULT,
310 DCERPC_PFC_FLAG_FIRST |
311 DCERPC_PFC_FLAG_LAST |
312 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
314 p->call_id,
316 &p->out_data.frag);
317 if (!NT_STATUS_IS_OK(status)) {
318 return False;
321 p->out_data.data_sent_length = 0;
322 p->out_data.current_pdu_sent = 0;
324 return True;
327 /*******************************************************************
328 Ensure a bind request has the correct abstract & transfer interface.
329 Used to reject unknown binds from Win2k.
330 *******************************************************************/
332 static bool check_bind_req(struct pipes_struct *p,
333 struct ndr_syntax_id* abstract,
334 struct ndr_syntax_id* transfer,
335 uint32_t context_id)
337 struct pipe_rpc_fns *context_fns;
338 bool ok;
340 DEBUG(3,("check_bind_req for %s\n",
341 get_pipe_name_from_syntax(talloc_tos(), abstract)));
343 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
344 if (rpc_srv_pipe_exists_by_id(abstract) &&
345 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
346 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
347 rpc_srv_get_pipe_cli_name(abstract),
348 rpc_srv_get_pipe_srv_name(abstract)));
349 } else {
350 return false;
353 ok = init_pipe_handles(p, abstract);
354 if (!ok) {
355 DEBUG(1, ("Failed to init pipe handles!\n"));
356 return false;
359 context_fns = talloc(p, struct pipe_rpc_fns);
360 if (context_fns == NULL) {
361 DEBUG(0,("check_bind_req: talloc() failed!\n"));
362 return false;
365 context_fns->next = context_fns->prev = NULL;
366 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
367 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
368 context_fns->context_id = context_id;
369 context_fns->syntax = *abstract;
371 /* add to the list of open contexts */
373 DLIST_ADD( p->contexts, context_fns );
375 return True;
379 * Is a named pipe known?
380 * @param[in] cli_filename The pipe name requested by the client
381 * @result Do we want to serve this?
383 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
385 const char *pipename = cli_filename;
386 NTSTATUS status;
388 if (strnequal(pipename, "\\PIPE\\", 6)) {
389 pipename += 5;
392 if (*pipename == '\\') {
393 pipename += 1;
396 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
397 DEBUG(10, ("refusing spoolss access\n"));
398 return false;
401 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
402 return true;
405 status = smb_probe_module("rpc", pipename);
406 if (!NT_STATUS_IS_OK(status)) {
407 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
408 return false;
410 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
413 * Scan the list again for the interface id
415 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
416 return true;
419 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
420 pipename));
422 return false;
425 /*******************************************************************
426 Handle the first part of a SPNEGO bind auth.
427 *******************************************************************/
429 static bool pipe_spnego_auth_bind(struct pipes_struct *p,
430 TALLOC_CTX *mem_ctx,
431 struct dcerpc_auth *auth_info,
432 DATA_BLOB *response)
434 struct spnego_context *spnego_ctx;
435 NTSTATUS status;
437 status = spnego_server_auth_start(p,
438 (auth_info->auth_level ==
439 DCERPC_AUTH_LEVEL_INTEGRITY),
440 (auth_info->auth_level ==
441 DCERPC_AUTH_LEVEL_PRIVACY),
442 true,
443 &auth_info->credentials,
444 response,
445 p->remote_address,
446 &spnego_ctx);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(0, ("Failed SPNEGO negotiate (%s)\n",
449 nt_errstr(status)));
450 return false;
453 /* Make sure data is bound to the memctx, to be freed the caller */
454 talloc_steal(mem_ctx, response->data);
456 p->auth.auth_ctx = spnego_ctx;
457 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
459 DEBUG(10, ("SPNEGO auth started\n"));
461 return true;
464 /*******************************************************************
465 Handle an schannel bind auth.
466 *******************************************************************/
468 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
469 TALLOC_CTX *mem_ctx,
470 struct dcerpc_auth *auth_info,
471 DATA_BLOB *response)
473 struct NL_AUTH_MESSAGE neg;
474 struct NL_AUTH_MESSAGE reply;
475 bool ret;
476 NTSTATUS status;
477 struct netlogon_creds_CredentialState *creds;
478 enum ndr_err_code ndr_err;
479 struct schannel_state *schannel_auth;
480 struct loadparm_context *lp_ctx;
482 ndr_err = ndr_pull_struct_blob(
483 &auth_info->credentials, mem_ctx, &neg,
484 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
485 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
486 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
487 return false;
490 if (DEBUGLEVEL >= 10) {
491 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
494 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
495 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
496 return false;
499 lp_ctx = loadparm_init_s3(p, loadparm_s3_context());
500 if (!lp_ctx) {
501 DEBUG(0,("pipe_schannel_auth_bind: loadparm_init_s3() failed!\n"));
502 return false;
506 * The neg.oem_netbios_computer.a key here must match the remote computer name
507 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
508 * operations that use credentials.
511 become_root();
512 status = schannel_get_creds_state(p, lp_ctx,
513 neg.oem_netbios_computer.a, &creds);
514 unbecome_root();
516 talloc_unlink(p, lp_ctx);
517 if (!NT_STATUS_IS_OK(status)) {
518 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
519 return False;
522 schannel_auth = talloc(p, struct schannel_state);
523 if (!schannel_auth) {
524 TALLOC_FREE(creds);
525 return False;
528 schannel_auth->state = SCHANNEL_STATE_START;
529 schannel_auth->seq_num = 0;
530 schannel_auth->initiator = false;
531 schannel_auth->creds = creds;
534 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
535 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
536 * struct of the person who opened the pipe. I need to test this further. JRA.
538 * VL. As we are mapping this to guest set the generic key
539 * "SystemLibraryDTC" key here. It's a bit difficult to test against
540 * W2k3, as it does not allow schannel binds against SAMR and LSA
541 * anymore.
544 ret = session_info_set_session_key(p->session_info, generic_session_key());
546 if (!ret) {
547 DEBUG(0, ("session_info_set_session_key failed\n"));
548 return false;
551 /*** SCHANNEL verifier ***/
553 reply.MessageType = NL_NEGOTIATE_RESPONSE;
554 reply.Flags = 0;
555 reply.Buffer.dummy = 5; /* ??? actually I don't think
556 * this has any meaning
557 * here - gd */
559 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
560 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
561 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
562 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
563 return false;
566 if (DEBUGLEVEL >= 10) {
567 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
570 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
571 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
573 /* We're finished with this bind - no more packets. */
574 p->auth.auth_ctx = schannel_auth;
575 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
577 p->pipe_bound = True;
579 return True;
582 /*******************************************************************
583 Handle an NTLMSSP bind auth.
584 *******************************************************************/
586 static bool pipe_auth_generic_bind(struct pipes_struct *p,
587 TALLOC_CTX *mem_ctx,
588 struct dcerpc_auth *auth_info,
589 DATA_BLOB *response)
591 struct gensec_security *gensec_security = NULL;
592 NTSTATUS status;
594 status = auth_generic_server_authtype_start(p,
595 auth_info->auth_type,
596 auth_info->auth_level,
597 &auth_info->credentials,
598 response,
599 p->remote_address,
600 &gensec_security);
601 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
602 DEBUG(0, (__location__ ": auth_generic_server_authtype_start failed: %s\n",
603 nt_errstr(status)));
604 return false;
607 /* Make sure data is bound to the memctx, to be freed the caller */
608 talloc_steal(mem_ctx, response->data);
610 p->auth.auth_ctx = gensec_security;
611 p->auth.auth_type = auth_info->auth_type;
613 return true;
616 /*******************************************************************
617 Process an NTLMSSP authentication response.
618 If this function succeeds, the user has been authenticated
619 and their domain, name and calling workstation stored in
620 the pipe struct.
621 *******************************************************************/
623 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
624 struct gensec_security *gensec_security,
625 enum dcerpc_AuthLevel auth_level,
626 struct auth_session_info **session_info)
628 NTSTATUS status;
629 bool ret;
631 DEBUG(5, (__location__ ": checking user details\n"));
633 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
634 ensure the underlying NTLMSSP flags are also set. If not we should
635 refuse the bind. */
637 status = auth_generic_server_check_flags(gensec_security,
638 (auth_level ==
639 DCERPC_AUTH_LEVEL_INTEGRITY),
640 (auth_level ==
641 DCERPC_AUTH_LEVEL_PRIVACY));
642 if (!NT_STATUS_IS_OK(status)) {
643 DEBUG(0, (__location__ ": Client failed to negotatie proper "
644 "security for rpc connection\n"));
645 return false;
648 TALLOC_FREE(*session_info);
650 status = auth_generic_server_get_user_info(gensec_security,
651 mem_ctx, session_info);
652 if (!NT_STATUS_IS_OK(status)) {
653 DEBUG(0, (__location__ ": failed to obtain the server info "
654 "for authenticated user: %s\n", nt_errstr(status)));
655 return false;
658 if ((*session_info)->security_token == NULL) {
659 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
660 return false;
664 * We're an authenticated bind over smb, so the session key needs to
665 * be set to "SystemLibraryDTC". Weird, but this is what Windows
666 * does. See the RPC-SAMBA3SESSIONKEY.
669 ret = session_info_set_session_key((*session_info), generic_session_key());
670 if (!ret) {
671 DEBUG(0, ("Failed to set session key!\n"));
672 return false;
675 return true;
678 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
680 struct gensec_security *gensec_security;
681 struct spnego_context *spnego_ctx;
682 NTSTATUS status;
684 switch (p->auth.auth_type) {
685 case DCERPC_AUTH_TYPE_NTLMSSP:
686 case DCERPC_AUTH_TYPE_KRB5:
687 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
688 struct gensec_security);
689 if (!pipe_auth_generic_verify_final(p, gensec_security,
690 p->auth.auth_level,
691 &p->session_info)) {
692 return NT_STATUS_ACCESS_DENIED;
694 break;
695 case DCERPC_AUTH_TYPE_SPNEGO:
696 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
697 struct spnego_context);
698 status = spnego_get_negotiated_mech(spnego_ctx, &gensec_security);
699 if (!NT_STATUS_IS_OK(status)) {
700 DEBUG(0, ("Bad SPNEGO state (%s)\n",
701 nt_errstr(status)));
702 return status;
704 if (!pipe_auth_generic_verify_final(p, gensec_security,
705 p->auth.auth_level,
706 &p->session_info)) {
707 return NT_STATUS_ACCESS_DENIED;
709 break;
710 default:
711 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
712 (unsigned int)p->auth.auth_type));
713 return NT_STATUS_ACCESS_DENIED;
716 p->pipe_bound = true;
718 return NT_STATUS_OK;
721 /*******************************************************************
722 Respond to a pipe bind request.
723 *******************************************************************/
725 static bool api_pipe_bind_req(struct pipes_struct *p,
726 struct ncacn_packet *pkt)
728 struct dcerpc_auth auth_info;
729 uint16 assoc_gid;
730 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
731 NTSTATUS status;
732 struct ndr_syntax_id id;
733 union dcerpc_payload u;
734 struct dcerpc_ack_ctx bind_ack_ctx;
735 DATA_BLOB auth_resp = data_blob_null;
736 DATA_BLOB auth_blob = data_blob_null;
738 /* No rebinds on a bound pipe - use alter context. */
739 if (p->pipe_bound) {
740 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
741 return setup_bind_nak(p, pkt);
744 if (pkt->u.bind.num_contexts == 0) {
745 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
746 goto err_exit;
750 * Try and find the correct pipe name to ensure
751 * that this is a pipe name we support.
753 id = pkt->u.bind.ctx_list[0].abstract_syntax;
754 if (rpc_srv_pipe_exists_by_id(&id)) {
755 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
756 rpc_srv_get_pipe_cli_name(&id),
757 rpc_srv_get_pipe_srv_name(&id)));
758 } else {
759 status = smb_probe_module(
760 "rpc", get_pipe_name_from_syntax(
761 talloc_tos(),
762 &id));
764 if (NT_STATUS_IS_ERR(status)) {
765 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
766 "%s in bind request.\n",
767 get_pipe_name_from_syntax(talloc_tos(), &id)));
769 return setup_bind_nak(p, pkt);
772 if (rpc_srv_get_pipe_interface_by_cli_name(
773 get_pipe_name_from_syntax(talloc_tos(),
774 &id),
775 &id)) {
776 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
777 rpc_srv_get_pipe_cli_name(&id),
778 rpc_srv_get_pipe_srv_name(&id)));
779 } else {
780 DEBUG(0, ("module %s doesn't provide functions for "
781 "pipe %s!\n",
782 get_pipe_name_from_syntax(talloc_tos(), &id),
783 get_pipe_name_from_syntax(talloc_tos(), &id)));
784 return setup_bind_nak(p, pkt);
788 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
790 if (pkt->u.bind.assoc_group_id != 0) {
791 assoc_gid = pkt->u.bind.assoc_group_id;
792 } else {
793 assoc_gid = 0x53f0;
797 * Create the bind response struct.
800 /* If the requested abstract synt uuid doesn't match our client pipe,
801 reject the bind_ack & set the transfer interface synt to all 0's,
802 ver 0 (observed when NT5 attempts to bind to abstract interfaces
803 unknown to NT4)
804 Needed when adding entries to a DACL from NT5 - SK */
806 if (check_bind_req(p,
807 &pkt->u.bind.ctx_list[0].abstract_syntax,
808 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
809 pkt->u.bind.ctx_list[0].context_id)) {
811 bind_ack_ctx.result = 0;
812 bind_ack_ctx.reason = 0;
813 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
814 } else {
815 p->pipe_bound = False;
816 /* Rejection reason: abstract syntax not supported */
817 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
818 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
819 bind_ack_ctx.syntax = null_ndr_syntax_id;
823 * Check if this is an authenticated bind request.
825 if (pkt->auth_length) {
826 /* Quick length check. Won't catch a bad auth footer,
827 * prevents overrun. */
829 if (pkt->frag_length < RPC_HEADER_LEN +
830 DCERPC_AUTH_TRAILER_LENGTH +
831 pkt->auth_length) {
832 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
833 "too long for fragment %u.\n",
834 (unsigned int)pkt->auth_length,
835 (unsigned int)pkt->frag_length));
836 goto err_exit;
840 * Decode the authentication verifier.
842 status = dcerpc_pull_dcerpc_auth(pkt,
843 &pkt->u.bind.auth_info,
844 &auth_info, p->endian);
845 if (!NT_STATUS_IS_OK(status)) {
846 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
847 goto err_exit;
850 auth_type = auth_info.auth_type;
852 /* Work out if we have to sign or seal etc. */
853 switch (auth_info.auth_level) {
854 case DCERPC_AUTH_LEVEL_INTEGRITY:
855 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
856 break;
857 case DCERPC_AUTH_LEVEL_PRIVACY:
858 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
859 break;
860 case DCERPC_AUTH_LEVEL_CONNECT:
861 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
862 break;
863 default:
864 DEBUG(0, ("Unexpected auth level (%u).\n",
865 (unsigned int)auth_info.auth_level ));
866 goto err_exit;
869 switch (auth_type) {
870 case DCERPC_AUTH_TYPE_NTLMSSP:
871 if (!pipe_auth_generic_bind(p, pkt,
872 &auth_info, &auth_resp)) {
873 goto err_exit;
875 assoc_gid = 0x7a77;
876 break;
878 case DCERPC_AUTH_TYPE_SCHANNEL:
879 if (!pipe_schannel_auth_bind(p, pkt,
880 &auth_info, &auth_resp)) {
881 goto err_exit;
883 break;
885 case DCERPC_AUTH_TYPE_SPNEGO:
886 if (!pipe_spnego_auth_bind(p, pkt,
887 &auth_info, &auth_resp)) {
888 goto err_exit;
890 break;
892 case DCERPC_AUTH_TYPE_KRB5:
893 if (!pipe_auth_generic_bind(p, pkt,
894 &auth_info, &auth_resp)) {
895 goto err_exit;
897 break;
899 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
900 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
901 TALLOC_FREE(p->session_info);
903 status = make_session_info_system(p,
904 &p->session_info);
905 if (!NT_STATUS_IS_OK(status)) {
906 goto err_exit;
909 auth_resp = data_blob_talloc(pkt,
910 "NCALRPC_AUTH_OK",
911 15);
913 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
914 p->pipe_bound = true;
915 } else {
916 goto err_exit;
918 break;
920 case DCERPC_AUTH_TYPE_NONE:
921 break;
923 default:
924 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
925 goto err_exit;
929 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
930 /* Unauthenticated bind request. */
931 /* We're finished - no more packets. */
932 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
933 /* We must set the pipe auth_level here also. */
934 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
935 p->pipe_bound = True;
936 /* The session key was initialized from the SMB
937 * session in make_internal_rpc_pipe_p */
940 ZERO_STRUCT(u.bind_ack);
941 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
942 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
943 u.bind_ack.assoc_group_id = assoc_gid;
945 /* name has to be \PIPE\xxxxx */
946 u.bind_ack.secondary_address =
947 talloc_asprintf(pkt, "\\PIPE\\%s",
948 rpc_srv_get_pipe_srv_name(&id));
949 if (!u.bind_ack.secondary_address) {
950 DEBUG(0, ("Out of memory!\n"));
951 goto err_exit;
953 u.bind_ack.secondary_address_size =
954 strlen(u.bind_ack.secondary_address) + 1;
956 u.bind_ack.num_results = 1;
957 u.bind_ack.ctx_list = &bind_ack_ctx;
959 /* NOTE: We leave the auth_info empty so we can calculate the padding
960 * later and then append the auth_info --simo */
963 * Marshall directly into the outgoing PDU space. We
964 * must do this as we need to set to the bind response
965 * header and are never sending more than one PDU here.
968 status = dcerpc_push_ncacn_packet(p->mem_ctx,
969 DCERPC_PKT_BIND_ACK,
970 DCERPC_PFC_FLAG_FIRST |
971 DCERPC_PFC_FLAG_LAST,
972 auth_resp.length,
973 pkt->call_id,
975 &p->out_data.frag);
976 if (!NT_STATUS_IS_OK(status)) {
977 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
978 nt_errstr(status)));
981 if (auth_resp.length) {
983 status = dcerpc_push_dcerpc_auth(pkt,
984 auth_type,
985 auth_info.auth_level,
987 1, /* auth_context_id */
988 &auth_resp,
989 &auth_blob);
990 if (!NT_STATUS_IS_OK(status)) {
991 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
992 goto err_exit;
996 /* Now that we have the auth len store it into the right place in
997 * the dcerpc header */
998 dcerpc_set_frag_length(&p->out_data.frag,
999 p->out_data.frag.length + auth_blob.length);
1001 if (auth_blob.length) {
1003 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1004 auth_blob.data, auth_blob.length)) {
1005 DEBUG(0, ("Append of auth info failed.\n"));
1006 goto err_exit;
1011 * Setup the lengths for the initial reply.
1014 p->out_data.data_sent_length = 0;
1015 p->out_data.current_pdu_sent = 0;
1017 TALLOC_FREE(auth_blob.data);
1018 return True;
1020 err_exit:
1022 data_blob_free(&p->out_data.frag);
1023 TALLOC_FREE(auth_blob.data);
1024 return setup_bind_nak(p, pkt);
1027 /*******************************************************************
1028 This is the "stage3" response after a bind request and reply.
1029 *******************************************************************/
1031 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1033 struct dcerpc_auth auth_info;
1034 DATA_BLOB response = data_blob_null;
1035 struct gensec_security *gensec_security;
1036 struct spnego_context *spnego_ctx;
1037 NTSTATUS status;
1039 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1041 if (pkt->auth_length == 0) {
1042 DEBUG(0, ("No auth field sent for bind request!\n"));
1043 goto err;
1046 /* Ensure there's enough data for an authenticated request. */
1047 if (pkt->frag_length < RPC_HEADER_LEN
1048 + DCERPC_AUTH_TRAILER_LENGTH
1049 + pkt->auth_length) {
1050 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
1051 "%u is too large.\n",
1052 (unsigned int)pkt->auth_length));
1053 goto err;
1057 * Decode the authentication verifier response.
1060 status = dcerpc_pull_dcerpc_auth(pkt,
1061 &pkt->u.auth3.auth_info,
1062 &auth_info, p->endian);
1063 if (!NT_STATUS_IS_OK(status)) {
1064 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1065 goto err;
1068 /* We must NEVER look at auth_info->auth_pad_len here,
1069 * as old Samba client code gets it wrong and sends it
1070 * as zero. JRA.
1073 if (auth_info.auth_type != p->auth.auth_type) {
1074 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1075 "but auth was started as type %d!\n",
1076 auth_info.auth_type, p->auth.auth_type));
1077 goto err;
1080 switch (auth_info.auth_type) {
1081 case DCERPC_AUTH_TYPE_NTLMSSP:
1082 case DCERPC_AUTH_TYPE_KRB5:
1083 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1084 struct gensec_security);
1085 status = auth_generic_server_step(gensec_security,
1086 pkt, &auth_info.credentials,
1087 &response);
1088 break;
1089 case DCERPC_AUTH_TYPE_SPNEGO:
1090 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1091 struct spnego_context);
1092 status = spnego_server_step(spnego_ctx,
1093 pkt, &auth_info.credentials,
1094 &response);
1095 break;
1096 default:
1097 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1098 (unsigned int)auth_info.auth_type));
1099 return false;
1102 if (NT_STATUS_EQUAL(status,
1103 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1104 response.length) {
1105 DEBUG(0, (__location__ ": This was supposed to be the final "
1106 "leg, but crypto machinery claims a response is "
1107 "needed, aborting auth!\n"));
1108 data_blob_free(&response);
1109 goto err;
1111 if (!NT_STATUS_IS_OK(status)) {
1112 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1113 goto err;
1116 /* Now verify auth was indeed successful and extract server info */
1117 status = pipe_auth_verify_final(p);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1120 goto err;
1123 return true;
1125 err:
1127 TALLOC_FREE(p->auth.auth_ctx);
1128 return false;
1131 /****************************************************************************
1132 Deal with an alter context call. Can be third part of 3 leg auth request for
1133 SPNEGO calls.
1134 ****************************************************************************/
1136 static bool api_pipe_alter_context(struct pipes_struct *p,
1137 struct ncacn_packet *pkt)
1139 struct dcerpc_auth auth_info;
1140 uint16 assoc_gid;
1141 NTSTATUS status;
1142 union dcerpc_payload u;
1143 struct dcerpc_ack_ctx bind_ack_ctx;
1144 DATA_BLOB auth_resp = data_blob_null;
1145 DATA_BLOB auth_blob = data_blob_null;
1146 int pad_len = 0;
1147 struct gensec_security *gensec_security;
1148 struct spnego_context *spnego_ctx;
1150 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1152 if (pkt->u.bind.assoc_group_id != 0) {
1153 assoc_gid = pkt->u.bind.assoc_group_id;
1154 } else {
1155 assoc_gid = 0x53f0;
1159 * Create the bind response struct.
1162 /* If the requested abstract synt uuid doesn't match our client pipe,
1163 reject the bind_ack & set the transfer interface synt to all 0's,
1164 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1165 unknown to NT4)
1166 Needed when adding entries to a DACL from NT5 - SK */
1168 if (check_bind_req(p,
1169 &pkt->u.bind.ctx_list[0].abstract_syntax,
1170 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1171 pkt->u.bind.ctx_list[0].context_id)) {
1173 bind_ack_ctx.result = 0;
1174 bind_ack_ctx.reason = 0;
1175 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1176 } else {
1177 p->pipe_bound = False;
1178 /* Rejection reason: abstract syntax not supported */
1179 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1180 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1181 bind_ack_ctx.syntax = null_ndr_syntax_id;
1185 * Check if this is an authenticated alter context request.
1187 if (pkt->auth_length) {
1188 /* Quick length check. Won't catch a bad auth footer,
1189 * prevents overrun. */
1191 if (pkt->frag_length < RPC_HEADER_LEN +
1192 DCERPC_AUTH_TRAILER_LENGTH +
1193 pkt->auth_length) {
1194 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1195 "too long for fragment %u.\n",
1196 (unsigned int)pkt->auth_length,
1197 (unsigned int)pkt->frag_length ));
1198 goto err_exit;
1201 status = dcerpc_pull_dcerpc_auth(pkt,
1202 &pkt->u.bind.auth_info,
1203 &auth_info, p->endian);
1204 if (!NT_STATUS_IS_OK(status)) {
1205 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1206 goto err_exit;
1209 /* We can only finish if the pipe is unbound for now */
1210 if (p->pipe_bound) {
1211 DEBUG(0, (__location__ ": Pipe already bound, "
1212 "Altering Context not yet supported!\n"));
1213 goto err_exit;
1216 if (auth_info.auth_type != p->auth.auth_type) {
1217 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1218 "but auth was started as type %d!\n",
1219 auth_info.auth_type, p->auth.auth_type));
1220 goto err_exit;
1224 switch (auth_info.auth_type) {
1225 case DCERPC_AUTH_TYPE_SPNEGO:
1226 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1227 struct spnego_context);
1228 status = spnego_server_step(spnego_ctx,
1229 pkt,
1230 &auth_info.credentials,
1231 &auth_resp);
1232 break;
1234 case DCERPC_AUTH_TYPE_KRB5:
1235 case DCERPC_AUTH_TYPE_NTLMSSP:
1236 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1237 struct gensec_security);
1238 status = auth_generic_server_step(gensec_security,
1239 pkt,
1240 &auth_info.credentials,
1241 &auth_resp);
1242 break;
1244 default:
1245 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1246 "in alter-context call\n",
1247 auth_info.auth_type));
1248 goto err_exit;
1251 if (NT_STATUS_IS_OK(status)) {
1252 /* third leg of auth, verify auth info */
1253 status = pipe_auth_verify_final(p);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 DEBUG(0, ("Auth Verify failed (%s)\n",
1256 nt_errstr(status)));
1257 goto err_exit;
1259 } else if (NT_STATUS_EQUAL(status,
1260 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1261 DEBUG(10, ("More auth legs required.\n"));
1262 } else {
1263 DEBUG(0, ("Auth step returned an error (%s)\n",
1264 nt_errstr(status)));
1265 goto err_exit;
1269 ZERO_STRUCT(u.alter_resp);
1270 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1271 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1272 u.alter_resp.assoc_group_id = assoc_gid;
1274 /* secondary address CAN be NULL
1275 * as the specs say it's ignored.
1276 * It MUST be NULL to have the spoolss working.
1278 u.alter_resp.secondary_address = "";
1279 u.alter_resp.secondary_address_size = 1;
1281 u.alter_resp.num_results = 1;
1282 u.alter_resp.ctx_list = &bind_ack_ctx;
1284 /* NOTE: We leave the auth_info empty so we can calculate the padding
1285 * later and then append the auth_info --simo */
1288 * Marshall directly into the outgoing PDU space. We
1289 * must do this as we need to set to the bind response
1290 * header and are never sending more than one PDU here.
1293 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1294 DCERPC_PKT_ALTER_RESP,
1295 DCERPC_PFC_FLAG_FIRST |
1296 DCERPC_PFC_FLAG_LAST,
1297 auth_resp.length,
1298 pkt->call_id,
1300 &p->out_data.frag);
1301 if (!NT_STATUS_IS_OK(status)) {
1302 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1303 nt_errstr(status)));
1306 if (auth_resp.length) {
1308 /* Work out any padding needed before the auth footer. */
1309 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1310 if (pad_len) {
1311 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1312 DEBUG(10, ("auth pad_len = %u\n",
1313 (unsigned int)pad_len));
1316 status = dcerpc_push_dcerpc_auth(pkt,
1317 auth_info.auth_type,
1318 auth_info.auth_level,
1319 pad_len,
1320 1, /* auth_context_id */
1321 &auth_resp,
1322 &auth_blob);
1323 if (!NT_STATUS_IS_OK(status)) {
1324 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1325 goto err_exit;
1329 /* Now that we have the auth len store it into the right place in
1330 * the dcerpc header */
1331 dcerpc_set_frag_length(&p->out_data.frag,
1332 p->out_data.frag.length +
1333 pad_len + auth_blob.length);
1335 if (auth_resp.length) {
1336 if (pad_len) {
1337 char pad[SERVER_NDR_PADDING_SIZE];
1338 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1339 if (!data_blob_append(p->mem_ctx,
1340 &p->out_data.frag,
1341 pad, pad_len)) {
1342 DEBUG(0, ("api_pipe_bind_req: failed to add "
1343 "%u bytes of pad data.\n",
1344 (unsigned int)pad_len));
1345 goto err_exit;
1349 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1350 auth_blob.data, auth_blob.length)) {
1351 DEBUG(0, ("Append of auth info failed.\n"));
1352 goto err_exit;
1357 * Setup the lengths for the initial reply.
1360 p->out_data.data_sent_length = 0;
1361 p->out_data.current_pdu_sent = 0;
1363 TALLOC_FREE(auth_blob.data);
1364 return True;
1366 err_exit:
1368 data_blob_free(&p->out_data.frag);
1369 TALLOC_FREE(auth_blob.data);
1370 return setup_bind_nak(p, pkt);
1373 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1374 const struct api_struct *api_rpc_cmds, int n_cmds,
1375 const struct ndr_syntax_id *syntax);
1377 /****************************************************************************
1378 Find the correct RPC function to call for this request.
1379 If the pipe is authenticated then become the correct UNIX user
1380 before doing the call.
1381 ****************************************************************************/
1383 static bool api_pipe_request(struct pipes_struct *p,
1384 struct ncacn_packet *pkt)
1386 bool ret = False;
1387 struct pipe_rpc_fns *pipe_fns;
1389 if (!p->pipe_bound) {
1390 DEBUG(1, ("Pipe not bound!\n"));
1391 data_blob_free(&p->out_data.rdata);
1392 return false;
1395 if (!become_authenticated_pipe_user(p->session_info)) {
1396 DEBUG(1, ("Failed to become pipe user!\n"));
1397 data_blob_free(&p->out_data.rdata);
1398 return false;
1401 /* get the set of RPC functions for this context */
1403 pipe_fns = find_pipe_fns_by_context(p->contexts,
1404 pkt->u.request.context_id);
1406 if ( pipe_fns ) {
1407 TALLOC_CTX *frame = talloc_stackframe();
1409 DEBUG(5, ("Requested %s rpc service\n",
1410 get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
1412 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1413 &pipe_fns->syntax);
1415 TALLOC_FREE(frame);
1417 else {
1418 DEBUG(0, ("No rpc function table associated with context "
1419 "[%d]\n",
1420 pkt->u.request.context_id));
1423 unbecome_authenticated_pipe_user();
1425 return ret;
1428 /*******************************************************************
1429 Calls the underlying RPC function for a named pipe.
1430 ********************************************************************/
1432 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1433 const struct api_struct *api_rpc_cmds, int n_cmds,
1434 const struct ndr_syntax_id *syntax)
1436 int fn_num;
1437 uint32_t offset1;
1439 /* interpret the command */
1440 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1441 get_pipe_name_from_syntax(talloc_tos(), syntax),
1442 pkt->u.request.opnum));
1444 if (DEBUGLEVEL >= 50) {
1445 fstring name;
1446 slprintf(name, sizeof(name)-1, "in_%s",
1447 get_pipe_name_from_syntax(talloc_tos(), syntax));
1448 dump_pdu_region(name, pkt->u.request.opnum,
1449 &p->in_data.data, 0,
1450 p->in_data.data.length);
1453 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1454 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1455 api_rpc_cmds[fn_num].fn != NULL) {
1456 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1457 api_rpc_cmds[fn_num].name));
1458 break;
1462 if (fn_num == n_cmds) {
1464 * For an unknown RPC just return a fault PDU but
1465 * return True to allow RPC's on the pipe to continue
1466 * and not put the pipe into fault state. JRA.
1468 DEBUG(4, ("unknown\n"));
1469 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1470 return True;
1473 offset1 = p->out_data.rdata.length;
1475 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1476 fn_num, api_rpc_cmds[fn_num].fn));
1477 /* do the actual command */
1478 if(!api_rpc_cmds[fn_num].fn(p)) {
1479 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1480 get_pipe_name_from_syntax(talloc_tos(), syntax),
1481 api_rpc_cmds[fn_num].name));
1482 data_blob_free(&p->out_data.rdata);
1483 return False;
1486 if (p->bad_handle_fault_state) {
1487 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1488 p->bad_handle_fault_state = False;
1489 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1490 return True;
1493 if (p->rng_fault_state) {
1494 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1495 p->rng_fault_state = False;
1496 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1497 return True;
1500 if (DEBUGLEVEL >= 50) {
1501 fstring name;
1502 slprintf(name, sizeof(name)-1, "out_%s",
1503 get_pipe_name_from_syntax(talloc_tos(), syntax));
1504 dump_pdu_region(name, pkt->u.request.opnum,
1505 &p->out_data.rdata, offset1,
1506 p->out_data.rdata.length);
1509 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1510 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1512 /* Check for buffer underflow in rpc parsing */
1513 if ((DEBUGLEVEL >= 10) &&
1514 (pkt->frag_length < p->in_data.data.length)) {
1515 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1516 dump_data(10, p->in_data.data.data + pkt->frag_length,
1517 p->in_data.data.length - pkt->frag_length);
1520 return True;
1523 /****************************************************************************
1524 Initialise an outgoing packet.
1525 ****************************************************************************/
1527 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1529 output_data *o_data = &p->out_data;
1531 /* Reset the offset counters. */
1532 o_data->data_sent_length = 0;
1533 o_data->current_pdu_sent = 0;
1535 data_blob_free(&o_data->frag);
1537 /* Free any memory in the current return data buffer. */
1538 data_blob_free(&o_data->rdata);
1540 return True;
1543 /****************************************************************************
1544 Sets the fault state on incoming packets.
1545 ****************************************************************************/
1547 void set_incoming_fault(struct pipes_struct *p)
1549 data_blob_free(&p->in_data.data);
1550 p->in_data.pdu_needed_len = 0;
1551 p->in_data.pdu.length = 0;
1552 p->fault_state = True;
1554 DEBUG(10, ("Setting fault state\n"));
1557 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1558 struct ncacn_packet *pkt,
1559 DATA_BLOB *raw_pkt)
1561 NTSTATUS status;
1562 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1563 size_t pad_len;
1565 DEBUG(10, ("Checking request auth.\n"));
1567 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1568 hdr_size += 16;
1571 /* in case of sealing this function will unseal the data in place */
1572 status = dcerpc_check_auth(auth, pkt,
1573 &pkt->u.request.stub_and_verifier,
1574 hdr_size, raw_pkt,
1575 &pad_len);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 return status;
1581 /* remove padding and auth trailer,
1582 * this way the caller will get just the data */
1583 if (pkt->auth_length) {
1584 size_t trail_len = pad_len
1585 + DCERPC_AUTH_TRAILER_LENGTH
1586 + pkt->auth_length;
1587 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1588 return NT_STATUS_INFO_LENGTH_MISMATCH;
1590 pkt->u.request.stub_and_verifier.length -= trail_len;
1593 return NT_STATUS_OK;
1596 /****************************************************************************
1597 Processes a request pdu. This will do auth processing if needed, and
1598 appends the data into the complete stream if the LAST flag is not set.
1599 ****************************************************************************/
1601 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1603 NTSTATUS status;
1604 DATA_BLOB data;
1606 if (!p->pipe_bound) {
1607 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1608 set_incoming_fault(p);
1609 return False;
1612 /* Store the opnum */
1613 p->opnum = pkt->u.request.opnum;
1615 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1616 if (!NT_STATUS_IS_OK(status)) {
1617 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1618 nt_errstr(status)));
1619 set_incoming_fault(p);
1620 return false;
1623 data = pkt->u.request.stub_and_verifier;
1626 * Check the data length doesn't go over the 15Mb limit.
1627 * increased after observing a bug in the Windows NT 4.0 SP6a
1628 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1629 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1632 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1633 DEBUG(0, ("process_request_pdu: "
1634 "rpc data buffer too large (%u) + (%u)\n",
1635 (unsigned int)p->in_data.data.length,
1636 (unsigned int)data.length));
1637 set_incoming_fault(p);
1638 return False;
1642 * Append the data portion into the buffer and return.
1645 if (data.length) {
1646 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1647 data.data, data.length)) {
1648 DEBUG(0, ("Unable to append data size %u "
1649 "to parse buffer of size %u.\n",
1650 (unsigned int)data.length,
1651 (unsigned int)p->in_data.data.length));
1652 set_incoming_fault(p);
1653 return False;
1657 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1658 bool ret = False;
1660 * Ok - we finally have a complete RPC stream.
1661 * Call the rpc command to process it.
1665 * Process the complete data stream here.
1667 if (pipe_init_outgoing_data(p)) {
1668 ret = api_pipe_request(p, pkt);
1671 return ret;
1674 return True;
1677 /****************************************************************************
1678 Processes a finished PDU stored in p->in_data.pdu.
1679 ****************************************************************************/
1681 void process_complete_pdu(struct pipes_struct *p)
1683 struct ncacn_packet *pkt = NULL;
1684 NTSTATUS status;
1685 bool reply = False;
1687 if(p->fault_state) {
1688 DEBUG(10,("RPC connection in fault state.\n"));
1689 goto done;
1692 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1693 if (!pkt) {
1694 DEBUG(0, ("Out of memory!\n"));
1695 goto done;
1699 * Ensure we're using the corrent endianness for both the
1700 * RPC header flags and the raw data we will be reading from.
1702 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1703 p->endian = RPC_LITTLE_ENDIAN;
1704 } else {
1705 p->endian = RPC_BIG_ENDIAN;
1707 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1709 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1710 pkt, p->endian);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1713 nt_errstr(status)));
1714 goto done;
1717 /* Store the call_id */
1718 p->call_id = pkt->call_id;
1720 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1722 switch (pkt->ptype) {
1723 case DCERPC_PKT_REQUEST:
1724 reply = process_request_pdu(p, pkt);
1725 break;
1727 case DCERPC_PKT_PING: /* CL request - ignore... */
1728 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1729 (unsigned int)pkt->ptype));
1730 break;
1732 case DCERPC_PKT_RESPONSE: /* No responses here. */
1733 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1734 break;
1736 case DCERPC_PKT_FAULT:
1737 case DCERPC_PKT_WORKING:
1738 /* CL request - reply to a ping when a call in process. */
1739 case DCERPC_PKT_NOCALL:
1740 /* CL - server reply to a ping call. */
1741 case DCERPC_PKT_REJECT:
1742 case DCERPC_PKT_ACK:
1743 case DCERPC_PKT_CL_CANCEL:
1744 case DCERPC_PKT_FACK:
1745 case DCERPC_PKT_CANCEL_ACK:
1746 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1747 (unsigned int)pkt->ptype));
1748 break;
1750 case DCERPC_PKT_BIND:
1752 * We assume that a pipe bind is only in one pdu.
1754 if (pipe_init_outgoing_data(p)) {
1755 reply = api_pipe_bind_req(p, pkt);
1757 break;
1759 case DCERPC_PKT_BIND_ACK:
1760 case DCERPC_PKT_BIND_NAK:
1761 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1762 "packet type %u received.\n",
1763 (unsigned int)pkt->ptype));
1764 break;
1767 case DCERPC_PKT_ALTER:
1769 * We assume that a pipe bind is only in one pdu.
1771 if (pipe_init_outgoing_data(p)) {
1772 reply = api_pipe_alter_context(p, pkt);
1774 break;
1776 case DCERPC_PKT_ALTER_RESP:
1777 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1778 "Should only be server -> client.\n"));
1779 break;
1781 case DCERPC_PKT_AUTH3:
1783 * The third packet in an auth exchange.
1785 if (pipe_init_outgoing_data(p)) {
1786 reply = api_pipe_bind_auth3(p, pkt);
1788 break;
1790 case DCERPC_PKT_SHUTDOWN:
1791 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1792 "Should only be server -> client.\n"));
1793 break;
1795 case DCERPC_PKT_CO_CANCEL:
1796 /* For now just free all client data and continue
1797 * processing. */
1798 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1799 " Abandoning rpc call.\n"));
1800 /* As we never do asynchronous RPC serving, we can
1801 * never cancel a call (as far as I know).
1802 * If we ever did we'd have to send a cancel_ack reply.
1803 * For now, just free all client data and continue
1804 * processing. */
1805 reply = True;
1806 break;
1808 #if 0
1809 /* Enable this if we're doing async rpc. */
1810 /* We must check the outstanding callid matches. */
1811 if (pipe_init_outgoing_data(p)) {
1812 /* Send a cancel_ack PDU reply. */
1813 /* We should probably check the auth-verifier here. */
1814 reply = setup_cancel_ack_reply(p, pkt);
1816 break;
1817 #endif
1819 case DCERPC_PKT_ORPHANED:
1820 /* We should probably check the auth-verifier here.
1821 * For now just free all client data and continue
1822 * processing. */
1823 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1824 " Abandoning rpc call.\n"));
1825 reply = True;
1826 break;
1828 default:
1829 DEBUG(0, ("process_complete_pdu: "
1830 "Unknown rpc type = %u received.\n",
1831 (unsigned int)pkt->ptype));
1832 break;
1835 done:
1836 if (!reply) {
1837 DEBUG(3,("DCE/RPC fault sent!"));
1838 set_incoming_fault(p);
1839 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1840 TALLOC_FREE(pkt);
1841 } else {
1843 * Reset the lengths. We're ready for a new pdu.
1845 TALLOC_FREE(p->in_data.pdu.data);
1846 p->in_data.pdu_needed_len = 0;
1847 p->in_data.pdu.length = 0;
1850 TALLOC_FREE(pkt);