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;
274 * Realloc pdu to have a least "size" bytes
277 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
281 if (prs_data_size(pdu) >= size) {
285 extra_size = size - prs_data_size(pdu);
287 if (!prs_force_grow(pdu, extra_size)) {
288 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
289 "%d bytes.\n", (int)extra_size));
293 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
294 (int)extra_size, prs_data_size(pdu)));
298 /*******************************************************************
299 Use SMBreadX to get rest of one fragment's worth of rpc data.
300 Reads the whole size or give an error message
301 ********************************************************************/
303 struct rpc_read_state {
304 struct event_context *ev;
305 struct rpc_cli_transport *transport;
311 static void rpc_read_done(struct tevent_req *subreq);
313 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
314 struct event_context *ev,
315 struct rpc_cli_transport *transport,
316 uint8_t *data, size_t size)
318 struct tevent_req *req, *subreq;
319 struct rpc_read_state *state;
321 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
326 state->transport = transport;
331 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
333 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
335 if (subreq == NULL) {
338 tevent_req_set_callback(subreq, rpc_read_done, req);
346 static void rpc_read_done(struct tevent_req *subreq)
348 struct tevent_req *req = tevent_req_callback_data(
349 subreq, struct tevent_req);
350 struct rpc_read_state *state = tevent_req_data(
351 req, struct rpc_read_state);
355 status = state->transport->read_recv(subreq, &received);
357 if (!NT_STATUS_IS_OK(status)) {
358 tevent_req_nterror(req, status);
362 state->num_read += received;
363 if (state->num_read == state->size) {
364 tevent_req_done(req);
368 subreq = state->transport->read_send(state, state->ev,
369 state->data + state->num_read,
370 state->size - state->num_read,
371 state->transport->priv);
372 if (tevent_req_nomem(subreq, req)) {
375 tevent_req_set_callback(subreq, rpc_read_done, req);
378 static NTSTATUS rpc_read_recv(struct tevent_req *req)
380 return tevent_req_simple_recv_ntstatus(req);
383 struct rpc_write_state {
384 struct event_context *ev;
385 struct rpc_cli_transport *transport;
391 static void rpc_write_done(struct tevent_req *subreq);
393 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
394 struct event_context *ev,
395 struct rpc_cli_transport *transport,
396 const uint8_t *data, size_t size)
398 struct tevent_req *req, *subreq;
399 struct rpc_write_state *state;
401 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
406 state->transport = transport;
409 state->num_written = 0;
411 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
413 subreq = transport->write_send(state, ev, data, size, transport->priv);
414 if (subreq == NULL) {
417 tevent_req_set_callback(subreq, rpc_write_done, req);
424 static void rpc_write_done(struct tevent_req *subreq)
426 struct tevent_req *req = tevent_req_callback_data(
427 subreq, struct tevent_req);
428 struct rpc_write_state *state = tevent_req_data(
429 req, struct rpc_write_state);
433 status = state->transport->write_recv(subreq, &written);
435 if (!NT_STATUS_IS_OK(status)) {
436 tevent_req_nterror(req, status);
440 state->num_written += written;
442 if (state->num_written == state->size) {
443 tevent_req_done(req);
447 subreq = state->transport->write_send(state, state->ev,
448 state->data + state->num_written,
449 state->size - state->num_written,
450 state->transport->priv);
451 if (tevent_req_nomem(subreq, req)) {
454 tevent_req_set_callback(subreq, rpc_write_done, req);
457 static NTSTATUS rpc_write_recv(struct tevent_req *req)
459 return tevent_req_simple_recv_ntstatus(req);
463 /****************************************************************************
464 Try and get a PDU's worth of data from current_pdu. If not, then read more
466 ****************************************************************************/
468 struct get_complete_frag_state {
469 struct event_context *ev;
470 struct rpc_pipe_client *cli;
475 static void get_complete_frag_got_header(struct tevent_req *subreq);
476 static void get_complete_frag_got_rest(struct tevent_req *subreq);
478 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
479 struct event_context *ev,
480 struct rpc_pipe_client *cli,
483 struct tevent_req *req, *subreq;
484 struct get_complete_frag_state *state;
489 req = tevent_req_create(mem_ctx, &state,
490 struct get_complete_frag_state);
496 state->frag_len = RPC_HEADER_LEN;
499 pdu_len = prs_data_size(pdu);
500 if (pdu_len < RPC_HEADER_LEN) {
501 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
502 status = NT_STATUS_NO_MEMORY;
505 subreq = rpc_read_send(
507 state->cli->transport,
508 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
509 RPC_HEADER_LEN - pdu_len);
510 if (subreq == NULL) {
511 status = NT_STATUS_NO_MEMORY;
514 tevent_req_set_callback(subreq, get_complete_frag_got_header,
519 blob = data_blob_const(prs_data_p(state->pdu), pdu_len);
520 state->frag_len = dcerpc_get_frag_length(&blob);
523 * Ensure we have frag_len bytes of data.
525 if (pdu_len < state->frag_len) {
526 if (!rpc_grow_buffer(pdu, state->frag_len)) {
527 status = NT_STATUS_NO_MEMORY;
530 subreq = rpc_read_send(state, state->ev,
531 state->cli->transport,
532 (uint8_t *)(prs_data_p(pdu) + pdu_len),
533 state->frag_len - pdu_len);
534 if (subreq == NULL) {
535 status = NT_STATUS_NO_MEMORY;
538 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
543 status = NT_STATUS_OK;
545 if (NT_STATUS_IS_OK(status)) {
546 tevent_req_done(req);
548 tevent_req_nterror(req, status);
550 return tevent_req_post(req, ev);
553 static void get_complete_frag_got_header(struct tevent_req *subreq)
555 struct tevent_req *req = tevent_req_callback_data(
556 subreq, struct tevent_req);
557 struct get_complete_frag_state *state = tevent_req_data(
558 req, struct get_complete_frag_state);
562 status = rpc_read_recv(subreq);
564 if (!NT_STATUS_IS_OK(status)) {
565 tevent_req_nterror(req, status);
569 pdu = data_blob_const(prs_data_p(state->pdu),
570 prs_data_size(state->pdu));
571 state->frag_len = dcerpc_get_frag_length(&pdu);
573 if (!rpc_grow_buffer(state->pdu, state->frag_len)) {
574 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
579 * We're here in this piece of code because we've read exactly
580 * RPC_HEADER_LEN bytes into state->pdu.
583 subreq = rpc_read_send(
584 state, state->ev, state->cli->transport,
585 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
586 state->frag_len - RPC_HEADER_LEN);
587 if (tevent_req_nomem(subreq, req)) {
590 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
593 static void get_complete_frag_got_rest(struct tevent_req *subreq)
595 struct tevent_req *req = tevent_req_callback_data(
596 subreq, struct tevent_req);
599 status = rpc_read_recv(subreq);
601 if (!NT_STATUS_IS_OK(status)) {
602 tevent_req_nterror(req, status);
605 tevent_req_done(req);
608 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
610 return tevent_req_simple_recv_ntstatus(req);
613 /****************************************************************************
614 NTLMSSP specific sign/seal.
615 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
616 In fact I should probably abstract these into identical pieces of code... JRA.
617 ****************************************************************************/
619 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
620 struct ncacn_packet *pkt,
621 prs_struct *current_pdu,
622 uint8 *p_ss_padding_len)
624 uint8_t *frag_data = (uint8_t *)prs_data_p(current_pdu);
625 struct dcerpc_auth auth_info;
629 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
630 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
634 if (!cli->auth->a_u.ntlmssp_state) {
635 return NT_STATUS_INVALID_PARAMETER;
638 /* Ensure there's enough data for an authenticated response. */
639 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
640 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
641 + DCERPC_AUTH_TRAILER_LENGTH
642 + pkt->auth_length)) {
643 DEBUG(0, ("auth_len %u is too long.\n",
644 (unsigned int)pkt->auth_length));
645 return NT_STATUS_BUFFER_TOO_SMALL;
648 /* get the auth blob at the end of the packet */
649 blob = data_blob_const(frag_data + pkt->frag_length
650 - DCERPC_AUTH_TRAILER_LENGTH
652 DCERPC_AUTH_TRAILER_LENGTH
655 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
656 if (!NT_STATUS_IS_OK(status)) {
657 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
661 /* Ensure auth_pad_len fits into the packet. */
662 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
663 + auth_info.auth_pad_length
664 + DCERPC_AUTH_TRAILER_LENGTH
665 + pkt->auth_length) {
666 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
667 "too large (%u), auth_len (%u), frag_len = (%u).\n",
668 (unsigned int)auth_info.auth_pad_length,
669 (unsigned int)pkt->auth_length,
670 (unsigned int)pkt->frag_length));
671 return NT_STATUS_BUFFER_TOO_SMALL;
675 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
676 * after the RPC header.
677 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
678 * functions as NTLMv2 checks the rpc headers also.
681 switch (cli->auth->auth_level) {
682 case DCERPC_AUTH_LEVEL_PRIVACY:
683 /* Data is encrypted. */
684 status = ntlmssp_unseal_packet(
685 cli->auth->a_u.ntlmssp_state,
686 &frag_data[DCERPC_RESPONSE_LENGTH],
688 - DCERPC_RESPONSE_LENGTH
689 - DCERPC_AUTH_TRAILER_LENGTH
692 pkt->frag_length - pkt->auth_length,
693 &auth_info.credentials);
694 if (!NT_STATUS_IS_OK(status)) {
695 DEBUG(0, ("failed to unseal packet from %s."
697 rpccli_pipe_txt(talloc_tos(), cli),
703 case DCERPC_AUTH_LEVEL_INTEGRITY:
704 /* Data is signed. */
705 status = ntlmssp_check_packet(
706 cli->auth->a_u.ntlmssp_state,
707 &frag_data[DCERPC_RESPONSE_LENGTH],
709 - DCERPC_RESPONSE_LENGTH
710 - DCERPC_AUTH_TRAILER_LENGTH
713 pkt->frag_length - pkt->auth_length,
714 &auth_info.credentials);
715 if (!NT_STATUS_IS_OK(status)) {
716 DEBUG(0, ("check signing failed on packet from %s."
718 rpccli_pipe_txt(talloc_tos(), cli),
725 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
726 "auth level %d\n", cli->auth->auth_level));
727 return NT_STATUS_INVALID_INFO_CLASS;
731 * Remember the padding length. We must remove it from the real data
732 * stream once the sign/seal is done.
735 *p_ss_padding_len = auth_info.auth_pad_length;
740 /****************************************************************************
741 schannel specific sign/seal.
742 ****************************************************************************/
744 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
745 struct ncacn_packet *pkt,
746 prs_struct *current_pdu,
747 uint8 *p_ss_padding_len)
749 uint8_t *frag_data = (uint8_t *)prs_data_p(current_pdu);
750 struct dcerpc_auth auth_info;
754 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
755 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
759 if (pkt->auth_length < SCHANNEL_SIG_SIZE) {
760 DEBUG(0, ("auth_len %u.\n", (unsigned int)pkt->auth_length));
761 return NT_STATUS_INVALID_PARAMETER;
764 if (!cli->auth->a_u.schannel_auth) {
765 return NT_STATUS_INVALID_PARAMETER;
768 /* Ensure there's enough data for an authenticated response. */
769 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
770 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
771 + DCERPC_AUTH_TRAILER_LENGTH
772 + pkt->auth_length)) {
773 DEBUG(0, ("auth_len %u is too long.\n",
774 (unsigned int)pkt->auth_length));
775 return NT_STATUS_INVALID_PARAMETER;
778 /* get the auth blob at the end of the packet */
779 blob = data_blob_const(frag_data + pkt->frag_length
780 - DCERPC_AUTH_TRAILER_LENGTH
782 DCERPC_AUTH_TRAILER_LENGTH
786 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
787 if (!NT_STATUS_IS_OK(status)) {
788 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
792 /* Ensure auth_pad_len fits into the packet. */
793 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
794 + auth_info.auth_pad_length
795 + DCERPC_AUTH_TRAILER_LENGTH
796 + pkt->auth_length) {
797 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
798 "too large (%u), auth_len (%u), frag_len = (%u).\n",
799 (unsigned int)auth_info.auth_pad_length,
800 (unsigned int)pkt->auth_length,
801 (unsigned int)pkt->frag_length));
802 return NT_STATUS_BUFFER_TOO_SMALL;
805 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
806 DEBUG(0, ("Invalid auth info %d on schannel\n",
807 auth_info.auth_type));
808 return NT_STATUS_BUFFER_TOO_SMALL;
811 if (DEBUGLEVEL >= 10) {
812 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_info.credentials);
815 switch (cli->auth->auth_level) {
816 case DCERPC_AUTH_LEVEL_PRIVACY:
817 status = netsec_incoming_packet(
818 cli->auth->a_u.schannel_auth,
821 &frag_data[DCERPC_RESPONSE_LENGTH],
823 - DCERPC_RESPONSE_LENGTH
824 - DCERPC_AUTH_TRAILER_LENGTH
826 &auth_info.credentials);
828 case DCERPC_AUTH_LEVEL_INTEGRITY:
829 status = netsec_incoming_packet(
830 cli->auth->a_u.schannel_auth,
833 &frag_data[DCERPC_RESPONSE_LENGTH],
835 - DCERPC_RESPONSE_LENGTH
836 - DCERPC_AUTH_TRAILER_LENGTH
838 &auth_info.credentials);
841 status = NT_STATUS_INTERNAL_ERROR;
845 if (!NT_STATUS_IS_OK(status)) {
846 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
847 "Connection to %s (%s).\n",
848 rpccli_pipe_txt(talloc_tos(), cli),
850 return NT_STATUS_INVALID_PARAMETER;
854 * Remember the padding length. We must remove it from the real data
855 * stream once the sign/seal is done.
858 *p_ss_padding_len = auth_info.auth_pad_length;
863 /****************************************************************************
864 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
865 ****************************************************************************/
867 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
868 struct ncacn_packet *pkt,
869 prs_struct *current_pdu,
870 uint8 *p_ss_padding_len)
872 NTSTATUS ret = NT_STATUS_OK;
874 /* Paranioa checks for auth_len. */
875 if (pkt->auth_length) {
876 if (pkt->auth_length > pkt->frag_length) {
877 return NT_STATUS_INVALID_PARAMETER;
880 if ((pkt->auth_length
881 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
882 < pkt->auth_length) ||
884 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
885 < (unsigned int)DCERPC_AUTH_TRAILER_LENGTH)) {
886 /* Integer wrap attempt. */
887 return NT_STATUS_INVALID_PARAMETER;
892 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
895 switch(cli->auth->auth_type) {
896 case PIPE_AUTH_TYPE_NONE:
897 if (pkt->auth_length) {
898 DEBUG(3, ("cli_pipe_validate_rpc_response: "
899 "Connection to %s - got non-zero "
901 rpccli_pipe_txt(talloc_tos(), cli),
902 (unsigned int)pkt->auth_length));
903 return NT_STATUS_INVALID_PARAMETER;
907 case PIPE_AUTH_TYPE_NTLMSSP:
908 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
909 ret = cli_pipe_verify_ntlmssp(cli, pkt, current_pdu,
911 if (!NT_STATUS_IS_OK(ret)) {
916 case PIPE_AUTH_TYPE_SCHANNEL:
917 ret = cli_pipe_verify_schannel(cli, pkt, current_pdu,
919 if (!NT_STATUS_IS_OK(ret)) {
924 case PIPE_AUTH_TYPE_KRB5:
925 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
927 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
928 "to %s - unknown internal auth type %u.\n",
929 rpccli_pipe_txt(talloc_tos(), cli),
930 cli->auth->auth_type ));
931 return NT_STATUS_INVALID_INFO_CLASS;
937 /****************************************************************************
938 Do basic authentication checks on an incoming pdu.
939 ****************************************************************************/
941 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
942 struct ncacn_packet *pkt,
943 prs_struct *current_pdu,
944 uint8 expected_pkt_type,
947 prs_struct *return_data)
949 NTSTATUS ret = NT_STATUS_OK;
950 uint32 current_pdu_len = prs_data_size(current_pdu);
951 DATA_BLOB blob = data_blob_const(prs_data_p(current_pdu),
952 prs_data_size(current_pdu));
954 ret = dcerpc_pull_ncacn_packet(cli, &blob, pkt);
955 if (!NT_STATUS_IS_OK(ret)) {
959 /* FIXME: although we already unmarshalled the whole packet,
960 * set the offset of the pdu to right after the header
961 * until the rest of the code downstream is changed
962 * to always use the already decoded packet and not try
963 * to unmarshall bits of the packet.
965 if (!prs_set_offset(current_pdu,
966 prs_offset(current_pdu) + RPC_HEADER_LEN)) {
967 return NT_STATUS_BUFFER_TOO_SMALL;
970 if (current_pdu_len != pkt->frag_length) {
971 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
972 (unsigned int)current_pdu_len,
973 (unsigned int)pkt->frag_length));
974 return NT_STATUS_INVALID_PARAMETER;
978 * Point the return values at the real data including the RPC
979 * header. Just in case the caller wants it.
981 *ppdata = prs_data_p(current_pdu);
982 *pdata_len = current_pdu_len;
984 /* Ensure we have the correct type. */
985 switch (pkt->ptype) {
986 case DCERPC_PKT_ALTER_RESP:
987 case DCERPC_PKT_BIND_ACK:
989 /* Alter context and bind ack share the same packet definitions. */
993 case DCERPC_PKT_RESPONSE:
995 uint8 ss_padding_len = 0;
997 if (!prs_set_offset(current_pdu, prs_offset(current_pdu) + RPC_HDR_RESP_LEN)) {
998 return NT_STATUS_BUFFER_TOO_SMALL;
1001 /* Here's where we deal with incoming sign/seal. */
1002 ret = cli_pipe_validate_rpc_response(cli, pkt,
1003 current_pdu, &ss_padding_len);
1004 if (!NT_STATUS_IS_OK(ret)) {
1008 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1009 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1011 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1012 return NT_STATUS_BUFFER_TOO_SMALL;
1015 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1017 /* Remember to remove the auth footer. */
1018 if (pkt->auth_length) {
1019 /* We've already done integer wrap tests on auth_len in
1020 cli_pipe_validate_rpc_response(). */
1021 if (*pdata_len < RPC_HDR_AUTH_LEN + pkt->auth_length) {
1022 return NT_STATUS_BUFFER_TOO_SMALL;
1024 *pdata_len -= (RPC_HDR_AUTH_LEN + pkt->auth_length);
1027 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1028 current_pdu_len, *pdata_len, ss_padding_len ));
1031 * If this is the first reply, and the allocation hint is reasonably, try and
1032 * set up the return_data parse_struct to the correct size.
1035 if ((prs_data_size(return_data) == 0) &&
1036 pkt->u.response.alloc_hint &&
1037 (pkt->u.response.alloc_hint < 15*1024*1024)) {
1038 if (!prs_set_buffer_size(return_data,
1039 pkt->u.response.alloc_hint)) {
1040 DEBUG(0, ("reply alloc hint %d too "
1041 "large to allocate\n",
1042 (int)pkt->u.response.alloc_hint));
1043 return NT_STATUS_NO_MEMORY;
1050 case DCERPC_PKT_BIND_NAK:
1051 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1052 "received from %s!\n",
1053 rpccli_pipe_txt(talloc_tos(), cli)));
1054 /* Use this for now... */
1055 return NT_STATUS_NETWORK_ACCESS_DENIED;
1057 case DCERPC_PKT_FAULT:
1059 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1060 "code %s received from %s!\n",
1061 dcerpc_errstr(talloc_tos(),
1062 pkt->u.fault.status),
1063 rpccli_pipe_txt(talloc_tos(), cli)));
1065 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
1066 return NT_STATUS_UNSUCCESSFUL;
1068 return NT_STATUS(pkt->u.fault.status);
1072 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1074 (unsigned int)pkt->ptype,
1075 rpccli_pipe_txt(talloc_tos(), cli)));
1076 return NT_STATUS_INVALID_INFO_CLASS;
1079 if (pkt->ptype != expected_pkt_type) {
1080 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1081 "got an unexpected RPC packet type - %u, not %u\n",
1082 rpccli_pipe_txt(talloc_tos(), cli),
1084 expected_pkt_type));
1085 return NT_STATUS_INVALID_INFO_CLASS;
1088 /* Do this just before return - we don't want to modify any rpc header
1089 data before now as we may have needed to do cryptographic actions on
1092 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
1093 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1094 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1095 "setting fragment first/last ON.\n"));
1096 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
1097 DCERPC_PFC_FLAG_LAST;
1100 return NT_STATUS_OK;
1103 /****************************************************************************
1104 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1105 Normally the frag_len and buffer size will match, but on the first trans
1106 reply there is a theoretical chance that buffer size > frag_len, so we must
1108 ****************************************************************************/
1110 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1111 struct ncacn_packet *pkt,
1112 prs_struct *current_pdu)
1114 uint32 current_pdu_len = prs_data_size(current_pdu);
1116 if (current_pdu_len < pkt->frag_length) {
1117 return NT_STATUS_BUFFER_TOO_SMALL;
1121 if (current_pdu_len == (uint32)pkt->frag_length) {
1122 prs_mem_free(current_pdu);
1123 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1124 /* Make current_pdu dynamic with no memory. */
1125 prs_give_memory(current_pdu, 0, 0, True);
1126 return NT_STATUS_OK;
1130 * Oh no ! More data in buffer than we processed in current pdu.
1131 * Cheat. Move the data down and shrink the buffer.
1134 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + pkt->frag_length,
1135 current_pdu_len - pkt->frag_length);
1137 /* Remember to set the read offset back to zero. */
1138 prs_set_offset(current_pdu, 0);
1140 /* Shrink the buffer. */
1141 if (!prs_set_buffer_size(current_pdu, current_pdu_len - pkt->frag_length)) {
1142 return NT_STATUS_BUFFER_TOO_SMALL;
1145 return NT_STATUS_OK;
1148 /****************************************************************************
1149 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1150 ****************************************************************************/
1152 struct cli_api_pipe_state {
1153 struct event_context *ev;
1154 struct rpc_cli_transport *transport;
1159 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1160 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1161 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1163 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1164 struct event_context *ev,
1165 struct rpc_cli_transport *transport,
1166 uint8_t *data, size_t data_len,
1167 uint32_t max_rdata_len)
1169 struct tevent_req *req, *subreq;
1170 struct cli_api_pipe_state *state;
1173 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1178 state->transport = transport;
1180 if (max_rdata_len < RPC_HEADER_LEN) {
1182 * For a RPC reply we always need at least RPC_HEADER_LEN
1183 * bytes. We check this here because we will receive
1184 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1186 status = NT_STATUS_INVALID_PARAMETER;
1190 if (transport->trans_send != NULL) {
1191 subreq = transport->trans_send(state, ev, data, data_len,
1192 max_rdata_len, transport->priv);
1193 if (subreq == NULL) {
1196 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1201 * If the transport does not provide a "trans" routine, i.e. for
1202 * example the ncacn_ip_tcp transport, do the write/read step here.
1205 subreq = rpc_write_send(state, ev, transport, data, data_len);
1206 if (subreq == NULL) {
1209 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1213 tevent_req_nterror(req, status);
1214 return tevent_req_post(req, ev);
1220 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1222 struct tevent_req *req = tevent_req_callback_data(
1223 subreq, struct tevent_req);
1224 struct cli_api_pipe_state *state = tevent_req_data(
1225 req, struct cli_api_pipe_state);
1228 status = state->transport->trans_recv(subreq, state, &state->rdata,
1230 TALLOC_FREE(subreq);
1231 if (!NT_STATUS_IS_OK(status)) {
1232 tevent_req_nterror(req, status);
1235 tevent_req_done(req);
1238 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1240 struct tevent_req *req = tevent_req_callback_data(
1241 subreq, struct tevent_req);
1242 struct cli_api_pipe_state *state = tevent_req_data(
1243 req, struct cli_api_pipe_state);
1246 status = rpc_write_recv(subreq);
1247 TALLOC_FREE(subreq);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 tevent_req_nterror(req, status);
1253 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1254 if (tevent_req_nomem(state->rdata, req)) {
1259 * We don't need to use rpc_read_send here, the upper layer will cope
1260 * with a short read, transport->trans_send could also return less
1261 * than state->max_rdata_len.
1263 subreq = state->transport->read_send(state, state->ev, state->rdata,
1265 state->transport->priv);
1266 if (tevent_req_nomem(subreq, req)) {
1269 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1272 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1274 struct tevent_req *req = tevent_req_callback_data(
1275 subreq, struct tevent_req);
1276 struct cli_api_pipe_state *state = tevent_req_data(
1277 req, struct cli_api_pipe_state);
1281 status = state->transport->read_recv(subreq, &received);
1282 TALLOC_FREE(subreq);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 tevent_req_nterror(req, status);
1287 state->rdata_len = received;
1288 tevent_req_done(req);
1291 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1292 uint8_t **prdata, uint32_t *prdata_len)
1294 struct cli_api_pipe_state *state = tevent_req_data(
1295 req, struct cli_api_pipe_state);
1298 if (tevent_req_is_nterror(req, &status)) {
1302 *prdata = talloc_move(mem_ctx, &state->rdata);
1303 *prdata_len = state->rdata_len;
1304 return NT_STATUS_OK;
1307 /****************************************************************************
1308 Send data on an rpc pipe via trans. The prs_struct data must be the last
1309 pdu fragment of an NDR data stream.
1311 Receive response data from an rpc pipe, which may be large...
1313 Read the first fragment: unfortunately have to use SMBtrans for the first
1314 bit, then SMBreadX for subsequent bits.
1316 If first fragment received also wasn't the last fragment, continue
1317 getting fragments until we _do_ receive the last fragment.
1319 Request/Response PDU's look like the following...
1321 |<------------------PDU len----------------------------------------------->|
1322 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1324 +------------+-----------------+-------------+---------------+-------------+
1325 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1326 +------------+-----------------+-------------+---------------+-------------+
1328 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1329 signing & sealing being negotiated.
1331 ****************************************************************************/
1333 struct rpc_api_pipe_state {
1334 struct event_context *ev;
1335 struct rpc_pipe_client *cli;
1336 uint8_t expected_pkt_type;
1338 prs_struct incoming_frag;
1339 struct ncacn_packet *pkt;
1341 prs_struct incoming_pdu; /* Incoming reply */
1342 uint32_t incoming_pdu_offset;
1345 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1346 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1348 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1349 struct event_context *ev,
1350 struct rpc_pipe_client *cli,
1351 prs_struct *data, /* Outgoing PDU */
1352 uint8_t expected_pkt_type)
1354 struct tevent_req *req, *subreq;
1355 struct rpc_api_pipe_state *state;
1356 uint16_t max_recv_frag;
1359 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1365 state->expected_pkt_type = expected_pkt_type;
1366 state->incoming_pdu_offset = 0;
1368 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1370 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1371 /* Make incoming_pdu dynamic with no memory. */
1372 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1375 * Ensure we're not sending too much.
1377 if (prs_offset(data) > cli->max_xmit_frag) {
1378 status = NT_STATUS_INVALID_PARAMETER;
1382 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1384 max_recv_frag = cli->max_recv_frag;
1387 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1390 subreq = cli_api_pipe_send(state, ev, cli->transport,
1391 (uint8_t *)prs_data_p(data),
1392 prs_offset(data), max_recv_frag);
1393 if (subreq == NULL) {
1396 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1400 tevent_req_nterror(req, status);
1401 return tevent_req_post(req, ev);
1407 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1409 struct tevent_req *req = tevent_req_callback_data(
1410 subreq, struct tevent_req);
1411 struct rpc_api_pipe_state *state = tevent_req_data(
1412 req, struct rpc_api_pipe_state);
1414 uint8_t *rdata = NULL;
1415 uint32_t rdata_len = 0;
1417 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1418 TALLOC_FREE(subreq);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1421 tevent_req_nterror(req, status);
1425 if (rdata == NULL) {
1426 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1427 rpccli_pipe_txt(talloc_tos(), state->cli)));
1428 tevent_req_done(req);
1433 * This is equivalent to a talloc_steal - gives rdata to
1434 * the prs_struct state->incoming_frag.
1436 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1439 /* Ensure we have enough data for a pdu. */
1440 subreq = get_complete_frag_send(state, state->ev, state->cli,
1441 &state->incoming_frag);
1442 if (tevent_req_nomem(subreq, req)) {
1445 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1448 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1450 struct tevent_req *req = tevent_req_callback_data(
1451 subreq, struct tevent_req);
1452 struct rpc_api_pipe_state *state = tevent_req_data(
1453 req, struct rpc_api_pipe_state);
1456 uint32_t rdata_len = 0;
1458 status = get_complete_frag_recv(subreq);
1459 TALLOC_FREE(subreq);
1460 if (!NT_STATUS_IS_OK(status)) {
1461 DEBUG(5, ("get_complete_frag failed: %s\n",
1462 nt_errstr(status)));
1463 tevent_req_nterror(req, status);
1467 state->pkt = talloc(state, struct ncacn_packet);
1469 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1473 status = cli_pipe_validate_current_pdu(
1474 state->cli, state->pkt, &state->incoming_frag,
1475 state->expected_pkt_type, &rdata, &rdata_len,
1476 &state->incoming_pdu);
1478 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1479 (unsigned)prs_data_size(&state->incoming_frag),
1480 (unsigned)state->incoming_pdu_offset,
1481 nt_errstr(status)));
1483 if (!NT_STATUS_IS_OK(status)) {
1484 tevent_req_nterror(req, status);
1488 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1489 && (state->pkt->drep[0] == 0)) {
1491 * Set the data type correctly for big-endian data on the
1494 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1496 rpccli_pipe_txt(talloc_tos(), state->cli)));
1497 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1500 * Check endianness on subsequent packets.
1502 if (state->incoming_frag.bigendian_data
1503 != state->incoming_pdu.bigendian_data) {
1504 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1506 state->incoming_pdu.bigendian_data?"big":"little",
1507 state->incoming_frag.bigendian_data?"big":"little"));
1508 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1512 /* Now copy the data portion out of the pdu into rbuf. */
1513 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1514 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1518 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1519 rdata, (size_t)rdata_len);
1520 state->incoming_pdu_offset += rdata_len;
1522 status = cli_pipe_reset_current_pdu(state->cli, state->pkt,
1523 &state->incoming_frag);
1524 if (!NT_STATUS_IS_OK(status)) {
1525 tevent_req_nterror(req, status);
1529 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1530 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1531 rpccli_pipe_txt(talloc_tos(), state->cli),
1532 (unsigned)prs_data_size(&state->incoming_pdu)));
1533 tevent_req_done(req);
1537 subreq = get_complete_frag_send(state, state->ev, state->cli,
1538 &state->incoming_frag);
1539 if (tevent_req_nomem(subreq, req)) {
1542 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1545 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1546 struct ncacn_packet **pkt,
1547 prs_struct *reply_pdu)
1549 struct rpc_api_pipe_state *state = tevent_req_data(
1550 req, struct rpc_api_pipe_state);
1553 if (tevent_req_is_nterror(req, &status)) {
1557 *reply_pdu = state->incoming_pdu;
1558 reply_pdu->mem_ctx = mem_ctx;
1561 * Prevent state->incoming_pdu from being freed
1562 * when state is freed.
1564 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1565 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1568 *pkt = talloc_steal(mem_ctx, state->pkt);
1571 return NT_STATUS_OK;
1574 /*******************************************************************
1575 Creates krb5 auth bind.
1576 ********************************************************************/
1578 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1579 enum dcerpc_AuthLevel auth_level,
1580 DATA_BLOB *auth_info)
1585 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1586 DATA_BLOB tkt = data_blob_null;
1587 DATA_BLOB tkt_wrapped = data_blob_null;
1589 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1590 a->service_principal ));
1592 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1594 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1595 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1598 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1600 a->service_principal,
1601 error_message(ret) ));
1603 data_blob_free(&tkt);
1604 return NT_STATUS_INVALID_PARAMETER;
1607 /* wrap that up in a nice GSS-API wrapping */
1608 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1610 data_blob_free(&tkt);
1612 status = dcerpc_push_dcerpc_auth(cli,
1613 DCERPC_AUTH_TYPE_KRB5,
1615 0, /* auth_pad_length */
1616 1, /* auth_context_id */
1619 if (!NT_STATUS_IS_OK(status)) {
1620 data_blob_free(&tkt_wrapped);
1624 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1625 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1627 return NT_STATUS_OK;
1629 return NT_STATUS_INVALID_PARAMETER;
1633 /*******************************************************************
1634 Creates SPNEGO NTLMSSP auth bind.
1635 ********************************************************************/
1637 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1638 enum dcerpc_AuthLevel auth_level,
1639 DATA_BLOB *auth_info)
1642 DATA_BLOB null_blob = data_blob_null;
1643 DATA_BLOB request = data_blob_null;
1644 DATA_BLOB spnego_msg = data_blob_null;
1646 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1647 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1651 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1652 data_blob_free(&request);
1656 /* Wrap this in SPNEGO. */
1657 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1659 data_blob_free(&request);
1661 status = dcerpc_push_dcerpc_auth(cli,
1662 DCERPC_AUTH_TYPE_SPNEGO,
1664 0, /* auth_pad_length */
1665 1, /* auth_context_id */
1668 if (!NT_STATUS_IS_OK(status)) {
1669 data_blob_free(&spnego_msg);
1673 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1674 dump_data(5, spnego_msg.data, spnego_msg.length);
1676 return NT_STATUS_OK;
1679 /*******************************************************************
1680 Creates NTLMSSP auth bind.
1681 ********************************************************************/
1683 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1684 enum dcerpc_AuthLevel auth_level,
1685 DATA_BLOB *auth_info)
1688 DATA_BLOB null_blob = data_blob_null;
1689 DATA_BLOB request = data_blob_null;
1691 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1692 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1696 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1697 data_blob_free(&request);
1701 status = dcerpc_push_dcerpc_auth(cli,
1702 DCERPC_AUTH_TYPE_NTLMSSP,
1704 0, /* auth_pad_length */
1705 1, /* auth_context_id */
1708 if (!NT_STATUS_IS_OK(status)) {
1709 data_blob_free(&request);
1713 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1714 dump_data(5, request.data, request.length);
1716 return NT_STATUS_OK;
1719 /*******************************************************************
1720 Creates schannel auth bind.
1721 ********************************************************************/
1723 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1724 enum dcerpc_AuthLevel auth_level,
1725 DATA_BLOB *auth_info)
1728 struct NL_AUTH_MESSAGE r;
1729 DATA_BLOB schannel_blob;
1731 /* Use lp_workgroup() if domain not specified */
1733 if (!cli->auth->domain || !cli->auth->domain[0]) {
1734 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1735 if (cli->auth->domain == NULL) {
1736 return NT_STATUS_NO_MEMORY;
1741 * Now marshall the data into the auth parse_struct.
1744 r.MessageType = NL_NEGOTIATE_REQUEST;
1745 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1746 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1747 r.oem_netbios_domain.a = cli->auth->domain;
1748 r.oem_netbios_computer.a = global_myname();
1750 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1751 if (!NT_STATUS_IS_OK(status)) {
1755 status = dcerpc_push_dcerpc_auth(cli,
1756 DCERPC_AUTH_TYPE_SCHANNEL,
1758 0, /* auth_pad_length */
1759 1, /* auth_context_id */
1762 if (!NT_STATUS_IS_OK(status)) {
1766 return NT_STATUS_OK;
1769 /*******************************************************************
1770 ********************************************************************/
1772 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1773 const struct ndr_syntax_id *abstract_syntax,
1774 const struct ndr_syntax_id *transfer_syntax,
1775 struct dcerpc_ctx_list **ctx_list_p)
1777 struct dcerpc_ctx_list *ctx_list;
1779 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1780 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1782 ctx_list[0].context_id = 0;
1783 ctx_list[0].num_transfer_syntaxes = 1;
1784 ctx_list[0].abstract_syntax = *abstract_syntax;
1785 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
1786 struct ndr_syntax_id,
1787 ctx_list[0].num_transfer_syntaxes);
1788 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1789 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
1791 *ctx_list_p = ctx_list;
1793 return NT_STATUS_OK;
1796 /*******************************************************************
1797 Creates the internals of a DCE/RPC bind request or alter context PDU.
1798 ********************************************************************/
1800 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
1801 prs_struct *rpc_out,
1803 const struct ndr_syntax_id *abstract,
1804 const struct ndr_syntax_id *transfer,
1805 const DATA_BLOB *auth_info)
1807 uint16 auth_len = auth_info->length;
1809 union dcerpc_payload u;
1811 struct dcerpc_ctx_list *ctx_list;
1813 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
1815 if (!NT_STATUS_IS_OK(status)) {
1819 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1820 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1821 u.bind.assoc_group_id = 0x0;
1822 u.bind.num_contexts = 1;
1823 u.bind.ctx_list = ctx_list;
1824 u.bind.auth_info = *auth_info;
1826 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
1828 DCERPC_PFC_FLAG_FIRST |
1829 DCERPC_PFC_FLAG_LAST,
1830 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
1834 if (!NT_STATUS_IS_OK(status)) {
1835 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1839 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
1840 return NT_STATUS_NO_MEMORY;
1843 return NT_STATUS_OK;
1846 /*******************************************************************
1847 Creates a DCE/RPC bind request.
1848 ********************************************************************/
1850 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1851 prs_struct *rpc_out,
1853 const struct ndr_syntax_id *abstract,
1854 const struct ndr_syntax_id *transfer,
1855 enum pipe_auth_type auth_type,
1856 enum dcerpc_AuthLevel auth_level)
1858 DATA_BLOB auth_info = data_blob_null;
1859 NTSTATUS ret = NT_STATUS_OK;
1861 switch (auth_type) {
1862 case PIPE_AUTH_TYPE_SCHANNEL:
1863 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
1864 if (!NT_STATUS_IS_OK(ret)) {
1869 case PIPE_AUTH_TYPE_NTLMSSP:
1870 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1871 if (!NT_STATUS_IS_OK(ret)) {
1876 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1877 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1878 if (!NT_STATUS_IS_OK(ret)) {
1883 case PIPE_AUTH_TYPE_KRB5:
1884 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
1885 if (!NT_STATUS_IS_OK(ret)) {
1890 case PIPE_AUTH_TYPE_NONE:
1894 /* "Can't" happen. */
1895 return NT_STATUS_INVALID_INFO_CLASS;
1898 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1907 /*******************************************************************
1908 Create and add the NTLMSSP sign/seal auth header and data.
1909 ********************************************************************/
1911 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1912 uint32 ss_padding_len,
1913 prs_struct *rpc_out)
1915 DATA_BLOB auth_info;
1917 DATA_BLOB auth_blob = data_blob_null;
1918 uint16_t data_and_pad_len =
1919 prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1921 if (!cli->auth->a_u.ntlmssp_state) {
1922 return NT_STATUS_INVALID_PARAMETER;
1925 /* marshall the dcerpc_auth with an actually empty auth_blob.
1926 * this is needed because the ntmlssp signature includes the
1928 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
1929 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1930 cli->auth->auth_level,
1932 1 /* context id. */,
1935 if (!NT_STATUS_IS_OK(status)) {
1939 /* append the header */
1940 if (!prs_copy_data_in(rpc_out,
1941 (char *)auth_info.data,
1942 auth_info.length)) {
1943 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1944 (unsigned int)auth_info.length));
1945 return NT_STATUS_NO_MEMORY;
1948 switch (cli->auth->auth_level) {
1949 case DCERPC_AUTH_LEVEL_PRIVACY:
1950 /* Data portion is encrypted. */
1951 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1952 prs_get_mem_context(rpc_out),
1953 (unsigned char *)prs_data_p(rpc_out)
1957 (unsigned char *)prs_data_p(rpc_out),
1958 (size_t)prs_offset(rpc_out),
1960 if (!NT_STATUS_IS_OK(status)) {
1965 case DCERPC_AUTH_LEVEL_INTEGRITY:
1966 /* Data is signed. */
1967 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1968 prs_get_mem_context(rpc_out),
1969 (unsigned char *)prs_data_p(rpc_out)
1973 (unsigned char *)prs_data_p(rpc_out),
1974 (size_t)prs_offset(rpc_out),
1976 if (!NT_STATUS_IS_OK(status)) {
1983 smb_panic("bad auth level");
1985 return NT_STATUS_INVALID_PARAMETER;
1988 /* Finally attach the blob. */
1989 if (!prs_copy_data_in(rpc_out,
1990 (char *)auth_blob.data,
1991 auth_blob.length)) {
1992 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1993 (unsigned int)auth_info.length));
1994 return NT_STATUS_NO_MEMORY;
1997 return NT_STATUS_OK;
2000 /*******************************************************************
2001 Create and add the schannel sign/seal auth header and data.
2002 ********************************************************************/
2004 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2005 uint32 ss_padding_len,
2006 prs_struct *rpc_out)
2008 DATA_BLOB auth_info;
2009 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2010 char *data_p = prs_data_p(rpc_out) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2011 size_t data_and_pad_len = prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2016 return NT_STATUS_INVALID_PARAMETER;
2019 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2022 switch (cli->auth->auth_level) {
2023 case DCERPC_AUTH_LEVEL_PRIVACY:
2024 status = netsec_outgoing_packet(sas,
2031 case DCERPC_AUTH_LEVEL_INTEGRITY:
2032 status = netsec_outgoing_packet(sas,
2040 status = NT_STATUS_INTERNAL_ERROR;
2044 if (!NT_STATUS_IS_OK(status)) {
2045 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2046 nt_errstr(status)));
2050 if (DEBUGLEVEL >= 10) {
2051 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2054 /* Finally marshall the blob. */
2055 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2056 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2057 cli->auth->auth_level,
2059 1 /* context id. */,
2062 if (!NT_STATUS_IS_OK(status)) {
2066 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.length)) {
2067 return NT_STATUS_NO_MEMORY;
2070 return NT_STATUS_OK;
2073 /*******************************************************************
2074 Calculate how much data we're going to send in this packet, also
2075 work out any sign/seal padding length.
2076 ********************************************************************/
2078 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2082 uint32 *p_ss_padding)
2084 uint32 data_space, data_len;
2087 if ((data_left > 0) && (sys_random() % 2)) {
2088 data_left = MAX(data_left/2, 1);
2092 switch (cli->auth->auth_level) {
2093 case DCERPC_AUTH_LEVEL_NONE:
2094 case DCERPC_AUTH_LEVEL_CONNECT:
2095 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2096 data_len = MIN(data_space, data_left);
2099 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2102 case DCERPC_AUTH_LEVEL_INTEGRITY:
2103 case DCERPC_AUTH_LEVEL_PRIVACY:
2104 /* Treat the same for all authenticated rpc requests. */
2105 switch(cli->auth->auth_type) {
2106 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2107 case PIPE_AUTH_TYPE_NTLMSSP:
2108 *p_auth_len = NTLMSSP_SIG_SIZE;
2110 case PIPE_AUTH_TYPE_SCHANNEL:
2111 *p_auth_len = SCHANNEL_SIG_SIZE;
2114 smb_panic("bad auth type");
2118 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2119 RPC_HDR_AUTH_LEN - *p_auth_len;
2121 data_len = MIN(data_space, data_left);
2123 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2124 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2126 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2127 data_len + *p_ss_padding + /* data plus padding. */
2128 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2132 smb_panic("bad auth level");
2138 /*******************************************************************
2140 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2141 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2142 and deals with signing/sealing details.
2143 ********************************************************************/
2145 struct rpc_api_pipe_req_state {
2146 struct event_context *ev;
2147 struct rpc_pipe_client *cli;
2150 prs_struct *req_data;
2151 uint32_t req_data_sent;
2152 prs_struct outgoing_frag;
2153 prs_struct reply_pdu;
2156 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2157 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2158 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2159 bool *is_last_frag);
2161 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2162 struct event_context *ev,
2163 struct rpc_pipe_client *cli,
2165 prs_struct *req_data)
2167 struct tevent_req *req, *subreq;
2168 struct rpc_api_pipe_req_state *state;
2172 req = tevent_req_create(mem_ctx, &state,
2173 struct rpc_api_pipe_req_state);
2179 state->op_num = op_num;
2180 state->req_data = req_data;
2181 state->req_data_sent = 0;
2182 state->call_id = get_rpc_call_id();
2184 if (cli->max_xmit_frag
2185 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2186 /* Server is screwed up ! */
2187 status = NT_STATUS_INVALID_PARAMETER;
2191 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2193 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2198 status = prepare_next_frag(state, &is_last_frag);
2199 if (!NT_STATUS_IS_OK(status)) {
2204 subreq = rpc_api_pipe_send(state, ev, state->cli,
2205 &state->outgoing_frag,
2206 DCERPC_PKT_RESPONSE);
2207 if (subreq == NULL) {
2210 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2212 subreq = rpc_write_send(
2213 state, ev, cli->transport,
2214 (uint8_t *)prs_data_p(&state->outgoing_frag),
2215 prs_offset(&state->outgoing_frag));
2216 if (subreq == NULL) {
2219 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2225 tevent_req_nterror(req, status);
2226 return tevent_req_post(req, ev);
2232 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2235 uint32_t data_sent_thistime;
2239 uint32_t ss_padding;
2241 char pad[8] = { 0, };
2243 union dcerpc_payload u;
2246 data_left = prs_offset(state->req_data) - state->req_data_sent;
2248 data_sent_thistime = calculate_data_len_tosend(
2249 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2251 if (state->req_data_sent == 0) {
2252 flags = DCERPC_PFC_FLAG_FIRST;
2255 if (data_sent_thistime == data_left) {
2256 flags |= DCERPC_PFC_FLAG_LAST;
2259 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2260 return NT_STATUS_NO_MEMORY;
2263 ZERO_STRUCT(u.request);
2265 u.request.alloc_hint = prs_offset(state->req_data);
2266 u.request.context_id = 0;
2267 u.request.opnum = state->op_num;
2269 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2276 if (!NT_STATUS_IS_OK(status)) {
2280 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
2281 * compute it right for requests */
2282 dcerpc_set_frag_length(&blob, frag_len);
2284 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2285 return NT_STATUS_NO_MEMORY;
2288 /* Copy in the data, plus any ss padding. */
2289 if (!prs_append_some_prs_data(&state->outgoing_frag,
2290 state->req_data, state->req_data_sent,
2291 data_sent_thistime)) {
2292 return NT_STATUS_NO_MEMORY;
2295 /* Copy the sign/seal padding data. */
2296 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2297 return NT_STATUS_NO_MEMORY;
2300 /* Generate any auth sign/seal and add the auth footer. */
2301 switch (state->cli->auth->auth_type) {
2302 case PIPE_AUTH_TYPE_NONE:
2303 status = NT_STATUS_OK;
2305 case PIPE_AUTH_TYPE_NTLMSSP:
2306 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2307 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2308 &state->outgoing_frag);
2310 case PIPE_AUTH_TYPE_SCHANNEL:
2311 status = add_schannel_auth_footer(state->cli, ss_padding,
2312 &state->outgoing_frag);
2315 status = NT_STATUS_INVALID_PARAMETER;
2319 state->req_data_sent += data_sent_thistime;
2320 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2325 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2327 struct tevent_req *req = tevent_req_callback_data(
2328 subreq, struct tevent_req);
2329 struct rpc_api_pipe_req_state *state = tevent_req_data(
2330 req, struct rpc_api_pipe_req_state);
2334 status = rpc_write_recv(subreq);
2335 TALLOC_FREE(subreq);
2336 if (!NT_STATUS_IS_OK(status)) {
2337 tevent_req_nterror(req, status);
2341 status = prepare_next_frag(state, &is_last_frag);
2342 if (!NT_STATUS_IS_OK(status)) {
2343 tevent_req_nterror(req, status);
2348 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2349 &state->outgoing_frag,
2350 DCERPC_PKT_RESPONSE);
2351 if (tevent_req_nomem(subreq, req)) {
2354 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2356 subreq = rpc_write_send(
2358 state->cli->transport,
2359 (uint8_t *)prs_data_p(&state->outgoing_frag),
2360 prs_offset(&state->outgoing_frag));
2361 if (tevent_req_nomem(subreq, req)) {
2364 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2369 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2371 struct tevent_req *req = tevent_req_callback_data(
2372 subreq, struct tevent_req);
2373 struct rpc_api_pipe_req_state *state = tevent_req_data(
2374 req, struct rpc_api_pipe_req_state);
2377 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
2378 TALLOC_FREE(subreq);
2379 if (!NT_STATUS_IS_OK(status)) {
2380 tevent_req_nterror(req, status);
2383 tevent_req_done(req);
2386 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2387 prs_struct *reply_pdu)
2389 struct rpc_api_pipe_req_state *state = tevent_req_data(
2390 req, struct rpc_api_pipe_req_state);
2393 if (tevent_req_is_nterror(req, &status)) {
2395 * We always have to initialize to reply pdu, even if there is
2396 * none. The rpccli_* caller routines expect this.
2398 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2402 *reply_pdu = state->reply_pdu;
2403 reply_pdu->mem_ctx = mem_ctx;
2406 * Prevent state->req_pdu from being freed
2407 * when state is freed.
2409 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2410 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2412 return NT_STATUS_OK;
2416 /****************************************************************************
2417 Set the handle state.
2418 ****************************************************************************/
2420 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2421 const char *pipe_name, uint16 device_state)
2423 bool state_set = False;
2425 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2426 char *rparam = NULL;
2428 uint32 rparam_len, rdata_len;
2430 if (pipe_name == NULL)
2433 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2434 cli->fnum, pipe_name, device_state));
2436 /* create parameters: device state */
2437 SSVAL(param, 0, device_state);
2439 /* create setup parameters. */
2441 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2443 /* send the data on \PIPE\ */
2444 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2445 setup, 2, 0, /* setup, length, max */
2446 param, 2, 0, /* param, length, max */
2447 NULL, 0, 1024, /* data, length, max */
2448 &rparam, &rparam_len, /* return param, length */
2449 &rdata, &rdata_len)) /* return data, length */
2451 DEBUG(5, ("Set Handle state: return OK\n"));
2462 /****************************************************************************
2463 Check the rpc bind acknowledge response.
2464 ****************************************************************************/
2466 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2467 const struct ndr_syntax_id *transfer)
2469 struct dcerpc_ack_ctx ctx;
2471 if (r->secondary_address_size == 0) {
2472 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2475 if (r->num_results < 1 || !r->ctx_list) {
2479 ctx = r->ctx_list[0];
2481 /* check the transfer syntax */
2482 if ((ctx.syntax.if_version != transfer->if_version) ||
2483 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2484 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2488 if (r->num_results != 0x1 || ctx.result != 0) {
2489 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2490 r->num_results, ctx.reason));
2493 DEBUG(5,("check_bind_response: accepted!\n"));
2497 /*******************************************************************
2498 Creates a DCE/RPC bind authentication response.
2499 This is the packet that is sent back to the server once we
2500 have received a BIND-ACK, to finish the third leg of
2501 the authentication handshake.
2502 ********************************************************************/
2504 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2506 enum pipe_auth_type auth_type,
2507 enum dcerpc_AuthLevel auth_level,
2508 DATA_BLOB *pauth_blob,
2509 prs_struct *rpc_out)
2512 union dcerpc_payload u;
2517 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2518 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2520 0, /* auth_pad_length */
2521 1, /* auth_context_id */
2523 &u.auth3.auth_info);
2524 if (!NT_STATUS_IS_OK(status)) {
2528 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2530 DCERPC_PFC_FLAG_FIRST |
2531 DCERPC_PFC_FLAG_LAST,
2536 if (!NT_STATUS_IS_OK(status)) {
2537 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2541 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2542 return NT_STATUS_NO_MEMORY;
2545 return NT_STATUS_OK;
2548 /*******************************************************************
2549 Creates a DCE/RPC bind alter context authentication request which
2550 may contain a spnego auth blobl
2551 ********************************************************************/
2553 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2554 const struct ndr_syntax_id *abstract,
2555 const struct ndr_syntax_id *transfer,
2556 enum dcerpc_AuthLevel auth_level,
2557 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2558 prs_struct *rpc_out)
2560 DATA_BLOB auth_info;
2563 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2564 DCERPC_AUTH_TYPE_SPNEGO,
2566 0, /* auth_pad_length */
2567 1, /* auth_context_id */
2570 if (!NT_STATUS_IS_OK(status)) {
2575 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2581 if (!NT_STATUS_IS_OK(status)) {
2588 /****************************************************************************
2590 ****************************************************************************/
2592 struct rpc_pipe_bind_state {
2593 struct event_context *ev;
2594 struct rpc_pipe_client *cli;
2596 uint32_t rpc_call_id;
2599 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2600 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2601 struct rpc_pipe_bind_state *state,
2602 struct ncacn_packet *r,
2603 prs_struct *reply_pdu);
2604 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2605 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2606 struct rpc_pipe_bind_state *state,
2607 struct ncacn_packet *r,
2608 prs_struct *reply_pdu);
2609 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2611 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2612 struct event_context *ev,
2613 struct rpc_pipe_client *cli,
2614 struct cli_pipe_auth_data *auth)
2616 struct tevent_req *req, *subreq;
2617 struct rpc_pipe_bind_state *state;
2620 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2625 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2626 rpccli_pipe_txt(talloc_tos(), cli),
2627 (unsigned int)auth->auth_type,
2628 (unsigned int)auth->auth_level ));
2632 state->rpc_call_id = get_rpc_call_id();
2634 prs_init_empty(&state->rpc_out, state, MARSHALL);
2636 cli->auth = talloc_move(cli, &auth);
2638 /* Marshall the outgoing data. */
2639 status = create_rpc_bind_req(cli, &state->rpc_out,
2641 &cli->abstract_syntax,
2642 &cli->transfer_syntax,
2643 cli->auth->auth_type,
2644 cli->auth->auth_level);
2646 if (!NT_STATUS_IS_OK(status)) {
2650 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2651 DCERPC_PKT_BIND_ACK);
2652 if (subreq == NULL) {
2655 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2659 tevent_req_nterror(req, status);
2660 return tevent_req_post(req, ev);
2666 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2668 struct tevent_req *req = tevent_req_callback_data(
2669 subreq, struct tevent_req);
2670 struct rpc_pipe_bind_state *state = tevent_req_data(
2671 req, struct rpc_pipe_bind_state);
2672 prs_struct reply_pdu;
2673 struct ncacn_packet *pkt;
2676 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
2677 TALLOC_FREE(subreq);
2678 if (!NT_STATUS_IS_OK(status)) {
2679 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2680 rpccli_pipe_txt(talloc_tos(), state->cli),
2681 nt_errstr(status)));
2682 tevent_req_nterror(req, status);
2686 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
2687 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2688 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2692 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
2693 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
2696 * For authenticated binds we may need to do 3 or 4 leg binds.
2699 switch(state->cli->auth->auth_type) {
2701 case PIPE_AUTH_TYPE_NONE:
2702 case PIPE_AUTH_TYPE_SCHANNEL:
2703 /* Bind complete. */
2704 tevent_req_done(req);
2707 case PIPE_AUTH_TYPE_NTLMSSP:
2708 /* Need to send AUTH3 packet - no reply. */
2709 status = rpc_finish_auth3_bind_send(req, state, pkt,
2711 if (!NT_STATUS_IS_OK(status)) {
2712 tevent_req_nterror(req, status);
2716 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2717 /* Need to send alter context request and reply. */
2718 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt,
2720 if (!NT_STATUS_IS_OK(status)) {
2721 tevent_req_nterror(req, status);
2725 case PIPE_AUTH_TYPE_KRB5:
2729 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2730 (unsigned int)state->cli->auth->auth_type));
2731 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2735 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2736 struct rpc_pipe_bind_state *state,
2737 struct ncacn_packet *r,
2738 prs_struct *reply_pdu)
2740 DATA_BLOB client_reply = data_blob_null;
2741 struct dcerpc_auth auth;
2742 struct tevent_req *subreq;
2745 if ((r->auth_length == 0)
2746 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
2747 return NT_STATUS_INVALID_PARAMETER;
2750 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
2751 &r->u.bind_ack.auth_info,
2753 if (!NT_STATUS_IS_OK(status)) {
2754 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2755 nt_errstr(status)));
2759 /* TODO - check auth_type/auth_level match. */
2761 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2762 auth.credentials, &client_reply);
2764 if (!NT_STATUS_IS_OK(status)) {
2765 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2766 "blob failed: %s.\n", nt_errstr(status)));
2770 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2772 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2773 state->cli->auth->auth_type,
2774 state->cli->auth->auth_level,
2775 &client_reply, &state->rpc_out);
2776 data_blob_free(&client_reply);
2778 if (!NT_STATUS_IS_OK(status)) {
2782 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2783 (uint8_t *)prs_data_p(&state->rpc_out),
2784 prs_offset(&state->rpc_out));
2785 if (subreq == NULL) {
2786 return NT_STATUS_NO_MEMORY;
2788 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2789 return NT_STATUS_OK;
2792 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2794 struct tevent_req *req = tevent_req_callback_data(
2795 subreq, struct tevent_req);
2798 status = rpc_write_recv(subreq);
2799 TALLOC_FREE(subreq);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 tevent_req_nterror(req, status);
2804 tevent_req_done(req);
2807 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2808 struct rpc_pipe_bind_state *state,
2809 struct ncacn_packet *r,
2812 DATA_BLOB server_ntlm_response = data_blob_null;
2813 DATA_BLOB client_reply = data_blob_null;
2814 DATA_BLOB tmp_blob = data_blob_null;
2815 struct dcerpc_auth auth_info;
2816 DATA_BLOB auth_blob;
2817 struct tevent_req *subreq;
2820 if ((r->auth_length == 0)
2821 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
2822 return NT_STATUS_INVALID_PARAMETER;
2825 /* Process the returned NTLMSSP blob first. */
2826 if (!prs_set_offset(
2828 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
2829 return NT_STATUS_INVALID_PARAMETER;
2832 auth_blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in),
2833 prs_data_size(rpc_in) - prs_offset(rpc_in));
2835 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
2836 if (!NT_STATUS_IS_OK(status)) {
2837 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
2842 * The server might give us back two challenges - tmp_blob is for the
2845 if (!spnego_parse_challenge(auth_info.credentials,
2846 &server_ntlm_response, &tmp_blob)) {
2847 data_blob_free(&server_ntlm_response);
2848 data_blob_free(&tmp_blob);
2849 return NT_STATUS_INVALID_PARAMETER;
2852 /* We're finished with the server spnego response and the tmp_blob. */
2853 data_blob_free(&tmp_blob);
2855 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2856 server_ntlm_response, &client_reply);
2858 /* Finished with the server_ntlm response */
2859 data_blob_free(&server_ntlm_response);
2861 if (!NT_STATUS_IS_OK(status)) {
2862 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2863 "using server blob failed.\n"));
2864 data_blob_free(&client_reply);
2868 /* SPNEGO wrap the client reply. */
2869 tmp_blob = spnego_gen_auth(client_reply);
2870 data_blob_free(&client_reply);
2871 client_reply = tmp_blob;
2872 tmp_blob = data_blob_null;
2874 /* Now prepare the alter context pdu. */
2875 prs_init_empty(&state->rpc_out, state, MARSHALL);
2877 status = create_rpc_alter_context(state->rpc_call_id,
2878 &state->cli->abstract_syntax,
2879 &state->cli->transfer_syntax,
2880 state->cli->auth->auth_level,
2883 data_blob_free(&client_reply);
2885 if (!NT_STATUS_IS_OK(status)) {
2889 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2890 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2891 if (subreq == NULL) {
2892 return NT_STATUS_NO_MEMORY;
2894 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2895 return NT_STATUS_OK;
2898 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2900 struct tevent_req *req = tevent_req_callback_data(
2901 subreq, struct tevent_req);
2902 struct rpc_pipe_bind_state *state = tevent_req_data(
2903 req, struct rpc_pipe_bind_state);
2904 DATA_BLOB tmp_blob = data_blob_null;
2905 struct ncacn_packet *pkt;
2906 struct dcerpc_auth auth;
2907 prs_struct reply_pdu;
2910 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
2911 TALLOC_FREE(subreq);
2912 if (!NT_STATUS_IS_OK(status)) {
2913 tevent_req_nterror(req, status);
2917 status = dcerpc_pull_dcerpc_auth(pkt,
2918 &pkt->u.alter_resp.auth_info,
2920 if (!NT_STATUS_IS_OK(status)) {
2921 tevent_req_nterror(req, status);
2925 /* Check we got a valid auth response. */
2926 if (!spnego_parse_auth_response(auth.credentials,
2928 OID_NTLMSSP, &tmp_blob)) {
2929 data_blob_free(&tmp_blob);
2930 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2934 data_blob_free(&tmp_blob);
2936 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2937 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2938 tevent_req_done(req);
2941 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2943 return tevent_req_simple_recv_ntstatus(req);
2946 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2947 struct cli_pipe_auth_data *auth)
2949 TALLOC_CTX *frame = talloc_stackframe();
2950 struct event_context *ev;
2951 struct tevent_req *req;
2952 NTSTATUS status = NT_STATUS_OK;
2954 ev = event_context_init(frame);
2956 status = NT_STATUS_NO_MEMORY;
2960 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2962 status = NT_STATUS_NO_MEMORY;
2966 if (!tevent_req_poll(req, ev)) {
2967 status = map_nt_error_from_unix(errno);
2971 status = rpc_pipe_bind_recv(req);
2977 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2979 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2980 unsigned int timeout)
2984 if (rpc_cli->transport == NULL) {
2985 return RPCCLI_DEFAULT_TIMEOUT;
2988 if (rpc_cli->transport->set_timeout == NULL) {
2989 return RPCCLI_DEFAULT_TIMEOUT;
2992 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2994 return RPCCLI_DEFAULT_TIMEOUT;
3000 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3002 if (rpc_cli == NULL) {
3006 if (rpc_cli->transport == NULL) {
3010 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3013 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3015 struct cli_state *cli;
3017 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3018 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3019 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3023 cli = rpc_pipe_np_smb_conn(rpc_cli);
3027 E_md4hash(cli->password ? cli->password : "", nt_hash);
3031 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3032 struct cli_pipe_auth_data **presult)
3034 struct cli_pipe_auth_data *result;
3036 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3037 if (result == NULL) {
3038 return NT_STATUS_NO_MEMORY;
3041 result->auth_type = PIPE_AUTH_TYPE_NONE;
3042 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3044 result->user_name = talloc_strdup(result, "");
3045 result->domain = talloc_strdup(result, "");
3046 if ((result->user_name == NULL) || (result->domain == NULL)) {
3047 TALLOC_FREE(result);
3048 return NT_STATUS_NO_MEMORY;
3052 return NT_STATUS_OK;
3055 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3057 ntlmssp_end(&auth->a_u.ntlmssp_state);
3061 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3062 enum pipe_auth_type auth_type,
3063 enum dcerpc_AuthLevel auth_level,
3065 const char *username,
3066 const char *password,
3067 struct cli_pipe_auth_data **presult)
3069 struct cli_pipe_auth_data *result;
3072 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3073 if (result == NULL) {
3074 return NT_STATUS_NO_MEMORY;
3077 result->auth_type = auth_type;
3078 result->auth_level = auth_level;
3080 result->user_name = talloc_strdup(result, username);
3081 result->domain = talloc_strdup(result, domain);
3082 if ((result->user_name == NULL) || (result->domain == NULL)) {
3083 status = NT_STATUS_NO_MEMORY;
3087 status = ntlmssp_client_start(NULL,
3090 lp_client_ntlmv2_auth(),
3091 &result->a_u.ntlmssp_state);
3092 if (!NT_STATUS_IS_OK(status)) {
3096 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3098 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3099 if (!NT_STATUS_IS_OK(status)) {
3103 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3104 if (!NT_STATUS_IS_OK(status)) {
3108 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3109 if (!NT_STATUS_IS_OK(status)) {
3114 * Turn off sign+seal to allow selected auth level to turn it back on.
3116 result->a_u.ntlmssp_state->neg_flags &=
3117 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3119 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3120 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3121 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3122 result->a_u.ntlmssp_state->neg_flags
3123 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3127 return NT_STATUS_OK;
3130 TALLOC_FREE(result);
3134 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3135 enum dcerpc_AuthLevel auth_level,
3136 struct netlogon_creds_CredentialState *creds,
3137 struct cli_pipe_auth_data **presult)
3139 struct cli_pipe_auth_data *result;
3141 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3142 if (result == NULL) {
3143 return NT_STATUS_NO_MEMORY;
3146 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3147 result->auth_level = auth_level;
3149 result->user_name = talloc_strdup(result, "");
3150 result->domain = talloc_strdup(result, domain);
3151 if ((result->user_name == NULL) || (result->domain == NULL)) {
3155 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3156 if (result->a_u.schannel_auth == NULL) {
3160 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3161 result->a_u.schannel_auth->seq_num = 0;
3162 result->a_u.schannel_auth->initiator = true;
3163 result->a_u.schannel_auth->creds = creds;
3166 return NT_STATUS_OK;
3169 TALLOC_FREE(result);
3170 return NT_STATUS_NO_MEMORY;
3174 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3176 data_blob_free(&auth->session_key);
3181 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3182 enum dcerpc_AuthLevel auth_level,
3183 const char *service_princ,
3184 const char *username,
3185 const char *password,
3186 struct cli_pipe_auth_data **presult)
3189 struct cli_pipe_auth_data *result;
3191 if ((username != NULL) && (password != NULL)) {
3192 int ret = kerberos_kinit_password(username, password, 0, NULL);
3194 return NT_STATUS_ACCESS_DENIED;
3198 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3199 if (result == NULL) {
3200 return NT_STATUS_NO_MEMORY;
3203 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3204 result->auth_level = auth_level;
3207 * Username / domain need fixing!
3209 result->user_name = talloc_strdup(result, "");
3210 result->domain = talloc_strdup(result, "");
3211 if ((result->user_name == NULL) || (result->domain == NULL)) {
3215 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3216 result, struct kerberos_auth_struct);
3217 if (result->a_u.kerberos_auth == NULL) {
3220 talloc_set_destructor(result->a_u.kerberos_auth,
3221 cli_auth_kerberos_data_destructor);
3223 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3224 result, service_princ);
3225 if (result->a_u.kerberos_auth->service_principal == NULL) {
3230 return NT_STATUS_OK;
3233 TALLOC_FREE(result);
3234 return NT_STATUS_NO_MEMORY;
3236 return NT_STATUS_NOT_SUPPORTED;
3241 * Create an rpc pipe client struct, connecting to a tcp port.
3243 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3245 const struct ndr_syntax_id *abstract_syntax,
3246 struct rpc_pipe_client **presult)
3248 struct rpc_pipe_client *result;
3249 struct sockaddr_storage addr;
3253 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3254 if (result == NULL) {
3255 return NT_STATUS_NO_MEMORY;
3258 result->abstract_syntax = *abstract_syntax;
3259 result->transfer_syntax = ndr_transfer_syntax;
3260 result->dispatch = cli_do_rpc_ndr;
3261 result->dispatch_send = cli_do_rpc_ndr_send;
3262 result->dispatch_recv = cli_do_rpc_ndr_recv;
3264 result->desthost = talloc_strdup(result, host);
3265 result->srv_name_slash = talloc_asprintf_strupper_m(
3266 result, "\\\\%s", result->desthost);
3267 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3268 status = NT_STATUS_NO_MEMORY;
3272 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3273 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3275 if (!resolve_name(host, &addr, 0, false)) {
3276 status = NT_STATUS_NOT_FOUND;
3280 status = open_socket_out(&addr, port, 60, &fd);
3281 if (!NT_STATUS_IS_OK(status)) {
3284 set_socket_options(fd, lp_socket_options());
3286 status = rpc_transport_sock_init(result, fd, &result->transport);
3287 if (!NT_STATUS_IS_OK(status)) {
3292 result->transport->transport = NCACN_IP_TCP;
3295 return NT_STATUS_OK;
3298 TALLOC_FREE(result);
3303 * Determine the tcp port on which a dcerpc interface is listening
3304 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3307 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3308 const struct ndr_syntax_id *abstract_syntax,
3312 struct rpc_pipe_client *epm_pipe = NULL;
3313 struct cli_pipe_auth_data *auth = NULL;
3314 struct dcerpc_binding *map_binding = NULL;
3315 struct dcerpc_binding *res_binding = NULL;
3316 struct epm_twr_t *map_tower = NULL;
3317 struct epm_twr_t *res_towers = NULL;
3318 struct policy_handle *entry_handle = NULL;
3319 uint32_t num_towers = 0;
3320 uint32_t max_towers = 1;
3321 struct epm_twr_p_t towers;
3322 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3324 if (pport == NULL) {
3325 status = NT_STATUS_INVALID_PARAMETER;
3329 /* open the connection to the endpoint mapper */
3330 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3331 &ndr_table_epmapper.syntax_id,
3334 if (!NT_STATUS_IS_OK(status)) {
3338 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3339 if (!NT_STATUS_IS_OK(status)) {
3343 status = rpc_pipe_bind(epm_pipe, auth);
3344 if (!NT_STATUS_IS_OK(status)) {
3348 /* create tower for asking the epmapper */
3350 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3351 if (map_binding == NULL) {
3352 status = NT_STATUS_NO_MEMORY;
3356 map_binding->transport = NCACN_IP_TCP;
3357 map_binding->object = *abstract_syntax;
3358 map_binding->host = host; /* needed? */
3359 map_binding->endpoint = "0"; /* correct? needed? */
3361 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3362 if (map_tower == NULL) {
3363 status = NT_STATUS_NO_MEMORY;
3367 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3368 &(map_tower->tower));
3369 if (!NT_STATUS_IS_OK(status)) {
3373 /* allocate further parameters for the epm_Map call */
3375 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3376 if (res_towers == NULL) {
3377 status = NT_STATUS_NO_MEMORY;
3380 towers.twr = res_towers;
3382 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3383 if (entry_handle == NULL) {
3384 status = NT_STATUS_NO_MEMORY;
3388 /* ask the endpoint mapper for the port */
3390 status = rpccli_epm_Map(epm_pipe,
3392 CONST_DISCARD(struct GUID *,
3393 &(abstract_syntax->uuid)),
3400 if (!NT_STATUS_IS_OK(status)) {
3404 if (num_towers != 1) {
3405 status = NT_STATUS_UNSUCCESSFUL;
3409 /* extract the port from the answer */
3411 status = dcerpc_binding_from_tower(tmp_ctx,
3412 &(towers.twr->tower),
3414 if (!NT_STATUS_IS_OK(status)) {
3418 /* are further checks here necessary? */
3419 if (res_binding->transport != NCACN_IP_TCP) {
3420 status = NT_STATUS_UNSUCCESSFUL;
3424 *pport = (uint16_t)atoi(res_binding->endpoint);
3427 TALLOC_FREE(tmp_ctx);
3432 * Create a rpc pipe client struct, connecting to a host via tcp.
3433 * The port is determined by asking the endpoint mapper on the given
3436 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3437 const struct ndr_syntax_id *abstract_syntax,
3438 struct rpc_pipe_client **presult)
3443 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3444 if (!NT_STATUS_IS_OK(status)) {
3448 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3449 abstract_syntax, presult);
3452 /********************************************************************
3453 Create a rpc pipe client struct, connecting to a unix domain socket
3454 ********************************************************************/
3455 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3456 const struct ndr_syntax_id *abstract_syntax,
3457 struct rpc_pipe_client **presult)
3459 struct rpc_pipe_client *result;
3460 struct sockaddr_un addr;
3464 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3465 if (result == NULL) {
3466 return NT_STATUS_NO_MEMORY;
3469 result->abstract_syntax = *abstract_syntax;
3470 result->transfer_syntax = ndr_transfer_syntax;
3471 result->dispatch = cli_do_rpc_ndr;
3472 result->dispatch_send = cli_do_rpc_ndr_send;
3473 result->dispatch_recv = cli_do_rpc_ndr_recv;
3475 result->desthost = get_myname(result);
3476 result->srv_name_slash = talloc_asprintf_strupper_m(
3477 result, "\\\\%s", result->desthost);
3478 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3479 status = NT_STATUS_NO_MEMORY;
3483 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3484 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3486 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3488 status = map_nt_error_from_unix(errno);
3493 addr.sun_family = AF_UNIX;
3494 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3496 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3497 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3500 return map_nt_error_from_unix(errno);
3503 status = rpc_transport_sock_init(result, fd, &result->transport);
3504 if (!NT_STATUS_IS_OK(status)) {
3509 result->transport->transport = NCALRPC;
3512 return NT_STATUS_OK;
3515 TALLOC_FREE(result);
3519 struct rpc_pipe_client_np_ref {
3520 struct cli_state *cli;
3521 struct rpc_pipe_client *pipe;
3524 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3526 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3530 /****************************************************************************
3531 Open a named pipe over SMB to a remote server.
3533 * CAVEAT CALLER OF THIS FUNCTION:
3534 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3535 * so be sure that this function is called AFTER any structure (vs pointer)
3536 * assignment of the cli. In particular, libsmbclient does structure
3537 * assignments of cli, which invalidates the data in the returned
3538 * rpc_pipe_client if this function is called before the structure assignment
3541 ****************************************************************************/
3543 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3544 const struct ndr_syntax_id *abstract_syntax,
3545 struct rpc_pipe_client **presult)
3547 struct rpc_pipe_client *result;
3549 struct rpc_pipe_client_np_ref *np_ref;
3551 /* sanity check to protect against crashes */
3554 return NT_STATUS_INVALID_HANDLE;
3557 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3558 if (result == NULL) {
3559 return NT_STATUS_NO_MEMORY;
3562 result->abstract_syntax = *abstract_syntax;
3563 result->transfer_syntax = ndr_transfer_syntax;
3564 result->dispatch = cli_do_rpc_ndr;
3565 result->dispatch_send = cli_do_rpc_ndr_send;
3566 result->dispatch_recv = cli_do_rpc_ndr_recv;
3567 result->desthost = talloc_strdup(result, cli->desthost);
3568 result->srv_name_slash = talloc_asprintf_strupper_m(
3569 result, "\\\\%s", result->desthost);
3571 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3572 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3574 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3575 TALLOC_FREE(result);
3576 return NT_STATUS_NO_MEMORY;
3579 status = rpc_transport_np_init(result, cli, abstract_syntax,
3580 &result->transport);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 TALLOC_FREE(result);
3586 result->transport->transport = NCACN_NP;
3588 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3589 if (np_ref == NULL) {
3590 TALLOC_FREE(result);
3591 return NT_STATUS_NO_MEMORY;
3594 np_ref->pipe = result;
3596 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3597 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3600 return NT_STATUS_OK;
3603 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3604 struct rpc_cli_smbd_conn *conn,
3605 const struct ndr_syntax_id *syntax,
3606 struct rpc_pipe_client **presult)
3608 struct rpc_pipe_client *result;
3609 struct cli_pipe_auth_data *auth;
3612 result = talloc(mem_ctx, struct rpc_pipe_client);
3613 if (result == NULL) {
3614 return NT_STATUS_NO_MEMORY;
3616 result->abstract_syntax = *syntax;
3617 result->transfer_syntax = ndr_transfer_syntax;
3618 result->dispatch = cli_do_rpc_ndr;
3619 result->dispatch_send = cli_do_rpc_ndr_send;
3620 result->dispatch_recv = cli_do_rpc_ndr_recv;
3621 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3622 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3624 result->desthost = talloc_strdup(result, global_myname());
3625 result->srv_name_slash = talloc_asprintf_strupper_m(
3626 result, "\\\\%s", global_myname());
3627 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3628 TALLOC_FREE(result);
3629 return NT_STATUS_NO_MEMORY;
3632 status = rpc_transport_smbd_init(result, conn, syntax,
3633 &result->transport);
3634 if (!NT_STATUS_IS_OK(status)) {
3635 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3636 nt_errstr(status)));
3637 TALLOC_FREE(result);
3641 status = rpccli_anon_bind_data(result, &auth);
3642 if (!NT_STATUS_IS_OK(status)) {
3643 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3644 nt_errstr(status)));
3645 TALLOC_FREE(result);
3649 status = rpc_pipe_bind(result, auth);
3650 if (!NT_STATUS_IS_OK(status)) {
3651 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3652 TALLOC_FREE(result);
3656 result->transport->transport = NCACN_INTERNAL;
3659 return NT_STATUS_OK;
3662 /****************************************************************************
3663 Open a pipe to a remote server.
3664 ****************************************************************************/
3666 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3667 enum dcerpc_transport_t transport,
3668 const struct ndr_syntax_id *interface,
3669 struct rpc_pipe_client **presult)
3671 switch (transport) {
3673 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3676 return rpc_pipe_open_np(cli, interface, presult);
3678 return NT_STATUS_NOT_IMPLEMENTED;
3682 /****************************************************************************
3683 Open a named pipe to an SMB server and bind anonymously.
3684 ****************************************************************************/
3686 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3687 enum dcerpc_transport_t transport,
3688 const struct ndr_syntax_id *interface,
3689 struct rpc_pipe_client **presult)
3691 struct rpc_pipe_client *result;
3692 struct cli_pipe_auth_data *auth;
3695 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3696 if (!NT_STATUS_IS_OK(status)) {
3700 status = rpccli_anon_bind_data(result, &auth);
3701 if (!NT_STATUS_IS_OK(status)) {
3702 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3703 nt_errstr(status)));
3704 TALLOC_FREE(result);
3709 * This is a bit of an abstraction violation due to the fact that an
3710 * anonymous bind on an authenticated SMB inherits the user/domain
3711 * from the enclosing SMB creds
3714 TALLOC_FREE(auth->user_name);
3715 TALLOC_FREE(auth->domain);
3717 auth->user_name = talloc_strdup(auth, cli->user_name);
3718 auth->domain = talloc_strdup(auth, cli->domain);
3719 auth->user_session_key = data_blob_talloc(auth,
3720 cli->user_session_key.data,
3721 cli->user_session_key.length);
3723 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3724 TALLOC_FREE(result);
3725 return NT_STATUS_NO_MEMORY;
3728 status = rpc_pipe_bind(result, auth);
3729 if (!NT_STATUS_IS_OK(status)) {
3731 if (ndr_syntax_id_equal(interface,
3732 &ndr_table_dssetup.syntax_id)) {
3733 /* non AD domains just don't have this pipe, avoid
3734 * level 0 statement in that case - gd */
3737 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3738 "%s failed with error %s\n",
3739 get_pipe_name_from_syntax(talloc_tos(), interface),
3740 nt_errstr(status) ));
3741 TALLOC_FREE(result);
3745 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3746 "%s and bound anonymously.\n",
3747 get_pipe_name_from_syntax(talloc_tos(), interface),
3751 return NT_STATUS_OK;
3754 /****************************************************************************
3755 ****************************************************************************/
3757 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3758 const struct ndr_syntax_id *interface,
3759 struct rpc_pipe_client **presult)
3761 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3762 interface, presult);
3765 /****************************************************************************
3766 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3767 ****************************************************************************/
3769 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3770 const struct ndr_syntax_id *interface,
3771 enum dcerpc_transport_t transport,
3772 enum pipe_auth_type auth_type,
3773 enum dcerpc_AuthLevel auth_level,
3775 const char *username,
3776 const char *password,
3777 struct rpc_pipe_client **presult)
3779 struct rpc_pipe_client *result;
3780 struct cli_pipe_auth_data *auth;
3783 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3784 if (!NT_STATUS_IS_OK(status)) {
3788 status = rpccli_ntlmssp_bind_data(
3789 result, auth_type, auth_level, domain, username,
3791 if (!NT_STATUS_IS_OK(status)) {
3792 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3793 nt_errstr(status)));
3797 status = rpc_pipe_bind(result, auth);
3798 if (!NT_STATUS_IS_OK(status)) {
3799 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3800 nt_errstr(status) ));
3804 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3805 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3806 get_pipe_name_from_syntax(talloc_tos(), interface),
3807 cli->desthost, domain, username ));
3810 return NT_STATUS_OK;
3814 TALLOC_FREE(result);
3818 /****************************************************************************
3820 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3821 ****************************************************************************/
3823 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3824 const struct ndr_syntax_id *interface,
3825 enum dcerpc_transport_t transport,
3826 enum dcerpc_AuthLevel auth_level,
3828 const char *username,
3829 const char *password,
3830 struct rpc_pipe_client **presult)
3832 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3835 PIPE_AUTH_TYPE_NTLMSSP,
3843 /****************************************************************************
3845 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3846 ****************************************************************************/
3848 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3849 const struct ndr_syntax_id *interface,
3850 enum dcerpc_transport_t transport,
3851 enum dcerpc_AuthLevel auth_level,
3853 const char *username,
3854 const char *password,
3855 struct rpc_pipe_client **presult)
3857 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3860 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3868 /****************************************************************************
3869 Get a the schannel session key out of an already opened netlogon pipe.
3870 ****************************************************************************/
3871 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3872 struct cli_state *cli,
3876 enum netr_SchannelType sec_chan_type = 0;
3877 unsigned char machine_pwd[16];
3878 const char *machine_account;
3881 /* Get the machine account credentials from secrets.tdb. */
3882 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3885 DEBUG(0, ("get_schannel_session_key: could not fetch "
3886 "trust account password for domain '%s'\n",
3888 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3891 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3892 cli->desthost, /* server name */
3893 domain, /* domain */
3894 global_myname(), /* client name */
3895 machine_account, /* machine account name */
3900 if (!NT_STATUS_IS_OK(status)) {
3901 DEBUG(3, ("get_schannel_session_key_common: "
3902 "rpccli_netlogon_setup_creds failed with result %s "
3903 "to server %s, domain %s, machine account %s.\n",
3904 nt_errstr(status), cli->desthost, domain,
3909 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3910 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3912 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3915 return NT_STATUS_OK;;
3918 /****************************************************************************
3919 Open a netlogon pipe and get the schannel session key.
3920 Now exposed to external callers.
3921 ****************************************************************************/
3924 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3927 struct rpc_pipe_client **presult)
3929 struct rpc_pipe_client *netlogon_pipe = NULL;
3932 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3934 if (!NT_STATUS_IS_OK(status)) {
3938 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3940 if (!NT_STATUS_IS_OK(status)) {
3941 TALLOC_FREE(netlogon_pipe);
3945 *presult = netlogon_pipe;
3946 return NT_STATUS_OK;
3949 /****************************************************************************
3951 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3952 using session_key. sign and seal.
3954 The *pdc will be stolen onto this new pipe
3955 ****************************************************************************/
3957 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3958 const struct ndr_syntax_id *interface,
3959 enum dcerpc_transport_t transport,
3960 enum dcerpc_AuthLevel auth_level,
3962 struct netlogon_creds_CredentialState **pdc,
3963 struct rpc_pipe_client **presult)
3965 struct rpc_pipe_client *result;
3966 struct cli_pipe_auth_data *auth;
3969 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3970 if (!NT_STATUS_IS_OK(status)) {
3974 status = rpccli_schannel_bind_data(result, domain, auth_level,
3976 if (!NT_STATUS_IS_OK(status)) {
3977 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3978 nt_errstr(status)));
3979 TALLOC_FREE(result);
3983 status = rpc_pipe_bind(result, auth);
3984 if (!NT_STATUS_IS_OK(status)) {
3985 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3986 "cli_rpc_pipe_bind failed with error %s\n",
3987 nt_errstr(status) ));
3988 TALLOC_FREE(result);
3993 * The credentials on a new netlogon pipe are the ones we are passed
3994 * in - reference them in
3996 result->dc = talloc_move(result, pdc);
3998 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3999 "for domain %s and bound using schannel.\n",
4000 get_pipe_name_from_syntax(talloc_tos(), interface),
4001 cli->desthost, domain ));
4004 return NT_STATUS_OK;
4007 /****************************************************************************
4008 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4009 Fetch the session key ourselves using a temporary netlogon pipe. This
4010 version uses an ntlmssp auth bound netlogon pipe to get the key.
4011 ****************************************************************************/
4013 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4015 const char *username,
4016 const char *password,
4018 struct rpc_pipe_client **presult)
4020 struct rpc_pipe_client *netlogon_pipe = NULL;
4023 status = cli_rpc_pipe_open_spnego_ntlmssp(
4024 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4025 DCERPC_AUTH_LEVEL_PRIVACY,
4026 domain, username, password, &netlogon_pipe);
4027 if (!NT_STATUS_IS_OK(status)) {
4031 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4033 if (!NT_STATUS_IS_OK(status)) {
4034 TALLOC_FREE(netlogon_pipe);
4038 *presult = netlogon_pipe;
4039 return NT_STATUS_OK;
4042 /****************************************************************************
4043 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4044 Fetch the session key ourselves using a temporary netlogon pipe. This version
4045 uses an ntlmssp bind to get the session key.
4046 ****************************************************************************/
4048 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4049 const struct ndr_syntax_id *interface,
4050 enum dcerpc_transport_t transport,
4051 enum dcerpc_AuthLevel auth_level,
4053 const char *username,
4054 const char *password,
4055 struct rpc_pipe_client **presult)
4057 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4058 struct rpc_pipe_client *netlogon_pipe = NULL;
4059 struct rpc_pipe_client *result = NULL;
4062 status = get_schannel_session_key_auth_ntlmssp(
4063 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4064 if (!NT_STATUS_IS_OK(status)) {
4065 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4066 "key from server %s for domain %s.\n",
4067 cli->desthost, domain ));
4071 status = cli_rpc_pipe_open_schannel_with_key(
4072 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4075 /* Now we've bound using the session key we can close the netlog pipe. */
4076 TALLOC_FREE(netlogon_pipe);
4078 if (NT_STATUS_IS_OK(status)) {
4084 /****************************************************************************
4085 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4086 Fetch the session key ourselves using a temporary netlogon pipe.
4087 ****************************************************************************/
4089 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4090 const struct ndr_syntax_id *interface,
4091 enum dcerpc_transport_t transport,
4092 enum dcerpc_AuthLevel auth_level,
4094 struct rpc_pipe_client **presult)
4096 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4097 struct rpc_pipe_client *netlogon_pipe = NULL;
4098 struct rpc_pipe_client *result = NULL;
4101 status = get_schannel_session_key(cli, domain, &neg_flags,
4103 if (!NT_STATUS_IS_OK(status)) {
4104 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4105 "key from server %s for domain %s.\n",
4106 cli->desthost, domain ));
4110 status = cli_rpc_pipe_open_schannel_with_key(
4111 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4114 /* Now we've bound using the session key we can close the netlog pipe. */
4115 TALLOC_FREE(netlogon_pipe);
4117 if (NT_STATUS_IS_OK(status)) {
4124 /****************************************************************************
4125 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4126 The idea is this can be called with service_princ, username and password all
4127 NULL so long as the caller has a TGT.
4128 ****************************************************************************/
4130 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4131 const struct ndr_syntax_id *interface,
4132 enum dcerpc_AuthLevel auth_level,
4133 const char *service_princ,
4134 const char *username,
4135 const char *password,
4136 struct rpc_pipe_client **presult)
4139 struct rpc_pipe_client *result;
4140 struct cli_pipe_auth_data *auth;
4143 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4144 if (!NT_STATUS_IS_OK(status)) {
4148 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4149 username, password, &auth);
4150 if (!NT_STATUS_IS_OK(status)) {
4151 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4152 nt_errstr(status)));
4153 TALLOC_FREE(result);
4157 status = rpc_pipe_bind(result, auth);
4158 if (!NT_STATUS_IS_OK(status)) {
4159 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4160 "with error %s\n", nt_errstr(status)));
4161 TALLOC_FREE(result);
4166 return NT_STATUS_OK;
4168 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4169 return NT_STATUS_NOT_IMPLEMENTED;
4173 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4174 struct rpc_pipe_client *cli,
4175 DATA_BLOB *session_key)
4177 if (!session_key || !cli) {
4178 return NT_STATUS_INVALID_PARAMETER;
4182 return NT_STATUS_INVALID_PARAMETER;
4185 switch (cli->auth->auth_type) {
4186 case PIPE_AUTH_TYPE_SCHANNEL:
4187 *session_key = data_blob_talloc(mem_ctx,
4188 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4190 case PIPE_AUTH_TYPE_NTLMSSP:
4191 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4192 *session_key = data_blob_talloc(mem_ctx,
4193 cli->auth->a_u.ntlmssp_state->session_key.data,
4194 cli->auth->a_u.ntlmssp_state->session_key.length);
4196 case PIPE_AUTH_TYPE_KRB5:
4197 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4198 *session_key = data_blob_talloc(mem_ctx,
4199 cli->auth->a_u.kerberos_auth->session_key.data,
4200 cli->auth->a_u.kerberos_auth->session_key.length);
4202 case PIPE_AUTH_TYPE_NONE:
4203 *session_key = data_blob_talloc(mem_ctx,
4204 cli->auth->user_session_key.data,
4205 cli->auth->user_session_key.length);
4208 return NT_STATUS_NO_USER_SESSION_KEY;
4211 return NT_STATUS_OK;