smbd: Fix calls to create_conn_struct_cwd to be correctly indented.
[Samba/gbeck.git] / source3 / rpc_server / srv_pipe.c
blob7cce1806e2891b9164f111188aa399976c9700a6
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 /* this module apparently provides an implementation of DCE/RPC over a
21 * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
22 * documentation are available (in on-line form) from the X-Open group.
24 * this module should provide a level of abstraction between SMB
25 * and DCE/RPC, while minimising the amount of mallocs, unnecessary
26 * data copies, and network traffic.
30 #include "includes.h"
31 #include "system/filesys.h"
32 #include "srv_pipe_internal.h"
33 #include "../librpc/gen_ndr/ndr_schannel.h"
34 #include "../librpc/gen_ndr/dcerpc.h"
35 #include "../librpc/rpc/rpc_common.h"
36 #include "../libcli/auth/schannel.h"
37 #include "../libcli/auth/spnego.h"
38 #include "dcesrv_auth_generic.h"
39 #include "rpc_server.h"
40 #include "rpc_dce.h"
41 #include "smbd/smbd.h"
42 #include "auth.h"
43 #include "ntdomain.h"
44 #include "rpc_server/srv_pipe.h"
45 #include "rpc_server/rpc_contexts.h"
46 #include "lib/param/param.h"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_RPC_SRV
51 /**
52 * Dump everything from the start of the end up of the provided data
53 * into a file, but only at debug level >= 50
54 **/
55 static void dump_pdu_region(const char *name, int v,
56 DATA_BLOB *data, size_t start, size_t end)
58 int fd, i;
59 char *fname = NULL;
60 ssize_t sz;
62 if (DEBUGLEVEL < 50) return;
64 if (start > data->length || end > data->length || start > end) return;
66 for (i = 1; i < 100; i++) {
67 if (v != -1) {
68 fname = talloc_asprintf(talloc_tos(),
69 "/tmp/%s_%d.%d.prs",
70 name, v, i);
71 } else {
72 fname = talloc_asprintf(talloc_tos(),
73 "/tmp/%s_%d.prs",
74 name, i);
76 if (!fname) {
77 return;
79 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
80 if (fd != -1 || errno != EEXIST) break;
82 if (fd != -1) {
83 sz = write(fd, data->data + start, end - start);
84 i = close(fd);
85 if ((sz != end - start) || (i != 0) ) {
86 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
87 fname, (unsigned long)sz,
88 (unsigned long)end - start, i));
89 } else {
90 DEBUG(0,("created %s\n", fname));
93 TALLOC_FREE(fname);
96 static DATA_BLOB generic_session_key(void)
98 return data_blob_const("SystemLibraryDTC", 16);
101 /*******************************************************************
102 Generate the next PDU to be returned from the data.
103 ********************************************************************/
105 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
106 struct pipe_auth_data *auth,
107 uint32_t call_id,
108 DATA_BLOB *rdata,
109 size_t data_sent_length,
110 DATA_BLOB *frag,
111 size_t *pdu_size)
113 union dcerpc_payload u;
114 uint8_t pfc_flags;
115 size_t data_left;
116 size_t data_to_send;
117 size_t frag_len;
118 size_t pad_len = 0;
119 size_t auth_len = 0;
120 NTSTATUS status;
122 ZERO_STRUCT(u.response);
124 /* Set up rpc packet pfc flags. */
125 if (data_sent_length == 0) {
126 pfc_flags = DCERPC_PFC_FLAG_FIRST;
127 } else {
128 pfc_flags = 0;
131 /* Work out how much we can fit in a single PDU. */
132 data_left = rdata->length - data_sent_length;
134 /* Ensure there really is data left to send. */
135 if (!data_left) {
136 DEBUG(0, ("No data left to send !\n"));
137 return NT_STATUS_BUFFER_TOO_SMALL;
140 status = dcerpc_guess_sizes(auth,
141 DCERPC_RESPONSE_LENGTH,
142 data_left,
143 RPC_MAX_PDU_FRAG_LEN,
144 SERVER_NDR_PADDING_SIZE,
145 &data_to_send, &frag_len,
146 &auth_len, &pad_len);
147 if (!NT_STATUS_IS_OK(status)) {
148 return status;
151 /* Set up the alloc hint. This should be the data left to send. */
152 u.response.alloc_hint = data_left;
154 /* Work out if this PDU will be the last. */
155 if (data_sent_length + data_to_send >= rdata->length) {
156 pfc_flags |= DCERPC_PFC_FLAG_LAST;
159 /* Prepare data to be NDR encoded. */
160 u.response.stub_and_verifier =
161 data_blob_const(rdata->data + data_sent_length, data_to_send);
163 /* Store the packet in the data stream. */
164 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
165 pfc_flags, auth_len, call_id,
166 &u, frag);
167 if (!NT_STATUS_IS_OK(status)) {
168 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
169 return status;
172 if (auth_len) {
173 /* Set the proper length on the pdu, including padding.
174 * Only needed if an auth trailer will be appended. */
175 dcerpc_set_frag_length(frag, frag->length
176 + pad_len
177 + DCERPC_AUTH_TRAILER_LENGTH
178 + auth_len);
181 if (auth_len) {
182 status = dcerpc_add_auth_footer(auth, pad_len, frag);
183 if (!NT_STATUS_IS_OK(status)) {
184 data_blob_free(frag);
185 return status;
189 *pdu_size = data_to_send;
190 return NT_STATUS_OK;
193 /*******************************************************************
194 Generate the next PDU to be returned from the data in p->rdata.
195 ********************************************************************/
197 bool create_next_pdu(struct pipes_struct *p)
199 size_t pdu_size = 0;
200 NTSTATUS status;
203 * If we're in the fault state, keep returning fault PDU's until
204 * the pipe gets closed. JRA.
206 if (p->fault_state) {
207 setup_fault_pdu(p, NT_STATUS(p->fault_state));
208 return true;
211 status = create_next_packet(p->mem_ctx, &p->auth,
212 p->call_id, &p->out_data.rdata,
213 p->out_data.data_sent_length,
214 &p->out_data.frag, &pdu_size);
215 if (!NT_STATUS_IS_OK(status)) {
216 DEBUG(0, ("Failed to create packet with error %s, "
217 "(auth level %u / type %u)\n",
218 nt_errstr(status),
219 (unsigned int)p->auth.auth_level,
220 (unsigned int)p->auth.auth_type));
221 return false;
224 /* Setup the counts for this PDU. */
225 p->out_data.data_sent_length += pdu_size;
226 p->out_data.current_pdu_sent = 0;
227 return true;
231 static bool pipe_init_outgoing_data(struct pipes_struct *p);
233 /*******************************************************************
234 Marshall a bind_nak pdu.
235 *******************************************************************/
237 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
239 NTSTATUS status;
240 union dcerpc_payload u;
242 /* Free any memory in the current return data buffer. */
243 pipe_init_outgoing_data(p);
246 * Initialize a bind_nak header.
249 ZERO_STRUCT(u);
251 u.bind_nak.reject_reason = 0;
254 * Marshall directly into the outgoing PDU space. We
255 * must do this as we need to set to the bind response
256 * header and are never sending more than one PDU here.
259 status = dcerpc_push_ncacn_packet(p->mem_ctx,
260 DCERPC_PKT_BIND_NAK,
261 DCERPC_PFC_FLAG_FIRST |
262 DCERPC_PFC_FLAG_LAST,
264 pkt->call_id,
266 &p->out_data.frag);
267 if (!NT_STATUS_IS_OK(status)) {
268 return False;
271 p->out_data.data_sent_length = 0;
272 p->out_data.current_pdu_sent = 0;
274 TALLOC_FREE(p->auth.auth_ctx);
275 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
276 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
277 p->pipe_bound = False;
279 return True;
282 /*******************************************************************
283 Marshall a fault pdu.
284 *******************************************************************/
286 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
288 NTSTATUS status;
289 union dcerpc_payload u;
291 /* Free any memory in the current return data buffer. */
292 pipe_init_outgoing_data(p);
295 * Initialize a fault header.
298 ZERO_STRUCT(u);
300 u.fault.status = NT_STATUS_V(fault_status);
301 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
304 * Marshall directly into the outgoing PDU space. We
305 * must do this as we need to set to the bind response
306 * header and are never sending more than one PDU here.
309 status = dcerpc_push_ncacn_packet(p->mem_ctx,
310 DCERPC_PKT_FAULT,
311 DCERPC_PFC_FLAG_FIRST |
312 DCERPC_PFC_FLAG_LAST |
313 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
315 p->call_id,
317 &p->out_data.frag);
318 if (!NT_STATUS_IS_OK(status)) {
319 return False;
322 p->out_data.data_sent_length = 0;
323 p->out_data.current_pdu_sent = 0;
325 return True;
328 /*******************************************************************
329 Ensure a bind request has the correct abstract & transfer interface.
330 Used to reject unknown binds from Win2k.
331 *******************************************************************/
333 static bool check_bind_req(struct pipes_struct *p,
334 struct ndr_syntax_id* abstract,
335 struct ndr_syntax_id* transfer,
336 uint32_t context_id)
338 struct pipe_rpc_fns *context_fns;
339 bool ok;
341 DEBUG(3,("check_bind_req for %s\n",
342 get_pipe_name_from_syntax(talloc_tos(), abstract)));
344 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
345 if (rpc_srv_pipe_exists_by_id(abstract) &&
346 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
347 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
348 rpc_srv_get_pipe_cli_name(abstract),
349 rpc_srv_get_pipe_srv_name(abstract)));
350 } else {
351 return false;
354 ok = init_pipe_handles(p, abstract);
355 if (!ok) {
356 DEBUG(1, ("Failed to init pipe handles!\n"));
357 return false;
360 context_fns = talloc(p, struct pipe_rpc_fns);
361 if (context_fns == NULL) {
362 DEBUG(0,("check_bind_req: talloc() failed!\n"));
363 return false;
366 context_fns->next = context_fns->prev = NULL;
367 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
368 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
369 context_fns->context_id = context_id;
370 context_fns->syntax = *abstract;
372 /* add to the list of open contexts */
374 DLIST_ADD( p->contexts, context_fns );
376 return True;
380 * Is a named pipe known?
381 * @param[in] pipename Just the filename
382 * @result Do we want to serve this?
384 bool is_known_pipename(const char *pipename, struct ndr_syntax_id *syntax)
386 NTSTATUS status;
388 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
389 DEBUG(10, ("refusing spoolss access\n"));
390 return false;
393 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
394 return true;
397 status = smb_probe_module("rpc", pipename);
398 if (!NT_STATUS_IS_OK(status)) {
399 DEBUG(10, ("is_known_pipename: %s unknown\n", pipename));
400 return false;
402 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
405 * Scan the list again for the interface id
407 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
408 return true;
411 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
412 pipename));
414 return false;
417 /*******************************************************************
418 Handle an schannel bind auth.
419 *******************************************************************/
421 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
422 TALLOC_CTX *mem_ctx,
423 struct dcerpc_auth *auth_info,
424 DATA_BLOB *response)
426 struct NL_AUTH_MESSAGE neg;
427 struct NL_AUTH_MESSAGE reply;
428 bool ret;
429 NTSTATUS status;
430 struct netlogon_creds_CredentialState *creds;
431 enum ndr_err_code ndr_err;
432 struct schannel_state *schannel_auth;
433 struct loadparm_context *lp_ctx;
435 ndr_err = ndr_pull_struct_blob(
436 &auth_info->credentials, mem_ctx, &neg,
437 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
438 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
439 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
440 return false;
443 if (DEBUGLEVEL >= 10) {
444 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
447 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
448 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
449 return false;
452 lp_ctx = loadparm_init_s3(p, loadparm_s3_helpers());
453 if (!lp_ctx) {
454 DEBUG(0,("pipe_schannel_auth_bind: loadparm_init_s3() failed!\n"));
455 return false;
459 * The neg.oem_netbios_computer.a key here must match the remote computer name
460 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
461 * operations that use credentials.
464 become_root();
465 status = schannel_get_creds_state(p, lp_ctx,
466 neg.oem_netbios_computer.a, &creds);
467 unbecome_root();
469 talloc_unlink(p, lp_ctx);
470 if (!NT_STATUS_IS_OK(status)) {
471 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
472 return False;
475 schannel_auth = talloc_zero(p, struct schannel_state);
476 if (!schannel_auth) {
477 TALLOC_FREE(creds);
478 return False;
481 schannel_auth->state = SCHANNEL_STATE_START;
482 schannel_auth->initiator = false;
483 schannel_auth->creds = creds;
486 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
487 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
488 * struct of the person who opened the pipe. I need to test this further. JRA.
490 * VL. As we are mapping this to guest set the generic key
491 * "SystemLibraryDTC" key here. It's a bit difficult to test against
492 * W2k3, as it does not allow schannel binds against SAMR and LSA
493 * anymore.
496 ret = session_info_set_session_key(p->session_info, generic_session_key());
498 if (!ret) {
499 DEBUG(0, ("session_info_set_session_key failed\n"));
500 return false;
503 /*** SCHANNEL verifier ***/
505 reply.MessageType = NL_NEGOTIATE_RESPONSE;
506 reply.Flags = 0;
507 reply.Buffer.dummy = 5; /* ??? actually I don't think
508 * this has any meaning
509 * here - gd */
511 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
512 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
513 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
514 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
515 return false;
518 if (DEBUGLEVEL >= 10) {
519 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
522 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
523 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
525 /* We're finished with this bind - no more packets. */
526 p->auth.auth_ctx = schannel_auth;
527 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
529 p->pipe_bound = True;
531 return True;
534 /*******************************************************************
535 Handle an NTLMSSP bind auth.
536 *******************************************************************/
538 static bool pipe_auth_generic_bind(struct pipes_struct *p,
539 TALLOC_CTX *mem_ctx,
540 struct dcerpc_auth *auth_info,
541 DATA_BLOB *response)
543 struct gensec_security *gensec_security = NULL;
544 NTSTATUS status;
546 status = auth_generic_server_authtype_start(p,
547 auth_info->auth_type,
548 auth_info->auth_level,
549 &auth_info->credentials,
550 response,
551 p->remote_address,
552 &gensec_security);
553 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
554 DEBUG(0, (__location__ ": auth_generic_server_authtype_start failed: %s\n",
555 nt_errstr(status)));
556 return false;
559 /* Make sure data is bound to the memctx, to be freed the caller */
560 talloc_steal(mem_ctx, response->data);
562 p->auth.auth_ctx = gensec_security;
563 p->auth.auth_type = auth_info->auth_type;
565 return true;
568 /*******************************************************************
569 Process an NTLMSSP authentication response.
570 If this function succeeds, the user has been authenticated
571 and their domain, name and calling workstation stored in
572 the pipe struct.
573 *******************************************************************/
575 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
576 struct gensec_security *gensec_security,
577 enum dcerpc_AuthLevel auth_level,
578 struct auth_session_info **session_info)
580 NTSTATUS status;
581 bool ret;
583 DEBUG(5, (__location__ ": checking user details\n"));
585 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
586 ensure the underlying NTLMSSP flags are also set. If not we should
587 refuse the bind. */
589 status = auth_generic_server_check_flags(gensec_security,
590 (auth_level ==
591 DCERPC_AUTH_LEVEL_INTEGRITY),
592 (auth_level ==
593 DCERPC_AUTH_LEVEL_PRIVACY));
594 if (!NT_STATUS_IS_OK(status)) {
595 DEBUG(0, (__location__ ": Client failed to negotatie proper "
596 "security for rpc connection\n"));
597 return false;
600 TALLOC_FREE(*session_info);
602 status = auth_generic_server_get_user_info(gensec_security,
603 mem_ctx, session_info);
604 if (!NT_STATUS_IS_OK(status)) {
605 DEBUG(0, (__location__ ": failed to obtain the server info "
606 "for authenticated user: %s\n", nt_errstr(status)));
607 return false;
610 if ((*session_info)->security_token == NULL) {
611 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
612 return false;
616 * We're an authenticated bind over smb, so the session key needs to
617 * be set to "SystemLibraryDTC". Weird, but this is what Windows
618 * does. See the RPC-SAMBA3SESSIONKEY.
621 ret = session_info_set_session_key((*session_info), generic_session_key());
622 if (!ret) {
623 DEBUG(0, ("Failed to set session key!\n"));
624 return false;
627 return true;
630 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
632 struct gensec_security *gensec_security;
634 switch (p->auth.auth_type) {
635 case DCERPC_AUTH_TYPE_NTLMSSP:
636 case DCERPC_AUTH_TYPE_KRB5:
637 case DCERPC_AUTH_TYPE_SPNEGO:
638 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
639 struct gensec_security);
640 if (!pipe_auth_generic_verify_final(p, gensec_security,
641 p->auth.auth_level,
642 &p->session_info)) {
643 return NT_STATUS_ACCESS_DENIED;
645 break;
646 default:
647 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
648 (unsigned int)p->auth.auth_type));
649 return NT_STATUS_ACCESS_DENIED;
652 p->pipe_bound = true;
654 return NT_STATUS_OK;
657 /*******************************************************************
658 Respond to a pipe bind request.
659 *******************************************************************/
661 static bool api_pipe_bind_req(struct pipes_struct *p,
662 struct ncacn_packet *pkt)
664 struct dcerpc_auth auth_info;
665 uint16 assoc_gid;
666 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
667 NTSTATUS status;
668 struct ndr_syntax_id id;
669 union dcerpc_payload u;
670 struct dcerpc_ack_ctx bind_ack_ctx;
671 DATA_BLOB auth_resp = data_blob_null;
672 DATA_BLOB auth_blob = data_blob_null;
674 /* No rebinds on a bound pipe - use alter context. */
675 if (p->pipe_bound) {
676 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
677 return setup_bind_nak(p, pkt);
680 if (pkt->u.bind.num_contexts == 0) {
681 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
682 goto err_exit;
686 * Try and find the correct pipe name to ensure
687 * that this is a pipe name we support.
689 id = pkt->u.bind.ctx_list[0].abstract_syntax;
690 if (rpc_srv_pipe_exists_by_id(&id)) {
691 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
692 rpc_srv_get_pipe_cli_name(&id),
693 rpc_srv_get_pipe_srv_name(&id)));
694 } else {
695 status = smb_probe_module(
696 "rpc", get_pipe_name_from_syntax(
697 talloc_tos(),
698 &id));
700 if (NT_STATUS_IS_ERR(status)) {
701 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
702 "%s in bind request.\n",
703 get_pipe_name_from_syntax(talloc_tos(), &id)));
705 return setup_bind_nak(p, pkt);
708 if (rpc_srv_get_pipe_interface_by_cli_name(
709 get_pipe_name_from_syntax(talloc_tos(),
710 &id),
711 &id)) {
712 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
713 rpc_srv_get_pipe_cli_name(&id),
714 rpc_srv_get_pipe_srv_name(&id)));
715 } else {
716 DEBUG(0, ("module %s doesn't provide functions for "
717 "pipe %s!\n",
718 get_pipe_name_from_syntax(talloc_tos(), &id),
719 get_pipe_name_from_syntax(talloc_tos(), &id)));
720 return setup_bind_nak(p, pkt);
724 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
726 if (pkt->u.bind.assoc_group_id != 0) {
727 assoc_gid = pkt->u.bind.assoc_group_id;
728 } else {
729 assoc_gid = 0x53f0;
733 * Create the bind response struct.
736 /* If the requested abstract synt uuid doesn't match our client pipe,
737 reject the bind_ack & set the transfer interface synt to all 0's,
738 ver 0 (observed when NT5 attempts to bind to abstract interfaces
739 unknown to NT4)
740 Needed when adding entries to a DACL from NT5 - SK */
742 if (check_bind_req(p,
743 &pkt->u.bind.ctx_list[0].abstract_syntax,
744 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
745 pkt->u.bind.ctx_list[0].context_id)) {
747 bind_ack_ctx.result = 0;
748 bind_ack_ctx.reason = 0;
749 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
750 } else {
751 p->pipe_bound = False;
752 /* Rejection reason: abstract syntax not supported */
753 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
754 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
755 bind_ack_ctx.syntax = ndr_syntax_id_null;
759 * Check if this is an authenticated bind request.
761 if (pkt->auth_length) {
762 /* Quick length check. Won't catch a bad auth footer,
763 * prevents overrun. */
765 if (pkt->frag_length < RPC_HEADER_LEN +
766 DCERPC_AUTH_TRAILER_LENGTH +
767 pkt->auth_length) {
768 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
769 "too long for fragment %u.\n",
770 (unsigned int)pkt->auth_length,
771 (unsigned int)pkt->frag_length));
772 goto err_exit;
776 * Decode the authentication verifier.
778 status = dcerpc_pull_dcerpc_auth(pkt,
779 &pkt->u.bind.auth_info,
780 &auth_info, p->endian);
781 if (!NT_STATUS_IS_OK(status)) {
782 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
783 goto err_exit;
786 auth_type = auth_info.auth_type;
788 /* Work out if we have to sign or seal etc. */
789 switch (auth_info.auth_level) {
790 case DCERPC_AUTH_LEVEL_INTEGRITY:
791 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
792 break;
793 case DCERPC_AUTH_LEVEL_PRIVACY:
794 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
795 break;
796 case DCERPC_AUTH_LEVEL_CONNECT:
797 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
798 break;
799 default:
800 DEBUG(0, ("Unexpected auth level (%u).\n",
801 (unsigned int)auth_info.auth_level ));
802 goto err_exit;
805 switch (auth_type) {
806 case DCERPC_AUTH_TYPE_NTLMSSP:
807 if (!pipe_auth_generic_bind(p, pkt,
808 &auth_info, &auth_resp)) {
809 goto err_exit;
811 assoc_gid = 0x7a77;
812 break;
814 case DCERPC_AUTH_TYPE_SCHANNEL:
815 if (!pipe_schannel_auth_bind(p, pkt,
816 &auth_info, &auth_resp)) {
817 goto err_exit;
819 break;
821 case DCERPC_AUTH_TYPE_SPNEGO:
822 case DCERPC_AUTH_TYPE_KRB5:
823 if (!pipe_auth_generic_bind(p, pkt,
824 &auth_info, &auth_resp)) {
825 goto err_exit;
827 break;
829 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
830 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
831 TALLOC_FREE(p->session_info);
833 status = make_session_info_system(p,
834 &p->session_info);
835 if (!NT_STATUS_IS_OK(status)) {
836 goto err_exit;
839 auth_resp = data_blob_talloc(pkt,
840 "NCALRPC_AUTH_OK",
841 15);
843 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
844 p->pipe_bound = true;
845 } else {
846 goto err_exit;
848 break;
850 case DCERPC_AUTH_TYPE_NONE:
851 break;
853 default:
854 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
855 goto err_exit;
859 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
860 /* Unauthenticated bind request. */
861 /* We're finished - no more packets. */
862 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
863 /* We must set the pipe auth_level here also. */
864 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
865 p->pipe_bound = True;
866 /* The session key was initialized from the SMB
867 * session in make_internal_rpc_pipe_p */
870 ZERO_STRUCT(u.bind_ack);
871 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
872 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
873 u.bind_ack.assoc_group_id = assoc_gid;
875 /* name has to be \PIPE\xxxxx */
876 u.bind_ack.secondary_address =
877 talloc_asprintf(pkt, "\\PIPE\\%s",
878 rpc_srv_get_pipe_srv_name(&id));
879 if (!u.bind_ack.secondary_address) {
880 DEBUG(0, ("Out of memory!\n"));
881 goto err_exit;
883 u.bind_ack.secondary_address_size =
884 strlen(u.bind_ack.secondary_address) + 1;
886 u.bind_ack.num_results = 1;
887 u.bind_ack.ctx_list = &bind_ack_ctx;
889 /* NOTE: We leave the auth_info empty so we can calculate the padding
890 * later and then append the auth_info --simo */
893 * Marshall directly into the outgoing PDU space. We
894 * must do this as we need to set to the bind response
895 * header and are never sending more than one PDU here.
898 status = dcerpc_push_ncacn_packet(p->mem_ctx,
899 DCERPC_PKT_BIND_ACK,
900 DCERPC_PFC_FLAG_FIRST |
901 DCERPC_PFC_FLAG_LAST,
902 auth_resp.length,
903 pkt->call_id,
905 &p->out_data.frag);
906 if (!NT_STATUS_IS_OK(status)) {
907 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
908 nt_errstr(status)));
911 if (auth_resp.length) {
913 status = dcerpc_push_dcerpc_auth(pkt,
914 auth_type,
915 auth_info.auth_level,
917 1, /* auth_context_id */
918 &auth_resp,
919 &auth_blob);
920 if (!NT_STATUS_IS_OK(status)) {
921 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
922 goto err_exit;
926 /* Now that we have the auth len store it into the right place in
927 * the dcerpc header */
928 dcerpc_set_frag_length(&p->out_data.frag,
929 p->out_data.frag.length + auth_blob.length);
931 if (auth_blob.length) {
933 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
934 auth_blob.data, auth_blob.length)) {
935 DEBUG(0, ("Append of auth info failed.\n"));
936 goto err_exit;
941 * Setup the lengths for the initial reply.
944 p->out_data.data_sent_length = 0;
945 p->out_data.current_pdu_sent = 0;
947 TALLOC_FREE(auth_blob.data);
948 return True;
950 err_exit:
952 data_blob_free(&p->out_data.frag);
953 TALLOC_FREE(auth_blob.data);
954 return setup_bind_nak(p, pkt);
957 /*******************************************************************
958 This is the "stage3" response after a bind request and reply.
959 *******************************************************************/
961 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
963 struct dcerpc_auth auth_info;
964 DATA_BLOB response = data_blob_null;
965 struct gensec_security *gensec_security;
966 NTSTATUS status;
968 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
970 if (pkt->auth_length == 0) {
971 DEBUG(0, ("No auth field sent for bind request!\n"));
972 goto err;
975 /* Ensure there's enough data for an authenticated request. */
976 if (pkt->frag_length < RPC_HEADER_LEN
977 + DCERPC_AUTH_TRAILER_LENGTH
978 + pkt->auth_length) {
979 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
980 "%u is too large.\n",
981 (unsigned int)pkt->auth_length));
982 goto err;
986 * Decode the authentication verifier response.
989 status = dcerpc_pull_dcerpc_auth(pkt,
990 &pkt->u.auth3.auth_info,
991 &auth_info, p->endian);
992 if (!NT_STATUS_IS_OK(status)) {
993 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
994 goto err;
997 /* We must NEVER look at auth_info->auth_pad_len here,
998 * as old Samba client code gets it wrong and sends it
999 * as zero. JRA.
1002 if (auth_info.auth_type != p->auth.auth_type) {
1003 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1004 "but auth was started as type %d!\n",
1005 auth_info.auth_type, p->auth.auth_type));
1006 goto err;
1009 switch (auth_info.auth_type) {
1010 case DCERPC_AUTH_TYPE_NTLMSSP:
1011 case DCERPC_AUTH_TYPE_KRB5:
1012 case DCERPC_AUTH_TYPE_SPNEGO:
1013 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1014 struct gensec_security);
1015 status = auth_generic_server_step(gensec_security,
1016 pkt, &auth_info.credentials,
1017 &response);
1018 break;
1019 default:
1020 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1021 (unsigned int)auth_info.auth_type));
1022 return false;
1025 if (NT_STATUS_EQUAL(status,
1026 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1027 response.length) {
1028 DEBUG(0, (__location__ ": This was supposed to be the final "
1029 "leg, but crypto machinery claims a response is "
1030 "needed, aborting auth!\n"));
1031 data_blob_free(&response);
1032 goto err;
1034 if (!NT_STATUS_IS_OK(status)) {
1035 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1036 goto err;
1039 /* Now verify auth was indeed successful and extract server info */
1040 status = pipe_auth_verify_final(p);
1041 if (!NT_STATUS_IS_OK(status)) {
1042 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1043 goto err;
1046 return true;
1048 err:
1050 TALLOC_FREE(p->auth.auth_ctx);
1051 return false;
1054 /****************************************************************************
1055 Deal with an alter context call. Can be third part of 3 leg auth request for
1056 SPNEGO calls.
1057 ****************************************************************************/
1059 static bool api_pipe_alter_context(struct pipes_struct *p,
1060 struct ncacn_packet *pkt)
1062 struct dcerpc_auth auth_info;
1063 uint16 assoc_gid;
1064 NTSTATUS status;
1065 union dcerpc_payload u;
1066 struct dcerpc_ack_ctx bind_ack_ctx;
1067 DATA_BLOB auth_resp = data_blob_null;
1068 DATA_BLOB auth_blob = data_blob_null;
1069 int pad_len = 0;
1070 struct gensec_security *gensec_security;
1072 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1074 if (pkt->u.bind.assoc_group_id != 0) {
1075 assoc_gid = pkt->u.bind.assoc_group_id;
1076 } else {
1077 assoc_gid = 0x53f0;
1081 * Create the bind response struct.
1084 /* If the requested abstract synt uuid doesn't match our client pipe,
1085 reject the bind_ack & set the transfer interface synt to all 0's,
1086 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1087 unknown to NT4)
1088 Needed when adding entries to a DACL from NT5 - SK */
1090 if (check_bind_req(p,
1091 &pkt->u.bind.ctx_list[0].abstract_syntax,
1092 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1093 pkt->u.bind.ctx_list[0].context_id)) {
1095 bind_ack_ctx.result = 0;
1096 bind_ack_ctx.reason = 0;
1097 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1098 } else {
1099 p->pipe_bound = False;
1100 /* Rejection reason: abstract syntax not supported */
1101 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1102 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1103 bind_ack_ctx.syntax = ndr_syntax_id_null;
1107 * Check if this is an authenticated alter context request.
1109 if (pkt->auth_length) {
1110 /* Quick length check. Won't catch a bad auth footer,
1111 * prevents overrun. */
1113 if (pkt->frag_length < RPC_HEADER_LEN +
1114 DCERPC_AUTH_TRAILER_LENGTH +
1115 pkt->auth_length) {
1116 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1117 "too long for fragment %u.\n",
1118 (unsigned int)pkt->auth_length,
1119 (unsigned int)pkt->frag_length ));
1120 goto err_exit;
1123 status = dcerpc_pull_dcerpc_auth(pkt,
1124 &pkt->u.bind.auth_info,
1125 &auth_info, p->endian);
1126 if (!NT_STATUS_IS_OK(status)) {
1127 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1128 goto err_exit;
1131 /* We can only finish if the pipe is unbound for now */
1132 if (p->pipe_bound) {
1133 DEBUG(0, (__location__ ": Pipe already bound, "
1134 "Altering Context not yet supported!\n"));
1135 goto err_exit;
1138 if (auth_info.auth_type != p->auth.auth_type) {
1139 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1140 "but auth was started as type %d!\n",
1141 auth_info.auth_type, p->auth.auth_type));
1142 goto err_exit;
1146 switch (auth_info.auth_type) {
1147 case DCERPC_AUTH_TYPE_SPNEGO:
1148 case DCERPC_AUTH_TYPE_KRB5:
1149 case DCERPC_AUTH_TYPE_NTLMSSP:
1150 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1151 struct gensec_security);
1152 status = auth_generic_server_step(gensec_security,
1153 pkt,
1154 &auth_info.credentials,
1155 &auth_resp);
1156 break;
1158 default:
1159 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1160 "in alter-context call\n",
1161 auth_info.auth_type));
1162 goto err_exit;
1165 if (NT_STATUS_IS_OK(status)) {
1166 /* third leg of auth, verify auth info */
1167 status = pipe_auth_verify_final(p);
1168 if (!NT_STATUS_IS_OK(status)) {
1169 DEBUG(0, ("Auth Verify failed (%s)\n",
1170 nt_errstr(status)));
1171 goto err_exit;
1173 } else if (NT_STATUS_EQUAL(status,
1174 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1175 DEBUG(10, ("More auth legs required.\n"));
1176 } else {
1177 DEBUG(0, ("Auth step returned an error (%s)\n",
1178 nt_errstr(status)));
1179 goto err_exit;
1183 ZERO_STRUCT(u.alter_resp);
1184 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1185 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1186 u.alter_resp.assoc_group_id = assoc_gid;
1188 /* secondary address CAN be NULL
1189 * as the specs say it's ignored.
1190 * It MUST be NULL to have the spoolss working.
1192 u.alter_resp.secondary_address = "";
1193 u.alter_resp.secondary_address_size = 1;
1195 u.alter_resp.num_results = 1;
1196 u.alter_resp.ctx_list = &bind_ack_ctx;
1198 /* NOTE: We leave the auth_info empty so we can calculate the padding
1199 * later and then append the auth_info --simo */
1202 * Marshall directly into the outgoing PDU space. We
1203 * must do this as we need to set to the bind response
1204 * header and are never sending more than one PDU here.
1207 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1208 DCERPC_PKT_ALTER_RESP,
1209 DCERPC_PFC_FLAG_FIRST |
1210 DCERPC_PFC_FLAG_LAST,
1211 auth_resp.length,
1212 pkt->call_id,
1214 &p->out_data.frag);
1215 if (!NT_STATUS_IS_OK(status)) {
1216 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1217 nt_errstr(status)));
1220 if (auth_resp.length) {
1222 /* Work out any padding needed before the auth footer. */
1223 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1224 if (pad_len) {
1225 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1226 DEBUG(10, ("auth pad_len = %u\n",
1227 (unsigned int)pad_len));
1230 status = dcerpc_push_dcerpc_auth(pkt,
1231 auth_info.auth_type,
1232 auth_info.auth_level,
1233 pad_len,
1234 1, /* auth_context_id */
1235 &auth_resp,
1236 &auth_blob);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1239 goto err_exit;
1243 /* Now that we have the auth len store it into the right place in
1244 * the dcerpc header */
1245 dcerpc_set_frag_length(&p->out_data.frag,
1246 p->out_data.frag.length +
1247 pad_len + auth_blob.length);
1249 if (auth_resp.length) {
1250 if (pad_len) {
1251 char pad[SERVER_NDR_PADDING_SIZE];
1252 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1253 if (!data_blob_append(p->mem_ctx,
1254 &p->out_data.frag,
1255 pad, pad_len)) {
1256 DEBUG(0, ("api_pipe_bind_req: failed to add "
1257 "%u bytes of pad data.\n",
1258 (unsigned int)pad_len));
1259 goto err_exit;
1263 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1264 auth_blob.data, auth_blob.length)) {
1265 DEBUG(0, ("Append of auth info failed.\n"));
1266 goto err_exit;
1271 * Setup the lengths for the initial reply.
1274 p->out_data.data_sent_length = 0;
1275 p->out_data.current_pdu_sent = 0;
1277 TALLOC_FREE(auth_blob.data);
1278 return True;
1280 err_exit:
1282 data_blob_free(&p->out_data.frag);
1283 TALLOC_FREE(auth_blob.data);
1284 return setup_bind_nak(p, pkt);
1287 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1288 const struct api_struct *api_rpc_cmds, int n_cmds,
1289 const struct ndr_syntax_id *syntax);
1291 /****************************************************************************
1292 Find the correct RPC function to call for this request.
1293 If the pipe is authenticated then become the correct UNIX user
1294 before doing the call.
1295 ****************************************************************************/
1297 static bool api_pipe_request(struct pipes_struct *p,
1298 struct ncacn_packet *pkt)
1300 bool ret = False;
1301 struct pipe_rpc_fns *pipe_fns;
1303 if (!p->pipe_bound) {
1304 DEBUG(1, ("Pipe not bound!\n"));
1305 data_blob_free(&p->out_data.rdata);
1306 return false;
1309 if (!become_authenticated_pipe_user(p->session_info)) {
1310 DEBUG(1, ("Failed to become pipe user!\n"));
1311 data_blob_free(&p->out_data.rdata);
1312 return false;
1315 /* get the set of RPC functions for this context */
1317 pipe_fns = find_pipe_fns_by_context(p->contexts,
1318 pkt->u.request.context_id);
1320 if ( pipe_fns ) {
1321 TALLOC_CTX *frame = talloc_stackframe();
1323 DEBUG(5, ("Requested %s rpc service\n",
1324 get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
1326 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1327 &pipe_fns->syntax);
1329 TALLOC_FREE(frame);
1331 else {
1332 DEBUG(0, ("No rpc function table associated with context "
1333 "[%d]\n",
1334 pkt->u.request.context_id));
1337 unbecome_authenticated_pipe_user();
1339 return ret;
1342 /*******************************************************************
1343 Calls the underlying RPC function for a named pipe.
1344 ********************************************************************/
1346 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1347 const struct api_struct *api_rpc_cmds, int n_cmds,
1348 const struct ndr_syntax_id *syntax)
1350 int fn_num;
1351 uint32_t offset1;
1353 /* interpret the command */
1354 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1355 get_pipe_name_from_syntax(talloc_tos(), syntax),
1356 pkt->u.request.opnum));
1358 if (DEBUGLEVEL >= 50) {
1359 fstring name;
1360 slprintf(name, sizeof(name)-1, "in_%s",
1361 get_pipe_name_from_syntax(talloc_tos(), syntax));
1362 dump_pdu_region(name, pkt->u.request.opnum,
1363 &p->in_data.data, 0,
1364 p->in_data.data.length);
1367 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1368 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1369 api_rpc_cmds[fn_num].fn != NULL) {
1370 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1371 api_rpc_cmds[fn_num].name));
1372 break;
1376 if (fn_num == n_cmds) {
1378 * For an unknown RPC just return a fault PDU but
1379 * return True to allow RPC's on the pipe to continue
1380 * and not put the pipe into fault state. JRA.
1382 DEBUG(4, ("unknown\n"));
1383 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1384 return True;
1387 offset1 = p->out_data.rdata.length;
1389 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1390 fn_num, api_rpc_cmds[fn_num].fn));
1391 /* do the actual command */
1392 if(!api_rpc_cmds[fn_num].fn(p)) {
1393 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1394 get_pipe_name_from_syntax(talloc_tos(), syntax),
1395 api_rpc_cmds[fn_num].name));
1396 data_blob_free(&p->out_data.rdata);
1397 return False;
1400 if (p->fault_state) {
1401 DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
1402 setup_fault_pdu(p, NT_STATUS(p->fault_state));
1403 p->fault_state = 0;
1404 return true;
1407 if (DEBUGLEVEL >= 50) {
1408 fstring name;
1409 slprintf(name, sizeof(name)-1, "out_%s",
1410 get_pipe_name_from_syntax(talloc_tos(), syntax));
1411 dump_pdu_region(name, pkt->u.request.opnum,
1412 &p->out_data.rdata, offset1,
1413 p->out_data.rdata.length);
1416 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1417 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1419 /* Check for buffer underflow in rpc parsing */
1420 if ((DEBUGLEVEL >= 10) &&
1421 (pkt->frag_length < p->in_data.data.length)) {
1422 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1423 dump_data(10, p->in_data.data.data + pkt->frag_length,
1424 p->in_data.data.length - pkt->frag_length);
1427 return True;
1430 /****************************************************************************
1431 Initialise an outgoing packet.
1432 ****************************************************************************/
1434 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1436 output_data *o_data = &p->out_data;
1438 /* Reset the offset counters. */
1439 o_data->data_sent_length = 0;
1440 o_data->current_pdu_sent = 0;
1442 data_blob_free(&o_data->frag);
1444 /* Free any memory in the current return data buffer. */
1445 data_blob_free(&o_data->rdata);
1447 return True;
1450 /****************************************************************************
1451 Sets the fault state on incoming packets.
1452 ****************************************************************************/
1454 void set_incoming_fault(struct pipes_struct *p)
1456 data_blob_free(&p->in_data.data);
1457 p->in_data.pdu_needed_len = 0;
1458 p->in_data.pdu.length = 0;
1459 p->fault_state = DCERPC_FAULT_CANT_PERFORM;
1461 DEBUG(10, ("Setting fault state\n"));
1464 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1465 struct ncacn_packet *pkt,
1466 DATA_BLOB *raw_pkt)
1468 NTSTATUS status;
1469 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1470 size_t pad_len;
1472 DEBUG(10, ("Checking request auth.\n"));
1474 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1475 hdr_size += 16;
1478 /* in case of sealing this function will unseal the data in place */
1479 status = dcerpc_check_auth(auth, pkt,
1480 &pkt->u.request.stub_and_verifier,
1481 hdr_size, raw_pkt,
1482 &pad_len);
1483 if (!NT_STATUS_IS_OK(status)) {
1484 return status;
1488 /* remove padding and auth trailer,
1489 * this way the caller will get just the data */
1490 if (pkt->auth_length) {
1491 size_t trail_len = pad_len
1492 + DCERPC_AUTH_TRAILER_LENGTH
1493 + pkt->auth_length;
1494 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1495 return NT_STATUS_INFO_LENGTH_MISMATCH;
1497 pkt->u.request.stub_and_verifier.length -= trail_len;
1500 return NT_STATUS_OK;
1503 /****************************************************************************
1504 Processes a request pdu. This will do auth processing if needed, and
1505 appends the data into the complete stream if the LAST flag is not set.
1506 ****************************************************************************/
1508 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1510 NTSTATUS status;
1511 DATA_BLOB data;
1513 if (!p->pipe_bound) {
1514 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1515 set_incoming_fault(p);
1516 return False;
1519 /* Store the opnum */
1520 p->opnum = pkt->u.request.opnum;
1522 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1525 nt_errstr(status)));
1526 set_incoming_fault(p);
1527 return false;
1530 data = pkt->u.request.stub_and_verifier;
1533 * Check the data length doesn't go over the 15Mb limit.
1534 * increased after observing a bug in the Windows NT 4.0 SP6a
1535 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1536 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1539 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1540 DEBUG(0, ("process_request_pdu: "
1541 "rpc data buffer too large (%u) + (%u)\n",
1542 (unsigned int)p->in_data.data.length,
1543 (unsigned int)data.length));
1544 set_incoming_fault(p);
1545 return False;
1549 * Append the data portion into the buffer and return.
1552 if (data.length) {
1553 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1554 data.data, data.length)) {
1555 DEBUG(0, ("Unable to append data size %u "
1556 "to parse buffer of size %u.\n",
1557 (unsigned int)data.length,
1558 (unsigned int)p->in_data.data.length));
1559 set_incoming_fault(p);
1560 return False;
1564 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1565 bool ret = False;
1567 * Ok - we finally have a complete RPC stream.
1568 * Call the rpc command to process it.
1572 * Process the complete data stream here.
1574 if (pipe_init_outgoing_data(p)) {
1575 ret = api_pipe_request(p, pkt);
1578 return ret;
1581 return True;
1584 /****************************************************************************
1585 Processes a finished PDU stored in p->in_data.pdu.
1586 ****************************************************************************/
1588 void process_complete_pdu(struct pipes_struct *p)
1590 struct ncacn_packet *pkt = NULL;
1591 NTSTATUS status;
1592 bool reply = False;
1594 if(p->fault_state) {
1595 DEBUG(10,("RPC connection in fault state.\n"));
1596 goto done;
1599 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1600 if (!pkt) {
1601 DEBUG(0, ("Out of memory!\n"));
1602 goto done;
1606 * Ensure we're using the corrent endianness for both the
1607 * RPC header flags and the raw data we will be reading from.
1609 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1610 p->endian = RPC_LITTLE_ENDIAN;
1611 } else {
1612 p->endian = RPC_BIG_ENDIAN;
1614 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1616 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1617 pkt, p->endian);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1620 nt_errstr(status)));
1621 goto done;
1624 /* Store the call_id */
1625 p->call_id = pkt->call_id;
1627 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1629 switch (pkt->ptype) {
1630 case DCERPC_PKT_REQUEST:
1631 reply = process_request_pdu(p, pkt);
1632 break;
1634 case DCERPC_PKT_PING: /* CL request - ignore... */
1635 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1636 (unsigned int)pkt->ptype));
1637 break;
1639 case DCERPC_PKT_RESPONSE: /* No responses here. */
1640 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1641 break;
1643 case DCERPC_PKT_FAULT:
1644 case DCERPC_PKT_WORKING:
1645 /* CL request - reply to a ping when a call in process. */
1646 case DCERPC_PKT_NOCALL:
1647 /* CL - server reply to a ping call. */
1648 case DCERPC_PKT_REJECT:
1649 case DCERPC_PKT_ACK:
1650 case DCERPC_PKT_CL_CANCEL:
1651 case DCERPC_PKT_FACK:
1652 case DCERPC_PKT_CANCEL_ACK:
1653 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1654 (unsigned int)pkt->ptype));
1655 break;
1657 case DCERPC_PKT_BIND:
1659 * We assume that a pipe bind is only in one pdu.
1661 if (pipe_init_outgoing_data(p)) {
1662 reply = api_pipe_bind_req(p, pkt);
1664 break;
1666 case DCERPC_PKT_BIND_ACK:
1667 case DCERPC_PKT_BIND_NAK:
1668 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1669 "packet type %u received.\n",
1670 (unsigned int)pkt->ptype));
1671 break;
1674 case DCERPC_PKT_ALTER:
1676 * We assume that a pipe bind is only in one pdu.
1678 if (pipe_init_outgoing_data(p)) {
1679 reply = api_pipe_alter_context(p, pkt);
1681 break;
1683 case DCERPC_PKT_ALTER_RESP:
1684 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1685 "Should only be server -> client.\n"));
1686 break;
1688 case DCERPC_PKT_AUTH3:
1690 * The third packet in an auth exchange.
1692 if (pipe_init_outgoing_data(p)) {
1693 reply = api_pipe_bind_auth3(p, pkt);
1695 break;
1697 case DCERPC_PKT_SHUTDOWN:
1698 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1699 "Should only be server -> client.\n"));
1700 break;
1702 case DCERPC_PKT_CO_CANCEL:
1703 /* For now just free all client data and continue
1704 * processing. */
1705 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1706 " Abandoning rpc call.\n"));
1707 /* As we never do asynchronous RPC serving, we can
1708 * never cancel a call (as far as I know).
1709 * If we ever did we'd have to send a cancel_ack reply.
1710 * For now, just free all client data and continue
1711 * processing. */
1712 reply = True;
1713 break;
1715 #if 0
1716 /* Enable this if we're doing async rpc. */
1717 /* We must check the outstanding callid matches. */
1718 if (pipe_init_outgoing_data(p)) {
1719 /* Send a cancel_ack PDU reply. */
1720 /* We should probably check the auth-verifier here. */
1721 reply = setup_cancel_ack_reply(p, pkt);
1723 break;
1724 #endif
1726 case DCERPC_PKT_ORPHANED:
1727 /* We should probably check the auth-verifier here.
1728 * For now just free all client data and continue
1729 * processing. */
1730 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1731 " Abandoning rpc call.\n"));
1732 reply = True;
1733 break;
1735 default:
1736 DEBUG(0, ("process_complete_pdu: "
1737 "Unknown rpc type = %u received.\n",
1738 (unsigned int)pkt->ptype));
1739 break;
1742 done:
1743 if (!reply) {
1744 DEBUG(3,("DCE/RPC fault sent!"));
1745 set_incoming_fault(p);
1746 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1747 TALLOC_FREE(pkt);
1748 } else {
1750 * Reset the lengths. We're ready for a new pdu.
1752 TALLOC_FREE(p->in_data.pdu.data);
1753 p->in_data.pdu_needed_len = 0;
1754 p->in_data.pdu.length = 0;
1757 TALLOC_FREE(pkt);