s3-dcerpc: make a few local functions as static
[Samba/vl.git] / source3 / rpc_server / srv_pipe.c
blob18414f0642da7e87e938a05e3da92cc70902f840
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 "../libcli/auth/ntlmssp.h"
36 #include "ntlmssp_wrap.h"
37 #include "rpc_server.h"
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_RPC_SRV
42 /**
43 * Dump everything from the start of the end up of the provided data
44 * into a file, but only at debug level >= 50
45 **/
46 static void dump_pdu_region(const char *name, int v,
47 DATA_BLOB *data, size_t start, size_t end)
49 int fd, i;
50 char *fname = NULL;
51 ssize_t sz;
53 if (DEBUGLEVEL < 50) return;
55 if (start > data->length || end > data->length || start > end) return;
57 for (i = 1; i < 100; i++) {
58 if (v != -1) {
59 fname = talloc_asprintf(talloc_tos(),
60 "/tmp/%s_%d.%d.prs",
61 name, v, i);
62 } else {
63 fname = talloc_asprintf(talloc_tos(),
64 "/tmp/%s_%d.prs",
65 name, i);
67 if (!fname) {
68 return;
70 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
71 if (fd != -1 || errno != EEXIST) break;
73 if (fd != -1) {
74 sz = write(fd, data->data + start, end - start);
75 i = close(fd);
76 if ((sz != end - start) || (i != 0) ) {
77 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
78 fname, (unsigned long)sz,
79 (unsigned long)end - start, i));
80 } else {
81 DEBUG(0,("created %s\n", fname));
84 TALLOC_FREE(fname);
87 static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth)
89 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
92 static void free_pipe_schannel_auth_data(struct pipe_auth_data *auth)
94 TALLOC_FREE(auth->a_u.schannel_auth);
97 static void free_pipe_auth_data(struct pipe_auth_data *auth)
99 if (auth->auth_data_free_func) {
100 (*auth->auth_data_free_func)(auth);
101 auth->auth_data_free_func = NULL;
105 static DATA_BLOB generic_session_key(void)
107 return data_blob("SystemLibraryDTC", 16);
110 /*******************************************************************
111 Generate the next PDU to be returned from the data.
112 ********************************************************************/
114 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
115 struct pipe_auth_data *auth,
116 uint32_t call_id,
117 DATA_BLOB *rdata,
118 size_t data_sent_length,
119 DATA_BLOB *frag,
120 size_t *pdu_size)
122 union dcerpc_payload u;
123 uint8_t pfc_flags;
124 size_t data_left;
125 size_t data_to_send;
126 size_t frag_len;
127 size_t pad_len = 0;
128 size_t auth_len = 0;
129 NTSTATUS status;
131 ZERO_STRUCT(u.response);
133 /* Set up rpc packet pfc flags. */
134 if (data_sent_length == 0) {
135 pfc_flags = DCERPC_PFC_FLAG_FIRST;
136 } else {
137 pfc_flags = 0;
140 /* Work out how much we can fit in a single PDU. */
141 data_left = rdata->length - data_sent_length;
143 /* Ensure there really is data left to send. */
144 if (!data_left) {
145 DEBUG(0, ("No data left to send !\n"));
146 return NT_STATUS_BUFFER_TOO_SMALL;
149 status = dcerpc_guess_sizes(auth,
150 DCERPC_RESPONSE_LENGTH,
151 data_left,
152 RPC_MAX_PDU_FRAG_LEN,
153 SERVER_NDR_PADDING_SIZE,
154 &data_to_send, &frag_len,
155 &auth_len, &pad_len);
156 if (!NT_STATUS_IS_OK(status)) {
157 return status;
160 /* Set up the alloc hint. This should be the data left to send. */
161 u.response.alloc_hint = data_left;
163 /* Work out if this PDU will be the last. */
164 if (data_sent_length + data_to_send >= rdata->length) {
165 pfc_flags |= DCERPC_PFC_FLAG_LAST;
168 /* Prepare data to be NDR encoded. */
169 u.response.stub_and_verifier =
170 data_blob_const(rdata->data + data_sent_length, data_to_send);
172 /* Store the packet in the data stream. */
173 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
174 pfc_flags, auth_len, call_id,
175 &u, frag);
176 if (!NT_STATUS_IS_OK(status)) {
177 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
178 return status;
181 if (auth_len) {
182 /* Set the proper length on the pdu, including padding.
183 * Only needed if an auth trailer will be appended. */
184 dcerpc_set_frag_length(frag, frag->length
185 + pad_len
186 + DCERPC_AUTH_TRAILER_LENGTH
187 + auth_len);
190 if (auth_len) {
191 status = dcerpc_add_auth_footer(auth, pad_len, frag);
192 if (!NT_STATUS_IS_OK(status)) {
193 data_blob_free(frag);
194 return status;
198 *pdu_size = data_to_send;
199 return NT_STATUS_OK;
202 /*******************************************************************
203 Generate the next PDU to be returned from the data in p->rdata.
204 ********************************************************************/
206 bool create_next_pdu(struct pipes_struct *p)
208 size_t pdu_size = 0;
209 NTSTATUS status;
212 * If we're in the fault state, keep returning fault PDU's until
213 * the pipe gets closed. JRA.
215 if (p->fault_state) {
216 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
217 return true;
220 status = create_next_packet(p->mem_ctx, &p->auth,
221 p->call_id, &p->out_data.rdata,
222 p->out_data.data_sent_length,
223 &p->out_data.frag, &pdu_size);
224 if (!NT_STATUS_IS_OK(status)) {
225 DEBUG(0, ("Failed to create packet with error %s, "
226 "(auth level %u / type %u)\n",
227 nt_errstr(status),
228 (unsigned int)p->auth.auth_level,
229 (unsigned int)p->auth.auth_type));
230 return false;
233 /* Setup the counts for this PDU. */
234 p->out_data.data_sent_length += pdu_size;
235 p->out_data.current_pdu_sent = 0;
236 return true;
239 /*******************************************************************
240 Process an NTLMSSP authentication response.
241 If this function succeeds, the user has been authenticated
242 and their domain, name and calling workstation stored in
243 the pipe struct.
244 *******************************************************************/
246 static bool pipe_ntlmssp_verify_final(struct pipes_struct *p,
247 DATA_BLOB *p_resp_blob)
249 DATA_BLOB session_key, reply;
250 NTSTATUS status;
251 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
252 bool ret;
254 DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n",
255 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
257 ZERO_STRUCT(reply);
259 /* this has to be done as root in order to verify the password */
260 become_root();
261 status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
262 unbecome_root();
264 /* Don't generate a reply. */
265 data_blob_free(&reply);
267 if (!NT_STATUS_IS_OK(status)) {
268 return False;
271 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
272 ensure the underlying NTLMSSP flags are also set. If not we should
273 refuse the bind. */
275 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
276 if (!auth_ntlmssp_negotiated_sign(a)) {
277 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet integrity requested "
278 "but client declined signing.\n",
279 get_pipe_name_from_syntax(talloc_tos(),
280 &p->syntax)));
281 return False;
284 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
285 if (!auth_ntlmssp_negotiated_seal(a)) {
286 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet privacy requested "
287 "but client declined sealing.\n",
288 get_pipe_name_from_syntax(talloc_tos(),
289 &p->syntax)));
290 return False;
294 DEBUG(5, ("pipe_ntlmssp_verify_final: OK: user: %s domain: %s "
295 "workstation: %s\n",
296 auth_ntlmssp_get_username(a),
297 auth_ntlmssp_get_domain(a),
298 auth_ntlmssp_get_client(a)));
300 TALLOC_FREE(p->server_info);
302 status = auth_ntlmssp_steal_server_info(p, a, &p->server_info);
303 if (!NT_STATUS_IS_OK(status)) {
304 DEBUG(0, ("auth_ntlmssp_server_info failed to obtain the server info for authenticated user: %s\n",
305 nt_errstr(status)));
306 return false;
309 if (p->server_info->ptok == NULL) {
310 DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
311 return False;
315 * We're an authenticated bind over smb, so the session key needs to
316 * be set to "SystemLibraryDTC". Weird, but this is what Windows
317 * does. See the RPC-SAMBA3SESSIONKEY.
320 session_key = generic_session_key();
321 if (session_key.data == NULL) {
322 return False;
325 ret = server_info_set_session_key(p->server_info, session_key);
327 data_blob_free(&session_key);
329 return True;
332 /*******************************************************************
333 This is the "stage3" NTLMSSP response after a bind request and reply.
334 *******************************************************************/
336 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
338 struct dcerpc_auth auth_info;
339 NTSTATUS status;
341 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
343 if (pkt->auth_length == 0) {
344 DEBUG(0, ("No auth field sent for bind request!\n"));
345 goto err;
348 /* Ensure there's enough data for an authenticated request. */
349 if (pkt->frag_length < RPC_HEADER_LEN
350 + DCERPC_AUTH_TRAILER_LENGTH
351 + pkt->auth_length) {
352 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
353 "%u is too large.\n",
354 (unsigned int)pkt->auth_length));
355 goto err;
359 * Decode the authentication verifier response.
362 status = dcerpc_pull_dcerpc_auth(pkt,
363 &pkt->u.auth3.auth_info,
364 &auth_info, p->endian);
365 if (!NT_STATUS_IS_OK(status)) {
366 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
367 goto err;
370 /* We must NEVER look at auth_info->auth_pad_len here,
371 * as old Samba client code gets it wrong and sends it
372 * as zero. JRA.
375 if (auth_info.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) {
376 DEBUG(0,("api_pipe_bind_auth3: incorrect auth type (%u).\n",
377 (unsigned int)auth_info.auth_type ));
378 return False;
382 * The following call actually checks the challenge/response data.
383 * for correctness against the given DOMAIN\user name.
386 if (!pipe_ntlmssp_verify_final(p, &auth_info.credentials)) {
387 goto err;
390 p->pipe_bound = True;
392 return True;
394 err:
396 free_pipe_auth_data(&p->auth);
398 return False;
401 static bool pipe_init_outgoing_data(struct pipes_struct *p);
403 /*******************************************************************
404 Marshall a bind_nak pdu.
405 *******************************************************************/
407 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
409 NTSTATUS status;
410 union dcerpc_payload u;
412 /* Free any memory in the current return data buffer. */
413 pipe_init_outgoing_data(p);
416 * Initialize a bind_nak header.
419 ZERO_STRUCT(u);
421 u.bind_nak.reject_reason = 0;
424 * Marshall directly into the outgoing PDU space. We
425 * must do this as we need to set to the bind response
426 * header and are never sending more than one PDU here.
429 status = dcerpc_push_ncacn_packet(p->mem_ctx,
430 DCERPC_PKT_BIND_NAK,
431 DCERPC_PFC_FLAG_FIRST |
432 DCERPC_PFC_FLAG_LAST,
434 pkt->call_id,
436 &p->out_data.frag);
437 if (!NT_STATUS_IS_OK(status)) {
438 return False;
441 p->out_data.data_sent_length = 0;
442 p->out_data.current_pdu_sent = 0;
444 free_pipe_auth_data(&p->auth);
445 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
446 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
447 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
448 p->pipe_bound = False;
450 return True;
453 /*******************************************************************
454 Marshall a fault pdu.
455 *******************************************************************/
457 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
459 NTSTATUS status;
460 union dcerpc_payload u;
462 /* Free any memory in the current return data buffer. */
463 pipe_init_outgoing_data(p);
466 * Initialize a fault header.
469 ZERO_STRUCT(u);
471 u.fault.status = NT_STATUS_V(fault_status);
472 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
475 * Marshall directly into the outgoing PDU space. We
476 * must do this as we need to set to the bind response
477 * header and are never sending more than one PDU here.
480 status = dcerpc_push_ncacn_packet(p->mem_ctx,
481 DCERPC_PKT_FAULT,
482 DCERPC_PFC_FLAG_FIRST |
483 DCERPC_PFC_FLAG_LAST |
484 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
486 p->call_id,
488 &p->out_data.frag);
489 if (!NT_STATUS_IS_OK(status)) {
490 return False;
493 p->out_data.data_sent_length = 0;
494 p->out_data.current_pdu_sent = 0;
496 return True;
499 /*******************************************************************
500 Ensure a bind request has the correct abstract & transfer interface.
501 Used to reject unknown binds from Win2k.
502 *******************************************************************/
504 static bool check_bind_req(struct pipes_struct *p,
505 struct ndr_syntax_id* abstract,
506 struct ndr_syntax_id* transfer,
507 uint32 context_id)
509 struct pipe_rpc_fns *context_fns;
511 DEBUG(3,("check_bind_req for %s\n",
512 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
514 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
515 if (rpc_srv_pipe_exists_by_id(abstract) &&
516 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
517 DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
518 rpc_srv_get_pipe_cli_name(abstract),
519 rpc_srv_get_pipe_srv_name(abstract)));
520 } else {
521 return false;
524 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
525 if (context_fns == NULL) {
526 DEBUG(0,("check_bind_req: malloc() failed!\n"));
527 return False;
530 context_fns->next = context_fns->prev = NULL;
531 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
532 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
533 context_fns->context_id = context_id;
535 /* add to the list of open contexts */
537 DLIST_ADD( p->contexts, context_fns );
539 return True;
543 * Is a named pipe known?
544 * @param[in] cli_filename The pipe name requested by the client
545 * @result Do we want to serve this?
547 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
549 const char *pipename = cli_filename;
550 NTSTATUS status;
552 if (strnequal(pipename, "\\PIPE\\", 6)) {
553 pipename += 5;
556 if (*pipename == '\\') {
557 pipename += 1;
560 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
561 DEBUG(10, ("refusing spoolss access\n"));
562 return false;
565 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
566 return true;
569 status = smb_probe_module("rpc", pipename);
570 if (!NT_STATUS_IS_OK(status)) {
571 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
572 return false;
574 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
577 * Scan the list again for the interface id
579 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
580 return true;
583 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
584 pipename));
586 return false;
589 /*******************************************************************
590 Handle a SPNEGO krb5 bind auth.
591 *******************************************************************/
593 static bool pipe_spnego_auth_bind_kerberos(struct pipes_struct *p,
594 TALLOC_CTX *mem_ctx,
595 struct dcerpc_auth *pauth_info,
596 DATA_BLOB *psecblob,
597 DATA_BLOB *response)
599 return False;
602 /*******************************************************************
603 Handle the first part of a SPNEGO bind auth.
604 *******************************************************************/
606 static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p,
607 TALLOC_CTX *mem_ctx,
608 struct dcerpc_auth *pauth_info,
609 DATA_BLOB *response)
611 DATA_BLOB secblob;
612 DATA_BLOB chal;
613 char *OIDs[ASN1_MAX_OIDS];
614 int i;
615 NTSTATUS status;
616 bool got_kerberos_mechanism = false;
617 struct auth_ntlmssp_state *a = NULL;
619 ZERO_STRUCT(secblob);
620 ZERO_STRUCT(chal);
622 if (pauth_info->credentials.data[0] != ASN1_APPLICATION(0)) {
623 goto err;
626 /* parse out the OIDs and the first sec blob */
627 if (!spnego_parse_negTokenInit(talloc_tos(),
628 pauth_info->credentials, OIDs, NULL, &secblob)) {
629 DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
630 goto err;
633 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
634 got_kerberos_mechanism = true;
637 for (i=0;OIDs[i];i++) {
638 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));
639 TALLOC_FREE(OIDs[i]);
641 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
643 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB) ) {
644 bool ret;
645 ret = pipe_spnego_auth_bind_kerberos(p, mem_ctx, pauth_info,
646 &secblob, response);
647 data_blob_free(&secblob);
648 return ret;
651 /* Free any previous auth type. */
652 free_pipe_auth_data(&p->auth);
654 if (!got_kerberos_mechanism) {
655 /* Initialize the NTLM engine. */
656 status = auth_ntlmssp_start(&a);
657 if (!NT_STATUS_IS_OK(status)) {
658 goto err;
661 /* Clear flags,
662 * then set them according to requested Auth Level */
663 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
664 NTLMSSP_NEGOTIATE_SEAL));
665 switch (pauth_info->auth_level) {
666 case DCERPC_AUTH_LEVEL_INTEGRITY:
667 auth_ntlmssp_or_flags(a,
668 NTLMSSP_NEGOTIATE_SIGN);
669 break;
670 case DCERPC_AUTH_LEVEL_PRIVACY:
671 /* Privacy always implies both sign and seal
672 * for ntlmssp */
673 auth_ntlmssp_or_flags(a,
674 NTLMSSP_NEGOTIATE_SIGN |
675 NTLMSSP_NEGOTIATE_SEAL);
676 break;
677 default:
678 break;
681 * Pass the first security blob of data to it.
682 * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
683 * which means we need another packet to complete the bind.
686 status = auth_ntlmssp_update(a, secblob, &chal);
688 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
689 DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
690 goto err;
693 /* Generate the response blob we need for step 2 of the bind. */
694 *response = spnego_gen_auth_response(mem_ctx, &chal, status, OID_NTLMSSP);
695 } else {
697 * SPNEGO negotiate down to NTLMSSP. The subsequent
698 * code to process follow-up packets is not complete
699 * yet. JRA.
701 *response = spnego_gen_auth_response(mem_ctx, NULL,
702 NT_STATUS_MORE_PROCESSING_REQUIRED,
703 OID_NTLMSSP);
706 /* auth_pad_len will be handled by the caller */
708 p->auth.a_u.auth_ntlmssp_state = a;
709 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
710 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
711 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
713 data_blob_free(&secblob);
714 data_blob_free(&chal);
716 /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */
717 return True;
719 err:
721 data_blob_free(&secblob);
722 data_blob_free(&chal);
724 p->auth.a_u.auth_ntlmssp_state = NULL;
726 return False;
729 /*******************************************************************
730 Handle the second part of a SPNEGO bind auth.
731 *******************************************************************/
733 static bool pipe_spnego_auth_bind_continue(struct pipes_struct *p,
734 TALLOC_CTX *mem_ctx,
735 struct dcerpc_auth *pauth_info,
736 DATA_BLOB *response)
738 DATA_BLOB auth_blob;
739 DATA_BLOB auth_reply;
740 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
742 ZERO_STRUCT(auth_blob);
743 ZERO_STRUCT(auth_reply);
746 * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently
747 * fail here as 'a' == NULL.
749 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO ||
750 p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {
751 DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));
752 goto err;
755 if (pauth_info->credentials.data[0] != ASN1_CONTEXT(1)) {
756 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));
757 goto err;
760 if (!spnego_parse_auth(talloc_tos(), pauth_info->credentials, &auth_blob)) {
761 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
762 goto err;
766 * The following call actually checks the challenge/response data.
767 * for correctness against the given DOMAIN\user name.
770 if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {
771 goto err;
774 data_blob_free(&auth_blob);
776 /* Generate the spnego "accept completed" blob - no incoming data. */
777 *response = spnego_gen_auth_response(mem_ctx, &auth_reply, NT_STATUS_OK, OID_NTLMSSP);
779 data_blob_free(&auth_reply);
781 p->pipe_bound = True;
783 return True;
785 err:
787 data_blob_free(&auth_blob);
788 data_blob_free(&auth_reply);
790 free_pipe_auth_data(&p->auth);
792 return False;
795 /*******************************************************************
796 Handle an schannel bind auth.
797 *******************************************************************/
799 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
800 TALLOC_CTX *mem_ctx,
801 struct dcerpc_auth *auth_info,
802 DATA_BLOB *response)
804 struct NL_AUTH_MESSAGE neg;
805 struct NL_AUTH_MESSAGE reply;
806 bool ret;
807 NTSTATUS status;
808 struct netlogon_creds_CredentialState *creds;
809 DATA_BLOB session_key;
810 enum ndr_err_code ndr_err;
812 ndr_err = ndr_pull_struct_blob(
813 &auth_info->credentials, mem_ctx, &neg,
814 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
815 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
816 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
817 return false;
820 if (DEBUGLEVEL >= 10) {
821 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
824 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
825 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
826 return false;
830 * The neg.oem_netbios_computer.a key here must match the remote computer name
831 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
832 * operations that use credentials.
835 become_root();
836 status = schannel_get_creds_state(p, lp_private_dir(),
837 neg.oem_netbios_computer.a, &creds);
838 unbecome_root();
840 if (!NT_STATUS_IS_OK(status)) {
841 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
842 return False;
845 p->auth.a_u.schannel_auth = talloc(p, struct schannel_state);
846 if (!p->auth.a_u.schannel_auth) {
847 TALLOC_FREE(creds);
848 return False;
851 p->auth.a_u.schannel_auth->state = SCHANNEL_STATE_START;
852 p->auth.a_u.schannel_auth->seq_num = 0;
853 p->auth.a_u.schannel_auth->initiator = false;
854 p->auth.a_u.schannel_auth->creds = creds;
857 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
858 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
859 * struct of the person who opened the pipe. I need to test this further. JRA.
861 * VL. As we are mapping this to guest set the generic key
862 * "SystemLibraryDTC" key here. It's a bit difficult to test against
863 * W2k3, as it does not allow schannel binds against SAMR and LSA
864 * anymore.
867 session_key = generic_session_key();
868 if (session_key.data == NULL) {
869 DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session"
870 " key\n"));
871 return false;
874 ret = server_info_set_session_key(p->server_info, session_key);
876 data_blob_free(&session_key);
878 if (!ret) {
879 DEBUG(0, ("server_info_set_session_key failed\n"));
880 return false;
883 /*** SCHANNEL verifier ***/
885 reply.MessageType = NL_NEGOTIATE_RESPONSE;
886 reply.Flags = 0;
887 reply.Buffer.dummy = 5; /* ??? actually I don't think
888 * this has any meaning
889 * here - gd */
891 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
892 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
893 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
894 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
895 return false;
898 if (DEBUGLEVEL >= 10) {
899 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
902 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
903 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
905 /* We're finished with this bind - no more packets. */
906 p->auth.auth_data_free_func = &free_pipe_schannel_auth_data;
907 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
909 p->pipe_bound = True;
911 return True;
914 /*******************************************************************
915 Handle an NTLMSSP bind auth.
916 *******************************************************************/
918 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
919 TALLOC_CTX *mem_ctx,
920 struct dcerpc_auth *auth_info,
921 DATA_BLOB *response)
923 NTSTATUS status;
924 struct auth_ntlmssp_state *a = NULL;
926 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
927 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
928 goto err;
931 /* We have an NTLMSSP blob. */
932 status = auth_ntlmssp_start(&a);
933 if (!NT_STATUS_IS_OK(status)) {
934 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",
935 nt_errstr(status) ));
936 goto err;
939 /* Clear flags, then set them according to requested Auth Level */
940 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
941 NTLMSSP_NEGOTIATE_SEAL));
943 switch (auth_info->auth_level) {
944 case DCERPC_AUTH_LEVEL_INTEGRITY:
945 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN);
946 break;
947 case DCERPC_AUTH_LEVEL_PRIVACY:
948 /* Privacy always implies both sign and seal for ntlmssp */
949 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN |
950 NTLMSSP_NEGOTIATE_SEAL);
951 break;
952 default:
953 break;
956 status = auth_ntlmssp_update(a, auth_info->credentials, response);
957 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
958 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n",
959 nt_errstr(status) ));
960 goto err;
963 /* Make sure data is bound to the memctx, to be freed the caller */
964 talloc_steal(mem_ctx, response->data);
966 p->auth.a_u.auth_ntlmssp_state = a;
967 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
968 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
970 DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
972 /* We can't set pipe_bound True yet - we need an DCERPC_PKT_AUTH3 response packet... */
973 return True;
975 err:
977 TALLOC_FREE(a);
978 return False;
981 /*******************************************************************
982 Respond to a pipe bind request.
983 *******************************************************************/
985 static bool api_pipe_bind_req(struct pipes_struct *p,
986 struct ncacn_packet *pkt)
988 struct dcerpc_auth auth_info;
989 uint16 assoc_gid;
990 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
991 NTSTATUS status;
992 struct ndr_syntax_id id;
993 union dcerpc_payload u;
994 struct dcerpc_ack_ctx bind_ack_ctx;
995 DATA_BLOB auth_resp = data_blob_null;
996 DATA_BLOB auth_blob = data_blob_null;
998 /* No rebinds on a bound pipe - use alter context. */
999 if (p->pipe_bound) {
1000 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
1001 "pipe %s.\n",
1002 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1003 return setup_bind_nak(p, pkt);
1006 if (pkt->u.bind.num_contexts == 0) {
1007 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
1008 goto err_exit;
1012 * Try and find the correct pipe name to ensure
1013 * that this is a pipe name we support.
1015 id = pkt->u.bind.ctx_list[0].abstract_syntax;
1016 if (rpc_srv_pipe_exists_by_id(&id)) {
1017 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1018 rpc_srv_get_pipe_cli_name(&id),
1019 rpc_srv_get_pipe_srv_name(&id)));
1020 } else {
1021 status = smb_probe_module(
1022 "rpc", get_pipe_name_from_syntax(
1023 talloc_tos(),
1024 &pkt->u.bind.ctx_list[0].abstract_syntax));
1026 if (NT_STATUS_IS_ERR(status)) {
1027 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
1028 get_pipe_name_from_syntax(
1029 talloc_tos(),
1030 &pkt->u.bind.ctx_list[0].abstract_syntax)));
1032 return setup_bind_nak(p, pkt);
1035 if (rpc_srv_get_pipe_interface_by_cli_name(
1036 get_pipe_name_from_syntax(talloc_tos(),
1037 &p->syntax),
1038 &id)) {
1039 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1040 rpc_srv_get_pipe_cli_name(&id),
1041 rpc_srv_get_pipe_srv_name(&id)));
1042 } else {
1043 DEBUG(0, ("module %s doesn't provide functions for "
1044 "pipe %s!\n",
1045 get_pipe_name_from_syntax(talloc_tos(),
1046 &p->syntax),
1047 get_pipe_name_from_syntax(talloc_tos(),
1048 &p->syntax)));
1049 return setup_bind_nak(p, pkt);
1053 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
1055 if (pkt->u.bind.assoc_group_id != 0) {
1056 assoc_gid = pkt->u.bind.assoc_group_id;
1057 } else {
1058 assoc_gid = 0x53f0;
1062 * Create the bind response struct.
1065 /* If the requested abstract synt uuid doesn't match our client pipe,
1066 reject the bind_ack & set the transfer interface synt to all 0's,
1067 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1068 unknown to NT4)
1069 Needed when adding entries to a DACL from NT5 - SK */
1071 if (check_bind_req(p,
1072 &pkt->u.bind.ctx_list[0].abstract_syntax,
1073 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1074 pkt->u.bind.ctx_list[0].context_id)) {
1076 bind_ack_ctx.result = 0;
1077 bind_ack_ctx.reason = 0;
1078 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1079 } else {
1080 p->pipe_bound = False;
1081 /* Rejection reason: abstract syntax not supported */
1082 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1083 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1084 bind_ack_ctx.syntax = null_ndr_syntax_id;
1088 * Check if this is an authenticated bind request.
1090 if (pkt->auth_length) {
1091 /* Quick length check. Won't catch a bad auth footer,
1092 * prevents overrun. */
1094 if (pkt->frag_length < RPC_HEADER_LEN +
1095 DCERPC_AUTH_TRAILER_LENGTH +
1096 pkt->auth_length) {
1097 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
1098 "too long for fragment %u.\n",
1099 (unsigned int)pkt->auth_length,
1100 (unsigned int)pkt->frag_length));
1101 goto err_exit;
1105 * Decode the authentication verifier.
1107 status = dcerpc_pull_dcerpc_auth(pkt,
1108 &pkt->u.bind.auth_info,
1109 &auth_info, p->endian);
1110 if (!NT_STATUS_IS_OK(status)) {
1111 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1112 goto err_exit;
1115 auth_type = auth_info.auth_type;
1117 /* Work out if we have to sign or seal etc. */
1118 switch (auth_info.auth_level) {
1119 case DCERPC_AUTH_LEVEL_INTEGRITY:
1120 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1121 break;
1122 case DCERPC_AUTH_LEVEL_PRIVACY:
1123 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1124 break;
1125 default:
1126 DEBUG(0, ("Unexpected auth level (%u).\n",
1127 (unsigned int)auth_info.auth_level ));
1128 goto err_exit;
1131 switch (auth_type) {
1132 case DCERPC_AUTH_TYPE_NTLMSSP:
1133 if (!pipe_ntlmssp_auth_bind(p, pkt,
1134 &auth_info, &auth_resp)) {
1135 goto err_exit;
1137 assoc_gid = 0x7a77;
1138 break;
1140 case DCERPC_AUTH_TYPE_SCHANNEL:
1141 if (!pipe_schannel_auth_bind(p, pkt,
1142 &auth_info, &auth_resp)) {
1143 goto err_exit;
1145 break;
1147 case DCERPC_AUTH_TYPE_SPNEGO:
1148 if (!pipe_spnego_auth_bind_negotiate(p, pkt,
1149 &auth_info, &auth_resp)) {
1150 goto err_exit;
1152 break;
1154 case DCERPC_AUTH_TYPE_NONE:
1155 break;
1157 default:
1158 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1159 goto err_exit;
1163 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1164 /* Unauthenticated bind request. */
1165 /* We're finished - no more packets. */
1166 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1167 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
1168 /* We must set the pipe auth_level here also. */
1169 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1170 p->pipe_bound = True;
1171 /* The session key was initialized from the SMB
1172 * session in make_internal_rpc_pipe_p */
1175 ZERO_STRUCT(u.bind_ack);
1176 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1177 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1178 u.bind_ack.assoc_group_id = assoc_gid;
1180 /* name has to be \PIPE\xxxxx */
1181 u.bind_ack.secondary_address =
1182 talloc_asprintf(pkt, "\\PIPE\\%s",
1183 rpc_srv_get_pipe_srv_name(&id));
1184 if (!u.bind_ack.secondary_address) {
1185 DEBUG(0, ("Out of memory!\n"));
1186 goto err_exit;
1188 u.bind_ack.secondary_address_size =
1189 strlen(u.bind_ack.secondary_address) + 1;
1191 u.bind_ack.num_results = 1;
1192 u.bind_ack.ctx_list = &bind_ack_ctx;
1194 /* NOTE: We leave the auth_info empty so we can calculate the padding
1195 * later and then append the auth_info --simo */
1198 * Marshall directly into the outgoing PDU space. We
1199 * must do this as we need to set to the bind response
1200 * header and are never sending more than one PDU here.
1203 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1204 DCERPC_PKT_BIND_ACK,
1205 DCERPC_PFC_FLAG_FIRST |
1206 DCERPC_PFC_FLAG_LAST,
1207 auth_resp.length,
1208 pkt->call_id,
1210 &p->out_data.frag);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1213 nt_errstr(status)));
1216 if (auth_resp.length) {
1218 status = dcerpc_push_dcerpc_auth(pkt,
1219 auth_type,
1220 auth_info.auth_level,
1222 1, /* auth_context_id */
1223 &auth_resp,
1224 &auth_blob);
1225 if (!NT_STATUS_IS_OK(status)) {
1226 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1227 goto err_exit;
1231 /* Now that we have the auth len store it into the right place in
1232 * the dcerpc header */
1233 dcerpc_set_frag_length(&p->out_data.frag,
1234 p->out_data.frag.length + auth_blob.length);
1236 if (auth_blob.length) {
1238 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1239 auth_blob.data, auth_blob.length)) {
1240 DEBUG(0, ("Append of auth info failed.\n"));
1241 goto err_exit;
1246 * Setup the lengths for the initial reply.
1249 p->out_data.data_sent_length = 0;
1250 p->out_data.current_pdu_sent = 0;
1252 TALLOC_FREE(auth_blob.data);
1253 return True;
1255 err_exit:
1257 data_blob_free(&p->out_data.frag);
1258 TALLOC_FREE(auth_blob.data);
1259 return setup_bind_nak(p, pkt);
1262 /****************************************************************************
1263 Deal with an alter context call. Can be third part of 3 leg auth request for
1264 SPNEGO calls.
1265 ****************************************************************************/
1267 static bool api_pipe_alter_context(struct pipes_struct *p,
1268 struct ncacn_packet *pkt)
1270 struct dcerpc_auth auth_info;
1271 uint16 assoc_gid;
1272 NTSTATUS status;
1273 union dcerpc_payload u;
1274 struct dcerpc_ack_ctx bind_ack_ctx;
1275 DATA_BLOB auth_resp = data_blob_null;
1276 DATA_BLOB auth_blob = data_blob_null;
1277 int pad_len = 0;
1279 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1281 if (pkt->u.bind.assoc_group_id != 0) {
1282 assoc_gid = pkt->u.bind.assoc_group_id;
1283 } else {
1284 assoc_gid = 0x53f0;
1288 * Create the bind response struct.
1291 /* If the requested abstract synt uuid doesn't match our client pipe,
1292 reject the bind_ack & set the transfer interface synt to all 0's,
1293 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1294 unknown to NT4)
1295 Needed when adding entries to a DACL from NT5 - SK */
1297 if (check_bind_req(p,
1298 &pkt->u.bind.ctx_list[0].abstract_syntax,
1299 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1300 pkt->u.bind.ctx_list[0].context_id)) {
1302 bind_ack_ctx.result = 0;
1303 bind_ack_ctx.reason = 0;
1304 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1305 } else {
1306 p->pipe_bound = False;
1307 /* Rejection reason: abstract syntax not supported */
1308 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1309 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1310 bind_ack_ctx.syntax = null_ndr_syntax_id;
1314 * Check if this is an authenticated alter context request.
1316 if (pkt->auth_length) {
1317 /* Quick length check. Won't catch a bad auth footer,
1318 * prevents overrun. */
1320 if (pkt->frag_length < RPC_HEADER_LEN +
1321 DCERPC_AUTH_TRAILER_LENGTH +
1322 pkt->auth_length) {
1323 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1324 "too long for fragment %u.\n",
1325 (unsigned int)pkt->auth_length,
1326 (unsigned int)pkt->frag_length ));
1327 goto err_exit;
1330 status = dcerpc_pull_dcerpc_auth(pkt,
1331 &pkt->u.bind.auth_info,
1332 &auth_info, p->endian);
1333 if (!NT_STATUS_IS_OK(status)) {
1334 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1335 goto err_exit;
1340 * Currently only the SPNEGO auth type uses the alter ctx
1341 * response in place of the NTLMSSP auth3 type.
1344 if (auth_info.auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1345 /* We can only finish if the pipe is unbound. */
1346 if (!p->pipe_bound) {
1347 if (!pipe_spnego_auth_bind_continue(p, pkt,
1348 &auth_info, &auth_resp)) {
1349 goto err_exit;
1352 } else {
1353 goto err_exit;
1358 ZERO_STRUCT(u.alter_resp);
1359 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1360 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1361 u.alter_resp.assoc_group_id = assoc_gid;
1363 /* secondary address CAN be NULL
1364 * as the specs say it's ignored.
1365 * It MUST be NULL to have the spoolss working.
1367 u.alter_resp.secondary_address = "";
1368 u.alter_resp.secondary_address_size = 1;
1370 u.alter_resp.num_results = 1;
1371 u.alter_resp.ctx_list = &bind_ack_ctx;
1373 /* NOTE: We leave the auth_info empty so we can calculate the padding
1374 * later and then append the auth_info --simo */
1377 * Marshall directly into the outgoing PDU space. We
1378 * must do this as we need to set to the bind response
1379 * header and are never sending more than one PDU here.
1382 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1383 DCERPC_PKT_ALTER_RESP,
1384 DCERPC_PFC_FLAG_FIRST |
1385 DCERPC_PFC_FLAG_LAST,
1386 auth_resp.length,
1387 pkt->call_id,
1389 &p->out_data.frag);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1392 nt_errstr(status)));
1395 if (auth_resp.length) {
1397 /* Work out any padding needed before the auth footer. */
1398 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1399 if (pad_len) {
1400 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1401 DEBUG(10, ("auth pad_len = %u\n",
1402 (unsigned int)pad_len));
1405 status = dcerpc_push_dcerpc_auth(pkt,
1406 auth_info.auth_type,
1407 auth_info.auth_level,
1408 pad_len,
1409 1, /* auth_context_id */
1410 &auth_resp,
1411 &auth_blob);
1412 if (!NT_STATUS_IS_OK(status)) {
1413 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1414 goto err_exit;
1418 /* Now that we have the auth len store it into the right place in
1419 * the dcerpc header */
1420 dcerpc_set_frag_length(&p->out_data.frag,
1421 p->out_data.frag.length +
1422 pad_len + auth_blob.length);
1424 if (auth_resp.length) {
1425 if (pad_len) {
1426 char pad[SERVER_NDR_PADDING_SIZE];
1427 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1428 if (!data_blob_append(p->mem_ctx,
1429 &p->out_data.frag,
1430 pad, pad_len)) {
1431 DEBUG(0, ("api_pipe_bind_req: failed to add "
1432 "%u bytes of pad data.\n",
1433 (unsigned int)pad_len));
1434 goto err_exit;
1438 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1439 auth_blob.data, auth_blob.length)) {
1440 DEBUG(0, ("Append of auth info failed.\n"));
1441 goto err_exit;
1446 * Setup the lengths for the initial reply.
1449 p->out_data.data_sent_length = 0;
1450 p->out_data.current_pdu_sent = 0;
1452 TALLOC_FREE(auth_blob.data);
1453 return True;
1455 err_exit:
1457 data_blob_free(&p->out_data.frag);
1458 TALLOC_FREE(auth_blob.data);
1459 return setup_bind_nak(p, pkt);
1462 /****************************************************************************
1463 Find the set of RPC functions associated with this context_id
1464 ****************************************************************************/
1466 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1468 PIPE_RPC_FNS *fns = NULL;
1470 if ( !list ) {
1471 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1472 return NULL;
1475 for (fns=list; fns; fns=fns->next ) {
1476 if ( fns->context_id == context_id )
1477 return fns;
1479 return NULL;
1482 /****************************************************************************
1483 Memory cleanup.
1484 ****************************************************************************/
1486 static void free_pipe_rpc_context( PIPE_RPC_FNS *list )
1488 PIPE_RPC_FNS *tmp = list;
1489 PIPE_RPC_FNS *tmp2;
1491 while (tmp) {
1492 tmp2 = tmp->next;
1493 SAFE_FREE(tmp);
1494 tmp = tmp2;
1497 return;
1500 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1501 const struct api_struct *api_rpc_cmds, int n_cmds);
1503 /****************************************************************************
1504 Find the correct RPC function to call for this request.
1505 If the pipe is authenticated then become the correct UNIX user
1506 before doing the call.
1507 ****************************************************************************/
1509 static bool api_pipe_request(struct pipes_struct *p,
1510 struct ncacn_packet *pkt)
1512 bool ret = False;
1513 bool changed_user = False;
1514 PIPE_RPC_FNS *pipe_fns;
1516 if (p->pipe_bound &&
1517 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1518 ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) &&
1519 (p->auth.spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)))) {
1520 if(!become_authenticated_pipe_user(p)) {
1521 data_blob_free(&p->out_data.rdata);
1522 return False;
1524 changed_user = True;
1527 DEBUG(5, ("Requested \\PIPE\\%s\n",
1528 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1530 /* get the set of RPC functions for this context */
1532 pipe_fns = find_pipe_fns_by_context(p->contexts,
1533 pkt->u.request.context_id);
1535 if ( pipe_fns ) {
1536 TALLOC_CTX *frame = talloc_stackframe();
1537 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1538 TALLOC_FREE(frame);
1540 else {
1541 DEBUG(0, ("No rpc function table associated with context "
1542 "[%d] on pipe [%s]\n",
1543 pkt->u.request.context_id,
1544 get_pipe_name_from_syntax(talloc_tos(),
1545 &p->syntax)));
1548 if (changed_user) {
1549 unbecome_authenticated_pipe_user();
1552 return ret;
1555 /*******************************************************************
1556 Calls the underlying RPC function for a named pipe.
1557 ********************************************************************/
1559 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1560 const struct api_struct *api_rpc_cmds, int n_cmds)
1562 int fn_num;
1563 uint32_t offset1;
1565 /* interpret the command */
1566 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1567 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1568 pkt->u.request.opnum));
1570 if (DEBUGLEVEL >= 50) {
1571 fstring name;
1572 slprintf(name, sizeof(name)-1, "in_%s",
1573 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1574 dump_pdu_region(name, pkt->u.request.opnum,
1575 &p->in_data.data, 0,
1576 p->in_data.data.length);
1579 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1580 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1581 api_rpc_cmds[fn_num].fn != NULL) {
1582 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1583 api_rpc_cmds[fn_num].name));
1584 break;
1588 if (fn_num == n_cmds) {
1590 * For an unknown RPC just return a fault PDU but
1591 * return True to allow RPC's on the pipe to continue
1592 * and not put the pipe into fault state. JRA.
1594 DEBUG(4, ("unknown\n"));
1595 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1596 return True;
1599 offset1 = p->out_data.rdata.length;
1601 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1602 fn_num, api_rpc_cmds[fn_num].fn));
1603 /* do the actual command */
1604 if(!api_rpc_cmds[fn_num].fn(p)) {
1605 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1606 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1607 api_rpc_cmds[fn_num].name));
1608 data_blob_free(&p->out_data.rdata);
1609 return False;
1612 if (p->bad_handle_fault_state) {
1613 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1614 p->bad_handle_fault_state = False;
1615 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1616 return True;
1619 if (p->rng_fault_state) {
1620 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1621 p->rng_fault_state = False;
1622 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1623 return True;
1626 if (DEBUGLEVEL >= 50) {
1627 fstring name;
1628 slprintf(name, sizeof(name)-1, "out_%s",
1629 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1630 dump_pdu_region(name, pkt->u.request.opnum,
1631 &p->out_data.rdata, offset1,
1632 p->out_data.rdata.length);
1635 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1636 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1638 /* Check for buffer underflow in rpc parsing */
1639 if ((DEBUGLEVEL >= 10) &&
1640 (pkt->frag_length < p->in_data.data.length)) {
1641 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1642 dump_data(10, p->in_data.data.data + pkt->frag_length,
1643 p->in_data.data.length - pkt->frag_length);
1646 return True;
1649 /****************************************************************************
1650 Initialise an outgoing packet.
1651 ****************************************************************************/
1653 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1655 output_data *o_data = &p->out_data;
1657 /* Reset the offset counters. */
1658 o_data->data_sent_length = 0;
1659 o_data->current_pdu_sent = 0;
1661 data_blob_free(&o_data->frag);
1663 /* Free any memory in the current return data buffer. */
1664 data_blob_free(&o_data->rdata);
1666 return True;
1669 /****************************************************************************
1670 Sets the fault state on incoming packets.
1671 ****************************************************************************/
1673 void set_incoming_fault(struct pipes_struct *p)
1675 data_blob_free(&p->in_data.data);
1676 p->in_data.pdu_needed_len = 0;
1677 p->in_data.pdu.length = 0;
1678 p->fault_state = True;
1679 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1680 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1683 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1684 struct ncacn_packet *pkt,
1685 DATA_BLOB *raw_pkt)
1687 NTSTATUS status;
1688 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1689 size_t pad_len;
1691 DEBUG(10, ("Checking request auth.\n"));
1693 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1694 hdr_size += 16;
1697 /* in case of sealing this function will unseal the data in place */
1698 status = dcerpc_check_auth(auth, pkt,
1699 &pkt->u.request.stub_and_verifier,
1700 hdr_size, raw_pkt,
1701 &pad_len);
1702 if (!NT_STATUS_IS_OK(status)) {
1703 return status;
1707 /* remove padding and auth trailer,
1708 * this way the caller will get just the data */
1709 if (pkt->auth_length) {
1710 size_t trail_len = pad_len
1711 + DCERPC_AUTH_TRAILER_LENGTH
1712 + pkt->auth_length;
1713 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1714 return NT_STATUS_INFO_LENGTH_MISMATCH;
1716 pkt->u.request.stub_and_verifier.length -= trail_len;
1719 return NT_STATUS_OK;
1722 /****************************************************************************
1723 Processes a request pdu. This will do auth processing if needed, and
1724 appends the data into the complete stream if the LAST flag is not set.
1725 ****************************************************************************/
1727 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1729 NTSTATUS status;
1730 DATA_BLOB data;
1732 if (!p->pipe_bound) {
1733 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1734 set_incoming_fault(p);
1735 return False;
1738 /* Store the opnum */
1739 p->opnum = pkt->u.request.opnum;
1741 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1742 if (!NT_STATUS_IS_OK(status)) {
1743 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1744 nt_errstr(status)));
1745 set_incoming_fault(p);
1746 return false;
1749 data = pkt->u.request.stub_and_verifier;
1752 * Check the data length doesn't go over the 15Mb limit.
1753 * increased after observing a bug in the Windows NT 4.0 SP6a
1754 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1755 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1758 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1759 DEBUG(0, ("process_request_pdu: "
1760 "rpc data buffer too large (%u) + (%u)\n",
1761 (unsigned int)p->in_data.data.length,
1762 (unsigned int)data.length));
1763 set_incoming_fault(p);
1764 return False;
1768 * Append the data portion into the buffer and return.
1771 if (data.length) {
1772 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1773 data.data, data.length)) {
1774 DEBUG(0, ("Unable to append data size %u "
1775 "to parse buffer of size %u.\n",
1776 (unsigned int)data.length,
1777 (unsigned int)p->in_data.data.length));
1778 set_incoming_fault(p);
1779 return False;
1783 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1784 bool ret = False;
1786 * Ok - we finally have a complete RPC stream.
1787 * Call the rpc command to process it.
1791 * Process the complete data stream here.
1793 if (pipe_init_outgoing_data(p)) {
1794 ret = api_pipe_request(p, pkt);
1797 return ret;
1800 return True;
1803 /****************************************************************************
1804 Processes a finished PDU stored in p->in_data.pdu.
1805 ****************************************************************************/
1807 void process_complete_pdu(struct pipes_struct *p)
1809 struct ncacn_packet *pkt = NULL;
1810 NTSTATUS status;
1811 bool reply = False;
1813 if(p->fault_state) {
1814 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
1815 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1816 goto done;
1819 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1820 if (!pkt) {
1821 DEBUG(0, ("Out of memory!\n"));
1822 goto done;
1826 * Ensure we're using the corrent endianness for both the
1827 * RPC header flags and the raw data we will be reading from.
1829 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1830 p->endian = RPC_LITTLE_ENDIAN;
1831 } else {
1832 p->endian = RPC_BIG_ENDIAN;
1834 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1836 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1837 pkt, p->endian);
1838 if (!NT_STATUS_IS_OK(status)) {
1839 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1840 nt_errstr(status)));
1841 goto done;
1844 /* Store the call_id */
1845 p->call_id = pkt->call_id;
1847 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
1849 switch (pkt->ptype) {
1850 case DCERPC_PKT_REQUEST:
1851 reply = process_request_pdu(p, pkt);
1852 break;
1854 case DCERPC_PKT_PING: /* CL request - ignore... */
1855 DEBUG(0, ("process_complete_pdu: Error. "
1856 "Connectionless packet type %d received on "
1857 "pipe %s.\n", (int)pkt->ptype,
1858 get_pipe_name_from_syntax(talloc_tos(),
1859 &p->syntax)));
1860 break;
1862 case DCERPC_PKT_RESPONSE: /* No responses here. */
1863 DEBUG(0, ("process_complete_pdu: Error. "
1864 "DCERPC_PKT_RESPONSE received from client "
1865 "on pipe %s.\n",
1866 get_pipe_name_from_syntax(talloc_tos(),
1867 &p->syntax)));
1868 break;
1870 case DCERPC_PKT_FAULT:
1871 case DCERPC_PKT_WORKING:
1872 /* CL request - reply to a ping when a call in process. */
1873 case DCERPC_PKT_NOCALL:
1874 /* CL - server reply to a ping call. */
1875 case DCERPC_PKT_REJECT:
1876 case DCERPC_PKT_ACK:
1877 case DCERPC_PKT_CL_CANCEL:
1878 case DCERPC_PKT_FACK:
1879 case DCERPC_PKT_CANCEL_ACK:
1880 DEBUG(0, ("process_complete_pdu: Error. "
1881 "Connectionless packet type %u received on "
1882 "pipe %s.\n", (unsigned int)pkt->ptype,
1883 get_pipe_name_from_syntax(talloc_tos(),
1884 &p->syntax)));
1885 break;
1887 case DCERPC_PKT_BIND:
1889 * We assume that a pipe bind is only in one pdu.
1891 if (pipe_init_outgoing_data(p)) {
1892 reply = api_pipe_bind_req(p, pkt);
1894 break;
1896 case DCERPC_PKT_BIND_ACK:
1897 case DCERPC_PKT_BIND_NAK:
1898 DEBUG(0, ("process_complete_pdu: Error. "
1899 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1900 "packet type %u received on pipe %s.\n",
1901 (unsigned int)pkt->ptype,
1902 get_pipe_name_from_syntax(talloc_tos(),
1903 &p->syntax)));
1904 break;
1907 case DCERPC_PKT_ALTER:
1909 * We assume that a pipe bind is only in one pdu.
1911 if (pipe_init_outgoing_data(p)) {
1912 reply = api_pipe_alter_context(p, pkt);
1914 break;
1916 case DCERPC_PKT_ALTER_RESP:
1917 DEBUG(0, ("process_complete_pdu: Error. "
1918 "DCERPC_PKT_ALTER_RESP on pipe %s: "
1919 "Should only be server -> client.\n",
1920 get_pipe_name_from_syntax(talloc_tos(),
1921 &p->syntax)));
1922 break;
1924 case DCERPC_PKT_AUTH3:
1926 * The third packet in an NTLMSSP auth exchange.
1928 if (pipe_init_outgoing_data(p)) {
1929 reply = api_pipe_bind_auth3(p, pkt);
1931 break;
1933 case DCERPC_PKT_SHUTDOWN:
1934 DEBUG(0, ("process_complete_pdu: Error. "
1935 "DCERPC_PKT_SHUTDOWN on pipe %s: "
1936 "Should only be server -> client.\n",
1937 get_pipe_name_from_syntax(talloc_tos(),
1938 &p->syntax)));
1939 break;
1941 case DCERPC_PKT_CO_CANCEL:
1942 /* For now just free all client data and continue
1943 * processing. */
1944 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1945 " Abandoning rpc call.\n"));
1946 /* As we never do asynchronous RPC serving, we can
1947 * never cancel a call (as far as I know).
1948 * If we ever did we'd have to send a cancel_ack reply.
1949 * For now, just free all client data and continue
1950 * processing. */
1951 reply = True;
1952 break;
1954 #if 0
1955 /* Enable this if we're doing async rpc. */
1956 /* We must check the outstanding callid matches. */
1957 if (pipe_init_outgoing_data(p)) {
1958 /* Send a cancel_ack PDU reply. */
1959 /* We should probably check the auth-verifier here. */
1960 reply = setup_cancel_ack_reply(p, pkt);
1962 break;
1963 #endif
1965 case DCERPC_PKT_ORPHANED:
1966 /* We should probably check the auth-verifier here.
1967 * For now just free all client data and continue
1968 * processing. */
1969 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1970 " Abandoning rpc call.\n"));
1971 reply = True;
1972 break;
1974 default:
1975 DEBUG(0, ("process_complete_pdu: "
1976 "Unknown rpc type = %u received.\n",
1977 (unsigned int)pkt->ptype));
1978 break;
1981 done:
1982 if (!reply) {
1983 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
1984 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
1985 &p->syntax)));
1986 set_incoming_fault(p);
1987 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1988 TALLOC_FREE(pkt);
1989 } else {
1991 * Reset the lengths. We're ready for a new pdu.
1993 TALLOC_FREE(p->in_data.pdu.data);
1994 p->in_data.pdu_needed_len = 0;
1995 p->in_data.pdu.length = 0;
1998 TALLOC_FREE(pkt);