2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
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/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_lsa.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../librpc/gen_ndr/ndr_samr.h"
26 #include "../librpc/gen_ndr/ndr_netlogon.h"
27 #include "../librpc/gen_ndr/ndr_srvsvc.h"
28 #include "../librpc/gen_ndr/ndr_wkssvc.h"
29 #include "../librpc/gen_ndr/ndr_winreg.h"
30 #include "../librpc/gen_ndr/ndr_spoolss.h"
31 #include "../librpc/gen_ndr/ndr_dfs.h"
32 #include "../librpc/gen_ndr/ndr_echo.h"
33 #include "../librpc/gen_ndr/ndr_initshutdown.h"
34 #include "../librpc/gen_ndr/ndr_svcctl.h"
35 #include "../librpc/gen_ndr/ndr_eventlog.h"
36 #include "../librpc/gen_ndr/ndr_ntsvcs.h"
37 #include "../librpc/gen_ndr/ndr_epmapper.h"
38 #include "../librpc/gen_ndr/ndr_drsuapi.h"
39 #include "../libcli/auth/schannel.h"
40 #include "../libcli/auth/spnego.h"
42 #include "../libcli/auth/ntlmssp.h"
43 #include "rpc_client/cli_netlogon.h"
44 #include "librpc/gen_ndr/ndr_dcerpc.h"
45 #include "librpc/rpc/dcerpc.h"
48 #define DBGC_CLASS DBGC_RPC_CLI
50 static const char *get_pipe_name_from_iface(
51 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
54 const struct ndr_interface_string_array *ep = interface->endpoints;
57 for (i=0; i<ep->count; i++) {
58 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
67 * extract the pipe name without \\pipe from for example
68 * ncacn_np:[\\pipe\\epmapper]
70 p = strchr(ep->names[i]+15, ']');
74 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
77 static const struct ndr_interface_table **interfaces;
79 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
81 int num_interfaces = talloc_array_length(interfaces);
82 const struct ndr_interface_table **tmp;
85 for (i=0; i<num_interfaces; i++) {
86 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
87 &interface->syntax_id)) {
92 tmp = talloc_realloc(NULL, interfaces,
93 const struct ndr_interface_table *,
96 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
100 interfaces[num_interfaces] = interface;
104 static bool initialize_interfaces(void)
106 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
109 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
112 if (!smb_register_ndr_interface(&ndr_table_samr)) {
115 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
118 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
121 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
124 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
127 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
130 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
133 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
136 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
139 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
142 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
145 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
148 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
151 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
157 const struct ndr_interface_table *get_iface_from_syntax(
158 const struct ndr_syntax_id *syntax)
163 if (interfaces == NULL) {
164 if (!initialize_interfaces()) {
168 num_interfaces = talloc_array_length(interfaces);
170 for (i=0; i<num_interfaces; i++) {
171 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
172 return interfaces[i];
179 /****************************************************************************
180 Return the pipe name from the interface.
181 ****************************************************************************/
183 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
184 const struct ndr_syntax_id *syntax)
186 const struct ndr_interface_table *interface;
190 interface = get_iface_from_syntax(syntax);
191 if (interface != NULL) {
192 result = get_pipe_name_from_iface(mem_ctx, interface);
193 if (result != NULL) {
199 * Here we should ask \\epmapper, but for now our code is only
200 * interested in the known pipes mentioned in pipe_names[]
203 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
204 if (guid_str == NULL) {
207 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
208 (int)syntax->if_version);
209 TALLOC_FREE(guid_str);
211 if (result == NULL) {
217 /********************************************************************
218 Map internal value to wire value.
219 ********************************************************************/
221 enum dcerpc_AuthType map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
225 case PIPE_AUTH_TYPE_NONE:
226 return DCERPC_AUTH_TYPE_NONE;
228 case PIPE_AUTH_TYPE_NTLMSSP:
229 return DCERPC_AUTH_TYPE_NTLMSSP;
231 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
232 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
233 return DCERPC_AUTH_TYPE_SPNEGO;
235 case PIPE_AUTH_TYPE_SCHANNEL:
236 return DCERPC_AUTH_TYPE_SCHANNEL;
238 case PIPE_AUTH_TYPE_KRB5:
239 return DCERPC_AUTH_TYPE_KRB5;
242 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
244 (unsigned int)auth_type ));
250 /********************************************************************
251 Pipe description for a DEBUG
252 ********************************************************************/
253 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
254 struct rpc_pipe_client *cli)
256 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
257 if (result == NULL) {
263 /********************************************************************
265 ********************************************************************/
267 static uint32 get_rpc_call_id(void)
269 static uint32 call_id = 0;
273 /*******************************************************************
274 Use SMBreadX to get rest of one fragment's worth of rpc data.
275 Reads the whole size or give an error message
276 ********************************************************************/
278 struct rpc_read_state {
279 struct event_context *ev;
280 struct rpc_cli_transport *transport;
286 static void rpc_read_done(struct tevent_req *subreq);
288 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
289 struct event_context *ev,
290 struct rpc_cli_transport *transport,
291 uint8_t *data, size_t size)
293 struct tevent_req *req, *subreq;
294 struct rpc_read_state *state;
296 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
301 state->transport = transport;
306 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
308 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
310 if (subreq == NULL) {
313 tevent_req_set_callback(subreq, rpc_read_done, req);
321 static void rpc_read_done(struct tevent_req *subreq)
323 struct tevent_req *req = tevent_req_callback_data(
324 subreq, struct tevent_req);
325 struct rpc_read_state *state = tevent_req_data(
326 req, struct rpc_read_state);
330 status = state->transport->read_recv(subreq, &received);
332 if (!NT_STATUS_IS_OK(status)) {
333 tevent_req_nterror(req, status);
337 state->num_read += received;
338 if (state->num_read == state->size) {
339 tevent_req_done(req);
343 subreq = state->transport->read_send(state, state->ev,
344 state->data + state->num_read,
345 state->size - state->num_read,
346 state->transport->priv);
347 if (tevent_req_nomem(subreq, req)) {
350 tevent_req_set_callback(subreq, rpc_read_done, req);
353 static NTSTATUS rpc_read_recv(struct tevent_req *req)
355 return tevent_req_simple_recv_ntstatus(req);
358 struct rpc_write_state {
359 struct event_context *ev;
360 struct rpc_cli_transport *transport;
366 static void rpc_write_done(struct tevent_req *subreq);
368 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
369 struct event_context *ev,
370 struct rpc_cli_transport *transport,
371 const uint8_t *data, size_t size)
373 struct tevent_req *req, *subreq;
374 struct rpc_write_state *state;
376 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
381 state->transport = transport;
384 state->num_written = 0;
386 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
388 subreq = transport->write_send(state, ev, data, size, transport->priv);
389 if (subreq == NULL) {
392 tevent_req_set_callback(subreq, rpc_write_done, req);
399 static void rpc_write_done(struct tevent_req *subreq)
401 struct tevent_req *req = tevent_req_callback_data(
402 subreq, struct tevent_req);
403 struct rpc_write_state *state = tevent_req_data(
404 req, struct rpc_write_state);
408 status = state->transport->write_recv(subreq, &written);
410 if (!NT_STATUS_IS_OK(status)) {
411 tevent_req_nterror(req, status);
415 state->num_written += written;
417 if (state->num_written == state->size) {
418 tevent_req_done(req);
422 subreq = state->transport->write_send(state, state->ev,
423 state->data + state->num_written,
424 state->size - state->num_written,
425 state->transport->priv);
426 if (tevent_req_nomem(subreq, req)) {
429 tevent_req_set_callback(subreq, rpc_write_done, req);
432 static NTSTATUS rpc_write_recv(struct tevent_req *req)
434 return tevent_req_simple_recv_ntstatus(req);
438 /****************************************************************************
439 Try and get a PDU's worth of data from current_pdu. If not, then read more
441 ****************************************************************************/
443 struct get_complete_frag_state {
444 struct event_context *ev;
445 struct rpc_pipe_client *cli;
450 static void get_complete_frag_got_header(struct tevent_req *subreq);
451 static void get_complete_frag_got_rest(struct tevent_req *subreq);
453 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
454 struct event_context *ev,
455 struct rpc_pipe_client *cli,
458 struct tevent_req *req, *subreq;
459 struct get_complete_frag_state *state;
463 req = tevent_req_create(mem_ctx, &state,
464 struct get_complete_frag_state);
470 state->frag_len = RPC_HEADER_LEN;
473 received = pdu->length;
474 if (received < RPC_HEADER_LEN) {
475 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
476 status = NT_STATUS_NO_MEMORY;
479 subreq = rpc_read_send(state, state->ev,
480 state->cli->transport,
481 pdu->data + received,
482 RPC_HEADER_LEN - received);
483 if (subreq == NULL) {
484 status = NT_STATUS_NO_MEMORY;
487 tevent_req_set_callback(subreq, get_complete_frag_got_header,
492 state->frag_len = dcerpc_get_frag_length(pdu);
495 * Ensure we have frag_len bytes of data.
497 if (received < state->frag_len) {
498 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
499 status = NT_STATUS_NO_MEMORY;
502 subreq = rpc_read_send(state, state->ev,
503 state->cli->transport,
504 pdu->data + received,
505 state->frag_len - received);
506 if (subreq == NULL) {
507 status = NT_STATUS_NO_MEMORY;
510 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
515 status = NT_STATUS_OK;
517 if (NT_STATUS_IS_OK(status)) {
518 tevent_req_done(req);
520 tevent_req_nterror(req, status);
522 return tevent_req_post(req, ev);
525 static void get_complete_frag_got_header(struct tevent_req *subreq)
527 struct tevent_req *req = tevent_req_callback_data(
528 subreq, struct tevent_req);
529 struct get_complete_frag_state *state = tevent_req_data(
530 req, struct get_complete_frag_state);
533 status = rpc_read_recv(subreq);
535 if (!NT_STATUS_IS_OK(status)) {
536 tevent_req_nterror(req, status);
540 state->frag_len = dcerpc_get_frag_length(state->pdu);
542 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
543 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
548 * We're here in this piece of code because we've read exactly
549 * RPC_HEADER_LEN bytes into state->pdu.
552 subreq = rpc_read_send(state, state->ev, state->cli->transport,
553 state->pdu->data + RPC_HEADER_LEN,
554 state->frag_len - RPC_HEADER_LEN);
555 if (tevent_req_nomem(subreq, req)) {
558 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
561 static void get_complete_frag_got_rest(struct tevent_req *subreq)
563 struct tevent_req *req = tevent_req_callback_data(
564 subreq, struct tevent_req);
567 status = rpc_read_recv(subreq);
569 if (!NT_STATUS_IS_OK(status)) {
570 tevent_req_nterror(req, status);
573 tevent_req_done(req);
576 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
578 return tevent_req_simple_recv_ntstatus(req);
581 /****************************************************************************
582 NTLMSSP specific sign/seal.
583 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
584 In fact I should probably abstract these into identical pieces of code... JRA.
585 ****************************************************************************/
587 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
588 struct ncacn_packet *pkt,
590 uint8 *p_ss_padding_len)
592 struct dcerpc_auth auth_info;
596 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
597 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
601 if (!cli->auth->a_u.ntlmssp_state) {
602 return NT_STATUS_INVALID_PARAMETER;
605 /* Ensure there's enough data for an authenticated response. */
606 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
607 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
608 + DCERPC_AUTH_TRAILER_LENGTH
609 + pkt->auth_length)) {
610 DEBUG(0, ("auth_len %u is too long.\n",
611 (unsigned int)pkt->auth_length));
612 return NT_STATUS_BUFFER_TOO_SMALL;
615 /* get the auth blob at the end of the packet */
616 blob = data_blob_const(pdu->data + pkt->frag_length
617 - DCERPC_AUTH_TRAILER_LENGTH
619 DCERPC_AUTH_TRAILER_LENGTH
622 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
623 if (!NT_STATUS_IS_OK(status)) {
624 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
628 /* Ensure auth_pad_len fits into the packet. */
629 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
630 + auth_info.auth_pad_length
631 + DCERPC_AUTH_TRAILER_LENGTH
632 + pkt->auth_length) {
633 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
634 "too large (%u), auth_len (%u), frag_len = (%u).\n",
635 (unsigned int)auth_info.auth_pad_length,
636 (unsigned int)pkt->auth_length,
637 (unsigned int)pkt->frag_length));
638 return NT_STATUS_BUFFER_TOO_SMALL;
642 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
643 * after the RPC header.
644 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
645 * functions as NTLMv2 checks the rpc headers also.
648 switch (cli->auth->auth_level) {
649 case DCERPC_AUTH_LEVEL_PRIVACY:
650 /* Data is encrypted. */
651 status = ntlmssp_unseal_packet(
652 cli->auth->a_u.ntlmssp_state,
653 pdu->data + DCERPC_RESPONSE_LENGTH,
655 - DCERPC_RESPONSE_LENGTH
656 - DCERPC_AUTH_TRAILER_LENGTH
659 pkt->frag_length - pkt->auth_length,
660 &auth_info.credentials);
661 if (!NT_STATUS_IS_OK(status)) {
662 DEBUG(0, ("failed to unseal packet from %s."
664 rpccli_pipe_txt(talloc_tos(), cli),
670 case DCERPC_AUTH_LEVEL_INTEGRITY:
671 /* Data is signed. */
672 status = ntlmssp_check_packet(
673 cli->auth->a_u.ntlmssp_state,
674 pdu->data + DCERPC_RESPONSE_LENGTH,
676 - DCERPC_RESPONSE_LENGTH
677 - DCERPC_AUTH_TRAILER_LENGTH
680 pkt->frag_length - pkt->auth_length,
681 &auth_info.credentials);
682 if (!NT_STATUS_IS_OK(status)) {
683 DEBUG(0, ("check signing failed on packet from %s."
685 rpccli_pipe_txt(talloc_tos(), cli),
692 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
693 "auth level %d\n", cli->auth->auth_level));
694 return NT_STATUS_INVALID_INFO_CLASS;
698 * Remember the padding length. We must remove it from the real data
699 * stream once the sign/seal is done.
702 *p_ss_padding_len = auth_info.auth_pad_length;
707 /****************************************************************************
708 schannel specific sign/seal.
709 ****************************************************************************/
711 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
712 struct ncacn_packet *pkt,
714 uint8 *p_ss_padding_len)
716 struct dcerpc_auth auth_info;
720 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
721 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
725 if (pkt->auth_length < SCHANNEL_SIG_SIZE) {
726 DEBUG(0, ("auth_len %u.\n", (unsigned int)pkt->auth_length));
727 return NT_STATUS_INVALID_PARAMETER;
730 if (!cli->auth->a_u.schannel_auth) {
731 return NT_STATUS_INVALID_PARAMETER;
734 /* Ensure there's enough data for an authenticated response. */
735 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
736 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
737 + DCERPC_AUTH_TRAILER_LENGTH
738 + pkt->auth_length)) {
739 DEBUG(0, ("auth_len %u is too long.\n",
740 (unsigned int)pkt->auth_length));
741 return NT_STATUS_INVALID_PARAMETER;
744 /* get the auth blob at the end of the packet */
745 blob = data_blob_const(pdu->data + pkt->frag_length
746 - DCERPC_AUTH_TRAILER_LENGTH
748 DCERPC_AUTH_TRAILER_LENGTH
752 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
753 if (!NT_STATUS_IS_OK(status)) {
754 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
758 /* Ensure auth_pad_len fits into the packet. */
759 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
760 + auth_info.auth_pad_length
761 + DCERPC_AUTH_TRAILER_LENGTH
762 + pkt->auth_length) {
763 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
764 "too large (%u), auth_len (%u), frag_len = (%u).\n",
765 (unsigned int)auth_info.auth_pad_length,
766 (unsigned int)pkt->auth_length,
767 (unsigned int)pkt->frag_length));
768 return NT_STATUS_BUFFER_TOO_SMALL;
771 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
772 DEBUG(0, ("Invalid auth info %d on schannel\n",
773 auth_info.auth_type));
774 return NT_STATUS_BUFFER_TOO_SMALL;
777 if (DEBUGLEVEL >= 10) {
778 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_info.credentials);
781 switch (cli->auth->auth_level) {
782 case DCERPC_AUTH_LEVEL_PRIVACY:
783 status = netsec_incoming_packet(
784 cli->auth->a_u.schannel_auth,
787 pdu->data + DCERPC_RESPONSE_LENGTH,
789 - DCERPC_RESPONSE_LENGTH
790 - DCERPC_AUTH_TRAILER_LENGTH
792 &auth_info.credentials);
794 case DCERPC_AUTH_LEVEL_INTEGRITY:
795 status = netsec_incoming_packet(
796 cli->auth->a_u.schannel_auth,
799 pdu->data + DCERPC_RESPONSE_LENGTH,
801 - DCERPC_RESPONSE_LENGTH
802 - DCERPC_AUTH_TRAILER_LENGTH
804 &auth_info.credentials);
807 status = NT_STATUS_INTERNAL_ERROR;
811 if (!NT_STATUS_IS_OK(status)) {
812 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
813 "Connection to %s (%s).\n",
814 rpccli_pipe_txt(talloc_tos(), cli),
816 return NT_STATUS_INVALID_PARAMETER;
820 * Remember the padding length. We must remove it from the real data
821 * stream once the sign/seal is done.
824 *p_ss_padding_len = auth_info.auth_pad_length;
829 /****************************************************************************
830 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
831 ****************************************************************************/
833 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
834 struct ncacn_packet *pkt,
836 uint8 *p_ss_padding_len)
838 NTSTATUS ret = NT_STATUS_OK;
840 /* Paranioa checks for auth_len. */
841 if (pkt->auth_length) {
842 if (pkt->auth_length > pkt->frag_length) {
843 return NT_STATUS_INVALID_PARAMETER;
846 if ((pkt->auth_length
847 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
848 < pkt->auth_length) ||
850 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
851 < (unsigned int)DCERPC_AUTH_TRAILER_LENGTH)) {
852 /* Integer wrap attempt. */
853 return NT_STATUS_INVALID_PARAMETER;
858 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
861 switch(cli->auth->auth_type) {
862 case PIPE_AUTH_TYPE_NONE:
863 if (pkt->auth_length) {
864 DEBUG(3, ("cli_pipe_validate_rpc_response: "
865 "Connection to %s - got non-zero "
867 rpccli_pipe_txt(talloc_tos(), cli),
868 (unsigned int)pkt->auth_length));
869 return NT_STATUS_INVALID_PARAMETER;
873 case PIPE_AUTH_TYPE_NTLMSSP:
874 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
875 ret = cli_pipe_verify_ntlmssp(cli, pkt, pdu,
877 if (!NT_STATUS_IS_OK(ret)) {
882 case PIPE_AUTH_TYPE_SCHANNEL:
883 ret = cli_pipe_verify_schannel(cli, pkt, pdu,
885 if (!NT_STATUS_IS_OK(ret)) {
890 case PIPE_AUTH_TYPE_KRB5:
891 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
893 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
894 "to %s - unknown internal auth type %u.\n",
895 rpccli_pipe_txt(talloc_tos(), cli),
896 cli->auth->auth_type ));
897 return NT_STATUS_INVALID_INFO_CLASS;
903 /****************************************************************************
904 Do basic authentication checks on an incoming pdu.
905 ****************************************************************************/
907 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
908 struct rpc_pipe_client *cli,
909 struct ncacn_packet *pkt,
911 uint8_t expected_pkt_type,
913 DATA_BLOB *reply_pdu)
915 NTSTATUS ret = NT_STATUS_OK;
916 uint8 ss_padding_len = 0;
918 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt);
919 if (!NT_STATUS_IS_OK(ret)) {
923 if (pdu->length != pkt->frag_length) {
924 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
925 (unsigned int)pdu->length,
926 (unsigned int)pkt->frag_length));
927 return NT_STATUS_INVALID_PARAMETER;
931 * Point the return values at the real data including the RPC
932 * header. Just in case the caller wants it.
936 /* Ensure we have the correct type. */
937 switch (pkt->ptype) {
938 case DCERPC_PKT_ALTER_RESP:
939 case DCERPC_PKT_BIND_ACK:
941 /* Alter context and bind ack share the same packet definitions. */
945 case DCERPC_PKT_RESPONSE:
947 /* Here's where we deal with incoming sign/seal. */
948 ret = cli_pipe_validate_rpc_response(cli, pkt, pdu,
950 if (!NT_STATUS_IS_OK(ret)) {
954 /* Point the return values at the NDR data.
955 * Remember to remove any ss padding. */
956 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
958 if (pdu->length < DCERPC_RESPONSE_LENGTH + ss_padding_len) {
959 return NT_STATUS_BUFFER_TOO_SMALL;
962 rdata->length = pdu->length
963 - DCERPC_RESPONSE_LENGTH
966 /* Remember to remove the auth footer. */
967 if (pkt->auth_length) {
968 /* We've already done integer wrap tests on auth_len in
969 cli_pipe_validate_rpc_response(). */
970 if (rdata->length < DCERPC_AUTH_TRAILER_LENGTH
971 + pkt->auth_length) {
972 return NT_STATUS_BUFFER_TOO_SMALL;
974 rdata->length -= (DCERPC_AUTH_TRAILER_LENGTH
978 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
979 pdu->length, rdata->length, ss_padding_len));
982 * If this is the first reply, and the allocation hint is
983 * reasonable, try and set up the reply_pdu DATA_BLOB to the
987 if ((reply_pdu->length == 0) &&
988 pkt->u.response.alloc_hint &&
989 (pkt->u.response.alloc_hint < 15*1024*1024)) {
990 if (!data_blob_realloc(mem_ctx, reply_pdu,
991 pkt->u.response.alloc_hint)) {
992 DEBUG(0, ("reply alloc hint %d too "
993 "large to allocate\n",
994 (int)pkt->u.response.alloc_hint));
995 return NT_STATUS_NO_MEMORY;
1001 case DCERPC_PKT_BIND_NAK:
1002 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1003 "received from %s!\n",
1004 rpccli_pipe_txt(talloc_tos(), cli)));
1005 /* Use this for now... */
1006 return NT_STATUS_NETWORK_ACCESS_DENIED;
1008 case DCERPC_PKT_FAULT:
1010 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1011 "code %s received from %s!\n",
1012 dcerpc_errstr(talloc_tos(),
1013 pkt->u.fault.status),
1014 rpccli_pipe_txt(talloc_tos(), cli)));
1016 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
1017 return NT_STATUS_UNSUCCESSFUL;
1019 return NT_STATUS(pkt->u.fault.status);
1023 DEBUG(0, ("Unknown packet type %u received from %s!\n",
1024 (unsigned int)pkt->ptype,
1025 rpccli_pipe_txt(talloc_tos(), cli)));
1026 return NT_STATUS_INVALID_INFO_CLASS;
1029 if (pkt->ptype != expected_pkt_type) {
1030 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1031 "got an unexpected RPC packet type - %u, not %u\n",
1032 rpccli_pipe_txt(talloc_tos(), cli),
1034 expected_pkt_type));
1035 return NT_STATUS_INVALID_INFO_CLASS;
1038 /* Do this just before return - we don't want to modify any rpc header
1039 data before now as we may have needed to do cryptographic actions on
1042 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
1043 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1044 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1045 "setting fragment first/last ON.\n"));
1046 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
1047 DCERPC_PFC_FLAG_LAST;
1050 return NT_STATUS_OK;
1053 /****************************************************************************
1054 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1055 ****************************************************************************/
1057 struct cli_api_pipe_state {
1058 struct event_context *ev;
1059 struct rpc_cli_transport *transport;
1064 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1065 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1066 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1068 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1069 struct event_context *ev,
1070 struct rpc_cli_transport *transport,
1071 uint8_t *data, size_t data_len,
1072 uint32_t max_rdata_len)
1074 struct tevent_req *req, *subreq;
1075 struct cli_api_pipe_state *state;
1078 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1083 state->transport = transport;
1085 if (max_rdata_len < RPC_HEADER_LEN) {
1087 * For a RPC reply we always need at least RPC_HEADER_LEN
1088 * bytes. We check this here because we will receive
1089 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1091 status = NT_STATUS_INVALID_PARAMETER;
1095 if (transport->trans_send != NULL) {
1096 subreq = transport->trans_send(state, ev, data, data_len,
1097 max_rdata_len, transport->priv);
1098 if (subreq == NULL) {
1101 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1106 * If the transport does not provide a "trans" routine, i.e. for
1107 * example the ncacn_ip_tcp transport, do the write/read step here.
1110 subreq = rpc_write_send(state, ev, transport, data, data_len);
1111 if (subreq == NULL) {
1114 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1118 tevent_req_nterror(req, status);
1119 return tevent_req_post(req, ev);
1125 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1127 struct tevent_req *req = tevent_req_callback_data(
1128 subreq, struct tevent_req);
1129 struct cli_api_pipe_state *state = tevent_req_data(
1130 req, struct cli_api_pipe_state);
1133 status = state->transport->trans_recv(subreq, state, &state->rdata,
1135 TALLOC_FREE(subreq);
1136 if (!NT_STATUS_IS_OK(status)) {
1137 tevent_req_nterror(req, status);
1140 tevent_req_done(req);
1143 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1145 struct tevent_req *req = tevent_req_callback_data(
1146 subreq, struct tevent_req);
1147 struct cli_api_pipe_state *state = tevent_req_data(
1148 req, struct cli_api_pipe_state);
1151 status = rpc_write_recv(subreq);
1152 TALLOC_FREE(subreq);
1153 if (!NT_STATUS_IS_OK(status)) {
1154 tevent_req_nterror(req, status);
1158 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1159 if (tevent_req_nomem(state->rdata, req)) {
1164 * We don't need to use rpc_read_send here, the upper layer will cope
1165 * with a short read, transport->trans_send could also return less
1166 * than state->max_rdata_len.
1168 subreq = state->transport->read_send(state, state->ev, state->rdata,
1170 state->transport->priv);
1171 if (tevent_req_nomem(subreq, req)) {
1174 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1177 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1179 struct tevent_req *req = tevent_req_callback_data(
1180 subreq, struct tevent_req);
1181 struct cli_api_pipe_state *state = tevent_req_data(
1182 req, struct cli_api_pipe_state);
1186 status = state->transport->read_recv(subreq, &received);
1187 TALLOC_FREE(subreq);
1188 if (!NT_STATUS_IS_OK(status)) {
1189 tevent_req_nterror(req, status);
1192 state->rdata_len = received;
1193 tevent_req_done(req);
1196 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1197 uint8_t **prdata, uint32_t *prdata_len)
1199 struct cli_api_pipe_state *state = tevent_req_data(
1200 req, struct cli_api_pipe_state);
1203 if (tevent_req_is_nterror(req, &status)) {
1207 *prdata = talloc_move(mem_ctx, &state->rdata);
1208 *prdata_len = state->rdata_len;
1209 return NT_STATUS_OK;
1212 /****************************************************************************
1213 Send data on an rpc pipe via trans. The prs_struct data must be the last
1214 pdu fragment of an NDR data stream.
1216 Receive response data from an rpc pipe, which may be large...
1218 Read the first fragment: unfortunately have to use SMBtrans for the first
1219 bit, then SMBreadX for subsequent bits.
1221 If first fragment received also wasn't the last fragment, continue
1222 getting fragments until we _do_ receive the last fragment.
1224 Request/Response PDU's look like the following...
1226 |<------------------PDU len----------------------------------------------->|
1227 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1229 +------------+-----------------+-------------+---------------+-------------+
1230 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1231 +------------+-----------------+-------------+---------------+-------------+
1233 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1234 signing & sealing being negotiated.
1236 ****************************************************************************/
1238 struct rpc_api_pipe_state {
1239 struct event_context *ev;
1240 struct rpc_pipe_client *cli;
1241 uint8_t expected_pkt_type;
1243 DATA_BLOB incoming_frag;
1244 struct ncacn_packet *pkt;
1246 /* Incoming reply */
1247 DATA_BLOB reply_pdu;
1248 size_t reply_pdu_offset;
1252 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1253 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1255 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1256 struct event_context *ev,
1257 struct rpc_pipe_client *cli,
1258 prs_struct *data, /* Outgoing PDU */
1259 uint8_t expected_pkt_type)
1261 struct tevent_req *req, *subreq;
1262 struct rpc_api_pipe_state *state;
1263 uint16_t max_recv_frag;
1266 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1272 state->expected_pkt_type = expected_pkt_type;
1273 state->incoming_frag = data_blob_null;
1274 state->reply_pdu = data_blob_null;
1275 state->reply_pdu_offset = 0;
1276 state->endianess = DCERPC_DREP_LE;
1279 * Ensure we're not sending too much.
1281 if (prs_offset(data) > cli->max_xmit_frag) {
1282 status = NT_STATUS_INVALID_PARAMETER;
1286 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1288 /* get the header first, then fetch the rest once we have
1289 * the frag_length available */
1290 max_recv_frag = RPC_HEADER_LEN;
1292 subreq = cli_api_pipe_send(state, ev, cli->transport,
1293 (uint8_t *)prs_data_p(data),
1294 prs_offset(data), max_recv_frag);
1295 if (subreq == NULL) {
1298 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1302 tevent_req_nterror(req, status);
1303 return tevent_req_post(req, ev);
1309 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1311 struct tevent_req *req = tevent_req_callback_data(
1312 subreq, struct tevent_req);
1313 struct rpc_api_pipe_state *state = tevent_req_data(
1314 req, struct rpc_api_pipe_state);
1316 uint8_t *rdata = NULL;
1317 uint32_t rdata_len = 0;
1319 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1320 TALLOC_FREE(subreq);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1323 tevent_req_nterror(req, status);
1327 if (rdata == NULL) {
1328 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1329 rpccli_pipe_txt(talloc_tos(), state->cli)));
1330 tevent_req_done(req);
1335 * Move data on state->incoming_frag.
1337 state->incoming_frag.data = talloc_move(state, &rdata);
1338 state->incoming_frag.length = rdata_len;
1339 if (!state->incoming_frag.data) {
1340 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1344 /* Ensure we have enough data for a pdu. */
1345 subreq = get_complete_frag_send(state, state->ev, state->cli,
1346 &state->incoming_frag);
1347 if (tevent_req_nomem(subreq, req)) {
1350 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1353 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1355 struct tevent_req *req = tevent_req_callback_data(
1356 subreq, struct tevent_req);
1357 struct rpc_api_pipe_state *state = tevent_req_data(
1358 req, struct rpc_api_pipe_state);
1360 DATA_BLOB rdata = data_blob_null;
1362 status = get_complete_frag_recv(subreq);
1363 TALLOC_FREE(subreq);
1364 if (!NT_STATUS_IS_OK(status)) {
1365 DEBUG(5, ("get_complete_frag failed: %s\n",
1366 nt_errstr(status)));
1367 tevent_req_nterror(req, status);
1371 state->pkt = talloc(state, struct ncacn_packet);
1373 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1377 status = cli_pipe_validate_current_pdu(state,
1378 state->cli, state->pkt,
1379 &state->incoming_frag,
1380 state->expected_pkt_type,
1384 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1385 (unsigned)state->incoming_frag.length,
1386 (unsigned)state->reply_pdu_offset,
1387 nt_errstr(status)));
1389 if (!NT_STATUS_IS_OK(status)) {
1390 tevent_req_nterror(req, status);
1394 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1395 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
1397 * Set the data type correctly for big-endian data on the
1400 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1402 rpccli_pipe_txt(talloc_tos(), state->cli)));
1403 state->endianess = 0x00; /* BIG ENDIAN */
1406 * Check endianness on subsequent packets.
1408 if (state->endianess != state->pkt->drep[0]) {
1409 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1411 state->endianess?"little":"big",
1412 state->pkt->drep[0]?"little":"big"));
1413 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1417 /* Now copy the data portion out of the pdu into rbuf. */
1418 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1419 if (!data_blob_realloc(NULL, &state->reply_pdu,
1420 state->reply_pdu_offset + rdata.length)) {
1421 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1426 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1427 rdata.data, rdata.length);
1428 state->reply_pdu_offset += rdata.length;
1430 /* reset state->incoming_frag, there is no need to free it,
1431 * it will be reallocated to the right size the next time
1433 state->incoming_frag.length = 0;
1435 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1436 /* make sure the pdu length is right now that we
1437 * have all the data available (alloc hint may
1438 * have allocated more than was actually used) */
1439 state->reply_pdu.length = state->reply_pdu_offset;
1440 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1441 rpccli_pipe_txt(talloc_tos(), state->cli),
1442 (unsigned)state->reply_pdu.length));
1443 tevent_req_done(req);
1447 subreq = get_complete_frag_send(state, state->ev, state->cli,
1448 &state->incoming_frag);
1449 if (tevent_req_nomem(subreq, req)) {
1452 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1455 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1456 struct ncacn_packet **pkt,
1457 DATA_BLOB *reply_pdu)
1459 struct rpc_api_pipe_state *state = tevent_req_data(
1460 req, struct rpc_api_pipe_state);
1463 if (tevent_req_is_nterror(req, &status)) {
1467 /* return data to caller and assign it ownership of memory */
1469 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1470 reply_pdu->length = state->reply_pdu.length;
1471 state->reply_pdu.length = 0;
1473 data_blob_free(&state->reply_pdu);
1477 *pkt = talloc_steal(mem_ctx, state->pkt);
1480 return NT_STATUS_OK;
1483 /*******************************************************************
1484 Creates krb5 auth bind.
1485 ********************************************************************/
1487 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1488 enum dcerpc_AuthLevel auth_level,
1489 DATA_BLOB *auth_info)
1494 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1495 DATA_BLOB tkt = data_blob_null;
1496 DATA_BLOB tkt_wrapped = data_blob_null;
1498 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1499 a->service_principal ));
1501 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1503 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1504 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1507 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1509 a->service_principal,
1510 error_message(ret) ));
1512 data_blob_free(&tkt);
1513 return NT_STATUS_INVALID_PARAMETER;
1516 /* wrap that up in a nice GSS-API wrapping */
1517 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1519 data_blob_free(&tkt);
1521 status = dcerpc_push_dcerpc_auth(cli,
1522 DCERPC_AUTH_TYPE_KRB5,
1524 0, /* auth_pad_length */
1525 1, /* auth_context_id */
1528 if (!NT_STATUS_IS_OK(status)) {
1529 data_blob_free(&tkt_wrapped);
1533 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1534 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1536 return NT_STATUS_OK;
1538 return NT_STATUS_INVALID_PARAMETER;
1542 /*******************************************************************
1543 Creates SPNEGO NTLMSSP auth bind.
1544 ********************************************************************/
1546 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1547 enum dcerpc_AuthLevel auth_level,
1548 DATA_BLOB *auth_info)
1551 DATA_BLOB null_blob = data_blob_null;
1552 DATA_BLOB request = data_blob_null;
1553 DATA_BLOB spnego_msg = data_blob_null;
1555 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1556 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1560 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1561 data_blob_free(&request);
1565 /* Wrap this in SPNEGO. */
1566 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1568 data_blob_free(&request);
1570 status = dcerpc_push_dcerpc_auth(cli,
1571 DCERPC_AUTH_TYPE_SPNEGO,
1573 0, /* auth_pad_length */
1574 1, /* auth_context_id */
1577 if (!NT_STATUS_IS_OK(status)) {
1578 data_blob_free(&spnego_msg);
1582 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1583 dump_data(5, spnego_msg.data, spnego_msg.length);
1585 return NT_STATUS_OK;
1588 /*******************************************************************
1589 Creates NTLMSSP auth bind.
1590 ********************************************************************/
1592 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1593 enum dcerpc_AuthLevel auth_level,
1594 DATA_BLOB *auth_info)
1597 DATA_BLOB null_blob = data_blob_null;
1598 DATA_BLOB request = data_blob_null;
1600 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1601 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1605 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1606 data_blob_free(&request);
1610 status = dcerpc_push_dcerpc_auth(cli,
1611 DCERPC_AUTH_TYPE_NTLMSSP,
1613 0, /* auth_pad_length */
1614 1, /* auth_context_id */
1617 if (!NT_STATUS_IS_OK(status)) {
1618 data_blob_free(&request);
1622 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1623 dump_data(5, request.data, request.length);
1625 return NT_STATUS_OK;
1628 /*******************************************************************
1629 Creates schannel auth bind.
1630 ********************************************************************/
1632 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1633 enum dcerpc_AuthLevel auth_level,
1634 DATA_BLOB *auth_info)
1637 struct NL_AUTH_MESSAGE r;
1638 DATA_BLOB schannel_blob;
1640 /* Use lp_workgroup() if domain not specified */
1642 if (!cli->auth->domain || !cli->auth->domain[0]) {
1643 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1644 if (cli->auth->domain == NULL) {
1645 return NT_STATUS_NO_MEMORY;
1650 * Now marshall the data into the auth parse_struct.
1653 r.MessageType = NL_NEGOTIATE_REQUEST;
1654 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1655 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1656 r.oem_netbios_domain.a = cli->auth->domain;
1657 r.oem_netbios_computer.a = global_myname();
1659 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1660 if (!NT_STATUS_IS_OK(status)) {
1664 status = dcerpc_push_dcerpc_auth(cli,
1665 DCERPC_AUTH_TYPE_SCHANNEL,
1667 0, /* auth_pad_length */
1668 1, /* auth_context_id */
1671 if (!NT_STATUS_IS_OK(status)) {
1675 return NT_STATUS_OK;
1678 /*******************************************************************
1679 Creates the internals of a DCE/RPC bind request or alter context PDU.
1680 ********************************************************************/
1682 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
1683 prs_struct *rpc_out,
1685 const struct ndr_syntax_id *abstract,
1686 const struct ndr_syntax_id *transfer,
1687 const DATA_BLOB *auth_info)
1689 uint16 auth_len = auth_info->length;
1691 union dcerpc_payload u;
1693 struct dcerpc_ctx_list ctx_list;
1696 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1699 ctx_list.context_id = 0;
1700 ctx_list.num_transfer_syntaxes = 1;
1701 ctx_list.abstract_syntax = *abstract;
1702 ctx_list.transfer_syntaxes = discard_const(transfer);
1704 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1705 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1706 u.bind.assoc_group_id = 0x0;
1707 u.bind.num_contexts = 1;
1708 u.bind.ctx_list = &ctx_list;
1709 u.bind.auth_info = *auth_info;
1711 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
1713 DCERPC_PFC_FLAG_FIRST |
1714 DCERPC_PFC_FLAG_LAST,
1719 if (!NT_STATUS_IS_OK(status)) {
1720 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1724 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
1725 return NT_STATUS_NO_MEMORY;
1728 return NT_STATUS_OK;
1731 /*******************************************************************
1732 Creates a DCE/RPC bind request.
1733 ********************************************************************/
1735 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1736 prs_struct *rpc_out,
1738 const struct ndr_syntax_id *abstract,
1739 const struct ndr_syntax_id *transfer,
1740 enum pipe_auth_type auth_type,
1741 enum dcerpc_AuthLevel auth_level)
1743 DATA_BLOB auth_info = data_blob_null;
1744 NTSTATUS ret = NT_STATUS_OK;
1746 switch (auth_type) {
1747 case PIPE_AUTH_TYPE_SCHANNEL:
1748 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
1749 if (!NT_STATUS_IS_OK(ret)) {
1754 case PIPE_AUTH_TYPE_NTLMSSP:
1755 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1756 if (!NT_STATUS_IS_OK(ret)) {
1761 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1762 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1763 if (!NT_STATUS_IS_OK(ret)) {
1768 case PIPE_AUTH_TYPE_KRB5:
1769 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
1770 if (!NT_STATUS_IS_OK(ret)) {
1775 case PIPE_AUTH_TYPE_NONE:
1779 /* "Can't" happen. */
1780 return NT_STATUS_INVALID_INFO_CLASS;
1783 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1792 /*******************************************************************
1793 Create and add the NTLMSSP sign/seal auth header and data.
1794 ********************************************************************/
1796 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1797 uint32 ss_padding_len,
1798 prs_struct *rpc_out)
1800 DATA_BLOB auth_info;
1802 DATA_BLOB auth_blob = data_blob_null;
1803 uint16_t data_and_pad_len = prs_offset(rpc_out)
1804 - DCERPC_RESPONSE_LENGTH;
1806 if (!cli->auth->a_u.ntlmssp_state) {
1807 return NT_STATUS_INVALID_PARAMETER;
1810 /* marshall the dcerpc_auth with an actually empty auth_blob.
1811 * this is needed because the ntmlssp signature includes the
1813 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
1814 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1815 cli->auth->auth_level,
1817 1 /* context id. */,
1820 if (!NT_STATUS_IS_OK(status)) {
1824 /* append the header */
1825 if (!prs_copy_data_in(rpc_out,
1826 (char *)auth_info.data,
1827 auth_info.length)) {
1828 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1829 (unsigned int)auth_info.length));
1830 return NT_STATUS_NO_MEMORY;
1833 switch (cli->auth->auth_level) {
1834 case DCERPC_AUTH_LEVEL_PRIVACY:
1835 /* Data portion is encrypted. */
1836 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1837 prs_get_mem_context(rpc_out),
1838 (unsigned char *)prs_data_p(rpc_out)
1839 + DCERPC_RESPONSE_LENGTH,
1841 (unsigned char *)prs_data_p(rpc_out),
1842 (size_t)prs_offset(rpc_out),
1844 if (!NT_STATUS_IS_OK(status)) {
1849 case DCERPC_AUTH_LEVEL_INTEGRITY:
1850 /* Data is signed. */
1851 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1852 prs_get_mem_context(rpc_out),
1853 (unsigned char *)prs_data_p(rpc_out)
1854 + DCERPC_RESPONSE_LENGTH,
1856 (unsigned char *)prs_data_p(rpc_out),
1857 (size_t)prs_offset(rpc_out),
1859 if (!NT_STATUS_IS_OK(status)) {
1866 smb_panic("bad auth level");
1868 return NT_STATUS_INVALID_PARAMETER;
1871 /* Finally attach the blob. */
1872 if (!prs_copy_data_in(rpc_out,
1873 (char *)auth_blob.data,
1874 auth_blob.length)) {
1875 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1876 (unsigned int)auth_info.length));
1877 return NT_STATUS_NO_MEMORY;
1880 return NT_STATUS_OK;
1883 /*******************************************************************
1884 Create and add the schannel sign/seal auth header and data.
1885 ********************************************************************/
1887 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1888 uint32 ss_padding_len,
1889 prs_struct *rpc_out)
1891 DATA_BLOB auth_info;
1892 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
1893 char *data_p = prs_data_p(rpc_out) + DCERPC_RESPONSE_LENGTH;
1894 size_t data_and_pad_len = prs_offset(rpc_out)
1895 - DCERPC_RESPONSE_LENGTH;
1900 return NT_STATUS_INVALID_PARAMETER;
1903 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1906 switch (cli->auth->auth_level) {
1907 case DCERPC_AUTH_LEVEL_PRIVACY:
1908 status = netsec_outgoing_packet(sas,
1915 case DCERPC_AUTH_LEVEL_INTEGRITY:
1916 status = netsec_outgoing_packet(sas,
1924 status = NT_STATUS_INTERNAL_ERROR;
1928 if (!NT_STATUS_IS_OK(status)) {
1929 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1930 nt_errstr(status)));
1934 if (DEBUGLEVEL >= 10) {
1935 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1938 /* Finally marshall the blob. */
1939 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
1940 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1941 cli->auth->auth_level,
1943 1 /* context id. */,
1946 if (!NT_STATUS_IS_OK(status)) {
1950 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.length)) {
1951 return NT_STATUS_NO_MEMORY;
1954 return NT_STATUS_OK;
1957 /*******************************************************************
1958 Calculate how much data we're going to send in this packet, also
1959 work out any sign/seal padding length.
1960 ********************************************************************/
1962 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1966 uint32 *p_ss_padding)
1968 uint32 data_space, data_len;
1971 if ((data_left > 0) && (sys_random() % 2)) {
1972 data_left = MAX(data_left/2, 1);
1976 switch (cli->auth->auth_level) {
1977 case DCERPC_AUTH_LEVEL_NONE:
1978 case DCERPC_AUTH_LEVEL_CONNECT:
1979 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1980 data_len = MIN(data_space, data_left);
1983 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1986 case DCERPC_AUTH_LEVEL_INTEGRITY:
1987 case DCERPC_AUTH_LEVEL_PRIVACY:
1988 /* Treat the same for all authenticated rpc requests. */
1989 switch(cli->auth->auth_type) {
1990 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1991 case PIPE_AUTH_TYPE_NTLMSSP:
1992 *p_auth_len = NTLMSSP_SIG_SIZE;
1994 case PIPE_AUTH_TYPE_SCHANNEL:
1995 *p_auth_len = SCHANNEL_SIG_SIZE;
1998 smb_panic("bad auth type");
2002 data_space = cli->max_xmit_frag
2003 - DCERPC_REQUEST_LENGTH
2004 - DCERPC_AUTH_TRAILER_LENGTH
2007 data_len = MIN(data_space, data_left);
2009 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2010 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2012 *p_frag_len = DCERPC_REQUEST_LENGTH
2013 + data_len + *p_ss_padding
2014 + DCERPC_AUTH_TRAILER_LENGTH
2019 smb_panic("bad auth level");
2025 /*******************************************************************
2027 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2028 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2029 and deals with signing/sealing details.
2030 ********************************************************************/
2032 struct rpc_api_pipe_req_state {
2033 struct event_context *ev;
2034 struct rpc_pipe_client *cli;
2037 prs_struct *req_data;
2038 uint32_t req_data_sent;
2039 prs_struct outgoing_frag;
2040 DATA_BLOB reply_pdu;
2043 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2044 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2045 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2046 bool *is_last_frag);
2048 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2049 struct event_context *ev,
2050 struct rpc_pipe_client *cli,
2052 prs_struct *req_data)
2054 struct tevent_req *req, *subreq;
2055 struct rpc_api_pipe_req_state *state;
2059 req = tevent_req_create(mem_ctx, &state,
2060 struct rpc_api_pipe_req_state);
2066 state->op_num = op_num;
2067 state->req_data = req_data;
2068 state->req_data_sent = 0;
2069 state->call_id = get_rpc_call_id();
2070 state->reply_pdu = data_blob_null;
2072 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
2073 + RPC_MAX_SIGN_SIZE) {
2074 /* Server is screwed up ! */
2075 status = NT_STATUS_INVALID_PARAMETER;
2079 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2084 status = prepare_next_frag(state, &is_last_frag);
2085 if (!NT_STATUS_IS_OK(status)) {
2090 subreq = rpc_api_pipe_send(state, ev, state->cli,
2091 &state->outgoing_frag,
2092 DCERPC_PKT_RESPONSE);
2093 if (subreq == NULL) {
2096 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2098 subreq = rpc_write_send(
2099 state, ev, cli->transport,
2100 (uint8_t *)prs_data_p(&state->outgoing_frag),
2101 prs_offset(&state->outgoing_frag));
2102 if (subreq == NULL) {
2105 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2111 tevent_req_nterror(req, status);
2112 return tevent_req_post(req, ev);
2118 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2121 uint32_t data_sent_thistime;
2125 uint32_t ss_padding;
2127 char pad[8] = { 0, };
2129 union dcerpc_payload u;
2132 data_left = prs_offset(state->req_data) - state->req_data_sent;
2134 data_sent_thistime = calculate_data_len_tosend(
2135 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2137 if (state->req_data_sent == 0) {
2138 flags = DCERPC_PFC_FLAG_FIRST;
2141 if (data_sent_thistime == data_left) {
2142 flags |= DCERPC_PFC_FLAG_LAST;
2145 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2146 return NT_STATUS_NO_MEMORY;
2149 ZERO_STRUCT(u.request);
2151 u.request.alloc_hint = prs_offset(state->req_data);
2152 u.request.context_id = 0;
2153 u.request.opnum = state->op_num;
2155 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2162 if (!NT_STATUS_IS_OK(status)) {
2166 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
2167 * compute it right for requests */
2168 dcerpc_set_frag_length(&blob, frag_len);
2170 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2171 return NT_STATUS_NO_MEMORY;
2174 /* Copy in the data, plus any ss padding. */
2175 if (!prs_append_some_prs_data(&state->outgoing_frag,
2176 state->req_data, state->req_data_sent,
2177 data_sent_thistime)) {
2178 return NT_STATUS_NO_MEMORY;
2181 /* Copy the sign/seal padding data. */
2182 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2183 return NT_STATUS_NO_MEMORY;
2186 /* Generate any auth sign/seal and add the auth footer. */
2187 switch (state->cli->auth->auth_type) {
2188 case PIPE_AUTH_TYPE_NONE:
2189 status = NT_STATUS_OK;
2191 case PIPE_AUTH_TYPE_NTLMSSP:
2192 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2193 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2194 &state->outgoing_frag);
2196 case PIPE_AUTH_TYPE_SCHANNEL:
2197 status = add_schannel_auth_footer(state->cli, ss_padding,
2198 &state->outgoing_frag);
2201 status = NT_STATUS_INVALID_PARAMETER;
2205 state->req_data_sent += data_sent_thistime;
2206 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2211 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2213 struct tevent_req *req = tevent_req_callback_data(
2214 subreq, struct tevent_req);
2215 struct rpc_api_pipe_req_state *state = tevent_req_data(
2216 req, struct rpc_api_pipe_req_state);
2220 status = rpc_write_recv(subreq);
2221 TALLOC_FREE(subreq);
2222 if (!NT_STATUS_IS_OK(status)) {
2223 tevent_req_nterror(req, status);
2227 status = prepare_next_frag(state, &is_last_frag);
2228 if (!NT_STATUS_IS_OK(status)) {
2229 tevent_req_nterror(req, status);
2234 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2235 &state->outgoing_frag,
2236 DCERPC_PKT_RESPONSE);
2237 if (tevent_req_nomem(subreq, req)) {
2240 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2242 subreq = rpc_write_send(
2244 state->cli->transport,
2245 (uint8_t *)prs_data_p(&state->outgoing_frag),
2246 prs_offset(&state->outgoing_frag));
2247 if (tevent_req_nomem(subreq, req)) {
2250 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2255 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2257 struct tevent_req *req = tevent_req_callback_data(
2258 subreq, struct tevent_req);
2259 struct rpc_api_pipe_req_state *state = tevent_req_data(
2260 req, struct rpc_api_pipe_req_state);
2263 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
2264 TALLOC_FREE(subreq);
2265 if (!NT_STATUS_IS_OK(status)) {
2266 tevent_req_nterror(req, status);
2269 tevent_req_done(req);
2272 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2273 DATA_BLOB *reply_pdu)
2275 struct rpc_api_pipe_req_state *state = tevent_req_data(
2276 req, struct rpc_api_pipe_req_state);
2279 if (tevent_req_is_nterror(req, &status)) {
2281 * We always have to initialize to reply pdu, even if there is
2282 * none. The rpccli_* caller routines expect this.
2284 *reply_pdu = data_blob_null;
2288 /* return data to caller and assign it ownership of memory */
2289 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
2290 reply_pdu->length = state->reply_pdu.length;
2291 state->reply_pdu.length = 0;
2293 return NT_STATUS_OK;
2297 /****************************************************************************
2298 Set the handle state.
2299 ****************************************************************************/
2301 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2302 const char *pipe_name, uint16 device_state)
2304 bool state_set = False;
2306 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2307 char *rparam = NULL;
2309 uint32 rparam_len, rdata_len;
2311 if (pipe_name == NULL)
2314 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2315 cli->fnum, pipe_name, device_state));
2317 /* create parameters: device state */
2318 SSVAL(param, 0, device_state);
2320 /* create setup parameters. */
2322 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2324 /* send the data on \PIPE\ */
2325 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2326 setup, 2, 0, /* setup, length, max */
2327 param, 2, 0, /* param, length, max */
2328 NULL, 0, 1024, /* data, length, max */
2329 &rparam, &rparam_len, /* return param, length */
2330 &rdata, &rdata_len)) /* return data, length */
2332 DEBUG(5, ("Set Handle state: return OK\n"));
2343 /****************************************************************************
2344 Check the rpc bind acknowledge response.
2345 ****************************************************************************/
2347 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2348 const struct ndr_syntax_id *transfer)
2350 struct dcerpc_ack_ctx ctx;
2352 if (r->secondary_address_size == 0) {
2353 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2356 if (r->num_results < 1 || !r->ctx_list) {
2360 ctx = r->ctx_list[0];
2362 /* check the transfer syntax */
2363 if ((ctx.syntax.if_version != transfer->if_version) ||
2364 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2365 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2369 if (r->num_results != 0x1 || ctx.result != 0) {
2370 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2371 r->num_results, ctx.reason));
2374 DEBUG(5,("check_bind_response: accepted!\n"));
2378 /*******************************************************************
2379 Creates a DCE/RPC bind authentication response.
2380 This is the packet that is sent back to the server once we
2381 have received a BIND-ACK, to finish the third leg of
2382 the authentication handshake.
2383 ********************************************************************/
2385 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2387 enum pipe_auth_type auth_type,
2388 enum dcerpc_AuthLevel auth_level,
2389 DATA_BLOB *pauth_blob,
2390 prs_struct *rpc_out)
2393 union dcerpc_payload u;
2398 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2399 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2401 0, /* auth_pad_length */
2402 1, /* auth_context_id */
2404 &u.auth3.auth_info);
2405 if (!NT_STATUS_IS_OK(status)) {
2409 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2411 DCERPC_PFC_FLAG_FIRST |
2412 DCERPC_PFC_FLAG_LAST,
2417 if (!NT_STATUS_IS_OK(status)) {
2418 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2422 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2423 return NT_STATUS_NO_MEMORY;
2426 return NT_STATUS_OK;
2429 /*******************************************************************
2430 Creates a DCE/RPC bind alter context authentication request which
2431 may contain a spnego auth blobl
2432 ********************************************************************/
2434 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2435 const struct ndr_syntax_id *abstract,
2436 const struct ndr_syntax_id *transfer,
2437 enum dcerpc_AuthLevel auth_level,
2438 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2439 prs_struct *rpc_out)
2441 DATA_BLOB auth_info;
2444 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2445 DCERPC_AUTH_TYPE_SPNEGO,
2447 0, /* auth_pad_length */
2448 1, /* auth_context_id */
2451 if (!NT_STATUS_IS_OK(status)) {
2456 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2462 if (!NT_STATUS_IS_OK(status)) {
2469 /****************************************************************************
2471 ****************************************************************************/
2473 struct rpc_pipe_bind_state {
2474 struct event_context *ev;
2475 struct rpc_pipe_client *cli;
2477 uint32_t rpc_call_id;
2480 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2481 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2482 struct rpc_pipe_bind_state *state,
2483 struct ncacn_packet *r);
2484 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2485 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2486 struct rpc_pipe_bind_state *state,
2487 struct ncacn_packet *r,
2488 DATA_BLOB *reply_pdu);
2489 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2491 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2492 struct event_context *ev,
2493 struct rpc_pipe_client *cli,
2494 struct cli_pipe_auth_data *auth)
2496 struct tevent_req *req, *subreq;
2497 struct rpc_pipe_bind_state *state;
2500 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2505 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2506 rpccli_pipe_txt(talloc_tos(), cli),
2507 (unsigned int)auth->auth_type,
2508 (unsigned int)auth->auth_level ));
2512 state->rpc_call_id = get_rpc_call_id();
2514 prs_init_empty(&state->rpc_out, state, MARSHALL);
2516 cli->auth = talloc_move(cli, &auth);
2518 /* Marshall the outgoing data. */
2519 status = create_rpc_bind_req(cli, &state->rpc_out,
2521 &cli->abstract_syntax,
2522 &cli->transfer_syntax,
2523 cli->auth->auth_type,
2524 cli->auth->auth_level);
2526 if (!NT_STATUS_IS_OK(status)) {
2530 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2531 DCERPC_PKT_BIND_ACK);
2532 if (subreq == NULL) {
2535 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2539 tevent_req_nterror(req, status);
2540 return tevent_req_post(req, ev);
2546 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2548 struct tevent_req *req = tevent_req_callback_data(
2549 subreq, struct tevent_req);
2550 struct rpc_pipe_bind_state *state = tevent_req_data(
2551 req, struct rpc_pipe_bind_state);
2552 DATA_BLOB reply_pdu;
2553 struct ncacn_packet *pkt;
2556 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
2557 TALLOC_FREE(subreq);
2558 if (!NT_STATUS_IS_OK(status)) {
2559 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2560 rpccli_pipe_txt(talloc_tos(), state->cli),
2561 nt_errstr(status)));
2562 tevent_req_nterror(req, status);
2566 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
2567 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2568 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2572 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
2573 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
2576 * For authenticated binds we may need to do 3 or 4 leg binds.
2579 switch(state->cli->auth->auth_type) {
2581 case PIPE_AUTH_TYPE_NONE:
2582 case PIPE_AUTH_TYPE_SCHANNEL:
2583 /* Bind complete. */
2584 tevent_req_done(req);
2587 case PIPE_AUTH_TYPE_NTLMSSP:
2588 /* Need to send AUTH3 packet - no reply. */
2589 status = rpc_finish_auth3_bind_send(req, state, pkt);
2590 if (!NT_STATUS_IS_OK(status)) {
2591 tevent_req_nterror(req, status);
2595 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2596 /* Need to send alter context request and reply. */
2597 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt,
2599 if (!NT_STATUS_IS_OK(status)) {
2600 tevent_req_nterror(req, status);
2604 case PIPE_AUTH_TYPE_KRB5:
2608 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2609 (unsigned int)state->cli->auth->auth_type));
2610 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2614 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2615 struct rpc_pipe_bind_state *state,
2616 struct ncacn_packet *r)
2618 DATA_BLOB client_reply = data_blob_null;
2619 struct dcerpc_auth auth;
2620 struct tevent_req *subreq;
2623 if ((r->auth_length == 0)
2624 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2625 + r->auth_length)) {
2626 return NT_STATUS_INVALID_PARAMETER;
2629 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
2630 &r->u.bind_ack.auth_info,
2632 if (!NT_STATUS_IS_OK(status)) {
2633 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2634 nt_errstr(status)));
2638 /* TODO - check auth_type/auth_level match. */
2640 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2641 auth.credentials, &client_reply);
2643 if (!NT_STATUS_IS_OK(status)) {
2644 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2645 "blob failed: %s.\n", nt_errstr(status)));
2649 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2651 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2652 state->cli->auth->auth_type,
2653 state->cli->auth->auth_level,
2654 &client_reply, &state->rpc_out);
2655 data_blob_free(&client_reply);
2657 if (!NT_STATUS_IS_OK(status)) {
2661 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2662 (uint8_t *)prs_data_p(&state->rpc_out),
2663 prs_offset(&state->rpc_out));
2664 if (subreq == NULL) {
2665 return NT_STATUS_NO_MEMORY;
2667 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2668 return NT_STATUS_OK;
2671 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2673 struct tevent_req *req = tevent_req_callback_data(
2674 subreq, struct tevent_req);
2677 status = rpc_write_recv(subreq);
2678 TALLOC_FREE(subreq);
2679 if (!NT_STATUS_IS_OK(status)) {
2680 tevent_req_nterror(req, status);
2683 tevent_req_done(req);
2686 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2687 struct rpc_pipe_bind_state *state,
2688 struct ncacn_packet *r,
2689 DATA_BLOB *reply_pdu)
2691 DATA_BLOB server_ntlm_response = data_blob_null;
2692 DATA_BLOB client_reply = data_blob_null;
2693 DATA_BLOB tmp_blob = data_blob_null;
2694 struct dcerpc_auth auth_info;
2695 DATA_BLOB auth_blob;
2696 struct tevent_req *subreq;
2699 if ((r->auth_length == 0)
2700 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2701 + r->auth_length)) {
2702 return NT_STATUS_INVALID_PARAMETER;
2705 /* Process the returned NTLMSSP blob first. */
2706 auth_blob = data_blob_const(reply_pdu->data
2708 - DCERPC_AUTH_TRAILER_LENGTH
2710 DCERPC_AUTH_TRAILER_LENGTH
2713 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
2714 if (!NT_STATUS_IS_OK(status)) {
2715 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
2720 * The server might give us back two challenges - tmp_blob is for the
2723 if (!spnego_parse_challenge(auth_info.credentials,
2724 &server_ntlm_response, &tmp_blob)) {
2725 data_blob_free(&server_ntlm_response);
2726 data_blob_free(&tmp_blob);
2727 return NT_STATUS_INVALID_PARAMETER;
2730 /* We're finished with the server spnego response and the tmp_blob. */
2731 data_blob_free(&tmp_blob);
2733 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2734 server_ntlm_response, &client_reply);
2736 /* Finished with the server_ntlm response */
2737 data_blob_free(&server_ntlm_response);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2741 "using server blob failed.\n"));
2742 data_blob_free(&client_reply);
2746 /* SPNEGO wrap the client reply. */
2747 tmp_blob = spnego_gen_auth(client_reply);
2748 data_blob_free(&client_reply);
2749 client_reply = tmp_blob;
2750 tmp_blob = data_blob_null;
2752 /* Now prepare the alter context pdu. */
2753 prs_init_empty(&state->rpc_out, state, MARSHALL);
2755 status = create_rpc_alter_context(state->rpc_call_id,
2756 &state->cli->abstract_syntax,
2757 &state->cli->transfer_syntax,
2758 state->cli->auth->auth_level,
2761 data_blob_free(&client_reply);
2763 if (!NT_STATUS_IS_OK(status)) {
2767 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2768 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2769 if (subreq == NULL) {
2770 return NT_STATUS_NO_MEMORY;
2772 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2773 return NT_STATUS_OK;
2776 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2778 struct tevent_req *req = tevent_req_callback_data(
2779 subreq, struct tevent_req);
2780 struct rpc_pipe_bind_state *state = tevent_req_data(
2781 req, struct rpc_pipe_bind_state);
2782 DATA_BLOB tmp_blob = data_blob_null;
2783 struct ncacn_packet *pkt;
2784 struct dcerpc_auth auth;
2787 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2788 TALLOC_FREE(subreq);
2789 if (!NT_STATUS_IS_OK(status)) {
2790 tevent_req_nterror(req, status);
2794 status = dcerpc_pull_dcerpc_auth(pkt,
2795 &pkt->u.alter_resp.auth_info,
2797 if (!NT_STATUS_IS_OK(status)) {
2798 tevent_req_nterror(req, status);
2802 /* Check we got a valid auth response. */
2803 if (!spnego_parse_auth_response(auth.credentials,
2805 OID_NTLMSSP, &tmp_blob)) {
2806 data_blob_free(&tmp_blob);
2807 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2811 data_blob_free(&tmp_blob);
2813 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2814 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2815 tevent_req_done(req);
2818 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2820 return tevent_req_simple_recv_ntstatus(req);
2823 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2824 struct cli_pipe_auth_data *auth)
2826 TALLOC_CTX *frame = talloc_stackframe();
2827 struct event_context *ev;
2828 struct tevent_req *req;
2829 NTSTATUS status = NT_STATUS_OK;
2831 ev = event_context_init(frame);
2833 status = NT_STATUS_NO_MEMORY;
2837 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2839 status = NT_STATUS_NO_MEMORY;
2843 if (!tevent_req_poll(req, ev)) {
2844 status = map_nt_error_from_unix(errno);
2848 status = rpc_pipe_bind_recv(req);
2854 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2856 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2857 unsigned int timeout)
2861 if (rpc_cli->transport == NULL) {
2862 return RPCCLI_DEFAULT_TIMEOUT;
2865 if (rpc_cli->transport->set_timeout == NULL) {
2866 return RPCCLI_DEFAULT_TIMEOUT;
2869 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2871 return RPCCLI_DEFAULT_TIMEOUT;
2877 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2879 if (rpc_cli == NULL) {
2883 if (rpc_cli->transport == NULL) {
2887 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2890 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2892 struct cli_state *cli;
2894 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2895 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2896 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2900 cli = rpc_pipe_np_smb_conn(rpc_cli);
2904 E_md4hash(cli->password ? cli->password : "", nt_hash);
2908 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2909 struct cli_pipe_auth_data **presult)
2911 struct cli_pipe_auth_data *result;
2913 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2914 if (result == NULL) {
2915 return NT_STATUS_NO_MEMORY;
2918 result->auth_type = PIPE_AUTH_TYPE_NONE;
2919 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2921 result->user_name = talloc_strdup(result, "");
2922 result->domain = talloc_strdup(result, "");
2923 if ((result->user_name == NULL) || (result->domain == NULL)) {
2924 TALLOC_FREE(result);
2925 return NT_STATUS_NO_MEMORY;
2929 return NT_STATUS_OK;
2932 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2934 ntlmssp_end(&auth->a_u.ntlmssp_state);
2938 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2939 enum pipe_auth_type auth_type,
2940 enum dcerpc_AuthLevel auth_level,
2942 const char *username,
2943 const char *password,
2944 struct cli_pipe_auth_data **presult)
2946 struct cli_pipe_auth_data *result;
2949 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2950 if (result == NULL) {
2951 return NT_STATUS_NO_MEMORY;
2954 result->auth_type = auth_type;
2955 result->auth_level = auth_level;
2957 result->user_name = talloc_strdup(result, username);
2958 result->domain = talloc_strdup(result, domain);
2959 if ((result->user_name == NULL) || (result->domain == NULL)) {
2960 status = NT_STATUS_NO_MEMORY;
2964 status = ntlmssp_client_start(NULL,
2967 lp_client_ntlmv2_auth(),
2968 &result->a_u.ntlmssp_state);
2969 if (!NT_STATUS_IS_OK(status)) {
2973 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2975 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2976 if (!NT_STATUS_IS_OK(status)) {
2980 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2981 if (!NT_STATUS_IS_OK(status)) {
2985 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2986 if (!NT_STATUS_IS_OK(status)) {
2991 * Turn off sign+seal to allow selected auth level to turn it back on.
2993 result->a_u.ntlmssp_state->neg_flags &=
2994 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2996 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2997 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2998 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2999 result->a_u.ntlmssp_state->neg_flags
3000 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3004 return NT_STATUS_OK;
3007 TALLOC_FREE(result);
3011 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3012 enum dcerpc_AuthLevel auth_level,
3013 struct netlogon_creds_CredentialState *creds,
3014 struct cli_pipe_auth_data **presult)
3016 struct cli_pipe_auth_data *result;
3018 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3019 if (result == NULL) {
3020 return NT_STATUS_NO_MEMORY;
3023 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3024 result->auth_level = auth_level;
3026 result->user_name = talloc_strdup(result, "");
3027 result->domain = talloc_strdup(result, domain);
3028 if ((result->user_name == NULL) || (result->domain == NULL)) {
3032 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3033 if (result->a_u.schannel_auth == NULL) {
3037 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3038 result->a_u.schannel_auth->seq_num = 0;
3039 result->a_u.schannel_auth->initiator = true;
3040 result->a_u.schannel_auth->creds = creds;
3043 return NT_STATUS_OK;
3046 TALLOC_FREE(result);
3047 return NT_STATUS_NO_MEMORY;
3051 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3053 data_blob_free(&auth->session_key);
3058 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3059 enum dcerpc_AuthLevel auth_level,
3060 const char *service_princ,
3061 const char *username,
3062 const char *password,
3063 struct cli_pipe_auth_data **presult)
3066 struct cli_pipe_auth_data *result;
3068 if ((username != NULL) && (password != NULL)) {
3069 int ret = kerberos_kinit_password(username, password, 0, NULL);
3071 return NT_STATUS_ACCESS_DENIED;
3075 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3076 if (result == NULL) {
3077 return NT_STATUS_NO_MEMORY;
3080 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3081 result->auth_level = auth_level;
3084 * Username / domain need fixing!
3086 result->user_name = talloc_strdup(result, "");
3087 result->domain = talloc_strdup(result, "");
3088 if ((result->user_name == NULL) || (result->domain == NULL)) {
3092 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3093 result, struct kerberos_auth_struct);
3094 if (result->a_u.kerberos_auth == NULL) {
3097 talloc_set_destructor(result->a_u.kerberos_auth,
3098 cli_auth_kerberos_data_destructor);
3100 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3101 result, service_princ);
3102 if (result->a_u.kerberos_auth->service_principal == NULL) {
3107 return NT_STATUS_OK;
3110 TALLOC_FREE(result);
3111 return NT_STATUS_NO_MEMORY;
3113 return NT_STATUS_NOT_SUPPORTED;
3118 * Create an rpc pipe client struct, connecting to a tcp port.
3120 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3122 const struct ndr_syntax_id *abstract_syntax,
3123 struct rpc_pipe_client **presult)
3125 struct rpc_pipe_client *result;
3126 struct sockaddr_storage addr;
3130 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3131 if (result == NULL) {
3132 return NT_STATUS_NO_MEMORY;
3135 result->abstract_syntax = *abstract_syntax;
3136 result->transfer_syntax = ndr_transfer_syntax;
3137 result->dispatch = cli_do_rpc_ndr;
3138 result->dispatch_send = cli_do_rpc_ndr_send;
3139 result->dispatch_recv = cli_do_rpc_ndr_recv;
3141 result->desthost = talloc_strdup(result, host);
3142 result->srv_name_slash = talloc_asprintf_strupper_m(
3143 result, "\\\\%s", result->desthost);
3144 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3145 status = NT_STATUS_NO_MEMORY;
3149 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3150 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3152 if (!resolve_name(host, &addr, 0, false)) {
3153 status = NT_STATUS_NOT_FOUND;
3157 status = open_socket_out(&addr, port, 60, &fd);
3158 if (!NT_STATUS_IS_OK(status)) {
3161 set_socket_options(fd, lp_socket_options());
3163 status = rpc_transport_sock_init(result, fd, &result->transport);
3164 if (!NT_STATUS_IS_OK(status)) {
3169 result->transport->transport = NCACN_IP_TCP;
3172 return NT_STATUS_OK;
3175 TALLOC_FREE(result);
3180 * Determine the tcp port on which a dcerpc interface is listening
3181 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3184 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3185 const struct ndr_syntax_id *abstract_syntax,
3189 struct rpc_pipe_client *epm_pipe = NULL;
3190 struct cli_pipe_auth_data *auth = NULL;
3191 struct dcerpc_binding *map_binding = NULL;
3192 struct dcerpc_binding *res_binding = NULL;
3193 struct epm_twr_t *map_tower = NULL;
3194 struct epm_twr_t *res_towers = NULL;
3195 struct policy_handle *entry_handle = NULL;
3196 uint32_t num_towers = 0;
3197 uint32_t max_towers = 1;
3198 struct epm_twr_p_t towers;
3199 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3201 if (pport == NULL) {
3202 status = NT_STATUS_INVALID_PARAMETER;
3206 /* open the connection to the endpoint mapper */
3207 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3208 &ndr_table_epmapper.syntax_id,
3211 if (!NT_STATUS_IS_OK(status)) {
3215 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3216 if (!NT_STATUS_IS_OK(status)) {
3220 status = rpc_pipe_bind(epm_pipe, auth);
3221 if (!NT_STATUS_IS_OK(status)) {
3225 /* create tower for asking the epmapper */
3227 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3228 if (map_binding == NULL) {
3229 status = NT_STATUS_NO_MEMORY;
3233 map_binding->transport = NCACN_IP_TCP;
3234 map_binding->object = *abstract_syntax;
3235 map_binding->host = host; /* needed? */
3236 map_binding->endpoint = "0"; /* correct? needed? */
3238 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3239 if (map_tower == NULL) {
3240 status = NT_STATUS_NO_MEMORY;
3244 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3245 &(map_tower->tower));
3246 if (!NT_STATUS_IS_OK(status)) {
3250 /* allocate further parameters for the epm_Map call */
3252 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3253 if (res_towers == NULL) {
3254 status = NT_STATUS_NO_MEMORY;
3257 towers.twr = res_towers;
3259 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3260 if (entry_handle == NULL) {
3261 status = NT_STATUS_NO_MEMORY;
3265 /* ask the endpoint mapper for the port */
3267 status = rpccli_epm_Map(epm_pipe,
3269 CONST_DISCARD(struct GUID *,
3270 &(abstract_syntax->uuid)),
3277 if (!NT_STATUS_IS_OK(status)) {
3281 if (num_towers != 1) {
3282 status = NT_STATUS_UNSUCCESSFUL;
3286 /* extract the port from the answer */
3288 status = dcerpc_binding_from_tower(tmp_ctx,
3289 &(towers.twr->tower),
3291 if (!NT_STATUS_IS_OK(status)) {
3295 /* are further checks here necessary? */
3296 if (res_binding->transport != NCACN_IP_TCP) {
3297 status = NT_STATUS_UNSUCCESSFUL;
3301 *pport = (uint16_t)atoi(res_binding->endpoint);
3304 TALLOC_FREE(tmp_ctx);
3309 * Create a rpc pipe client struct, connecting to a host via tcp.
3310 * The port is determined by asking the endpoint mapper on the given
3313 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3314 const struct ndr_syntax_id *abstract_syntax,
3315 struct rpc_pipe_client **presult)
3320 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3321 if (!NT_STATUS_IS_OK(status)) {
3325 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3326 abstract_syntax, presult);
3329 /********************************************************************
3330 Create a rpc pipe client struct, connecting to a unix domain socket
3331 ********************************************************************/
3332 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3333 const struct ndr_syntax_id *abstract_syntax,
3334 struct rpc_pipe_client **presult)
3336 struct rpc_pipe_client *result;
3337 struct sockaddr_un addr;
3341 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3342 if (result == NULL) {
3343 return NT_STATUS_NO_MEMORY;
3346 result->abstract_syntax = *abstract_syntax;
3347 result->transfer_syntax = ndr_transfer_syntax;
3348 result->dispatch = cli_do_rpc_ndr;
3349 result->dispatch_send = cli_do_rpc_ndr_send;
3350 result->dispatch_recv = cli_do_rpc_ndr_recv;
3352 result->desthost = get_myname(result);
3353 result->srv_name_slash = talloc_asprintf_strupper_m(
3354 result, "\\\\%s", result->desthost);
3355 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3356 status = NT_STATUS_NO_MEMORY;
3360 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3361 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3363 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3365 status = map_nt_error_from_unix(errno);
3370 addr.sun_family = AF_UNIX;
3371 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3373 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3374 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3377 return map_nt_error_from_unix(errno);
3380 status = rpc_transport_sock_init(result, fd, &result->transport);
3381 if (!NT_STATUS_IS_OK(status)) {
3386 result->transport->transport = NCALRPC;
3389 return NT_STATUS_OK;
3392 TALLOC_FREE(result);
3396 struct rpc_pipe_client_np_ref {
3397 struct cli_state *cli;
3398 struct rpc_pipe_client *pipe;
3401 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3403 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3407 /****************************************************************************
3408 Open a named pipe over SMB to a remote server.
3410 * CAVEAT CALLER OF THIS FUNCTION:
3411 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3412 * so be sure that this function is called AFTER any structure (vs pointer)
3413 * assignment of the cli. In particular, libsmbclient does structure
3414 * assignments of cli, which invalidates the data in the returned
3415 * rpc_pipe_client if this function is called before the structure assignment
3418 ****************************************************************************/
3420 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3421 const struct ndr_syntax_id *abstract_syntax,
3422 struct rpc_pipe_client **presult)
3424 struct rpc_pipe_client *result;
3426 struct rpc_pipe_client_np_ref *np_ref;
3428 /* sanity check to protect against crashes */
3431 return NT_STATUS_INVALID_HANDLE;
3434 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3435 if (result == NULL) {
3436 return NT_STATUS_NO_MEMORY;
3439 result->abstract_syntax = *abstract_syntax;
3440 result->transfer_syntax = ndr_transfer_syntax;
3441 result->dispatch = cli_do_rpc_ndr;
3442 result->dispatch_send = cli_do_rpc_ndr_send;
3443 result->dispatch_recv = cli_do_rpc_ndr_recv;
3444 result->desthost = talloc_strdup(result, cli->desthost);
3445 result->srv_name_slash = talloc_asprintf_strupper_m(
3446 result, "\\\\%s", result->desthost);
3448 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3449 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3451 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3452 TALLOC_FREE(result);
3453 return NT_STATUS_NO_MEMORY;
3456 status = rpc_transport_np_init(result, cli, abstract_syntax,
3457 &result->transport);
3458 if (!NT_STATUS_IS_OK(status)) {
3459 TALLOC_FREE(result);
3463 result->transport->transport = NCACN_NP;
3465 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3466 if (np_ref == NULL) {
3467 TALLOC_FREE(result);
3468 return NT_STATUS_NO_MEMORY;
3471 np_ref->pipe = result;
3473 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3474 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3477 return NT_STATUS_OK;
3480 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3481 struct rpc_cli_smbd_conn *conn,
3482 const struct ndr_syntax_id *syntax,
3483 struct rpc_pipe_client **presult)
3485 struct rpc_pipe_client *result;
3486 struct cli_pipe_auth_data *auth;
3489 result = talloc(mem_ctx, struct rpc_pipe_client);
3490 if (result == NULL) {
3491 return NT_STATUS_NO_MEMORY;
3493 result->abstract_syntax = *syntax;
3494 result->transfer_syntax = ndr_transfer_syntax;
3495 result->dispatch = cli_do_rpc_ndr;
3496 result->dispatch_send = cli_do_rpc_ndr_send;
3497 result->dispatch_recv = cli_do_rpc_ndr_recv;
3498 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3499 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3501 result->desthost = talloc_strdup(result, global_myname());
3502 result->srv_name_slash = talloc_asprintf_strupper_m(
3503 result, "\\\\%s", global_myname());
3504 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3505 TALLOC_FREE(result);
3506 return NT_STATUS_NO_MEMORY;
3509 status = rpc_transport_smbd_init(result, conn, syntax,
3510 &result->transport);
3511 if (!NT_STATUS_IS_OK(status)) {
3512 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3513 nt_errstr(status)));
3514 TALLOC_FREE(result);
3518 status = rpccli_anon_bind_data(result, &auth);
3519 if (!NT_STATUS_IS_OK(status)) {
3520 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3521 nt_errstr(status)));
3522 TALLOC_FREE(result);
3526 status = rpc_pipe_bind(result, auth);
3527 if (!NT_STATUS_IS_OK(status)) {
3528 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3529 TALLOC_FREE(result);
3533 result->transport->transport = NCACN_INTERNAL;
3536 return NT_STATUS_OK;
3539 /****************************************************************************
3540 Open a pipe to a remote server.
3541 ****************************************************************************/
3543 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3544 enum dcerpc_transport_t transport,
3545 const struct ndr_syntax_id *interface,
3546 struct rpc_pipe_client **presult)
3548 switch (transport) {
3550 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3553 return rpc_pipe_open_np(cli, interface, presult);
3555 return NT_STATUS_NOT_IMPLEMENTED;
3559 /****************************************************************************
3560 Open a named pipe to an SMB server and bind anonymously.
3561 ****************************************************************************/
3563 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3564 enum dcerpc_transport_t transport,
3565 const struct ndr_syntax_id *interface,
3566 struct rpc_pipe_client **presult)
3568 struct rpc_pipe_client *result;
3569 struct cli_pipe_auth_data *auth;
3572 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3573 if (!NT_STATUS_IS_OK(status)) {
3577 status = rpccli_anon_bind_data(result, &auth);
3578 if (!NT_STATUS_IS_OK(status)) {
3579 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3580 nt_errstr(status)));
3581 TALLOC_FREE(result);
3586 * This is a bit of an abstraction violation due to the fact that an
3587 * anonymous bind on an authenticated SMB inherits the user/domain
3588 * from the enclosing SMB creds
3591 TALLOC_FREE(auth->user_name);
3592 TALLOC_FREE(auth->domain);
3594 auth->user_name = talloc_strdup(auth, cli->user_name);
3595 auth->domain = talloc_strdup(auth, cli->domain);
3596 auth->user_session_key = data_blob_talloc(auth,
3597 cli->user_session_key.data,
3598 cli->user_session_key.length);
3600 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3601 TALLOC_FREE(result);
3602 return NT_STATUS_NO_MEMORY;
3605 status = rpc_pipe_bind(result, auth);
3606 if (!NT_STATUS_IS_OK(status)) {
3608 if (ndr_syntax_id_equal(interface,
3609 &ndr_table_dssetup.syntax_id)) {
3610 /* non AD domains just don't have this pipe, avoid
3611 * level 0 statement in that case - gd */
3614 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3615 "%s failed with error %s\n",
3616 get_pipe_name_from_syntax(talloc_tos(), interface),
3617 nt_errstr(status) ));
3618 TALLOC_FREE(result);
3622 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3623 "%s and bound anonymously.\n",
3624 get_pipe_name_from_syntax(talloc_tos(), interface),
3628 return NT_STATUS_OK;
3631 /****************************************************************************
3632 ****************************************************************************/
3634 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3635 const struct ndr_syntax_id *interface,
3636 struct rpc_pipe_client **presult)
3638 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3639 interface, presult);
3642 /****************************************************************************
3643 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3644 ****************************************************************************/
3646 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3647 const struct ndr_syntax_id *interface,
3648 enum dcerpc_transport_t transport,
3649 enum pipe_auth_type auth_type,
3650 enum dcerpc_AuthLevel auth_level,
3652 const char *username,
3653 const char *password,
3654 struct rpc_pipe_client **presult)
3656 struct rpc_pipe_client *result;
3657 struct cli_pipe_auth_data *auth;
3660 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3661 if (!NT_STATUS_IS_OK(status)) {
3665 status = rpccli_ntlmssp_bind_data(
3666 result, auth_type, auth_level, domain, username,
3668 if (!NT_STATUS_IS_OK(status)) {
3669 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3670 nt_errstr(status)));
3674 status = rpc_pipe_bind(result, auth);
3675 if (!NT_STATUS_IS_OK(status)) {
3676 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3677 nt_errstr(status) ));
3681 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3682 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3683 get_pipe_name_from_syntax(talloc_tos(), interface),
3684 cli->desthost, domain, username ));
3687 return NT_STATUS_OK;
3691 TALLOC_FREE(result);
3695 /****************************************************************************
3697 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3698 ****************************************************************************/
3700 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3701 const struct ndr_syntax_id *interface,
3702 enum dcerpc_transport_t transport,
3703 enum dcerpc_AuthLevel auth_level,
3705 const char *username,
3706 const char *password,
3707 struct rpc_pipe_client **presult)
3709 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3712 PIPE_AUTH_TYPE_NTLMSSP,
3720 /****************************************************************************
3722 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3723 ****************************************************************************/
3725 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3726 const struct ndr_syntax_id *interface,
3727 enum dcerpc_transport_t transport,
3728 enum dcerpc_AuthLevel auth_level,
3730 const char *username,
3731 const char *password,
3732 struct rpc_pipe_client **presult)
3734 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3737 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3745 /****************************************************************************
3746 Get a the schannel session key out of an already opened netlogon pipe.
3747 ****************************************************************************/
3748 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3749 struct cli_state *cli,
3753 enum netr_SchannelType sec_chan_type = 0;
3754 unsigned char machine_pwd[16];
3755 const char *machine_account;
3758 /* Get the machine account credentials from secrets.tdb. */
3759 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3762 DEBUG(0, ("get_schannel_session_key: could not fetch "
3763 "trust account password for domain '%s'\n",
3765 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3768 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3769 cli->desthost, /* server name */
3770 domain, /* domain */
3771 global_myname(), /* client name */
3772 machine_account, /* machine account name */
3777 if (!NT_STATUS_IS_OK(status)) {
3778 DEBUG(3, ("get_schannel_session_key_common: "
3779 "rpccli_netlogon_setup_creds failed with result %s "
3780 "to server %s, domain %s, machine account %s.\n",
3781 nt_errstr(status), cli->desthost, domain,
3786 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3787 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3789 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3792 return NT_STATUS_OK;;
3795 /****************************************************************************
3796 Open a netlogon pipe and get the schannel session key.
3797 Now exposed to external callers.
3798 ****************************************************************************/
3801 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3804 struct rpc_pipe_client **presult)
3806 struct rpc_pipe_client *netlogon_pipe = NULL;
3809 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3811 if (!NT_STATUS_IS_OK(status)) {
3815 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3817 if (!NT_STATUS_IS_OK(status)) {
3818 TALLOC_FREE(netlogon_pipe);
3822 *presult = netlogon_pipe;
3823 return NT_STATUS_OK;
3826 /****************************************************************************
3828 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3829 using session_key. sign and seal.
3831 The *pdc will be stolen onto this new pipe
3832 ****************************************************************************/
3834 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3835 const struct ndr_syntax_id *interface,
3836 enum dcerpc_transport_t transport,
3837 enum dcerpc_AuthLevel auth_level,
3839 struct netlogon_creds_CredentialState **pdc,
3840 struct rpc_pipe_client **presult)
3842 struct rpc_pipe_client *result;
3843 struct cli_pipe_auth_data *auth;
3846 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3847 if (!NT_STATUS_IS_OK(status)) {
3851 status = rpccli_schannel_bind_data(result, domain, auth_level,
3853 if (!NT_STATUS_IS_OK(status)) {
3854 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3855 nt_errstr(status)));
3856 TALLOC_FREE(result);
3860 status = rpc_pipe_bind(result, auth);
3861 if (!NT_STATUS_IS_OK(status)) {
3862 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3863 "cli_rpc_pipe_bind failed with error %s\n",
3864 nt_errstr(status) ));
3865 TALLOC_FREE(result);
3870 * The credentials on a new netlogon pipe are the ones we are passed
3871 * in - reference them in
3873 result->dc = talloc_move(result, pdc);
3875 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3876 "for domain %s and bound using schannel.\n",
3877 get_pipe_name_from_syntax(talloc_tos(), interface),
3878 cli->desthost, domain ));
3881 return NT_STATUS_OK;
3884 /****************************************************************************
3885 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3886 Fetch the session key ourselves using a temporary netlogon pipe. This
3887 version uses an ntlmssp auth bound netlogon pipe to get the key.
3888 ****************************************************************************/
3890 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3892 const char *username,
3893 const char *password,
3895 struct rpc_pipe_client **presult)
3897 struct rpc_pipe_client *netlogon_pipe = NULL;
3900 status = cli_rpc_pipe_open_spnego_ntlmssp(
3901 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3902 DCERPC_AUTH_LEVEL_PRIVACY,
3903 domain, username, password, &netlogon_pipe);
3904 if (!NT_STATUS_IS_OK(status)) {
3908 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3910 if (!NT_STATUS_IS_OK(status)) {
3911 TALLOC_FREE(netlogon_pipe);
3915 *presult = netlogon_pipe;
3916 return NT_STATUS_OK;
3919 /****************************************************************************
3920 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3921 Fetch the session key ourselves using a temporary netlogon pipe. This version
3922 uses an ntlmssp bind to get the session key.
3923 ****************************************************************************/
3925 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3926 const struct ndr_syntax_id *interface,
3927 enum dcerpc_transport_t transport,
3928 enum dcerpc_AuthLevel auth_level,
3930 const char *username,
3931 const char *password,
3932 struct rpc_pipe_client **presult)
3934 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3935 struct rpc_pipe_client *netlogon_pipe = NULL;
3936 struct rpc_pipe_client *result = NULL;
3939 status = get_schannel_session_key_auth_ntlmssp(
3940 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3941 if (!NT_STATUS_IS_OK(status)) {
3942 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3943 "key from server %s for domain %s.\n",
3944 cli->desthost, domain ));
3948 status = cli_rpc_pipe_open_schannel_with_key(
3949 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3952 /* Now we've bound using the session key we can close the netlog pipe. */
3953 TALLOC_FREE(netlogon_pipe);
3955 if (NT_STATUS_IS_OK(status)) {
3961 /****************************************************************************
3962 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3963 Fetch the session key ourselves using a temporary netlogon pipe.
3964 ****************************************************************************/
3966 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3967 const struct ndr_syntax_id *interface,
3968 enum dcerpc_transport_t transport,
3969 enum dcerpc_AuthLevel auth_level,
3971 struct rpc_pipe_client **presult)
3973 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3974 struct rpc_pipe_client *netlogon_pipe = NULL;
3975 struct rpc_pipe_client *result = NULL;
3978 status = get_schannel_session_key(cli, domain, &neg_flags,
3980 if (!NT_STATUS_IS_OK(status)) {
3981 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3982 "key from server %s for domain %s.\n",
3983 cli->desthost, domain ));
3987 status = cli_rpc_pipe_open_schannel_with_key(
3988 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3991 /* Now we've bound using the session key we can close the netlog pipe. */
3992 TALLOC_FREE(netlogon_pipe);
3994 if (NT_STATUS_IS_OK(status)) {
4001 /****************************************************************************
4002 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4003 The idea is this can be called with service_princ, username and password all
4004 NULL so long as the caller has a TGT.
4005 ****************************************************************************/
4007 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4008 const struct ndr_syntax_id *interface,
4009 enum dcerpc_AuthLevel auth_level,
4010 const char *service_princ,
4011 const char *username,
4012 const char *password,
4013 struct rpc_pipe_client **presult)
4016 struct rpc_pipe_client *result;
4017 struct cli_pipe_auth_data *auth;
4020 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4021 if (!NT_STATUS_IS_OK(status)) {
4025 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4026 username, password, &auth);
4027 if (!NT_STATUS_IS_OK(status)) {
4028 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4029 nt_errstr(status)));
4030 TALLOC_FREE(result);
4034 status = rpc_pipe_bind(result, auth);
4035 if (!NT_STATUS_IS_OK(status)) {
4036 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4037 "with error %s\n", nt_errstr(status)));
4038 TALLOC_FREE(result);
4043 return NT_STATUS_OK;
4045 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4046 return NT_STATUS_NOT_IMPLEMENTED;
4050 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4051 struct rpc_pipe_client *cli,
4052 DATA_BLOB *session_key)
4054 if (!session_key || !cli) {
4055 return NT_STATUS_INVALID_PARAMETER;
4059 return NT_STATUS_INVALID_PARAMETER;
4062 switch (cli->auth->auth_type) {
4063 case PIPE_AUTH_TYPE_SCHANNEL:
4064 *session_key = data_blob_talloc(mem_ctx,
4065 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4067 case PIPE_AUTH_TYPE_NTLMSSP:
4068 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4069 *session_key = data_blob_talloc(mem_ctx,
4070 cli->auth->a_u.ntlmssp_state->session_key.data,
4071 cli->auth->a_u.ntlmssp_state->session_key.length);
4073 case PIPE_AUTH_TYPE_KRB5:
4074 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4075 *session_key = data_blob_talloc(mem_ctx,
4076 cli->auth->a_u.kerberos_auth->session_key.data,
4077 cli->auth->a_u.kerberos_auth->session_key.length);
4079 case PIPE_AUTH_TYPE_NONE:
4080 *session_key = data_blob_talloc(mem_ctx,
4081 cli->auth->user_session_key.data,
4082 cli->auth->user_session_key.length);
4085 return NT_STATUS_NO_USER_SESSION_KEY;
4088 return NT_STATUS_OK;