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 RPC_HDR_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;
802 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
803 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
807 if (!ntlmssp_state) {
808 return NT_STATUS_INVALID_PARAMETER;
811 /* Ensure there's enough data for an authenticated response. */
812 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
813 prhdr->frag_length < RPC_HEADER_LEN +
815 RPC_HDR_AUTH_LEN + auth_len) {
816 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
817 (unsigned int)auth_len ));
818 return NT_STATUS_BUFFER_TOO_SMALL;
822 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
823 * after the RPC header.
824 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
825 * functions as NTLMv2 checks the rpc headers also.
828 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
829 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
831 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
832 full_packet_data_len = prhdr->frag_length - auth_len;
834 /* Pull the auth header and the following data into a blob. */
835 /* NB. The offset of the auth_header is relative to the *end*
836 * of the packet, not the start. */
837 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
838 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
839 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
840 return NT_STATUS_BUFFER_TOO_SMALL;
843 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
844 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
845 return NT_STATUS_BUFFER_TOO_SMALL;
848 /* Ensure auth_pad_len fits into the packet. */
849 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
850 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
851 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
852 "too large (%u), auth_len (%u), frag_len = (%u).\n",
853 (unsigned int)auth_info.auth_pad_len,
854 (unsigned int)auth_len,
855 (unsigned int)prhdr->frag_length));
856 return NT_STATUS_BUFFER_TOO_SMALL;
860 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
861 auth_blob.length = auth_len;
863 switch (cli->auth->auth_level) {
864 case DCERPC_AUTH_LEVEL_PRIVACY:
865 /* Data is encrypted. */
866 status = ntlmssp_unseal_packet(ntlmssp_state,
869 full_packet_data_len,
871 if (!NT_STATUS_IS_OK(status)) {
872 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
873 "packet from %s. Error was %s.\n",
874 rpccli_pipe_txt(talloc_tos(), cli),
875 nt_errstr(status) ));
879 case DCERPC_AUTH_LEVEL_INTEGRITY:
880 /* Data is signed. */
881 status = ntlmssp_check_packet(ntlmssp_state,
884 full_packet_data_len,
886 if (!NT_STATUS_IS_OK(status)) {
887 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
888 "packet from %s. Error was %s.\n",
889 rpccli_pipe_txt(talloc_tos(), cli),
890 nt_errstr(status) ));
895 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
896 "auth level %d\n", cli->auth->auth_level));
897 return NT_STATUS_INVALID_INFO_CLASS;
901 * Return the current pointer to the data offset.
904 if(!prs_set_offset(current_pdu, save_offset)) {
905 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
906 (unsigned int)save_offset ));
907 return NT_STATUS_BUFFER_TOO_SMALL;
911 * Remember the padding length. We must remove it from the real data
912 * stream once the sign/seal is done.
915 *p_ss_padding_len = auth_info.auth_pad_len;
920 /****************************************************************************
921 schannel specific sign/seal.
922 ****************************************************************************/
924 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
925 struct ncacn_packet_header *prhdr,
926 prs_struct *current_pdu,
927 uint8 *p_ss_padding_len)
929 RPC_HDR_AUTH auth_info;
930 uint32_t auth_len = prhdr->auth_length;
931 uint32 save_offset = prs_offset(current_pdu);
932 struct schannel_state *schannel_auth =
933 cli->auth->a_u.schannel_auth;
939 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
940 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
944 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
945 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
946 return NT_STATUS_INVALID_PARAMETER;
949 if (!schannel_auth) {
950 return NT_STATUS_INVALID_PARAMETER;
953 /* Ensure there's enough data for an authenticated response. */
954 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
955 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length)) {
956 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
957 (unsigned int)auth_len ));
958 return NT_STATUS_INVALID_PARAMETER;
961 data_len = prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
963 /* Pull the auth header and the following data into a blob. */
964 /* NB. The offset of the auth_header is relative to the *end*
965 * of the packet, not the start. */
966 if(!prs_set_offset(current_pdu,
967 prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
968 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
970 (unsigned int)(prhdr->frag_length -
971 RPC_HDR_AUTH_LEN - auth_len) ));
972 return NT_STATUS_BUFFER_TOO_SMALL;
975 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
976 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
977 return NT_STATUS_BUFFER_TOO_SMALL;
980 /* Ensure auth_pad_len fits into the packet. */
981 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
982 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
983 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
984 "too large (%u), auth_len (%u), frag_len = (%u).\n",
985 (unsigned int)auth_info.auth_pad_len,
986 (unsigned int)auth_len,
987 (unsigned int)prhdr->frag_length));
988 return NT_STATUS_BUFFER_TOO_SMALL;
991 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
992 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
993 auth_info.auth_type));
994 return NT_STATUS_BUFFER_TOO_SMALL;
997 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
999 if (DEBUGLEVEL >= 10) {
1000 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1003 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1005 switch (cli->auth->auth_level) {
1006 case DCERPC_AUTH_LEVEL_PRIVACY:
1007 status = netsec_incoming_packet(schannel_auth,
1014 case DCERPC_AUTH_LEVEL_INTEGRITY:
1015 status = netsec_incoming_packet(schannel_auth,
1023 status = NT_STATUS_INTERNAL_ERROR;
1027 if (!NT_STATUS_IS_OK(status)) {
1028 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1029 "Connection to %s (%s).\n",
1030 rpccli_pipe_txt(talloc_tos(), cli),
1031 nt_errstr(status)));
1032 return NT_STATUS_INVALID_PARAMETER;
1036 * Return the current pointer to the data offset.
1039 if(!prs_set_offset(current_pdu, save_offset)) {
1040 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1041 (unsigned int)save_offset ));
1042 return NT_STATUS_BUFFER_TOO_SMALL;
1046 * Remember the padding length. We must remove it from the real data
1047 * stream once the sign/seal is done.
1050 *p_ss_padding_len = auth_info.auth_pad_len;
1052 return NT_STATUS_OK;
1055 /****************************************************************************
1056 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1057 ****************************************************************************/
1059 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1060 struct ncacn_packet_header *prhdr,
1061 prs_struct *current_pdu,
1062 uint8 *p_ss_padding_len)
1064 NTSTATUS ret = NT_STATUS_OK;
1066 /* Paranioa checks for auth_len. */
1067 if (prhdr->auth_length) {
1068 if (prhdr->auth_length > prhdr->frag_length) {
1069 return NT_STATUS_INVALID_PARAMETER;
1072 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1073 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1074 /* Integer wrap attempt. */
1075 return NT_STATUS_INVALID_PARAMETER;
1080 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1083 switch(cli->auth->auth_type) {
1084 case PIPE_AUTH_TYPE_NONE:
1085 if (prhdr->auth_length) {
1086 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1087 "Connection to %s - got non-zero "
1089 rpccli_pipe_txt(talloc_tos(), cli),
1090 (unsigned int)prhdr->auth_length));
1091 return NT_STATUS_INVALID_PARAMETER;
1095 case PIPE_AUTH_TYPE_NTLMSSP:
1096 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1097 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1098 if (!NT_STATUS_IS_OK(ret)) {
1103 case PIPE_AUTH_TYPE_SCHANNEL:
1104 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1105 if (!NT_STATUS_IS_OK(ret)) {
1110 case PIPE_AUTH_TYPE_KRB5:
1111 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1113 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1114 "to %s - unknown internal auth type %u.\n",
1115 rpccli_pipe_txt(talloc_tos(), cli),
1116 cli->auth->auth_type ));
1117 return NT_STATUS_INVALID_INFO_CLASS;
1120 return NT_STATUS_OK;
1123 /****************************************************************************
1124 Do basic authentication checks on an incoming pdu.
1125 ****************************************************************************/
1127 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1128 struct ncacn_packet_header *prhdr,
1129 prs_struct *current_pdu,
1130 uint8 expected_pkt_type,
1133 prs_struct *return_data)
1136 NTSTATUS ret = NT_STATUS_OK;
1137 uint32 current_pdu_len = prs_data_size(current_pdu);
1139 if (current_pdu_len != prhdr->frag_length) {
1140 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1141 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_length));
1142 return NT_STATUS_INVALID_PARAMETER;
1146 * Point the return values at the real data including the RPC
1147 * header. Just in case the caller wants it.
1149 *ppdata = prs_data_p(current_pdu);
1150 *pdata_len = current_pdu_len;
1152 /* Ensure we have the correct type. */
1153 switch (prhdr->ptype) {
1154 case DCERPC_PKT_ALTER_RESP:
1155 case DCERPC_PKT_BIND_ACK:
1157 /* Alter context and bind ack share the same packet definitions. */
1161 case DCERPC_PKT_RESPONSE:
1163 RPC_HDR_RESP rhdr_resp;
1164 uint8 ss_padding_len = 0;
1166 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1167 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1168 return NT_STATUS_BUFFER_TOO_SMALL;
1171 /* Here's where we deal with incoming sign/seal. */
1172 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1173 current_pdu, &ss_padding_len);
1174 if (!NT_STATUS_IS_OK(ret)) {
1178 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1179 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1181 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1182 return NT_STATUS_BUFFER_TOO_SMALL;
1185 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1187 /* Remember to remove the auth footer. */
1188 if (prhdr->auth_length) {
1189 /* We've already done integer wrap tests on auth_len in
1190 cli_pipe_validate_rpc_response(). */
1191 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_length) {
1192 return NT_STATUS_BUFFER_TOO_SMALL;
1194 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_length);
1197 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1198 current_pdu_len, *pdata_len, ss_padding_len ));
1201 * If this is the first reply, and the allocation hint is reasonably, try and
1202 * set up the return_data parse_struct to the correct size.
1205 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1206 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1207 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1208 "too large to allocate\n",
1209 (unsigned int)rhdr_resp.alloc_hint ));
1210 return NT_STATUS_NO_MEMORY;
1217 case DCERPC_PKT_BIND_NAK:
1218 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1219 "received from %s!\n",
1220 rpccli_pipe_txt(talloc_tos(), cli)));
1221 /* Use this for now... */
1222 return NT_STATUS_NETWORK_ACCESS_DENIED;
1224 case DCERPC_PKT_FAULT:
1227 struct ncacn_packet r;
1229 blob = data_blob_const(prs_data_p(current_pdu),
1230 prs_data_size(current_pdu));
1232 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1233 if (!NT_STATUS_IS_OK(ret)) {
1236 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1237 "code %s received from %s!\n",
1238 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1239 rpccli_pipe_txt(talloc_tos(), cli)));
1241 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1242 return NT_STATUS_UNSUCCESSFUL;
1244 return NT_STATUS(r.u.fault.status);
1249 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1251 (unsigned int)prhdr->ptype,
1252 rpccli_pipe_txt(talloc_tos(), cli)));
1253 return NT_STATUS_INVALID_INFO_CLASS;
1256 if (prhdr->ptype != expected_pkt_type) {
1257 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1258 "got an unexpected RPC packet type - %u, not %u\n",
1259 rpccli_pipe_txt(talloc_tos(), cli),
1261 expected_pkt_type));
1262 return NT_STATUS_INVALID_INFO_CLASS;
1265 /* Do this just before return - we don't want to modify any rpc header
1266 data before now as we may have needed to do cryptographic actions on
1269 if ((prhdr->ptype == DCERPC_PKT_BIND_ACK) && !(prhdr->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1270 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1271 "setting fragment first/last ON.\n"));
1272 prhdr->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1275 return NT_STATUS_OK;
1278 /****************************************************************************
1279 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1280 Normally the frag_len and buffer size will match, but on the first trans
1281 reply there is a theoretical chance that buffer size > frag_len, so we must
1283 ****************************************************************************/
1285 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1286 struct ncacn_packet_header *prhdr,
1287 prs_struct *current_pdu)
1289 uint32 current_pdu_len = prs_data_size(current_pdu);
1291 if (current_pdu_len < prhdr->frag_length) {
1292 return NT_STATUS_BUFFER_TOO_SMALL;
1296 if (current_pdu_len == (uint32)prhdr->frag_length) {
1297 prs_mem_free(current_pdu);
1298 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1299 /* Make current_pdu dynamic with no memory. */
1300 prs_give_memory(current_pdu, 0, 0, True);
1301 return NT_STATUS_OK;
1305 * Oh no ! More data in buffer than we processed in current pdu.
1306 * Cheat. Move the data down and shrink the buffer.
1309 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_length,
1310 current_pdu_len - prhdr->frag_length);
1312 /* Remember to set the read offset back to zero. */
1313 prs_set_offset(current_pdu, 0);
1315 /* Shrink the buffer. */
1316 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_length)) {
1317 return NT_STATUS_BUFFER_TOO_SMALL;
1320 return NT_STATUS_OK;
1323 /****************************************************************************
1324 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1325 ****************************************************************************/
1327 struct cli_api_pipe_state {
1328 struct event_context *ev;
1329 struct rpc_cli_transport *transport;
1334 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1335 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1336 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1338 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1339 struct event_context *ev,
1340 struct rpc_cli_transport *transport,
1341 uint8_t *data, size_t data_len,
1342 uint32_t max_rdata_len)
1344 struct tevent_req *req, *subreq;
1345 struct cli_api_pipe_state *state;
1348 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1353 state->transport = transport;
1355 if (max_rdata_len < RPC_HEADER_LEN) {
1357 * For a RPC reply we always need at least RPC_HEADER_LEN
1358 * bytes. We check this here because we will receive
1359 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1361 status = NT_STATUS_INVALID_PARAMETER;
1365 if (transport->trans_send != NULL) {
1366 subreq = transport->trans_send(state, ev, data, data_len,
1367 max_rdata_len, transport->priv);
1368 if (subreq == NULL) {
1371 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1376 * If the transport does not provide a "trans" routine, i.e. for
1377 * example the ncacn_ip_tcp transport, do the write/read step here.
1380 subreq = rpc_write_send(state, ev, transport, data, data_len);
1381 if (subreq == NULL) {
1384 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1388 tevent_req_nterror(req, status);
1389 return tevent_req_post(req, ev);
1395 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1397 struct tevent_req *req = tevent_req_callback_data(
1398 subreq, struct tevent_req);
1399 struct cli_api_pipe_state *state = tevent_req_data(
1400 req, struct cli_api_pipe_state);
1403 status = state->transport->trans_recv(subreq, state, &state->rdata,
1405 TALLOC_FREE(subreq);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 tevent_req_nterror(req, status);
1410 tevent_req_done(req);
1413 static void cli_api_pipe_write_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 = rpc_write_recv(subreq);
1422 TALLOC_FREE(subreq);
1423 if (!NT_STATUS_IS_OK(status)) {
1424 tevent_req_nterror(req, status);
1428 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1429 if (tevent_req_nomem(state->rdata, req)) {
1434 * We don't need to use rpc_read_send here, the upper layer will cope
1435 * with a short read, transport->trans_send could also return less
1436 * than state->max_rdata_len.
1438 subreq = state->transport->read_send(state, state->ev, state->rdata,
1440 state->transport->priv);
1441 if (tevent_req_nomem(subreq, req)) {
1444 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1447 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1449 struct tevent_req *req = tevent_req_callback_data(
1450 subreq, struct tevent_req);
1451 struct cli_api_pipe_state *state = tevent_req_data(
1452 req, struct cli_api_pipe_state);
1456 status = state->transport->read_recv(subreq, &received);
1457 TALLOC_FREE(subreq);
1458 if (!NT_STATUS_IS_OK(status)) {
1459 tevent_req_nterror(req, status);
1462 state->rdata_len = received;
1463 tevent_req_done(req);
1466 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1467 uint8_t **prdata, uint32_t *prdata_len)
1469 struct cli_api_pipe_state *state = tevent_req_data(
1470 req, struct cli_api_pipe_state);
1473 if (tevent_req_is_nterror(req, &status)) {
1477 *prdata = talloc_move(mem_ctx, &state->rdata);
1478 *prdata_len = state->rdata_len;
1479 return NT_STATUS_OK;
1482 /****************************************************************************
1483 Send data on an rpc pipe via trans. The prs_struct data must be the last
1484 pdu fragment of an NDR data stream.
1486 Receive response data from an rpc pipe, which may be large...
1488 Read the first fragment: unfortunately have to use SMBtrans for the first
1489 bit, then SMBreadX for subsequent bits.
1491 If first fragment received also wasn't the last fragment, continue
1492 getting fragments until we _do_ receive the last fragment.
1494 Request/Response PDU's look like the following...
1496 |<------------------PDU len----------------------------------------------->|
1497 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1499 +------------+-----------------+-------------+---------------+-------------+
1500 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1501 +------------+-----------------+-------------+---------------+-------------+
1503 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1504 signing & sealing being negotiated.
1506 ****************************************************************************/
1508 struct rpc_api_pipe_state {
1509 struct event_context *ev;
1510 struct rpc_pipe_client *cli;
1511 uint8_t expected_pkt_type;
1513 prs_struct incoming_frag;
1514 struct ncacn_packet_header rhdr;
1516 prs_struct incoming_pdu; /* Incoming reply */
1517 uint32_t incoming_pdu_offset;
1520 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1521 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1523 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1524 struct event_context *ev,
1525 struct rpc_pipe_client *cli,
1526 prs_struct *data, /* Outgoing PDU */
1527 uint8_t expected_pkt_type)
1529 struct tevent_req *req, *subreq;
1530 struct rpc_api_pipe_state *state;
1531 uint16_t max_recv_frag;
1534 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1540 state->expected_pkt_type = expected_pkt_type;
1541 state->incoming_pdu_offset = 0;
1543 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1545 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1546 /* Make incoming_pdu dynamic with no memory. */
1547 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1550 * Ensure we're not sending too much.
1552 if (prs_offset(data) > cli->max_xmit_frag) {
1553 status = NT_STATUS_INVALID_PARAMETER;
1557 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1559 max_recv_frag = cli->max_recv_frag;
1562 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1565 subreq = cli_api_pipe_send(state, ev, cli->transport,
1566 (uint8_t *)prs_data_p(data),
1567 prs_offset(data), max_recv_frag);
1568 if (subreq == NULL) {
1571 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1575 tevent_req_nterror(req, status);
1576 return tevent_req_post(req, ev);
1582 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1584 struct tevent_req *req = tevent_req_callback_data(
1585 subreq, struct tevent_req);
1586 struct rpc_api_pipe_state *state = tevent_req_data(
1587 req, struct rpc_api_pipe_state);
1589 uint8_t *rdata = NULL;
1590 uint32_t rdata_len = 0;
1592 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1593 TALLOC_FREE(subreq);
1594 if (!NT_STATUS_IS_OK(status)) {
1595 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1596 tevent_req_nterror(req, status);
1600 if (rdata == NULL) {
1601 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1602 rpccli_pipe_txt(talloc_tos(), state->cli)));
1603 tevent_req_done(req);
1608 * This is equivalent to a talloc_steal - gives rdata to
1609 * the prs_struct state->incoming_frag.
1611 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1614 /* Ensure we have enough data for a pdu. */
1615 subreq = get_complete_frag_send(state, state->ev, state->cli,
1616 &state->rhdr, &state->incoming_frag);
1617 if (tevent_req_nomem(subreq, req)) {
1620 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1623 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1625 struct tevent_req *req = tevent_req_callback_data(
1626 subreq, struct tevent_req);
1627 struct rpc_api_pipe_state *state = tevent_req_data(
1628 req, struct rpc_api_pipe_state);
1631 uint32_t rdata_len = 0;
1633 status = get_complete_frag_recv(subreq);
1634 TALLOC_FREE(subreq);
1635 if (!NT_STATUS_IS_OK(status)) {
1636 DEBUG(5, ("get_complete_frag failed: %s\n",
1637 nt_errstr(status)));
1638 tevent_req_nterror(req, status);
1642 status = cli_pipe_validate_current_pdu(
1643 state->cli, &state->rhdr, &state->incoming_frag,
1644 state->expected_pkt_type, &rdata, &rdata_len,
1645 &state->incoming_pdu);
1647 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1648 (unsigned)prs_data_size(&state->incoming_frag),
1649 (unsigned)state->incoming_pdu_offset,
1650 nt_errstr(status)));
1652 if (!NT_STATUS_IS_OK(status)) {
1653 tevent_req_nterror(req, status);
1657 if ((state->rhdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)
1658 && (state->rhdr.drep[0] == 0)) {
1660 * Set the data type correctly for big-endian data on the
1663 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1665 rpccli_pipe_txt(talloc_tos(), state->cli)));
1666 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1669 * Check endianness on subsequent packets.
1671 if (state->incoming_frag.bigendian_data
1672 != state->incoming_pdu.bigendian_data) {
1673 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1675 state->incoming_pdu.bigendian_data?"big":"little",
1676 state->incoming_frag.bigendian_data?"big":"little"));
1677 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1681 /* Now copy the data portion out of the pdu into rbuf. */
1682 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1683 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1687 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1688 rdata, (size_t)rdata_len);
1689 state->incoming_pdu_offset += rdata_len;
1691 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1692 &state->incoming_frag);
1693 if (!NT_STATUS_IS_OK(status)) {
1694 tevent_req_nterror(req, status);
1698 if (state->rhdr.pfc_flags & DCERPC_PFC_FLAG_LAST) {
1699 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1700 rpccli_pipe_txt(talloc_tos(), state->cli),
1701 (unsigned)prs_data_size(&state->incoming_pdu)));
1702 tevent_req_done(req);
1706 subreq = get_complete_frag_send(state, state->ev, state->cli,
1707 &state->rhdr, &state->incoming_frag);
1708 if (tevent_req_nomem(subreq, req)) {
1711 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1714 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1715 prs_struct *reply_pdu)
1717 struct rpc_api_pipe_state *state = tevent_req_data(
1718 req, struct rpc_api_pipe_state);
1721 if (tevent_req_is_nterror(req, &status)) {
1725 *reply_pdu = state->incoming_pdu;
1726 reply_pdu->mem_ctx = mem_ctx;
1729 * Prevent state->incoming_pdu from being freed
1730 * when state is freed.
1732 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1733 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1735 return NT_STATUS_OK;
1738 /*******************************************************************
1739 ********************************************************************/
1741 static NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1742 enum dcerpc_AuthType auth_type,
1743 enum dcerpc_AuthLevel auth_level,
1744 uint8_t auth_pad_length,
1745 uint32_t auth_context_id,
1746 const DATA_BLOB *credentials,
1749 struct dcerpc_auth r;
1750 enum ndr_err_code ndr_err;
1752 r.auth_type = auth_type;
1753 r.auth_level = auth_level;
1754 r.auth_pad_length = auth_pad_length;
1755 r.auth_reserved = 0;
1756 r.auth_context_id = auth_context_id;
1757 r.credentials = *credentials;
1759 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1760 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1761 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1762 return ndr_map_error2ntstatus(ndr_err);
1765 if (DEBUGLEVEL >= 10) {
1766 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1769 return NT_STATUS_OK;
1772 /*******************************************************************
1773 Creates krb5 auth bind.
1774 ********************************************************************/
1776 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1777 enum dcerpc_AuthLevel auth_level,
1778 DATA_BLOB *auth_info)
1783 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1784 DATA_BLOB tkt = data_blob_null;
1785 DATA_BLOB tkt_wrapped = data_blob_null;
1787 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1788 a->service_principal ));
1790 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1792 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1793 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1796 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1798 a->service_principal,
1799 error_message(ret) ));
1801 data_blob_free(&tkt);
1802 return NT_STATUS_INVALID_PARAMETER;
1805 /* wrap that up in a nice GSS-API wrapping */
1806 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1808 data_blob_free(&tkt);
1810 status = dcerpc_push_dcerpc_auth(cli,
1811 DCERPC_AUTH_TYPE_KRB5,
1813 0, /* auth_pad_length */
1814 1, /* auth_context_id */
1817 if (!NT_STATUS_IS_OK(status)) {
1818 data_blob_free(&tkt_wrapped);
1822 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1823 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1825 return NT_STATUS_OK;
1827 return NT_STATUS_INVALID_PARAMETER;
1831 /*******************************************************************
1832 Creates SPNEGO NTLMSSP auth bind.
1833 ********************************************************************/
1835 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1836 enum dcerpc_AuthLevel auth_level,
1837 DATA_BLOB *auth_info)
1840 DATA_BLOB null_blob = data_blob_null;
1841 DATA_BLOB request = data_blob_null;
1842 DATA_BLOB spnego_msg = data_blob_null;
1844 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1845 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1849 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1850 data_blob_free(&request);
1854 /* Wrap this in SPNEGO. */
1855 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1857 data_blob_free(&request);
1859 status = dcerpc_push_dcerpc_auth(cli,
1860 DCERPC_AUTH_TYPE_SPNEGO,
1862 0, /* auth_pad_length */
1863 1, /* auth_context_id */
1866 if (!NT_STATUS_IS_OK(status)) {
1867 data_blob_free(&spnego_msg);
1871 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1872 dump_data(5, spnego_msg.data, spnego_msg.length);
1874 return NT_STATUS_OK;
1877 /*******************************************************************
1878 Creates NTLMSSP auth bind.
1879 ********************************************************************/
1881 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1882 enum dcerpc_AuthLevel auth_level,
1883 DATA_BLOB *auth_info)
1886 DATA_BLOB null_blob = data_blob_null;
1887 DATA_BLOB request = data_blob_null;
1889 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1890 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1894 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1895 data_blob_free(&request);
1899 status = dcerpc_push_dcerpc_auth(cli,
1900 DCERPC_AUTH_TYPE_NTLMSSP,
1902 0, /* auth_pad_length */
1903 1, /* auth_context_id */
1906 if (!NT_STATUS_IS_OK(status)) {
1907 data_blob_free(&request);
1911 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1912 dump_data(5, request.data, request.length);
1914 return NT_STATUS_OK;
1917 /*******************************************************************
1918 Creates schannel auth bind.
1919 ********************************************************************/
1921 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1922 enum dcerpc_AuthLevel auth_level,
1923 DATA_BLOB *auth_info)
1926 struct NL_AUTH_MESSAGE r;
1927 DATA_BLOB schannel_blob;
1929 /* Use lp_workgroup() if domain not specified */
1931 if (!cli->auth->domain || !cli->auth->domain[0]) {
1932 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1933 if (cli->auth->domain == NULL) {
1934 return NT_STATUS_NO_MEMORY;
1939 * Now marshall the data into the auth parse_struct.
1942 r.MessageType = NL_NEGOTIATE_REQUEST;
1943 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1944 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1945 r.oem_netbios_domain.a = cli->auth->domain;
1946 r.oem_netbios_computer.a = global_myname();
1948 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1949 if (!NT_STATUS_IS_OK(status)) {
1953 status = dcerpc_push_dcerpc_auth(cli,
1954 DCERPC_AUTH_TYPE_SCHANNEL,
1956 0, /* auth_pad_length */
1957 1, /* auth_context_id */
1960 if (!NT_STATUS_IS_OK(status)) {
1964 return NT_STATUS_OK;
1967 /*******************************************************************
1968 ********************************************************************/
1970 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1971 const struct ndr_syntax_id *abstract_syntax,
1972 const struct ndr_syntax_id *transfer_syntax,
1973 struct dcerpc_ctx_list **ctx_list_p)
1975 struct dcerpc_ctx_list *ctx_list;
1977 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1978 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1980 ctx_list[0].context_id = 0;
1981 ctx_list[0].num_transfer_syntaxes = 1;
1982 ctx_list[0].abstract_syntax = *abstract_syntax;
1983 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
1984 struct ndr_syntax_id,
1985 ctx_list[0].num_transfer_syntaxes);
1986 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1987 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
1989 *ctx_list_p = ctx_list;
1991 return NT_STATUS_OK;
1994 /*******************************************************************
1995 Creates the internals of a DCE/RPC bind request or alter context PDU.
1996 ********************************************************************/
1998 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
1999 prs_struct *rpc_out,
2001 const struct ndr_syntax_id *abstract,
2002 const struct ndr_syntax_id *transfer,
2003 const DATA_BLOB *auth_info)
2005 uint16 auth_len = auth_info->length;
2006 uint16 frag_len = 0;
2008 union dcerpc_payload u;
2010 struct dcerpc_ctx_list *ctx_list;
2012 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2014 if (!NT_STATUS_IS_OK(status)) {
2018 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2019 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2020 u.bind.assoc_group_id = 0x0;
2021 u.bind.num_contexts = 1;
2022 u.bind.ctx_list = ctx_list;
2023 u.bind.auth_info = *auth_info;
2025 /* Start building the frag length. */
2026 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind) + auth_len;
2028 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2030 DCERPC_PFC_FLAG_FIRST |
2031 DCERPC_PFC_FLAG_LAST,
2033 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2037 if (!NT_STATUS_IS_OK(status)) {
2038 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2042 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2043 return NT_STATUS_NO_MEMORY;
2046 return NT_STATUS_OK;
2049 /*******************************************************************
2050 Creates a DCE/RPC bind request.
2051 ********************************************************************/
2053 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2054 prs_struct *rpc_out,
2056 const struct ndr_syntax_id *abstract,
2057 const struct ndr_syntax_id *transfer,
2058 enum pipe_auth_type auth_type,
2059 enum dcerpc_AuthLevel auth_level)
2061 DATA_BLOB auth_info = data_blob_null;
2062 NTSTATUS ret = NT_STATUS_OK;
2064 switch (auth_type) {
2065 case PIPE_AUTH_TYPE_SCHANNEL:
2066 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2067 if (!NT_STATUS_IS_OK(ret)) {
2072 case PIPE_AUTH_TYPE_NTLMSSP:
2073 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2074 if (!NT_STATUS_IS_OK(ret)) {
2079 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2080 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2081 if (!NT_STATUS_IS_OK(ret)) {
2086 case PIPE_AUTH_TYPE_KRB5:
2087 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2088 if (!NT_STATUS_IS_OK(ret)) {
2093 case PIPE_AUTH_TYPE_NONE:
2097 /* "Can't" happen. */
2098 return NT_STATUS_INVALID_INFO_CLASS;
2101 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2110 /*******************************************************************
2111 Create and add the NTLMSSP sign/seal auth header and data.
2112 ********************************************************************/
2114 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2116 uint32 ss_padding_len,
2117 prs_struct *outgoing_pdu)
2119 RPC_HDR_AUTH auth_info;
2121 DATA_BLOB auth_blob = data_blob_null;
2122 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2125 if (!cli->auth->a_u.ntlmssp_state) {
2126 return NT_STATUS_INVALID_PARAMETER;
2129 frame = talloc_stackframe();
2131 /* Init and marshall the auth header. */
2132 init_rpc_hdr_auth(&auth_info,
2133 map_pipe_auth_type_to_rpc_auth_type(
2134 cli->auth->auth_type),
2135 cli->auth->auth_level,
2137 1 /* context id. */);
2139 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2140 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2142 return NT_STATUS_NO_MEMORY;
2145 switch (cli->auth->auth_level) {
2146 case DCERPC_AUTH_LEVEL_PRIVACY:
2147 /* Data portion is encrypted. */
2148 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2150 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2152 (unsigned char *)prs_data_p(outgoing_pdu),
2153 (size_t)prs_offset(outgoing_pdu),
2155 if (!NT_STATUS_IS_OK(status)) {
2161 case DCERPC_AUTH_LEVEL_INTEGRITY:
2162 /* Data is signed. */
2163 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2165 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2167 (unsigned char *)prs_data_p(outgoing_pdu),
2168 (size_t)prs_offset(outgoing_pdu),
2170 if (!NT_STATUS_IS_OK(status)) {
2178 smb_panic("bad auth level");
2180 return NT_STATUS_INVALID_PARAMETER;
2183 /* Finally marshall the blob. */
2185 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2186 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2187 (unsigned int)NTLMSSP_SIG_SIZE));
2189 return NT_STATUS_NO_MEMORY;
2193 return NT_STATUS_OK;
2196 /*******************************************************************
2197 Create and add the schannel sign/seal auth header and data.
2198 ********************************************************************/
2200 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2202 uint32 ss_padding_len,
2203 prs_struct *outgoing_pdu)
2205 RPC_HDR_AUTH auth_info;
2206 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2207 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2208 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2213 return NT_STATUS_INVALID_PARAMETER;
2216 /* Init and marshall the auth header. */
2217 init_rpc_hdr_auth(&auth_info,
2218 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2219 cli->auth->auth_level,
2221 1 /* context id. */);
2223 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2224 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2225 return NT_STATUS_NO_MEMORY;
2228 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2231 switch (cli->auth->auth_level) {
2232 case DCERPC_AUTH_LEVEL_PRIVACY:
2233 status = netsec_outgoing_packet(sas,
2240 case DCERPC_AUTH_LEVEL_INTEGRITY:
2241 status = netsec_outgoing_packet(sas,
2249 status = NT_STATUS_INTERNAL_ERROR;
2253 if (!NT_STATUS_IS_OK(status)) {
2254 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2255 nt_errstr(status)));
2259 if (DEBUGLEVEL >= 10) {
2260 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2263 /* Finally marshall the blob. */
2264 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2265 return NT_STATUS_NO_MEMORY;
2268 return NT_STATUS_OK;
2271 /*******************************************************************
2272 Calculate how much data we're going to send in this packet, also
2273 work out any sign/seal padding length.
2274 ********************************************************************/
2276 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2280 uint32 *p_ss_padding)
2282 uint32 data_space, data_len;
2285 if ((data_left > 0) && (sys_random() % 2)) {
2286 data_left = MAX(data_left/2, 1);
2290 switch (cli->auth->auth_level) {
2291 case DCERPC_AUTH_LEVEL_NONE:
2292 case DCERPC_AUTH_LEVEL_CONNECT:
2293 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2294 data_len = MIN(data_space, data_left);
2297 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2300 case DCERPC_AUTH_LEVEL_INTEGRITY:
2301 case DCERPC_AUTH_LEVEL_PRIVACY:
2302 /* Treat the same for all authenticated rpc requests. */
2303 switch(cli->auth->auth_type) {
2304 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2305 case PIPE_AUTH_TYPE_NTLMSSP:
2306 *p_auth_len = NTLMSSP_SIG_SIZE;
2308 case PIPE_AUTH_TYPE_SCHANNEL:
2309 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2312 smb_panic("bad auth type");
2316 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2317 RPC_HDR_AUTH_LEN - *p_auth_len;
2319 data_len = MIN(data_space, data_left);
2321 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2322 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2324 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2325 data_len + *p_ss_padding + /* data plus padding. */
2326 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2330 smb_panic("bad auth level");
2336 /*******************************************************************
2338 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2339 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2340 and deals with signing/sealing details.
2341 ********************************************************************/
2343 struct rpc_api_pipe_req_state {
2344 struct event_context *ev;
2345 struct rpc_pipe_client *cli;
2348 prs_struct *req_data;
2349 uint32_t req_data_sent;
2350 prs_struct outgoing_frag;
2351 prs_struct reply_pdu;
2354 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2355 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2356 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2357 bool *is_last_frag);
2359 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2360 struct event_context *ev,
2361 struct rpc_pipe_client *cli,
2363 prs_struct *req_data)
2365 struct tevent_req *req, *subreq;
2366 struct rpc_api_pipe_req_state *state;
2370 req = tevent_req_create(mem_ctx, &state,
2371 struct rpc_api_pipe_req_state);
2377 state->op_num = op_num;
2378 state->req_data = req_data;
2379 state->req_data_sent = 0;
2380 state->call_id = get_rpc_call_id();
2382 if (cli->max_xmit_frag
2383 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2384 /* Server is screwed up ! */
2385 status = NT_STATUS_INVALID_PARAMETER;
2389 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2391 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2396 status = prepare_next_frag(state, &is_last_frag);
2397 if (!NT_STATUS_IS_OK(status)) {
2402 subreq = rpc_api_pipe_send(state, ev, state->cli,
2403 &state->outgoing_frag,
2404 DCERPC_PKT_RESPONSE);
2405 if (subreq == NULL) {
2408 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2410 subreq = rpc_write_send(
2411 state, ev, cli->transport,
2412 (uint8_t *)prs_data_p(&state->outgoing_frag),
2413 prs_offset(&state->outgoing_frag));
2414 if (subreq == NULL) {
2417 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2423 tevent_req_nterror(req, status);
2424 return tevent_req_post(req, ev);
2430 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2434 RPC_HDR_REQ hdr_req;
2435 uint32_t data_sent_thistime;
2439 uint32_t ss_padding;
2441 char pad[8] = { 0, };
2444 data_left = prs_offset(state->req_data) - state->req_data_sent;
2446 data_sent_thistime = calculate_data_len_tosend(
2447 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2449 if (state->req_data_sent == 0) {
2450 flags = DCERPC_PFC_FLAG_FIRST;
2453 if (data_sent_thistime == data_left) {
2454 flags |= DCERPC_PFC_FLAG_LAST;
2457 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2458 return NT_STATUS_NO_MEMORY;
2461 /* Create and marshall the header and request header. */
2462 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2465 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2466 return NT_STATUS_NO_MEMORY;
2469 /* Create the rpc request RPC_HDR_REQ */
2470 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2473 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2474 &state->outgoing_frag, 0)) {
2475 return NT_STATUS_NO_MEMORY;
2478 /* Copy in the data, plus any ss padding. */
2479 if (!prs_append_some_prs_data(&state->outgoing_frag,
2480 state->req_data, state->req_data_sent,
2481 data_sent_thistime)) {
2482 return NT_STATUS_NO_MEMORY;
2485 /* Copy the sign/seal padding data. */
2486 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2487 return NT_STATUS_NO_MEMORY;
2490 /* Generate any auth sign/seal and add the auth footer. */
2491 switch (state->cli->auth->auth_type) {
2492 case PIPE_AUTH_TYPE_NONE:
2493 status = NT_STATUS_OK;
2495 case PIPE_AUTH_TYPE_NTLMSSP:
2496 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2497 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2498 &state->outgoing_frag);
2500 case PIPE_AUTH_TYPE_SCHANNEL:
2501 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2502 &state->outgoing_frag);
2505 status = NT_STATUS_INVALID_PARAMETER;
2509 state->req_data_sent += data_sent_thistime;
2510 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2515 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2517 struct tevent_req *req = tevent_req_callback_data(
2518 subreq, struct tevent_req);
2519 struct rpc_api_pipe_req_state *state = tevent_req_data(
2520 req, struct rpc_api_pipe_req_state);
2524 status = rpc_write_recv(subreq);
2525 TALLOC_FREE(subreq);
2526 if (!NT_STATUS_IS_OK(status)) {
2527 tevent_req_nterror(req, status);
2531 status = prepare_next_frag(state, &is_last_frag);
2532 if (!NT_STATUS_IS_OK(status)) {
2533 tevent_req_nterror(req, status);
2538 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2539 &state->outgoing_frag,
2540 DCERPC_PKT_RESPONSE);
2541 if (tevent_req_nomem(subreq, req)) {
2544 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2546 subreq = rpc_write_send(
2548 state->cli->transport,
2549 (uint8_t *)prs_data_p(&state->outgoing_frag),
2550 prs_offset(&state->outgoing_frag));
2551 if (tevent_req_nomem(subreq, req)) {
2554 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2559 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2561 struct tevent_req *req = tevent_req_callback_data(
2562 subreq, struct tevent_req);
2563 struct rpc_api_pipe_req_state *state = tevent_req_data(
2564 req, struct rpc_api_pipe_req_state);
2567 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2568 TALLOC_FREE(subreq);
2569 if (!NT_STATUS_IS_OK(status)) {
2570 tevent_req_nterror(req, status);
2573 tevent_req_done(req);
2576 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2577 prs_struct *reply_pdu)
2579 struct rpc_api_pipe_req_state *state = tevent_req_data(
2580 req, struct rpc_api_pipe_req_state);
2583 if (tevent_req_is_nterror(req, &status)) {
2585 * We always have to initialize to reply pdu, even if there is
2586 * none. The rpccli_* caller routines expect this.
2588 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2592 *reply_pdu = state->reply_pdu;
2593 reply_pdu->mem_ctx = mem_ctx;
2596 * Prevent state->req_pdu from being freed
2597 * when state is freed.
2599 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2600 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2602 return NT_STATUS_OK;
2606 /****************************************************************************
2607 Set the handle state.
2608 ****************************************************************************/
2610 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2611 const char *pipe_name, uint16 device_state)
2613 bool state_set = False;
2615 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2616 char *rparam = NULL;
2618 uint32 rparam_len, rdata_len;
2620 if (pipe_name == NULL)
2623 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2624 cli->fnum, pipe_name, device_state));
2626 /* create parameters: device state */
2627 SSVAL(param, 0, device_state);
2629 /* create setup parameters. */
2631 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2633 /* send the data on \PIPE\ */
2634 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2635 setup, 2, 0, /* setup, length, max */
2636 param, 2, 0, /* param, length, max */
2637 NULL, 0, 1024, /* data, length, max */
2638 &rparam, &rparam_len, /* return param, length */
2639 &rdata, &rdata_len)) /* return data, length */
2641 DEBUG(5, ("Set Handle state: return OK\n"));
2652 /****************************************************************************
2653 Check the rpc bind acknowledge response.
2654 ****************************************************************************/
2656 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2657 const struct ndr_syntax_id *transfer)
2659 if ( hdr_ba->addr.len == 0) {
2660 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2663 /* check the transfer syntax */
2664 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2665 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2666 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2670 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2671 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2672 hdr_ba->res.num_results, hdr_ba->res.reason));
2675 DEBUG(5,("check_bind_response: accepted!\n"));
2679 /*******************************************************************
2680 Creates a DCE/RPC bind authentication response.
2681 This is the packet that is sent back to the server once we
2682 have received a BIND-ACK, to finish the third leg of
2683 the authentication handshake.
2684 ********************************************************************/
2686 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2688 enum pipe_auth_type auth_type,
2689 enum dcerpc_AuthLevel auth_level,
2690 DATA_BLOB *pauth_blob,
2691 prs_struct *rpc_out)
2694 RPC_HDR_AUTH hdr_auth;
2697 /* Create the request RPC_HDR */
2698 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2699 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2700 pauth_blob->length );
2703 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2704 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2705 return NT_STATUS_NO_MEMORY;
2709 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2710 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2713 /* 4 bytes padding. */
2714 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2715 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2716 return NT_STATUS_NO_MEMORY;
2719 /* Create the request RPC_HDR_AUTHA */
2720 init_rpc_hdr_auth(&hdr_auth,
2721 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2724 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2725 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2726 return NT_STATUS_NO_MEMORY;
2730 * Append the auth data to the outgoing buffer.
2733 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2734 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2735 return NT_STATUS_NO_MEMORY;
2738 return NT_STATUS_OK;
2741 /*******************************************************************
2742 Creates a DCE/RPC bind alter context authentication request which
2743 may contain a spnego auth blobl
2744 ********************************************************************/
2746 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2747 const struct ndr_syntax_id *abstract,
2748 const struct ndr_syntax_id *transfer,
2749 enum dcerpc_AuthLevel auth_level,
2750 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2751 prs_struct *rpc_out)
2753 DATA_BLOB auth_info;
2756 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2757 DCERPC_AUTH_TYPE_SPNEGO,
2759 0, /* auth_pad_length */
2760 1, /* auth_context_id */
2763 if (!NT_STATUS_IS_OK(status)) {
2768 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2774 if (!NT_STATUS_IS_OK(status)) {
2781 /****************************************************************************
2783 ****************************************************************************/
2785 struct rpc_pipe_bind_state {
2786 struct event_context *ev;
2787 struct rpc_pipe_client *cli;
2789 uint32_t rpc_call_id;
2792 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2793 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2794 struct rpc_pipe_bind_state *state,
2795 struct rpc_hdr_info *phdr,
2796 prs_struct *reply_pdu);
2797 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2798 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2799 struct rpc_pipe_bind_state *state,
2800 struct rpc_hdr_info *phdr,
2801 prs_struct *reply_pdu);
2802 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2804 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2805 struct event_context *ev,
2806 struct rpc_pipe_client *cli,
2807 struct cli_pipe_auth_data *auth)
2809 struct tevent_req *req, *subreq;
2810 struct rpc_pipe_bind_state *state;
2813 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2818 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2819 rpccli_pipe_txt(talloc_tos(), cli),
2820 (unsigned int)auth->auth_type,
2821 (unsigned int)auth->auth_level ));
2825 state->rpc_call_id = get_rpc_call_id();
2827 prs_init_empty(&state->rpc_out, state, MARSHALL);
2829 cli->auth = talloc_move(cli, &auth);
2831 /* Marshall the outgoing data. */
2832 status = create_rpc_bind_req(cli, &state->rpc_out,
2834 &cli->abstract_syntax,
2835 &cli->transfer_syntax,
2836 cli->auth->auth_type,
2837 cli->auth->auth_level);
2839 if (!NT_STATUS_IS_OK(status)) {
2843 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2844 DCERPC_PKT_BIND_ACK);
2845 if (subreq == NULL) {
2848 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2852 tevent_req_nterror(req, status);
2853 return tevent_req_post(req, ev);
2859 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2861 struct tevent_req *req = tevent_req_callback_data(
2862 subreq, struct tevent_req);
2863 struct rpc_pipe_bind_state *state = tevent_req_data(
2864 req, struct rpc_pipe_bind_state);
2865 prs_struct reply_pdu;
2866 struct rpc_hdr_info hdr;
2867 struct rpc_hdr_ba_info hdr_ba;
2870 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2871 TALLOC_FREE(subreq);
2872 if (!NT_STATUS_IS_OK(status)) {
2873 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2874 rpccli_pipe_txt(talloc_tos(), state->cli),
2875 nt_errstr(status)));
2876 tevent_req_nterror(req, status);
2880 /* Unmarshall the RPC header */
2881 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2882 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2883 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2887 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2888 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2890 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2894 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2895 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2896 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2900 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2901 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2904 * For authenticated binds we may need to do 3 or 4 leg binds.
2907 switch(state->cli->auth->auth_type) {
2909 case PIPE_AUTH_TYPE_NONE:
2910 case PIPE_AUTH_TYPE_SCHANNEL:
2911 /* Bind complete. */
2912 tevent_req_done(req);
2915 case PIPE_AUTH_TYPE_NTLMSSP:
2916 /* Need to send AUTH3 packet - no reply. */
2917 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2919 if (!NT_STATUS_IS_OK(status)) {
2920 tevent_req_nterror(req, status);
2924 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2925 /* Need to send alter context request and reply. */
2926 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2928 if (!NT_STATUS_IS_OK(status)) {
2929 tevent_req_nterror(req, status);
2933 case PIPE_AUTH_TYPE_KRB5:
2937 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2938 (unsigned int)state->cli->auth->auth_type));
2939 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2943 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2944 struct rpc_pipe_bind_state *state,
2945 struct rpc_hdr_info *phdr,
2946 prs_struct *reply_pdu)
2948 DATA_BLOB server_response = data_blob_null;
2949 DATA_BLOB client_reply = data_blob_null;
2950 struct rpc_hdr_auth_info hdr_auth;
2951 struct tevent_req *subreq;
2954 if ((phdr->auth_len == 0)
2955 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2956 return NT_STATUS_INVALID_PARAMETER;
2959 if (!prs_set_offset(
2961 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2962 return NT_STATUS_INVALID_PARAMETER;
2965 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2966 return NT_STATUS_INVALID_PARAMETER;
2969 /* TODO - check auth_type/auth_level match. */
2971 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2972 prs_copy_data_out((char *)server_response.data, reply_pdu,
2975 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2976 server_response, &client_reply);
2978 if (!NT_STATUS_IS_OK(status)) {
2979 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2980 "blob failed: %s.\n", nt_errstr(status)));
2984 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2986 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2987 state->cli->auth->auth_type,
2988 state->cli->auth->auth_level,
2989 &client_reply, &state->rpc_out);
2990 data_blob_free(&client_reply);
2992 if (!NT_STATUS_IS_OK(status)) {
2996 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2997 (uint8_t *)prs_data_p(&state->rpc_out),
2998 prs_offset(&state->rpc_out));
2999 if (subreq == NULL) {
3000 return NT_STATUS_NO_MEMORY;
3002 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3003 return NT_STATUS_OK;
3006 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3008 struct tevent_req *req = tevent_req_callback_data(
3009 subreq, struct tevent_req);
3012 status = rpc_write_recv(subreq);
3013 TALLOC_FREE(subreq);
3014 if (!NT_STATUS_IS_OK(status)) {
3015 tevent_req_nterror(req, status);
3018 tevent_req_done(req);
3021 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3022 struct rpc_pipe_bind_state *state,
3023 struct rpc_hdr_info *phdr,
3024 prs_struct *reply_pdu)
3026 DATA_BLOB server_spnego_response = data_blob_null;
3027 DATA_BLOB server_ntlm_response = data_blob_null;
3028 DATA_BLOB client_reply = data_blob_null;
3029 DATA_BLOB tmp_blob = data_blob_null;
3030 RPC_HDR_AUTH hdr_auth;
3031 struct tevent_req *subreq;
3034 if ((phdr->auth_len == 0)
3035 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
3036 return NT_STATUS_INVALID_PARAMETER;
3039 /* Process the returned NTLMSSP blob first. */
3040 if (!prs_set_offset(
3042 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
3043 return NT_STATUS_INVALID_PARAMETER;
3046 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3047 return NT_STATUS_INVALID_PARAMETER;
3050 server_spnego_response = data_blob(NULL, phdr->auth_len);
3051 prs_copy_data_out((char *)server_spnego_response.data,
3052 reply_pdu, phdr->auth_len);
3055 * The server might give us back two challenges - tmp_blob is for the
3058 if (!spnego_parse_challenge(server_spnego_response,
3059 &server_ntlm_response, &tmp_blob)) {
3060 data_blob_free(&server_spnego_response);
3061 data_blob_free(&server_ntlm_response);
3062 data_blob_free(&tmp_blob);
3063 return NT_STATUS_INVALID_PARAMETER;
3066 /* We're finished with the server spnego response and the tmp_blob. */
3067 data_blob_free(&server_spnego_response);
3068 data_blob_free(&tmp_blob);
3070 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3071 server_ntlm_response, &client_reply);
3073 /* Finished with the server_ntlm response */
3074 data_blob_free(&server_ntlm_response);
3076 if (!NT_STATUS_IS_OK(status)) {
3077 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3078 "using server blob failed.\n"));
3079 data_blob_free(&client_reply);
3083 /* SPNEGO wrap the client reply. */
3084 tmp_blob = spnego_gen_auth(client_reply);
3085 data_blob_free(&client_reply);
3086 client_reply = tmp_blob;
3087 tmp_blob = data_blob_null;
3089 /* Now prepare the alter context pdu. */
3090 prs_init_empty(&state->rpc_out, state, MARSHALL);
3092 status = create_rpc_alter_context(state->rpc_call_id,
3093 &state->cli->abstract_syntax,
3094 &state->cli->transfer_syntax,
3095 state->cli->auth->auth_level,
3098 data_blob_free(&client_reply);
3100 if (!NT_STATUS_IS_OK(status)) {
3104 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3105 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3106 if (subreq == NULL) {
3107 return NT_STATUS_NO_MEMORY;
3109 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3110 return NT_STATUS_OK;
3113 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3115 struct tevent_req *req = tevent_req_callback_data(
3116 subreq, struct tevent_req);
3117 struct rpc_pipe_bind_state *state = tevent_req_data(
3118 req, struct rpc_pipe_bind_state);
3119 DATA_BLOB server_spnego_response = data_blob_null;
3120 DATA_BLOB tmp_blob = data_blob_null;
3121 prs_struct reply_pdu;
3122 struct rpc_hdr_info hdr;
3123 struct rpc_hdr_auth_info hdr_auth;
3126 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3127 TALLOC_FREE(subreq);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 tevent_req_nterror(req, status);
3133 /* Get the auth blob from the reply. */
3134 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3135 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3136 "unmarshall RPC_HDR.\n"));
3137 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3141 if (!prs_set_offset(
3143 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3144 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3148 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3149 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3153 server_spnego_response = data_blob(NULL, hdr.auth_len);
3154 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3157 /* Check we got a valid auth response. */
3158 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3159 OID_NTLMSSP, &tmp_blob)) {
3160 data_blob_free(&server_spnego_response);
3161 data_blob_free(&tmp_blob);
3162 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3166 data_blob_free(&server_spnego_response);
3167 data_blob_free(&tmp_blob);
3169 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3170 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3171 tevent_req_done(req);
3174 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3176 return tevent_req_simple_recv_ntstatus(req);
3179 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3180 struct cli_pipe_auth_data *auth)
3182 TALLOC_CTX *frame = talloc_stackframe();
3183 struct event_context *ev;
3184 struct tevent_req *req;
3185 NTSTATUS status = NT_STATUS_OK;
3187 ev = event_context_init(frame);
3189 status = NT_STATUS_NO_MEMORY;
3193 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3195 status = NT_STATUS_NO_MEMORY;
3199 if (!tevent_req_poll(req, ev)) {
3200 status = map_nt_error_from_unix(errno);
3204 status = rpc_pipe_bind_recv(req);
3210 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3212 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3213 unsigned int timeout)
3217 if (rpc_cli->transport == NULL) {
3218 return RPCCLI_DEFAULT_TIMEOUT;
3221 if (rpc_cli->transport->set_timeout == NULL) {
3222 return RPCCLI_DEFAULT_TIMEOUT;
3225 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3227 return RPCCLI_DEFAULT_TIMEOUT;
3233 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3235 if (rpc_cli == NULL) {
3239 if (rpc_cli->transport == NULL) {
3243 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3246 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3248 struct cli_state *cli;
3250 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3251 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3252 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3256 cli = rpc_pipe_np_smb_conn(rpc_cli);
3260 E_md4hash(cli->password ? cli->password : "", nt_hash);
3264 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3265 struct cli_pipe_auth_data **presult)
3267 struct cli_pipe_auth_data *result;
3269 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3270 if (result == NULL) {
3271 return NT_STATUS_NO_MEMORY;
3274 result->auth_type = PIPE_AUTH_TYPE_NONE;
3275 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3277 result->user_name = talloc_strdup(result, "");
3278 result->domain = talloc_strdup(result, "");
3279 if ((result->user_name == NULL) || (result->domain == NULL)) {
3280 TALLOC_FREE(result);
3281 return NT_STATUS_NO_MEMORY;
3285 return NT_STATUS_OK;
3288 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3290 ntlmssp_end(&auth->a_u.ntlmssp_state);
3294 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3295 enum pipe_auth_type auth_type,
3296 enum dcerpc_AuthLevel auth_level,
3298 const char *username,
3299 const char *password,
3300 struct cli_pipe_auth_data **presult)
3302 struct cli_pipe_auth_data *result;
3305 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3306 if (result == NULL) {
3307 return NT_STATUS_NO_MEMORY;
3310 result->auth_type = auth_type;
3311 result->auth_level = auth_level;
3313 result->user_name = talloc_strdup(result, username);
3314 result->domain = talloc_strdup(result, domain);
3315 if ((result->user_name == NULL) || (result->domain == NULL)) {
3316 status = NT_STATUS_NO_MEMORY;
3320 status = ntlmssp_client_start(NULL,
3323 lp_client_ntlmv2_auth(),
3324 &result->a_u.ntlmssp_state);
3325 if (!NT_STATUS_IS_OK(status)) {
3329 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3331 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3332 if (!NT_STATUS_IS_OK(status)) {
3336 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3337 if (!NT_STATUS_IS_OK(status)) {
3341 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3342 if (!NT_STATUS_IS_OK(status)) {
3347 * Turn off sign+seal to allow selected auth level to turn it back on.
3349 result->a_u.ntlmssp_state->neg_flags &=
3350 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3352 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3353 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3354 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3355 result->a_u.ntlmssp_state->neg_flags
3356 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3360 return NT_STATUS_OK;
3363 TALLOC_FREE(result);
3367 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3368 enum dcerpc_AuthLevel auth_level,
3369 struct netlogon_creds_CredentialState *creds,
3370 struct cli_pipe_auth_data **presult)
3372 struct cli_pipe_auth_data *result;
3374 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3375 if (result == NULL) {
3376 return NT_STATUS_NO_MEMORY;
3379 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3380 result->auth_level = auth_level;
3382 result->user_name = talloc_strdup(result, "");
3383 result->domain = talloc_strdup(result, domain);
3384 if ((result->user_name == NULL) || (result->domain == NULL)) {
3388 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3389 if (result->a_u.schannel_auth == NULL) {
3393 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3394 result->a_u.schannel_auth->seq_num = 0;
3395 result->a_u.schannel_auth->initiator = true;
3396 result->a_u.schannel_auth->creds = creds;
3399 return NT_STATUS_OK;
3402 TALLOC_FREE(result);
3403 return NT_STATUS_NO_MEMORY;
3407 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3409 data_blob_free(&auth->session_key);
3414 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3415 enum dcerpc_AuthLevel auth_level,
3416 const char *service_princ,
3417 const char *username,
3418 const char *password,
3419 struct cli_pipe_auth_data **presult)
3422 struct cli_pipe_auth_data *result;
3424 if ((username != NULL) && (password != NULL)) {
3425 int ret = kerberos_kinit_password(username, password, 0, NULL);
3427 return NT_STATUS_ACCESS_DENIED;
3431 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3432 if (result == NULL) {
3433 return NT_STATUS_NO_MEMORY;
3436 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3437 result->auth_level = auth_level;
3440 * Username / domain need fixing!
3442 result->user_name = talloc_strdup(result, "");
3443 result->domain = talloc_strdup(result, "");
3444 if ((result->user_name == NULL) || (result->domain == NULL)) {
3448 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3449 result, struct kerberos_auth_struct);
3450 if (result->a_u.kerberos_auth == NULL) {
3453 talloc_set_destructor(result->a_u.kerberos_auth,
3454 cli_auth_kerberos_data_destructor);
3456 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3457 result, service_princ);
3458 if (result->a_u.kerberos_auth->service_principal == NULL) {
3463 return NT_STATUS_OK;
3466 TALLOC_FREE(result);
3467 return NT_STATUS_NO_MEMORY;
3469 return NT_STATUS_NOT_SUPPORTED;
3474 * Create an rpc pipe client struct, connecting to a tcp port.
3476 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3478 const struct ndr_syntax_id *abstract_syntax,
3479 struct rpc_pipe_client **presult)
3481 struct rpc_pipe_client *result;
3482 struct sockaddr_storage addr;
3486 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3487 if (result == NULL) {
3488 return NT_STATUS_NO_MEMORY;
3491 result->abstract_syntax = *abstract_syntax;
3492 result->transfer_syntax = ndr_transfer_syntax;
3493 result->dispatch = cli_do_rpc_ndr;
3494 result->dispatch_send = cli_do_rpc_ndr_send;
3495 result->dispatch_recv = cli_do_rpc_ndr_recv;
3497 result->desthost = talloc_strdup(result, host);
3498 result->srv_name_slash = talloc_asprintf_strupper_m(
3499 result, "\\\\%s", result->desthost);
3500 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3501 status = NT_STATUS_NO_MEMORY;
3505 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3506 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3508 if (!resolve_name(host, &addr, 0, false)) {
3509 status = NT_STATUS_NOT_FOUND;
3513 status = open_socket_out(&addr, port, 60, &fd);
3514 if (!NT_STATUS_IS_OK(status)) {
3517 set_socket_options(fd, lp_socket_options());
3519 status = rpc_transport_sock_init(result, fd, &result->transport);
3520 if (!NT_STATUS_IS_OK(status)) {
3525 result->transport->transport = NCACN_IP_TCP;
3528 return NT_STATUS_OK;
3531 TALLOC_FREE(result);
3536 * Determine the tcp port on which a dcerpc interface is listening
3537 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3540 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3541 const struct ndr_syntax_id *abstract_syntax,
3545 struct rpc_pipe_client *epm_pipe = NULL;
3546 struct cli_pipe_auth_data *auth = NULL;
3547 struct dcerpc_binding *map_binding = NULL;
3548 struct dcerpc_binding *res_binding = NULL;
3549 struct epm_twr_t *map_tower = NULL;
3550 struct epm_twr_t *res_towers = NULL;
3551 struct policy_handle *entry_handle = NULL;
3552 uint32_t num_towers = 0;
3553 uint32_t max_towers = 1;
3554 struct epm_twr_p_t towers;
3555 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3557 if (pport == NULL) {
3558 status = NT_STATUS_INVALID_PARAMETER;
3562 /* open the connection to the endpoint mapper */
3563 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3564 &ndr_table_epmapper.syntax_id,
3567 if (!NT_STATUS_IS_OK(status)) {
3571 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3572 if (!NT_STATUS_IS_OK(status)) {
3576 status = rpc_pipe_bind(epm_pipe, auth);
3577 if (!NT_STATUS_IS_OK(status)) {
3581 /* create tower for asking the epmapper */
3583 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3584 if (map_binding == NULL) {
3585 status = NT_STATUS_NO_MEMORY;
3589 map_binding->transport = NCACN_IP_TCP;
3590 map_binding->object = *abstract_syntax;
3591 map_binding->host = host; /* needed? */
3592 map_binding->endpoint = "0"; /* correct? needed? */
3594 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3595 if (map_tower == NULL) {
3596 status = NT_STATUS_NO_MEMORY;
3600 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3601 &(map_tower->tower));
3602 if (!NT_STATUS_IS_OK(status)) {
3606 /* allocate further parameters for the epm_Map call */
3608 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3609 if (res_towers == NULL) {
3610 status = NT_STATUS_NO_MEMORY;
3613 towers.twr = res_towers;
3615 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3616 if (entry_handle == NULL) {
3617 status = NT_STATUS_NO_MEMORY;
3621 /* ask the endpoint mapper for the port */
3623 status = rpccli_epm_Map(epm_pipe,
3625 CONST_DISCARD(struct GUID *,
3626 &(abstract_syntax->uuid)),
3633 if (!NT_STATUS_IS_OK(status)) {
3637 if (num_towers != 1) {
3638 status = NT_STATUS_UNSUCCESSFUL;
3642 /* extract the port from the answer */
3644 status = dcerpc_binding_from_tower(tmp_ctx,
3645 &(towers.twr->tower),
3647 if (!NT_STATUS_IS_OK(status)) {
3651 /* are further checks here necessary? */
3652 if (res_binding->transport != NCACN_IP_TCP) {
3653 status = NT_STATUS_UNSUCCESSFUL;
3657 *pport = (uint16_t)atoi(res_binding->endpoint);
3660 TALLOC_FREE(tmp_ctx);
3665 * Create a rpc pipe client struct, connecting to a host via tcp.
3666 * The port is determined by asking the endpoint mapper on the given
3669 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3670 const struct ndr_syntax_id *abstract_syntax,
3671 struct rpc_pipe_client **presult)
3676 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3677 if (!NT_STATUS_IS_OK(status)) {
3681 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3682 abstract_syntax, presult);
3685 /********************************************************************
3686 Create a rpc pipe client struct, connecting to a unix domain socket
3687 ********************************************************************/
3688 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3689 const struct ndr_syntax_id *abstract_syntax,
3690 struct rpc_pipe_client **presult)
3692 struct rpc_pipe_client *result;
3693 struct sockaddr_un addr;
3697 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3698 if (result == NULL) {
3699 return NT_STATUS_NO_MEMORY;
3702 result->abstract_syntax = *abstract_syntax;
3703 result->transfer_syntax = ndr_transfer_syntax;
3704 result->dispatch = cli_do_rpc_ndr;
3705 result->dispatch_send = cli_do_rpc_ndr_send;
3706 result->dispatch_recv = cli_do_rpc_ndr_recv;
3708 result->desthost = get_myname(result);
3709 result->srv_name_slash = talloc_asprintf_strupper_m(
3710 result, "\\\\%s", result->desthost);
3711 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3712 status = NT_STATUS_NO_MEMORY;
3716 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3717 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3719 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3721 status = map_nt_error_from_unix(errno);
3726 addr.sun_family = AF_UNIX;
3727 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3729 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3730 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3733 return map_nt_error_from_unix(errno);
3736 status = rpc_transport_sock_init(result, fd, &result->transport);
3737 if (!NT_STATUS_IS_OK(status)) {
3742 result->transport->transport = NCALRPC;
3745 return NT_STATUS_OK;
3748 TALLOC_FREE(result);
3752 struct rpc_pipe_client_np_ref {
3753 struct cli_state *cli;
3754 struct rpc_pipe_client *pipe;
3757 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3759 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3763 /****************************************************************************
3764 Open a named pipe over SMB to a remote server.
3766 * CAVEAT CALLER OF THIS FUNCTION:
3767 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3768 * so be sure that this function is called AFTER any structure (vs pointer)
3769 * assignment of the cli. In particular, libsmbclient does structure
3770 * assignments of cli, which invalidates the data in the returned
3771 * rpc_pipe_client if this function is called before the structure assignment
3774 ****************************************************************************/
3776 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3777 const struct ndr_syntax_id *abstract_syntax,
3778 struct rpc_pipe_client **presult)
3780 struct rpc_pipe_client *result;
3782 struct rpc_pipe_client_np_ref *np_ref;
3784 /* sanity check to protect against crashes */
3787 return NT_STATUS_INVALID_HANDLE;
3790 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3791 if (result == NULL) {
3792 return NT_STATUS_NO_MEMORY;
3795 result->abstract_syntax = *abstract_syntax;
3796 result->transfer_syntax = ndr_transfer_syntax;
3797 result->dispatch = cli_do_rpc_ndr;
3798 result->dispatch_send = cli_do_rpc_ndr_send;
3799 result->dispatch_recv = cli_do_rpc_ndr_recv;
3800 result->desthost = talloc_strdup(result, cli->desthost);
3801 result->srv_name_slash = talloc_asprintf_strupper_m(
3802 result, "\\\\%s", result->desthost);
3804 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3805 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3807 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3808 TALLOC_FREE(result);
3809 return NT_STATUS_NO_MEMORY;
3812 status = rpc_transport_np_init(result, cli, abstract_syntax,
3813 &result->transport);
3814 if (!NT_STATUS_IS_OK(status)) {
3815 TALLOC_FREE(result);
3819 result->transport->transport = NCACN_NP;
3821 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3822 if (np_ref == NULL) {
3823 TALLOC_FREE(result);
3824 return NT_STATUS_NO_MEMORY;
3827 np_ref->pipe = result;
3829 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3830 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3833 return NT_STATUS_OK;
3836 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3837 struct rpc_cli_smbd_conn *conn,
3838 const struct ndr_syntax_id *syntax,
3839 struct rpc_pipe_client **presult)
3841 struct rpc_pipe_client *result;
3842 struct cli_pipe_auth_data *auth;
3845 result = talloc(mem_ctx, struct rpc_pipe_client);
3846 if (result == NULL) {
3847 return NT_STATUS_NO_MEMORY;
3849 result->abstract_syntax = *syntax;
3850 result->transfer_syntax = ndr_transfer_syntax;
3851 result->dispatch = cli_do_rpc_ndr;
3852 result->dispatch_send = cli_do_rpc_ndr_send;
3853 result->dispatch_recv = cli_do_rpc_ndr_recv;
3854 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3855 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3857 result->desthost = talloc_strdup(result, global_myname());
3858 result->srv_name_slash = talloc_asprintf_strupper_m(
3859 result, "\\\\%s", global_myname());
3860 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3861 TALLOC_FREE(result);
3862 return NT_STATUS_NO_MEMORY;
3865 status = rpc_transport_smbd_init(result, conn, syntax,
3866 &result->transport);
3867 if (!NT_STATUS_IS_OK(status)) {
3868 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3869 nt_errstr(status)));
3870 TALLOC_FREE(result);
3874 status = rpccli_anon_bind_data(result, &auth);
3875 if (!NT_STATUS_IS_OK(status)) {
3876 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3877 nt_errstr(status)));
3878 TALLOC_FREE(result);
3882 status = rpc_pipe_bind(result, auth);
3883 if (!NT_STATUS_IS_OK(status)) {
3884 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3885 TALLOC_FREE(result);
3889 result->transport->transport = NCACN_INTERNAL;
3892 return NT_STATUS_OK;
3895 /****************************************************************************
3896 Open a pipe to a remote server.
3897 ****************************************************************************/
3899 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3900 enum dcerpc_transport_t transport,
3901 const struct ndr_syntax_id *interface,
3902 struct rpc_pipe_client **presult)
3904 switch (transport) {
3906 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3909 return rpc_pipe_open_np(cli, interface, presult);
3911 return NT_STATUS_NOT_IMPLEMENTED;
3915 /****************************************************************************
3916 Open a named pipe to an SMB server and bind anonymously.
3917 ****************************************************************************/
3919 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3920 enum dcerpc_transport_t transport,
3921 const struct ndr_syntax_id *interface,
3922 struct rpc_pipe_client **presult)
3924 struct rpc_pipe_client *result;
3925 struct cli_pipe_auth_data *auth;
3928 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3929 if (!NT_STATUS_IS_OK(status)) {
3933 status = rpccli_anon_bind_data(result, &auth);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3936 nt_errstr(status)));
3937 TALLOC_FREE(result);
3942 * This is a bit of an abstraction violation due to the fact that an
3943 * anonymous bind on an authenticated SMB inherits the user/domain
3944 * from the enclosing SMB creds
3947 TALLOC_FREE(auth->user_name);
3948 TALLOC_FREE(auth->domain);
3950 auth->user_name = talloc_strdup(auth, cli->user_name);
3951 auth->domain = talloc_strdup(auth, cli->domain);
3952 auth->user_session_key = data_blob_talloc(auth,
3953 cli->user_session_key.data,
3954 cli->user_session_key.length);
3956 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3957 TALLOC_FREE(result);
3958 return NT_STATUS_NO_MEMORY;
3961 status = rpc_pipe_bind(result, auth);
3962 if (!NT_STATUS_IS_OK(status)) {
3964 if (ndr_syntax_id_equal(interface,
3965 &ndr_table_dssetup.syntax_id)) {
3966 /* non AD domains just don't have this pipe, avoid
3967 * level 0 statement in that case - gd */
3970 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3971 "%s failed with error %s\n",
3972 get_pipe_name_from_syntax(talloc_tos(), interface),
3973 nt_errstr(status) ));
3974 TALLOC_FREE(result);
3978 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3979 "%s and bound anonymously.\n",
3980 get_pipe_name_from_syntax(talloc_tos(), interface),
3984 return NT_STATUS_OK;
3987 /****************************************************************************
3988 ****************************************************************************/
3990 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3991 const struct ndr_syntax_id *interface,
3992 struct rpc_pipe_client **presult)
3994 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3995 interface, presult);
3998 /****************************************************************************
3999 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4000 ****************************************************************************/
4002 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4003 const struct ndr_syntax_id *interface,
4004 enum dcerpc_transport_t transport,
4005 enum pipe_auth_type auth_type,
4006 enum dcerpc_AuthLevel auth_level,
4008 const char *username,
4009 const char *password,
4010 struct rpc_pipe_client **presult)
4012 struct rpc_pipe_client *result;
4013 struct cli_pipe_auth_data *auth;
4016 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4017 if (!NT_STATUS_IS_OK(status)) {
4021 status = rpccli_ntlmssp_bind_data(
4022 result, auth_type, auth_level, domain, username,
4024 if (!NT_STATUS_IS_OK(status)) {
4025 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4026 nt_errstr(status)));
4030 status = rpc_pipe_bind(result, auth);
4031 if (!NT_STATUS_IS_OK(status)) {
4032 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4033 nt_errstr(status) ));
4037 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4038 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4039 get_pipe_name_from_syntax(talloc_tos(), interface),
4040 cli->desthost, domain, username ));
4043 return NT_STATUS_OK;
4047 TALLOC_FREE(result);
4051 /****************************************************************************
4053 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4054 ****************************************************************************/
4056 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4057 const struct ndr_syntax_id *interface,
4058 enum dcerpc_transport_t transport,
4059 enum dcerpc_AuthLevel auth_level,
4061 const char *username,
4062 const char *password,
4063 struct rpc_pipe_client **presult)
4065 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4068 PIPE_AUTH_TYPE_NTLMSSP,
4076 /****************************************************************************
4078 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4079 ****************************************************************************/
4081 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4082 const struct ndr_syntax_id *interface,
4083 enum dcerpc_transport_t transport,
4084 enum dcerpc_AuthLevel auth_level,
4086 const char *username,
4087 const char *password,
4088 struct rpc_pipe_client **presult)
4090 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4093 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4101 /****************************************************************************
4102 Get a the schannel session key out of an already opened netlogon pipe.
4103 ****************************************************************************/
4104 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4105 struct cli_state *cli,
4109 enum netr_SchannelType sec_chan_type = 0;
4110 unsigned char machine_pwd[16];
4111 const char *machine_account;
4114 /* Get the machine account credentials from secrets.tdb. */
4115 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4118 DEBUG(0, ("get_schannel_session_key: could not fetch "
4119 "trust account password for domain '%s'\n",
4121 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4124 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4125 cli->desthost, /* server name */
4126 domain, /* domain */
4127 global_myname(), /* client name */
4128 machine_account, /* machine account name */
4133 if (!NT_STATUS_IS_OK(status)) {
4134 DEBUG(3, ("get_schannel_session_key_common: "
4135 "rpccli_netlogon_setup_creds failed with result %s "
4136 "to server %s, domain %s, machine account %s.\n",
4137 nt_errstr(status), cli->desthost, domain,
4142 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4143 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4145 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4148 return NT_STATUS_OK;;
4151 /****************************************************************************
4152 Open a netlogon pipe and get the schannel session key.
4153 Now exposed to external callers.
4154 ****************************************************************************/
4157 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4160 struct rpc_pipe_client **presult)
4162 struct rpc_pipe_client *netlogon_pipe = NULL;
4165 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4167 if (!NT_STATUS_IS_OK(status)) {
4171 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4173 if (!NT_STATUS_IS_OK(status)) {
4174 TALLOC_FREE(netlogon_pipe);
4178 *presult = netlogon_pipe;
4179 return NT_STATUS_OK;
4182 /****************************************************************************
4184 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4185 using session_key. sign and seal.
4187 The *pdc will be stolen onto this new pipe
4188 ****************************************************************************/
4190 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4191 const struct ndr_syntax_id *interface,
4192 enum dcerpc_transport_t transport,
4193 enum dcerpc_AuthLevel auth_level,
4195 struct netlogon_creds_CredentialState **pdc,
4196 struct rpc_pipe_client **presult)
4198 struct rpc_pipe_client *result;
4199 struct cli_pipe_auth_data *auth;
4202 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4203 if (!NT_STATUS_IS_OK(status)) {
4207 status = rpccli_schannel_bind_data(result, domain, auth_level,
4209 if (!NT_STATUS_IS_OK(status)) {
4210 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4211 nt_errstr(status)));
4212 TALLOC_FREE(result);
4216 status = rpc_pipe_bind(result, auth);
4217 if (!NT_STATUS_IS_OK(status)) {
4218 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4219 "cli_rpc_pipe_bind failed with error %s\n",
4220 nt_errstr(status) ));
4221 TALLOC_FREE(result);
4226 * The credentials on a new netlogon pipe are the ones we are passed
4227 * in - reference them in
4229 result->dc = talloc_move(result, pdc);
4231 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4232 "for domain %s and bound using schannel.\n",
4233 get_pipe_name_from_syntax(talloc_tos(), interface),
4234 cli->desthost, domain ));
4237 return NT_STATUS_OK;
4240 /****************************************************************************
4241 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4242 Fetch the session key ourselves using a temporary netlogon pipe. This
4243 version uses an ntlmssp auth bound netlogon pipe to get the key.
4244 ****************************************************************************/
4246 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4248 const char *username,
4249 const char *password,
4251 struct rpc_pipe_client **presult)
4253 struct rpc_pipe_client *netlogon_pipe = NULL;
4256 status = cli_rpc_pipe_open_spnego_ntlmssp(
4257 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4258 DCERPC_AUTH_LEVEL_PRIVACY,
4259 domain, username, password, &netlogon_pipe);
4260 if (!NT_STATUS_IS_OK(status)) {
4264 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4266 if (!NT_STATUS_IS_OK(status)) {
4267 TALLOC_FREE(netlogon_pipe);
4271 *presult = netlogon_pipe;
4272 return NT_STATUS_OK;
4275 /****************************************************************************
4276 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4277 Fetch the session key ourselves using a temporary netlogon pipe. This version
4278 uses an ntlmssp bind to get the session key.
4279 ****************************************************************************/
4281 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4282 const struct ndr_syntax_id *interface,
4283 enum dcerpc_transport_t transport,
4284 enum dcerpc_AuthLevel auth_level,
4286 const char *username,
4287 const char *password,
4288 struct rpc_pipe_client **presult)
4290 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4291 struct rpc_pipe_client *netlogon_pipe = NULL;
4292 struct rpc_pipe_client *result = NULL;
4295 status = get_schannel_session_key_auth_ntlmssp(
4296 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4297 if (!NT_STATUS_IS_OK(status)) {
4298 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4299 "key from server %s for domain %s.\n",
4300 cli->desthost, domain ));
4304 status = cli_rpc_pipe_open_schannel_with_key(
4305 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4308 /* Now we've bound using the session key we can close the netlog pipe. */
4309 TALLOC_FREE(netlogon_pipe);
4311 if (NT_STATUS_IS_OK(status)) {
4317 /****************************************************************************
4318 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4319 Fetch the session key ourselves using a temporary netlogon pipe.
4320 ****************************************************************************/
4322 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4323 const struct ndr_syntax_id *interface,
4324 enum dcerpc_transport_t transport,
4325 enum dcerpc_AuthLevel auth_level,
4327 struct rpc_pipe_client **presult)
4329 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4330 struct rpc_pipe_client *netlogon_pipe = NULL;
4331 struct rpc_pipe_client *result = NULL;
4334 status = get_schannel_session_key(cli, domain, &neg_flags,
4336 if (!NT_STATUS_IS_OK(status)) {
4337 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4338 "key from server %s for domain %s.\n",
4339 cli->desthost, domain ));
4343 status = cli_rpc_pipe_open_schannel_with_key(
4344 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4347 /* Now we've bound using the session key we can close the netlog pipe. */
4348 TALLOC_FREE(netlogon_pipe);
4350 if (NT_STATUS_IS_OK(status)) {
4357 /****************************************************************************
4358 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4359 The idea is this can be called with service_princ, username and password all
4360 NULL so long as the caller has a TGT.
4361 ****************************************************************************/
4363 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4364 const struct ndr_syntax_id *interface,
4365 enum dcerpc_AuthLevel auth_level,
4366 const char *service_princ,
4367 const char *username,
4368 const char *password,
4369 struct rpc_pipe_client **presult)
4372 struct rpc_pipe_client *result;
4373 struct cli_pipe_auth_data *auth;
4376 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4377 if (!NT_STATUS_IS_OK(status)) {
4381 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4382 username, password, &auth);
4383 if (!NT_STATUS_IS_OK(status)) {
4384 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4385 nt_errstr(status)));
4386 TALLOC_FREE(result);
4390 status = rpc_pipe_bind(result, auth);
4391 if (!NT_STATUS_IS_OK(status)) {
4392 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4393 "with error %s\n", nt_errstr(status)));
4394 TALLOC_FREE(result);
4399 return NT_STATUS_OK;
4401 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4402 return NT_STATUS_NOT_IMPLEMENTED;
4406 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4407 struct rpc_pipe_client *cli,
4408 DATA_BLOB *session_key)
4410 if (!session_key || !cli) {
4411 return NT_STATUS_INVALID_PARAMETER;
4415 return NT_STATUS_INVALID_PARAMETER;
4418 switch (cli->auth->auth_type) {
4419 case PIPE_AUTH_TYPE_SCHANNEL:
4420 *session_key = data_blob_talloc(mem_ctx,
4421 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4423 case PIPE_AUTH_TYPE_NTLMSSP:
4424 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4425 *session_key = data_blob_talloc(mem_ctx,
4426 cli->auth->a_u.ntlmssp_state->session_key.data,
4427 cli->auth->a_u.ntlmssp_state->session_key.length);
4429 case PIPE_AUTH_TYPE_KRB5:
4430 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4431 *session_key = data_blob_talloc(mem_ctx,
4432 cli->auth->a_u.kerberos_auth->session_key.data,
4433 cli->auth->a_u.kerberos_auth->session_key.length);
4435 case PIPE_AUTH_TYPE_NONE:
4436 *session_key = data_blob_talloc(mem_ctx,
4437 cli->auth->user_session_key.data,
4438 cli->auth->user_session_key.length);
4441 return NT_STATUS_NO_USER_SESSION_KEY;
4444 return NT_STATUS_OK;