s3: Fix the build of vfs_aixacl2.c
[Samba.git] / source3 / rpc_server / srv_pipe.c
blobcb50573f4aed91d410987ccb8b28e8d635af8ec1
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"
44 #include "rpc_server/srv_pipe.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 context_id)
336 struct pipe_rpc_fns *context_fns;
338 DEBUG(3,("check_bind_req for %s\n",
339 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
341 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
342 if (rpc_srv_pipe_exists_by_id(abstract) &&
343 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
344 DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
345 rpc_srv_get_pipe_cli_name(abstract),
346 rpc_srv_get_pipe_srv_name(abstract)));
347 } else {
348 return false;
351 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
352 if (context_fns == NULL) {
353 DEBUG(0,("check_bind_req: malloc() failed!\n"));
354 return False;
357 context_fns->next = context_fns->prev = NULL;
358 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
359 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
360 context_fns->context_id = context_id;
362 /* add to the list of open contexts */
364 DLIST_ADD( p->contexts, context_fns );
366 return True;
370 * Is a named pipe known?
371 * @param[in] cli_filename The pipe name requested by the client
372 * @result Do we want to serve this?
374 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
376 const char *pipename = cli_filename;
377 NTSTATUS status;
379 if (strnequal(pipename, "\\PIPE\\", 6)) {
380 pipename += 5;
383 if (*pipename == '\\') {
384 pipename += 1;
387 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
388 DEBUG(10, ("refusing spoolss access\n"));
389 return false;
392 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
393 return true;
396 status = smb_probe_module("rpc", pipename);
397 if (!NT_STATUS_IS_OK(status)) {
398 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
399 return false;
401 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
404 * Scan the list again for the interface id
406 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
407 return true;
410 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
411 pipename));
413 return false;
416 /*******************************************************************
417 Handle the first part of a SPNEGO bind auth.
418 *******************************************************************/
420 static bool pipe_spnego_auth_bind(struct pipes_struct *p,
421 TALLOC_CTX *mem_ctx,
422 struct dcerpc_auth *auth_info,
423 DATA_BLOB *response)
425 struct spnego_context *spnego_ctx;
426 NTSTATUS status;
428 status = spnego_server_auth_start(p,
429 (auth_info->auth_level ==
430 DCERPC_AUTH_LEVEL_INTEGRITY),
431 (auth_info->auth_level ==
432 DCERPC_AUTH_LEVEL_PRIVACY),
433 true,
434 &auth_info->credentials,
435 response,
436 &spnego_ctx);
437 if (!NT_STATUS_IS_OK(status)) {
438 DEBUG(0, ("Failed SPNEGO negotiate (%s)\n",
439 nt_errstr(status)));
440 return false;
443 /* Make sure data is bound to the memctx, to be freed the caller */
444 talloc_steal(mem_ctx, response->data);
446 p->auth.auth_ctx = spnego_ctx;
447 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
449 DEBUG(10, ("SPNEGO auth started\n"));
451 return true;
454 /*******************************************************************
455 Handle an schannel bind auth.
456 *******************************************************************/
458 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
459 TALLOC_CTX *mem_ctx,
460 struct dcerpc_auth *auth_info,
461 DATA_BLOB *response)
463 struct NL_AUTH_MESSAGE neg;
464 struct NL_AUTH_MESSAGE reply;
465 bool ret;
466 NTSTATUS status;
467 struct netlogon_creds_CredentialState *creds;
468 enum ndr_err_code ndr_err;
469 struct schannel_state *schannel_auth;
471 ndr_err = ndr_pull_struct_blob(
472 &auth_info->credentials, mem_ctx, &neg,
473 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
474 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
475 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
476 return false;
479 if (DEBUGLEVEL >= 10) {
480 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
483 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
484 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
485 return false;
489 * The neg.oem_netbios_computer.a key here must match the remote computer name
490 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
491 * operations that use credentials.
494 become_root();
495 status = schannel_get_creds_state(p, lp_private_dir(),
496 neg.oem_netbios_computer.a, &creds);
497 unbecome_root();
499 if (!NT_STATUS_IS_OK(status)) {
500 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
501 return False;
504 schannel_auth = talloc(p, struct schannel_state);
505 if (!schannel_auth) {
506 TALLOC_FREE(creds);
507 return False;
510 schannel_auth->state = SCHANNEL_STATE_START;
511 schannel_auth->seq_num = 0;
512 schannel_auth->initiator = false;
513 schannel_auth->creds = creds;
516 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
517 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
518 * struct of the person who opened the pipe. I need to test this further. JRA.
520 * VL. As we are mapping this to guest set the generic key
521 * "SystemLibraryDTC" key here. It's a bit difficult to test against
522 * W2k3, as it does not allow schannel binds against SAMR and LSA
523 * anymore.
526 ret = session_info_set_session_key(p->session_info, generic_session_key());
528 if (!ret) {
529 DEBUG(0, ("session_info_set_session_key failed\n"));
530 return false;
533 /*** SCHANNEL verifier ***/
535 reply.MessageType = NL_NEGOTIATE_RESPONSE;
536 reply.Flags = 0;
537 reply.Buffer.dummy = 5; /* ??? actually I don't think
538 * this has any meaning
539 * here - gd */
541 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
542 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
543 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
544 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
545 return false;
548 if (DEBUGLEVEL >= 10) {
549 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
552 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
553 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
555 /* We're finished with this bind - no more packets. */
556 p->auth.auth_ctx = schannel_auth;
557 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
559 p->pipe_bound = True;
561 return True;
564 /*******************************************************************
565 Handle an NTLMSSP bind auth.
566 *******************************************************************/
568 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
569 TALLOC_CTX *mem_ctx,
570 struct dcerpc_auth *auth_info,
571 DATA_BLOB *response)
573 struct auth_ntlmssp_state *ntlmssp_state = NULL;
574 NTSTATUS status;
576 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
577 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
578 return false;
581 /* We have an NTLMSSP blob. */
582 status = ntlmssp_server_auth_start(p,
583 (auth_info->auth_level ==
584 DCERPC_AUTH_LEVEL_INTEGRITY),
585 (auth_info->auth_level ==
586 DCERPC_AUTH_LEVEL_PRIVACY),
587 true,
588 &auth_info->credentials,
589 response,
590 &ntlmssp_state);
591 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
592 DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
593 nt_errstr(status)));
594 return false;
597 /* Make sure data is bound to the memctx, to be freed the caller */
598 talloc_steal(mem_ctx, response->data);
600 p->auth.auth_ctx = ntlmssp_state;
601 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
603 DEBUG(10, (__location__ ": NTLMSSP auth started\n"));
605 return true;
608 /*******************************************************************
609 Process an NTLMSSP authentication response.
610 If this function succeeds, the user has been authenticated
611 and their domain, name and calling workstation stored in
612 the pipe struct.
613 *******************************************************************/
615 static bool pipe_ntlmssp_verify_final(TALLOC_CTX *mem_ctx,
616 struct auth_ntlmssp_state *ntlmssp_ctx,
617 enum dcerpc_AuthLevel auth_level,
618 struct client_address *client_id,
619 struct ndr_syntax_id *syntax,
620 struct auth_serversupplied_info **session_info)
622 NTSTATUS status;
623 bool ret;
625 DEBUG(5, (__location__ ": pipe %s checking user details\n",
626 get_pipe_name_from_syntax(talloc_tos(), syntax)));
628 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
629 ensure the underlying NTLMSSP flags are also set. If not we should
630 refuse the bind. */
632 status = ntlmssp_server_check_flags(ntlmssp_ctx,
633 (auth_level ==
634 DCERPC_AUTH_LEVEL_INTEGRITY),
635 (auth_level ==
636 DCERPC_AUTH_LEVEL_PRIVACY));
637 if (!NT_STATUS_IS_OK(status)) {
638 DEBUG(0, (__location__ ": Client failed to negotatie proper "
639 "security for pipe %s\n",
640 get_pipe_name_from_syntax(talloc_tos(), syntax)));
641 return false;
644 TALLOC_FREE(*session_info);
646 status = ntlmssp_server_get_user_info(ntlmssp_ctx,
647 mem_ctx, session_info);
648 if (!NT_STATUS_IS_OK(status)) {
649 DEBUG(0, (__location__ ": failed to obtain the server info "
650 "for authenticated user: %s\n", nt_errstr(status)));
651 return false;
654 if ((*session_info)->security_token == NULL) {
655 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
656 return false;
660 * We're an authenticated bind over smb, so the session key needs to
661 * be set to "SystemLibraryDTC". Weird, but this is what Windows
662 * does. See the RPC-SAMBA3SESSIONKEY.
665 ret = session_info_set_session_key((*session_info), generic_session_key());
666 if (!ret) {
667 DEBUG(0, ("Failed to set session key!\n"));
668 return false;
671 return true;
674 /*******************************************************************
675 Handle a GSSAPI bind auth.
676 *******************************************************************/
678 static bool pipe_gssapi_auth_bind(struct pipes_struct *p,
679 TALLOC_CTX *mem_ctx,
680 struct dcerpc_auth *auth_info,
681 DATA_BLOB *response)
683 NTSTATUS status;
684 struct gse_context *gse_ctx = NULL;
686 status = gssapi_server_auth_start(p,
687 (auth_info->auth_level ==
688 DCERPC_AUTH_LEVEL_INTEGRITY),
689 (auth_info->auth_level ==
690 DCERPC_AUTH_LEVEL_PRIVACY),
691 true,
692 &auth_info->credentials,
693 response,
694 &gse_ctx);
695 if (!NT_STATUS_IS_OK(status)) {
696 DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
697 nt_errstr(status)));
698 goto err;
701 /* Make sure data is bound to the memctx, to be freed the caller */
702 talloc_steal(mem_ctx, response->data);
704 p->auth.auth_ctx = gse_ctx;
705 p->auth.auth_type = DCERPC_AUTH_TYPE_KRB5;
707 DEBUG(10, ("KRB5 auth started\n"));
709 return true;
711 err:
712 TALLOC_FREE(gse_ctx);
713 return false;
716 static NTSTATUS pipe_gssapi_verify_final(TALLOC_CTX *mem_ctx,
717 struct gse_context *gse_ctx,
718 struct client_address *client_id,
719 struct auth_serversupplied_info **session_info)
721 NTSTATUS status;
722 bool bret;
724 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
725 ensure the underlying flags are also set. If not we should
726 refuse the bind. */
728 status = gssapi_server_check_flags(gse_ctx);
729 if (!NT_STATUS_IS_OK(status)) {
730 DEBUG(0, ("Requested Security Layers not honored!\n"));
731 return status;
734 status = gssapi_server_get_user_info(gse_ctx, mem_ctx,
735 client_id, session_info);
736 if (!NT_STATUS_IS_OK(status)) {
737 DEBUG(0, (__location__ ": failed to obtain the server info "
738 "for authenticated user: %s\n", nt_errstr(status)));
739 return status;
742 if ((*session_info)->security_token == NULL) {
743 status = create_local_token(*session_info);
744 if (!NT_STATUS_IS_OK(status)) {
745 DEBUG(1, ("Failed to create local user token (%s)\n",
746 nt_errstr(status)));
747 status = NT_STATUS_ACCESS_DENIED;
748 return status;
752 /* TODO: this is what the ntlmssp code does with the session_key, check
753 * it is ok with gssapi too */
755 * We're an authenticated bind over smb, so the session key needs to
756 * be set to "SystemLibraryDTC". Weird, but this is what Windows
757 * does. See the RPC-SAMBA3SESSIONKEY.
760 bret = session_info_set_session_key((*session_info), generic_session_key());
761 if (!bret) {
762 return NT_STATUS_ACCESS_DENIED;
765 return NT_STATUS_OK;
768 static NTSTATUS pipe_auth_verify_final(struct pipes_struct *p)
770 enum spnego_mech auth_type;
771 struct auth_ntlmssp_state *ntlmssp_ctx;
772 struct spnego_context *spnego_ctx;
773 struct gse_context *gse_ctx;
774 void *mech_ctx;
775 NTSTATUS status;
777 switch (p->auth.auth_type) {
778 case DCERPC_AUTH_TYPE_NTLMSSP:
779 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
780 struct auth_ntlmssp_state);
781 if (!pipe_ntlmssp_verify_final(p, ntlmssp_ctx,
782 p->auth.auth_level,
783 p->client_id, &p->syntax,
784 &p->session_info)) {
785 return NT_STATUS_ACCESS_DENIED;
787 break;
788 case DCERPC_AUTH_TYPE_KRB5:
789 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
790 struct gse_context);
791 status = pipe_gssapi_verify_final(p, gse_ctx,
792 p->client_id,
793 &p->session_info);
794 if (!NT_STATUS_IS_OK(status)) {
795 DEBUG(1, ("gssapi bind failed with: %s",
796 nt_errstr(status)));
797 return status;
799 break;
800 case DCERPC_AUTH_TYPE_SPNEGO:
801 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
802 struct spnego_context);
803 status = spnego_get_negotiated_mech(spnego_ctx,
804 &auth_type, &mech_ctx);
805 if (!NT_STATUS_IS_OK(status)) {
806 DEBUG(0, ("Bad SPNEGO state (%s)\n",
807 nt_errstr(status)));
808 return status;
810 switch(auth_type) {
811 case SPNEGO_KRB5:
812 gse_ctx = talloc_get_type_abort(mech_ctx,
813 struct gse_context);
814 status = pipe_gssapi_verify_final(p, gse_ctx,
815 p->client_id,
816 &p->session_info);
817 if (!NT_STATUS_IS_OK(status)) {
818 DEBUG(1, ("gssapi bind failed with: %s",
819 nt_errstr(status)));
820 return status;
822 break;
823 case SPNEGO_NTLMSSP:
824 ntlmssp_ctx = talloc_get_type_abort(mech_ctx,
825 struct auth_ntlmssp_state);
826 if (!pipe_ntlmssp_verify_final(p, ntlmssp_ctx,
827 p->auth.auth_level,
828 p->client_id,
829 &p->syntax,
830 &p->session_info)) {
831 return NT_STATUS_ACCESS_DENIED;
833 break;
834 default:
835 DEBUG(0, (__location__ ": incorrect spnego type "
836 "(%d).\n", auth_type));
837 return NT_STATUS_ACCESS_DENIED;
839 break;
840 default:
841 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
842 (unsigned int)p->auth.auth_type));
843 return NT_STATUS_ACCESS_DENIED;
846 p->pipe_bound = true;
848 return NT_STATUS_OK;
851 /*******************************************************************
852 Respond to a pipe bind request.
853 *******************************************************************/
855 static bool api_pipe_bind_req(struct pipes_struct *p,
856 struct ncacn_packet *pkt)
858 struct dcerpc_auth auth_info;
859 uint16 assoc_gid;
860 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
861 NTSTATUS status;
862 struct ndr_syntax_id id;
863 union dcerpc_payload u;
864 struct dcerpc_ack_ctx bind_ack_ctx;
865 DATA_BLOB auth_resp = data_blob_null;
866 DATA_BLOB auth_blob = data_blob_null;
868 /* No rebinds on a bound pipe - use alter context. */
869 if (p->pipe_bound) {
870 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
871 "pipe %s.\n",
872 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
873 return setup_bind_nak(p, pkt);
876 if (pkt->u.bind.num_contexts == 0) {
877 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
878 goto err_exit;
882 * Try and find the correct pipe name to ensure
883 * that this is a pipe name we support.
885 id = pkt->u.bind.ctx_list[0].abstract_syntax;
886 if (rpc_srv_pipe_exists_by_id(&id)) {
887 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
888 rpc_srv_get_pipe_cli_name(&id),
889 rpc_srv_get_pipe_srv_name(&id)));
890 } else {
891 status = smb_probe_module(
892 "rpc", get_pipe_name_from_syntax(
893 talloc_tos(),
894 &pkt->u.bind.ctx_list[0].abstract_syntax));
896 if (NT_STATUS_IS_ERR(status)) {
897 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
898 get_pipe_name_from_syntax(
899 talloc_tos(),
900 &pkt->u.bind.ctx_list[0].abstract_syntax)));
902 return setup_bind_nak(p, pkt);
905 if (rpc_srv_get_pipe_interface_by_cli_name(
906 get_pipe_name_from_syntax(talloc_tos(),
907 &p->syntax),
908 &id)) {
909 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
910 rpc_srv_get_pipe_cli_name(&id),
911 rpc_srv_get_pipe_srv_name(&id)));
912 } else {
913 DEBUG(0, ("module %s doesn't provide functions for "
914 "pipe %s!\n",
915 get_pipe_name_from_syntax(talloc_tos(),
916 &p->syntax),
917 get_pipe_name_from_syntax(talloc_tos(),
918 &p->syntax)));
919 return setup_bind_nak(p, pkt);
923 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
925 if (pkt->u.bind.assoc_group_id != 0) {
926 assoc_gid = pkt->u.bind.assoc_group_id;
927 } else {
928 assoc_gid = 0x53f0;
932 * Create the bind response struct.
935 /* If the requested abstract synt uuid doesn't match our client pipe,
936 reject the bind_ack & set the transfer interface synt to all 0's,
937 ver 0 (observed when NT5 attempts to bind to abstract interfaces
938 unknown to NT4)
939 Needed when adding entries to a DACL from NT5 - SK */
941 if (check_bind_req(p,
942 &pkt->u.bind.ctx_list[0].abstract_syntax,
943 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
944 pkt->u.bind.ctx_list[0].context_id)) {
946 bind_ack_ctx.result = 0;
947 bind_ack_ctx.reason = 0;
948 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
949 } else {
950 p->pipe_bound = False;
951 /* Rejection reason: abstract syntax not supported */
952 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
953 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
954 bind_ack_ctx.syntax = null_ndr_syntax_id;
958 * Check if this is an authenticated bind request.
960 if (pkt->auth_length) {
961 /* Quick length check. Won't catch a bad auth footer,
962 * prevents overrun. */
964 if (pkt->frag_length < RPC_HEADER_LEN +
965 DCERPC_AUTH_TRAILER_LENGTH +
966 pkt->auth_length) {
967 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
968 "too long for fragment %u.\n",
969 (unsigned int)pkt->auth_length,
970 (unsigned int)pkt->frag_length));
971 goto err_exit;
975 * Decode the authentication verifier.
977 status = dcerpc_pull_dcerpc_auth(pkt,
978 &pkt->u.bind.auth_info,
979 &auth_info, p->endian);
980 if (!NT_STATUS_IS_OK(status)) {
981 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
982 goto err_exit;
985 auth_type = auth_info.auth_type;
987 /* Work out if we have to sign or seal etc. */
988 switch (auth_info.auth_level) {
989 case DCERPC_AUTH_LEVEL_INTEGRITY:
990 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
991 break;
992 case DCERPC_AUTH_LEVEL_PRIVACY:
993 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
994 break;
995 case DCERPC_AUTH_LEVEL_CONNECT:
996 p->auth.auth_level = DCERPC_AUTH_LEVEL_CONNECT;
997 break;
998 default:
999 DEBUG(0, ("Unexpected auth level (%u).\n",
1000 (unsigned int)auth_info.auth_level ));
1001 goto err_exit;
1004 switch (auth_type) {
1005 case DCERPC_AUTH_TYPE_NTLMSSP:
1006 if (!pipe_ntlmssp_auth_bind(p, pkt,
1007 &auth_info, &auth_resp)) {
1008 goto err_exit;
1010 assoc_gid = 0x7a77;
1011 break;
1013 case DCERPC_AUTH_TYPE_SCHANNEL:
1014 if (!pipe_schannel_auth_bind(p, pkt,
1015 &auth_info, &auth_resp)) {
1016 goto err_exit;
1018 break;
1020 case DCERPC_AUTH_TYPE_SPNEGO:
1021 if (!pipe_spnego_auth_bind(p, pkt,
1022 &auth_info, &auth_resp)) {
1023 goto err_exit;
1025 break;
1027 case DCERPC_AUTH_TYPE_KRB5:
1028 if (!pipe_gssapi_auth_bind(p, pkt,
1029 &auth_info, &auth_resp)) {
1030 goto err_exit;
1032 break;
1034 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1035 if (p->transport == NCALRPC && p->ncalrpc_as_system) {
1036 TALLOC_FREE(p->session_info);
1038 status = make_session_info_system(p,
1039 &p->session_info);
1040 if (!NT_STATUS_IS_OK(status)) {
1041 goto err_exit;
1044 auth_resp = data_blob_talloc(pkt,
1045 "NCALRPC_AUTH_OK",
1046 15);
1048 p->auth.auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
1049 p->pipe_bound = true;
1050 } else {
1051 goto err_exit;
1053 break;
1055 case DCERPC_AUTH_TYPE_NONE:
1056 break;
1058 default:
1059 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1060 goto err_exit;
1064 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1065 /* Unauthenticated bind request. */
1066 /* We're finished - no more packets. */
1067 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1068 /* We must set the pipe auth_level here also. */
1069 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1070 p->pipe_bound = True;
1071 /* The session key was initialized from the SMB
1072 * session in make_internal_rpc_pipe_p */
1075 ZERO_STRUCT(u.bind_ack);
1076 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1077 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1078 u.bind_ack.assoc_group_id = assoc_gid;
1080 /* name has to be \PIPE\xxxxx */
1081 u.bind_ack.secondary_address =
1082 talloc_asprintf(pkt, "\\PIPE\\%s",
1083 rpc_srv_get_pipe_srv_name(&id));
1084 if (!u.bind_ack.secondary_address) {
1085 DEBUG(0, ("Out of memory!\n"));
1086 goto err_exit;
1088 u.bind_ack.secondary_address_size =
1089 strlen(u.bind_ack.secondary_address) + 1;
1091 u.bind_ack.num_results = 1;
1092 u.bind_ack.ctx_list = &bind_ack_ctx;
1094 /* NOTE: We leave the auth_info empty so we can calculate the padding
1095 * later and then append the auth_info --simo */
1098 * Marshall directly into the outgoing PDU space. We
1099 * must do this as we need to set to the bind response
1100 * header and are never sending more than one PDU here.
1103 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1104 DCERPC_PKT_BIND_ACK,
1105 DCERPC_PFC_FLAG_FIRST |
1106 DCERPC_PFC_FLAG_LAST,
1107 auth_resp.length,
1108 pkt->call_id,
1110 &p->out_data.frag);
1111 if (!NT_STATUS_IS_OK(status)) {
1112 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1113 nt_errstr(status)));
1116 if (auth_resp.length) {
1118 status = dcerpc_push_dcerpc_auth(pkt,
1119 auth_type,
1120 auth_info.auth_level,
1122 1, /* auth_context_id */
1123 &auth_resp,
1124 &auth_blob);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1127 goto err_exit;
1131 /* Now that we have the auth len store it into the right place in
1132 * the dcerpc header */
1133 dcerpc_set_frag_length(&p->out_data.frag,
1134 p->out_data.frag.length + auth_blob.length);
1136 if (auth_blob.length) {
1138 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1139 auth_blob.data, auth_blob.length)) {
1140 DEBUG(0, ("Append of auth info failed.\n"));
1141 goto err_exit;
1146 * Setup the lengths for the initial reply.
1149 p->out_data.data_sent_length = 0;
1150 p->out_data.current_pdu_sent = 0;
1152 TALLOC_FREE(auth_blob.data);
1153 return True;
1155 err_exit:
1157 data_blob_free(&p->out_data.frag);
1158 TALLOC_FREE(auth_blob.data);
1159 return setup_bind_nak(p, pkt);
1162 /*******************************************************************
1163 This is the "stage3" response after a bind request and reply.
1164 *******************************************************************/
1166 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
1168 struct dcerpc_auth auth_info;
1169 DATA_BLOB response = data_blob_null;
1170 struct auth_ntlmssp_state *ntlmssp_ctx;
1171 struct spnego_context *spnego_ctx;
1172 struct gse_context *gse_ctx;
1173 NTSTATUS status;
1175 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
1177 if (pkt->auth_length == 0) {
1178 DEBUG(0, ("No auth field sent for bind request!\n"));
1179 goto err;
1182 /* Ensure there's enough data for an authenticated request. */
1183 if (pkt->frag_length < RPC_HEADER_LEN
1184 + DCERPC_AUTH_TRAILER_LENGTH
1185 + pkt->auth_length) {
1186 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
1187 "%u is too large.\n",
1188 (unsigned int)pkt->auth_length));
1189 goto err;
1193 * Decode the authentication verifier response.
1196 status = dcerpc_pull_dcerpc_auth(pkt,
1197 &pkt->u.auth3.auth_info,
1198 &auth_info, p->endian);
1199 if (!NT_STATUS_IS_OK(status)) {
1200 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
1201 goto err;
1204 /* We must NEVER look at auth_info->auth_pad_len here,
1205 * as old Samba client code gets it wrong and sends it
1206 * as zero. JRA.
1209 if (auth_info.auth_type != p->auth.auth_type) {
1210 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1211 "but auth was started as type %d!\n",
1212 auth_info.auth_type, p->auth.auth_type));
1213 goto err;
1216 switch (auth_info.auth_type) {
1217 case DCERPC_AUTH_TYPE_NTLMSSP:
1218 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1219 struct auth_ntlmssp_state);
1220 status = ntlmssp_server_step(ntlmssp_ctx,
1221 pkt, &auth_info.credentials,
1222 &response);
1223 break;
1224 case DCERPC_AUTH_TYPE_KRB5:
1225 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1226 struct gse_context);
1227 status = gssapi_server_step(gse_ctx,
1228 pkt, &auth_info.credentials,
1229 &response);
1230 break;
1231 case DCERPC_AUTH_TYPE_SPNEGO:
1232 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1233 struct spnego_context);
1234 status = spnego_server_step(spnego_ctx,
1235 pkt, &auth_info.credentials,
1236 &response);
1237 break;
1238 default:
1239 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
1240 (unsigned int)auth_info.auth_type));
1241 return false;
1244 if (NT_STATUS_EQUAL(status,
1245 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
1246 response.length) {
1247 DEBUG(0, (__location__ ": This was supposed to be the final "
1248 "leg, but crypto machinery claims a response is "
1249 "needed, aborting auth!\n"));
1250 data_blob_free(&response);
1251 goto err;
1253 if (!NT_STATUS_IS_OK(status)) {
1254 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
1255 goto err;
1258 /* Now verify auth was indeed successful and extract server info */
1259 status = pipe_auth_verify_final(p);
1260 if (!NT_STATUS_IS_OK(status)) {
1261 DEBUG(0, ("Auth Verify failed (%s)\n", nt_errstr(status)));
1262 goto err;
1265 return true;
1267 err:
1269 TALLOC_FREE(p->auth.auth_ctx);
1270 return false;
1273 /****************************************************************************
1274 Deal with an alter context call. Can be third part of 3 leg auth request for
1275 SPNEGO calls.
1276 ****************************************************************************/
1278 static bool api_pipe_alter_context(struct pipes_struct *p,
1279 struct ncacn_packet *pkt)
1281 struct dcerpc_auth auth_info;
1282 uint16 assoc_gid;
1283 NTSTATUS status;
1284 union dcerpc_payload u;
1285 struct dcerpc_ack_ctx bind_ack_ctx;
1286 DATA_BLOB auth_resp = data_blob_null;
1287 DATA_BLOB auth_blob = data_blob_null;
1288 int pad_len = 0;
1289 struct auth_ntlmssp_state *ntlmssp_ctx;
1290 struct spnego_context *spnego_ctx;
1291 struct gse_context *gse_ctx;
1293 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1295 if (pkt->u.bind.assoc_group_id != 0) {
1296 assoc_gid = pkt->u.bind.assoc_group_id;
1297 } else {
1298 assoc_gid = 0x53f0;
1302 * Create the bind response struct.
1305 /* If the requested abstract synt uuid doesn't match our client pipe,
1306 reject the bind_ack & set the transfer interface synt to all 0's,
1307 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1308 unknown to NT4)
1309 Needed when adding entries to a DACL from NT5 - SK */
1311 if (check_bind_req(p,
1312 &pkt->u.bind.ctx_list[0].abstract_syntax,
1313 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1314 pkt->u.bind.ctx_list[0].context_id)) {
1316 bind_ack_ctx.result = 0;
1317 bind_ack_ctx.reason = 0;
1318 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1319 } else {
1320 p->pipe_bound = False;
1321 /* Rejection reason: abstract syntax not supported */
1322 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1323 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1324 bind_ack_ctx.syntax = null_ndr_syntax_id;
1328 * Check if this is an authenticated alter context request.
1330 if (pkt->auth_length) {
1331 /* Quick length check. Won't catch a bad auth footer,
1332 * prevents overrun. */
1334 if (pkt->frag_length < RPC_HEADER_LEN +
1335 DCERPC_AUTH_TRAILER_LENGTH +
1336 pkt->auth_length) {
1337 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1338 "too long for fragment %u.\n",
1339 (unsigned int)pkt->auth_length,
1340 (unsigned int)pkt->frag_length ));
1341 goto err_exit;
1344 status = dcerpc_pull_dcerpc_auth(pkt,
1345 &pkt->u.bind.auth_info,
1346 &auth_info, p->endian);
1347 if (!NT_STATUS_IS_OK(status)) {
1348 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1349 goto err_exit;
1352 /* We can only finish if the pipe is unbound for now */
1353 if (p->pipe_bound) {
1354 DEBUG(0, (__location__ ": Pipe already bound, "
1355 "Altering Context not yet supported!\n"));
1356 goto err_exit;
1359 if (auth_info.auth_type != p->auth.auth_type) {
1360 DEBUG(0, ("Auth type mismatch! Client sent %d, "
1361 "but auth was started as type %d!\n",
1362 auth_info.auth_type, p->auth.auth_type));
1363 goto err_exit;
1367 switch (auth_info.auth_type) {
1368 case DCERPC_AUTH_TYPE_SPNEGO:
1369 spnego_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1370 struct spnego_context);
1371 status = spnego_server_step(spnego_ctx,
1372 pkt,
1373 &auth_info.credentials,
1374 &auth_resp);
1375 break;
1377 case DCERPC_AUTH_TYPE_KRB5:
1378 gse_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1379 struct gse_context);
1380 status = gssapi_server_step(gse_ctx,
1381 pkt,
1382 &auth_info.credentials,
1383 &auth_resp);
1384 break;
1385 case DCERPC_AUTH_TYPE_NTLMSSP:
1386 ntlmssp_ctx = talloc_get_type_abort(p->auth.auth_ctx,
1387 struct auth_ntlmssp_state);
1388 status = ntlmssp_server_step(ntlmssp_ctx,
1389 pkt,
1390 &auth_info.credentials,
1391 &auth_resp);
1392 break;
1394 default:
1395 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1396 "in alter-context call\n",
1397 auth_info.auth_type));
1398 goto err_exit;
1401 if (NT_STATUS_IS_OK(status)) {
1402 /* third leg of auth, verify auth info */
1403 status = pipe_auth_verify_final(p);
1404 if (!NT_STATUS_IS_OK(status)) {
1405 DEBUG(0, ("Auth Verify failed (%s)\n",
1406 nt_errstr(status)));
1407 goto err_exit;
1409 } else if (NT_STATUS_EQUAL(status,
1410 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1411 DEBUG(10, ("More auth legs required.\n"));
1412 } else {
1413 DEBUG(0, ("Auth step returned an error (%s)\n",
1414 nt_errstr(status)));
1415 goto err_exit;
1419 ZERO_STRUCT(u.alter_resp);
1420 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1421 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1422 u.alter_resp.assoc_group_id = assoc_gid;
1424 /* secondary address CAN be NULL
1425 * as the specs say it's ignored.
1426 * It MUST be NULL to have the spoolss working.
1428 u.alter_resp.secondary_address = "";
1429 u.alter_resp.secondary_address_size = 1;
1431 u.alter_resp.num_results = 1;
1432 u.alter_resp.ctx_list = &bind_ack_ctx;
1434 /* NOTE: We leave the auth_info empty so we can calculate the padding
1435 * later and then append the auth_info --simo */
1438 * Marshall directly into the outgoing PDU space. We
1439 * must do this as we need to set to the bind response
1440 * header and are never sending more than one PDU here.
1443 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1444 DCERPC_PKT_ALTER_RESP,
1445 DCERPC_PFC_FLAG_FIRST |
1446 DCERPC_PFC_FLAG_LAST,
1447 auth_resp.length,
1448 pkt->call_id,
1450 &p->out_data.frag);
1451 if (!NT_STATUS_IS_OK(status)) {
1452 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1453 nt_errstr(status)));
1456 if (auth_resp.length) {
1458 /* Work out any padding needed before the auth footer. */
1459 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1460 if (pad_len) {
1461 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1462 DEBUG(10, ("auth pad_len = %u\n",
1463 (unsigned int)pad_len));
1466 status = dcerpc_push_dcerpc_auth(pkt,
1467 auth_info.auth_type,
1468 auth_info.auth_level,
1469 pad_len,
1470 1, /* auth_context_id */
1471 &auth_resp,
1472 &auth_blob);
1473 if (!NT_STATUS_IS_OK(status)) {
1474 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1475 goto err_exit;
1479 /* Now that we have the auth len store it into the right place in
1480 * the dcerpc header */
1481 dcerpc_set_frag_length(&p->out_data.frag,
1482 p->out_data.frag.length +
1483 pad_len + auth_blob.length);
1485 if (auth_resp.length) {
1486 if (pad_len) {
1487 char pad[SERVER_NDR_PADDING_SIZE];
1488 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1489 if (!data_blob_append(p->mem_ctx,
1490 &p->out_data.frag,
1491 pad, pad_len)) {
1492 DEBUG(0, ("api_pipe_bind_req: failed to add "
1493 "%u bytes of pad data.\n",
1494 (unsigned int)pad_len));
1495 goto err_exit;
1499 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1500 auth_blob.data, auth_blob.length)) {
1501 DEBUG(0, ("Append of auth info failed.\n"));
1502 goto err_exit;
1507 * Setup the lengths for the initial reply.
1510 p->out_data.data_sent_length = 0;
1511 p->out_data.current_pdu_sent = 0;
1513 TALLOC_FREE(auth_blob.data);
1514 return True;
1516 err_exit:
1518 data_blob_free(&p->out_data.frag);
1519 TALLOC_FREE(auth_blob.data);
1520 return setup_bind_nak(p, pkt);
1523 /****************************************************************************
1524 Find the set of RPC functions associated with this context_id
1525 ****************************************************************************/
1527 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1529 PIPE_RPC_FNS *fns = NULL;
1531 if ( !list ) {
1532 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1533 return NULL;
1536 for (fns=list; fns; fns=fns->next ) {
1537 if ( fns->context_id == context_id )
1538 return fns;
1540 return NULL;
1543 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1544 const struct api_struct *api_rpc_cmds, int n_cmds);
1546 /****************************************************************************
1547 Find the correct RPC function to call for this request.
1548 If the pipe is authenticated then become the correct UNIX user
1549 before doing the call.
1550 ****************************************************************************/
1552 static bool api_pipe_request(struct pipes_struct *p,
1553 struct ncacn_packet *pkt)
1555 bool ret = False;
1556 bool changed_user = False;
1557 PIPE_RPC_FNS *pipe_fns;
1559 if (p->pipe_bound &&
1560 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1561 (p->auth.auth_type == DCERPC_AUTH_TYPE_KRB5) ||
1562 (p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO))) {
1563 if(!become_authenticated_pipe_user(p->session_info)) {
1564 data_blob_free(&p->out_data.rdata);
1565 return False;
1567 changed_user = True;
1570 DEBUG(5, ("Requested \\PIPE\\%s\n",
1571 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1573 /* get the set of RPC functions for this context */
1575 pipe_fns = find_pipe_fns_by_context(p->contexts,
1576 pkt->u.request.context_id);
1578 if ( pipe_fns ) {
1579 TALLOC_CTX *frame = talloc_stackframe();
1580 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1581 TALLOC_FREE(frame);
1583 else {
1584 DEBUG(0, ("No rpc function table associated with context "
1585 "[%d] on pipe [%s]\n",
1586 pkt->u.request.context_id,
1587 get_pipe_name_from_syntax(talloc_tos(),
1588 &p->syntax)));
1591 if (changed_user) {
1592 unbecome_authenticated_pipe_user();
1595 return ret;
1598 /*******************************************************************
1599 Calls the underlying RPC function for a named pipe.
1600 ********************************************************************/
1602 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1603 const struct api_struct *api_rpc_cmds, int n_cmds)
1605 int fn_num;
1606 uint32_t offset1;
1608 /* interpret the command */
1609 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1610 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1611 pkt->u.request.opnum));
1613 if (DEBUGLEVEL >= 50) {
1614 fstring name;
1615 slprintf(name, sizeof(name)-1, "in_%s",
1616 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1617 dump_pdu_region(name, pkt->u.request.opnum,
1618 &p->in_data.data, 0,
1619 p->in_data.data.length);
1622 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1623 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1624 api_rpc_cmds[fn_num].fn != NULL) {
1625 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1626 api_rpc_cmds[fn_num].name));
1627 break;
1631 if (fn_num == n_cmds) {
1633 * For an unknown RPC just return a fault PDU but
1634 * return True to allow RPC's on the pipe to continue
1635 * and not put the pipe into fault state. JRA.
1637 DEBUG(4, ("unknown\n"));
1638 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1639 return True;
1642 offset1 = p->out_data.rdata.length;
1644 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1645 fn_num, api_rpc_cmds[fn_num].fn));
1646 /* do the actual command */
1647 if(!api_rpc_cmds[fn_num].fn(p)) {
1648 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1649 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1650 api_rpc_cmds[fn_num].name));
1651 data_blob_free(&p->out_data.rdata);
1652 return False;
1655 if (p->bad_handle_fault_state) {
1656 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1657 p->bad_handle_fault_state = False;
1658 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1659 return True;
1662 if (p->rng_fault_state) {
1663 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1664 p->rng_fault_state = False;
1665 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1666 return True;
1669 if (DEBUGLEVEL >= 50) {
1670 fstring name;
1671 slprintf(name, sizeof(name)-1, "out_%s",
1672 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1673 dump_pdu_region(name, pkt->u.request.opnum,
1674 &p->out_data.rdata, offset1,
1675 p->out_data.rdata.length);
1678 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1679 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1681 /* Check for buffer underflow in rpc parsing */
1682 if ((DEBUGLEVEL >= 10) &&
1683 (pkt->frag_length < p->in_data.data.length)) {
1684 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1685 dump_data(10, p->in_data.data.data + pkt->frag_length,
1686 p->in_data.data.length - pkt->frag_length);
1689 return True;
1692 /****************************************************************************
1693 Initialise an outgoing packet.
1694 ****************************************************************************/
1696 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1698 output_data *o_data = &p->out_data;
1700 /* Reset the offset counters. */
1701 o_data->data_sent_length = 0;
1702 o_data->current_pdu_sent = 0;
1704 data_blob_free(&o_data->frag);
1706 /* Free any memory in the current return data buffer. */
1707 data_blob_free(&o_data->rdata);
1709 return True;
1712 /****************************************************************************
1713 Sets the fault state on incoming packets.
1714 ****************************************************************************/
1716 void set_incoming_fault(struct pipes_struct *p)
1718 data_blob_free(&p->in_data.data);
1719 p->in_data.pdu_needed_len = 0;
1720 p->in_data.pdu.length = 0;
1721 p->fault_state = True;
1722 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1723 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1726 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1727 struct ncacn_packet *pkt,
1728 DATA_BLOB *raw_pkt)
1730 NTSTATUS status;
1731 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1732 size_t pad_len;
1734 DEBUG(10, ("Checking request auth.\n"));
1736 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1737 hdr_size += 16;
1740 /* in case of sealing this function will unseal the data in place */
1741 status = dcerpc_check_auth(auth, pkt,
1742 &pkt->u.request.stub_and_verifier,
1743 hdr_size, raw_pkt,
1744 &pad_len);
1745 if (!NT_STATUS_IS_OK(status)) {
1746 return status;
1750 /* remove padding and auth trailer,
1751 * this way the caller will get just the data */
1752 if (pkt->auth_length) {
1753 size_t trail_len = pad_len
1754 + DCERPC_AUTH_TRAILER_LENGTH
1755 + pkt->auth_length;
1756 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1757 return NT_STATUS_INFO_LENGTH_MISMATCH;
1759 pkt->u.request.stub_and_verifier.length -= trail_len;
1762 return NT_STATUS_OK;
1765 /****************************************************************************
1766 Processes a request pdu. This will do auth processing if needed, and
1767 appends the data into the complete stream if the LAST flag is not set.
1768 ****************************************************************************/
1770 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1772 NTSTATUS status;
1773 DATA_BLOB data;
1775 if (!p->pipe_bound) {
1776 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1777 set_incoming_fault(p);
1778 return False;
1781 /* Store the opnum */
1782 p->opnum = pkt->u.request.opnum;
1784 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1785 if (!NT_STATUS_IS_OK(status)) {
1786 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1787 nt_errstr(status)));
1788 set_incoming_fault(p);
1789 return false;
1792 data = pkt->u.request.stub_and_verifier;
1795 * Check the data length doesn't go over the 15Mb limit.
1796 * increased after observing a bug in the Windows NT 4.0 SP6a
1797 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1798 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1801 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1802 DEBUG(0, ("process_request_pdu: "
1803 "rpc data buffer too large (%u) + (%u)\n",
1804 (unsigned int)p->in_data.data.length,
1805 (unsigned int)data.length));
1806 set_incoming_fault(p);
1807 return False;
1811 * Append the data portion into the buffer and return.
1814 if (data.length) {
1815 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1816 data.data, data.length)) {
1817 DEBUG(0, ("Unable to append data size %u "
1818 "to parse buffer of size %u.\n",
1819 (unsigned int)data.length,
1820 (unsigned int)p->in_data.data.length));
1821 set_incoming_fault(p);
1822 return False;
1826 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1827 bool ret = False;
1829 * Ok - we finally have a complete RPC stream.
1830 * Call the rpc command to process it.
1834 * Process the complete data stream here.
1836 if (pipe_init_outgoing_data(p)) {
1837 ret = api_pipe_request(p, pkt);
1840 return ret;
1843 return True;
1846 /****************************************************************************
1847 Processes a finished PDU stored in p->in_data.pdu.
1848 ****************************************************************************/
1850 void process_complete_pdu(struct pipes_struct *p)
1852 struct ncacn_packet *pkt = NULL;
1853 NTSTATUS status;
1854 bool reply = False;
1856 if(p->fault_state) {
1857 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
1858 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1859 goto done;
1862 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1863 if (!pkt) {
1864 DEBUG(0, ("Out of memory!\n"));
1865 goto done;
1869 * Ensure we're using the corrent endianness for both the
1870 * RPC header flags and the raw data we will be reading from.
1872 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1873 p->endian = RPC_LITTLE_ENDIAN;
1874 } else {
1875 p->endian = RPC_BIG_ENDIAN;
1877 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1879 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1880 pkt, p->endian);
1881 if (!NT_STATUS_IS_OK(status)) {
1882 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1883 nt_errstr(status)));
1884 goto done;
1887 /* Store the call_id */
1888 p->call_id = pkt->call_id;
1890 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
1892 switch (pkt->ptype) {
1893 case DCERPC_PKT_REQUEST:
1894 reply = process_request_pdu(p, pkt);
1895 break;
1897 case DCERPC_PKT_PING: /* CL request - ignore... */
1898 DEBUG(0, ("process_complete_pdu: Error. "
1899 "Connectionless packet type %d received on "
1900 "pipe %s.\n", (int)pkt->ptype,
1901 get_pipe_name_from_syntax(talloc_tos(),
1902 &p->syntax)));
1903 break;
1905 case DCERPC_PKT_RESPONSE: /* No responses here. */
1906 DEBUG(0, ("process_complete_pdu: Error. "
1907 "DCERPC_PKT_RESPONSE received from client "
1908 "on pipe %s.\n",
1909 get_pipe_name_from_syntax(talloc_tos(),
1910 &p->syntax)));
1911 break;
1913 case DCERPC_PKT_FAULT:
1914 case DCERPC_PKT_WORKING:
1915 /* CL request - reply to a ping when a call in process. */
1916 case DCERPC_PKT_NOCALL:
1917 /* CL - server reply to a ping call. */
1918 case DCERPC_PKT_REJECT:
1919 case DCERPC_PKT_ACK:
1920 case DCERPC_PKT_CL_CANCEL:
1921 case DCERPC_PKT_FACK:
1922 case DCERPC_PKT_CANCEL_ACK:
1923 DEBUG(0, ("process_complete_pdu: Error. "
1924 "Connectionless packet type %u received on "
1925 "pipe %s.\n", (unsigned int)pkt->ptype,
1926 get_pipe_name_from_syntax(talloc_tos(),
1927 &p->syntax)));
1928 break;
1930 case DCERPC_PKT_BIND:
1932 * We assume that a pipe bind is only in one pdu.
1934 if (pipe_init_outgoing_data(p)) {
1935 reply = api_pipe_bind_req(p, pkt);
1937 break;
1939 case DCERPC_PKT_BIND_ACK:
1940 case DCERPC_PKT_BIND_NAK:
1941 DEBUG(0, ("process_complete_pdu: Error. "
1942 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1943 "packet type %u received on pipe %s.\n",
1944 (unsigned int)pkt->ptype,
1945 get_pipe_name_from_syntax(talloc_tos(),
1946 &p->syntax)));
1947 break;
1950 case DCERPC_PKT_ALTER:
1952 * We assume that a pipe bind is only in one pdu.
1954 if (pipe_init_outgoing_data(p)) {
1955 reply = api_pipe_alter_context(p, pkt);
1957 break;
1959 case DCERPC_PKT_ALTER_RESP:
1960 DEBUG(0, ("process_complete_pdu: Error. "
1961 "DCERPC_PKT_ALTER_RESP on pipe %s: "
1962 "Should only be server -> client.\n",
1963 get_pipe_name_from_syntax(talloc_tos(),
1964 &p->syntax)));
1965 break;
1967 case DCERPC_PKT_AUTH3:
1969 * The third packet in an auth exchange.
1971 if (pipe_init_outgoing_data(p)) {
1972 reply = api_pipe_bind_auth3(p, pkt);
1974 break;
1976 case DCERPC_PKT_SHUTDOWN:
1977 DEBUG(0, ("process_complete_pdu: Error. "
1978 "DCERPC_PKT_SHUTDOWN on pipe %s: "
1979 "Should only be server -> client.\n",
1980 get_pipe_name_from_syntax(talloc_tos(),
1981 &p->syntax)));
1982 break;
1984 case DCERPC_PKT_CO_CANCEL:
1985 /* For now just free all client data and continue
1986 * processing. */
1987 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1988 " Abandoning rpc call.\n"));
1989 /* As we never do asynchronous RPC serving, we can
1990 * never cancel a call (as far as I know).
1991 * If we ever did we'd have to send a cancel_ack reply.
1992 * For now, just free all client data and continue
1993 * processing. */
1994 reply = True;
1995 break;
1997 #if 0
1998 /* Enable this if we're doing async rpc. */
1999 /* We must check the outstanding callid matches. */
2000 if (pipe_init_outgoing_data(p)) {
2001 /* Send a cancel_ack PDU reply. */
2002 /* We should probably check the auth-verifier here. */
2003 reply = setup_cancel_ack_reply(p, pkt);
2005 break;
2006 #endif
2008 case DCERPC_PKT_ORPHANED:
2009 /* We should probably check the auth-verifier here.
2010 * For now just free all client data and continue
2011 * processing. */
2012 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
2013 " Abandoning rpc call.\n"));
2014 reply = True;
2015 break;
2017 default:
2018 DEBUG(0, ("process_complete_pdu: "
2019 "Unknown rpc type = %u received.\n",
2020 (unsigned int)pkt->ptype));
2021 break;
2024 done:
2025 if (!reply) {
2026 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
2027 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
2028 &p->syntax)));
2029 set_incoming_fault(p);
2030 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
2031 TALLOC_FREE(pkt);
2032 } else {
2034 * Reset the lengths. We're ready for a new pdu.
2036 TALLOC_FREE(p->in_data.pdu.data);
2037 p->in_data.pdu_needed_len = 0;
2038 p->in_data.pdu.length = 0;
2041 TALLOC_FREE(pkt);