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"
47 #define DBGC_CLASS DBGC_RPC_CLI
49 static const char *get_pipe_name_from_iface(
50 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
53 const struct ndr_interface_string_array *ep = interface->endpoints;
56 for (i=0; i<ep->count; i++) {
57 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
66 * extract the pipe name without \\pipe from for example
67 * ncacn_np:[\\pipe\\epmapper]
69 p = strchr(ep->names[i]+15, ']');
73 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
76 static const struct ndr_interface_table **interfaces;
78 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
80 int num_interfaces = talloc_array_length(interfaces);
81 const struct ndr_interface_table **tmp;
84 for (i=0; i<num_interfaces; i++) {
85 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
86 &interface->syntax_id)) {
91 tmp = talloc_realloc(NULL, interfaces,
92 const struct ndr_interface_table *,
95 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
99 interfaces[num_interfaces] = interface;
103 static bool initialize_interfaces(void)
105 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
108 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
111 if (!smb_register_ndr_interface(&ndr_table_samr)) {
114 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
117 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
120 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
123 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
126 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
129 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
132 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
135 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
138 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
141 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
144 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
147 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
150 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
156 const struct ndr_interface_table *get_iface_from_syntax(
157 const struct ndr_syntax_id *syntax)
162 if (interfaces == NULL) {
163 if (!initialize_interfaces()) {
167 num_interfaces = talloc_array_length(interfaces);
169 for (i=0; i<num_interfaces; i++) {
170 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
171 return interfaces[i];
178 /****************************************************************************
179 Return the pipe name from the interface.
180 ****************************************************************************/
182 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
183 const struct ndr_syntax_id *syntax)
185 const struct ndr_interface_table *interface;
189 interface = get_iface_from_syntax(syntax);
190 if (interface != NULL) {
191 result = get_pipe_name_from_iface(mem_ctx, interface);
192 if (result != NULL) {
198 * Here we should ask \\epmapper, but for now our code is only
199 * interested in the known pipes mentioned in pipe_names[]
202 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
203 if (guid_str == NULL) {
206 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
207 (int)syntax->if_version);
208 TALLOC_FREE(guid_str);
210 if (result == NULL) {
216 /********************************************************************
217 Map internal value to wire value.
218 ********************************************************************/
220 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
224 case PIPE_AUTH_TYPE_NONE:
225 return DCERPC_AUTH_TYPE_NONE;
227 case PIPE_AUTH_TYPE_NTLMSSP:
228 return DCERPC_AUTH_TYPE_NTLMSSP;
230 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
231 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
232 return DCERPC_AUTH_TYPE_SPNEGO;
234 case PIPE_AUTH_TYPE_SCHANNEL:
235 return DCERPC_AUTH_TYPE_SCHANNEL;
237 case PIPE_AUTH_TYPE_KRB5:
238 return DCERPC_AUTH_TYPE_KRB5;
241 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
243 (unsigned int)auth_type ));
249 /********************************************************************
250 Pipe description for a DEBUG
251 ********************************************************************/
252 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
253 struct rpc_pipe_client *cli)
255 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
256 if (result == NULL) {
262 /********************************************************************
264 ********************************************************************/
266 static uint32 get_rpc_call_id(void)
268 static uint32 call_id = 0;
273 * Realloc pdu to have a least "size" bytes
276 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
280 if (prs_data_size(pdu) >= size) {
284 extra_size = size - prs_data_size(pdu);
286 if (!prs_force_grow(pdu, extra_size)) {
287 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
288 "%d bytes.\n", (int)extra_size));
292 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
293 (int)extra_size, prs_data_size(pdu)));
297 /*******************************************************************
298 *******************************************************************/
300 NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
301 enum dcerpc_pkt_type ptype,
303 uint16_t frag_length,
304 uint16_t auth_length,
306 union dcerpc_payload u,
309 struct ncacn_packet r;
310 enum ndr_err_code ndr_err;
313 r.rpc_vers_minor = 0;
315 r.pfc_flags = pfc_flags;
316 r.drep[0] = DCERPC_DREP_LE;
320 r.frag_length = frag_length;
321 r.auth_length = auth_length;
325 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
326 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
327 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
328 return ndr_map_error2ntstatus(ndr_err);
331 if (DEBUGLEVEL >= 10) {
332 NDR_PRINT_DEBUG(ncacn_packet, &r);
338 /*******************************************************************
339 Use SMBreadX to get rest of one fragment's worth of rpc data.
340 Reads the whole size or give an error message
341 ********************************************************************/
343 struct rpc_read_state {
344 struct event_context *ev;
345 struct rpc_cli_transport *transport;
351 static void rpc_read_done(struct tevent_req *subreq);
353 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
354 struct event_context *ev,
355 struct rpc_cli_transport *transport,
356 uint8_t *data, size_t size)
358 struct tevent_req *req, *subreq;
359 struct rpc_read_state *state;
361 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
366 state->transport = transport;
371 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
373 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
375 if (subreq == NULL) {
378 tevent_req_set_callback(subreq, rpc_read_done, req);
386 static void rpc_read_done(struct tevent_req *subreq)
388 struct tevent_req *req = tevent_req_callback_data(
389 subreq, struct tevent_req);
390 struct rpc_read_state *state = tevent_req_data(
391 req, struct rpc_read_state);
395 status = state->transport->read_recv(subreq, &received);
397 if (!NT_STATUS_IS_OK(status)) {
398 tevent_req_nterror(req, status);
402 state->num_read += received;
403 if (state->num_read == state->size) {
404 tevent_req_done(req);
408 subreq = state->transport->read_send(state, state->ev,
409 state->data + state->num_read,
410 state->size - state->num_read,
411 state->transport->priv);
412 if (tevent_req_nomem(subreq, req)) {
415 tevent_req_set_callback(subreq, rpc_read_done, req);
418 static NTSTATUS rpc_read_recv(struct tevent_req *req)
420 return tevent_req_simple_recv_ntstatus(req);
423 struct rpc_write_state {
424 struct event_context *ev;
425 struct rpc_cli_transport *transport;
431 static void rpc_write_done(struct tevent_req *subreq);
433 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
434 struct event_context *ev,
435 struct rpc_cli_transport *transport,
436 const uint8_t *data, size_t size)
438 struct tevent_req *req, *subreq;
439 struct rpc_write_state *state;
441 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
446 state->transport = transport;
449 state->num_written = 0;
451 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
453 subreq = transport->write_send(state, ev, data, size, transport->priv);
454 if (subreq == NULL) {
457 tevent_req_set_callback(subreq, rpc_write_done, req);
464 static void rpc_write_done(struct tevent_req *subreq)
466 struct tevent_req *req = tevent_req_callback_data(
467 subreq, struct tevent_req);
468 struct rpc_write_state *state = tevent_req_data(
469 req, struct rpc_write_state);
473 status = state->transport->write_recv(subreq, &written);
475 if (!NT_STATUS_IS_OK(status)) {
476 tevent_req_nterror(req, status);
480 state->num_written += written;
482 if (state->num_written == state->size) {
483 tevent_req_done(req);
487 subreq = state->transport->write_send(state, state->ev,
488 state->data + state->num_written,
489 state->size - state->num_written,
490 state->transport->priv);
491 if (tevent_req_nomem(subreq, req)) {
494 tevent_req_set_callback(subreq, rpc_write_done, req);
497 static NTSTATUS rpc_write_recv(struct tevent_req *req)
499 return tevent_req_simple_recv_ntstatus(req);
503 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
504 struct rpc_hdr_info *prhdr,
508 * This next call sets the endian bit correctly in current_pdu. We
509 * will propagate this to rbuf later.
512 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
513 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
514 return NT_STATUS_BUFFER_TOO_SMALL;
517 if (prhdr->frag_len > cli->max_recv_frag) {
518 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
519 " we only allow %d\n", (int)prhdr->frag_len,
520 (int)cli->max_recv_frag));
521 return NT_STATUS_BUFFER_TOO_SMALL;
527 /****************************************************************************
528 Try and get a PDU's worth of data from current_pdu. If not, then read more
530 ****************************************************************************/
532 struct get_complete_frag_state {
533 struct event_context *ev;
534 struct rpc_pipe_client *cli;
535 struct rpc_hdr_info *prhdr;
539 static void get_complete_frag_got_header(struct tevent_req *subreq);
540 static void get_complete_frag_got_rest(struct tevent_req *subreq);
542 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
543 struct event_context *ev,
544 struct rpc_pipe_client *cli,
545 struct rpc_hdr_info *prhdr,
548 struct tevent_req *req, *subreq;
549 struct get_complete_frag_state *state;
553 req = tevent_req_create(mem_ctx, &state,
554 struct get_complete_frag_state);
560 state->prhdr = prhdr;
563 pdu_len = prs_data_size(pdu);
564 if (pdu_len < RPC_HEADER_LEN) {
565 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
566 status = NT_STATUS_NO_MEMORY;
569 subreq = rpc_read_send(
571 state->cli->transport,
572 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
573 RPC_HEADER_LEN - pdu_len);
574 if (subreq == NULL) {
575 status = NT_STATUS_NO_MEMORY;
578 tevent_req_set_callback(subreq, get_complete_frag_got_header,
583 status = parse_rpc_header(cli, prhdr, pdu);
584 if (!NT_STATUS_IS_OK(status)) {
589 * Ensure we have frag_len bytes of data.
591 if (pdu_len < prhdr->frag_len) {
592 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
593 status = NT_STATUS_NO_MEMORY;
596 subreq = rpc_read_send(state, state->ev,
597 state->cli->transport,
598 (uint8_t *)(prs_data_p(pdu) + pdu_len),
599 prhdr->frag_len - pdu_len);
600 if (subreq == NULL) {
601 status = NT_STATUS_NO_MEMORY;
604 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
609 status = NT_STATUS_OK;
611 if (NT_STATUS_IS_OK(status)) {
612 tevent_req_done(req);
614 tevent_req_nterror(req, status);
616 return tevent_req_post(req, ev);
619 static void get_complete_frag_got_header(struct tevent_req *subreq)
621 struct tevent_req *req = tevent_req_callback_data(
622 subreq, struct tevent_req);
623 struct get_complete_frag_state *state = tevent_req_data(
624 req, struct get_complete_frag_state);
627 status = rpc_read_recv(subreq);
629 if (!NT_STATUS_IS_OK(status)) {
630 tevent_req_nterror(req, status);
634 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
635 if (!NT_STATUS_IS_OK(status)) {
636 tevent_req_nterror(req, status);
640 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
641 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
646 * We're here in this piece of code because we've read exactly
647 * RPC_HEADER_LEN bytes into state->pdu.
650 subreq = rpc_read_send(
651 state, state->ev, state->cli->transport,
652 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
653 state->prhdr->frag_len - RPC_HEADER_LEN);
654 if (tevent_req_nomem(subreq, req)) {
657 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
660 static void get_complete_frag_got_rest(struct tevent_req *subreq)
662 struct tevent_req *req = tevent_req_callback_data(
663 subreq, struct tevent_req);
666 status = rpc_read_recv(subreq);
668 if (!NT_STATUS_IS_OK(status)) {
669 tevent_req_nterror(req, status);
672 tevent_req_done(req);
675 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
677 return tevent_req_simple_recv_ntstatus(req);
680 /****************************************************************************
681 NTLMSSP specific sign/seal.
682 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
683 In fact I should probably abstract these into identical pieces of code... JRA.
684 ****************************************************************************/
686 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
687 prs_struct *current_pdu,
688 uint8 *p_ss_padding_len)
690 RPC_HDR_AUTH auth_info;
691 uint32 save_offset = prs_offset(current_pdu);
692 uint32 auth_len = prhdr->auth_len;
693 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
694 unsigned char *data = NULL;
696 unsigned char *full_packet_data = NULL;
697 size_t full_packet_data_len;
701 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
702 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
706 if (!ntlmssp_state) {
707 return NT_STATUS_INVALID_PARAMETER;
710 /* Ensure there's enough data for an authenticated response. */
711 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
712 prhdr->frag_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
713 RPC_HDR_AUTH_LEN + auth_len) {
714 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
715 (unsigned int)auth_len ));
716 return NT_STATUS_BUFFER_TOO_SMALL;
720 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
721 * after the RPC header.
722 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
723 * functions as NTLMv2 checks the rpc headers also.
726 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
727 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
729 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
730 full_packet_data_len = prhdr->frag_len - auth_len;
732 /* Pull the auth header and the following data into a blob. */
733 /* NB. The offset of the auth_header is relative to the *end*
734 * of the packet, not the start. */
735 if(!prs_set_offset(current_pdu, prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
736 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
737 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
738 return NT_STATUS_BUFFER_TOO_SMALL;
741 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
742 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
743 return NT_STATUS_BUFFER_TOO_SMALL;
746 /* Ensure auth_pad_len fits into the packet. */
747 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
748 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
749 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
750 "too large (%u), auth_len (%u), frag_len = (%u).\n",
751 (unsigned int)auth_info.auth_pad_len,
752 (unsigned int)auth_len,
753 (unsigned int)prhdr->frag_len ));
754 return NT_STATUS_BUFFER_TOO_SMALL;
758 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
759 auth_blob.length = auth_len;
761 switch (cli->auth->auth_level) {
762 case DCERPC_AUTH_LEVEL_PRIVACY:
763 /* Data is encrypted. */
764 status = ntlmssp_unseal_packet(ntlmssp_state,
767 full_packet_data_len,
769 if (!NT_STATUS_IS_OK(status)) {
770 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
771 "packet from %s. Error was %s.\n",
772 rpccli_pipe_txt(talloc_tos(), cli),
773 nt_errstr(status) ));
777 case DCERPC_AUTH_LEVEL_INTEGRITY:
778 /* Data is signed. */
779 status = ntlmssp_check_packet(ntlmssp_state,
782 full_packet_data_len,
784 if (!NT_STATUS_IS_OK(status)) {
785 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
786 "packet from %s. Error was %s.\n",
787 rpccli_pipe_txt(talloc_tos(), cli),
788 nt_errstr(status) ));
793 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
794 "auth level %d\n", cli->auth->auth_level));
795 return NT_STATUS_INVALID_INFO_CLASS;
799 * Return the current pointer to the data offset.
802 if(!prs_set_offset(current_pdu, save_offset)) {
803 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
804 (unsigned int)save_offset ));
805 return NT_STATUS_BUFFER_TOO_SMALL;
809 * Remember the padding length. We must remove it from the real data
810 * stream once the sign/seal is done.
813 *p_ss_padding_len = auth_info.auth_pad_len;
818 /****************************************************************************
819 schannel specific sign/seal.
820 ****************************************************************************/
822 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
823 prs_struct *current_pdu,
824 uint8 *p_ss_padding_len)
826 RPC_HDR_AUTH auth_info;
827 uint32 auth_len = prhdr->auth_len;
828 uint32 save_offset = prs_offset(current_pdu);
829 struct schannel_state *schannel_auth =
830 cli->auth->a_u.schannel_auth;
836 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
837 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
841 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
842 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
843 return NT_STATUS_INVALID_PARAMETER;
846 if (!schannel_auth) {
847 return NT_STATUS_INVALID_PARAMETER;
850 /* Ensure there's enough data for an authenticated response. */
851 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
852 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
853 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
854 (unsigned int)auth_len ));
855 return NT_STATUS_INVALID_PARAMETER;
858 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
860 /* Pull the auth header and the following data into a blob. */
861 /* NB. The offset of the auth_header is relative to the *end*
862 * of the packet, not the start. */
863 if(!prs_set_offset(current_pdu,
864 prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
865 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
867 (unsigned int)(prhdr->frag_len -
868 RPC_HDR_AUTH_LEN - auth_len) ));
869 return NT_STATUS_BUFFER_TOO_SMALL;
872 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
873 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
874 return NT_STATUS_BUFFER_TOO_SMALL;
877 /* Ensure auth_pad_len fits into the packet. */
878 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
879 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
880 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
881 "too large (%u), auth_len (%u), frag_len = (%u).\n",
882 (unsigned int)auth_info.auth_pad_len,
883 (unsigned int)auth_len,
884 (unsigned int)prhdr->frag_len ));
885 return NT_STATUS_BUFFER_TOO_SMALL;
888 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
889 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
890 auth_info.auth_type));
891 return NT_STATUS_BUFFER_TOO_SMALL;
894 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
896 if (DEBUGLEVEL >= 10) {
897 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
900 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
902 switch (cli->auth->auth_level) {
903 case DCERPC_AUTH_LEVEL_PRIVACY:
904 status = netsec_incoming_packet(schannel_auth,
911 case DCERPC_AUTH_LEVEL_INTEGRITY:
912 status = netsec_incoming_packet(schannel_auth,
920 status = NT_STATUS_INTERNAL_ERROR;
924 if (!NT_STATUS_IS_OK(status)) {
925 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
926 "Connection to %s (%s).\n",
927 rpccli_pipe_txt(talloc_tos(), cli),
929 return NT_STATUS_INVALID_PARAMETER;
933 * Return the current pointer to the data offset.
936 if(!prs_set_offset(current_pdu, save_offset)) {
937 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
938 (unsigned int)save_offset ));
939 return NT_STATUS_BUFFER_TOO_SMALL;
943 * Remember the padding length. We must remove it from the real data
944 * stream once the sign/seal is done.
947 *p_ss_padding_len = auth_info.auth_pad_len;
952 /****************************************************************************
953 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
954 ****************************************************************************/
956 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
957 prs_struct *current_pdu,
958 uint8 *p_ss_padding_len)
960 NTSTATUS ret = NT_STATUS_OK;
962 /* Paranioa checks for auth_len. */
963 if (prhdr->auth_len) {
964 if (prhdr->auth_len > prhdr->frag_len) {
965 return NT_STATUS_INVALID_PARAMETER;
968 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
969 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
970 /* Integer wrap attempt. */
971 return NT_STATUS_INVALID_PARAMETER;
976 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
979 switch(cli->auth->auth_type) {
980 case PIPE_AUTH_TYPE_NONE:
981 if (prhdr->auth_len) {
982 DEBUG(3, ("cli_pipe_validate_rpc_response: "
983 "Connection to %s - got non-zero "
985 rpccli_pipe_txt(talloc_tos(), cli),
986 (unsigned int)prhdr->auth_len ));
987 return NT_STATUS_INVALID_PARAMETER;
991 case PIPE_AUTH_TYPE_NTLMSSP:
992 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
993 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
994 if (!NT_STATUS_IS_OK(ret)) {
999 case PIPE_AUTH_TYPE_SCHANNEL:
1000 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1001 if (!NT_STATUS_IS_OK(ret)) {
1006 case PIPE_AUTH_TYPE_KRB5:
1007 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1009 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1010 "to %s - unknown internal auth type %u.\n",
1011 rpccli_pipe_txt(talloc_tos(), cli),
1012 cli->auth->auth_type ));
1013 return NT_STATUS_INVALID_INFO_CLASS;
1016 return NT_STATUS_OK;
1019 /****************************************************************************
1020 Do basic authentication checks on an incoming pdu.
1021 ****************************************************************************/
1023 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
1024 prs_struct *current_pdu,
1025 uint8 expected_pkt_type,
1028 prs_struct *return_data)
1031 NTSTATUS ret = NT_STATUS_OK;
1032 uint32 current_pdu_len = prs_data_size(current_pdu);
1034 if (current_pdu_len != prhdr->frag_len) {
1035 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1036 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
1037 return NT_STATUS_INVALID_PARAMETER;
1041 * Point the return values at the real data including the RPC
1042 * header. Just in case the caller wants it.
1044 *ppdata = prs_data_p(current_pdu);
1045 *pdata_len = current_pdu_len;
1047 /* Ensure we have the correct type. */
1048 switch (prhdr->pkt_type) {
1049 case DCERPC_PKT_ALTER_RESP:
1050 case DCERPC_PKT_BIND_ACK:
1052 /* Alter context and bind ack share the same packet definitions. */
1056 case DCERPC_PKT_RESPONSE:
1058 RPC_HDR_RESP rhdr_resp;
1059 uint8 ss_padding_len = 0;
1061 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1062 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1063 return NT_STATUS_BUFFER_TOO_SMALL;
1066 /* Here's where we deal with incoming sign/seal. */
1067 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1068 current_pdu, &ss_padding_len);
1069 if (!NT_STATUS_IS_OK(ret)) {
1073 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1074 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1076 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1077 return NT_STATUS_BUFFER_TOO_SMALL;
1080 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1082 /* Remember to remove the auth footer. */
1083 if (prhdr->auth_len) {
1084 /* We've already done integer wrap tests on auth_len in
1085 cli_pipe_validate_rpc_response(). */
1086 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
1087 return NT_STATUS_BUFFER_TOO_SMALL;
1089 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1092 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1093 current_pdu_len, *pdata_len, ss_padding_len ));
1096 * If this is the first reply, and the allocation hint is reasonably, try and
1097 * set up the return_data parse_struct to the correct size.
1100 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1101 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1102 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1103 "too large to allocate\n",
1104 (unsigned int)rhdr_resp.alloc_hint ));
1105 return NT_STATUS_NO_MEMORY;
1112 case DCERPC_PKT_BIND_NAK:
1113 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1114 "received from %s!\n",
1115 rpccli_pipe_txt(talloc_tos(), cli)));
1116 /* Use this for now... */
1117 return NT_STATUS_NETWORK_ACCESS_DENIED;
1119 case DCERPC_PKT_FAULT:
1121 RPC_HDR_RESP rhdr_resp;
1122 RPC_HDR_FAULT fault_resp;
1124 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1125 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1126 return NT_STATUS_BUFFER_TOO_SMALL;
1129 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
1130 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1131 return NT_STATUS_BUFFER_TOO_SMALL;
1134 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1135 "code %s received from %s!\n",
1136 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
1137 rpccli_pipe_txt(talloc_tos(), cli)));
1138 if (NT_STATUS_IS_OK(fault_resp.status)) {
1139 return NT_STATUS_UNSUCCESSFUL;
1141 return fault_resp.status;
1146 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1148 (unsigned int)prhdr->pkt_type,
1149 rpccli_pipe_txt(talloc_tos(), cli)));
1150 return NT_STATUS_INVALID_INFO_CLASS;
1153 if (prhdr->pkt_type != expected_pkt_type) {
1154 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1155 "got an unexpected RPC packet type - %u, not %u\n",
1156 rpccli_pipe_txt(talloc_tos(), cli),
1158 expected_pkt_type));
1159 return NT_STATUS_INVALID_INFO_CLASS;
1162 /* Do this just before return - we don't want to modify any rpc header
1163 data before now as we may have needed to do cryptographic actions on
1166 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1167 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1168 "setting fragment first/last ON.\n"));
1169 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1172 return NT_STATUS_OK;
1175 /****************************************************************************
1176 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1177 Normally the frag_len and buffer size will match, but on the first trans
1178 reply there is a theoretical chance that buffer size > frag_len, so we must
1180 ****************************************************************************/
1182 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1184 uint32 current_pdu_len = prs_data_size(current_pdu);
1186 if (current_pdu_len < prhdr->frag_len) {
1187 return NT_STATUS_BUFFER_TOO_SMALL;
1191 if (current_pdu_len == (uint32)prhdr->frag_len) {
1192 prs_mem_free(current_pdu);
1193 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1194 /* Make current_pdu dynamic with no memory. */
1195 prs_give_memory(current_pdu, 0, 0, True);
1196 return NT_STATUS_OK;
1200 * Oh no ! More data in buffer than we processed in current pdu.
1201 * Cheat. Move the data down and shrink the buffer.
1204 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1205 current_pdu_len - prhdr->frag_len);
1207 /* Remember to set the read offset back to zero. */
1208 prs_set_offset(current_pdu, 0);
1210 /* Shrink the buffer. */
1211 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1212 return NT_STATUS_BUFFER_TOO_SMALL;
1215 return NT_STATUS_OK;
1218 /****************************************************************************
1219 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1220 ****************************************************************************/
1222 struct cli_api_pipe_state {
1223 struct event_context *ev;
1224 struct rpc_cli_transport *transport;
1229 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1230 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1231 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1233 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1234 struct event_context *ev,
1235 struct rpc_cli_transport *transport,
1236 uint8_t *data, size_t data_len,
1237 uint32_t max_rdata_len)
1239 struct tevent_req *req, *subreq;
1240 struct cli_api_pipe_state *state;
1243 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1248 state->transport = transport;
1250 if (max_rdata_len < RPC_HEADER_LEN) {
1252 * For a RPC reply we always need at least RPC_HEADER_LEN
1253 * bytes. We check this here because we will receive
1254 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1256 status = NT_STATUS_INVALID_PARAMETER;
1260 if (transport->trans_send != NULL) {
1261 subreq = transport->trans_send(state, ev, data, data_len,
1262 max_rdata_len, transport->priv);
1263 if (subreq == NULL) {
1266 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1271 * If the transport does not provide a "trans" routine, i.e. for
1272 * example the ncacn_ip_tcp transport, do the write/read step here.
1275 subreq = rpc_write_send(state, ev, transport, data, data_len);
1276 if (subreq == NULL) {
1279 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1283 tevent_req_nterror(req, status);
1284 return tevent_req_post(req, ev);
1290 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1292 struct tevent_req *req = tevent_req_callback_data(
1293 subreq, struct tevent_req);
1294 struct cli_api_pipe_state *state = tevent_req_data(
1295 req, struct cli_api_pipe_state);
1298 status = state->transport->trans_recv(subreq, state, &state->rdata,
1300 TALLOC_FREE(subreq);
1301 if (!NT_STATUS_IS_OK(status)) {
1302 tevent_req_nterror(req, status);
1305 tevent_req_done(req);
1308 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1310 struct tevent_req *req = tevent_req_callback_data(
1311 subreq, struct tevent_req);
1312 struct cli_api_pipe_state *state = tevent_req_data(
1313 req, struct cli_api_pipe_state);
1316 status = rpc_write_recv(subreq);
1317 TALLOC_FREE(subreq);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 tevent_req_nterror(req, status);
1323 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1324 if (tevent_req_nomem(state->rdata, req)) {
1329 * We don't need to use rpc_read_send here, the upper layer will cope
1330 * with a short read, transport->trans_send could also return less
1331 * than state->max_rdata_len.
1333 subreq = state->transport->read_send(state, state->ev, state->rdata,
1335 state->transport->priv);
1336 if (tevent_req_nomem(subreq, req)) {
1339 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1342 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1344 struct tevent_req *req = tevent_req_callback_data(
1345 subreq, struct tevent_req);
1346 struct cli_api_pipe_state *state = tevent_req_data(
1347 req, struct cli_api_pipe_state);
1351 status = state->transport->read_recv(subreq, &received);
1352 TALLOC_FREE(subreq);
1353 if (!NT_STATUS_IS_OK(status)) {
1354 tevent_req_nterror(req, status);
1357 state->rdata_len = received;
1358 tevent_req_done(req);
1361 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1362 uint8_t **prdata, uint32_t *prdata_len)
1364 struct cli_api_pipe_state *state = tevent_req_data(
1365 req, struct cli_api_pipe_state);
1368 if (tevent_req_is_nterror(req, &status)) {
1372 *prdata = talloc_move(mem_ctx, &state->rdata);
1373 *prdata_len = state->rdata_len;
1374 return NT_STATUS_OK;
1377 /****************************************************************************
1378 Send data on an rpc pipe via trans. The prs_struct data must be the last
1379 pdu fragment of an NDR data stream.
1381 Receive response data from an rpc pipe, which may be large...
1383 Read the first fragment: unfortunately have to use SMBtrans for the first
1384 bit, then SMBreadX for subsequent bits.
1386 If first fragment received also wasn't the last fragment, continue
1387 getting fragments until we _do_ receive the last fragment.
1389 Request/Response PDU's look like the following...
1391 |<------------------PDU len----------------------------------------------->|
1392 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1394 +------------+-----------------+-------------+---------------+-------------+
1395 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1396 +------------+-----------------+-------------+---------------+-------------+
1398 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1399 signing & sealing being negotiated.
1401 ****************************************************************************/
1403 struct rpc_api_pipe_state {
1404 struct event_context *ev;
1405 struct rpc_pipe_client *cli;
1406 uint8_t expected_pkt_type;
1408 prs_struct incoming_frag;
1409 struct rpc_hdr_info rhdr;
1411 prs_struct incoming_pdu; /* Incoming reply */
1412 uint32_t incoming_pdu_offset;
1415 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1416 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1418 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1419 struct event_context *ev,
1420 struct rpc_pipe_client *cli,
1421 prs_struct *data, /* Outgoing PDU */
1422 uint8_t expected_pkt_type)
1424 struct tevent_req *req, *subreq;
1425 struct rpc_api_pipe_state *state;
1426 uint16_t max_recv_frag;
1429 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1435 state->expected_pkt_type = expected_pkt_type;
1436 state->incoming_pdu_offset = 0;
1438 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1440 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1441 /* Make incoming_pdu dynamic with no memory. */
1442 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1445 * Ensure we're not sending too much.
1447 if (prs_offset(data) > cli->max_xmit_frag) {
1448 status = NT_STATUS_INVALID_PARAMETER;
1452 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1454 max_recv_frag = cli->max_recv_frag;
1457 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1460 subreq = cli_api_pipe_send(state, ev, cli->transport,
1461 (uint8_t *)prs_data_p(data),
1462 prs_offset(data), max_recv_frag);
1463 if (subreq == NULL) {
1466 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1470 tevent_req_nterror(req, status);
1471 return tevent_req_post(req, ev);
1477 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1479 struct tevent_req *req = tevent_req_callback_data(
1480 subreq, struct tevent_req);
1481 struct rpc_api_pipe_state *state = tevent_req_data(
1482 req, struct rpc_api_pipe_state);
1484 uint8_t *rdata = NULL;
1485 uint32_t rdata_len = 0;
1487 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1488 TALLOC_FREE(subreq);
1489 if (!NT_STATUS_IS_OK(status)) {
1490 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1491 tevent_req_nterror(req, status);
1495 if (rdata == NULL) {
1496 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1497 rpccli_pipe_txt(talloc_tos(), state->cli)));
1498 tevent_req_done(req);
1503 * This is equivalent to a talloc_steal - gives rdata to
1504 * the prs_struct state->incoming_frag.
1506 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1509 /* Ensure we have enough data for a pdu. */
1510 subreq = get_complete_frag_send(state, state->ev, state->cli,
1511 &state->rhdr, &state->incoming_frag);
1512 if (tevent_req_nomem(subreq, req)) {
1515 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1518 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1520 struct tevent_req *req = tevent_req_callback_data(
1521 subreq, struct tevent_req);
1522 struct rpc_api_pipe_state *state = tevent_req_data(
1523 req, struct rpc_api_pipe_state);
1526 uint32_t rdata_len = 0;
1528 status = get_complete_frag_recv(subreq);
1529 TALLOC_FREE(subreq);
1530 if (!NT_STATUS_IS_OK(status)) {
1531 DEBUG(5, ("get_complete_frag failed: %s\n",
1532 nt_errstr(status)));
1533 tevent_req_nterror(req, status);
1537 status = cli_pipe_validate_current_pdu(
1538 state->cli, &state->rhdr, &state->incoming_frag,
1539 state->expected_pkt_type, &rdata, &rdata_len,
1540 &state->incoming_pdu);
1542 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1543 (unsigned)prs_data_size(&state->incoming_frag),
1544 (unsigned)state->incoming_pdu_offset,
1545 nt_errstr(status)));
1547 if (!NT_STATUS_IS_OK(status)) {
1548 tevent_req_nterror(req, status);
1552 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1553 && (state->rhdr.pack_type[0] == 0)) {
1555 * Set the data type correctly for big-endian data on the
1558 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1560 rpccli_pipe_txt(talloc_tos(), state->cli)));
1561 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1564 * Check endianness on subsequent packets.
1566 if (state->incoming_frag.bigendian_data
1567 != state->incoming_pdu.bigendian_data) {
1568 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1570 state->incoming_pdu.bigendian_data?"big":"little",
1571 state->incoming_frag.bigendian_data?"big":"little"));
1572 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1576 /* Now copy the data portion out of the pdu into rbuf. */
1577 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1578 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1582 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1583 rdata, (size_t)rdata_len);
1584 state->incoming_pdu_offset += rdata_len;
1586 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1587 &state->incoming_frag);
1588 if (!NT_STATUS_IS_OK(status)) {
1589 tevent_req_nterror(req, status);
1593 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1594 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1595 rpccli_pipe_txt(talloc_tos(), state->cli),
1596 (unsigned)prs_data_size(&state->incoming_pdu)));
1597 tevent_req_done(req);
1601 subreq = get_complete_frag_send(state, state->ev, state->cli,
1602 &state->rhdr, &state->incoming_frag);
1603 if (tevent_req_nomem(subreq, req)) {
1606 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1609 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1610 prs_struct *reply_pdu)
1612 struct rpc_api_pipe_state *state = tevent_req_data(
1613 req, struct rpc_api_pipe_state);
1616 if (tevent_req_is_nterror(req, &status)) {
1620 *reply_pdu = state->incoming_pdu;
1621 reply_pdu->mem_ctx = mem_ctx;
1624 * Prevent state->incoming_pdu from being freed
1625 * when state is freed.
1627 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1628 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1630 return NT_STATUS_OK;
1633 /*******************************************************************
1634 Creates krb5 auth bind.
1635 ********************************************************************/
1637 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1638 enum dcerpc_AuthLevel auth_level,
1639 RPC_HDR_AUTH *pauth_out,
1640 prs_struct *auth_data)
1644 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1645 DATA_BLOB tkt = data_blob_null;
1646 DATA_BLOB tkt_wrapped = data_blob_null;
1648 /* We may change the pad length before marshalling. */
1649 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1651 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1652 a->service_principal ));
1654 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1656 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1657 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1660 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1662 a->service_principal,
1663 error_message(ret) ));
1665 data_blob_free(&tkt);
1666 return NT_STATUS_INVALID_PARAMETER;
1669 /* wrap that up in a nice GSS-API wrapping */
1670 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1672 data_blob_free(&tkt);
1674 /* Auth len in the rpc header doesn't include auth_header. */
1675 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1676 data_blob_free(&tkt_wrapped);
1677 return NT_STATUS_NO_MEMORY;
1680 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1681 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1683 data_blob_free(&tkt_wrapped);
1684 return NT_STATUS_OK;
1686 return NT_STATUS_INVALID_PARAMETER;
1690 /*******************************************************************
1691 Creates SPNEGO NTLMSSP auth bind.
1692 ********************************************************************/
1694 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1695 enum dcerpc_AuthLevel auth_level,
1696 RPC_HDR_AUTH *pauth_out,
1697 prs_struct *auth_data)
1700 DATA_BLOB null_blob = data_blob_null;
1701 DATA_BLOB request = data_blob_null;
1702 DATA_BLOB spnego_msg = data_blob_null;
1704 /* We may change the pad length before marshalling. */
1705 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1707 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1708 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1712 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1713 data_blob_free(&request);
1717 /* Wrap this in SPNEGO. */
1718 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1720 data_blob_free(&request);
1722 /* Auth len in the rpc header doesn't include auth_header. */
1723 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1724 data_blob_free(&spnego_msg);
1725 return NT_STATUS_NO_MEMORY;
1728 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1729 dump_data(5, spnego_msg.data, spnego_msg.length);
1731 data_blob_free(&spnego_msg);
1732 return NT_STATUS_OK;
1735 /*******************************************************************
1736 Creates NTLMSSP auth bind.
1737 ********************************************************************/
1739 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1740 enum dcerpc_AuthLevel auth_level,
1741 RPC_HDR_AUTH *pauth_out,
1742 prs_struct *auth_data)
1745 DATA_BLOB null_blob = data_blob_null;
1746 DATA_BLOB request = data_blob_null;
1748 /* We may change the pad length before marshalling. */
1749 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1751 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1752 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1756 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1757 data_blob_free(&request);
1761 /* Auth len in the rpc header doesn't include auth_header. */
1762 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1763 data_blob_free(&request);
1764 return NT_STATUS_NO_MEMORY;
1767 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1768 dump_data(5, request.data, request.length);
1770 data_blob_free(&request);
1771 return NT_STATUS_OK;
1774 /*******************************************************************
1775 Creates schannel auth bind.
1776 ********************************************************************/
1778 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1779 enum dcerpc_AuthLevel auth_level,
1780 RPC_HDR_AUTH *pauth_out,
1781 prs_struct *auth_data)
1783 struct NL_AUTH_MESSAGE r;
1784 enum ndr_err_code ndr_err;
1787 /* We may change the pad length before marshalling. */
1788 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1790 /* Use lp_workgroup() if domain not specified */
1792 if (!cli->auth->domain || !cli->auth->domain[0]) {
1793 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1794 if (cli->auth->domain == NULL) {
1795 return NT_STATUS_NO_MEMORY;
1800 * Now marshall the data into the auth parse_struct.
1803 r.MessageType = NL_NEGOTIATE_REQUEST;
1804 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1805 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1806 r.oem_netbios_domain.a = cli->auth->domain;
1807 r.oem_netbios_computer.a = global_myname();
1809 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &r,
1810 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1811 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1812 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1813 return ndr_map_error2ntstatus(ndr_err);
1816 if (DEBUGLEVEL >= 10) {
1817 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1820 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1822 return NT_STATUS_NO_MEMORY;
1825 return NT_STATUS_OK;
1828 /*******************************************************************
1829 Creates the internals of a DCE/RPC bind request or alter context PDU.
1830 ********************************************************************/
1832 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1833 prs_struct *rpc_out,
1835 const struct ndr_syntax_id *abstract,
1836 const struct ndr_syntax_id *transfer,
1837 RPC_HDR_AUTH *phdr_auth,
1838 prs_struct *pauth_info)
1842 RPC_CONTEXT rpc_ctx;
1843 uint16 auth_len = prs_offset(pauth_info);
1844 uint8 ss_padding_len = 0;
1845 uint16 frag_len = 0;
1847 /* create the RPC context. */
1848 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1850 /* create the bind request RPC_HDR_RB */
1851 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1853 /* Start building the frag length. */
1854 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1856 /* Do we need to pad ? */
1858 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1859 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1860 ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1861 phdr_auth->auth_pad_len = ss_padding_len;
1863 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1866 /* Create the request RPC_HDR */
1867 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1869 /* Marshall the RPC header */
1870 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1871 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1872 return NT_STATUS_NO_MEMORY;
1875 /* Marshall the bind request data */
1876 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1877 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1878 return NT_STATUS_NO_MEMORY;
1882 * Grow the outgoing buffer to store any auth info.
1886 if (ss_padding_len) {
1887 char pad[CLIENT_NDR_PADDING_SIZE];
1888 memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1889 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1890 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1891 return NT_STATUS_NO_MEMORY;
1895 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1896 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1897 return NT_STATUS_NO_MEMORY;
1901 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1902 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1903 return NT_STATUS_NO_MEMORY;
1907 return NT_STATUS_OK;
1910 /*******************************************************************
1911 Creates a DCE/RPC bind request.
1912 ********************************************************************/
1914 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1915 prs_struct *rpc_out,
1917 const struct ndr_syntax_id *abstract,
1918 const struct ndr_syntax_id *transfer,
1919 enum pipe_auth_type auth_type,
1920 enum dcerpc_AuthLevel auth_level)
1922 RPC_HDR_AUTH hdr_auth;
1923 prs_struct auth_info;
1924 NTSTATUS ret = NT_STATUS_OK;
1926 ZERO_STRUCT(hdr_auth);
1927 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1928 return NT_STATUS_NO_MEMORY;
1930 switch (auth_type) {
1931 case PIPE_AUTH_TYPE_SCHANNEL:
1932 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1933 if (!NT_STATUS_IS_OK(ret)) {
1938 case PIPE_AUTH_TYPE_NTLMSSP:
1939 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1940 if (!NT_STATUS_IS_OK(ret)) {
1945 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1946 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1947 if (!NT_STATUS_IS_OK(ret)) {
1952 case PIPE_AUTH_TYPE_KRB5:
1953 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1954 if (!NT_STATUS_IS_OK(ret)) {
1959 case PIPE_AUTH_TYPE_NONE:
1963 /* "Can't" happen. */
1964 return NT_STATUS_INVALID_INFO_CLASS;
1967 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1978 /*******************************************************************
1979 Create and add the NTLMSSP sign/seal auth header and data.
1980 ********************************************************************/
1982 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1984 uint32 ss_padding_len,
1985 prs_struct *outgoing_pdu)
1987 RPC_HDR_AUTH auth_info;
1989 DATA_BLOB auth_blob = data_blob_null;
1990 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1993 if (!cli->auth->a_u.ntlmssp_state) {
1994 return NT_STATUS_INVALID_PARAMETER;
1997 frame = talloc_stackframe();
1999 /* Init and marshall the auth header. */
2000 init_rpc_hdr_auth(&auth_info,
2001 map_pipe_auth_type_to_rpc_auth_type(
2002 cli->auth->auth_type),
2003 cli->auth->auth_level,
2005 1 /* context id. */);
2007 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2008 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2010 return NT_STATUS_NO_MEMORY;
2013 switch (cli->auth->auth_level) {
2014 case DCERPC_AUTH_LEVEL_PRIVACY:
2015 /* Data portion is encrypted. */
2016 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2018 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2020 (unsigned char *)prs_data_p(outgoing_pdu),
2021 (size_t)prs_offset(outgoing_pdu),
2023 if (!NT_STATUS_IS_OK(status)) {
2029 case DCERPC_AUTH_LEVEL_INTEGRITY:
2030 /* Data is signed. */
2031 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2033 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2035 (unsigned char *)prs_data_p(outgoing_pdu),
2036 (size_t)prs_offset(outgoing_pdu),
2038 if (!NT_STATUS_IS_OK(status)) {
2046 smb_panic("bad auth level");
2048 return NT_STATUS_INVALID_PARAMETER;
2051 /* Finally marshall the blob. */
2053 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2054 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2055 (unsigned int)NTLMSSP_SIG_SIZE));
2057 return NT_STATUS_NO_MEMORY;
2061 return NT_STATUS_OK;
2064 /*******************************************************************
2065 Create and add the schannel sign/seal auth header and data.
2066 ********************************************************************/
2068 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2070 uint32 ss_padding_len,
2071 prs_struct *outgoing_pdu)
2073 RPC_HDR_AUTH auth_info;
2074 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2075 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2076 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2081 return NT_STATUS_INVALID_PARAMETER;
2084 /* Init and marshall the auth header. */
2085 init_rpc_hdr_auth(&auth_info,
2086 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2087 cli->auth->auth_level,
2089 1 /* context id. */);
2091 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2092 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2093 return NT_STATUS_NO_MEMORY;
2096 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2099 switch (cli->auth->auth_level) {
2100 case DCERPC_AUTH_LEVEL_PRIVACY:
2101 status = netsec_outgoing_packet(sas,
2108 case DCERPC_AUTH_LEVEL_INTEGRITY:
2109 status = netsec_outgoing_packet(sas,
2117 status = NT_STATUS_INTERNAL_ERROR;
2121 if (!NT_STATUS_IS_OK(status)) {
2122 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2123 nt_errstr(status)));
2127 if (DEBUGLEVEL >= 10) {
2128 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2131 /* Finally marshall the blob. */
2132 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2133 return NT_STATUS_NO_MEMORY;
2136 return NT_STATUS_OK;
2139 /*******************************************************************
2140 Calculate how much data we're going to send in this packet, also
2141 work out any sign/seal padding length.
2142 ********************************************************************/
2144 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2148 uint32 *p_ss_padding)
2150 uint32 data_space, data_len;
2153 if ((data_left > 0) && (sys_random() % 2)) {
2154 data_left = MAX(data_left/2, 1);
2158 switch (cli->auth->auth_level) {
2159 case DCERPC_AUTH_LEVEL_NONE:
2160 case DCERPC_AUTH_LEVEL_CONNECT:
2161 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2162 data_len = MIN(data_space, data_left);
2165 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2168 case DCERPC_AUTH_LEVEL_INTEGRITY:
2169 case DCERPC_AUTH_LEVEL_PRIVACY:
2170 /* Treat the same for all authenticated rpc requests. */
2171 switch(cli->auth->auth_type) {
2172 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2173 case PIPE_AUTH_TYPE_NTLMSSP:
2174 *p_auth_len = NTLMSSP_SIG_SIZE;
2176 case PIPE_AUTH_TYPE_SCHANNEL:
2177 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2180 smb_panic("bad auth type");
2184 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2185 RPC_HDR_AUTH_LEN - *p_auth_len;
2187 data_len = MIN(data_space, data_left);
2189 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2190 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2192 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2193 data_len + *p_ss_padding + /* data plus padding. */
2194 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2198 smb_panic("bad auth level");
2204 /*******************************************************************
2206 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2207 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2208 and deals with signing/sealing details.
2209 ********************************************************************/
2211 struct rpc_api_pipe_req_state {
2212 struct event_context *ev;
2213 struct rpc_pipe_client *cli;
2216 prs_struct *req_data;
2217 uint32_t req_data_sent;
2218 prs_struct outgoing_frag;
2219 prs_struct reply_pdu;
2222 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2223 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2224 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2225 bool *is_last_frag);
2227 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2228 struct event_context *ev,
2229 struct rpc_pipe_client *cli,
2231 prs_struct *req_data)
2233 struct tevent_req *req, *subreq;
2234 struct rpc_api_pipe_req_state *state;
2238 req = tevent_req_create(mem_ctx, &state,
2239 struct rpc_api_pipe_req_state);
2245 state->op_num = op_num;
2246 state->req_data = req_data;
2247 state->req_data_sent = 0;
2248 state->call_id = get_rpc_call_id();
2250 if (cli->max_xmit_frag
2251 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2252 /* Server is screwed up ! */
2253 status = NT_STATUS_INVALID_PARAMETER;
2257 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2259 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2264 status = prepare_next_frag(state, &is_last_frag);
2265 if (!NT_STATUS_IS_OK(status)) {
2270 subreq = rpc_api_pipe_send(state, ev, state->cli,
2271 &state->outgoing_frag,
2272 DCERPC_PKT_RESPONSE);
2273 if (subreq == NULL) {
2276 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2278 subreq = rpc_write_send(
2279 state, ev, cli->transport,
2280 (uint8_t *)prs_data_p(&state->outgoing_frag),
2281 prs_offset(&state->outgoing_frag));
2282 if (subreq == NULL) {
2285 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2291 tevent_req_nterror(req, status);
2292 return tevent_req_post(req, ev);
2298 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2302 RPC_HDR_REQ hdr_req;
2303 uint32_t data_sent_thistime;
2307 uint32_t ss_padding;
2309 char pad[8] = { 0, };
2312 data_left = prs_offset(state->req_data) - state->req_data_sent;
2314 data_sent_thistime = calculate_data_len_tosend(
2315 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2317 if (state->req_data_sent == 0) {
2318 flags = DCERPC_PFC_FLAG_FIRST;
2321 if (data_sent_thistime == data_left) {
2322 flags |= DCERPC_PFC_FLAG_LAST;
2325 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2326 return NT_STATUS_NO_MEMORY;
2329 /* Create and marshall the header and request header. */
2330 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2333 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2334 return NT_STATUS_NO_MEMORY;
2337 /* Create the rpc request RPC_HDR_REQ */
2338 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2341 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2342 &state->outgoing_frag, 0)) {
2343 return NT_STATUS_NO_MEMORY;
2346 /* Copy in the data, plus any ss padding. */
2347 if (!prs_append_some_prs_data(&state->outgoing_frag,
2348 state->req_data, state->req_data_sent,
2349 data_sent_thistime)) {
2350 return NT_STATUS_NO_MEMORY;
2353 /* Copy the sign/seal padding data. */
2354 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2355 return NT_STATUS_NO_MEMORY;
2358 /* Generate any auth sign/seal and add the auth footer. */
2359 switch (state->cli->auth->auth_type) {
2360 case PIPE_AUTH_TYPE_NONE:
2361 status = NT_STATUS_OK;
2363 case PIPE_AUTH_TYPE_NTLMSSP:
2364 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2365 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2366 &state->outgoing_frag);
2368 case PIPE_AUTH_TYPE_SCHANNEL:
2369 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2370 &state->outgoing_frag);
2373 status = NT_STATUS_INVALID_PARAMETER;
2377 state->req_data_sent += data_sent_thistime;
2378 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2383 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2385 struct tevent_req *req = tevent_req_callback_data(
2386 subreq, struct tevent_req);
2387 struct rpc_api_pipe_req_state *state = tevent_req_data(
2388 req, struct rpc_api_pipe_req_state);
2392 status = rpc_write_recv(subreq);
2393 TALLOC_FREE(subreq);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 tevent_req_nterror(req, status);
2399 status = prepare_next_frag(state, &is_last_frag);
2400 if (!NT_STATUS_IS_OK(status)) {
2401 tevent_req_nterror(req, status);
2406 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2407 &state->outgoing_frag,
2408 DCERPC_PKT_RESPONSE);
2409 if (tevent_req_nomem(subreq, req)) {
2412 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2414 subreq = rpc_write_send(
2416 state->cli->transport,
2417 (uint8_t *)prs_data_p(&state->outgoing_frag),
2418 prs_offset(&state->outgoing_frag));
2419 if (tevent_req_nomem(subreq, req)) {
2422 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2427 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2429 struct tevent_req *req = tevent_req_callback_data(
2430 subreq, struct tevent_req);
2431 struct rpc_api_pipe_req_state *state = tevent_req_data(
2432 req, struct rpc_api_pipe_req_state);
2435 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2436 TALLOC_FREE(subreq);
2437 if (!NT_STATUS_IS_OK(status)) {
2438 tevent_req_nterror(req, status);
2441 tevent_req_done(req);
2444 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2445 prs_struct *reply_pdu)
2447 struct rpc_api_pipe_req_state *state = tevent_req_data(
2448 req, struct rpc_api_pipe_req_state);
2451 if (tevent_req_is_nterror(req, &status)) {
2453 * We always have to initialize to reply pdu, even if there is
2454 * none. The rpccli_* caller routines expect this.
2456 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2460 *reply_pdu = state->reply_pdu;
2461 reply_pdu->mem_ctx = mem_ctx;
2464 * Prevent state->req_pdu from being freed
2465 * when state is freed.
2467 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2468 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2470 return NT_STATUS_OK;
2474 /****************************************************************************
2475 Set the handle state.
2476 ****************************************************************************/
2478 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2479 const char *pipe_name, uint16 device_state)
2481 bool state_set = False;
2483 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2484 char *rparam = NULL;
2486 uint32 rparam_len, rdata_len;
2488 if (pipe_name == NULL)
2491 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2492 cli->fnum, pipe_name, device_state));
2494 /* create parameters: device state */
2495 SSVAL(param, 0, device_state);
2497 /* create setup parameters. */
2499 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2501 /* send the data on \PIPE\ */
2502 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2503 setup, 2, 0, /* setup, length, max */
2504 param, 2, 0, /* param, length, max */
2505 NULL, 0, 1024, /* data, length, max */
2506 &rparam, &rparam_len, /* return param, length */
2507 &rdata, &rdata_len)) /* return data, length */
2509 DEBUG(5, ("Set Handle state: return OK\n"));
2520 /****************************************************************************
2521 Check the rpc bind acknowledge response.
2522 ****************************************************************************/
2524 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2525 const struct ndr_syntax_id *transfer)
2527 if ( hdr_ba->addr.len == 0) {
2528 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2531 /* check the transfer syntax */
2532 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2533 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2534 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2538 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2539 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2540 hdr_ba->res.num_results, hdr_ba->res.reason));
2543 DEBUG(5,("check_bind_response: accepted!\n"));
2547 /*******************************************************************
2548 Creates a DCE/RPC bind authentication response.
2549 This is the packet that is sent back to the server once we
2550 have received a BIND-ACK, to finish the third leg of
2551 the authentication handshake.
2552 ********************************************************************/
2554 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2556 enum pipe_auth_type auth_type,
2557 enum dcerpc_AuthLevel auth_level,
2558 DATA_BLOB *pauth_blob,
2559 prs_struct *rpc_out)
2562 RPC_HDR_AUTH hdr_auth;
2565 /* Create the request RPC_HDR */
2566 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2567 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2568 pauth_blob->length );
2571 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2572 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2573 return NT_STATUS_NO_MEMORY;
2577 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2578 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2581 /* 4 bytes padding. */
2582 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2583 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2584 return NT_STATUS_NO_MEMORY;
2587 /* Create the request RPC_HDR_AUTHA */
2588 init_rpc_hdr_auth(&hdr_auth,
2589 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2592 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2593 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2594 return NT_STATUS_NO_MEMORY;
2598 * Append the auth data to the outgoing buffer.
2601 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2602 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2603 return NT_STATUS_NO_MEMORY;
2606 return NT_STATUS_OK;
2609 /*******************************************************************
2610 Creates a DCE/RPC bind alter context authentication request which
2611 may contain a spnego auth blobl
2612 ********************************************************************/
2614 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2615 const struct ndr_syntax_id *abstract,
2616 const struct ndr_syntax_id *transfer,
2617 enum dcerpc_AuthLevel auth_level,
2618 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2619 prs_struct *rpc_out)
2621 RPC_HDR_AUTH hdr_auth;
2622 prs_struct auth_info;
2623 NTSTATUS ret = NT_STATUS_OK;
2625 ZERO_STRUCT(hdr_auth);
2626 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2627 return NT_STATUS_NO_MEMORY;
2629 /* We may change the pad length before marshalling. */
2630 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2632 if (pauth_blob->length) {
2633 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2634 return NT_STATUS_NO_MEMORY;
2638 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2648 /****************************************************************************
2650 ****************************************************************************/
2652 struct rpc_pipe_bind_state {
2653 struct event_context *ev;
2654 struct rpc_pipe_client *cli;
2656 uint32_t rpc_call_id;
2659 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2660 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2661 struct rpc_pipe_bind_state *state,
2662 struct rpc_hdr_info *phdr,
2663 prs_struct *reply_pdu);
2664 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2665 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2666 struct rpc_pipe_bind_state *state,
2667 struct rpc_hdr_info *phdr,
2668 prs_struct *reply_pdu);
2669 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2671 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2672 struct event_context *ev,
2673 struct rpc_pipe_client *cli,
2674 struct cli_pipe_auth_data *auth)
2676 struct tevent_req *req, *subreq;
2677 struct rpc_pipe_bind_state *state;
2680 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2685 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2686 rpccli_pipe_txt(talloc_tos(), cli),
2687 (unsigned int)auth->auth_type,
2688 (unsigned int)auth->auth_level ));
2692 state->rpc_call_id = get_rpc_call_id();
2694 prs_init_empty(&state->rpc_out, state, MARSHALL);
2696 cli->auth = talloc_move(cli, &auth);
2698 /* Marshall the outgoing data. */
2699 status = create_rpc_bind_req(cli, &state->rpc_out,
2701 &cli->abstract_syntax,
2702 &cli->transfer_syntax,
2703 cli->auth->auth_type,
2704 cli->auth->auth_level);
2706 if (!NT_STATUS_IS_OK(status)) {
2710 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2711 DCERPC_PKT_BIND_ACK);
2712 if (subreq == NULL) {
2715 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2719 tevent_req_nterror(req, status);
2720 return tevent_req_post(req, ev);
2726 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2728 struct tevent_req *req = tevent_req_callback_data(
2729 subreq, struct tevent_req);
2730 struct rpc_pipe_bind_state *state = tevent_req_data(
2731 req, struct rpc_pipe_bind_state);
2732 prs_struct reply_pdu;
2733 struct rpc_hdr_info hdr;
2734 struct rpc_hdr_ba_info hdr_ba;
2737 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2738 TALLOC_FREE(subreq);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2741 rpccli_pipe_txt(talloc_tos(), state->cli),
2742 nt_errstr(status)));
2743 tevent_req_nterror(req, status);
2747 /* Unmarshall the RPC header */
2748 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2749 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2750 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2754 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2755 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2757 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2761 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2762 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2763 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2767 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2768 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2771 * For authenticated binds we may need to do 3 or 4 leg binds.
2774 switch(state->cli->auth->auth_type) {
2776 case PIPE_AUTH_TYPE_NONE:
2777 case PIPE_AUTH_TYPE_SCHANNEL:
2778 /* Bind complete. */
2779 tevent_req_done(req);
2782 case PIPE_AUTH_TYPE_NTLMSSP:
2783 /* Need to send AUTH3 packet - no reply. */
2784 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2786 if (!NT_STATUS_IS_OK(status)) {
2787 tevent_req_nterror(req, status);
2791 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2792 /* Need to send alter context request and reply. */
2793 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2795 if (!NT_STATUS_IS_OK(status)) {
2796 tevent_req_nterror(req, status);
2800 case PIPE_AUTH_TYPE_KRB5:
2804 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2805 (unsigned int)state->cli->auth->auth_type));
2806 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2810 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2811 struct rpc_pipe_bind_state *state,
2812 struct rpc_hdr_info *phdr,
2813 prs_struct *reply_pdu)
2815 DATA_BLOB server_response = data_blob_null;
2816 DATA_BLOB client_reply = data_blob_null;
2817 struct rpc_hdr_auth_info hdr_auth;
2818 struct tevent_req *subreq;
2821 if ((phdr->auth_len == 0)
2822 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2823 return NT_STATUS_INVALID_PARAMETER;
2826 if (!prs_set_offset(
2828 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2829 return NT_STATUS_INVALID_PARAMETER;
2832 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2833 return NT_STATUS_INVALID_PARAMETER;
2836 /* TODO - check auth_type/auth_level match. */
2838 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2839 prs_copy_data_out((char *)server_response.data, reply_pdu,
2842 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2843 server_response, &client_reply);
2845 if (!NT_STATUS_IS_OK(status)) {
2846 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2847 "blob failed: %s.\n", nt_errstr(status)));
2851 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2853 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2854 state->cli->auth->auth_type,
2855 state->cli->auth->auth_level,
2856 &client_reply, &state->rpc_out);
2857 data_blob_free(&client_reply);
2859 if (!NT_STATUS_IS_OK(status)) {
2863 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2864 (uint8_t *)prs_data_p(&state->rpc_out),
2865 prs_offset(&state->rpc_out));
2866 if (subreq == NULL) {
2867 return NT_STATUS_NO_MEMORY;
2869 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2870 return NT_STATUS_OK;
2873 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2875 struct tevent_req *req = tevent_req_callback_data(
2876 subreq, struct tevent_req);
2879 status = rpc_write_recv(subreq);
2880 TALLOC_FREE(subreq);
2881 if (!NT_STATUS_IS_OK(status)) {
2882 tevent_req_nterror(req, status);
2885 tevent_req_done(req);
2888 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2889 struct rpc_pipe_bind_state *state,
2890 struct rpc_hdr_info *phdr,
2891 prs_struct *reply_pdu)
2893 DATA_BLOB server_spnego_response = data_blob_null;
2894 DATA_BLOB server_ntlm_response = data_blob_null;
2895 DATA_BLOB client_reply = data_blob_null;
2896 DATA_BLOB tmp_blob = data_blob_null;
2897 RPC_HDR_AUTH hdr_auth;
2898 struct tevent_req *subreq;
2901 if ((phdr->auth_len == 0)
2902 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2903 return NT_STATUS_INVALID_PARAMETER;
2906 /* Process the returned NTLMSSP blob first. */
2907 if (!prs_set_offset(
2909 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2910 return NT_STATUS_INVALID_PARAMETER;
2913 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2914 return NT_STATUS_INVALID_PARAMETER;
2917 server_spnego_response = data_blob(NULL, phdr->auth_len);
2918 prs_copy_data_out((char *)server_spnego_response.data,
2919 reply_pdu, phdr->auth_len);
2922 * The server might give us back two challenges - tmp_blob is for the
2925 if (!spnego_parse_challenge(server_spnego_response,
2926 &server_ntlm_response, &tmp_blob)) {
2927 data_blob_free(&server_spnego_response);
2928 data_blob_free(&server_ntlm_response);
2929 data_blob_free(&tmp_blob);
2930 return NT_STATUS_INVALID_PARAMETER;
2933 /* We're finished with the server spnego response and the tmp_blob. */
2934 data_blob_free(&server_spnego_response);
2935 data_blob_free(&tmp_blob);
2937 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2938 server_ntlm_response, &client_reply);
2940 /* Finished with the server_ntlm response */
2941 data_blob_free(&server_ntlm_response);
2943 if (!NT_STATUS_IS_OK(status)) {
2944 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2945 "using server blob failed.\n"));
2946 data_blob_free(&client_reply);
2950 /* SPNEGO wrap the client reply. */
2951 tmp_blob = spnego_gen_auth(client_reply);
2952 data_blob_free(&client_reply);
2953 client_reply = tmp_blob;
2954 tmp_blob = data_blob_null;
2956 /* Now prepare the alter context pdu. */
2957 prs_init_empty(&state->rpc_out, state, MARSHALL);
2959 status = create_rpc_alter_context(state->rpc_call_id,
2960 &state->cli->abstract_syntax,
2961 &state->cli->transfer_syntax,
2962 state->cli->auth->auth_level,
2965 data_blob_free(&client_reply);
2967 if (!NT_STATUS_IS_OK(status)) {
2971 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2972 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2973 if (subreq == NULL) {
2974 return NT_STATUS_NO_MEMORY;
2976 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2977 return NT_STATUS_OK;
2980 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2982 struct tevent_req *req = tevent_req_callback_data(
2983 subreq, struct tevent_req);
2984 struct rpc_pipe_bind_state *state = tevent_req_data(
2985 req, struct rpc_pipe_bind_state);
2986 DATA_BLOB server_spnego_response = data_blob_null;
2987 DATA_BLOB tmp_blob = data_blob_null;
2988 prs_struct reply_pdu;
2989 struct rpc_hdr_info hdr;
2990 struct rpc_hdr_auth_info hdr_auth;
2993 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2994 TALLOC_FREE(subreq);
2995 if (!NT_STATUS_IS_OK(status)) {
2996 tevent_req_nterror(req, status);
3000 /* Get the auth blob from the reply. */
3001 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3002 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3003 "unmarshall RPC_HDR.\n"));
3004 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3008 if (!prs_set_offset(
3010 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3011 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3015 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3016 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3020 server_spnego_response = data_blob(NULL, hdr.auth_len);
3021 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3024 /* Check we got a valid auth response. */
3025 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3026 OID_NTLMSSP, &tmp_blob)) {
3027 data_blob_free(&server_spnego_response);
3028 data_blob_free(&tmp_blob);
3029 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3033 data_blob_free(&server_spnego_response);
3034 data_blob_free(&tmp_blob);
3036 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3037 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3038 tevent_req_done(req);
3041 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3043 return tevent_req_simple_recv_ntstatus(req);
3046 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3047 struct cli_pipe_auth_data *auth)
3049 TALLOC_CTX *frame = talloc_stackframe();
3050 struct event_context *ev;
3051 struct tevent_req *req;
3052 NTSTATUS status = NT_STATUS_OK;
3054 ev = event_context_init(frame);
3056 status = NT_STATUS_NO_MEMORY;
3060 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3062 status = NT_STATUS_NO_MEMORY;
3066 if (!tevent_req_poll(req, ev)) {
3067 status = map_nt_error_from_unix(errno);
3071 status = rpc_pipe_bind_recv(req);
3077 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3079 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3080 unsigned int timeout)
3084 if (rpc_cli->transport == NULL) {
3085 return RPCCLI_DEFAULT_TIMEOUT;
3088 if (rpc_cli->transport->set_timeout == NULL) {
3089 return RPCCLI_DEFAULT_TIMEOUT;
3092 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3094 return RPCCLI_DEFAULT_TIMEOUT;
3100 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3102 if (rpc_cli == NULL) {
3106 if (rpc_cli->transport == NULL) {
3110 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3113 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3115 struct cli_state *cli;
3117 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3118 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3119 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3123 cli = rpc_pipe_np_smb_conn(rpc_cli);
3127 E_md4hash(cli->password ? cli->password : "", nt_hash);
3131 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3132 struct cli_pipe_auth_data **presult)
3134 struct cli_pipe_auth_data *result;
3136 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3137 if (result == NULL) {
3138 return NT_STATUS_NO_MEMORY;
3141 result->auth_type = PIPE_AUTH_TYPE_NONE;
3142 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3144 result->user_name = talloc_strdup(result, "");
3145 result->domain = talloc_strdup(result, "");
3146 if ((result->user_name == NULL) || (result->domain == NULL)) {
3147 TALLOC_FREE(result);
3148 return NT_STATUS_NO_MEMORY;
3152 return NT_STATUS_OK;
3155 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3157 ntlmssp_end(&auth->a_u.ntlmssp_state);
3161 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3162 enum pipe_auth_type auth_type,
3163 enum dcerpc_AuthLevel auth_level,
3165 const char *username,
3166 const char *password,
3167 struct cli_pipe_auth_data **presult)
3169 struct cli_pipe_auth_data *result;
3172 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3173 if (result == NULL) {
3174 return NT_STATUS_NO_MEMORY;
3177 result->auth_type = auth_type;
3178 result->auth_level = auth_level;
3180 result->user_name = talloc_strdup(result, username);
3181 result->domain = talloc_strdup(result, domain);
3182 if ((result->user_name == NULL) || (result->domain == NULL)) {
3183 status = NT_STATUS_NO_MEMORY;
3187 status = ntlmssp_client_start(NULL,
3190 lp_client_ntlmv2_auth(),
3191 &result->a_u.ntlmssp_state);
3192 if (!NT_STATUS_IS_OK(status)) {
3196 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3198 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3199 if (!NT_STATUS_IS_OK(status)) {
3203 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3204 if (!NT_STATUS_IS_OK(status)) {
3208 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3209 if (!NT_STATUS_IS_OK(status)) {
3214 * Turn off sign+seal to allow selected auth level to turn it back on.
3216 result->a_u.ntlmssp_state->neg_flags &=
3217 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3219 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3220 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3221 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3222 result->a_u.ntlmssp_state->neg_flags
3223 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3227 return NT_STATUS_OK;
3230 TALLOC_FREE(result);
3234 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3235 enum dcerpc_AuthLevel auth_level,
3236 struct netlogon_creds_CredentialState *creds,
3237 struct cli_pipe_auth_data **presult)
3239 struct cli_pipe_auth_data *result;
3241 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3242 if (result == NULL) {
3243 return NT_STATUS_NO_MEMORY;
3246 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3247 result->auth_level = auth_level;
3249 result->user_name = talloc_strdup(result, "");
3250 result->domain = talloc_strdup(result, domain);
3251 if ((result->user_name == NULL) || (result->domain == NULL)) {
3255 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3256 if (result->a_u.schannel_auth == NULL) {
3260 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3261 result->a_u.schannel_auth->seq_num = 0;
3262 result->a_u.schannel_auth->initiator = true;
3263 result->a_u.schannel_auth->creds = creds;
3266 return NT_STATUS_OK;
3269 TALLOC_FREE(result);
3270 return NT_STATUS_NO_MEMORY;
3274 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3276 data_blob_free(&auth->session_key);
3281 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3282 enum dcerpc_AuthLevel auth_level,
3283 const char *service_princ,
3284 const char *username,
3285 const char *password,
3286 struct cli_pipe_auth_data **presult)
3289 struct cli_pipe_auth_data *result;
3291 if ((username != NULL) && (password != NULL)) {
3292 int ret = kerberos_kinit_password(username, password, 0, NULL);
3294 return NT_STATUS_ACCESS_DENIED;
3298 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3299 if (result == NULL) {
3300 return NT_STATUS_NO_MEMORY;
3303 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3304 result->auth_level = auth_level;
3307 * Username / domain need fixing!
3309 result->user_name = talloc_strdup(result, "");
3310 result->domain = talloc_strdup(result, "");
3311 if ((result->user_name == NULL) || (result->domain == NULL)) {
3315 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3316 result, struct kerberos_auth_struct);
3317 if (result->a_u.kerberos_auth == NULL) {
3320 talloc_set_destructor(result->a_u.kerberos_auth,
3321 cli_auth_kerberos_data_destructor);
3323 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3324 result, service_princ);
3325 if (result->a_u.kerberos_auth->service_principal == NULL) {
3330 return NT_STATUS_OK;
3333 TALLOC_FREE(result);
3334 return NT_STATUS_NO_MEMORY;
3336 return NT_STATUS_NOT_SUPPORTED;
3341 * Create an rpc pipe client struct, connecting to a tcp port.
3343 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3345 const struct ndr_syntax_id *abstract_syntax,
3346 struct rpc_pipe_client **presult)
3348 struct rpc_pipe_client *result;
3349 struct sockaddr_storage addr;
3353 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3354 if (result == NULL) {
3355 return NT_STATUS_NO_MEMORY;
3358 result->abstract_syntax = *abstract_syntax;
3359 result->transfer_syntax = ndr_transfer_syntax;
3360 result->dispatch = cli_do_rpc_ndr;
3361 result->dispatch_send = cli_do_rpc_ndr_send;
3362 result->dispatch_recv = cli_do_rpc_ndr_recv;
3364 result->desthost = talloc_strdup(result, host);
3365 result->srv_name_slash = talloc_asprintf_strupper_m(
3366 result, "\\\\%s", result->desthost);
3367 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3368 status = NT_STATUS_NO_MEMORY;
3372 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3373 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3375 if (!resolve_name(host, &addr, 0, false)) {
3376 status = NT_STATUS_NOT_FOUND;
3380 status = open_socket_out(&addr, port, 60, &fd);
3381 if (!NT_STATUS_IS_OK(status)) {
3384 set_socket_options(fd, lp_socket_options());
3386 status = rpc_transport_sock_init(result, fd, &result->transport);
3387 if (!NT_STATUS_IS_OK(status)) {
3392 result->transport->transport = NCACN_IP_TCP;
3395 return NT_STATUS_OK;
3398 TALLOC_FREE(result);
3403 * Determine the tcp port on which a dcerpc interface is listening
3404 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3407 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3408 const struct ndr_syntax_id *abstract_syntax,
3412 struct rpc_pipe_client *epm_pipe = NULL;
3413 struct cli_pipe_auth_data *auth = NULL;
3414 struct dcerpc_binding *map_binding = NULL;
3415 struct dcerpc_binding *res_binding = NULL;
3416 struct epm_twr_t *map_tower = NULL;
3417 struct epm_twr_t *res_towers = NULL;
3418 struct policy_handle *entry_handle = NULL;
3419 uint32_t num_towers = 0;
3420 uint32_t max_towers = 1;
3421 struct epm_twr_p_t towers;
3422 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3424 if (pport == NULL) {
3425 status = NT_STATUS_INVALID_PARAMETER;
3429 /* open the connection to the endpoint mapper */
3430 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3431 &ndr_table_epmapper.syntax_id,
3434 if (!NT_STATUS_IS_OK(status)) {
3438 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3439 if (!NT_STATUS_IS_OK(status)) {
3443 status = rpc_pipe_bind(epm_pipe, auth);
3444 if (!NT_STATUS_IS_OK(status)) {
3448 /* create tower for asking the epmapper */
3450 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3451 if (map_binding == NULL) {
3452 status = NT_STATUS_NO_MEMORY;
3456 map_binding->transport = NCACN_IP_TCP;
3457 map_binding->object = *abstract_syntax;
3458 map_binding->host = host; /* needed? */
3459 map_binding->endpoint = "0"; /* correct? needed? */
3461 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3462 if (map_tower == NULL) {
3463 status = NT_STATUS_NO_MEMORY;
3467 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3468 &(map_tower->tower));
3469 if (!NT_STATUS_IS_OK(status)) {
3473 /* allocate further parameters for the epm_Map call */
3475 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3476 if (res_towers == NULL) {
3477 status = NT_STATUS_NO_MEMORY;
3480 towers.twr = res_towers;
3482 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3483 if (entry_handle == NULL) {
3484 status = NT_STATUS_NO_MEMORY;
3488 /* ask the endpoint mapper for the port */
3490 status = rpccli_epm_Map(epm_pipe,
3492 CONST_DISCARD(struct GUID *,
3493 &(abstract_syntax->uuid)),
3500 if (!NT_STATUS_IS_OK(status)) {
3504 if (num_towers != 1) {
3505 status = NT_STATUS_UNSUCCESSFUL;
3509 /* extract the port from the answer */
3511 status = dcerpc_binding_from_tower(tmp_ctx,
3512 &(towers.twr->tower),
3514 if (!NT_STATUS_IS_OK(status)) {
3518 /* are further checks here necessary? */
3519 if (res_binding->transport != NCACN_IP_TCP) {
3520 status = NT_STATUS_UNSUCCESSFUL;
3524 *pport = (uint16_t)atoi(res_binding->endpoint);
3527 TALLOC_FREE(tmp_ctx);
3532 * Create a rpc pipe client struct, connecting to a host via tcp.
3533 * The port is determined by asking the endpoint mapper on the given
3536 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3537 const struct ndr_syntax_id *abstract_syntax,
3538 struct rpc_pipe_client **presult)
3543 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3544 if (!NT_STATUS_IS_OK(status)) {
3548 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3549 abstract_syntax, presult);
3552 /********************************************************************
3553 Create a rpc pipe client struct, connecting to a unix domain socket
3554 ********************************************************************/
3555 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3556 const struct ndr_syntax_id *abstract_syntax,
3557 struct rpc_pipe_client **presult)
3559 struct rpc_pipe_client *result;
3560 struct sockaddr_un addr;
3564 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3565 if (result == NULL) {
3566 return NT_STATUS_NO_MEMORY;
3569 result->abstract_syntax = *abstract_syntax;
3570 result->transfer_syntax = ndr_transfer_syntax;
3571 result->dispatch = cli_do_rpc_ndr;
3572 result->dispatch_send = cli_do_rpc_ndr_send;
3573 result->dispatch_recv = cli_do_rpc_ndr_recv;
3575 result->desthost = get_myname(result);
3576 result->srv_name_slash = talloc_asprintf_strupper_m(
3577 result, "\\\\%s", result->desthost);
3578 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3579 status = NT_STATUS_NO_MEMORY;
3583 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3584 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3586 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3588 status = map_nt_error_from_unix(errno);
3593 addr.sun_family = AF_UNIX;
3594 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3596 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3597 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3600 return map_nt_error_from_unix(errno);
3603 status = rpc_transport_sock_init(result, fd, &result->transport);
3604 if (!NT_STATUS_IS_OK(status)) {
3609 result->transport->transport = NCALRPC;
3612 return NT_STATUS_OK;
3615 TALLOC_FREE(result);
3619 struct rpc_pipe_client_np_ref {
3620 struct cli_state *cli;
3621 struct rpc_pipe_client *pipe;
3624 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3626 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3630 /****************************************************************************
3631 Open a named pipe over SMB to a remote server.
3633 * CAVEAT CALLER OF THIS FUNCTION:
3634 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3635 * so be sure that this function is called AFTER any structure (vs pointer)
3636 * assignment of the cli. In particular, libsmbclient does structure
3637 * assignments of cli, which invalidates the data in the returned
3638 * rpc_pipe_client if this function is called before the structure assignment
3641 ****************************************************************************/
3643 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3644 const struct ndr_syntax_id *abstract_syntax,
3645 struct rpc_pipe_client **presult)
3647 struct rpc_pipe_client *result;
3649 struct rpc_pipe_client_np_ref *np_ref;
3651 /* sanity check to protect against crashes */
3654 return NT_STATUS_INVALID_HANDLE;
3657 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3658 if (result == NULL) {
3659 return NT_STATUS_NO_MEMORY;
3662 result->abstract_syntax = *abstract_syntax;
3663 result->transfer_syntax = ndr_transfer_syntax;
3664 result->dispatch = cli_do_rpc_ndr;
3665 result->dispatch_send = cli_do_rpc_ndr_send;
3666 result->dispatch_recv = cli_do_rpc_ndr_recv;
3667 result->desthost = talloc_strdup(result, cli->desthost);
3668 result->srv_name_slash = talloc_asprintf_strupper_m(
3669 result, "\\\\%s", result->desthost);
3671 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3672 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3674 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3675 TALLOC_FREE(result);
3676 return NT_STATUS_NO_MEMORY;
3679 status = rpc_transport_np_init(result, cli, abstract_syntax,
3680 &result->transport);
3681 if (!NT_STATUS_IS_OK(status)) {
3682 TALLOC_FREE(result);
3686 result->transport->transport = NCACN_NP;
3688 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3689 if (np_ref == NULL) {
3690 TALLOC_FREE(result);
3691 return NT_STATUS_NO_MEMORY;
3694 np_ref->pipe = result;
3696 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3697 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3700 return NT_STATUS_OK;
3703 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3704 struct rpc_cli_smbd_conn *conn,
3705 const struct ndr_syntax_id *syntax,
3706 struct rpc_pipe_client **presult)
3708 struct rpc_pipe_client *result;
3709 struct cli_pipe_auth_data *auth;
3712 result = talloc(mem_ctx, struct rpc_pipe_client);
3713 if (result == NULL) {
3714 return NT_STATUS_NO_MEMORY;
3716 result->abstract_syntax = *syntax;
3717 result->transfer_syntax = ndr_transfer_syntax;
3718 result->dispatch = cli_do_rpc_ndr;
3719 result->dispatch_send = cli_do_rpc_ndr_send;
3720 result->dispatch_recv = cli_do_rpc_ndr_recv;
3721 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3722 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3724 result->desthost = talloc_strdup(result, global_myname());
3725 result->srv_name_slash = talloc_asprintf_strupper_m(
3726 result, "\\\\%s", global_myname());
3727 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3728 TALLOC_FREE(result);
3729 return NT_STATUS_NO_MEMORY;
3732 status = rpc_transport_smbd_init(result, conn, syntax,
3733 &result->transport);
3734 if (!NT_STATUS_IS_OK(status)) {
3735 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3736 nt_errstr(status)));
3737 TALLOC_FREE(result);
3741 status = rpccli_anon_bind_data(result, &auth);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3744 nt_errstr(status)));
3745 TALLOC_FREE(result);
3749 status = rpc_pipe_bind(result, auth);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3752 TALLOC_FREE(result);
3756 result->transport->transport = NCACN_INTERNAL;
3759 return NT_STATUS_OK;
3762 /****************************************************************************
3763 Open a pipe to a remote server.
3764 ****************************************************************************/
3766 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3767 enum dcerpc_transport_t transport,
3768 const struct ndr_syntax_id *interface,
3769 struct rpc_pipe_client **presult)
3771 switch (transport) {
3773 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3776 return rpc_pipe_open_np(cli, interface, presult);
3778 return NT_STATUS_NOT_IMPLEMENTED;
3782 /****************************************************************************
3783 Open a named pipe to an SMB server and bind anonymously.
3784 ****************************************************************************/
3786 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3787 enum dcerpc_transport_t transport,
3788 const struct ndr_syntax_id *interface,
3789 struct rpc_pipe_client **presult)
3791 struct rpc_pipe_client *result;
3792 struct cli_pipe_auth_data *auth;
3795 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3796 if (!NT_STATUS_IS_OK(status)) {
3800 status = rpccli_anon_bind_data(result, &auth);
3801 if (!NT_STATUS_IS_OK(status)) {
3802 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3803 nt_errstr(status)));
3804 TALLOC_FREE(result);
3809 * This is a bit of an abstraction violation due to the fact that an
3810 * anonymous bind on an authenticated SMB inherits the user/domain
3811 * from the enclosing SMB creds
3814 TALLOC_FREE(auth->user_name);
3815 TALLOC_FREE(auth->domain);
3817 auth->user_name = talloc_strdup(auth, cli->user_name);
3818 auth->domain = talloc_strdup(auth, cli->domain);
3819 auth->user_session_key = data_blob_talloc(auth,
3820 cli->user_session_key.data,
3821 cli->user_session_key.length);
3823 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3824 TALLOC_FREE(result);
3825 return NT_STATUS_NO_MEMORY;
3828 status = rpc_pipe_bind(result, auth);
3829 if (!NT_STATUS_IS_OK(status)) {
3831 if (ndr_syntax_id_equal(interface,
3832 &ndr_table_dssetup.syntax_id)) {
3833 /* non AD domains just don't have this pipe, avoid
3834 * level 0 statement in that case - gd */
3837 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3838 "%s failed with error %s\n",
3839 get_pipe_name_from_syntax(talloc_tos(), interface),
3840 nt_errstr(status) ));
3841 TALLOC_FREE(result);
3845 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3846 "%s and bound anonymously.\n",
3847 get_pipe_name_from_syntax(talloc_tos(), interface),
3851 return NT_STATUS_OK;
3854 /****************************************************************************
3855 ****************************************************************************/
3857 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3858 const struct ndr_syntax_id *interface,
3859 struct rpc_pipe_client **presult)
3861 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3862 interface, presult);
3865 /****************************************************************************
3866 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3867 ****************************************************************************/
3869 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3870 const struct ndr_syntax_id *interface,
3871 enum dcerpc_transport_t transport,
3872 enum pipe_auth_type auth_type,
3873 enum dcerpc_AuthLevel auth_level,
3875 const char *username,
3876 const char *password,
3877 struct rpc_pipe_client **presult)
3879 struct rpc_pipe_client *result;
3880 struct cli_pipe_auth_data *auth;
3883 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3884 if (!NT_STATUS_IS_OK(status)) {
3888 status = rpccli_ntlmssp_bind_data(
3889 result, auth_type, auth_level, domain, username,
3891 if (!NT_STATUS_IS_OK(status)) {
3892 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3893 nt_errstr(status)));
3897 status = rpc_pipe_bind(result, auth);
3898 if (!NT_STATUS_IS_OK(status)) {
3899 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3900 nt_errstr(status) ));
3904 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3905 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3906 get_pipe_name_from_syntax(talloc_tos(), interface),
3907 cli->desthost, domain, username ));
3910 return NT_STATUS_OK;
3914 TALLOC_FREE(result);
3918 /****************************************************************************
3920 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3921 ****************************************************************************/
3923 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3924 const struct ndr_syntax_id *interface,
3925 enum dcerpc_transport_t transport,
3926 enum dcerpc_AuthLevel auth_level,
3928 const char *username,
3929 const char *password,
3930 struct rpc_pipe_client **presult)
3932 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3935 PIPE_AUTH_TYPE_NTLMSSP,
3943 /****************************************************************************
3945 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3946 ****************************************************************************/
3948 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3949 const struct ndr_syntax_id *interface,
3950 enum dcerpc_transport_t transport,
3951 enum dcerpc_AuthLevel auth_level,
3953 const char *username,
3954 const char *password,
3955 struct rpc_pipe_client **presult)
3957 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3960 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3968 /****************************************************************************
3969 Get a the schannel session key out of an already opened netlogon pipe.
3970 ****************************************************************************/
3971 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3972 struct cli_state *cli,
3976 enum netr_SchannelType sec_chan_type = 0;
3977 unsigned char machine_pwd[16];
3978 const char *machine_account;
3981 /* Get the machine account credentials from secrets.tdb. */
3982 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3985 DEBUG(0, ("get_schannel_session_key: could not fetch "
3986 "trust account password for domain '%s'\n",
3988 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3991 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3992 cli->desthost, /* server name */
3993 domain, /* domain */
3994 global_myname(), /* client name */
3995 machine_account, /* machine account name */
4000 if (!NT_STATUS_IS_OK(status)) {
4001 DEBUG(3, ("get_schannel_session_key_common: "
4002 "rpccli_netlogon_setup_creds failed with result %s "
4003 "to server %s, domain %s, machine account %s.\n",
4004 nt_errstr(status), cli->desthost, domain,
4009 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4010 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4012 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4015 return NT_STATUS_OK;;
4018 /****************************************************************************
4019 Open a netlogon pipe and get the schannel session key.
4020 Now exposed to external callers.
4021 ****************************************************************************/
4024 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4027 struct rpc_pipe_client **presult)
4029 struct rpc_pipe_client *netlogon_pipe = NULL;
4032 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4034 if (!NT_STATUS_IS_OK(status)) {
4038 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4040 if (!NT_STATUS_IS_OK(status)) {
4041 TALLOC_FREE(netlogon_pipe);
4045 *presult = netlogon_pipe;
4046 return NT_STATUS_OK;
4049 /****************************************************************************
4051 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4052 using session_key. sign and seal.
4054 The *pdc will be stolen onto this new pipe
4055 ****************************************************************************/
4057 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4058 const struct ndr_syntax_id *interface,
4059 enum dcerpc_transport_t transport,
4060 enum dcerpc_AuthLevel auth_level,
4062 struct netlogon_creds_CredentialState **pdc,
4063 struct rpc_pipe_client **presult)
4065 struct rpc_pipe_client *result;
4066 struct cli_pipe_auth_data *auth;
4069 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4070 if (!NT_STATUS_IS_OK(status)) {
4074 status = rpccli_schannel_bind_data(result, domain, auth_level,
4076 if (!NT_STATUS_IS_OK(status)) {
4077 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4078 nt_errstr(status)));
4079 TALLOC_FREE(result);
4083 status = rpc_pipe_bind(result, auth);
4084 if (!NT_STATUS_IS_OK(status)) {
4085 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4086 "cli_rpc_pipe_bind failed with error %s\n",
4087 nt_errstr(status) ));
4088 TALLOC_FREE(result);
4093 * The credentials on a new netlogon pipe are the ones we are passed
4094 * in - reference them in
4096 result->dc = talloc_move(result, pdc);
4098 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4099 "for domain %s and bound using schannel.\n",
4100 get_pipe_name_from_syntax(talloc_tos(), interface),
4101 cli->desthost, domain ));
4104 return NT_STATUS_OK;
4107 /****************************************************************************
4108 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4109 Fetch the session key ourselves using a temporary netlogon pipe. This
4110 version uses an ntlmssp auth bound netlogon pipe to get the key.
4111 ****************************************************************************/
4113 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4115 const char *username,
4116 const char *password,
4118 struct rpc_pipe_client **presult)
4120 struct rpc_pipe_client *netlogon_pipe = NULL;
4123 status = cli_rpc_pipe_open_spnego_ntlmssp(
4124 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4125 DCERPC_AUTH_LEVEL_PRIVACY,
4126 domain, username, password, &netlogon_pipe);
4127 if (!NT_STATUS_IS_OK(status)) {
4131 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4133 if (!NT_STATUS_IS_OK(status)) {
4134 TALLOC_FREE(netlogon_pipe);
4138 *presult = netlogon_pipe;
4139 return NT_STATUS_OK;
4142 /****************************************************************************
4143 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4144 Fetch the session key ourselves using a temporary netlogon pipe. This version
4145 uses an ntlmssp bind to get the session key.
4146 ****************************************************************************/
4148 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4149 const struct ndr_syntax_id *interface,
4150 enum dcerpc_transport_t transport,
4151 enum dcerpc_AuthLevel auth_level,
4153 const char *username,
4154 const char *password,
4155 struct rpc_pipe_client **presult)
4157 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4158 struct rpc_pipe_client *netlogon_pipe = NULL;
4159 struct rpc_pipe_client *result = NULL;
4162 status = get_schannel_session_key_auth_ntlmssp(
4163 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4164 if (!NT_STATUS_IS_OK(status)) {
4165 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4166 "key from server %s for domain %s.\n",
4167 cli->desthost, domain ));
4171 status = cli_rpc_pipe_open_schannel_with_key(
4172 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4175 /* Now we've bound using the session key we can close the netlog pipe. */
4176 TALLOC_FREE(netlogon_pipe);
4178 if (NT_STATUS_IS_OK(status)) {
4184 /****************************************************************************
4185 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4186 Fetch the session key ourselves using a temporary netlogon pipe.
4187 ****************************************************************************/
4189 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4190 const struct ndr_syntax_id *interface,
4191 enum dcerpc_transport_t transport,
4192 enum dcerpc_AuthLevel auth_level,
4194 struct rpc_pipe_client **presult)
4196 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4197 struct rpc_pipe_client *netlogon_pipe = NULL;
4198 struct rpc_pipe_client *result = NULL;
4201 status = get_schannel_session_key(cli, domain, &neg_flags,
4203 if (!NT_STATUS_IS_OK(status)) {
4204 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4205 "key from server %s for domain %s.\n",
4206 cli->desthost, domain ));
4210 status = cli_rpc_pipe_open_schannel_with_key(
4211 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4214 /* Now we've bound using the session key we can close the netlog pipe. */
4215 TALLOC_FREE(netlogon_pipe);
4217 if (NT_STATUS_IS_OK(status)) {
4224 /****************************************************************************
4225 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4226 The idea is this can be called with service_princ, username and password all
4227 NULL so long as the caller has a TGT.
4228 ****************************************************************************/
4230 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4231 const struct ndr_syntax_id *interface,
4232 enum dcerpc_AuthLevel auth_level,
4233 const char *service_princ,
4234 const char *username,
4235 const char *password,
4236 struct rpc_pipe_client **presult)
4239 struct rpc_pipe_client *result;
4240 struct cli_pipe_auth_data *auth;
4243 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4244 if (!NT_STATUS_IS_OK(status)) {
4248 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4249 username, password, &auth);
4250 if (!NT_STATUS_IS_OK(status)) {
4251 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4252 nt_errstr(status)));
4253 TALLOC_FREE(result);
4257 status = rpc_pipe_bind(result, auth);
4258 if (!NT_STATUS_IS_OK(status)) {
4259 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4260 "with error %s\n", nt_errstr(status)));
4261 TALLOC_FREE(result);
4266 return NT_STATUS_OK;
4268 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4269 return NT_STATUS_NOT_IMPLEMENTED;
4273 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4274 struct rpc_pipe_client *cli,
4275 DATA_BLOB *session_key)
4277 if (!session_key || !cli) {
4278 return NT_STATUS_INVALID_PARAMETER;
4282 return NT_STATUS_INVALID_PARAMETER;
4285 switch (cli->auth->auth_type) {
4286 case PIPE_AUTH_TYPE_SCHANNEL:
4287 *session_key = data_blob_talloc(mem_ctx,
4288 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4290 case PIPE_AUTH_TYPE_NTLMSSP:
4291 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4292 *session_key = data_blob_talloc(mem_ctx,
4293 cli->auth->a_u.ntlmssp_state->session_key.data,
4294 cli->auth->a_u.ntlmssp_state->session_key.length);
4296 case PIPE_AUTH_TYPE_KRB5:
4297 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4298 *session_key = data_blob_talloc(mem_ctx,
4299 cli->auth->a_u.kerberos_auth->session_key.data,
4300 cli->auth->a_u.kerberos_auth->session_key.length);
4302 case PIPE_AUTH_TYPE_NONE:
4303 *session_key = data_blob_talloc(mem_ctx,
4304 cli->auth->user_session_key.data,
4305 cli->auth->user_session_key.length);
4308 return NT_STATUS_NO_USER_SESSION_KEY;
4311 return NT_STATUS_OK;