2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_lsa.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../librpc/gen_ndr/ndr_samr.h"
26 #include "../librpc/gen_ndr/ndr_netlogon.h"
27 #include "../librpc/gen_ndr/ndr_srvsvc.h"
28 #include "../librpc/gen_ndr/ndr_wkssvc.h"
29 #include "../librpc/gen_ndr/ndr_winreg.h"
30 #include "../librpc/gen_ndr/ndr_spoolss.h"
31 #include "../librpc/gen_ndr/ndr_dfs.h"
32 #include "../librpc/gen_ndr/ndr_echo.h"
33 #include "../librpc/gen_ndr/ndr_initshutdown.h"
34 #include "../librpc/gen_ndr/ndr_svcctl.h"
35 #include "../librpc/gen_ndr/ndr_eventlog.h"
36 #include "../librpc/gen_ndr/ndr_ntsvcs.h"
37 #include "../librpc/gen_ndr/ndr_epmapper.h"
38 #include "../librpc/gen_ndr/ndr_drsuapi.h"
39 #include "../libcli/auth/schannel.h"
40 #include "../libcli/auth/spnego.h"
42 #include "../libcli/auth/ntlmssp.h"
43 #include "rpc_client/cli_netlogon.h"
44 #include "librpc/gen_ndr/ndr_dcerpc.h"
47 #define DBGC_CLASS DBGC_RPC_CLI
49 static const char *get_pipe_name_from_iface(
50 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
53 const struct ndr_interface_string_array *ep = interface->endpoints;
56 for (i=0; i<ep->count; i++) {
57 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
66 * extract the pipe name without \\pipe from for example
67 * ncacn_np:[\\pipe\\epmapper]
69 p = strchr(ep->names[i]+15, ']');
73 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
76 static const struct ndr_interface_table **interfaces;
78 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
80 int num_interfaces = talloc_array_length(interfaces);
81 const struct ndr_interface_table **tmp;
84 for (i=0; i<num_interfaces; i++) {
85 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
86 &interface->syntax_id)) {
91 tmp = talloc_realloc(NULL, interfaces,
92 const struct ndr_interface_table *,
95 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
99 interfaces[num_interfaces] = interface;
103 static bool initialize_interfaces(void)
105 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
108 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
111 if (!smb_register_ndr_interface(&ndr_table_samr)) {
114 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
117 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
120 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
123 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
126 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
129 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
132 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
135 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
138 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
141 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
144 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
147 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
150 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
156 const struct ndr_interface_table *get_iface_from_syntax(
157 const struct ndr_syntax_id *syntax)
162 if (interfaces == NULL) {
163 if (!initialize_interfaces()) {
167 num_interfaces = talloc_array_length(interfaces);
169 for (i=0; i<num_interfaces; i++) {
170 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
171 return interfaces[i];
178 /****************************************************************************
179 Return the pipe name from the interface.
180 ****************************************************************************/
182 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
183 const struct ndr_syntax_id *syntax)
185 const struct ndr_interface_table *interface;
189 interface = get_iface_from_syntax(syntax);
190 if (interface != NULL) {
191 result = get_pipe_name_from_iface(mem_ctx, interface);
192 if (result != NULL) {
198 * Here we should ask \\epmapper, but for now our code is only
199 * interested in the known pipes mentioned in pipe_names[]
202 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
203 if (guid_str == NULL) {
206 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
207 (int)syntax->if_version);
208 TALLOC_FREE(guid_str);
210 if (result == NULL) {
216 /********************************************************************
217 Map internal value to wire value.
218 ********************************************************************/
220 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
224 case PIPE_AUTH_TYPE_NONE:
225 return DCERPC_AUTH_TYPE_NONE;
227 case PIPE_AUTH_TYPE_NTLMSSP:
228 return DCERPC_AUTH_TYPE_NTLMSSP;
230 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
231 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
232 return DCERPC_AUTH_TYPE_SPNEGO;
234 case PIPE_AUTH_TYPE_SCHANNEL:
235 return DCERPC_AUTH_TYPE_SCHANNEL;
237 case PIPE_AUTH_TYPE_KRB5:
238 return DCERPC_AUTH_TYPE_KRB5;
241 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
243 (unsigned int)auth_type ));
249 /********************************************************************
250 Pipe description for a DEBUG
251 ********************************************************************/
252 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
253 struct rpc_pipe_client *cli)
255 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
256 if (result == NULL) {
262 /********************************************************************
264 ********************************************************************/
266 static uint32 get_rpc_call_id(void)
268 static uint32 call_id = 0;
273 * Realloc pdu to have a least "size" bytes
276 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
280 if (prs_data_size(pdu) >= size) {
284 extra_size = size - prs_data_size(pdu);
286 if (!prs_force_grow(pdu, extra_size)) {
287 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
288 "%d bytes.\n", (int)extra_size));
292 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
293 (int)extra_size, prs_data_size(pdu)));
297 /*******************************************************************
298 *******************************************************************/
300 NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
301 enum dcerpc_pkt_type ptype,
303 uint16_t frag_length,
304 uint16_t auth_length,
306 union dcerpc_payload u,
309 struct ncacn_packet r;
310 enum ndr_err_code ndr_err;
313 r.rpc_vers_minor = 0;
315 r.pfc_flags = pfc_flags;
316 r.drep[0] = DCERPC_DREP_LE;
320 r.frag_length = frag_length;
321 r.auth_length = auth_length;
325 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
326 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
327 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
328 return ndr_map_error2ntstatus(ndr_err);
331 if (DEBUGLEVEL >= 10) {
332 NDR_PRINT_DEBUG(ncacn_packet, &r);
338 /*******************************************************************
339 *******************************************************************/
341 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
342 const DATA_BLOB *blob,
343 struct ncacn_packet *r)
345 enum ndr_err_code ndr_err;
347 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
348 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
350 return ndr_map_error2ntstatus(ndr_err);
353 if (DEBUGLEVEL >= 10) {
354 NDR_PRINT_DEBUG(ncacn_packet, r);
360 /*******************************************************************
361 *******************************************************************/
363 NTSTATUS dcerpc_pull_ncacn_packet_header(TALLOC_CTX *mem_ctx,
364 const DATA_BLOB *blob,
365 struct ncacn_packet_header *r)
367 enum ndr_err_code ndr_err;
369 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
370 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet_header);
371 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
372 return ndr_map_error2ntstatus(ndr_err);
375 if (DEBUGLEVEL >= 10) {
376 NDR_PRINT_DEBUG(ncacn_packet_header, r);
382 /*******************************************************************
383 ********************************************************************/
385 static NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
386 struct NL_AUTH_MESSAGE *r,
389 enum ndr_err_code ndr_err;
391 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
392 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
393 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
394 return ndr_map_error2ntstatus(ndr_err);
397 if (DEBUGLEVEL >= 10) {
398 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
404 /*******************************************************************
405 ********************************************************************/
407 static NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
408 const DATA_BLOB *blob,
409 struct dcerpc_auth *r)
411 enum ndr_err_code ndr_err;
413 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
414 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
415 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
416 return ndr_map_error2ntstatus(ndr_err);
419 if (DEBUGLEVEL >= 10) {
420 NDR_PRINT_DEBUG(dcerpc_auth, r);
426 /*******************************************************************
427 Use SMBreadX to get rest of one fragment's worth of rpc data.
428 Reads the whole size or give an error message
429 ********************************************************************/
431 struct rpc_read_state {
432 struct event_context *ev;
433 struct rpc_cli_transport *transport;
439 static void rpc_read_done(struct tevent_req *subreq);
441 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
442 struct event_context *ev,
443 struct rpc_cli_transport *transport,
444 uint8_t *data, size_t size)
446 struct tevent_req *req, *subreq;
447 struct rpc_read_state *state;
449 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
454 state->transport = transport;
459 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
461 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
463 if (subreq == NULL) {
466 tevent_req_set_callback(subreq, rpc_read_done, req);
474 static void rpc_read_done(struct tevent_req *subreq)
476 struct tevent_req *req = tevent_req_callback_data(
477 subreq, struct tevent_req);
478 struct rpc_read_state *state = tevent_req_data(
479 req, struct rpc_read_state);
483 status = state->transport->read_recv(subreq, &received);
485 if (!NT_STATUS_IS_OK(status)) {
486 tevent_req_nterror(req, status);
490 state->num_read += received;
491 if (state->num_read == state->size) {
492 tevent_req_done(req);
496 subreq = state->transport->read_send(state, state->ev,
497 state->data + state->num_read,
498 state->size - state->num_read,
499 state->transport->priv);
500 if (tevent_req_nomem(subreq, req)) {
503 tevent_req_set_callback(subreq, rpc_read_done, req);
506 static NTSTATUS rpc_read_recv(struct tevent_req *req)
508 return tevent_req_simple_recv_ntstatus(req);
511 struct rpc_write_state {
512 struct event_context *ev;
513 struct rpc_cli_transport *transport;
519 static void rpc_write_done(struct tevent_req *subreq);
521 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
522 struct event_context *ev,
523 struct rpc_cli_transport *transport,
524 const uint8_t *data, size_t size)
526 struct tevent_req *req, *subreq;
527 struct rpc_write_state *state;
529 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
534 state->transport = transport;
537 state->num_written = 0;
539 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
541 subreq = transport->write_send(state, ev, data, size, transport->priv);
542 if (subreq == NULL) {
545 tevent_req_set_callback(subreq, rpc_write_done, req);
552 static void rpc_write_done(struct tevent_req *subreq)
554 struct tevent_req *req = tevent_req_callback_data(
555 subreq, struct tevent_req);
556 struct rpc_write_state *state = tevent_req_data(
557 req, struct rpc_write_state);
561 status = state->transport->write_recv(subreq, &written);
563 if (!NT_STATUS_IS_OK(status)) {
564 tevent_req_nterror(req, status);
568 state->num_written += written;
570 if (state->num_written == state->size) {
571 tevent_req_done(req);
575 subreq = state->transport->write_send(state, state->ev,
576 state->data + state->num_written,
577 state->size - state->num_written,
578 state->transport->priv);
579 if (tevent_req_nomem(subreq, req)) {
582 tevent_req_set_callback(subreq, rpc_write_done, req);
585 static NTSTATUS rpc_write_recv(struct tevent_req *req)
587 return tevent_req_simple_recv_ntstatus(req);
591 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
592 struct ncacn_packet_header *prhdr,
596 DATA_BLOB blob = data_blob_const(prs_data_p(pdu), prs_data_size(pdu));
599 * This next call sets the endian bit correctly in current_pdu. We
600 * will propagate this to rbuf later.
603 status = dcerpc_pull_ncacn_packet_header(cli, &blob, prhdr);
604 if (!NT_STATUS_IS_OK(status)) {
608 if (!prs_set_offset(pdu, prs_offset(pdu) + RPC_HEADER_LEN)) {
609 return NT_STATUS_BUFFER_TOO_SMALL;
612 if (UNMARSHALLING(pdu) && prhdr->drep[0] == 0) {
613 DEBUG(10,("parse_rpc_header: PDU data format is big-endian. Setting flag.\n"));
614 prs_set_endian_data(pdu, RPC_BIG_ENDIAN);
617 if (prhdr->frag_length > cli->max_recv_frag) {
618 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
619 " we only allow %d\n", (int)prhdr->frag_length,
620 (int)cli->max_recv_frag));
621 return NT_STATUS_BUFFER_TOO_SMALL;
627 /****************************************************************************
628 Try and get a PDU's worth of data from current_pdu. If not, then read more
630 ****************************************************************************/
632 struct get_complete_frag_state {
633 struct event_context *ev;
634 struct rpc_pipe_client *cli;
635 struct ncacn_packet_header *prhdr;
639 static void get_complete_frag_got_header(struct tevent_req *subreq);
640 static void get_complete_frag_got_rest(struct tevent_req *subreq);
642 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
643 struct event_context *ev,
644 struct rpc_pipe_client *cli,
645 struct ncacn_packet_header *prhdr,
648 struct tevent_req *req, *subreq;
649 struct get_complete_frag_state *state;
653 req = tevent_req_create(mem_ctx, &state,
654 struct get_complete_frag_state);
660 state->prhdr = prhdr;
663 pdu_len = prs_data_size(pdu);
664 if (pdu_len < RPC_HEADER_LEN) {
665 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
666 status = NT_STATUS_NO_MEMORY;
669 subreq = rpc_read_send(
671 state->cli->transport,
672 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
673 RPC_HEADER_LEN - pdu_len);
674 if (subreq == NULL) {
675 status = NT_STATUS_NO_MEMORY;
678 tevent_req_set_callback(subreq, get_complete_frag_got_header,
683 status = parse_rpc_header(cli, prhdr, pdu);
684 if (!NT_STATUS_IS_OK(status)) {
689 * Ensure we have frag_len bytes of data.
691 if (pdu_len < prhdr->frag_length) {
692 if (!rpc_grow_buffer(pdu, prhdr->frag_length)) {
693 status = NT_STATUS_NO_MEMORY;
696 subreq = rpc_read_send(state, state->ev,
697 state->cli->transport,
698 (uint8_t *)(prs_data_p(pdu) + pdu_len),
699 prhdr->frag_length - pdu_len);
700 if (subreq == NULL) {
701 status = NT_STATUS_NO_MEMORY;
704 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
709 status = NT_STATUS_OK;
711 if (NT_STATUS_IS_OK(status)) {
712 tevent_req_done(req);
714 tevent_req_nterror(req, status);
716 return tevent_req_post(req, ev);
719 static void get_complete_frag_got_header(struct tevent_req *subreq)
721 struct tevent_req *req = tevent_req_callback_data(
722 subreq, struct tevent_req);
723 struct get_complete_frag_state *state = tevent_req_data(
724 req, struct get_complete_frag_state);
727 status = rpc_read_recv(subreq);
729 if (!NT_STATUS_IS_OK(status)) {
730 tevent_req_nterror(req, status);
734 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
735 if (!NT_STATUS_IS_OK(status)) {
736 tevent_req_nterror(req, status);
740 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_length)) {
741 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
746 * We're here in this piece of code because we've read exactly
747 * RPC_HEADER_LEN bytes into state->pdu.
750 subreq = rpc_read_send(
751 state, state->ev, state->cli->transport,
752 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
753 state->prhdr->frag_length - RPC_HEADER_LEN);
754 if (tevent_req_nomem(subreq, req)) {
757 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
760 static void get_complete_frag_got_rest(struct tevent_req *subreq)
762 struct tevent_req *req = tevent_req_callback_data(
763 subreq, struct tevent_req);
766 status = rpc_read_recv(subreq);
768 if (!NT_STATUS_IS_OK(status)) {
769 tevent_req_nterror(req, status);
772 tevent_req_done(req);
775 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
777 return tevent_req_simple_recv_ntstatus(req);
780 /****************************************************************************
781 NTLMSSP specific sign/seal.
782 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
783 In fact I should probably abstract these into identical pieces of code... JRA.
784 ****************************************************************************/
786 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
787 struct ncacn_packet_header *prhdr,
788 prs_struct *current_pdu,
789 uint8 *p_ss_padding_len)
791 struct dcerpc_auth auth_info;
792 uint32 save_offset = prs_offset(current_pdu);
793 uint32_t auth_len = prhdr->auth_length;
794 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
795 unsigned char *data = NULL;
797 unsigned char *full_packet_data = NULL;
798 size_t full_packet_data_len;
803 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
804 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
808 if (!ntlmssp_state) {
809 return NT_STATUS_INVALID_PARAMETER;
812 /* Ensure there's enough data for an authenticated response. */
813 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
814 prhdr->frag_length < RPC_HEADER_LEN +
816 RPC_HDR_AUTH_LEN + auth_len) {
817 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
818 (unsigned int)auth_len ));
819 return NT_STATUS_BUFFER_TOO_SMALL;
823 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
824 * after the RPC header.
825 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
826 * functions as NTLMv2 checks the rpc headers also.
829 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
830 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
832 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
833 full_packet_data_len = prhdr->frag_length - auth_len;
835 /* Pull the auth header and the following data into a blob. */
836 /* NB. The offset of the auth_header is relative to the *end*
837 * of the packet, not the start. */
838 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
839 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
840 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
841 return NT_STATUS_BUFFER_TOO_SMALL;
844 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu),
845 prs_data_size(current_pdu) - prs_offset(current_pdu));
847 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
848 if (!NT_STATUS_IS_OK(status)) {
849 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
853 /* Ensure auth_pad_len fits into the packet. */
854 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
855 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
856 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
857 "too large (%u), auth_len (%u), frag_len = (%u).\n",
858 (unsigned int)auth_info.auth_pad_length,
859 (unsigned int)auth_len,
860 (unsigned int)prhdr->frag_length));
861 return NT_STATUS_BUFFER_TOO_SMALL;
865 auth_blob = auth_info.credentials;
867 switch (cli->auth->auth_level) {
868 case DCERPC_AUTH_LEVEL_PRIVACY:
869 /* Data is encrypted. */
870 status = ntlmssp_unseal_packet(ntlmssp_state,
873 full_packet_data_len,
875 if (!NT_STATUS_IS_OK(status)) {
876 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
877 "packet from %s. Error was %s.\n",
878 rpccli_pipe_txt(talloc_tos(), cli),
879 nt_errstr(status) ));
883 case DCERPC_AUTH_LEVEL_INTEGRITY:
884 /* Data is signed. */
885 status = ntlmssp_check_packet(ntlmssp_state,
888 full_packet_data_len,
890 if (!NT_STATUS_IS_OK(status)) {
891 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
892 "packet from %s. Error was %s.\n",
893 rpccli_pipe_txt(talloc_tos(), cli),
894 nt_errstr(status) ));
899 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
900 "auth level %d\n", cli->auth->auth_level));
901 return NT_STATUS_INVALID_INFO_CLASS;
905 * Return the current pointer to the data offset.
908 if(!prs_set_offset(current_pdu, save_offset)) {
909 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
910 (unsigned int)save_offset ));
911 return NT_STATUS_BUFFER_TOO_SMALL;
915 * Remember the padding length. We must remove it from the real data
916 * stream once the sign/seal is done.
919 *p_ss_padding_len = auth_info.auth_pad_length;
924 /****************************************************************************
925 schannel specific sign/seal.
926 ****************************************************************************/
928 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
929 struct ncacn_packet_header *prhdr,
930 prs_struct *current_pdu,
931 uint8 *p_ss_padding_len)
933 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 ********************************************************************/
1759 static NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1760 enum dcerpc_AuthType auth_type,
1761 enum dcerpc_AuthLevel auth_level,
1762 uint8_t auth_pad_length,
1763 uint32_t auth_context_id,
1764 const DATA_BLOB *credentials,
1767 struct dcerpc_auth r;
1768 enum ndr_err_code ndr_err;
1770 r.auth_type = auth_type;
1771 r.auth_level = auth_level;
1772 r.auth_pad_length = auth_pad_length;
1773 r.auth_reserved = 0;
1774 r.auth_context_id = auth_context_id;
1775 r.credentials = *credentials;
1777 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1778 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1779 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1780 return ndr_map_error2ntstatus(ndr_err);
1783 if (DEBUGLEVEL >= 10) {
1784 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1787 return NT_STATUS_OK;
1790 /*******************************************************************
1791 Creates krb5 auth bind.
1792 ********************************************************************/
1794 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1795 enum dcerpc_AuthLevel auth_level,
1796 DATA_BLOB *auth_info)
1801 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1802 DATA_BLOB tkt = data_blob_null;
1803 DATA_BLOB tkt_wrapped = data_blob_null;
1805 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1806 a->service_principal ));
1808 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1810 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1811 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1814 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1816 a->service_principal,
1817 error_message(ret) ));
1819 data_blob_free(&tkt);
1820 return NT_STATUS_INVALID_PARAMETER;
1823 /* wrap that up in a nice GSS-API wrapping */
1824 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1826 data_blob_free(&tkt);
1828 status = dcerpc_push_dcerpc_auth(cli,
1829 DCERPC_AUTH_TYPE_KRB5,
1831 0, /* auth_pad_length */
1832 1, /* auth_context_id */
1835 if (!NT_STATUS_IS_OK(status)) {
1836 data_blob_free(&tkt_wrapped);
1840 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1841 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1843 return NT_STATUS_OK;
1845 return NT_STATUS_INVALID_PARAMETER;
1849 /*******************************************************************
1850 Creates SPNEGO NTLMSSP auth bind.
1851 ********************************************************************/
1853 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1854 enum dcerpc_AuthLevel auth_level,
1855 DATA_BLOB *auth_info)
1858 DATA_BLOB null_blob = data_blob_null;
1859 DATA_BLOB request = data_blob_null;
1860 DATA_BLOB spnego_msg = data_blob_null;
1862 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1863 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1867 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1868 data_blob_free(&request);
1872 /* Wrap this in SPNEGO. */
1873 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1875 data_blob_free(&request);
1877 status = dcerpc_push_dcerpc_auth(cli,
1878 DCERPC_AUTH_TYPE_SPNEGO,
1880 0, /* auth_pad_length */
1881 1, /* auth_context_id */
1884 if (!NT_STATUS_IS_OK(status)) {
1885 data_blob_free(&spnego_msg);
1889 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1890 dump_data(5, spnego_msg.data, spnego_msg.length);
1892 return NT_STATUS_OK;
1895 /*******************************************************************
1896 Creates NTLMSSP auth bind.
1897 ********************************************************************/
1899 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1900 enum dcerpc_AuthLevel auth_level,
1901 DATA_BLOB *auth_info)
1904 DATA_BLOB null_blob = data_blob_null;
1905 DATA_BLOB request = data_blob_null;
1907 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1908 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1912 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1913 data_blob_free(&request);
1917 status = dcerpc_push_dcerpc_auth(cli,
1918 DCERPC_AUTH_TYPE_NTLMSSP,
1920 0, /* auth_pad_length */
1921 1, /* auth_context_id */
1924 if (!NT_STATUS_IS_OK(status)) {
1925 data_blob_free(&request);
1929 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1930 dump_data(5, request.data, request.length);
1932 return NT_STATUS_OK;
1935 /*******************************************************************
1936 Creates schannel auth bind.
1937 ********************************************************************/
1939 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1940 enum dcerpc_AuthLevel auth_level,
1941 DATA_BLOB *auth_info)
1944 struct NL_AUTH_MESSAGE r;
1945 DATA_BLOB schannel_blob;
1947 /* Use lp_workgroup() if domain not specified */
1949 if (!cli->auth->domain || !cli->auth->domain[0]) {
1950 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1951 if (cli->auth->domain == NULL) {
1952 return NT_STATUS_NO_MEMORY;
1957 * Now marshall the data into the auth parse_struct.
1960 r.MessageType = NL_NEGOTIATE_REQUEST;
1961 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1962 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1963 r.oem_netbios_domain.a = cli->auth->domain;
1964 r.oem_netbios_computer.a = global_myname();
1966 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1967 if (!NT_STATUS_IS_OK(status)) {
1971 status = dcerpc_push_dcerpc_auth(cli,
1972 DCERPC_AUTH_TYPE_SCHANNEL,
1974 0, /* auth_pad_length */
1975 1, /* auth_context_id */
1978 if (!NT_STATUS_IS_OK(status)) {
1982 return NT_STATUS_OK;
1985 /*******************************************************************
1986 ********************************************************************/
1988 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1989 const struct ndr_syntax_id *abstract_syntax,
1990 const struct ndr_syntax_id *transfer_syntax,
1991 struct dcerpc_ctx_list **ctx_list_p)
1993 struct dcerpc_ctx_list *ctx_list;
1995 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1996 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1998 ctx_list[0].context_id = 0;
1999 ctx_list[0].num_transfer_syntaxes = 1;
2000 ctx_list[0].abstract_syntax = *abstract_syntax;
2001 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
2002 struct ndr_syntax_id,
2003 ctx_list[0].num_transfer_syntaxes);
2004 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
2005 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
2007 *ctx_list_p = ctx_list;
2009 return NT_STATUS_OK;
2012 /*******************************************************************
2013 Creates the internals of a DCE/RPC bind request or alter context PDU.
2014 ********************************************************************/
2016 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2017 prs_struct *rpc_out,
2019 const struct ndr_syntax_id *abstract,
2020 const struct ndr_syntax_id *transfer,
2021 const DATA_BLOB *auth_info)
2023 uint16 auth_len = auth_info->length;
2024 uint16 frag_len = 0;
2026 union dcerpc_payload u;
2028 struct dcerpc_ctx_list *ctx_list;
2030 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2032 if (!NT_STATUS_IS_OK(status)) {
2036 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2037 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2038 u.bind.assoc_group_id = 0x0;
2039 u.bind.num_contexts = 1;
2040 u.bind.ctx_list = ctx_list;
2041 u.bind.auth_info = *auth_info;
2043 /* Start building the frag length. */
2044 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind) + auth_len;
2046 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2048 DCERPC_PFC_FLAG_FIRST |
2049 DCERPC_PFC_FLAG_LAST,
2051 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2055 if (!NT_STATUS_IS_OK(status)) {
2056 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2060 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2061 return NT_STATUS_NO_MEMORY;
2064 return NT_STATUS_OK;
2067 /*******************************************************************
2068 Creates a DCE/RPC bind request.
2069 ********************************************************************/
2071 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2072 prs_struct *rpc_out,
2074 const struct ndr_syntax_id *abstract,
2075 const struct ndr_syntax_id *transfer,
2076 enum pipe_auth_type auth_type,
2077 enum dcerpc_AuthLevel auth_level)
2079 DATA_BLOB auth_info = data_blob_null;
2080 NTSTATUS ret = NT_STATUS_OK;
2082 switch (auth_type) {
2083 case PIPE_AUTH_TYPE_SCHANNEL:
2084 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2085 if (!NT_STATUS_IS_OK(ret)) {
2090 case PIPE_AUTH_TYPE_NTLMSSP:
2091 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2092 if (!NT_STATUS_IS_OK(ret)) {
2097 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2098 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2099 if (!NT_STATUS_IS_OK(ret)) {
2104 case PIPE_AUTH_TYPE_KRB5:
2105 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2106 if (!NT_STATUS_IS_OK(ret)) {
2111 case PIPE_AUTH_TYPE_NONE:
2115 /* "Can't" happen. */
2116 return NT_STATUS_INVALID_INFO_CLASS;
2119 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2128 /*******************************************************************
2129 Create and add the NTLMSSP sign/seal auth header and data.
2130 ********************************************************************/
2132 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2133 uint32 ss_padding_len,
2134 prs_struct *outgoing_pdu)
2136 RPC_HDR_AUTH auth_info;
2138 DATA_BLOB auth_blob = data_blob_null;
2139 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2142 if (!cli->auth->a_u.ntlmssp_state) {
2143 return NT_STATUS_INVALID_PARAMETER;
2146 frame = talloc_stackframe();
2148 /* Init and marshall the auth header. */
2149 init_rpc_hdr_auth(&auth_info,
2150 map_pipe_auth_type_to_rpc_auth_type(
2151 cli->auth->auth_type),
2152 cli->auth->auth_level,
2154 1 /* context id. */);
2156 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2157 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2159 return NT_STATUS_NO_MEMORY;
2162 switch (cli->auth->auth_level) {
2163 case DCERPC_AUTH_LEVEL_PRIVACY:
2164 /* Data portion is encrypted. */
2165 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2167 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2169 (unsigned char *)prs_data_p(outgoing_pdu),
2170 (size_t)prs_offset(outgoing_pdu),
2172 if (!NT_STATUS_IS_OK(status)) {
2178 case DCERPC_AUTH_LEVEL_INTEGRITY:
2179 /* Data is signed. */
2180 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2182 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2184 (unsigned char *)prs_data_p(outgoing_pdu),
2185 (size_t)prs_offset(outgoing_pdu),
2187 if (!NT_STATUS_IS_OK(status)) {
2195 smb_panic("bad auth level");
2197 return NT_STATUS_INVALID_PARAMETER;
2200 /* Finally marshall the blob. */
2202 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2203 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2204 (unsigned int)NTLMSSP_SIG_SIZE));
2206 return NT_STATUS_NO_MEMORY;
2210 return NT_STATUS_OK;
2213 /*******************************************************************
2214 Create and add the schannel sign/seal auth header and data.
2215 ********************************************************************/
2217 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2218 uint32 ss_padding_len,
2219 prs_struct *outgoing_pdu)
2221 RPC_HDR_AUTH auth_info;
2222 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2223 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2224 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2229 return NT_STATUS_INVALID_PARAMETER;
2232 /* Init and marshall the auth header. */
2233 init_rpc_hdr_auth(&auth_info,
2234 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2235 cli->auth->auth_level,
2237 1 /* context id. */);
2239 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2240 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2241 return NT_STATUS_NO_MEMORY;
2244 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2247 switch (cli->auth->auth_level) {
2248 case DCERPC_AUTH_LEVEL_PRIVACY:
2249 status = netsec_outgoing_packet(sas,
2256 case DCERPC_AUTH_LEVEL_INTEGRITY:
2257 status = netsec_outgoing_packet(sas,
2265 status = NT_STATUS_INTERNAL_ERROR;
2269 if (!NT_STATUS_IS_OK(status)) {
2270 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2271 nt_errstr(status)));
2275 if (DEBUGLEVEL >= 10) {
2276 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2279 /* Finally marshall the blob. */
2280 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2281 return NT_STATUS_NO_MEMORY;
2284 return NT_STATUS_OK;
2287 /*******************************************************************
2288 Calculate how much data we're going to send in this packet, also
2289 work out any sign/seal padding length.
2290 ********************************************************************/
2292 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2296 uint32 *p_ss_padding)
2298 uint32 data_space, data_len;
2301 if ((data_left > 0) && (sys_random() % 2)) {
2302 data_left = MAX(data_left/2, 1);
2306 switch (cli->auth->auth_level) {
2307 case DCERPC_AUTH_LEVEL_NONE:
2308 case DCERPC_AUTH_LEVEL_CONNECT:
2309 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2310 data_len = MIN(data_space, data_left);
2313 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2316 case DCERPC_AUTH_LEVEL_INTEGRITY:
2317 case DCERPC_AUTH_LEVEL_PRIVACY:
2318 /* Treat the same for all authenticated rpc requests. */
2319 switch(cli->auth->auth_type) {
2320 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2321 case PIPE_AUTH_TYPE_NTLMSSP:
2322 *p_auth_len = NTLMSSP_SIG_SIZE;
2324 case PIPE_AUTH_TYPE_SCHANNEL:
2325 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2328 smb_panic("bad auth type");
2332 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2333 RPC_HDR_AUTH_LEN - *p_auth_len;
2335 data_len = MIN(data_space, data_left);
2337 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2338 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2340 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2341 data_len + *p_ss_padding + /* data plus padding. */
2342 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2346 smb_panic("bad auth level");
2352 /*******************************************************************
2354 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2355 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2356 and deals with signing/sealing details.
2357 ********************************************************************/
2359 struct rpc_api_pipe_req_state {
2360 struct event_context *ev;
2361 struct rpc_pipe_client *cli;
2364 prs_struct *req_data;
2365 uint32_t req_data_sent;
2366 prs_struct outgoing_frag;
2367 prs_struct reply_pdu;
2370 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2371 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2372 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2373 bool *is_last_frag);
2375 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2376 struct event_context *ev,
2377 struct rpc_pipe_client *cli,
2379 prs_struct *req_data)
2381 struct tevent_req *req, *subreq;
2382 struct rpc_api_pipe_req_state *state;
2386 req = tevent_req_create(mem_ctx, &state,
2387 struct rpc_api_pipe_req_state);
2393 state->op_num = op_num;
2394 state->req_data = req_data;
2395 state->req_data_sent = 0;
2396 state->call_id = get_rpc_call_id();
2398 if (cli->max_xmit_frag
2399 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2400 /* Server is screwed up ! */
2401 status = NT_STATUS_INVALID_PARAMETER;
2405 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2407 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2412 status = prepare_next_frag(state, &is_last_frag);
2413 if (!NT_STATUS_IS_OK(status)) {
2418 subreq = rpc_api_pipe_send(state, ev, state->cli,
2419 &state->outgoing_frag,
2420 DCERPC_PKT_RESPONSE);
2421 if (subreq == NULL) {
2424 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2426 subreq = rpc_write_send(
2427 state, ev, cli->transport,
2428 (uint8_t *)prs_data_p(&state->outgoing_frag),
2429 prs_offset(&state->outgoing_frag));
2430 if (subreq == NULL) {
2433 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2439 tevent_req_nterror(req, status);
2440 return tevent_req_post(req, ev);
2446 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2449 uint32_t data_sent_thistime;
2453 uint32_t ss_padding;
2455 char pad[8] = { 0, };
2457 union dcerpc_payload u;
2460 data_left = prs_offset(state->req_data) - state->req_data_sent;
2462 data_sent_thistime = calculate_data_len_tosend(
2463 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2465 if (state->req_data_sent == 0) {
2466 flags = DCERPC_PFC_FLAG_FIRST;
2469 if (data_sent_thistime == data_left) {
2470 flags |= DCERPC_PFC_FLAG_LAST;
2473 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2474 return NT_STATUS_NO_MEMORY;
2477 ZERO_STRUCT(u.request);
2479 u.request.alloc_hint = prs_offset(state->req_data);
2480 u.request.context_id = 0;
2481 u.request.opnum = state->op_num;
2483 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2491 if (!NT_STATUS_IS_OK(status)) {
2495 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2496 return NT_STATUS_NO_MEMORY;
2499 /* Copy in the data, plus any ss padding. */
2500 if (!prs_append_some_prs_data(&state->outgoing_frag,
2501 state->req_data, state->req_data_sent,
2502 data_sent_thistime)) {
2503 return NT_STATUS_NO_MEMORY;
2506 /* Copy the sign/seal padding data. */
2507 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2508 return NT_STATUS_NO_MEMORY;
2511 /* Generate any auth sign/seal and add the auth footer. */
2512 switch (state->cli->auth->auth_type) {
2513 case PIPE_AUTH_TYPE_NONE:
2514 status = NT_STATUS_OK;
2516 case PIPE_AUTH_TYPE_NTLMSSP:
2517 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2518 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2519 &state->outgoing_frag);
2521 case PIPE_AUTH_TYPE_SCHANNEL:
2522 status = add_schannel_auth_footer(state->cli, ss_padding,
2523 &state->outgoing_frag);
2526 status = NT_STATUS_INVALID_PARAMETER;
2530 state->req_data_sent += data_sent_thistime;
2531 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2536 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2538 struct tevent_req *req = tevent_req_callback_data(
2539 subreq, struct tevent_req);
2540 struct rpc_api_pipe_req_state *state = tevent_req_data(
2541 req, struct rpc_api_pipe_req_state);
2545 status = rpc_write_recv(subreq);
2546 TALLOC_FREE(subreq);
2547 if (!NT_STATUS_IS_OK(status)) {
2548 tevent_req_nterror(req, status);
2552 status = prepare_next_frag(state, &is_last_frag);
2553 if (!NT_STATUS_IS_OK(status)) {
2554 tevent_req_nterror(req, status);
2559 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2560 &state->outgoing_frag,
2561 DCERPC_PKT_RESPONSE);
2562 if (tevent_req_nomem(subreq, req)) {
2565 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2567 subreq = rpc_write_send(
2569 state->cli->transport,
2570 (uint8_t *)prs_data_p(&state->outgoing_frag),
2571 prs_offset(&state->outgoing_frag));
2572 if (tevent_req_nomem(subreq, req)) {
2575 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2580 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2582 struct tevent_req *req = tevent_req_callback_data(
2583 subreq, struct tevent_req);
2584 struct rpc_api_pipe_req_state *state = tevent_req_data(
2585 req, struct rpc_api_pipe_req_state);
2588 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2589 TALLOC_FREE(subreq);
2590 if (!NT_STATUS_IS_OK(status)) {
2591 tevent_req_nterror(req, status);
2594 tevent_req_done(req);
2597 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2598 prs_struct *reply_pdu)
2600 struct rpc_api_pipe_req_state *state = tevent_req_data(
2601 req, struct rpc_api_pipe_req_state);
2604 if (tevent_req_is_nterror(req, &status)) {
2606 * We always have to initialize to reply pdu, even if there is
2607 * none. The rpccli_* caller routines expect this.
2609 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2613 *reply_pdu = state->reply_pdu;
2614 reply_pdu->mem_ctx = mem_ctx;
2617 * Prevent state->req_pdu from being freed
2618 * when state is freed.
2620 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2621 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2623 return NT_STATUS_OK;
2627 /****************************************************************************
2628 Set the handle state.
2629 ****************************************************************************/
2631 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2632 const char *pipe_name, uint16 device_state)
2634 bool state_set = False;
2636 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2637 char *rparam = NULL;
2639 uint32 rparam_len, rdata_len;
2641 if (pipe_name == NULL)
2644 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2645 cli->fnum, pipe_name, device_state));
2647 /* create parameters: device state */
2648 SSVAL(param, 0, device_state);
2650 /* create setup parameters. */
2652 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2654 /* send the data on \PIPE\ */
2655 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2656 setup, 2, 0, /* setup, length, max */
2657 param, 2, 0, /* param, length, max */
2658 NULL, 0, 1024, /* data, length, max */
2659 &rparam, &rparam_len, /* return param, length */
2660 &rdata, &rdata_len)) /* return data, length */
2662 DEBUG(5, ("Set Handle state: return OK\n"));
2673 /****************************************************************************
2674 Check the rpc bind acknowledge response.
2675 ****************************************************************************/
2677 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2678 const struct ndr_syntax_id *transfer)
2680 struct dcerpc_ack_ctx ctx;
2682 if (r->secondary_address_size == 0) {
2683 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2686 if (r->num_results < 1 || !r->ctx_list) {
2690 ctx = r->ctx_list[0];
2692 /* check the transfer syntax */
2693 if ((ctx.syntax.if_version != transfer->if_version) ||
2694 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2695 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2699 if (r->num_results != 0x1 || ctx.result != 0) {
2700 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2701 r->num_results, ctx.reason));
2704 DEBUG(5,("check_bind_response: accepted!\n"));
2708 /*******************************************************************
2709 Creates a DCE/RPC bind authentication response.
2710 This is the packet that is sent back to the server once we
2711 have received a BIND-ACK, to finish the third leg of
2712 the authentication handshake.
2713 ********************************************************************/
2715 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2717 enum pipe_auth_type auth_type,
2718 enum dcerpc_AuthLevel auth_level,
2719 DATA_BLOB *pauth_blob,
2720 prs_struct *rpc_out)
2722 uint16_t auth_len = pauth_blob->length;
2723 uint16_t frag_len = 0;
2725 union dcerpc_payload u;
2730 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2731 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2733 0, /* auth_pad_length */
2734 1, /* auth_context_id */
2736 &u.auth3.auth_info);
2737 if (!NT_STATUS_IS_OK(status)) {
2741 /* Start building the frag length. */
2742 frag_len = RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + auth_len;
2744 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2746 DCERPC_PFC_FLAG_FIRST |
2747 DCERPC_PFC_FLAG_LAST,
2749 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2753 if (!NT_STATUS_IS_OK(status)) {
2754 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2758 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2759 return NT_STATUS_NO_MEMORY;
2762 return NT_STATUS_OK;
2765 /*******************************************************************
2766 Creates a DCE/RPC bind alter context authentication request which
2767 may contain a spnego auth blobl
2768 ********************************************************************/
2770 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2771 const struct ndr_syntax_id *abstract,
2772 const struct ndr_syntax_id *transfer,
2773 enum dcerpc_AuthLevel auth_level,
2774 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2775 prs_struct *rpc_out)
2777 DATA_BLOB auth_info;
2780 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2781 DCERPC_AUTH_TYPE_SPNEGO,
2783 0, /* auth_pad_length */
2784 1, /* auth_context_id */
2787 if (!NT_STATUS_IS_OK(status)) {
2792 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2798 if (!NT_STATUS_IS_OK(status)) {
2805 /****************************************************************************
2807 ****************************************************************************/
2809 struct rpc_pipe_bind_state {
2810 struct event_context *ev;
2811 struct rpc_pipe_client *cli;
2813 uint32_t rpc_call_id;
2816 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2817 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2818 struct rpc_pipe_bind_state *state,
2819 struct ncacn_packet *r,
2820 prs_struct *reply_pdu);
2821 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2822 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2823 struct rpc_pipe_bind_state *state,
2824 struct ncacn_packet *r,
2825 prs_struct *reply_pdu);
2826 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2828 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2829 struct event_context *ev,
2830 struct rpc_pipe_client *cli,
2831 struct cli_pipe_auth_data *auth)
2833 struct tevent_req *req, *subreq;
2834 struct rpc_pipe_bind_state *state;
2837 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2842 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2843 rpccli_pipe_txt(talloc_tos(), cli),
2844 (unsigned int)auth->auth_type,
2845 (unsigned int)auth->auth_level ));
2849 state->rpc_call_id = get_rpc_call_id();
2851 prs_init_empty(&state->rpc_out, state, MARSHALL);
2853 cli->auth = talloc_move(cli, &auth);
2855 /* Marshall the outgoing data. */
2856 status = create_rpc_bind_req(cli, &state->rpc_out,
2858 &cli->abstract_syntax,
2859 &cli->transfer_syntax,
2860 cli->auth->auth_type,
2861 cli->auth->auth_level);
2863 if (!NT_STATUS_IS_OK(status)) {
2867 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2868 DCERPC_PKT_BIND_ACK);
2869 if (subreq == NULL) {
2872 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2876 tevent_req_nterror(req, status);
2877 return tevent_req_post(req, ev);
2883 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2885 struct tevent_req *req = tevent_req_callback_data(
2886 subreq, struct tevent_req);
2887 struct rpc_pipe_bind_state *state = tevent_req_data(
2888 req, struct rpc_pipe_bind_state);
2889 prs_struct reply_pdu;
2891 struct ncacn_packet r;
2894 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2895 TALLOC_FREE(subreq);
2896 if (!NT_STATUS_IS_OK(status)) {
2897 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2898 rpccli_pipe_txt(talloc_tos(), state->cli),
2899 nt_errstr(status)));
2900 tevent_req_nterror(req, status);
2904 blob = data_blob_const(prs_data_p(&reply_pdu),
2905 prs_data_size(&reply_pdu));
2907 status = dcerpc_pull_ncacn_packet(talloc_tos(), &blob, &r);
2908 if (!NT_STATUS_IS_OK(status)) {
2909 tevent_req_nterror(req, status);
2913 if (!check_bind_response(&r.u.bind_ack, &state->cli->transfer_syntax)) {
2914 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2915 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2919 state->cli->max_xmit_frag = r.u.bind_ack.max_xmit_frag;
2920 state->cli->max_recv_frag = r.u.bind_ack.max_recv_frag;
2923 * For authenticated binds we may need to do 3 or 4 leg binds.
2926 switch(state->cli->auth->auth_type) {
2928 case PIPE_AUTH_TYPE_NONE:
2929 case PIPE_AUTH_TYPE_SCHANNEL:
2930 /* Bind complete. */
2931 tevent_req_done(req);
2934 case PIPE_AUTH_TYPE_NTLMSSP:
2935 /* Need to send AUTH3 packet - no reply. */
2936 status = rpc_finish_auth3_bind_send(req, state, &r,
2938 if (!NT_STATUS_IS_OK(status)) {
2939 tevent_req_nterror(req, status);
2943 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2944 /* Need to send alter context request and reply. */
2945 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &r,
2947 if (!NT_STATUS_IS_OK(status)) {
2948 tevent_req_nterror(req, status);
2952 case PIPE_AUTH_TYPE_KRB5:
2956 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2957 (unsigned int)state->cli->auth->auth_type));
2958 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2962 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2963 struct rpc_pipe_bind_state *state,
2964 struct ncacn_packet *r,
2965 prs_struct *reply_pdu)
2967 DATA_BLOB server_response = data_blob_null;
2968 DATA_BLOB client_reply = data_blob_null;
2969 struct rpc_hdr_auth_info hdr_auth;
2970 struct tevent_req *subreq;
2973 if ((r->auth_length == 0)
2974 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
2975 return NT_STATUS_INVALID_PARAMETER;
2978 if (!prs_set_offset(
2980 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
2981 return NT_STATUS_INVALID_PARAMETER;
2984 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2985 return NT_STATUS_INVALID_PARAMETER;
2988 /* TODO - check auth_type/auth_level match. */
2990 server_response = data_blob_talloc(talloc_tos(), NULL, r->auth_length);
2991 prs_copy_data_out((char *)server_response.data, reply_pdu,
2994 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2995 server_response, &client_reply);
2997 if (!NT_STATUS_IS_OK(status)) {
2998 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2999 "blob failed: %s.\n", nt_errstr(status)));
3003 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
3005 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
3006 state->cli->auth->auth_type,
3007 state->cli->auth->auth_level,
3008 &client_reply, &state->rpc_out);
3009 data_blob_free(&client_reply);
3011 if (!NT_STATUS_IS_OK(status)) {
3015 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3016 (uint8_t *)prs_data_p(&state->rpc_out),
3017 prs_offset(&state->rpc_out));
3018 if (subreq == NULL) {
3019 return NT_STATUS_NO_MEMORY;
3021 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3022 return NT_STATUS_OK;
3025 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3027 struct tevent_req *req = tevent_req_callback_data(
3028 subreq, struct tevent_req);
3031 status = rpc_write_recv(subreq);
3032 TALLOC_FREE(subreq);
3033 if (!NT_STATUS_IS_OK(status)) {
3034 tevent_req_nterror(req, status);
3037 tevent_req_done(req);
3040 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3041 struct rpc_pipe_bind_state *state,
3042 struct ncacn_packet *r,
3043 prs_struct *reply_pdu)
3045 DATA_BLOB server_spnego_response = data_blob_null;
3046 DATA_BLOB server_ntlm_response = data_blob_null;
3047 DATA_BLOB client_reply = data_blob_null;
3048 DATA_BLOB tmp_blob = data_blob_null;
3049 RPC_HDR_AUTH hdr_auth;
3050 struct tevent_req *subreq;
3053 if ((r->auth_length == 0)
3054 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3055 return NT_STATUS_INVALID_PARAMETER;
3058 /* Process the returned NTLMSSP blob first. */
3059 if (!prs_set_offset(
3061 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3062 return NT_STATUS_INVALID_PARAMETER;
3065 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3066 return NT_STATUS_INVALID_PARAMETER;
3069 server_spnego_response = data_blob(NULL, r->auth_length);
3070 prs_copy_data_out((char *)server_spnego_response.data,
3071 reply_pdu, r->auth_length);
3074 * The server might give us back two challenges - tmp_blob is for the
3077 if (!spnego_parse_challenge(server_spnego_response,
3078 &server_ntlm_response, &tmp_blob)) {
3079 data_blob_free(&server_spnego_response);
3080 data_blob_free(&server_ntlm_response);
3081 data_blob_free(&tmp_blob);
3082 return NT_STATUS_INVALID_PARAMETER;
3085 /* We're finished with the server spnego response and the tmp_blob. */
3086 data_blob_free(&server_spnego_response);
3087 data_blob_free(&tmp_blob);
3089 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3090 server_ntlm_response, &client_reply);
3092 /* Finished with the server_ntlm response */
3093 data_blob_free(&server_ntlm_response);
3095 if (!NT_STATUS_IS_OK(status)) {
3096 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3097 "using server blob failed.\n"));
3098 data_blob_free(&client_reply);
3102 /* SPNEGO wrap the client reply. */
3103 tmp_blob = spnego_gen_auth(client_reply);
3104 data_blob_free(&client_reply);
3105 client_reply = tmp_blob;
3106 tmp_blob = data_blob_null;
3108 /* Now prepare the alter context pdu. */
3109 prs_init_empty(&state->rpc_out, state, MARSHALL);
3111 status = create_rpc_alter_context(state->rpc_call_id,
3112 &state->cli->abstract_syntax,
3113 &state->cli->transfer_syntax,
3114 state->cli->auth->auth_level,
3117 data_blob_free(&client_reply);
3119 if (!NT_STATUS_IS_OK(status)) {
3123 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3124 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3125 if (subreq == NULL) {
3126 return NT_STATUS_NO_MEMORY;
3128 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3129 return NT_STATUS_OK;
3132 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3134 struct tevent_req *req = tevent_req_callback_data(
3135 subreq, struct tevent_req);
3136 struct rpc_pipe_bind_state *state = tevent_req_data(
3137 req, struct rpc_pipe_bind_state);
3138 DATA_BLOB server_spnego_response = data_blob_null;
3139 DATA_BLOB tmp_blob = data_blob_null;
3140 prs_struct reply_pdu;
3141 struct ncacn_packet_header hdr;
3142 struct rpc_hdr_auth_info hdr_auth;
3145 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3146 TALLOC_FREE(subreq);
3147 if (!NT_STATUS_IS_OK(status)) {
3148 tevent_req_nterror(req, status);
3152 status = parse_rpc_header(state->cli, &hdr, &reply_pdu);
3153 if (!NT_STATUS_IS_OK(status)) {
3154 tevent_req_nterror(req, status);
3158 if (!prs_set_offset(
3160 hdr.frag_length - hdr.auth_length - RPC_HDR_AUTH_LEN)) {
3161 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3165 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3166 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3170 server_spnego_response = data_blob(NULL, hdr.auth_length);
3171 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3174 /* Check we got a valid auth response. */
3175 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3176 OID_NTLMSSP, &tmp_blob)) {
3177 data_blob_free(&server_spnego_response);
3178 data_blob_free(&tmp_blob);
3179 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3183 data_blob_free(&server_spnego_response);
3184 data_blob_free(&tmp_blob);
3186 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3187 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3188 tevent_req_done(req);
3191 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3193 return tevent_req_simple_recv_ntstatus(req);
3196 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3197 struct cli_pipe_auth_data *auth)
3199 TALLOC_CTX *frame = talloc_stackframe();
3200 struct event_context *ev;
3201 struct tevent_req *req;
3202 NTSTATUS status = NT_STATUS_OK;
3204 ev = event_context_init(frame);
3206 status = NT_STATUS_NO_MEMORY;
3210 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3212 status = NT_STATUS_NO_MEMORY;
3216 if (!tevent_req_poll(req, ev)) {
3217 status = map_nt_error_from_unix(errno);
3221 status = rpc_pipe_bind_recv(req);
3227 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3229 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3230 unsigned int timeout)
3234 if (rpc_cli->transport == NULL) {
3235 return RPCCLI_DEFAULT_TIMEOUT;
3238 if (rpc_cli->transport->set_timeout == NULL) {
3239 return RPCCLI_DEFAULT_TIMEOUT;
3242 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3244 return RPCCLI_DEFAULT_TIMEOUT;
3250 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3252 if (rpc_cli == NULL) {
3256 if (rpc_cli->transport == NULL) {
3260 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3263 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3265 struct cli_state *cli;
3267 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3268 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3269 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3273 cli = rpc_pipe_np_smb_conn(rpc_cli);
3277 E_md4hash(cli->password ? cli->password : "", nt_hash);
3281 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3282 struct cli_pipe_auth_data **presult)
3284 struct cli_pipe_auth_data *result;
3286 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3287 if (result == NULL) {
3288 return NT_STATUS_NO_MEMORY;
3291 result->auth_type = PIPE_AUTH_TYPE_NONE;
3292 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3294 result->user_name = talloc_strdup(result, "");
3295 result->domain = talloc_strdup(result, "");
3296 if ((result->user_name == NULL) || (result->domain == NULL)) {
3297 TALLOC_FREE(result);
3298 return NT_STATUS_NO_MEMORY;
3302 return NT_STATUS_OK;
3305 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3307 ntlmssp_end(&auth->a_u.ntlmssp_state);
3311 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3312 enum pipe_auth_type auth_type,
3313 enum dcerpc_AuthLevel auth_level,
3315 const char *username,
3316 const char *password,
3317 struct cli_pipe_auth_data **presult)
3319 struct cli_pipe_auth_data *result;
3322 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3323 if (result == NULL) {
3324 return NT_STATUS_NO_MEMORY;
3327 result->auth_type = auth_type;
3328 result->auth_level = auth_level;
3330 result->user_name = talloc_strdup(result, username);
3331 result->domain = talloc_strdup(result, domain);
3332 if ((result->user_name == NULL) || (result->domain == NULL)) {
3333 status = NT_STATUS_NO_MEMORY;
3337 status = ntlmssp_client_start(NULL,
3340 lp_client_ntlmv2_auth(),
3341 &result->a_u.ntlmssp_state);
3342 if (!NT_STATUS_IS_OK(status)) {
3346 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3348 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3349 if (!NT_STATUS_IS_OK(status)) {
3353 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3354 if (!NT_STATUS_IS_OK(status)) {
3358 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3359 if (!NT_STATUS_IS_OK(status)) {
3364 * Turn off sign+seal to allow selected auth level to turn it back on.
3366 result->a_u.ntlmssp_state->neg_flags &=
3367 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3369 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3370 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3371 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3372 result->a_u.ntlmssp_state->neg_flags
3373 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3377 return NT_STATUS_OK;
3380 TALLOC_FREE(result);
3384 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3385 enum dcerpc_AuthLevel auth_level,
3386 struct netlogon_creds_CredentialState *creds,
3387 struct cli_pipe_auth_data **presult)
3389 struct cli_pipe_auth_data *result;
3391 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3392 if (result == NULL) {
3393 return NT_STATUS_NO_MEMORY;
3396 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3397 result->auth_level = auth_level;
3399 result->user_name = talloc_strdup(result, "");
3400 result->domain = talloc_strdup(result, domain);
3401 if ((result->user_name == NULL) || (result->domain == NULL)) {
3405 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3406 if (result->a_u.schannel_auth == NULL) {
3410 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3411 result->a_u.schannel_auth->seq_num = 0;
3412 result->a_u.schannel_auth->initiator = true;
3413 result->a_u.schannel_auth->creds = creds;
3416 return NT_STATUS_OK;
3419 TALLOC_FREE(result);
3420 return NT_STATUS_NO_MEMORY;
3424 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3426 data_blob_free(&auth->session_key);
3431 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3432 enum dcerpc_AuthLevel auth_level,
3433 const char *service_princ,
3434 const char *username,
3435 const char *password,
3436 struct cli_pipe_auth_data **presult)
3439 struct cli_pipe_auth_data *result;
3441 if ((username != NULL) && (password != NULL)) {
3442 int ret = kerberos_kinit_password(username, password, 0, NULL);
3444 return NT_STATUS_ACCESS_DENIED;
3448 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3449 if (result == NULL) {
3450 return NT_STATUS_NO_MEMORY;
3453 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3454 result->auth_level = auth_level;
3457 * Username / domain need fixing!
3459 result->user_name = talloc_strdup(result, "");
3460 result->domain = talloc_strdup(result, "");
3461 if ((result->user_name == NULL) || (result->domain == NULL)) {
3465 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3466 result, struct kerberos_auth_struct);
3467 if (result->a_u.kerberos_auth == NULL) {
3470 talloc_set_destructor(result->a_u.kerberos_auth,
3471 cli_auth_kerberos_data_destructor);
3473 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3474 result, service_princ);
3475 if (result->a_u.kerberos_auth->service_principal == NULL) {
3480 return NT_STATUS_OK;
3483 TALLOC_FREE(result);
3484 return NT_STATUS_NO_MEMORY;
3486 return NT_STATUS_NOT_SUPPORTED;
3491 * Create an rpc pipe client struct, connecting to a tcp port.
3493 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3495 const struct ndr_syntax_id *abstract_syntax,
3496 struct rpc_pipe_client **presult)
3498 struct rpc_pipe_client *result;
3499 struct sockaddr_storage addr;
3503 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3504 if (result == NULL) {
3505 return NT_STATUS_NO_MEMORY;
3508 result->abstract_syntax = *abstract_syntax;
3509 result->transfer_syntax = ndr_transfer_syntax;
3510 result->dispatch = cli_do_rpc_ndr;
3511 result->dispatch_send = cli_do_rpc_ndr_send;
3512 result->dispatch_recv = cli_do_rpc_ndr_recv;
3514 result->desthost = talloc_strdup(result, host);
3515 result->srv_name_slash = talloc_asprintf_strupper_m(
3516 result, "\\\\%s", result->desthost);
3517 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3518 status = NT_STATUS_NO_MEMORY;
3522 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3523 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3525 if (!resolve_name(host, &addr, 0, false)) {
3526 status = NT_STATUS_NOT_FOUND;
3530 status = open_socket_out(&addr, port, 60, &fd);
3531 if (!NT_STATUS_IS_OK(status)) {
3534 set_socket_options(fd, lp_socket_options());
3536 status = rpc_transport_sock_init(result, fd, &result->transport);
3537 if (!NT_STATUS_IS_OK(status)) {
3542 result->transport->transport = NCACN_IP_TCP;
3545 return NT_STATUS_OK;
3548 TALLOC_FREE(result);
3553 * Determine the tcp port on which a dcerpc interface is listening
3554 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3557 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3558 const struct ndr_syntax_id *abstract_syntax,
3562 struct rpc_pipe_client *epm_pipe = NULL;
3563 struct cli_pipe_auth_data *auth = NULL;
3564 struct dcerpc_binding *map_binding = NULL;
3565 struct dcerpc_binding *res_binding = NULL;
3566 struct epm_twr_t *map_tower = NULL;
3567 struct epm_twr_t *res_towers = NULL;
3568 struct policy_handle *entry_handle = NULL;
3569 uint32_t num_towers = 0;
3570 uint32_t max_towers = 1;
3571 struct epm_twr_p_t towers;
3572 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3574 if (pport == NULL) {
3575 status = NT_STATUS_INVALID_PARAMETER;
3579 /* open the connection to the endpoint mapper */
3580 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3581 &ndr_table_epmapper.syntax_id,
3584 if (!NT_STATUS_IS_OK(status)) {
3588 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3589 if (!NT_STATUS_IS_OK(status)) {
3593 status = rpc_pipe_bind(epm_pipe, auth);
3594 if (!NT_STATUS_IS_OK(status)) {
3598 /* create tower for asking the epmapper */
3600 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3601 if (map_binding == NULL) {
3602 status = NT_STATUS_NO_MEMORY;
3606 map_binding->transport = NCACN_IP_TCP;
3607 map_binding->object = *abstract_syntax;
3608 map_binding->host = host; /* needed? */
3609 map_binding->endpoint = "0"; /* correct? needed? */
3611 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3612 if (map_tower == NULL) {
3613 status = NT_STATUS_NO_MEMORY;
3617 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3618 &(map_tower->tower));
3619 if (!NT_STATUS_IS_OK(status)) {
3623 /* allocate further parameters for the epm_Map call */
3625 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3626 if (res_towers == NULL) {
3627 status = NT_STATUS_NO_MEMORY;
3630 towers.twr = res_towers;
3632 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3633 if (entry_handle == NULL) {
3634 status = NT_STATUS_NO_MEMORY;
3638 /* ask the endpoint mapper for the port */
3640 status = rpccli_epm_Map(epm_pipe,
3642 CONST_DISCARD(struct GUID *,
3643 &(abstract_syntax->uuid)),
3650 if (!NT_STATUS_IS_OK(status)) {
3654 if (num_towers != 1) {
3655 status = NT_STATUS_UNSUCCESSFUL;
3659 /* extract the port from the answer */
3661 status = dcerpc_binding_from_tower(tmp_ctx,
3662 &(towers.twr->tower),
3664 if (!NT_STATUS_IS_OK(status)) {
3668 /* are further checks here necessary? */
3669 if (res_binding->transport != NCACN_IP_TCP) {
3670 status = NT_STATUS_UNSUCCESSFUL;
3674 *pport = (uint16_t)atoi(res_binding->endpoint);
3677 TALLOC_FREE(tmp_ctx);
3682 * Create a rpc pipe client struct, connecting to a host via tcp.
3683 * The port is determined by asking the endpoint mapper on the given
3686 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3687 const struct ndr_syntax_id *abstract_syntax,
3688 struct rpc_pipe_client **presult)
3693 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3694 if (!NT_STATUS_IS_OK(status)) {
3698 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3699 abstract_syntax, presult);
3702 /********************************************************************
3703 Create a rpc pipe client struct, connecting to a unix domain socket
3704 ********************************************************************/
3705 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3706 const struct ndr_syntax_id *abstract_syntax,
3707 struct rpc_pipe_client **presult)
3709 struct rpc_pipe_client *result;
3710 struct sockaddr_un addr;
3714 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3715 if (result == NULL) {
3716 return NT_STATUS_NO_MEMORY;
3719 result->abstract_syntax = *abstract_syntax;
3720 result->transfer_syntax = ndr_transfer_syntax;
3721 result->dispatch = cli_do_rpc_ndr;
3722 result->dispatch_send = cli_do_rpc_ndr_send;
3723 result->dispatch_recv = cli_do_rpc_ndr_recv;
3725 result->desthost = get_myname(result);
3726 result->srv_name_slash = talloc_asprintf_strupper_m(
3727 result, "\\\\%s", result->desthost);
3728 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3729 status = NT_STATUS_NO_MEMORY;
3733 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3734 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3736 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3738 status = map_nt_error_from_unix(errno);
3743 addr.sun_family = AF_UNIX;
3744 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3746 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3747 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3750 return map_nt_error_from_unix(errno);
3753 status = rpc_transport_sock_init(result, fd, &result->transport);
3754 if (!NT_STATUS_IS_OK(status)) {
3759 result->transport->transport = NCALRPC;
3762 return NT_STATUS_OK;
3765 TALLOC_FREE(result);
3769 struct rpc_pipe_client_np_ref {
3770 struct cli_state *cli;
3771 struct rpc_pipe_client *pipe;
3774 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3776 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3780 /****************************************************************************
3781 Open a named pipe over SMB to a remote server.
3783 * CAVEAT CALLER OF THIS FUNCTION:
3784 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3785 * so be sure that this function is called AFTER any structure (vs pointer)
3786 * assignment of the cli. In particular, libsmbclient does structure
3787 * assignments of cli, which invalidates the data in the returned
3788 * rpc_pipe_client if this function is called before the structure assignment
3791 ****************************************************************************/
3793 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3794 const struct ndr_syntax_id *abstract_syntax,
3795 struct rpc_pipe_client **presult)
3797 struct rpc_pipe_client *result;
3799 struct rpc_pipe_client_np_ref *np_ref;
3801 /* sanity check to protect against crashes */
3804 return NT_STATUS_INVALID_HANDLE;
3807 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3808 if (result == NULL) {
3809 return NT_STATUS_NO_MEMORY;
3812 result->abstract_syntax = *abstract_syntax;
3813 result->transfer_syntax = ndr_transfer_syntax;
3814 result->dispatch = cli_do_rpc_ndr;
3815 result->dispatch_send = cli_do_rpc_ndr_send;
3816 result->dispatch_recv = cli_do_rpc_ndr_recv;
3817 result->desthost = talloc_strdup(result, cli->desthost);
3818 result->srv_name_slash = talloc_asprintf_strupper_m(
3819 result, "\\\\%s", result->desthost);
3821 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3822 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3824 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3825 TALLOC_FREE(result);
3826 return NT_STATUS_NO_MEMORY;
3829 status = rpc_transport_np_init(result, cli, abstract_syntax,
3830 &result->transport);
3831 if (!NT_STATUS_IS_OK(status)) {
3832 TALLOC_FREE(result);
3836 result->transport->transport = NCACN_NP;
3838 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3839 if (np_ref == NULL) {
3840 TALLOC_FREE(result);
3841 return NT_STATUS_NO_MEMORY;
3844 np_ref->pipe = result;
3846 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3847 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3850 return NT_STATUS_OK;
3853 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3854 struct rpc_cli_smbd_conn *conn,
3855 const struct ndr_syntax_id *syntax,
3856 struct rpc_pipe_client **presult)
3858 struct rpc_pipe_client *result;
3859 struct cli_pipe_auth_data *auth;
3862 result = talloc(mem_ctx, struct rpc_pipe_client);
3863 if (result == NULL) {
3864 return NT_STATUS_NO_MEMORY;
3866 result->abstract_syntax = *syntax;
3867 result->transfer_syntax = ndr_transfer_syntax;
3868 result->dispatch = cli_do_rpc_ndr;
3869 result->dispatch_send = cli_do_rpc_ndr_send;
3870 result->dispatch_recv = cli_do_rpc_ndr_recv;
3871 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3872 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3874 result->desthost = talloc_strdup(result, global_myname());
3875 result->srv_name_slash = talloc_asprintf_strupper_m(
3876 result, "\\\\%s", global_myname());
3877 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3878 TALLOC_FREE(result);
3879 return NT_STATUS_NO_MEMORY;
3882 status = rpc_transport_smbd_init(result, conn, syntax,
3883 &result->transport);
3884 if (!NT_STATUS_IS_OK(status)) {
3885 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3886 nt_errstr(status)));
3887 TALLOC_FREE(result);
3891 status = rpccli_anon_bind_data(result, &auth);
3892 if (!NT_STATUS_IS_OK(status)) {
3893 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3894 nt_errstr(status)));
3895 TALLOC_FREE(result);
3899 status = rpc_pipe_bind(result, auth);
3900 if (!NT_STATUS_IS_OK(status)) {
3901 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3902 TALLOC_FREE(result);
3906 result->transport->transport = NCACN_INTERNAL;
3909 return NT_STATUS_OK;
3912 /****************************************************************************
3913 Open a pipe to a remote server.
3914 ****************************************************************************/
3916 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3917 enum dcerpc_transport_t transport,
3918 const struct ndr_syntax_id *interface,
3919 struct rpc_pipe_client **presult)
3921 switch (transport) {
3923 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3926 return rpc_pipe_open_np(cli, interface, presult);
3928 return NT_STATUS_NOT_IMPLEMENTED;
3932 /****************************************************************************
3933 Open a named pipe to an SMB server and bind anonymously.
3934 ****************************************************************************/
3936 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3937 enum dcerpc_transport_t transport,
3938 const struct ndr_syntax_id *interface,
3939 struct rpc_pipe_client **presult)
3941 struct rpc_pipe_client *result;
3942 struct cli_pipe_auth_data *auth;
3945 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3946 if (!NT_STATUS_IS_OK(status)) {
3950 status = rpccli_anon_bind_data(result, &auth);
3951 if (!NT_STATUS_IS_OK(status)) {
3952 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3953 nt_errstr(status)));
3954 TALLOC_FREE(result);
3959 * This is a bit of an abstraction violation due to the fact that an
3960 * anonymous bind on an authenticated SMB inherits the user/domain
3961 * from the enclosing SMB creds
3964 TALLOC_FREE(auth->user_name);
3965 TALLOC_FREE(auth->domain);
3967 auth->user_name = talloc_strdup(auth, cli->user_name);
3968 auth->domain = talloc_strdup(auth, cli->domain);
3969 auth->user_session_key = data_blob_talloc(auth,
3970 cli->user_session_key.data,
3971 cli->user_session_key.length);
3973 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3974 TALLOC_FREE(result);
3975 return NT_STATUS_NO_MEMORY;
3978 status = rpc_pipe_bind(result, auth);
3979 if (!NT_STATUS_IS_OK(status)) {
3981 if (ndr_syntax_id_equal(interface,
3982 &ndr_table_dssetup.syntax_id)) {
3983 /* non AD domains just don't have this pipe, avoid
3984 * level 0 statement in that case - gd */
3987 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3988 "%s failed with error %s\n",
3989 get_pipe_name_from_syntax(talloc_tos(), interface),
3990 nt_errstr(status) ));
3991 TALLOC_FREE(result);
3995 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3996 "%s and bound anonymously.\n",
3997 get_pipe_name_from_syntax(talloc_tos(), interface),
4001 return NT_STATUS_OK;
4004 /****************************************************************************
4005 ****************************************************************************/
4007 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4008 const struct ndr_syntax_id *interface,
4009 struct rpc_pipe_client **presult)
4011 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4012 interface, presult);
4015 /****************************************************************************
4016 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4017 ****************************************************************************/
4019 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4020 const struct ndr_syntax_id *interface,
4021 enum dcerpc_transport_t transport,
4022 enum pipe_auth_type auth_type,
4023 enum dcerpc_AuthLevel auth_level,
4025 const char *username,
4026 const char *password,
4027 struct rpc_pipe_client **presult)
4029 struct rpc_pipe_client *result;
4030 struct cli_pipe_auth_data *auth;
4033 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4034 if (!NT_STATUS_IS_OK(status)) {
4038 status = rpccli_ntlmssp_bind_data(
4039 result, auth_type, auth_level, domain, username,
4041 if (!NT_STATUS_IS_OK(status)) {
4042 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4043 nt_errstr(status)));
4047 status = rpc_pipe_bind(result, auth);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4050 nt_errstr(status) ));
4054 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4055 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4056 get_pipe_name_from_syntax(talloc_tos(), interface),
4057 cli->desthost, domain, username ));
4060 return NT_STATUS_OK;
4064 TALLOC_FREE(result);
4068 /****************************************************************************
4070 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4071 ****************************************************************************/
4073 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4074 const struct ndr_syntax_id *interface,
4075 enum dcerpc_transport_t transport,
4076 enum dcerpc_AuthLevel auth_level,
4078 const char *username,
4079 const char *password,
4080 struct rpc_pipe_client **presult)
4082 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4085 PIPE_AUTH_TYPE_NTLMSSP,
4093 /****************************************************************************
4095 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4096 ****************************************************************************/
4098 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4099 const struct ndr_syntax_id *interface,
4100 enum dcerpc_transport_t transport,
4101 enum dcerpc_AuthLevel auth_level,
4103 const char *username,
4104 const char *password,
4105 struct rpc_pipe_client **presult)
4107 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4110 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4118 /****************************************************************************
4119 Get a the schannel session key out of an already opened netlogon pipe.
4120 ****************************************************************************/
4121 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4122 struct cli_state *cli,
4126 enum netr_SchannelType sec_chan_type = 0;
4127 unsigned char machine_pwd[16];
4128 const char *machine_account;
4131 /* Get the machine account credentials from secrets.tdb. */
4132 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4135 DEBUG(0, ("get_schannel_session_key: could not fetch "
4136 "trust account password for domain '%s'\n",
4138 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4141 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4142 cli->desthost, /* server name */
4143 domain, /* domain */
4144 global_myname(), /* client name */
4145 machine_account, /* machine account name */
4150 if (!NT_STATUS_IS_OK(status)) {
4151 DEBUG(3, ("get_schannel_session_key_common: "
4152 "rpccli_netlogon_setup_creds failed with result %s "
4153 "to server %s, domain %s, machine account %s.\n",
4154 nt_errstr(status), cli->desthost, domain,
4159 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4160 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4162 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4165 return NT_STATUS_OK;;
4168 /****************************************************************************
4169 Open a netlogon pipe and get the schannel session key.
4170 Now exposed to external callers.
4171 ****************************************************************************/
4174 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4177 struct rpc_pipe_client **presult)
4179 struct rpc_pipe_client *netlogon_pipe = NULL;
4182 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4184 if (!NT_STATUS_IS_OK(status)) {
4188 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4190 if (!NT_STATUS_IS_OK(status)) {
4191 TALLOC_FREE(netlogon_pipe);
4195 *presult = netlogon_pipe;
4196 return NT_STATUS_OK;
4199 /****************************************************************************
4201 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4202 using session_key. sign and seal.
4204 The *pdc will be stolen onto this new pipe
4205 ****************************************************************************/
4207 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4208 const struct ndr_syntax_id *interface,
4209 enum dcerpc_transport_t transport,
4210 enum dcerpc_AuthLevel auth_level,
4212 struct netlogon_creds_CredentialState **pdc,
4213 struct rpc_pipe_client **presult)
4215 struct rpc_pipe_client *result;
4216 struct cli_pipe_auth_data *auth;
4219 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4220 if (!NT_STATUS_IS_OK(status)) {
4224 status = rpccli_schannel_bind_data(result, domain, auth_level,
4226 if (!NT_STATUS_IS_OK(status)) {
4227 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4228 nt_errstr(status)));
4229 TALLOC_FREE(result);
4233 status = rpc_pipe_bind(result, auth);
4234 if (!NT_STATUS_IS_OK(status)) {
4235 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4236 "cli_rpc_pipe_bind failed with error %s\n",
4237 nt_errstr(status) ));
4238 TALLOC_FREE(result);
4243 * The credentials on a new netlogon pipe are the ones we are passed
4244 * in - reference them in
4246 result->dc = talloc_move(result, pdc);
4248 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4249 "for domain %s and bound using schannel.\n",
4250 get_pipe_name_from_syntax(talloc_tos(), interface),
4251 cli->desthost, domain ));
4254 return NT_STATUS_OK;
4257 /****************************************************************************
4258 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4259 Fetch the session key ourselves using a temporary netlogon pipe. This
4260 version uses an ntlmssp auth bound netlogon pipe to get the key.
4261 ****************************************************************************/
4263 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4265 const char *username,
4266 const char *password,
4268 struct rpc_pipe_client **presult)
4270 struct rpc_pipe_client *netlogon_pipe = NULL;
4273 status = cli_rpc_pipe_open_spnego_ntlmssp(
4274 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4275 DCERPC_AUTH_LEVEL_PRIVACY,
4276 domain, username, password, &netlogon_pipe);
4277 if (!NT_STATUS_IS_OK(status)) {
4281 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4283 if (!NT_STATUS_IS_OK(status)) {
4284 TALLOC_FREE(netlogon_pipe);
4288 *presult = netlogon_pipe;
4289 return NT_STATUS_OK;
4292 /****************************************************************************
4293 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4294 Fetch the session key ourselves using a temporary netlogon pipe. This version
4295 uses an ntlmssp bind to get the session key.
4296 ****************************************************************************/
4298 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4299 const struct ndr_syntax_id *interface,
4300 enum dcerpc_transport_t transport,
4301 enum dcerpc_AuthLevel auth_level,
4303 const char *username,
4304 const char *password,
4305 struct rpc_pipe_client **presult)
4307 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4308 struct rpc_pipe_client *netlogon_pipe = NULL;
4309 struct rpc_pipe_client *result = NULL;
4312 status = get_schannel_session_key_auth_ntlmssp(
4313 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4314 if (!NT_STATUS_IS_OK(status)) {
4315 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4316 "key from server %s for domain %s.\n",
4317 cli->desthost, domain ));
4321 status = cli_rpc_pipe_open_schannel_with_key(
4322 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4325 /* Now we've bound using the session key we can close the netlog pipe. */
4326 TALLOC_FREE(netlogon_pipe);
4328 if (NT_STATUS_IS_OK(status)) {
4334 /****************************************************************************
4335 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4336 Fetch the session key ourselves using a temporary netlogon pipe.
4337 ****************************************************************************/
4339 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4340 const struct ndr_syntax_id *interface,
4341 enum dcerpc_transport_t transport,
4342 enum dcerpc_AuthLevel auth_level,
4344 struct rpc_pipe_client **presult)
4346 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4347 struct rpc_pipe_client *netlogon_pipe = NULL;
4348 struct rpc_pipe_client *result = NULL;
4351 status = get_schannel_session_key(cli, domain, &neg_flags,
4353 if (!NT_STATUS_IS_OK(status)) {
4354 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4355 "key from server %s for domain %s.\n",
4356 cli->desthost, domain ));
4360 status = cli_rpc_pipe_open_schannel_with_key(
4361 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4364 /* Now we've bound using the session key we can close the netlog pipe. */
4365 TALLOC_FREE(netlogon_pipe);
4367 if (NT_STATUS_IS_OK(status)) {
4374 /****************************************************************************
4375 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4376 The idea is this can be called with service_princ, username and password all
4377 NULL so long as the caller has a TGT.
4378 ****************************************************************************/
4380 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4381 const struct ndr_syntax_id *interface,
4382 enum dcerpc_AuthLevel auth_level,
4383 const char *service_princ,
4384 const char *username,
4385 const char *password,
4386 struct rpc_pipe_client **presult)
4389 struct rpc_pipe_client *result;
4390 struct cli_pipe_auth_data *auth;
4393 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4394 if (!NT_STATUS_IS_OK(status)) {
4398 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4399 username, password, &auth);
4400 if (!NT_STATUS_IS_OK(status)) {
4401 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4402 nt_errstr(status)));
4403 TALLOC_FREE(result);
4407 status = rpc_pipe_bind(result, auth);
4408 if (!NT_STATUS_IS_OK(status)) {
4409 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4410 "with error %s\n", nt_errstr(status)));
4411 TALLOC_FREE(result);
4416 return NT_STATUS_OK;
4418 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4419 return NT_STATUS_NOT_IMPLEMENTED;
4423 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4424 struct rpc_pipe_client *cli,
4425 DATA_BLOB *session_key)
4427 if (!session_key || !cli) {
4428 return NT_STATUS_INVALID_PARAMETER;
4432 return NT_STATUS_INVALID_PARAMETER;
4435 switch (cli->auth->auth_type) {
4436 case PIPE_AUTH_TYPE_SCHANNEL:
4437 *session_key = data_blob_talloc(mem_ctx,
4438 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4440 case PIPE_AUTH_TYPE_NTLMSSP:
4441 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4442 *session_key = data_blob_talloc(mem_ctx,
4443 cli->auth->a_u.ntlmssp_state->session_key.data,
4444 cli->auth->a_u.ntlmssp_state->session_key.length);
4446 case PIPE_AUTH_TYPE_KRB5:
4447 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4448 *session_key = data_blob_talloc(mem_ctx,
4449 cli->auth->a_u.kerberos_auth->session_key.data,
4450 cli->auth->a_u.kerberos_auth->session_key.length);
4452 case PIPE_AUTH_TYPE_NONE:
4453 *session_key = data_blob_talloc(mem_ctx,
4454 cli->auth->user_session_key.data,
4455 cli->auth->user_session_key.length);
4458 return NT_STATUS_NO_USER_SESSION_KEY;
4461 return NT_STATUS_OK;