Revert "s3: Use cups-config --libs"
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_pipe.c
blobe704d758d7cfec3efa48d6a990651e7b2e6e7cd3
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 /* this module apparently provides an implementation of DCE/RPC over a
21 * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
22 * documentation are available (in on-line form) from the X-Open group.
24 * this module should provide a level of abstraction between SMB
25 * and DCE/RPC, while minimising the amount of mallocs, unnecessary
26 * data copies, and network traffic.
30 #include "includes.h"
31 #include "srv_pipe_internal.h"
32 #include "../librpc/gen_ndr/ndr_schannel.h"
33 #include "../libcli/auth/schannel.h"
34 #include "../libcli/auth/spnego.h"
35 #include "../libcli/auth/ntlmssp.h"
36 #include "ntlmssp_wrap.h"
37 #include "rpc_server.h"
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_RPC_SRV
42 /**
43 * Dump everything from the start of the end up of the provided data
44 * into a file, but only at debug level >= 50
45 **/
46 static void dump_pdu_region(const char *name, int v,
47 DATA_BLOB *data, size_t start, size_t end)
49 int fd, i;
50 char *fname = NULL;
51 ssize_t sz;
53 if (DEBUGLEVEL < 50) return;
55 if (start > data->length || end > data->length || start > end) return;
57 for (i = 1; i < 100; i++) {
58 if (v != -1) {
59 fname = talloc_asprintf(talloc_tos(),
60 "/tmp/%s_%d.%d.prs",
61 name, v, i);
62 } else {
63 fname = talloc_asprintf(talloc_tos(),
64 "/tmp/%s_%d.prs",
65 name, i);
67 if (!fname) {
68 return;
70 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
71 if (fd != -1 || errno != EEXIST) break;
73 if (fd != -1) {
74 sz = write(fd, data->data + start, end - start);
75 i = close(fd);
76 if ((sz != end - start) || (i != 0) ) {
77 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
78 fname, (unsigned long)sz,
79 (unsigned long)end - start, i));
80 } else {
81 DEBUG(0,("created %s\n", fname));
84 TALLOC_FREE(fname);
87 static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth)
89 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
92 static void free_pipe_schannel_auth_data(struct pipe_auth_data *auth)
94 TALLOC_FREE(auth->a_u.schannel_auth);
97 static void free_pipe_auth_data(struct pipe_auth_data *auth)
99 if (auth->auth_data_free_func) {
100 (*auth->auth_data_free_func)(auth);
101 auth->auth_data_free_func = NULL;
105 static DATA_BLOB generic_session_key(void)
107 return data_blob("SystemLibraryDTC", 16);
110 /*******************************************************************
111 Generate the next PDU to be returned from the data.
112 ********************************************************************/
114 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
115 struct pipe_auth_data *auth,
116 uint32_t call_id,
117 DATA_BLOB *rdata,
118 size_t data_sent_length,
119 DATA_BLOB *frag,
120 size_t *pdu_size)
122 union dcerpc_payload u;
123 uint8_t pfc_flags;
124 size_t data_left;
125 size_t data_to_send;
126 size_t frag_len;
127 size_t pad_len = 0;
128 size_t auth_len = 0;
129 NTSTATUS status;
131 ZERO_STRUCT(u.response);
133 /* Set up rpc packet pfc flags. */
134 if (data_sent_length == 0) {
135 pfc_flags = DCERPC_PFC_FLAG_FIRST;
136 } else {
137 pfc_flags = 0;
140 /* Work out how much we can fit in a single PDU. */
141 data_left = rdata->length - data_sent_length;
143 /* Ensure there really is data left to send. */
144 if (!data_left) {
145 DEBUG(0, ("No data left to send !\n"));
146 return NT_STATUS_BUFFER_TOO_SMALL;
149 status = dcerpc_guess_sizes(auth,
150 DCERPC_RESPONSE_LENGTH,
151 data_left,
152 RPC_MAX_PDU_FRAG_LEN,
153 SERVER_NDR_PADDING_SIZE,
154 &data_to_send, &frag_len,
155 &auth_len, &pad_len);
156 if (!NT_STATUS_IS_OK(status)) {
157 return status;
160 /* Set up the alloc hint. This should be the data left to send. */
161 u.response.alloc_hint = data_left;
163 /* Work out if this PDU will be the last. */
164 if (data_sent_length + data_to_send >= rdata->length) {
165 pfc_flags |= DCERPC_PFC_FLAG_LAST;
168 /* Prepare data to be NDR encoded. */
169 u.response.stub_and_verifier =
170 data_blob_const(rdata->data + data_sent_length, data_to_send);
172 /* Store the packet in the data stream. */
173 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
174 pfc_flags, auth_len, call_id,
175 &u, frag);
176 if (!NT_STATUS_IS_OK(status)) {
177 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
178 return status;
181 if (auth_len) {
182 /* Set the proper length on the pdu, including padding.
183 * Only needed if an auth trailer will be appended. */
184 dcerpc_set_frag_length(frag, frag->length
185 + pad_len
186 + DCERPC_AUTH_TRAILER_LENGTH
187 + auth_len);
190 if (auth_len) {
191 status = dcerpc_add_auth_footer(auth, pad_len, frag);
192 if (!NT_STATUS_IS_OK(status)) {
193 data_blob_free(frag);
194 return status;
198 *pdu_size = data_to_send;
199 return NT_STATUS_OK;
202 /*******************************************************************
203 Generate the next PDU to be returned from the data in p->rdata.
204 ********************************************************************/
206 bool create_next_pdu(struct pipes_struct *p)
208 size_t pdu_size = 0;
209 NTSTATUS status;
212 * If we're in the fault state, keep returning fault PDU's until
213 * the pipe gets closed. JRA.
215 if (p->fault_state) {
216 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
217 return true;
220 status = create_next_packet(p->mem_ctx, &p->auth,
221 p->call_id, &p->out_data.rdata,
222 p->out_data.data_sent_length,
223 &p->out_data.frag, &pdu_size);
224 if (!NT_STATUS_IS_OK(status)) {
225 DEBUG(0, ("Failed to create packet with error %s, "
226 "(auth level %u / type %u)\n",
227 nt_errstr(status),
228 (unsigned int)p->auth.auth_level,
229 (unsigned int)p->auth.auth_type));
230 return false;
233 /* Setup the counts for this PDU. */
234 p->out_data.data_sent_length += pdu_size;
235 p->out_data.current_pdu_sent = 0;
236 return true;
239 /*******************************************************************
240 Process an NTLMSSP authentication response.
241 If this function succeeds, the user has been authenticated
242 and their domain, name and calling workstation stored in
243 the pipe struct.
244 *******************************************************************/
246 static bool pipe_ntlmssp_verify_final(struct pipes_struct *p,
247 DATA_BLOB *p_resp_blob)
249 DATA_BLOB session_key, reply;
250 NTSTATUS status;
251 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
252 bool ret;
254 DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n",
255 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
257 ZERO_STRUCT(reply);
259 /* this has to be done as root in order to verify the password */
260 become_root();
261 status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
262 unbecome_root();
264 /* Don't generate a reply. */
265 data_blob_free(&reply);
267 if (!NT_STATUS_IS_OK(status)) {
268 return False;
271 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
272 ensure the underlying NTLMSSP flags are also set. If not we should
273 refuse the bind. */
275 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
276 if (!auth_ntlmssp_negotiated_sign(a)) {
277 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet integrity requested "
278 "but client declined signing.\n",
279 get_pipe_name_from_syntax(talloc_tos(),
280 &p->syntax)));
281 return False;
284 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
285 if (!auth_ntlmssp_negotiated_seal(a)) {
286 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet privacy requested "
287 "but client declined sealing.\n",
288 get_pipe_name_from_syntax(talloc_tos(),
289 &p->syntax)));
290 return False;
294 DEBUG(5, ("pipe_ntlmssp_verify_final: OK: user: %s domain: %s "
295 "workstation: %s\n",
296 auth_ntlmssp_get_username(a),
297 auth_ntlmssp_get_domain(a),
298 auth_ntlmssp_get_client(a)));
300 TALLOC_FREE(p->server_info);
302 status = auth_ntlmssp_steal_server_info(p, a, &p->server_info);
303 if (!NT_STATUS_IS_OK(status)) {
304 DEBUG(0, ("auth_ntlmssp_server_info failed to obtain the server info for authenticated user: %s\n",
305 nt_errstr(status)));
306 return false;
309 if (p->server_info->ptok == NULL) {
310 DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
311 return False;
315 * We're an authenticated bind over smb, so the session key needs to
316 * be set to "SystemLibraryDTC". Weird, but this is what Windows
317 * does. See the RPC-SAMBA3SESSIONKEY.
320 session_key = generic_session_key();
321 if (session_key.data == NULL) {
322 return False;
325 ret = server_info_set_session_key(p->server_info, session_key);
327 data_blob_free(&session_key);
329 return True;
332 /*******************************************************************
333 This is the "stage3" NTLMSSP response after a bind request and reply.
334 *******************************************************************/
336 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
338 struct dcerpc_auth auth_info;
339 NTSTATUS status;
341 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
343 if (pkt->auth_length == 0) {
344 DEBUG(0, ("No auth field sent for bind request!\n"));
345 goto err;
348 /* Ensure there's enough data for an authenticated request. */
349 if (pkt->frag_length < RPC_HEADER_LEN
350 + DCERPC_AUTH_TRAILER_LENGTH
351 + pkt->auth_length) {
352 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
353 "%u is too large.\n",
354 (unsigned int)pkt->auth_length));
355 goto err;
359 * Decode the authentication verifier response.
362 status = dcerpc_pull_dcerpc_auth(pkt,
363 &pkt->u.auth3.auth_info,
364 &auth_info, p->endian);
365 if (!NT_STATUS_IS_OK(status)) {
366 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
367 goto err;
370 /* We must NEVER look at auth_info->auth_pad_len here,
371 * as old Samba client code gets it wrong and sends it
372 * as zero. JRA.
375 if (auth_info.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) {
376 DEBUG(0,("api_pipe_bind_auth3: incorrect auth type (%u).\n",
377 (unsigned int)auth_info.auth_type ));
378 return False;
382 * The following call actually checks the challenge/response data.
383 * for correctness against the given DOMAIN\user name.
386 if (!pipe_ntlmssp_verify_final(p, &auth_info.credentials)) {
387 goto err;
390 p->pipe_bound = True;
392 return True;
394 err:
396 free_pipe_auth_data(&p->auth);
398 return False;
401 static bool pipe_init_outgoing_data(struct pipes_struct *p);
403 /*******************************************************************
404 Marshall a bind_nak pdu.
405 *******************************************************************/
407 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
409 NTSTATUS status;
410 union dcerpc_payload u;
412 /* Free any memory in the current return data buffer. */
413 pipe_init_outgoing_data(p);
416 * Initialize a bind_nak header.
419 ZERO_STRUCT(u);
421 u.bind_nak.reject_reason = 0;
424 * Marshall directly into the outgoing PDU space. We
425 * must do this as we need to set to the bind response
426 * header and are never sending more than one PDU here.
429 status = dcerpc_push_ncacn_packet(p->mem_ctx,
430 DCERPC_PKT_BIND_NAK,
431 DCERPC_PFC_FLAG_FIRST |
432 DCERPC_PFC_FLAG_LAST,
434 pkt->call_id,
436 &p->out_data.frag);
437 if (!NT_STATUS_IS_OK(status)) {
438 return False;
441 p->out_data.data_sent_length = 0;
442 p->out_data.current_pdu_sent = 0;
444 free_pipe_auth_data(&p->auth);
445 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
446 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
447 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
448 p->pipe_bound = False;
450 return True;
453 /*******************************************************************
454 Marshall a fault pdu.
455 *******************************************************************/
457 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
459 NTSTATUS status;
460 union dcerpc_payload u;
462 /* Free any memory in the current return data buffer. */
463 pipe_init_outgoing_data(p);
466 * Initialize a fault header.
469 ZERO_STRUCT(u);
471 u.fault.status = NT_STATUS_V(fault_status);
472 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
475 * Marshall directly into the outgoing PDU space. We
476 * must do this as we need to set to the bind response
477 * header and are never sending more than one PDU here.
480 status = dcerpc_push_ncacn_packet(p->mem_ctx,
481 DCERPC_PKT_FAULT,
482 DCERPC_PFC_FLAG_FIRST |
483 DCERPC_PFC_FLAG_LAST |
484 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
486 p->call_id,
488 &p->out_data.frag);
489 if (!NT_STATUS_IS_OK(status)) {
490 return False;
493 p->out_data.data_sent_length = 0;
494 p->out_data.current_pdu_sent = 0;
496 return True;
499 /*******************************************************************
500 Ensure a bind request has the correct abstract & transfer interface.
501 Used to reject unknown binds from Win2k.
502 *******************************************************************/
504 static bool check_bind_req(struct pipes_struct *p,
505 struct ndr_syntax_id* abstract,
506 struct ndr_syntax_id* transfer,
507 uint32 context_id)
509 struct pipe_rpc_fns *context_fns;
511 DEBUG(3,("check_bind_req for %s\n",
512 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
514 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
515 if (rpc_srv_pipe_exists_by_id(abstract) &&
516 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
517 DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
518 rpc_srv_get_pipe_cli_name(abstract),
519 rpc_srv_get_pipe_srv_name(abstract)));
520 } else {
521 return false;
524 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
525 if (context_fns == NULL) {
526 DEBUG(0,("check_bind_req: malloc() failed!\n"));
527 return False;
530 context_fns->next = context_fns->prev = NULL;
531 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
532 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
533 context_fns->context_id = context_id;
535 /* add to the list of open contexts */
537 DLIST_ADD( p->contexts, context_fns );
539 return True;
543 * Is a named pipe known?
544 * @param[in] cli_filename The pipe name requested by the client
545 * @result Do we want to serve this?
547 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
549 const char *pipename = cli_filename;
550 NTSTATUS status;
552 if (strnequal(pipename, "\\PIPE\\", 6)) {
553 pipename += 5;
556 if (*pipename == '\\') {
557 pipename += 1;
560 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
561 DEBUG(10, ("refusing spoolss access\n"));
562 return false;
565 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
566 return true;
569 status = smb_probe_module("rpc", pipename);
570 if (!NT_STATUS_IS_OK(status)) {
571 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
572 return false;
574 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
577 * Scan the list again for the interface id
579 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
580 return true;
583 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
584 pipename));
586 return false;
589 /*******************************************************************
590 Handle a SPNEGO krb5 bind auth.
591 *******************************************************************/
593 static bool pipe_spnego_auth_bind_kerberos(struct pipes_struct *p,
594 TALLOC_CTX *mem_ctx,
595 struct dcerpc_auth *pauth_info,
596 DATA_BLOB *psecblob,
597 DATA_BLOB *response)
599 return False;
602 /*******************************************************************
603 Handle the first part of a SPNEGO bind auth.
604 *******************************************************************/
606 static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p,
607 TALLOC_CTX *mem_ctx,
608 struct dcerpc_auth *pauth_info,
609 DATA_BLOB *response)
611 DATA_BLOB secblob;
612 DATA_BLOB chal;
613 char *OIDs[ASN1_MAX_OIDS];
614 int i;
615 NTSTATUS status;
616 bool got_kerberos_mechanism = false;
617 struct auth_ntlmssp_state *a = NULL;
619 ZERO_STRUCT(secblob);
620 ZERO_STRUCT(chal);
622 if (pauth_info->credentials.data[0] != ASN1_APPLICATION(0)) {
623 goto err;
626 /* parse out the OIDs and the first sec blob */
627 if (!spnego_parse_negTokenInit(talloc_tos(),
628 pauth_info->credentials, OIDs, NULL, &secblob)) {
629 DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
630 goto err;
633 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
634 got_kerberos_mechanism = true;
637 for (i=0;OIDs[i];i++) {
638 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));
639 TALLOC_FREE(OIDs[i]);
641 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
643 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB) ) {
644 bool ret;
645 ret = pipe_spnego_auth_bind_kerberos(p, mem_ctx, pauth_info,
646 &secblob, response);
647 data_blob_free(&secblob);
648 return ret;
651 /* Free any previous auth type. */
652 free_pipe_auth_data(&p->auth);
654 if (!got_kerberos_mechanism) {
655 /* Initialize the NTLM engine. */
656 status = auth_ntlmssp_start(&a);
657 if (!NT_STATUS_IS_OK(status)) {
658 goto err;
661 /* Clear flags,
662 * then set them according to requested Auth Level */
663 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
664 NTLMSSP_NEGOTIATE_SEAL));
665 switch (pauth_info->auth_level) {
666 case DCERPC_AUTH_LEVEL_INTEGRITY:
667 auth_ntlmssp_or_flags(a,
668 NTLMSSP_NEGOTIATE_SIGN);
669 break;
670 case DCERPC_AUTH_LEVEL_PRIVACY:
671 /* Privacy always implies both sign and seal
672 * for ntlmssp */
673 auth_ntlmssp_or_flags(a,
674 NTLMSSP_NEGOTIATE_SIGN |
675 NTLMSSP_NEGOTIATE_SEAL);
676 break;
677 default:
678 break;
681 * Pass the first security blob of data to it.
682 * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
683 * which means we need another packet to complete the bind.
686 status = auth_ntlmssp_update(a, secblob, &chal);
688 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
689 DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
690 goto err;
693 /* Generate the response blob we need for step 2 of the bind. */
694 *response = spnego_gen_auth_response(mem_ctx, &chal, status, OID_NTLMSSP);
695 } else {
697 * SPNEGO negotiate down to NTLMSSP. The subsequent
698 * code to process follow-up packets is not complete
699 * yet. JRA.
701 *response = spnego_gen_auth_response(mem_ctx, NULL,
702 NT_STATUS_MORE_PROCESSING_REQUIRED,
703 OID_NTLMSSP);
706 /* auth_pad_len will be handled by the caller */
708 p->auth.a_u.auth_ntlmssp_state = a;
709 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
710 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
711 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
713 data_blob_free(&secblob);
714 data_blob_free(&chal);
716 /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */
717 return True;
719 err:
721 data_blob_free(&secblob);
722 data_blob_free(&chal);
724 p->auth.a_u.auth_ntlmssp_state = NULL;
726 return False;
729 /*******************************************************************
730 Handle the second part of a SPNEGO bind auth.
731 *******************************************************************/
733 static bool pipe_spnego_auth_bind_continue(struct pipes_struct *p,
734 TALLOC_CTX *mem_ctx,
735 struct dcerpc_auth *pauth_info,
736 DATA_BLOB *response)
738 DATA_BLOB auth_blob;
739 DATA_BLOB auth_reply;
740 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
742 ZERO_STRUCT(auth_blob);
743 ZERO_STRUCT(auth_reply);
746 * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently
747 * fail here as 'a' == NULL.
749 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO ||
750 p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {
751 DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));
752 goto err;
755 if (pauth_info->credentials.data[0] != ASN1_CONTEXT(1)) {
756 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));
757 goto err;
760 if (!spnego_parse_auth(talloc_tos(), pauth_info->credentials, &auth_blob)) {
761 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
762 goto err;
766 * The following call actually checks the challenge/response data.
767 * for correctness against the given DOMAIN\user name.
770 if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {
771 goto err;
774 data_blob_free(&auth_blob);
776 /* Generate the spnego "accept completed" blob - no incoming data. */
777 *response = spnego_gen_auth_response(mem_ctx, &auth_reply, NT_STATUS_OK, OID_NTLMSSP);
779 data_blob_free(&auth_reply);
781 p->pipe_bound = True;
783 return True;
785 err:
787 data_blob_free(&auth_blob);
788 data_blob_free(&auth_reply);
790 free_pipe_auth_data(&p->auth);
792 return False;
795 /*******************************************************************
796 Handle an schannel bind auth.
797 *******************************************************************/
799 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
800 TALLOC_CTX *mem_ctx,
801 struct dcerpc_auth *auth_info,
802 DATA_BLOB *response)
804 struct NL_AUTH_MESSAGE neg;
805 struct NL_AUTH_MESSAGE reply;
806 bool ret;
807 NTSTATUS status;
808 struct netlogon_creds_CredentialState *creds;
809 DATA_BLOB session_key;
810 enum ndr_err_code ndr_err;
812 ndr_err = ndr_pull_struct_blob(
813 &auth_info->credentials, mem_ctx, &neg,
814 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
815 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
816 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
817 return false;
820 if (DEBUGLEVEL >= 10) {
821 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
824 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
825 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
826 return false;
830 * The neg.oem_netbios_computer.a key here must match the remote computer name
831 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
832 * operations that use credentials.
835 become_root();
836 status = schannel_get_creds_state(p, lp_private_dir(),
837 neg.oem_netbios_computer.a, &creds);
838 unbecome_root();
840 if (!NT_STATUS_IS_OK(status)) {
841 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
842 return False;
845 p->auth.a_u.schannel_auth = talloc(p, struct schannel_state);
846 if (!p->auth.a_u.schannel_auth) {
847 TALLOC_FREE(creds);
848 return False;
851 p->auth.a_u.schannel_auth->state = SCHANNEL_STATE_START;
852 p->auth.a_u.schannel_auth->seq_num = 0;
853 p->auth.a_u.schannel_auth->initiator = false;
854 p->auth.a_u.schannel_auth->creds = creds;
857 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
858 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
859 * struct of the person who opened the pipe. I need to test this further. JRA.
861 * VL. As we are mapping this to guest set the generic key
862 * "SystemLibraryDTC" key here. It's a bit difficult to test against
863 * W2k3, as it does not allow schannel binds against SAMR and LSA
864 * anymore.
867 session_key = generic_session_key();
868 if (session_key.data == NULL) {
869 DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session"
870 " key\n"));
871 return false;
874 ret = server_info_set_session_key(p->server_info, session_key);
876 data_blob_free(&session_key);
878 if (!ret) {
879 DEBUG(0, ("server_info_set_session_key failed\n"));
880 return false;
883 /*** SCHANNEL verifier ***/
885 reply.MessageType = NL_NEGOTIATE_RESPONSE;
886 reply.Flags = 0;
887 reply.Buffer.dummy = 5; /* ??? actually I don't think
888 * this has any meaning
889 * here - gd */
891 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
892 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
893 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
894 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
895 return false;
898 if (DEBUGLEVEL >= 10) {
899 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
902 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
903 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
905 /* We're finished with this bind - no more packets. */
906 p->auth.auth_data_free_func = &free_pipe_schannel_auth_data;
907 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
909 p->pipe_bound = True;
911 return True;
914 /*******************************************************************
915 Handle an NTLMSSP bind auth.
916 *******************************************************************/
918 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
919 TALLOC_CTX *mem_ctx,
920 struct dcerpc_auth *auth_info,
921 DATA_BLOB *response)
923 NTSTATUS status;
924 struct auth_ntlmssp_state *a = NULL;
926 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
927 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
928 goto err;
931 /* We have an NTLMSSP blob. */
932 status = auth_ntlmssp_start(&a);
933 if (!NT_STATUS_IS_OK(status)) {
934 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",
935 nt_errstr(status) ));
936 goto err;
939 /* Clear flags, then set them according to requested Auth Level */
940 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
941 NTLMSSP_NEGOTIATE_SEAL));
943 switch (auth_info->auth_level) {
944 case DCERPC_AUTH_LEVEL_INTEGRITY:
945 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN);
946 break;
947 case DCERPC_AUTH_LEVEL_PRIVACY:
948 /* Privacy always implies both sign and seal for ntlmssp */
949 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN |
950 NTLMSSP_NEGOTIATE_SEAL);
951 break;
952 default:
953 break;
956 status = auth_ntlmssp_update(a, auth_info->credentials, response);
957 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
958 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n",
959 nt_errstr(status) ));
960 goto err;
963 /* Make sure data is bound to the memctx, to be freed the caller */
964 talloc_steal(mem_ctx, response->data);
966 p->auth.a_u.auth_ntlmssp_state = a;
967 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
968 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
970 DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
972 /* We can't set pipe_bound True yet - we need an DCERPC_PKT_AUTH3 response packet... */
973 return True;
975 err:
977 TALLOC_FREE(a);
978 return False;
981 /*******************************************************************
982 Respond to a pipe bind request.
983 *******************************************************************/
985 bool api_pipe_bind_req(struct pipes_struct *p, struct ncacn_packet *pkt)
987 struct dcerpc_auth auth_info;
988 uint16 assoc_gid;
989 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
990 NTSTATUS status;
991 struct ndr_syntax_id id;
992 union dcerpc_payload u;
993 struct dcerpc_ack_ctx bind_ack_ctx;
994 DATA_BLOB auth_resp = data_blob_null;
995 DATA_BLOB auth_blob = data_blob_null;
997 /* No rebinds on a bound pipe - use alter context. */
998 if (p->pipe_bound) {
999 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
1000 "pipe %s.\n",
1001 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1002 return setup_bind_nak(p, pkt);
1005 if (pkt->u.bind.num_contexts == 0) {
1006 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
1007 goto err_exit;
1011 * Try and find the correct pipe name to ensure
1012 * that this is a pipe name we support.
1014 id = pkt->u.bind.ctx_list[0].abstract_syntax;
1015 if (rpc_srv_pipe_exists_by_id(&id)) {
1016 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1017 rpc_srv_get_pipe_cli_name(&id),
1018 rpc_srv_get_pipe_srv_name(&id)));
1019 } else {
1020 status = smb_probe_module(
1021 "rpc", get_pipe_name_from_syntax(
1022 talloc_tos(),
1023 &pkt->u.bind.ctx_list[0].abstract_syntax));
1025 if (NT_STATUS_IS_ERR(status)) {
1026 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
1027 get_pipe_name_from_syntax(
1028 talloc_tos(),
1029 &pkt->u.bind.ctx_list[0].abstract_syntax)));
1031 return setup_bind_nak(p, pkt);
1034 if (rpc_srv_get_pipe_interface_by_cli_name(
1035 get_pipe_name_from_syntax(talloc_tos(),
1036 &p->syntax),
1037 &id)) {
1038 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1039 rpc_srv_get_pipe_cli_name(&id),
1040 rpc_srv_get_pipe_srv_name(&id)));
1041 } else {
1042 DEBUG(0, ("module %s doesn't provide functions for "
1043 "pipe %s!\n",
1044 get_pipe_name_from_syntax(talloc_tos(),
1045 &p->syntax),
1046 get_pipe_name_from_syntax(talloc_tos(),
1047 &p->syntax)));
1048 return setup_bind_nak(p, pkt);
1052 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
1054 if (pkt->u.bind.assoc_group_id != 0) {
1055 assoc_gid = pkt->u.bind.assoc_group_id;
1056 } else {
1057 assoc_gid = 0x53f0;
1061 * Create the bind response struct.
1064 /* If the requested abstract synt uuid doesn't match our client pipe,
1065 reject the bind_ack & set the transfer interface synt to all 0's,
1066 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1067 unknown to NT4)
1068 Needed when adding entries to a DACL from NT5 - SK */
1070 if (check_bind_req(p,
1071 &pkt->u.bind.ctx_list[0].abstract_syntax,
1072 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1073 pkt->u.bind.ctx_list[0].context_id)) {
1075 bind_ack_ctx.result = 0;
1076 bind_ack_ctx.reason = 0;
1077 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1078 } else {
1079 p->pipe_bound = False;
1080 /* Rejection reason: abstract syntax not supported */
1081 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1082 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1083 bind_ack_ctx.syntax = null_ndr_syntax_id;
1087 * Check if this is an authenticated bind request.
1089 if (pkt->auth_length) {
1090 /* Quick length check. Won't catch a bad auth footer,
1091 * prevents overrun. */
1093 if (pkt->frag_length < RPC_HEADER_LEN +
1094 DCERPC_AUTH_TRAILER_LENGTH +
1095 pkt->auth_length) {
1096 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
1097 "too long for fragment %u.\n",
1098 (unsigned int)pkt->auth_length,
1099 (unsigned int)pkt->frag_length));
1100 goto err_exit;
1104 * Decode the authentication verifier.
1106 status = dcerpc_pull_dcerpc_auth(pkt,
1107 &pkt->u.bind.auth_info,
1108 &auth_info, p->endian);
1109 if (!NT_STATUS_IS_OK(status)) {
1110 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1111 goto err_exit;
1114 auth_type = auth_info.auth_type;
1116 /* Work out if we have to sign or seal etc. */
1117 switch (auth_info.auth_level) {
1118 case DCERPC_AUTH_LEVEL_INTEGRITY:
1119 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1120 break;
1121 case DCERPC_AUTH_LEVEL_PRIVACY:
1122 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1123 break;
1124 default:
1125 DEBUG(0, ("Unexpected auth level (%u).\n",
1126 (unsigned int)auth_info.auth_level ));
1127 goto err_exit;
1130 switch (auth_type) {
1131 case DCERPC_AUTH_TYPE_NTLMSSP:
1132 if (!pipe_ntlmssp_auth_bind(p, pkt,
1133 &auth_info, &auth_resp)) {
1134 goto err_exit;
1136 assoc_gid = 0x7a77;
1137 break;
1139 case DCERPC_AUTH_TYPE_SCHANNEL:
1140 if (!pipe_schannel_auth_bind(p, pkt,
1141 &auth_info, &auth_resp)) {
1142 goto err_exit;
1144 break;
1146 case DCERPC_AUTH_TYPE_SPNEGO:
1147 if (!pipe_spnego_auth_bind_negotiate(p, pkt,
1148 &auth_info, &auth_resp)) {
1149 goto err_exit;
1151 break;
1153 case DCERPC_AUTH_TYPE_NONE:
1154 break;
1156 default:
1157 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1158 goto err_exit;
1162 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1163 /* Unauthenticated bind request. */
1164 /* We're finished - no more packets. */
1165 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1166 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
1167 /* We must set the pipe auth_level here also. */
1168 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1169 p->pipe_bound = True;
1170 /* The session key was initialized from the SMB
1171 * session in make_internal_rpc_pipe_p */
1174 ZERO_STRUCT(u.bind_ack);
1175 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1176 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1177 u.bind_ack.assoc_group_id = assoc_gid;
1179 /* name has to be \PIPE\xxxxx */
1180 u.bind_ack.secondary_address =
1181 talloc_asprintf(pkt, "\\PIPE\\%s",
1182 rpc_srv_get_pipe_srv_name(&id));
1183 if (!u.bind_ack.secondary_address) {
1184 DEBUG(0, ("Out of memory!\n"));
1185 goto err_exit;
1187 u.bind_ack.secondary_address_size =
1188 strlen(u.bind_ack.secondary_address) + 1;
1190 u.bind_ack.num_results = 1;
1191 u.bind_ack.ctx_list = &bind_ack_ctx;
1193 /* NOTE: We leave the auth_info empty so we can calculate the padding
1194 * later and then append the auth_info --simo */
1197 * Marshall directly into the outgoing PDU space. We
1198 * must do this as we need to set to the bind response
1199 * header and are never sending more than one PDU here.
1202 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1203 DCERPC_PKT_BIND_ACK,
1204 DCERPC_PFC_FLAG_FIRST |
1205 DCERPC_PFC_FLAG_LAST,
1206 auth_resp.length,
1207 pkt->call_id,
1209 &p->out_data.frag);
1210 if (!NT_STATUS_IS_OK(status)) {
1211 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1212 nt_errstr(status)));
1215 if (auth_resp.length) {
1217 status = dcerpc_push_dcerpc_auth(pkt,
1218 auth_type,
1219 auth_info.auth_level,
1221 1, /* auth_context_id */
1222 &auth_resp,
1223 &auth_blob);
1224 if (!NT_STATUS_IS_OK(status)) {
1225 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1226 goto err_exit;
1230 /* Now that we have the auth len store it into the right place in
1231 * the dcerpc header */
1232 dcerpc_set_frag_length(&p->out_data.frag,
1233 p->out_data.frag.length + auth_blob.length);
1235 if (auth_blob.length) {
1237 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1238 auth_blob.data, auth_blob.length)) {
1239 DEBUG(0, ("Append of auth info failed.\n"));
1240 goto err_exit;
1245 * Setup the lengths for the initial reply.
1248 p->out_data.data_sent_length = 0;
1249 p->out_data.current_pdu_sent = 0;
1251 TALLOC_FREE(auth_blob.data);
1252 return True;
1254 err_exit:
1256 data_blob_free(&p->out_data.frag);
1257 TALLOC_FREE(auth_blob.data);
1258 return setup_bind_nak(p, pkt);
1261 /****************************************************************************
1262 Deal with an alter context call. Can be third part of 3 leg auth request for
1263 SPNEGO calls.
1264 ****************************************************************************/
1266 bool api_pipe_alter_context(struct pipes_struct *p, struct ncacn_packet *pkt)
1268 struct dcerpc_auth auth_info;
1269 uint16 assoc_gid;
1270 NTSTATUS status;
1271 union dcerpc_payload u;
1272 struct dcerpc_ack_ctx bind_ack_ctx;
1273 DATA_BLOB auth_resp = data_blob_null;
1274 DATA_BLOB auth_blob = data_blob_null;
1275 int pad_len = 0;
1277 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1279 if (pkt->u.bind.assoc_group_id != 0) {
1280 assoc_gid = pkt->u.bind.assoc_group_id;
1281 } else {
1282 assoc_gid = 0x53f0;
1286 * Create the bind response struct.
1289 /* If the requested abstract synt uuid doesn't match our client pipe,
1290 reject the bind_ack & set the transfer interface synt to all 0's,
1291 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1292 unknown to NT4)
1293 Needed when adding entries to a DACL from NT5 - SK */
1295 if (check_bind_req(p,
1296 &pkt->u.bind.ctx_list[0].abstract_syntax,
1297 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1298 pkt->u.bind.ctx_list[0].context_id)) {
1300 bind_ack_ctx.result = 0;
1301 bind_ack_ctx.reason = 0;
1302 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1303 } else {
1304 p->pipe_bound = False;
1305 /* Rejection reason: abstract syntax not supported */
1306 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1307 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1308 bind_ack_ctx.syntax = null_ndr_syntax_id;
1312 * Check if this is an authenticated alter context request.
1314 if (pkt->auth_length) {
1315 /* Quick length check. Won't catch a bad auth footer,
1316 * prevents overrun. */
1318 if (pkt->frag_length < RPC_HEADER_LEN +
1319 DCERPC_AUTH_TRAILER_LENGTH +
1320 pkt->auth_length) {
1321 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1322 "too long for fragment %u.\n",
1323 (unsigned int)pkt->auth_length,
1324 (unsigned int)pkt->frag_length ));
1325 goto err_exit;
1328 status = dcerpc_pull_dcerpc_auth(pkt,
1329 &pkt->u.bind.auth_info,
1330 &auth_info, p->endian);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1333 goto err_exit;
1338 * Currently only the SPNEGO auth type uses the alter ctx
1339 * response in place of the NTLMSSP auth3 type.
1342 if (auth_info.auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
1343 /* We can only finish if the pipe is unbound. */
1344 if (!p->pipe_bound) {
1345 if (!pipe_spnego_auth_bind_continue(p, pkt,
1346 &auth_info, &auth_resp)) {
1347 goto err_exit;
1350 } else {
1351 goto err_exit;
1356 ZERO_STRUCT(u.alter_resp);
1357 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1358 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1359 u.alter_resp.assoc_group_id = assoc_gid;
1361 /* secondary address CAN be NULL
1362 * as the specs say it's ignored.
1363 * It MUST be NULL to have the spoolss working.
1365 u.alter_resp.secondary_address = "";
1366 u.alter_resp.secondary_address_size = 1;
1368 u.alter_resp.num_results = 1;
1369 u.alter_resp.ctx_list = &bind_ack_ctx;
1371 /* NOTE: We leave the auth_info empty so we can calculate the padding
1372 * later and then append the auth_info --simo */
1375 * Marshall directly into the outgoing PDU space. We
1376 * must do this as we need to set to the bind response
1377 * header and are never sending more than one PDU here.
1380 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1381 DCERPC_PKT_ALTER_RESP,
1382 DCERPC_PFC_FLAG_FIRST |
1383 DCERPC_PFC_FLAG_LAST,
1384 auth_resp.length,
1385 pkt->call_id,
1387 &p->out_data.frag);
1388 if (!NT_STATUS_IS_OK(status)) {
1389 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1390 nt_errstr(status)));
1393 if (auth_resp.length) {
1395 /* Work out any padding needed before the auth footer. */
1396 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1397 if (pad_len) {
1398 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1399 DEBUG(10, ("auth pad_len = %u\n",
1400 (unsigned int)pad_len));
1403 status = dcerpc_push_dcerpc_auth(pkt,
1404 auth_info.auth_type,
1405 auth_info.auth_level,
1406 pad_len,
1407 1, /* auth_context_id */
1408 &auth_resp,
1409 &auth_blob);
1410 if (!NT_STATUS_IS_OK(status)) {
1411 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1412 goto err_exit;
1416 /* Now that we have the auth len store it into the right place in
1417 * the dcerpc header */
1418 dcerpc_set_frag_length(&p->out_data.frag,
1419 p->out_data.frag.length +
1420 pad_len + auth_blob.length);
1422 if (auth_resp.length) {
1423 if (pad_len) {
1424 char pad[SERVER_NDR_PADDING_SIZE];
1425 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1426 if (!data_blob_append(p->mem_ctx,
1427 &p->out_data.frag,
1428 pad, pad_len)) {
1429 DEBUG(0, ("api_pipe_bind_req: failed to add "
1430 "%u bytes of pad data.\n",
1431 (unsigned int)pad_len));
1432 goto err_exit;
1436 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1437 auth_blob.data, auth_blob.length)) {
1438 DEBUG(0, ("Append of auth info failed.\n"));
1439 goto err_exit;
1444 * Setup the lengths for the initial reply.
1447 p->out_data.data_sent_length = 0;
1448 p->out_data.current_pdu_sent = 0;
1450 TALLOC_FREE(auth_blob.data);
1451 return True;
1453 err_exit:
1455 data_blob_free(&p->out_data.frag);
1456 TALLOC_FREE(auth_blob.data);
1457 return setup_bind_nak(p, pkt);
1460 /****************************************************************************
1461 Find the set of RPC functions associated with this context_id
1462 ****************************************************************************/
1464 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1466 PIPE_RPC_FNS *fns = NULL;
1468 if ( !list ) {
1469 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1470 return NULL;
1473 for (fns=list; fns; fns=fns->next ) {
1474 if ( fns->context_id == context_id )
1475 return fns;
1477 return NULL;
1480 /****************************************************************************
1481 Memory cleanup.
1482 ****************************************************************************/
1484 void free_pipe_rpc_context( PIPE_RPC_FNS *list )
1486 PIPE_RPC_FNS *tmp = list;
1487 PIPE_RPC_FNS *tmp2;
1489 while (tmp) {
1490 tmp2 = tmp->next;
1491 SAFE_FREE(tmp);
1492 tmp = tmp2;
1495 return;
1498 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1499 const struct api_struct *api_rpc_cmds, int n_cmds);
1501 /****************************************************************************
1502 Find the correct RPC function to call for this request.
1503 If the pipe is authenticated then become the correct UNIX user
1504 before doing the call.
1505 ****************************************************************************/
1507 bool api_pipe_request(struct pipes_struct *p, struct ncacn_packet *pkt)
1509 bool ret = False;
1510 bool changed_user = False;
1511 PIPE_RPC_FNS *pipe_fns;
1513 if (p->pipe_bound &&
1514 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1515 ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) &&
1516 (p->auth.spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)))) {
1517 if(!become_authenticated_pipe_user(p)) {
1518 data_blob_free(&p->out_data.rdata);
1519 return False;
1521 changed_user = True;
1524 DEBUG(5, ("Requested \\PIPE\\%s\n",
1525 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1527 /* get the set of RPC functions for this context */
1529 pipe_fns = find_pipe_fns_by_context(p->contexts,
1530 pkt->u.request.context_id);
1532 if ( pipe_fns ) {
1533 TALLOC_CTX *frame = talloc_stackframe();
1534 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1535 TALLOC_FREE(frame);
1537 else {
1538 DEBUG(0, ("No rpc function table associated with context "
1539 "[%d] on pipe [%s]\n",
1540 pkt->u.request.context_id,
1541 get_pipe_name_from_syntax(talloc_tos(),
1542 &p->syntax)));
1545 if (changed_user) {
1546 unbecome_authenticated_pipe_user();
1549 return ret;
1552 /*******************************************************************
1553 Calls the underlying RPC function for a named pipe.
1554 ********************************************************************/
1556 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1557 const struct api_struct *api_rpc_cmds, int n_cmds)
1559 int fn_num;
1560 uint32_t offset1;
1562 /* interpret the command */
1563 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1564 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1565 pkt->u.request.opnum));
1567 if (DEBUGLEVEL >= 50) {
1568 fstring name;
1569 slprintf(name, sizeof(name)-1, "in_%s",
1570 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1571 dump_pdu_region(name, pkt->u.request.opnum,
1572 &p->in_data.data, 0,
1573 p->in_data.data.length);
1576 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1577 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1578 api_rpc_cmds[fn_num].fn != NULL) {
1579 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1580 api_rpc_cmds[fn_num].name));
1581 break;
1585 if (fn_num == n_cmds) {
1587 * For an unknown RPC just return a fault PDU but
1588 * return True to allow RPC's on the pipe to continue
1589 * and not put the pipe into fault state. JRA.
1591 DEBUG(4, ("unknown\n"));
1592 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1593 return True;
1596 offset1 = p->out_data.rdata.length;
1598 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1599 fn_num, api_rpc_cmds[fn_num].fn));
1600 /* do the actual command */
1601 if(!api_rpc_cmds[fn_num].fn(p)) {
1602 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1603 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1604 api_rpc_cmds[fn_num].name));
1605 data_blob_free(&p->out_data.rdata);
1606 return False;
1609 if (p->bad_handle_fault_state) {
1610 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1611 p->bad_handle_fault_state = False;
1612 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1613 return True;
1616 if (p->rng_fault_state) {
1617 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1618 p->rng_fault_state = False;
1619 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1620 return True;
1623 if (DEBUGLEVEL >= 50) {
1624 fstring name;
1625 slprintf(name, sizeof(name)-1, "out_%s",
1626 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1627 dump_pdu_region(name, pkt->u.request.opnum,
1628 &p->out_data.rdata, offset1,
1629 p->out_data.rdata.length);
1632 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1633 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1635 /* Check for buffer underflow in rpc parsing */
1636 if ((DEBUGLEVEL >= 10) &&
1637 (pkt->frag_length < p->in_data.data.length)) {
1638 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1639 dump_data(10, p->in_data.data.data + pkt->frag_length,
1640 p->in_data.data.length - pkt->frag_length);
1643 return True;
1646 /****************************************************************************
1647 Initialise an outgoing packet.
1648 ****************************************************************************/
1650 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1652 output_data *o_data = &p->out_data;
1654 /* Reset the offset counters. */
1655 o_data->data_sent_length = 0;
1656 o_data->current_pdu_sent = 0;
1658 data_blob_free(&o_data->frag);
1660 /* Free any memory in the current return data buffer. */
1661 data_blob_free(&o_data->rdata);
1663 return True;
1666 /****************************************************************************
1667 Sets the fault state on incoming packets.
1668 ****************************************************************************/
1670 void set_incoming_fault(struct pipes_struct *p)
1672 data_blob_free(&p->in_data.data);
1673 p->in_data.pdu_needed_len = 0;
1674 p->in_data.pdu.length = 0;
1675 p->fault_state = True;
1676 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1677 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1680 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
1681 struct ncacn_packet *pkt,
1682 DATA_BLOB *raw_pkt)
1684 NTSTATUS status;
1685 size_t hdr_size = DCERPC_REQUEST_LENGTH;
1686 size_t pad_len;
1688 DEBUG(10, ("Checking request auth.\n"));
1690 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1691 hdr_size += 16;
1694 /* in case of sealing this function will unseal the data in place */
1695 status = dcerpc_check_auth(auth, pkt,
1696 &pkt->u.request.stub_and_verifier,
1697 hdr_size, raw_pkt,
1698 &pad_len);
1699 if (!NT_STATUS_IS_OK(status)) {
1700 return status;
1704 /* remove padding and auth trailer,
1705 * this way the caller will get just the data */
1706 if (pkt->auth_length) {
1707 size_t trail_len = pad_len
1708 + DCERPC_AUTH_TRAILER_LENGTH
1709 + pkt->auth_length;
1710 if (pkt->u.request.stub_and_verifier.length < trail_len) {
1711 return NT_STATUS_INFO_LENGTH_MISMATCH;
1713 pkt->u.request.stub_and_verifier.length -= trail_len;
1716 return NT_STATUS_OK;
1719 /****************************************************************************
1720 Processes a request pdu. This will do auth processing if needed, and
1721 appends the data into the complete stream if the LAST flag is not set.
1722 ****************************************************************************/
1724 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
1726 NTSTATUS status;
1727 DATA_BLOB data;
1729 if (!p->pipe_bound) {
1730 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
1731 set_incoming_fault(p);
1732 return False;
1735 /* Store the opnum */
1736 p->opnum = pkt->u.request.opnum;
1738 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
1739 if (!NT_STATUS_IS_OK(status)) {
1740 DEBUG(0, ("Failed to check packet auth. (%s)\n",
1741 nt_errstr(status)));
1742 set_incoming_fault(p);
1743 return false;
1746 data = pkt->u.request.stub_and_verifier;
1749 * Check the data length doesn't go over the 15Mb limit.
1750 * increased after observing a bug in the Windows NT 4.0 SP6a
1751 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
1752 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
1755 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
1756 DEBUG(0, ("process_request_pdu: "
1757 "rpc data buffer too large (%u) + (%u)\n",
1758 (unsigned int)p->in_data.data.length,
1759 (unsigned int)data.length));
1760 set_incoming_fault(p);
1761 return False;
1765 * Append the data portion into the buffer and return.
1768 if (data.length) {
1769 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
1770 data.data, data.length)) {
1771 DEBUG(0, ("Unable to append data size %u "
1772 "to parse buffer of size %u.\n",
1773 (unsigned int)data.length,
1774 (unsigned int)p->in_data.data.length));
1775 set_incoming_fault(p);
1776 return False;
1780 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1781 bool ret = False;
1783 * Ok - we finally have a complete RPC stream.
1784 * Call the rpc command to process it.
1788 * Process the complete data stream here.
1790 if (pipe_init_outgoing_data(p)) {
1791 ret = api_pipe_request(p, pkt);
1794 return ret;
1797 return True;
1800 /****************************************************************************
1801 Processes a finished PDU stored in p->in_data.pdu.
1802 ****************************************************************************/
1804 void process_complete_pdu(struct pipes_struct *p)
1806 struct ncacn_packet *pkt = NULL;
1807 NTSTATUS status;
1808 bool reply = False;
1810 if(p->fault_state) {
1811 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
1812 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1813 goto done;
1816 pkt = talloc(p->mem_ctx, struct ncacn_packet);
1817 if (!pkt) {
1818 DEBUG(0, ("Out of memory!\n"));
1819 goto done;
1823 * Ensure we're using the corrent endianness for both the
1824 * RPC header flags and the raw data we will be reading from.
1826 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
1827 p->endian = RPC_LITTLE_ENDIAN;
1828 } else {
1829 p->endian = RPC_BIG_ENDIAN;
1831 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
1833 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
1834 pkt, p->endian);
1835 if (!NT_STATUS_IS_OK(status)) {
1836 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
1837 nt_errstr(status)));
1838 goto done;
1841 /* Store the call_id */
1842 p->call_id = pkt->call_id;
1844 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
1846 switch (pkt->ptype) {
1847 case DCERPC_PKT_REQUEST:
1848 reply = process_request_pdu(p, pkt);
1849 break;
1851 case DCERPC_PKT_PING: /* CL request - ignore... */
1852 DEBUG(0, ("process_complete_pdu: Error. "
1853 "Connectionless packet type %d received on "
1854 "pipe %s.\n", (int)pkt->ptype,
1855 get_pipe_name_from_syntax(talloc_tos(),
1856 &p->syntax)));
1857 break;
1859 case DCERPC_PKT_RESPONSE: /* No responses here. */
1860 DEBUG(0, ("process_complete_pdu: Error. "
1861 "DCERPC_PKT_RESPONSE received from client "
1862 "on pipe %s.\n",
1863 get_pipe_name_from_syntax(talloc_tos(),
1864 &p->syntax)));
1865 break;
1867 case DCERPC_PKT_FAULT:
1868 case DCERPC_PKT_WORKING:
1869 /* CL request - reply to a ping when a call in process. */
1870 case DCERPC_PKT_NOCALL:
1871 /* CL - server reply to a ping call. */
1872 case DCERPC_PKT_REJECT:
1873 case DCERPC_PKT_ACK:
1874 case DCERPC_PKT_CL_CANCEL:
1875 case DCERPC_PKT_FACK:
1876 case DCERPC_PKT_CANCEL_ACK:
1877 DEBUG(0, ("process_complete_pdu: Error. "
1878 "Connectionless packet type %u received on "
1879 "pipe %s.\n", (unsigned int)pkt->ptype,
1880 get_pipe_name_from_syntax(talloc_tos(),
1881 &p->syntax)));
1882 break;
1884 case DCERPC_PKT_BIND:
1886 * We assume that a pipe bind is only in one pdu.
1888 if (pipe_init_outgoing_data(p)) {
1889 reply = api_pipe_bind_req(p, pkt);
1891 break;
1893 case DCERPC_PKT_BIND_ACK:
1894 case DCERPC_PKT_BIND_NAK:
1895 DEBUG(0, ("process_complete_pdu: Error. "
1896 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
1897 "packet type %u received on pipe %s.\n",
1898 (unsigned int)pkt->ptype,
1899 get_pipe_name_from_syntax(talloc_tos(),
1900 &p->syntax)));
1901 break;
1904 case DCERPC_PKT_ALTER:
1906 * We assume that a pipe bind is only in one pdu.
1908 if (pipe_init_outgoing_data(p)) {
1909 reply = api_pipe_alter_context(p, pkt);
1911 break;
1913 case DCERPC_PKT_ALTER_RESP:
1914 DEBUG(0, ("process_complete_pdu: Error. "
1915 "DCERPC_PKT_ALTER_RESP on pipe %s: "
1916 "Should only be server -> client.\n",
1917 get_pipe_name_from_syntax(talloc_tos(),
1918 &p->syntax)));
1919 break;
1921 case DCERPC_PKT_AUTH3:
1923 * The third packet in an NTLMSSP auth exchange.
1925 if (pipe_init_outgoing_data(p)) {
1926 reply = api_pipe_bind_auth3(p, pkt);
1928 break;
1930 case DCERPC_PKT_SHUTDOWN:
1931 DEBUG(0, ("process_complete_pdu: Error. "
1932 "DCERPC_PKT_SHUTDOWN on pipe %s: "
1933 "Should only be server -> client.\n",
1934 get_pipe_name_from_syntax(talloc_tos(),
1935 &p->syntax)));
1936 break;
1938 case DCERPC_PKT_CO_CANCEL:
1939 /* For now just free all client data and continue
1940 * processing. */
1941 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
1942 " Abandoning rpc call.\n"));
1943 /* As we never do asynchronous RPC serving, we can
1944 * never cancel a call (as far as I know).
1945 * If we ever did we'd have to send a cancel_ack reply.
1946 * For now, just free all client data and continue
1947 * processing. */
1948 reply = True;
1949 break;
1951 #if 0
1952 /* Enable this if we're doing async rpc. */
1953 /* We must check the outstanding callid matches. */
1954 if (pipe_init_outgoing_data(p)) {
1955 /* Send a cancel_ack PDU reply. */
1956 /* We should probably check the auth-verifier here. */
1957 reply = setup_cancel_ack_reply(p, pkt);
1959 break;
1960 #endif
1962 case DCERPC_PKT_ORPHANED:
1963 /* We should probably check the auth-verifier here.
1964 * For now just free all client data and continue
1965 * processing. */
1966 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
1967 " Abandoning rpc call.\n"));
1968 reply = True;
1969 break;
1971 default:
1972 DEBUG(0, ("process_complete_pdu: "
1973 "Unknown rpc type = %u received.\n",
1974 (unsigned int)pkt->ptype));
1975 break;
1978 done:
1979 if (!reply) {
1980 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
1981 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
1982 &p->syntax)));
1983 set_incoming_fault(p);
1984 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1985 TALLOC_FREE(pkt);
1986 } else {
1988 * Reset the lengths. We're ready for a new pdu.
1990 TALLOC_FREE(p->in_data.pdu.data);
1991 p->in_data.pdu_needed_len = 0;
1992 p->in_data.pdu.length = 0;
1995 TALLOC_FREE(pkt);