s3-dcerpc: move crypto stuff in /librpc/crypto
[Samba.git] / source3 / rpc_server / srv_pipe.c
blob4a159ce99724a9f0978f2c3e22d75d6018189aad
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 "../librpc/gen_ndr/ndr_krb5pac.h"
34 #include "../libcli/auth/schannel.h"
35 #include "../libcli/auth/spnego.h"
36 #include "../libcli/auth/ntlmssp.h"
37 #include "ntlmssp_wrap.h"
38 #include "rpc_server.h"
39 #include "rpc_dce.h"
40 #include "librpc/crypto/gse.h"
42 #undef DBGC_CLASS
43 #define DBGC_CLASS DBGC_RPC_SRV
45 /**
46 * Dump everything from the start of the end up of the provided data
47 * into a file, but only at debug level >= 50
48 **/
49 static void dump_pdu_region(const char *name, int v,
50 DATA_BLOB *data, size_t start, size_t end)
52 int fd, i;
53 char *fname = NULL;
54 ssize_t sz;
56 if (DEBUGLEVEL < 50) return;
58 if (start > data->length || end > data->length || start > end) return;
60 for (i = 1; i < 100; i++) {
61 if (v != -1) {
62 fname = talloc_asprintf(talloc_tos(),
63 "/tmp/%s_%d.%d.prs",
64 name, v, i);
65 } else {
66 fname = talloc_asprintf(talloc_tos(),
67 "/tmp/%s_%d.prs",
68 name, i);
70 if (!fname) {
71 return;
73 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
74 if (fd != -1 || errno != EEXIST) break;
76 if (fd != -1) {
77 sz = write(fd, data->data + start, end - start);
78 i = close(fd);
79 if ((sz != end - start) || (i != 0) ) {
80 DEBUG(0, ("Error writing/closing %s: %ld!=%ld %d\n",
81 fname, (unsigned long)sz,
82 (unsigned long)end - start, i));
83 } else {
84 DEBUG(0,("created %s\n", fname));
87 TALLOC_FREE(fname);
90 static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth)
92 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
95 static void free_pipe_schannel_auth_data(struct pipe_auth_data *auth)
97 TALLOC_FREE(auth->a_u.schannel_auth);
100 static void free_pipe_gssapi_auth_data(struct pipe_auth_data *auth)
102 TALLOC_FREE(auth->a_u.gssapi_state);
105 static void free_pipe_auth_data(struct pipe_auth_data *auth)
107 if (auth->auth_data_free_func) {
108 (*auth->auth_data_free_func)(auth);
109 auth->auth_data_free_func = NULL;
113 static DATA_BLOB generic_session_key(void)
115 return data_blob("SystemLibraryDTC", 16);
118 /*******************************************************************
119 Generate the next PDU to be returned from the data.
120 ********************************************************************/
122 static NTSTATUS create_next_packet(TALLOC_CTX *mem_ctx,
123 struct pipe_auth_data *auth,
124 uint32_t call_id,
125 DATA_BLOB *rdata,
126 size_t data_sent_length,
127 DATA_BLOB *frag,
128 size_t *pdu_size)
130 union dcerpc_payload u;
131 uint8_t pfc_flags;
132 size_t data_left;
133 size_t data_to_send;
134 size_t frag_len;
135 size_t pad_len = 0;
136 size_t auth_len = 0;
137 NTSTATUS status;
139 ZERO_STRUCT(u.response);
141 /* Set up rpc packet pfc flags. */
142 if (data_sent_length == 0) {
143 pfc_flags = DCERPC_PFC_FLAG_FIRST;
144 } else {
145 pfc_flags = 0;
148 /* Work out how much we can fit in a single PDU. */
149 data_left = rdata->length - data_sent_length;
151 /* Ensure there really is data left to send. */
152 if (!data_left) {
153 DEBUG(0, ("No data left to send !\n"));
154 return NT_STATUS_BUFFER_TOO_SMALL;
157 status = dcerpc_guess_sizes(auth,
158 DCERPC_RESPONSE_LENGTH,
159 data_left,
160 RPC_MAX_PDU_FRAG_LEN,
161 SERVER_NDR_PADDING_SIZE,
162 &data_to_send, &frag_len,
163 &auth_len, &pad_len);
164 if (!NT_STATUS_IS_OK(status)) {
165 return status;
168 /* Set up the alloc hint. This should be the data left to send. */
169 u.response.alloc_hint = data_left;
171 /* Work out if this PDU will be the last. */
172 if (data_sent_length + data_to_send >= rdata->length) {
173 pfc_flags |= DCERPC_PFC_FLAG_LAST;
176 /* Prepare data to be NDR encoded. */
177 u.response.stub_and_verifier =
178 data_blob_const(rdata->data + data_sent_length, data_to_send);
180 /* Store the packet in the data stream. */
181 status = dcerpc_push_ncacn_packet(mem_ctx, DCERPC_PKT_RESPONSE,
182 pfc_flags, auth_len, call_id,
183 &u, frag);
184 if (!NT_STATUS_IS_OK(status)) {
185 DEBUG(0, ("Failed to marshall RPC Packet.\n"));
186 return status;
189 if (auth_len) {
190 /* Set the proper length on the pdu, including padding.
191 * Only needed if an auth trailer will be appended. */
192 dcerpc_set_frag_length(frag, frag->length
193 + pad_len
194 + DCERPC_AUTH_TRAILER_LENGTH
195 + auth_len);
198 if (auth_len) {
199 status = dcerpc_add_auth_footer(auth, pad_len, frag);
200 if (!NT_STATUS_IS_OK(status)) {
201 data_blob_free(frag);
202 return status;
206 *pdu_size = data_to_send;
207 return NT_STATUS_OK;
210 /*******************************************************************
211 Generate the next PDU to be returned from the data in p->rdata.
212 ********************************************************************/
214 bool create_next_pdu(struct pipes_struct *p)
216 size_t pdu_size = 0;
217 NTSTATUS status;
220 * If we're in the fault state, keep returning fault PDU's until
221 * the pipe gets closed. JRA.
223 if (p->fault_state) {
224 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
225 return true;
228 status = create_next_packet(p->mem_ctx, &p->auth,
229 p->call_id, &p->out_data.rdata,
230 p->out_data.data_sent_length,
231 &p->out_data.frag, &pdu_size);
232 if (!NT_STATUS_IS_OK(status)) {
233 DEBUG(0, ("Failed to create packet with error %s, "
234 "(auth level %u / type %u)\n",
235 nt_errstr(status),
236 (unsigned int)p->auth.auth_level,
237 (unsigned int)p->auth.auth_type));
238 return false;
241 /* Setup the counts for this PDU. */
242 p->out_data.data_sent_length += pdu_size;
243 p->out_data.current_pdu_sent = 0;
244 return true;
247 /*******************************************************************
248 Process an NTLMSSP authentication response.
249 If this function succeeds, the user has been authenticated
250 and their domain, name and calling workstation stored in
251 the pipe struct.
252 *******************************************************************/
254 static bool pipe_ntlmssp_verify_final(struct pipes_struct *p,
255 DATA_BLOB *p_resp_blob)
257 DATA_BLOB session_key, reply;
258 NTSTATUS status;
259 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
260 bool ret;
262 DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n",
263 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
265 ZERO_STRUCT(reply);
267 /* this has to be done as root in order to verify the password */
268 become_root();
269 status = auth_ntlmssp_update(a, *p_resp_blob, &reply);
270 unbecome_root();
272 /* Don't generate a reply. */
273 data_blob_free(&reply);
275 if (!NT_STATUS_IS_OK(status)) {
276 return False;
279 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
280 ensure the underlying NTLMSSP flags are also set. If not we should
281 refuse the bind. */
283 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
284 if (!auth_ntlmssp_negotiated_sign(a)) {
285 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet integrity requested "
286 "but client declined signing.\n",
287 get_pipe_name_from_syntax(talloc_tos(),
288 &p->syntax)));
289 return False;
292 if (p->auth.auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
293 if (!auth_ntlmssp_negotiated_seal(a)) {
294 DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet privacy requested "
295 "but client declined sealing.\n",
296 get_pipe_name_from_syntax(talloc_tos(),
297 &p->syntax)));
298 return False;
302 DEBUG(5, ("pipe_ntlmssp_verify_final: OK: user: %s domain: %s "
303 "workstation: %s\n",
304 auth_ntlmssp_get_username(a),
305 auth_ntlmssp_get_domain(a),
306 auth_ntlmssp_get_client(a)));
308 TALLOC_FREE(p->server_info);
310 status = auth_ntlmssp_steal_server_info(p, a, &p->server_info);
311 if (!NT_STATUS_IS_OK(status)) {
312 DEBUG(0, ("auth_ntlmssp_server_info failed to obtain the server info for authenticated user: %s\n",
313 nt_errstr(status)));
314 return false;
317 if (p->server_info->ptok == NULL) {
318 DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n"));
319 return False;
323 * We're an authenticated bind over smb, so the session key needs to
324 * be set to "SystemLibraryDTC". Weird, but this is what Windows
325 * does. See the RPC-SAMBA3SESSIONKEY.
328 session_key = generic_session_key();
329 if (session_key.data == NULL) {
330 return False;
333 ret = server_info_set_session_key(p->server_info, session_key);
335 data_blob_free(&session_key);
337 return True;
340 static NTSTATUS pipe_gssapi_auth_bind_next(struct pipes_struct *p,
341 TALLOC_CTX *mem_ctx,
342 struct dcerpc_auth *pauth_info,
343 DATA_BLOB *response);
345 /*******************************************************************
346 This is the "stage3" response after a bind request and reply.
347 *******************************************************************/
349 bool api_pipe_bind_auth3(struct pipes_struct *p, struct ncacn_packet *pkt)
351 struct dcerpc_auth auth_info;
352 DATA_BLOB response = data_blob_null;
353 NTSTATUS status;
355 DEBUG(5, ("api_pipe_bind_auth3: decode request. %d\n", __LINE__));
357 if (pkt->auth_length == 0) {
358 DEBUG(0, ("No auth field sent for bind request!\n"));
359 goto err;
362 /* Ensure there's enough data for an authenticated request. */
363 if (pkt->frag_length < RPC_HEADER_LEN
364 + DCERPC_AUTH_TRAILER_LENGTH
365 + pkt->auth_length) {
366 DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len "
367 "%u is too large.\n",
368 (unsigned int)pkt->auth_length));
369 goto err;
373 * Decode the authentication verifier response.
376 status = dcerpc_pull_dcerpc_auth(pkt,
377 &pkt->u.auth3.auth_info,
378 &auth_info, p->endian);
379 if (!NT_STATUS_IS_OK(status)) {
380 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
381 goto err;
384 /* We must NEVER look at auth_info->auth_pad_len here,
385 * as old Samba client code gets it wrong and sends it
386 * as zero. JRA.
389 switch (auth_info.auth_type) {
390 case DCERPC_AUTH_TYPE_NTLMSSP:
391 if (!pipe_ntlmssp_verify_final(p, &auth_info.credentials)) {
392 goto err;
394 break;
395 case DCERPC_AUTH_TYPE_KRB5:
396 status = pipe_gssapi_auth_bind_next(p, pkt,
397 &auth_info, &response);
398 if (!NT_STATUS_IS_OK(status)) {
399 goto err;
401 if (response.length) {
402 DEBUG(0, (__location__ ": This was supposed to be "
403 "the final leg, but gssapi machinery "
404 "claims a response is needed, "
405 "aborting auth!\n"));
406 data_blob_free(&response);
407 goto err;
410 break;
411 default:
412 DEBUG(0, (__location__ ": incorrect auth type (%u).\n",
413 (unsigned int)auth_info.auth_type));
414 return false;
418 * The following call actually checks the challenge/response data.
419 * for correctness against the given DOMAIN\user name.
422 p->pipe_bound = true;
423 return true;
425 err:
427 free_pipe_auth_data(&p->auth);
428 return false;
431 static bool pipe_init_outgoing_data(struct pipes_struct *p);
433 /*******************************************************************
434 Marshall a bind_nak pdu.
435 *******************************************************************/
437 static bool setup_bind_nak(struct pipes_struct *p, struct ncacn_packet *pkt)
439 NTSTATUS status;
440 union dcerpc_payload u;
442 /* Free any memory in the current return data buffer. */
443 pipe_init_outgoing_data(p);
446 * Initialize a bind_nak header.
449 ZERO_STRUCT(u);
451 u.bind_nak.reject_reason = 0;
454 * Marshall directly into the outgoing PDU space. We
455 * must do this as we need to set to the bind response
456 * header and are never sending more than one PDU here.
459 status = dcerpc_push_ncacn_packet(p->mem_ctx,
460 DCERPC_PKT_BIND_NAK,
461 DCERPC_PFC_FLAG_FIRST |
462 DCERPC_PFC_FLAG_LAST,
464 pkt->call_id,
466 &p->out_data.frag);
467 if (!NT_STATUS_IS_OK(status)) {
468 return False;
471 p->out_data.data_sent_length = 0;
472 p->out_data.current_pdu_sent = 0;
474 free_pipe_auth_data(&p->auth);
475 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
476 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
477 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
478 p->pipe_bound = False;
480 return True;
483 /*******************************************************************
484 Marshall a fault pdu.
485 *******************************************************************/
487 bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
489 NTSTATUS status;
490 union dcerpc_payload u;
492 /* Free any memory in the current return data buffer. */
493 pipe_init_outgoing_data(p);
496 * Initialize a fault header.
499 ZERO_STRUCT(u);
501 u.fault.status = NT_STATUS_V(fault_status);
502 u.fault._pad = data_blob_talloc_zero(p->mem_ctx, 4);
505 * Marshall directly into the outgoing PDU space. We
506 * must do this as we need to set to the bind response
507 * header and are never sending more than one PDU here.
510 status = dcerpc_push_ncacn_packet(p->mem_ctx,
511 DCERPC_PKT_FAULT,
512 DCERPC_PFC_FLAG_FIRST |
513 DCERPC_PFC_FLAG_LAST |
514 DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
516 p->call_id,
518 &p->out_data.frag);
519 if (!NT_STATUS_IS_OK(status)) {
520 return False;
523 p->out_data.data_sent_length = 0;
524 p->out_data.current_pdu_sent = 0;
526 return True;
529 /*******************************************************************
530 Ensure a bind request has the correct abstract & transfer interface.
531 Used to reject unknown binds from Win2k.
532 *******************************************************************/
534 static bool check_bind_req(struct pipes_struct *p,
535 struct ndr_syntax_id* abstract,
536 struct ndr_syntax_id* transfer,
537 uint32 context_id)
539 struct pipe_rpc_fns *context_fns;
541 DEBUG(3,("check_bind_req for %s\n",
542 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
544 /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
545 if (rpc_srv_pipe_exists_by_id(abstract) &&
546 ndr_syntax_id_equal(transfer, &ndr_transfer_syntax)) {
547 DEBUG(3, ("check_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
548 rpc_srv_get_pipe_cli_name(abstract),
549 rpc_srv_get_pipe_srv_name(abstract)));
550 } else {
551 return false;
554 context_fns = SMB_MALLOC_P(struct pipe_rpc_fns);
555 if (context_fns == NULL) {
556 DEBUG(0,("check_bind_req: malloc() failed!\n"));
557 return False;
560 context_fns->next = context_fns->prev = NULL;
561 context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(abstract);
562 context_fns->cmds = rpc_srv_get_pipe_cmds(abstract);
563 context_fns->context_id = context_id;
565 /* add to the list of open contexts */
567 DLIST_ADD( p->contexts, context_fns );
569 return True;
573 * Is a named pipe known?
574 * @param[in] cli_filename The pipe name requested by the client
575 * @result Do we want to serve this?
577 bool is_known_pipename(const char *cli_filename, struct ndr_syntax_id *syntax)
579 const char *pipename = cli_filename;
580 NTSTATUS status;
582 if (strnequal(pipename, "\\PIPE\\", 6)) {
583 pipename += 5;
586 if (*pipename == '\\') {
587 pipename += 1;
590 if (lp_disable_spoolss() && strequal(pipename, "spoolss")) {
591 DEBUG(10, ("refusing spoolss access\n"));
592 return false;
595 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
596 return true;
599 status = smb_probe_module("rpc", pipename);
600 if (!NT_STATUS_IS_OK(status)) {
601 DEBUG(10, ("is_known_pipename: %s unknown\n", cli_filename));
602 return false;
604 DEBUG(10, ("is_known_pipename: %s loaded dynamically\n", pipename));
607 * Scan the list again for the interface id
609 if (rpc_srv_get_pipe_interface_by_cli_name(pipename, syntax)) {
610 return true;
613 DEBUG(10, ("is_known_pipename: pipe %s did not register itself!\n",
614 pipename));
616 return false;
619 /*******************************************************************
620 Handle a SPNEGO krb5 bind auth.
621 *******************************************************************/
623 static bool pipe_spnego_auth_bind_kerberos(struct pipes_struct *p,
624 TALLOC_CTX *mem_ctx,
625 struct dcerpc_auth *pauth_info,
626 DATA_BLOB *psecblob,
627 DATA_BLOB *response)
629 return False;
632 /*******************************************************************
633 Handle the first part of a SPNEGO bind auth.
634 *******************************************************************/
636 static bool pipe_spnego_auth_bind_negotiate(struct pipes_struct *p,
637 TALLOC_CTX *mem_ctx,
638 struct dcerpc_auth *pauth_info,
639 DATA_BLOB *response)
641 DATA_BLOB secblob;
642 DATA_BLOB chal;
643 char *OIDs[ASN1_MAX_OIDS];
644 int i;
645 NTSTATUS status;
646 bool got_kerberos_mechanism = false;
647 struct auth_ntlmssp_state *a = NULL;
649 ZERO_STRUCT(secblob);
650 ZERO_STRUCT(chal);
652 if (pauth_info->credentials.data[0] != ASN1_APPLICATION(0)) {
653 goto err;
656 /* parse out the OIDs and the first sec blob */
657 if (!spnego_parse_negTokenInit(talloc_tos(),
658 pauth_info->credentials, OIDs, NULL, &secblob)) {
659 DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
660 goto err;
663 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
664 got_kerberos_mechanism = true;
667 for (i=0;OIDs[i];i++) {
668 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i]));
669 TALLOC_FREE(OIDs[i]);
671 DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
673 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB) ) {
674 bool ret;
675 ret = pipe_spnego_auth_bind_kerberos(p, mem_ctx, pauth_info,
676 &secblob, response);
677 data_blob_free(&secblob);
678 return ret;
681 /* Free any previous auth type. */
682 free_pipe_auth_data(&p->auth);
684 if (!got_kerberos_mechanism) {
685 /* Initialize the NTLM engine. */
686 status = auth_ntlmssp_start(&a);
687 if (!NT_STATUS_IS_OK(status)) {
688 goto err;
691 /* Clear flags,
692 * then set them according to requested Auth Level */
693 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
694 NTLMSSP_NEGOTIATE_SEAL));
695 switch (pauth_info->auth_level) {
696 case DCERPC_AUTH_LEVEL_INTEGRITY:
697 auth_ntlmssp_or_flags(a,
698 NTLMSSP_NEGOTIATE_SIGN);
699 break;
700 case DCERPC_AUTH_LEVEL_PRIVACY:
701 /* Privacy always implies both sign and seal
702 * for ntlmssp */
703 auth_ntlmssp_or_flags(a,
704 NTLMSSP_NEGOTIATE_SIGN |
705 NTLMSSP_NEGOTIATE_SEAL);
706 break;
707 default:
708 break;
711 * Pass the first security blob of data to it.
712 * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
713 * which means we need another packet to complete the bind.
716 status = auth_ntlmssp_update(a, secblob, &chal);
718 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
719 DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
720 goto err;
723 /* Generate the response blob we need for step 2 of the bind. */
724 *response = spnego_gen_auth_response(mem_ctx, &chal, status, OID_NTLMSSP);
725 } else {
727 * SPNEGO negotiate down to NTLMSSP. The subsequent
728 * code to process follow-up packets is not complete
729 * yet. JRA.
731 *response = spnego_gen_auth_response(mem_ctx, NULL,
732 NT_STATUS_MORE_PROCESSING_REQUIRED,
733 OID_NTLMSSP);
736 /* auth_pad_len will be handled by the caller */
738 p->auth.a_u.auth_ntlmssp_state = a;
739 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
740 p->auth.auth_type = DCERPC_AUTH_TYPE_SPNEGO;
741 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
743 data_blob_free(&secblob);
744 data_blob_free(&chal);
746 /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */
747 return True;
749 err:
751 data_blob_free(&secblob);
752 data_blob_free(&chal);
754 p->auth.a_u.auth_ntlmssp_state = NULL;
756 return False;
759 /*******************************************************************
760 Handle the second part of a SPNEGO bind auth.
761 *******************************************************************/
763 static bool pipe_spnego_auth_bind_continue(struct pipes_struct *p,
764 TALLOC_CTX *mem_ctx,
765 struct dcerpc_auth *pauth_info,
766 DATA_BLOB *response)
768 DATA_BLOB auth_blob;
769 DATA_BLOB auth_reply;
770 struct auth_ntlmssp_state *a = p->auth.a_u.auth_ntlmssp_state;
772 ZERO_STRUCT(auth_blob);
773 ZERO_STRUCT(auth_reply);
776 * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently
777 * fail here as 'a' == NULL.
779 if (p->auth.auth_type != DCERPC_AUTH_TYPE_SPNEGO ||
780 p->auth.spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) {
781 DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n"));
782 goto err;
785 if (pauth_info->credentials.data[0] != ASN1_CONTEXT(1)) {
786 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n"));
787 goto err;
790 if (!spnego_parse_auth(talloc_tos(), pauth_info->credentials, &auth_blob)) {
791 DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n"));
792 goto err;
796 * The following call actually checks the challenge/response data.
797 * for correctness against the given DOMAIN\user name.
800 if (!pipe_ntlmssp_verify_final(p, &auth_blob)) {
801 goto err;
804 data_blob_free(&auth_blob);
806 /* Generate the spnego "accept completed" blob - no incoming data. */
807 *response = spnego_gen_auth_response(mem_ctx, &auth_reply, NT_STATUS_OK, OID_NTLMSSP);
809 data_blob_free(&auth_reply);
811 p->pipe_bound = True;
813 return True;
815 err:
817 data_blob_free(&auth_blob);
818 data_blob_free(&auth_reply);
820 free_pipe_auth_data(&p->auth);
822 return False;
825 /*******************************************************************
826 Handle an schannel bind auth.
827 *******************************************************************/
829 static bool pipe_schannel_auth_bind(struct pipes_struct *p,
830 TALLOC_CTX *mem_ctx,
831 struct dcerpc_auth *auth_info,
832 DATA_BLOB *response)
834 struct NL_AUTH_MESSAGE neg;
835 struct NL_AUTH_MESSAGE reply;
836 bool ret;
837 NTSTATUS status;
838 struct netlogon_creds_CredentialState *creds;
839 DATA_BLOB session_key;
840 enum ndr_err_code ndr_err;
842 ndr_err = ndr_pull_struct_blob(
843 &auth_info->credentials, mem_ctx, &neg,
844 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
845 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
846 DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n"));
847 return false;
850 if (DEBUGLEVEL >= 10) {
851 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &neg);
854 if (!(neg.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME)) {
855 DEBUG(0,("pipe_schannel_auth_bind: Did not receive netbios computer name\n"));
856 return false;
860 * The neg.oem_netbios_computer.a key here must match the remote computer name
861 * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe
862 * operations that use credentials.
865 become_root();
866 status = schannel_get_creds_state(p, lp_private_dir(),
867 neg.oem_netbios_computer.a, &creds);
868 unbecome_root();
870 if (!NT_STATUS_IS_OK(status)) {
871 DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n"));
872 return False;
875 p->auth.a_u.schannel_auth = talloc(p, struct schannel_state);
876 if (!p->auth.a_u.schannel_auth) {
877 TALLOC_FREE(creds);
878 return False;
881 p->auth.a_u.schannel_auth->state = SCHANNEL_STATE_START;
882 p->auth.a_u.schannel_auth->seq_num = 0;
883 p->auth.a_u.schannel_auth->initiator = false;
884 p->auth.a_u.schannel_auth->creds = creds;
887 * JRA. Should we also copy the schannel session key into the pipe session key p->session_key
888 * here ? We do that for NTLMSSP, but the session key is already set up from the vuser
889 * struct of the person who opened the pipe. I need to test this further. JRA.
891 * VL. As we are mapping this to guest set the generic key
892 * "SystemLibraryDTC" key here. It's a bit difficult to test against
893 * W2k3, as it does not allow schannel binds against SAMR and LSA
894 * anymore.
897 session_key = generic_session_key();
898 if (session_key.data == NULL) {
899 DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session"
900 " key\n"));
901 return false;
904 ret = server_info_set_session_key(p->server_info, session_key);
906 data_blob_free(&session_key);
908 if (!ret) {
909 DEBUG(0, ("server_info_set_session_key failed\n"));
910 return false;
913 /*** SCHANNEL verifier ***/
915 reply.MessageType = NL_NEGOTIATE_RESPONSE;
916 reply.Flags = 0;
917 reply.Buffer.dummy = 5; /* ??? actually I don't think
918 * this has any meaning
919 * here - gd */
921 ndr_err = ndr_push_struct_blob(response, mem_ctx, &reply,
922 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
923 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
924 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
925 return false;
928 if (DEBUGLEVEL >= 10) {
929 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &reply);
932 DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n",
933 neg.oem_netbios_domain.a, neg.oem_netbios_computer.a));
935 /* We're finished with this bind - no more packets. */
936 p->auth.auth_data_free_func = &free_pipe_schannel_auth_data;
937 p->auth.auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
939 p->pipe_bound = True;
941 return True;
944 /*******************************************************************
945 Handle an NTLMSSP bind auth.
946 *******************************************************************/
948 static bool pipe_ntlmssp_auth_bind(struct pipes_struct *p,
949 TALLOC_CTX *mem_ctx,
950 struct dcerpc_auth *auth_info,
951 DATA_BLOB *response)
953 NTSTATUS status;
954 struct auth_ntlmssp_state *a = NULL;
956 if (strncmp((char *)auth_info->credentials.data, "NTLMSSP", 7) != 0) {
957 DEBUG(0, ("Failed to read NTLMSSP in blob\n"));
958 goto err;
961 /* We have an NTLMSSP blob. */
962 status = auth_ntlmssp_start(&a);
963 if (!NT_STATUS_IS_OK(status)) {
964 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n",
965 nt_errstr(status) ));
966 goto err;
969 /* Clear flags, then set them according to requested Auth Level */
970 auth_ntlmssp_and_flags(a, ~(NTLMSSP_NEGOTIATE_SIGN |
971 NTLMSSP_NEGOTIATE_SEAL));
973 switch (auth_info->auth_level) {
974 case DCERPC_AUTH_LEVEL_INTEGRITY:
975 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN);
976 break;
977 case DCERPC_AUTH_LEVEL_PRIVACY:
978 /* Privacy always implies both sign and seal for ntlmssp */
979 auth_ntlmssp_or_flags(a, NTLMSSP_NEGOTIATE_SIGN |
980 NTLMSSP_NEGOTIATE_SEAL);
981 break;
982 default:
983 break;
986 status = auth_ntlmssp_update(a, auth_info->credentials, response);
987 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
988 DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n",
989 nt_errstr(status) ));
990 goto err;
993 /* Make sure data is bound to the memctx, to be freed the caller */
994 talloc_steal(mem_ctx, response->data);
996 p->auth.a_u.auth_ntlmssp_state = a;
997 p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data;
998 p->auth.auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
1000 DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n"));
1002 /* We can't set pipe_bound True yet - we need an DCERPC_PKT_AUTH3 response packet... */
1003 return True;
1005 err:
1007 TALLOC_FREE(a);
1008 return False;
1011 /*******************************************************************
1012 Handle a GSSAPI bind auth.
1013 *******************************************************************/
1015 static bool pipe_gssapi_auth_bind(struct pipes_struct *p,
1016 TALLOC_CTX *mem_ctx,
1017 struct dcerpc_auth *auth_info,
1018 DATA_BLOB *response)
1020 NTSTATUS status;
1021 struct gse_context *gse_ctx = NULL;
1023 /* Let's init the gssapi machinery for this connection */
1024 /* passing a NULL server name means the server will try
1025 * to accept any connection regardless of the name used as
1026 * long as it can find a decryption key */
1027 /* by passing NULL, the code will attempt to set a default
1028 * keytab based on configuration options */
1029 status = gse_init_server(p,
1030 DCERPC_AUTH_TYPE_KRB5,
1031 auth_info->auth_level,
1032 GSS_C_DCE_STYLE,
1033 NULL, NULL,
1034 &gse_ctx);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 DEBUG(0, ("Failed to init dcerpc gssapi server (%s)\n",
1037 nt_errstr(status)));
1038 goto err;
1041 status = gse_get_server_auth_token(mem_ctx, gse_ctx,
1042 &auth_info->credentials,
1043 response);
1044 if (!NT_STATUS_IS_OK(status)) {
1045 DEBUG(0, ("Failed to parse initial client token (%s)\n",
1046 nt_errstr(status)));
1047 goto err;
1050 p->auth.a_u.gssapi_state = gse_ctx;
1051 p->auth.auth_data_free_func = &free_pipe_gssapi_auth_data;
1052 p->auth.auth_type = DCERPC_AUTH_TYPE_KRB5;
1054 DEBUG(10, ("KRB5 auth started\n"));
1056 return true;
1058 err:
1059 TALLOC_FREE(gse_ctx);
1060 return false;
1063 static NTSTATUS finalize_gssapi_bind(TALLOC_CTX *mem_ctx,
1064 struct gse_context *gse_ctx,
1065 struct client_address *client_id,
1066 struct auth_serversupplied_info **sinfo)
1068 TALLOC_CTX *tmp_ctx;
1069 DATA_BLOB session_key;
1070 DATA_BLOB auth_data;
1071 DATA_BLOB pac;
1072 bool bret;
1073 NTSTATUS status;
1074 char *princ_name;
1075 time_t tgs_authtime;
1076 NTTIME tgs_authtime_nttime;
1077 struct PAC_DATA *pac_data;
1078 struct PAC_LOGON_NAME *logon_name = NULL;
1079 struct PAC_LOGON_INFO *logon_info = NULL;
1080 enum ndr_err_code ndr_err;
1081 unsigned int i;
1082 bool is_mapped;
1083 bool is_guest;
1084 char *ntuser;
1085 char *ntdomain;
1086 char *username;
1087 struct passwd *pw;
1088 struct auth_serversupplied_info *server_info;
1090 tmp_ctx = talloc_new(mem_ctx);
1091 if (!tmp_ctx) {
1092 return NT_STATUS_NO_MEMORY;
1095 /* Finally - if the pipe negotiated integrity (sign) or privacy (seal)
1096 ensure the underlying flags are also set. If not we should
1097 refuse the bind. */
1099 status = gse_verify_server_auth_flags(gse_ctx);
1100 if (!NT_STATUS_IS_OK(status)) {
1101 DEBUG(0, ("Requested Security Layers not honored!\n"));
1102 goto done;
1105 status = gse_get_authz_data(gse_ctx, tmp_ctx, &auth_data);
1106 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
1107 /* TODO: Fetch user by principal name ? */
1108 status = NT_STATUS_ACCESS_DENIED;
1109 goto done;
1111 if (!NT_STATUS_IS_OK(status)) {
1112 goto done;
1115 bret = unwrap_pac(tmp_ctx, &auth_data, &pac);
1116 if (!bret) {
1117 DEBUG(1, ("Failed to unwrap PAC\n"));
1118 status = NT_STATUS_ACCESS_DENIED;
1119 goto done;
1122 status = gse_get_client_name(gse_ctx, tmp_ctx, &princ_name);
1123 if (!NT_STATUS_IS_OK(status)) {
1124 goto done;
1127 status = gse_get_authtime(gse_ctx, &tgs_authtime);
1128 if (!NT_STATUS_IS_OK(status)) {
1129 goto done;
1131 unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime);
1133 pac_data = talloc_zero(tmp_ctx, struct PAC_DATA);
1134 if (!pac_data) {
1135 status = NT_STATUS_NO_MEMORY;
1136 goto done;
1139 ndr_err = ndr_pull_struct_blob(&pac, pac_data, pac_data,
1140 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
1141 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1142 DEBUG(1, ("Failed to parse the PAC for %s\n", princ_name));
1143 status = ndr_map_error2ntstatus(ndr_err);
1144 goto done;
1147 /* get logon name and logon info */
1148 for (i = 0; i < pac_data->num_buffers; i++) {
1149 struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
1151 switch (data_buf->type) {
1152 case PAC_TYPE_LOGON_INFO:
1153 if (!data_buf->info) {
1154 break;
1156 logon_info = data_buf->info->logon_info.info;
1157 break;
1158 case PAC_TYPE_LOGON_NAME:
1159 logon_name = &data_buf->info->logon_name;
1160 break;
1161 default:
1162 break;
1165 if (!logon_info) {
1166 DEBUG(1, ("Invalid PAC data, missing logon info!\n"));
1167 status = NT_STATUS_NOT_FOUND;
1168 goto done;
1170 if (!logon_name) {
1171 DEBUG(1, ("Invalid PAC data, missing logon info!\n"));
1172 status = NT_STATUS_NOT_FOUND;
1173 goto done;
1176 /* check time */
1177 if (tgs_authtime_nttime != logon_name->logon_time) {
1178 DEBUG(1, ("Logon time mismatch between ticket and PAC!\n"
1179 "PAC Time = %s | Ticket Time = %s\n",
1180 nt_time_string(tmp_ctx, logon_name->logon_time),
1181 nt_time_string(tmp_ctx, tgs_authtime_nttime)));
1182 status = NT_STATUS_ACCESS_DENIED;
1183 goto done;
1186 /* TODO: Should we check princ_name against account_name in
1187 * logon_name ? Are they supposed to be identical, or can an
1188 * account_name be different from the UPN ? */
1190 status = get_user_from_kerberos_info(talloc_tos(), client_id->name,
1191 princ_name, logon_info,
1192 &is_mapped, &is_guest,
1193 &ntuser, &ntdomain,
1194 &username, &pw);
1195 if (!NT_STATUS_IS_OK(status)) {
1196 DEBUG(1, ("Failed to map kerberos principal to system user "
1197 "(%s)\n", nt_errstr(status)));
1198 status = NT_STATUS_ACCESS_DENIED;
1199 goto done;
1202 /* TODO: save PAC data in netsamlogon cache ? */
1204 status = make_server_info_krb5(mem_ctx,
1205 ntuser, ntdomain, username, pw,
1206 logon_info, is_guest, &server_info);
1207 if (!NT_STATUS_IS_OK(status)) {
1208 DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
1209 nt_errstr(status)));
1210 status = NT_STATUS_ACCESS_DENIED;
1211 goto done;
1214 if (server_info->ptok == NULL) {
1215 status = create_local_token(server_info);
1216 if (!NT_STATUS_IS_OK(status)) {
1217 DEBUG(1, ("Failed to create local user token (%s)\n",
1218 nt_errstr(status)));
1219 status = NT_STATUS_ACCESS_DENIED;
1220 goto done;
1224 /* TODO: this is what the ntlmssp code does with the session_key,
1225 * probably need to be moved to an upper level as this will not apply
1226 * to tcp/ip connections */
1229 * We're an authenticated bind over smb, so the session key needs to
1230 * be set to "SystemLibraryDTC". Weird, but this is what Windows
1231 * does. See the RPC-SAMBA3SESSIONKEY.
1234 session_key = generic_session_key();
1235 if (session_key.data == NULL) {
1236 status = NT_STATUS_ACCESS_DENIED;
1237 goto done;
1240 bret = server_info_set_session_key(server_info, session_key);
1241 if (!bret) {
1242 status = NT_STATUS_ACCESS_DENIED;
1243 goto done;
1246 data_blob_free(&session_key);
1248 *sinfo = server_info;
1249 status = NT_STATUS_OK;
1251 done:
1252 TALLOC_FREE(tmp_ctx);
1253 return status;
1256 /*******************************************************************
1257 Process a KRB5 authentication response.
1258 If this function succeeds, the user has been authenticated
1259 and their domain, name and calling workstation stored in
1260 the pipe struct.
1261 *******************************************************************/
1263 static NTSTATUS pipe_gssapi_auth_bind_next(struct pipes_struct *p,
1264 TALLOC_CTX *mem_ctx,
1265 struct dcerpc_auth *pauth_info,
1266 DATA_BLOB *response)
1268 struct gse_context *gse_ctx = p->auth.a_u.gssapi_state;
1269 NTSTATUS status;
1271 DEBUG(5, (__location__ ": pipe %s checking user details\n",
1272 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1274 status = gse_get_server_auth_token(mem_ctx, gse_ctx,
1275 &pauth_info->credentials,
1276 response);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 data_blob_free(response);
1279 return status;
1282 if (gse_require_more_processing(gse_ctx)) {
1283 /* ask for next leg */
1284 return NT_STATUS_OK;
1287 status = finalize_gssapi_bind(p, gse_ctx,
1288 p->client_id, &p->server_info);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 DEBUG(1, ("gssapi bind failed with: %s", nt_errstr(status)));
1291 return NT_STATUS_ACCESS_DENIED;
1294 return NT_STATUS_OK;
1297 /*******************************************************************
1298 Respond to a pipe bind request.
1299 *******************************************************************/
1301 static bool api_pipe_bind_req(struct pipes_struct *p,
1302 struct ncacn_packet *pkt)
1304 struct dcerpc_auth auth_info;
1305 uint16 assoc_gid;
1306 unsigned int auth_type = DCERPC_AUTH_TYPE_NONE;
1307 NTSTATUS status;
1308 struct ndr_syntax_id id;
1309 union dcerpc_payload u;
1310 struct dcerpc_ack_ctx bind_ack_ctx;
1311 DATA_BLOB auth_resp = data_blob_null;
1312 DATA_BLOB auth_blob = data_blob_null;
1314 /* No rebinds on a bound pipe - use alter context. */
1315 if (p->pipe_bound) {
1316 DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound "
1317 "pipe %s.\n",
1318 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1319 return setup_bind_nak(p, pkt);
1322 if (pkt->u.bind.num_contexts == 0) {
1323 DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n"));
1324 goto err_exit;
1328 * Try and find the correct pipe name to ensure
1329 * that this is a pipe name we support.
1331 id = pkt->u.bind.ctx_list[0].abstract_syntax;
1332 if (rpc_srv_pipe_exists_by_id(&id)) {
1333 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1334 rpc_srv_get_pipe_cli_name(&id),
1335 rpc_srv_get_pipe_srv_name(&id)));
1336 } else {
1337 status = smb_probe_module(
1338 "rpc", get_pipe_name_from_syntax(
1339 talloc_tos(),
1340 &pkt->u.bind.ctx_list[0].abstract_syntax));
1342 if (NT_STATUS_IS_ERR(status)) {
1343 DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
1344 get_pipe_name_from_syntax(
1345 talloc_tos(),
1346 &pkt->u.bind.ctx_list[0].abstract_syntax)));
1348 return setup_bind_nak(p, pkt);
1351 if (rpc_srv_get_pipe_interface_by_cli_name(
1352 get_pipe_name_from_syntax(talloc_tos(),
1353 &p->syntax),
1354 &id)) {
1355 DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
1356 rpc_srv_get_pipe_cli_name(&id),
1357 rpc_srv_get_pipe_srv_name(&id)));
1358 } else {
1359 DEBUG(0, ("module %s doesn't provide functions for "
1360 "pipe %s!\n",
1361 get_pipe_name_from_syntax(talloc_tos(),
1362 &p->syntax),
1363 get_pipe_name_from_syntax(talloc_tos(),
1364 &p->syntax)));
1365 return setup_bind_nak(p, pkt);
1369 DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
1371 if (pkt->u.bind.assoc_group_id != 0) {
1372 assoc_gid = pkt->u.bind.assoc_group_id;
1373 } else {
1374 assoc_gid = 0x53f0;
1378 * Create the bind response struct.
1381 /* If the requested abstract synt uuid doesn't match our client pipe,
1382 reject the bind_ack & set the transfer interface synt to all 0's,
1383 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1384 unknown to NT4)
1385 Needed when adding entries to a DACL from NT5 - SK */
1387 if (check_bind_req(p,
1388 &pkt->u.bind.ctx_list[0].abstract_syntax,
1389 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1390 pkt->u.bind.ctx_list[0].context_id)) {
1392 bind_ack_ctx.result = 0;
1393 bind_ack_ctx.reason = 0;
1394 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1395 } else {
1396 p->pipe_bound = False;
1397 /* Rejection reason: abstract syntax not supported */
1398 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1399 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1400 bind_ack_ctx.syntax = null_ndr_syntax_id;
1404 * Check if this is an authenticated bind request.
1406 if (pkt->auth_length) {
1407 /* Quick length check. Won't catch a bad auth footer,
1408 * prevents overrun. */
1410 if (pkt->frag_length < RPC_HEADER_LEN +
1411 DCERPC_AUTH_TRAILER_LENGTH +
1412 pkt->auth_length) {
1413 DEBUG(0,("api_pipe_bind_req: auth_len (%u) "
1414 "too long for fragment %u.\n",
1415 (unsigned int)pkt->auth_length,
1416 (unsigned int)pkt->frag_length));
1417 goto err_exit;
1421 * Decode the authentication verifier.
1423 status = dcerpc_pull_dcerpc_auth(pkt,
1424 &pkt->u.bind.auth_info,
1425 &auth_info, p->endian);
1426 if (!NT_STATUS_IS_OK(status)) {
1427 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1428 goto err_exit;
1431 auth_type = auth_info.auth_type;
1433 /* Work out if we have to sign or seal etc. */
1434 switch (auth_info.auth_level) {
1435 case DCERPC_AUTH_LEVEL_INTEGRITY:
1436 p->auth.auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1437 break;
1438 case DCERPC_AUTH_LEVEL_PRIVACY:
1439 p->auth.auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1440 break;
1441 default:
1442 DEBUG(0, ("Unexpected auth level (%u).\n",
1443 (unsigned int)auth_info.auth_level ));
1444 goto err_exit;
1447 switch (auth_type) {
1448 case DCERPC_AUTH_TYPE_NTLMSSP:
1449 if (!pipe_ntlmssp_auth_bind(p, pkt,
1450 &auth_info, &auth_resp)) {
1451 goto err_exit;
1453 assoc_gid = 0x7a77;
1454 break;
1456 case DCERPC_AUTH_TYPE_SCHANNEL:
1457 if (!pipe_schannel_auth_bind(p, pkt,
1458 &auth_info, &auth_resp)) {
1459 goto err_exit;
1461 break;
1463 case DCERPC_AUTH_TYPE_SPNEGO:
1464 if (!pipe_spnego_auth_bind_negotiate(p, pkt,
1465 &auth_info, &auth_resp)) {
1466 goto err_exit;
1468 break;
1470 case DCERPC_AUTH_TYPE_KRB5:
1471 if (!pipe_gssapi_auth_bind(p, pkt,
1472 &auth_info, &auth_resp)) {
1473 goto err_exit;
1475 break;
1477 case DCERPC_AUTH_TYPE_NONE:
1478 break;
1480 default:
1481 DEBUG(0, ("Unknown auth type %x requested.\n", auth_type));
1482 goto err_exit;
1486 if (auth_type == DCERPC_AUTH_TYPE_NONE) {
1487 /* Unauthenticated bind request. */
1488 /* We're finished - no more packets. */
1489 p->auth.auth_type = DCERPC_AUTH_TYPE_NONE;
1490 p->auth.spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
1491 /* We must set the pipe auth_level here also. */
1492 p->auth.auth_level = DCERPC_AUTH_LEVEL_NONE;
1493 p->pipe_bound = True;
1494 /* The session key was initialized from the SMB
1495 * session in make_internal_rpc_pipe_p */
1498 ZERO_STRUCT(u.bind_ack);
1499 u.bind_ack.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1500 u.bind_ack.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1501 u.bind_ack.assoc_group_id = assoc_gid;
1503 /* name has to be \PIPE\xxxxx */
1504 u.bind_ack.secondary_address =
1505 talloc_asprintf(pkt, "\\PIPE\\%s",
1506 rpc_srv_get_pipe_srv_name(&id));
1507 if (!u.bind_ack.secondary_address) {
1508 DEBUG(0, ("Out of memory!\n"));
1509 goto err_exit;
1511 u.bind_ack.secondary_address_size =
1512 strlen(u.bind_ack.secondary_address) + 1;
1514 u.bind_ack.num_results = 1;
1515 u.bind_ack.ctx_list = &bind_ack_ctx;
1517 /* NOTE: We leave the auth_info empty so we can calculate the padding
1518 * later and then append the auth_info --simo */
1521 * Marshall directly into the outgoing PDU space. We
1522 * must do this as we need to set to the bind response
1523 * header and are never sending more than one PDU here.
1526 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1527 DCERPC_PKT_BIND_ACK,
1528 DCERPC_PFC_FLAG_FIRST |
1529 DCERPC_PFC_FLAG_LAST,
1530 auth_resp.length,
1531 pkt->call_id,
1533 &p->out_data.frag);
1534 if (!NT_STATUS_IS_OK(status)) {
1535 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1536 nt_errstr(status)));
1539 if (auth_resp.length) {
1541 status = dcerpc_push_dcerpc_auth(pkt,
1542 auth_type,
1543 auth_info.auth_level,
1545 1, /* auth_context_id */
1546 &auth_resp,
1547 &auth_blob);
1548 if (!NT_STATUS_IS_OK(status)) {
1549 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1550 goto err_exit;
1554 /* Now that we have the auth len store it into the right place in
1555 * the dcerpc header */
1556 dcerpc_set_frag_length(&p->out_data.frag,
1557 p->out_data.frag.length + auth_blob.length);
1559 if (auth_blob.length) {
1561 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1562 auth_blob.data, auth_blob.length)) {
1563 DEBUG(0, ("Append of auth info failed.\n"));
1564 goto err_exit;
1569 * Setup the lengths for the initial reply.
1572 p->out_data.data_sent_length = 0;
1573 p->out_data.current_pdu_sent = 0;
1575 TALLOC_FREE(auth_blob.data);
1576 return True;
1578 err_exit:
1580 data_blob_free(&p->out_data.frag);
1581 TALLOC_FREE(auth_blob.data);
1582 return setup_bind_nak(p, pkt);
1585 /****************************************************************************
1586 Deal with an alter context call. Can be third part of 3 leg auth request for
1587 SPNEGO calls.
1588 ****************************************************************************/
1590 static bool api_pipe_alter_context(struct pipes_struct *p,
1591 struct ncacn_packet *pkt)
1593 struct dcerpc_auth auth_info;
1594 uint16 assoc_gid;
1595 NTSTATUS status;
1596 union dcerpc_payload u;
1597 struct dcerpc_ack_ctx bind_ack_ctx;
1598 DATA_BLOB auth_resp = data_blob_null;
1599 DATA_BLOB auth_blob = data_blob_null;
1600 int pad_len = 0;
1602 DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__));
1604 if (pkt->u.bind.assoc_group_id != 0) {
1605 assoc_gid = pkt->u.bind.assoc_group_id;
1606 } else {
1607 assoc_gid = 0x53f0;
1611 * Create the bind response struct.
1614 /* If the requested abstract synt uuid doesn't match our client pipe,
1615 reject the bind_ack & set the transfer interface synt to all 0's,
1616 ver 0 (observed when NT5 attempts to bind to abstract interfaces
1617 unknown to NT4)
1618 Needed when adding entries to a DACL from NT5 - SK */
1620 if (check_bind_req(p,
1621 &pkt->u.bind.ctx_list[0].abstract_syntax,
1622 &pkt->u.bind.ctx_list[0].transfer_syntaxes[0],
1623 pkt->u.bind.ctx_list[0].context_id)) {
1625 bind_ack_ctx.result = 0;
1626 bind_ack_ctx.reason = 0;
1627 bind_ack_ctx.syntax = pkt->u.bind.ctx_list[0].transfer_syntaxes[0];
1628 } else {
1629 p->pipe_bound = False;
1630 /* Rejection reason: abstract syntax not supported */
1631 bind_ack_ctx.result = DCERPC_BIND_PROVIDER_REJECT;
1632 bind_ack_ctx.reason = DCERPC_BIND_REASON_ASYNTAX;
1633 bind_ack_ctx.syntax = null_ndr_syntax_id;
1637 * Check if this is an authenticated alter context request.
1639 if (pkt->auth_length) {
1640 /* Quick length check. Won't catch a bad auth footer,
1641 * prevents overrun. */
1643 if (pkt->frag_length < RPC_HEADER_LEN +
1644 DCERPC_AUTH_TRAILER_LENGTH +
1645 pkt->auth_length) {
1646 DEBUG(0,("api_pipe_alter_context: auth_len (%u) "
1647 "too long for fragment %u.\n",
1648 (unsigned int)pkt->auth_length,
1649 (unsigned int)pkt->frag_length ));
1650 goto err_exit;
1653 status = dcerpc_pull_dcerpc_auth(pkt,
1654 &pkt->u.bind.auth_info,
1655 &auth_info, p->endian);
1656 if (!NT_STATUS_IS_OK(status)) {
1657 DEBUG(0, ("Unable to unmarshall dcerpc_auth.\n"));
1658 goto err_exit;
1661 /* We can only finish if the pipe is unbound for now */
1662 if (p->pipe_bound) {
1663 DEBUG(0, (__location__ ": Pipe already bound, "
1664 "Altering Context not yet supported!\n"));
1665 goto err_exit;
1668 switch (auth_info.auth_type) {
1669 case DCERPC_AUTH_TYPE_SPNEGO:
1670 if (!pipe_spnego_auth_bind_continue(p, pkt,
1671 &auth_info,
1672 &auth_resp)) {
1673 goto err_exit;
1675 break;
1677 case DCERPC_AUTH_TYPE_KRB5:
1678 status = pipe_gssapi_auth_bind_next(p, pkt,
1679 &auth_info,
1680 &auth_resp);
1681 if (!NT_STATUS_IS_OK(status)) {
1682 goto err_exit;
1684 break;
1686 default:
1687 DEBUG(3, (__location__ ": Usupported auth type (%d) "
1688 "in alter-context call\n",
1689 auth_info.auth_type));
1690 goto err_exit;
1694 ZERO_STRUCT(u.alter_resp);
1695 u.alter_resp.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1696 u.alter_resp.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1697 u.alter_resp.assoc_group_id = assoc_gid;
1699 /* secondary address CAN be NULL
1700 * as the specs say it's ignored.
1701 * It MUST be NULL to have the spoolss working.
1703 u.alter_resp.secondary_address = "";
1704 u.alter_resp.secondary_address_size = 1;
1706 u.alter_resp.num_results = 1;
1707 u.alter_resp.ctx_list = &bind_ack_ctx;
1709 /* NOTE: We leave the auth_info empty so we can calculate the padding
1710 * later and then append the auth_info --simo */
1713 * Marshall directly into the outgoing PDU space. We
1714 * must do this as we need to set to the bind response
1715 * header and are never sending more than one PDU here.
1718 status = dcerpc_push_ncacn_packet(p->mem_ctx,
1719 DCERPC_PKT_ALTER_RESP,
1720 DCERPC_PFC_FLAG_FIRST |
1721 DCERPC_PFC_FLAG_LAST,
1722 auth_resp.length,
1723 pkt->call_id,
1725 &p->out_data.frag);
1726 if (!NT_STATUS_IS_OK(status)) {
1727 DEBUG(0, ("Failed to marshall bind_ack packet. (%s)\n",
1728 nt_errstr(status)));
1731 if (auth_resp.length) {
1733 /* Work out any padding needed before the auth footer. */
1734 pad_len = p->out_data.frag.length % SERVER_NDR_PADDING_SIZE;
1735 if (pad_len) {
1736 pad_len = SERVER_NDR_PADDING_SIZE - pad_len;
1737 DEBUG(10, ("auth pad_len = %u\n",
1738 (unsigned int)pad_len));
1741 status = dcerpc_push_dcerpc_auth(pkt,
1742 auth_info.auth_type,
1743 auth_info.auth_level,
1744 pad_len,
1745 1, /* auth_context_id */
1746 &auth_resp,
1747 &auth_blob);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 DEBUG(0, ("Marshalling of dcerpc_auth failed.\n"));
1750 goto err_exit;
1754 /* Now that we have the auth len store it into the right place in
1755 * the dcerpc header */
1756 dcerpc_set_frag_length(&p->out_data.frag,
1757 p->out_data.frag.length +
1758 pad_len + auth_blob.length);
1760 if (auth_resp.length) {
1761 if (pad_len) {
1762 char pad[SERVER_NDR_PADDING_SIZE];
1763 memset(pad, '\0', SERVER_NDR_PADDING_SIZE);
1764 if (!data_blob_append(p->mem_ctx,
1765 &p->out_data.frag,
1766 pad, pad_len)) {
1767 DEBUG(0, ("api_pipe_bind_req: failed to add "
1768 "%u bytes of pad data.\n",
1769 (unsigned int)pad_len));
1770 goto err_exit;
1774 if (!data_blob_append(p->mem_ctx, &p->out_data.frag,
1775 auth_blob.data, auth_blob.length)) {
1776 DEBUG(0, ("Append of auth info failed.\n"));
1777 goto err_exit;
1782 * Setup the lengths for the initial reply.
1785 p->out_data.data_sent_length = 0;
1786 p->out_data.current_pdu_sent = 0;
1788 TALLOC_FREE(auth_blob.data);
1789 return True;
1791 err_exit:
1793 data_blob_free(&p->out_data.frag);
1794 TALLOC_FREE(auth_blob.data);
1795 return setup_bind_nak(p, pkt);
1798 /****************************************************************************
1799 Find the set of RPC functions associated with this context_id
1800 ****************************************************************************/
1802 static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
1804 PIPE_RPC_FNS *fns = NULL;
1806 if ( !list ) {
1807 DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
1808 return NULL;
1811 for (fns=list; fns; fns=fns->next ) {
1812 if ( fns->context_id == context_id )
1813 return fns;
1815 return NULL;
1818 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1819 const struct api_struct *api_rpc_cmds, int n_cmds);
1821 /****************************************************************************
1822 Find the correct RPC function to call for this request.
1823 If the pipe is authenticated then become the correct UNIX user
1824 before doing the call.
1825 ****************************************************************************/
1827 static bool api_pipe_request(struct pipes_struct *p,
1828 struct ncacn_packet *pkt)
1830 bool ret = False;
1831 bool changed_user = False;
1832 PIPE_RPC_FNS *pipe_fns;
1834 if (p->pipe_bound &&
1835 ((p->auth.auth_type == DCERPC_AUTH_TYPE_NTLMSSP) ||
1836 ((p->auth.auth_type == DCERPC_AUTH_TYPE_SPNEGO) &&
1837 (p->auth.spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)))) {
1838 if(!become_authenticated_pipe_user(p)) {
1839 data_blob_free(&p->out_data.rdata);
1840 return False;
1842 changed_user = True;
1845 DEBUG(5, ("Requested \\PIPE\\%s\n",
1846 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1848 /* get the set of RPC functions for this context */
1850 pipe_fns = find_pipe_fns_by_context(p->contexts,
1851 pkt->u.request.context_id);
1853 if ( pipe_fns ) {
1854 TALLOC_CTX *frame = talloc_stackframe();
1855 ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds);
1856 TALLOC_FREE(frame);
1858 else {
1859 DEBUG(0, ("No rpc function table associated with context "
1860 "[%d] on pipe [%s]\n",
1861 pkt->u.request.context_id,
1862 get_pipe_name_from_syntax(talloc_tos(),
1863 &p->syntax)));
1866 if (changed_user) {
1867 unbecome_authenticated_pipe_user();
1870 return ret;
1873 /*******************************************************************
1874 Calls the underlying RPC function for a named pipe.
1875 ********************************************************************/
1877 static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
1878 const struct api_struct *api_rpc_cmds, int n_cmds)
1880 int fn_num;
1881 uint32_t offset1;
1883 /* interpret the command */
1884 DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
1885 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1886 pkt->u.request.opnum));
1888 if (DEBUGLEVEL >= 50) {
1889 fstring name;
1890 slprintf(name, sizeof(name)-1, "in_%s",
1891 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1892 dump_pdu_region(name, pkt->u.request.opnum,
1893 &p->in_data.data, 0,
1894 p->in_data.data.length);
1897 for (fn_num = 0; fn_num < n_cmds; fn_num++) {
1898 if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
1899 api_rpc_cmds[fn_num].fn != NULL) {
1900 DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
1901 api_rpc_cmds[fn_num].name));
1902 break;
1906 if (fn_num == n_cmds) {
1908 * For an unknown RPC just return a fault PDU but
1909 * return True to allow RPC's on the pipe to continue
1910 * and not put the pipe into fault state. JRA.
1912 DEBUG(4, ("unknown\n"));
1913 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1914 return True;
1917 offset1 = p->out_data.rdata.length;
1919 DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
1920 fn_num, api_rpc_cmds[fn_num].fn));
1921 /* do the actual command */
1922 if(!api_rpc_cmds[fn_num].fn(p)) {
1923 DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
1924 get_pipe_name_from_syntax(talloc_tos(), &p->syntax),
1925 api_rpc_cmds[fn_num].name));
1926 data_blob_free(&p->out_data.rdata);
1927 return False;
1930 if (p->bad_handle_fault_state) {
1931 DEBUG(4,("api_rpcTNP: bad handle fault return.\n"));
1932 p->bad_handle_fault_state = False;
1933 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH));
1934 return True;
1937 if (p->rng_fault_state) {
1938 DEBUG(4, ("api_rpcTNP: rng fault return\n"));
1939 p->rng_fault_state = False;
1940 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
1941 return True;
1944 if (DEBUGLEVEL >= 50) {
1945 fstring name;
1946 slprintf(name, sizeof(name)-1, "out_%s",
1947 get_pipe_name_from_syntax(talloc_tos(), &p->syntax));
1948 dump_pdu_region(name, pkt->u.request.opnum,
1949 &p->out_data.rdata, offset1,
1950 p->out_data.rdata.length);
1953 DEBUG(5,("api_rpcTNP: called %s successfully\n",
1954 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
1956 /* Check for buffer underflow in rpc parsing */
1957 if ((DEBUGLEVEL >= 10) &&
1958 (pkt->frag_length < p->in_data.data.length)) {
1959 DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
1960 dump_data(10, p->in_data.data.data + pkt->frag_length,
1961 p->in_data.data.length - pkt->frag_length);
1964 return True;
1967 /****************************************************************************
1968 Initialise an outgoing packet.
1969 ****************************************************************************/
1971 static bool pipe_init_outgoing_data(struct pipes_struct *p)
1973 output_data *o_data = &p->out_data;
1975 /* Reset the offset counters. */
1976 o_data->data_sent_length = 0;
1977 o_data->current_pdu_sent = 0;
1979 data_blob_free(&o_data->frag);
1981 /* Free any memory in the current return data buffer. */
1982 data_blob_free(&o_data->rdata);
1984 return True;
1987 /****************************************************************************
1988 Sets the fault state on incoming packets.
1989 ****************************************************************************/
1991 void set_incoming_fault(struct pipes_struct *p)
1993 data_blob_free(&p->in_data.data);
1994 p->in_data.pdu_needed_len = 0;
1995 p->in_data.pdu.length = 0;
1996 p->fault_state = True;
1997 DEBUG(10, ("set_incoming_fault: Setting fault state on pipe %s\n",
1998 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
2001 static NTSTATUS dcesrv_auth_request(struct pipe_auth_data *auth,
2002 struct ncacn_packet *pkt,
2003 DATA_BLOB *raw_pkt)
2005 NTSTATUS status;
2006 size_t hdr_size = DCERPC_REQUEST_LENGTH;
2007 size_t pad_len;
2009 DEBUG(10, ("Checking request auth.\n"));
2011 if (pkt->pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2012 hdr_size += 16;
2015 /* in case of sealing this function will unseal the data in place */
2016 status = dcerpc_check_auth(auth, pkt,
2017 &pkt->u.request.stub_and_verifier,
2018 hdr_size, raw_pkt,
2019 &pad_len);
2020 if (!NT_STATUS_IS_OK(status)) {
2021 return status;
2025 /* remove padding and auth trailer,
2026 * this way the caller will get just the data */
2027 if (pkt->auth_length) {
2028 size_t trail_len = pad_len
2029 + DCERPC_AUTH_TRAILER_LENGTH
2030 + pkt->auth_length;
2031 if (pkt->u.request.stub_and_verifier.length < trail_len) {
2032 return NT_STATUS_INFO_LENGTH_MISMATCH;
2034 pkt->u.request.stub_and_verifier.length -= trail_len;
2037 return NT_STATUS_OK;
2040 /****************************************************************************
2041 Processes a request pdu. This will do auth processing if needed, and
2042 appends the data into the complete stream if the LAST flag is not set.
2043 ****************************************************************************/
2045 static bool process_request_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
2047 NTSTATUS status;
2048 DATA_BLOB data;
2050 if (!p->pipe_bound) {
2051 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
2052 set_incoming_fault(p);
2053 return False;
2056 /* Store the opnum */
2057 p->opnum = pkt->u.request.opnum;
2059 status = dcesrv_auth_request(&p->auth, pkt, &p->in_data.pdu);
2060 if (!NT_STATUS_IS_OK(status)) {
2061 DEBUG(0, ("Failed to check packet auth. (%s)\n",
2062 nt_errstr(status)));
2063 set_incoming_fault(p);
2064 return false;
2067 data = pkt->u.request.stub_and_verifier;
2070 * Check the data length doesn't go over the 15Mb limit.
2071 * increased after observing a bug in the Windows NT 4.0 SP6a
2072 * spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
2073 * will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
2076 if (p->in_data.data.length + data.length > MAX_RPC_DATA_SIZE) {
2077 DEBUG(0, ("process_request_pdu: "
2078 "rpc data buffer too large (%u) + (%u)\n",
2079 (unsigned int)p->in_data.data.length,
2080 (unsigned int)data.length));
2081 set_incoming_fault(p);
2082 return False;
2086 * Append the data portion into the buffer and return.
2089 if (data.length) {
2090 if (!data_blob_append(p->mem_ctx, &p->in_data.data,
2091 data.data, data.length)) {
2092 DEBUG(0, ("Unable to append data size %u "
2093 "to parse buffer of size %u.\n",
2094 (unsigned int)data.length,
2095 (unsigned int)p->in_data.data.length));
2096 set_incoming_fault(p);
2097 return False;
2101 if (pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
2102 bool ret = False;
2104 * Ok - we finally have a complete RPC stream.
2105 * Call the rpc command to process it.
2109 * Process the complete data stream here.
2111 if (pipe_init_outgoing_data(p)) {
2112 ret = api_pipe_request(p, pkt);
2115 return ret;
2118 return True;
2121 /****************************************************************************
2122 Processes a finished PDU stored in p->in_data.pdu.
2123 ****************************************************************************/
2125 void process_complete_pdu(struct pipes_struct *p)
2127 struct ncacn_packet *pkt = NULL;
2128 NTSTATUS status;
2129 bool reply = False;
2131 if(p->fault_state) {
2132 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
2133 get_pipe_name_from_syntax(talloc_tos(), &p->syntax)));
2134 goto done;
2137 pkt = talloc(p->mem_ctx, struct ncacn_packet);
2138 if (!pkt) {
2139 DEBUG(0, ("Out of memory!\n"));
2140 goto done;
2144 * Ensure we're using the corrent endianness for both the
2145 * RPC header flags and the raw data we will be reading from.
2147 if (dcerpc_get_endian_flag(&p->in_data.pdu) & DCERPC_DREP_LE) {
2148 p->endian = RPC_LITTLE_ENDIAN;
2149 } else {
2150 p->endian = RPC_BIG_ENDIAN;
2152 DEBUG(10, ("PDU is in %s Endian format!\n", p->endian?"Big":"Little"));
2154 status = dcerpc_pull_ncacn_packet(pkt, &p->in_data.pdu,
2155 pkt, p->endian);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 DEBUG(0, ("Failed to unmarshal rpc packet: %s!\n",
2158 nt_errstr(status)));
2159 goto done;
2162 /* Store the call_id */
2163 p->call_id = pkt->call_id;
2165 DEBUG(10, ("Processing packet type %d\n", (int)pkt->ptype));
2167 switch (pkt->ptype) {
2168 case DCERPC_PKT_REQUEST:
2169 reply = process_request_pdu(p, pkt);
2170 break;
2172 case DCERPC_PKT_PING: /* CL request - ignore... */
2173 DEBUG(0, ("process_complete_pdu: Error. "
2174 "Connectionless packet type %d received on "
2175 "pipe %s.\n", (int)pkt->ptype,
2176 get_pipe_name_from_syntax(talloc_tos(),
2177 &p->syntax)));
2178 break;
2180 case DCERPC_PKT_RESPONSE: /* No responses here. */
2181 DEBUG(0, ("process_complete_pdu: Error. "
2182 "DCERPC_PKT_RESPONSE received from client "
2183 "on pipe %s.\n",
2184 get_pipe_name_from_syntax(talloc_tos(),
2185 &p->syntax)));
2186 break;
2188 case DCERPC_PKT_FAULT:
2189 case DCERPC_PKT_WORKING:
2190 /* CL request - reply to a ping when a call in process. */
2191 case DCERPC_PKT_NOCALL:
2192 /* CL - server reply to a ping call. */
2193 case DCERPC_PKT_REJECT:
2194 case DCERPC_PKT_ACK:
2195 case DCERPC_PKT_CL_CANCEL:
2196 case DCERPC_PKT_FACK:
2197 case DCERPC_PKT_CANCEL_ACK:
2198 DEBUG(0, ("process_complete_pdu: Error. "
2199 "Connectionless packet type %u received on "
2200 "pipe %s.\n", (unsigned int)pkt->ptype,
2201 get_pipe_name_from_syntax(talloc_tos(),
2202 &p->syntax)));
2203 break;
2205 case DCERPC_PKT_BIND:
2207 * We assume that a pipe bind is only in one pdu.
2209 if (pipe_init_outgoing_data(p)) {
2210 reply = api_pipe_bind_req(p, pkt);
2212 break;
2214 case DCERPC_PKT_BIND_ACK:
2215 case DCERPC_PKT_BIND_NAK:
2216 DEBUG(0, ("process_complete_pdu: Error. "
2217 "DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
2218 "packet type %u received on pipe %s.\n",
2219 (unsigned int)pkt->ptype,
2220 get_pipe_name_from_syntax(talloc_tos(),
2221 &p->syntax)));
2222 break;
2225 case DCERPC_PKT_ALTER:
2227 * We assume that a pipe bind is only in one pdu.
2229 if (pipe_init_outgoing_data(p)) {
2230 reply = api_pipe_alter_context(p, pkt);
2232 break;
2234 case DCERPC_PKT_ALTER_RESP:
2235 DEBUG(0, ("process_complete_pdu: Error. "
2236 "DCERPC_PKT_ALTER_RESP on pipe %s: "
2237 "Should only be server -> client.\n",
2238 get_pipe_name_from_syntax(talloc_tos(),
2239 &p->syntax)));
2240 break;
2242 case DCERPC_PKT_AUTH3:
2244 * The third packet in an auth exchange.
2246 if (pipe_init_outgoing_data(p)) {
2247 reply = api_pipe_bind_auth3(p, pkt);
2249 break;
2251 case DCERPC_PKT_SHUTDOWN:
2252 DEBUG(0, ("process_complete_pdu: Error. "
2253 "DCERPC_PKT_SHUTDOWN on pipe %s: "
2254 "Should only be server -> client.\n",
2255 get_pipe_name_from_syntax(talloc_tos(),
2256 &p->syntax)));
2257 break;
2259 case DCERPC_PKT_CO_CANCEL:
2260 /* For now just free all client data and continue
2261 * processing. */
2262 DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
2263 " Abandoning rpc call.\n"));
2264 /* As we never do asynchronous RPC serving, we can
2265 * never cancel a call (as far as I know).
2266 * If we ever did we'd have to send a cancel_ack reply.
2267 * For now, just free all client data and continue
2268 * processing. */
2269 reply = True;
2270 break;
2272 #if 0
2273 /* Enable this if we're doing async rpc. */
2274 /* We must check the outstanding callid matches. */
2275 if (pipe_init_outgoing_data(p)) {
2276 /* Send a cancel_ack PDU reply. */
2277 /* We should probably check the auth-verifier here. */
2278 reply = setup_cancel_ack_reply(p, pkt);
2280 break;
2281 #endif
2283 case DCERPC_PKT_ORPHANED:
2284 /* We should probably check the auth-verifier here.
2285 * For now just free all client data and continue
2286 * processing. */
2287 DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
2288 " Abandoning rpc call.\n"));
2289 reply = True;
2290 break;
2292 default:
2293 DEBUG(0, ("process_complete_pdu: "
2294 "Unknown rpc type = %u received.\n",
2295 (unsigned int)pkt->ptype));
2296 break;
2299 done:
2300 if (!reply) {
2301 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
2302 "pipe %s\n", get_pipe_name_from_syntax(talloc_tos(),
2303 &p->syntax)));
2304 set_incoming_fault(p);
2305 setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
2306 TALLOC_FREE(pkt);
2307 } else {
2309 * Reset the lengths. We're ready for a new pdu.
2311 TALLOC_FREE(p->in_data.pdu.data);
2312 p->in_data.pdu_needed_len = 0;
2313 p->in_data.pdu.length = 0;
2316 TALLOC_FREE(pkt);