s3: Fix Coverity ID 242726 Uninitialized scalar variable
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_pipe.c
blob0bc48b1a06809009128e45be4c1202c25306d7ce
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 "rpc_server.h"
38 #include "rpc_dce.h"
39 #include "smbd/smbd.h"
40 #include "auth.h"
41 #include "ntdomain.h"
42 #include "rpc_server/srv_pipe.h"
43 #include "rpc_server/rpc_contexts.h"
44 #include "lib/param/param.h"
46 #undef DBGC_CLASS
47 #define DBGC_CLASS DBGC_RPC_SRV
49 /**
50 * Dump everything from the start of the end up of the provided data
51 * into a file, but only at debug level >= 50
52 **/
53 static void dump_pdu_region(const char *name, int v,
54 DATA_BLOB *data, size_t start, size_t end)
56 int fd, i;
57 char *fname = NULL;
58 ssize_t sz;
60 if (DEBUGLEVEL < 50) return;
62 if (start > data->length || end > data->length || start > end) return;
64 for (i = 1; i < 100; i++) {
65 if (v != -1) {
66 fname = talloc_asprintf(talloc_tos(),
67 "/tmp/%s_%d.%d.prs",
68 name, v, i);
69 } else {
70 fname = talloc_asprintf(talloc_tos(),
71 "/tmp/%s_%d.prs",
72 name, i);
74 if (!fname) {
75 return;
77 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
78 if (fd != -1 || errno != EEXIST) break;
80 if (fd != -1) {
81 sz = write(fd, data->data + start, end - start);
82 i = close(fd);
83 if ((sz != end - start) || (i != 0) ) {
84 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
85 fname, (unsigned long)sz,
86 (unsigned long)end - start, i));
87 } else {
88 DEBUG(0,("created %s\n", fname));
91 TALLOC_FREE(fname);
94 static DATA_BLOB generic_session_key(void)
96 return data_blob_const("SystemLibraryDTC", 16);
99 /*******************************************************************
100 Generate the next PDU to be returned from the data.
101 ********************************************************************/
103 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
104 struct pipe_auth_data *auth,
105 uint32_t call_id,
106 DATA_BLOB *rdata,
107 size_t data_sent_length,
108 DATA_BLOB *frag,
109 size_t *pdu_size)
111 union dcerpc_payload u;
112 uint8_t pfc_flags;
113 size_t data_left;
114 size_t data_to_send;
115 size_t frag_len;
116 size_t pad_len = 0;
117 size_t auth_len = 0;
118 NTSTATUS status;
120 ZERO_STRUCT(u.response);
122 /* Set up rpc packet pfc flags. */
123 if (data_sent_length == 0) {
124 pfc_flags = DCERPC_PFC_FLAG_FIRST;
125 } else {
126 pfc_flags = 0;
129 /* Work out how much we can fit in a single PDU. */
130 data_left = rdata->length - data_sent_length;
132 /* Ensure there really is data left to send. */
133 if (!data_left) {
134 DEBUG(0, ("No data left to send !\n"));
135 return NT_STATUS_BUFFER_TOO_SMALL;
138 status = dcerpc_guess_sizes(auth,
139 DCERPC_RESPONSE_LENGTH,
140 data_left,
141 RPC_MAX_PDU_FRAG_LEN,
142 SERVER_NDR_PADDING_SIZE,
143 &data_to_send, &frag_len,
144 &auth_len, &pad_len);
145 if (!NT_STATUS_IS_OK(status)) {
146 return status;
149 /* Set up the alloc hint. This should be the data left to send. */
150 u.response.alloc_hint = data_left;
152 /* Work out if this PDU will be the last. */
153 if (data_sent_length + data_to_send >= rdata->length) {
154 pfc_flags |= DCERPC_PFC_FLAG_LAST;
157 /* Prepare data to be NDR encoded. */
158 u.response.stub_and_verifier =
159 data_blob_const(rdata->data + data_sent_length, data_to_send);
161 /* Store the packet in the data stream. */
162 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
163 pfc_flags, auth_len, call_id,
164 &u, frag);
165 if (!NT_STATUS_IS_OK(status)) {
166 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
167 return status;
170 if (auth_len) {
171 /* Set the proper length on the pdu, including padding.
172 * Only needed if an auth trailer will be appended. */
173 dcerpc_set_frag_length(frag, frag->length
174 + pad_len
175 + DCERPC_AUTH_TRAILER_LENGTH
176 + auth_len);
179 if (auth_len) {
180 status = dcerpc_add_auth_footer(auth, pad_len, frag);
181 if (!NT_STATUS_IS_OK(status)) {
182 data_blob_free(frag);
183 return status;
187 *pdu_size = data_to_send;
188 return NT_STATUS_OK;
191 /*******************************************************************
192 Generate the next PDU to be returned from the data in p->rdata.
193 ********************************************************************/
195 bool create_next_pdu(struct pipes_struct *p)
197 size_t pdu_size = 0;
198 NTSTATUS status;
201 * If we're in the fault state, keep returning fault PDU's until
202 * the pipe gets closed. JRA.
204 if (p->fault_state) {
205 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
206 return true;
209 status = create_next_packet(p->mem_ctx, &p->auth,
210 p->call_id, &p->out_data.rdata,
211 p->out_data.data_sent_length,
212 &p->out_data.frag, &pdu_size);
213 if (!NT_STATUS_IS_OK(status)) {
214 DEBUG(0, ("Failed to create packet with error %s, "
215 "(auth level %u / type %u)\n",
216 nt_errstr(status),
217 (unsigned int)p->auth.auth_level,
218 (unsigned int)p->auth.auth_type));
219 return false;
222 /* Setup the counts for this PDU. */
223 p->out_data.data_sent_length += pdu_size;
224 p->out_data.current_pdu_sent = 0;
225 return true;
229 static bool pipe_init_outgoing_data(struct pipes_struct *p);
231 /*******************************************************************
232 Marshall a bind_nak pdu.
233 *******************************************************************/
235 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
237 NTSTATUS status;
238 union dcerpc_payload u;
240 /* Free any memory in the current return data buffer. */
241 pipe_init_outgoing_data(p);
244 * Initialize a bind_nak header.
247 ZERO_STRUCT(u);
249 u.bind_nak.reject_reason = 0;
252 * Marshall directly into the outgoing PDU space. We
253 * must do this as we need to set to the bind response
254 * header and are never sending more than one PDU here.
257 status = dcerpc_push_ncacn_packet(p->mem_ctx,
258 DCERPC_PKT_BIND_NAK,
259 DCERPC_PFC_FLAG_FIRST |
260 DCERPC_PFC_FLAG_LAST,
262 pkt->call_id,
264 &p->out_data.frag);
265 if (!NT_STATUS_IS_OK(status)) {
266 return False;
269 p->out_data.data_sent_length = 0;
270 p->out_data.current_pdu_sent = 0;
272 TALLOC_FREE(p->auth.auth_ctx);
273 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
274 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
275 p->pipe_bound = False;
277 return True;
280 /*******************************************************************
281 Marshall a fault pdu.
282 *******************************************************************/
284 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
286 NTSTATUS status;
287 union dcerpc_payload u;
289 /* Free any memory in the current return data buffer. */
290 pipe_init_outgoing_data(p);
293 * Initialize a fault header.
296 ZERO_STRUCT(u);
298 u.fault.status = NT_STATUS_V(fault_status);
299 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
302 * Marshall directly into the outgoing PDU space. We
303 * must do this as we need to set to the bind response
304 * header and are never sending more than one PDU here.
307 status = dcerpc_push_ncacn_packet(p->mem_ctx,
308 DCERPC_PKT_FAULT,
309 DCERPC_PFC_FLAG_FIRST |
310 DCERPC_PFC_FLAG_LAST |
311 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
313 p->call_id,
315 &p->out_data.frag);
316 if (!NT_STATUS_IS_OK(status)) {
317 return False;
320 p->out_data.data_sent_length = 0;
321 p->out_data.current_pdu_sent = 0;
323 return True;
326 /*******************************************************************
327 Ensure a bind request has the correct abstract & transfer interface.
328 Used to reject unknown binds from Win2k.
329 *******************************************************************/
331 static bool check_bind_req(struct pipes_struct *p,
332 struct ndr_syntax_id* abstract,
333 struct ndr_syntax_id* transfer,
334 uint32_t context_id)
336 struct pipe_rpc_fns *context_fns;
337 bool ok;
339 DEBUG(3,("check_bind_req for %s\n",
340 get_pipe_name_from_syntax(talloc_tos(), abstract)));
342 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
343 if (rpc_srv_pipe_exists_by_id(abstract) &&
344 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax_ndr)) {
345 DEBUG(3, ("check_bind_req: %s -> %s rpc service\n",
346 rpc_srv_get_pipe_cli_name(abstract),
347 rpc_srv_get_pipe_srv_name(abstract)));
348 } else {
349 return false;
352 ok = init_pipe_handles(p, abstract);
353 if (!ok) {
354 DEBUG(1, ("Failed to init pipe handles!\n"));
355 return false;
358 context_fns = talloc(p, struct pipe_rpc_fns);
359 if (context_fns == NULL) {
360 DEBUG(0,("check_bind_req: talloc() failed!\n"));
361 return false;
364 context_fns->next = context_fns->prev = NULL;
365 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
366 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
367 context_fns->context_id = context_id;
368 context_fns->syntax = *abstract;
370 /* add to the list of open contexts */
372 DLIST_ADD( p->contexts, context_fns );
374 return True;
378 * Is a named pipe known?
379 * @param[in] cli_filename The pipe name requested by the client
380 * @result Do we want to serve this?
382 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
384 const char *pipename = cli_filename;
385 NTSTATUS status;
387 if (strnequal(pipename, "\\PIPE\\", 6)) {
388 pipename += 5;
391 if (*pipename == '\\') {
392 pipename += 1;
395 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
396 DEBUG(10, ("refusing spoolss access\n"));
397 return false;
400 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
401 return true;
404 status = smb_probe_module("rpc", pipename);
405 if (!NT_STATUS_IS_OK(status)) {
406 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
407 return false;
409 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
412 * Scan the list again for the interface id
414 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
415 return true;
418 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
419 pipename));
421 return false;
424 /*******************************************************************
425 Handle an schannel bind auth.
426 *******************************************************************/
428 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
429 TALLOC_CTX *mem_ctx,
430 struct dcerpc_auth *auth_info,
431 DATA_BLOB *response)
433 struct NL_AUTH_MESSAGE neg;
434 struct NL_AUTH_MESSAGE reply;
435 bool ret;
436 NTSTATUS status;
437 struct netlogon_creds_CredentialState *creds;
438 enum ndr_err_code ndr_err;
439 struct schannel_state *schannel_auth;
440 struct loadparm_context *lp_ctx;
442 ndr_err = ndr_pull_struct_blob(
443 &auth_info->credentials, mem_ctx, &neg,
444 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
445 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
446 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
447 return false;
450 if (DEBUGLEVEL >= 10) {
451 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
454 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
455 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
456 return false;
459 lp_ctx = loadparm_init_s3(p, loadparm_s3_context());
460 if (!lp_ctx) {
461 DEBUG(0,("pipe_schannel_auth_bind: loadparm_init_s3() failed!\n"));
462 return false;
466 * The neg.oem_netbios_computer.a key here must match the remote computer name
467 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
468 * operations that use credentials.
471 become_root();
472 status = schannel_get_creds_state(p, lp_ctx,
473 neg.oem_netbios_computer.a, &creds);
474 unbecome_root();
476 talloc_unlink(p, lp_ctx);
477 if (!NT_STATUS_IS_OK(status)) {
478 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
479 return False;
482 schannel_auth = talloc_zero(p, struct schannel_state);
483 if (!schannel_auth) {
484 TALLOC_FREE(creds);
485 return False;
488 schannel_auth->state = SCHANNEL_STATE_START;
489 schannel_auth->initiator = false;
490 schannel_auth->creds = creds;
493 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
494 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
495 * struct of the person who opened the pipe. I need to test this further. JRA.
497 * VL. As we are mapping this to guest set the generic key
498 * "SystemLibraryDTC" key here. It's a bit difficult to test against
499 * W2k3, as it does not allow schannel binds against SAMR and LSA
500 * anymore.
503 ret = session_info_set_session_key(p->session_info, generic_session_key());
505 if (!ret) {
506 DEBUG(0, ("session_info_set_session_key failed\n"));
507 return false;
510 /*** SCHANNEL verifier ***/
512 reply.MessageType = NL_NEGOTIATE_RESPONSE;
513 reply.Flags = 0;
514 reply.Buffer.dummy = 5; /* ??? actually I don't think
515 * this has any meaning
516 * here - gd */
518 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
519 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
520 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
521 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
522 return false;
525 if (DEBUGLEVEL >= 10) {
526 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
529 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
530 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
532 /* We're finished with this bind - no more packets. */
533 p->auth.auth_ctx = schannel_auth;
534 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
536 p->pipe_bound = True;
538 return True;
541 /*******************************************************************
542 Handle an NTLMSSP bind auth.
543 *******************************************************************/
545 static bool pipe_auth_generic_bind(struct pipes_struct *p,
546 TALLOC_CTX *mem_ctx,
547 struct dcerpc_auth *auth_info,
548 DATA_BLOB *response)
550 struct gensec_security *gensec_security = NULL;
551 NTSTATUS status;
553 status = auth_generic_server_authtype_start(p,
554 auth_info->auth_type,
555 auth_info->auth_level,
556 &auth_info->credentials,
557 response,
558 p->remote_address,
559 &gensec_security);
560 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
561 DEBUG(0, (__location__ ": auth_generic_server_authtype_start failed: %s\n",
562 nt_errstr(status)));
563 return false;
566 /* Make sure data is bound to the memctx, to be freed the caller */
567 talloc_steal(mem_ctx, response->data);
569 p->auth.auth_ctx = gensec_security;
570 p->auth.auth_type = auth_info->auth_type;
572 return true;
575 /*******************************************************************
576 Process an NTLMSSP authentication response.
577 If this function succeeds, the user has been authenticated
578 and their domain, name and calling workstation stored in
579 the pipe struct.
580 *******************************************************************/
582 static bool pipe_auth_generic_verify_final(TALLOC_CTX *mem_ctx,
583 struct gensec_security *gensec_security,
584 enum dcerpc_AuthLevel auth_level,
585 struct auth_session_info **session_info)
587 NTSTATUS status;
588 bool ret;
590 DEBUG(5, (__location__ ": checking user details\n"));
592 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
593 ensure the underlying NTLMSSP flags are also set. If not we should
594 refuse the bind. */
596 status = auth_generic_server_check_flags(gensec_security,
597 (auth_level ==
598 DCERPC_AUTH_LEVEL_INTEGRITY),
599 (auth_level ==
600 DCERPC_AUTH_LEVEL_PRIVACY));
601 if (!NT_STATUS_IS_OK(status)) {
602 DEBUG(0, (__location__ ": Client failed to negotatie proper "
603 "security for rpc connection\n"));
604 return false;
607 TALLOC_FREE(*session_info);
609 status = auth_generic_server_get_user_info(gensec_security,
610 mem_ctx, session_info);
611 if (!NT_STATUS_IS_OK(status)) {
612 DEBUG(0, (__location__ ": failed to obtain the server info "
613 "for authenticated user: %s\n", nt_errstr(status)));
614 return false;
617 if ((*session_info)->security_token == NULL) {
618 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
619 return false;
623 * We're an authenticated bind over smb, so the session key needs to
624 * be set to "SystemLibraryDTC". Weird, but this is what Windows
625 * does. See the RPC-SAMBA3SESSIONKEY.
628 ret = session_info_set_session_key((*session_info), generic_session_key());
629 if (!ret) {
630 DEBUG(0, ("Failed to set session key!\n"));
631 return false;
634 return true;
637 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
639 struct gensec_security *gensec_security;
641 switch (p->auth.auth_type) {
642 case DCERPC_AUTH_TYPE_NTLMSSP:
643 case DCERPC_AUTH_TYPE_KRB5:
644 case DCERPC_AUTH_TYPE_SPNEGO:
645 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
646 struct gensec_security);
647 if (!pipe_auth_generic_verify_final(p, gensec_security,
648 p->auth.auth_level,
649 &p->session_info)) {
650 return NT_STATUS_ACCESS_DENIED;
652 break;
653 default:
654 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
655 (unsigned int)p->auth.auth_type));
656 return NT_STATUS_ACCESS_DENIED;
659 p->pipe_bound = true;
661 return NT_STATUS_OK;
664 /*******************************************************************
665 Respond to a pipe bind request.
666 *******************************************************************/
668 static bool api_pipe_bind_req(struct pipes_struct *p,
669 struct ncacn_packet *pkt)
671 struct dcerpc_auth auth_info;
672 uint16 assoc_gid;
673 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
674 NTSTATUS status;
675 struct ndr_syntax_id id;
676 union dcerpc_payload u;
677 struct dcerpc_ack_ctx bind_ack_ctx;
678 DATA_BLOB auth_resp = data_blob_null;
679 DATA_BLOB auth_blob = data_blob_null;
681 /* No rebinds on a bound pipe - use alter context. */
682 if (p->pipe_bound) {
683 DEBUG(2,("Rejecting bind request on bound rpc connection\n"));
684 return setup_bind_nak(p, pkt);
687 if (pkt->u.bind.num_contexts == 0) {
688 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
689 goto err_exit;
693 * Try and find the correct pipe name to ensure
694 * that this is a pipe name we support.
696 id = pkt->u.bind.ctx_list[0].abstract_syntax;
697 if (rpc_srv_pipe_exists_by_id(&id)) {
698 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
699 rpc_srv_get_pipe_cli_name(&id),
700 rpc_srv_get_pipe_srv_name(&id)));
701 } else {
702 status = smb_probe_module(
703 "rpc", get_pipe_name_from_syntax(
704 talloc_tos(),
705 &id));
707 if (NT_STATUS_IS_ERR(status)) {
708 DEBUG(3,("api_pipe_bind_req: Unknown rpc service name "
709 "%s in bind request.\n",
710 get_pipe_name_from_syntax(talloc_tos(), &id)));
712 return setup_bind_nak(p, pkt);
715 if (rpc_srv_get_pipe_interface_by_cli_name(
716 get_pipe_name_from_syntax(talloc_tos(),
717 &id),
718 &id)) {
719 DEBUG(3, ("api_pipe_bind_req: %s -> %s rpc service\n",
720 rpc_srv_get_pipe_cli_name(&id),
721 rpc_srv_get_pipe_srv_name(&id)));
722 } else {
723 DEBUG(0, ("module %s doesn't provide functions for "
724 "pipe %s!\n",
725 get_pipe_name_from_syntax(talloc_tos(), &id),
726 get_pipe_name_from_syntax(talloc_tos(), &id)));
727 return setup_bind_nak(p, pkt);
731 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
733 if (pkt->u.bind.assoc_group_id != 0) {
734 assoc_gid = pkt->u.bind.assoc_group_id;
735 } else {
736 assoc_gid = 0x53f0;
740 * Create the bind response struct.
743 /* If the requested abstract synt uuid doesn't match our client pipe,
744 reject the bind_ack & set the transfer interface synt to all 0's,
745 ver 0 (observed when NT5 attempts to bind to abstract interfaces
746 unknown to NT4)
747 Needed when adding entries to a DACL from NT5 - SK */
749 if (check_bind_req(p,
750 &pkt->u.bind.ctx_list[0].abstract_syntax,
751 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
752 pkt->u.bind.ctx_list[0].context_id)) {
754 bind_ack_ctx.result = 0;
755 bind_ack_ctx.reason = 0;
756 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
757 } else {
758 p->pipe_bound = False;
759 /* Rejection reason: abstract syntax not supported */
760 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
761 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
762 bind_ack_ctx.syntax = ndr_syntax_id_null;
766 * Check if this is an authenticated bind request.
768 if (pkt->auth_length) {
769 /* Quick length check. Won't catch a bad auth footer,
770 * prevents overrun. */
772 if (pkt->frag_length < RPC_HEADER_LEN +
773 DCERPC_AUTH_TRAILER_LENGTH +
774 pkt->auth_length) {
775 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
776 "too long for fragment %u.\n",
777 (unsigned int)pkt->auth_length,
778 (unsigned int)pkt->frag_length));
779 goto err_exit;
783 * Decode the authentication verifier.
785 status = dcerpc_pull_dcerpc_auth(pkt,
786 &pkt->u.bind.auth_info,
787 &auth_info, p->endian);
788 if (!NT_STATUS_IS_OK(status)) {
789 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
790 goto err_exit;
793 auth_type = auth_info.auth_type;
795 /* Work out if we have to sign or seal etc. */
796 switch (auth_info.auth_level) {
797 case DCERPC_AUTH_LEVEL_INTEGRITY:
798 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
799 break;
800 case DCERPC_AUTH_LEVEL_PRIVACY:
801 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
802 break;
803 case DCERPC_AUTH_LEVEL_CONNECT:
804 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
805 break;
806 default:
807 DEBUG(0, ("Unexpected auth level (%u).\n",
808 (unsigned int)auth_info.auth_level ));
809 goto err_exit;
812 switch (auth_type) {
813 case DCERPC_AUTH_TYPE_NTLMSSP:
814 if (!pipe_auth_generic_bind(p, pkt,
815 &auth_info, &auth_resp)) {
816 goto err_exit;
818 assoc_gid = 0x7a77;
819 break;
821 case DCERPC_AUTH_TYPE_SCHANNEL:
822 if (!pipe_schannel_auth_bind(p, pkt,
823 &auth_info, &auth_resp)) {
824 goto err_exit;
826 break;
828 case DCERPC_AUTH_TYPE_SPNEGO:
829 case DCERPC_AUTH_TYPE_KRB5:
830 if (!pipe_auth_generic_bind(p, pkt,
831 &auth_info, &auth_resp)) {
832 goto err_exit;
834 break;
836 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
837 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
838 TALLOC_FREE(p->session_info);
840 status = make_session_info_system(p,
841 &p->session_info);
842 if (!NT_STATUS_IS_OK(status)) {
843 goto err_exit;
846 auth_resp = data_blob_talloc(pkt,
847 "NCALRPC_AUTH_OK",
848 15);
850 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
851 p->pipe_bound = true;
852 } else {
853 goto err_exit;
855 break;
857 case DCERPC_AUTH_TYPE_NONE:
858 break;
860 default:
861 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
862 goto err_exit;
866 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
867 /* Unauthenticated bind request. */
868 /* We're finished - no more packets. */
869 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
870 /* We must set the pipe auth_level here also. */
871 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
872 p->pipe_bound = True;
873 /* The session key was initialized from the SMB
874 * session in make_internal_rpc_pipe_p */
877 ZERO_STRUCT(u.bind_ack);
878 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
879 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
880 u.bind_ack.assoc_group_id = assoc_gid;
882 /* name has to be \PIPE\xxxxx */
883 u.bind_ack.secondary_address =
884 talloc_asprintf(pkt, "\\PIPE\\%s",
885 rpc_srv_get_pipe_srv_name(&id));
886 if (!u.bind_ack.secondary_address) {
887 DEBUG(0, ("Out of memory!\n"));
888 goto err_exit;
890 u.bind_ack.secondary_address_size =
891 strlen(u.bind_ack.secondary_address) + 1;
893 u.bind_ack.num_results = 1;
894 u.bind_ack.ctx_list = &bind_ack_ctx;
896 /* NOTE: We leave the auth_info empty so we can calculate the padding
897 * later and then append the auth_info --simo */
900 * Marshall directly into the outgoing PDU space. We
901 * must do this as we need to set to the bind response
902 * header and are never sending more than one PDU here.
905 status = dcerpc_push_ncacn_packet(p->mem_ctx,
906 DCERPC_PKT_BIND_ACK,
907 DCERPC_PFC_FLAG_FIRST |
908 DCERPC_PFC_FLAG_LAST,
909 auth_resp.length,
910 pkt->call_id,
912 &p->out_data.frag);
913 if (!NT_STATUS_IS_OK(status)) {
914 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
915 nt_errstr(status)));
918 if (auth_resp.length) {
920 status = dcerpc_push_dcerpc_auth(pkt,
921 auth_type,
922 auth_info.auth_level,
924 1, /* auth_context_id */
925 &auth_resp,
926 &auth_blob);
927 if (!NT_STATUS_IS_OK(status)) {
928 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
929 goto err_exit;
933 /* Now that we have the auth len store it into the right place in
934 * the dcerpc header */
935 dcerpc_set_frag_length(&p->out_data.frag,
936 p->out_data.frag.length + auth_blob.length);
938 if (auth_blob.length) {
940 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
941 auth_blob.data, auth_blob.length)) {
942 DEBUG(0, ("Append of auth info failed.\n"));
943 goto err_exit;
948 * Setup the lengths for the initial reply.
951 p->out_data.data_sent_length = 0;
952 p->out_data.current_pdu_sent = 0;
954 TALLOC_FREE(auth_blob.data);
955 return True;
957 err_exit:
959 data_blob_free(&p->out_data.frag);
960 TALLOC_FREE(auth_blob.data);
961 return setup_bind_nak(p, pkt);
964 /*******************************************************************
965 This is the "stage3" response after a bind request and reply.
966 *******************************************************************/
968 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
970 struct dcerpc_auth auth_info;
971 DATA_BLOB response = data_blob_null;
972 struct gensec_security *gensec_security;
973 NTSTATUS status;
975 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
977 if (pkt->auth_length == 0) {
978 DEBUG(0, ("No auth field sent for bind request!\n"));
979 goto err;
982 /* Ensure there's enough data for an authenticated request. */
983 if (pkt->frag_length < RPC_HEADER_LEN
984 + DCERPC_AUTH_TRAILER_LENGTH
985 + pkt->auth_length) {
986 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
987 "%u is too large.\n",
988 (unsigned int)pkt->auth_length));
989 goto err;
993 * Decode the authentication verifier response.
996 status = dcerpc_pull_dcerpc_auth(pkt,
997 &pkt->u.auth3.auth_info,
998 &auth_info, p->endian);
999 if (!NT_STATUS_IS_OK(status)) {
1000 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1001 goto err;
1004 /* We must NEVER look at auth_info->auth_pad_len here,
1005 * as old Samba client code gets it wrong and sends it
1006 * as zero. JRA.
1009 if (auth_info.auth_type != p->auth.auth_type) {
1010 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1011 "but auth was started as type %d!\n",
1012 auth_info.auth_type, p->auth.auth_type));
1013 goto err;
1016 switch (auth_info.auth_type) {
1017 case DCERPC_AUTH_TYPE_NTLMSSP:
1018 case DCERPC_AUTH_TYPE_KRB5:
1019 case DCERPC_AUTH_TYPE_SPNEGO:
1020 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1021 struct gensec_security);
1022 status = auth_generic_server_step(gensec_security,
1023 pkt, &auth_info.credentials,
1024 &response);
1025 break;
1026 default:
1027 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1028 (unsigned int)auth_info.auth_type));
1029 return false;
1032 if (NT_STATUS_EQUAL(status,
1033 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1034 response.length) {
1035 DEBUG(0, (__location__ ": This was supposed to be the final "
1036 "leg, but crypto machinery claims a response is "
1037 "needed, aborting auth!\n"));
1038 data_blob_free(&response);
1039 goto err;
1041 if (!NT_STATUS_IS_OK(status)) {
1042 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1043 goto err;
1046 /* Now verify auth was indeed successful and extract server info */
1047 status = pipe_auth_verify_final(p);
1048 if (!NT_STATUS_IS_OK(status)) {
1049 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1050 goto err;
1053 return true;
1055 err:
1057 TALLOC_FREE(p->auth.auth_ctx);
1058 return false;
1061 /****************************************************************************
1062 Deal with an alter context call. Can be third part of 3 leg auth request for
1063 SPNEGO calls.
1064 ****************************************************************************/
1066 static bool api_pipe_alter_context(struct pipes_struct *p,
1067 struct ncacn_packet *pkt)
1069 struct dcerpc_auth auth_info;
1070 uint16 assoc_gid;
1071 NTSTATUS status;
1072 union dcerpc_payload u;
1073 struct dcerpc_ack_ctx bind_ack_ctx;
1074 DATA_BLOB auth_resp = data_blob_null;
1075 DATA_BLOB auth_blob = data_blob_null;
1076 int pad_len = 0;
1077 struct gensec_security *gensec_security;
1079 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1081 if (pkt->u.bind.assoc_group_id != 0) {
1082 assoc_gid = pkt->u.bind.assoc_group_id;
1083 } else {
1084 assoc_gid = 0x53f0;
1088 * Create the bind response struct.
1091 /* If the requested abstract synt uuid doesn't match our client pipe,
1092 reject the bind_ack & set the transfer interface synt to all 0's,
1093 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1094 unknown to NT4)
1095 Needed when adding entries to a DACL from NT5 - SK */
1097 if (check_bind_req(p,
1098 &pkt->u.bind.ctx_list[0].abstract_syntax,
1099 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1100 pkt->u.bind.ctx_list[0].context_id)) {
1102 bind_ack_ctx.result = 0;
1103 bind_ack_ctx.reason = 0;
1104 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1105 } else {
1106 p->pipe_bound = False;
1107 /* Rejection reason: abstract syntax not supported */
1108 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1109 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1110 bind_ack_ctx.syntax = ndr_syntax_id_null;
1114 * Check if this is an authenticated alter context request.
1116 if (pkt->auth_length) {
1117 /* Quick length check. Won't catch a bad auth footer,
1118 * prevents overrun. */
1120 if (pkt->frag_length < RPC_HEADER_LEN +
1121 DCERPC_AUTH_TRAILER_LENGTH +
1122 pkt->auth_length) {
1123 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1124 "too long for fragment %u.\n",
1125 (unsigned int)pkt->auth_length,
1126 (unsigned int)pkt->frag_length ));
1127 goto err_exit;
1130 status = dcerpc_pull_dcerpc_auth(pkt,
1131 &pkt->u.bind.auth_info,
1132 &auth_info, p->endian);
1133 if (!NT_STATUS_IS_OK(status)) {
1134 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1135 goto err_exit;
1138 /* We can only finish if the pipe is unbound for now */
1139 if (p->pipe_bound) {
1140 DEBUG(0, (__location__ ": Pipe already bound, "
1141 "Altering Context not yet supported!\n"));
1142 goto err_exit;
1145 if (auth_info.auth_type != p->auth.auth_type) {
1146 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1147 "but auth was started as type %d!\n",
1148 auth_info.auth_type, p->auth.auth_type));
1149 goto err_exit;
1153 switch (auth_info.auth_type) {
1154 case DCERPC_AUTH_TYPE_SPNEGO:
1155 case DCERPC_AUTH_TYPE_KRB5:
1156 case DCERPC_AUTH_TYPE_NTLMSSP:
1157 gensec_security = talloc_get_type_abort(p->auth.auth_ctx,
1158 struct gensec_security);
1159 status = auth_generic_server_step(gensec_security,
1160 pkt,
1161 &auth_info.credentials,
1162 &auth_resp);
1163 break;
1165 default:
1166 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1167 "in alter-context call\n",
1168 auth_info.auth_type));
1169 goto err_exit;
1172 if (NT_STATUS_IS_OK(status)) {
1173 /* third leg of auth, verify auth info */
1174 status = pipe_auth_verify_final(p);
1175 if (!NT_STATUS_IS_OK(status)) {
1176 DEBUG(0, ("Auth Verify failed (%s)\n",
1177 nt_errstr(status)));
1178 goto err_exit;
1180 } else if (NT_STATUS_EQUAL(status,
1181 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1182 DEBUG(10, ("More auth legs required.\n"));
1183 } else {
1184 DEBUG(0, ("Auth step returned an error (%s)\n",
1185 nt_errstr(status)));
1186 goto err_exit;
1190 ZERO_STRUCT(u.alter_resp);
1191 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1192 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1193 u.alter_resp.assoc_group_id = assoc_gid;
1195 /* secondary address CAN be NULL
1196 * as the specs say it's ignored.
1197 * It MUST be NULL to have the spoolss working.
1199 u.alter_resp.secondary_address = "";
1200 u.alter_resp.secondary_address_size = 1;
1202 u.alter_resp.num_results = 1;
1203 u.alter_resp.ctx_list = &bind_ack_ctx;
1205 /* NOTE: We leave the auth_info empty so we can calculate the padding
1206 * later and then append the auth_info --simo */
1209 * Marshall directly into the outgoing PDU space. We
1210 * must do this as we need to set to the bind response
1211 * header and are never sending more than one PDU here.
1214 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1215 DCERPC_PKT_ALTER_RESP,
1216 DCERPC_PFC_FLAG_FIRST |
1217 DCERPC_PFC_FLAG_LAST,
1218 auth_resp.length,
1219 pkt->call_id,
1221 &p->out_data.frag);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1224 nt_errstr(status)));
1227 if (auth_resp.length) {
1229 /* Work out any padding needed before the auth footer. */
1230 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1231 if (pad_len) {
1232 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1233 DEBUG(10, ("auth pad_len = %u\n",
1234 (unsigned int)pad_len));
1237 status = dcerpc_push_dcerpc_auth(pkt,
1238 auth_info.auth_type,
1239 auth_info.auth_level,
1240 pad_len,
1241 1, /* auth_context_id */
1242 &auth_resp,
1243 &auth_blob);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1246 goto err_exit;
1250 /* Now that we have the auth len store it into the right place in
1251 * the dcerpc header */
1252 dcerpc_set_frag_length(&p->out_data.frag,
1253 p->out_data.frag.length +
1254 pad_len + auth_blob.length);
1256 if (auth_resp.length) {
1257 if (pad_len) {
1258 char pad[SERVER_NDR_PADDING_SIZE];
1259 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1260 if (!data_blob_append(p->mem_ctx,
1261 &p->out_data.frag,
1262 pad, pad_len)) {
1263 DEBUG(0, ("api_pipe_bind_req: failed to add "
1264 "%u bytes of pad data.\n",
1265 (unsigned int)pad_len));
1266 goto err_exit;
1270 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1271 auth_blob.data, auth_blob.length)) {
1272 DEBUG(0, ("Append of auth info failed.\n"));
1273 goto err_exit;
1278 * Setup the lengths for the initial reply.
1281 p->out_data.data_sent_length = 0;
1282 p->out_data.current_pdu_sent = 0;
1284 TALLOC_FREE(auth_blob.data);
1285 return True;
1287 err_exit:
1289 data_blob_free(&p->out_data.frag);
1290 TALLOC_FREE(auth_blob.data);
1291 return setup_bind_nak(p, pkt);
1294 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1295 const struct api_struct *api_rpc_cmds, int n_cmds,
1296 const struct ndr_syntax_id *syntax);
1298 /****************************************************************************
1299 Find the correct RPC function to call for this request.
1300 If the pipe is authenticated then become the correct UNIX user
1301 before doing the call.
1302 ****************************************************************************/
1304 static bool api_pipe_request(struct pipes_struct *p,
1305 struct ncacn_packet *pkt)
1307 bool ret = False;
1308 struct pipe_rpc_fns *pipe_fns;
1310 if (!p->pipe_bound) {
1311 DEBUG(1, ("Pipe not bound!\n"));
1312 data_blob_free(&p->out_data.rdata);
1313 return false;
1316 if (!become_authenticated_pipe_user(p->session_info)) {
1317 DEBUG(1, ("Failed to become pipe user!\n"));
1318 data_blob_free(&p->out_data.rdata);
1319 return false;
1322 /* get the set of RPC functions for this context */
1324 pipe_fns = find_pipe_fns_by_context(p->contexts,
1325 pkt->u.request.context_id);
1327 if ( pipe_fns ) {
1328 TALLOC_CTX *frame = talloc_stackframe();
1330 DEBUG(5, ("Requested %s rpc service\n",
1331 get_pipe_name_from_syntax(talloc_tos(), &pipe_fns->syntax)));
1333 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
1334 &pipe_fns->syntax);
1336 TALLOC_FREE(frame);
1338 else {
1339 DEBUG(0, ("No rpc function table associated with context "
1340 "[%d]\n",
1341 pkt->u.request.context_id));
1344 unbecome_authenticated_pipe_user();
1346 return ret;
1349 /*******************************************************************
1350 Calls the underlying RPC function for a named pipe.
1351 ********************************************************************/
1353 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1354 const struct api_struct *api_rpc_cmds, int n_cmds,
1355 const struct ndr_syntax_id *syntax)
1357 int fn_num;
1358 uint32_t offset1;
1360 /* interpret the command */
1361 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1362 get_pipe_name_from_syntax(talloc_tos(), syntax),
1363 pkt->u.request.opnum));
1365 if (DEBUGLEVEL >= 50) {
1366 fstring name;
1367 slprintf(name, sizeof(name)-1, "in_%s",
1368 get_pipe_name_from_syntax(talloc_tos(), syntax));
1369 dump_pdu_region(name, pkt->u.request.opnum,
1370 &p->in_data.data, 0,
1371 p->in_data.data.length);
1374 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1375 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1376 api_rpc_cmds[fn_num].fn != NULL) {
1377 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1378 api_rpc_cmds[fn_num].name));
1379 break;
1383 if (fn_num == n_cmds) {
1385 * For an unknown RPC just return a fault PDU but
1386 * return True to allow RPC's on the pipe to continue
1387 * and not put the pipe into fault state. JRA.
1389 DEBUG(4, ("unknown\n"));
1390 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1391 return True;
1394 offset1 = p->out_data.rdata.length;
1396 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1397 fn_num, api_rpc_cmds[fn_num].fn));
1398 /* do the actual command */
1399 if(!api_rpc_cmds[fn_num].fn(p)) {
1400 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1401 get_pipe_name_from_syntax(talloc_tos(), syntax),
1402 api_rpc_cmds[fn_num].name));
1403 data_blob_free(&p->out_data.rdata);
1404 return False;
1407 if (p->bad_handle_fault_state) {
1408 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1409 p->bad_handle_fault_state = False;
1410 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1411 return True;
1414 if (p->rng_fault_state) {
1415 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1416 p->rng_fault_state = False;
1417 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1418 return True;
1421 if (DEBUGLEVEL >= 50) {
1422 fstring name;
1423 slprintf(name, sizeof(name)-1, "out_%s",
1424 get_pipe_name_from_syntax(talloc_tos(), syntax));
1425 dump_pdu_region(name, pkt->u.request.opnum,
1426 &p->out_data.rdata, offset1,
1427 p->out_data.rdata.length);
1430 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1431 get_pipe_name_from_syntax(talloc_tos(), syntax)));
1433 /* Check for buffer underflow in rpc parsing */
1434 if ((DEBUGLEVEL >= 10) &&
1435 (pkt->frag_length < p->in_data.data.length)) {
1436 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1437 dump_data(10, p->in_data.data.data + pkt->frag_length,
1438 p->in_data.data.length - pkt->frag_length);
1441 return True;
1444 /****************************************************************************
1445 Initialise an outgoing packet.
1446 ****************************************************************************/
1448 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1450 output_data *o_data = &p->out_data;
1452 /* Reset the offset counters. */
1453 o_data->data_sent_length = 0;
1454 o_data->current_pdu_sent = 0;
1456 data_blob_free(&o_data->frag);
1458 /* Free any memory in the current return data buffer. */
1459 data_blob_free(&o_data->rdata);
1461 return True;
1464 /****************************************************************************
1465 Sets the fault state on incoming packets.
1466 ****************************************************************************/
1468 void set_incoming_fault(struct pipes_struct *p)
1470 data_blob_free(&p->in_data.data);
1471 p->in_data.pdu_needed_len = 0;
1472 p->in_data.pdu.length = 0;
1473 p->fault_state = True;
1475 DEBUG(10, ("Setting fault state\n"));
1478 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1479 struct ncacn_packet *pkt,
1480 DATA_BLOB *raw_pkt)
1482 NTSTATUS status;
1483 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1484 size_t pad_len;
1486 DEBUG(10, ("Checking request auth.\n"));
1488 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1489 hdr_size += 16;
1492 /* in case of sealing this function will unseal the data in place */
1493 status = dcerpc_check_auth(auth, pkt,
1494 &pkt->u.request.stub_and_verifier,
1495 hdr_size, raw_pkt,
1496 &pad_len);
1497 if (!NT_STATUS_IS_OK(status)) {
1498 return status;
1502 /* remove padding and auth trailer,
1503 * this way the caller will get just the data */
1504 if (pkt->auth_length) {
1505 size_t trail_len = pad_len
1506 + DCERPC_AUTH_TRAILER_LENGTH
1507 + pkt->auth_length;
1508 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1509 return NT_STATUS_INFO_LENGTH_MISMATCH;
1511 pkt->u.request.stub_and_verifier.length -= trail_len;
1514 return NT_STATUS_OK;
1517 /****************************************************************************
1518 Processes a request pdu. This will do auth processing if needed, and
1519 appends the data into the complete stream if the LAST flag is not set.
1520 ****************************************************************************/
1522 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1524 NTSTATUS status;
1525 DATA_BLOB data;
1527 if (!p->pipe_bound) {
1528 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1529 set_incoming_fault(p);
1530 return False;
1533 /* Store the opnum */
1534 p->opnum = pkt->u.request.opnum;
1536 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1537 if (!NT_STATUS_IS_OK(status)) {
1538 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1539 nt_errstr(status)));
1540 set_incoming_fault(p);
1541 return false;
1544 data = pkt->u.request.stub_and_verifier;
1547 * Check the data length doesn't go over the 15Mb limit.
1548 * increased after observing a bug in the Windows NT 4.0 SP6a
1549 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1550 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1553 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1554 DEBUG(0, ("process_request_pdu: "
1555 "rpc data buffer too large (%u) + (%u)\n",
1556 (unsigned int)p->in_data.data.length,
1557 (unsigned int)data.length));
1558 set_incoming_fault(p);
1559 return False;
1563 * Append the data portion into the buffer and return.
1566 if (data.length) {
1567 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1568 data.data, data.length)) {
1569 DEBUG(0, ("Unable to append data size %u "
1570 "to parse buffer of size %u.\n",
1571 (unsigned int)data.length,
1572 (unsigned int)p->in_data.data.length));
1573 set_incoming_fault(p);
1574 return False;
1578 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1579 bool ret = False;
1581 * Ok - we finally have a complete RPC stream.
1582 * Call the rpc command to process it.
1586 * Process the complete data stream here.
1588 if (pipe_init_outgoing_data(p)) {
1589 ret = api_pipe_request(p, pkt);
1592 return ret;
1595 return True;
1598 /****************************************************************************
1599 Processes a finished PDU stored in p->in_data.pdu.
1600 ****************************************************************************/
1602 void process_complete_pdu(struct pipes_struct *p)
1604 struct ncacn_packet *pkt = NULL;
1605 NTSTATUS status;
1606 bool reply = False;
1608 if(p->fault_state) {
1609 DEBUG(10,("RPC connection in fault state.\n"));
1610 goto done;
1613 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1614 if (!pkt) {
1615 DEBUG(0, ("Out of memory!\n"));
1616 goto done;
1620 * Ensure we're using the corrent endianness for both the
1621 * RPC header flags and the raw data we will be reading from.
1623 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1624 p->endian = RPC_LITTLE_ENDIAN;
1625 } else {
1626 p->endian = RPC_BIG_ENDIAN;
1628 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1630 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1631 pkt, p->endian);
1632 if (!NT_STATUS_IS_OK(status)) {
1633 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1634 nt_errstr(status)));
1635 goto done;
1638 /* Store the call_id */
1639 p->call_id = pkt->call_id;
1641 DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));
1643 switch (pkt->ptype) {
1644 case DCERPC_PKT_REQUEST:
1645 reply = process_request_pdu(p, pkt);
1646 break;
1648 case DCERPC_PKT_PING: /* CL request - ignore... */
1649 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1650 (unsigned int)pkt->ptype));
1651 break;
1653 case DCERPC_PKT_RESPONSE: /* No responses here. */
1654 DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
1655 break;
1657 case DCERPC_PKT_FAULT:
1658 case DCERPC_PKT_WORKING:
1659 /* CL request - reply to a ping when a call in process. */
1660 case DCERPC_PKT_NOCALL:
1661 /* CL - server reply to a ping call. */
1662 case DCERPC_PKT_REJECT:
1663 case DCERPC_PKT_ACK:
1664 case DCERPC_PKT_CL_CANCEL:
1665 case DCERPC_PKT_FACK:
1666 case DCERPC_PKT_CANCEL_ACK:
1667 DEBUG(0, ("Error - Connectionless packet type %u received\n",
1668 (unsigned int)pkt->ptype));
1669 break;
1671 case DCERPC_PKT_BIND:
1673 * We assume that a pipe bind is only in one pdu.
1675 if (pipe_init_outgoing_data(p)) {
1676 reply = api_pipe_bind_req(p, pkt);
1678 break;
1680 case DCERPC_PKT_BIND_ACK:
1681 case DCERPC_PKT_BIND_NAK:
1682 DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1683 "packet type %u received.\n",
1684 (unsigned int)pkt->ptype));
1685 break;
1688 case DCERPC_PKT_ALTER:
1690 * We assume that a pipe bind is only in one pdu.
1692 if (pipe_init_outgoing_data(p)) {
1693 reply = api_pipe_alter_context(p, pkt);
1695 break;
1697 case DCERPC_PKT_ALTER_RESP:
1698 DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
1699 "Should only be server -> client.\n"));
1700 break;
1702 case DCERPC_PKT_AUTH3:
1704 * The third packet in an auth exchange.
1706 if (pipe_init_outgoing_data(p)) {
1707 reply = api_pipe_bind_auth3(p, pkt);
1709 break;
1711 case DCERPC_PKT_SHUTDOWN:
1712 DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
1713 "Should only be server -> client.\n"));
1714 break;
1716 case DCERPC_PKT_CO_CANCEL:
1717 /* For now just free all client data and continue
1718 * processing. */
1719 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1720 " Abandoning rpc call.\n"));
1721 /* As we never do asynchronous RPC serving, we can
1722 * never cancel a call (as far as I know).
1723 * If we ever did we'd have to send a cancel_ack reply.
1724 * For now, just free all client data and continue
1725 * processing. */
1726 reply = True;
1727 break;
1729 #if 0
1730 /* Enable this if we're doing async rpc. */
1731 /* We must check the outstanding callid matches. */
1732 if (pipe_init_outgoing_data(p)) {
1733 /* Send a cancel_ack PDU reply. */
1734 /* We should probably check the auth-verifier here. */
1735 reply = setup_cancel_ack_reply(p, pkt);
1737 break;
1738 #endif
1740 case DCERPC_PKT_ORPHANED:
1741 /* We should probably check the auth-verifier here.
1742 * For now just free all client data and continue
1743 * processing. */
1744 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1745 " Abandoning rpc call.\n"));
1746 reply = True;
1747 break;
1749 default:
1750 DEBUG(0, ("process_complete_pdu: "
1751 "Unknown rpc type = %u received.\n",
1752 (unsigned int)pkt->ptype));
1753 break;
1756 done:
1757 if (!reply) {
1758 DEBUG(3,("DCE/RPC fault sent!"));
1759 set_incoming_fault(p);
1760 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1761 TALLOC_FREE(pkt);
1762 } else {
1764 * Reset the lengths. We're ready for a new pdu.
1766 TALLOC_FREE(p->in_data.pdu.data);
1767 p->in_data.pdu_needed_len = 0;
1768 p->in_data.pdu.length = 0;
1771 TALLOC_FREE(pkt);