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 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
631 struct ncacn_packet_header *prhdr,
635 DATA_BLOB blob = data_blob_const(prs_data_p(pdu), prs_data_size(pdu));
638 * This next call sets the endian bit correctly in current_pdu. We
639 * will propagate this to rbuf later.
642 status = dcerpc_pull_ncacn_packet_header(cli, &blob, prhdr);
643 if (!NT_STATUS_IS_OK(status)) {
647 if (!prs_set_offset(pdu, prs_offset(pdu) + RPC_HEADER_LEN)) {
648 return NT_STATUS_BUFFER_TOO_SMALL;
651 if (UNMARSHALLING(pdu) && prhdr->drep[0] == 0) {
652 DEBUG(10,("parse_rpc_header: PDU data format is big-endian. Setting flag.\n"));
653 prs_set_endian_data(pdu, RPC_BIG_ENDIAN);
656 if (prhdr->frag_length > cli->max_recv_frag) {
657 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
658 " we only allow %d\n", (int)prhdr->frag_length,
659 (int)cli->max_recv_frag));
660 return NT_STATUS_BUFFER_TOO_SMALL;
666 /****************************************************************************
667 Try and get a PDU's worth of data from current_pdu. If not, then read more
669 ****************************************************************************/
671 struct get_complete_frag_state {
672 struct event_context *ev;
673 struct rpc_pipe_client *cli;
678 static void get_complete_frag_got_header(struct tevent_req *subreq);
679 static void get_complete_frag_got_rest(struct tevent_req *subreq);
681 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
682 struct event_context *ev,
683 struct rpc_pipe_client *cli,
686 struct tevent_req *req, *subreq;
687 struct get_complete_frag_state *state;
692 req = tevent_req_create(mem_ctx, &state,
693 struct get_complete_frag_state);
699 state->frag_len = RPC_HEADER_LEN;
702 pdu_len = prs_data_size(pdu);
703 if (pdu_len < RPC_HEADER_LEN) {
704 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
705 status = NT_STATUS_NO_MEMORY;
708 subreq = rpc_read_send(
710 state->cli->transport,
711 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
712 RPC_HEADER_LEN - pdu_len);
713 if (subreq == NULL) {
714 status = NT_STATUS_NO_MEMORY;
717 tevent_req_set_callback(subreq, get_complete_frag_got_header,
722 blob = data_blob_const(prs_data_p(state->pdu), pdu_len);
723 state->frag_len = dcerpc_get_frag_length(&blob);
726 * Ensure we have frag_len bytes of data.
728 if (pdu_len < state->frag_len) {
729 if (!rpc_grow_buffer(pdu, state->frag_len)) {
730 status = NT_STATUS_NO_MEMORY;
733 subreq = rpc_read_send(state, state->ev,
734 state->cli->transport,
735 (uint8_t *)(prs_data_p(pdu) + pdu_len),
736 state->frag_len - pdu_len);
737 if (subreq == NULL) {
738 status = NT_STATUS_NO_MEMORY;
741 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
746 status = NT_STATUS_OK;
748 if (NT_STATUS_IS_OK(status)) {
749 tevent_req_done(req);
751 tevent_req_nterror(req, status);
753 return tevent_req_post(req, ev);
756 static void get_complete_frag_got_header(struct tevent_req *subreq)
758 struct tevent_req *req = tevent_req_callback_data(
759 subreq, struct tevent_req);
760 struct get_complete_frag_state *state = tevent_req_data(
761 req, struct get_complete_frag_state);
765 status = rpc_read_recv(subreq);
767 if (!NT_STATUS_IS_OK(status)) {
768 tevent_req_nterror(req, status);
772 pdu = data_blob_const(prs_data_p(state->pdu),
773 prs_data_size(state->pdu));
774 state->frag_len = dcerpc_get_frag_length(&pdu);
776 if (!rpc_grow_buffer(state->pdu, state->frag_len)) {
777 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
782 * We're here in this piece of code because we've read exactly
783 * RPC_HEADER_LEN bytes into state->pdu.
786 subreq = rpc_read_send(
787 state, state->ev, state->cli->transport,
788 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
789 state->frag_len - RPC_HEADER_LEN);
790 if (tevent_req_nomem(subreq, req)) {
793 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
796 static void get_complete_frag_got_rest(struct tevent_req *subreq)
798 struct tevent_req *req = tevent_req_callback_data(
799 subreq, struct tevent_req);
802 status = rpc_read_recv(subreq);
804 if (!NT_STATUS_IS_OK(status)) {
805 tevent_req_nterror(req, status);
808 tevent_req_done(req);
811 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
813 return tevent_req_simple_recv_ntstatus(req);
816 /****************************************************************************
817 NTLMSSP specific sign/seal.
818 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
819 In fact I should probably abstract these into identical pieces of code... JRA.
820 ****************************************************************************/
822 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
823 struct ncacn_packet_header *prhdr,
824 prs_struct *current_pdu,
825 uint8 *p_ss_padding_len)
827 struct dcerpc_auth auth_info;
828 uint32 save_offset = prs_offset(current_pdu);
829 uint32_t auth_len = prhdr->auth_length;
830 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
831 unsigned char *data = NULL;
833 unsigned char *full_packet_data = NULL;
834 size_t full_packet_data_len;
839 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
840 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
844 if (!ntlmssp_state) {
845 return NT_STATUS_INVALID_PARAMETER;
848 /* Ensure there's enough data for an authenticated response. */
849 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
850 prhdr->frag_length < RPC_HEADER_LEN +
852 RPC_HDR_AUTH_LEN + auth_len) {
853 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
854 (unsigned int)auth_len ));
855 return NT_STATUS_BUFFER_TOO_SMALL;
859 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
860 * after the RPC header.
861 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
862 * functions as NTLMv2 checks the rpc headers also.
865 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
866 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
868 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
869 full_packet_data_len = prhdr->frag_length - auth_len;
871 /* Pull the auth header and the following data into a blob. */
872 /* NB. The offset of the auth_header is relative to the *end*
873 * of the packet, not the start. */
874 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
875 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
876 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
877 return NT_STATUS_BUFFER_TOO_SMALL;
880 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu),
881 prs_data_size(current_pdu) - prs_offset(current_pdu));
883 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
884 if (!NT_STATUS_IS_OK(status)) {
885 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
889 /* Ensure auth_pad_len fits into the packet. */
890 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
891 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
892 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
893 "too large (%u), auth_len (%u), frag_len = (%u).\n",
894 (unsigned int)auth_info.auth_pad_length,
895 (unsigned int)auth_len,
896 (unsigned int)prhdr->frag_length));
897 return NT_STATUS_BUFFER_TOO_SMALL;
901 auth_blob = auth_info.credentials;
903 switch (cli->auth->auth_level) {
904 case DCERPC_AUTH_LEVEL_PRIVACY:
905 /* Data is encrypted. */
906 status = ntlmssp_unseal_packet(ntlmssp_state,
909 full_packet_data_len,
911 if (!NT_STATUS_IS_OK(status)) {
912 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
913 "packet from %s. Error was %s.\n",
914 rpccli_pipe_txt(talloc_tos(), cli),
915 nt_errstr(status) ));
919 case DCERPC_AUTH_LEVEL_INTEGRITY:
920 /* Data is signed. */
921 status = ntlmssp_check_packet(ntlmssp_state,
924 full_packet_data_len,
926 if (!NT_STATUS_IS_OK(status)) {
927 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
928 "packet from %s. Error was %s.\n",
929 rpccli_pipe_txt(talloc_tos(), cli),
930 nt_errstr(status) ));
935 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
936 "auth level %d\n", cli->auth->auth_level));
937 return NT_STATUS_INVALID_INFO_CLASS;
941 * Return the current pointer to the data offset.
944 if(!prs_set_offset(current_pdu, save_offset)) {
945 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
946 (unsigned int)save_offset ));
947 return NT_STATUS_BUFFER_TOO_SMALL;
951 * Remember the padding length. We must remove it from the real data
952 * stream once the sign/seal is done.
955 *p_ss_padding_len = auth_info.auth_pad_length;
960 /****************************************************************************
961 schannel specific sign/seal.
962 ****************************************************************************/
964 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
965 struct ncacn_packet_header *prhdr,
966 prs_struct *current_pdu,
967 uint8 *p_ss_padding_len)
969 struct dcerpc_auth auth_info;
970 uint32_t auth_len = prhdr->auth_length;
971 uint32 save_offset = prs_offset(current_pdu);
972 struct schannel_state *schannel_auth =
973 cli->auth->a_u.schannel_auth;
979 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
980 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
984 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
985 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
986 return NT_STATUS_INVALID_PARAMETER;
989 if (!schannel_auth) {
990 return NT_STATUS_INVALID_PARAMETER;
993 /* Ensure there's enough data for an authenticated response. */
994 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
995 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length)) {
996 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
997 (unsigned int)auth_len ));
998 return NT_STATUS_INVALID_PARAMETER;
1001 data_len = prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
1003 /* Pull the auth header and the following data into a blob. */
1004 /* NB. The offset of the auth_header is relative to the *end*
1005 * of the packet, not the start. */
1006 if(!prs_set_offset(current_pdu,
1007 prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
1008 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
1010 (unsigned int)(prhdr->frag_length -
1011 RPC_HDR_AUTH_LEN - auth_len) ));
1012 return NT_STATUS_BUFFER_TOO_SMALL;
1015 blob = data_blob_const(prs_data_p(current_pdu)
1016 + prs_offset(current_pdu),
1017 prs_data_size(current_pdu)
1018 - prs_offset(current_pdu));
1020 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
1021 if (!NT_STATUS_IS_OK(status)) {
1022 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
1026 /* Ensure auth_pad_len fits into the packet. */
1027 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
1028 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
1029 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
1030 "too large (%u), auth_len (%u), frag_len = (%u).\n",
1031 (unsigned int)auth_info.auth_pad_length,
1032 (unsigned int)auth_len,
1033 (unsigned int)prhdr->frag_length));
1034 return NT_STATUS_BUFFER_TOO_SMALL;
1037 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1038 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
1039 auth_info.auth_type));
1040 return NT_STATUS_BUFFER_TOO_SMALL;
1043 blob = data_blob_const(prs_data_p(current_pdu) +
1044 prs_offset(current_pdu) +
1045 RPC_HDR_AUTH_LEN, auth_len);
1047 if (DEBUGLEVEL >= 10) {
1048 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1051 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1053 switch (cli->auth->auth_level) {
1054 case DCERPC_AUTH_LEVEL_PRIVACY:
1055 status = netsec_incoming_packet(schannel_auth,
1062 case DCERPC_AUTH_LEVEL_INTEGRITY:
1063 status = netsec_incoming_packet(schannel_auth,
1071 status = NT_STATUS_INTERNAL_ERROR;
1075 if (!NT_STATUS_IS_OK(status)) {
1076 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1077 "Connection to %s (%s).\n",
1078 rpccli_pipe_txt(talloc_tos(), cli),
1079 nt_errstr(status)));
1080 return NT_STATUS_INVALID_PARAMETER;
1084 * Return the current pointer to the data offset.
1087 if(!prs_set_offset(current_pdu, save_offset)) {
1088 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1089 (unsigned int)save_offset ));
1090 return NT_STATUS_BUFFER_TOO_SMALL;
1094 * Remember the padding length. We must remove it from the real data
1095 * stream once the sign/seal is done.
1098 *p_ss_padding_len = auth_info.auth_pad_length;
1100 return NT_STATUS_OK;
1103 /****************************************************************************
1104 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1105 ****************************************************************************/
1107 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1108 struct ncacn_packet_header *prhdr,
1109 prs_struct *current_pdu,
1110 uint8 *p_ss_padding_len)
1112 NTSTATUS ret = NT_STATUS_OK;
1114 /* Paranioa checks for auth_len. */
1115 if (prhdr->auth_length) {
1116 if (prhdr->auth_length > prhdr->frag_length) {
1117 return NT_STATUS_INVALID_PARAMETER;
1120 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1121 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1122 /* Integer wrap attempt. */
1123 return NT_STATUS_INVALID_PARAMETER;
1128 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1131 switch(cli->auth->auth_type) {
1132 case PIPE_AUTH_TYPE_NONE:
1133 if (prhdr->auth_length) {
1134 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1135 "Connection to %s - got non-zero "
1137 rpccli_pipe_txt(talloc_tos(), cli),
1138 (unsigned int)prhdr->auth_length));
1139 return NT_STATUS_INVALID_PARAMETER;
1143 case PIPE_AUTH_TYPE_NTLMSSP:
1144 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1145 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1146 if (!NT_STATUS_IS_OK(ret)) {
1151 case PIPE_AUTH_TYPE_SCHANNEL:
1152 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1153 if (!NT_STATUS_IS_OK(ret)) {
1158 case PIPE_AUTH_TYPE_KRB5:
1159 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1161 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1162 "to %s - unknown internal auth type %u.\n",
1163 rpccli_pipe_txt(talloc_tos(), cli),
1164 cli->auth->auth_type ));
1165 return NT_STATUS_INVALID_INFO_CLASS;
1168 return NT_STATUS_OK;
1171 /****************************************************************************
1172 Do basic authentication checks on an incoming pdu.
1173 ****************************************************************************/
1175 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1176 struct ncacn_packet_header *prhdr,
1177 prs_struct *current_pdu,
1178 uint8 expected_pkt_type,
1181 prs_struct *return_data)
1184 NTSTATUS ret = NT_STATUS_OK;
1185 uint32 current_pdu_len = prs_data_size(current_pdu);
1187 ret = parse_rpc_header(cli, prhdr, current_pdu);
1188 if (!NT_STATUS_IS_OK(ret)) {
1192 if (current_pdu_len != prhdr->frag_length) {
1193 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1194 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_length));
1195 return NT_STATUS_INVALID_PARAMETER;
1199 * Point the return values at the real data including the RPC
1200 * header. Just in case the caller wants it.
1202 *ppdata = prs_data_p(current_pdu);
1203 *pdata_len = current_pdu_len;
1205 /* Ensure we have the correct type. */
1206 switch (prhdr->ptype) {
1207 case DCERPC_PKT_ALTER_RESP:
1208 case DCERPC_PKT_BIND_ACK:
1210 /* Alter context and bind ack share the same packet definitions. */
1214 case DCERPC_PKT_RESPONSE:
1216 uint8 ss_padding_len = 0;
1218 struct ncacn_packet r;
1220 blob = data_blob_const(prs_data_p(current_pdu),
1221 prs_data_size(current_pdu));
1223 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1224 if (!NT_STATUS_IS_OK(ret)) {
1228 if (!prs_set_offset(current_pdu, prs_offset(current_pdu) + RPC_HDR_RESP_LEN)) {
1229 return NT_STATUS_BUFFER_TOO_SMALL;
1232 /* Here's where we deal with incoming sign/seal. */
1233 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1234 current_pdu, &ss_padding_len);
1235 if (!NT_STATUS_IS_OK(ret)) {
1239 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1240 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1242 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1243 return NT_STATUS_BUFFER_TOO_SMALL;
1246 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1248 /* Remember to remove the auth footer. */
1249 if (prhdr->auth_length) {
1250 /* We've already done integer wrap tests on auth_len in
1251 cli_pipe_validate_rpc_response(). */
1252 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_length) {
1253 return NT_STATUS_BUFFER_TOO_SMALL;
1255 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_length);
1258 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1259 current_pdu_len, *pdata_len, ss_padding_len ));
1262 * If this is the first reply, and the allocation hint is reasonably, try and
1263 * set up the return_data parse_struct to the correct size.
1266 if ((prs_data_size(return_data) == 0) && r.u.response.alloc_hint && (r.u.response.alloc_hint < 15*1024*1024)) {
1267 if (!prs_set_buffer_size(return_data, r.u.response.alloc_hint)) {
1268 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1269 "too large to allocate\n",
1270 (unsigned int)r.u.response.alloc_hint ));
1271 return NT_STATUS_NO_MEMORY;
1278 case DCERPC_PKT_BIND_NAK:
1279 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1280 "received from %s!\n",
1281 rpccli_pipe_txt(talloc_tos(), cli)));
1282 /* Use this for now... */
1283 return NT_STATUS_NETWORK_ACCESS_DENIED;
1285 case DCERPC_PKT_FAULT:
1288 struct ncacn_packet r;
1290 blob = data_blob_const(prs_data_p(current_pdu),
1291 prs_data_size(current_pdu));
1293 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1294 if (!NT_STATUS_IS_OK(ret)) {
1297 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1298 "code %s received from %s!\n",
1299 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1300 rpccli_pipe_txt(talloc_tos(), cli)));
1302 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1303 return NT_STATUS_UNSUCCESSFUL;
1305 return NT_STATUS(r.u.fault.status);
1310 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1312 (unsigned int)prhdr->ptype,
1313 rpccli_pipe_txt(talloc_tos(), cli)));
1314 return NT_STATUS_INVALID_INFO_CLASS;
1317 if (prhdr->ptype != expected_pkt_type) {
1318 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1319 "got an unexpected RPC packet type - %u, not %u\n",
1320 rpccli_pipe_txt(talloc_tos(), cli),
1322 expected_pkt_type));
1323 return NT_STATUS_INVALID_INFO_CLASS;
1326 /* Do this just before return - we don't want to modify any rpc header
1327 data before now as we may have needed to do cryptographic actions on
1330 if ((prhdr->ptype == DCERPC_PKT_BIND_ACK) && !(prhdr->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1331 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1332 "setting fragment first/last ON.\n"));
1333 prhdr->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1336 return NT_STATUS_OK;
1339 /****************************************************************************
1340 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1341 Normally the frag_len and buffer size will match, but on the first trans
1342 reply there is a theoretical chance that buffer size > frag_len, so we must
1344 ****************************************************************************/
1346 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1347 struct ncacn_packet_header *prhdr,
1348 prs_struct *current_pdu)
1350 uint32 current_pdu_len = prs_data_size(current_pdu);
1352 if (current_pdu_len < prhdr->frag_length) {
1353 return NT_STATUS_BUFFER_TOO_SMALL;
1357 if (current_pdu_len == (uint32)prhdr->frag_length) {
1358 prs_mem_free(current_pdu);
1359 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1360 /* Make current_pdu dynamic with no memory. */
1361 prs_give_memory(current_pdu, 0, 0, True);
1362 return NT_STATUS_OK;
1366 * Oh no ! More data in buffer than we processed in current pdu.
1367 * Cheat. Move the data down and shrink the buffer.
1370 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_length,
1371 current_pdu_len - prhdr->frag_length);
1373 /* Remember to set the read offset back to zero. */
1374 prs_set_offset(current_pdu, 0);
1376 /* Shrink the buffer. */
1377 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_length)) {
1378 return NT_STATUS_BUFFER_TOO_SMALL;
1381 return NT_STATUS_OK;
1384 /****************************************************************************
1385 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1386 ****************************************************************************/
1388 struct cli_api_pipe_state {
1389 struct event_context *ev;
1390 struct rpc_cli_transport *transport;
1395 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1396 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1397 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1399 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1400 struct event_context *ev,
1401 struct rpc_cli_transport *transport,
1402 uint8_t *data, size_t data_len,
1403 uint32_t max_rdata_len)
1405 struct tevent_req *req, *subreq;
1406 struct cli_api_pipe_state *state;
1409 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1414 state->transport = transport;
1416 if (max_rdata_len < RPC_HEADER_LEN) {
1418 * For a RPC reply we always need at least RPC_HEADER_LEN
1419 * bytes. We check this here because we will receive
1420 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1422 status = NT_STATUS_INVALID_PARAMETER;
1426 if (transport->trans_send != NULL) {
1427 subreq = transport->trans_send(state, ev, data, data_len,
1428 max_rdata_len, transport->priv);
1429 if (subreq == NULL) {
1432 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1437 * If the transport does not provide a "trans" routine, i.e. for
1438 * example the ncacn_ip_tcp transport, do the write/read step here.
1441 subreq = rpc_write_send(state, ev, transport, data, data_len);
1442 if (subreq == NULL) {
1445 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1449 tevent_req_nterror(req, status);
1450 return tevent_req_post(req, ev);
1456 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1458 struct tevent_req *req = tevent_req_callback_data(
1459 subreq, struct tevent_req);
1460 struct cli_api_pipe_state *state = tevent_req_data(
1461 req, struct cli_api_pipe_state);
1464 status = state->transport->trans_recv(subreq, state, &state->rdata,
1466 TALLOC_FREE(subreq);
1467 if (!NT_STATUS_IS_OK(status)) {
1468 tevent_req_nterror(req, status);
1471 tevent_req_done(req);
1474 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1476 struct tevent_req *req = tevent_req_callback_data(
1477 subreq, struct tevent_req);
1478 struct cli_api_pipe_state *state = tevent_req_data(
1479 req, struct cli_api_pipe_state);
1482 status = rpc_write_recv(subreq);
1483 TALLOC_FREE(subreq);
1484 if (!NT_STATUS_IS_OK(status)) {
1485 tevent_req_nterror(req, status);
1489 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1490 if (tevent_req_nomem(state->rdata, req)) {
1495 * We don't need to use rpc_read_send here, the upper layer will cope
1496 * with a short read, transport->trans_send could also return less
1497 * than state->max_rdata_len.
1499 subreq = state->transport->read_send(state, state->ev, state->rdata,
1501 state->transport->priv);
1502 if (tevent_req_nomem(subreq, req)) {
1505 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1508 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1510 struct tevent_req *req = tevent_req_callback_data(
1511 subreq, struct tevent_req);
1512 struct cli_api_pipe_state *state = tevent_req_data(
1513 req, struct cli_api_pipe_state);
1517 status = state->transport->read_recv(subreq, &received);
1518 TALLOC_FREE(subreq);
1519 if (!NT_STATUS_IS_OK(status)) {
1520 tevent_req_nterror(req, status);
1523 state->rdata_len = received;
1524 tevent_req_done(req);
1527 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1528 uint8_t **prdata, uint32_t *prdata_len)
1530 struct cli_api_pipe_state *state = tevent_req_data(
1531 req, struct cli_api_pipe_state);
1534 if (tevent_req_is_nterror(req, &status)) {
1538 *prdata = talloc_move(mem_ctx, &state->rdata);
1539 *prdata_len = state->rdata_len;
1540 return NT_STATUS_OK;
1543 /****************************************************************************
1544 Send data on an rpc pipe via trans. The prs_struct data must be the last
1545 pdu fragment of an NDR data stream.
1547 Receive response data from an rpc pipe, which may be large...
1549 Read the first fragment: unfortunately have to use SMBtrans for the first
1550 bit, then SMBreadX for subsequent bits.
1552 If first fragment received also wasn't the last fragment, continue
1553 getting fragments until we _do_ receive the last fragment.
1555 Request/Response PDU's look like the following...
1557 |<------------------PDU len----------------------------------------------->|
1558 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1560 +------------+-----------------+-------------+---------------+-------------+
1561 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1562 +------------+-----------------+-------------+---------------+-------------+
1564 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1565 signing & sealing being negotiated.
1567 ****************************************************************************/
1569 struct rpc_api_pipe_state {
1570 struct event_context *ev;
1571 struct rpc_pipe_client *cli;
1572 uint8_t expected_pkt_type;
1574 prs_struct incoming_frag;
1575 struct ncacn_packet_header rhdr;
1577 prs_struct incoming_pdu; /* Incoming reply */
1578 uint32_t incoming_pdu_offset;
1581 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1582 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1584 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1585 struct event_context *ev,
1586 struct rpc_pipe_client *cli,
1587 prs_struct *data, /* Outgoing PDU */
1588 uint8_t expected_pkt_type)
1590 struct tevent_req *req, *subreq;
1591 struct rpc_api_pipe_state *state;
1592 uint16_t max_recv_frag;
1595 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1601 state->expected_pkt_type = expected_pkt_type;
1602 state->incoming_pdu_offset = 0;
1604 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1606 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1607 /* Make incoming_pdu dynamic with no memory. */
1608 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1611 * Ensure we're not sending too much.
1613 if (prs_offset(data) > cli->max_xmit_frag) {
1614 status = NT_STATUS_INVALID_PARAMETER;
1618 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1620 max_recv_frag = cli->max_recv_frag;
1623 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1626 subreq = cli_api_pipe_send(state, ev, cli->transport,
1627 (uint8_t *)prs_data_p(data),
1628 prs_offset(data), max_recv_frag);
1629 if (subreq == NULL) {
1632 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1636 tevent_req_nterror(req, status);
1637 return tevent_req_post(req, ev);
1643 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1645 struct tevent_req *req = tevent_req_callback_data(
1646 subreq, struct tevent_req);
1647 struct rpc_api_pipe_state *state = tevent_req_data(
1648 req, struct rpc_api_pipe_state);
1650 uint8_t *rdata = NULL;
1651 uint32_t rdata_len = 0;
1653 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1654 TALLOC_FREE(subreq);
1655 if (!NT_STATUS_IS_OK(status)) {
1656 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1657 tevent_req_nterror(req, status);
1661 if (rdata == NULL) {
1662 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1663 rpccli_pipe_txt(talloc_tos(), state->cli)));
1664 tevent_req_done(req);
1669 * This is equivalent to a talloc_steal - gives rdata to
1670 * the prs_struct state->incoming_frag.
1672 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1675 /* Ensure we have enough data for a pdu. */
1676 subreq = get_complete_frag_send(state, state->ev, state->cli,
1677 &state->incoming_frag);
1678 if (tevent_req_nomem(subreq, req)) {
1681 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1684 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1686 struct tevent_req *req = tevent_req_callback_data(
1687 subreq, struct tevent_req);
1688 struct rpc_api_pipe_state *state = tevent_req_data(
1689 req, struct rpc_api_pipe_state);
1692 uint32_t rdata_len = 0;
1694 status = get_complete_frag_recv(subreq);
1695 TALLOC_FREE(subreq);
1696 if (!NT_STATUS_IS_OK(status)) {
1697 DEBUG(5, ("get_complete_frag failed: %s\n",
1698 nt_errstr(status)));
1699 tevent_req_nterror(req, status);
1703 status = cli_pipe_validate_current_pdu(
1704 state->cli, &state->rhdr, &state->incoming_frag,
1705 state->expected_pkt_type, &rdata, &rdata_len,
1706 &state->incoming_pdu);
1708 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1709 (unsigned)prs_data_size(&state->incoming_frag),
1710 (unsigned)state->incoming_pdu_offset,
1711 nt_errstr(status)));
1713 if (!NT_STATUS_IS_OK(status)) {
1714 tevent_req_nterror(req, status);
1718 if ((state->rhdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)
1719 && (state->rhdr.drep[0] == 0)) {
1721 * Set the data type correctly for big-endian data on the
1724 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1726 rpccli_pipe_txt(talloc_tos(), state->cli)));
1727 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1730 * Check endianness on subsequent packets.
1732 if (state->incoming_frag.bigendian_data
1733 != state->incoming_pdu.bigendian_data) {
1734 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1736 state->incoming_pdu.bigendian_data?"big":"little",
1737 state->incoming_frag.bigendian_data?"big":"little"));
1738 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1742 /* Now copy the data portion out of the pdu into rbuf. */
1743 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1744 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1748 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1749 rdata, (size_t)rdata_len);
1750 state->incoming_pdu_offset += rdata_len;
1752 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1753 &state->incoming_frag);
1754 if (!NT_STATUS_IS_OK(status)) {
1755 tevent_req_nterror(req, status);
1759 if (state->rhdr.pfc_flags & DCERPC_PFC_FLAG_LAST) {
1760 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1761 rpccli_pipe_txt(talloc_tos(), state->cli),
1762 (unsigned)prs_data_size(&state->incoming_pdu)));
1763 tevent_req_done(req);
1767 subreq = get_complete_frag_send(state, state->ev, state->cli,
1768 &state->incoming_frag);
1769 if (tevent_req_nomem(subreq, req)) {
1772 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1775 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1776 prs_struct *reply_pdu)
1778 struct rpc_api_pipe_state *state = tevent_req_data(
1779 req, struct rpc_api_pipe_state);
1782 if (tevent_req_is_nterror(req, &status)) {
1786 *reply_pdu = state->incoming_pdu;
1787 reply_pdu->mem_ctx = mem_ctx;
1790 * Prevent state->incoming_pdu from being freed
1791 * when state is freed.
1793 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1794 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1796 return NT_STATUS_OK;
1799 /*******************************************************************
1800 Creates an auth_data blob.
1801 ********************************************************************/
1803 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1804 enum dcerpc_AuthType auth_type,
1805 enum dcerpc_AuthLevel auth_level,
1806 uint8_t auth_pad_length,
1807 uint32_t auth_context_id,
1808 const DATA_BLOB *credentials,
1811 struct dcerpc_auth r;
1812 enum ndr_err_code ndr_err;
1814 r.auth_type = auth_type;
1815 r.auth_level = auth_level;
1816 r.auth_pad_length = auth_pad_length;
1817 r.auth_reserved = 0;
1818 r.auth_context_id = auth_context_id;
1819 r.credentials = *credentials;
1821 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1822 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1823 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1824 return ndr_map_error2ntstatus(ndr_err);
1827 if (DEBUGLEVEL >= 10) {
1828 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1831 return NT_STATUS_OK;
1834 /*******************************************************************
1835 Creates krb5 auth bind.
1836 ********************************************************************/
1838 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1839 enum dcerpc_AuthLevel auth_level,
1840 DATA_BLOB *auth_info)
1845 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1846 DATA_BLOB tkt = data_blob_null;
1847 DATA_BLOB tkt_wrapped = data_blob_null;
1849 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1850 a->service_principal ));
1852 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1854 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1855 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1858 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1860 a->service_principal,
1861 error_message(ret) ));
1863 data_blob_free(&tkt);
1864 return NT_STATUS_INVALID_PARAMETER;
1867 /* wrap that up in a nice GSS-API wrapping */
1868 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1870 data_blob_free(&tkt);
1872 status = dcerpc_push_dcerpc_auth(cli,
1873 DCERPC_AUTH_TYPE_KRB5,
1875 0, /* auth_pad_length */
1876 1, /* auth_context_id */
1879 if (!NT_STATUS_IS_OK(status)) {
1880 data_blob_free(&tkt_wrapped);
1884 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1885 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1887 return NT_STATUS_OK;
1889 return NT_STATUS_INVALID_PARAMETER;
1893 /*******************************************************************
1894 Creates SPNEGO NTLMSSP auth bind.
1895 ********************************************************************/
1897 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1898 enum dcerpc_AuthLevel auth_level,
1899 DATA_BLOB *auth_info)
1902 DATA_BLOB null_blob = data_blob_null;
1903 DATA_BLOB request = data_blob_null;
1904 DATA_BLOB spnego_msg = data_blob_null;
1906 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1907 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1911 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1912 data_blob_free(&request);
1916 /* Wrap this in SPNEGO. */
1917 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1919 data_blob_free(&request);
1921 status = dcerpc_push_dcerpc_auth(cli,
1922 DCERPC_AUTH_TYPE_SPNEGO,
1924 0, /* auth_pad_length */
1925 1, /* auth_context_id */
1928 if (!NT_STATUS_IS_OK(status)) {
1929 data_blob_free(&spnego_msg);
1933 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1934 dump_data(5, spnego_msg.data, spnego_msg.length);
1936 return NT_STATUS_OK;
1939 /*******************************************************************
1940 Creates NTLMSSP auth bind.
1941 ********************************************************************/
1943 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1944 enum dcerpc_AuthLevel auth_level,
1945 DATA_BLOB *auth_info)
1948 DATA_BLOB null_blob = data_blob_null;
1949 DATA_BLOB request = data_blob_null;
1951 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1952 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1956 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1957 data_blob_free(&request);
1961 status = dcerpc_push_dcerpc_auth(cli,
1962 DCERPC_AUTH_TYPE_NTLMSSP,
1964 0, /* auth_pad_length */
1965 1, /* auth_context_id */
1968 if (!NT_STATUS_IS_OK(status)) {
1969 data_blob_free(&request);
1973 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1974 dump_data(5, request.data, request.length);
1976 return NT_STATUS_OK;
1979 /*******************************************************************
1980 Creates schannel auth bind.
1981 ********************************************************************/
1983 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1984 enum dcerpc_AuthLevel auth_level,
1985 DATA_BLOB *auth_info)
1988 struct NL_AUTH_MESSAGE r;
1989 DATA_BLOB schannel_blob;
1991 /* Use lp_workgroup() if domain not specified */
1993 if (!cli->auth->domain || !cli->auth->domain[0]) {
1994 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1995 if (cli->auth->domain == NULL) {
1996 return NT_STATUS_NO_MEMORY;
2001 * Now marshall the data into the auth parse_struct.
2004 r.MessageType = NL_NEGOTIATE_REQUEST;
2005 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
2006 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
2007 r.oem_netbios_domain.a = cli->auth->domain;
2008 r.oem_netbios_computer.a = global_myname();
2010 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
2011 if (!NT_STATUS_IS_OK(status)) {
2015 status = dcerpc_push_dcerpc_auth(cli,
2016 DCERPC_AUTH_TYPE_SCHANNEL,
2018 0, /* auth_pad_length */
2019 1, /* auth_context_id */
2022 if (!NT_STATUS_IS_OK(status)) {
2026 return NT_STATUS_OK;
2029 /*******************************************************************
2030 ********************************************************************/
2032 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
2033 const struct ndr_syntax_id *abstract_syntax,
2034 const struct ndr_syntax_id *transfer_syntax,
2035 struct dcerpc_ctx_list **ctx_list_p)
2037 struct dcerpc_ctx_list *ctx_list;
2039 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
2040 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
2042 ctx_list[0].context_id = 0;
2043 ctx_list[0].num_transfer_syntaxes = 1;
2044 ctx_list[0].abstract_syntax = *abstract_syntax;
2045 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
2046 struct ndr_syntax_id,
2047 ctx_list[0].num_transfer_syntaxes);
2048 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
2049 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
2051 *ctx_list_p = ctx_list;
2053 return NT_STATUS_OK;
2056 /*******************************************************************
2057 Creates the internals of a DCE/RPC bind request or alter context PDU.
2058 ********************************************************************/
2060 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2061 prs_struct *rpc_out,
2063 const struct ndr_syntax_id *abstract,
2064 const struct ndr_syntax_id *transfer,
2065 const DATA_BLOB *auth_info)
2067 uint16 auth_len = auth_info->length;
2069 union dcerpc_payload u;
2071 struct dcerpc_ctx_list *ctx_list;
2073 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2075 if (!NT_STATUS_IS_OK(status)) {
2079 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2080 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2081 u.bind.assoc_group_id = 0x0;
2082 u.bind.num_contexts = 1;
2083 u.bind.ctx_list = ctx_list;
2084 u.bind.auth_info = *auth_info;
2086 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2088 DCERPC_PFC_FLAG_FIRST |
2089 DCERPC_PFC_FLAG_LAST,
2090 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2094 if (!NT_STATUS_IS_OK(status)) {
2095 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2099 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2100 return NT_STATUS_NO_MEMORY;
2103 return NT_STATUS_OK;
2106 /*******************************************************************
2107 Creates a DCE/RPC bind request.
2108 ********************************************************************/
2110 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2111 prs_struct *rpc_out,
2113 const struct ndr_syntax_id *abstract,
2114 const struct ndr_syntax_id *transfer,
2115 enum pipe_auth_type auth_type,
2116 enum dcerpc_AuthLevel auth_level)
2118 DATA_BLOB auth_info = data_blob_null;
2119 NTSTATUS ret = NT_STATUS_OK;
2121 switch (auth_type) {
2122 case PIPE_AUTH_TYPE_SCHANNEL:
2123 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2124 if (!NT_STATUS_IS_OK(ret)) {
2129 case PIPE_AUTH_TYPE_NTLMSSP:
2130 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2131 if (!NT_STATUS_IS_OK(ret)) {
2136 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2137 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2138 if (!NT_STATUS_IS_OK(ret)) {
2143 case PIPE_AUTH_TYPE_KRB5:
2144 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2145 if (!NT_STATUS_IS_OK(ret)) {
2150 case PIPE_AUTH_TYPE_NONE:
2154 /* "Can't" happen. */
2155 return NT_STATUS_INVALID_INFO_CLASS;
2158 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2167 /*******************************************************************
2168 Create and add the NTLMSSP sign/seal auth header and data.
2169 ********************************************************************/
2171 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2172 uint32 ss_padding_len,
2173 prs_struct *rpc_out)
2175 DATA_BLOB auth_info;
2177 DATA_BLOB auth_blob = data_blob_null;
2178 uint16_t data_and_pad_len =
2179 prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2181 if (!cli->auth->a_u.ntlmssp_state) {
2182 return NT_STATUS_INVALID_PARAMETER;
2185 /* marshall the dcerpc_auth with an actually empty auth_blob.
2186 * this is needed because the ntmlssp signature includes the
2188 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2189 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2190 cli->auth->auth_level,
2192 1 /* context id. */,
2195 if (!NT_STATUS_IS_OK(status)) {
2199 /* append the header */
2200 if (!prs_copy_data_in(rpc_out,
2201 (char *)auth_info.data,
2202 auth_info.length)) {
2203 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2204 (unsigned int)auth_info.length));
2205 return NT_STATUS_NO_MEMORY;
2208 switch (cli->auth->auth_level) {
2209 case DCERPC_AUTH_LEVEL_PRIVACY:
2210 /* Data portion is encrypted. */
2211 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2212 prs_get_mem_context(rpc_out),
2213 (unsigned char *)prs_data_p(rpc_out)
2217 (unsigned char *)prs_data_p(rpc_out),
2218 (size_t)prs_offset(rpc_out),
2220 if (!NT_STATUS_IS_OK(status)) {
2225 case DCERPC_AUTH_LEVEL_INTEGRITY:
2226 /* Data is signed. */
2227 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2228 prs_get_mem_context(rpc_out),
2229 (unsigned char *)prs_data_p(rpc_out)
2233 (unsigned char *)prs_data_p(rpc_out),
2234 (size_t)prs_offset(rpc_out),
2236 if (!NT_STATUS_IS_OK(status)) {
2243 smb_panic("bad auth level");
2245 return NT_STATUS_INVALID_PARAMETER;
2248 /* Finally attach the blob. */
2249 if (!prs_copy_data_in(rpc_out,
2250 (char *)auth_blob.data,
2251 auth_blob.length)) {
2252 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2253 (unsigned int)auth_info.length));
2254 return NT_STATUS_NO_MEMORY;
2257 return NT_STATUS_OK;
2260 /*******************************************************************
2261 Create and add the schannel sign/seal auth header and data.
2262 ********************************************************************/
2264 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2265 uint32 ss_padding_len,
2266 prs_struct *rpc_out)
2268 DATA_BLOB auth_info;
2269 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2270 char *data_p = prs_data_p(rpc_out) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2271 size_t data_and_pad_len = prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2276 return NT_STATUS_INVALID_PARAMETER;
2279 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2282 switch (cli->auth->auth_level) {
2283 case DCERPC_AUTH_LEVEL_PRIVACY:
2284 status = netsec_outgoing_packet(sas,
2291 case DCERPC_AUTH_LEVEL_INTEGRITY:
2292 status = netsec_outgoing_packet(sas,
2300 status = NT_STATUS_INTERNAL_ERROR;
2304 if (!NT_STATUS_IS_OK(status)) {
2305 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2306 nt_errstr(status)));
2310 if (DEBUGLEVEL >= 10) {
2311 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2314 /* Finally marshall the blob. */
2315 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2316 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2317 cli->auth->auth_level,
2319 1 /* context id. */,
2322 if (!NT_STATUS_IS_OK(status)) {
2326 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.length)) {
2327 return NT_STATUS_NO_MEMORY;
2330 return NT_STATUS_OK;
2333 /*******************************************************************
2334 Calculate how much data we're going to send in this packet, also
2335 work out any sign/seal padding length.
2336 ********************************************************************/
2338 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2342 uint32 *p_ss_padding)
2344 uint32 data_space, data_len;
2347 if ((data_left > 0) && (sys_random() % 2)) {
2348 data_left = MAX(data_left/2, 1);
2352 switch (cli->auth->auth_level) {
2353 case DCERPC_AUTH_LEVEL_NONE:
2354 case DCERPC_AUTH_LEVEL_CONNECT:
2355 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2356 data_len = MIN(data_space, data_left);
2359 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2362 case DCERPC_AUTH_LEVEL_INTEGRITY:
2363 case DCERPC_AUTH_LEVEL_PRIVACY:
2364 /* Treat the same for all authenticated rpc requests. */
2365 switch(cli->auth->auth_type) {
2366 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2367 case PIPE_AUTH_TYPE_NTLMSSP:
2368 *p_auth_len = NTLMSSP_SIG_SIZE;
2370 case PIPE_AUTH_TYPE_SCHANNEL:
2371 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2374 smb_panic("bad auth type");
2378 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2379 RPC_HDR_AUTH_LEN - *p_auth_len;
2381 data_len = MIN(data_space, data_left);
2383 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2384 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2386 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2387 data_len + *p_ss_padding + /* data plus padding. */
2388 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2392 smb_panic("bad auth level");
2398 /*******************************************************************
2400 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2401 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2402 and deals with signing/sealing details.
2403 ********************************************************************/
2405 struct rpc_api_pipe_req_state {
2406 struct event_context *ev;
2407 struct rpc_pipe_client *cli;
2410 prs_struct *req_data;
2411 uint32_t req_data_sent;
2412 prs_struct outgoing_frag;
2413 prs_struct reply_pdu;
2416 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2417 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2418 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2419 bool *is_last_frag);
2421 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2422 struct event_context *ev,
2423 struct rpc_pipe_client *cli,
2425 prs_struct *req_data)
2427 struct tevent_req *req, *subreq;
2428 struct rpc_api_pipe_req_state *state;
2432 req = tevent_req_create(mem_ctx, &state,
2433 struct rpc_api_pipe_req_state);
2439 state->op_num = op_num;
2440 state->req_data = req_data;
2441 state->req_data_sent = 0;
2442 state->call_id = get_rpc_call_id();
2444 if (cli->max_xmit_frag
2445 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2446 /* Server is screwed up ! */
2447 status = NT_STATUS_INVALID_PARAMETER;
2451 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2453 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2458 status = prepare_next_frag(state, &is_last_frag);
2459 if (!NT_STATUS_IS_OK(status)) {
2464 subreq = rpc_api_pipe_send(state, ev, state->cli,
2465 &state->outgoing_frag,
2466 DCERPC_PKT_RESPONSE);
2467 if (subreq == NULL) {
2470 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2472 subreq = rpc_write_send(
2473 state, ev, cli->transport,
2474 (uint8_t *)prs_data_p(&state->outgoing_frag),
2475 prs_offset(&state->outgoing_frag));
2476 if (subreq == NULL) {
2479 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2485 tevent_req_nterror(req, status);
2486 return tevent_req_post(req, ev);
2492 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2495 uint32_t data_sent_thistime;
2499 uint32_t ss_padding;
2501 char pad[8] = { 0, };
2503 union dcerpc_payload u;
2506 data_left = prs_offset(state->req_data) - state->req_data_sent;
2508 data_sent_thistime = calculate_data_len_tosend(
2509 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2511 if (state->req_data_sent == 0) {
2512 flags = DCERPC_PFC_FLAG_FIRST;
2515 if (data_sent_thistime == data_left) {
2516 flags |= DCERPC_PFC_FLAG_LAST;
2519 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2520 return NT_STATUS_NO_MEMORY;
2523 ZERO_STRUCT(u.request);
2525 u.request.alloc_hint = prs_offset(state->req_data);
2526 u.request.context_id = 0;
2527 u.request.opnum = state->op_num;
2529 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2536 if (!NT_STATUS_IS_OK(status)) {
2540 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
2541 * compute it right for requests */
2542 dcerpc_set_frag_length(&blob, frag_len);
2544 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2545 return NT_STATUS_NO_MEMORY;
2548 /* Copy in the data, plus any ss padding. */
2549 if (!prs_append_some_prs_data(&state->outgoing_frag,
2550 state->req_data, state->req_data_sent,
2551 data_sent_thistime)) {
2552 return NT_STATUS_NO_MEMORY;
2555 /* Copy the sign/seal padding data. */
2556 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2557 return NT_STATUS_NO_MEMORY;
2560 /* Generate any auth sign/seal and add the auth footer. */
2561 switch (state->cli->auth->auth_type) {
2562 case PIPE_AUTH_TYPE_NONE:
2563 status = NT_STATUS_OK;
2565 case PIPE_AUTH_TYPE_NTLMSSP:
2566 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2567 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2568 &state->outgoing_frag);
2570 case PIPE_AUTH_TYPE_SCHANNEL:
2571 status = add_schannel_auth_footer(state->cli, ss_padding,
2572 &state->outgoing_frag);
2575 status = NT_STATUS_INVALID_PARAMETER;
2579 state->req_data_sent += data_sent_thistime;
2580 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2585 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2587 struct tevent_req *req = tevent_req_callback_data(
2588 subreq, struct tevent_req);
2589 struct rpc_api_pipe_req_state *state = tevent_req_data(
2590 req, struct rpc_api_pipe_req_state);
2594 status = rpc_write_recv(subreq);
2595 TALLOC_FREE(subreq);
2596 if (!NT_STATUS_IS_OK(status)) {
2597 tevent_req_nterror(req, status);
2601 status = prepare_next_frag(state, &is_last_frag);
2602 if (!NT_STATUS_IS_OK(status)) {
2603 tevent_req_nterror(req, status);
2608 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2609 &state->outgoing_frag,
2610 DCERPC_PKT_RESPONSE);
2611 if (tevent_req_nomem(subreq, req)) {
2614 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2616 subreq = rpc_write_send(
2618 state->cli->transport,
2619 (uint8_t *)prs_data_p(&state->outgoing_frag),
2620 prs_offset(&state->outgoing_frag));
2621 if (tevent_req_nomem(subreq, req)) {
2624 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2629 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2631 struct tevent_req *req = tevent_req_callback_data(
2632 subreq, struct tevent_req);
2633 struct rpc_api_pipe_req_state *state = tevent_req_data(
2634 req, struct rpc_api_pipe_req_state);
2637 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2638 TALLOC_FREE(subreq);
2639 if (!NT_STATUS_IS_OK(status)) {
2640 tevent_req_nterror(req, status);
2643 tevent_req_done(req);
2646 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2647 prs_struct *reply_pdu)
2649 struct rpc_api_pipe_req_state *state = tevent_req_data(
2650 req, struct rpc_api_pipe_req_state);
2653 if (tevent_req_is_nterror(req, &status)) {
2655 * We always have to initialize to reply pdu, even if there is
2656 * none. The rpccli_* caller routines expect this.
2658 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2662 *reply_pdu = state->reply_pdu;
2663 reply_pdu->mem_ctx = mem_ctx;
2666 * Prevent state->req_pdu from being freed
2667 * when state is freed.
2669 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2670 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2672 return NT_STATUS_OK;
2676 /****************************************************************************
2677 Set the handle state.
2678 ****************************************************************************/
2680 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2681 const char *pipe_name, uint16 device_state)
2683 bool state_set = False;
2685 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2686 char *rparam = NULL;
2688 uint32 rparam_len, rdata_len;
2690 if (pipe_name == NULL)
2693 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2694 cli->fnum, pipe_name, device_state));
2696 /* create parameters: device state */
2697 SSVAL(param, 0, device_state);
2699 /* create setup parameters. */
2701 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2703 /* send the data on \PIPE\ */
2704 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2705 setup, 2, 0, /* setup, length, max */
2706 param, 2, 0, /* param, length, max */
2707 NULL, 0, 1024, /* data, length, max */
2708 &rparam, &rparam_len, /* return param, length */
2709 &rdata, &rdata_len)) /* return data, length */
2711 DEBUG(5, ("Set Handle state: return OK\n"));
2722 /****************************************************************************
2723 Check the rpc bind acknowledge response.
2724 ****************************************************************************/
2726 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2727 const struct ndr_syntax_id *transfer)
2729 struct dcerpc_ack_ctx ctx;
2731 if (r->secondary_address_size == 0) {
2732 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2735 if (r->num_results < 1 || !r->ctx_list) {
2739 ctx = r->ctx_list[0];
2741 /* check the transfer syntax */
2742 if ((ctx.syntax.if_version != transfer->if_version) ||
2743 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2744 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2748 if (r->num_results != 0x1 || ctx.result != 0) {
2749 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2750 r->num_results, ctx.reason));
2753 DEBUG(5,("check_bind_response: accepted!\n"));
2757 /*******************************************************************
2758 Creates a DCE/RPC bind authentication response.
2759 This is the packet that is sent back to the server once we
2760 have received a BIND-ACK, to finish the third leg of
2761 the authentication handshake.
2762 ********************************************************************/
2764 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2766 enum pipe_auth_type auth_type,
2767 enum dcerpc_AuthLevel auth_level,
2768 DATA_BLOB *pauth_blob,
2769 prs_struct *rpc_out)
2772 union dcerpc_payload u;
2777 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2778 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2780 0, /* auth_pad_length */
2781 1, /* auth_context_id */
2783 &u.auth3.auth_info);
2784 if (!NT_STATUS_IS_OK(status)) {
2788 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2790 DCERPC_PFC_FLAG_FIRST |
2791 DCERPC_PFC_FLAG_LAST,
2796 if (!NT_STATUS_IS_OK(status)) {
2797 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2801 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2802 return NT_STATUS_NO_MEMORY;
2805 return NT_STATUS_OK;
2808 /*******************************************************************
2809 Creates a DCE/RPC bind alter context authentication request which
2810 may contain a spnego auth blobl
2811 ********************************************************************/
2813 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2814 const struct ndr_syntax_id *abstract,
2815 const struct ndr_syntax_id *transfer,
2816 enum dcerpc_AuthLevel auth_level,
2817 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2818 prs_struct *rpc_out)
2820 DATA_BLOB auth_info;
2823 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2824 DCERPC_AUTH_TYPE_SPNEGO,
2826 0, /* auth_pad_length */
2827 1, /* auth_context_id */
2830 if (!NT_STATUS_IS_OK(status)) {
2835 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2841 if (!NT_STATUS_IS_OK(status)) {
2848 /****************************************************************************
2850 ****************************************************************************/
2852 struct rpc_pipe_bind_state {
2853 struct event_context *ev;
2854 struct rpc_pipe_client *cli;
2856 uint32_t rpc_call_id;
2859 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2860 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2861 struct rpc_pipe_bind_state *state,
2862 struct ncacn_packet *r,
2863 prs_struct *reply_pdu);
2864 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2865 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2866 struct rpc_pipe_bind_state *state,
2867 struct ncacn_packet *r,
2868 prs_struct *reply_pdu);
2869 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2871 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2872 struct event_context *ev,
2873 struct rpc_pipe_client *cli,
2874 struct cli_pipe_auth_data *auth)
2876 struct tevent_req *req, *subreq;
2877 struct rpc_pipe_bind_state *state;
2880 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2885 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2886 rpccli_pipe_txt(talloc_tos(), cli),
2887 (unsigned int)auth->auth_type,
2888 (unsigned int)auth->auth_level ));
2892 state->rpc_call_id = get_rpc_call_id();
2894 prs_init_empty(&state->rpc_out, state, MARSHALL);
2896 cli->auth = talloc_move(cli, &auth);
2898 /* Marshall the outgoing data. */
2899 status = create_rpc_bind_req(cli, &state->rpc_out,
2901 &cli->abstract_syntax,
2902 &cli->transfer_syntax,
2903 cli->auth->auth_type,
2904 cli->auth->auth_level);
2906 if (!NT_STATUS_IS_OK(status)) {
2910 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2911 DCERPC_PKT_BIND_ACK);
2912 if (subreq == NULL) {
2915 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2919 tevent_req_nterror(req, status);
2920 return tevent_req_post(req, ev);
2926 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2928 struct tevent_req *req = tevent_req_callback_data(
2929 subreq, struct tevent_req);
2930 struct rpc_pipe_bind_state *state = tevent_req_data(
2931 req, struct rpc_pipe_bind_state);
2932 prs_struct reply_pdu;
2934 struct ncacn_packet r;
2937 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2938 TALLOC_FREE(subreq);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2941 rpccli_pipe_txt(talloc_tos(), state->cli),
2942 nt_errstr(status)));
2943 tevent_req_nterror(req, status);
2947 blob = data_blob_const(prs_data_p(&reply_pdu),
2948 prs_data_size(&reply_pdu));
2950 status = dcerpc_pull_ncacn_packet(talloc_tos(), &blob, &r);
2951 if (!NT_STATUS_IS_OK(status)) {
2952 tevent_req_nterror(req, status);
2956 if (!check_bind_response(&r.u.bind_ack, &state->cli->transfer_syntax)) {
2957 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2958 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2962 state->cli->max_xmit_frag = r.u.bind_ack.max_xmit_frag;
2963 state->cli->max_recv_frag = r.u.bind_ack.max_recv_frag;
2966 * For authenticated binds we may need to do 3 or 4 leg binds.
2969 switch(state->cli->auth->auth_type) {
2971 case PIPE_AUTH_TYPE_NONE:
2972 case PIPE_AUTH_TYPE_SCHANNEL:
2973 /* Bind complete. */
2974 tevent_req_done(req);
2977 case PIPE_AUTH_TYPE_NTLMSSP:
2978 /* Need to send AUTH3 packet - no reply. */
2979 status = rpc_finish_auth3_bind_send(req, state, &r,
2981 if (!NT_STATUS_IS_OK(status)) {
2982 tevent_req_nterror(req, status);
2986 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2987 /* Need to send alter context request and reply. */
2988 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &r,
2990 if (!NT_STATUS_IS_OK(status)) {
2991 tevent_req_nterror(req, status);
2995 case PIPE_AUTH_TYPE_KRB5:
2999 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
3000 (unsigned int)state->cli->auth->auth_type));
3001 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3005 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
3006 struct rpc_pipe_bind_state *state,
3007 struct ncacn_packet *r,
3008 prs_struct *reply_pdu)
3010 DATA_BLOB server_response = data_blob_null;
3011 DATA_BLOB client_reply = data_blob_null;
3012 struct rpc_hdr_auth_info hdr_auth;
3013 struct tevent_req *subreq;
3016 if ((r->auth_length == 0)
3017 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3018 return NT_STATUS_INVALID_PARAMETER;
3021 if (!prs_set_offset(
3023 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3024 return NT_STATUS_INVALID_PARAMETER;
3027 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3028 return NT_STATUS_INVALID_PARAMETER;
3031 /* TODO - check auth_type/auth_level match. */
3033 server_response = data_blob_talloc(talloc_tos(), NULL, r->auth_length);
3034 prs_copy_data_out((char *)server_response.data, reply_pdu,
3037 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3038 server_response, &client_reply);
3040 if (!NT_STATUS_IS_OK(status)) {
3041 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
3042 "blob failed: %s.\n", nt_errstr(status)));
3046 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
3048 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
3049 state->cli->auth->auth_type,
3050 state->cli->auth->auth_level,
3051 &client_reply, &state->rpc_out);
3052 data_blob_free(&client_reply);
3054 if (!NT_STATUS_IS_OK(status)) {
3058 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3059 (uint8_t *)prs_data_p(&state->rpc_out),
3060 prs_offset(&state->rpc_out));
3061 if (subreq == NULL) {
3062 return NT_STATUS_NO_MEMORY;
3064 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3065 return NT_STATUS_OK;
3068 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3070 struct tevent_req *req = tevent_req_callback_data(
3071 subreq, struct tevent_req);
3074 status = rpc_write_recv(subreq);
3075 TALLOC_FREE(subreq);
3076 if (!NT_STATUS_IS_OK(status)) {
3077 tevent_req_nterror(req, status);
3080 tevent_req_done(req);
3083 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3084 struct rpc_pipe_bind_state *state,
3085 struct ncacn_packet *r,
3088 DATA_BLOB server_ntlm_response = data_blob_null;
3089 DATA_BLOB client_reply = data_blob_null;
3090 DATA_BLOB tmp_blob = data_blob_null;
3091 struct dcerpc_auth auth_info;
3092 DATA_BLOB auth_blob;
3093 struct tevent_req *subreq;
3096 if ((r->auth_length == 0)
3097 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3098 return NT_STATUS_INVALID_PARAMETER;
3101 /* Process the returned NTLMSSP blob first. */
3102 if (!prs_set_offset(
3104 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3105 return NT_STATUS_INVALID_PARAMETER;
3108 auth_blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in),
3109 prs_data_size(rpc_in) - prs_offset(rpc_in));
3111 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
3118 * The server might give us back two challenges - tmp_blob is for the
3121 if (!spnego_parse_challenge(auth_info.credentials,
3122 &server_ntlm_response, &tmp_blob)) {
3123 data_blob_free(&server_ntlm_response);
3124 data_blob_free(&tmp_blob);
3125 return NT_STATUS_INVALID_PARAMETER;
3128 /* We're finished with the server spnego response and the tmp_blob. */
3129 data_blob_free(&tmp_blob);
3131 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3132 server_ntlm_response, &client_reply);
3134 /* Finished with the server_ntlm response */
3135 data_blob_free(&server_ntlm_response);
3137 if (!NT_STATUS_IS_OK(status)) {
3138 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3139 "using server blob failed.\n"));
3140 data_blob_free(&client_reply);
3144 /* SPNEGO wrap the client reply. */
3145 tmp_blob = spnego_gen_auth(client_reply);
3146 data_blob_free(&client_reply);
3147 client_reply = tmp_blob;
3148 tmp_blob = data_blob_null;
3150 /* Now prepare the alter context pdu. */
3151 prs_init_empty(&state->rpc_out, state, MARSHALL);
3153 status = create_rpc_alter_context(state->rpc_call_id,
3154 &state->cli->abstract_syntax,
3155 &state->cli->transfer_syntax,
3156 state->cli->auth->auth_level,
3159 data_blob_free(&client_reply);
3161 if (!NT_STATUS_IS_OK(status)) {
3165 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3166 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3167 if (subreq == NULL) {
3168 return NT_STATUS_NO_MEMORY;
3170 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3171 return NT_STATUS_OK;
3174 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3176 struct tevent_req *req = tevent_req_callback_data(
3177 subreq, struct tevent_req);
3178 struct rpc_pipe_bind_state *state = tevent_req_data(
3179 req, struct rpc_pipe_bind_state);
3180 DATA_BLOB server_spnego_response = data_blob_null;
3181 DATA_BLOB tmp_blob = data_blob_null;
3182 prs_struct reply_pdu;
3183 struct ncacn_packet_header hdr;
3184 struct rpc_hdr_auth_info hdr_auth;
3187 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3188 TALLOC_FREE(subreq);
3189 if (!NT_STATUS_IS_OK(status)) {
3190 tevent_req_nterror(req, status);
3194 status = parse_rpc_header(state->cli, &hdr, &reply_pdu);
3195 if (!NT_STATUS_IS_OK(status)) {
3196 tevent_req_nterror(req, status);
3200 if (!prs_set_offset(
3202 hdr.frag_length - hdr.auth_length - RPC_HDR_AUTH_LEN)) {
3203 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3207 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3208 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3212 server_spnego_response = data_blob(NULL, hdr.auth_length);
3213 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3216 /* Check we got a valid auth response. */
3217 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3218 OID_NTLMSSP, &tmp_blob)) {
3219 data_blob_free(&server_spnego_response);
3220 data_blob_free(&tmp_blob);
3221 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3225 data_blob_free(&server_spnego_response);
3226 data_blob_free(&tmp_blob);
3228 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3229 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3230 tevent_req_done(req);
3233 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3235 return tevent_req_simple_recv_ntstatus(req);
3238 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3239 struct cli_pipe_auth_data *auth)
3241 TALLOC_CTX *frame = talloc_stackframe();
3242 struct event_context *ev;
3243 struct tevent_req *req;
3244 NTSTATUS status = NT_STATUS_OK;
3246 ev = event_context_init(frame);
3248 status = NT_STATUS_NO_MEMORY;
3252 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3254 status = NT_STATUS_NO_MEMORY;
3258 if (!tevent_req_poll(req, ev)) {
3259 status = map_nt_error_from_unix(errno);
3263 status = rpc_pipe_bind_recv(req);
3269 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3271 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3272 unsigned int timeout)
3276 if (rpc_cli->transport == NULL) {
3277 return RPCCLI_DEFAULT_TIMEOUT;
3280 if (rpc_cli->transport->set_timeout == NULL) {
3281 return RPCCLI_DEFAULT_TIMEOUT;
3284 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3286 return RPCCLI_DEFAULT_TIMEOUT;
3292 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3294 if (rpc_cli == NULL) {
3298 if (rpc_cli->transport == NULL) {
3302 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3305 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3307 struct cli_state *cli;
3309 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3310 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3311 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3315 cli = rpc_pipe_np_smb_conn(rpc_cli);
3319 E_md4hash(cli->password ? cli->password : "", nt_hash);
3323 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3324 struct cli_pipe_auth_data **presult)
3326 struct cli_pipe_auth_data *result;
3328 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3329 if (result == NULL) {
3330 return NT_STATUS_NO_MEMORY;
3333 result->auth_type = PIPE_AUTH_TYPE_NONE;
3334 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3336 result->user_name = talloc_strdup(result, "");
3337 result->domain = talloc_strdup(result, "");
3338 if ((result->user_name == NULL) || (result->domain == NULL)) {
3339 TALLOC_FREE(result);
3340 return NT_STATUS_NO_MEMORY;
3344 return NT_STATUS_OK;
3347 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3349 ntlmssp_end(&auth->a_u.ntlmssp_state);
3353 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3354 enum pipe_auth_type auth_type,
3355 enum dcerpc_AuthLevel auth_level,
3357 const char *username,
3358 const char *password,
3359 struct cli_pipe_auth_data **presult)
3361 struct cli_pipe_auth_data *result;
3364 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3365 if (result == NULL) {
3366 return NT_STATUS_NO_MEMORY;
3369 result->auth_type = auth_type;
3370 result->auth_level = auth_level;
3372 result->user_name = talloc_strdup(result, username);
3373 result->domain = talloc_strdup(result, domain);
3374 if ((result->user_name == NULL) || (result->domain == NULL)) {
3375 status = NT_STATUS_NO_MEMORY;
3379 status = ntlmssp_client_start(NULL,
3382 lp_client_ntlmv2_auth(),
3383 &result->a_u.ntlmssp_state);
3384 if (!NT_STATUS_IS_OK(status)) {
3388 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3390 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3391 if (!NT_STATUS_IS_OK(status)) {
3395 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3396 if (!NT_STATUS_IS_OK(status)) {
3400 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3401 if (!NT_STATUS_IS_OK(status)) {
3406 * Turn off sign+seal to allow selected auth level to turn it back on.
3408 result->a_u.ntlmssp_state->neg_flags &=
3409 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3411 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3412 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3413 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3414 result->a_u.ntlmssp_state->neg_flags
3415 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3419 return NT_STATUS_OK;
3422 TALLOC_FREE(result);
3426 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3427 enum dcerpc_AuthLevel auth_level,
3428 struct netlogon_creds_CredentialState *creds,
3429 struct cli_pipe_auth_data **presult)
3431 struct cli_pipe_auth_data *result;
3433 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3434 if (result == NULL) {
3435 return NT_STATUS_NO_MEMORY;
3438 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3439 result->auth_level = auth_level;
3441 result->user_name = talloc_strdup(result, "");
3442 result->domain = talloc_strdup(result, domain);
3443 if ((result->user_name == NULL) || (result->domain == NULL)) {
3447 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3448 if (result->a_u.schannel_auth == NULL) {
3452 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3453 result->a_u.schannel_auth->seq_num = 0;
3454 result->a_u.schannel_auth->initiator = true;
3455 result->a_u.schannel_auth->creds = creds;
3458 return NT_STATUS_OK;
3461 TALLOC_FREE(result);
3462 return NT_STATUS_NO_MEMORY;
3466 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3468 data_blob_free(&auth->session_key);
3473 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3474 enum dcerpc_AuthLevel auth_level,
3475 const char *service_princ,
3476 const char *username,
3477 const char *password,
3478 struct cli_pipe_auth_data **presult)
3481 struct cli_pipe_auth_data *result;
3483 if ((username != NULL) && (password != NULL)) {
3484 int ret = kerberos_kinit_password(username, password, 0, NULL);
3486 return NT_STATUS_ACCESS_DENIED;
3490 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3491 if (result == NULL) {
3492 return NT_STATUS_NO_MEMORY;
3495 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3496 result->auth_level = auth_level;
3499 * Username / domain need fixing!
3501 result->user_name = talloc_strdup(result, "");
3502 result->domain = talloc_strdup(result, "");
3503 if ((result->user_name == NULL) || (result->domain == NULL)) {
3507 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3508 result, struct kerberos_auth_struct);
3509 if (result->a_u.kerberos_auth == NULL) {
3512 talloc_set_destructor(result->a_u.kerberos_auth,
3513 cli_auth_kerberos_data_destructor);
3515 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3516 result, service_princ);
3517 if (result->a_u.kerberos_auth->service_principal == NULL) {
3522 return NT_STATUS_OK;
3525 TALLOC_FREE(result);
3526 return NT_STATUS_NO_MEMORY;
3528 return NT_STATUS_NOT_SUPPORTED;
3533 * Create an rpc pipe client struct, connecting to a tcp port.
3535 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3537 const struct ndr_syntax_id *abstract_syntax,
3538 struct rpc_pipe_client **presult)
3540 struct rpc_pipe_client *result;
3541 struct sockaddr_storage addr;
3545 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3546 if (result == NULL) {
3547 return NT_STATUS_NO_MEMORY;
3550 result->abstract_syntax = *abstract_syntax;
3551 result->transfer_syntax = ndr_transfer_syntax;
3552 result->dispatch = cli_do_rpc_ndr;
3553 result->dispatch_send = cli_do_rpc_ndr_send;
3554 result->dispatch_recv = cli_do_rpc_ndr_recv;
3556 result->desthost = talloc_strdup(result, host);
3557 result->srv_name_slash = talloc_asprintf_strupper_m(
3558 result, "\\\\%s", result->desthost);
3559 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3560 status = NT_STATUS_NO_MEMORY;
3564 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3565 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3567 if (!resolve_name(host, &addr, 0, false)) {
3568 status = NT_STATUS_NOT_FOUND;
3572 status = open_socket_out(&addr, port, 60, &fd);
3573 if (!NT_STATUS_IS_OK(status)) {
3576 set_socket_options(fd, lp_socket_options());
3578 status = rpc_transport_sock_init(result, fd, &result->transport);
3579 if (!NT_STATUS_IS_OK(status)) {
3584 result->transport->transport = NCACN_IP_TCP;
3587 return NT_STATUS_OK;
3590 TALLOC_FREE(result);
3595 * Determine the tcp port on which a dcerpc interface is listening
3596 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3599 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3600 const struct ndr_syntax_id *abstract_syntax,
3604 struct rpc_pipe_client *epm_pipe = NULL;
3605 struct cli_pipe_auth_data *auth = NULL;
3606 struct dcerpc_binding *map_binding = NULL;
3607 struct dcerpc_binding *res_binding = NULL;
3608 struct epm_twr_t *map_tower = NULL;
3609 struct epm_twr_t *res_towers = NULL;
3610 struct policy_handle *entry_handle = NULL;
3611 uint32_t num_towers = 0;
3612 uint32_t max_towers = 1;
3613 struct epm_twr_p_t towers;
3614 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3616 if (pport == NULL) {
3617 status = NT_STATUS_INVALID_PARAMETER;
3621 /* open the connection to the endpoint mapper */
3622 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3623 &ndr_table_epmapper.syntax_id,
3626 if (!NT_STATUS_IS_OK(status)) {
3630 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3631 if (!NT_STATUS_IS_OK(status)) {
3635 status = rpc_pipe_bind(epm_pipe, auth);
3636 if (!NT_STATUS_IS_OK(status)) {
3640 /* create tower for asking the epmapper */
3642 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3643 if (map_binding == NULL) {
3644 status = NT_STATUS_NO_MEMORY;
3648 map_binding->transport = NCACN_IP_TCP;
3649 map_binding->object = *abstract_syntax;
3650 map_binding->host = host; /* needed? */
3651 map_binding->endpoint = "0"; /* correct? needed? */
3653 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3654 if (map_tower == NULL) {
3655 status = NT_STATUS_NO_MEMORY;
3659 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3660 &(map_tower->tower));
3661 if (!NT_STATUS_IS_OK(status)) {
3665 /* allocate further parameters for the epm_Map call */
3667 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3668 if (res_towers == NULL) {
3669 status = NT_STATUS_NO_MEMORY;
3672 towers.twr = res_towers;
3674 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3675 if (entry_handle == NULL) {
3676 status = NT_STATUS_NO_MEMORY;
3680 /* ask the endpoint mapper for the port */
3682 status = rpccli_epm_Map(epm_pipe,
3684 CONST_DISCARD(struct GUID *,
3685 &(abstract_syntax->uuid)),
3692 if (!NT_STATUS_IS_OK(status)) {
3696 if (num_towers != 1) {
3697 status = NT_STATUS_UNSUCCESSFUL;
3701 /* extract the port from the answer */
3703 status = dcerpc_binding_from_tower(tmp_ctx,
3704 &(towers.twr->tower),
3706 if (!NT_STATUS_IS_OK(status)) {
3710 /* are further checks here necessary? */
3711 if (res_binding->transport != NCACN_IP_TCP) {
3712 status = NT_STATUS_UNSUCCESSFUL;
3716 *pport = (uint16_t)atoi(res_binding->endpoint);
3719 TALLOC_FREE(tmp_ctx);
3724 * Create a rpc pipe client struct, connecting to a host via tcp.
3725 * The port is determined by asking the endpoint mapper on the given
3728 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3729 const struct ndr_syntax_id *abstract_syntax,
3730 struct rpc_pipe_client **presult)
3735 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3736 if (!NT_STATUS_IS_OK(status)) {
3740 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3741 abstract_syntax, presult);
3744 /********************************************************************
3745 Create a rpc pipe client struct, connecting to a unix domain socket
3746 ********************************************************************/
3747 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3748 const struct ndr_syntax_id *abstract_syntax,
3749 struct rpc_pipe_client **presult)
3751 struct rpc_pipe_client *result;
3752 struct sockaddr_un addr;
3756 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3757 if (result == NULL) {
3758 return NT_STATUS_NO_MEMORY;
3761 result->abstract_syntax = *abstract_syntax;
3762 result->transfer_syntax = ndr_transfer_syntax;
3763 result->dispatch = cli_do_rpc_ndr;
3764 result->dispatch_send = cli_do_rpc_ndr_send;
3765 result->dispatch_recv = cli_do_rpc_ndr_recv;
3767 result->desthost = get_myname(result);
3768 result->srv_name_slash = talloc_asprintf_strupper_m(
3769 result, "\\\\%s", result->desthost);
3770 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3771 status = NT_STATUS_NO_MEMORY;
3775 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3776 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3778 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3780 status = map_nt_error_from_unix(errno);
3785 addr.sun_family = AF_UNIX;
3786 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3788 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3789 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3792 return map_nt_error_from_unix(errno);
3795 status = rpc_transport_sock_init(result, fd, &result->transport);
3796 if (!NT_STATUS_IS_OK(status)) {
3801 result->transport->transport = NCALRPC;
3804 return NT_STATUS_OK;
3807 TALLOC_FREE(result);
3811 struct rpc_pipe_client_np_ref {
3812 struct cli_state *cli;
3813 struct rpc_pipe_client *pipe;
3816 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3818 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3822 /****************************************************************************
3823 Open a named pipe over SMB to a remote server.
3825 * CAVEAT CALLER OF THIS FUNCTION:
3826 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3827 * so be sure that this function is called AFTER any structure (vs pointer)
3828 * assignment of the cli. In particular, libsmbclient does structure
3829 * assignments of cli, which invalidates the data in the returned
3830 * rpc_pipe_client if this function is called before the structure assignment
3833 ****************************************************************************/
3835 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3836 const struct ndr_syntax_id *abstract_syntax,
3837 struct rpc_pipe_client **presult)
3839 struct rpc_pipe_client *result;
3841 struct rpc_pipe_client_np_ref *np_ref;
3843 /* sanity check to protect against crashes */
3846 return NT_STATUS_INVALID_HANDLE;
3849 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3850 if (result == NULL) {
3851 return NT_STATUS_NO_MEMORY;
3854 result->abstract_syntax = *abstract_syntax;
3855 result->transfer_syntax = ndr_transfer_syntax;
3856 result->dispatch = cli_do_rpc_ndr;
3857 result->dispatch_send = cli_do_rpc_ndr_send;
3858 result->dispatch_recv = cli_do_rpc_ndr_recv;
3859 result->desthost = talloc_strdup(result, cli->desthost);
3860 result->srv_name_slash = talloc_asprintf_strupper_m(
3861 result, "\\\\%s", result->desthost);
3863 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3864 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3866 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3867 TALLOC_FREE(result);
3868 return NT_STATUS_NO_MEMORY;
3871 status = rpc_transport_np_init(result, cli, abstract_syntax,
3872 &result->transport);
3873 if (!NT_STATUS_IS_OK(status)) {
3874 TALLOC_FREE(result);
3878 result->transport->transport = NCACN_NP;
3880 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3881 if (np_ref == NULL) {
3882 TALLOC_FREE(result);
3883 return NT_STATUS_NO_MEMORY;
3886 np_ref->pipe = result;
3888 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3889 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3892 return NT_STATUS_OK;
3895 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3896 struct rpc_cli_smbd_conn *conn,
3897 const struct ndr_syntax_id *syntax,
3898 struct rpc_pipe_client **presult)
3900 struct rpc_pipe_client *result;
3901 struct cli_pipe_auth_data *auth;
3904 result = talloc(mem_ctx, struct rpc_pipe_client);
3905 if (result == NULL) {
3906 return NT_STATUS_NO_MEMORY;
3908 result->abstract_syntax = *syntax;
3909 result->transfer_syntax = ndr_transfer_syntax;
3910 result->dispatch = cli_do_rpc_ndr;
3911 result->dispatch_send = cli_do_rpc_ndr_send;
3912 result->dispatch_recv = cli_do_rpc_ndr_recv;
3913 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3914 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3916 result->desthost = talloc_strdup(result, global_myname());
3917 result->srv_name_slash = talloc_asprintf_strupper_m(
3918 result, "\\\\%s", global_myname());
3919 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3920 TALLOC_FREE(result);
3921 return NT_STATUS_NO_MEMORY;
3924 status = rpc_transport_smbd_init(result, conn, syntax,
3925 &result->transport);
3926 if (!NT_STATUS_IS_OK(status)) {
3927 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3928 nt_errstr(status)));
3929 TALLOC_FREE(result);
3933 status = rpccli_anon_bind_data(result, &auth);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3936 nt_errstr(status)));
3937 TALLOC_FREE(result);
3941 status = rpc_pipe_bind(result, auth);
3942 if (!NT_STATUS_IS_OK(status)) {
3943 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3944 TALLOC_FREE(result);
3948 result->transport->transport = NCACN_INTERNAL;
3951 return NT_STATUS_OK;
3954 /****************************************************************************
3955 Open a pipe to a remote server.
3956 ****************************************************************************/
3958 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3959 enum dcerpc_transport_t transport,
3960 const struct ndr_syntax_id *interface,
3961 struct rpc_pipe_client **presult)
3963 switch (transport) {
3965 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3968 return rpc_pipe_open_np(cli, interface, presult);
3970 return NT_STATUS_NOT_IMPLEMENTED;
3974 /****************************************************************************
3975 Open a named pipe to an SMB server and bind anonymously.
3976 ****************************************************************************/
3978 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3979 enum dcerpc_transport_t transport,
3980 const struct ndr_syntax_id *interface,
3981 struct rpc_pipe_client **presult)
3983 struct rpc_pipe_client *result;
3984 struct cli_pipe_auth_data *auth;
3987 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3988 if (!NT_STATUS_IS_OK(status)) {
3992 status = rpccli_anon_bind_data(result, &auth);
3993 if (!NT_STATUS_IS_OK(status)) {
3994 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3995 nt_errstr(status)));
3996 TALLOC_FREE(result);
4001 * This is a bit of an abstraction violation due to the fact that an
4002 * anonymous bind on an authenticated SMB inherits the user/domain
4003 * from the enclosing SMB creds
4006 TALLOC_FREE(auth->user_name);
4007 TALLOC_FREE(auth->domain);
4009 auth->user_name = talloc_strdup(auth, cli->user_name);
4010 auth->domain = talloc_strdup(auth, cli->domain);
4011 auth->user_session_key = data_blob_talloc(auth,
4012 cli->user_session_key.data,
4013 cli->user_session_key.length);
4015 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
4016 TALLOC_FREE(result);
4017 return NT_STATUS_NO_MEMORY;
4020 status = rpc_pipe_bind(result, auth);
4021 if (!NT_STATUS_IS_OK(status)) {
4023 if (ndr_syntax_id_equal(interface,
4024 &ndr_table_dssetup.syntax_id)) {
4025 /* non AD domains just don't have this pipe, avoid
4026 * level 0 statement in that case - gd */
4029 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
4030 "%s failed with error %s\n",
4031 get_pipe_name_from_syntax(talloc_tos(), interface),
4032 nt_errstr(status) ));
4033 TALLOC_FREE(result);
4037 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
4038 "%s and bound anonymously.\n",
4039 get_pipe_name_from_syntax(talloc_tos(), interface),
4043 return NT_STATUS_OK;
4046 /****************************************************************************
4047 ****************************************************************************/
4049 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4050 const struct ndr_syntax_id *interface,
4051 struct rpc_pipe_client **presult)
4053 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4054 interface, presult);
4057 /****************************************************************************
4058 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4059 ****************************************************************************/
4061 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4062 const struct ndr_syntax_id *interface,
4063 enum dcerpc_transport_t transport,
4064 enum pipe_auth_type auth_type,
4065 enum dcerpc_AuthLevel auth_level,
4067 const char *username,
4068 const char *password,
4069 struct rpc_pipe_client **presult)
4071 struct rpc_pipe_client *result;
4072 struct cli_pipe_auth_data *auth;
4075 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4076 if (!NT_STATUS_IS_OK(status)) {
4080 status = rpccli_ntlmssp_bind_data(
4081 result, auth_type, auth_level, domain, username,
4083 if (!NT_STATUS_IS_OK(status)) {
4084 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4085 nt_errstr(status)));
4089 status = rpc_pipe_bind(result, auth);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4092 nt_errstr(status) ));
4096 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4097 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4098 get_pipe_name_from_syntax(talloc_tos(), interface),
4099 cli->desthost, domain, username ));
4102 return NT_STATUS_OK;
4106 TALLOC_FREE(result);
4110 /****************************************************************************
4112 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4113 ****************************************************************************/
4115 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4116 const struct ndr_syntax_id *interface,
4117 enum dcerpc_transport_t transport,
4118 enum dcerpc_AuthLevel auth_level,
4120 const char *username,
4121 const char *password,
4122 struct rpc_pipe_client **presult)
4124 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4127 PIPE_AUTH_TYPE_NTLMSSP,
4135 /****************************************************************************
4137 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4138 ****************************************************************************/
4140 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4141 const struct ndr_syntax_id *interface,
4142 enum dcerpc_transport_t transport,
4143 enum dcerpc_AuthLevel auth_level,
4145 const char *username,
4146 const char *password,
4147 struct rpc_pipe_client **presult)
4149 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4152 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4160 /****************************************************************************
4161 Get a the schannel session key out of an already opened netlogon pipe.
4162 ****************************************************************************/
4163 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4164 struct cli_state *cli,
4168 enum netr_SchannelType sec_chan_type = 0;
4169 unsigned char machine_pwd[16];
4170 const char *machine_account;
4173 /* Get the machine account credentials from secrets.tdb. */
4174 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4177 DEBUG(0, ("get_schannel_session_key: could not fetch "
4178 "trust account password for domain '%s'\n",
4180 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4183 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4184 cli->desthost, /* server name */
4185 domain, /* domain */
4186 global_myname(), /* client name */
4187 machine_account, /* machine account name */
4192 if (!NT_STATUS_IS_OK(status)) {
4193 DEBUG(3, ("get_schannel_session_key_common: "
4194 "rpccli_netlogon_setup_creds failed with result %s "
4195 "to server %s, domain %s, machine account %s.\n",
4196 nt_errstr(status), cli->desthost, domain,
4201 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4202 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4204 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4207 return NT_STATUS_OK;;
4210 /****************************************************************************
4211 Open a netlogon pipe and get the schannel session key.
4212 Now exposed to external callers.
4213 ****************************************************************************/
4216 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4219 struct rpc_pipe_client **presult)
4221 struct rpc_pipe_client *netlogon_pipe = NULL;
4224 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4226 if (!NT_STATUS_IS_OK(status)) {
4230 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4232 if (!NT_STATUS_IS_OK(status)) {
4233 TALLOC_FREE(netlogon_pipe);
4237 *presult = netlogon_pipe;
4238 return NT_STATUS_OK;
4241 /****************************************************************************
4243 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4244 using session_key. sign and seal.
4246 The *pdc will be stolen onto this new pipe
4247 ****************************************************************************/
4249 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4250 const struct ndr_syntax_id *interface,
4251 enum dcerpc_transport_t transport,
4252 enum dcerpc_AuthLevel auth_level,
4254 struct netlogon_creds_CredentialState **pdc,
4255 struct rpc_pipe_client **presult)
4257 struct rpc_pipe_client *result;
4258 struct cli_pipe_auth_data *auth;
4261 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4262 if (!NT_STATUS_IS_OK(status)) {
4266 status = rpccli_schannel_bind_data(result, domain, auth_level,
4268 if (!NT_STATUS_IS_OK(status)) {
4269 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4270 nt_errstr(status)));
4271 TALLOC_FREE(result);
4275 status = rpc_pipe_bind(result, auth);
4276 if (!NT_STATUS_IS_OK(status)) {
4277 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4278 "cli_rpc_pipe_bind failed with error %s\n",
4279 nt_errstr(status) ));
4280 TALLOC_FREE(result);
4285 * The credentials on a new netlogon pipe are the ones we are passed
4286 * in - reference them in
4288 result->dc = talloc_move(result, pdc);
4290 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4291 "for domain %s and bound using schannel.\n",
4292 get_pipe_name_from_syntax(talloc_tos(), interface),
4293 cli->desthost, domain ));
4296 return NT_STATUS_OK;
4299 /****************************************************************************
4300 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4301 Fetch the session key ourselves using a temporary netlogon pipe. This
4302 version uses an ntlmssp auth bound netlogon pipe to get the key.
4303 ****************************************************************************/
4305 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4307 const char *username,
4308 const char *password,
4310 struct rpc_pipe_client **presult)
4312 struct rpc_pipe_client *netlogon_pipe = NULL;
4315 status = cli_rpc_pipe_open_spnego_ntlmssp(
4316 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4317 DCERPC_AUTH_LEVEL_PRIVACY,
4318 domain, username, password, &netlogon_pipe);
4319 if (!NT_STATUS_IS_OK(status)) {
4323 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4325 if (!NT_STATUS_IS_OK(status)) {
4326 TALLOC_FREE(netlogon_pipe);
4330 *presult = netlogon_pipe;
4331 return NT_STATUS_OK;
4334 /****************************************************************************
4335 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4336 Fetch the session key ourselves using a temporary netlogon pipe. This version
4337 uses an ntlmssp bind to get the session key.
4338 ****************************************************************************/
4340 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4341 const struct ndr_syntax_id *interface,
4342 enum dcerpc_transport_t transport,
4343 enum dcerpc_AuthLevel auth_level,
4345 const char *username,
4346 const char *password,
4347 struct rpc_pipe_client **presult)
4349 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4350 struct rpc_pipe_client *netlogon_pipe = NULL;
4351 struct rpc_pipe_client *result = NULL;
4354 status = get_schannel_session_key_auth_ntlmssp(
4355 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4356 if (!NT_STATUS_IS_OK(status)) {
4357 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4358 "key from server %s for domain %s.\n",
4359 cli->desthost, domain ));
4363 status = cli_rpc_pipe_open_schannel_with_key(
4364 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4367 /* Now we've bound using the session key we can close the netlog pipe. */
4368 TALLOC_FREE(netlogon_pipe);
4370 if (NT_STATUS_IS_OK(status)) {
4376 /****************************************************************************
4377 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4378 Fetch the session key ourselves using a temporary netlogon pipe.
4379 ****************************************************************************/
4381 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4382 const struct ndr_syntax_id *interface,
4383 enum dcerpc_transport_t transport,
4384 enum dcerpc_AuthLevel auth_level,
4386 struct rpc_pipe_client **presult)
4388 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4389 struct rpc_pipe_client *netlogon_pipe = NULL;
4390 struct rpc_pipe_client *result = NULL;
4393 status = get_schannel_session_key(cli, domain, &neg_flags,
4395 if (!NT_STATUS_IS_OK(status)) {
4396 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4397 "key from server %s for domain %s.\n",
4398 cli->desthost, domain ));
4402 status = cli_rpc_pipe_open_schannel_with_key(
4403 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4406 /* Now we've bound using the session key we can close the netlog pipe. */
4407 TALLOC_FREE(netlogon_pipe);
4409 if (NT_STATUS_IS_OK(status)) {
4416 /****************************************************************************
4417 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4418 The idea is this can be called with service_princ, username and password all
4419 NULL so long as the caller has a TGT.
4420 ****************************************************************************/
4422 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4423 const struct ndr_syntax_id *interface,
4424 enum dcerpc_AuthLevel auth_level,
4425 const char *service_princ,
4426 const char *username,
4427 const char *password,
4428 struct rpc_pipe_client **presult)
4431 struct rpc_pipe_client *result;
4432 struct cli_pipe_auth_data *auth;
4435 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4436 if (!NT_STATUS_IS_OK(status)) {
4440 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4441 username, password, &auth);
4442 if (!NT_STATUS_IS_OK(status)) {
4443 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4444 nt_errstr(status)));
4445 TALLOC_FREE(result);
4449 status = rpc_pipe_bind(result, auth);
4450 if (!NT_STATUS_IS_OK(status)) {
4451 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4452 "with error %s\n", nt_errstr(status)));
4453 TALLOC_FREE(result);
4458 return NT_STATUS_OK;
4460 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4461 return NT_STATUS_NOT_IMPLEMENTED;
4465 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4466 struct rpc_pipe_client *cli,
4467 DATA_BLOB *session_key)
4469 if (!session_key || !cli) {
4470 return NT_STATUS_INVALID_PARAMETER;
4474 return NT_STATUS_INVALID_PARAMETER;
4477 switch (cli->auth->auth_type) {
4478 case PIPE_AUTH_TYPE_SCHANNEL:
4479 *session_key = data_blob_talloc(mem_ctx,
4480 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4482 case PIPE_AUTH_TYPE_NTLMSSP:
4483 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4484 *session_key = data_blob_talloc(mem_ctx,
4485 cli->auth->a_u.ntlmssp_state->session_key.data,
4486 cli->auth->a_u.ntlmssp_state->session_key.length);
4488 case PIPE_AUTH_TYPE_KRB5:
4489 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4490 *session_key = data_blob_talloc(mem_ctx,
4491 cli->auth->a_u.kerberos_auth->session_key.data,
4492 cli->auth->a_u.kerberos_auth->session_key.length);
4494 case PIPE_AUTH_TYPE_NONE:
4495 *session_key = data_blob_talloc(mem_ctx,
4496 cli->auth->user_session_key.data,
4497 cli->auth->user_session_key.length);
4500 return NT_STATUS_NO_USER_SESSION_KEY;
4503 return NT_STATUS_OK;