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 auth_length,
305 union dcerpc_payload *u,
308 struct ncacn_packet r;
309 enum ndr_err_code ndr_err;
312 r.rpc_vers_minor = 0;
314 r.pfc_flags = pfc_flags;
315 r.drep[0] = DCERPC_DREP_LE;
319 r.auth_length = auth_length;
323 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
324 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
325 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
326 return ndr_map_error2ntstatus(ndr_err);
329 dcerpc_set_frag_length(blob, blob->length);
332 if (DEBUGLEVEL >= 10) {
333 /* set frag len for print function */
334 r.frag_length = blob->length;
335 NDR_PRINT_DEBUG(ncacn_packet, &r);
341 NTSTATUS dcerpc_push_ncacn_packet_header(TALLOC_CTX *mem_ctx,
342 enum dcerpc_pkt_type ptype,
344 uint16_t frag_length,
345 uint16_t auth_length,
349 struct ncacn_packet_header r;
350 enum ndr_err_code ndr_err;
353 r.rpc_vers_minor = 0;
355 r.pfc_flags = pfc_flags;
356 r.drep[0] = DCERPC_DREP_LE;
360 r.frag_length = frag_length;
361 r.auth_length = auth_length;
364 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
365 (ndr_push_flags_fn_t)ndr_push_ncacn_packet_header);
366 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
367 return ndr_map_error2ntstatus(ndr_err);
370 if (DEBUGLEVEL >= 10) {
371 NDR_PRINT_DEBUG(ncacn_packet_header, &r);
377 /*******************************************************************
378 *******************************************************************/
380 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
381 const DATA_BLOB *blob,
382 struct ncacn_packet *r)
384 enum ndr_err_code ndr_err;
386 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
387 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
388 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
389 return ndr_map_error2ntstatus(ndr_err);
392 if (DEBUGLEVEL >= 10) {
393 NDR_PRINT_DEBUG(ncacn_packet, r);
399 /*******************************************************************
400 *******************************************************************/
402 NTSTATUS dcerpc_pull_ncacn_packet_header(TALLOC_CTX *mem_ctx,
403 const DATA_BLOB *blob,
404 struct ncacn_packet_header *r)
406 enum ndr_err_code ndr_err;
408 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
409 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet_header);
410 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
411 return ndr_map_error2ntstatus(ndr_err);
414 if (DEBUGLEVEL >= 10) {
415 NDR_PRINT_DEBUG(ncacn_packet_header, r);
421 /*******************************************************************
422 ********************************************************************/
424 static NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
425 struct NL_AUTH_MESSAGE *r,
428 enum ndr_err_code ndr_err;
430 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
431 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
432 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
433 return ndr_map_error2ntstatus(ndr_err);
436 if (DEBUGLEVEL >= 10) {
437 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
443 /*******************************************************************
444 ********************************************************************/
446 NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
447 const DATA_BLOB *blob,
448 struct dcerpc_auth *r)
450 enum ndr_err_code ndr_err;
452 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
453 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
454 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
455 return ndr_map_error2ntstatus(ndr_err);
458 if (DEBUGLEVEL >= 10) {
459 NDR_PRINT_DEBUG(dcerpc_auth, r);
465 /*******************************************************************
466 Use SMBreadX to get rest of one fragment's worth of rpc data.
467 Reads the whole size or give an error message
468 ********************************************************************/
470 struct rpc_read_state {
471 struct event_context *ev;
472 struct rpc_cli_transport *transport;
478 static void rpc_read_done(struct tevent_req *subreq);
480 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
481 struct event_context *ev,
482 struct rpc_cli_transport *transport,
483 uint8_t *data, size_t size)
485 struct tevent_req *req, *subreq;
486 struct rpc_read_state *state;
488 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
493 state->transport = transport;
498 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
500 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
502 if (subreq == NULL) {
505 tevent_req_set_callback(subreq, rpc_read_done, req);
513 static void rpc_read_done(struct tevent_req *subreq)
515 struct tevent_req *req = tevent_req_callback_data(
516 subreq, struct tevent_req);
517 struct rpc_read_state *state = tevent_req_data(
518 req, struct rpc_read_state);
522 status = state->transport->read_recv(subreq, &received);
524 if (!NT_STATUS_IS_OK(status)) {
525 tevent_req_nterror(req, status);
529 state->num_read += received;
530 if (state->num_read == state->size) {
531 tevent_req_done(req);
535 subreq = state->transport->read_send(state, state->ev,
536 state->data + state->num_read,
537 state->size - state->num_read,
538 state->transport->priv);
539 if (tevent_req_nomem(subreq, req)) {
542 tevent_req_set_callback(subreq, rpc_read_done, req);
545 static NTSTATUS rpc_read_recv(struct tevent_req *req)
547 return tevent_req_simple_recv_ntstatus(req);
550 struct rpc_write_state {
551 struct event_context *ev;
552 struct rpc_cli_transport *transport;
558 static void rpc_write_done(struct tevent_req *subreq);
560 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
561 struct event_context *ev,
562 struct rpc_cli_transport *transport,
563 const uint8_t *data, size_t size)
565 struct tevent_req *req, *subreq;
566 struct rpc_write_state *state;
568 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
573 state->transport = transport;
576 state->num_written = 0;
578 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
580 subreq = transport->write_send(state, ev, data, size, transport->priv);
581 if (subreq == NULL) {
584 tevent_req_set_callback(subreq, rpc_write_done, req);
591 static void rpc_write_done(struct tevent_req *subreq)
593 struct tevent_req *req = tevent_req_callback_data(
594 subreq, struct tevent_req);
595 struct rpc_write_state *state = tevent_req_data(
596 req, struct rpc_write_state);
600 status = state->transport->write_recv(subreq, &written);
602 if (!NT_STATUS_IS_OK(status)) {
603 tevent_req_nterror(req, status);
607 state->num_written += written;
609 if (state->num_written == state->size) {
610 tevent_req_done(req);
614 subreq = state->transport->write_send(state, state->ev,
615 state->data + state->num_written,
616 state->size - state->num_written,
617 state->transport->priv);
618 if (tevent_req_nomem(subreq, req)) {
621 tevent_req_set_callback(subreq, rpc_write_done, req);
624 static NTSTATUS rpc_write_recv(struct tevent_req *req)
626 return tevent_req_simple_recv_ntstatus(req);
630 /****************************************************************************
631 Try and get a PDU's worth of data from current_pdu. If not, then read more
633 ****************************************************************************/
635 struct get_complete_frag_state {
636 struct event_context *ev;
637 struct rpc_pipe_client *cli;
642 static void get_complete_frag_got_header(struct tevent_req *subreq);
643 static void get_complete_frag_got_rest(struct tevent_req *subreq);
645 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
646 struct event_context *ev,
647 struct rpc_pipe_client *cli,
650 struct tevent_req *req, *subreq;
651 struct get_complete_frag_state *state;
656 req = tevent_req_create(mem_ctx, &state,
657 struct get_complete_frag_state);
663 state->frag_len = RPC_HEADER_LEN;
666 pdu_len = prs_data_size(pdu);
667 if (pdu_len < RPC_HEADER_LEN) {
668 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
669 status = NT_STATUS_NO_MEMORY;
672 subreq = rpc_read_send(
674 state->cli->transport,
675 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
676 RPC_HEADER_LEN - pdu_len);
677 if (subreq == NULL) {
678 status = NT_STATUS_NO_MEMORY;
681 tevent_req_set_callback(subreq, get_complete_frag_got_header,
686 blob = data_blob_const(prs_data_p(state->pdu), pdu_len);
687 state->frag_len = dcerpc_get_frag_length(&blob);
690 * Ensure we have frag_len bytes of data.
692 if (pdu_len < state->frag_len) {
693 if (!rpc_grow_buffer(pdu, state->frag_len)) {
694 status = NT_STATUS_NO_MEMORY;
697 subreq = rpc_read_send(state, state->ev,
698 state->cli->transport,
699 (uint8_t *)(prs_data_p(pdu) + pdu_len),
700 state->frag_len - pdu_len);
701 if (subreq == NULL) {
702 status = NT_STATUS_NO_MEMORY;
705 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
710 status = NT_STATUS_OK;
712 if (NT_STATUS_IS_OK(status)) {
713 tevent_req_done(req);
715 tevent_req_nterror(req, status);
717 return tevent_req_post(req, ev);
720 static void get_complete_frag_got_header(struct tevent_req *subreq)
722 struct tevent_req *req = tevent_req_callback_data(
723 subreq, struct tevent_req);
724 struct get_complete_frag_state *state = tevent_req_data(
725 req, struct get_complete_frag_state);
729 status = rpc_read_recv(subreq);
731 if (!NT_STATUS_IS_OK(status)) {
732 tevent_req_nterror(req, status);
736 pdu = data_blob_const(prs_data_p(state->pdu),
737 prs_data_size(state->pdu));
738 state->frag_len = dcerpc_get_frag_length(&pdu);
740 if (!rpc_grow_buffer(state->pdu, state->frag_len)) {
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->frag_len - RPC_HEADER_LEN);
754 if (tevent_req_nomem(subreq, req)) {
757 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
760 static void get_complete_frag_got_rest(struct tevent_req *subreq)
762 struct tevent_req *req = tevent_req_callback_data(
763 subreq, struct tevent_req);
766 status = rpc_read_recv(subreq);
768 if (!NT_STATUS_IS_OK(status)) {
769 tevent_req_nterror(req, status);
772 tevent_req_done(req);
775 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
777 return tevent_req_simple_recv_ntstatus(req);
780 /****************************************************************************
781 NTLMSSP specific sign/seal.
782 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
783 In fact I should probably abstract these into identical pieces of code... JRA.
784 ****************************************************************************/
786 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
787 struct ncacn_packet_header *prhdr,
788 prs_struct *current_pdu,
789 uint8 *p_ss_padding_len)
791 struct dcerpc_auth auth_info;
792 uint32 save_offset = prs_offset(current_pdu);
793 uint32_t auth_len = prhdr->auth_length;
794 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
795 unsigned char *data = NULL;
797 unsigned char *full_packet_data = NULL;
798 size_t full_packet_data_len;
803 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
804 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
808 if (!ntlmssp_state) {
809 return NT_STATUS_INVALID_PARAMETER;
812 /* Ensure there's enough data for an authenticated response. */
813 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
814 prhdr->frag_length < RPC_HEADER_LEN +
816 RPC_HDR_AUTH_LEN + auth_len) {
817 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
818 (unsigned int)auth_len ));
819 return NT_STATUS_BUFFER_TOO_SMALL;
823 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
824 * after the RPC header.
825 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
826 * functions as NTLMv2 checks the rpc headers also.
829 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
830 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
832 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
833 full_packet_data_len = prhdr->frag_length - auth_len;
835 /* Pull the auth header and the following data into a blob. */
836 /* NB. The offset of the auth_header is relative to the *end*
837 * of the packet, not the start. */
838 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
839 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
840 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
841 return NT_STATUS_BUFFER_TOO_SMALL;
844 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu),
845 prs_data_size(current_pdu) - prs_offset(current_pdu));
847 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
848 if (!NT_STATUS_IS_OK(status)) {
849 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
853 /* Ensure auth_pad_len fits into the packet. */
854 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
855 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
856 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
857 "too large (%u), auth_len (%u), frag_len = (%u).\n",
858 (unsigned int)auth_info.auth_pad_length,
859 (unsigned int)auth_len,
860 (unsigned int)prhdr->frag_length));
861 return NT_STATUS_BUFFER_TOO_SMALL;
865 auth_blob = auth_info.credentials;
867 switch (cli->auth->auth_level) {
868 case DCERPC_AUTH_LEVEL_PRIVACY:
869 /* Data is encrypted. */
870 status = ntlmssp_unseal_packet(ntlmssp_state,
873 full_packet_data_len,
875 if (!NT_STATUS_IS_OK(status)) {
876 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
877 "packet from %s. Error was %s.\n",
878 rpccli_pipe_txt(talloc_tos(), cli),
879 nt_errstr(status) ));
883 case DCERPC_AUTH_LEVEL_INTEGRITY:
884 /* Data is signed. */
885 status = ntlmssp_check_packet(ntlmssp_state,
888 full_packet_data_len,
890 if (!NT_STATUS_IS_OK(status)) {
891 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
892 "packet from %s. Error was %s.\n",
893 rpccli_pipe_txt(talloc_tos(), cli),
894 nt_errstr(status) ));
899 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
900 "auth level %d\n", cli->auth->auth_level));
901 return NT_STATUS_INVALID_INFO_CLASS;
905 * Return the current pointer to the data offset.
908 if(!prs_set_offset(current_pdu, save_offset)) {
909 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
910 (unsigned int)save_offset ));
911 return NT_STATUS_BUFFER_TOO_SMALL;
915 * Remember the padding length. We must remove it from the real data
916 * stream once the sign/seal is done.
919 *p_ss_padding_len = auth_info.auth_pad_length;
924 /****************************************************************************
925 schannel specific sign/seal.
926 ****************************************************************************/
928 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
929 struct ncacn_packet_header *prhdr,
930 prs_struct *current_pdu,
931 uint8 *p_ss_padding_len)
933 struct dcerpc_auth auth_info;
934 uint32_t auth_len = prhdr->auth_length;
935 uint32 save_offset = prs_offset(current_pdu);
936 struct schannel_state *schannel_auth =
937 cli->auth->a_u.schannel_auth;
943 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
944 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
948 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
949 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
950 return NT_STATUS_INVALID_PARAMETER;
953 if (!schannel_auth) {
954 return NT_STATUS_INVALID_PARAMETER;
957 /* Ensure there's enough data for an authenticated response. */
958 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
959 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length)) {
960 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
961 (unsigned int)auth_len ));
962 return NT_STATUS_INVALID_PARAMETER;
965 data_len = prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
967 /* Pull the auth header and the following data into a blob. */
968 /* NB. The offset of the auth_header is relative to the *end*
969 * of the packet, not the start. */
970 if(!prs_set_offset(current_pdu,
971 prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
972 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
974 (unsigned int)(prhdr->frag_length -
975 RPC_HDR_AUTH_LEN - auth_len) ));
976 return NT_STATUS_BUFFER_TOO_SMALL;
979 blob = data_blob_const(prs_data_p(current_pdu)
980 + prs_offset(current_pdu),
981 prs_data_size(current_pdu)
982 - prs_offset(current_pdu));
984 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
985 if (!NT_STATUS_IS_OK(status)) {
986 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
990 /* Ensure auth_pad_len fits into the packet. */
991 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
992 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
993 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
994 "too large (%u), auth_len (%u), frag_len = (%u).\n",
995 (unsigned int)auth_info.auth_pad_length,
996 (unsigned int)auth_len,
997 (unsigned int)prhdr->frag_length));
998 return NT_STATUS_BUFFER_TOO_SMALL;
1001 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1002 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
1003 auth_info.auth_type));
1004 return NT_STATUS_BUFFER_TOO_SMALL;
1007 blob = data_blob_const(prs_data_p(current_pdu) +
1008 prs_offset(current_pdu) +
1009 RPC_HDR_AUTH_LEN, auth_len);
1011 if (DEBUGLEVEL >= 10) {
1012 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1015 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1017 switch (cli->auth->auth_level) {
1018 case DCERPC_AUTH_LEVEL_PRIVACY:
1019 status = netsec_incoming_packet(schannel_auth,
1026 case DCERPC_AUTH_LEVEL_INTEGRITY:
1027 status = netsec_incoming_packet(schannel_auth,
1035 status = NT_STATUS_INTERNAL_ERROR;
1039 if (!NT_STATUS_IS_OK(status)) {
1040 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1041 "Connection to %s (%s).\n",
1042 rpccli_pipe_txt(talloc_tos(), cli),
1043 nt_errstr(status)));
1044 return NT_STATUS_INVALID_PARAMETER;
1048 * Return the current pointer to the data offset.
1051 if(!prs_set_offset(current_pdu, save_offset)) {
1052 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1053 (unsigned int)save_offset ));
1054 return NT_STATUS_BUFFER_TOO_SMALL;
1058 * Remember the padding length. We must remove it from the real data
1059 * stream once the sign/seal is done.
1062 *p_ss_padding_len = auth_info.auth_pad_length;
1064 return NT_STATUS_OK;
1067 /****************************************************************************
1068 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1069 ****************************************************************************/
1071 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1072 struct ncacn_packet_header *prhdr,
1073 prs_struct *current_pdu,
1074 uint8 *p_ss_padding_len)
1076 NTSTATUS ret = NT_STATUS_OK;
1078 /* Paranioa checks for auth_len. */
1079 if (prhdr->auth_length) {
1080 if (prhdr->auth_length > prhdr->frag_length) {
1081 return NT_STATUS_INVALID_PARAMETER;
1084 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1085 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1086 /* Integer wrap attempt. */
1087 return NT_STATUS_INVALID_PARAMETER;
1092 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1095 switch(cli->auth->auth_type) {
1096 case PIPE_AUTH_TYPE_NONE:
1097 if (prhdr->auth_length) {
1098 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1099 "Connection to %s - got non-zero "
1101 rpccli_pipe_txt(talloc_tos(), cli),
1102 (unsigned int)prhdr->auth_length));
1103 return NT_STATUS_INVALID_PARAMETER;
1107 case PIPE_AUTH_TYPE_NTLMSSP:
1108 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1109 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1110 if (!NT_STATUS_IS_OK(ret)) {
1115 case PIPE_AUTH_TYPE_SCHANNEL:
1116 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1117 if (!NT_STATUS_IS_OK(ret)) {
1122 case PIPE_AUTH_TYPE_KRB5:
1123 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1125 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1126 "to %s - unknown internal auth type %u.\n",
1127 rpccli_pipe_txt(talloc_tos(), cli),
1128 cli->auth->auth_type ));
1129 return NT_STATUS_INVALID_INFO_CLASS;
1132 return NT_STATUS_OK;
1135 /****************************************************************************
1136 Do basic authentication checks on an incoming pdu.
1137 ****************************************************************************/
1139 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1140 struct ncacn_packet *pkt,
1141 prs_struct *current_pdu,
1142 uint8 expected_pkt_type,
1145 prs_struct *return_data)
1147 struct ncacn_packet_header prhdr;
1148 NTSTATUS ret = NT_STATUS_OK;
1149 uint32 current_pdu_len = prs_data_size(current_pdu);
1150 DATA_BLOB blob = data_blob_const(prs_data_p(current_pdu),
1151 prs_data_size(current_pdu));
1153 ret = dcerpc_pull_ncacn_packet(cli, &blob, pkt);
1154 if (!NT_STATUS_IS_OK(ret)) {
1158 /* FIXME: although we already unmarshalled the whole packet,
1159 * set the offset of the pdu to right after the header
1160 * until the rest of the code downstream is changed
1161 * to always use the already decoded packet and not try
1162 * to unmarshall bits of the packet.
1164 if (!prs_set_offset(current_pdu,
1165 prs_offset(current_pdu) + RPC_HEADER_LEN)) {
1166 return NT_STATUS_BUFFER_TOO_SMALL;
1169 /* FIXME: until all functions are converted to take in
1170 * a fully decoded packet
1172 memcpy(&prhdr, pkt, sizeof(prhdr));
1175 if (current_pdu_len != pkt->frag_length) {
1176 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
1177 (unsigned int)current_pdu_len,
1178 (unsigned int)pkt->frag_length));
1179 return NT_STATUS_INVALID_PARAMETER;
1183 * Point the return values at the real data including the RPC
1184 * header. Just in case the caller wants it.
1186 *ppdata = prs_data_p(current_pdu);
1187 *pdata_len = current_pdu_len;
1189 /* Ensure we have the correct type. */
1190 switch (pkt->ptype) {
1191 case DCERPC_PKT_ALTER_RESP:
1192 case DCERPC_PKT_BIND_ACK:
1194 /* Alter context and bind ack share the same packet definitions. */
1198 case DCERPC_PKT_RESPONSE:
1200 uint8 ss_padding_len = 0;
1202 if (!prs_set_offset(current_pdu, prs_offset(current_pdu) + RPC_HDR_RESP_LEN)) {
1203 return NT_STATUS_BUFFER_TOO_SMALL;
1206 /* Here's where we deal with incoming sign/seal. */
1207 ret = cli_pipe_validate_rpc_response(cli, &prhdr,
1208 current_pdu, &ss_padding_len);
1209 if (!NT_STATUS_IS_OK(ret)) {
1213 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1214 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1216 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1217 return NT_STATUS_BUFFER_TOO_SMALL;
1220 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1222 /* Remember to remove the auth footer. */
1223 if (pkt->auth_length) {
1224 /* We've already done integer wrap tests on auth_len in
1225 cli_pipe_validate_rpc_response(). */
1226 if (*pdata_len < RPC_HDR_AUTH_LEN + pkt->auth_length) {
1227 return NT_STATUS_BUFFER_TOO_SMALL;
1229 *pdata_len -= (RPC_HDR_AUTH_LEN + pkt->auth_length);
1232 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1233 current_pdu_len, *pdata_len, ss_padding_len ));
1236 * If this is the first reply, and the allocation hint is reasonably, try and
1237 * set up the return_data parse_struct to the correct size.
1240 if ((prs_data_size(return_data) == 0) &&
1241 pkt->u.response.alloc_hint &&
1242 (pkt->u.response.alloc_hint < 15*1024*1024)) {
1243 if (!prs_set_buffer_size(return_data,
1244 pkt->u.response.alloc_hint)) {
1245 DEBUG(0, ("reply alloc hint %d too "
1246 "large to allocate\n",
1247 (int)pkt->u.response.alloc_hint));
1248 return NT_STATUS_NO_MEMORY;
1255 case DCERPC_PKT_BIND_NAK:
1256 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1257 "received from %s!\n",
1258 rpccli_pipe_txt(talloc_tos(), cli)));
1259 /* Use this for now... */
1260 return NT_STATUS_NETWORK_ACCESS_DENIED;
1262 case DCERPC_PKT_FAULT:
1264 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1265 "code %s received from %s!\n",
1266 dcerpc_errstr(talloc_tos(),
1267 pkt->u.fault.status),
1268 rpccli_pipe_txt(talloc_tos(), cli)));
1270 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
1271 return NT_STATUS_UNSUCCESSFUL;
1273 return NT_STATUS(pkt->u.fault.status);
1277 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1279 (unsigned int)pkt->ptype,
1280 rpccli_pipe_txt(talloc_tos(), cli)));
1281 return NT_STATUS_INVALID_INFO_CLASS;
1284 if (pkt->ptype != expected_pkt_type) {
1285 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1286 "got an unexpected RPC packet type - %u, not %u\n",
1287 rpccli_pipe_txt(talloc_tos(), cli),
1289 expected_pkt_type));
1290 return NT_STATUS_INVALID_INFO_CLASS;
1293 /* Do this just before return - we don't want to modify any rpc header
1294 data before now as we may have needed to do cryptographic actions on
1297 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
1298 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1299 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1300 "setting fragment first/last ON.\n"));
1301 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
1302 DCERPC_PFC_FLAG_LAST;
1305 return NT_STATUS_OK;
1308 /****************************************************************************
1309 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1310 Normally the frag_len and buffer size will match, but on the first trans
1311 reply there is a theoretical chance that buffer size > frag_len, so we must
1313 ****************************************************************************/
1315 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1316 struct ncacn_packet *pkt,
1317 prs_struct *current_pdu)
1319 uint32 current_pdu_len = prs_data_size(current_pdu);
1321 if (current_pdu_len < pkt->frag_length) {
1322 return NT_STATUS_BUFFER_TOO_SMALL;
1326 if (current_pdu_len == (uint32)pkt->frag_length) {
1327 prs_mem_free(current_pdu);
1328 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1329 /* Make current_pdu dynamic with no memory. */
1330 prs_give_memory(current_pdu, 0, 0, True);
1331 return NT_STATUS_OK;
1335 * Oh no ! More data in buffer than we processed in current pdu.
1336 * Cheat. Move the data down and shrink the buffer.
1339 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + pkt->frag_length,
1340 current_pdu_len - pkt->frag_length);
1342 /* Remember to set the read offset back to zero. */
1343 prs_set_offset(current_pdu, 0);
1345 /* Shrink the buffer. */
1346 if (!prs_set_buffer_size(current_pdu, current_pdu_len - pkt->frag_length)) {
1347 return NT_STATUS_BUFFER_TOO_SMALL;
1350 return NT_STATUS_OK;
1353 /****************************************************************************
1354 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1355 ****************************************************************************/
1357 struct cli_api_pipe_state {
1358 struct event_context *ev;
1359 struct rpc_cli_transport *transport;
1364 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1365 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1366 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1368 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1369 struct event_context *ev,
1370 struct rpc_cli_transport *transport,
1371 uint8_t *data, size_t data_len,
1372 uint32_t max_rdata_len)
1374 struct tevent_req *req, *subreq;
1375 struct cli_api_pipe_state *state;
1378 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1383 state->transport = transport;
1385 if (max_rdata_len < RPC_HEADER_LEN) {
1387 * For a RPC reply we always need at least RPC_HEADER_LEN
1388 * bytes. We check this here because we will receive
1389 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1391 status = NT_STATUS_INVALID_PARAMETER;
1395 if (transport->trans_send != NULL) {
1396 subreq = transport->trans_send(state, ev, data, data_len,
1397 max_rdata_len, transport->priv);
1398 if (subreq == NULL) {
1401 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1406 * If the transport does not provide a "trans" routine, i.e. for
1407 * example the ncacn_ip_tcp transport, do the write/read step here.
1410 subreq = rpc_write_send(state, ev, transport, data, data_len);
1411 if (subreq == NULL) {
1414 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1418 tevent_req_nterror(req, status);
1419 return tevent_req_post(req, ev);
1425 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1427 struct tevent_req *req = tevent_req_callback_data(
1428 subreq, struct tevent_req);
1429 struct cli_api_pipe_state *state = tevent_req_data(
1430 req, struct cli_api_pipe_state);
1433 status = state->transport->trans_recv(subreq, state, &state->rdata,
1435 TALLOC_FREE(subreq);
1436 if (!NT_STATUS_IS_OK(status)) {
1437 tevent_req_nterror(req, status);
1440 tevent_req_done(req);
1443 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1445 struct tevent_req *req = tevent_req_callback_data(
1446 subreq, struct tevent_req);
1447 struct cli_api_pipe_state *state = tevent_req_data(
1448 req, struct cli_api_pipe_state);
1451 status = rpc_write_recv(subreq);
1452 TALLOC_FREE(subreq);
1453 if (!NT_STATUS_IS_OK(status)) {
1454 tevent_req_nterror(req, status);
1458 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1459 if (tevent_req_nomem(state->rdata, req)) {
1464 * We don't need to use rpc_read_send here, the upper layer will cope
1465 * with a short read, transport->trans_send could also return less
1466 * than state->max_rdata_len.
1468 subreq = state->transport->read_send(state, state->ev, state->rdata,
1470 state->transport->priv);
1471 if (tevent_req_nomem(subreq, req)) {
1474 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1477 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1479 struct tevent_req *req = tevent_req_callback_data(
1480 subreq, struct tevent_req);
1481 struct cli_api_pipe_state *state = tevent_req_data(
1482 req, struct cli_api_pipe_state);
1486 status = state->transport->read_recv(subreq, &received);
1487 TALLOC_FREE(subreq);
1488 if (!NT_STATUS_IS_OK(status)) {
1489 tevent_req_nterror(req, status);
1492 state->rdata_len = received;
1493 tevent_req_done(req);
1496 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1497 uint8_t **prdata, uint32_t *prdata_len)
1499 struct cli_api_pipe_state *state = tevent_req_data(
1500 req, struct cli_api_pipe_state);
1503 if (tevent_req_is_nterror(req, &status)) {
1507 *prdata = talloc_move(mem_ctx, &state->rdata);
1508 *prdata_len = state->rdata_len;
1509 return NT_STATUS_OK;
1512 /****************************************************************************
1513 Send data on an rpc pipe via trans. The prs_struct data must be the last
1514 pdu fragment of an NDR data stream.
1516 Receive response data from an rpc pipe, which may be large...
1518 Read the first fragment: unfortunately have to use SMBtrans for the first
1519 bit, then SMBreadX for subsequent bits.
1521 If first fragment received also wasn't the last fragment, continue
1522 getting fragments until we _do_ receive the last fragment.
1524 Request/Response PDU's look like the following...
1526 |<------------------PDU len----------------------------------------------->|
1527 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1529 +------------+-----------------+-------------+---------------+-------------+
1530 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1531 +------------+-----------------+-------------+---------------+-------------+
1533 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1534 signing & sealing being negotiated.
1536 ****************************************************************************/
1538 struct rpc_api_pipe_state {
1539 struct event_context *ev;
1540 struct rpc_pipe_client *cli;
1541 uint8_t expected_pkt_type;
1543 prs_struct incoming_frag;
1544 struct ncacn_packet *pkt;
1546 prs_struct incoming_pdu; /* Incoming reply */
1547 uint32_t incoming_pdu_offset;
1550 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1551 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1553 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1554 struct event_context *ev,
1555 struct rpc_pipe_client *cli,
1556 prs_struct *data, /* Outgoing PDU */
1557 uint8_t expected_pkt_type)
1559 struct tevent_req *req, *subreq;
1560 struct rpc_api_pipe_state *state;
1561 uint16_t max_recv_frag;
1564 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1570 state->expected_pkt_type = expected_pkt_type;
1571 state->incoming_pdu_offset = 0;
1573 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1575 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1576 /* Make incoming_pdu dynamic with no memory. */
1577 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1580 * Ensure we're not sending too much.
1582 if (prs_offset(data) > cli->max_xmit_frag) {
1583 status = NT_STATUS_INVALID_PARAMETER;
1587 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1589 max_recv_frag = cli->max_recv_frag;
1592 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1595 subreq = cli_api_pipe_send(state, ev, cli->transport,
1596 (uint8_t *)prs_data_p(data),
1597 prs_offset(data), max_recv_frag);
1598 if (subreq == NULL) {
1601 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1605 tevent_req_nterror(req, status);
1606 return tevent_req_post(req, ev);
1612 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1614 struct tevent_req *req = tevent_req_callback_data(
1615 subreq, struct tevent_req);
1616 struct rpc_api_pipe_state *state = tevent_req_data(
1617 req, struct rpc_api_pipe_state);
1619 uint8_t *rdata = NULL;
1620 uint32_t rdata_len = 0;
1622 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1623 TALLOC_FREE(subreq);
1624 if (!NT_STATUS_IS_OK(status)) {
1625 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1626 tevent_req_nterror(req, status);
1630 if (rdata == NULL) {
1631 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1632 rpccli_pipe_txt(talloc_tos(), state->cli)));
1633 tevent_req_done(req);
1638 * This is equivalent to a talloc_steal - gives rdata to
1639 * the prs_struct state->incoming_frag.
1641 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1644 /* Ensure we have enough data for a pdu. */
1645 subreq = get_complete_frag_send(state, state->ev, state->cli,
1646 &state->incoming_frag);
1647 if (tevent_req_nomem(subreq, req)) {
1650 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1653 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1655 struct tevent_req *req = tevent_req_callback_data(
1656 subreq, struct tevent_req);
1657 struct rpc_api_pipe_state *state = tevent_req_data(
1658 req, struct rpc_api_pipe_state);
1661 uint32_t rdata_len = 0;
1663 status = get_complete_frag_recv(subreq);
1664 TALLOC_FREE(subreq);
1665 if (!NT_STATUS_IS_OK(status)) {
1666 DEBUG(5, ("get_complete_frag failed: %s\n",
1667 nt_errstr(status)));
1668 tevent_req_nterror(req, status);
1672 state->pkt = talloc(state, struct ncacn_packet);
1674 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1678 status = cli_pipe_validate_current_pdu(
1679 state->cli, state->pkt, &state->incoming_frag,
1680 state->expected_pkt_type, &rdata, &rdata_len,
1681 &state->incoming_pdu);
1683 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1684 (unsigned)prs_data_size(&state->incoming_frag),
1685 (unsigned)state->incoming_pdu_offset,
1686 nt_errstr(status)));
1688 if (!NT_STATUS_IS_OK(status)) {
1689 tevent_req_nterror(req, status);
1693 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1694 && (state->pkt->drep[0] == 0)) {
1696 * Set the data type correctly for big-endian data on the
1699 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1701 rpccli_pipe_txt(talloc_tos(), state->cli)));
1702 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1705 * Check endianness on subsequent packets.
1707 if (state->incoming_frag.bigendian_data
1708 != state->incoming_pdu.bigendian_data) {
1709 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1711 state->incoming_pdu.bigendian_data?"big":"little",
1712 state->incoming_frag.bigendian_data?"big":"little"));
1713 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1717 /* Now copy the data portion out of the pdu into rbuf. */
1718 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1719 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1723 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1724 rdata, (size_t)rdata_len);
1725 state->incoming_pdu_offset += rdata_len;
1727 status = cli_pipe_reset_current_pdu(state->cli, state->pkt,
1728 &state->incoming_frag);
1729 if (!NT_STATUS_IS_OK(status)) {
1730 tevent_req_nterror(req, status);
1734 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1735 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1736 rpccli_pipe_txt(talloc_tos(), state->cli),
1737 (unsigned)prs_data_size(&state->incoming_pdu)));
1738 tevent_req_done(req);
1742 subreq = get_complete_frag_send(state, state->ev, state->cli,
1743 &state->incoming_frag);
1744 if (tevent_req_nomem(subreq, req)) {
1747 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1750 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1751 struct ncacn_packet **pkt,
1752 prs_struct *reply_pdu)
1754 struct rpc_api_pipe_state *state = tevent_req_data(
1755 req, struct rpc_api_pipe_state);
1758 if (tevent_req_is_nterror(req, &status)) {
1762 *reply_pdu = state->incoming_pdu;
1763 reply_pdu->mem_ctx = mem_ctx;
1766 * Prevent state->incoming_pdu from being freed
1767 * when state is freed.
1769 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1770 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1773 *pkt = talloc_steal(mem_ctx, state->pkt);
1776 return NT_STATUS_OK;
1779 /*******************************************************************
1780 Creates an auth_data blob.
1781 ********************************************************************/
1783 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1784 enum dcerpc_AuthType auth_type,
1785 enum dcerpc_AuthLevel auth_level,
1786 uint8_t auth_pad_length,
1787 uint32_t auth_context_id,
1788 const DATA_BLOB *credentials,
1791 struct dcerpc_auth r;
1792 enum ndr_err_code ndr_err;
1794 r.auth_type = auth_type;
1795 r.auth_level = auth_level;
1796 r.auth_pad_length = auth_pad_length;
1797 r.auth_reserved = 0;
1798 r.auth_context_id = auth_context_id;
1799 r.credentials = *credentials;
1801 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1802 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1803 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1804 return ndr_map_error2ntstatus(ndr_err);
1807 if (DEBUGLEVEL >= 10) {
1808 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1811 return NT_STATUS_OK;
1814 /*******************************************************************
1815 Creates krb5 auth bind.
1816 ********************************************************************/
1818 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1819 enum dcerpc_AuthLevel auth_level,
1820 DATA_BLOB *auth_info)
1825 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1826 DATA_BLOB tkt = data_blob_null;
1827 DATA_BLOB tkt_wrapped = data_blob_null;
1829 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1830 a->service_principal ));
1832 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1834 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1835 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1838 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1840 a->service_principal,
1841 error_message(ret) ));
1843 data_blob_free(&tkt);
1844 return NT_STATUS_INVALID_PARAMETER;
1847 /* wrap that up in a nice GSS-API wrapping */
1848 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1850 data_blob_free(&tkt);
1852 status = dcerpc_push_dcerpc_auth(cli,
1853 DCERPC_AUTH_TYPE_KRB5,
1855 0, /* auth_pad_length */
1856 1, /* auth_context_id */
1859 if (!NT_STATUS_IS_OK(status)) {
1860 data_blob_free(&tkt_wrapped);
1864 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1865 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1867 return NT_STATUS_OK;
1869 return NT_STATUS_INVALID_PARAMETER;
1873 /*******************************************************************
1874 Creates SPNEGO NTLMSSP auth bind.
1875 ********************************************************************/
1877 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1878 enum dcerpc_AuthLevel auth_level,
1879 DATA_BLOB *auth_info)
1882 DATA_BLOB null_blob = data_blob_null;
1883 DATA_BLOB request = data_blob_null;
1884 DATA_BLOB spnego_msg = data_blob_null;
1886 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1887 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1891 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1892 data_blob_free(&request);
1896 /* Wrap this in SPNEGO. */
1897 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1899 data_blob_free(&request);
1901 status = dcerpc_push_dcerpc_auth(cli,
1902 DCERPC_AUTH_TYPE_SPNEGO,
1904 0, /* auth_pad_length */
1905 1, /* auth_context_id */
1908 if (!NT_STATUS_IS_OK(status)) {
1909 data_blob_free(&spnego_msg);
1913 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1914 dump_data(5, spnego_msg.data, spnego_msg.length);
1916 return NT_STATUS_OK;
1919 /*******************************************************************
1920 Creates NTLMSSP auth bind.
1921 ********************************************************************/
1923 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1924 enum dcerpc_AuthLevel auth_level,
1925 DATA_BLOB *auth_info)
1928 DATA_BLOB null_blob = data_blob_null;
1929 DATA_BLOB request = data_blob_null;
1931 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1932 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1936 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1937 data_blob_free(&request);
1941 status = dcerpc_push_dcerpc_auth(cli,
1942 DCERPC_AUTH_TYPE_NTLMSSP,
1944 0, /* auth_pad_length */
1945 1, /* auth_context_id */
1948 if (!NT_STATUS_IS_OK(status)) {
1949 data_blob_free(&request);
1953 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1954 dump_data(5, request.data, request.length);
1956 return NT_STATUS_OK;
1959 /*******************************************************************
1960 Creates schannel auth bind.
1961 ********************************************************************/
1963 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1964 enum dcerpc_AuthLevel auth_level,
1965 DATA_BLOB *auth_info)
1968 struct NL_AUTH_MESSAGE r;
1969 DATA_BLOB schannel_blob;
1971 /* Use lp_workgroup() if domain not specified */
1973 if (!cli->auth->domain || !cli->auth->domain[0]) {
1974 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1975 if (cli->auth->domain == NULL) {
1976 return NT_STATUS_NO_MEMORY;
1981 * Now marshall the data into the auth parse_struct.
1984 r.MessageType = NL_NEGOTIATE_REQUEST;
1985 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1986 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1987 r.oem_netbios_domain.a = cli->auth->domain;
1988 r.oem_netbios_computer.a = global_myname();
1990 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1991 if (!NT_STATUS_IS_OK(status)) {
1995 status = dcerpc_push_dcerpc_auth(cli,
1996 DCERPC_AUTH_TYPE_SCHANNEL,
1998 0, /* auth_pad_length */
1999 1, /* auth_context_id */
2002 if (!NT_STATUS_IS_OK(status)) {
2006 return NT_STATUS_OK;
2009 /*******************************************************************
2010 ********************************************************************/
2012 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
2013 const struct ndr_syntax_id *abstract_syntax,
2014 const struct ndr_syntax_id *transfer_syntax,
2015 struct dcerpc_ctx_list **ctx_list_p)
2017 struct dcerpc_ctx_list *ctx_list;
2019 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
2020 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
2022 ctx_list[0].context_id = 0;
2023 ctx_list[0].num_transfer_syntaxes = 1;
2024 ctx_list[0].abstract_syntax = *abstract_syntax;
2025 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
2026 struct ndr_syntax_id,
2027 ctx_list[0].num_transfer_syntaxes);
2028 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
2029 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
2031 *ctx_list_p = ctx_list;
2033 return NT_STATUS_OK;
2036 /*******************************************************************
2037 Creates the internals of a DCE/RPC bind request or alter context PDU.
2038 ********************************************************************/
2040 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2041 prs_struct *rpc_out,
2043 const struct ndr_syntax_id *abstract,
2044 const struct ndr_syntax_id *transfer,
2045 const DATA_BLOB *auth_info)
2047 uint16 auth_len = auth_info->length;
2049 union dcerpc_payload u;
2051 struct dcerpc_ctx_list *ctx_list;
2053 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2055 if (!NT_STATUS_IS_OK(status)) {
2059 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2060 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2061 u.bind.assoc_group_id = 0x0;
2062 u.bind.num_contexts = 1;
2063 u.bind.ctx_list = ctx_list;
2064 u.bind.auth_info = *auth_info;
2066 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2068 DCERPC_PFC_FLAG_FIRST |
2069 DCERPC_PFC_FLAG_LAST,
2070 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2074 if (!NT_STATUS_IS_OK(status)) {
2075 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2079 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2080 return NT_STATUS_NO_MEMORY;
2083 return NT_STATUS_OK;
2086 /*******************************************************************
2087 Creates a DCE/RPC bind request.
2088 ********************************************************************/
2090 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2091 prs_struct *rpc_out,
2093 const struct ndr_syntax_id *abstract,
2094 const struct ndr_syntax_id *transfer,
2095 enum pipe_auth_type auth_type,
2096 enum dcerpc_AuthLevel auth_level)
2098 DATA_BLOB auth_info = data_blob_null;
2099 NTSTATUS ret = NT_STATUS_OK;
2101 switch (auth_type) {
2102 case PIPE_AUTH_TYPE_SCHANNEL:
2103 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2104 if (!NT_STATUS_IS_OK(ret)) {
2109 case PIPE_AUTH_TYPE_NTLMSSP:
2110 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2111 if (!NT_STATUS_IS_OK(ret)) {
2116 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2117 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2118 if (!NT_STATUS_IS_OK(ret)) {
2123 case PIPE_AUTH_TYPE_KRB5:
2124 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2125 if (!NT_STATUS_IS_OK(ret)) {
2130 case PIPE_AUTH_TYPE_NONE:
2134 /* "Can't" happen. */
2135 return NT_STATUS_INVALID_INFO_CLASS;
2138 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2147 /*******************************************************************
2148 Create and add the NTLMSSP sign/seal auth header and data.
2149 ********************************************************************/
2151 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2152 uint32 ss_padding_len,
2153 prs_struct *rpc_out)
2155 DATA_BLOB auth_info;
2157 DATA_BLOB auth_blob = data_blob_null;
2158 uint16_t data_and_pad_len =
2159 prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2161 if (!cli->auth->a_u.ntlmssp_state) {
2162 return NT_STATUS_INVALID_PARAMETER;
2165 /* marshall the dcerpc_auth with an actually empty auth_blob.
2166 * this is needed because the ntmlssp signature includes the
2168 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2169 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2170 cli->auth->auth_level,
2172 1 /* context id. */,
2175 if (!NT_STATUS_IS_OK(status)) {
2179 /* append the header */
2180 if (!prs_copy_data_in(rpc_out,
2181 (char *)auth_info.data,
2182 auth_info.length)) {
2183 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2184 (unsigned int)auth_info.length));
2185 return NT_STATUS_NO_MEMORY;
2188 switch (cli->auth->auth_level) {
2189 case DCERPC_AUTH_LEVEL_PRIVACY:
2190 /* Data portion is encrypted. */
2191 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2192 prs_get_mem_context(rpc_out),
2193 (unsigned char *)prs_data_p(rpc_out)
2197 (unsigned char *)prs_data_p(rpc_out),
2198 (size_t)prs_offset(rpc_out),
2200 if (!NT_STATUS_IS_OK(status)) {
2205 case DCERPC_AUTH_LEVEL_INTEGRITY:
2206 /* Data is signed. */
2207 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2208 prs_get_mem_context(rpc_out),
2209 (unsigned char *)prs_data_p(rpc_out)
2213 (unsigned char *)prs_data_p(rpc_out),
2214 (size_t)prs_offset(rpc_out),
2216 if (!NT_STATUS_IS_OK(status)) {
2223 smb_panic("bad auth level");
2225 return NT_STATUS_INVALID_PARAMETER;
2228 /* Finally attach the blob. */
2229 if (!prs_copy_data_in(rpc_out,
2230 (char *)auth_blob.data,
2231 auth_blob.length)) {
2232 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2233 (unsigned int)auth_info.length));
2234 return NT_STATUS_NO_MEMORY;
2237 return NT_STATUS_OK;
2240 /*******************************************************************
2241 Create and add the schannel sign/seal auth header and data.
2242 ********************************************************************/
2244 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2245 uint32 ss_padding_len,
2246 prs_struct *rpc_out)
2248 DATA_BLOB auth_info;
2249 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2250 char *data_p = prs_data_p(rpc_out) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2251 size_t data_and_pad_len = prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2256 return NT_STATUS_INVALID_PARAMETER;
2259 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2262 switch (cli->auth->auth_level) {
2263 case DCERPC_AUTH_LEVEL_PRIVACY:
2264 status = netsec_outgoing_packet(sas,
2271 case DCERPC_AUTH_LEVEL_INTEGRITY:
2272 status = netsec_outgoing_packet(sas,
2280 status = NT_STATUS_INTERNAL_ERROR;
2284 if (!NT_STATUS_IS_OK(status)) {
2285 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2286 nt_errstr(status)));
2290 if (DEBUGLEVEL >= 10) {
2291 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2294 /* Finally marshall the blob. */
2295 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2296 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2297 cli->auth->auth_level,
2299 1 /* context id. */,
2302 if (!NT_STATUS_IS_OK(status)) {
2306 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.length)) {
2307 return NT_STATUS_NO_MEMORY;
2310 return NT_STATUS_OK;
2313 /*******************************************************************
2314 Calculate how much data we're going to send in this packet, also
2315 work out any sign/seal padding length.
2316 ********************************************************************/
2318 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2322 uint32 *p_ss_padding)
2324 uint32 data_space, data_len;
2327 if ((data_left > 0) && (sys_random() % 2)) {
2328 data_left = MAX(data_left/2, 1);
2332 switch (cli->auth->auth_level) {
2333 case DCERPC_AUTH_LEVEL_NONE:
2334 case DCERPC_AUTH_LEVEL_CONNECT:
2335 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2336 data_len = MIN(data_space, data_left);
2339 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2342 case DCERPC_AUTH_LEVEL_INTEGRITY:
2343 case DCERPC_AUTH_LEVEL_PRIVACY:
2344 /* Treat the same for all authenticated rpc requests. */
2345 switch(cli->auth->auth_type) {
2346 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2347 case PIPE_AUTH_TYPE_NTLMSSP:
2348 *p_auth_len = NTLMSSP_SIG_SIZE;
2350 case PIPE_AUTH_TYPE_SCHANNEL:
2351 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2354 smb_panic("bad auth type");
2358 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2359 RPC_HDR_AUTH_LEN - *p_auth_len;
2361 data_len = MIN(data_space, data_left);
2363 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2364 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2366 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2367 data_len + *p_ss_padding + /* data plus padding. */
2368 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2372 smb_panic("bad auth level");
2378 /*******************************************************************
2380 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2381 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2382 and deals with signing/sealing details.
2383 ********************************************************************/
2385 struct rpc_api_pipe_req_state {
2386 struct event_context *ev;
2387 struct rpc_pipe_client *cli;
2390 prs_struct *req_data;
2391 uint32_t req_data_sent;
2392 prs_struct outgoing_frag;
2393 prs_struct reply_pdu;
2396 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2397 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2398 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2399 bool *is_last_frag);
2401 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2402 struct event_context *ev,
2403 struct rpc_pipe_client *cli,
2405 prs_struct *req_data)
2407 struct tevent_req *req, *subreq;
2408 struct rpc_api_pipe_req_state *state;
2412 req = tevent_req_create(mem_ctx, &state,
2413 struct rpc_api_pipe_req_state);
2419 state->op_num = op_num;
2420 state->req_data = req_data;
2421 state->req_data_sent = 0;
2422 state->call_id = get_rpc_call_id();
2424 if (cli->max_xmit_frag
2425 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2426 /* Server is screwed up ! */
2427 status = NT_STATUS_INVALID_PARAMETER;
2431 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2433 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2438 status = prepare_next_frag(state, &is_last_frag);
2439 if (!NT_STATUS_IS_OK(status)) {
2444 subreq = rpc_api_pipe_send(state, ev, state->cli,
2445 &state->outgoing_frag,
2446 DCERPC_PKT_RESPONSE);
2447 if (subreq == NULL) {
2450 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2452 subreq = rpc_write_send(
2453 state, ev, cli->transport,
2454 (uint8_t *)prs_data_p(&state->outgoing_frag),
2455 prs_offset(&state->outgoing_frag));
2456 if (subreq == NULL) {
2459 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2465 tevent_req_nterror(req, status);
2466 return tevent_req_post(req, ev);
2472 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2475 uint32_t data_sent_thistime;
2479 uint32_t ss_padding;
2481 char pad[8] = { 0, };
2483 union dcerpc_payload u;
2486 data_left = prs_offset(state->req_data) - state->req_data_sent;
2488 data_sent_thistime = calculate_data_len_tosend(
2489 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2491 if (state->req_data_sent == 0) {
2492 flags = DCERPC_PFC_FLAG_FIRST;
2495 if (data_sent_thistime == data_left) {
2496 flags |= DCERPC_PFC_FLAG_LAST;
2499 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2500 return NT_STATUS_NO_MEMORY;
2503 ZERO_STRUCT(u.request);
2505 u.request.alloc_hint = prs_offset(state->req_data);
2506 u.request.context_id = 0;
2507 u.request.opnum = state->op_num;
2509 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2516 if (!NT_STATUS_IS_OK(status)) {
2520 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
2521 * compute it right for requests */
2522 dcerpc_set_frag_length(&blob, frag_len);
2524 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2525 return NT_STATUS_NO_MEMORY;
2528 /* Copy in the data, plus any ss padding. */
2529 if (!prs_append_some_prs_data(&state->outgoing_frag,
2530 state->req_data, state->req_data_sent,
2531 data_sent_thistime)) {
2532 return NT_STATUS_NO_MEMORY;
2535 /* Copy the sign/seal padding data. */
2536 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2537 return NT_STATUS_NO_MEMORY;
2540 /* Generate any auth sign/seal and add the auth footer. */
2541 switch (state->cli->auth->auth_type) {
2542 case PIPE_AUTH_TYPE_NONE:
2543 status = NT_STATUS_OK;
2545 case PIPE_AUTH_TYPE_NTLMSSP:
2546 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2547 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2548 &state->outgoing_frag);
2550 case PIPE_AUTH_TYPE_SCHANNEL:
2551 status = add_schannel_auth_footer(state->cli, ss_padding,
2552 &state->outgoing_frag);
2555 status = NT_STATUS_INVALID_PARAMETER;
2559 state->req_data_sent += data_sent_thistime;
2560 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2565 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2567 struct tevent_req *req = tevent_req_callback_data(
2568 subreq, struct tevent_req);
2569 struct rpc_api_pipe_req_state *state = tevent_req_data(
2570 req, struct rpc_api_pipe_req_state);
2574 status = rpc_write_recv(subreq);
2575 TALLOC_FREE(subreq);
2576 if (!NT_STATUS_IS_OK(status)) {
2577 tevent_req_nterror(req, status);
2581 status = prepare_next_frag(state, &is_last_frag);
2582 if (!NT_STATUS_IS_OK(status)) {
2583 tevent_req_nterror(req, status);
2588 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2589 &state->outgoing_frag,
2590 DCERPC_PKT_RESPONSE);
2591 if (tevent_req_nomem(subreq, req)) {
2594 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2596 subreq = rpc_write_send(
2598 state->cli->transport,
2599 (uint8_t *)prs_data_p(&state->outgoing_frag),
2600 prs_offset(&state->outgoing_frag));
2601 if (tevent_req_nomem(subreq, req)) {
2604 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2609 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2611 struct tevent_req *req = tevent_req_callback_data(
2612 subreq, struct tevent_req);
2613 struct rpc_api_pipe_req_state *state = tevent_req_data(
2614 req, struct rpc_api_pipe_req_state);
2617 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
2618 TALLOC_FREE(subreq);
2619 if (!NT_STATUS_IS_OK(status)) {
2620 tevent_req_nterror(req, status);
2623 tevent_req_done(req);
2626 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2627 prs_struct *reply_pdu)
2629 struct rpc_api_pipe_req_state *state = tevent_req_data(
2630 req, struct rpc_api_pipe_req_state);
2633 if (tevent_req_is_nterror(req, &status)) {
2635 * We always have to initialize to reply pdu, even if there is
2636 * none. The rpccli_* caller routines expect this.
2638 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2642 *reply_pdu = state->reply_pdu;
2643 reply_pdu->mem_ctx = mem_ctx;
2646 * Prevent state->req_pdu from being freed
2647 * when state is freed.
2649 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2650 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2652 return NT_STATUS_OK;
2656 /****************************************************************************
2657 Set the handle state.
2658 ****************************************************************************/
2660 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2661 const char *pipe_name, uint16 device_state)
2663 bool state_set = False;
2665 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2666 char *rparam = NULL;
2668 uint32 rparam_len, rdata_len;
2670 if (pipe_name == NULL)
2673 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2674 cli->fnum, pipe_name, device_state));
2676 /* create parameters: device state */
2677 SSVAL(param, 0, device_state);
2679 /* create setup parameters. */
2681 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2683 /* send the data on \PIPE\ */
2684 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2685 setup, 2, 0, /* setup, length, max */
2686 param, 2, 0, /* param, length, max */
2687 NULL, 0, 1024, /* data, length, max */
2688 &rparam, &rparam_len, /* return param, length */
2689 &rdata, &rdata_len)) /* return data, length */
2691 DEBUG(5, ("Set Handle state: return OK\n"));
2702 /****************************************************************************
2703 Check the rpc bind acknowledge response.
2704 ****************************************************************************/
2706 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2707 const struct ndr_syntax_id *transfer)
2709 struct dcerpc_ack_ctx ctx;
2711 if (r->secondary_address_size == 0) {
2712 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2715 if (r->num_results < 1 || !r->ctx_list) {
2719 ctx = r->ctx_list[0];
2721 /* check the transfer syntax */
2722 if ((ctx.syntax.if_version != transfer->if_version) ||
2723 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2724 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2728 if (r->num_results != 0x1 || ctx.result != 0) {
2729 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2730 r->num_results, ctx.reason));
2733 DEBUG(5,("check_bind_response: accepted!\n"));
2737 /*******************************************************************
2738 Creates a DCE/RPC bind authentication response.
2739 This is the packet that is sent back to the server once we
2740 have received a BIND-ACK, to finish the third leg of
2741 the authentication handshake.
2742 ********************************************************************/
2744 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2746 enum pipe_auth_type auth_type,
2747 enum dcerpc_AuthLevel auth_level,
2748 DATA_BLOB *pauth_blob,
2749 prs_struct *rpc_out)
2752 union dcerpc_payload u;
2757 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2758 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2760 0, /* auth_pad_length */
2761 1, /* auth_context_id */
2763 &u.auth3.auth_info);
2764 if (!NT_STATUS_IS_OK(status)) {
2768 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2770 DCERPC_PFC_FLAG_FIRST |
2771 DCERPC_PFC_FLAG_LAST,
2776 if (!NT_STATUS_IS_OK(status)) {
2777 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2781 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2782 return NT_STATUS_NO_MEMORY;
2785 return NT_STATUS_OK;
2788 /*******************************************************************
2789 Creates a DCE/RPC bind alter context authentication request which
2790 may contain a spnego auth blobl
2791 ********************************************************************/
2793 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2794 const struct ndr_syntax_id *abstract,
2795 const struct ndr_syntax_id *transfer,
2796 enum dcerpc_AuthLevel auth_level,
2797 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2798 prs_struct *rpc_out)
2800 DATA_BLOB auth_info;
2803 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2804 DCERPC_AUTH_TYPE_SPNEGO,
2806 0, /* auth_pad_length */
2807 1, /* auth_context_id */
2810 if (!NT_STATUS_IS_OK(status)) {
2815 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2821 if (!NT_STATUS_IS_OK(status)) {
2828 /****************************************************************************
2830 ****************************************************************************/
2832 struct rpc_pipe_bind_state {
2833 struct event_context *ev;
2834 struct rpc_pipe_client *cli;
2836 uint32_t rpc_call_id;
2839 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2840 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2841 struct rpc_pipe_bind_state *state,
2842 struct ncacn_packet *r,
2843 prs_struct *reply_pdu);
2844 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2845 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2846 struct rpc_pipe_bind_state *state,
2847 struct ncacn_packet *r,
2848 prs_struct *reply_pdu);
2849 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2851 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2852 struct event_context *ev,
2853 struct rpc_pipe_client *cli,
2854 struct cli_pipe_auth_data *auth)
2856 struct tevent_req *req, *subreq;
2857 struct rpc_pipe_bind_state *state;
2860 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2865 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2866 rpccli_pipe_txt(talloc_tos(), cli),
2867 (unsigned int)auth->auth_type,
2868 (unsigned int)auth->auth_level ));
2872 state->rpc_call_id = get_rpc_call_id();
2874 prs_init_empty(&state->rpc_out, state, MARSHALL);
2876 cli->auth = talloc_move(cli, &auth);
2878 /* Marshall the outgoing data. */
2879 status = create_rpc_bind_req(cli, &state->rpc_out,
2881 &cli->abstract_syntax,
2882 &cli->transfer_syntax,
2883 cli->auth->auth_type,
2884 cli->auth->auth_level);
2886 if (!NT_STATUS_IS_OK(status)) {
2890 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2891 DCERPC_PKT_BIND_ACK);
2892 if (subreq == NULL) {
2895 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2899 tevent_req_nterror(req, status);
2900 return tevent_req_post(req, ev);
2906 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2908 struct tevent_req *req = tevent_req_callback_data(
2909 subreq, struct tevent_req);
2910 struct rpc_pipe_bind_state *state = tevent_req_data(
2911 req, struct rpc_pipe_bind_state);
2912 prs_struct reply_pdu;
2913 struct ncacn_packet *pkt;
2916 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
2917 TALLOC_FREE(subreq);
2918 if (!NT_STATUS_IS_OK(status)) {
2919 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2920 rpccli_pipe_txt(talloc_tos(), state->cli),
2921 nt_errstr(status)));
2922 tevent_req_nterror(req, status);
2926 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
2927 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2928 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2932 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
2933 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
2936 * For authenticated binds we may need to do 3 or 4 leg binds.
2939 switch(state->cli->auth->auth_type) {
2941 case PIPE_AUTH_TYPE_NONE:
2942 case PIPE_AUTH_TYPE_SCHANNEL:
2943 /* Bind complete. */
2944 tevent_req_done(req);
2947 case PIPE_AUTH_TYPE_NTLMSSP:
2948 /* Need to send AUTH3 packet - no reply. */
2949 status = rpc_finish_auth3_bind_send(req, state, pkt,
2951 if (!NT_STATUS_IS_OK(status)) {
2952 tevent_req_nterror(req, status);
2956 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2957 /* Need to send alter context request and reply. */
2958 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt,
2960 if (!NT_STATUS_IS_OK(status)) {
2961 tevent_req_nterror(req, status);
2965 case PIPE_AUTH_TYPE_KRB5:
2969 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2970 (unsigned int)state->cli->auth->auth_type));
2971 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2975 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2976 struct rpc_pipe_bind_state *state,
2977 struct ncacn_packet *r,
2978 prs_struct *reply_pdu)
2980 DATA_BLOB server_response = data_blob_null;
2981 DATA_BLOB client_reply = data_blob_null;
2982 struct rpc_hdr_auth_info hdr_auth;
2983 struct tevent_req *subreq;
2986 if ((r->auth_length == 0)
2987 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
2988 return NT_STATUS_INVALID_PARAMETER;
2991 if (!prs_set_offset(
2993 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
2994 return NT_STATUS_INVALID_PARAMETER;
2997 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2998 return NT_STATUS_INVALID_PARAMETER;
3001 /* TODO - check auth_type/auth_level match. */
3003 server_response = data_blob_talloc(talloc_tos(), NULL, r->auth_length);
3004 prs_copy_data_out((char *)server_response.data, reply_pdu,
3007 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3008 server_response, &client_reply);
3010 if (!NT_STATUS_IS_OK(status)) {
3011 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
3012 "blob failed: %s.\n", nt_errstr(status)));
3016 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
3018 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
3019 state->cli->auth->auth_type,
3020 state->cli->auth->auth_level,
3021 &client_reply, &state->rpc_out);
3022 data_blob_free(&client_reply);
3024 if (!NT_STATUS_IS_OK(status)) {
3028 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3029 (uint8_t *)prs_data_p(&state->rpc_out),
3030 prs_offset(&state->rpc_out));
3031 if (subreq == NULL) {
3032 return NT_STATUS_NO_MEMORY;
3034 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3035 return NT_STATUS_OK;
3038 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3040 struct tevent_req *req = tevent_req_callback_data(
3041 subreq, struct tevent_req);
3044 status = rpc_write_recv(subreq);
3045 TALLOC_FREE(subreq);
3046 if (!NT_STATUS_IS_OK(status)) {
3047 tevent_req_nterror(req, status);
3050 tevent_req_done(req);
3053 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3054 struct rpc_pipe_bind_state *state,
3055 struct ncacn_packet *r,
3058 DATA_BLOB server_ntlm_response = data_blob_null;
3059 DATA_BLOB client_reply = data_blob_null;
3060 DATA_BLOB tmp_blob = data_blob_null;
3061 struct dcerpc_auth auth_info;
3062 DATA_BLOB auth_blob;
3063 struct tevent_req *subreq;
3066 if ((r->auth_length == 0)
3067 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3068 return NT_STATUS_INVALID_PARAMETER;
3071 /* Process the returned NTLMSSP blob first. */
3072 if (!prs_set_offset(
3074 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3075 return NT_STATUS_INVALID_PARAMETER;
3078 auth_blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in),
3079 prs_data_size(rpc_in) - prs_offset(rpc_in));
3081 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
3082 if (!NT_STATUS_IS_OK(status)) {
3083 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
3088 * The server might give us back two challenges - tmp_blob is for the
3091 if (!spnego_parse_challenge(auth_info.credentials,
3092 &server_ntlm_response, &tmp_blob)) {
3093 data_blob_free(&server_ntlm_response);
3094 data_blob_free(&tmp_blob);
3095 return NT_STATUS_INVALID_PARAMETER;
3098 /* We're finished with the server spnego response and the tmp_blob. */
3099 data_blob_free(&tmp_blob);
3101 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3102 server_ntlm_response, &client_reply);
3104 /* Finished with the server_ntlm response */
3105 data_blob_free(&server_ntlm_response);
3107 if (!NT_STATUS_IS_OK(status)) {
3108 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3109 "using server blob failed.\n"));
3110 data_blob_free(&client_reply);
3114 /* SPNEGO wrap the client reply. */
3115 tmp_blob = spnego_gen_auth(client_reply);
3116 data_blob_free(&client_reply);
3117 client_reply = tmp_blob;
3118 tmp_blob = data_blob_null;
3120 /* Now prepare the alter context pdu. */
3121 prs_init_empty(&state->rpc_out, state, MARSHALL);
3123 status = create_rpc_alter_context(state->rpc_call_id,
3124 &state->cli->abstract_syntax,
3125 &state->cli->transfer_syntax,
3126 state->cli->auth->auth_level,
3129 data_blob_free(&client_reply);
3131 if (!NT_STATUS_IS_OK(status)) {
3135 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3136 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3137 if (subreq == NULL) {
3138 return NT_STATUS_NO_MEMORY;
3140 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3141 return NT_STATUS_OK;
3144 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3146 struct tevent_req *req = tevent_req_callback_data(
3147 subreq, struct tevent_req);
3148 struct rpc_pipe_bind_state *state = tevent_req_data(
3149 req, struct rpc_pipe_bind_state);
3150 DATA_BLOB tmp_blob = data_blob_null;
3151 struct ncacn_packet *pkt;
3152 struct dcerpc_auth auth;
3153 prs_struct reply_pdu;
3156 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
3157 TALLOC_FREE(subreq);
3158 if (!NT_STATUS_IS_OK(status)) {
3159 tevent_req_nterror(req, status);
3163 status = dcerpc_pull_dcerpc_auth(pkt,
3164 &pkt->u.alter_resp.auth_info,
3166 if (!NT_STATUS_IS_OK(status)) {
3167 tevent_req_nterror(req, status);
3171 /* Check we got a valid auth response. */
3172 if (!spnego_parse_auth_response(auth.credentials,
3174 OID_NTLMSSP, &tmp_blob)) {
3175 data_blob_free(&tmp_blob);
3176 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3180 data_blob_free(&tmp_blob);
3182 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3183 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3184 tevent_req_done(req);
3187 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3189 return tevent_req_simple_recv_ntstatus(req);
3192 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3193 struct cli_pipe_auth_data *auth)
3195 TALLOC_CTX *frame = talloc_stackframe();
3196 struct event_context *ev;
3197 struct tevent_req *req;
3198 NTSTATUS status = NT_STATUS_OK;
3200 ev = event_context_init(frame);
3202 status = NT_STATUS_NO_MEMORY;
3206 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3208 status = NT_STATUS_NO_MEMORY;
3212 if (!tevent_req_poll(req, ev)) {
3213 status = map_nt_error_from_unix(errno);
3217 status = rpc_pipe_bind_recv(req);
3223 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3225 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3226 unsigned int timeout)
3230 if (rpc_cli->transport == NULL) {
3231 return RPCCLI_DEFAULT_TIMEOUT;
3234 if (rpc_cli->transport->set_timeout == NULL) {
3235 return RPCCLI_DEFAULT_TIMEOUT;
3238 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3240 return RPCCLI_DEFAULT_TIMEOUT;
3246 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3248 if (rpc_cli == NULL) {
3252 if (rpc_cli->transport == NULL) {
3256 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3259 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3261 struct cli_state *cli;
3263 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3264 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3265 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3269 cli = rpc_pipe_np_smb_conn(rpc_cli);
3273 E_md4hash(cli->password ? cli->password : "", nt_hash);
3277 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3278 struct cli_pipe_auth_data **presult)
3280 struct cli_pipe_auth_data *result;
3282 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3283 if (result == NULL) {
3284 return NT_STATUS_NO_MEMORY;
3287 result->auth_type = PIPE_AUTH_TYPE_NONE;
3288 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3290 result->user_name = talloc_strdup(result, "");
3291 result->domain = talloc_strdup(result, "");
3292 if ((result->user_name == NULL) || (result->domain == NULL)) {
3293 TALLOC_FREE(result);
3294 return NT_STATUS_NO_MEMORY;
3298 return NT_STATUS_OK;
3301 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3303 ntlmssp_end(&auth->a_u.ntlmssp_state);
3307 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3308 enum pipe_auth_type auth_type,
3309 enum dcerpc_AuthLevel auth_level,
3311 const char *username,
3312 const char *password,
3313 struct cli_pipe_auth_data **presult)
3315 struct cli_pipe_auth_data *result;
3318 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3319 if (result == NULL) {
3320 return NT_STATUS_NO_MEMORY;
3323 result->auth_type = auth_type;
3324 result->auth_level = auth_level;
3326 result->user_name = talloc_strdup(result, username);
3327 result->domain = talloc_strdup(result, domain);
3328 if ((result->user_name == NULL) || (result->domain == NULL)) {
3329 status = NT_STATUS_NO_MEMORY;
3333 status = ntlmssp_client_start(NULL,
3336 lp_client_ntlmv2_auth(),
3337 &result->a_u.ntlmssp_state);
3338 if (!NT_STATUS_IS_OK(status)) {
3342 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3344 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3345 if (!NT_STATUS_IS_OK(status)) {
3349 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3350 if (!NT_STATUS_IS_OK(status)) {
3354 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3355 if (!NT_STATUS_IS_OK(status)) {
3360 * Turn off sign+seal to allow selected auth level to turn it back on.
3362 result->a_u.ntlmssp_state->neg_flags &=
3363 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3365 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3366 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3367 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3368 result->a_u.ntlmssp_state->neg_flags
3369 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3373 return NT_STATUS_OK;
3376 TALLOC_FREE(result);
3380 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3381 enum dcerpc_AuthLevel auth_level,
3382 struct netlogon_creds_CredentialState *creds,
3383 struct cli_pipe_auth_data **presult)
3385 struct cli_pipe_auth_data *result;
3387 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3388 if (result == NULL) {
3389 return NT_STATUS_NO_MEMORY;
3392 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3393 result->auth_level = auth_level;
3395 result->user_name = talloc_strdup(result, "");
3396 result->domain = talloc_strdup(result, domain);
3397 if ((result->user_name == NULL) || (result->domain == NULL)) {
3401 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3402 if (result->a_u.schannel_auth == NULL) {
3406 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3407 result->a_u.schannel_auth->seq_num = 0;
3408 result->a_u.schannel_auth->initiator = true;
3409 result->a_u.schannel_auth->creds = creds;
3412 return NT_STATUS_OK;
3415 TALLOC_FREE(result);
3416 return NT_STATUS_NO_MEMORY;
3420 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3422 data_blob_free(&auth->session_key);
3427 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3428 enum dcerpc_AuthLevel auth_level,
3429 const char *service_princ,
3430 const char *username,
3431 const char *password,
3432 struct cli_pipe_auth_data **presult)
3435 struct cli_pipe_auth_data *result;
3437 if ((username != NULL) && (password != NULL)) {
3438 int ret = kerberos_kinit_password(username, password, 0, NULL);
3440 return NT_STATUS_ACCESS_DENIED;
3444 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3445 if (result == NULL) {
3446 return NT_STATUS_NO_MEMORY;
3449 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3450 result->auth_level = auth_level;
3453 * Username / domain need fixing!
3455 result->user_name = talloc_strdup(result, "");
3456 result->domain = talloc_strdup(result, "");
3457 if ((result->user_name == NULL) || (result->domain == NULL)) {
3461 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3462 result, struct kerberos_auth_struct);
3463 if (result->a_u.kerberos_auth == NULL) {
3466 talloc_set_destructor(result->a_u.kerberos_auth,
3467 cli_auth_kerberos_data_destructor);
3469 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3470 result, service_princ);
3471 if (result->a_u.kerberos_auth->service_principal == NULL) {
3476 return NT_STATUS_OK;
3479 TALLOC_FREE(result);
3480 return NT_STATUS_NO_MEMORY;
3482 return NT_STATUS_NOT_SUPPORTED;
3487 * Create an rpc pipe client struct, connecting to a tcp port.
3489 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3491 const struct ndr_syntax_id *abstract_syntax,
3492 struct rpc_pipe_client **presult)
3494 struct rpc_pipe_client *result;
3495 struct sockaddr_storage addr;
3499 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3500 if (result == NULL) {
3501 return NT_STATUS_NO_MEMORY;
3504 result->abstract_syntax = *abstract_syntax;
3505 result->transfer_syntax = ndr_transfer_syntax;
3506 result->dispatch = cli_do_rpc_ndr;
3507 result->dispatch_send = cli_do_rpc_ndr_send;
3508 result->dispatch_recv = cli_do_rpc_ndr_recv;
3510 result->desthost = talloc_strdup(result, host);
3511 result->srv_name_slash = talloc_asprintf_strupper_m(
3512 result, "\\\\%s", result->desthost);
3513 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3514 status = NT_STATUS_NO_MEMORY;
3518 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3519 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3521 if (!resolve_name(host, &addr, 0, false)) {
3522 status = NT_STATUS_NOT_FOUND;
3526 status = open_socket_out(&addr, port, 60, &fd);
3527 if (!NT_STATUS_IS_OK(status)) {
3530 set_socket_options(fd, lp_socket_options());
3532 status = rpc_transport_sock_init(result, fd, &result->transport);
3533 if (!NT_STATUS_IS_OK(status)) {
3538 result->transport->transport = NCACN_IP_TCP;
3541 return NT_STATUS_OK;
3544 TALLOC_FREE(result);
3549 * Determine the tcp port on which a dcerpc interface is listening
3550 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3553 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3554 const struct ndr_syntax_id *abstract_syntax,
3558 struct rpc_pipe_client *epm_pipe = NULL;
3559 struct cli_pipe_auth_data *auth = NULL;
3560 struct dcerpc_binding *map_binding = NULL;
3561 struct dcerpc_binding *res_binding = NULL;
3562 struct epm_twr_t *map_tower = NULL;
3563 struct epm_twr_t *res_towers = NULL;
3564 struct policy_handle *entry_handle = NULL;
3565 uint32_t num_towers = 0;
3566 uint32_t max_towers = 1;
3567 struct epm_twr_p_t towers;
3568 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3570 if (pport == NULL) {
3571 status = NT_STATUS_INVALID_PARAMETER;
3575 /* open the connection to the endpoint mapper */
3576 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3577 &ndr_table_epmapper.syntax_id,
3580 if (!NT_STATUS_IS_OK(status)) {
3584 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3585 if (!NT_STATUS_IS_OK(status)) {
3589 status = rpc_pipe_bind(epm_pipe, auth);
3590 if (!NT_STATUS_IS_OK(status)) {
3594 /* create tower for asking the epmapper */
3596 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3597 if (map_binding == NULL) {
3598 status = NT_STATUS_NO_MEMORY;
3602 map_binding->transport = NCACN_IP_TCP;
3603 map_binding->object = *abstract_syntax;
3604 map_binding->host = host; /* needed? */
3605 map_binding->endpoint = "0"; /* correct? needed? */
3607 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3608 if (map_tower == NULL) {
3609 status = NT_STATUS_NO_MEMORY;
3613 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3614 &(map_tower->tower));
3615 if (!NT_STATUS_IS_OK(status)) {
3619 /* allocate further parameters for the epm_Map call */
3621 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3622 if (res_towers == NULL) {
3623 status = NT_STATUS_NO_MEMORY;
3626 towers.twr = res_towers;
3628 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3629 if (entry_handle == NULL) {
3630 status = NT_STATUS_NO_MEMORY;
3634 /* ask the endpoint mapper for the port */
3636 status = rpccli_epm_Map(epm_pipe,
3638 CONST_DISCARD(struct GUID *,
3639 &(abstract_syntax->uuid)),
3646 if (!NT_STATUS_IS_OK(status)) {
3650 if (num_towers != 1) {
3651 status = NT_STATUS_UNSUCCESSFUL;
3655 /* extract the port from the answer */
3657 status = dcerpc_binding_from_tower(tmp_ctx,
3658 &(towers.twr->tower),
3660 if (!NT_STATUS_IS_OK(status)) {
3664 /* are further checks here necessary? */
3665 if (res_binding->transport != NCACN_IP_TCP) {
3666 status = NT_STATUS_UNSUCCESSFUL;
3670 *pport = (uint16_t)atoi(res_binding->endpoint);
3673 TALLOC_FREE(tmp_ctx);
3678 * Create a rpc pipe client struct, connecting to a host via tcp.
3679 * The port is determined by asking the endpoint mapper on the given
3682 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3683 const struct ndr_syntax_id *abstract_syntax,
3684 struct rpc_pipe_client **presult)
3689 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3690 if (!NT_STATUS_IS_OK(status)) {
3694 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3695 abstract_syntax, presult);
3698 /********************************************************************
3699 Create a rpc pipe client struct, connecting to a unix domain socket
3700 ********************************************************************/
3701 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3702 const struct ndr_syntax_id *abstract_syntax,
3703 struct rpc_pipe_client **presult)
3705 struct rpc_pipe_client *result;
3706 struct sockaddr_un addr;
3710 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3711 if (result == NULL) {
3712 return NT_STATUS_NO_MEMORY;
3715 result->abstract_syntax = *abstract_syntax;
3716 result->transfer_syntax = ndr_transfer_syntax;
3717 result->dispatch = cli_do_rpc_ndr;
3718 result->dispatch_send = cli_do_rpc_ndr_send;
3719 result->dispatch_recv = cli_do_rpc_ndr_recv;
3721 result->desthost = get_myname(result);
3722 result->srv_name_slash = talloc_asprintf_strupper_m(
3723 result, "\\\\%s", result->desthost);
3724 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3725 status = NT_STATUS_NO_MEMORY;
3729 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3730 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3732 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3734 status = map_nt_error_from_unix(errno);
3739 addr.sun_family = AF_UNIX;
3740 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3742 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3743 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3746 return map_nt_error_from_unix(errno);
3749 status = rpc_transport_sock_init(result, fd, &result->transport);
3750 if (!NT_STATUS_IS_OK(status)) {
3755 result->transport->transport = NCALRPC;
3758 return NT_STATUS_OK;
3761 TALLOC_FREE(result);
3765 struct rpc_pipe_client_np_ref {
3766 struct cli_state *cli;
3767 struct rpc_pipe_client *pipe;
3770 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3772 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3776 /****************************************************************************
3777 Open a named pipe over SMB to a remote server.
3779 * CAVEAT CALLER OF THIS FUNCTION:
3780 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3781 * so be sure that this function is called AFTER any structure (vs pointer)
3782 * assignment of the cli. In particular, libsmbclient does structure
3783 * assignments of cli, which invalidates the data in the returned
3784 * rpc_pipe_client if this function is called before the structure assignment
3787 ****************************************************************************/
3789 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3790 const struct ndr_syntax_id *abstract_syntax,
3791 struct rpc_pipe_client **presult)
3793 struct rpc_pipe_client *result;
3795 struct rpc_pipe_client_np_ref *np_ref;
3797 /* sanity check to protect against crashes */
3800 return NT_STATUS_INVALID_HANDLE;
3803 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3804 if (result == NULL) {
3805 return NT_STATUS_NO_MEMORY;
3808 result->abstract_syntax = *abstract_syntax;
3809 result->transfer_syntax = ndr_transfer_syntax;
3810 result->dispatch = cli_do_rpc_ndr;
3811 result->dispatch_send = cli_do_rpc_ndr_send;
3812 result->dispatch_recv = cli_do_rpc_ndr_recv;
3813 result->desthost = talloc_strdup(result, cli->desthost);
3814 result->srv_name_slash = talloc_asprintf_strupper_m(
3815 result, "\\\\%s", result->desthost);
3817 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3818 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3820 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3821 TALLOC_FREE(result);
3822 return NT_STATUS_NO_MEMORY;
3825 status = rpc_transport_np_init(result, cli, abstract_syntax,
3826 &result->transport);
3827 if (!NT_STATUS_IS_OK(status)) {
3828 TALLOC_FREE(result);
3832 result->transport->transport = NCACN_NP;
3834 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3835 if (np_ref == NULL) {
3836 TALLOC_FREE(result);
3837 return NT_STATUS_NO_MEMORY;
3840 np_ref->pipe = result;
3842 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3843 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3846 return NT_STATUS_OK;
3849 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3850 struct rpc_cli_smbd_conn *conn,
3851 const struct ndr_syntax_id *syntax,
3852 struct rpc_pipe_client **presult)
3854 struct rpc_pipe_client *result;
3855 struct cli_pipe_auth_data *auth;
3858 result = talloc(mem_ctx, struct rpc_pipe_client);
3859 if (result == NULL) {
3860 return NT_STATUS_NO_MEMORY;
3862 result->abstract_syntax = *syntax;
3863 result->transfer_syntax = ndr_transfer_syntax;
3864 result->dispatch = cli_do_rpc_ndr;
3865 result->dispatch_send = cli_do_rpc_ndr_send;
3866 result->dispatch_recv = cli_do_rpc_ndr_recv;
3867 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3868 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3870 result->desthost = talloc_strdup(result, global_myname());
3871 result->srv_name_slash = talloc_asprintf_strupper_m(
3872 result, "\\\\%s", global_myname());
3873 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3874 TALLOC_FREE(result);
3875 return NT_STATUS_NO_MEMORY;
3878 status = rpc_transport_smbd_init(result, conn, syntax,
3879 &result->transport);
3880 if (!NT_STATUS_IS_OK(status)) {
3881 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3882 nt_errstr(status)));
3883 TALLOC_FREE(result);
3887 status = rpccli_anon_bind_data(result, &auth);
3888 if (!NT_STATUS_IS_OK(status)) {
3889 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3890 nt_errstr(status)));
3891 TALLOC_FREE(result);
3895 status = rpc_pipe_bind(result, auth);
3896 if (!NT_STATUS_IS_OK(status)) {
3897 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3898 TALLOC_FREE(result);
3902 result->transport->transport = NCACN_INTERNAL;
3905 return NT_STATUS_OK;
3908 /****************************************************************************
3909 Open a pipe to a remote server.
3910 ****************************************************************************/
3912 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3913 enum dcerpc_transport_t transport,
3914 const struct ndr_syntax_id *interface,
3915 struct rpc_pipe_client **presult)
3917 switch (transport) {
3919 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3922 return rpc_pipe_open_np(cli, interface, presult);
3924 return NT_STATUS_NOT_IMPLEMENTED;
3928 /****************************************************************************
3929 Open a named pipe to an SMB server and bind anonymously.
3930 ****************************************************************************/
3932 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3933 enum dcerpc_transport_t transport,
3934 const struct ndr_syntax_id *interface,
3935 struct rpc_pipe_client **presult)
3937 struct rpc_pipe_client *result;
3938 struct cli_pipe_auth_data *auth;
3941 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3942 if (!NT_STATUS_IS_OK(status)) {
3946 status = rpccli_anon_bind_data(result, &auth);
3947 if (!NT_STATUS_IS_OK(status)) {
3948 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3949 nt_errstr(status)));
3950 TALLOC_FREE(result);
3955 * This is a bit of an abstraction violation due to the fact that an
3956 * anonymous bind on an authenticated SMB inherits the user/domain
3957 * from the enclosing SMB creds
3960 TALLOC_FREE(auth->user_name);
3961 TALLOC_FREE(auth->domain);
3963 auth->user_name = talloc_strdup(auth, cli->user_name);
3964 auth->domain = talloc_strdup(auth, cli->domain);
3965 auth->user_session_key = data_blob_talloc(auth,
3966 cli->user_session_key.data,
3967 cli->user_session_key.length);
3969 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3970 TALLOC_FREE(result);
3971 return NT_STATUS_NO_MEMORY;
3974 status = rpc_pipe_bind(result, auth);
3975 if (!NT_STATUS_IS_OK(status)) {
3977 if (ndr_syntax_id_equal(interface,
3978 &ndr_table_dssetup.syntax_id)) {
3979 /* non AD domains just don't have this pipe, avoid
3980 * level 0 statement in that case - gd */
3983 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3984 "%s failed with error %s\n",
3985 get_pipe_name_from_syntax(talloc_tos(), interface),
3986 nt_errstr(status) ));
3987 TALLOC_FREE(result);
3991 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3992 "%s and bound anonymously.\n",
3993 get_pipe_name_from_syntax(talloc_tos(), interface),
3997 return NT_STATUS_OK;
4000 /****************************************************************************
4001 ****************************************************************************/
4003 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4004 const struct ndr_syntax_id *interface,
4005 struct rpc_pipe_client **presult)
4007 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4008 interface, presult);
4011 /****************************************************************************
4012 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4013 ****************************************************************************/
4015 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4016 const struct ndr_syntax_id *interface,
4017 enum dcerpc_transport_t transport,
4018 enum pipe_auth_type auth_type,
4019 enum dcerpc_AuthLevel auth_level,
4021 const char *username,
4022 const char *password,
4023 struct rpc_pipe_client **presult)
4025 struct rpc_pipe_client *result;
4026 struct cli_pipe_auth_data *auth;
4029 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4030 if (!NT_STATUS_IS_OK(status)) {
4034 status = rpccli_ntlmssp_bind_data(
4035 result, auth_type, auth_level, domain, username,
4037 if (!NT_STATUS_IS_OK(status)) {
4038 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4039 nt_errstr(status)));
4043 status = rpc_pipe_bind(result, auth);
4044 if (!NT_STATUS_IS_OK(status)) {
4045 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4046 nt_errstr(status) ));
4050 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4051 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4052 get_pipe_name_from_syntax(talloc_tos(), interface),
4053 cli->desthost, domain, username ));
4056 return NT_STATUS_OK;
4060 TALLOC_FREE(result);
4064 /****************************************************************************
4066 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4067 ****************************************************************************/
4069 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4070 const struct ndr_syntax_id *interface,
4071 enum dcerpc_transport_t transport,
4072 enum dcerpc_AuthLevel auth_level,
4074 const char *username,
4075 const char *password,
4076 struct rpc_pipe_client **presult)
4078 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4081 PIPE_AUTH_TYPE_NTLMSSP,
4089 /****************************************************************************
4091 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4092 ****************************************************************************/
4094 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4095 const struct ndr_syntax_id *interface,
4096 enum dcerpc_transport_t transport,
4097 enum dcerpc_AuthLevel auth_level,
4099 const char *username,
4100 const char *password,
4101 struct rpc_pipe_client **presult)
4103 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4106 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4114 /****************************************************************************
4115 Get a the schannel session key out of an already opened netlogon pipe.
4116 ****************************************************************************/
4117 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4118 struct cli_state *cli,
4122 enum netr_SchannelType sec_chan_type = 0;
4123 unsigned char machine_pwd[16];
4124 const char *machine_account;
4127 /* Get the machine account credentials from secrets.tdb. */
4128 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4131 DEBUG(0, ("get_schannel_session_key: could not fetch "
4132 "trust account password for domain '%s'\n",
4134 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4137 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4138 cli->desthost, /* server name */
4139 domain, /* domain */
4140 global_myname(), /* client name */
4141 machine_account, /* machine account name */
4146 if (!NT_STATUS_IS_OK(status)) {
4147 DEBUG(3, ("get_schannel_session_key_common: "
4148 "rpccli_netlogon_setup_creds failed with result %s "
4149 "to server %s, domain %s, machine account %s.\n",
4150 nt_errstr(status), cli->desthost, domain,
4155 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4156 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4158 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4161 return NT_STATUS_OK;;
4164 /****************************************************************************
4165 Open a netlogon pipe and get the schannel session key.
4166 Now exposed to external callers.
4167 ****************************************************************************/
4170 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4173 struct rpc_pipe_client **presult)
4175 struct rpc_pipe_client *netlogon_pipe = NULL;
4178 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4180 if (!NT_STATUS_IS_OK(status)) {
4184 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4186 if (!NT_STATUS_IS_OK(status)) {
4187 TALLOC_FREE(netlogon_pipe);
4191 *presult = netlogon_pipe;
4192 return NT_STATUS_OK;
4195 /****************************************************************************
4197 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4198 using session_key. sign and seal.
4200 The *pdc will be stolen onto this new pipe
4201 ****************************************************************************/
4203 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4204 const struct ndr_syntax_id *interface,
4205 enum dcerpc_transport_t transport,
4206 enum dcerpc_AuthLevel auth_level,
4208 struct netlogon_creds_CredentialState **pdc,
4209 struct rpc_pipe_client **presult)
4211 struct rpc_pipe_client *result;
4212 struct cli_pipe_auth_data *auth;
4215 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4216 if (!NT_STATUS_IS_OK(status)) {
4220 status = rpccli_schannel_bind_data(result, domain, auth_level,
4222 if (!NT_STATUS_IS_OK(status)) {
4223 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4224 nt_errstr(status)));
4225 TALLOC_FREE(result);
4229 status = rpc_pipe_bind(result, auth);
4230 if (!NT_STATUS_IS_OK(status)) {
4231 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4232 "cli_rpc_pipe_bind failed with error %s\n",
4233 nt_errstr(status) ));
4234 TALLOC_FREE(result);
4239 * The credentials on a new netlogon pipe are the ones we are passed
4240 * in - reference them in
4242 result->dc = talloc_move(result, pdc);
4244 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4245 "for domain %s and bound using schannel.\n",
4246 get_pipe_name_from_syntax(talloc_tos(), interface),
4247 cli->desthost, domain ));
4250 return NT_STATUS_OK;
4253 /****************************************************************************
4254 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4255 Fetch the session key ourselves using a temporary netlogon pipe. This
4256 version uses an ntlmssp auth bound netlogon pipe to get the key.
4257 ****************************************************************************/
4259 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4261 const char *username,
4262 const char *password,
4264 struct rpc_pipe_client **presult)
4266 struct rpc_pipe_client *netlogon_pipe = NULL;
4269 status = cli_rpc_pipe_open_spnego_ntlmssp(
4270 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4271 DCERPC_AUTH_LEVEL_PRIVACY,
4272 domain, username, password, &netlogon_pipe);
4273 if (!NT_STATUS_IS_OK(status)) {
4277 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4279 if (!NT_STATUS_IS_OK(status)) {
4280 TALLOC_FREE(netlogon_pipe);
4284 *presult = netlogon_pipe;
4285 return NT_STATUS_OK;
4288 /****************************************************************************
4289 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4290 Fetch the session key ourselves using a temporary netlogon pipe. This version
4291 uses an ntlmssp bind to get the session key.
4292 ****************************************************************************/
4294 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4295 const struct ndr_syntax_id *interface,
4296 enum dcerpc_transport_t transport,
4297 enum dcerpc_AuthLevel auth_level,
4299 const char *username,
4300 const char *password,
4301 struct rpc_pipe_client **presult)
4303 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4304 struct rpc_pipe_client *netlogon_pipe = NULL;
4305 struct rpc_pipe_client *result = NULL;
4308 status = get_schannel_session_key_auth_ntlmssp(
4309 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4310 if (!NT_STATUS_IS_OK(status)) {
4311 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4312 "key from server %s for domain %s.\n",
4313 cli->desthost, domain ));
4317 status = cli_rpc_pipe_open_schannel_with_key(
4318 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4321 /* Now we've bound using the session key we can close the netlog pipe. */
4322 TALLOC_FREE(netlogon_pipe);
4324 if (NT_STATUS_IS_OK(status)) {
4330 /****************************************************************************
4331 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4332 Fetch the session key ourselves using a temporary netlogon pipe.
4333 ****************************************************************************/
4335 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4336 const struct ndr_syntax_id *interface,
4337 enum dcerpc_transport_t transport,
4338 enum dcerpc_AuthLevel auth_level,
4340 struct rpc_pipe_client **presult)
4342 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4343 struct rpc_pipe_client *netlogon_pipe = NULL;
4344 struct rpc_pipe_client *result = NULL;
4347 status = get_schannel_session_key(cli, domain, &neg_flags,
4349 if (!NT_STATUS_IS_OK(status)) {
4350 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4351 "key from server %s for domain %s.\n",
4352 cli->desthost, domain ));
4356 status = cli_rpc_pipe_open_schannel_with_key(
4357 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4360 /* Now we've bound using the session key we can close the netlog pipe. */
4361 TALLOC_FREE(netlogon_pipe);
4363 if (NT_STATUS_IS_OK(status)) {
4370 /****************************************************************************
4371 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4372 The idea is this can be called with service_princ, username and password all
4373 NULL so long as the caller has a TGT.
4374 ****************************************************************************/
4376 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4377 const struct ndr_syntax_id *interface,
4378 enum dcerpc_AuthLevel auth_level,
4379 const char *service_princ,
4380 const char *username,
4381 const char *password,
4382 struct rpc_pipe_client **presult)
4385 struct rpc_pipe_client *result;
4386 struct cli_pipe_auth_data *auth;
4389 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4390 if (!NT_STATUS_IS_OK(status)) {
4394 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4395 username, password, &auth);
4396 if (!NT_STATUS_IS_OK(status)) {
4397 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4398 nt_errstr(status)));
4399 TALLOC_FREE(result);
4403 status = rpc_pipe_bind(result, auth);
4404 if (!NT_STATUS_IS_OK(status)) {
4405 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4406 "with error %s\n", nt_errstr(status)));
4407 TALLOC_FREE(result);
4412 return NT_STATUS_OK;
4414 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4415 return NT_STATUS_NOT_IMPLEMENTED;
4419 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4420 struct rpc_pipe_client *cli,
4421 DATA_BLOB *session_key)
4423 if (!session_key || !cli) {
4424 return NT_STATUS_INVALID_PARAMETER;
4428 return NT_STATUS_INVALID_PARAMETER;
4431 switch (cli->auth->auth_type) {
4432 case PIPE_AUTH_TYPE_SCHANNEL:
4433 *session_key = data_blob_talloc(mem_ctx,
4434 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4436 case PIPE_AUTH_TYPE_NTLMSSP:
4437 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4438 *session_key = data_blob_talloc(mem_ctx,
4439 cli->auth->a_u.ntlmssp_state->session_key.data,
4440 cli->auth->a_u.ntlmssp_state->session_key.length);
4442 case PIPE_AUTH_TYPE_KRB5:
4443 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4444 *session_key = data_blob_talloc(mem_ctx,
4445 cli->auth->a_u.kerberos_auth->session_key.data,
4446 cli->auth->a_u.kerberos_auth->session_key.length);
4448 case PIPE_AUTH_TYPE_NONE:
4449 *session_key = data_blob_talloc(mem_ctx,
4450 cli->auth->user_session_key.data,
4451 cli->auth->user_session_key.length);
4454 return NT_STATUS_NO_USER_SESSION_KEY;
4457 return NT_STATUS_OK;