s3-dcerpc: rationalize packet creation in the server code
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob3f8855de3a229955068836ea271fa51551eb25fd
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 bool 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_len_left;
125 size_t data_len;
126 size_t max_len;
127 size_t pad_len = 0;
128 size_t auth_len = 0;
129 NTSTATUS status;
131 switch (auth->auth_level) {
132 case DCERPC_AUTH_LEVEL_NONE:
133 case DCERPC_AUTH_LEVEL_CONNECT:
134 /* This is incorrect for auth level connect. Fixme. JRA */
136 /* No authentication done. */
137 break;
139 case DCERPC_AUTH_LEVEL_CALL:
140 case DCERPC_AUTH_LEVEL_PACKET:
141 case DCERPC_AUTH_LEVEL_INTEGRITY:
142 case DCERPC_AUTH_LEVEL_PRIVACY:
144 switch(auth->auth_type) {
145 case DCERPC_AUTH_TYPE_NTLMSSP:
146 auth_len = NTLMSSP_SIG_SIZE;
147 break;
148 case DCERPC_AUTH_TYPE_SPNEGO:
149 if (auth->spnego_type !=
150 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
151 return false;
153 auth_len = NTLMSSP_SIG_SIZE;
154 break;
156 case DCERPC_AUTH_TYPE_SCHANNEL:
157 auth_len = NL_AUTH_SIGNATURE_SIZE;
158 break;
160 default:
161 return false;
164 break;
166 default:
167 return false;
170 ZERO_STRUCT(u.response);
172 /* Set up rpc packet pfc flags. */
173 if (data_sent_length == 0) {
174 pfc_flags = DCERPC_PFC_FLAG_FIRST;
175 } else {
176 pfc_flags = 0;
179 /* Work out how much we can fit in a single PDU. */
180 data_len_left = rdata->length - data_sent_length;
182 /* Ensure there really is data left to send. */
183 if (!data_len_left) {
184 DEBUG(0, ("No data left to send !\n"));
185 return false;
188 /* Max space available - not including padding. */
189 if (auth_len) {
190 max_len = RPC_MAX_PDU_FRAG_LEN
191 - DCERPC_RESPONSE_LENGTH
192 - DCERPC_AUTH_TRAILER_LENGTH
193 - auth_len;
194 } else {
195 max_len = RPC_MAX_PDU_FRAG_LEN - DCERPC_RESPONSE_LENGTH;
199 * The amount we send is the minimum of the max_len
200 * and the amount left to send.
202 data_len = MIN(data_len_left, max_len);
204 if (auth_len) {
205 /* Work out any padding alignment requirements. */
206 pad_len = (DCERPC_RESPONSE_LENGTH + data_len) %
207 SERVER_NDR_PADDING_SIZE;
208 if (pad_len) {
209 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
210 DEBUG(10, ("Padding size is: %d\n", (int)pad_len));
211 /* If we're over filling the packet, we need to make
212 * space for the padding at the end of the data. */
213 if (data_len + pad_len > max_len) {
214 data_len -= SERVER_NDR_PADDING_SIZE;
219 /* Set up the alloc hint. This should be the data left to send. */
220 u.response.alloc_hint = data_len_left;
222 /* Work out if this PDU will be the last. */
223 if (data_sent_length + data_len >= rdata->length) {
224 pfc_flags |= DCERPC_PFC_FLAG_LAST;
227 /* Prepare data to be NDR encoded. */
228 u.response.stub_and_verifier =
229 data_blob_const(rdata->data + data_sent_length, data_len);
231 /* Store the packet in the data stream. */
232 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
233 pfc_flags, auth_len, call_id,
234 &u, frag);
235 if (!NT_STATUS_IS_OK(status)) {
236 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
237 return false;
240 if (auth_len) {
241 /* Set the proper length on the pdu, including padding.
242 * Only needed if an auth trailer will be appended. */
243 dcerpc_set_frag_length(frag, frag->length
244 + pad_len
245 + DCERPC_AUTH_TRAILER_LENGTH
246 + auth_len);
249 if (auth_len) {
250 status = dcerpc_add_auth_footer(auth, pad_len, frag);
251 if (!NT_STATUS_IS_OK(status)) {
252 data_blob_free(frag);
253 return false;
257 *pdu_size = data_len;
258 return true;
261 /*******************************************************************
262 Generate the next PDU to be returned from the data in p->rdata.
263 ********************************************************************/
265 bool create_next_pdu(struct pipes_struct *p)
267 size_t pdu_size;
268 bool ret;
271 * If we're in the fault state, keep returning fault PDU's until
272 * the pipe gets closed. JRA.
274 if (p->fault_state) {
275 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
276 return true;
279 ret = create_next_packet(p->mem_ctx, &p->auth, p->call_id,
280 &p->out_data.rdata,
281 p->out_data.data_sent_length,
282 &p->out_data.frag, &pdu_size);
283 if (!ret) {
284 DEBUG(0, ("Invalid internal auth level %u / type %u\n",
285 (unsigned int)p->auth.auth_level,
286 (unsigned int)p->auth.auth_type));
287 return false;
290 /* Setup the counts for this PDU. */
291 p->out_data.data_sent_length += pdu_size;
292 p->out_data.current_pdu_sent = 0;
293 return true;
296 /*******************************************************************
297 Process an NTLMSSP authentication response.
298 If this function succeeds, the user has been authenticated
299 and their domain, name and calling workstation stored in
300 the pipe struct.
301 *******************************************************************/
303 static bool pipe_ntlmssp_verify_final(struct pipes_struct *p,
304 DATA_BLOB *p_resp_blob)
306 DATA_BLOB session_key, reply;
307 NTSTATUS status;
308 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
309 bool ret;
311 DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n",
312 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
314 ZERO_STRUCT(reply);
316 /* this has to be done as root in order to verify the password */
317 become_root();
318 status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
319 unbecome_root();
321 /* Don't generate a reply. */
322 data_blob_free(&reply);
324 if (!NT_STATUS_IS_OK(status)) {
325 return False;
328 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
329 ensure the underlying NTLMSSP flags are also set. If not we should
330 refuse the bind. */
332 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
333 if (!auth_ntlmssp_negotiated_sign(a)) {
334 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet integrity requested "
335 "but client declined signing.\n",
336 get_pipe_name_from_syntax(talloc_tos(),
337 &p->syntax)));
338 return False;
341 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
342 if (!auth_ntlmssp_negotiated_seal(a)) {
343 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet privacy requested "
344 "but client declined sealing.\n",
345 get_pipe_name_from_syntax(talloc_tos(),
346 &p->syntax)));
347 return False;
351 DEBUG(5, ("pipe_ntlmssp_verify_final: OK: user: %s domain: %s "
352 "workstation: %s\n",
353 auth_ntlmssp_get_username(a),
354 auth_ntlmssp_get_domain(a),
355 auth_ntlmssp_get_client(a)));
357 TALLOC_FREE(p->server_info);
359 status = auth_ntlmssp_steal_server_info(p, a, &p->server_info);
360 if (!NT_STATUS_IS_OK(status)) {
361 DEBUG(0, ("auth_ntlmssp_server_info failed to obtain the server info for authenticated user: %s\n",
362 nt_errstr(status)));
363 return false;
366 if (p->server_info->ptok == NULL) {
367 DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
368 return False;
372 * We're an authenticated bind over smb, so the session key needs to
373 * be set to "SystemLibraryDTC". Weird, but this is what Windows
374 * does. See the RPC-SAMBA3SESSIONKEY.
377 session_key = generic_session_key();
378 if (session_key.data == NULL) {
379 return False;
382 ret = server_info_set_session_key(p->server_info, session_key);
384 data_blob_free(&session_key);
386 return True;
389 /*******************************************************************
390 This is the "stage3" NTLMSSP response after a bind request and reply.
391 *******************************************************************/
393 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
395 struct dcerpc_auth auth_info;
396 NTSTATUS status;
398 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
400 if (pkt->auth_length == 0) {
401 DEBUG(0, ("No auth field sent for bind request!\n"));
402 goto err;
405 /* Ensure there's enough data for an authenticated request. */
406 if (pkt->frag_length < RPC_HEADER_LEN
407 + DCERPC_AUTH_TRAILER_LENGTH
408 + pkt->auth_length) {
409 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
410 "%u is too large.\n",
411 (unsigned int)pkt->auth_length));
412 goto err;
416 * Decode the authentication verifier response.
419 status = dcerpc_pull_dcerpc_auth(pkt,
420 &pkt->u.auth3.auth_info,
421 &auth_info, p->endian);
422 if (!NT_STATUS_IS_OK(status)) {
423 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
424 goto err;
427 /* We must NEVER look at auth_info->auth_pad_len here,
428 * as old Samba client code gets it wrong and sends it
429 * as zero. JRA.
432 if (auth_info.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) {
433 DEBUG(0,("api_pipe_bind_auth3: incorrect auth type (%u).\n",
434 (unsigned int)auth_info.auth_type ));
435 return False;
439 * The following call actually checks the challenge/response data.
440 * for correctness against the given DOMAIN\user name.
443 if (!pipe_ntlmssp_verify_final(p, &auth_info.credentials)) {
444 goto err;
447 p->pipe_bound = True;
449 return True;
451 err:
453 free_pipe_auth_data(&p->auth);
455 return False;
458 static bool pipe_init_outgoing_data(struct pipes_struct *p);
460 /*******************************************************************
461 Marshall a bind_nak pdu.
462 *******************************************************************/
464 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
466 NTSTATUS status;
467 union dcerpc_payload u;
469 /* Free any memory in the current return data buffer. */
470 pipe_init_outgoing_data(p);
473 * Initialize a bind_nak header.
476 ZERO_STRUCT(u);
478 u.bind_nak.reject_reason = 0;
481 * Marshall directly into the outgoing PDU space. We
482 * must do this as we need to set to the bind response
483 * header and are never sending more than one PDU here.
486 status = dcerpc_push_ncacn_packet(p->mem_ctx,
487 DCERPC_PKT_BIND_NAK,
488 DCERPC_PFC_FLAG_FIRST |
489 DCERPC_PFC_FLAG_LAST,
491 pkt->call_id,
493 &p->out_data.frag);
494 if (!NT_STATUS_IS_OK(status)) {
495 return False;
498 p->out_data.data_sent_length = 0;
499 p->out_data.current_pdu_sent = 0;
501 free_pipe_auth_data(&p->auth);
502 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
503 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
504 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
505 p->pipe_bound = False;
507 return True;
510 /*******************************************************************
511 Marshall a fault pdu.
512 *******************************************************************/
514 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
516 NTSTATUS status;
517 union dcerpc_payload u;
519 /* Free any memory in the current return data buffer. */
520 pipe_init_outgoing_data(p);
523 * Initialize a fault header.
526 ZERO_STRUCT(u);
528 u.fault.status = NT_STATUS_V(fault_status);
529 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
532 * Marshall directly into the outgoing PDU space. We
533 * must do this as we need to set to the bind response
534 * header and are never sending more than one PDU here.
537 status = dcerpc_push_ncacn_packet(p->mem_ctx,
538 DCERPC_PKT_FAULT,
539 DCERPC_PFC_FLAG_FIRST |
540 DCERPC_PFC_FLAG_LAST |
541 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
543 p->call_id,
545 &p->out_data.frag);
546 if (!NT_STATUS_IS_OK(status)) {
547 return False;
550 p->out_data.data_sent_length = 0;
551 p->out_data.current_pdu_sent = 0;
553 return True;
556 /*******************************************************************
557 Ensure a bind request has the correct abstract & transfer interface.
558 Used to reject unknown binds from Win2k.
559 *******************************************************************/
561 static bool check_bind_req(struct pipes_struct *p,
562 struct ndr_syntax_id* abstract,
563 struct ndr_syntax_id* transfer,
564 uint32 context_id)
566 struct pipe_rpc_fns *context_fns;
568 DEBUG(3,("check_bind_req for %s\n",
569 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
571 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
572 if (rpc_srv_pipe_exists_by_id(abstract) &&
573 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
574 DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
575 rpc_srv_get_pipe_cli_name(abstract),
576 rpc_srv_get_pipe_srv_name(abstract)));
577 } else {
578 return false;
581 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
582 if (context_fns == NULL) {
583 DEBUG(0,("check_bind_req: malloc() failed!\n"));
584 return False;
587 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
588 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
589 context_fns->context_id = context_id;
591 /* add to the list of open contexts */
593 DLIST_ADD( p->contexts, context_fns );
595 return True;
599 * Is a named pipe known?
600 * @param[in] cli_filename The pipe name requested by the client
601 * @result Do we want to serve this?
603 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
605 const char *pipename = cli_filename;
606 NTSTATUS status;
608 if (strnequal(pipename, "\\PIPE\\", 6)) {
609 pipename += 5;
612 if (*pipename == '\\') {
613 pipename += 1;
616 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
617 DEBUG(10, ("refusing spoolss access\n"));
618 return false;
621 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
622 return true;
625 status = smb_probe_module("rpc", pipename);
626 if (!NT_STATUS_IS_OK(status)) {
627 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
628 return false;
630 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
633 * Scan the list again for the interface id
635 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
636 return true;
639 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
640 pipename));
642 return false;
645 /*******************************************************************
646 Handle a SPNEGO krb5 bind auth.
647 *******************************************************************/
649 static bool pipe_spnego_auth_bind_kerberos(struct pipes_struct *p,
650 TALLOC_CTX *mem_ctx,
651 struct dcerpc_auth *pauth_info,
652 DATA_BLOB *psecblob,
653 DATA_BLOB *response)
655 return False;
658 /*******************************************************************
659 Handle the first part of a SPNEGO bind auth.
660 *******************************************************************/
662 static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p,
663 TALLOC_CTX *mem_ctx,
664 struct dcerpc_auth *pauth_info,
665 DATA_BLOB *response)
667 DATA_BLOB secblob;
668 DATA_BLOB chal;
669 char *OIDs[ASN1_MAX_OIDS];
670 int i;
671 NTSTATUS status;
672 bool got_kerberos_mechanism = false;
673 struct auth_ntlmssp_state *a = NULL;
675 ZERO_STRUCT(secblob);
676 ZERO_STRUCT(chal);
678 if (pauth_info->credentials.data[0] != ASN1_APPLICATION(0)) {
679 goto err;
682 /* parse out the OIDs and the first sec blob */
683 if (!spnego_parse_negTokenInit(talloc_tos(),
684 pauth_info->credentials, OIDs, NULL, &secblob)) {
685 DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
686 goto err;
689 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
690 got_kerberos_mechanism = true;
693 for (i=0;OIDs[i];i++) {
694 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));
695 TALLOC_FREE(OIDs[i]);
697 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
699 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB) ) {
700 bool ret;
701 ret = pipe_spnego_auth_bind_kerberos(p, mem_ctx, pauth_info,
702 &secblob, response);
703 data_blob_free(&secblob);
704 return ret;
707 /* Free any previous auth type. */
708 free_pipe_auth_data(&p->auth);
710 if (!got_kerberos_mechanism) {
711 /* Initialize the NTLM engine. */
712 status = auth_ntlmssp_start(&a);
713 if (!NT_STATUS_IS_OK(status)) {
714 goto err;
717 /* Clear flags,
718 * then set them according to requested Auth Level */
719 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
720 NTLMSSP_NEGOTIATE_SEAL));
721 switch (pauth_info->auth_level) {
722 case DCERPC_AUTH_LEVEL_INTEGRITY:
723 auth_ntlmssp_or_flags(a,
724 NTLMSSP_NEGOTIATE_SIGN);
725 break;
726 case DCERPC_AUTH_LEVEL_PRIVACY:
727 /* Privacy always implies both sign and seal
728 * for ntlmssp */
729 auth_ntlmssp_or_flags(a,
730 NTLMSSP_NEGOTIATE_SIGN |
731 NTLMSSP_NEGOTIATE_SEAL);
732 break;
733 default:
734 break;
737 * Pass the first security blob of data to it.
738 * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
739 * which means we need another packet to complete the bind.
742 status = auth_ntlmssp_update(a, secblob, &chal);
744 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
745 DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
746 goto err;
749 /* Generate the response blob we need for step 2 of the bind. */
750 *response = spnego_gen_auth_response(mem_ctx, &chal, status, OID_NTLMSSP);
751 } else {
753 * SPNEGO negotiate down to NTLMSSP. The subsequent
754 * code to process follow-up packets is not complete
755 * yet. JRA.
757 *response = spnego_gen_auth_response(mem_ctx, NULL,
758 NT_STATUS_MORE_PROCESSING_REQUIRED,
759 OID_NTLMSSP);
762 /* auth_pad_len will be handled by the caller */
764 p->auth.a_u.auth_ntlmssp_state = a;
765 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
766 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
767 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
769 data_blob_free(&secblob);
770 data_blob_free(&chal);
772 /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */
773 return True;
775 err:
777 data_blob_free(&secblob);
778 data_blob_free(&chal);
780 p->auth.a_u.auth_ntlmssp_state = NULL;
782 return False;
785 /*******************************************************************
786 Handle the second part of a SPNEGO bind auth.
787 *******************************************************************/
789 static bool pipe_spnego_auth_bind_continue(struct pipes_struct *p,
790 TALLOC_CTX *mem_ctx,
791 struct dcerpc_auth *pauth_info,
792 DATA_BLOB *response)
794 DATA_BLOB auth_blob;
795 DATA_BLOB auth_reply;
796 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
798 ZERO_STRUCT(auth_blob);
799 ZERO_STRUCT(auth_reply);
802 * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently
803 * fail here as 'a' == NULL.
805 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO ||
806 p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {
807 DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));
808 goto err;
811 if (pauth_info->credentials.data[0] != ASN1_CONTEXT(1)) {
812 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));
813 goto err;
816 if (!spnego_parse_auth(talloc_tos(), pauth_info->credentials, &auth_blob)) {
817 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
818 goto err;
822 * The following call actually checks the challenge/response data.
823 * for correctness against the given DOMAIN\user name.
826 if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {
827 goto err;
830 data_blob_free(&auth_blob);
832 /* Generate the spnego "accept completed" blob - no incoming data. */
833 *response = spnego_gen_auth_response(mem_ctx, &auth_reply, NT_STATUS_OK, OID_NTLMSSP);
835 data_blob_free(&auth_reply);
837 p->pipe_bound = True;
839 return True;
841 err:
843 data_blob_free(&auth_blob);
844 data_blob_free(&auth_reply);
846 free_pipe_auth_data(&p->auth);
848 return False;
851 /*******************************************************************
852 Handle an schannel bind auth.
853 *******************************************************************/
855 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
856 TALLOC_CTX *mem_ctx,
857 struct dcerpc_auth *auth_info,
858 DATA_BLOB *response)
860 struct NL_AUTH_MESSAGE neg;
861 struct NL_AUTH_MESSAGE reply;
862 bool ret;
863 NTSTATUS status;
864 struct netlogon_creds_CredentialState *creds;
865 DATA_BLOB session_key;
866 enum ndr_err_code ndr_err;
868 ndr_err = ndr_pull_struct_blob(
869 &auth_info->credentials, mem_ctx, &neg,
870 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
871 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
872 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
873 return false;
876 if (DEBUGLEVEL >= 10) {
877 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
880 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
881 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
882 return false;
886 * The neg.oem_netbios_computer.a key here must match the remote computer name
887 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
888 * operations that use credentials.
891 become_root();
892 status = schannel_get_creds_state(p, lp_private_dir(),
893 neg.oem_netbios_computer.a, &creds);
894 unbecome_root();
896 if (!NT_STATUS_IS_OK(status)) {
897 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
898 return False;
901 p->auth.a_u.schannel_auth = talloc(p, struct schannel_state);
902 if (!p->auth.a_u.schannel_auth) {
903 TALLOC_FREE(creds);
904 return False;
907 p->auth.a_u.schannel_auth->state = SCHANNEL_STATE_START;
908 p->auth.a_u.schannel_auth->seq_num = 0;
909 p->auth.a_u.schannel_auth->initiator = false;
910 p->auth.a_u.schannel_auth->creds = creds;
913 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
914 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
915 * struct of the person who opened the pipe. I need to test this further. JRA.
917 * VL. As we are mapping this to guest set the generic key
918 * "SystemLibraryDTC" key here. It's a bit difficult to test against
919 * W2k3, as it does not allow schannel binds against SAMR and LSA
920 * anymore.
923 session_key = generic_session_key();
924 if (session_key.data == NULL) {
925 DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session"
926 " key\n"));
927 return false;
930 ret = server_info_set_session_key(p->server_info, session_key);
932 data_blob_free(&session_key);
934 if (!ret) {
935 DEBUG(0, ("server_info_set_session_key failed\n"));
936 return false;
939 /*** SCHANNEL verifier ***/
941 reply.MessageType = NL_NEGOTIATE_RESPONSE;
942 reply.Flags = 0;
943 reply.Buffer.dummy = 5; /* ??? actually I don't think
944 * this has any meaning
945 * here - gd */
947 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
948 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
949 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
950 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
951 return false;
954 if (DEBUGLEVEL >= 10) {
955 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
958 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
959 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
961 /* We're finished with this bind - no more packets. */
962 p->auth.auth_data_free_func = &free_pipe_schannel_auth_data;
963 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
965 p->pipe_bound = True;
967 return True;
970 /*******************************************************************
971 Handle an NTLMSSP bind auth.
972 *******************************************************************/
974 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
975 TALLOC_CTX *mem_ctx,
976 struct dcerpc_auth *auth_info,
977 DATA_BLOB *response)
979 NTSTATUS status;
980 struct auth_ntlmssp_state *a = NULL;
982 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
983 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
984 goto err;
987 /* We have an NTLMSSP blob. */
988 status = auth_ntlmssp_start(&a);
989 if (!NT_STATUS_IS_OK(status)) {
990 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",
991 nt_errstr(status) ));
992 goto err;
995 /* Clear flags, then set them according to requested Auth Level */
996 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
997 NTLMSSP_NEGOTIATE_SEAL));
999 switch (auth_info->auth_level) {
1000 case DCERPC_AUTH_LEVEL_INTEGRITY:
1001 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN);
1002 break;
1003 case DCERPC_AUTH_LEVEL_PRIVACY:
1004 /* Privacy always implies both sign and seal for ntlmssp */
1005 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN |
1006 NTLMSSP_NEGOTIATE_SEAL);
1007 break;
1008 default:
1009 break;
1012 status = auth_ntlmssp_update(a, auth_info->credentials, response);
1013 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1014 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n",
1015 nt_errstr(status) ));
1016 goto err;
1019 /* Make sure data is bound to the memctx, to be freed the caller */
1020 talloc_steal(mem_ctx, response->data);
1022 p->auth.a_u.auth_ntlmssp_state = a;
1023 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
1024 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1026 DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
1028 /* We can't set pipe_bound True yet - we need an DCERPC_PKT_AUTH3 response packet... */
1029 return True;
1031 err:
1033 TALLOC_FREE(a);
1034 return False;
1037 /*******************************************************************
1038 Respond to a pipe bind request.
1039 *******************************************************************/
1041 bool api_pipe_bind_req(struct pipes_struct *p, struct ncacn_packet *pkt)
1043 struct dcerpc_auth auth_info;
1044 uint16 assoc_gid;
1045 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
1046 NTSTATUS status;
1047 struct ndr_syntax_id id;
1048 union dcerpc_payload u;
1049 struct dcerpc_ack_ctx bind_ack_ctx;
1050 DATA_BLOB auth_resp = data_blob_null;
1051 DATA_BLOB auth_blob = data_blob_null;
1053 /* No rebinds on a bound pipe - use alter context. */
1054 if (p->pipe_bound) {
1055 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
1056 "pipe %s.\n",
1057 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1058 return setup_bind_nak(p, pkt);
1061 if (pkt->u.bind.num_contexts == 0) {
1062 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
1063 goto err_exit;
1067 * Try and find the correct pipe name to ensure
1068 * that this is a pipe name we support.
1070 id = pkt->u.bind.ctx_list[0].abstract_syntax;
1071 if (rpc_srv_pipe_exists_by_id(&id)) {
1072 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1073 rpc_srv_get_pipe_cli_name(&id),
1074 rpc_srv_get_pipe_srv_name(&id)));
1075 } else {
1076 status = smb_probe_module(
1077 "rpc", get_pipe_name_from_syntax(
1078 talloc_tos(),
1079 &pkt->u.bind.ctx_list[0].abstract_syntax));
1081 if (NT_STATUS_IS_ERR(status)) {
1082 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
1083 get_pipe_name_from_syntax(
1084 talloc_tos(),
1085 &pkt->u.bind.ctx_list[0].abstract_syntax)));
1087 return setup_bind_nak(p, pkt);
1090 if (rpc_srv_get_pipe_interface_by_cli_name(
1091 get_pipe_name_from_syntax(talloc_tos(),
1092 &p->syntax),
1093 &id)) {
1094 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1095 rpc_srv_get_pipe_cli_name(&id),
1096 rpc_srv_get_pipe_srv_name(&id)));
1097 } else {
1098 DEBUG(0, ("module %s doesn't provide functions for "
1099 "pipe %s!\n",
1100 get_pipe_name_from_syntax(talloc_tos(),
1101 &p->syntax),
1102 get_pipe_name_from_syntax(talloc_tos(),
1103 &p->syntax)));
1104 return setup_bind_nak(p, pkt);
1108 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
1110 if (pkt->u.bind.assoc_group_id != 0) {
1111 assoc_gid = pkt->u.bind.assoc_group_id;
1112 } else {
1113 assoc_gid = 0x53f0;
1117 * Create the bind response struct.
1120 /* If the requested abstract synt uuid doesn't match our client pipe,
1121 reject the bind_ack & set the transfer interface synt to all 0's,
1122 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1123 unknown to NT4)
1124 Needed when adding entries to a DACL from NT5 - SK */
1126 if (check_bind_req(p,
1127 &pkt->u.bind.ctx_list[0].abstract_syntax,
1128 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1129 pkt->u.bind.ctx_list[0].context_id)) {
1131 bind_ack_ctx.result = 0;
1132 bind_ack_ctx.reason = 0;
1133 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1134 } else {
1135 p->pipe_bound = False;
1136 /* Rejection reason: abstract syntax not supported */
1137 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1138 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1139 bind_ack_ctx.syntax = null_ndr_syntax_id;
1143 * Check if this is an authenticated bind request.
1145 if (pkt->auth_length) {
1146 /* Quick length check. Won't catch a bad auth footer,
1147 * prevents overrun. */
1149 if (pkt->frag_length < RPC_HEADER_LEN +
1150 DCERPC_AUTH_TRAILER_LENGTH +
1151 pkt->auth_length) {
1152 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
1153 "too long for fragment %u.\n",
1154 (unsigned int)pkt->auth_length,
1155 (unsigned int)pkt->frag_length));
1156 goto err_exit;
1160 * Decode the authentication verifier.
1162 status = dcerpc_pull_dcerpc_auth(pkt,
1163 &pkt->u.bind.auth_info,
1164 &auth_info, p->endian);
1165 if (!NT_STATUS_IS_OK(status)) {
1166 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1167 goto err_exit;
1170 auth_type = auth_info.auth_type;
1172 /* Work out if we have to sign or seal etc. */
1173 switch (auth_info.auth_level) {
1174 case DCERPC_AUTH_LEVEL_INTEGRITY:
1175 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1176 break;
1177 case DCERPC_AUTH_LEVEL_PRIVACY:
1178 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1179 break;
1180 default:
1181 DEBUG(0, ("Unexpected auth level (%u).\n",
1182 (unsigned int)auth_info.auth_level ));
1183 goto err_exit;
1186 switch (auth_type) {
1187 case DCERPC_AUTH_TYPE_NTLMSSP:
1188 if (!pipe_ntlmssp_auth_bind(p, pkt,
1189 &auth_info, &auth_resp)) {
1190 goto err_exit;
1192 assoc_gid = 0x7a77;
1193 break;
1195 case DCERPC_AUTH_TYPE_SCHANNEL:
1196 if (!pipe_schannel_auth_bind(p, pkt,
1197 &auth_info, &auth_resp)) {
1198 goto err_exit;
1200 break;
1202 case DCERPC_AUTH_TYPE_SPNEGO:
1203 if (!pipe_spnego_auth_bind_negotiate(p, pkt,
1204 &auth_info, &auth_resp)) {
1205 goto err_exit;
1207 break;
1209 case DCERPC_AUTH_TYPE_NONE:
1210 break;
1212 default:
1213 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1214 goto err_exit;
1218 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1219 /* Unauthenticated bind request. */
1220 /* We're finished - no more packets. */
1221 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1222 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
1223 /* We must set the pipe auth_level here also. */
1224 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1225 p->pipe_bound = True;
1226 /* The session key was initialized from the SMB
1227 * session in make_internal_rpc_pipe_p */
1230 ZERO_STRUCT(u.bind_ack);
1231 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1232 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1233 u.bind_ack.assoc_group_id = assoc_gid;
1235 /* name has to be \PIPE\xxxxx */
1236 u.bind_ack.secondary_address =
1237 talloc_asprintf(pkt, "\\PIPE\\%s",
1238 rpc_srv_get_pipe_srv_name(&id));
1239 if (!u.bind_ack.secondary_address) {
1240 DEBUG(0, ("Out of memory!\n"));
1241 goto err_exit;
1243 u.bind_ack.secondary_address_size =
1244 strlen(u.bind_ack.secondary_address) + 1;
1246 u.bind_ack.num_results = 1;
1247 u.bind_ack.ctx_list = &bind_ack_ctx;
1249 /* NOTE: We leave the auth_info empty so we can calculate the padding
1250 * later and then append the auth_info --simo */
1253 * Marshall directly into the outgoing PDU space. We
1254 * must do this as we need to set to the bind response
1255 * header and are never sending more than one PDU here.
1258 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1259 DCERPC_PKT_BIND_ACK,
1260 DCERPC_PFC_FLAG_FIRST |
1261 DCERPC_PFC_FLAG_LAST,
1262 auth_resp.length,
1263 pkt->call_id,
1265 &p->out_data.frag);
1266 if (!NT_STATUS_IS_OK(status)) {
1267 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1268 nt_errstr(status)));
1271 if (auth_resp.length) {
1273 status = dcerpc_push_dcerpc_auth(pkt,
1274 auth_type,
1275 auth_info.auth_level,
1277 1, /* auth_context_id */
1278 &auth_resp,
1279 &auth_blob);
1280 if (!NT_STATUS_IS_OK(status)) {
1281 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1282 goto err_exit;
1286 /* Now that we have the auth len store it into the right place in
1287 * the dcerpc header */
1288 dcerpc_set_frag_length(&p->out_data.frag,
1289 p->out_data.frag.length + auth_blob.length);
1291 if (auth_blob.length) {
1293 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1294 auth_blob.data, auth_blob.length)) {
1295 DEBUG(0, ("Append of auth info failed.\n"));
1296 goto err_exit;
1301 * Setup the lengths for the initial reply.
1304 p->out_data.data_sent_length = 0;
1305 p->out_data.current_pdu_sent = 0;
1307 TALLOC_FREE(auth_blob.data);
1308 return True;
1310 err_exit:
1312 data_blob_free(&p->out_data.frag);
1313 TALLOC_FREE(auth_blob.data);
1314 return setup_bind_nak(p, pkt);
1317 /****************************************************************************
1318 Deal with an alter context call. Can be third part of 3 leg auth request for
1319 SPNEGO calls.
1320 ****************************************************************************/
1322 bool api_pipe_alter_context(struct pipes_struct *p, struct ncacn_packet *pkt)
1324 struct dcerpc_auth auth_info;
1325 uint16 assoc_gid;
1326 NTSTATUS status;
1327 union dcerpc_payload u;
1328 struct dcerpc_ack_ctx bind_ack_ctx;
1329 DATA_BLOB auth_resp = data_blob_null;
1330 DATA_BLOB auth_blob = data_blob_null;
1331 int pad_len = 0;
1333 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1335 if (pkt->u.bind.assoc_group_id != 0) {
1336 assoc_gid = pkt->u.bind.assoc_group_id;
1337 } else {
1338 assoc_gid = 0x53f0;
1342 * Create the bind response struct.
1345 /* If the requested abstract synt uuid doesn't match our client pipe,
1346 reject the bind_ack & set the transfer interface synt to all 0's,
1347 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1348 unknown to NT4)
1349 Needed when adding entries to a DACL from NT5 - SK */
1351 if (check_bind_req(p,
1352 &pkt->u.bind.ctx_list[0].abstract_syntax,
1353 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1354 pkt->u.bind.ctx_list[0].context_id)) {
1356 bind_ack_ctx.result = 0;
1357 bind_ack_ctx.reason = 0;
1358 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1359 } else {
1360 p->pipe_bound = False;
1361 /* Rejection reason: abstract syntax not supported */
1362 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1363 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1364 bind_ack_ctx.syntax = null_ndr_syntax_id;
1368 * Check if this is an authenticated alter context request.
1370 if (pkt->auth_length) {
1371 /* Quick length check. Won't catch a bad auth footer,
1372 * prevents overrun. */
1374 if (pkt->frag_length < RPC_HEADER_LEN +
1375 DCERPC_AUTH_TRAILER_LENGTH +
1376 pkt->auth_length) {
1377 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1378 "too long for fragment %u.\n",
1379 (unsigned int)pkt->auth_length,
1380 (unsigned int)pkt->frag_length ));
1381 goto err_exit;
1384 status = dcerpc_pull_dcerpc_auth(pkt,
1385 &pkt->u.bind.auth_info,
1386 &auth_info, p->endian);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1389 goto err_exit;
1394 * Currently only the SPNEGO auth type uses the alter ctx
1395 * response in place of the NTLMSSP auth3 type.
1398 if (auth_info.auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1399 /* We can only finish if the pipe is unbound. */
1400 if (!p->pipe_bound) {
1401 if (!pipe_spnego_auth_bind_continue(p, pkt,
1402 &auth_info, &auth_resp)) {
1403 goto err_exit;
1406 } else {
1407 goto err_exit;
1412 ZERO_STRUCT(u.alter_resp);
1413 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1414 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1415 u.alter_resp.assoc_group_id = assoc_gid;
1417 /* secondary address CAN be NULL
1418 * as the specs say it's ignored.
1419 * It MUST be NULL to have the spoolss working.
1421 u.alter_resp.secondary_address = "";
1422 u.alter_resp.secondary_address_size = 1;
1424 u.alter_resp.num_results = 1;
1425 u.alter_resp.ctx_list = &bind_ack_ctx;
1427 /* NOTE: We leave the auth_info empty so we can calculate the padding
1428 * later and then append the auth_info --simo */
1431 * Marshall directly into the outgoing PDU space. We
1432 * must do this as we need to set to the bind response
1433 * header and are never sending more than one PDU here.
1436 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1437 DCERPC_PKT_ALTER_RESP,
1438 DCERPC_PFC_FLAG_FIRST |
1439 DCERPC_PFC_FLAG_LAST,
1440 auth_resp.length,
1441 pkt->call_id,
1443 &p->out_data.frag);
1444 if (!NT_STATUS_IS_OK(status)) {
1445 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1446 nt_errstr(status)));
1449 if (auth_resp.length) {
1451 /* Work out any padding needed before the auth footer. */
1452 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1453 if (pad_len) {
1454 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1455 DEBUG(10, ("auth pad_len = %u\n",
1456 (unsigned int)pad_len));
1459 status = dcerpc_push_dcerpc_auth(pkt,
1460 auth_info.auth_type,
1461 auth_info.auth_level,
1462 pad_len,
1463 1, /* auth_context_id */
1464 &auth_resp,
1465 &auth_blob);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1468 goto err_exit;
1472 /* Now that we have the auth len store it into the right place in
1473 * the dcerpc header */
1474 dcerpc_set_frag_length(&p->out_data.frag,
1475 p->out_data.frag.length +
1476 pad_len + auth_blob.length);
1478 if (auth_resp.length) {
1479 if (pad_len) {
1480 char pad[SERVER_NDR_PADDING_SIZE];
1481 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1482 if (!data_blob_append(p->mem_ctx,
1483 &p->out_data.frag,
1484 pad, pad_len)) {
1485 DEBUG(0, ("api_pipe_bind_req: failed to add "
1486 "%u bytes of pad data.\n",
1487 (unsigned int)pad_len));
1488 goto err_exit;
1492 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1493 auth_blob.data, auth_blob.length)) {
1494 DEBUG(0, ("Append of auth info failed.\n"));
1495 goto err_exit;
1500 * Setup the lengths for the initial reply.
1503 p->out_data.data_sent_length = 0;
1504 p->out_data.current_pdu_sent = 0;
1506 TALLOC_FREE(auth_blob.data);
1507 return True;
1509 err_exit:
1511 data_blob_free(&p->out_data.frag);
1512 TALLOC_FREE(auth_blob.data);
1513 return setup_bind_nak(p, pkt);
1516 /****************************************************************************
1517 Find the set of RPC functions associated with this context_id
1518 ****************************************************************************/
1520 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1522 PIPE_RPC_FNS *fns = NULL;
1524 if ( !list ) {
1525 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1526 return NULL;
1529 for (fns=list; fns; fns=fns->next ) {
1530 if ( fns->context_id == context_id )
1531 return fns;
1533 return NULL;
1536 /****************************************************************************
1537 Memory cleanup.
1538 ****************************************************************************/
1540 void free_pipe_rpc_context( PIPE_RPC_FNS *list )
1542 PIPE_RPC_FNS *tmp = list;
1543 PIPE_RPC_FNS *tmp2;
1545 while (tmp) {
1546 tmp2 = tmp->next;
1547 SAFE_FREE(tmp);
1548 tmp = tmp2;
1551 return;
1554 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1555 const struct api_struct *api_rpc_cmds, int n_cmds);
1557 /****************************************************************************
1558 Find the correct RPC function to call for this request.
1559 If the pipe is authenticated then become the correct UNIX user
1560 before doing the call.
1561 ****************************************************************************/
1563 bool api_pipe_request(struct pipes_struct *p, struct ncacn_packet *pkt)
1565 bool ret = False;
1566 bool changed_user = False;
1567 PIPE_RPC_FNS *pipe_fns;
1569 if (p->pipe_bound &&
1570 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1571 ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) &&
1572 (p->auth.spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)))) {
1573 if(!become_authenticated_pipe_user(p)) {
1574 data_blob_free(&p->out_data.rdata);
1575 return False;
1577 changed_user = True;
1580 DEBUG(5, ("Requested \\PIPE\\%s\n",
1581 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1583 /* get the set of RPC functions for this context */
1585 pipe_fns = find_pipe_fns_by_context(p->contexts,
1586 pkt->u.request.context_id);
1588 if ( pipe_fns ) {
1589 TALLOC_CTX *frame = talloc_stackframe();
1590 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1591 TALLOC_FREE(frame);
1593 else {
1594 DEBUG(0, ("No rpc function table associated with context "
1595 "[%d] on pipe [%s]\n",
1596 pkt->u.request.context_id,
1597 get_pipe_name_from_syntax(talloc_tos(),
1598 &p->syntax)));
1601 if (changed_user) {
1602 unbecome_authenticated_pipe_user();
1605 return ret;
1608 /*******************************************************************
1609 Calls the underlying RPC function for a named pipe.
1610 ********************************************************************/
1612 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1613 const struct api_struct *api_rpc_cmds, int n_cmds)
1615 int fn_num;
1616 uint32_t offset1;
1618 /* interpret the command */
1619 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1620 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1621 pkt->u.request.opnum));
1623 if (DEBUGLEVEL >= 50) {
1624 fstring name;
1625 slprintf(name, sizeof(name)-1, "in_%s",
1626 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1627 dump_pdu_region(name, pkt->u.request.opnum,
1628 &p->in_data.data, 0,
1629 p->in_data.data.length);
1632 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1633 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1634 api_rpc_cmds[fn_num].fn != NULL) {
1635 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1636 api_rpc_cmds[fn_num].name));
1637 break;
1641 if (fn_num == n_cmds) {
1643 * For an unknown RPC just return a fault PDU but
1644 * return True to allow RPC's on the pipe to continue
1645 * and not put the pipe into fault state. JRA.
1647 DEBUG(4, ("unknown\n"));
1648 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1649 return True;
1652 offset1 = p->out_data.rdata.length;
1654 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1655 fn_num, api_rpc_cmds[fn_num].fn));
1656 /* do the actual command */
1657 if(!api_rpc_cmds[fn_num].fn(p)) {
1658 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1659 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1660 api_rpc_cmds[fn_num].name));
1661 data_blob_free(&p->out_data.rdata);
1662 return False;
1665 if (p->bad_handle_fault_state) {
1666 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1667 p->bad_handle_fault_state = False;
1668 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1669 return True;
1672 if (p->rng_fault_state) {
1673 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1674 p->rng_fault_state = False;
1675 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1676 return True;
1679 if (DEBUGLEVEL >= 50) {
1680 fstring name;
1681 slprintf(name, sizeof(name)-1, "out_%s",
1682 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1683 dump_pdu_region(name, pkt->u.request.opnum,
1684 &p->out_data.rdata, offset1,
1685 p->out_data.rdata.length);
1688 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1689 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1691 /* Check for buffer underflow in rpc parsing */
1692 if ((DEBUGLEVEL >= 10) &&
1693 (pkt->frag_length < p->in_data.data.length)) {
1694 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1695 dump_data(10, p->in_data.data.data + pkt->frag_length,
1696 p->in_data.data.length - pkt->frag_length);
1699 return True;
1702 /****************************************************************************
1703 Initialise an outgoing packet.
1704 ****************************************************************************/
1706 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1708 output_data *o_data = &p->out_data;
1710 /* Reset the offset counters. */
1711 o_data->data_sent_length = 0;
1712 o_data->current_pdu_sent = 0;
1714 data_blob_free(&o_data->frag);
1716 /* Free any memory in the current return data buffer. */
1717 data_blob_free(&o_data->rdata);
1719 return True;
1722 /****************************************************************************
1723 Sets the fault state on incoming packets.
1724 ****************************************************************************/
1726 void set_incoming_fault(struct pipes_struct *p)
1728 data_blob_free(&p->in_data.data);
1729 p->in_data.pdu_needed_len = 0;
1730 p->in_data.pdu.length = 0;
1731 p->fault_state = True;
1732 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1733 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1736 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1737 struct ncacn_packet *pkt,
1738 DATA_BLOB *raw_pkt)
1740 NTSTATUS status;
1741 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1742 size_t pad_len;
1744 DEBUG(10, ("Checking request auth.\n"));
1746 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1747 hdr_size += 16;
1750 /* in case of sealing this function will unseal the data in place */
1751 status = dcerpc_check_auth(auth, pkt,
1752 &pkt->u.request.stub_and_verifier,
1753 hdr_size, raw_pkt,
1754 &pad_len);
1755 if (!NT_STATUS_IS_OK(status)) {
1756 return status;
1760 /* remove padding and auth trailer,
1761 * this way the caller will get just the data */
1762 if (pkt->auth_length) {
1763 size_t trail_len = pad_len
1764 + DCERPC_AUTH_TRAILER_LENGTH
1765 + pkt->auth_length;
1766 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1767 return NT_STATUS_INFO_LENGTH_MISMATCH;
1769 pkt->u.request.stub_and_verifier.length -= trail_len;
1772 return NT_STATUS_OK;
1775 /****************************************************************************
1776 Processes a request pdu. This will do auth processing if needed, and
1777 appends the data into the complete stream if the LAST flag is not set.
1778 ****************************************************************************/
1780 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1782 NTSTATUS status;
1783 DATA_BLOB data;
1785 if (!p->pipe_bound) {
1786 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1787 set_incoming_fault(p);
1788 return False;
1791 /* Store the opnum */
1792 p->opnum = pkt->u.request.opnum;
1794 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1795 if (!NT_STATUS_IS_OK(status)) {
1796 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1797 nt_errstr(status)));
1798 set_incoming_fault(p);
1799 return false;
1802 data = pkt->u.request.stub_and_verifier;
1805 * Check the data length doesn't go over the 15Mb limit.
1806 * increased after observing a bug in the Windows NT 4.0 SP6a
1807 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1808 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1811 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1812 DEBUG(0, ("process_request_pdu: "
1813 "rpc data buffer too large (%u) + (%u)\n",
1814 (unsigned int)p->in_data.data.length,
1815 (unsigned int)data.length));
1816 set_incoming_fault(p);
1817 return False;
1821 * Append the data portion into the buffer and return.
1824 if (data.length) {
1825 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1826 data.data, data.length)) {
1827 DEBUG(0, ("Unable to append data size %u "
1828 "to parse buffer of size %u.\n",
1829 (unsigned int)data.length,
1830 (unsigned int)p->in_data.data.length));
1831 set_incoming_fault(p);
1832 return False;
1836 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1837 bool ret = False;
1839 * Ok - we finally have a complete RPC stream.
1840 * Call the rpc command to process it.
1844 * Process the complete data stream here.
1846 if (pipe_init_outgoing_data(p)) {
1847 ret = api_pipe_request(p, pkt);
1850 return ret;
1853 return True;
1856 /****************************************************************************
1857 Processes a finished PDU stored in p->in_data.pdu.
1858 ****************************************************************************/
1860 void process_complete_pdu(struct pipes_struct *p)
1862 struct ncacn_packet *pkt = NULL;
1863 NTSTATUS status;
1864 bool reply = False;
1866 if(p->fault_state) {
1867 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
1868 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1869 goto done;
1872 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1873 if (!pkt) {
1874 DEBUG(0, ("Out of memory!\n"));
1875 goto done;
1879 * Ensure we're using the corrent endianness for both the
1880 * RPC header flags and the raw data we will be reading from.
1882 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1883 p->endian = RPC_LITTLE_ENDIAN;
1884 } else {
1885 p->endian = RPC_BIG_ENDIAN;
1887 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1889 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1890 pkt, p->endian);
1891 if (!NT_STATUS_IS_OK(status)) {
1892 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1893 nt_errstr(status)));
1894 goto done;
1897 /* Store the call_id */
1898 p->call_id = pkt->call_id;
1900 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
1902 switch (pkt->ptype) {
1903 case DCERPC_PKT_REQUEST:
1904 reply = process_request_pdu(p, pkt);
1905 break;
1907 case DCERPC_PKT_PING: /* CL request - ignore... */
1908 DEBUG(0, ("process_complete_pdu: Error. "
1909 "Connectionless packet type %d received on "
1910 "pipe %s.\n", (int)pkt->ptype,
1911 get_pipe_name_from_syntax(talloc_tos(),
1912 &p->syntax)));
1913 break;
1915 case DCERPC_PKT_RESPONSE: /* No responses here. */
1916 DEBUG(0, ("process_complete_pdu: Error. "
1917 "DCERPC_PKT_RESPONSE received from client "
1918 "on pipe %s.\n",
1919 get_pipe_name_from_syntax(talloc_tos(),
1920 &p->syntax)));
1921 break;
1923 case DCERPC_PKT_FAULT:
1924 case DCERPC_PKT_WORKING:
1925 /* CL request - reply to a ping when a call in process. */
1926 case DCERPC_PKT_NOCALL:
1927 /* CL - server reply to a ping call. */
1928 case DCERPC_PKT_REJECT:
1929 case DCERPC_PKT_ACK:
1930 case DCERPC_PKT_CL_CANCEL:
1931 case DCERPC_PKT_FACK:
1932 case DCERPC_PKT_CANCEL_ACK:
1933 DEBUG(0, ("process_complete_pdu: Error. "
1934 "Connectionless packet type %u received on "
1935 "pipe %s.\n", (unsigned int)pkt->ptype,
1936 get_pipe_name_from_syntax(talloc_tos(),
1937 &p->syntax)));
1938 break;
1940 case DCERPC_PKT_BIND:
1942 * We assume that a pipe bind is only in one pdu.
1944 if (pipe_init_outgoing_data(p)) {
1945 reply = api_pipe_bind_req(p, pkt);
1947 break;
1949 case DCERPC_PKT_BIND_ACK:
1950 case DCERPC_PKT_BIND_NAK:
1951 DEBUG(0, ("process_complete_pdu: Error. "
1952 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1953 "packet type %u received on pipe %s.\n",
1954 (unsigned int)pkt->ptype,
1955 get_pipe_name_from_syntax(talloc_tos(),
1956 &p->syntax)));
1957 break;
1960 case DCERPC_PKT_ALTER:
1962 * We assume that a pipe bind is only in one pdu.
1964 if (pipe_init_outgoing_data(p)) {
1965 reply = api_pipe_alter_context(p, pkt);
1967 break;
1969 case DCERPC_PKT_ALTER_RESP:
1970 DEBUG(0, ("process_complete_pdu: Error. "
1971 "DCERPC_PKT_ALTER_RESP on pipe %s: "
1972 "Should only be server -> client.\n",
1973 get_pipe_name_from_syntax(talloc_tos(),
1974 &p->syntax)));
1975 break;
1977 case DCERPC_PKT_AUTH3:
1979 * The third packet in an NTLMSSP auth exchange.
1981 if (pipe_init_outgoing_data(p)) {
1982 reply = api_pipe_bind_auth3(p, pkt);
1984 break;
1986 case DCERPC_PKT_SHUTDOWN:
1987 DEBUG(0, ("process_complete_pdu: Error. "
1988 "DCERPC_PKT_SHUTDOWN on pipe %s: "
1989 "Should only be server -> client.\n",
1990 get_pipe_name_from_syntax(talloc_tos(),
1991 &p->syntax)));
1992 break;
1994 case DCERPC_PKT_CO_CANCEL:
1995 /* For now just free all client data and continue
1996 * processing. */
1997 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1998 " Abandoning rpc call.\n"));
1999 /* As we never do asynchronous RPC serving, we can
2000 * never cancel a call (as far as I know).
2001 * If we ever did we'd have to send a cancel_ack reply.
2002 * For now, just free all client data and continue
2003 * processing. */
2004 reply = True;
2005 break;
2007 #if 0
2008 /* Enable this if we're doing async rpc. */
2009 /* We must check the outstanding callid matches. */
2010 if (pipe_init_outgoing_data(p)) {
2011 /* Send a cancel_ack PDU reply. */
2012 /* We should probably check the auth-verifier here. */
2013 reply = setup_cancel_ack_reply(p, pkt);
2015 break;
2016 #endif
2018 case DCERPC_PKT_ORPHANED:
2019 /* We should probably check the auth-verifier here.
2020 * For now just free all client data and continue
2021 * processing. */
2022 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
2023 " Abandoning rpc call.\n"));
2024 reply = True;
2025 break;
2027 default:
2028 DEBUG(0, ("process_complete_pdu: "
2029 "Unknown rpc type = %u received.\n",
2030 (unsigned int)pkt->ptype));
2031 break;
2034 done:
2035 if (!reply) {
2036 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
2037 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
2038 &p->syntax)));
2039 set_incoming_fault(p);
2040 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
2041 TALLOC_FREE(pkt);
2042 } else {
2044 * Reset the lengths. We're ready for a new pdu.
2046 TALLOC_FREE(p->in_data.pdu.data);
2047 p->in_data.pdu_needed_len = 0;
2048 p->in_data.pdu.length = 0;
2051 TALLOC_FREE(pkt);