s3: Fix Coverity ID 986, BUFFER_SIZE_WARNING
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob73a34866b20eab95b443af96418cf75c5f18ce9e
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_ntlmssp.h"
37 #include "dcesrv_gssapi.h"
38 #include "dcesrv_spnego.h"
39 #include "rpc_server.h"
40 #include "rpc_dce.h"
41 #include "smbd/smbd.h"
42 #include "auth.h"
43 #include "ntdomain.h"
45 #undef DBGC_CLASS
46 #define DBGC_CLASS DBGC_RPC_SRV
48 /**
49 * Dump everything from the start of the end up of the provided data
50 * into a file, but only at debug level >= 50
51 **/
52 static void dump_pdu_region(const char *name, int v,
53 DATA_BLOB *data, size_t start, size_t end)
55 int fd, i;
56 char *fname = NULL;
57 ssize_t sz;
59 if (DEBUGLEVEL < 50) return;
61 if (start > data->length || end > data->length || start > end) return;
63 for (i = 1; i < 100; i++) {
64 if (v != -1) {
65 fname = talloc_asprintf(talloc_tos(),
66 "/tmp/%s_%d.%d.prs",
67 name, v, i);
68 } else {
69 fname = talloc_asprintf(talloc_tos(),
70 "/tmp/%s_%d.prs",
71 name, i);
73 if (!fname) {
74 return;
76 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
77 if (fd != -1 || errno != EEXIST) break;
79 if (fd != -1) {
80 sz = write(fd, data->data + start, end - start);
81 i = close(fd);
82 if ((sz != end - start) || (i != 0) ) {
83 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
84 fname, (unsigned long)sz,
85 (unsigned long)end - start, i));
86 } else {
87 DEBUG(0,("created %s\n", fname));
90 TALLOC_FREE(fname);
93 static DATA_BLOB generic_session_key(void)
95 return data_blob_const("SystemLibraryDTC", 16);
98 /*******************************************************************
99 Generate the next PDU to be returned from the data.
100 ********************************************************************/
102 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
103 struct pipe_auth_data *auth,
104 uint32_t call_id,
105 DATA_BLOB *rdata,
106 size_t data_sent_length,
107 DATA_BLOB *frag,
108 size_t *pdu_size)
110 union dcerpc_payload u;
111 uint8_t pfc_flags;
112 size_t data_left;
113 size_t data_to_send;
114 size_t frag_len;
115 size_t pad_len = 0;
116 size_t auth_len = 0;
117 NTSTATUS status;
119 ZERO_STRUCT(u.response);
121 /* Set up rpc packet pfc flags. */
122 if (data_sent_length == 0) {
123 pfc_flags = DCERPC_PFC_FLAG_FIRST;
124 } else {
125 pfc_flags = 0;
128 /* Work out how much we can fit in a single PDU. */
129 data_left = rdata->length - data_sent_length;
131 /* Ensure there really is data left to send. */
132 if (!data_left) {
133 DEBUG(0, ("No data left to send !\n"));
134 return NT_STATUS_BUFFER_TOO_SMALL;
137 status = dcerpc_guess_sizes(auth,
138 DCERPC_RESPONSE_LENGTH,
139 data_left,
140 RPC_MAX_PDU_FRAG_LEN,
141 SERVER_NDR_PADDING_SIZE,
142 &data_to_send, &frag_len,
143 &auth_len, &pad_len);
144 if (!NT_STATUS_IS_OK(status)) {
145 return status;
148 /* Set up the alloc hint. This should be the data left to send. */
149 u.response.alloc_hint = data_left;
151 /* Work out if this PDU will be the last. */
152 if (data_sent_length + data_to_send >= rdata->length) {
153 pfc_flags |= DCERPC_PFC_FLAG_LAST;
156 /* Prepare data to be NDR encoded. */
157 u.response.stub_and_verifier =
158 data_blob_const(rdata->data + data_sent_length, data_to_send);
160 /* Store the packet in the data stream. */
161 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
162 pfc_flags, auth_len, call_id,
163 &u, frag);
164 if (!NT_STATUS_IS_OK(status)) {
165 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
166 return status;
169 if (auth_len) {
170 /* Set the proper length on the pdu, including padding.
171 * Only needed if an auth trailer will be appended. */
172 dcerpc_set_frag_length(frag, frag->length
173 + pad_len
174 + DCERPC_AUTH_TRAILER_LENGTH
175 + auth_len);
178 if (auth_len) {
179 status = dcerpc_add_auth_footer(auth, pad_len, frag);
180 if (!NT_STATUS_IS_OK(status)) {
181 data_blob_free(frag);
182 return status;
186 *pdu_size = data_to_send;
187 return NT_STATUS_OK;
190 /*******************************************************************
191 Generate the next PDU to be returned from the data in p->rdata.
192 ********************************************************************/
194 bool create_next_pdu(struct pipes_struct *p)
196 size_t pdu_size = 0;
197 NTSTATUS status;
200 * If we're in the fault state, keep returning fault PDU's until
201 * the pipe gets closed. JRA.
203 if (p->fault_state) {
204 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
205 return true;
208 status = create_next_packet(p->mem_ctx, &p->auth,
209 p->call_id, &p->out_data.rdata,
210 p->out_data.data_sent_length,
211 &p->out_data.frag, &pdu_size);
212 if (!NT_STATUS_IS_OK(status)) {
213 DEBUG(0, ("Failed to create packet with error %s, "
214 "(auth level %u / type %u)\n",
215 nt_errstr(status),
216 (unsigned int)p->auth.auth_level,
217 (unsigned int)p->auth.auth_type));
218 return false;
221 /* Setup the counts for this PDU. */
222 p->out_data.data_sent_length += pdu_size;
223 p->out_data.current_pdu_sent = 0;
224 return true;
228 static bool pipe_init_outgoing_data(struct pipes_struct *p);
230 /*******************************************************************
231 Marshall a bind_nak pdu.
232 *******************************************************************/
234 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
236 NTSTATUS status;
237 union dcerpc_payload u;
239 /* Free any memory in the current return data buffer. */
240 pipe_init_outgoing_data(p);
243 * Initialize a bind_nak header.
246 ZERO_STRUCT(u);
248 u.bind_nak.reject_reason = 0;
251 * Marshall directly into the outgoing PDU space. We
252 * must do this as we need to set to the bind response
253 * header and are never sending more than one PDU here.
256 status = dcerpc_push_ncacn_packet(p->mem_ctx,
257 DCERPC_PKT_BIND_NAK,
258 DCERPC_PFC_FLAG_FIRST |
259 DCERPC_PFC_FLAG_LAST,
261 pkt->call_id,
263 &p->out_data.frag);
264 if (!NT_STATUS_IS_OK(status)) {
265 return False;
268 p->out_data.data_sent_length = 0;
269 p->out_data.current_pdu_sent = 0;
271 TALLOC_FREE(p->auth.auth_ctx);
272 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
273 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
274 p->pipe_bound = False;
276 return True;
279 /*******************************************************************
280 Marshall a fault pdu.
281 *******************************************************************/
283 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
285 NTSTATUS status;
286 union dcerpc_payload u;
288 /* Free any memory in the current return data buffer. */
289 pipe_init_outgoing_data(p);
292 * Initialize a fault header.
295 ZERO_STRUCT(u);
297 u.fault.status = NT_STATUS_V(fault_status);
298 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
301 * Marshall directly into the outgoing PDU space. We
302 * must do this as we need to set to the bind response
303 * header and are never sending more than one PDU here.
306 status = dcerpc_push_ncacn_packet(p->mem_ctx,
307 DCERPC_PKT_FAULT,
308 DCERPC_PFC_FLAG_FIRST |
309 DCERPC_PFC_FLAG_LAST |
310 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
312 p->call_id,
314 &p->out_data.frag);
315 if (!NT_STATUS_IS_OK(status)) {
316 return False;
319 p->out_data.data_sent_length = 0;
320 p->out_data.current_pdu_sent = 0;
322 return True;
325 /*******************************************************************
326 Ensure a bind request has the correct abstract & transfer interface.
327 Used to reject unknown binds from Win2k.
328 *******************************************************************/
330 static bool check_bind_req(struct pipes_struct *p,
331 struct ndr_syntax_id* abstract,
332 struct ndr_syntax_id* transfer,
333 uint32 context_id)
335 struct pipe_rpc_fns *context_fns;
337 DEBUG(3,("check_bind_req for %s\n",
338 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
340 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
341 if (rpc_srv_pipe_exists_by_id(abstract) &&
342 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
343 DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
344 rpc_srv_get_pipe_cli_name(abstract),
345 rpc_srv_get_pipe_srv_name(abstract)));
346 } else {
347 return false;
350 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
351 if (context_fns == NULL) {
352 DEBUG(0,("check_bind_req: malloc() failed!\n"));
353 return False;
356 context_fns->next = context_fns->prev = NULL;
357 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
358 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
359 context_fns->context_id = context_id;
361 /* add to the list of open contexts */
363 DLIST_ADD( p->contexts, context_fns );
365 return True;
369 * Is a named pipe known?
370 * @param[in] cli_filename The pipe name requested by the client
371 * @result Do we want to serve this?
373 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
375 const char *pipename = cli_filename;
376 NTSTATUS status;
378 if (strnequal(pipename, "\\PIPE\\", 6)) {
379 pipename += 5;
382 if (*pipename == '\\') {
383 pipename += 1;
386 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
387 DEBUG(10, ("refusing spoolss access\n"));
388 return false;
391 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
392 return true;
395 status = smb_probe_module("rpc", pipename);
396 if (!NT_STATUS_IS_OK(status)) {
397 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
398 return false;
400 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
403 * Scan the list again for the interface id
405 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
406 return true;
409 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
410 pipename));
412 return false;
415 /*******************************************************************
416 Handle the first part of a SPNEGO bind auth.
417 *******************************************************************/
419 static bool pipe_spnego_auth_bind(struct pipes_struct *p,
420 TALLOC_CTX *mem_ctx,
421 struct dcerpc_auth *auth_info,
422 DATA_BLOB *response)
424 struct spnego_context *spnego_ctx;
425 NTSTATUS status;
427 status = spnego_server_auth_start(p,
428 (auth_info->auth_level ==
429 DCERPC_AUTH_LEVEL_INTEGRITY),
430 (auth_info->auth_level ==
431 DCERPC_AUTH_LEVEL_PRIVACY),
432 true,
433 &auth_info->credentials,
434 response,
435 &spnego_ctx);
436 if (!NT_STATUS_IS_OK(status)) {
437 DEBUG(0, ("Failed SPNEGO negotiate (%s)\n",
438 nt_errstr(status)));
439 return false;
442 /* Make sure data is bound to the memctx, to be freed the caller */
443 talloc_steal(mem_ctx, response->data);
445 p->auth.auth_ctx = spnego_ctx;
446 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
448 DEBUG(10, ("SPNEGO auth started\n"));
450 return true;
453 /*******************************************************************
454 Handle an schannel bind auth.
455 *******************************************************************/
457 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
458 TALLOC_CTX *mem_ctx,
459 struct dcerpc_auth *auth_info,
460 DATA_BLOB *response)
462 struct NL_AUTH_MESSAGE neg;
463 struct NL_AUTH_MESSAGE reply;
464 bool ret;
465 NTSTATUS status;
466 struct netlogon_creds_CredentialState *creds;
467 enum ndr_err_code ndr_err;
468 struct schannel_state *schannel_auth;
470 ndr_err = ndr_pull_struct_blob(
471 &auth_info->credentials, mem_ctx, &neg,
472 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
473 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
474 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
475 return false;
478 if (DEBUGLEVEL >= 10) {
479 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
482 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
483 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
484 return false;
488 * The neg.oem_netbios_computer.a key here must match the remote computer name
489 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
490 * operations that use credentials.
493 become_root();
494 status = schannel_get_creds_state(p, lp_private_dir(),
495 neg.oem_netbios_computer.a, &creds);
496 unbecome_root();
498 if (!NT_STATUS_IS_OK(status)) {
499 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
500 return False;
503 schannel_auth = talloc(p, struct schannel_state);
504 if (!schannel_auth) {
505 TALLOC_FREE(creds);
506 return False;
509 schannel_auth->state = SCHANNEL_STATE_START;
510 schannel_auth->seq_num = 0;
511 schannel_auth->initiator = false;
512 schannel_auth->creds = creds;
515 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
516 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
517 * struct of the person who opened the pipe. I need to test this further. JRA.
519 * VL. As we are mapping this to guest set the generic key
520 * "SystemLibraryDTC" key here. It's a bit difficult to test against
521 * W2k3, as it does not allow schannel binds against SAMR and LSA
522 * anymore.
525 ret = session_info_set_session_key(p->session_info, generic_session_key());
527 if (!ret) {
528 DEBUG(0, ("session_info_set_session_key failed\n"));
529 return false;
532 /*** SCHANNEL verifier ***/
534 reply.MessageType = NL_NEGOTIATE_RESPONSE;
535 reply.Flags = 0;
536 reply.Buffer.dummy = 5; /* ??? actually I don't think
537 * this has any meaning
538 * here - gd */
540 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
541 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
542 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
543 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
544 return false;
547 if (DEBUGLEVEL >= 10) {
548 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
551 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
552 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
554 /* We're finished with this bind - no more packets. */
555 p->auth.auth_ctx = schannel_auth;
556 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
558 p->pipe_bound = True;
560 return True;
563 /*******************************************************************
564 Handle an NTLMSSP bind auth.
565 *******************************************************************/
567 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
568 TALLOC_CTX *mem_ctx,
569 struct dcerpc_auth *auth_info,
570 DATA_BLOB *response)
572 struct auth_ntlmssp_state *ntlmssp_state = NULL;
573 NTSTATUS status;
575 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
576 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
577 return false;
580 /* We have an NTLMSSP blob. */
581 status = ntlmssp_server_auth_start(p,
582 (auth_info->auth_level ==
583 DCERPC_AUTH_LEVEL_INTEGRITY),
584 (auth_info->auth_level ==
585 DCERPC_AUTH_LEVEL_PRIVACY),
586 true,
587 &auth_info->credentials,
588 response,
589 &ntlmssp_state);
590 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
591 DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
592 nt_errstr(status)));
593 return false;
596 /* Make sure data is bound to the memctx, to be freed the caller */
597 talloc_steal(mem_ctx, response->data);
599 p->auth.auth_ctx = ntlmssp_state;
600 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
602 DEBUG(10, (__location__ ": NTLMSSP auth started\n"));
604 return true;
607 /*******************************************************************
608 Process an NTLMSSP authentication response.
609 If this function succeeds, the user has been authenticated
610 and their domain, name and calling workstation stored in
611 the pipe struct.
612 *******************************************************************/
614 static bool pipe_ntlmssp_verify_final(TALLOC_CTX *mem_ctx,
615 struct auth_ntlmssp_state *ntlmssp_ctx,
616 enum dcerpc_AuthLevel auth_level,
617 struct client_address *client_id,
618 struct ndr_syntax_id *syntax,
619 struct auth_serversupplied_info **session_info)
621 NTSTATUS status;
622 bool ret;
624 DEBUG(5, (__location__ ": pipe %s checking user details\n",
625 get_pipe_name_from_syntax(talloc_tos(), syntax)));
627 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
628 ensure the underlying NTLMSSP flags are also set. If not we should
629 refuse the bind. */
631 status = ntlmssp_server_check_flags(ntlmssp_ctx,
632 (auth_level ==
633 DCERPC_AUTH_LEVEL_INTEGRITY),
634 (auth_level ==
635 DCERPC_AUTH_LEVEL_PRIVACY));
636 if (!NT_STATUS_IS_OK(status)) {
637 DEBUG(0, (__location__ ": Client failed to negotatie proper "
638 "security for pipe %s\n",
639 get_pipe_name_from_syntax(talloc_tos(), syntax)));
640 return false;
643 TALLOC_FREE(*session_info);
645 status = ntlmssp_server_get_user_info(ntlmssp_ctx,
646 mem_ctx, session_info);
647 if (!NT_STATUS_IS_OK(status)) {
648 DEBUG(0, (__location__ ": failed to obtain the server info "
649 "for authenticated user: %s\n", nt_errstr(status)));
650 return false;
653 if ((*session_info)->security_token == NULL) {
654 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
655 return false;
659 * We're an authenticated bind over smb, so the session key needs to
660 * be set to "SystemLibraryDTC". Weird, but this is what Windows
661 * does. See the RPC-SAMBA3SESSIONKEY.
664 ret = session_info_set_session_key((*session_info), generic_session_key());
665 if (!ret) {
666 DEBUG(0, ("Failed to set session key!\n"));
667 return false;
670 return true;
673 /*******************************************************************
674 Handle a GSSAPI bind auth.
675 *******************************************************************/
677 static bool pipe_gssapi_auth_bind(struct pipes_struct *p,
678 TALLOC_CTX *mem_ctx,
679 struct dcerpc_auth *auth_info,
680 DATA_BLOB *response)
682 NTSTATUS status;
683 struct gse_context *gse_ctx = NULL;
685 status = gssapi_server_auth_start(p,
686 (auth_info->auth_level ==
687 DCERPC_AUTH_LEVEL_INTEGRITY),
688 (auth_info->auth_level ==
689 DCERPC_AUTH_LEVEL_PRIVACY),
690 true,
691 &auth_info->credentials,
692 response,
693 &gse_ctx);
694 if (!NT_STATUS_IS_OK(status)) {
695 DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
696 nt_errstr(status)));
697 goto err;
700 /* Make sure data is bound to the memctx, to be freed the caller */
701 talloc_steal(mem_ctx, response->data);
703 p->auth.auth_ctx = gse_ctx;
704 p->auth.auth_type = DCERPC_AUTH_TYPE_KRB5;
706 DEBUG(10, ("KRB5 auth started\n"));
708 return true;
710 err:
711 TALLOC_FREE(gse_ctx);
712 return false;
715 static NTSTATUS pipe_gssapi_verify_final(TALLOC_CTX *mem_ctx,
716 struct gse_context *gse_ctx,
717 struct client_address *client_id,
718 struct auth_serversupplied_info **session_info)
720 NTSTATUS status;
721 bool bret;
723 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
724 ensure the underlying flags are also set. If not we should
725 refuse the bind. */
727 status = gssapi_server_check_flags(gse_ctx);
728 if (!NT_STATUS_IS_OK(status)) {
729 DEBUG(0, ("Requested Security Layers not honored!\n"));
730 return status;
733 status = gssapi_server_get_user_info(gse_ctx, mem_ctx,
734 client_id, session_info);
735 if (!NT_STATUS_IS_OK(status)) {
736 DEBUG(0, (__location__ ": failed to obtain the server info "
737 "for authenticated user: %s\n", nt_errstr(status)));
738 return status;
741 if ((*session_info)->security_token == NULL) {
742 status = create_local_token(*session_info);
743 if (!NT_STATUS_IS_OK(status)) {
744 DEBUG(1, ("Failed to create local user token (%s)\n",
745 nt_errstr(status)));
746 status = NT_STATUS_ACCESS_DENIED;
747 return status;
751 /* TODO: this is what the ntlmssp code does with the session_key, check
752 * it is ok with gssapi too */
754 * We're an authenticated bind over smb, so the session key needs to
755 * be set to "SystemLibraryDTC". Weird, but this is what Windows
756 * does. See the RPC-SAMBA3SESSIONKEY.
759 bret = session_info_set_session_key((*session_info), generic_session_key());
760 if (!bret) {
761 return NT_STATUS_ACCESS_DENIED;
764 return NT_STATUS_OK;
767 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
769 enum spnego_mech auth_type;
770 struct auth_ntlmssp_state *ntlmssp_ctx;
771 struct spnego_context *spnego_ctx;
772 struct gse_context *gse_ctx;
773 void *mech_ctx;
774 NTSTATUS status;
776 switch (p->auth.auth_type) {
777 case DCERPC_AUTH_TYPE_NTLMSSP:
778 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
779 struct auth_ntlmssp_state);
780 if (!pipe_ntlmssp_verify_final(p, ntlmssp_ctx,
781 p->auth.auth_level,
782 p->client_id, &p->syntax,
783 &p->session_info)) {
784 return NT_STATUS_ACCESS_DENIED;
786 break;
787 case DCERPC_AUTH_TYPE_KRB5:
788 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
789 struct gse_context);
790 status = pipe_gssapi_verify_final(p, gse_ctx,
791 p->client_id,
792 &p->session_info);
793 if (!NT_STATUS_IS_OK(status)) {
794 DEBUG(1, ("gssapi bind failed with: %s",
795 nt_errstr(status)));
796 return status;
798 break;
799 case DCERPC_AUTH_TYPE_SPNEGO:
800 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
801 struct spnego_context);
802 status = spnego_get_negotiated_mech(spnego_ctx,
803 &auth_type, &mech_ctx);
804 if (!NT_STATUS_IS_OK(status)) {
805 DEBUG(0, ("Bad SPNEGO state (%s)\n",
806 nt_errstr(status)));
807 return status;
809 switch(auth_type) {
810 case SPNEGO_KRB5:
811 gse_ctx = talloc_get_type_abort(mech_ctx,
812 struct gse_context);
813 status = pipe_gssapi_verify_final(p, gse_ctx,
814 p->client_id,
815 &p->session_info);
816 if (!NT_STATUS_IS_OK(status)) {
817 DEBUG(1, ("gssapi bind failed with: %s",
818 nt_errstr(status)));
819 return status;
821 break;
822 case SPNEGO_NTLMSSP:
823 ntlmssp_ctx = talloc_get_type_abort(mech_ctx,
824 struct auth_ntlmssp_state);
825 if (!pipe_ntlmssp_verify_final(p, ntlmssp_ctx,
826 p->auth.auth_level,
827 p->client_id,
828 &p->syntax,
829 &p->session_info)) {
830 return NT_STATUS_ACCESS_DENIED;
832 break;
833 default:
834 DEBUG(0, (__location__ ": incorrect spnego type "
835 "(%d).\n", auth_type));
836 return NT_STATUS_ACCESS_DENIED;
838 break;
839 default:
840 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
841 (unsigned int)p->auth.auth_type));
842 return NT_STATUS_ACCESS_DENIED;
845 p->pipe_bound = true;
847 return NT_STATUS_OK;
850 /*******************************************************************
851 Respond to a pipe bind request.
852 *******************************************************************/
854 static bool api_pipe_bind_req(struct pipes_struct *p,
855 struct ncacn_packet *pkt)
857 struct dcerpc_auth auth_info;
858 uint16 assoc_gid;
859 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
860 NTSTATUS status;
861 struct ndr_syntax_id id;
862 union dcerpc_payload u;
863 struct dcerpc_ack_ctx bind_ack_ctx;
864 DATA_BLOB auth_resp = data_blob_null;
865 DATA_BLOB auth_blob = data_blob_null;
867 /* No rebinds on a bound pipe - use alter context. */
868 if (p->pipe_bound) {
869 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
870 "pipe %s.\n",
871 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
872 return setup_bind_nak(p, pkt);
875 if (pkt->u.bind.num_contexts == 0) {
876 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
877 goto err_exit;
881 * Try and find the correct pipe name to ensure
882 * that this is a pipe name we support.
884 id = pkt->u.bind.ctx_list[0].abstract_syntax;
885 if (rpc_srv_pipe_exists_by_id(&id)) {
886 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
887 rpc_srv_get_pipe_cli_name(&id),
888 rpc_srv_get_pipe_srv_name(&id)));
889 } else {
890 status = smb_probe_module(
891 "rpc", get_pipe_name_from_syntax(
892 talloc_tos(),
893 &pkt->u.bind.ctx_list[0].abstract_syntax));
895 if (NT_STATUS_IS_ERR(status)) {
896 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
897 get_pipe_name_from_syntax(
898 talloc_tos(),
899 &pkt->u.bind.ctx_list[0].abstract_syntax)));
901 return setup_bind_nak(p, pkt);
904 if (rpc_srv_get_pipe_interface_by_cli_name(
905 get_pipe_name_from_syntax(talloc_tos(),
906 &p->syntax),
907 &id)) {
908 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
909 rpc_srv_get_pipe_cli_name(&id),
910 rpc_srv_get_pipe_srv_name(&id)));
911 } else {
912 DEBUG(0, ("module %s doesn't provide functions for "
913 "pipe %s!\n",
914 get_pipe_name_from_syntax(talloc_tos(),
915 &p->syntax),
916 get_pipe_name_from_syntax(talloc_tos(),
917 &p->syntax)));
918 return setup_bind_nak(p, pkt);
922 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
924 if (pkt->u.bind.assoc_group_id != 0) {
925 assoc_gid = pkt->u.bind.assoc_group_id;
926 } else {
927 assoc_gid = 0x53f0;
931 * Create the bind response struct.
934 /* If the requested abstract synt uuid doesn't match our client pipe,
935 reject the bind_ack & set the transfer interface synt to all 0's,
936 ver 0 (observed when NT5 attempts to bind to abstract interfaces
937 unknown to NT4)
938 Needed when adding entries to a DACL from NT5 - SK */
940 if (check_bind_req(p,
941 &pkt->u.bind.ctx_list[0].abstract_syntax,
942 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
943 pkt->u.bind.ctx_list[0].context_id)) {
945 bind_ack_ctx.result = 0;
946 bind_ack_ctx.reason = 0;
947 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
948 } else {
949 p->pipe_bound = False;
950 /* Rejection reason: abstract syntax not supported */
951 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
952 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
953 bind_ack_ctx.syntax = null_ndr_syntax_id;
957 * Check if this is an authenticated bind request.
959 if (pkt->auth_length) {
960 /* Quick length check. Won't catch a bad auth footer,
961 * prevents overrun. */
963 if (pkt->frag_length < RPC_HEADER_LEN +
964 DCERPC_AUTH_TRAILER_LENGTH +
965 pkt->auth_length) {
966 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
967 "too long for fragment %u.\n",
968 (unsigned int)pkt->auth_length,
969 (unsigned int)pkt->frag_length));
970 goto err_exit;
974 * Decode the authentication verifier.
976 status = dcerpc_pull_dcerpc_auth(pkt,
977 &pkt->u.bind.auth_info,
978 &auth_info, p->endian);
979 if (!NT_STATUS_IS_OK(status)) {
980 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
981 goto err_exit;
984 auth_type = auth_info.auth_type;
986 /* Work out if we have to sign or seal etc. */
987 switch (auth_info.auth_level) {
988 case DCERPC_AUTH_LEVEL_INTEGRITY:
989 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
990 break;
991 case DCERPC_AUTH_LEVEL_PRIVACY:
992 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
993 break;
994 case DCERPC_AUTH_LEVEL_CONNECT:
995 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
996 break;
997 default:
998 DEBUG(0, ("Unexpected auth level (%u).\n",
999 (unsigned int)auth_info.auth_level ));
1000 goto err_exit;
1003 switch (auth_type) {
1004 case DCERPC_AUTH_TYPE_NTLMSSP:
1005 if (!pipe_ntlmssp_auth_bind(p, pkt,
1006 &auth_info, &auth_resp)) {
1007 goto err_exit;
1009 assoc_gid = 0x7a77;
1010 break;
1012 case DCERPC_AUTH_TYPE_SCHANNEL:
1013 if (!pipe_schannel_auth_bind(p, pkt,
1014 &auth_info, &auth_resp)) {
1015 goto err_exit;
1017 break;
1019 case DCERPC_AUTH_TYPE_SPNEGO:
1020 if (!pipe_spnego_auth_bind(p, pkt,
1021 &auth_info, &auth_resp)) {
1022 goto err_exit;
1024 break;
1026 case DCERPC_AUTH_TYPE_KRB5:
1027 if (!pipe_gssapi_auth_bind(p, pkt,
1028 &auth_info, &auth_resp)) {
1029 goto err_exit;
1031 break;
1033 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1034 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
1035 TALLOC_FREE(p->session_info);
1037 status = make_session_info_system(p,
1038 &p->session_info);
1039 if (!NT_STATUS_IS_OK(status)) {
1040 goto err_exit;
1043 auth_resp = data_blob_talloc(pkt,
1044 "NCALRPC_AUTH_OK",
1045 15);
1047 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
1048 p->pipe_bound = true;
1049 } else {
1050 goto err_exit;
1052 break;
1054 case DCERPC_AUTH_TYPE_NONE:
1055 break;
1057 default:
1058 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1059 goto err_exit;
1063 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1064 /* Unauthenticated bind request. */
1065 /* We're finished - no more packets. */
1066 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1067 /* We must set the pipe auth_level here also. */
1068 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1069 p->pipe_bound = True;
1070 /* The session key was initialized from the SMB
1071 * session in make_internal_rpc_pipe_p */
1074 ZERO_STRUCT(u.bind_ack);
1075 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1076 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1077 u.bind_ack.assoc_group_id = assoc_gid;
1079 /* name has to be \PIPE\xxxxx */
1080 u.bind_ack.secondary_address =
1081 talloc_asprintf(pkt, "\\PIPE\\%s",
1082 rpc_srv_get_pipe_srv_name(&id));
1083 if (!u.bind_ack.secondary_address) {
1084 DEBUG(0, ("Out of memory!\n"));
1085 goto err_exit;
1087 u.bind_ack.secondary_address_size =
1088 strlen(u.bind_ack.secondary_address) + 1;
1090 u.bind_ack.num_results = 1;
1091 u.bind_ack.ctx_list = &bind_ack_ctx;
1093 /* NOTE: We leave the auth_info empty so we can calculate the padding
1094 * later and then append the auth_info --simo */
1097 * Marshall directly into the outgoing PDU space. We
1098 * must do this as we need to set to the bind response
1099 * header and are never sending more than one PDU here.
1102 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1103 DCERPC_PKT_BIND_ACK,
1104 DCERPC_PFC_FLAG_FIRST |
1105 DCERPC_PFC_FLAG_LAST,
1106 auth_resp.length,
1107 pkt->call_id,
1109 &p->out_data.frag);
1110 if (!NT_STATUS_IS_OK(status)) {
1111 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1112 nt_errstr(status)));
1115 if (auth_resp.length) {
1117 status = dcerpc_push_dcerpc_auth(pkt,
1118 auth_type,
1119 auth_info.auth_level,
1121 1, /* auth_context_id */
1122 &auth_resp,
1123 &auth_blob);
1124 if (!NT_STATUS_IS_OK(status)) {
1125 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1126 goto err_exit;
1130 /* Now that we have the auth len store it into the right place in
1131 * the dcerpc header */
1132 dcerpc_set_frag_length(&p->out_data.frag,
1133 p->out_data.frag.length + auth_blob.length);
1135 if (auth_blob.length) {
1137 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1138 auth_blob.data, auth_blob.length)) {
1139 DEBUG(0, ("Append of auth info failed.\n"));
1140 goto err_exit;
1145 * Setup the lengths for the initial reply.
1148 p->out_data.data_sent_length = 0;
1149 p->out_data.current_pdu_sent = 0;
1151 TALLOC_FREE(auth_blob.data);
1152 return True;
1154 err_exit:
1156 data_blob_free(&p->out_data.frag);
1157 TALLOC_FREE(auth_blob.data);
1158 return setup_bind_nak(p, pkt);
1161 /*******************************************************************
1162 This is the "stage3" response after a bind request and reply.
1163 *******************************************************************/
1165 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1167 struct dcerpc_auth auth_info;
1168 DATA_BLOB response = data_blob_null;
1169 struct auth_ntlmssp_state *ntlmssp_ctx;
1170 struct spnego_context *spnego_ctx;
1171 struct gse_context *gse_ctx;
1172 NTSTATUS status;
1174 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1176 if (pkt->auth_length == 0) {
1177 DEBUG(0, ("No auth field sent for bind request!\n"));
1178 goto err;
1181 /* Ensure there's enough data for an authenticated request. */
1182 if (pkt->frag_length < RPC_HEADER_LEN
1183 + DCERPC_AUTH_TRAILER_LENGTH
1184 + pkt->auth_length) {
1185 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
1186 "%u is too large.\n",
1187 (unsigned int)pkt->auth_length));
1188 goto err;
1192 * Decode the authentication verifier response.
1195 status = dcerpc_pull_dcerpc_auth(pkt,
1196 &pkt->u.auth3.auth_info,
1197 &auth_info, p->endian);
1198 if (!NT_STATUS_IS_OK(status)) {
1199 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1200 goto err;
1203 /* We must NEVER look at auth_info->auth_pad_len here,
1204 * as old Samba client code gets it wrong and sends it
1205 * as zero. JRA.
1208 if (auth_info.auth_type != p->auth.auth_type) {
1209 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1210 "but auth was started as type %d!\n",
1211 auth_info.auth_type, p->auth.auth_type));
1212 goto err;
1215 switch (auth_info.auth_type) {
1216 case DCERPC_AUTH_TYPE_NTLMSSP:
1217 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1218 struct auth_ntlmssp_state);
1219 status = ntlmssp_server_step(ntlmssp_ctx,
1220 pkt, &auth_info.credentials,
1221 &response);
1222 break;
1223 case DCERPC_AUTH_TYPE_KRB5:
1224 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1225 struct gse_context);
1226 status = gssapi_server_step(gse_ctx,
1227 pkt, &auth_info.credentials,
1228 &response);
1229 break;
1230 case DCERPC_AUTH_TYPE_SPNEGO:
1231 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1232 struct spnego_context);
1233 status = spnego_server_step(spnego_ctx,
1234 pkt, &auth_info.credentials,
1235 &response);
1236 break;
1237 default:
1238 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1239 (unsigned int)auth_info.auth_type));
1240 return false;
1243 if (NT_STATUS_EQUAL(status,
1244 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1245 response.length) {
1246 DEBUG(0, (__location__ ": This was supposed to be the final "
1247 "leg, but crypto machinery claims a response is "
1248 "needed, aborting auth!\n"));
1249 data_blob_free(&response);
1250 goto err;
1252 if (!NT_STATUS_IS_OK(status)) {
1253 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1254 goto err;
1257 /* Now verify auth was indeed successful and extract server info */
1258 status = pipe_auth_verify_final(p);
1259 if (!NT_STATUS_IS_OK(status)) {
1260 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1261 goto err;
1264 return true;
1266 err:
1268 TALLOC_FREE(p->auth.auth_ctx);
1269 return false;
1272 /****************************************************************************
1273 Deal with an alter context call. Can be third part of 3 leg auth request for
1274 SPNEGO calls.
1275 ****************************************************************************/
1277 static bool api_pipe_alter_context(struct pipes_struct *p,
1278 struct ncacn_packet *pkt)
1280 struct dcerpc_auth auth_info;
1281 uint16 assoc_gid;
1282 NTSTATUS status;
1283 union dcerpc_payload u;
1284 struct dcerpc_ack_ctx bind_ack_ctx;
1285 DATA_BLOB auth_resp = data_blob_null;
1286 DATA_BLOB auth_blob = data_blob_null;
1287 int pad_len = 0;
1288 struct auth_ntlmssp_state *ntlmssp_ctx;
1289 struct spnego_context *spnego_ctx;
1290 struct gse_context *gse_ctx;
1292 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1294 if (pkt->u.bind.assoc_group_id != 0) {
1295 assoc_gid = pkt->u.bind.assoc_group_id;
1296 } else {
1297 assoc_gid = 0x53f0;
1301 * Create the bind response struct.
1304 /* If the requested abstract synt uuid doesn't match our client pipe,
1305 reject the bind_ack & set the transfer interface synt to all 0's,
1306 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1307 unknown to NT4)
1308 Needed when adding entries to a DACL from NT5 - SK */
1310 if (check_bind_req(p,
1311 &pkt->u.bind.ctx_list[0].abstract_syntax,
1312 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1313 pkt->u.bind.ctx_list[0].context_id)) {
1315 bind_ack_ctx.result = 0;
1316 bind_ack_ctx.reason = 0;
1317 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1318 } else {
1319 p->pipe_bound = False;
1320 /* Rejection reason: abstract syntax not supported */
1321 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1322 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1323 bind_ack_ctx.syntax = null_ndr_syntax_id;
1327 * Check if this is an authenticated alter context request.
1329 if (pkt->auth_length) {
1330 /* Quick length check. Won't catch a bad auth footer,
1331 * prevents overrun. */
1333 if (pkt->frag_length < RPC_HEADER_LEN +
1334 DCERPC_AUTH_TRAILER_LENGTH +
1335 pkt->auth_length) {
1336 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1337 "too long for fragment %u.\n",
1338 (unsigned int)pkt->auth_length,
1339 (unsigned int)pkt->frag_length ));
1340 goto err_exit;
1343 status = dcerpc_pull_dcerpc_auth(pkt,
1344 &pkt->u.bind.auth_info,
1345 &auth_info, p->endian);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1348 goto err_exit;
1351 /* We can only finish if the pipe is unbound for now */
1352 if (p->pipe_bound) {
1353 DEBUG(0, (__location__ ": Pipe already bound, "
1354 "Altering Context not yet supported!\n"));
1355 goto err_exit;
1358 if (auth_info.auth_type != p->auth.auth_type) {
1359 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1360 "but auth was started as type %d!\n",
1361 auth_info.auth_type, p->auth.auth_type));
1362 goto err_exit;
1366 switch (auth_info.auth_type) {
1367 case DCERPC_AUTH_TYPE_SPNEGO:
1368 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1369 struct spnego_context);
1370 status = spnego_server_step(spnego_ctx,
1371 pkt,
1372 &auth_info.credentials,
1373 &auth_resp);
1374 break;
1376 case DCERPC_AUTH_TYPE_KRB5:
1377 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1378 struct gse_context);
1379 status = gssapi_server_step(gse_ctx,
1380 pkt,
1381 &auth_info.credentials,
1382 &auth_resp);
1383 break;
1384 case DCERPC_AUTH_TYPE_NTLMSSP:
1385 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1386 struct auth_ntlmssp_state);
1387 status = ntlmssp_server_step(ntlmssp_ctx,
1388 pkt,
1389 &auth_info.credentials,
1390 &auth_resp);
1391 break;
1393 default:
1394 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1395 "in alter-context call\n",
1396 auth_info.auth_type));
1397 goto err_exit;
1400 if (NT_STATUS_IS_OK(status)) {
1401 /* third leg of auth, verify auth info */
1402 status = pipe_auth_verify_final(p);
1403 if (!NT_STATUS_IS_OK(status)) {
1404 DEBUG(0, ("Auth Verify failed (%s)\n",
1405 nt_errstr(status)));
1406 goto err_exit;
1408 } else if (NT_STATUS_EQUAL(status,
1409 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1410 DEBUG(10, ("More auth legs required.\n"));
1411 } else {
1412 DEBUG(0, ("Auth step returned an error (%s)\n",
1413 nt_errstr(status)));
1414 goto err_exit;
1418 ZERO_STRUCT(u.alter_resp);
1419 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1420 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1421 u.alter_resp.assoc_group_id = assoc_gid;
1423 /* secondary address CAN be NULL
1424 * as the specs say it's ignored.
1425 * It MUST be NULL to have the spoolss working.
1427 u.alter_resp.secondary_address = "";
1428 u.alter_resp.secondary_address_size = 1;
1430 u.alter_resp.num_results = 1;
1431 u.alter_resp.ctx_list = &bind_ack_ctx;
1433 /* NOTE: We leave the auth_info empty so we can calculate the padding
1434 * later and then append the auth_info --simo */
1437 * Marshall directly into the outgoing PDU space. We
1438 * must do this as we need to set to the bind response
1439 * header and are never sending more than one PDU here.
1442 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1443 DCERPC_PKT_ALTER_RESP,
1444 DCERPC_PFC_FLAG_FIRST |
1445 DCERPC_PFC_FLAG_LAST,
1446 auth_resp.length,
1447 pkt->call_id,
1449 &p->out_data.frag);
1450 if (!NT_STATUS_IS_OK(status)) {
1451 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1452 nt_errstr(status)));
1455 if (auth_resp.length) {
1457 /* Work out any padding needed before the auth footer. */
1458 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1459 if (pad_len) {
1460 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1461 DEBUG(10, ("auth pad_len = %u\n",
1462 (unsigned int)pad_len));
1465 status = dcerpc_push_dcerpc_auth(pkt,
1466 auth_info.auth_type,
1467 auth_info.auth_level,
1468 pad_len,
1469 1, /* auth_context_id */
1470 &auth_resp,
1471 &auth_blob);
1472 if (!NT_STATUS_IS_OK(status)) {
1473 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1474 goto err_exit;
1478 /* Now that we have the auth len store it into the right place in
1479 * the dcerpc header */
1480 dcerpc_set_frag_length(&p->out_data.frag,
1481 p->out_data.frag.length +
1482 pad_len + auth_blob.length);
1484 if (auth_resp.length) {
1485 if (pad_len) {
1486 char pad[SERVER_NDR_PADDING_SIZE];
1487 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1488 if (!data_blob_append(p->mem_ctx,
1489 &p->out_data.frag,
1490 pad, pad_len)) {
1491 DEBUG(0, ("api_pipe_bind_req: failed to add "
1492 "%u bytes of pad data.\n",
1493 (unsigned int)pad_len));
1494 goto err_exit;
1498 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1499 auth_blob.data, auth_blob.length)) {
1500 DEBUG(0, ("Append of auth info failed.\n"));
1501 goto err_exit;
1506 * Setup the lengths for the initial reply.
1509 p->out_data.data_sent_length = 0;
1510 p->out_data.current_pdu_sent = 0;
1512 TALLOC_FREE(auth_blob.data);
1513 return True;
1515 err_exit:
1517 data_blob_free(&p->out_data.frag);
1518 TALLOC_FREE(auth_blob.data);
1519 return setup_bind_nak(p, pkt);
1522 /****************************************************************************
1523 Find the set of RPC functions associated with this context_id
1524 ****************************************************************************/
1526 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1528 PIPE_RPC_FNS *fns = NULL;
1530 if ( !list ) {
1531 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1532 return NULL;
1535 for (fns=list; fns; fns=fns->next ) {
1536 if ( fns->context_id == context_id )
1537 return fns;
1539 return NULL;
1542 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1543 const struct api_struct *api_rpc_cmds, int n_cmds);
1545 /****************************************************************************
1546 Find the correct RPC function to call for this request.
1547 If the pipe is authenticated then become the correct UNIX user
1548 before doing the call.
1549 ****************************************************************************/
1551 static bool api_pipe_request(struct pipes_struct *p,
1552 struct ncacn_packet *pkt)
1554 bool ret = False;
1555 bool changed_user = False;
1556 PIPE_RPC_FNS *pipe_fns;
1558 if (p->pipe_bound &&
1559 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1560 (p->auth.auth_type == DCERPC_AUTH_TYPE_KRB5) ||
1561 (p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO))) {
1562 if(!become_authenticated_pipe_user(p)) {
1563 data_blob_free(&p->out_data.rdata);
1564 return False;
1566 changed_user = True;
1569 DEBUG(5, ("Requested \\PIPE\\%s\n",
1570 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1572 /* get the set of RPC functions for this context */
1574 pipe_fns = find_pipe_fns_by_context(p->contexts,
1575 pkt->u.request.context_id);
1577 if ( pipe_fns ) {
1578 TALLOC_CTX *frame = talloc_stackframe();
1579 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1580 TALLOC_FREE(frame);
1582 else {
1583 DEBUG(0, ("No rpc function table associated with context "
1584 "[%d] on pipe [%s]\n",
1585 pkt->u.request.context_id,
1586 get_pipe_name_from_syntax(talloc_tos(),
1587 &p->syntax)));
1590 if (changed_user) {
1591 unbecome_authenticated_pipe_user();
1594 return ret;
1597 /*******************************************************************
1598 Calls the underlying RPC function for a named pipe.
1599 ********************************************************************/
1601 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1602 const struct api_struct *api_rpc_cmds, int n_cmds)
1604 int fn_num;
1605 uint32_t offset1;
1607 /* interpret the command */
1608 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1609 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1610 pkt->u.request.opnum));
1612 if (DEBUGLEVEL >= 50) {
1613 fstring name;
1614 slprintf(name, sizeof(name)-1, "in_%s",
1615 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1616 dump_pdu_region(name, pkt->u.request.opnum,
1617 &p->in_data.data, 0,
1618 p->in_data.data.length);
1621 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1622 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1623 api_rpc_cmds[fn_num].fn != NULL) {
1624 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1625 api_rpc_cmds[fn_num].name));
1626 break;
1630 if (fn_num == n_cmds) {
1632 * For an unknown RPC just return a fault PDU but
1633 * return True to allow RPC's on the pipe to continue
1634 * and not put the pipe into fault state. JRA.
1636 DEBUG(4, ("unknown\n"));
1637 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1638 return True;
1641 offset1 = p->out_data.rdata.length;
1643 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1644 fn_num, api_rpc_cmds[fn_num].fn));
1645 /* do the actual command */
1646 if(!api_rpc_cmds[fn_num].fn(p)) {
1647 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1648 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1649 api_rpc_cmds[fn_num].name));
1650 data_blob_free(&p->out_data.rdata);
1651 return False;
1654 if (p->bad_handle_fault_state) {
1655 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1656 p->bad_handle_fault_state = False;
1657 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1658 return True;
1661 if (p->rng_fault_state) {
1662 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1663 p->rng_fault_state = False;
1664 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1665 return True;
1668 if (DEBUGLEVEL >= 50) {
1669 fstring name;
1670 slprintf(name, sizeof(name)-1, "out_%s",
1671 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1672 dump_pdu_region(name, pkt->u.request.opnum,
1673 &p->out_data.rdata, offset1,
1674 p->out_data.rdata.length);
1677 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1678 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1680 /* Check for buffer underflow in rpc parsing */
1681 if ((DEBUGLEVEL >= 10) &&
1682 (pkt->frag_length < p->in_data.data.length)) {
1683 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1684 dump_data(10, p->in_data.data.data + pkt->frag_length,
1685 p->in_data.data.length - pkt->frag_length);
1688 return True;
1691 /****************************************************************************
1692 Initialise an outgoing packet.
1693 ****************************************************************************/
1695 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1697 output_data *o_data = &p->out_data;
1699 /* Reset the offset counters. */
1700 o_data->data_sent_length = 0;
1701 o_data->current_pdu_sent = 0;
1703 data_blob_free(&o_data->frag);
1705 /* Free any memory in the current return data buffer. */
1706 data_blob_free(&o_data->rdata);
1708 return True;
1711 /****************************************************************************
1712 Sets the fault state on incoming packets.
1713 ****************************************************************************/
1715 void set_incoming_fault(struct pipes_struct *p)
1717 data_blob_free(&p->in_data.data);
1718 p->in_data.pdu_needed_len = 0;
1719 p->in_data.pdu.length = 0;
1720 p->fault_state = True;
1721 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1722 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1725 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1726 struct ncacn_packet *pkt,
1727 DATA_BLOB *raw_pkt)
1729 NTSTATUS status;
1730 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1731 size_t pad_len;
1733 DEBUG(10, ("Checking request auth.\n"));
1735 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1736 hdr_size += 16;
1739 /* in case of sealing this function will unseal the data in place */
1740 status = dcerpc_check_auth(auth, pkt,
1741 &pkt->u.request.stub_and_verifier,
1742 hdr_size, raw_pkt,
1743 &pad_len);
1744 if (!NT_STATUS_IS_OK(status)) {
1745 return status;
1749 /* remove padding and auth trailer,
1750 * this way the caller will get just the data */
1751 if (pkt->auth_length) {
1752 size_t trail_len = pad_len
1753 + DCERPC_AUTH_TRAILER_LENGTH
1754 + pkt->auth_length;
1755 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1756 return NT_STATUS_INFO_LENGTH_MISMATCH;
1758 pkt->u.request.stub_and_verifier.length -= trail_len;
1761 return NT_STATUS_OK;
1764 /****************************************************************************
1765 Processes a request pdu. This will do auth processing if needed, and
1766 appends the data into the complete stream if the LAST flag is not set.
1767 ****************************************************************************/
1769 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1771 NTSTATUS status;
1772 DATA_BLOB data;
1774 if (!p->pipe_bound) {
1775 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1776 set_incoming_fault(p);
1777 return False;
1780 /* Store the opnum */
1781 p->opnum = pkt->u.request.opnum;
1783 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1784 if (!NT_STATUS_IS_OK(status)) {
1785 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1786 nt_errstr(status)));
1787 set_incoming_fault(p);
1788 return false;
1791 data = pkt->u.request.stub_and_verifier;
1794 * Check the data length doesn't go over the 15Mb limit.
1795 * increased after observing a bug in the Windows NT 4.0 SP6a
1796 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1797 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1800 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1801 DEBUG(0, ("process_request_pdu: "
1802 "rpc data buffer too large (%u) + (%u)\n",
1803 (unsigned int)p->in_data.data.length,
1804 (unsigned int)data.length));
1805 set_incoming_fault(p);
1806 return False;
1810 * Append the data portion into the buffer and return.
1813 if (data.length) {
1814 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1815 data.data, data.length)) {
1816 DEBUG(0, ("Unable to append data size %u "
1817 "to parse buffer of size %u.\n",
1818 (unsigned int)data.length,
1819 (unsigned int)p->in_data.data.length));
1820 set_incoming_fault(p);
1821 return False;
1825 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1826 bool ret = False;
1828 * Ok - we finally have a complete RPC stream.
1829 * Call the rpc command to process it.
1833 * Process the complete data stream here.
1835 if (pipe_init_outgoing_data(p)) {
1836 ret = api_pipe_request(p, pkt);
1839 return ret;
1842 return True;
1845 /****************************************************************************
1846 Processes a finished PDU stored in p->in_data.pdu.
1847 ****************************************************************************/
1849 void process_complete_pdu(struct pipes_struct *p)
1851 struct ncacn_packet *pkt = NULL;
1852 NTSTATUS status;
1853 bool reply = False;
1855 if(p->fault_state) {
1856 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
1857 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1858 goto done;
1861 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1862 if (!pkt) {
1863 DEBUG(0, ("Out of memory!\n"));
1864 goto done;
1868 * Ensure we're using the corrent endianness for both the
1869 * RPC header flags and the raw data we will be reading from.
1871 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1872 p->endian = RPC_LITTLE_ENDIAN;
1873 } else {
1874 p->endian = RPC_BIG_ENDIAN;
1876 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1878 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1879 pkt, p->endian);
1880 if (!NT_STATUS_IS_OK(status)) {
1881 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1882 nt_errstr(status)));
1883 goto done;
1886 /* Store the call_id */
1887 p->call_id = pkt->call_id;
1889 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
1891 switch (pkt->ptype) {
1892 case DCERPC_PKT_REQUEST:
1893 reply = process_request_pdu(p, pkt);
1894 break;
1896 case DCERPC_PKT_PING: /* CL request - ignore... */
1897 DEBUG(0, ("process_complete_pdu: Error. "
1898 "Connectionless packet type %d received on "
1899 "pipe %s.\n", (int)pkt->ptype,
1900 get_pipe_name_from_syntax(talloc_tos(),
1901 &p->syntax)));
1902 break;
1904 case DCERPC_PKT_RESPONSE: /* No responses here. */
1905 DEBUG(0, ("process_complete_pdu: Error. "
1906 "DCERPC_PKT_RESPONSE received from client "
1907 "on pipe %s.\n",
1908 get_pipe_name_from_syntax(talloc_tos(),
1909 &p->syntax)));
1910 break;
1912 case DCERPC_PKT_FAULT:
1913 case DCERPC_PKT_WORKING:
1914 /* CL request - reply to a ping when a call in process. */
1915 case DCERPC_PKT_NOCALL:
1916 /* CL - server reply to a ping call. */
1917 case DCERPC_PKT_REJECT:
1918 case DCERPC_PKT_ACK:
1919 case DCERPC_PKT_CL_CANCEL:
1920 case DCERPC_PKT_FACK:
1921 case DCERPC_PKT_CANCEL_ACK:
1922 DEBUG(0, ("process_complete_pdu: Error. "
1923 "Connectionless packet type %u received on "
1924 "pipe %s.\n", (unsigned int)pkt->ptype,
1925 get_pipe_name_from_syntax(talloc_tos(),
1926 &p->syntax)));
1927 break;
1929 case DCERPC_PKT_BIND:
1931 * We assume that a pipe bind is only in one pdu.
1933 if (pipe_init_outgoing_data(p)) {
1934 reply = api_pipe_bind_req(p, pkt);
1936 break;
1938 case DCERPC_PKT_BIND_ACK:
1939 case DCERPC_PKT_BIND_NAK:
1940 DEBUG(0, ("process_complete_pdu: Error. "
1941 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1942 "packet type %u received on pipe %s.\n",
1943 (unsigned int)pkt->ptype,
1944 get_pipe_name_from_syntax(talloc_tos(),
1945 &p->syntax)));
1946 break;
1949 case DCERPC_PKT_ALTER:
1951 * We assume that a pipe bind is only in one pdu.
1953 if (pipe_init_outgoing_data(p)) {
1954 reply = api_pipe_alter_context(p, pkt);
1956 break;
1958 case DCERPC_PKT_ALTER_RESP:
1959 DEBUG(0, ("process_complete_pdu: Error. "
1960 "DCERPC_PKT_ALTER_RESP on pipe %s: "
1961 "Should only be server -> client.\n",
1962 get_pipe_name_from_syntax(talloc_tos(),
1963 &p->syntax)));
1964 break;
1966 case DCERPC_PKT_AUTH3:
1968 * The third packet in an auth exchange.
1970 if (pipe_init_outgoing_data(p)) {
1971 reply = api_pipe_bind_auth3(p, pkt);
1973 break;
1975 case DCERPC_PKT_SHUTDOWN:
1976 DEBUG(0, ("process_complete_pdu: Error. "
1977 "DCERPC_PKT_SHUTDOWN on pipe %s: "
1978 "Should only be server -> client.\n",
1979 get_pipe_name_from_syntax(talloc_tos(),
1980 &p->syntax)));
1981 break;
1983 case DCERPC_PKT_CO_CANCEL:
1984 /* For now just free all client data and continue
1985 * processing. */
1986 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1987 " Abandoning rpc call.\n"));
1988 /* As we never do asynchronous RPC serving, we can
1989 * never cancel a call (as far as I know).
1990 * If we ever did we'd have to send a cancel_ack reply.
1991 * For now, just free all client data and continue
1992 * processing. */
1993 reply = True;
1994 break;
1996 #if 0
1997 /* Enable this if we're doing async rpc. */
1998 /* We must check the outstanding callid matches. */
1999 if (pipe_init_outgoing_data(p)) {
2000 /* Send a cancel_ack PDU reply. */
2001 /* We should probably check the auth-verifier here. */
2002 reply = setup_cancel_ack_reply(p, pkt);
2004 break;
2005 #endif
2007 case DCERPC_PKT_ORPHANED:
2008 /* We should probably check the auth-verifier here.
2009 * For now just free all client data and continue
2010 * processing. */
2011 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
2012 " Abandoning rpc call.\n"));
2013 reply = True;
2014 break;
2016 default:
2017 DEBUG(0, ("process_complete_pdu: "
2018 "Unknown rpc type = %u received.\n",
2019 (unsigned int)pkt->ptype));
2020 break;
2023 done:
2024 if (!reply) {
2025 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
2026 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
2027 &p->syntax)));
2028 set_incoming_fault(p);
2029 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
2030 TALLOC_FREE(pkt);
2031 } else {
2033 * Reset the lengths. We're ready for a new pdu.
2035 TALLOC_FREE(p->in_data.pdu.data);
2036 p->in_data.pdu_needed_len = 0;
2037 p->in_data.pdu.length = 0;
2040 TALLOC_FREE(pkt);