s3-dcesrv: use gssapi helper in srv_pipe.c
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob18831130cba555aabda79019ad3ab557d288342f
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 "srv_pipe_internal.h"
32 #include "../librpc/gen_ndr/ndr_schannel.h"
33 #include "../libcli/auth/schannel.h"
34 #include "../libcli/auth/spnego.h"
35 #include "dcesrv_ntlmssp.h"
36 #include "dcesrv_gssapi.h"
37 #include "rpc_server.h"
38 #include "rpc_dce.h"
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_RPC_SRV
43 /**
44 * Dump everything from the start of the end up of the provided data
45 * into a file, but only at debug level >= 50
46 **/
47 static void dump_pdu_region(const char *name, int v,
48 DATA_BLOB *data, size_t start, size_t end)
50 int fd, i;
51 char *fname = NULL;
52 ssize_t sz;
54 if (DEBUGLEVEL < 50) return;
56 if (start > data->length || end > data->length || start > end) return;
58 for (i = 1; i < 100; i++) {
59 if (v != -1) {
60 fname = talloc_asprintf(talloc_tos(),
61 "/tmp/%s_%d.%d.prs",
62 name, v, i);
63 } else {
64 fname = talloc_asprintf(talloc_tos(),
65 "/tmp/%s_%d.prs",
66 name, i);
68 if (!fname) {
69 return;
71 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
72 if (fd != -1 || errno != EEXIST) break;
74 if (fd != -1) {
75 sz = write(fd, data->data + start, end - start);
76 i = close(fd);
77 if ((sz != end - start) || (i != 0) ) {
78 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
79 fname, (unsigned long)sz,
80 (unsigned long)end - start, i));
81 } else {
82 DEBUG(0,("created %s\n", fname));
85 TALLOC_FREE(fname);
88 static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth)
90 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
93 static void free_pipe_schannel_auth_data(struct pipe_auth_data *auth)
95 TALLOC_FREE(auth->a_u.schannel_auth);
98 static void free_pipe_gssapi_auth_data(struct pipe_auth_data *auth)
100 TALLOC_FREE(auth->a_u.gssapi_state);
103 static void free_pipe_auth_data(struct pipe_auth_data *auth)
105 if (auth->auth_data_free_func) {
106 (*auth->auth_data_free_func)(auth);
107 auth->auth_data_free_func = NULL;
111 static DATA_BLOB generic_session_key(void)
113 return data_blob("SystemLibraryDTC", 16);
116 /*******************************************************************
117 Generate the next PDU to be returned from the data.
118 ********************************************************************/
120 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
121 struct pipe_auth_data *auth,
122 uint32_t call_id,
123 DATA_BLOB *rdata,
124 size_t data_sent_length,
125 DATA_BLOB *frag,
126 size_t *pdu_size)
128 union dcerpc_payload u;
129 uint8_t pfc_flags;
130 size_t data_left;
131 size_t data_to_send;
132 size_t frag_len;
133 size_t pad_len = 0;
134 size_t auth_len = 0;
135 NTSTATUS status;
137 ZERO_STRUCT(u.response);
139 /* Set up rpc packet pfc flags. */
140 if (data_sent_length == 0) {
141 pfc_flags = DCERPC_PFC_FLAG_FIRST;
142 } else {
143 pfc_flags = 0;
146 /* Work out how much we can fit in a single PDU. */
147 data_left = rdata->length - data_sent_length;
149 /* Ensure there really is data left to send. */
150 if (!data_left) {
151 DEBUG(0, ("No data left to send !\n"));
152 return NT_STATUS_BUFFER_TOO_SMALL;
155 status = dcerpc_guess_sizes(auth,
156 DCERPC_RESPONSE_LENGTH,
157 data_left,
158 RPC_MAX_PDU_FRAG_LEN,
159 SERVER_NDR_PADDING_SIZE,
160 &data_to_send, &frag_len,
161 &auth_len, &pad_len);
162 if (!NT_STATUS_IS_OK(status)) {
163 return status;
166 /* Set up the alloc hint. This should be the data left to send. */
167 u.response.alloc_hint = data_left;
169 /* Work out if this PDU will be the last. */
170 if (data_sent_length + data_to_send >= rdata->length) {
171 pfc_flags |= DCERPC_PFC_FLAG_LAST;
174 /* Prepare data to be NDR encoded. */
175 u.response.stub_and_verifier =
176 data_blob_const(rdata->data + data_sent_length, data_to_send);
178 /* Store the packet in the data stream. */
179 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
180 pfc_flags, auth_len, call_id,
181 &u, frag);
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
184 return status;
187 if (auth_len) {
188 /* Set the proper length on the pdu, including padding.
189 * Only needed if an auth trailer will be appended. */
190 dcerpc_set_frag_length(frag, frag->length
191 + pad_len
192 + DCERPC_AUTH_TRAILER_LENGTH
193 + auth_len);
196 if (auth_len) {
197 status = dcerpc_add_auth_footer(auth, pad_len, frag);
198 if (!NT_STATUS_IS_OK(status)) {
199 data_blob_free(frag);
200 return status;
204 *pdu_size = data_to_send;
205 return NT_STATUS_OK;
208 /*******************************************************************
209 Generate the next PDU to be returned from the data in p->rdata.
210 ********************************************************************/
212 bool create_next_pdu(struct pipes_struct *p)
214 size_t pdu_size = 0;
215 NTSTATUS status;
218 * If we're in the fault state, keep returning fault PDU's until
219 * the pipe gets closed. JRA.
221 if (p->fault_state) {
222 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
223 return true;
226 status = create_next_packet(p->mem_ctx, &p->auth,
227 p->call_id, &p->out_data.rdata,
228 p->out_data.data_sent_length,
229 &p->out_data.frag, &pdu_size);
230 if (!NT_STATUS_IS_OK(status)) {
231 DEBUG(0, ("Failed to create packet with error %s, "
232 "(auth level %u / type %u)\n",
233 nt_errstr(status),
234 (unsigned int)p->auth.auth_level,
235 (unsigned int)p->auth.auth_type));
236 return false;
239 /* Setup the counts for this PDU. */
240 p->out_data.data_sent_length += pdu_size;
241 p->out_data.current_pdu_sent = 0;
242 return true;
245 /*******************************************************************
246 Process an NTLMSSP authentication response.
247 If this function succeeds, the user has been authenticated
248 and their domain, name and calling workstation stored in
249 the pipe struct.
250 *******************************************************************/
252 static bool pipe_ntlmssp_verify_final(TALLOC_CTX *mem_ctx,
253 struct auth_ntlmssp_state *ntlmssp_ctx,
254 enum dcerpc_AuthLevel auth_level,
255 struct client_address *client_id,
256 struct ndr_syntax_id *syntax,
257 struct auth_serversupplied_info **server_info)
259 DATA_BLOB session_key;
260 NTSTATUS status;
261 bool ret;
263 DEBUG(5, (__location__ ": pipe %s checking user details\n",
264 get_pipe_name_from_syntax(talloc_tos(), syntax)));
266 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
267 ensure the underlying NTLMSSP flags are also set. If not we should
268 refuse the bind. */
270 status = ntlmssp_server_check_flags(ntlmssp_ctx,
271 (auth_level ==
272 DCERPC_AUTH_LEVEL_INTEGRITY),
273 (auth_level ==
274 DCERPC_AUTH_LEVEL_PRIVACY));
275 if (!NT_STATUS_IS_OK(status)) {
276 DEBUG(0, (__location__ ": Client failed to negotatie proper "
277 "security for pipe %s\n",
278 get_pipe_name_from_syntax(talloc_tos(), syntax)));
279 return false;
282 TALLOC_FREE(*server_info);
284 status = ntlmssp_server_get_user_info(ntlmssp_ctx,
285 mem_ctx, server_info);
286 if (!NT_STATUS_IS_OK(status)) {
287 DEBUG(0, (__location__ ": failed to obtain the server info "
288 "for authenticated user: %s\n", nt_errstr(status)));
289 return false;
292 if ((*server_info)->ptok == NULL) {
293 DEBUG(1, ("Auth module failed to provide nt_user_token\n"));
294 return false;
298 * We're an authenticated bind over smb, so the session key needs to
299 * be set to "SystemLibraryDTC". Weird, but this is what Windows
300 * does. See the RPC-SAMBA3SESSIONKEY.
303 session_key = generic_session_key();
304 if (session_key.data == NULL) {
305 return false;
308 ret = server_info_set_session_key((*server_info), session_key);
309 data_blob_free(&session_key);
310 if (!ret) {
311 DEBUG(0, ("Failed to set session key!\n"));
312 return false;
315 return true;
318 static NTSTATUS pipe_gssapi_verify_final(TALLOC_CTX *mem_ctx,
319 struct gse_context *gse_ctx,
320 struct client_address *client_id,
321 struct auth_serversupplied_info **server_info);
323 /*******************************************************************
324 This is the "stage3" response after a bind request and reply.
325 *******************************************************************/
327 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
329 struct dcerpc_auth auth_info;
330 DATA_BLOB response = data_blob_null;
331 NTSTATUS status;
333 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
335 if (pkt->auth_length == 0) {
336 DEBUG(0, ("No auth field sent for bind request!\n"));
337 goto err;
340 /* Ensure there's enough data for an authenticated request. */
341 if (pkt->frag_length < RPC_HEADER_LEN
342 + DCERPC_AUTH_TRAILER_LENGTH
343 + pkt->auth_length) {
344 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
345 "%u is too large.\n",
346 (unsigned int)pkt->auth_length));
347 goto err;
351 * Decode the authentication verifier response.
354 status = dcerpc_pull_dcerpc_auth(pkt,
355 &pkt->u.auth3.auth_info,
356 &auth_info, p->endian);
357 if (!NT_STATUS_IS_OK(status)) {
358 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
359 goto err;
362 /* We must NEVER look at auth_info->auth_pad_len here,
363 * as old Samba client code gets it wrong and sends it
364 * as zero. JRA.
367 switch (auth_info.auth_type) {
368 case DCERPC_AUTH_TYPE_NTLMSSP:
369 status = ntlmssp_server_step(p->auth.a_u.auth_ntlmssp_state,
370 pkt, &auth_info.credentials,
371 &response);
372 break;
373 case DCERPC_AUTH_TYPE_KRB5:
374 status = gssapi_server_step(p->auth.a_u.gssapi_state,
375 pkt, &auth_info.credentials,
376 &response);
377 break;
378 default:
379 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
380 (unsigned int)auth_info.auth_type));
381 return false;
384 if (NT_STATUS_EQUAL(status,
385 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
386 response.length) {
387 DEBUG(0, (__location__ ": This was supposed to be the final "
388 "leg, but crypto machinery claims a response is "
389 "needed, aborting auth!\n"));
390 data_blob_free(&response);
391 goto err;
393 if (!NT_STATUS_IS_OK(status)) {
394 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
395 goto err;
398 /* Now verify auth was indeed successful and extract server info */
400 switch (auth_info.auth_type) {
401 case DCERPC_AUTH_TYPE_NTLMSSP:
402 if (!pipe_ntlmssp_verify_final(p,
403 p->auth.a_u.auth_ntlmssp_state,
404 p->auth.auth_level,
405 p->client_id, &p->syntax,
406 &p->server_info)) {
407 goto err;
409 break;
410 case DCERPC_AUTH_TYPE_KRB5:
411 status = pipe_gssapi_verify_final(p,
412 p->auth.a_u.gssapi_state,
413 p->client_id,
414 &p->server_info);
415 if (!NT_STATUS_IS_OK(status)) {
416 DEBUG(1, ("gssapi bind failed with: %s",
417 nt_errstr(status)));
418 goto err;
421 break;
422 default:
423 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
424 (unsigned int)auth_info.auth_type));
425 return false;
429 * The following call actually checks the challenge/response data.
430 * for correctness against the given DOMAIN\user name.
433 p->pipe_bound = true;
434 return true;
436 err:
438 free_pipe_auth_data(&p->auth);
439 return false;
442 static bool pipe_init_outgoing_data(struct pipes_struct *p);
444 /*******************************************************************
445 Marshall a bind_nak pdu.
446 *******************************************************************/
448 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
450 NTSTATUS status;
451 union dcerpc_payload u;
453 /* Free any memory in the current return data buffer. */
454 pipe_init_outgoing_data(p);
457 * Initialize a bind_nak header.
460 ZERO_STRUCT(u);
462 u.bind_nak.reject_reason = 0;
465 * Marshall directly into the outgoing PDU space. We
466 * must do this as we need to set to the bind response
467 * header and are never sending more than one PDU here.
470 status = dcerpc_push_ncacn_packet(p->mem_ctx,
471 DCERPC_PKT_BIND_NAK,
472 DCERPC_PFC_FLAG_FIRST |
473 DCERPC_PFC_FLAG_LAST,
475 pkt->call_id,
477 &p->out_data.frag);
478 if (!NT_STATUS_IS_OK(status)) {
479 return False;
482 p->out_data.data_sent_length = 0;
483 p->out_data.current_pdu_sent = 0;
485 free_pipe_auth_data(&p->auth);
486 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
487 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
488 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
489 p->pipe_bound = False;
491 return True;
494 /*******************************************************************
495 Marshall a fault pdu.
496 *******************************************************************/
498 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
500 NTSTATUS status;
501 union dcerpc_payload u;
503 /* Free any memory in the current return data buffer. */
504 pipe_init_outgoing_data(p);
507 * Initialize a fault header.
510 ZERO_STRUCT(u);
512 u.fault.status = NT_STATUS_V(fault_status);
513 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
516 * Marshall directly into the outgoing PDU space. We
517 * must do this as we need to set to the bind response
518 * header and are never sending more than one PDU here.
521 status = dcerpc_push_ncacn_packet(p->mem_ctx,
522 DCERPC_PKT_FAULT,
523 DCERPC_PFC_FLAG_FIRST |
524 DCERPC_PFC_FLAG_LAST |
525 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
527 p->call_id,
529 &p->out_data.frag);
530 if (!NT_STATUS_IS_OK(status)) {
531 return False;
534 p->out_data.data_sent_length = 0;
535 p->out_data.current_pdu_sent = 0;
537 return True;
540 /*******************************************************************
541 Ensure a bind request has the correct abstract & transfer interface.
542 Used to reject unknown binds from Win2k.
543 *******************************************************************/
545 static bool check_bind_req(struct pipes_struct *p,
546 struct ndr_syntax_id* abstract,
547 struct ndr_syntax_id* transfer,
548 uint32 context_id)
550 struct pipe_rpc_fns *context_fns;
552 DEBUG(3,("check_bind_req for %s\n",
553 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
555 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
556 if (rpc_srv_pipe_exists_by_id(abstract) &&
557 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
558 DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
559 rpc_srv_get_pipe_cli_name(abstract),
560 rpc_srv_get_pipe_srv_name(abstract)));
561 } else {
562 return false;
565 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
566 if (context_fns == NULL) {
567 DEBUG(0,("check_bind_req: malloc() failed!\n"));
568 return False;
571 context_fns->next = context_fns->prev = NULL;
572 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
573 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
574 context_fns->context_id = context_id;
576 /* add to the list of open contexts */
578 DLIST_ADD( p->contexts, context_fns );
580 return True;
584 * Is a named pipe known?
585 * @param[in] cli_filename The pipe name requested by the client
586 * @result Do we want to serve this?
588 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
590 const char *pipename = cli_filename;
591 NTSTATUS status;
593 if (strnequal(pipename, "\\PIPE\\", 6)) {
594 pipename += 5;
597 if (*pipename == '\\') {
598 pipename += 1;
601 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
602 DEBUG(10, ("refusing spoolss access\n"));
603 return false;
606 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
607 return true;
610 status = smb_probe_module("rpc", pipename);
611 if (!NT_STATUS_IS_OK(status)) {
612 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
613 return false;
615 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
618 * Scan the list again for the interface id
620 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
621 return true;
624 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
625 pipename));
627 return false;
630 /*******************************************************************
631 Handle a SPNEGO krb5 bind auth.
632 *******************************************************************/
634 static bool pipe_spnego_auth_bind_kerberos(struct pipes_struct *p,
635 TALLOC_CTX *mem_ctx,
636 struct dcerpc_auth *pauth_info,
637 DATA_BLOB *psecblob,
638 DATA_BLOB *response)
640 return False;
643 /*******************************************************************
644 Handle the first part of a SPNEGO bind auth.
645 *******************************************************************/
647 static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p,
648 TALLOC_CTX *mem_ctx,
649 struct dcerpc_auth *pauth_info,
650 DATA_BLOB *response)
652 DATA_BLOB secblob = data_blob_null;
653 DATA_BLOB chal = data_blob_null;
654 char *OIDs[ASN1_MAX_OIDS];
655 int i;
656 NTSTATUS status;
657 bool got_kerberos_mechanism = false;
658 bool ret;
660 if (pauth_info->credentials.data[0] != ASN1_APPLICATION(0)) {
661 ret = false;
662 goto done;
665 /* parse out the OIDs and the first sec blob */
666 ret = spnego_parse_negTokenInit(talloc_tos(),
667 pauth_info->credentials, OIDs, NULL, &secblob);
668 if (!ret) {
669 DEBUG(0, (__location__ ": Failed to parse the secblob.\n"));
670 goto done;
673 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
674 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
675 got_kerberos_mechanism = true;
678 for (i = 0; OIDs[i]; i++) {
679 DEBUG(3, (__location__ ": Got OID %s\n", OIDs[i]));
680 TALLOC_FREE(OIDs[i]);
682 DEBUG(3, (__location__ ": Got secblob of size %lu\n",
683 (unsigned long)secblob.length));
685 if (got_kerberos_mechanism &&
686 ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB)) {
687 ret = pipe_spnego_auth_bind_kerberos(p, mem_ctx, pauth_info,
688 &secblob, response);
689 goto done;
692 /* Free any previous auth type. */
693 free_pipe_auth_data(&p->auth);
694 p->auth.a_u.auth_ntlmssp_state = NULL;
696 if (!got_kerberos_mechanism) {
697 /* Initialize the NTLM engine. */
698 status = ntlmssp_server_auth_start(p,
699 (pauth_info->auth_level ==
700 DCERPC_AUTH_LEVEL_INTEGRITY),
701 (pauth_info->auth_level ==
702 DCERPC_AUTH_LEVEL_PRIVACY),
703 true, &secblob, &chal,
704 &p->auth.a_u.auth_ntlmssp_state);
706 if (!NT_STATUS_IS_OK(status)) {
707 DEBUG(3, (__location__ ": Failed to start NTLMSSP "
708 "auth (%s).\n", nt_errstr(status)));
709 ret = false;
710 goto done;
713 /* Generate the response blob we need for step 2 of the bind. */
714 *response = spnego_gen_auth_response(
715 mem_ctx, &chal,
716 NT_STATUS_MORE_PROCESSING_REQUIRED,
717 OID_NTLMSSP);
718 } else {
720 * SPNEGO negotiate down to NTLMSSP. The subsequent
721 * code to process follow-up packets is not complete
722 * yet. JRA.
724 *response = spnego_gen_auth_response(mem_ctx, NULL,
725 NT_STATUS_MORE_PROCESSING_REQUIRED,
726 OID_NTLMSSP);
729 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
730 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
731 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
733 ret = true;
735 done:
737 data_blob_free(&secblob);
738 data_blob_free(&chal);
740 return ret;
743 /*******************************************************************
744 Handle the second part of a SPNEGO bind auth.
745 *******************************************************************/
747 static bool pipe_spnego_auth_bind_continue(struct pipes_struct *p,
748 TALLOC_CTX *mem_ctx,
749 struct dcerpc_auth *pauth_info,
750 DATA_BLOB *response)
752 DATA_BLOB auth_blob = data_blob_null;
753 DATA_BLOB auth_reply = data_blob_null;
754 NTSTATUS status;
755 bool ret;
758 * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently
759 * fail here as 'a' == NULL.
761 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO ||
762 p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP ||
763 p->auth.a_u.auth_ntlmssp_state == NULL) {
764 DEBUG(0, (__location__ ": not in NTLMSSP auth state.\n"));
765 goto err;
768 if (pauth_info->credentials.data[0] != ASN1_CONTEXT(1)) {
769 DEBUG(0, (__location__ ": invalid SPNEGO blob type.\n"));
770 goto err;
773 ret = spnego_parse_auth(talloc_tos(),
774 pauth_info->credentials, &auth_blob);
775 if (!ret) {
776 DEBUG(0, (__location__ ": invalid SPNEGO blob.\n"));
777 goto err;
780 status = ntlmssp_server_step(p->auth.a_u.auth_ntlmssp_state,
781 p, &auth_blob, &auth_reply);
782 if (NT_STATUS_EQUAL(status,
783 NT_STATUS_MORE_PROCESSING_REQUIRED) ||
784 auth_reply.length) {
785 DEBUG(0, (__location__ ": This was supposed to be the final "
786 "leg, but crypto machinery claims a response is "
787 "needed, aborting auth!\n"));
788 goto err;
790 if (!NT_STATUS_IS_OK(status)) {
791 DEBUG(0, ("Auth failed (%s)\n", nt_errstr(status)));
792 goto err;
795 ret = pipe_ntlmssp_verify_final(p,
796 p->auth.a_u.auth_ntlmssp_state,
797 p->auth.auth_level,
798 p->client_id, &p->syntax,
799 &p->server_info);
800 if (!ret) {
801 goto err;
804 data_blob_free(&auth_blob);
806 /* Generate the spnego "accept completed" blob - no incoming data. */
807 *response = spnego_gen_auth_response(mem_ctx, &auth_reply,
808 NT_STATUS_OK, OID_NTLMSSP);
810 data_blob_free(&auth_reply);
812 p->pipe_bound = true;
813 return true;
815 err:
816 data_blob_free(&auth_blob);
817 data_blob_free(&auth_reply);
818 free_pipe_auth_data(&p->auth);
820 return false;
823 /*******************************************************************
824 Handle an schannel bind auth.
825 *******************************************************************/
827 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
828 TALLOC_CTX *mem_ctx,
829 struct dcerpc_auth *auth_info,
830 DATA_BLOB *response)
832 struct NL_AUTH_MESSAGE neg;
833 struct NL_AUTH_MESSAGE reply;
834 bool ret;
835 NTSTATUS status;
836 struct netlogon_creds_CredentialState *creds;
837 DATA_BLOB session_key;
838 enum ndr_err_code ndr_err;
840 ndr_err = ndr_pull_struct_blob(
841 &auth_info->credentials, mem_ctx, &neg,
842 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
843 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
844 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
845 return false;
848 if (DEBUGLEVEL >= 10) {
849 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
852 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
853 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
854 return false;
858 * The neg.oem_netbios_computer.a key here must match the remote computer name
859 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
860 * operations that use credentials.
863 become_root();
864 status = schannel_get_creds_state(p, lp_private_dir(),
865 neg.oem_netbios_computer.a, &creds);
866 unbecome_root();
868 if (!NT_STATUS_IS_OK(status)) {
869 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
870 return False;
873 p->auth.a_u.schannel_auth = talloc(p, struct schannel_state);
874 if (!p->auth.a_u.schannel_auth) {
875 TALLOC_FREE(creds);
876 return False;
879 p->auth.a_u.schannel_auth->state = SCHANNEL_STATE_START;
880 p->auth.a_u.schannel_auth->seq_num = 0;
881 p->auth.a_u.schannel_auth->initiator = false;
882 p->auth.a_u.schannel_auth->creds = creds;
885 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
886 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
887 * struct of the person who opened the pipe. I need to test this further. JRA.
889 * VL. As we are mapping this to guest set the generic key
890 * "SystemLibraryDTC" key here. It's a bit difficult to test against
891 * W2k3, as it does not allow schannel binds against SAMR and LSA
892 * anymore.
895 session_key = generic_session_key();
896 if (session_key.data == NULL) {
897 DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session"
898 " key\n"));
899 return false;
902 ret = server_info_set_session_key(p->server_info, session_key);
904 data_blob_free(&session_key);
906 if (!ret) {
907 DEBUG(0, ("server_info_set_session_key failed\n"));
908 return false;
911 /*** SCHANNEL verifier ***/
913 reply.MessageType = NL_NEGOTIATE_RESPONSE;
914 reply.Flags = 0;
915 reply.Buffer.dummy = 5; /* ??? actually I don't think
916 * this has any meaning
917 * here - gd */
919 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
920 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
921 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
922 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
923 return false;
926 if (DEBUGLEVEL >= 10) {
927 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
930 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
931 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
933 /* We're finished with this bind - no more packets. */
934 p->auth.auth_data_free_func = &free_pipe_schannel_auth_data;
935 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
937 p->pipe_bound = True;
939 return True;
942 /*******************************************************************
943 Handle an NTLMSSP bind auth.
944 *******************************************************************/
946 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
947 TALLOC_CTX *mem_ctx,
948 struct dcerpc_auth *auth_info,
949 DATA_BLOB *response)
951 NTSTATUS status;
953 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
954 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
955 return false;
958 /* We have an NTLMSSP blob. */
959 status = ntlmssp_server_auth_start(p,
960 (auth_info->auth_level ==
961 DCERPC_AUTH_LEVEL_INTEGRITY),
962 (auth_info->auth_level ==
963 DCERPC_AUTH_LEVEL_PRIVACY),
964 true,
965 &auth_info->credentials,
966 response,
967 &p->auth.a_u.auth_ntlmssp_state);
968 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
969 DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
970 nt_errstr(status)));
971 return false;
974 /* Make sure data is bound to the memctx, to be freed the caller */
975 talloc_steal(mem_ctx, response->data);
977 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
978 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
980 DEBUG(10, (__location__ ": NTLMSSP auth started\n"));
982 return true;
985 /*******************************************************************
986 Handle a GSSAPI bind auth.
987 *******************************************************************/
989 static bool pipe_gssapi_auth_bind(struct pipes_struct *p,
990 TALLOC_CTX *mem_ctx,
991 struct dcerpc_auth *auth_info,
992 DATA_BLOB *response)
994 NTSTATUS status;
995 struct gse_context *gse_ctx = NULL;
997 status = gssapi_server_auth_start(p,
998 (auth_info->auth_level ==
999 DCERPC_AUTH_LEVEL_INTEGRITY),
1000 (auth_info->auth_level ==
1001 DCERPC_AUTH_LEVEL_PRIVACY),
1002 true,
1003 &auth_info->credentials,
1004 response,
1005 &gse_ctx);
1006 if (!NT_STATUS_IS_OK(status)) {
1007 DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
1008 nt_errstr(status)));
1009 goto err;
1012 /* Make sure data is bound to the memctx, to be freed the caller */
1013 talloc_steal(mem_ctx, response->data);
1015 p->auth.a_u.gssapi_state = gse_ctx;
1016 p->auth.auth_data_free_func = &free_pipe_gssapi_auth_data;
1017 p->auth.auth_type = DCERPC_AUTH_TYPE_KRB5;
1019 DEBUG(10, ("KRB5 auth started\n"));
1021 return true;
1023 err:
1024 TALLOC_FREE(gse_ctx);
1025 return false;
1028 static NTSTATUS pipe_gssapi_verify_final(TALLOC_CTX *mem_ctx,
1029 struct gse_context *gse_ctx,
1030 struct client_address *client_id,
1031 struct auth_serversupplied_info **server_info)
1033 DATA_BLOB session_key;
1034 NTSTATUS status;
1035 bool bret;
1037 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
1038 ensure the underlying flags are also set. If not we should
1039 refuse the bind. */
1041 status = gssapi_server_check_flags(gse_ctx);
1042 if (!NT_STATUS_IS_OK(status)) {
1043 DEBUG(0, ("Requested Security Layers not honored!\n"));
1044 return status;
1047 status = gssapi_server_get_user_info(gse_ctx, mem_ctx,
1048 client_id, server_info);
1049 if (!NT_STATUS_IS_OK(status)) {
1050 DEBUG(0, (__location__ ": failed to obtain the server info "
1051 "for authenticated user: %s\n", nt_errstr(status)));
1052 return status;
1055 if ((*server_info)->ptok == NULL) {
1056 status = create_local_token(*server_info);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 DEBUG(1, ("Failed to create local user token (%s)\n",
1059 nt_errstr(status)));
1060 status = NT_STATUS_ACCESS_DENIED;
1061 return status;
1065 /* TODO: this is what the ntlmssp code does with the session_key, check
1066 * it is ok with gssapi too */
1068 * We're an authenticated bind over smb, so the session key needs to
1069 * be set to "SystemLibraryDTC". Weird, but this is what Windows
1070 * does. See the RPC-SAMBA3SESSIONKEY.
1073 session_key = generic_session_key();
1074 if (session_key.data == NULL) {
1075 return NT_STATUS_ACCESS_DENIED;
1078 bret = server_info_set_session_key((*server_info), session_key);
1079 data_blob_free(&session_key);
1080 if (!bret) {
1081 return NT_STATUS_ACCESS_DENIED;
1084 return NT_STATUS_OK;
1087 /*******************************************************************
1088 Respond to a pipe bind request.
1089 *******************************************************************/
1091 static bool api_pipe_bind_req(struct pipes_struct *p,
1092 struct ncacn_packet *pkt)
1094 struct dcerpc_auth auth_info;
1095 uint16 assoc_gid;
1096 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
1097 NTSTATUS status;
1098 struct ndr_syntax_id id;
1099 union dcerpc_payload u;
1100 struct dcerpc_ack_ctx bind_ack_ctx;
1101 DATA_BLOB auth_resp = data_blob_null;
1102 DATA_BLOB auth_blob = data_blob_null;
1104 /* No rebinds on a bound pipe - use alter context. */
1105 if (p->pipe_bound) {
1106 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
1107 "pipe %s.\n",
1108 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1109 return setup_bind_nak(p, pkt);
1112 if (pkt->u.bind.num_contexts == 0) {
1113 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
1114 goto err_exit;
1118 * Try and find the correct pipe name to ensure
1119 * that this is a pipe name we support.
1121 id = pkt->u.bind.ctx_list[0].abstract_syntax;
1122 if (rpc_srv_pipe_exists_by_id(&id)) {
1123 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1124 rpc_srv_get_pipe_cli_name(&id),
1125 rpc_srv_get_pipe_srv_name(&id)));
1126 } else {
1127 status = smb_probe_module(
1128 "rpc", get_pipe_name_from_syntax(
1129 talloc_tos(),
1130 &pkt->u.bind.ctx_list[0].abstract_syntax));
1132 if (NT_STATUS_IS_ERR(status)) {
1133 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
1134 get_pipe_name_from_syntax(
1135 talloc_tos(),
1136 &pkt->u.bind.ctx_list[0].abstract_syntax)));
1138 return setup_bind_nak(p, pkt);
1141 if (rpc_srv_get_pipe_interface_by_cli_name(
1142 get_pipe_name_from_syntax(talloc_tos(),
1143 &p->syntax),
1144 &id)) {
1145 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1146 rpc_srv_get_pipe_cli_name(&id),
1147 rpc_srv_get_pipe_srv_name(&id)));
1148 } else {
1149 DEBUG(0, ("module %s doesn't provide functions for "
1150 "pipe %s!\n",
1151 get_pipe_name_from_syntax(talloc_tos(),
1152 &p->syntax),
1153 get_pipe_name_from_syntax(talloc_tos(),
1154 &p->syntax)));
1155 return setup_bind_nak(p, pkt);
1159 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
1161 if (pkt->u.bind.assoc_group_id != 0) {
1162 assoc_gid = pkt->u.bind.assoc_group_id;
1163 } else {
1164 assoc_gid = 0x53f0;
1168 * Create the bind response struct.
1171 /* If the requested abstract synt uuid doesn't match our client pipe,
1172 reject the bind_ack & set the transfer interface synt to all 0's,
1173 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1174 unknown to NT4)
1175 Needed when adding entries to a DACL from NT5 - SK */
1177 if (check_bind_req(p,
1178 &pkt->u.bind.ctx_list[0].abstract_syntax,
1179 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1180 pkt->u.bind.ctx_list[0].context_id)) {
1182 bind_ack_ctx.result = 0;
1183 bind_ack_ctx.reason = 0;
1184 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1185 } else {
1186 p->pipe_bound = False;
1187 /* Rejection reason: abstract syntax not supported */
1188 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1189 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1190 bind_ack_ctx.syntax = null_ndr_syntax_id;
1194 * Check if this is an authenticated bind request.
1196 if (pkt->auth_length) {
1197 /* Quick length check. Won't catch a bad auth footer,
1198 * prevents overrun. */
1200 if (pkt->frag_length < RPC_HEADER_LEN +
1201 DCERPC_AUTH_TRAILER_LENGTH +
1202 pkt->auth_length) {
1203 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
1204 "too long for fragment %u.\n",
1205 (unsigned int)pkt->auth_length,
1206 (unsigned int)pkt->frag_length));
1207 goto err_exit;
1211 * Decode the authentication verifier.
1213 status = dcerpc_pull_dcerpc_auth(pkt,
1214 &pkt->u.bind.auth_info,
1215 &auth_info, p->endian);
1216 if (!NT_STATUS_IS_OK(status)) {
1217 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1218 goto err_exit;
1221 auth_type = auth_info.auth_type;
1223 /* Work out if we have to sign or seal etc. */
1224 switch (auth_info.auth_level) {
1225 case DCERPC_AUTH_LEVEL_INTEGRITY:
1226 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1227 break;
1228 case DCERPC_AUTH_LEVEL_PRIVACY:
1229 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1230 break;
1231 default:
1232 DEBUG(0, ("Unexpected auth level (%u).\n",
1233 (unsigned int)auth_info.auth_level ));
1234 goto err_exit;
1237 switch (auth_type) {
1238 case DCERPC_AUTH_TYPE_NTLMSSP:
1239 if (!pipe_ntlmssp_auth_bind(p, pkt,
1240 &auth_info, &auth_resp)) {
1241 goto err_exit;
1243 assoc_gid = 0x7a77;
1244 break;
1246 case DCERPC_AUTH_TYPE_SCHANNEL:
1247 if (!pipe_schannel_auth_bind(p, pkt,
1248 &auth_info, &auth_resp)) {
1249 goto err_exit;
1251 break;
1253 case DCERPC_AUTH_TYPE_SPNEGO:
1254 if (!pipe_spnego_auth_bind_negotiate(p, pkt,
1255 &auth_info, &auth_resp)) {
1256 goto err_exit;
1258 break;
1260 case DCERPC_AUTH_TYPE_KRB5:
1261 if (!pipe_gssapi_auth_bind(p, pkt,
1262 &auth_info, &auth_resp)) {
1263 goto err_exit;
1265 break;
1267 case DCERPC_AUTH_TYPE_NONE:
1268 break;
1270 default:
1271 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1272 goto err_exit;
1276 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1277 /* Unauthenticated bind request. */
1278 /* We're finished - no more packets. */
1279 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1280 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
1281 /* We must set the pipe auth_level here also. */
1282 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1283 p->pipe_bound = True;
1284 /* The session key was initialized from the SMB
1285 * session in make_internal_rpc_pipe_p */
1288 ZERO_STRUCT(u.bind_ack);
1289 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1290 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1291 u.bind_ack.assoc_group_id = assoc_gid;
1293 /* name has to be \PIPE\xxxxx */
1294 u.bind_ack.secondary_address =
1295 talloc_asprintf(pkt, "\\PIPE\\%s",
1296 rpc_srv_get_pipe_srv_name(&id));
1297 if (!u.bind_ack.secondary_address) {
1298 DEBUG(0, ("Out of memory!\n"));
1299 goto err_exit;
1301 u.bind_ack.secondary_address_size =
1302 strlen(u.bind_ack.secondary_address) + 1;
1304 u.bind_ack.num_results = 1;
1305 u.bind_ack.ctx_list = &bind_ack_ctx;
1307 /* NOTE: We leave the auth_info empty so we can calculate the padding
1308 * later and then append the auth_info --simo */
1311 * Marshall directly into the outgoing PDU space. We
1312 * must do this as we need to set to the bind response
1313 * header and are never sending more than one PDU here.
1316 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1317 DCERPC_PKT_BIND_ACK,
1318 DCERPC_PFC_FLAG_FIRST |
1319 DCERPC_PFC_FLAG_LAST,
1320 auth_resp.length,
1321 pkt->call_id,
1323 &p->out_data.frag);
1324 if (!NT_STATUS_IS_OK(status)) {
1325 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1326 nt_errstr(status)));
1329 if (auth_resp.length) {
1331 status = dcerpc_push_dcerpc_auth(pkt,
1332 auth_type,
1333 auth_info.auth_level,
1335 1, /* auth_context_id */
1336 &auth_resp,
1337 &auth_blob);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1340 goto err_exit;
1344 /* Now that we have the auth len store it into the right place in
1345 * the dcerpc header */
1346 dcerpc_set_frag_length(&p->out_data.frag,
1347 p->out_data.frag.length + auth_blob.length);
1349 if (auth_blob.length) {
1351 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1352 auth_blob.data, auth_blob.length)) {
1353 DEBUG(0, ("Append of auth info failed.\n"));
1354 goto err_exit;
1359 * Setup the lengths for the initial reply.
1362 p->out_data.data_sent_length = 0;
1363 p->out_data.current_pdu_sent = 0;
1365 TALLOC_FREE(auth_blob.data);
1366 return True;
1368 err_exit:
1370 data_blob_free(&p->out_data.frag);
1371 TALLOC_FREE(auth_blob.data);
1372 return setup_bind_nak(p, pkt);
1375 /****************************************************************************
1376 Deal with an alter context call. Can be third part of 3 leg auth request for
1377 SPNEGO calls.
1378 ****************************************************************************/
1380 static bool api_pipe_alter_context(struct pipes_struct *p,
1381 struct ncacn_packet *pkt)
1383 struct dcerpc_auth auth_info;
1384 uint16 assoc_gid;
1385 NTSTATUS status;
1386 union dcerpc_payload u;
1387 struct dcerpc_ack_ctx bind_ack_ctx;
1388 DATA_BLOB auth_resp = data_blob_null;
1389 DATA_BLOB auth_blob = data_blob_null;
1390 int pad_len = 0;
1392 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1394 if (pkt->u.bind.assoc_group_id != 0) {
1395 assoc_gid = pkt->u.bind.assoc_group_id;
1396 } else {
1397 assoc_gid = 0x53f0;
1401 * Create the bind response struct.
1404 /* If the requested abstract synt uuid doesn't match our client pipe,
1405 reject the bind_ack & set the transfer interface synt to all 0's,
1406 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1407 unknown to NT4)
1408 Needed when adding entries to a DACL from NT5 - SK */
1410 if (check_bind_req(p,
1411 &pkt->u.bind.ctx_list[0].abstract_syntax,
1412 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1413 pkt->u.bind.ctx_list[0].context_id)) {
1415 bind_ack_ctx.result = 0;
1416 bind_ack_ctx.reason = 0;
1417 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1418 } else {
1419 p->pipe_bound = False;
1420 /* Rejection reason: abstract syntax not supported */
1421 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1422 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1423 bind_ack_ctx.syntax = null_ndr_syntax_id;
1427 * Check if this is an authenticated alter context request.
1429 if (pkt->auth_length) {
1430 /* Quick length check. Won't catch a bad auth footer,
1431 * prevents overrun. */
1433 if (pkt->frag_length < RPC_HEADER_LEN +
1434 DCERPC_AUTH_TRAILER_LENGTH +
1435 pkt->auth_length) {
1436 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1437 "too long for fragment %u.\n",
1438 (unsigned int)pkt->auth_length,
1439 (unsigned int)pkt->frag_length ));
1440 goto err_exit;
1443 status = dcerpc_pull_dcerpc_auth(pkt,
1444 &pkt->u.bind.auth_info,
1445 &auth_info, p->endian);
1446 if (!NT_STATUS_IS_OK(status)) {
1447 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1448 goto err_exit;
1451 /* We can only finish if the pipe is unbound for now */
1452 if (p->pipe_bound) {
1453 DEBUG(0, (__location__ ": Pipe already bound, "
1454 "Altering Context not yet supported!\n"));
1455 goto err_exit;
1458 switch (auth_info.auth_type) {
1459 case DCERPC_AUTH_TYPE_SPNEGO:
1460 if (!pipe_spnego_auth_bind_continue(p, pkt,
1461 &auth_info,
1462 &auth_resp)) {
1463 goto err_exit;
1465 break;
1467 case DCERPC_AUTH_TYPE_KRB5:
1468 status = gssapi_server_step(p->auth.a_u.gssapi_state,
1469 pkt,
1470 &auth_info.credentials,
1471 &auth_resp);
1472 if (!NT_STATUS_IS_OK(status)) {
1473 goto err_exit;
1475 break;
1477 default:
1478 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1479 "in alter-context call\n",
1480 auth_info.auth_type));
1481 goto err_exit;
1485 ZERO_STRUCT(u.alter_resp);
1486 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1487 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1488 u.alter_resp.assoc_group_id = assoc_gid;
1490 /* secondary address CAN be NULL
1491 * as the specs say it's ignored.
1492 * It MUST be NULL to have the spoolss working.
1494 u.alter_resp.secondary_address = "";
1495 u.alter_resp.secondary_address_size = 1;
1497 u.alter_resp.num_results = 1;
1498 u.alter_resp.ctx_list = &bind_ack_ctx;
1500 /* NOTE: We leave the auth_info empty so we can calculate the padding
1501 * later and then append the auth_info --simo */
1504 * Marshall directly into the outgoing PDU space. We
1505 * must do this as we need to set to the bind response
1506 * header and are never sending more than one PDU here.
1509 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1510 DCERPC_PKT_ALTER_RESP,
1511 DCERPC_PFC_FLAG_FIRST |
1512 DCERPC_PFC_FLAG_LAST,
1513 auth_resp.length,
1514 pkt->call_id,
1516 &p->out_data.frag);
1517 if (!NT_STATUS_IS_OK(status)) {
1518 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1519 nt_errstr(status)));
1522 if (auth_resp.length) {
1524 /* Work out any padding needed before the auth footer. */
1525 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1526 if (pad_len) {
1527 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1528 DEBUG(10, ("auth pad_len = %u\n",
1529 (unsigned int)pad_len));
1532 status = dcerpc_push_dcerpc_auth(pkt,
1533 auth_info.auth_type,
1534 auth_info.auth_level,
1535 pad_len,
1536 1, /* auth_context_id */
1537 &auth_resp,
1538 &auth_blob);
1539 if (!NT_STATUS_IS_OK(status)) {
1540 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1541 goto err_exit;
1545 /* Now that we have the auth len store it into the right place in
1546 * the dcerpc header */
1547 dcerpc_set_frag_length(&p->out_data.frag,
1548 p->out_data.frag.length +
1549 pad_len + auth_blob.length);
1551 if (auth_resp.length) {
1552 if (pad_len) {
1553 char pad[SERVER_NDR_PADDING_SIZE];
1554 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1555 if (!data_blob_append(p->mem_ctx,
1556 &p->out_data.frag,
1557 pad, pad_len)) {
1558 DEBUG(0, ("api_pipe_bind_req: failed to add "
1559 "%u bytes of pad data.\n",
1560 (unsigned int)pad_len));
1561 goto err_exit;
1565 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1566 auth_blob.data, auth_blob.length)) {
1567 DEBUG(0, ("Append of auth info failed.\n"));
1568 goto err_exit;
1573 * Setup the lengths for the initial reply.
1576 p->out_data.data_sent_length = 0;
1577 p->out_data.current_pdu_sent = 0;
1579 TALLOC_FREE(auth_blob.data);
1580 return True;
1582 err_exit:
1584 data_blob_free(&p->out_data.frag);
1585 TALLOC_FREE(auth_blob.data);
1586 return setup_bind_nak(p, pkt);
1589 /****************************************************************************
1590 Find the set of RPC functions associated with this context_id
1591 ****************************************************************************/
1593 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1595 PIPE_RPC_FNS *fns = NULL;
1597 if ( !list ) {
1598 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1599 return NULL;
1602 for (fns=list; fns; fns=fns->next ) {
1603 if ( fns->context_id == context_id )
1604 return fns;
1606 return NULL;
1609 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1610 const struct api_struct *api_rpc_cmds, int n_cmds);
1612 /****************************************************************************
1613 Find the correct RPC function to call for this request.
1614 If the pipe is authenticated then become the correct UNIX user
1615 before doing the call.
1616 ****************************************************************************/
1618 static bool api_pipe_request(struct pipes_struct *p,
1619 struct ncacn_packet *pkt)
1621 bool ret = False;
1622 bool changed_user = False;
1623 PIPE_RPC_FNS *pipe_fns;
1625 if (p->pipe_bound &&
1626 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1627 ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) &&
1628 (p->auth.spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)))) {
1629 if(!become_authenticated_pipe_user(p)) {
1630 data_blob_free(&p->out_data.rdata);
1631 return False;
1633 changed_user = True;
1636 DEBUG(5, ("Requested \\PIPE\\%s\n",
1637 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1639 /* get the set of RPC functions for this context */
1641 pipe_fns = find_pipe_fns_by_context(p->contexts,
1642 pkt->u.request.context_id);
1644 if ( pipe_fns ) {
1645 TALLOC_CTX *frame = talloc_stackframe();
1646 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1647 TALLOC_FREE(frame);
1649 else {
1650 DEBUG(0, ("No rpc function table associated with context "
1651 "[%d] on pipe [%s]\n",
1652 pkt->u.request.context_id,
1653 get_pipe_name_from_syntax(talloc_tos(),
1654 &p->syntax)));
1657 if (changed_user) {
1658 unbecome_authenticated_pipe_user();
1661 return ret;
1664 /*******************************************************************
1665 Calls the underlying RPC function for a named pipe.
1666 ********************************************************************/
1668 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1669 const struct api_struct *api_rpc_cmds, int n_cmds)
1671 int fn_num;
1672 uint32_t offset1;
1674 /* interpret the command */
1675 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1676 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1677 pkt->u.request.opnum));
1679 if (DEBUGLEVEL >= 50) {
1680 fstring name;
1681 slprintf(name, sizeof(name)-1, "in_%s",
1682 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1683 dump_pdu_region(name, pkt->u.request.opnum,
1684 &p->in_data.data, 0,
1685 p->in_data.data.length);
1688 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1689 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1690 api_rpc_cmds[fn_num].fn != NULL) {
1691 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1692 api_rpc_cmds[fn_num].name));
1693 break;
1697 if (fn_num == n_cmds) {
1699 * For an unknown RPC just return a fault PDU but
1700 * return True to allow RPC's on the pipe to continue
1701 * and not put the pipe into fault state. JRA.
1703 DEBUG(4, ("unknown\n"));
1704 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1705 return True;
1708 offset1 = p->out_data.rdata.length;
1710 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1711 fn_num, api_rpc_cmds[fn_num].fn));
1712 /* do the actual command */
1713 if(!api_rpc_cmds[fn_num].fn(p)) {
1714 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1715 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1716 api_rpc_cmds[fn_num].name));
1717 data_blob_free(&p->out_data.rdata);
1718 return False;
1721 if (p->bad_handle_fault_state) {
1722 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1723 p->bad_handle_fault_state = False;
1724 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1725 return True;
1728 if (p->rng_fault_state) {
1729 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1730 p->rng_fault_state = False;
1731 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1732 return True;
1735 if (DEBUGLEVEL >= 50) {
1736 fstring name;
1737 slprintf(name, sizeof(name)-1, "out_%s",
1738 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1739 dump_pdu_region(name, pkt->u.request.opnum,
1740 &p->out_data.rdata, offset1,
1741 p->out_data.rdata.length);
1744 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1745 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1747 /* Check for buffer underflow in rpc parsing */
1748 if ((DEBUGLEVEL >= 10) &&
1749 (pkt->frag_length < p->in_data.data.length)) {
1750 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1751 dump_data(10, p->in_data.data.data + pkt->frag_length,
1752 p->in_data.data.length - pkt->frag_length);
1755 return True;
1758 /****************************************************************************
1759 Initialise an outgoing packet.
1760 ****************************************************************************/
1762 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1764 output_data *o_data = &p->out_data;
1766 /* Reset the offset counters. */
1767 o_data->data_sent_length = 0;
1768 o_data->current_pdu_sent = 0;
1770 data_blob_free(&o_data->frag);
1772 /* Free any memory in the current return data buffer. */
1773 data_blob_free(&o_data->rdata);
1775 return True;
1778 /****************************************************************************
1779 Sets the fault state on incoming packets.
1780 ****************************************************************************/
1782 void set_incoming_fault(struct pipes_struct *p)
1784 data_blob_free(&p->in_data.data);
1785 p->in_data.pdu_needed_len = 0;
1786 p->in_data.pdu.length = 0;
1787 p->fault_state = True;
1788 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1789 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1792 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1793 struct ncacn_packet *pkt,
1794 DATA_BLOB *raw_pkt)
1796 NTSTATUS status;
1797 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1798 size_t pad_len;
1800 DEBUG(10, ("Checking request auth.\n"));
1802 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1803 hdr_size += 16;
1806 /* in case of sealing this function will unseal the data in place */
1807 status = dcerpc_check_auth(auth, pkt,
1808 &pkt->u.request.stub_and_verifier,
1809 hdr_size, raw_pkt,
1810 &pad_len);
1811 if (!NT_STATUS_IS_OK(status)) {
1812 return status;
1816 /* remove padding and auth trailer,
1817 * this way the caller will get just the data */
1818 if (pkt->auth_length) {
1819 size_t trail_len = pad_len
1820 + DCERPC_AUTH_TRAILER_LENGTH
1821 + pkt->auth_length;
1822 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1823 return NT_STATUS_INFO_LENGTH_MISMATCH;
1825 pkt->u.request.stub_and_verifier.length -= trail_len;
1828 return NT_STATUS_OK;
1831 /****************************************************************************
1832 Processes a request pdu. This will do auth processing if needed, and
1833 appends the data into the complete stream if the LAST flag is not set.
1834 ****************************************************************************/
1836 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1838 NTSTATUS status;
1839 DATA_BLOB data;
1841 if (!p->pipe_bound) {
1842 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1843 set_incoming_fault(p);
1844 return False;
1847 /* Store the opnum */
1848 p->opnum = pkt->u.request.opnum;
1850 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1853 nt_errstr(status)));
1854 set_incoming_fault(p);
1855 return false;
1858 data = pkt->u.request.stub_and_verifier;
1861 * Check the data length doesn't go over the 15Mb limit.
1862 * increased after observing a bug in the Windows NT 4.0 SP6a
1863 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1864 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1867 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1868 DEBUG(0, ("process_request_pdu: "
1869 "rpc data buffer too large (%u) + (%u)\n",
1870 (unsigned int)p->in_data.data.length,
1871 (unsigned int)data.length));
1872 set_incoming_fault(p);
1873 return False;
1877 * Append the data portion into the buffer and return.
1880 if (data.length) {
1881 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1882 data.data, data.length)) {
1883 DEBUG(0, ("Unable to append data size %u "
1884 "to parse buffer of size %u.\n",
1885 (unsigned int)data.length,
1886 (unsigned int)p->in_data.data.length));
1887 set_incoming_fault(p);
1888 return False;
1892 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1893 bool ret = False;
1895 * Ok - we finally have a complete RPC stream.
1896 * Call the rpc command to process it.
1900 * Process the complete data stream here.
1902 if (pipe_init_outgoing_data(p)) {
1903 ret = api_pipe_request(p, pkt);
1906 return ret;
1909 return True;
1912 /****************************************************************************
1913 Processes a finished PDU stored in p->in_data.pdu.
1914 ****************************************************************************/
1916 void process_complete_pdu(struct pipes_struct *p)
1918 struct ncacn_packet *pkt = NULL;
1919 NTSTATUS status;
1920 bool reply = False;
1922 if(p->fault_state) {
1923 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
1924 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1925 goto done;
1928 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1929 if (!pkt) {
1930 DEBUG(0, ("Out of memory!\n"));
1931 goto done;
1935 * Ensure we're using the corrent endianness for both the
1936 * RPC header flags and the raw data we will be reading from.
1938 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1939 p->endian = RPC_LITTLE_ENDIAN;
1940 } else {
1941 p->endian = RPC_BIG_ENDIAN;
1943 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1945 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1946 pkt, p->endian);
1947 if (!NT_STATUS_IS_OK(status)) {
1948 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1949 nt_errstr(status)));
1950 goto done;
1953 /* Store the call_id */
1954 p->call_id = pkt->call_id;
1956 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
1958 switch (pkt->ptype) {
1959 case DCERPC_PKT_REQUEST:
1960 reply = process_request_pdu(p, pkt);
1961 break;
1963 case DCERPC_PKT_PING: /* CL request - ignore... */
1964 DEBUG(0, ("process_complete_pdu: Error. "
1965 "Connectionless packet type %d received on "
1966 "pipe %s.\n", (int)pkt->ptype,
1967 get_pipe_name_from_syntax(talloc_tos(),
1968 &p->syntax)));
1969 break;
1971 case DCERPC_PKT_RESPONSE: /* No responses here. */
1972 DEBUG(0, ("process_complete_pdu: Error. "
1973 "DCERPC_PKT_RESPONSE received from client "
1974 "on pipe %s.\n",
1975 get_pipe_name_from_syntax(talloc_tos(),
1976 &p->syntax)));
1977 break;
1979 case DCERPC_PKT_FAULT:
1980 case DCERPC_PKT_WORKING:
1981 /* CL request - reply to a ping when a call in process. */
1982 case DCERPC_PKT_NOCALL:
1983 /* CL - server reply to a ping call. */
1984 case DCERPC_PKT_REJECT:
1985 case DCERPC_PKT_ACK:
1986 case DCERPC_PKT_CL_CANCEL:
1987 case DCERPC_PKT_FACK:
1988 case DCERPC_PKT_CANCEL_ACK:
1989 DEBUG(0, ("process_complete_pdu: Error. "
1990 "Connectionless packet type %u received on "
1991 "pipe %s.\n", (unsigned int)pkt->ptype,
1992 get_pipe_name_from_syntax(talloc_tos(),
1993 &p->syntax)));
1994 break;
1996 case DCERPC_PKT_BIND:
1998 * We assume that a pipe bind is only in one pdu.
2000 if (pipe_init_outgoing_data(p)) {
2001 reply = api_pipe_bind_req(p, pkt);
2003 break;
2005 case DCERPC_PKT_BIND_ACK:
2006 case DCERPC_PKT_BIND_NAK:
2007 DEBUG(0, ("process_complete_pdu: Error. "
2008 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
2009 "packet type %u received on pipe %s.\n",
2010 (unsigned int)pkt->ptype,
2011 get_pipe_name_from_syntax(talloc_tos(),
2012 &p->syntax)));
2013 break;
2016 case DCERPC_PKT_ALTER:
2018 * We assume that a pipe bind is only in one pdu.
2020 if (pipe_init_outgoing_data(p)) {
2021 reply = api_pipe_alter_context(p, pkt);
2023 break;
2025 case DCERPC_PKT_ALTER_RESP:
2026 DEBUG(0, ("process_complete_pdu: Error. "
2027 "DCERPC_PKT_ALTER_RESP on pipe %s: "
2028 "Should only be server -> client.\n",
2029 get_pipe_name_from_syntax(talloc_tos(),
2030 &p->syntax)));
2031 break;
2033 case DCERPC_PKT_AUTH3:
2035 * The third packet in an auth exchange.
2037 if (pipe_init_outgoing_data(p)) {
2038 reply = api_pipe_bind_auth3(p, pkt);
2040 break;
2042 case DCERPC_PKT_SHUTDOWN:
2043 DEBUG(0, ("process_complete_pdu: Error. "
2044 "DCERPC_PKT_SHUTDOWN on pipe %s: "
2045 "Should only be server -> client.\n",
2046 get_pipe_name_from_syntax(talloc_tos(),
2047 &p->syntax)));
2048 break;
2050 case DCERPC_PKT_CO_CANCEL:
2051 /* For now just free all client data and continue
2052 * processing. */
2053 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
2054 " Abandoning rpc call.\n"));
2055 /* As we never do asynchronous RPC serving, we can
2056 * never cancel a call (as far as I know).
2057 * If we ever did we'd have to send a cancel_ack reply.
2058 * For now, just free all client data and continue
2059 * processing. */
2060 reply = True;
2061 break;
2063 #if 0
2064 /* Enable this if we're doing async rpc. */
2065 /* We must check the outstanding callid matches. */
2066 if (pipe_init_outgoing_data(p)) {
2067 /* Send a cancel_ack PDU reply. */
2068 /* We should probably check the auth-verifier here. */
2069 reply = setup_cancel_ack_reply(p, pkt);
2071 break;
2072 #endif
2074 case DCERPC_PKT_ORPHANED:
2075 /* We should probably check the auth-verifier here.
2076 * For now just free all client data and continue
2077 * processing. */
2078 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
2079 " Abandoning rpc call.\n"));
2080 reply = True;
2081 break;
2083 default:
2084 DEBUG(0, ("process_complete_pdu: "
2085 "Unknown rpc type = %u received.\n",
2086 (unsigned int)pkt->ptype));
2087 break;
2090 done:
2091 if (!reply) {
2092 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
2093 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
2094 &p->syntax)));
2095 set_incoming_fault(p);
2096 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
2097 TALLOC_FREE(pkt);
2098 } else {
2100 * Reset the lengths. We're ready for a new pdu.
2102 TALLOC_FREE(p->in_data.pdu.data);
2103 p->in_data.pdu_needed_len = 0;
2104 p->in_data.pdu.length = 0;
2107 TALLOC_FREE(pkt);