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 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 struct dcerpc_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 blob = data_blob_const(prs_data_p(current_pdu)
980 + prs_offset(current_pdu),
981 prs_data_size(current_pdu)
982 - prs_offset(current_pdu));
984 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
985 if (!NT_STATUS_IS_OK(status)) {
986 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
990 /* Ensure auth_pad_len fits into the packet. */
991 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
992 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
993 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
994 "too large (%u), auth_len (%u), frag_len = (%u).\n",
995 (unsigned int)auth_info.auth_pad_length,
996 (unsigned int)auth_len,
997 (unsigned int)prhdr->frag_length));
998 return NT_STATUS_BUFFER_TOO_SMALL;
1001 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1002 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
1003 auth_info.auth_type));
1004 return NT_STATUS_BUFFER_TOO_SMALL;
1007 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
1009 if (DEBUGLEVEL >= 10) {
1010 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1013 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1015 switch (cli->auth->auth_level) {
1016 case DCERPC_AUTH_LEVEL_PRIVACY:
1017 status = netsec_incoming_packet(schannel_auth,
1024 case DCERPC_AUTH_LEVEL_INTEGRITY:
1025 status = netsec_incoming_packet(schannel_auth,
1033 status = NT_STATUS_INTERNAL_ERROR;
1037 if (!NT_STATUS_IS_OK(status)) {
1038 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1039 "Connection to %s (%s).\n",
1040 rpccli_pipe_txt(talloc_tos(), cli),
1041 nt_errstr(status)));
1042 return NT_STATUS_INVALID_PARAMETER;
1046 * Return the current pointer to the data offset.
1049 if(!prs_set_offset(current_pdu, save_offset)) {
1050 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1051 (unsigned int)save_offset ));
1052 return NT_STATUS_BUFFER_TOO_SMALL;
1056 * Remember the padding length. We must remove it from the real data
1057 * stream once the sign/seal is done.
1060 *p_ss_padding_len = auth_info.auth_pad_length;
1062 return NT_STATUS_OK;
1065 /****************************************************************************
1066 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1067 ****************************************************************************/
1069 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1070 struct ncacn_packet_header *prhdr,
1071 prs_struct *current_pdu,
1072 uint8 *p_ss_padding_len)
1074 NTSTATUS ret = NT_STATUS_OK;
1076 /* Paranioa checks for auth_len. */
1077 if (prhdr->auth_length) {
1078 if (prhdr->auth_length > prhdr->frag_length) {
1079 return NT_STATUS_INVALID_PARAMETER;
1082 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1083 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1084 /* Integer wrap attempt. */
1085 return NT_STATUS_INVALID_PARAMETER;
1090 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1093 switch(cli->auth->auth_type) {
1094 case PIPE_AUTH_TYPE_NONE:
1095 if (prhdr->auth_length) {
1096 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1097 "Connection to %s - got non-zero "
1099 rpccli_pipe_txt(talloc_tos(), cli),
1100 (unsigned int)prhdr->auth_length));
1101 return NT_STATUS_INVALID_PARAMETER;
1105 case PIPE_AUTH_TYPE_NTLMSSP:
1106 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1107 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1108 if (!NT_STATUS_IS_OK(ret)) {
1113 case PIPE_AUTH_TYPE_SCHANNEL:
1114 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1115 if (!NT_STATUS_IS_OK(ret)) {
1120 case PIPE_AUTH_TYPE_KRB5:
1121 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1123 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1124 "to %s - unknown internal auth type %u.\n",
1125 rpccli_pipe_txt(talloc_tos(), cli),
1126 cli->auth->auth_type ));
1127 return NT_STATUS_INVALID_INFO_CLASS;
1130 return NT_STATUS_OK;
1133 /****************************************************************************
1134 Do basic authentication checks on an incoming pdu.
1135 ****************************************************************************/
1137 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1138 struct ncacn_packet_header *prhdr,
1139 prs_struct *current_pdu,
1140 uint8 expected_pkt_type,
1143 prs_struct *return_data)
1146 NTSTATUS ret = NT_STATUS_OK;
1147 uint32 current_pdu_len = prs_data_size(current_pdu);
1149 if (current_pdu_len != prhdr->frag_length) {
1150 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1151 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_length));
1152 return NT_STATUS_INVALID_PARAMETER;
1156 * Point the return values at the real data including the RPC
1157 * header. Just in case the caller wants it.
1159 *ppdata = prs_data_p(current_pdu);
1160 *pdata_len = current_pdu_len;
1162 /* Ensure we have the correct type. */
1163 switch (prhdr->ptype) {
1164 case DCERPC_PKT_ALTER_RESP:
1165 case DCERPC_PKT_BIND_ACK:
1167 /* Alter context and bind ack share the same packet definitions. */
1171 case DCERPC_PKT_RESPONSE:
1173 uint8 ss_padding_len = 0;
1175 struct ncacn_packet r;
1177 blob = data_blob_const(prs_data_p(current_pdu),
1178 prs_data_size(current_pdu));
1180 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1181 if (!NT_STATUS_IS_OK(ret)) {
1185 if (!prs_set_offset(current_pdu, prs_offset(current_pdu) + RPC_HDR_RESP_LEN)) {
1186 return NT_STATUS_BUFFER_TOO_SMALL;
1189 /* Here's where we deal with incoming sign/seal. */
1190 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1191 current_pdu, &ss_padding_len);
1192 if (!NT_STATUS_IS_OK(ret)) {
1196 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1197 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1199 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1200 return NT_STATUS_BUFFER_TOO_SMALL;
1203 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1205 /* Remember to remove the auth footer. */
1206 if (prhdr->auth_length) {
1207 /* We've already done integer wrap tests on auth_len in
1208 cli_pipe_validate_rpc_response(). */
1209 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_length) {
1210 return NT_STATUS_BUFFER_TOO_SMALL;
1212 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_length);
1215 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1216 current_pdu_len, *pdata_len, ss_padding_len ));
1219 * If this is the first reply, and the allocation hint is reasonably, try and
1220 * set up the return_data parse_struct to the correct size.
1223 if ((prs_data_size(return_data) == 0) && r.u.response.alloc_hint && (r.u.response.alloc_hint < 15*1024*1024)) {
1224 if (!prs_set_buffer_size(return_data, r.u.response.alloc_hint)) {
1225 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1226 "too large to allocate\n",
1227 (unsigned int)r.u.response.alloc_hint ));
1228 return NT_STATUS_NO_MEMORY;
1235 case DCERPC_PKT_BIND_NAK:
1236 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1237 "received from %s!\n",
1238 rpccli_pipe_txt(talloc_tos(), cli)));
1239 /* Use this for now... */
1240 return NT_STATUS_NETWORK_ACCESS_DENIED;
1242 case DCERPC_PKT_FAULT:
1245 struct ncacn_packet r;
1247 blob = data_blob_const(prs_data_p(current_pdu),
1248 prs_data_size(current_pdu));
1250 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1251 if (!NT_STATUS_IS_OK(ret)) {
1254 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1255 "code %s received from %s!\n",
1256 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1257 rpccli_pipe_txt(talloc_tos(), cli)));
1259 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1260 return NT_STATUS_UNSUCCESSFUL;
1262 return NT_STATUS(r.u.fault.status);
1267 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1269 (unsigned int)prhdr->ptype,
1270 rpccli_pipe_txt(talloc_tos(), cli)));
1271 return NT_STATUS_INVALID_INFO_CLASS;
1274 if (prhdr->ptype != expected_pkt_type) {
1275 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1276 "got an unexpected RPC packet type - %u, not %u\n",
1277 rpccli_pipe_txt(talloc_tos(), cli),
1279 expected_pkt_type));
1280 return NT_STATUS_INVALID_INFO_CLASS;
1283 /* Do this just before return - we don't want to modify any rpc header
1284 data before now as we may have needed to do cryptographic actions on
1287 if ((prhdr->ptype == DCERPC_PKT_BIND_ACK) && !(prhdr->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1288 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1289 "setting fragment first/last ON.\n"));
1290 prhdr->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1293 return NT_STATUS_OK;
1296 /****************************************************************************
1297 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1298 Normally the frag_len and buffer size will match, but on the first trans
1299 reply there is a theoretical chance that buffer size > frag_len, so we must
1301 ****************************************************************************/
1303 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1304 struct ncacn_packet_header *prhdr,
1305 prs_struct *current_pdu)
1307 uint32 current_pdu_len = prs_data_size(current_pdu);
1309 if (current_pdu_len < prhdr->frag_length) {
1310 return NT_STATUS_BUFFER_TOO_SMALL;
1314 if (current_pdu_len == (uint32)prhdr->frag_length) {
1315 prs_mem_free(current_pdu);
1316 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1317 /* Make current_pdu dynamic with no memory. */
1318 prs_give_memory(current_pdu, 0, 0, True);
1319 return NT_STATUS_OK;
1323 * Oh no ! More data in buffer than we processed in current pdu.
1324 * Cheat. Move the data down and shrink the buffer.
1327 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_length,
1328 current_pdu_len - prhdr->frag_length);
1330 /* Remember to set the read offset back to zero. */
1331 prs_set_offset(current_pdu, 0);
1333 /* Shrink the buffer. */
1334 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_length)) {
1335 return NT_STATUS_BUFFER_TOO_SMALL;
1338 return NT_STATUS_OK;
1341 /****************************************************************************
1342 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1343 ****************************************************************************/
1345 struct cli_api_pipe_state {
1346 struct event_context *ev;
1347 struct rpc_cli_transport *transport;
1352 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1353 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1354 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1356 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1357 struct event_context *ev,
1358 struct rpc_cli_transport *transport,
1359 uint8_t *data, size_t data_len,
1360 uint32_t max_rdata_len)
1362 struct tevent_req *req, *subreq;
1363 struct cli_api_pipe_state *state;
1366 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1371 state->transport = transport;
1373 if (max_rdata_len < RPC_HEADER_LEN) {
1375 * For a RPC reply we always need at least RPC_HEADER_LEN
1376 * bytes. We check this here because we will receive
1377 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1379 status = NT_STATUS_INVALID_PARAMETER;
1383 if (transport->trans_send != NULL) {
1384 subreq = transport->trans_send(state, ev, data, data_len,
1385 max_rdata_len, transport->priv);
1386 if (subreq == NULL) {
1389 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1394 * If the transport does not provide a "trans" routine, i.e. for
1395 * example the ncacn_ip_tcp transport, do the write/read step here.
1398 subreq = rpc_write_send(state, ev, transport, data, data_len);
1399 if (subreq == NULL) {
1402 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1406 tevent_req_nterror(req, status);
1407 return tevent_req_post(req, ev);
1413 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1415 struct tevent_req *req = tevent_req_callback_data(
1416 subreq, struct tevent_req);
1417 struct cli_api_pipe_state *state = tevent_req_data(
1418 req, struct cli_api_pipe_state);
1421 status = state->transport->trans_recv(subreq, state, &state->rdata,
1423 TALLOC_FREE(subreq);
1424 if (!NT_STATUS_IS_OK(status)) {
1425 tevent_req_nterror(req, status);
1428 tevent_req_done(req);
1431 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1433 struct tevent_req *req = tevent_req_callback_data(
1434 subreq, struct tevent_req);
1435 struct cli_api_pipe_state *state = tevent_req_data(
1436 req, struct cli_api_pipe_state);
1439 status = rpc_write_recv(subreq);
1440 TALLOC_FREE(subreq);
1441 if (!NT_STATUS_IS_OK(status)) {
1442 tevent_req_nterror(req, status);
1446 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1447 if (tevent_req_nomem(state->rdata, req)) {
1452 * We don't need to use rpc_read_send here, the upper layer will cope
1453 * with a short read, transport->trans_send could also return less
1454 * than state->max_rdata_len.
1456 subreq = state->transport->read_send(state, state->ev, state->rdata,
1458 state->transport->priv);
1459 if (tevent_req_nomem(subreq, req)) {
1462 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1465 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1467 struct tevent_req *req = tevent_req_callback_data(
1468 subreq, struct tevent_req);
1469 struct cli_api_pipe_state *state = tevent_req_data(
1470 req, struct cli_api_pipe_state);
1474 status = state->transport->read_recv(subreq, &received);
1475 TALLOC_FREE(subreq);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 tevent_req_nterror(req, status);
1480 state->rdata_len = received;
1481 tevent_req_done(req);
1484 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1485 uint8_t **prdata, uint32_t *prdata_len)
1487 struct cli_api_pipe_state *state = tevent_req_data(
1488 req, struct cli_api_pipe_state);
1491 if (tevent_req_is_nterror(req, &status)) {
1495 *prdata = talloc_move(mem_ctx, &state->rdata);
1496 *prdata_len = state->rdata_len;
1497 return NT_STATUS_OK;
1500 /****************************************************************************
1501 Send data on an rpc pipe via trans. The prs_struct data must be the last
1502 pdu fragment of an NDR data stream.
1504 Receive response data from an rpc pipe, which may be large...
1506 Read the first fragment: unfortunately have to use SMBtrans for the first
1507 bit, then SMBreadX for subsequent bits.
1509 If first fragment received also wasn't the last fragment, continue
1510 getting fragments until we _do_ receive the last fragment.
1512 Request/Response PDU's look like the following...
1514 |<------------------PDU len----------------------------------------------->|
1515 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1517 +------------+-----------------+-------------+---------------+-------------+
1518 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1519 +------------+-----------------+-------------+---------------+-------------+
1521 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1522 signing & sealing being negotiated.
1524 ****************************************************************************/
1526 struct rpc_api_pipe_state {
1527 struct event_context *ev;
1528 struct rpc_pipe_client *cli;
1529 uint8_t expected_pkt_type;
1531 prs_struct incoming_frag;
1532 struct ncacn_packet_header rhdr;
1534 prs_struct incoming_pdu; /* Incoming reply */
1535 uint32_t incoming_pdu_offset;
1538 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1539 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1541 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1542 struct event_context *ev,
1543 struct rpc_pipe_client *cli,
1544 prs_struct *data, /* Outgoing PDU */
1545 uint8_t expected_pkt_type)
1547 struct tevent_req *req, *subreq;
1548 struct rpc_api_pipe_state *state;
1549 uint16_t max_recv_frag;
1552 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1558 state->expected_pkt_type = expected_pkt_type;
1559 state->incoming_pdu_offset = 0;
1561 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1563 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1564 /* Make incoming_pdu dynamic with no memory. */
1565 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1568 * Ensure we're not sending too much.
1570 if (prs_offset(data) > cli->max_xmit_frag) {
1571 status = NT_STATUS_INVALID_PARAMETER;
1575 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1577 max_recv_frag = cli->max_recv_frag;
1580 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1583 subreq = cli_api_pipe_send(state, ev, cli->transport,
1584 (uint8_t *)prs_data_p(data),
1585 prs_offset(data), max_recv_frag);
1586 if (subreq == NULL) {
1589 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1593 tevent_req_nterror(req, status);
1594 return tevent_req_post(req, ev);
1600 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1602 struct tevent_req *req = tevent_req_callback_data(
1603 subreq, struct tevent_req);
1604 struct rpc_api_pipe_state *state = tevent_req_data(
1605 req, struct rpc_api_pipe_state);
1607 uint8_t *rdata = NULL;
1608 uint32_t rdata_len = 0;
1610 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1611 TALLOC_FREE(subreq);
1612 if (!NT_STATUS_IS_OK(status)) {
1613 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1614 tevent_req_nterror(req, status);
1618 if (rdata == NULL) {
1619 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1620 rpccli_pipe_txt(talloc_tos(), state->cli)));
1621 tevent_req_done(req);
1626 * This is equivalent to a talloc_steal - gives rdata to
1627 * the prs_struct state->incoming_frag.
1629 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1632 /* Ensure we have enough data for a pdu. */
1633 subreq = get_complete_frag_send(state, state->ev, state->cli,
1634 &state->rhdr, &state->incoming_frag);
1635 if (tevent_req_nomem(subreq, req)) {
1638 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1641 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1643 struct tevent_req *req = tevent_req_callback_data(
1644 subreq, struct tevent_req);
1645 struct rpc_api_pipe_state *state = tevent_req_data(
1646 req, struct rpc_api_pipe_state);
1649 uint32_t rdata_len = 0;
1651 status = get_complete_frag_recv(subreq);
1652 TALLOC_FREE(subreq);
1653 if (!NT_STATUS_IS_OK(status)) {
1654 DEBUG(5, ("get_complete_frag failed: %s\n",
1655 nt_errstr(status)));
1656 tevent_req_nterror(req, status);
1660 status = cli_pipe_validate_current_pdu(
1661 state->cli, &state->rhdr, &state->incoming_frag,
1662 state->expected_pkt_type, &rdata, &rdata_len,
1663 &state->incoming_pdu);
1665 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1666 (unsigned)prs_data_size(&state->incoming_frag),
1667 (unsigned)state->incoming_pdu_offset,
1668 nt_errstr(status)));
1670 if (!NT_STATUS_IS_OK(status)) {
1671 tevent_req_nterror(req, status);
1675 if ((state->rhdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)
1676 && (state->rhdr.drep[0] == 0)) {
1678 * Set the data type correctly for big-endian data on the
1681 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1683 rpccli_pipe_txt(talloc_tos(), state->cli)));
1684 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1687 * Check endianness on subsequent packets.
1689 if (state->incoming_frag.bigendian_data
1690 != state->incoming_pdu.bigendian_data) {
1691 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1693 state->incoming_pdu.bigendian_data?"big":"little",
1694 state->incoming_frag.bigendian_data?"big":"little"));
1695 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1699 /* Now copy the data portion out of the pdu into rbuf. */
1700 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1701 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1705 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1706 rdata, (size_t)rdata_len);
1707 state->incoming_pdu_offset += rdata_len;
1709 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1710 &state->incoming_frag);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 tevent_req_nterror(req, status);
1716 if (state->rhdr.pfc_flags & DCERPC_PFC_FLAG_LAST) {
1717 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1718 rpccli_pipe_txt(talloc_tos(), state->cli),
1719 (unsigned)prs_data_size(&state->incoming_pdu)));
1720 tevent_req_done(req);
1724 subreq = get_complete_frag_send(state, state->ev, state->cli,
1725 &state->rhdr, &state->incoming_frag);
1726 if (tevent_req_nomem(subreq, req)) {
1729 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1732 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1733 prs_struct *reply_pdu)
1735 struct rpc_api_pipe_state *state = tevent_req_data(
1736 req, struct rpc_api_pipe_state);
1739 if (tevent_req_is_nterror(req, &status)) {
1743 *reply_pdu = state->incoming_pdu;
1744 reply_pdu->mem_ctx = mem_ctx;
1747 * Prevent state->incoming_pdu from being freed
1748 * when state is freed.
1750 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1751 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1753 return NT_STATUS_OK;
1756 /*******************************************************************
1757 Creates an auth_data blob.
1758 ********************************************************************/
1760 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1761 enum dcerpc_AuthType auth_type,
1762 enum dcerpc_AuthLevel auth_level,
1763 uint8_t auth_pad_length,
1764 uint32_t auth_context_id,
1765 const DATA_BLOB *credentials,
1768 struct dcerpc_auth r;
1769 enum ndr_err_code ndr_err;
1771 r.auth_type = auth_type;
1772 r.auth_level = auth_level;
1773 r.auth_pad_length = auth_pad_length;
1774 r.auth_reserved = 0;
1775 r.auth_context_id = auth_context_id;
1776 r.credentials = *credentials;
1778 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1779 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1780 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1781 return ndr_map_error2ntstatus(ndr_err);
1784 if (DEBUGLEVEL >= 10) {
1785 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1788 return NT_STATUS_OK;
1791 /*******************************************************************
1792 Creates krb5 auth bind.
1793 ********************************************************************/
1795 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1796 enum dcerpc_AuthLevel auth_level,
1797 DATA_BLOB *auth_info)
1802 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1803 DATA_BLOB tkt = data_blob_null;
1804 DATA_BLOB tkt_wrapped = data_blob_null;
1806 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1807 a->service_principal ));
1809 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1811 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1812 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1815 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1817 a->service_principal,
1818 error_message(ret) ));
1820 data_blob_free(&tkt);
1821 return NT_STATUS_INVALID_PARAMETER;
1824 /* wrap that up in a nice GSS-API wrapping */
1825 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1827 data_blob_free(&tkt);
1829 status = dcerpc_push_dcerpc_auth(cli,
1830 DCERPC_AUTH_TYPE_KRB5,
1832 0, /* auth_pad_length */
1833 1, /* auth_context_id */
1836 if (!NT_STATUS_IS_OK(status)) {
1837 data_blob_free(&tkt_wrapped);
1841 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1842 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1844 return NT_STATUS_OK;
1846 return NT_STATUS_INVALID_PARAMETER;
1850 /*******************************************************************
1851 Creates SPNEGO NTLMSSP auth bind.
1852 ********************************************************************/
1854 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1855 enum dcerpc_AuthLevel auth_level,
1856 DATA_BLOB *auth_info)
1859 DATA_BLOB null_blob = data_blob_null;
1860 DATA_BLOB request = data_blob_null;
1861 DATA_BLOB spnego_msg = data_blob_null;
1863 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1864 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1868 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1869 data_blob_free(&request);
1873 /* Wrap this in SPNEGO. */
1874 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1876 data_blob_free(&request);
1878 status = dcerpc_push_dcerpc_auth(cli,
1879 DCERPC_AUTH_TYPE_SPNEGO,
1881 0, /* auth_pad_length */
1882 1, /* auth_context_id */
1885 if (!NT_STATUS_IS_OK(status)) {
1886 data_blob_free(&spnego_msg);
1890 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1891 dump_data(5, spnego_msg.data, spnego_msg.length);
1893 return NT_STATUS_OK;
1896 /*******************************************************************
1897 Creates NTLMSSP auth bind.
1898 ********************************************************************/
1900 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1901 enum dcerpc_AuthLevel auth_level,
1902 DATA_BLOB *auth_info)
1905 DATA_BLOB null_blob = data_blob_null;
1906 DATA_BLOB request = data_blob_null;
1908 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1909 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1913 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1914 data_blob_free(&request);
1918 status = dcerpc_push_dcerpc_auth(cli,
1919 DCERPC_AUTH_TYPE_NTLMSSP,
1921 0, /* auth_pad_length */
1922 1, /* auth_context_id */
1925 if (!NT_STATUS_IS_OK(status)) {
1926 data_blob_free(&request);
1930 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1931 dump_data(5, request.data, request.length);
1933 return NT_STATUS_OK;
1936 /*******************************************************************
1937 Creates schannel auth bind.
1938 ********************************************************************/
1940 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1941 enum dcerpc_AuthLevel auth_level,
1942 DATA_BLOB *auth_info)
1945 struct NL_AUTH_MESSAGE r;
1946 DATA_BLOB schannel_blob;
1948 /* Use lp_workgroup() if domain not specified */
1950 if (!cli->auth->domain || !cli->auth->domain[0]) {
1951 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1952 if (cli->auth->domain == NULL) {
1953 return NT_STATUS_NO_MEMORY;
1958 * Now marshall the data into the auth parse_struct.
1961 r.MessageType = NL_NEGOTIATE_REQUEST;
1962 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1963 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1964 r.oem_netbios_domain.a = cli->auth->domain;
1965 r.oem_netbios_computer.a = global_myname();
1967 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1968 if (!NT_STATUS_IS_OK(status)) {
1972 status = dcerpc_push_dcerpc_auth(cli,
1973 DCERPC_AUTH_TYPE_SCHANNEL,
1975 0, /* auth_pad_length */
1976 1, /* auth_context_id */
1979 if (!NT_STATUS_IS_OK(status)) {
1983 return NT_STATUS_OK;
1986 /*******************************************************************
1987 ********************************************************************/
1989 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1990 const struct ndr_syntax_id *abstract_syntax,
1991 const struct ndr_syntax_id *transfer_syntax,
1992 struct dcerpc_ctx_list **ctx_list_p)
1994 struct dcerpc_ctx_list *ctx_list;
1996 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1997 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1999 ctx_list[0].context_id = 0;
2000 ctx_list[0].num_transfer_syntaxes = 1;
2001 ctx_list[0].abstract_syntax = *abstract_syntax;
2002 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
2003 struct ndr_syntax_id,
2004 ctx_list[0].num_transfer_syntaxes);
2005 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
2006 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
2008 *ctx_list_p = ctx_list;
2010 return NT_STATUS_OK;
2013 /*******************************************************************
2014 Creates the internals of a DCE/RPC bind request or alter context PDU.
2015 ********************************************************************/
2017 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2018 prs_struct *rpc_out,
2020 const struct ndr_syntax_id *abstract,
2021 const struct ndr_syntax_id *transfer,
2022 const DATA_BLOB *auth_info)
2024 uint16 auth_len = auth_info->length;
2025 uint16 frag_len = 0;
2027 union dcerpc_payload u;
2029 struct dcerpc_ctx_list *ctx_list;
2031 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2033 if (!NT_STATUS_IS_OK(status)) {
2037 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2038 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2039 u.bind.assoc_group_id = 0x0;
2040 u.bind.num_contexts = 1;
2041 u.bind.ctx_list = ctx_list;
2042 u.bind.auth_info = *auth_info;
2044 /* Start building the frag length. */
2045 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind) + auth_len;
2047 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2049 DCERPC_PFC_FLAG_FIRST |
2050 DCERPC_PFC_FLAG_LAST,
2052 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2056 if (!NT_STATUS_IS_OK(status)) {
2057 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2061 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2062 return NT_STATUS_NO_MEMORY;
2065 return NT_STATUS_OK;
2068 /*******************************************************************
2069 Creates a DCE/RPC bind request.
2070 ********************************************************************/
2072 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2073 prs_struct *rpc_out,
2075 const struct ndr_syntax_id *abstract,
2076 const struct ndr_syntax_id *transfer,
2077 enum pipe_auth_type auth_type,
2078 enum dcerpc_AuthLevel auth_level)
2080 DATA_BLOB auth_info = data_blob_null;
2081 NTSTATUS ret = NT_STATUS_OK;
2083 switch (auth_type) {
2084 case PIPE_AUTH_TYPE_SCHANNEL:
2085 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2086 if (!NT_STATUS_IS_OK(ret)) {
2091 case PIPE_AUTH_TYPE_NTLMSSP:
2092 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2093 if (!NT_STATUS_IS_OK(ret)) {
2098 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2099 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2100 if (!NT_STATUS_IS_OK(ret)) {
2105 case PIPE_AUTH_TYPE_KRB5:
2106 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2107 if (!NT_STATUS_IS_OK(ret)) {
2112 case PIPE_AUTH_TYPE_NONE:
2116 /* "Can't" happen. */
2117 return NT_STATUS_INVALID_INFO_CLASS;
2120 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2129 /*******************************************************************
2130 Create and add the NTLMSSP sign/seal auth header and data.
2131 ********************************************************************/
2133 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2134 uint32 ss_padding_len,
2135 prs_struct *rpc_out)
2137 DATA_BLOB auth_info;
2139 DATA_BLOB auth_blob = data_blob_null;
2140 uint16_t data_and_pad_len =
2141 prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2143 if (!cli->auth->a_u.ntlmssp_state) {
2144 return NT_STATUS_INVALID_PARAMETER;
2147 switch (cli->auth->auth_level) {
2148 case DCERPC_AUTH_LEVEL_PRIVACY:
2149 /* Data portion is encrypted. */
2150 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2151 prs_get_mem_context(rpc_out),
2152 (unsigned char *)prs_data_p(rpc_out)
2156 (unsigned char *)prs_data_p(rpc_out),
2157 (size_t)prs_offset(rpc_out),
2159 if (!NT_STATUS_IS_OK(status)) {
2164 case DCERPC_AUTH_LEVEL_INTEGRITY:
2165 /* Data is signed. */
2166 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2167 prs_get_mem_context(rpc_out),
2168 (unsigned char *)prs_data_p(rpc_out)
2172 (unsigned char *)prs_data_p(rpc_out),
2173 (size_t)prs_offset(rpc_out),
2175 if (!NT_STATUS_IS_OK(status)) {
2182 smb_panic("bad auth level");
2184 return NT_STATUS_INVALID_PARAMETER;
2187 /* Finally marshall the blob. */
2188 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2189 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2190 cli->auth->auth_level,
2192 1 /* context id. */,
2195 if (!NT_STATUS_IS_OK(status)) {
2199 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.length)) {
2200 DEBUG(0, ("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2201 (unsigned int)auth_info.length));
2202 return NT_STATUS_NO_MEMORY;
2205 return NT_STATUS_OK;
2208 /*******************************************************************
2209 Create and add the schannel sign/seal auth header and data.
2210 ********************************************************************/
2212 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2213 uint32 ss_padding_len,
2214 prs_struct *rpc_out)
2216 DATA_BLOB auth_info;
2217 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2218 char *data_p = prs_data_p(rpc_out) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2219 size_t data_and_pad_len = prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2224 return NT_STATUS_INVALID_PARAMETER;
2227 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2230 switch (cli->auth->auth_level) {
2231 case DCERPC_AUTH_LEVEL_PRIVACY:
2232 status = netsec_outgoing_packet(sas,
2239 case DCERPC_AUTH_LEVEL_INTEGRITY:
2240 status = netsec_outgoing_packet(sas,
2248 status = NT_STATUS_INTERNAL_ERROR;
2252 if (!NT_STATUS_IS_OK(status)) {
2253 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2254 nt_errstr(status)));
2258 if (DEBUGLEVEL >= 10) {
2259 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2262 /* Finally marshall the blob. */
2263 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2264 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2265 cli->auth->auth_level,
2267 1 /* context id. */,
2270 if (!NT_STATUS_IS_OK(status)) {
2274 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.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(const struct dcerpc_bind_ack *r,
2672 const struct ndr_syntax_id *transfer)
2674 struct dcerpc_ack_ctx ctx;
2676 if (r->secondary_address_size == 0) {
2677 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2680 if (r->num_results < 1 || !r->ctx_list) {
2684 ctx = r->ctx_list[0];
2686 /* check the transfer syntax */
2687 if ((ctx.syntax.if_version != transfer->if_version) ||
2688 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2689 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2693 if (r->num_results != 0x1 || ctx.result != 0) {
2694 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2695 r->num_results, ctx.reason));
2698 DEBUG(5,("check_bind_response: accepted!\n"));
2702 /*******************************************************************
2703 Creates a DCE/RPC bind authentication response.
2704 This is the packet that is sent back to the server once we
2705 have received a BIND-ACK, to finish the third leg of
2706 the authentication handshake.
2707 ********************************************************************/
2709 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2711 enum pipe_auth_type auth_type,
2712 enum dcerpc_AuthLevel auth_level,
2713 DATA_BLOB *pauth_blob,
2714 prs_struct *rpc_out)
2716 uint16_t auth_len = pauth_blob->length;
2717 uint16_t frag_len = 0;
2719 union dcerpc_payload u;
2724 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2725 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2727 0, /* auth_pad_length */
2728 1, /* auth_context_id */
2730 &u.auth3.auth_info);
2731 if (!NT_STATUS_IS_OK(status)) {
2735 /* Start building the frag length. */
2736 frag_len = RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + auth_len;
2738 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2740 DCERPC_PFC_FLAG_FIRST |
2741 DCERPC_PFC_FLAG_LAST,
2743 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2747 if (!NT_STATUS_IS_OK(status)) {
2748 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2752 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2753 return NT_STATUS_NO_MEMORY;
2756 return NT_STATUS_OK;
2759 /*******************************************************************
2760 Creates a DCE/RPC bind alter context authentication request which
2761 may contain a spnego auth blobl
2762 ********************************************************************/
2764 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2765 const struct ndr_syntax_id *abstract,
2766 const struct ndr_syntax_id *transfer,
2767 enum dcerpc_AuthLevel auth_level,
2768 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2769 prs_struct *rpc_out)
2771 DATA_BLOB auth_info;
2774 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2775 DCERPC_AUTH_TYPE_SPNEGO,
2777 0, /* auth_pad_length */
2778 1, /* auth_context_id */
2781 if (!NT_STATUS_IS_OK(status)) {
2786 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2792 if (!NT_STATUS_IS_OK(status)) {
2799 /****************************************************************************
2801 ****************************************************************************/
2803 struct rpc_pipe_bind_state {
2804 struct event_context *ev;
2805 struct rpc_pipe_client *cli;
2807 uint32_t rpc_call_id;
2810 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2811 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2812 struct rpc_pipe_bind_state *state,
2813 struct ncacn_packet *r,
2814 prs_struct *reply_pdu);
2815 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2816 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2817 struct rpc_pipe_bind_state *state,
2818 struct ncacn_packet *r,
2819 prs_struct *reply_pdu);
2820 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2822 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2823 struct event_context *ev,
2824 struct rpc_pipe_client *cli,
2825 struct cli_pipe_auth_data *auth)
2827 struct tevent_req *req, *subreq;
2828 struct rpc_pipe_bind_state *state;
2831 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2836 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2837 rpccli_pipe_txt(talloc_tos(), cli),
2838 (unsigned int)auth->auth_type,
2839 (unsigned int)auth->auth_level ));
2843 state->rpc_call_id = get_rpc_call_id();
2845 prs_init_empty(&state->rpc_out, state, MARSHALL);
2847 cli->auth = talloc_move(cli, &auth);
2849 /* Marshall the outgoing data. */
2850 status = create_rpc_bind_req(cli, &state->rpc_out,
2852 &cli->abstract_syntax,
2853 &cli->transfer_syntax,
2854 cli->auth->auth_type,
2855 cli->auth->auth_level);
2857 if (!NT_STATUS_IS_OK(status)) {
2861 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2862 DCERPC_PKT_BIND_ACK);
2863 if (subreq == NULL) {
2866 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2870 tevent_req_nterror(req, status);
2871 return tevent_req_post(req, ev);
2877 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2879 struct tevent_req *req = tevent_req_callback_data(
2880 subreq, struct tevent_req);
2881 struct rpc_pipe_bind_state *state = tevent_req_data(
2882 req, struct rpc_pipe_bind_state);
2883 prs_struct reply_pdu;
2885 struct ncacn_packet r;
2888 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2889 TALLOC_FREE(subreq);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2892 rpccli_pipe_txt(talloc_tos(), state->cli),
2893 nt_errstr(status)));
2894 tevent_req_nterror(req, status);
2898 blob = data_blob_const(prs_data_p(&reply_pdu),
2899 prs_data_size(&reply_pdu));
2901 status = dcerpc_pull_ncacn_packet(talloc_tos(), &blob, &r);
2902 if (!NT_STATUS_IS_OK(status)) {
2903 tevent_req_nterror(req, status);
2907 if (!check_bind_response(&r.u.bind_ack, &state->cli->transfer_syntax)) {
2908 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2909 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2913 state->cli->max_xmit_frag = r.u.bind_ack.max_xmit_frag;
2914 state->cli->max_recv_frag = r.u.bind_ack.max_recv_frag;
2917 * For authenticated binds we may need to do 3 or 4 leg binds.
2920 switch(state->cli->auth->auth_type) {
2922 case PIPE_AUTH_TYPE_NONE:
2923 case PIPE_AUTH_TYPE_SCHANNEL:
2924 /* Bind complete. */
2925 tevent_req_done(req);
2928 case PIPE_AUTH_TYPE_NTLMSSP:
2929 /* Need to send AUTH3 packet - no reply. */
2930 status = rpc_finish_auth3_bind_send(req, state, &r,
2932 if (!NT_STATUS_IS_OK(status)) {
2933 tevent_req_nterror(req, status);
2937 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2938 /* Need to send alter context request and reply. */
2939 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &r,
2941 if (!NT_STATUS_IS_OK(status)) {
2942 tevent_req_nterror(req, status);
2946 case PIPE_AUTH_TYPE_KRB5:
2950 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2951 (unsigned int)state->cli->auth->auth_type));
2952 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2956 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2957 struct rpc_pipe_bind_state *state,
2958 struct ncacn_packet *r,
2959 prs_struct *reply_pdu)
2961 DATA_BLOB server_response = data_blob_null;
2962 DATA_BLOB client_reply = data_blob_null;
2963 struct rpc_hdr_auth_info hdr_auth;
2964 struct tevent_req *subreq;
2967 if ((r->auth_length == 0)
2968 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
2969 return NT_STATUS_INVALID_PARAMETER;
2972 if (!prs_set_offset(
2974 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
2975 return NT_STATUS_INVALID_PARAMETER;
2978 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2979 return NT_STATUS_INVALID_PARAMETER;
2982 /* TODO - check auth_type/auth_level match. */
2984 server_response = data_blob_talloc(talloc_tos(), NULL, r->auth_length);
2985 prs_copy_data_out((char *)server_response.data, reply_pdu,
2988 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2989 server_response, &client_reply);
2991 if (!NT_STATUS_IS_OK(status)) {
2992 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2993 "blob failed: %s.\n", nt_errstr(status)));
2997 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2999 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
3000 state->cli->auth->auth_type,
3001 state->cli->auth->auth_level,
3002 &client_reply, &state->rpc_out);
3003 data_blob_free(&client_reply);
3005 if (!NT_STATUS_IS_OK(status)) {
3009 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3010 (uint8_t *)prs_data_p(&state->rpc_out),
3011 prs_offset(&state->rpc_out));
3012 if (subreq == NULL) {
3013 return NT_STATUS_NO_MEMORY;
3015 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3016 return NT_STATUS_OK;
3019 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3021 struct tevent_req *req = tevent_req_callback_data(
3022 subreq, struct tevent_req);
3025 status = rpc_write_recv(subreq);
3026 TALLOC_FREE(subreq);
3027 if (!NT_STATUS_IS_OK(status)) {
3028 tevent_req_nterror(req, status);
3031 tevent_req_done(req);
3034 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3035 struct rpc_pipe_bind_state *state,
3036 struct ncacn_packet *r,
3039 DATA_BLOB server_ntlm_response = data_blob_null;
3040 DATA_BLOB client_reply = data_blob_null;
3041 DATA_BLOB tmp_blob = data_blob_null;
3042 struct dcerpc_auth auth_info;
3043 DATA_BLOB auth_blob;
3044 struct tevent_req *subreq;
3047 if ((r->auth_length == 0)
3048 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3049 return NT_STATUS_INVALID_PARAMETER;
3052 /* Process the returned NTLMSSP blob first. */
3053 if (!prs_set_offset(
3055 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3056 return NT_STATUS_INVALID_PARAMETER;
3059 auth_blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in),
3060 prs_data_size(rpc_in) - prs_offset(rpc_in));
3062 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
3063 if (!NT_STATUS_IS_OK(status)) {
3064 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
3069 * The server might give us back two challenges - tmp_blob is for the
3072 if (!spnego_parse_challenge(auth_info.credentials,
3073 &server_ntlm_response, &tmp_blob)) {
3074 data_blob_free(&server_ntlm_response);
3075 data_blob_free(&tmp_blob);
3076 return NT_STATUS_INVALID_PARAMETER;
3079 /* We're finished with the server spnego response and the tmp_blob. */
3080 data_blob_free(&tmp_blob);
3082 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3083 server_ntlm_response, &client_reply);
3085 /* Finished with the server_ntlm response */
3086 data_blob_free(&server_ntlm_response);
3088 if (!NT_STATUS_IS_OK(status)) {
3089 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3090 "using server blob failed.\n"));
3091 data_blob_free(&client_reply);
3095 /* SPNEGO wrap the client reply. */
3096 tmp_blob = spnego_gen_auth(client_reply);
3097 data_blob_free(&client_reply);
3098 client_reply = tmp_blob;
3099 tmp_blob = data_blob_null;
3101 /* Now prepare the alter context pdu. */
3102 prs_init_empty(&state->rpc_out, state, MARSHALL);
3104 status = create_rpc_alter_context(state->rpc_call_id,
3105 &state->cli->abstract_syntax,
3106 &state->cli->transfer_syntax,
3107 state->cli->auth->auth_level,
3110 data_blob_free(&client_reply);
3112 if (!NT_STATUS_IS_OK(status)) {
3116 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3117 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3118 if (subreq == NULL) {
3119 return NT_STATUS_NO_MEMORY;
3121 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3122 return NT_STATUS_OK;
3125 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3127 struct tevent_req *req = tevent_req_callback_data(
3128 subreq, struct tevent_req);
3129 struct rpc_pipe_bind_state *state = tevent_req_data(
3130 req, struct rpc_pipe_bind_state);
3131 DATA_BLOB server_spnego_response = data_blob_null;
3132 DATA_BLOB tmp_blob = data_blob_null;
3133 prs_struct reply_pdu;
3134 struct ncacn_packet_header hdr;
3135 struct rpc_hdr_auth_info hdr_auth;
3138 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3139 TALLOC_FREE(subreq);
3140 if (!NT_STATUS_IS_OK(status)) {
3141 tevent_req_nterror(req, status);
3145 status = parse_rpc_header(state->cli, &hdr, &reply_pdu);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 tevent_req_nterror(req, status);
3151 if (!prs_set_offset(
3153 hdr.frag_length - hdr.auth_length - RPC_HDR_AUTH_LEN)) {
3154 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3158 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3159 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3163 server_spnego_response = data_blob(NULL, hdr.auth_length);
3164 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3167 /* Check we got a valid auth response. */
3168 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3169 OID_NTLMSSP, &tmp_blob)) {
3170 data_blob_free(&server_spnego_response);
3171 data_blob_free(&tmp_blob);
3172 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3176 data_blob_free(&server_spnego_response);
3177 data_blob_free(&tmp_blob);
3179 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3180 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3181 tevent_req_done(req);
3184 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3186 return tevent_req_simple_recv_ntstatus(req);
3189 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3190 struct cli_pipe_auth_data *auth)
3192 TALLOC_CTX *frame = talloc_stackframe();
3193 struct event_context *ev;
3194 struct tevent_req *req;
3195 NTSTATUS status = NT_STATUS_OK;
3197 ev = event_context_init(frame);
3199 status = NT_STATUS_NO_MEMORY;
3203 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3205 status = NT_STATUS_NO_MEMORY;
3209 if (!tevent_req_poll(req, ev)) {
3210 status = map_nt_error_from_unix(errno);
3214 status = rpc_pipe_bind_recv(req);
3220 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3222 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3223 unsigned int timeout)
3227 if (rpc_cli->transport == NULL) {
3228 return RPCCLI_DEFAULT_TIMEOUT;
3231 if (rpc_cli->transport->set_timeout == NULL) {
3232 return RPCCLI_DEFAULT_TIMEOUT;
3235 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3237 return RPCCLI_DEFAULT_TIMEOUT;
3243 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3245 if (rpc_cli == NULL) {
3249 if (rpc_cli->transport == NULL) {
3253 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3256 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3258 struct cli_state *cli;
3260 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3261 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3262 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3266 cli = rpc_pipe_np_smb_conn(rpc_cli);
3270 E_md4hash(cli->password ? cli->password : "", nt_hash);
3274 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3275 struct cli_pipe_auth_data **presult)
3277 struct cli_pipe_auth_data *result;
3279 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3280 if (result == NULL) {
3281 return NT_STATUS_NO_MEMORY;
3284 result->auth_type = PIPE_AUTH_TYPE_NONE;
3285 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3287 result->user_name = talloc_strdup(result, "");
3288 result->domain = talloc_strdup(result, "");
3289 if ((result->user_name == NULL) || (result->domain == NULL)) {
3290 TALLOC_FREE(result);
3291 return NT_STATUS_NO_MEMORY;
3295 return NT_STATUS_OK;
3298 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3300 ntlmssp_end(&auth->a_u.ntlmssp_state);
3304 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3305 enum pipe_auth_type auth_type,
3306 enum dcerpc_AuthLevel auth_level,
3308 const char *username,
3309 const char *password,
3310 struct cli_pipe_auth_data **presult)
3312 struct cli_pipe_auth_data *result;
3315 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3316 if (result == NULL) {
3317 return NT_STATUS_NO_MEMORY;
3320 result->auth_type = auth_type;
3321 result->auth_level = auth_level;
3323 result->user_name = talloc_strdup(result, username);
3324 result->domain = talloc_strdup(result, domain);
3325 if ((result->user_name == NULL) || (result->domain == NULL)) {
3326 status = NT_STATUS_NO_MEMORY;
3330 status = ntlmssp_client_start(NULL,
3333 lp_client_ntlmv2_auth(),
3334 &result->a_u.ntlmssp_state);
3335 if (!NT_STATUS_IS_OK(status)) {
3339 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3341 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3342 if (!NT_STATUS_IS_OK(status)) {
3346 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3347 if (!NT_STATUS_IS_OK(status)) {
3351 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3352 if (!NT_STATUS_IS_OK(status)) {
3357 * Turn off sign+seal to allow selected auth level to turn it back on.
3359 result->a_u.ntlmssp_state->neg_flags &=
3360 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3362 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3363 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3364 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3365 result->a_u.ntlmssp_state->neg_flags
3366 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3370 return NT_STATUS_OK;
3373 TALLOC_FREE(result);
3377 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3378 enum dcerpc_AuthLevel auth_level,
3379 struct netlogon_creds_CredentialState *creds,
3380 struct cli_pipe_auth_data **presult)
3382 struct cli_pipe_auth_data *result;
3384 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3385 if (result == NULL) {
3386 return NT_STATUS_NO_MEMORY;
3389 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3390 result->auth_level = auth_level;
3392 result->user_name = talloc_strdup(result, "");
3393 result->domain = talloc_strdup(result, domain);
3394 if ((result->user_name == NULL) || (result->domain == NULL)) {
3398 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3399 if (result->a_u.schannel_auth == NULL) {
3403 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3404 result->a_u.schannel_auth->seq_num = 0;
3405 result->a_u.schannel_auth->initiator = true;
3406 result->a_u.schannel_auth->creds = creds;
3409 return NT_STATUS_OK;
3412 TALLOC_FREE(result);
3413 return NT_STATUS_NO_MEMORY;
3417 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3419 data_blob_free(&auth->session_key);
3424 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3425 enum dcerpc_AuthLevel auth_level,
3426 const char *service_princ,
3427 const char *username,
3428 const char *password,
3429 struct cli_pipe_auth_data **presult)
3432 struct cli_pipe_auth_data *result;
3434 if ((username != NULL) && (password != NULL)) {
3435 int ret = kerberos_kinit_password(username, password, 0, NULL);
3437 return NT_STATUS_ACCESS_DENIED;
3441 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3442 if (result == NULL) {
3443 return NT_STATUS_NO_MEMORY;
3446 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3447 result->auth_level = auth_level;
3450 * Username / domain need fixing!
3452 result->user_name = talloc_strdup(result, "");
3453 result->domain = talloc_strdup(result, "");
3454 if ((result->user_name == NULL) || (result->domain == NULL)) {
3458 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3459 result, struct kerberos_auth_struct);
3460 if (result->a_u.kerberos_auth == NULL) {
3463 talloc_set_destructor(result->a_u.kerberos_auth,
3464 cli_auth_kerberos_data_destructor);
3466 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3467 result, service_princ);
3468 if (result->a_u.kerberos_auth->service_principal == NULL) {
3473 return NT_STATUS_OK;
3476 TALLOC_FREE(result);
3477 return NT_STATUS_NO_MEMORY;
3479 return NT_STATUS_NOT_SUPPORTED;
3484 * Create an rpc pipe client struct, connecting to a tcp port.
3486 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3488 const struct ndr_syntax_id *abstract_syntax,
3489 struct rpc_pipe_client **presult)
3491 struct rpc_pipe_client *result;
3492 struct sockaddr_storage addr;
3496 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3497 if (result == NULL) {
3498 return NT_STATUS_NO_MEMORY;
3501 result->abstract_syntax = *abstract_syntax;
3502 result->transfer_syntax = ndr_transfer_syntax;
3503 result->dispatch = cli_do_rpc_ndr;
3504 result->dispatch_send = cli_do_rpc_ndr_send;
3505 result->dispatch_recv = cli_do_rpc_ndr_recv;
3507 result->desthost = talloc_strdup(result, host);
3508 result->srv_name_slash = talloc_asprintf_strupper_m(
3509 result, "\\\\%s", result->desthost);
3510 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3511 status = NT_STATUS_NO_MEMORY;
3515 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3516 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3518 if (!resolve_name(host, &addr, 0, false)) {
3519 status = NT_STATUS_NOT_FOUND;
3523 status = open_socket_out(&addr, port, 60, &fd);
3524 if (!NT_STATUS_IS_OK(status)) {
3527 set_socket_options(fd, lp_socket_options());
3529 status = rpc_transport_sock_init(result, fd, &result->transport);
3530 if (!NT_STATUS_IS_OK(status)) {
3535 result->transport->transport = NCACN_IP_TCP;
3538 return NT_STATUS_OK;
3541 TALLOC_FREE(result);
3546 * Determine the tcp port on which a dcerpc interface is listening
3547 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3550 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3551 const struct ndr_syntax_id *abstract_syntax,
3555 struct rpc_pipe_client *epm_pipe = NULL;
3556 struct cli_pipe_auth_data *auth = NULL;
3557 struct dcerpc_binding *map_binding = NULL;
3558 struct dcerpc_binding *res_binding = NULL;
3559 struct epm_twr_t *map_tower = NULL;
3560 struct epm_twr_t *res_towers = NULL;
3561 struct policy_handle *entry_handle = NULL;
3562 uint32_t num_towers = 0;
3563 uint32_t max_towers = 1;
3564 struct epm_twr_p_t towers;
3565 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3567 if (pport == NULL) {
3568 status = NT_STATUS_INVALID_PARAMETER;
3572 /* open the connection to the endpoint mapper */
3573 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3574 &ndr_table_epmapper.syntax_id,
3577 if (!NT_STATUS_IS_OK(status)) {
3581 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3582 if (!NT_STATUS_IS_OK(status)) {
3586 status = rpc_pipe_bind(epm_pipe, auth);
3587 if (!NT_STATUS_IS_OK(status)) {
3591 /* create tower for asking the epmapper */
3593 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3594 if (map_binding == NULL) {
3595 status = NT_STATUS_NO_MEMORY;
3599 map_binding->transport = NCACN_IP_TCP;
3600 map_binding->object = *abstract_syntax;
3601 map_binding->host = host; /* needed? */
3602 map_binding->endpoint = "0"; /* correct? needed? */
3604 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3605 if (map_tower == NULL) {
3606 status = NT_STATUS_NO_MEMORY;
3610 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3611 &(map_tower->tower));
3612 if (!NT_STATUS_IS_OK(status)) {
3616 /* allocate further parameters for the epm_Map call */
3618 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3619 if (res_towers == NULL) {
3620 status = NT_STATUS_NO_MEMORY;
3623 towers.twr = res_towers;
3625 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3626 if (entry_handle == NULL) {
3627 status = NT_STATUS_NO_MEMORY;
3631 /* ask the endpoint mapper for the port */
3633 status = rpccli_epm_Map(epm_pipe,
3635 CONST_DISCARD(struct GUID *,
3636 &(abstract_syntax->uuid)),
3643 if (!NT_STATUS_IS_OK(status)) {
3647 if (num_towers != 1) {
3648 status = NT_STATUS_UNSUCCESSFUL;
3652 /* extract the port from the answer */
3654 status = dcerpc_binding_from_tower(tmp_ctx,
3655 &(towers.twr->tower),
3657 if (!NT_STATUS_IS_OK(status)) {
3661 /* are further checks here necessary? */
3662 if (res_binding->transport != NCACN_IP_TCP) {
3663 status = NT_STATUS_UNSUCCESSFUL;
3667 *pport = (uint16_t)atoi(res_binding->endpoint);
3670 TALLOC_FREE(tmp_ctx);
3675 * Create a rpc pipe client struct, connecting to a host via tcp.
3676 * The port is determined by asking the endpoint mapper on the given
3679 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3680 const struct ndr_syntax_id *abstract_syntax,
3681 struct rpc_pipe_client **presult)
3686 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3687 if (!NT_STATUS_IS_OK(status)) {
3691 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3692 abstract_syntax, presult);
3695 /********************************************************************
3696 Create a rpc pipe client struct, connecting to a unix domain socket
3697 ********************************************************************/
3698 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3699 const struct ndr_syntax_id *abstract_syntax,
3700 struct rpc_pipe_client **presult)
3702 struct rpc_pipe_client *result;
3703 struct sockaddr_un addr;
3707 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3708 if (result == NULL) {
3709 return NT_STATUS_NO_MEMORY;
3712 result->abstract_syntax = *abstract_syntax;
3713 result->transfer_syntax = ndr_transfer_syntax;
3714 result->dispatch = cli_do_rpc_ndr;
3715 result->dispatch_send = cli_do_rpc_ndr_send;
3716 result->dispatch_recv = cli_do_rpc_ndr_recv;
3718 result->desthost = get_myname(result);
3719 result->srv_name_slash = talloc_asprintf_strupper_m(
3720 result, "\\\\%s", result->desthost);
3721 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3722 status = NT_STATUS_NO_MEMORY;
3726 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3727 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3729 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3731 status = map_nt_error_from_unix(errno);
3736 addr.sun_family = AF_UNIX;
3737 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3739 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3740 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3743 return map_nt_error_from_unix(errno);
3746 status = rpc_transport_sock_init(result, fd, &result->transport);
3747 if (!NT_STATUS_IS_OK(status)) {
3752 result->transport->transport = NCALRPC;
3755 return NT_STATUS_OK;
3758 TALLOC_FREE(result);
3762 struct rpc_pipe_client_np_ref {
3763 struct cli_state *cli;
3764 struct rpc_pipe_client *pipe;
3767 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3769 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3773 /****************************************************************************
3774 Open a named pipe over SMB to a remote server.
3776 * CAVEAT CALLER OF THIS FUNCTION:
3777 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3778 * so be sure that this function is called AFTER any structure (vs pointer)
3779 * assignment of the cli. In particular, libsmbclient does structure
3780 * assignments of cli, which invalidates the data in the returned
3781 * rpc_pipe_client if this function is called before the structure assignment
3784 ****************************************************************************/
3786 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3787 const struct ndr_syntax_id *abstract_syntax,
3788 struct rpc_pipe_client **presult)
3790 struct rpc_pipe_client *result;
3792 struct rpc_pipe_client_np_ref *np_ref;
3794 /* sanity check to protect against crashes */
3797 return NT_STATUS_INVALID_HANDLE;
3800 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3801 if (result == NULL) {
3802 return NT_STATUS_NO_MEMORY;
3805 result->abstract_syntax = *abstract_syntax;
3806 result->transfer_syntax = ndr_transfer_syntax;
3807 result->dispatch = cli_do_rpc_ndr;
3808 result->dispatch_send = cli_do_rpc_ndr_send;
3809 result->dispatch_recv = cli_do_rpc_ndr_recv;
3810 result->desthost = talloc_strdup(result, cli->desthost);
3811 result->srv_name_slash = talloc_asprintf_strupper_m(
3812 result, "\\\\%s", result->desthost);
3814 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3815 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3817 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3818 TALLOC_FREE(result);
3819 return NT_STATUS_NO_MEMORY;
3822 status = rpc_transport_np_init(result, cli, abstract_syntax,
3823 &result->transport);
3824 if (!NT_STATUS_IS_OK(status)) {
3825 TALLOC_FREE(result);
3829 result->transport->transport = NCACN_NP;
3831 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3832 if (np_ref == NULL) {
3833 TALLOC_FREE(result);
3834 return NT_STATUS_NO_MEMORY;
3837 np_ref->pipe = result;
3839 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3840 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3843 return NT_STATUS_OK;
3846 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3847 struct rpc_cli_smbd_conn *conn,
3848 const struct ndr_syntax_id *syntax,
3849 struct rpc_pipe_client **presult)
3851 struct rpc_pipe_client *result;
3852 struct cli_pipe_auth_data *auth;
3855 result = talloc(mem_ctx, struct rpc_pipe_client);
3856 if (result == NULL) {
3857 return NT_STATUS_NO_MEMORY;
3859 result->abstract_syntax = *syntax;
3860 result->transfer_syntax = ndr_transfer_syntax;
3861 result->dispatch = cli_do_rpc_ndr;
3862 result->dispatch_send = cli_do_rpc_ndr_send;
3863 result->dispatch_recv = cli_do_rpc_ndr_recv;
3864 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3865 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3867 result->desthost = talloc_strdup(result, global_myname());
3868 result->srv_name_slash = talloc_asprintf_strupper_m(
3869 result, "\\\\%s", global_myname());
3870 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3871 TALLOC_FREE(result);
3872 return NT_STATUS_NO_MEMORY;
3875 status = rpc_transport_smbd_init(result, conn, syntax,
3876 &result->transport);
3877 if (!NT_STATUS_IS_OK(status)) {
3878 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3879 nt_errstr(status)));
3880 TALLOC_FREE(result);
3884 status = rpccli_anon_bind_data(result, &auth);
3885 if (!NT_STATUS_IS_OK(status)) {
3886 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3887 nt_errstr(status)));
3888 TALLOC_FREE(result);
3892 status = rpc_pipe_bind(result, auth);
3893 if (!NT_STATUS_IS_OK(status)) {
3894 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3895 TALLOC_FREE(result);
3899 result->transport->transport = NCACN_INTERNAL;
3902 return NT_STATUS_OK;
3905 /****************************************************************************
3906 Open a pipe to a remote server.
3907 ****************************************************************************/
3909 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3910 enum dcerpc_transport_t transport,
3911 const struct ndr_syntax_id *interface,
3912 struct rpc_pipe_client **presult)
3914 switch (transport) {
3916 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3919 return rpc_pipe_open_np(cli, interface, presult);
3921 return NT_STATUS_NOT_IMPLEMENTED;
3925 /****************************************************************************
3926 Open a named pipe to an SMB server and bind anonymously.
3927 ****************************************************************************/
3929 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3930 enum dcerpc_transport_t transport,
3931 const struct ndr_syntax_id *interface,
3932 struct rpc_pipe_client **presult)
3934 struct rpc_pipe_client *result;
3935 struct cli_pipe_auth_data *auth;
3938 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3939 if (!NT_STATUS_IS_OK(status)) {
3943 status = rpccli_anon_bind_data(result, &auth);
3944 if (!NT_STATUS_IS_OK(status)) {
3945 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3946 nt_errstr(status)));
3947 TALLOC_FREE(result);
3952 * This is a bit of an abstraction violation due to the fact that an
3953 * anonymous bind on an authenticated SMB inherits the user/domain
3954 * from the enclosing SMB creds
3957 TALLOC_FREE(auth->user_name);
3958 TALLOC_FREE(auth->domain);
3960 auth->user_name = talloc_strdup(auth, cli->user_name);
3961 auth->domain = talloc_strdup(auth, cli->domain);
3962 auth->user_session_key = data_blob_talloc(auth,
3963 cli->user_session_key.data,
3964 cli->user_session_key.length);
3966 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3967 TALLOC_FREE(result);
3968 return NT_STATUS_NO_MEMORY;
3971 status = rpc_pipe_bind(result, auth);
3972 if (!NT_STATUS_IS_OK(status)) {
3974 if (ndr_syntax_id_equal(interface,
3975 &ndr_table_dssetup.syntax_id)) {
3976 /* non AD domains just don't have this pipe, avoid
3977 * level 0 statement in that case - gd */
3980 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3981 "%s failed with error %s\n",
3982 get_pipe_name_from_syntax(talloc_tos(), interface),
3983 nt_errstr(status) ));
3984 TALLOC_FREE(result);
3988 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3989 "%s and bound anonymously.\n",
3990 get_pipe_name_from_syntax(talloc_tos(), interface),
3994 return NT_STATUS_OK;
3997 /****************************************************************************
3998 ****************************************************************************/
4000 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4001 const struct ndr_syntax_id *interface,
4002 struct rpc_pipe_client **presult)
4004 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4005 interface, presult);
4008 /****************************************************************************
4009 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4010 ****************************************************************************/
4012 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4013 const struct ndr_syntax_id *interface,
4014 enum dcerpc_transport_t transport,
4015 enum pipe_auth_type auth_type,
4016 enum dcerpc_AuthLevel auth_level,
4018 const char *username,
4019 const char *password,
4020 struct rpc_pipe_client **presult)
4022 struct rpc_pipe_client *result;
4023 struct cli_pipe_auth_data *auth;
4026 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4027 if (!NT_STATUS_IS_OK(status)) {
4031 status = rpccli_ntlmssp_bind_data(
4032 result, auth_type, auth_level, domain, username,
4034 if (!NT_STATUS_IS_OK(status)) {
4035 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4036 nt_errstr(status)));
4040 status = rpc_pipe_bind(result, auth);
4041 if (!NT_STATUS_IS_OK(status)) {
4042 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4043 nt_errstr(status) ));
4047 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4048 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4049 get_pipe_name_from_syntax(talloc_tos(), interface),
4050 cli->desthost, domain, username ));
4053 return NT_STATUS_OK;
4057 TALLOC_FREE(result);
4061 /****************************************************************************
4063 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4064 ****************************************************************************/
4066 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4067 const struct ndr_syntax_id *interface,
4068 enum dcerpc_transport_t transport,
4069 enum dcerpc_AuthLevel auth_level,
4071 const char *username,
4072 const char *password,
4073 struct rpc_pipe_client **presult)
4075 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4078 PIPE_AUTH_TYPE_NTLMSSP,
4086 /****************************************************************************
4088 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4089 ****************************************************************************/
4091 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4092 const struct ndr_syntax_id *interface,
4093 enum dcerpc_transport_t transport,
4094 enum dcerpc_AuthLevel auth_level,
4096 const char *username,
4097 const char *password,
4098 struct rpc_pipe_client **presult)
4100 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4103 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4111 /****************************************************************************
4112 Get a the schannel session key out of an already opened netlogon pipe.
4113 ****************************************************************************/
4114 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4115 struct cli_state *cli,
4119 enum netr_SchannelType sec_chan_type = 0;
4120 unsigned char machine_pwd[16];
4121 const char *machine_account;
4124 /* Get the machine account credentials from secrets.tdb. */
4125 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4128 DEBUG(0, ("get_schannel_session_key: could not fetch "
4129 "trust account password for domain '%s'\n",
4131 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4134 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4135 cli->desthost, /* server name */
4136 domain, /* domain */
4137 global_myname(), /* client name */
4138 machine_account, /* machine account name */
4143 if (!NT_STATUS_IS_OK(status)) {
4144 DEBUG(3, ("get_schannel_session_key_common: "
4145 "rpccli_netlogon_setup_creds failed with result %s "
4146 "to server %s, domain %s, machine account %s.\n",
4147 nt_errstr(status), cli->desthost, domain,
4152 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4153 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4155 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4158 return NT_STATUS_OK;;
4161 /****************************************************************************
4162 Open a netlogon pipe and get the schannel session key.
4163 Now exposed to external callers.
4164 ****************************************************************************/
4167 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4170 struct rpc_pipe_client **presult)
4172 struct rpc_pipe_client *netlogon_pipe = NULL;
4175 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4177 if (!NT_STATUS_IS_OK(status)) {
4181 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4183 if (!NT_STATUS_IS_OK(status)) {
4184 TALLOC_FREE(netlogon_pipe);
4188 *presult = netlogon_pipe;
4189 return NT_STATUS_OK;
4192 /****************************************************************************
4194 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4195 using session_key. sign and seal.
4197 The *pdc will be stolen onto this new pipe
4198 ****************************************************************************/
4200 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4201 const struct ndr_syntax_id *interface,
4202 enum dcerpc_transport_t transport,
4203 enum dcerpc_AuthLevel auth_level,
4205 struct netlogon_creds_CredentialState **pdc,
4206 struct rpc_pipe_client **presult)
4208 struct rpc_pipe_client *result;
4209 struct cli_pipe_auth_data *auth;
4212 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4213 if (!NT_STATUS_IS_OK(status)) {
4217 status = rpccli_schannel_bind_data(result, domain, auth_level,
4219 if (!NT_STATUS_IS_OK(status)) {
4220 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4221 nt_errstr(status)));
4222 TALLOC_FREE(result);
4226 status = rpc_pipe_bind(result, auth);
4227 if (!NT_STATUS_IS_OK(status)) {
4228 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4229 "cli_rpc_pipe_bind failed with error %s\n",
4230 nt_errstr(status) ));
4231 TALLOC_FREE(result);
4236 * The credentials on a new netlogon pipe are the ones we are passed
4237 * in - reference them in
4239 result->dc = talloc_move(result, pdc);
4241 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4242 "for domain %s and bound using schannel.\n",
4243 get_pipe_name_from_syntax(talloc_tos(), interface),
4244 cli->desthost, domain ));
4247 return NT_STATUS_OK;
4250 /****************************************************************************
4251 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4252 Fetch the session key ourselves using a temporary netlogon pipe. This
4253 version uses an ntlmssp auth bound netlogon pipe to get the key.
4254 ****************************************************************************/
4256 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4258 const char *username,
4259 const char *password,
4261 struct rpc_pipe_client **presult)
4263 struct rpc_pipe_client *netlogon_pipe = NULL;
4266 status = cli_rpc_pipe_open_spnego_ntlmssp(
4267 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4268 DCERPC_AUTH_LEVEL_PRIVACY,
4269 domain, username, password, &netlogon_pipe);
4270 if (!NT_STATUS_IS_OK(status)) {
4274 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4276 if (!NT_STATUS_IS_OK(status)) {
4277 TALLOC_FREE(netlogon_pipe);
4281 *presult = netlogon_pipe;
4282 return NT_STATUS_OK;
4285 /****************************************************************************
4286 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4287 Fetch the session key ourselves using a temporary netlogon pipe. This version
4288 uses an ntlmssp bind to get the session key.
4289 ****************************************************************************/
4291 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4292 const struct ndr_syntax_id *interface,
4293 enum dcerpc_transport_t transport,
4294 enum dcerpc_AuthLevel auth_level,
4296 const char *username,
4297 const char *password,
4298 struct rpc_pipe_client **presult)
4300 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4301 struct rpc_pipe_client *netlogon_pipe = NULL;
4302 struct rpc_pipe_client *result = NULL;
4305 status = get_schannel_session_key_auth_ntlmssp(
4306 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4307 if (!NT_STATUS_IS_OK(status)) {
4308 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4309 "key from server %s for domain %s.\n",
4310 cli->desthost, domain ));
4314 status = cli_rpc_pipe_open_schannel_with_key(
4315 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4318 /* Now we've bound using the session key we can close the netlog pipe. */
4319 TALLOC_FREE(netlogon_pipe);
4321 if (NT_STATUS_IS_OK(status)) {
4327 /****************************************************************************
4328 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4329 Fetch the session key ourselves using a temporary netlogon pipe.
4330 ****************************************************************************/
4332 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4333 const struct ndr_syntax_id *interface,
4334 enum dcerpc_transport_t transport,
4335 enum dcerpc_AuthLevel auth_level,
4337 struct rpc_pipe_client **presult)
4339 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4340 struct rpc_pipe_client *netlogon_pipe = NULL;
4341 struct rpc_pipe_client *result = NULL;
4344 status = get_schannel_session_key(cli, domain, &neg_flags,
4346 if (!NT_STATUS_IS_OK(status)) {
4347 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4348 "key from server %s for domain %s.\n",
4349 cli->desthost, domain ));
4353 status = cli_rpc_pipe_open_schannel_with_key(
4354 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4357 /* Now we've bound using the session key we can close the netlog pipe. */
4358 TALLOC_FREE(netlogon_pipe);
4360 if (NT_STATUS_IS_OK(status)) {
4367 /****************************************************************************
4368 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4369 The idea is this can be called with service_princ, username and password all
4370 NULL so long as the caller has a TGT.
4371 ****************************************************************************/
4373 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4374 const struct ndr_syntax_id *interface,
4375 enum dcerpc_AuthLevel auth_level,
4376 const char *service_princ,
4377 const char *username,
4378 const char *password,
4379 struct rpc_pipe_client **presult)
4382 struct rpc_pipe_client *result;
4383 struct cli_pipe_auth_data *auth;
4386 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4387 if (!NT_STATUS_IS_OK(status)) {
4391 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4392 username, password, &auth);
4393 if (!NT_STATUS_IS_OK(status)) {
4394 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4395 nt_errstr(status)));
4396 TALLOC_FREE(result);
4400 status = rpc_pipe_bind(result, auth);
4401 if (!NT_STATUS_IS_OK(status)) {
4402 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4403 "with error %s\n", nt_errstr(status)));
4404 TALLOC_FREE(result);
4409 return NT_STATUS_OK;
4411 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4412 return NT_STATUS_NOT_IMPLEMENTED;
4416 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4417 struct rpc_pipe_client *cli,
4418 DATA_BLOB *session_key)
4420 if (!session_key || !cli) {
4421 return NT_STATUS_INVALID_PARAMETER;
4425 return NT_STATUS_INVALID_PARAMETER;
4428 switch (cli->auth->auth_type) {
4429 case PIPE_AUTH_TYPE_SCHANNEL:
4430 *session_key = data_blob_talloc(mem_ctx,
4431 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4433 case PIPE_AUTH_TYPE_NTLMSSP:
4434 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4435 *session_key = data_blob_talloc(mem_ctx,
4436 cli->auth->a_u.ntlmssp_state->session_key.data,
4437 cli->auth->a_u.ntlmssp_state->session_key.length);
4439 case PIPE_AUTH_TYPE_KRB5:
4440 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4441 *session_key = data_blob_talloc(mem_ctx,
4442 cli->auth->a_u.kerberos_auth->session_key.data,
4443 cli->auth->a_u.kerberos_auth->session_key.length);
4445 case PIPE_AUTH_TYPE_NONE:
4446 *session_key = data_blob_talloc(mem_ctx,
4447 cli->auth->user_session_key.data,
4448 cli->auth->user_session_key.length);
4451 return NT_STATUS_NO_USER_SESSION_KEY;
4454 return NT_STATUS_OK;