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 *******************************************************************/
341 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
342 const DATA_BLOB *blob,
343 struct ncacn_packet *r)
345 enum ndr_err_code ndr_err;
347 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
348 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
350 return ndr_map_error2ntstatus(ndr_err);
353 if (DEBUGLEVEL >= 10) {
354 NDR_PRINT_DEBUG(ncacn_packet, r);
360 /*******************************************************************
361 *******************************************************************/
363 NTSTATUS dcerpc_pull_ncacn_packet_header(TALLOC_CTX *mem_ctx,
364 const DATA_BLOB *blob,
365 struct ncacn_packet_header *r)
367 enum ndr_err_code ndr_err;
369 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
370 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet_header);
371 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
372 return ndr_map_error2ntstatus(ndr_err);
375 if (DEBUGLEVEL >= 10) {
376 NDR_PRINT_DEBUG(ncacn_packet_header, r);
382 /*******************************************************************
383 ********************************************************************/
385 static NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
386 struct NL_AUTH_MESSAGE *r,
389 enum ndr_err_code ndr_err;
391 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
392 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
393 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
394 return ndr_map_error2ntstatus(ndr_err);
397 if (DEBUGLEVEL >= 10) {
398 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
404 /*******************************************************************
405 Use SMBreadX to get rest of one fragment's worth of rpc data.
406 Reads the whole size or give an error message
407 ********************************************************************/
409 struct rpc_read_state {
410 struct event_context *ev;
411 struct rpc_cli_transport *transport;
417 static void rpc_read_done(struct tevent_req *subreq);
419 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
420 struct event_context *ev,
421 struct rpc_cli_transport *transport,
422 uint8_t *data, size_t size)
424 struct tevent_req *req, *subreq;
425 struct rpc_read_state *state;
427 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
432 state->transport = transport;
437 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
439 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
441 if (subreq == NULL) {
444 tevent_req_set_callback(subreq, rpc_read_done, req);
452 static void rpc_read_done(struct tevent_req *subreq)
454 struct tevent_req *req = tevent_req_callback_data(
455 subreq, struct tevent_req);
456 struct rpc_read_state *state = tevent_req_data(
457 req, struct rpc_read_state);
461 status = state->transport->read_recv(subreq, &received);
463 if (!NT_STATUS_IS_OK(status)) {
464 tevent_req_nterror(req, status);
468 state->num_read += received;
469 if (state->num_read == state->size) {
470 tevent_req_done(req);
474 subreq = state->transport->read_send(state, state->ev,
475 state->data + state->num_read,
476 state->size - state->num_read,
477 state->transport->priv);
478 if (tevent_req_nomem(subreq, req)) {
481 tevent_req_set_callback(subreq, rpc_read_done, req);
484 static NTSTATUS rpc_read_recv(struct tevent_req *req)
486 return tevent_req_simple_recv_ntstatus(req);
489 struct rpc_write_state {
490 struct event_context *ev;
491 struct rpc_cli_transport *transport;
497 static void rpc_write_done(struct tevent_req *subreq);
499 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
500 struct event_context *ev,
501 struct rpc_cli_transport *transport,
502 const uint8_t *data, size_t size)
504 struct tevent_req *req, *subreq;
505 struct rpc_write_state *state;
507 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
512 state->transport = transport;
515 state->num_written = 0;
517 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
519 subreq = transport->write_send(state, ev, data, size, transport->priv);
520 if (subreq == NULL) {
523 tevent_req_set_callback(subreq, rpc_write_done, req);
530 static void rpc_write_done(struct tevent_req *subreq)
532 struct tevent_req *req = tevent_req_callback_data(
533 subreq, struct tevent_req);
534 struct rpc_write_state *state = tevent_req_data(
535 req, struct rpc_write_state);
539 status = state->transport->write_recv(subreq, &written);
541 if (!NT_STATUS_IS_OK(status)) {
542 tevent_req_nterror(req, status);
546 state->num_written += written;
548 if (state->num_written == state->size) {
549 tevent_req_done(req);
553 subreq = state->transport->write_send(state, state->ev,
554 state->data + state->num_written,
555 state->size - state->num_written,
556 state->transport->priv);
557 if (tevent_req_nomem(subreq, req)) {
560 tevent_req_set_callback(subreq, rpc_write_done, req);
563 static NTSTATUS rpc_write_recv(struct tevent_req *req)
565 return tevent_req_simple_recv_ntstatus(req);
569 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
570 struct rpc_hdr_info *prhdr,
574 * This next call sets the endian bit correctly in current_pdu. We
575 * will propagate this to rbuf later.
578 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
579 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
580 return NT_STATUS_BUFFER_TOO_SMALL;
583 if (prhdr->frag_len > cli->max_recv_frag) {
584 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
585 " we only allow %d\n", (int)prhdr->frag_len,
586 (int)cli->max_recv_frag));
587 return NT_STATUS_BUFFER_TOO_SMALL;
593 /****************************************************************************
594 Try and get a PDU's worth of data from current_pdu. If not, then read more
596 ****************************************************************************/
598 struct get_complete_frag_state {
599 struct event_context *ev;
600 struct rpc_pipe_client *cli;
601 struct rpc_hdr_info *prhdr;
605 static void get_complete_frag_got_header(struct tevent_req *subreq);
606 static void get_complete_frag_got_rest(struct tevent_req *subreq);
608 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
609 struct event_context *ev,
610 struct rpc_pipe_client *cli,
611 struct rpc_hdr_info *prhdr,
614 struct tevent_req *req, *subreq;
615 struct get_complete_frag_state *state;
619 req = tevent_req_create(mem_ctx, &state,
620 struct get_complete_frag_state);
626 state->prhdr = prhdr;
629 pdu_len = prs_data_size(pdu);
630 if (pdu_len < RPC_HEADER_LEN) {
631 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
632 status = NT_STATUS_NO_MEMORY;
635 subreq = rpc_read_send(
637 state->cli->transport,
638 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
639 RPC_HEADER_LEN - pdu_len);
640 if (subreq == NULL) {
641 status = NT_STATUS_NO_MEMORY;
644 tevent_req_set_callback(subreq, get_complete_frag_got_header,
649 status = parse_rpc_header(cli, prhdr, pdu);
650 if (!NT_STATUS_IS_OK(status)) {
655 * Ensure we have frag_len bytes of data.
657 if (pdu_len < prhdr->frag_len) {
658 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
659 status = NT_STATUS_NO_MEMORY;
662 subreq = rpc_read_send(state, state->ev,
663 state->cli->transport,
664 (uint8_t *)(prs_data_p(pdu) + pdu_len),
665 prhdr->frag_len - pdu_len);
666 if (subreq == NULL) {
667 status = NT_STATUS_NO_MEMORY;
670 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
675 status = NT_STATUS_OK;
677 if (NT_STATUS_IS_OK(status)) {
678 tevent_req_done(req);
680 tevent_req_nterror(req, status);
682 return tevent_req_post(req, ev);
685 static void get_complete_frag_got_header(struct tevent_req *subreq)
687 struct tevent_req *req = tevent_req_callback_data(
688 subreq, struct tevent_req);
689 struct get_complete_frag_state *state = tevent_req_data(
690 req, struct get_complete_frag_state);
693 status = rpc_read_recv(subreq);
695 if (!NT_STATUS_IS_OK(status)) {
696 tevent_req_nterror(req, status);
700 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
701 if (!NT_STATUS_IS_OK(status)) {
702 tevent_req_nterror(req, status);
706 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
707 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
712 * We're here in this piece of code because we've read exactly
713 * RPC_HEADER_LEN bytes into state->pdu.
716 subreq = rpc_read_send(
717 state, state->ev, state->cli->transport,
718 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
719 state->prhdr->frag_len - RPC_HEADER_LEN);
720 if (tevent_req_nomem(subreq, req)) {
723 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
726 static void get_complete_frag_got_rest(struct tevent_req *subreq)
728 struct tevent_req *req = tevent_req_callback_data(
729 subreq, struct tevent_req);
732 status = rpc_read_recv(subreq);
734 if (!NT_STATUS_IS_OK(status)) {
735 tevent_req_nterror(req, status);
738 tevent_req_done(req);
741 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
743 return tevent_req_simple_recv_ntstatus(req);
746 /****************************************************************************
747 NTLMSSP specific sign/seal.
748 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
749 In fact I should probably abstract these into identical pieces of code... JRA.
750 ****************************************************************************/
752 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
753 prs_struct *current_pdu,
754 uint8 *p_ss_padding_len)
756 RPC_HDR_AUTH auth_info;
757 uint32 save_offset = prs_offset(current_pdu);
758 uint32 auth_len = prhdr->auth_len;
759 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
760 unsigned char *data = NULL;
762 unsigned char *full_packet_data = NULL;
763 size_t full_packet_data_len;
767 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
768 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
772 if (!ntlmssp_state) {
773 return NT_STATUS_INVALID_PARAMETER;
776 /* Ensure there's enough data for an authenticated response. */
777 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
778 prhdr->frag_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
779 RPC_HDR_AUTH_LEN + auth_len) {
780 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
781 (unsigned int)auth_len ));
782 return NT_STATUS_BUFFER_TOO_SMALL;
786 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
787 * after the RPC header.
788 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
789 * functions as NTLMv2 checks the rpc headers also.
792 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
793 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
795 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
796 full_packet_data_len = prhdr->frag_len - auth_len;
798 /* Pull the auth header and the following data into a blob. */
799 /* NB. The offset of the auth_header is relative to the *end*
800 * of the packet, not the start. */
801 if(!prs_set_offset(current_pdu, prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
802 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
803 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
804 return NT_STATUS_BUFFER_TOO_SMALL;
807 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
808 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
809 return NT_STATUS_BUFFER_TOO_SMALL;
812 /* Ensure auth_pad_len fits into the packet. */
813 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
814 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
815 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
816 "too large (%u), auth_len (%u), frag_len = (%u).\n",
817 (unsigned int)auth_info.auth_pad_len,
818 (unsigned int)auth_len,
819 (unsigned int)prhdr->frag_len ));
820 return NT_STATUS_BUFFER_TOO_SMALL;
824 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
825 auth_blob.length = auth_len;
827 switch (cli->auth->auth_level) {
828 case DCERPC_AUTH_LEVEL_PRIVACY:
829 /* Data is encrypted. */
830 status = ntlmssp_unseal_packet(ntlmssp_state,
833 full_packet_data_len,
835 if (!NT_STATUS_IS_OK(status)) {
836 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
837 "packet from %s. Error was %s.\n",
838 rpccli_pipe_txt(talloc_tos(), cli),
839 nt_errstr(status) ));
843 case DCERPC_AUTH_LEVEL_INTEGRITY:
844 /* Data is signed. */
845 status = ntlmssp_check_packet(ntlmssp_state,
848 full_packet_data_len,
850 if (!NT_STATUS_IS_OK(status)) {
851 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
852 "packet from %s. Error was %s.\n",
853 rpccli_pipe_txt(talloc_tos(), cli),
854 nt_errstr(status) ));
859 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
860 "auth level %d\n", cli->auth->auth_level));
861 return NT_STATUS_INVALID_INFO_CLASS;
865 * Return the current pointer to the data offset.
868 if(!prs_set_offset(current_pdu, save_offset)) {
869 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
870 (unsigned int)save_offset ));
871 return NT_STATUS_BUFFER_TOO_SMALL;
875 * Remember the padding length. We must remove it from the real data
876 * stream once the sign/seal is done.
879 *p_ss_padding_len = auth_info.auth_pad_len;
884 /****************************************************************************
885 schannel specific sign/seal.
886 ****************************************************************************/
888 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
889 prs_struct *current_pdu,
890 uint8 *p_ss_padding_len)
892 RPC_HDR_AUTH auth_info;
893 uint32 auth_len = prhdr->auth_len;
894 uint32 save_offset = prs_offset(current_pdu);
895 struct schannel_state *schannel_auth =
896 cli->auth->a_u.schannel_auth;
902 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
903 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
907 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
908 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
909 return NT_STATUS_INVALID_PARAMETER;
912 if (!schannel_auth) {
913 return NT_STATUS_INVALID_PARAMETER;
916 /* Ensure there's enough data for an authenticated response. */
917 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
918 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
919 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
920 (unsigned int)auth_len ));
921 return NT_STATUS_INVALID_PARAMETER;
924 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
926 /* Pull the auth header and the following data into a blob. */
927 /* NB. The offset of the auth_header is relative to the *end*
928 * of the packet, not the start. */
929 if(!prs_set_offset(current_pdu,
930 prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
931 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
933 (unsigned int)(prhdr->frag_len -
934 RPC_HDR_AUTH_LEN - auth_len) ));
935 return NT_STATUS_BUFFER_TOO_SMALL;
938 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
939 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
940 return NT_STATUS_BUFFER_TOO_SMALL;
943 /* Ensure auth_pad_len fits into the packet. */
944 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
945 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
946 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
947 "too large (%u), auth_len (%u), frag_len = (%u).\n",
948 (unsigned int)auth_info.auth_pad_len,
949 (unsigned int)auth_len,
950 (unsigned int)prhdr->frag_len ));
951 return NT_STATUS_BUFFER_TOO_SMALL;
954 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
955 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
956 auth_info.auth_type));
957 return NT_STATUS_BUFFER_TOO_SMALL;
960 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
962 if (DEBUGLEVEL >= 10) {
963 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
966 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
968 switch (cli->auth->auth_level) {
969 case DCERPC_AUTH_LEVEL_PRIVACY:
970 status = netsec_incoming_packet(schannel_auth,
977 case DCERPC_AUTH_LEVEL_INTEGRITY:
978 status = netsec_incoming_packet(schannel_auth,
986 status = NT_STATUS_INTERNAL_ERROR;
990 if (!NT_STATUS_IS_OK(status)) {
991 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
992 "Connection to %s (%s).\n",
993 rpccli_pipe_txt(talloc_tos(), cli),
995 return NT_STATUS_INVALID_PARAMETER;
999 * Return the current pointer to the data offset.
1002 if(!prs_set_offset(current_pdu, save_offset)) {
1003 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1004 (unsigned int)save_offset ));
1005 return NT_STATUS_BUFFER_TOO_SMALL;
1009 * Remember the padding length. We must remove it from the real data
1010 * stream once the sign/seal is done.
1013 *p_ss_padding_len = auth_info.auth_pad_len;
1015 return NT_STATUS_OK;
1018 /****************************************************************************
1019 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1020 ****************************************************************************/
1022 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
1023 prs_struct *current_pdu,
1024 uint8 *p_ss_padding_len)
1026 NTSTATUS ret = NT_STATUS_OK;
1028 /* Paranioa checks for auth_len. */
1029 if (prhdr->auth_len) {
1030 if (prhdr->auth_len > prhdr->frag_len) {
1031 return NT_STATUS_INVALID_PARAMETER;
1034 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
1035 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1036 /* Integer wrap attempt. */
1037 return NT_STATUS_INVALID_PARAMETER;
1042 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1045 switch(cli->auth->auth_type) {
1046 case PIPE_AUTH_TYPE_NONE:
1047 if (prhdr->auth_len) {
1048 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1049 "Connection to %s - got non-zero "
1051 rpccli_pipe_txt(talloc_tos(), cli),
1052 (unsigned int)prhdr->auth_len ));
1053 return NT_STATUS_INVALID_PARAMETER;
1057 case PIPE_AUTH_TYPE_NTLMSSP:
1058 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1059 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1060 if (!NT_STATUS_IS_OK(ret)) {
1065 case PIPE_AUTH_TYPE_SCHANNEL:
1066 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1067 if (!NT_STATUS_IS_OK(ret)) {
1072 case PIPE_AUTH_TYPE_KRB5:
1073 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1075 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1076 "to %s - unknown internal auth type %u.\n",
1077 rpccli_pipe_txt(talloc_tos(), cli),
1078 cli->auth->auth_type ));
1079 return NT_STATUS_INVALID_INFO_CLASS;
1082 return NT_STATUS_OK;
1085 /****************************************************************************
1086 Do basic authentication checks on an incoming pdu.
1087 ****************************************************************************/
1089 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
1090 prs_struct *current_pdu,
1091 uint8 expected_pkt_type,
1094 prs_struct *return_data)
1097 NTSTATUS ret = NT_STATUS_OK;
1098 uint32 current_pdu_len = prs_data_size(current_pdu);
1100 if (current_pdu_len != prhdr->frag_len) {
1101 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1102 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
1103 return NT_STATUS_INVALID_PARAMETER;
1107 * Point the return values at the real data including the RPC
1108 * header. Just in case the caller wants it.
1110 *ppdata = prs_data_p(current_pdu);
1111 *pdata_len = current_pdu_len;
1113 /* Ensure we have the correct type. */
1114 switch (prhdr->pkt_type) {
1115 case DCERPC_PKT_ALTER_RESP:
1116 case DCERPC_PKT_BIND_ACK:
1118 /* Alter context and bind ack share the same packet definitions. */
1122 case DCERPC_PKT_RESPONSE:
1124 RPC_HDR_RESP rhdr_resp;
1125 uint8 ss_padding_len = 0;
1127 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1128 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1129 return NT_STATUS_BUFFER_TOO_SMALL;
1132 /* Here's where we deal with incoming sign/seal. */
1133 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1134 current_pdu, &ss_padding_len);
1135 if (!NT_STATUS_IS_OK(ret)) {
1139 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1140 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1142 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1143 return NT_STATUS_BUFFER_TOO_SMALL;
1146 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1148 /* Remember to remove the auth footer. */
1149 if (prhdr->auth_len) {
1150 /* We've already done integer wrap tests on auth_len in
1151 cli_pipe_validate_rpc_response(). */
1152 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
1153 return NT_STATUS_BUFFER_TOO_SMALL;
1155 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1158 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1159 current_pdu_len, *pdata_len, ss_padding_len ));
1162 * If this is the first reply, and the allocation hint is reasonably, try and
1163 * set up the return_data parse_struct to the correct size.
1166 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1167 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1168 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1169 "too large to allocate\n",
1170 (unsigned int)rhdr_resp.alloc_hint ));
1171 return NT_STATUS_NO_MEMORY;
1178 case DCERPC_PKT_BIND_NAK:
1179 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1180 "received from %s!\n",
1181 rpccli_pipe_txt(talloc_tos(), cli)));
1182 /* Use this for now... */
1183 return NT_STATUS_NETWORK_ACCESS_DENIED;
1185 case DCERPC_PKT_FAULT:
1188 struct ncacn_packet r;
1190 blob = data_blob_const(prs_data_p(current_pdu),
1191 prs_data_size(current_pdu));
1193 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1194 if (!NT_STATUS_IS_OK(ret)) {
1197 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1198 "code %s received from %s!\n",
1199 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1200 rpccli_pipe_txt(talloc_tos(), cli)));
1202 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1203 return NT_STATUS_UNSUCCESSFUL;
1205 return NT_STATUS(r.u.fault.status);
1210 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1212 (unsigned int)prhdr->pkt_type,
1213 rpccli_pipe_txt(talloc_tos(), cli)));
1214 return NT_STATUS_INVALID_INFO_CLASS;
1217 if (prhdr->pkt_type != expected_pkt_type) {
1218 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1219 "got an unexpected RPC packet type - %u, not %u\n",
1220 rpccli_pipe_txt(talloc_tos(), cli),
1222 expected_pkt_type));
1223 return NT_STATUS_INVALID_INFO_CLASS;
1226 /* Do this just before return - we don't want to modify any rpc header
1227 data before now as we may have needed to do cryptographic actions on
1230 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1231 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1232 "setting fragment first/last ON.\n"));
1233 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1236 return NT_STATUS_OK;
1239 /****************************************************************************
1240 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1241 Normally the frag_len and buffer size will match, but on the first trans
1242 reply there is a theoretical chance that buffer size > frag_len, so we must
1244 ****************************************************************************/
1246 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1248 uint32 current_pdu_len = prs_data_size(current_pdu);
1250 if (current_pdu_len < prhdr->frag_len) {
1251 return NT_STATUS_BUFFER_TOO_SMALL;
1255 if (current_pdu_len == (uint32)prhdr->frag_len) {
1256 prs_mem_free(current_pdu);
1257 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1258 /* Make current_pdu dynamic with no memory. */
1259 prs_give_memory(current_pdu, 0, 0, True);
1260 return NT_STATUS_OK;
1264 * Oh no ! More data in buffer than we processed in current pdu.
1265 * Cheat. Move the data down and shrink the buffer.
1268 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1269 current_pdu_len - prhdr->frag_len);
1271 /* Remember to set the read offset back to zero. */
1272 prs_set_offset(current_pdu, 0);
1274 /* Shrink the buffer. */
1275 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1276 return NT_STATUS_BUFFER_TOO_SMALL;
1279 return NT_STATUS_OK;
1282 /****************************************************************************
1283 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1284 ****************************************************************************/
1286 struct cli_api_pipe_state {
1287 struct event_context *ev;
1288 struct rpc_cli_transport *transport;
1293 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1294 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1295 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1297 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1298 struct event_context *ev,
1299 struct rpc_cli_transport *transport,
1300 uint8_t *data, size_t data_len,
1301 uint32_t max_rdata_len)
1303 struct tevent_req *req, *subreq;
1304 struct cli_api_pipe_state *state;
1307 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1312 state->transport = transport;
1314 if (max_rdata_len < RPC_HEADER_LEN) {
1316 * For a RPC reply we always need at least RPC_HEADER_LEN
1317 * bytes. We check this here because we will receive
1318 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1320 status = NT_STATUS_INVALID_PARAMETER;
1324 if (transport->trans_send != NULL) {
1325 subreq = transport->trans_send(state, ev, data, data_len,
1326 max_rdata_len, transport->priv);
1327 if (subreq == NULL) {
1330 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1335 * If the transport does not provide a "trans" routine, i.e. for
1336 * example the ncacn_ip_tcp transport, do the write/read step here.
1339 subreq = rpc_write_send(state, ev, transport, data, data_len);
1340 if (subreq == NULL) {
1343 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1347 tevent_req_nterror(req, status);
1348 return tevent_req_post(req, ev);
1354 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1356 struct tevent_req *req = tevent_req_callback_data(
1357 subreq, struct tevent_req);
1358 struct cli_api_pipe_state *state = tevent_req_data(
1359 req, struct cli_api_pipe_state);
1362 status = state->transport->trans_recv(subreq, state, &state->rdata,
1364 TALLOC_FREE(subreq);
1365 if (!NT_STATUS_IS_OK(status)) {
1366 tevent_req_nterror(req, status);
1369 tevent_req_done(req);
1372 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1374 struct tevent_req *req = tevent_req_callback_data(
1375 subreq, struct tevent_req);
1376 struct cli_api_pipe_state *state = tevent_req_data(
1377 req, struct cli_api_pipe_state);
1380 status = rpc_write_recv(subreq);
1381 TALLOC_FREE(subreq);
1382 if (!NT_STATUS_IS_OK(status)) {
1383 tevent_req_nterror(req, status);
1387 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1388 if (tevent_req_nomem(state->rdata, req)) {
1393 * We don't need to use rpc_read_send here, the upper layer will cope
1394 * with a short read, transport->trans_send could also return less
1395 * than state->max_rdata_len.
1397 subreq = state->transport->read_send(state, state->ev, state->rdata,
1399 state->transport->priv);
1400 if (tevent_req_nomem(subreq, req)) {
1403 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1406 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1408 struct tevent_req *req = tevent_req_callback_data(
1409 subreq, struct tevent_req);
1410 struct cli_api_pipe_state *state = tevent_req_data(
1411 req, struct cli_api_pipe_state);
1415 status = state->transport->read_recv(subreq, &received);
1416 TALLOC_FREE(subreq);
1417 if (!NT_STATUS_IS_OK(status)) {
1418 tevent_req_nterror(req, status);
1421 state->rdata_len = received;
1422 tevent_req_done(req);
1425 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1426 uint8_t **prdata, uint32_t *prdata_len)
1428 struct cli_api_pipe_state *state = tevent_req_data(
1429 req, struct cli_api_pipe_state);
1432 if (tevent_req_is_nterror(req, &status)) {
1436 *prdata = talloc_move(mem_ctx, &state->rdata);
1437 *prdata_len = state->rdata_len;
1438 return NT_STATUS_OK;
1441 /****************************************************************************
1442 Send data on an rpc pipe via trans. The prs_struct data must be the last
1443 pdu fragment of an NDR data stream.
1445 Receive response data from an rpc pipe, which may be large...
1447 Read the first fragment: unfortunately have to use SMBtrans for the first
1448 bit, then SMBreadX for subsequent bits.
1450 If first fragment received also wasn't the last fragment, continue
1451 getting fragments until we _do_ receive the last fragment.
1453 Request/Response PDU's look like the following...
1455 |<------------------PDU len----------------------------------------------->|
1456 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1458 +------------+-----------------+-------------+---------------+-------------+
1459 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1460 +------------+-----------------+-------------+---------------+-------------+
1462 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1463 signing & sealing being negotiated.
1465 ****************************************************************************/
1467 struct rpc_api_pipe_state {
1468 struct event_context *ev;
1469 struct rpc_pipe_client *cli;
1470 uint8_t expected_pkt_type;
1472 prs_struct incoming_frag;
1473 struct rpc_hdr_info rhdr;
1475 prs_struct incoming_pdu; /* Incoming reply */
1476 uint32_t incoming_pdu_offset;
1479 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1480 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1482 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1483 struct event_context *ev,
1484 struct rpc_pipe_client *cli,
1485 prs_struct *data, /* Outgoing PDU */
1486 uint8_t expected_pkt_type)
1488 struct tevent_req *req, *subreq;
1489 struct rpc_api_pipe_state *state;
1490 uint16_t max_recv_frag;
1493 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1499 state->expected_pkt_type = expected_pkt_type;
1500 state->incoming_pdu_offset = 0;
1502 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1504 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1505 /* Make incoming_pdu dynamic with no memory. */
1506 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1509 * Ensure we're not sending too much.
1511 if (prs_offset(data) > cli->max_xmit_frag) {
1512 status = NT_STATUS_INVALID_PARAMETER;
1516 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1518 max_recv_frag = cli->max_recv_frag;
1521 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1524 subreq = cli_api_pipe_send(state, ev, cli->transport,
1525 (uint8_t *)prs_data_p(data),
1526 prs_offset(data), max_recv_frag);
1527 if (subreq == NULL) {
1530 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1534 tevent_req_nterror(req, status);
1535 return tevent_req_post(req, ev);
1541 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1543 struct tevent_req *req = tevent_req_callback_data(
1544 subreq, struct tevent_req);
1545 struct rpc_api_pipe_state *state = tevent_req_data(
1546 req, struct rpc_api_pipe_state);
1548 uint8_t *rdata = NULL;
1549 uint32_t rdata_len = 0;
1551 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1552 TALLOC_FREE(subreq);
1553 if (!NT_STATUS_IS_OK(status)) {
1554 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1555 tevent_req_nterror(req, status);
1559 if (rdata == NULL) {
1560 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1561 rpccli_pipe_txt(talloc_tos(), state->cli)));
1562 tevent_req_done(req);
1567 * This is equivalent to a talloc_steal - gives rdata to
1568 * the prs_struct state->incoming_frag.
1570 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1573 /* Ensure we have enough data for a pdu. */
1574 subreq = get_complete_frag_send(state, state->ev, state->cli,
1575 &state->rhdr, &state->incoming_frag);
1576 if (tevent_req_nomem(subreq, req)) {
1579 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1582 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1584 struct tevent_req *req = tevent_req_callback_data(
1585 subreq, struct tevent_req);
1586 struct rpc_api_pipe_state *state = tevent_req_data(
1587 req, struct rpc_api_pipe_state);
1590 uint32_t rdata_len = 0;
1592 status = get_complete_frag_recv(subreq);
1593 TALLOC_FREE(subreq);
1594 if (!NT_STATUS_IS_OK(status)) {
1595 DEBUG(5, ("get_complete_frag failed: %s\n",
1596 nt_errstr(status)));
1597 tevent_req_nterror(req, status);
1601 status = cli_pipe_validate_current_pdu(
1602 state->cli, &state->rhdr, &state->incoming_frag,
1603 state->expected_pkt_type, &rdata, &rdata_len,
1604 &state->incoming_pdu);
1606 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1607 (unsigned)prs_data_size(&state->incoming_frag),
1608 (unsigned)state->incoming_pdu_offset,
1609 nt_errstr(status)));
1611 if (!NT_STATUS_IS_OK(status)) {
1612 tevent_req_nterror(req, status);
1616 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1617 && (state->rhdr.pack_type[0] == 0)) {
1619 * Set the data type correctly for big-endian data on the
1622 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1624 rpccli_pipe_txt(talloc_tos(), state->cli)));
1625 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1628 * Check endianness on subsequent packets.
1630 if (state->incoming_frag.bigendian_data
1631 != state->incoming_pdu.bigendian_data) {
1632 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1634 state->incoming_pdu.bigendian_data?"big":"little",
1635 state->incoming_frag.bigendian_data?"big":"little"));
1636 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1640 /* Now copy the data portion out of the pdu into rbuf. */
1641 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1642 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1646 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1647 rdata, (size_t)rdata_len);
1648 state->incoming_pdu_offset += rdata_len;
1650 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1651 &state->incoming_frag);
1652 if (!NT_STATUS_IS_OK(status)) {
1653 tevent_req_nterror(req, status);
1657 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1658 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1659 rpccli_pipe_txt(talloc_tos(), state->cli),
1660 (unsigned)prs_data_size(&state->incoming_pdu)));
1661 tevent_req_done(req);
1665 subreq = get_complete_frag_send(state, state->ev, state->cli,
1666 &state->rhdr, &state->incoming_frag);
1667 if (tevent_req_nomem(subreq, req)) {
1670 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1673 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1674 prs_struct *reply_pdu)
1676 struct rpc_api_pipe_state *state = tevent_req_data(
1677 req, struct rpc_api_pipe_state);
1680 if (tevent_req_is_nterror(req, &status)) {
1684 *reply_pdu = state->incoming_pdu;
1685 reply_pdu->mem_ctx = mem_ctx;
1688 * Prevent state->incoming_pdu from being freed
1689 * when state is freed.
1691 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1692 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1694 return NT_STATUS_OK;
1697 /*******************************************************************
1698 ********************************************************************/
1700 static NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1701 enum dcerpc_AuthType auth_type,
1702 enum dcerpc_AuthLevel auth_level,
1703 uint8_t auth_pad_length,
1704 uint32_t auth_context_id,
1705 const DATA_BLOB *credentials,
1708 struct dcerpc_auth r;
1709 enum ndr_err_code ndr_err;
1711 r.auth_type = auth_type;
1712 r.auth_level = auth_level;
1713 r.auth_pad_length = auth_pad_length;
1714 r.auth_reserved = 0;
1715 r.auth_context_id = auth_context_id;
1716 r.credentials = *credentials;
1718 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1719 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1720 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1721 return ndr_map_error2ntstatus(ndr_err);
1724 if (DEBUGLEVEL >= 10) {
1725 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1728 return NT_STATUS_OK;
1731 /*******************************************************************
1732 Creates krb5 auth bind.
1733 ********************************************************************/
1735 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1736 enum dcerpc_AuthLevel auth_level,
1737 DATA_BLOB *auth_info)
1742 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1743 DATA_BLOB tkt = data_blob_null;
1744 DATA_BLOB tkt_wrapped = data_blob_null;
1746 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1747 a->service_principal ));
1749 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1751 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1752 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1755 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1757 a->service_principal,
1758 error_message(ret) ));
1760 data_blob_free(&tkt);
1761 return NT_STATUS_INVALID_PARAMETER;
1764 /* wrap that up in a nice GSS-API wrapping */
1765 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1767 data_blob_free(&tkt);
1769 status = dcerpc_push_dcerpc_auth(cli,
1770 DCERPC_AUTH_TYPE_KRB5,
1772 0, /* auth_pad_length */
1773 1, /* auth_context_id */
1776 if (!NT_STATUS_IS_OK(status)) {
1777 data_blob_free(&tkt_wrapped);
1781 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1782 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1784 return NT_STATUS_OK;
1786 return NT_STATUS_INVALID_PARAMETER;
1790 /*******************************************************************
1791 Creates SPNEGO NTLMSSP auth bind.
1792 ********************************************************************/
1794 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1795 enum dcerpc_AuthLevel auth_level,
1796 DATA_BLOB *auth_info)
1799 DATA_BLOB null_blob = data_blob_null;
1800 DATA_BLOB request = data_blob_null;
1801 DATA_BLOB spnego_msg = data_blob_null;
1803 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1804 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1808 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1809 data_blob_free(&request);
1813 /* Wrap this in SPNEGO. */
1814 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1816 data_blob_free(&request);
1818 status = dcerpc_push_dcerpc_auth(cli,
1819 DCERPC_AUTH_TYPE_SPNEGO,
1821 0, /* auth_pad_length */
1822 1, /* auth_context_id */
1825 if (!NT_STATUS_IS_OK(status)) {
1826 data_blob_free(&spnego_msg);
1830 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1831 dump_data(5, spnego_msg.data, spnego_msg.length);
1833 return NT_STATUS_OK;
1836 /*******************************************************************
1837 Creates NTLMSSP auth bind.
1838 ********************************************************************/
1840 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1841 enum dcerpc_AuthLevel auth_level,
1842 DATA_BLOB *auth_info)
1845 DATA_BLOB null_blob = data_blob_null;
1846 DATA_BLOB request = data_blob_null;
1848 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1849 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1853 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1854 data_blob_free(&request);
1858 status = dcerpc_push_dcerpc_auth(cli,
1859 DCERPC_AUTH_TYPE_NTLMSSP,
1861 0, /* auth_pad_length */
1862 1, /* auth_context_id */
1865 if (!NT_STATUS_IS_OK(status)) {
1866 data_blob_free(&request);
1870 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1871 dump_data(5, request.data, request.length);
1873 return NT_STATUS_OK;
1876 /*******************************************************************
1877 Creates schannel auth bind.
1878 ********************************************************************/
1880 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1881 enum dcerpc_AuthLevel auth_level,
1882 DATA_BLOB *auth_info)
1885 struct NL_AUTH_MESSAGE r;
1886 DATA_BLOB schannel_blob;
1888 /* Use lp_workgroup() if domain not specified */
1890 if (!cli->auth->domain || !cli->auth->domain[0]) {
1891 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1892 if (cli->auth->domain == NULL) {
1893 return NT_STATUS_NO_MEMORY;
1898 * Now marshall the data into the auth parse_struct.
1901 r.MessageType = NL_NEGOTIATE_REQUEST;
1902 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1903 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1904 r.oem_netbios_domain.a = cli->auth->domain;
1905 r.oem_netbios_computer.a = global_myname();
1907 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1908 if (!NT_STATUS_IS_OK(status)) {
1912 status = dcerpc_push_dcerpc_auth(cli,
1913 DCERPC_AUTH_TYPE_SCHANNEL,
1915 0, /* auth_pad_length */
1916 1, /* auth_context_id */
1919 if (!NT_STATUS_IS_OK(status)) {
1923 return NT_STATUS_OK;
1926 /*******************************************************************
1927 ********************************************************************/
1929 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1930 const struct ndr_syntax_id *abstract_syntax,
1931 const struct ndr_syntax_id *transfer_syntax,
1932 struct dcerpc_ctx_list **ctx_list_p)
1934 struct dcerpc_ctx_list *ctx_list;
1936 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1937 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1939 ctx_list[0].context_id = 0;
1940 ctx_list[0].num_transfer_syntaxes = 1;
1941 ctx_list[0].abstract_syntax = *abstract_syntax;
1942 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
1943 struct ndr_syntax_id,
1944 ctx_list[0].num_transfer_syntaxes);
1945 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1946 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
1948 *ctx_list_p = ctx_list;
1950 return NT_STATUS_OK;
1953 /*******************************************************************
1954 Creates the internals of a DCE/RPC bind request or alter context PDU.
1955 ********************************************************************/
1957 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
1958 prs_struct *rpc_out,
1960 const struct ndr_syntax_id *abstract,
1961 const struct ndr_syntax_id *transfer,
1962 const DATA_BLOB *auth_info)
1964 uint16 auth_len = auth_info->length;
1965 uint16 frag_len = 0;
1967 union dcerpc_payload u;
1969 struct dcerpc_ctx_list *ctx_list;
1971 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
1973 if (!NT_STATUS_IS_OK(status)) {
1977 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1978 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1979 u.bind.assoc_group_id = 0x0;
1980 u.bind.num_contexts = 1;
1981 u.bind.ctx_list = ctx_list;
1982 u.bind.auth_info = *auth_info;
1984 /* Start building the frag length. */
1985 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind) + auth_len;
1987 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
1989 DCERPC_PFC_FLAG_FIRST |
1990 DCERPC_PFC_FLAG_LAST,
1992 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
1996 if (!NT_STATUS_IS_OK(status)) {
1997 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2001 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2002 return NT_STATUS_NO_MEMORY;
2005 return NT_STATUS_OK;
2008 /*******************************************************************
2009 Creates a DCE/RPC bind request.
2010 ********************************************************************/
2012 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2013 prs_struct *rpc_out,
2015 const struct ndr_syntax_id *abstract,
2016 const struct ndr_syntax_id *transfer,
2017 enum pipe_auth_type auth_type,
2018 enum dcerpc_AuthLevel auth_level)
2020 DATA_BLOB auth_info = data_blob_null;
2021 NTSTATUS ret = NT_STATUS_OK;
2023 switch (auth_type) {
2024 case PIPE_AUTH_TYPE_SCHANNEL:
2025 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2026 if (!NT_STATUS_IS_OK(ret)) {
2031 case PIPE_AUTH_TYPE_NTLMSSP:
2032 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2033 if (!NT_STATUS_IS_OK(ret)) {
2038 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2039 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2040 if (!NT_STATUS_IS_OK(ret)) {
2045 case PIPE_AUTH_TYPE_KRB5:
2046 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2047 if (!NT_STATUS_IS_OK(ret)) {
2052 case PIPE_AUTH_TYPE_NONE:
2056 /* "Can't" happen. */
2057 return NT_STATUS_INVALID_INFO_CLASS;
2060 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2069 /*******************************************************************
2070 Create and add the NTLMSSP sign/seal auth header and data.
2071 ********************************************************************/
2073 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2075 uint32 ss_padding_len,
2076 prs_struct *outgoing_pdu)
2078 RPC_HDR_AUTH auth_info;
2080 DATA_BLOB auth_blob = data_blob_null;
2081 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2084 if (!cli->auth->a_u.ntlmssp_state) {
2085 return NT_STATUS_INVALID_PARAMETER;
2088 frame = talloc_stackframe();
2090 /* Init and marshall the auth header. */
2091 init_rpc_hdr_auth(&auth_info,
2092 map_pipe_auth_type_to_rpc_auth_type(
2093 cli->auth->auth_type),
2094 cli->auth->auth_level,
2096 1 /* context id. */);
2098 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2099 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2101 return NT_STATUS_NO_MEMORY;
2104 switch (cli->auth->auth_level) {
2105 case DCERPC_AUTH_LEVEL_PRIVACY:
2106 /* Data portion is encrypted. */
2107 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2109 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2111 (unsigned char *)prs_data_p(outgoing_pdu),
2112 (size_t)prs_offset(outgoing_pdu),
2114 if (!NT_STATUS_IS_OK(status)) {
2120 case DCERPC_AUTH_LEVEL_INTEGRITY:
2121 /* Data is signed. */
2122 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2124 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2126 (unsigned char *)prs_data_p(outgoing_pdu),
2127 (size_t)prs_offset(outgoing_pdu),
2129 if (!NT_STATUS_IS_OK(status)) {
2137 smb_panic("bad auth level");
2139 return NT_STATUS_INVALID_PARAMETER;
2142 /* Finally marshall the blob. */
2144 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2145 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2146 (unsigned int)NTLMSSP_SIG_SIZE));
2148 return NT_STATUS_NO_MEMORY;
2152 return NT_STATUS_OK;
2155 /*******************************************************************
2156 Create and add the schannel sign/seal auth header and data.
2157 ********************************************************************/
2159 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2161 uint32 ss_padding_len,
2162 prs_struct *outgoing_pdu)
2164 RPC_HDR_AUTH auth_info;
2165 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2166 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2167 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2172 return NT_STATUS_INVALID_PARAMETER;
2175 /* Init and marshall the auth header. */
2176 init_rpc_hdr_auth(&auth_info,
2177 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2178 cli->auth->auth_level,
2180 1 /* context id. */);
2182 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2183 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2184 return NT_STATUS_NO_MEMORY;
2187 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2190 switch (cli->auth->auth_level) {
2191 case DCERPC_AUTH_LEVEL_PRIVACY:
2192 status = netsec_outgoing_packet(sas,
2199 case DCERPC_AUTH_LEVEL_INTEGRITY:
2200 status = netsec_outgoing_packet(sas,
2208 status = NT_STATUS_INTERNAL_ERROR;
2212 if (!NT_STATUS_IS_OK(status)) {
2213 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2214 nt_errstr(status)));
2218 if (DEBUGLEVEL >= 10) {
2219 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2222 /* Finally marshall the blob. */
2223 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2224 return NT_STATUS_NO_MEMORY;
2227 return NT_STATUS_OK;
2230 /*******************************************************************
2231 Calculate how much data we're going to send in this packet, also
2232 work out any sign/seal padding length.
2233 ********************************************************************/
2235 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2239 uint32 *p_ss_padding)
2241 uint32 data_space, data_len;
2244 if ((data_left > 0) && (sys_random() % 2)) {
2245 data_left = MAX(data_left/2, 1);
2249 switch (cli->auth->auth_level) {
2250 case DCERPC_AUTH_LEVEL_NONE:
2251 case DCERPC_AUTH_LEVEL_CONNECT:
2252 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2253 data_len = MIN(data_space, data_left);
2256 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2259 case DCERPC_AUTH_LEVEL_INTEGRITY:
2260 case DCERPC_AUTH_LEVEL_PRIVACY:
2261 /* Treat the same for all authenticated rpc requests. */
2262 switch(cli->auth->auth_type) {
2263 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2264 case PIPE_AUTH_TYPE_NTLMSSP:
2265 *p_auth_len = NTLMSSP_SIG_SIZE;
2267 case PIPE_AUTH_TYPE_SCHANNEL:
2268 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2271 smb_panic("bad auth type");
2275 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2276 RPC_HDR_AUTH_LEN - *p_auth_len;
2278 data_len = MIN(data_space, data_left);
2280 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2281 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2283 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2284 data_len + *p_ss_padding + /* data plus padding. */
2285 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2289 smb_panic("bad auth level");
2295 /*******************************************************************
2297 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2298 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2299 and deals with signing/sealing details.
2300 ********************************************************************/
2302 struct rpc_api_pipe_req_state {
2303 struct event_context *ev;
2304 struct rpc_pipe_client *cli;
2307 prs_struct *req_data;
2308 uint32_t req_data_sent;
2309 prs_struct outgoing_frag;
2310 prs_struct reply_pdu;
2313 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2314 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2315 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2316 bool *is_last_frag);
2318 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2319 struct event_context *ev,
2320 struct rpc_pipe_client *cli,
2322 prs_struct *req_data)
2324 struct tevent_req *req, *subreq;
2325 struct rpc_api_pipe_req_state *state;
2329 req = tevent_req_create(mem_ctx, &state,
2330 struct rpc_api_pipe_req_state);
2336 state->op_num = op_num;
2337 state->req_data = req_data;
2338 state->req_data_sent = 0;
2339 state->call_id = get_rpc_call_id();
2341 if (cli->max_xmit_frag
2342 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2343 /* Server is screwed up ! */
2344 status = NT_STATUS_INVALID_PARAMETER;
2348 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2350 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2355 status = prepare_next_frag(state, &is_last_frag);
2356 if (!NT_STATUS_IS_OK(status)) {
2361 subreq = rpc_api_pipe_send(state, ev, state->cli,
2362 &state->outgoing_frag,
2363 DCERPC_PKT_RESPONSE);
2364 if (subreq == NULL) {
2367 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2369 subreq = rpc_write_send(
2370 state, ev, cli->transport,
2371 (uint8_t *)prs_data_p(&state->outgoing_frag),
2372 prs_offset(&state->outgoing_frag));
2373 if (subreq == NULL) {
2376 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2382 tevent_req_nterror(req, status);
2383 return tevent_req_post(req, ev);
2389 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2393 RPC_HDR_REQ hdr_req;
2394 uint32_t data_sent_thistime;
2398 uint32_t ss_padding;
2400 char pad[8] = { 0, };
2403 data_left = prs_offset(state->req_data) - state->req_data_sent;
2405 data_sent_thistime = calculate_data_len_tosend(
2406 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2408 if (state->req_data_sent == 0) {
2409 flags = DCERPC_PFC_FLAG_FIRST;
2412 if (data_sent_thistime == data_left) {
2413 flags |= DCERPC_PFC_FLAG_LAST;
2416 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2417 return NT_STATUS_NO_MEMORY;
2420 /* Create and marshall the header and request header. */
2421 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2424 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2425 return NT_STATUS_NO_MEMORY;
2428 /* Create the rpc request RPC_HDR_REQ */
2429 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2432 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2433 &state->outgoing_frag, 0)) {
2434 return NT_STATUS_NO_MEMORY;
2437 /* Copy in the data, plus any ss padding. */
2438 if (!prs_append_some_prs_data(&state->outgoing_frag,
2439 state->req_data, state->req_data_sent,
2440 data_sent_thistime)) {
2441 return NT_STATUS_NO_MEMORY;
2444 /* Copy the sign/seal padding data. */
2445 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2446 return NT_STATUS_NO_MEMORY;
2449 /* Generate any auth sign/seal and add the auth footer. */
2450 switch (state->cli->auth->auth_type) {
2451 case PIPE_AUTH_TYPE_NONE:
2452 status = NT_STATUS_OK;
2454 case PIPE_AUTH_TYPE_NTLMSSP:
2455 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2456 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2457 &state->outgoing_frag);
2459 case PIPE_AUTH_TYPE_SCHANNEL:
2460 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2461 &state->outgoing_frag);
2464 status = NT_STATUS_INVALID_PARAMETER;
2468 state->req_data_sent += data_sent_thistime;
2469 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2474 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2476 struct tevent_req *req = tevent_req_callback_data(
2477 subreq, struct tevent_req);
2478 struct rpc_api_pipe_req_state *state = tevent_req_data(
2479 req, struct rpc_api_pipe_req_state);
2483 status = rpc_write_recv(subreq);
2484 TALLOC_FREE(subreq);
2485 if (!NT_STATUS_IS_OK(status)) {
2486 tevent_req_nterror(req, status);
2490 status = prepare_next_frag(state, &is_last_frag);
2491 if (!NT_STATUS_IS_OK(status)) {
2492 tevent_req_nterror(req, status);
2497 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2498 &state->outgoing_frag,
2499 DCERPC_PKT_RESPONSE);
2500 if (tevent_req_nomem(subreq, req)) {
2503 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2505 subreq = rpc_write_send(
2507 state->cli->transport,
2508 (uint8_t *)prs_data_p(&state->outgoing_frag),
2509 prs_offset(&state->outgoing_frag));
2510 if (tevent_req_nomem(subreq, req)) {
2513 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2518 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2520 struct tevent_req *req = tevent_req_callback_data(
2521 subreq, struct tevent_req);
2522 struct rpc_api_pipe_req_state *state = tevent_req_data(
2523 req, struct rpc_api_pipe_req_state);
2526 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2527 TALLOC_FREE(subreq);
2528 if (!NT_STATUS_IS_OK(status)) {
2529 tevent_req_nterror(req, status);
2532 tevent_req_done(req);
2535 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2536 prs_struct *reply_pdu)
2538 struct rpc_api_pipe_req_state *state = tevent_req_data(
2539 req, struct rpc_api_pipe_req_state);
2542 if (tevent_req_is_nterror(req, &status)) {
2544 * We always have to initialize to reply pdu, even if there is
2545 * none. The rpccli_* caller routines expect this.
2547 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2551 *reply_pdu = state->reply_pdu;
2552 reply_pdu->mem_ctx = mem_ctx;
2555 * Prevent state->req_pdu from being freed
2556 * when state is freed.
2558 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2559 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2561 return NT_STATUS_OK;
2565 /****************************************************************************
2566 Set the handle state.
2567 ****************************************************************************/
2569 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2570 const char *pipe_name, uint16 device_state)
2572 bool state_set = False;
2574 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2575 char *rparam = NULL;
2577 uint32 rparam_len, rdata_len;
2579 if (pipe_name == NULL)
2582 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2583 cli->fnum, pipe_name, device_state));
2585 /* create parameters: device state */
2586 SSVAL(param, 0, device_state);
2588 /* create setup parameters. */
2590 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2592 /* send the data on \PIPE\ */
2593 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2594 setup, 2, 0, /* setup, length, max */
2595 param, 2, 0, /* param, length, max */
2596 NULL, 0, 1024, /* data, length, max */
2597 &rparam, &rparam_len, /* return param, length */
2598 &rdata, &rdata_len)) /* return data, length */
2600 DEBUG(5, ("Set Handle state: return OK\n"));
2611 /****************************************************************************
2612 Check the rpc bind acknowledge response.
2613 ****************************************************************************/
2615 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2616 const struct ndr_syntax_id *transfer)
2618 if ( hdr_ba->addr.len == 0) {
2619 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2622 /* check the transfer syntax */
2623 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2624 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2625 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2629 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2630 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2631 hdr_ba->res.num_results, hdr_ba->res.reason));
2634 DEBUG(5,("check_bind_response: accepted!\n"));
2638 /*******************************************************************
2639 Creates a DCE/RPC bind authentication response.
2640 This is the packet that is sent back to the server once we
2641 have received a BIND-ACK, to finish the third leg of
2642 the authentication handshake.
2643 ********************************************************************/
2645 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2647 enum pipe_auth_type auth_type,
2648 enum dcerpc_AuthLevel auth_level,
2649 DATA_BLOB *pauth_blob,
2650 prs_struct *rpc_out)
2653 RPC_HDR_AUTH hdr_auth;
2656 /* Create the request RPC_HDR */
2657 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2658 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2659 pauth_blob->length );
2662 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2663 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2664 return NT_STATUS_NO_MEMORY;
2668 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2669 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2672 /* 4 bytes padding. */
2673 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2674 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2675 return NT_STATUS_NO_MEMORY;
2678 /* Create the request RPC_HDR_AUTHA */
2679 init_rpc_hdr_auth(&hdr_auth,
2680 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2683 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2684 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2685 return NT_STATUS_NO_MEMORY;
2689 * Append the auth data to the outgoing buffer.
2692 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2693 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2694 return NT_STATUS_NO_MEMORY;
2697 return NT_STATUS_OK;
2700 /*******************************************************************
2701 Creates a DCE/RPC bind alter context authentication request which
2702 may contain a spnego auth blobl
2703 ********************************************************************/
2705 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2706 const struct ndr_syntax_id *abstract,
2707 const struct ndr_syntax_id *transfer,
2708 enum dcerpc_AuthLevel auth_level,
2709 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2710 prs_struct *rpc_out)
2712 DATA_BLOB auth_info;
2715 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2716 DCERPC_AUTH_TYPE_SPNEGO,
2718 0, /* auth_pad_length */
2719 1, /* auth_context_id */
2722 if (!NT_STATUS_IS_OK(status)) {
2727 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2733 if (!NT_STATUS_IS_OK(status)) {
2740 /****************************************************************************
2742 ****************************************************************************/
2744 struct rpc_pipe_bind_state {
2745 struct event_context *ev;
2746 struct rpc_pipe_client *cli;
2748 uint32_t rpc_call_id;
2751 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2752 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2753 struct rpc_pipe_bind_state *state,
2754 struct rpc_hdr_info *phdr,
2755 prs_struct *reply_pdu);
2756 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2757 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2758 struct rpc_pipe_bind_state *state,
2759 struct rpc_hdr_info *phdr,
2760 prs_struct *reply_pdu);
2761 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2763 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2764 struct event_context *ev,
2765 struct rpc_pipe_client *cli,
2766 struct cli_pipe_auth_data *auth)
2768 struct tevent_req *req, *subreq;
2769 struct rpc_pipe_bind_state *state;
2772 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2777 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2778 rpccli_pipe_txt(talloc_tos(), cli),
2779 (unsigned int)auth->auth_type,
2780 (unsigned int)auth->auth_level ));
2784 state->rpc_call_id = get_rpc_call_id();
2786 prs_init_empty(&state->rpc_out, state, MARSHALL);
2788 cli->auth = talloc_move(cli, &auth);
2790 /* Marshall the outgoing data. */
2791 status = create_rpc_bind_req(cli, &state->rpc_out,
2793 &cli->abstract_syntax,
2794 &cli->transfer_syntax,
2795 cli->auth->auth_type,
2796 cli->auth->auth_level);
2798 if (!NT_STATUS_IS_OK(status)) {
2802 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2803 DCERPC_PKT_BIND_ACK);
2804 if (subreq == NULL) {
2807 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2811 tevent_req_nterror(req, status);
2812 return tevent_req_post(req, ev);
2818 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2820 struct tevent_req *req = tevent_req_callback_data(
2821 subreq, struct tevent_req);
2822 struct rpc_pipe_bind_state *state = tevent_req_data(
2823 req, struct rpc_pipe_bind_state);
2824 prs_struct reply_pdu;
2825 struct rpc_hdr_info hdr;
2826 struct rpc_hdr_ba_info hdr_ba;
2829 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2830 TALLOC_FREE(subreq);
2831 if (!NT_STATUS_IS_OK(status)) {
2832 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2833 rpccli_pipe_txt(talloc_tos(), state->cli),
2834 nt_errstr(status)));
2835 tevent_req_nterror(req, status);
2839 /* Unmarshall the RPC header */
2840 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2841 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2842 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2846 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2847 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2849 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2853 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2854 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2855 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2859 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2860 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2863 * For authenticated binds we may need to do 3 or 4 leg binds.
2866 switch(state->cli->auth->auth_type) {
2868 case PIPE_AUTH_TYPE_NONE:
2869 case PIPE_AUTH_TYPE_SCHANNEL:
2870 /* Bind complete. */
2871 tevent_req_done(req);
2874 case PIPE_AUTH_TYPE_NTLMSSP:
2875 /* Need to send AUTH3 packet - no reply. */
2876 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2878 if (!NT_STATUS_IS_OK(status)) {
2879 tevent_req_nterror(req, status);
2883 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2884 /* Need to send alter context request and reply. */
2885 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2887 if (!NT_STATUS_IS_OK(status)) {
2888 tevent_req_nterror(req, status);
2892 case PIPE_AUTH_TYPE_KRB5:
2896 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2897 (unsigned int)state->cli->auth->auth_type));
2898 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2902 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2903 struct rpc_pipe_bind_state *state,
2904 struct rpc_hdr_info *phdr,
2905 prs_struct *reply_pdu)
2907 DATA_BLOB server_response = data_blob_null;
2908 DATA_BLOB client_reply = data_blob_null;
2909 struct rpc_hdr_auth_info hdr_auth;
2910 struct tevent_req *subreq;
2913 if ((phdr->auth_len == 0)
2914 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2915 return NT_STATUS_INVALID_PARAMETER;
2918 if (!prs_set_offset(
2920 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2921 return NT_STATUS_INVALID_PARAMETER;
2924 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2925 return NT_STATUS_INVALID_PARAMETER;
2928 /* TODO - check auth_type/auth_level match. */
2930 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2931 prs_copy_data_out((char *)server_response.data, reply_pdu,
2934 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2935 server_response, &client_reply);
2937 if (!NT_STATUS_IS_OK(status)) {
2938 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2939 "blob failed: %s.\n", nt_errstr(status)));
2943 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2945 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2946 state->cli->auth->auth_type,
2947 state->cli->auth->auth_level,
2948 &client_reply, &state->rpc_out);
2949 data_blob_free(&client_reply);
2951 if (!NT_STATUS_IS_OK(status)) {
2955 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2956 (uint8_t *)prs_data_p(&state->rpc_out),
2957 prs_offset(&state->rpc_out));
2958 if (subreq == NULL) {
2959 return NT_STATUS_NO_MEMORY;
2961 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2962 return NT_STATUS_OK;
2965 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2967 struct tevent_req *req = tevent_req_callback_data(
2968 subreq, struct tevent_req);
2971 status = rpc_write_recv(subreq);
2972 TALLOC_FREE(subreq);
2973 if (!NT_STATUS_IS_OK(status)) {
2974 tevent_req_nterror(req, status);
2977 tevent_req_done(req);
2980 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2981 struct rpc_pipe_bind_state *state,
2982 struct rpc_hdr_info *phdr,
2983 prs_struct *reply_pdu)
2985 DATA_BLOB server_spnego_response = data_blob_null;
2986 DATA_BLOB server_ntlm_response = data_blob_null;
2987 DATA_BLOB client_reply = data_blob_null;
2988 DATA_BLOB tmp_blob = data_blob_null;
2989 RPC_HDR_AUTH hdr_auth;
2990 struct tevent_req *subreq;
2993 if ((phdr->auth_len == 0)
2994 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2995 return NT_STATUS_INVALID_PARAMETER;
2998 /* Process the returned NTLMSSP blob first. */
2999 if (!prs_set_offset(
3001 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
3002 return NT_STATUS_INVALID_PARAMETER;
3005 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3006 return NT_STATUS_INVALID_PARAMETER;
3009 server_spnego_response = data_blob(NULL, phdr->auth_len);
3010 prs_copy_data_out((char *)server_spnego_response.data,
3011 reply_pdu, phdr->auth_len);
3014 * The server might give us back two challenges - tmp_blob is for the
3017 if (!spnego_parse_challenge(server_spnego_response,
3018 &server_ntlm_response, &tmp_blob)) {
3019 data_blob_free(&server_spnego_response);
3020 data_blob_free(&server_ntlm_response);
3021 data_blob_free(&tmp_blob);
3022 return NT_STATUS_INVALID_PARAMETER;
3025 /* We're finished with the server spnego response and the tmp_blob. */
3026 data_blob_free(&server_spnego_response);
3027 data_blob_free(&tmp_blob);
3029 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3030 server_ntlm_response, &client_reply);
3032 /* Finished with the server_ntlm response */
3033 data_blob_free(&server_ntlm_response);
3035 if (!NT_STATUS_IS_OK(status)) {
3036 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3037 "using server blob failed.\n"));
3038 data_blob_free(&client_reply);
3042 /* SPNEGO wrap the client reply. */
3043 tmp_blob = spnego_gen_auth(client_reply);
3044 data_blob_free(&client_reply);
3045 client_reply = tmp_blob;
3046 tmp_blob = data_blob_null;
3048 /* Now prepare the alter context pdu. */
3049 prs_init_empty(&state->rpc_out, state, MARSHALL);
3051 status = create_rpc_alter_context(state->rpc_call_id,
3052 &state->cli->abstract_syntax,
3053 &state->cli->transfer_syntax,
3054 state->cli->auth->auth_level,
3057 data_blob_free(&client_reply);
3059 if (!NT_STATUS_IS_OK(status)) {
3063 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3064 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3065 if (subreq == NULL) {
3066 return NT_STATUS_NO_MEMORY;
3068 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3069 return NT_STATUS_OK;
3072 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3074 struct tevent_req *req = tevent_req_callback_data(
3075 subreq, struct tevent_req);
3076 struct rpc_pipe_bind_state *state = tevent_req_data(
3077 req, struct rpc_pipe_bind_state);
3078 DATA_BLOB server_spnego_response = data_blob_null;
3079 DATA_BLOB tmp_blob = data_blob_null;
3080 prs_struct reply_pdu;
3081 struct rpc_hdr_info hdr;
3082 struct rpc_hdr_auth_info hdr_auth;
3085 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3086 TALLOC_FREE(subreq);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 tevent_req_nterror(req, status);
3092 /* Get the auth blob from the reply. */
3093 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3094 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3095 "unmarshall RPC_HDR.\n"));
3096 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3100 if (!prs_set_offset(
3102 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3103 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3107 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3108 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3112 server_spnego_response = data_blob(NULL, hdr.auth_len);
3113 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3116 /* Check we got a valid auth response. */
3117 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3118 OID_NTLMSSP, &tmp_blob)) {
3119 data_blob_free(&server_spnego_response);
3120 data_blob_free(&tmp_blob);
3121 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3125 data_blob_free(&server_spnego_response);
3126 data_blob_free(&tmp_blob);
3128 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3129 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3130 tevent_req_done(req);
3133 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3135 return tevent_req_simple_recv_ntstatus(req);
3138 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3139 struct cli_pipe_auth_data *auth)
3141 TALLOC_CTX *frame = talloc_stackframe();
3142 struct event_context *ev;
3143 struct tevent_req *req;
3144 NTSTATUS status = NT_STATUS_OK;
3146 ev = event_context_init(frame);
3148 status = NT_STATUS_NO_MEMORY;
3152 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3154 status = NT_STATUS_NO_MEMORY;
3158 if (!tevent_req_poll(req, ev)) {
3159 status = map_nt_error_from_unix(errno);
3163 status = rpc_pipe_bind_recv(req);
3169 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3171 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3172 unsigned int timeout)
3176 if (rpc_cli->transport == NULL) {
3177 return RPCCLI_DEFAULT_TIMEOUT;
3180 if (rpc_cli->transport->set_timeout == NULL) {
3181 return RPCCLI_DEFAULT_TIMEOUT;
3184 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3186 return RPCCLI_DEFAULT_TIMEOUT;
3192 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3194 if (rpc_cli == NULL) {
3198 if (rpc_cli->transport == NULL) {
3202 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3205 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3207 struct cli_state *cli;
3209 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3210 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3211 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3215 cli = rpc_pipe_np_smb_conn(rpc_cli);
3219 E_md4hash(cli->password ? cli->password : "", nt_hash);
3223 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3224 struct cli_pipe_auth_data **presult)
3226 struct cli_pipe_auth_data *result;
3228 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3229 if (result == NULL) {
3230 return NT_STATUS_NO_MEMORY;
3233 result->auth_type = PIPE_AUTH_TYPE_NONE;
3234 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3236 result->user_name = talloc_strdup(result, "");
3237 result->domain = talloc_strdup(result, "");
3238 if ((result->user_name == NULL) || (result->domain == NULL)) {
3239 TALLOC_FREE(result);
3240 return NT_STATUS_NO_MEMORY;
3244 return NT_STATUS_OK;
3247 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3249 ntlmssp_end(&auth->a_u.ntlmssp_state);
3253 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3254 enum pipe_auth_type auth_type,
3255 enum dcerpc_AuthLevel auth_level,
3257 const char *username,
3258 const char *password,
3259 struct cli_pipe_auth_data **presult)
3261 struct cli_pipe_auth_data *result;
3264 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3265 if (result == NULL) {
3266 return NT_STATUS_NO_MEMORY;
3269 result->auth_type = auth_type;
3270 result->auth_level = auth_level;
3272 result->user_name = talloc_strdup(result, username);
3273 result->domain = talloc_strdup(result, domain);
3274 if ((result->user_name == NULL) || (result->domain == NULL)) {
3275 status = NT_STATUS_NO_MEMORY;
3279 status = ntlmssp_client_start(NULL,
3282 lp_client_ntlmv2_auth(),
3283 &result->a_u.ntlmssp_state);
3284 if (!NT_STATUS_IS_OK(status)) {
3288 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3290 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3291 if (!NT_STATUS_IS_OK(status)) {
3295 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3296 if (!NT_STATUS_IS_OK(status)) {
3300 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3301 if (!NT_STATUS_IS_OK(status)) {
3306 * Turn off sign+seal to allow selected auth level to turn it back on.
3308 result->a_u.ntlmssp_state->neg_flags &=
3309 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3311 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3312 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3313 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3314 result->a_u.ntlmssp_state->neg_flags
3315 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3319 return NT_STATUS_OK;
3322 TALLOC_FREE(result);
3326 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3327 enum dcerpc_AuthLevel auth_level,
3328 struct netlogon_creds_CredentialState *creds,
3329 struct cli_pipe_auth_data **presult)
3331 struct cli_pipe_auth_data *result;
3333 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3334 if (result == NULL) {
3335 return NT_STATUS_NO_MEMORY;
3338 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3339 result->auth_level = auth_level;
3341 result->user_name = talloc_strdup(result, "");
3342 result->domain = talloc_strdup(result, domain);
3343 if ((result->user_name == NULL) || (result->domain == NULL)) {
3347 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3348 if (result->a_u.schannel_auth == NULL) {
3352 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3353 result->a_u.schannel_auth->seq_num = 0;
3354 result->a_u.schannel_auth->initiator = true;
3355 result->a_u.schannel_auth->creds = creds;
3358 return NT_STATUS_OK;
3361 TALLOC_FREE(result);
3362 return NT_STATUS_NO_MEMORY;
3366 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3368 data_blob_free(&auth->session_key);
3373 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3374 enum dcerpc_AuthLevel auth_level,
3375 const char *service_princ,
3376 const char *username,
3377 const char *password,
3378 struct cli_pipe_auth_data **presult)
3381 struct cli_pipe_auth_data *result;
3383 if ((username != NULL) && (password != NULL)) {
3384 int ret = kerberos_kinit_password(username, password, 0, NULL);
3386 return NT_STATUS_ACCESS_DENIED;
3390 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3391 if (result == NULL) {
3392 return NT_STATUS_NO_MEMORY;
3395 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3396 result->auth_level = auth_level;
3399 * Username / domain need fixing!
3401 result->user_name = talloc_strdup(result, "");
3402 result->domain = talloc_strdup(result, "");
3403 if ((result->user_name == NULL) || (result->domain == NULL)) {
3407 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3408 result, struct kerberos_auth_struct);
3409 if (result->a_u.kerberos_auth == NULL) {
3412 talloc_set_destructor(result->a_u.kerberos_auth,
3413 cli_auth_kerberos_data_destructor);
3415 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3416 result, service_princ);
3417 if (result->a_u.kerberos_auth->service_principal == NULL) {
3422 return NT_STATUS_OK;
3425 TALLOC_FREE(result);
3426 return NT_STATUS_NO_MEMORY;
3428 return NT_STATUS_NOT_SUPPORTED;
3433 * Create an rpc pipe client struct, connecting to a tcp port.
3435 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3437 const struct ndr_syntax_id *abstract_syntax,
3438 struct rpc_pipe_client **presult)
3440 struct rpc_pipe_client *result;
3441 struct sockaddr_storage addr;
3445 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3446 if (result == NULL) {
3447 return NT_STATUS_NO_MEMORY;
3450 result->abstract_syntax = *abstract_syntax;
3451 result->transfer_syntax = ndr_transfer_syntax;
3452 result->dispatch = cli_do_rpc_ndr;
3453 result->dispatch_send = cli_do_rpc_ndr_send;
3454 result->dispatch_recv = cli_do_rpc_ndr_recv;
3456 result->desthost = talloc_strdup(result, host);
3457 result->srv_name_slash = talloc_asprintf_strupper_m(
3458 result, "\\\\%s", result->desthost);
3459 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3460 status = NT_STATUS_NO_MEMORY;
3464 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3465 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3467 if (!resolve_name(host, &addr, 0, false)) {
3468 status = NT_STATUS_NOT_FOUND;
3472 status = open_socket_out(&addr, port, 60, &fd);
3473 if (!NT_STATUS_IS_OK(status)) {
3476 set_socket_options(fd, lp_socket_options());
3478 status = rpc_transport_sock_init(result, fd, &result->transport);
3479 if (!NT_STATUS_IS_OK(status)) {
3484 result->transport->transport = NCACN_IP_TCP;
3487 return NT_STATUS_OK;
3490 TALLOC_FREE(result);
3495 * Determine the tcp port on which a dcerpc interface is listening
3496 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3499 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3500 const struct ndr_syntax_id *abstract_syntax,
3504 struct rpc_pipe_client *epm_pipe = NULL;
3505 struct cli_pipe_auth_data *auth = NULL;
3506 struct dcerpc_binding *map_binding = NULL;
3507 struct dcerpc_binding *res_binding = NULL;
3508 struct epm_twr_t *map_tower = NULL;
3509 struct epm_twr_t *res_towers = NULL;
3510 struct policy_handle *entry_handle = NULL;
3511 uint32_t num_towers = 0;
3512 uint32_t max_towers = 1;
3513 struct epm_twr_p_t towers;
3514 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3516 if (pport == NULL) {
3517 status = NT_STATUS_INVALID_PARAMETER;
3521 /* open the connection to the endpoint mapper */
3522 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3523 &ndr_table_epmapper.syntax_id,
3526 if (!NT_STATUS_IS_OK(status)) {
3530 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3531 if (!NT_STATUS_IS_OK(status)) {
3535 status = rpc_pipe_bind(epm_pipe, auth);
3536 if (!NT_STATUS_IS_OK(status)) {
3540 /* create tower for asking the epmapper */
3542 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3543 if (map_binding == NULL) {
3544 status = NT_STATUS_NO_MEMORY;
3548 map_binding->transport = NCACN_IP_TCP;
3549 map_binding->object = *abstract_syntax;
3550 map_binding->host = host; /* needed? */
3551 map_binding->endpoint = "0"; /* correct? needed? */
3553 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3554 if (map_tower == NULL) {
3555 status = NT_STATUS_NO_MEMORY;
3559 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3560 &(map_tower->tower));
3561 if (!NT_STATUS_IS_OK(status)) {
3565 /* allocate further parameters for the epm_Map call */
3567 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3568 if (res_towers == NULL) {
3569 status = NT_STATUS_NO_MEMORY;
3572 towers.twr = res_towers;
3574 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3575 if (entry_handle == NULL) {
3576 status = NT_STATUS_NO_MEMORY;
3580 /* ask the endpoint mapper for the port */
3582 status = rpccli_epm_Map(epm_pipe,
3584 CONST_DISCARD(struct GUID *,
3585 &(abstract_syntax->uuid)),
3592 if (!NT_STATUS_IS_OK(status)) {
3596 if (num_towers != 1) {
3597 status = NT_STATUS_UNSUCCESSFUL;
3601 /* extract the port from the answer */
3603 status = dcerpc_binding_from_tower(tmp_ctx,
3604 &(towers.twr->tower),
3606 if (!NT_STATUS_IS_OK(status)) {
3610 /* are further checks here necessary? */
3611 if (res_binding->transport != NCACN_IP_TCP) {
3612 status = NT_STATUS_UNSUCCESSFUL;
3616 *pport = (uint16_t)atoi(res_binding->endpoint);
3619 TALLOC_FREE(tmp_ctx);
3624 * Create a rpc pipe client struct, connecting to a host via tcp.
3625 * The port is determined by asking the endpoint mapper on the given
3628 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3629 const struct ndr_syntax_id *abstract_syntax,
3630 struct rpc_pipe_client **presult)
3635 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3636 if (!NT_STATUS_IS_OK(status)) {
3640 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3641 abstract_syntax, presult);
3644 /********************************************************************
3645 Create a rpc pipe client struct, connecting to a unix domain socket
3646 ********************************************************************/
3647 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3648 const struct ndr_syntax_id *abstract_syntax,
3649 struct rpc_pipe_client **presult)
3651 struct rpc_pipe_client *result;
3652 struct sockaddr_un addr;
3656 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3657 if (result == NULL) {
3658 return NT_STATUS_NO_MEMORY;
3661 result->abstract_syntax = *abstract_syntax;
3662 result->transfer_syntax = ndr_transfer_syntax;
3663 result->dispatch = cli_do_rpc_ndr;
3664 result->dispatch_send = cli_do_rpc_ndr_send;
3665 result->dispatch_recv = cli_do_rpc_ndr_recv;
3667 result->desthost = get_myname(result);
3668 result->srv_name_slash = talloc_asprintf_strupper_m(
3669 result, "\\\\%s", result->desthost);
3670 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3671 status = NT_STATUS_NO_MEMORY;
3675 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3676 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3678 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3680 status = map_nt_error_from_unix(errno);
3685 addr.sun_family = AF_UNIX;
3686 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3688 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3689 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3692 return map_nt_error_from_unix(errno);
3695 status = rpc_transport_sock_init(result, fd, &result->transport);
3696 if (!NT_STATUS_IS_OK(status)) {
3701 result->transport->transport = NCALRPC;
3704 return NT_STATUS_OK;
3707 TALLOC_FREE(result);
3711 struct rpc_pipe_client_np_ref {
3712 struct cli_state *cli;
3713 struct rpc_pipe_client *pipe;
3716 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3718 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3722 /****************************************************************************
3723 Open a named pipe over SMB to a remote server.
3725 * CAVEAT CALLER OF THIS FUNCTION:
3726 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3727 * so be sure that this function is called AFTER any structure (vs pointer)
3728 * assignment of the cli. In particular, libsmbclient does structure
3729 * assignments of cli, which invalidates the data in the returned
3730 * rpc_pipe_client if this function is called before the structure assignment
3733 ****************************************************************************/
3735 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3736 const struct ndr_syntax_id *abstract_syntax,
3737 struct rpc_pipe_client **presult)
3739 struct rpc_pipe_client *result;
3741 struct rpc_pipe_client_np_ref *np_ref;
3743 /* sanity check to protect against crashes */
3746 return NT_STATUS_INVALID_HANDLE;
3749 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3750 if (result == NULL) {
3751 return NT_STATUS_NO_MEMORY;
3754 result->abstract_syntax = *abstract_syntax;
3755 result->transfer_syntax = ndr_transfer_syntax;
3756 result->dispatch = cli_do_rpc_ndr;
3757 result->dispatch_send = cli_do_rpc_ndr_send;
3758 result->dispatch_recv = cli_do_rpc_ndr_recv;
3759 result->desthost = talloc_strdup(result, cli->desthost);
3760 result->srv_name_slash = talloc_asprintf_strupper_m(
3761 result, "\\\\%s", result->desthost);
3763 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3764 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3766 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3767 TALLOC_FREE(result);
3768 return NT_STATUS_NO_MEMORY;
3771 status = rpc_transport_np_init(result, cli, abstract_syntax,
3772 &result->transport);
3773 if (!NT_STATUS_IS_OK(status)) {
3774 TALLOC_FREE(result);
3778 result->transport->transport = NCACN_NP;
3780 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3781 if (np_ref == NULL) {
3782 TALLOC_FREE(result);
3783 return NT_STATUS_NO_MEMORY;
3786 np_ref->pipe = result;
3788 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3789 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3792 return NT_STATUS_OK;
3795 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3796 struct rpc_cli_smbd_conn *conn,
3797 const struct ndr_syntax_id *syntax,
3798 struct rpc_pipe_client **presult)
3800 struct rpc_pipe_client *result;
3801 struct cli_pipe_auth_data *auth;
3804 result = talloc(mem_ctx, struct rpc_pipe_client);
3805 if (result == NULL) {
3806 return NT_STATUS_NO_MEMORY;
3808 result->abstract_syntax = *syntax;
3809 result->transfer_syntax = ndr_transfer_syntax;
3810 result->dispatch = cli_do_rpc_ndr;
3811 result->dispatch_send = cli_do_rpc_ndr_send;
3812 result->dispatch_recv = cli_do_rpc_ndr_recv;
3813 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3814 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3816 result->desthost = talloc_strdup(result, global_myname());
3817 result->srv_name_slash = talloc_asprintf_strupper_m(
3818 result, "\\\\%s", global_myname());
3819 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3820 TALLOC_FREE(result);
3821 return NT_STATUS_NO_MEMORY;
3824 status = rpc_transport_smbd_init(result, conn, syntax,
3825 &result->transport);
3826 if (!NT_STATUS_IS_OK(status)) {
3827 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3828 nt_errstr(status)));
3829 TALLOC_FREE(result);
3833 status = rpccli_anon_bind_data(result, &auth);
3834 if (!NT_STATUS_IS_OK(status)) {
3835 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3836 nt_errstr(status)));
3837 TALLOC_FREE(result);
3841 status = rpc_pipe_bind(result, auth);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3844 TALLOC_FREE(result);
3848 result->transport->transport = NCACN_INTERNAL;
3851 return NT_STATUS_OK;
3854 /****************************************************************************
3855 Open a pipe to a remote server.
3856 ****************************************************************************/
3858 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3859 enum dcerpc_transport_t transport,
3860 const struct ndr_syntax_id *interface,
3861 struct rpc_pipe_client **presult)
3863 switch (transport) {
3865 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3868 return rpc_pipe_open_np(cli, interface, presult);
3870 return NT_STATUS_NOT_IMPLEMENTED;
3874 /****************************************************************************
3875 Open a named pipe to an SMB server and bind anonymously.
3876 ****************************************************************************/
3878 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3879 enum dcerpc_transport_t transport,
3880 const struct ndr_syntax_id *interface,
3881 struct rpc_pipe_client **presult)
3883 struct rpc_pipe_client *result;
3884 struct cli_pipe_auth_data *auth;
3887 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3888 if (!NT_STATUS_IS_OK(status)) {
3892 status = rpccli_anon_bind_data(result, &auth);
3893 if (!NT_STATUS_IS_OK(status)) {
3894 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3895 nt_errstr(status)));
3896 TALLOC_FREE(result);
3901 * This is a bit of an abstraction violation due to the fact that an
3902 * anonymous bind on an authenticated SMB inherits the user/domain
3903 * from the enclosing SMB creds
3906 TALLOC_FREE(auth->user_name);
3907 TALLOC_FREE(auth->domain);
3909 auth->user_name = talloc_strdup(auth, cli->user_name);
3910 auth->domain = talloc_strdup(auth, cli->domain);
3911 auth->user_session_key = data_blob_talloc(auth,
3912 cli->user_session_key.data,
3913 cli->user_session_key.length);
3915 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3916 TALLOC_FREE(result);
3917 return NT_STATUS_NO_MEMORY;
3920 status = rpc_pipe_bind(result, auth);
3921 if (!NT_STATUS_IS_OK(status)) {
3923 if (ndr_syntax_id_equal(interface,
3924 &ndr_table_dssetup.syntax_id)) {
3925 /* non AD domains just don't have this pipe, avoid
3926 * level 0 statement in that case - gd */
3929 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3930 "%s failed with error %s\n",
3931 get_pipe_name_from_syntax(talloc_tos(), interface),
3932 nt_errstr(status) ));
3933 TALLOC_FREE(result);
3937 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3938 "%s and bound anonymously.\n",
3939 get_pipe_name_from_syntax(talloc_tos(), interface),
3943 return NT_STATUS_OK;
3946 /****************************************************************************
3947 ****************************************************************************/
3949 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3950 const struct ndr_syntax_id *interface,
3951 struct rpc_pipe_client **presult)
3953 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3954 interface, presult);
3957 /****************************************************************************
3958 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3959 ****************************************************************************/
3961 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3962 const struct ndr_syntax_id *interface,
3963 enum dcerpc_transport_t transport,
3964 enum pipe_auth_type auth_type,
3965 enum dcerpc_AuthLevel auth_level,
3967 const char *username,
3968 const char *password,
3969 struct rpc_pipe_client **presult)
3971 struct rpc_pipe_client *result;
3972 struct cli_pipe_auth_data *auth;
3975 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3976 if (!NT_STATUS_IS_OK(status)) {
3980 status = rpccli_ntlmssp_bind_data(
3981 result, auth_type, auth_level, domain, username,
3983 if (!NT_STATUS_IS_OK(status)) {
3984 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3985 nt_errstr(status)));
3989 status = rpc_pipe_bind(result, auth);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3992 nt_errstr(status) ));
3996 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3997 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3998 get_pipe_name_from_syntax(talloc_tos(), interface),
3999 cli->desthost, domain, username ));
4002 return NT_STATUS_OK;
4006 TALLOC_FREE(result);
4010 /****************************************************************************
4012 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4013 ****************************************************************************/
4015 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4016 const struct ndr_syntax_id *interface,
4017 enum dcerpc_transport_t transport,
4018 enum dcerpc_AuthLevel auth_level,
4020 const char *username,
4021 const char *password,
4022 struct rpc_pipe_client **presult)
4024 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4027 PIPE_AUTH_TYPE_NTLMSSP,
4035 /****************************************************************************
4037 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4038 ****************************************************************************/
4040 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4041 const struct ndr_syntax_id *interface,
4042 enum dcerpc_transport_t transport,
4043 enum dcerpc_AuthLevel auth_level,
4045 const char *username,
4046 const char *password,
4047 struct rpc_pipe_client **presult)
4049 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4052 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4060 /****************************************************************************
4061 Get a the schannel session key out of an already opened netlogon pipe.
4062 ****************************************************************************/
4063 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4064 struct cli_state *cli,
4068 enum netr_SchannelType sec_chan_type = 0;
4069 unsigned char machine_pwd[16];
4070 const char *machine_account;
4073 /* Get the machine account credentials from secrets.tdb. */
4074 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4077 DEBUG(0, ("get_schannel_session_key: could not fetch "
4078 "trust account password for domain '%s'\n",
4080 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4083 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4084 cli->desthost, /* server name */
4085 domain, /* domain */
4086 global_myname(), /* client name */
4087 machine_account, /* machine account name */
4092 if (!NT_STATUS_IS_OK(status)) {
4093 DEBUG(3, ("get_schannel_session_key_common: "
4094 "rpccli_netlogon_setup_creds failed with result %s "
4095 "to server %s, domain %s, machine account %s.\n",
4096 nt_errstr(status), cli->desthost, domain,
4101 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4102 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4104 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4107 return NT_STATUS_OK;;
4110 /****************************************************************************
4111 Open a netlogon pipe and get the schannel session key.
4112 Now exposed to external callers.
4113 ****************************************************************************/
4116 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4119 struct rpc_pipe_client **presult)
4121 struct rpc_pipe_client *netlogon_pipe = NULL;
4124 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4126 if (!NT_STATUS_IS_OK(status)) {
4130 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4132 if (!NT_STATUS_IS_OK(status)) {
4133 TALLOC_FREE(netlogon_pipe);
4137 *presult = netlogon_pipe;
4138 return NT_STATUS_OK;
4141 /****************************************************************************
4143 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4144 using session_key. sign and seal.
4146 The *pdc will be stolen onto this new pipe
4147 ****************************************************************************/
4149 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4150 const struct ndr_syntax_id *interface,
4151 enum dcerpc_transport_t transport,
4152 enum dcerpc_AuthLevel auth_level,
4154 struct netlogon_creds_CredentialState **pdc,
4155 struct rpc_pipe_client **presult)
4157 struct rpc_pipe_client *result;
4158 struct cli_pipe_auth_data *auth;
4161 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4162 if (!NT_STATUS_IS_OK(status)) {
4166 status = rpccli_schannel_bind_data(result, domain, auth_level,
4168 if (!NT_STATUS_IS_OK(status)) {
4169 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4170 nt_errstr(status)));
4171 TALLOC_FREE(result);
4175 status = rpc_pipe_bind(result, auth);
4176 if (!NT_STATUS_IS_OK(status)) {
4177 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4178 "cli_rpc_pipe_bind failed with error %s\n",
4179 nt_errstr(status) ));
4180 TALLOC_FREE(result);
4185 * The credentials on a new netlogon pipe are the ones we are passed
4186 * in - reference them in
4188 result->dc = talloc_move(result, pdc);
4190 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4191 "for domain %s and bound using schannel.\n",
4192 get_pipe_name_from_syntax(talloc_tos(), interface),
4193 cli->desthost, domain ));
4196 return NT_STATUS_OK;
4199 /****************************************************************************
4200 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4201 Fetch the session key ourselves using a temporary netlogon pipe. This
4202 version uses an ntlmssp auth bound netlogon pipe to get the key.
4203 ****************************************************************************/
4205 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4207 const char *username,
4208 const char *password,
4210 struct rpc_pipe_client **presult)
4212 struct rpc_pipe_client *netlogon_pipe = NULL;
4215 status = cli_rpc_pipe_open_spnego_ntlmssp(
4216 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4217 DCERPC_AUTH_LEVEL_PRIVACY,
4218 domain, username, password, &netlogon_pipe);
4219 if (!NT_STATUS_IS_OK(status)) {
4223 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4225 if (!NT_STATUS_IS_OK(status)) {
4226 TALLOC_FREE(netlogon_pipe);
4230 *presult = netlogon_pipe;
4231 return NT_STATUS_OK;
4234 /****************************************************************************
4235 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4236 Fetch the session key ourselves using a temporary netlogon pipe. This version
4237 uses an ntlmssp bind to get the session key.
4238 ****************************************************************************/
4240 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4241 const struct ndr_syntax_id *interface,
4242 enum dcerpc_transport_t transport,
4243 enum dcerpc_AuthLevel auth_level,
4245 const char *username,
4246 const char *password,
4247 struct rpc_pipe_client **presult)
4249 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4250 struct rpc_pipe_client *netlogon_pipe = NULL;
4251 struct rpc_pipe_client *result = NULL;
4254 status = get_schannel_session_key_auth_ntlmssp(
4255 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4256 if (!NT_STATUS_IS_OK(status)) {
4257 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4258 "key from server %s for domain %s.\n",
4259 cli->desthost, domain ));
4263 status = cli_rpc_pipe_open_schannel_with_key(
4264 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4267 /* Now we've bound using the session key we can close the netlog pipe. */
4268 TALLOC_FREE(netlogon_pipe);
4270 if (NT_STATUS_IS_OK(status)) {
4276 /****************************************************************************
4277 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4278 Fetch the session key ourselves using a temporary netlogon pipe.
4279 ****************************************************************************/
4281 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4282 const struct ndr_syntax_id *interface,
4283 enum dcerpc_transport_t transport,
4284 enum dcerpc_AuthLevel auth_level,
4286 struct rpc_pipe_client **presult)
4288 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4289 struct rpc_pipe_client *netlogon_pipe = NULL;
4290 struct rpc_pipe_client *result = NULL;
4293 status = get_schannel_session_key(cli, domain, &neg_flags,
4295 if (!NT_STATUS_IS_OK(status)) {
4296 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4297 "key from server %s for domain %s.\n",
4298 cli->desthost, domain ));
4302 status = cli_rpc_pipe_open_schannel_with_key(
4303 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4306 /* Now we've bound using the session key we can close the netlog pipe. */
4307 TALLOC_FREE(netlogon_pipe);
4309 if (NT_STATUS_IS_OK(status)) {
4316 /****************************************************************************
4317 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4318 The idea is this can be called with service_princ, username and password all
4319 NULL so long as the caller has a TGT.
4320 ****************************************************************************/
4322 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4323 const struct ndr_syntax_id *interface,
4324 enum dcerpc_AuthLevel auth_level,
4325 const char *service_princ,
4326 const char *username,
4327 const char *password,
4328 struct rpc_pipe_client **presult)
4331 struct rpc_pipe_client *result;
4332 struct cli_pipe_auth_data *auth;
4335 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4336 if (!NT_STATUS_IS_OK(status)) {
4340 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4341 username, password, &auth);
4342 if (!NT_STATUS_IS_OK(status)) {
4343 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4344 nt_errstr(status)));
4345 TALLOC_FREE(result);
4349 status = rpc_pipe_bind(result, auth);
4350 if (!NT_STATUS_IS_OK(status)) {
4351 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4352 "with error %s\n", nt_errstr(status)));
4353 TALLOC_FREE(result);
4358 return NT_STATUS_OK;
4360 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4361 return NT_STATUS_NOT_IMPLEMENTED;
4365 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4366 struct rpc_pipe_client *cli,
4367 DATA_BLOB *session_key)
4369 if (!session_key || !cli) {
4370 return NT_STATUS_INVALID_PARAMETER;
4374 return NT_STATUS_INVALID_PARAMETER;
4377 switch (cli->auth->auth_type) {
4378 case PIPE_AUTH_TYPE_SCHANNEL:
4379 *session_key = data_blob_talloc(mem_ctx,
4380 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4382 case PIPE_AUTH_TYPE_NTLMSSP:
4383 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4384 *session_key = data_blob_talloc(mem_ctx,
4385 cli->auth->a_u.ntlmssp_state->session_key.data,
4386 cli->auth->a_u.ntlmssp_state->session_key.length);
4388 case PIPE_AUTH_TYPE_KRB5:
4389 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4390 *session_key = data_blob_talloc(mem_ctx,
4391 cli->auth->a_u.kerberos_auth->session_key.data,
4392 cli->auth->a_u.kerberos_auth->session_key.length);
4394 case PIPE_AUTH_TYPE_NONE:
4395 *session_key = data_blob_talloc(mem_ctx,
4396 cli->auth->user_session_key.data,
4397 cli->auth->user_session_key.length);
4400 return NT_STATUS_NO_USER_SESSION_KEY;
4403 return NT_STATUS_OK;