s3-dcerpc: fix some uninitialized variables build warnings.
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob436e5be709c1bf537510707e9c59579fc02c9920
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->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
531 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
532 context_fns->context_id = context_id;
534 /* add to the list of open contexts */
536 DLIST_ADD( p->contexts, context_fns );
538 return True;
542 * Is a named pipe known?
543 * @param[in] cli_filename The pipe name requested by the client
544 * @result Do we want to serve this?
546 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
548 const char *pipename = cli_filename;
549 NTSTATUS status;
551 if (strnequal(pipename, "\\PIPE\\", 6)) {
552 pipename += 5;
555 if (*pipename == '\\') {
556 pipename += 1;
559 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
560 DEBUG(10, ("refusing spoolss access\n"));
561 return false;
564 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
565 return true;
568 status = smb_probe_module("rpc", pipename);
569 if (!NT_STATUS_IS_OK(status)) {
570 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
571 return false;
573 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
576 * Scan the list again for the interface id
578 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
579 return true;
582 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
583 pipename));
585 return false;
588 /*******************************************************************
589 Handle a SPNEGO krb5 bind auth.
590 *******************************************************************/
592 static bool pipe_spnego_auth_bind_kerberos(struct pipes_struct *p,
593 TALLOC_CTX *mem_ctx,
594 struct dcerpc_auth *pauth_info,
595 DATA_BLOB *psecblob,
596 DATA_BLOB *response)
598 return False;
601 /*******************************************************************
602 Handle the first part of a SPNEGO bind auth.
603 *******************************************************************/
605 static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p,
606 TALLOC_CTX *mem_ctx,
607 struct dcerpc_auth *pauth_info,
608 DATA_BLOB *response)
610 DATA_BLOB secblob;
611 DATA_BLOB chal;
612 char *OIDs[ASN1_MAX_OIDS];
613 int i;
614 NTSTATUS status;
615 bool got_kerberos_mechanism = false;
616 struct auth_ntlmssp_state *a = NULL;
618 ZERO_STRUCT(secblob);
619 ZERO_STRUCT(chal);
621 if (pauth_info->credentials.data[0] != ASN1_APPLICATION(0)) {
622 goto err;
625 /* parse out the OIDs and the first sec blob */
626 if (!spnego_parse_negTokenInit(talloc_tos(),
627 pauth_info->credentials, OIDs, NULL, &secblob)) {
628 DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
629 goto err;
632 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
633 got_kerberos_mechanism = true;
636 for (i=0;OIDs[i];i++) {
637 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));
638 TALLOC_FREE(OIDs[i]);
640 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
642 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB) ) {
643 bool ret;
644 ret = pipe_spnego_auth_bind_kerberos(p, mem_ctx, pauth_info,
645 &secblob, response);
646 data_blob_free(&secblob);
647 return ret;
650 /* Free any previous auth type. */
651 free_pipe_auth_data(&p->auth);
653 if (!got_kerberos_mechanism) {
654 /* Initialize the NTLM engine. */
655 status = auth_ntlmssp_start(&a);
656 if (!NT_STATUS_IS_OK(status)) {
657 goto err;
660 /* Clear flags,
661 * then set them according to requested Auth Level */
662 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
663 NTLMSSP_NEGOTIATE_SEAL));
664 switch (pauth_info->auth_level) {
665 case DCERPC_AUTH_LEVEL_INTEGRITY:
666 auth_ntlmssp_or_flags(a,
667 NTLMSSP_NEGOTIATE_SIGN);
668 break;
669 case DCERPC_AUTH_LEVEL_PRIVACY:
670 /* Privacy always implies both sign and seal
671 * for ntlmssp */
672 auth_ntlmssp_or_flags(a,
673 NTLMSSP_NEGOTIATE_SIGN |
674 NTLMSSP_NEGOTIATE_SEAL);
675 break;
676 default:
677 break;
680 * Pass the first security blob of data to it.
681 * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
682 * which means we need another packet to complete the bind.
685 status = auth_ntlmssp_update(a, secblob, &chal);
687 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
688 DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
689 goto err;
692 /* Generate the response blob we need for step 2 of the bind. */
693 *response = spnego_gen_auth_response(mem_ctx, &chal, status, OID_NTLMSSP);
694 } else {
696 * SPNEGO negotiate down to NTLMSSP. The subsequent
697 * code to process follow-up packets is not complete
698 * yet. JRA.
700 *response = spnego_gen_auth_response(mem_ctx, NULL,
701 NT_STATUS_MORE_PROCESSING_REQUIRED,
702 OID_NTLMSSP);
705 /* auth_pad_len will be handled by the caller */
707 p->auth.a_u.auth_ntlmssp_state = a;
708 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
709 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
710 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
712 data_blob_free(&secblob);
713 data_blob_free(&chal);
715 /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */
716 return True;
718 err:
720 data_blob_free(&secblob);
721 data_blob_free(&chal);
723 p->auth.a_u.auth_ntlmssp_state = NULL;
725 return False;
728 /*******************************************************************
729 Handle the second part of a SPNEGO bind auth.
730 *******************************************************************/
732 static bool pipe_spnego_auth_bind_continue(struct pipes_struct *p,
733 TALLOC_CTX *mem_ctx,
734 struct dcerpc_auth *pauth_info,
735 DATA_BLOB *response)
737 DATA_BLOB auth_blob;
738 DATA_BLOB auth_reply;
739 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
741 ZERO_STRUCT(auth_blob);
742 ZERO_STRUCT(auth_reply);
745 * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently
746 * fail here as 'a' == NULL.
748 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO ||
749 p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {
750 DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));
751 goto err;
754 if (pauth_info->credentials.data[0] != ASN1_CONTEXT(1)) {
755 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));
756 goto err;
759 if (!spnego_parse_auth(talloc_tos(), pauth_info->credentials, &auth_blob)) {
760 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
761 goto err;
765 * The following call actually checks the challenge/response data.
766 * for correctness against the given DOMAIN\user name.
769 if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {
770 goto err;
773 data_blob_free(&auth_blob);
775 /* Generate the spnego "accept completed" blob - no incoming data. */
776 *response = spnego_gen_auth_response(mem_ctx, &auth_reply, NT_STATUS_OK, OID_NTLMSSP);
778 data_blob_free(&auth_reply);
780 p->pipe_bound = True;
782 return True;
784 err:
786 data_blob_free(&auth_blob);
787 data_blob_free(&auth_reply);
789 free_pipe_auth_data(&p->auth);
791 return False;
794 /*******************************************************************
795 Handle an schannel bind auth.
796 *******************************************************************/
798 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
799 TALLOC_CTX *mem_ctx,
800 struct dcerpc_auth *auth_info,
801 DATA_BLOB *response)
803 struct NL_AUTH_MESSAGE neg;
804 struct NL_AUTH_MESSAGE reply;
805 bool ret;
806 NTSTATUS status;
807 struct netlogon_creds_CredentialState *creds;
808 DATA_BLOB session_key;
809 enum ndr_err_code ndr_err;
811 ndr_err = ndr_pull_struct_blob(
812 &auth_info->credentials, mem_ctx, &neg,
813 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
814 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
815 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
816 return false;
819 if (DEBUGLEVEL >= 10) {
820 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
823 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
824 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
825 return false;
829 * The neg.oem_netbios_computer.a key here must match the remote computer name
830 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
831 * operations that use credentials.
834 become_root();
835 status = schannel_get_creds_state(p, lp_private_dir(),
836 neg.oem_netbios_computer.a, &creds);
837 unbecome_root();
839 if (!NT_STATUS_IS_OK(status)) {
840 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
841 return False;
844 p->auth.a_u.schannel_auth = talloc(p, struct schannel_state);
845 if (!p->auth.a_u.schannel_auth) {
846 TALLOC_FREE(creds);
847 return False;
850 p->auth.a_u.schannel_auth->state = SCHANNEL_STATE_START;
851 p->auth.a_u.schannel_auth->seq_num = 0;
852 p->auth.a_u.schannel_auth->initiator = false;
853 p->auth.a_u.schannel_auth->creds = creds;
856 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
857 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
858 * struct of the person who opened the pipe. I need to test this further. JRA.
860 * VL. As we are mapping this to guest set the generic key
861 * "SystemLibraryDTC" key here. It's a bit difficult to test against
862 * W2k3, as it does not allow schannel binds against SAMR and LSA
863 * anymore.
866 session_key = generic_session_key();
867 if (session_key.data == NULL) {
868 DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session"
869 " key\n"));
870 return false;
873 ret = server_info_set_session_key(p->server_info, session_key);
875 data_blob_free(&session_key);
877 if (!ret) {
878 DEBUG(0, ("server_info_set_session_key failed\n"));
879 return false;
882 /*** SCHANNEL verifier ***/
884 reply.MessageType = NL_NEGOTIATE_RESPONSE;
885 reply.Flags = 0;
886 reply.Buffer.dummy = 5; /* ??? actually I don't think
887 * this has any meaning
888 * here - gd */
890 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
891 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
892 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
893 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
894 return false;
897 if (DEBUGLEVEL >= 10) {
898 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
901 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
902 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
904 /* We're finished with this bind - no more packets. */
905 p->auth.auth_data_free_func = &free_pipe_schannel_auth_data;
906 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
908 p->pipe_bound = True;
910 return True;
913 /*******************************************************************
914 Handle an NTLMSSP bind auth.
915 *******************************************************************/
917 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
918 TALLOC_CTX *mem_ctx,
919 struct dcerpc_auth *auth_info,
920 DATA_BLOB *response)
922 NTSTATUS status;
923 struct auth_ntlmssp_state *a = NULL;
925 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
926 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
927 goto err;
930 /* We have an NTLMSSP blob. */
931 status = auth_ntlmssp_start(&a);
932 if (!NT_STATUS_IS_OK(status)) {
933 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",
934 nt_errstr(status) ));
935 goto err;
938 /* Clear flags, then set them according to requested Auth Level */
939 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
940 NTLMSSP_NEGOTIATE_SEAL));
942 switch (auth_info->auth_level) {
943 case DCERPC_AUTH_LEVEL_INTEGRITY:
944 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN);
945 break;
946 case DCERPC_AUTH_LEVEL_PRIVACY:
947 /* Privacy always implies both sign and seal for ntlmssp */
948 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN |
949 NTLMSSP_NEGOTIATE_SEAL);
950 break;
951 default:
952 break;
955 status = auth_ntlmssp_update(a, auth_info->credentials, response);
956 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
957 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n",
958 nt_errstr(status) ));
959 goto err;
962 /* Make sure data is bound to the memctx, to be freed the caller */
963 talloc_steal(mem_ctx, response->data);
965 p->auth.a_u.auth_ntlmssp_state = a;
966 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
967 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
969 DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
971 /* We can't set pipe_bound True yet - we need an DCERPC_PKT_AUTH3 response packet... */
972 return True;
974 err:
976 TALLOC_FREE(a);
977 return False;
980 /*******************************************************************
981 Respond to a pipe bind request.
982 *******************************************************************/
984 bool api_pipe_bind_req(struct pipes_struct *p, struct ncacn_packet *pkt)
986 struct dcerpc_auth auth_info;
987 uint16 assoc_gid;
988 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
989 NTSTATUS status;
990 struct ndr_syntax_id id;
991 union dcerpc_payload u;
992 struct dcerpc_ack_ctx bind_ack_ctx;
993 DATA_BLOB auth_resp = data_blob_null;
994 DATA_BLOB auth_blob = data_blob_null;
996 /* No rebinds on a bound pipe - use alter context. */
997 if (p->pipe_bound) {
998 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
999 "pipe %s.\n",
1000 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1001 return setup_bind_nak(p, pkt);
1004 if (pkt->u.bind.num_contexts == 0) {
1005 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
1006 goto err_exit;
1010 * Try and find the correct pipe name to ensure
1011 * that this is a pipe name we support.
1013 id = pkt->u.bind.ctx_list[0].abstract_syntax;
1014 if (rpc_srv_pipe_exists_by_id(&id)) {
1015 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1016 rpc_srv_get_pipe_cli_name(&id),
1017 rpc_srv_get_pipe_srv_name(&id)));
1018 } else {
1019 status = smb_probe_module(
1020 "rpc", get_pipe_name_from_syntax(
1021 talloc_tos(),
1022 &pkt->u.bind.ctx_list[0].abstract_syntax));
1024 if (NT_STATUS_IS_ERR(status)) {
1025 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
1026 get_pipe_name_from_syntax(
1027 talloc_tos(),
1028 &pkt->u.bind.ctx_list[0].abstract_syntax)));
1030 return setup_bind_nak(p, pkt);
1033 if (rpc_srv_get_pipe_interface_by_cli_name(
1034 get_pipe_name_from_syntax(talloc_tos(),
1035 &p->syntax),
1036 &id)) {
1037 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1038 rpc_srv_get_pipe_cli_name(&id),
1039 rpc_srv_get_pipe_srv_name(&id)));
1040 } else {
1041 DEBUG(0, ("module %s doesn't provide functions for "
1042 "pipe %s!\n",
1043 get_pipe_name_from_syntax(talloc_tos(),
1044 &p->syntax),
1045 get_pipe_name_from_syntax(talloc_tos(),
1046 &p->syntax)));
1047 return setup_bind_nak(p, pkt);
1051 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
1053 if (pkt->u.bind.assoc_group_id != 0) {
1054 assoc_gid = pkt->u.bind.assoc_group_id;
1055 } else {
1056 assoc_gid = 0x53f0;
1060 * Create the bind response struct.
1063 /* If the requested abstract synt uuid doesn't match our client pipe,
1064 reject the bind_ack & set the transfer interface synt to all 0's,
1065 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1066 unknown to NT4)
1067 Needed when adding entries to a DACL from NT5 - SK */
1069 if (check_bind_req(p,
1070 &pkt->u.bind.ctx_list[0].abstract_syntax,
1071 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1072 pkt->u.bind.ctx_list[0].context_id)) {
1074 bind_ack_ctx.result = 0;
1075 bind_ack_ctx.reason = 0;
1076 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1077 } else {
1078 p->pipe_bound = False;
1079 /* Rejection reason: abstract syntax not supported */
1080 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1081 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1082 bind_ack_ctx.syntax = null_ndr_syntax_id;
1086 * Check if this is an authenticated bind request.
1088 if (pkt->auth_length) {
1089 /* Quick length check. Won't catch a bad auth footer,
1090 * prevents overrun. */
1092 if (pkt->frag_length < RPC_HEADER_LEN +
1093 DCERPC_AUTH_TRAILER_LENGTH +
1094 pkt->auth_length) {
1095 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
1096 "too long for fragment %u.\n",
1097 (unsigned int)pkt->auth_length,
1098 (unsigned int)pkt->frag_length));
1099 goto err_exit;
1103 * Decode the authentication verifier.
1105 status = dcerpc_pull_dcerpc_auth(pkt,
1106 &pkt->u.bind.auth_info,
1107 &auth_info, p->endian);
1108 if (!NT_STATUS_IS_OK(status)) {
1109 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1110 goto err_exit;
1113 auth_type = auth_info.auth_type;
1115 /* Work out if we have to sign or seal etc. */
1116 switch (auth_info.auth_level) {
1117 case DCERPC_AUTH_LEVEL_INTEGRITY:
1118 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1119 break;
1120 case DCERPC_AUTH_LEVEL_PRIVACY:
1121 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1122 break;
1123 default:
1124 DEBUG(0, ("Unexpected auth level (%u).\n",
1125 (unsigned int)auth_info.auth_level ));
1126 goto err_exit;
1129 switch (auth_type) {
1130 case DCERPC_AUTH_TYPE_NTLMSSP:
1131 if (!pipe_ntlmssp_auth_bind(p, pkt,
1132 &auth_info, &auth_resp)) {
1133 goto err_exit;
1135 assoc_gid = 0x7a77;
1136 break;
1138 case DCERPC_AUTH_TYPE_SCHANNEL:
1139 if (!pipe_schannel_auth_bind(p, pkt,
1140 &auth_info, &auth_resp)) {
1141 goto err_exit;
1143 break;
1145 case DCERPC_AUTH_TYPE_SPNEGO:
1146 if (!pipe_spnego_auth_bind_negotiate(p, pkt,
1147 &auth_info, &auth_resp)) {
1148 goto err_exit;
1150 break;
1152 case DCERPC_AUTH_TYPE_NONE:
1153 break;
1155 default:
1156 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1157 goto err_exit;
1161 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1162 /* Unauthenticated bind request. */
1163 /* We're finished - no more packets. */
1164 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1165 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
1166 /* We must set the pipe auth_level here also. */
1167 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1168 p->pipe_bound = True;
1169 /* The session key was initialized from the SMB
1170 * session in make_internal_rpc_pipe_p */
1173 ZERO_STRUCT(u.bind_ack);
1174 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1175 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1176 u.bind_ack.assoc_group_id = assoc_gid;
1178 /* name has to be \PIPE\xxxxx */
1179 u.bind_ack.secondary_address =
1180 talloc_asprintf(pkt, "\\PIPE\\%s",
1181 rpc_srv_get_pipe_srv_name(&id));
1182 if (!u.bind_ack.secondary_address) {
1183 DEBUG(0, ("Out of memory!\n"));
1184 goto err_exit;
1186 u.bind_ack.secondary_address_size =
1187 strlen(u.bind_ack.secondary_address) + 1;
1189 u.bind_ack.num_results = 1;
1190 u.bind_ack.ctx_list = &bind_ack_ctx;
1192 /* NOTE: We leave the auth_info empty so we can calculate the padding
1193 * later and then append the auth_info --simo */
1196 * Marshall directly into the outgoing PDU space. We
1197 * must do this as we need to set to the bind response
1198 * header and are never sending more than one PDU here.
1201 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1202 DCERPC_PKT_BIND_ACK,
1203 DCERPC_PFC_FLAG_FIRST |
1204 DCERPC_PFC_FLAG_LAST,
1205 auth_resp.length,
1206 pkt->call_id,
1208 &p->out_data.frag);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1211 nt_errstr(status)));
1214 if (auth_resp.length) {
1216 status = dcerpc_push_dcerpc_auth(pkt,
1217 auth_type,
1218 auth_info.auth_level,
1220 1, /* auth_context_id */
1221 &auth_resp,
1222 &auth_blob);
1223 if (!NT_STATUS_IS_OK(status)) {
1224 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1225 goto err_exit;
1229 /* Now that we have the auth len store it into the right place in
1230 * the dcerpc header */
1231 dcerpc_set_frag_length(&p->out_data.frag,
1232 p->out_data.frag.length + auth_blob.length);
1234 if (auth_blob.length) {
1236 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1237 auth_blob.data, auth_blob.length)) {
1238 DEBUG(0, ("Append of auth info failed.\n"));
1239 goto err_exit;
1244 * Setup the lengths for the initial reply.
1247 p->out_data.data_sent_length = 0;
1248 p->out_data.current_pdu_sent = 0;
1250 TALLOC_FREE(auth_blob.data);
1251 return True;
1253 err_exit:
1255 data_blob_free(&p->out_data.frag);
1256 TALLOC_FREE(auth_blob.data);
1257 return setup_bind_nak(p, pkt);
1260 /****************************************************************************
1261 Deal with an alter context call. Can be third part of 3 leg auth request for
1262 SPNEGO calls.
1263 ****************************************************************************/
1265 bool api_pipe_alter_context(struct pipes_struct *p, struct ncacn_packet *pkt)
1267 struct dcerpc_auth auth_info;
1268 uint16 assoc_gid;
1269 NTSTATUS status;
1270 union dcerpc_payload u;
1271 struct dcerpc_ack_ctx bind_ack_ctx;
1272 DATA_BLOB auth_resp = data_blob_null;
1273 DATA_BLOB auth_blob = data_blob_null;
1274 int pad_len = 0;
1276 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1278 if (pkt->u.bind.assoc_group_id != 0) {
1279 assoc_gid = pkt->u.bind.assoc_group_id;
1280 } else {
1281 assoc_gid = 0x53f0;
1285 * Create the bind response struct.
1288 /* If the requested abstract synt uuid doesn't match our client pipe,
1289 reject the bind_ack & set the transfer interface synt to all 0's,
1290 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1291 unknown to NT4)
1292 Needed when adding entries to a DACL from NT5 - SK */
1294 if (check_bind_req(p,
1295 &pkt->u.bind.ctx_list[0].abstract_syntax,
1296 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1297 pkt->u.bind.ctx_list[0].context_id)) {
1299 bind_ack_ctx.result = 0;
1300 bind_ack_ctx.reason = 0;
1301 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1302 } else {
1303 p->pipe_bound = False;
1304 /* Rejection reason: abstract syntax not supported */
1305 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1306 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1307 bind_ack_ctx.syntax = null_ndr_syntax_id;
1311 * Check if this is an authenticated alter context request.
1313 if (pkt->auth_length) {
1314 /* Quick length check. Won't catch a bad auth footer,
1315 * prevents overrun. */
1317 if (pkt->frag_length < RPC_HEADER_LEN +
1318 DCERPC_AUTH_TRAILER_LENGTH +
1319 pkt->auth_length) {
1320 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1321 "too long for fragment %u.\n",
1322 (unsigned int)pkt->auth_length,
1323 (unsigned int)pkt->frag_length ));
1324 goto err_exit;
1327 status = dcerpc_pull_dcerpc_auth(pkt,
1328 &pkt->u.bind.auth_info,
1329 &auth_info, p->endian);
1330 if (!NT_STATUS_IS_OK(status)) {
1331 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1332 goto err_exit;
1337 * Currently only the SPNEGO auth type uses the alter ctx
1338 * response in place of the NTLMSSP auth3 type.
1341 if (auth_info.auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1342 /* We can only finish if the pipe is unbound. */
1343 if (!p->pipe_bound) {
1344 if (!pipe_spnego_auth_bind_continue(p, pkt,
1345 &auth_info, &auth_resp)) {
1346 goto err_exit;
1349 } else {
1350 goto err_exit;
1355 ZERO_STRUCT(u.alter_resp);
1356 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1357 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1358 u.alter_resp.assoc_group_id = assoc_gid;
1360 /* secondary address CAN be NULL
1361 * as the specs say it's ignored.
1362 * It MUST be NULL to have the spoolss working.
1364 u.alter_resp.secondary_address = "";
1365 u.alter_resp.secondary_address_size = 1;
1367 u.alter_resp.num_results = 1;
1368 u.alter_resp.ctx_list = &bind_ack_ctx;
1370 /* NOTE: We leave the auth_info empty so we can calculate the padding
1371 * later and then append the auth_info --simo */
1374 * Marshall directly into the outgoing PDU space. We
1375 * must do this as we need to set to the bind response
1376 * header and are never sending more than one PDU here.
1379 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1380 DCERPC_PKT_ALTER_RESP,
1381 DCERPC_PFC_FLAG_FIRST |
1382 DCERPC_PFC_FLAG_LAST,
1383 auth_resp.length,
1384 pkt->call_id,
1386 &p->out_data.frag);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1389 nt_errstr(status)));
1392 if (auth_resp.length) {
1394 /* Work out any padding needed before the auth footer. */
1395 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1396 if (pad_len) {
1397 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1398 DEBUG(10, ("auth pad_len = %u\n",
1399 (unsigned int)pad_len));
1402 status = dcerpc_push_dcerpc_auth(pkt,
1403 auth_info.auth_type,
1404 auth_info.auth_level,
1405 pad_len,
1406 1, /* auth_context_id */
1407 &auth_resp,
1408 &auth_blob);
1409 if (!NT_STATUS_IS_OK(status)) {
1410 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1411 goto err_exit;
1415 /* Now that we have the auth len store it into the right place in
1416 * the dcerpc header */
1417 dcerpc_set_frag_length(&p->out_data.frag,
1418 p->out_data.frag.length +
1419 pad_len + auth_blob.length);
1421 if (auth_resp.length) {
1422 if (pad_len) {
1423 char pad[SERVER_NDR_PADDING_SIZE];
1424 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1425 if (!data_blob_append(p->mem_ctx,
1426 &p->out_data.frag,
1427 pad, pad_len)) {
1428 DEBUG(0, ("api_pipe_bind_req: failed to add "
1429 "%u bytes of pad data.\n",
1430 (unsigned int)pad_len));
1431 goto err_exit;
1435 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1436 auth_blob.data, auth_blob.length)) {
1437 DEBUG(0, ("Append of auth info failed.\n"));
1438 goto err_exit;
1443 * Setup the lengths for the initial reply.
1446 p->out_data.data_sent_length = 0;
1447 p->out_data.current_pdu_sent = 0;
1449 TALLOC_FREE(auth_blob.data);
1450 return True;
1452 err_exit:
1454 data_blob_free(&p->out_data.frag);
1455 TALLOC_FREE(auth_blob.data);
1456 return setup_bind_nak(p, pkt);
1459 /****************************************************************************
1460 Find the set of RPC functions associated with this context_id
1461 ****************************************************************************/
1463 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1465 PIPE_RPC_FNS *fns = NULL;
1467 if ( !list ) {
1468 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1469 return NULL;
1472 for (fns=list; fns; fns=fns->next ) {
1473 if ( fns->context_id == context_id )
1474 return fns;
1476 return NULL;
1479 /****************************************************************************
1480 Memory cleanup.
1481 ****************************************************************************/
1483 void free_pipe_rpc_context( PIPE_RPC_FNS *list )
1485 PIPE_RPC_FNS *tmp = list;
1486 PIPE_RPC_FNS *tmp2;
1488 while (tmp) {
1489 tmp2 = tmp->next;
1490 SAFE_FREE(tmp);
1491 tmp = tmp2;
1494 return;
1497 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1498 const struct api_struct *api_rpc_cmds, int n_cmds);
1500 /****************************************************************************
1501 Find the correct RPC function to call for this request.
1502 If the pipe is authenticated then become the correct UNIX user
1503 before doing the call.
1504 ****************************************************************************/
1506 bool api_pipe_request(struct pipes_struct *p, struct ncacn_packet *pkt)
1508 bool ret = False;
1509 bool changed_user = False;
1510 PIPE_RPC_FNS *pipe_fns;
1512 if (p->pipe_bound &&
1513 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1514 ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) &&
1515 (p->auth.spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)))) {
1516 if(!become_authenticated_pipe_user(p)) {
1517 data_blob_free(&p->out_data.rdata);
1518 return False;
1520 changed_user = True;
1523 DEBUG(5, ("Requested \\PIPE\\%s\n",
1524 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1526 /* get the set of RPC functions for this context */
1528 pipe_fns = find_pipe_fns_by_context(p->contexts,
1529 pkt->u.request.context_id);
1531 if ( pipe_fns ) {
1532 TALLOC_CTX *frame = talloc_stackframe();
1533 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1534 TALLOC_FREE(frame);
1536 else {
1537 DEBUG(0, ("No rpc function table associated with context "
1538 "[%d] on pipe [%s]\n",
1539 pkt->u.request.context_id,
1540 get_pipe_name_from_syntax(talloc_tos(),
1541 &p->syntax)));
1544 if (changed_user) {
1545 unbecome_authenticated_pipe_user();
1548 return ret;
1551 /*******************************************************************
1552 Calls the underlying RPC function for a named pipe.
1553 ********************************************************************/
1555 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1556 const struct api_struct *api_rpc_cmds, int n_cmds)
1558 int fn_num;
1559 uint32_t offset1;
1561 /* interpret the command */
1562 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1563 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1564 pkt->u.request.opnum));
1566 if (DEBUGLEVEL >= 50) {
1567 fstring name;
1568 slprintf(name, sizeof(name)-1, "in_%s",
1569 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1570 dump_pdu_region(name, pkt->u.request.opnum,
1571 &p->in_data.data, 0,
1572 p->in_data.data.length);
1575 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1576 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1577 api_rpc_cmds[fn_num].fn != NULL) {
1578 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1579 api_rpc_cmds[fn_num].name));
1580 break;
1584 if (fn_num == n_cmds) {
1586 * For an unknown RPC just return a fault PDU but
1587 * return True to allow RPC's on the pipe to continue
1588 * and not put the pipe into fault state. JRA.
1590 DEBUG(4, ("unknown\n"));
1591 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1592 return True;
1595 offset1 = p->out_data.rdata.length;
1597 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1598 fn_num, api_rpc_cmds[fn_num].fn));
1599 /* do the actual command */
1600 if(!api_rpc_cmds[fn_num].fn(p)) {
1601 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1602 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1603 api_rpc_cmds[fn_num].name));
1604 data_blob_free(&p->out_data.rdata);
1605 return False;
1608 if (p->bad_handle_fault_state) {
1609 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1610 p->bad_handle_fault_state = False;
1611 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1612 return True;
1615 if (p->rng_fault_state) {
1616 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1617 p->rng_fault_state = False;
1618 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1619 return True;
1622 if (DEBUGLEVEL >= 50) {
1623 fstring name;
1624 slprintf(name, sizeof(name)-1, "out_%s",
1625 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1626 dump_pdu_region(name, pkt->u.request.opnum,
1627 &p->out_data.rdata, offset1,
1628 p->out_data.rdata.length);
1631 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1632 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1634 /* Check for buffer underflow in rpc parsing */
1635 if ((DEBUGLEVEL >= 10) &&
1636 (pkt->frag_length < p->in_data.data.length)) {
1637 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1638 dump_data(10, p->in_data.data.data + pkt->frag_length,
1639 p->in_data.data.length - pkt->frag_length);
1642 return True;
1645 /****************************************************************************
1646 Initialise an outgoing packet.
1647 ****************************************************************************/
1649 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1651 output_data *o_data = &p->out_data;
1653 /* Reset the offset counters. */
1654 o_data->data_sent_length = 0;
1655 o_data->current_pdu_sent = 0;
1657 data_blob_free(&o_data->frag);
1659 /* Free any memory in the current return data buffer. */
1660 data_blob_free(&o_data->rdata);
1662 return True;
1665 /****************************************************************************
1666 Sets the fault state on incoming packets.
1667 ****************************************************************************/
1669 void set_incoming_fault(struct pipes_struct *p)
1671 data_blob_free(&p->in_data.data);
1672 p->in_data.pdu_needed_len = 0;
1673 p->in_data.pdu.length = 0;
1674 p->fault_state = True;
1675 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1676 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1679 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1680 struct ncacn_packet *pkt,
1681 DATA_BLOB *raw_pkt)
1683 NTSTATUS status;
1684 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1685 size_t pad_len;
1687 DEBUG(10, ("Checking request auth.\n"));
1689 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1690 hdr_size += 16;
1693 /* in case of sealing this function will unseal the data in place */
1694 status = dcerpc_check_auth(auth, pkt,
1695 &pkt->u.request.stub_and_verifier,
1696 hdr_size, raw_pkt,
1697 &pad_len);
1698 if (!NT_STATUS_IS_OK(status)) {
1699 return status;
1703 /* remove padding and auth trailer,
1704 * this way the caller will get just the data */
1705 if (pkt->auth_length) {
1706 size_t trail_len = pad_len
1707 + DCERPC_AUTH_TRAILER_LENGTH
1708 + pkt->auth_length;
1709 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1710 return NT_STATUS_INFO_LENGTH_MISMATCH;
1712 pkt->u.request.stub_and_verifier.length -= trail_len;
1715 return NT_STATUS_OK;
1718 /****************************************************************************
1719 Processes a request pdu. This will do auth processing if needed, and
1720 appends the data into the complete stream if the LAST flag is not set.
1721 ****************************************************************************/
1723 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1725 NTSTATUS status;
1726 DATA_BLOB data;
1728 if (!p->pipe_bound) {
1729 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1730 set_incoming_fault(p);
1731 return False;
1734 /* Store the opnum */
1735 p->opnum = pkt->u.request.opnum;
1737 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1738 if (!NT_STATUS_IS_OK(status)) {
1739 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1740 nt_errstr(status)));
1741 set_incoming_fault(p);
1742 return false;
1745 data = pkt->u.request.stub_and_verifier;
1748 * Check the data length doesn't go over the 15Mb limit.
1749 * increased after observing a bug in the Windows NT 4.0 SP6a
1750 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1751 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1754 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1755 DEBUG(0, ("process_request_pdu: "
1756 "rpc data buffer too large (%u) + (%u)\n",
1757 (unsigned int)p->in_data.data.length,
1758 (unsigned int)data.length));
1759 set_incoming_fault(p);
1760 return False;
1764 * Append the data portion into the buffer and return.
1767 if (data.length) {
1768 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1769 data.data, data.length)) {
1770 DEBUG(0, ("Unable to append data size %u "
1771 "to parse buffer of size %u.\n",
1772 (unsigned int)data.length,
1773 (unsigned int)p->in_data.data.length));
1774 set_incoming_fault(p);
1775 return False;
1779 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1780 bool ret = False;
1782 * Ok - we finally have a complete RPC stream.
1783 * Call the rpc command to process it.
1787 * Process the complete data stream here.
1789 if (pipe_init_outgoing_data(p)) {
1790 ret = api_pipe_request(p, pkt);
1793 return ret;
1796 return True;
1799 /****************************************************************************
1800 Processes a finished PDU stored in p->in_data.pdu.
1801 ****************************************************************************/
1803 void process_complete_pdu(struct pipes_struct *p)
1805 struct ncacn_packet *pkt = NULL;
1806 NTSTATUS status;
1807 bool reply = False;
1809 if(p->fault_state) {
1810 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
1811 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1812 goto done;
1815 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1816 if (!pkt) {
1817 DEBUG(0, ("Out of memory!\n"));
1818 goto done;
1822 * Ensure we're using the corrent endianness for both the
1823 * RPC header flags and the raw data we will be reading from.
1825 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1826 p->endian = RPC_LITTLE_ENDIAN;
1827 } else {
1828 p->endian = RPC_BIG_ENDIAN;
1830 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1832 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1833 pkt, p->endian);
1834 if (!NT_STATUS_IS_OK(status)) {
1835 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1836 nt_errstr(status)));
1837 goto done;
1840 /* Store the call_id */
1841 p->call_id = pkt->call_id;
1843 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
1845 switch (pkt->ptype) {
1846 case DCERPC_PKT_REQUEST:
1847 reply = process_request_pdu(p, pkt);
1848 break;
1850 case DCERPC_PKT_PING: /* CL request - ignore... */
1851 DEBUG(0, ("process_complete_pdu: Error. "
1852 "Connectionless packet type %d received on "
1853 "pipe %s.\n", (int)pkt->ptype,
1854 get_pipe_name_from_syntax(talloc_tos(),
1855 &p->syntax)));
1856 break;
1858 case DCERPC_PKT_RESPONSE: /* No responses here. */
1859 DEBUG(0, ("process_complete_pdu: Error. "
1860 "DCERPC_PKT_RESPONSE received from client "
1861 "on pipe %s.\n",
1862 get_pipe_name_from_syntax(talloc_tos(),
1863 &p->syntax)));
1864 break;
1866 case DCERPC_PKT_FAULT:
1867 case DCERPC_PKT_WORKING:
1868 /* CL request - reply to a ping when a call in process. */
1869 case DCERPC_PKT_NOCALL:
1870 /* CL - server reply to a ping call. */
1871 case DCERPC_PKT_REJECT:
1872 case DCERPC_PKT_ACK:
1873 case DCERPC_PKT_CL_CANCEL:
1874 case DCERPC_PKT_FACK:
1875 case DCERPC_PKT_CANCEL_ACK:
1876 DEBUG(0, ("process_complete_pdu: Error. "
1877 "Connectionless packet type %u received on "
1878 "pipe %s.\n", (unsigned int)pkt->ptype,
1879 get_pipe_name_from_syntax(talloc_tos(),
1880 &p->syntax)));
1881 break;
1883 case DCERPC_PKT_BIND:
1885 * We assume that a pipe bind is only in one pdu.
1887 if (pipe_init_outgoing_data(p)) {
1888 reply = api_pipe_bind_req(p, pkt);
1890 break;
1892 case DCERPC_PKT_BIND_ACK:
1893 case DCERPC_PKT_BIND_NAK:
1894 DEBUG(0, ("process_complete_pdu: Error. "
1895 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1896 "packet type %u received on pipe %s.\n",
1897 (unsigned int)pkt->ptype,
1898 get_pipe_name_from_syntax(talloc_tos(),
1899 &p->syntax)));
1900 break;
1903 case DCERPC_PKT_ALTER:
1905 * We assume that a pipe bind is only in one pdu.
1907 if (pipe_init_outgoing_data(p)) {
1908 reply = api_pipe_alter_context(p, pkt);
1910 break;
1912 case DCERPC_PKT_ALTER_RESP:
1913 DEBUG(0, ("process_complete_pdu: Error. "
1914 "DCERPC_PKT_ALTER_RESP on pipe %s: "
1915 "Should only be server -> client.\n",
1916 get_pipe_name_from_syntax(talloc_tos(),
1917 &p->syntax)));
1918 break;
1920 case DCERPC_PKT_AUTH3:
1922 * The third packet in an NTLMSSP auth exchange.
1924 if (pipe_init_outgoing_data(p)) {
1925 reply = api_pipe_bind_auth3(p, pkt);
1927 break;
1929 case DCERPC_PKT_SHUTDOWN:
1930 DEBUG(0, ("process_complete_pdu: Error. "
1931 "DCERPC_PKT_SHUTDOWN on pipe %s: "
1932 "Should only be server -> client.\n",
1933 get_pipe_name_from_syntax(talloc_tos(),
1934 &p->syntax)));
1935 break;
1937 case DCERPC_PKT_CO_CANCEL:
1938 /* For now just free all client data and continue
1939 * processing. */
1940 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1941 " Abandoning rpc call.\n"));
1942 /* As we never do asynchronous RPC serving, we can
1943 * never cancel a call (as far as I know).
1944 * If we ever did we'd have to send a cancel_ack reply.
1945 * For now, just free all client data and continue
1946 * processing. */
1947 reply = True;
1948 break;
1950 #if 0
1951 /* Enable this if we're doing async rpc. */
1952 /* We must check the outstanding callid matches. */
1953 if (pipe_init_outgoing_data(p)) {
1954 /* Send a cancel_ack PDU reply. */
1955 /* We should probably check the auth-verifier here. */
1956 reply = setup_cancel_ack_reply(p, pkt);
1958 break;
1959 #endif
1961 case DCERPC_PKT_ORPHANED:
1962 /* We should probably check the auth-verifier here.
1963 * For now just free all client data and continue
1964 * processing. */
1965 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1966 " Abandoning rpc call.\n"));
1967 reply = True;
1968 break;
1970 default:
1971 DEBUG(0, ("process_complete_pdu: "
1972 "Unknown rpc type = %u received.\n",
1973 (unsigned int)pkt->ptype));
1974 break;
1977 done:
1978 if (!reply) {
1979 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
1980 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
1981 &p->syntax)));
1982 set_incoming_fault(p);
1983 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1984 TALLOC_FREE(pkt);
1985 } else {
1987 * Reset the lengths. We're ready for a new pdu.
1989 TALLOC_FREE(p->in_data.pdu.data);
1990 p->in_data.pdu_needed_len = 0;
1991 p->in_data.pdu.length = 0;
1994 TALLOC_FREE(pkt);