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 ********************************************************************/
407 static NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
408 const DATA_BLOB *blob,
409 struct dcerpc_auth *r)
411 enum ndr_err_code ndr_err;
413 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
414 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
415 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
416 return ndr_map_error2ntstatus(ndr_err);
419 if (DEBUGLEVEL >= 10) {
420 NDR_PRINT_DEBUG(dcerpc_auth, r);
426 /*******************************************************************
427 Use SMBreadX to get rest of one fragment's worth of rpc data.
428 Reads the whole size or give an error message
429 ********************************************************************/
431 struct rpc_read_state {
432 struct event_context *ev;
433 struct rpc_cli_transport *transport;
439 static void rpc_read_done(struct tevent_req *subreq);
441 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
442 struct event_context *ev,
443 struct rpc_cli_transport *transport,
444 uint8_t *data, size_t size)
446 struct tevent_req *req, *subreq;
447 struct rpc_read_state *state;
449 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
454 state->transport = transport;
459 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
461 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
463 if (subreq == NULL) {
466 tevent_req_set_callback(subreq, rpc_read_done, req);
474 static void rpc_read_done(struct tevent_req *subreq)
476 struct tevent_req *req = tevent_req_callback_data(
477 subreq, struct tevent_req);
478 struct rpc_read_state *state = tevent_req_data(
479 req, struct rpc_read_state);
483 status = state->transport->read_recv(subreq, &received);
485 if (!NT_STATUS_IS_OK(status)) {
486 tevent_req_nterror(req, status);
490 state->num_read += received;
491 if (state->num_read == state->size) {
492 tevent_req_done(req);
496 subreq = state->transport->read_send(state, state->ev,
497 state->data + state->num_read,
498 state->size - state->num_read,
499 state->transport->priv);
500 if (tevent_req_nomem(subreq, req)) {
503 tevent_req_set_callback(subreq, rpc_read_done, req);
506 static NTSTATUS rpc_read_recv(struct tevent_req *req)
508 return tevent_req_simple_recv_ntstatus(req);
511 struct rpc_write_state {
512 struct event_context *ev;
513 struct rpc_cli_transport *transport;
519 static void rpc_write_done(struct tevent_req *subreq);
521 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
522 struct event_context *ev,
523 struct rpc_cli_transport *transport,
524 const uint8_t *data, size_t size)
526 struct tevent_req *req, *subreq;
527 struct rpc_write_state *state;
529 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
534 state->transport = transport;
537 state->num_written = 0;
539 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
541 subreq = transport->write_send(state, ev, data, size, transport->priv);
542 if (subreq == NULL) {
545 tevent_req_set_callback(subreq, rpc_write_done, req);
552 static void rpc_write_done(struct tevent_req *subreq)
554 struct tevent_req *req = tevent_req_callback_data(
555 subreq, struct tevent_req);
556 struct rpc_write_state *state = tevent_req_data(
557 req, struct rpc_write_state);
561 status = state->transport->write_recv(subreq, &written);
563 if (!NT_STATUS_IS_OK(status)) {
564 tevent_req_nterror(req, status);
568 state->num_written += written;
570 if (state->num_written == state->size) {
571 tevent_req_done(req);
575 subreq = state->transport->write_send(state, state->ev,
576 state->data + state->num_written,
577 state->size - state->num_written,
578 state->transport->priv);
579 if (tevent_req_nomem(subreq, req)) {
582 tevent_req_set_callback(subreq, rpc_write_done, req);
585 static NTSTATUS rpc_write_recv(struct tevent_req *req)
587 return tevent_req_simple_recv_ntstatus(req);
591 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
592 struct ncacn_packet_header *prhdr,
596 DATA_BLOB blob = data_blob_const(prs_data_p(pdu), prs_data_size(pdu));
599 * This next call sets the endian bit correctly in current_pdu. We
600 * will propagate this to rbuf later.
603 status = dcerpc_pull_ncacn_packet_header(cli, &blob, prhdr);
604 if (!NT_STATUS_IS_OK(status)) {
608 if (!prs_set_offset(pdu, prs_offset(pdu) + RPC_HEADER_LEN)) {
609 return NT_STATUS_BUFFER_TOO_SMALL;
612 if (UNMARSHALLING(pdu) && prhdr->drep[0] == 0) {
613 DEBUG(10,("parse_rpc_header: PDU data format is big-endian. Setting flag.\n"));
614 prs_set_endian_data(pdu, RPC_BIG_ENDIAN);
617 if (prhdr->frag_length > cli->max_recv_frag) {
618 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
619 " we only allow %d\n", (int)prhdr->frag_length,
620 (int)cli->max_recv_frag));
621 return NT_STATUS_BUFFER_TOO_SMALL;
627 /****************************************************************************
628 Try and get a PDU's worth of data from current_pdu. If not, then read more
630 ****************************************************************************/
632 struct get_complete_frag_state {
633 struct event_context *ev;
634 struct rpc_pipe_client *cli;
635 struct ncacn_packet_header *prhdr;
639 static void get_complete_frag_got_header(struct tevent_req *subreq);
640 static void get_complete_frag_got_rest(struct tevent_req *subreq);
642 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
643 struct event_context *ev,
644 struct rpc_pipe_client *cli,
645 struct ncacn_packet_header *prhdr,
648 struct tevent_req *req, *subreq;
649 struct get_complete_frag_state *state;
653 req = tevent_req_create(mem_ctx, &state,
654 struct get_complete_frag_state);
660 state->prhdr = prhdr;
663 pdu_len = prs_data_size(pdu);
664 if (pdu_len < RPC_HEADER_LEN) {
665 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
666 status = NT_STATUS_NO_MEMORY;
669 subreq = rpc_read_send(
671 state->cli->transport,
672 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
673 RPC_HEADER_LEN - pdu_len);
674 if (subreq == NULL) {
675 status = NT_STATUS_NO_MEMORY;
678 tevent_req_set_callback(subreq, get_complete_frag_got_header,
683 status = parse_rpc_header(cli, prhdr, pdu);
684 if (!NT_STATUS_IS_OK(status)) {
689 * Ensure we have frag_len bytes of data.
691 if (pdu_len < prhdr->frag_length) {
692 if (!rpc_grow_buffer(pdu, prhdr->frag_length)) {
693 status = NT_STATUS_NO_MEMORY;
696 subreq = rpc_read_send(state, state->ev,
697 state->cli->transport,
698 (uint8_t *)(prs_data_p(pdu) + pdu_len),
699 prhdr->frag_length - pdu_len);
700 if (subreq == NULL) {
701 status = NT_STATUS_NO_MEMORY;
704 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
709 status = NT_STATUS_OK;
711 if (NT_STATUS_IS_OK(status)) {
712 tevent_req_done(req);
714 tevent_req_nterror(req, status);
716 return tevent_req_post(req, ev);
719 static void get_complete_frag_got_header(struct tevent_req *subreq)
721 struct tevent_req *req = tevent_req_callback_data(
722 subreq, struct tevent_req);
723 struct get_complete_frag_state *state = tevent_req_data(
724 req, struct get_complete_frag_state);
727 status = rpc_read_recv(subreq);
729 if (!NT_STATUS_IS_OK(status)) {
730 tevent_req_nterror(req, status);
734 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
735 if (!NT_STATUS_IS_OK(status)) {
736 tevent_req_nterror(req, status);
740 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_length)) {
741 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
746 * We're here in this piece of code because we've read exactly
747 * RPC_HEADER_LEN bytes into state->pdu.
750 subreq = rpc_read_send(
751 state, state->ev, state->cli->transport,
752 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
753 state->prhdr->frag_length - RPC_HEADER_LEN);
754 if (tevent_req_nomem(subreq, req)) {
757 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
760 static void get_complete_frag_got_rest(struct tevent_req *subreq)
762 struct tevent_req *req = tevent_req_callback_data(
763 subreq, struct tevent_req);
766 status = rpc_read_recv(subreq);
768 if (!NT_STATUS_IS_OK(status)) {
769 tevent_req_nterror(req, status);
772 tevent_req_done(req);
775 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
777 return tevent_req_simple_recv_ntstatus(req);
780 /****************************************************************************
781 NTLMSSP specific sign/seal.
782 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
783 In fact I should probably abstract these into identical pieces of code... JRA.
784 ****************************************************************************/
786 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
787 struct ncacn_packet_header *prhdr,
788 prs_struct *current_pdu,
789 uint8 *p_ss_padding_len)
791 struct dcerpc_auth auth_info;
792 uint32 save_offset = prs_offset(current_pdu);
793 uint32_t auth_len = prhdr->auth_length;
794 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
795 unsigned char *data = NULL;
797 unsigned char *full_packet_data = NULL;
798 size_t full_packet_data_len;
803 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
804 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
808 if (!ntlmssp_state) {
809 return NT_STATUS_INVALID_PARAMETER;
812 /* Ensure there's enough data for an authenticated response. */
813 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
814 prhdr->frag_length < RPC_HEADER_LEN +
816 RPC_HDR_AUTH_LEN + auth_len) {
817 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
818 (unsigned int)auth_len ));
819 return NT_STATUS_BUFFER_TOO_SMALL;
823 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
824 * after the RPC header.
825 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
826 * functions as NTLMv2 checks the rpc headers also.
829 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
830 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
832 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
833 full_packet_data_len = prhdr->frag_length - auth_len;
835 /* Pull the auth header and the following data into a blob. */
836 /* NB. The offset of the auth_header is relative to the *end*
837 * of the packet, not the start. */
838 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
839 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
840 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
841 return NT_STATUS_BUFFER_TOO_SMALL;
844 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu),
845 prs_data_size(current_pdu) - prs_offset(current_pdu));
847 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
848 if (!NT_STATUS_IS_OK(status)) {
849 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
853 /* Ensure auth_pad_len fits into the packet. */
854 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
855 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
856 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
857 "too large (%u), auth_len (%u), frag_len = (%u).\n",
858 (unsigned int)auth_info.auth_pad_length,
859 (unsigned int)auth_len,
860 (unsigned int)prhdr->frag_length));
861 return NT_STATUS_BUFFER_TOO_SMALL;
865 auth_blob = auth_info.credentials;
867 switch (cli->auth->auth_level) {
868 case DCERPC_AUTH_LEVEL_PRIVACY:
869 /* Data is encrypted. */
870 status = ntlmssp_unseal_packet(ntlmssp_state,
873 full_packet_data_len,
875 if (!NT_STATUS_IS_OK(status)) {
876 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
877 "packet from %s. Error was %s.\n",
878 rpccli_pipe_txt(talloc_tos(), cli),
879 nt_errstr(status) ));
883 case DCERPC_AUTH_LEVEL_INTEGRITY:
884 /* Data is signed. */
885 status = ntlmssp_check_packet(ntlmssp_state,
888 full_packet_data_len,
890 if (!NT_STATUS_IS_OK(status)) {
891 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
892 "packet from %s. Error was %s.\n",
893 rpccli_pipe_txt(talloc_tos(), cli),
894 nt_errstr(status) ));
899 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
900 "auth level %d\n", cli->auth->auth_level));
901 return NT_STATUS_INVALID_INFO_CLASS;
905 * Return the current pointer to the data offset.
908 if(!prs_set_offset(current_pdu, save_offset)) {
909 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
910 (unsigned int)save_offset ));
911 return NT_STATUS_BUFFER_TOO_SMALL;
915 * Remember the padding length. We must remove it from the real data
916 * stream once the sign/seal is done.
919 *p_ss_padding_len = auth_info.auth_pad_length;
924 /****************************************************************************
925 schannel specific sign/seal.
926 ****************************************************************************/
928 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
929 struct ncacn_packet_header *prhdr,
930 prs_struct *current_pdu,
931 uint8 *p_ss_padding_len)
933 RPC_HDR_AUTH auth_info;
934 uint32_t auth_len = prhdr->auth_length;
935 uint32 save_offset = prs_offset(current_pdu);
936 struct schannel_state *schannel_auth =
937 cli->auth->a_u.schannel_auth;
943 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
944 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
948 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
949 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
950 return NT_STATUS_INVALID_PARAMETER;
953 if (!schannel_auth) {
954 return NT_STATUS_INVALID_PARAMETER;
957 /* Ensure there's enough data for an authenticated response. */
958 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
959 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length)) {
960 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
961 (unsigned int)auth_len ));
962 return NT_STATUS_INVALID_PARAMETER;
965 data_len = prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
967 /* Pull the auth header and the following data into a blob. */
968 /* NB. The offset of the auth_header is relative to the *end*
969 * of the packet, not the start. */
970 if(!prs_set_offset(current_pdu,
971 prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
972 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
974 (unsigned int)(prhdr->frag_length -
975 RPC_HDR_AUTH_LEN - auth_len) ));
976 return NT_STATUS_BUFFER_TOO_SMALL;
979 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
980 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
981 return NT_STATUS_BUFFER_TOO_SMALL;
984 /* Ensure auth_pad_len fits into the packet. */
985 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
986 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
987 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
988 "too large (%u), auth_len (%u), frag_len = (%u).\n",
989 (unsigned int)auth_info.auth_pad_len,
990 (unsigned int)auth_len,
991 (unsigned int)prhdr->frag_length));
992 return NT_STATUS_BUFFER_TOO_SMALL;
995 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
996 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
997 auth_info.auth_type));
998 return NT_STATUS_BUFFER_TOO_SMALL;
1001 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
1003 if (DEBUGLEVEL >= 10) {
1004 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1007 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1009 switch (cli->auth->auth_level) {
1010 case DCERPC_AUTH_LEVEL_PRIVACY:
1011 status = netsec_incoming_packet(schannel_auth,
1018 case DCERPC_AUTH_LEVEL_INTEGRITY:
1019 status = netsec_incoming_packet(schannel_auth,
1027 status = NT_STATUS_INTERNAL_ERROR;
1031 if (!NT_STATUS_IS_OK(status)) {
1032 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1033 "Connection to %s (%s).\n",
1034 rpccli_pipe_txt(talloc_tos(), cli),
1035 nt_errstr(status)));
1036 return NT_STATUS_INVALID_PARAMETER;
1040 * Return the current pointer to the data offset.
1043 if(!prs_set_offset(current_pdu, save_offset)) {
1044 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1045 (unsigned int)save_offset ));
1046 return NT_STATUS_BUFFER_TOO_SMALL;
1050 * Remember the padding length. We must remove it from the real data
1051 * stream once the sign/seal is done.
1054 *p_ss_padding_len = auth_info.auth_pad_len;
1056 return NT_STATUS_OK;
1059 /****************************************************************************
1060 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1061 ****************************************************************************/
1063 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1064 struct ncacn_packet_header *prhdr,
1065 prs_struct *current_pdu,
1066 uint8 *p_ss_padding_len)
1068 NTSTATUS ret = NT_STATUS_OK;
1070 /* Paranioa checks for auth_len. */
1071 if (prhdr->auth_length) {
1072 if (prhdr->auth_length > prhdr->frag_length) {
1073 return NT_STATUS_INVALID_PARAMETER;
1076 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1077 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1078 /* Integer wrap attempt. */
1079 return NT_STATUS_INVALID_PARAMETER;
1084 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1087 switch(cli->auth->auth_type) {
1088 case PIPE_AUTH_TYPE_NONE:
1089 if (prhdr->auth_length) {
1090 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1091 "Connection to %s - got non-zero "
1093 rpccli_pipe_txt(talloc_tos(), cli),
1094 (unsigned int)prhdr->auth_length));
1095 return NT_STATUS_INVALID_PARAMETER;
1099 case PIPE_AUTH_TYPE_NTLMSSP:
1100 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1101 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1102 if (!NT_STATUS_IS_OK(ret)) {
1107 case PIPE_AUTH_TYPE_SCHANNEL:
1108 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1109 if (!NT_STATUS_IS_OK(ret)) {
1114 case PIPE_AUTH_TYPE_KRB5:
1115 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1117 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1118 "to %s - unknown internal auth type %u.\n",
1119 rpccli_pipe_txt(talloc_tos(), cli),
1120 cli->auth->auth_type ));
1121 return NT_STATUS_INVALID_INFO_CLASS;
1124 return NT_STATUS_OK;
1127 /****************************************************************************
1128 Do basic authentication checks on an incoming pdu.
1129 ****************************************************************************/
1131 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1132 struct ncacn_packet_header *prhdr,
1133 prs_struct *current_pdu,
1134 uint8 expected_pkt_type,
1137 prs_struct *return_data)
1140 NTSTATUS ret = NT_STATUS_OK;
1141 uint32 current_pdu_len = prs_data_size(current_pdu);
1143 if (current_pdu_len != prhdr->frag_length) {
1144 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1145 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_length));
1146 return NT_STATUS_INVALID_PARAMETER;
1150 * Point the return values at the real data including the RPC
1151 * header. Just in case the caller wants it.
1153 *ppdata = prs_data_p(current_pdu);
1154 *pdata_len = current_pdu_len;
1156 /* Ensure we have the correct type. */
1157 switch (prhdr->ptype) {
1158 case DCERPC_PKT_ALTER_RESP:
1159 case DCERPC_PKT_BIND_ACK:
1161 /* Alter context and bind ack share the same packet definitions. */
1165 case DCERPC_PKT_RESPONSE:
1167 uint8 ss_padding_len = 0;
1169 struct ncacn_packet r;
1171 blob = data_blob_const(prs_data_p(current_pdu),
1172 prs_data_size(current_pdu));
1174 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1175 if (!NT_STATUS_IS_OK(ret)) {
1179 if (!prs_set_offset(current_pdu, prs_offset(current_pdu) + RPC_HDR_RESP_LEN)) {
1180 return NT_STATUS_BUFFER_TOO_SMALL;
1183 /* Here's where we deal with incoming sign/seal. */
1184 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1185 current_pdu, &ss_padding_len);
1186 if (!NT_STATUS_IS_OK(ret)) {
1190 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1191 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1193 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1194 return NT_STATUS_BUFFER_TOO_SMALL;
1197 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1199 /* Remember to remove the auth footer. */
1200 if (prhdr->auth_length) {
1201 /* We've already done integer wrap tests on auth_len in
1202 cli_pipe_validate_rpc_response(). */
1203 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_length) {
1204 return NT_STATUS_BUFFER_TOO_SMALL;
1206 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_length);
1209 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1210 current_pdu_len, *pdata_len, ss_padding_len ));
1213 * If this is the first reply, and the allocation hint is reasonably, try and
1214 * set up the return_data parse_struct to the correct size.
1217 if ((prs_data_size(return_data) == 0) && r.u.response.alloc_hint && (r.u.response.alloc_hint < 15*1024*1024)) {
1218 if (!prs_set_buffer_size(return_data, r.u.response.alloc_hint)) {
1219 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1220 "too large to allocate\n",
1221 (unsigned int)r.u.response.alloc_hint ));
1222 return NT_STATUS_NO_MEMORY;
1229 case DCERPC_PKT_BIND_NAK:
1230 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1231 "received from %s!\n",
1232 rpccli_pipe_txt(talloc_tos(), cli)));
1233 /* Use this for now... */
1234 return NT_STATUS_NETWORK_ACCESS_DENIED;
1236 case DCERPC_PKT_FAULT:
1239 struct ncacn_packet r;
1241 blob = data_blob_const(prs_data_p(current_pdu),
1242 prs_data_size(current_pdu));
1244 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1245 if (!NT_STATUS_IS_OK(ret)) {
1248 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1249 "code %s received from %s!\n",
1250 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1251 rpccli_pipe_txt(talloc_tos(), cli)));
1253 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1254 return NT_STATUS_UNSUCCESSFUL;
1256 return NT_STATUS(r.u.fault.status);
1261 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1263 (unsigned int)prhdr->ptype,
1264 rpccli_pipe_txt(talloc_tos(), cli)));
1265 return NT_STATUS_INVALID_INFO_CLASS;
1268 if (prhdr->ptype != expected_pkt_type) {
1269 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1270 "got an unexpected RPC packet type - %u, not %u\n",
1271 rpccli_pipe_txt(talloc_tos(), cli),
1273 expected_pkt_type));
1274 return NT_STATUS_INVALID_INFO_CLASS;
1277 /* Do this just before return - we don't want to modify any rpc header
1278 data before now as we may have needed to do cryptographic actions on
1281 if ((prhdr->ptype == DCERPC_PKT_BIND_ACK) && !(prhdr->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1282 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1283 "setting fragment first/last ON.\n"));
1284 prhdr->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1287 return NT_STATUS_OK;
1290 /****************************************************************************
1291 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1292 Normally the frag_len and buffer size will match, but on the first trans
1293 reply there is a theoretical chance that buffer size > frag_len, so we must
1295 ****************************************************************************/
1297 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1298 struct ncacn_packet_header *prhdr,
1299 prs_struct *current_pdu)
1301 uint32 current_pdu_len = prs_data_size(current_pdu);
1303 if (current_pdu_len < prhdr->frag_length) {
1304 return NT_STATUS_BUFFER_TOO_SMALL;
1308 if (current_pdu_len == (uint32)prhdr->frag_length) {
1309 prs_mem_free(current_pdu);
1310 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1311 /* Make current_pdu dynamic with no memory. */
1312 prs_give_memory(current_pdu, 0, 0, True);
1313 return NT_STATUS_OK;
1317 * Oh no ! More data in buffer than we processed in current pdu.
1318 * Cheat. Move the data down and shrink the buffer.
1321 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_length,
1322 current_pdu_len - prhdr->frag_length);
1324 /* Remember to set the read offset back to zero. */
1325 prs_set_offset(current_pdu, 0);
1327 /* Shrink the buffer. */
1328 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_length)) {
1329 return NT_STATUS_BUFFER_TOO_SMALL;
1332 return NT_STATUS_OK;
1335 /****************************************************************************
1336 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1337 ****************************************************************************/
1339 struct cli_api_pipe_state {
1340 struct event_context *ev;
1341 struct rpc_cli_transport *transport;
1346 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1347 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1348 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1350 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1351 struct event_context *ev,
1352 struct rpc_cli_transport *transport,
1353 uint8_t *data, size_t data_len,
1354 uint32_t max_rdata_len)
1356 struct tevent_req *req, *subreq;
1357 struct cli_api_pipe_state *state;
1360 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1365 state->transport = transport;
1367 if (max_rdata_len < RPC_HEADER_LEN) {
1369 * For a RPC reply we always need at least RPC_HEADER_LEN
1370 * bytes. We check this here because we will receive
1371 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1373 status = NT_STATUS_INVALID_PARAMETER;
1377 if (transport->trans_send != NULL) {
1378 subreq = transport->trans_send(state, ev, data, data_len,
1379 max_rdata_len, transport->priv);
1380 if (subreq == NULL) {
1383 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1388 * If the transport does not provide a "trans" routine, i.e. for
1389 * example the ncacn_ip_tcp transport, do the write/read step here.
1392 subreq = rpc_write_send(state, ev, transport, data, data_len);
1393 if (subreq == NULL) {
1396 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1400 tevent_req_nterror(req, status);
1401 return tevent_req_post(req, ev);
1407 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1409 struct tevent_req *req = tevent_req_callback_data(
1410 subreq, struct tevent_req);
1411 struct cli_api_pipe_state *state = tevent_req_data(
1412 req, struct cli_api_pipe_state);
1415 status = state->transport->trans_recv(subreq, state, &state->rdata,
1417 TALLOC_FREE(subreq);
1418 if (!NT_STATUS_IS_OK(status)) {
1419 tevent_req_nterror(req, status);
1422 tevent_req_done(req);
1425 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1427 struct tevent_req *req = tevent_req_callback_data(
1428 subreq, struct tevent_req);
1429 struct cli_api_pipe_state *state = tevent_req_data(
1430 req, struct cli_api_pipe_state);
1433 status = rpc_write_recv(subreq);
1434 TALLOC_FREE(subreq);
1435 if (!NT_STATUS_IS_OK(status)) {
1436 tevent_req_nterror(req, status);
1440 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1441 if (tevent_req_nomem(state->rdata, req)) {
1446 * We don't need to use rpc_read_send here, the upper layer will cope
1447 * with a short read, transport->trans_send could also return less
1448 * than state->max_rdata_len.
1450 subreq = state->transport->read_send(state, state->ev, state->rdata,
1452 state->transport->priv);
1453 if (tevent_req_nomem(subreq, req)) {
1456 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1459 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1461 struct tevent_req *req = tevent_req_callback_data(
1462 subreq, struct tevent_req);
1463 struct cli_api_pipe_state *state = tevent_req_data(
1464 req, struct cli_api_pipe_state);
1468 status = state->transport->read_recv(subreq, &received);
1469 TALLOC_FREE(subreq);
1470 if (!NT_STATUS_IS_OK(status)) {
1471 tevent_req_nterror(req, status);
1474 state->rdata_len = received;
1475 tevent_req_done(req);
1478 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1479 uint8_t **prdata, uint32_t *prdata_len)
1481 struct cli_api_pipe_state *state = tevent_req_data(
1482 req, struct cli_api_pipe_state);
1485 if (tevent_req_is_nterror(req, &status)) {
1489 *prdata = talloc_move(mem_ctx, &state->rdata);
1490 *prdata_len = state->rdata_len;
1491 return NT_STATUS_OK;
1494 /****************************************************************************
1495 Send data on an rpc pipe via trans. The prs_struct data must be the last
1496 pdu fragment of an NDR data stream.
1498 Receive response data from an rpc pipe, which may be large...
1500 Read the first fragment: unfortunately have to use SMBtrans for the first
1501 bit, then SMBreadX for subsequent bits.
1503 If first fragment received also wasn't the last fragment, continue
1504 getting fragments until we _do_ receive the last fragment.
1506 Request/Response PDU's look like the following...
1508 |<------------------PDU len----------------------------------------------->|
1509 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1511 +------------+-----------------+-------------+---------------+-------------+
1512 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1513 +------------+-----------------+-------------+---------------+-------------+
1515 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1516 signing & sealing being negotiated.
1518 ****************************************************************************/
1520 struct rpc_api_pipe_state {
1521 struct event_context *ev;
1522 struct rpc_pipe_client *cli;
1523 uint8_t expected_pkt_type;
1525 prs_struct incoming_frag;
1526 struct ncacn_packet_header rhdr;
1528 prs_struct incoming_pdu; /* Incoming reply */
1529 uint32_t incoming_pdu_offset;
1532 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1533 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1535 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1536 struct event_context *ev,
1537 struct rpc_pipe_client *cli,
1538 prs_struct *data, /* Outgoing PDU */
1539 uint8_t expected_pkt_type)
1541 struct tevent_req *req, *subreq;
1542 struct rpc_api_pipe_state *state;
1543 uint16_t max_recv_frag;
1546 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1552 state->expected_pkt_type = expected_pkt_type;
1553 state->incoming_pdu_offset = 0;
1555 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1557 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1558 /* Make incoming_pdu dynamic with no memory. */
1559 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1562 * Ensure we're not sending too much.
1564 if (prs_offset(data) > cli->max_xmit_frag) {
1565 status = NT_STATUS_INVALID_PARAMETER;
1569 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1571 max_recv_frag = cli->max_recv_frag;
1574 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1577 subreq = cli_api_pipe_send(state, ev, cli->transport,
1578 (uint8_t *)prs_data_p(data),
1579 prs_offset(data), max_recv_frag);
1580 if (subreq == NULL) {
1583 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1587 tevent_req_nterror(req, status);
1588 return tevent_req_post(req, ev);
1594 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1596 struct tevent_req *req = tevent_req_callback_data(
1597 subreq, struct tevent_req);
1598 struct rpc_api_pipe_state *state = tevent_req_data(
1599 req, struct rpc_api_pipe_state);
1601 uint8_t *rdata = NULL;
1602 uint32_t rdata_len = 0;
1604 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1605 TALLOC_FREE(subreq);
1606 if (!NT_STATUS_IS_OK(status)) {
1607 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1608 tevent_req_nterror(req, status);
1612 if (rdata == NULL) {
1613 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1614 rpccli_pipe_txt(talloc_tos(), state->cli)));
1615 tevent_req_done(req);
1620 * This is equivalent to a talloc_steal - gives rdata to
1621 * the prs_struct state->incoming_frag.
1623 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1626 /* Ensure we have enough data for a pdu. */
1627 subreq = get_complete_frag_send(state, state->ev, state->cli,
1628 &state->rhdr, &state->incoming_frag);
1629 if (tevent_req_nomem(subreq, req)) {
1632 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1635 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1637 struct tevent_req *req = tevent_req_callback_data(
1638 subreq, struct tevent_req);
1639 struct rpc_api_pipe_state *state = tevent_req_data(
1640 req, struct rpc_api_pipe_state);
1643 uint32_t rdata_len = 0;
1645 status = get_complete_frag_recv(subreq);
1646 TALLOC_FREE(subreq);
1647 if (!NT_STATUS_IS_OK(status)) {
1648 DEBUG(5, ("get_complete_frag failed: %s\n",
1649 nt_errstr(status)));
1650 tevent_req_nterror(req, status);
1654 status = cli_pipe_validate_current_pdu(
1655 state->cli, &state->rhdr, &state->incoming_frag,
1656 state->expected_pkt_type, &rdata, &rdata_len,
1657 &state->incoming_pdu);
1659 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1660 (unsigned)prs_data_size(&state->incoming_frag),
1661 (unsigned)state->incoming_pdu_offset,
1662 nt_errstr(status)));
1664 if (!NT_STATUS_IS_OK(status)) {
1665 tevent_req_nterror(req, status);
1669 if ((state->rhdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)
1670 && (state->rhdr.drep[0] == 0)) {
1672 * Set the data type correctly for big-endian data on the
1675 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1677 rpccli_pipe_txt(talloc_tos(), state->cli)));
1678 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1681 * Check endianness on subsequent packets.
1683 if (state->incoming_frag.bigendian_data
1684 != state->incoming_pdu.bigendian_data) {
1685 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1687 state->incoming_pdu.bigendian_data?"big":"little",
1688 state->incoming_frag.bigendian_data?"big":"little"));
1689 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1693 /* Now copy the data portion out of the pdu into rbuf. */
1694 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1695 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1699 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1700 rdata, (size_t)rdata_len);
1701 state->incoming_pdu_offset += rdata_len;
1703 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1704 &state->incoming_frag);
1705 if (!NT_STATUS_IS_OK(status)) {
1706 tevent_req_nterror(req, status);
1710 if (state->rhdr.pfc_flags & DCERPC_PFC_FLAG_LAST) {
1711 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1712 rpccli_pipe_txt(talloc_tos(), state->cli),
1713 (unsigned)prs_data_size(&state->incoming_pdu)));
1714 tevent_req_done(req);
1718 subreq = get_complete_frag_send(state, state->ev, state->cli,
1719 &state->rhdr, &state->incoming_frag);
1720 if (tevent_req_nomem(subreq, req)) {
1723 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1726 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1727 prs_struct *reply_pdu)
1729 struct rpc_api_pipe_state *state = tevent_req_data(
1730 req, struct rpc_api_pipe_state);
1733 if (tevent_req_is_nterror(req, &status)) {
1737 *reply_pdu = state->incoming_pdu;
1738 reply_pdu->mem_ctx = mem_ctx;
1741 * Prevent state->incoming_pdu from being freed
1742 * when state is freed.
1744 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1745 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1747 return NT_STATUS_OK;
1750 /*******************************************************************
1751 ********************************************************************/
1753 static NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1754 enum dcerpc_AuthType auth_type,
1755 enum dcerpc_AuthLevel auth_level,
1756 uint8_t auth_pad_length,
1757 uint32_t auth_context_id,
1758 const DATA_BLOB *credentials,
1761 struct dcerpc_auth r;
1762 enum ndr_err_code ndr_err;
1764 r.auth_type = auth_type;
1765 r.auth_level = auth_level;
1766 r.auth_pad_length = auth_pad_length;
1767 r.auth_reserved = 0;
1768 r.auth_context_id = auth_context_id;
1769 r.credentials = *credentials;
1771 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1772 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1773 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1774 return ndr_map_error2ntstatus(ndr_err);
1777 if (DEBUGLEVEL >= 10) {
1778 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1781 return NT_STATUS_OK;
1784 /*******************************************************************
1785 Creates krb5 auth bind.
1786 ********************************************************************/
1788 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1789 enum dcerpc_AuthLevel auth_level,
1790 DATA_BLOB *auth_info)
1795 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1796 DATA_BLOB tkt = data_blob_null;
1797 DATA_BLOB tkt_wrapped = data_blob_null;
1799 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1800 a->service_principal ));
1802 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1804 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1805 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1808 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1810 a->service_principal,
1811 error_message(ret) ));
1813 data_blob_free(&tkt);
1814 return NT_STATUS_INVALID_PARAMETER;
1817 /* wrap that up in a nice GSS-API wrapping */
1818 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1820 data_blob_free(&tkt);
1822 status = dcerpc_push_dcerpc_auth(cli,
1823 DCERPC_AUTH_TYPE_KRB5,
1825 0, /* auth_pad_length */
1826 1, /* auth_context_id */
1829 if (!NT_STATUS_IS_OK(status)) {
1830 data_blob_free(&tkt_wrapped);
1834 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1835 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1837 return NT_STATUS_OK;
1839 return NT_STATUS_INVALID_PARAMETER;
1843 /*******************************************************************
1844 Creates SPNEGO NTLMSSP auth bind.
1845 ********************************************************************/
1847 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1848 enum dcerpc_AuthLevel auth_level,
1849 DATA_BLOB *auth_info)
1852 DATA_BLOB null_blob = data_blob_null;
1853 DATA_BLOB request = data_blob_null;
1854 DATA_BLOB spnego_msg = data_blob_null;
1856 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1857 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1861 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1862 data_blob_free(&request);
1866 /* Wrap this in SPNEGO. */
1867 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1869 data_blob_free(&request);
1871 status = dcerpc_push_dcerpc_auth(cli,
1872 DCERPC_AUTH_TYPE_SPNEGO,
1874 0, /* auth_pad_length */
1875 1, /* auth_context_id */
1878 if (!NT_STATUS_IS_OK(status)) {
1879 data_blob_free(&spnego_msg);
1883 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1884 dump_data(5, spnego_msg.data, spnego_msg.length);
1886 return NT_STATUS_OK;
1889 /*******************************************************************
1890 Creates NTLMSSP auth bind.
1891 ********************************************************************/
1893 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1894 enum dcerpc_AuthLevel auth_level,
1895 DATA_BLOB *auth_info)
1898 DATA_BLOB null_blob = data_blob_null;
1899 DATA_BLOB request = data_blob_null;
1901 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1902 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1906 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1907 data_blob_free(&request);
1911 status = dcerpc_push_dcerpc_auth(cli,
1912 DCERPC_AUTH_TYPE_NTLMSSP,
1914 0, /* auth_pad_length */
1915 1, /* auth_context_id */
1918 if (!NT_STATUS_IS_OK(status)) {
1919 data_blob_free(&request);
1923 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1924 dump_data(5, request.data, request.length);
1926 return NT_STATUS_OK;
1929 /*******************************************************************
1930 Creates schannel auth bind.
1931 ********************************************************************/
1933 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1934 enum dcerpc_AuthLevel auth_level,
1935 DATA_BLOB *auth_info)
1938 struct NL_AUTH_MESSAGE r;
1939 DATA_BLOB schannel_blob;
1941 /* Use lp_workgroup() if domain not specified */
1943 if (!cli->auth->domain || !cli->auth->domain[0]) {
1944 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1945 if (cli->auth->domain == NULL) {
1946 return NT_STATUS_NO_MEMORY;
1951 * Now marshall the data into the auth parse_struct.
1954 r.MessageType = NL_NEGOTIATE_REQUEST;
1955 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1956 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1957 r.oem_netbios_domain.a = cli->auth->domain;
1958 r.oem_netbios_computer.a = global_myname();
1960 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1961 if (!NT_STATUS_IS_OK(status)) {
1965 status = dcerpc_push_dcerpc_auth(cli,
1966 DCERPC_AUTH_TYPE_SCHANNEL,
1968 0, /* auth_pad_length */
1969 1, /* auth_context_id */
1972 if (!NT_STATUS_IS_OK(status)) {
1976 return NT_STATUS_OK;
1979 /*******************************************************************
1980 ********************************************************************/
1982 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1983 const struct ndr_syntax_id *abstract_syntax,
1984 const struct ndr_syntax_id *transfer_syntax,
1985 struct dcerpc_ctx_list **ctx_list_p)
1987 struct dcerpc_ctx_list *ctx_list;
1989 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1990 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1992 ctx_list[0].context_id = 0;
1993 ctx_list[0].num_transfer_syntaxes = 1;
1994 ctx_list[0].abstract_syntax = *abstract_syntax;
1995 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
1996 struct ndr_syntax_id,
1997 ctx_list[0].num_transfer_syntaxes);
1998 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1999 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
2001 *ctx_list_p = ctx_list;
2003 return NT_STATUS_OK;
2006 /*******************************************************************
2007 Creates the internals of a DCE/RPC bind request or alter context PDU.
2008 ********************************************************************/
2010 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2011 prs_struct *rpc_out,
2013 const struct ndr_syntax_id *abstract,
2014 const struct ndr_syntax_id *transfer,
2015 const DATA_BLOB *auth_info)
2017 uint16 auth_len = auth_info->length;
2018 uint16 frag_len = 0;
2020 union dcerpc_payload u;
2022 struct dcerpc_ctx_list *ctx_list;
2024 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2026 if (!NT_STATUS_IS_OK(status)) {
2030 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2031 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2032 u.bind.assoc_group_id = 0x0;
2033 u.bind.num_contexts = 1;
2034 u.bind.ctx_list = ctx_list;
2035 u.bind.auth_info = *auth_info;
2037 /* Start building the frag length. */
2038 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind) + auth_len;
2040 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2042 DCERPC_PFC_FLAG_FIRST |
2043 DCERPC_PFC_FLAG_LAST,
2045 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2049 if (!NT_STATUS_IS_OK(status)) {
2050 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2054 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2055 return NT_STATUS_NO_MEMORY;
2058 return NT_STATUS_OK;
2061 /*******************************************************************
2062 Creates a DCE/RPC bind request.
2063 ********************************************************************/
2065 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2066 prs_struct *rpc_out,
2068 const struct ndr_syntax_id *abstract,
2069 const struct ndr_syntax_id *transfer,
2070 enum pipe_auth_type auth_type,
2071 enum dcerpc_AuthLevel auth_level)
2073 DATA_BLOB auth_info = data_blob_null;
2074 NTSTATUS ret = NT_STATUS_OK;
2076 switch (auth_type) {
2077 case PIPE_AUTH_TYPE_SCHANNEL:
2078 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2079 if (!NT_STATUS_IS_OK(ret)) {
2084 case PIPE_AUTH_TYPE_NTLMSSP:
2085 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2086 if (!NT_STATUS_IS_OK(ret)) {
2091 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2092 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2093 if (!NT_STATUS_IS_OK(ret)) {
2098 case PIPE_AUTH_TYPE_KRB5:
2099 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2100 if (!NT_STATUS_IS_OK(ret)) {
2105 case PIPE_AUTH_TYPE_NONE:
2109 /* "Can't" happen. */
2110 return NT_STATUS_INVALID_INFO_CLASS;
2113 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2122 /*******************************************************************
2123 Create and add the NTLMSSP sign/seal auth header and data.
2124 ********************************************************************/
2126 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2127 uint32 ss_padding_len,
2128 prs_struct *outgoing_pdu)
2130 RPC_HDR_AUTH auth_info;
2132 DATA_BLOB auth_blob = data_blob_null;
2133 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2136 if (!cli->auth->a_u.ntlmssp_state) {
2137 return NT_STATUS_INVALID_PARAMETER;
2140 frame = talloc_stackframe();
2142 /* Init and marshall the auth header. */
2143 init_rpc_hdr_auth(&auth_info,
2144 map_pipe_auth_type_to_rpc_auth_type(
2145 cli->auth->auth_type),
2146 cli->auth->auth_level,
2148 1 /* context id. */);
2150 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2151 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2153 return NT_STATUS_NO_MEMORY;
2156 switch (cli->auth->auth_level) {
2157 case DCERPC_AUTH_LEVEL_PRIVACY:
2158 /* Data portion is encrypted. */
2159 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2161 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2163 (unsigned char *)prs_data_p(outgoing_pdu),
2164 (size_t)prs_offset(outgoing_pdu),
2166 if (!NT_STATUS_IS_OK(status)) {
2172 case DCERPC_AUTH_LEVEL_INTEGRITY:
2173 /* Data is signed. */
2174 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2176 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2178 (unsigned char *)prs_data_p(outgoing_pdu),
2179 (size_t)prs_offset(outgoing_pdu),
2181 if (!NT_STATUS_IS_OK(status)) {
2189 smb_panic("bad auth level");
2191 return NT_STATUS_INVALID_PARAMETER;
2194 /* Finally marshall the blob. */
2196 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2197 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2198 (unsigned int)NTLMSSP_SIG_SIZE));
2200 return NT_STATUS_NO_MEMORY;
2204 return NT_STATUS_OK;
2207 /*******************************************************************
2208 Create and add the schannel sign/seal auth header and data.
2209 ********************************************************************/
2211 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2212 uint32 ss_padding_len,
2213 prs_struct *outgoing_pdu)
2215 RPC_HDR_AUTH auth_info;
2216 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2217 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2218 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2223 return NT_STATUS_INVALID_PARAMETER;
2226 /* Init and marshall the auth header. */
2227 init_rpc_hdr_auth(&auth_info,
2228 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2229 cli->auth->auth_level,
2231 1 /* context id. */);
2233 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2234 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2235 return NT_STATUS_NO_MEMORY;
2238 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2241 switch (cli->auth->auth_level) {
2242 case DCERPC_AUTH_LEVEL_PRIVACY:
2243 status = netsec_outgoing_packet(sas,
2250 case DCERPC_AUTH_LEVEL_INTEGRITY:
2251 status = netsec_outgoing_packet(sas,
2259 status = NT_STATUS_INTERNAL_ERROR;
2263 if (!NT_STATUS_IS_OK(status)) {
2264 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2265 nt_errstr(status)));
2269 if (DEBUGLEVEL >= 10) {
2270 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2273 /* Finally marshall the blob. */
2274 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2275 return NT_STATUS_NO_MEMORY;
2278 return NT_STATUS_OK;
2281 /*******************************************************************
2282 Calculate how much data we're going to send in this packet, also
2283 work out any sign/seal padding length.
2284 ********************************************************************/
2286 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2290 uint32 *p_ss_padding)
2292 uint32 data_space, data_len;
2295 if ((data_left > 0) && (sys_random() % 2)) {
2296 data_left = MAX(data_left/2, 1);
2300 switch (cli->auth->auth_level) {
2301 case DCERPC_AUTH_LEVEL_NONE:
2302 case DCERPC_AUTH_LEVEL_CONNECT:
2303 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2304 data_len = MIN(data_space, data_left);
2307 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2310 case DCERPC_AUTH_LEVEL_INTEGRITY:
2311 case DCERPC_AUTH_LEVEL_PRIVACY:
2312 /* Treat the same for all authenticated rpc requests. */
2313 switch(cli->auth->auth_type) {
2314 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2315 case PIPE_AUTH_TYPE_NTLMSSP:
2316 *p_auth_len = NTLMSSP_SIG_SIZE;
2318 case PIPE_AUTH_TYPE_SCHANNEL:
2319 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2322 smb_panic("bad auth type");
2326 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2327 RPC_HDR_AUTH_LEN - *p_auth_len;
2329 data_len = MIN(data_space, data_left);
2331 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2332 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2334 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2335 data_len + *p_ss_padding + /* data plus padding. */
2336 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2340 smb_panic("bad auth level");
2346 /*******************************************************************
2348 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2349 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2350 and deals with signing/sealing details.
2351 ********************************************************************/
2353 struct rpc_api_pipe_req_state {
2354 struct event_context *ev;
2355 struct rpc_pipe_client *cli;
2358 prs_struct *req_data;
2359 uint32_t req_data_sent;
2360 prs_struct outgoing_frag;
2361 prs_struct reply_pdu;
2364 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2365 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2366 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2367 bool *is_last_frag);
2369 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2370 struct event_context *ev,
2371 struct rpc_pipe_client *cli,
2373 prs_struct *req_data)
2375 struct tevent_req *req, *subreq;
2376 struct rpc_api_pipe_req_state *state;
2380 req = tevent_req_create(mem_ctx, &state,
2381 struct rpc_api_pipe_req_state);
2387 state->op_num = op_num;
2388 state->req_data = req_data;
2389 state->req_data_sent = 0;
2390 state->call_id = get_rpc_call_id();
2392 if (cli->max_xmit_frag
2393 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2394 /* Server is screwed up ! */
2395 status = NT_STATUS_INVALID_PARAMETER;
2399 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2401 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2406 status = prepare_next_frag(state, &is_last_frag);
2407 if (!NT_STATUS_IS_OK(status)) {
2412 subreq = rpc_api_pipe_send(state, ev, state->cli,
2413 &state->outgoing_frag,
2414 DCERPC_PKT_RESPONSE);
2415 if (subreq == NULL) {
2418 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2420 subreq = rpc_write_send(
2421 state, ev, cli->transport,
2422 (uint8_t *)prs_data_p(&state->outgoing_frag),
2423 prs_offset(&state->outgoing_frag));
2424 if (subreq == NULL) {
2427 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2433 tevent_req_nterror(req, status);
2434 return tevent_req_post(req, ev);
2440 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2443 uint32_t data_sent_thistime;
2447 uint32_t ss_padding;
2449 char pad[8] = { 0, };
2451 union dcerpc_payload u;
2454 data_left = prs_offset(state->req_data) - state->req_data_sent;
2456 data_sent_thistime = calculate_data_len_tosend(
2457 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2459 if (state->req_data_sent == 0) {
2460 flags = DCERPC_PFC_FLAG_FIRST;
2463 if (data_sent_thistime == data_left) {
2464 flags |= DCERPC_PFC_FLAG_LAST;
2467 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2468 return NT_STATUS_NO_MEMORY;
2471 ZERO_STRUCT(u.request);
2473 u.request.alloc_hint = prs_offset(state->req_data);
2474 u.request.context_id = 0;
2475 u.request.opnum = state->op_num;
2477 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2485 if (!NT_STATUS_IS_OK(status)) {
2489 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2490 return NT_STATUS_NO_MEMORY;
2493 /* Copy in the data, plus any ss padding. */
2494 if (!prs_append_some_prs_data(&state->outgoing_frag,
2495 state->req_data, state->req_data_sent,
2496 data_sent_thistime)) {
2497 return NT_STATUS_NO_MEMORY;
2500 /* Copy the sign/seal padding data. */
2501 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2502 return NT_STATUS_NO_MEMORY;
2505 /* Generate any auth sign/seal and add the auth footer. */
2506 switch (state->cli->auth->auth_type) {
2507 case PIPE_AUTH_TYPE_NONE:
2508 status = NT_STATUS_OK;
2510 case PIPE_AUTH_TYPE_NTLMSSP:
2511 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2512 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2513 &state->outgoing_frag);
2515 case PIPE_AUTH_TYPE_SCHANNEL:
2516 status = add_schannel_auth_footer(state->cli, ss_padding,
2517 &state->outgoing_frag);
2520 status = NT_STATUS_INVALID_PARAMETER;
2524 state->req_data_sent += data_sent_thistime;
2525 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2530 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2532 struct tevent_req *req = tevent_req_callback_data(
2533 subreq, struct tevent_req);
2534 struct rpc_api_pipe_req_state *state = tevent_req_data(
2535 req, struct rpc_api_pipe_req_state);
2539 status = rpc_write_recv(subreq);
2540 TALLOC_FREE(subreq);
2541 if (!NT_STATUS_IS_OK(status)) {
2542 tevent_req_nterror(req, status);
2546 status = prepare_next_frag(state, &is_last_frag);
2547 if (!NT_STATUS_IS_OK(status)) {
2548 tevent_req_nterror(req, status);
2553 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2554 &state->outgoing_frag,
2555 DCERPC_PKT_RESPONSE);
2556 if (tevent_req_nomem(subreq, req)) {
2559 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2561 subreq = rpc_write_send(
2563 state->cli->transport,
2564 (uint8_t *)prs_data_p(&state->outgoing_frag),
2565 prs_offset(&state->outgoing_frag));
2566 if (tevent_req_nomem(subreq, req)) {
2569 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2574 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2576 struct tevent_req *req = tevent_req_callback_data(
2577 subreq, struct tevent_req);
2578 struct rpc_api_pipe_req_state *state = tevent_req_data(
2579 req, struct rpc_api_pipe_req_state);
2582 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2583 TALLOC_FREE(subreq);
2584 if (!NT_STATUS_IS_OK(status)) {
2585 tevent_req_nterror(req, status);
2588 tevent_req_done(req);
2591 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2592 prs_struct *reply_pdu)
2594 struct rpc_api_pipe_req_state *state = tevent_req_data(
2595 req, struct rpc_api_pipe_req_state);
2598 if (tevent_req_is_nterror(req, &status)) {
2600 * We always have to initialize to reply pdu, even if there is
2601 * none. The rpccli_* caller routines expect this.
2603 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2607 *reply_pdu = state->reply_pdu;
2608 reply_pdu->mem_ctx = mem_ctx;
2611 * Prevent state->req_pdu from being freed
2612 * when state is freed.
2614 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2615 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2617 return NT_STATUS_OK;
2621 /****************************************************************************
2622 Set the handle state.
2623 ****************************************************************************/
2625 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2626 const char *pipe_name, uint16 device_state)
2628 bool state_set = False;
2630 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2631 char *rparam = NULL;
2633 uint32 rparam_len, rdata_len;
2635 if (pipe_name == NULL)
2638 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2639 cli->fnum, pipe_name, device_state));
2641 /* create parameters: device state */
2642 SSVAL(param, 0, device_state);
2644 /* create setup parameters. */
2646 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2648 /* send the data on \PIPE\ */
2649 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2650 setup, 2, 0, /* setup, length, max */
2651 param, 2, 0, /* param, length, max */
2652 NULL, 0, 1024, /* data, length, max */
2653 &rparam, &rparam_len, /* return param, length */
2654 &rdata, &rdata_len)) /* return data, length */
2656 DEBUG(5, ("Set Handle state: return OK\n"));
2667 /****************************************************************************
2668 Check the rpc bind acknowledge response.
2669 ****************************************************************************/
2671 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2672 const struct ndr_syntax_id *transfer)
2674 if ( hdr_ba->addr.len == 0) {
2675 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2678 /* check the transfer syntax */
2679 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2680 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2681 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2685 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2686 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2687 hdr_ba->res.num_results, hdr_ba->res.reason));
2690 DEBUG(5,("check_bind_response: accepted!\n"));
2694 /*******************************************************************
2695 Creates a DCE/RPC bind authentication response.
2696 This is the packet that is sent back to the server once we
2697 have received a BIND-ACK, to finish the third leg of
2698 the authentication handshake.
2699 ********************************************************************/
2701 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2703 enum pipe_auth_type auth_type,
2704 enum dcerpc_AuthLevel auth_level,
2705 DATA_BLOB *pauth_blob,
2706 prs_struct *rpc_out)
2709 RPC_HDR_AUTH hdr_auth;
2712 /* Create the request RPC_HDR */
2713 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2714 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2715 pauth_blob->length );
2718 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2719 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2720 return NT_STATUS_NO_MEMORY;
2724 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2725 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2728 /* 4 bytes padding. */
2729 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2730 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2731 return NT_STATUS_NO_MEMORY;
2734 /* Create the request RPC_HDR_AUTHA */
2735 init_rpc_hdr_auth(&hdr_auth,
2736 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2739 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2740 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2741 return NT_STATUS_NO_MEMORY;
2745 * Append the auth data to the outgoing buffer.
2748 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2749 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2750 return NT_STATUS_NO_MEMORY;
2753 return NT_STATUS_OK;
2756 /*******************************************************************
2757 Creates a DCE/RPC bind alter context authentication request which
2758 may contain a spnego auth blobl
2759 ********************************************************************/
2761 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2762 const struct ndr_syntax_id *abstract,
2763 const struct ndr_syntax_id *transfer,
2764 enum dcerpc_AuthLevel auth_level,
2765 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2766 prs_struct *rpc_out)
2768 DATA_BLOB auth_info;
2771 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2772 DCERPC_AUTH_TYPE_SPNEGO,
2774 0, /* auth_pad_length */
2775 1, /* auth_context_id */
2778 if (!NT_STATUS_IS_OK(status)) {
2783 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2789 if (!NT_STATUS_IS_OK(status)) {
2796 /****************************************************************************
2798 ****************************************************************************/
2800 struct rpc_pipe_bind_state {
2801 struct event_context *ev;
2802 struct rpc_pipe_client *cli;
2804 uint32_t rpc_call_id;
2807 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2808 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2809 struct rpc_pipe_bind_state *state,
2810 struct rpc_hdr_info *phdr,
2811 prs_struct *reply_pdu);
2812 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2813 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2814 struct rpc_pipe_bind_state *state,
2815 struct rpc_hdr_info *phdr,
2816 prs_struct *reply_pdu);
2817 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2819 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2820 struct event_context *ev,
2821 struct rpc_pipe_client *cli,
2822 struct cli_pipe_auth_data *auth)
2824 struct tevent_req *req, *subreq;
2825 struct rpc_pipe_bind_state *state;
2828 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2833 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2834 rpccli_pipe_txt(talloc_tos(), cli),
2835 (unsigned int)auth->auth_type,
2836 (unsigned int)auth->auth_level ));
2840 state->rpc_call_id = get_rpc_call_id();
2842 prs_init_empty(&state->rpc_out, state, MARSHALL);
2844 cli->auth = talloc_move(cli, &auth);
2846 /* Marshall the outgoing data. */
2847 status = create_rpc_bind_req(cli, &state->rpc_out,
2849 &cli->abstract_syntax,
2850 &cli->transfer_syntax,
2851 cli->auth->auth_type,
2852 cli->auth->auth_level);
2854 if (!NT_STATUS_IS_OK(status)) {
2858 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2859 DCERPC_PKT_BIND_ACK);
2860 if (subreq == NULL) {
2863 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2867 tevent_req_nterror(req, status);
2868 return tevent_req_post(req, ev);
2874 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2876 struct tevent_req *req = tevent_req_callback_data(
2877 subreq, struct tevent_req);
2878 struct rpc_pipe_bind_state *state = tevent_req_data(
2879 req, struct rpc_pipe_bind_state);
2880 prs_struct reply_pdu;
2881 struct rpc_hdr_info hdr;
2882 struct rpc_hdr_ba_info hdr_ba;
2885 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2886 TALLOC_FREE(subreq);
2887 if (!NT_STATUS_IS_OK(status)) {
2888 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2889 rpccli_pipe_txt(talloc_tos(), state->cli),
2890 nt_errstr(status)));
2891 tevent_req_nterror(req, status);
2895 /* Unmarshall the RPC header */
2896 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2897 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2898 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2902 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2903 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2905 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2909 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2910 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2911 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2915 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2916 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2919 * For authenticated binds we may need to do 3 or 4 leg binds.
2922 switch(state->cli->auth->auth_type) {
2924 case PIPE_AUTH_TYPE_NONE:
2925 case PIPE_AUTH_TYPE_SCHANNEL:
2926 /* Bind complete. */
2927 tevent_req_done(req);
2930 case PIPE_AUTH_TYPE_NTLMSSP:
2931 /* Need to send AUTH3 packet - no reply. */
2932 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2934 if (!NT_STATUS_IS_OK(status)) {
2935 tevent_req_nterror(req, status);
2939 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2940 /* Need to send alter context request and reply. */
2941 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2943 if (!NT_STATUS_IS_OK(status)) {
2944 tevent_req_nterror(req, status);
2948 case PIPE_AUTH_TYPE_KRB5:
2952 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2953 (unsigned int)state->cli->auth->auth_type));
2954 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2958 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2959 struct rpc_pipe_bind_state *state,
2960 struct rpc_hdr_info *phdr,
2961 prs_struct *reply_pdu)
2963 DATA_BLOB server_response = data_blob_null;
2964 DATA_BLOB client_reply = data_blob_null;
2965 struct rpc_hdr_auth_info hdr_auth;
2966 struct tevent_req *subreq;
2969 if ((phdr->auth_len == 0)
2970 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2971 return NT_STATUS_INVALID_PARAMETER;
2974 if (!prs_set_offset(
2976 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2977 return NT_STATUS_INVALID_PARAMETER;
2980 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2981 return NT_STATUS_INVALID_PARAMETER;
2984 /* TODO - check auth_type/auth_level match. */
2986 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2987 prs_copy_data_out((char *)server_response.data, reply_pdu,
2990 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2991 server_response, &client_reply);
2993 if (!NT_STATUS_IS_OK(status)) {
2994 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2995 "blob failed: %s.\n", nt_errstr(status)));
2999 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
3001 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
3002 state->cli->auth->auth_type,
3003 state->cli->auth->auth_level,
3004 &client_reply, &state->rpc_out);
3005 data_blob_free(&client_reply);
3007 if (!NT_STATUS_IS_OK(status)) {
3011 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3012 (uint8_t *)prs_data_p(&state->rpc_out),
3013 prs_offset(&state->rpc_out));
3014 if (subreq == NULL) {
3015 return NT_STATUS_NO_MEMORY;
3017 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3018 return NT_STATUS_OK;
3021 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3023 struct tevent_req *req = tevent_req_callback_data(
3024 subreq, struct tevent_req);
3027 status = rpc_write_recv(subreq);
3028 TALLOC_FREE(subreq);
3029 if (!NT_STATUS_IS_OK(status)) {
3030 tevent_req_nterror(req, status);
3033 tevent_req_done(req);
3036 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3037 struct rpc_pipe_bind_state *state,
3038 struct rpc_hdr_info *phdr,
3039 prs_struct *reply_pdu)
3041 DATA_BLOB server_spnego_response = data_blob_null;
3042 DATA_BLOB server_ntlm_response = data_blob_null;
3043 DATA_BLOB client_reply = data_blob_null;
3044 DATA_BLOB tmp_blob = data_blob_null;
3045 RPC_HDR_AUTH hdr_auth;
3046 struct tevent_req *subreq;
3049 if ((phdr->auth_len == 0)
3050 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
3051 return NT_STATUS_INVALID_PARAMETER;
3054 /* Process the returned NTLMSSP blob first. */
3055 if (!prs_set_offset(
3057 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
3058 return NT_STATUS_INVALID_PARAMETER;
3061 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3062 return NT_STATUS_INVALID_PARAMETER;
3065 server_spnego_response = data_blob(NULL, phdr->auth_len);
3066 prs_copy_data_out((char *)server_spnego_response.data,
3067 reply_pdu, phdr->auth_len);
3070 * The server might give us back two challenges - tmp_blob is for the
3073 if (!spnego_parse_challenge(server_spnego_response,
3074 &server_ntlm_response, &tmp_blob)) {
3075 data_blob_free(&server_spnego_response);
3076 data_blob_free(&server_ntlm_response);
3077 data_blob_free(&tmp_blob);
3078 return NT_STATUS_INVALID_PARAMETER;
3081 /* We're finished with the server spnego response and the tmp_blob. */
3082 data_blob_free(&server_spnego_response);
3083 data_blob_free(&tmp_blob);
3085 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3086 server_ntlm_response, &client_reply);
3088 /* Finished with the server_ntlm response */
3089 data_blob_free(&server_ntlm_response);
3091 if (!NT_STATUS_IS_OK(status)) {
3092 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3093 "using server blob failed.\n"));
3094 data_blob_free(&client_reply);
3098 /* SPNEGO wrap the client reply. */
3099 tmp_blob = spnego_gen_auth(client_reply);
3100 data_blob_free(&client_reply);
3101 client_reply = tmp_blob;
3102 tmp_blob = data_blob_null;
3104 /* Now prepare the alter context pdu. */
3105 prs_init_empty(&state->rpc_out, state, MARSHALL);
3107 status = create_rpc_alter_context(state->rpc_call_id,
3108 &state->cli->abstract_syntax,
3109 &state->cli->transfer_syntax,
3110 state->cli->auth->auth_level,
3113 data_blob_free(&client_reply);
3115 if (!NT_STATUS_IS_OK(status)) {
3119 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3120 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3121 if (subreq == NULL) {
3122 return NT_STATUS_NO_MEMORY;
3124 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3125 return NT_STATUS_OK;
3128 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3130 struct tevent_req *req = tevent_req_callback_data(
3131 subreq, struct tevent_req);
3132 struct rpc_pipe_bind_state *state = tevent_req_data(
3133 req, struct rpc_pipe_bind_state);
3134 DATA_BLOB server_spnego_response = data_blob_null;
3135 DATA_BLOB tmp_blob = data_blob_null;
3136 prs_struct reply_pdu;
3137 struct rpc_hdr_info hdr;
3138 struct rpc_hdr_auth_info hdr_auth;
3141 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3142 TALLOC_FREE(subreq);
3143 if (!NT_STATUS_IS_OK(status)) {
3144 tevent_req_nterror(req, status);
3148 /* Get the auth blob from the reply. */
3149 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3150 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3151 "unmarshall RPC_HDR.\n"));
3152 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3156 if (!prs_set_offset(
3158 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3159 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3163 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3164 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3168 server_spnego_response = data_blob(NULL, hdr.auth_len);
3169 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3172 /* Check we got a valid auth response. */
3173 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3174 OID_NTLMSSP, &tmp_blob)) {
3175 data_blob_free(&server_spnego_response);
3176 data_blob_free(&tmp_blob);
3177 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3181 data_blob_free(&server_spnego_response);
3182 data_blob_free(&tmp_blob);
3184 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3185 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3186 tevent_req_done(req);
3189 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3191 return tevent_req_simple_recv_ntstatus(req);
3194 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3195 struct cli_pipe_auth_data *auth)
3197 TALLOC_CTX *frame = talloc_stackframe();
3198 struct event_context *ev;
3199 struct tevent_req *req;
3200 NTSTATUS status = NT_STATUS_OK;
3202 ev = event_context_init(frame);
3204 status = NT_STATUS_NO_MEMORY;
3208 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3210 status = NT_STATUS_NO_MEMORY;
3214 if (!tevent_req_poll(req, ev)) {
3215 status = map_nt_error_from_unix(errno);
3219 status = rpc_pipe_bind_recv(req);
3225 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3227 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3228 unsigned int timeout)
3232 if (rpc_cli->transport == NULL) {
3233 return RPCCLI_DEFAULT_TIMEOUT;
3236 if (rpc_cli->transport->set_timeout == NULL) {
3237 return RPCCLI_DEFAULT_TIMEOUT;
3240 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3242 return RPCCLI_DEFAULT_TIMEOUT;
3248 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3250 if (rpc_cli == NULL) {
3254 if (rpc_cli->transport == NULL) {
3258 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3261 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3263 struct cli_state *cli;
3265 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3266 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3267 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3271 cli = rpc_pipe_np_smb_conn(rpc_cli);
3275 E_md4hash(cli->password ? cli->password : "", nt_hash);
3279 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3280 struct cli_pipe_auth_data **presult)
3282 struct cli_pipe_auth_data *result;
3284 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3285 if (result == NULL) {
3286 return NT_STATUS_NO_MEMORY;
3289 result->auth_type = PIPE_AUTH_TYPE_NONE;
3290 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3292 result->user_name = talloc_strdup(result, "");
3293 result->domain = talloc_strdup(result, "");
3294 if ((result->user_name == NULL) || (result->domain == NULL)) {
3295 TALLOC_FREE(result);
3296 return NT_STATUS_NO_MEMORY;
3300 return NT_STATUS_OK;
3303 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3305 ntlmssp_end(&auth->a_u.ntlmssp_state);
3309 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3310 enum pipe_auth_type auth_type,
3311 enum dcerpc_AuthLevel auth_level,
3313 const char *username,
3314 const char *password,
3315 struct cli_pipe_auth_data **presult)
3317 struct cli_pipe_auth_data *result;
3320 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3321 if (result == NULL) {
3322 return NT_STATUS_NO_MEMORY;
3325 result->auth_type = auth_type;
3326 result->auth_level = auth_level;
3328 result->user_name = talloc_strdup(result, username);
3329 result->domain = talloc_strdup(result, domain);
3330 if ((result->user_name == NULL) || (result->domain == NULL)) {
3331 status = NT_STATUS_NO_MEMORY;
3335 status = ntlmssp_client_start(NULL,
3338 lp_client_ntlmv2_auth(),
3339 &result->a_u.ntlmssp_state);
3340 if (!NT_STATUS_IS_OK(status)) {
3344 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3346 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3347 if (!NT_STATUS_IS_OK(status)) {
3351 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3352 if (!NT_STATUS_IS_OK(status)) {
3356 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3357 if (!NT_STATUS_IS_OK(status)) {
3362 * Turn off sign+seal to allow selected auth level to turn it back on.
3364 result->a_u.ntlmssp_state->neg_flags &=
3365 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3367 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3368 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3369 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3370 result->a_u.ntlmssp_state->neg_flags
3371 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3375 return NT_STATUS_OK;
3378 TALLOC_FREE(result);
3382 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3383 enum dcerpc_AuthLevel auth_level,
3384 struct netlogon_creds_CredentialState *creds,
3385 struct cli_pipe_auth_data **presult)
3387 struct cli_pipe_auth_data *result;
3389 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3390 if (result == NULL) {
3391 return NT_STATUS_NO_MEMORY;
3394 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3395 result->auth_level = auth_level;
3397 result->user_name = talloc_strdup(result, "");
3398 result->domain = talloc_strdup(result, domain);
3399 if ((result->user_name == NULL) || (result->domain == NULL)) {
3403 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3404 if (result->a_u.schannel_auth == NULL) {
3408 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3409 result->a_u.schannel_auth->seq_num = 0;
3410 result->a_u.schannel_auth->initiator = true;
3411 result->a_u.schannel_auth->creds = creds;
3414 return NT_STATUS_OK;
3417 TALLOC_FREE(result);
3418 return NT_STATUS_NO_MEMORY;
3422 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3424 data_blob_free(&auth->session_key);
3429 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3430 enum dcerpc_AuthLevel auth_level,
3431 const char *service_princ,
3432 const char *username,
3433 const char *password,
3434 struct cli_pipe_auth_data **presult)
3437 struct cli_pipe_auth_data *result;
3439 if ((username != NULL) && (password != NULL)) {
3440 int ret = kerberos_kinit_password(username, password, 0, NULL);
3442 return NT_STATUS_ACCESS_DENIED;
3446 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3447 if (result == NULL) {
3448 return NT_STATUS_NO_MEMORY;
3451 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3452 result->auth_level = auth_level;
3455 * Username / domain need fixing!
3457 result->user_name = talloc_strdup(result, "");
3458 result->domain = talloc_strdup(result, "");
3459 if ((result->user_name == NULL) || (result->domain == NULL)) {
3463 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3464 result, struct kerberos_auth_struct);
3465 if (result->a_u.kerberos_auth == NULL) {
3468 talloc_set_destructor(result->a_u.kerberos_auth,
3469 cli_auth_kerberos_data_destructor);
3471 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3472 result, service_princ);
3473 if (result->a_u.kerberos_auth->service_principal == NULL) {
3478 return NT_STATUS_OK;
3481 TALLOC_FREE(result);
3482 return NT_STATUS_NO_MEMORY;
3484 return NT_STATUS_NOT_SUPPORTED;
3489 * Create an rpc pipe client struct, connecting to a tcp port.
3491 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3493 const struct ndr_syntax_id *abstract_syntax,
3494 struct rpc_pipe_client **presult)
3496 struct rpc_pipe_client *result;
3497 struct sockaddr_storage addr;
3501 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3502 if (result == NULL) {
3503 return NT_STATUS_NO_MEMORY;
3506 result->abstract_syntax = *abstract_syntax;
3507 result->transfer_syntax = ndr_transfer_syntax;
3508 result->dispatch = cli_do_rpc_ndr;
3509 result->dispatch_send = cli_do_rpc_ndr_send;
3510 result->dispatch_recv = cli_do_rpc_ndr_recv;
3512 result->desthost = talloc_strdup(result, host);
3513 result->srv_name_slash = talloc_asprintf_strupper_m(
3514 result, "\\\\%s", result->desthost);
3515 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3516 status = NT_STATUS_NO_MEMORY;
3520 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3521 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3523 if (!resolve_name(host, &addr, 0, false)) {
3524 status = NT_STATUS_NOT_FOUND;
3528 status = open_socket_out(&addr, port, 60, &fd);
3529 if (!NT_STATUS_IS_OK(status)) {
3532 set_socket_options(fd, lp_socket_options());
3534 status = rpc_transport_sock_init(result, fd, &result->transport);
3535 if (!NT_STATUS_IS_OK(status)) {
3540 result->transport->transport = NCACN_IP_TCP;
3543 return NT_STATUS_OK;
3546 TALLOC_FREE(result);
3551 * Determine the tcp port on which a dcerpc interface is listening
3552 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3555 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3556 const struct ndr_syntax_id *abstract_syntax,
3560 struct rpc_pipe_client *epm_pipe = NULL;
3561 struct cli_pipe_auth_data *auth = NULL;
3562 struct dcerpc_binding *map_binding = NULL;
3563 struct dcerpc_binding *res_binding = NULL;
3564 struct epm_twr_t *map_tower = NULL;
3565 struct epm_twr_t *res_towers = NULL;
3566 struct policy_handle *entry_handle = NULL;
3567 uint32_t num_towers = 0;
3568 uint32_t max_towers = 1;
3569 struct epm_twr_p_t towers;
3570 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3572 if (pport == NULL) {
3573 status = NT_STATUS_INVALID_PARAMETER;
3577 /* open the connection to the endpoint mapper */
3578 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3579 &ndr_table_epmapper.syntax_id,
3582 if (!NT_STATUS_IS_OK(status)) {
3586 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3587 if (!NT_STATUS_IS_OK(status)) {
3591 status = rpc_pipe_bind(epm_pipe, auth);
3592 if (!NT_STATUS_IS_OK(status)) {
3596 /* create tower for asking the epmapper */
3598 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3599 if (map_binding == NULL) {
3600 status = NT_STATUS_NO_MEMORY;
3604 map_binding->transport = NCACN_IP_TCP;
3605 map_binding->object = *abstract_syntax;
3606 map_binding->host = host; /* needed? */
3607 map_binding->endpoint = "0"; /* correct? needed? */
3609 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3610 if (map_tower == NULL) {
3611 status = NT_STATUS_NO_MEMORY;
3615 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3616 &(map_tower->tower));
3617 if (!NT_STATUS_IS_OK(status)) {
3621 /* allocate further parameters for the epm_Map call */
3623 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3624 if (res_towers == NULL) {
3625 status = NT_STATUS_NO_MEMORY;
3628 towers.twr = res_towers;
3630 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3631 if (entry_handle == NULL) {
3632 status = NT_STATUS_NO_MEMORY;
3636 /* ask the endpoint mapper for the port */
3638 status = rpccli_epm_Map(epm_pipe,
3640 CONST_DISCARD(struct GUID *,
3641 &(abstract_syntax->uuid)),
3648 if (!NT_STATUS_IS_OK(status)) {
3652 if (num_towers != 1) {
3653 status = NT_STATUS_UNSUCCESSFUL;
3657 /* extract the port from the answer */
3659 status = dcerpc_binding_from_tower(tmp_ctx,
3660 &(towers.twr->tower),
3662 if (!NT_STATUS_IS_OK(status)) {
3666 /* are further checks here necessary? */
3667 if (res_binding->transport != NCACN_IP_TCP) {
3668 status = NT_STATUS_UNSUCCESSFUL;
3672 *pport = (uint16_t)atoi(res_binding->endpoint);
3675 TALLOC_FREE(tmp_ctx);
3680 * Create a rpc pipe client struct, connecting to a host via tcp.
3681 * The port is determined by asking the endpoint mapper on the given
3684 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3685 const struct ndr_syntax_id *abstract_syntax,
3686 struct rpc_pipe_client **presult)
3691 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3692 if (!NT_STATUS_IS_OK(status)) {
3696 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3697 abstract_syntax, presult);
3700 /********************************************************************
3701 Create a rpc pipe client struct, connecting to a unix domain socket
3702 ********************************************************************/
3703 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3704 const struct ndr_syntax_id *abstract_syntax,
3705 struct rpc_pipe_client **presult)
3707 struct rpc_pipe_client *result;
3708 struct sockaddr_un addr;
3712 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3713 if (result == NULL) {
3714 return NT_STATUS_NO_MEMORY;
3717 result->abstract_syntax = *abstract_syntax;
3718 result->transfer_syntax = ndr_transfer_syntax;
3719 result->dispatch = cli_do_rpc_ndr;
3720 result->dispatch_send = cli_do_rpc_ndr_send;
3721 result->dispatch_recv = cli_do_rpc_ndr_recv;
3723 result->desthost = get_myname(result);
3724 result->srv_name_slash = talloc_asprintf_strupper_m(
3725 result, "\\\\%s", result->desthost);
3726 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3727 status = NT_STATUS_NO_MEMORY;
3731 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3732 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3734 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3736 status = map_nt_error_from_unix(errno);
3741 addr.sun_family = AF_UNIX;
3742 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3744 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3745 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3748 return map_nt_error_from_unix(errno);
3751 status = rpc_transport_sock_init(result, fd, &result->transport);
3752 if (!NT_STATUS_IS_OK(status)) {
3757 result->transport->transport = NCALRPC;
3760 return NT_STATUS_OK;
3763 TALLOC_FREE(result);
3767 struct rpc_pipe_client_np_ref {
3768 struct cli_state *cli;
3769 struct rpc_pipe_client *pipe;
3772 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3774 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3778 /****************************************************************************
3779 Open a named pipe over SMB to a remote server.
3781 * CAVEAT CALLER OF THIS FUNCTION:
3782 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3783 * so be sure that this function is called AFTER any structure (vs pointer)
3784 * assignment of the cli. In particular, libsmbclient does structure
3785 * assignments of cli, which invalidates the data in the returned
3786 * rpc_pipe_client if this function is called before the structure assignment
3789 ****************************************************************************/
3791 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3792 const struct ndr_syntax_id *abstract_syntax,
3793 struct rpc_pipe_client **presult)
3795 struct rpc_pipe_client *result;
3797 struct rpc_pipe_client_np_ref *np_ref;
3799 /* sanity check to protect against crashes */
3802 return NT_STATUS_INVALID_HANDLE;
3805 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3806 if (result == NULL) {
3807 return NT_STATUS_NO_MEMORY;
3810 result->abstract_syntax = *abstract_syntax;
3811 result->transfer_syntax = ndr_transfer_syntax;
3812 result->dispatch = cli_do_rpc_ndr;
3813 result->dispatch_send = cli_do_rpc_ndr_send;
3814 result->dispatch_recv = cli_do_rpc_ndr_recv;
3815 result->desthost = talloc_strdup(result, cli->desthost);
3816 result->srv_name_slash = talloc_asprintf_strupper_m(
3817 result, "\\\\%s", result->desthost);
3819 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3820 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3822 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3823 TALLOC_FREE(result);
3824 return NT_STATUS_NO_MEMORY;
3827 status = rpc_transport_np_init(result, cli, abstract_syntax,
3828 &result->transport);
3829 if (!NT_STATUS_IS_OK(status)) {
3830 TALLOC_FREE(result);
3834 result->transport->transport = NCACN_NP;
3836 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3837 if (np_ref == NULL) {
3838 TALLOC_FREE(result);
3839 return NT_STATUS_NO_MEMORY;
3842 np_ref->pipe = result;
3844 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3845 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3848 return NT_STATUS_OK;
3851 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3852 struct rpc_cli_smbd_conn *conn,
3853 const struct ndr_syntax_id *syntax,
3854 struct rpc_pipe_client **presult)
3856 struct rpc_pipe_client *result;
3857 struct cli_pipe_auth_data *auth;
3860 result = talloc(mem_ctx, struct rpc_pipe_client);
3861 if (result == NULL) {
3862 return NT_STATUS_NO_MEMORY;
3864 result->abstract_syntax = *syntax;
3865 result->transfer_syntax = ndr_transfer_syntax;
3866 result->dispatch = cli_do_rpc_ndr;
3867 result->dispatch_send = cli_do_rpc_ndr_send;
3868 result->dispatch_recv = cli_do_rpc_ndr_recv;
3869 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3870 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3872 result->desthost = talloc_strdup(result, global_myname());
3873 result->srv_name_slash = talloc_asprintf_strupper_m(
3874 result, "\\\\%s", global_myname());
3875 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3876 TALLOC_FREE(result);
3877 return NT_STATUS_NO_MEMORY;
3880 status = rpc_transport_smbd_init(result, conn, syntax,
3881 &result->transport);
3882 if (!NT_STATUS_IS_OK(status)) {
3883 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3884 nt_errstr(status)));
3885 TALLOC_FREE(result);
3889 status = rpccli_anon_bind_data(result, &auth);
3890 if (!NT_STATUS_IS_OK(status)) {
3891 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3892 nt_errstr(status)));
3893 TALLOC_FREE(result);
3897 status = rpc_pipe_bind(result, auth);
3898 if (!NT_STATUS_IS_OK(status)) {
3899 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3900 TALLOC_FREE(result);
3904 result->transport->transport = NCACN_INTERNAL;
3907 return NT_STATUS_OK;
3910 /****************************************************************************
3911 Open a pipe to a remote server.
3912 ****************************************************************************/
3914 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3915 enum dcerpc_transport_t transport,
3916 const struct ndr_syntax_id *interface,
3917 struct rpc_pipe_client **presult)
3919 switch (transport) {
3921 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3924 return rpc_pipe_open_np(cli, interface, presult);
3926 return NT_STATUS_NOT_IMPLEMENTED;
3930 /****************************************************************************
3931 Open a named pipe to an SMB server and bind anonymously.
3932 ****************************************************************************/
3934 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3935 enum dcerpc_transport_t transport,
3936 const struct ndr_syntax_id *interface,
3937 struct rpc_pipe_client **presult)
3939 struct rpc_pipe_client *result;
3940 struct cli_pipe_auth_data *auth;
3943 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3944 if (!NT_STATUS_IS_OK(status)) {
3948 status = rpccli_anon_bind_data(result, &auth);
3949 if (!NT_STATUS_IS_OK(status)) {
3950 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3951 nt_errstr(status)));
3952 TALLOC_FREE(result);
3957 * This is a bit of an abstraction violation due to the fact that an
3958 * anonymous bind on an authenticated SMB inherits the user/domain
3959 * from the enclosing SMB creds
3962 TALLOC_FREE(auth->user_name);
3963 TALLOC_FREE(auth->domain);
3965 auth->user_name = talloc_strdup(auth, cli->user_name);
3966 auth->domain = talloc_strdup(auth, cli->domain);
3967 auth->user_session_key = data_blob_talloc(auth,
3968 cli->user_session_key.data,
3969 cli->user_session_key.length);
3971 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3972 TALLOC_FREE(result);
3973 return NT_STATUS_NO_MEMORY;
3976 status = rpc_pipe_bind(result, auth);
3977 if (!NT_STATUS_IS_OK(status)) {
3979 if (ndr_syntax_id_equal(interface,
3980 &ndr_table_dssetup.syntax_id)) {
3981 /* non AD domains just don't have this pipe, avoid
3982 * level 0 statement in that case - gd */
3985 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3986 "%s failed with error %s\n",
3987 get_pipe_name_from_syntax(talloc_tos(), interface),
3988 nt_errstr(status) ));
3989 TALLOC_FREE(result);
3993 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3994 "%s and bound anonymously.\n",
3995 get_pipe_name_from_syntax(talloc_tos(), interface),
3999 return NT_STATUS_OK;
4002 /****************************************************************************
4003 ****************************************************************************/
4005 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4006 const struct ndr_syntax_id *interface,
4007 struct rpc_pipe_client **presult)
4009 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4010 interface, presult);
4013 /****************************************************************************
4014 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4015 ****************************************************************************/
4017 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4018 const struct ndr_syntax_id *interface,
4019 enum dcerpc_transport_t transport,
4020 enum pipe_auth_type auth_type,
4021 enum dcerpc_AuthLevel auth_level,
4023 const char *username,
4024 const char *password,
4025 struct rpc_pipe_client **presult)
4027 struct rpc_pipe_client *result;
4028 struct cli_pipe_auth_data *auth;
4031 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4032 if (!NT_STATUS_IS_OK(status)) {
4036 status = rpccli_ntlmssp_bind_data(
4037 result, auth_type, auth_level, domain, username,
4039 if (!NT_STATUS_IS_OK(status)) {
4040 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4041 nt_errstr(status)));
4045 status = rpc_pipe_bind(result, auth);
4046 if (!NT_STATUS_IS_OK(status)) {
4047 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4048 nt_errstr(status) ));
4052 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4053 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4054 get_pipe_name_from_syntax(talloc_tos(), interface),
4055 cli->desthost, domain, username ));
4058 return NT_STATUS_OK;
4062 TALLOC_FREE(result);
4066 /****************************************************************************
4068 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4069 ****************************************************************************/
4071 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4072 const struct ndr_syntax_id *interface,
4073 enum dcerpc_transport_t transport,
4074 enum dcerpc_AuthLevel auth_level,
4076 const char *username,
4077 const char *password,
4078 struct rpc_pipe_client **presult)
4080 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4083 PIPE_AUTH_TYPE_NTLMSSP,
4091 /****************************************************************************
4093 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4094 ****************************************************************************/
4096 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4097 const struct ndr_syntax_id *interface,
4098 enum dcerpc_transport_t transport,
4099 enum dcerpc_AuthLevel auth_level,
4101 const char *username,
4102 const char *password,
4103 struct rpc_pipe_client **presult)
4105 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4108 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4116 /****************************************************************************
4117 Get a the schannel session key out of an already opened netlogon pipe.
4118 ****************************************************************************/
4119 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4120 struct cli_state *cli,
4124 enum netr_SchannelType sec_chan_type = 0;
4125 unsigned char machine_pwd[16];
4126 const char *machine_account;
4129 /* Get the machine account credentials from secrets.tdb. */
4130 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4133 DEBUG(0, ("get_schannel_session_key: could not fetch "
4134 "trust account password for domain '%s'\n",
4136 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4139 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4140 cli->desthost, /* server name */
4141 domain, /* domain */
4142 global_myname(), /* client name */
4143 machine_account, /* machine account name */
4148 if (!NT_STATUS_IS_OK(status)) {
4149 DEBUG(3, ("get_schannel_session_key_common: "
4150 "rpccli_netlogon_setup_creds failed with result %s "
4151 "to server %s, domain %s, machine account %s.\n",
4152 nt_errstr(status), cli->desthost, domain,
4157 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4158 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4160 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4163 return NT_STATUS_OK;;
4166 /****************************************************************************
4167 Open a netlogon pipe and get the schannel session key.
4168 Now exposed to external callers.
4169 ****************************************************************************/
4172 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4175 struct rpc_pipe_client **presult)
4177 struct rpc_pipe_client *netlogon_pipe = NULL;
4180 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4182 if (!NT_STATUS_IS_OK(status)) {
4186 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4188 if (!NT_STATUS_IS_OK(status)) {
4189 TALLOC_FREE(netlogon_pipe);
4193 *presult = netlogon_pipe;
4194 return NT_STATUS_OK;
4197 /****************************************************************************
4199 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4200 using session_key. sign and seal.
4202 The *pdc will be stolen onto this new pipe
4203 ****************************************************************************/
4205 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4206 const struct ndr_syntax_id *interface,
4207 enum dcerpc_transport_t transport,
4208 enum dcerpc_AuthLevel auth_level,
4210 struct netlogon_creds_CredentialState **pdc,
4211 struct rpc_pipe_client **presult)
4213 struct rpc_pipe_client *result;
4214 struct cli_pipe_auth_data *auth;
4217 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4218 if (!NT_STATUS_IS_OK(status)) {
4222 status = rpccli_schannel_bind_data(result, domain, auth_level,
4224 if (!NT_STATUS_IS_OK(status)) {
4225 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4226 nt_errstr(status)));
4227 TALLOC_FREE(result);
4231 status = rpc_pipe_bind(result, auth);
4232 if (!NT_STATUS_IS_OK(status)) {
4233 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4234 "cli_rpc_pipe_bind failed with error %s\n",
4235 nt_errstr(status) ));
4236 TALLOC_FREE(result);
4241 * The credentials on a new netlogon pipe are the ones we are passed
4242 * in - reference them in
4244 result->dc = talloc_move(result, pdc);
4246 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4247 "for domain %s and bound using schannel.\n",
4248 get_pipe_name_from_syntax(talloc_tos(), interface),
4249 cli->desthost, domain ));
4252 return NT_STATUS_OK;
4255 /****************************************************************************
4256 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4257 Fetch the session key ourselves using a temporary netlogon pipe. This
4258 version uses an ntlmssp auth bound netlogon pipe to get the key.
4259 ****************************************************************************/
4261 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4263 const char *username,
4264 const char *password,
4266 struct rpc_pipe_client **presult)
4268 struct rpc_pipe_client *netlogon_pipe = NULL;
4271 status = cli_rpc_pipe_open_spnego_ntlmssp(
4272 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4273 DCERPC_AUTH_LEVEL_PRIVACY,
4274 domain, username, password, &netlogon_pipe);
4275 if (!NT_STATUS_IS_OK(status)) {
4279 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4281 if (!NT_STATUS_IS_OK(status)) {
4282 TALLOC_FREE(netlogon_pipe);
4286 *presult = netlogon_pipe;
4287 return NT_STATUS_OK;
4290 /****************************************************************************
4291 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4292 Fetch the session key ourselves using a temporary netlogon pipe. This version
4293 uses an ntlmssp bind to get the session key.
4294 ****************************************************************************/
4296 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4297 const struct ndr_syntax_id *interface,
4298 enum dcerpc_transport_t transport,
4299 enum dcerpc_AuthLevel auth_level,
4301 const char *username,
4302 const char *password,
4303 struct rpc_pipe_client **presult)
4305 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4306 struct rpc_pipe_client *netlogon_pipe = NULL;
4307 struct rpc_pipe_client *result = NULL;
4310 status = get_schannel_session_key_auth_ntlmssp(
4311 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4312 if (!NT_STATUS_IS_OK(status)) {
4313 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4314 "key from server %s for domain %s.\n",
4315 cli->desthost, domain ));
4319 status = cli_rpc_pipe_open_schannel_with_key(
4320 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4323 /* Now we've bound using the session key we can close the netlog pipe. */
4324 TALLOC_FREE(netlogon_pipe);
4326 if (NT_STATUS_IS_OK(status)) {
4332 /****************************************************************************
4333 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4334 Fetch the session key ourselves using a temporary netlogon pipe.
4335 ****************************************************************************/
4337 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4338 const struct ndr_syntax_id *interface,
4339 enum dcerpc_transport_t transport,
4340 enum dcerpc_AuthLevel auth_level,
4342 struct rpc_pipe_client **presult)
4344 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4345 struct rpc_pipe_client *netlogon_pipe = NULL;
4346 struct rpc_pipe_client *result = NULL;
4349 status = get_schannel_session_key(cli, domain, &neg_flags,
4351 if (!NT_STATUS_IS_OK(status)) {
4352 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4353 "key from server %s for domain %s.\n",
4354 cli->desthost, domain ));
4358 status = cli_rpc_pipe_open_schannel_with_key(
4359 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4362 /* Now we've bound using the session key we can close the netlog pipe. */
4363 TALLOC_FREE(netlogon_pipe);
4365 if (NT_STATUS_IS_OK(status)) {
4372 /****************************************************************************
4373 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4374 The idea is this can be called with service_princ, username and password all
4375 NULL so long as the caller has a TGT.
4376 ****************************************************************************/
4378 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4379 const struct ndr_syntax_id *interface,
4380 enum dcerpc_AuthLevel auth_level,
4381 const char *service_princ,
4382 const char *username,
4383 const char *password,
4384 struct rpc_pipe_client **presult)
4387 struct rpc_pipe_client *result;
4388 struct cli_pipe_auth_data *auth;
4391 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4392 if (!NT_STATUS_IS_OK(status)) {
4396 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4397 username, password, &auth);
4398 if (!NT_STATUS_IS_OK(status)) {
4399 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4400 nt_errstr(status)));
4401 TALLOC_FREE(result);
4405 status = rpc_pipe_bind(result, auth);
4406 if (!NT_STATUS_IS_OK(status)) {
4407 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4408 "with error %s\n", nt_errstr(status)));
4409 TALLOC_FREE(result);
4414 return NT_STATUS_OK;
4416 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4417 return NT_STATUS_NOT_IMPLEMENTED;
4421 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4422 struct rpc_pipe_client *cli,
4423 DATA_BLOB *session_key)
4425 if (!session_key || !cli) {
4426 return NT_STATUS_INVALID_PARAMETER;
4430 return NT_STATUS_INVALID_PARAMETER;
4433 switch (cli->auth->auth_type) {
4434 case PIPE_AUTH_TYPE_SCHANNEL:
4435 *session_key = data_blob_talloc(mem_ctx,
4436 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4438 case PIPE_AUTH_TYPE_NTLMSSP:
4439 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4440 *session_key = data_blob_talloc(mem_ctx,
4441 cli->auth->a_u.ntlmssp_state->session_key.data,
4442 cli->auth->a_u.ntlmssp_state->session_key.length);
4444 case PIPE_AUTH_TYPE_KRB5:
4445 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4446 *session_key = data_blob_talloc(mem_ctx,
4447 cli->auth->a_u.kerberos_auth->session_key.data,
4448 cli->auth->a_u.kerberos_auth->session_key.length);
4450 case PIPE_AUTH_TYPE_NONE:
4451 *session_key = data_blob_talloc(mem_ctx,
4452 cli->auth->user_session_key.data,
4453 cli->auth->user_session_key.length);
4456 return NT_STATUS_NO_USER_SESSION_KEY;
4459 return NT_STATUS_OK;