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;
674 struct ncacn_packet_header *prhdr;
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,
684 struct ncacn_packet_header *prhdr,
687 struct tevent_req *req, *subreq;
688 struct get_complete_frag_state *state;
692 req = tevent_req_create(mem_ctx, &state,
693 struct get_complete_frag_state);
699 state->prhdr = prhdr;
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 status = parse_rpc_header(cli, prhdr, pdu);
723 if (!NT_STATUS_IS_OK(status)) {
728 * Ensure we have frag_len bytes of data.
730 if (pdu_len < prhdr->frag_length) {
731 if (!rpc_grow_buffer(pdu, prhdr->frag_length)) {
732 status = NT_STATUS_NO_MEMORY;
735 subreq = rpc_read_send(state, state->ev,
736 state->cli->transport,
737 (uint8_t *)(prs_data_p(pdu) + pdu_len),
738 prhdr->frag_length - pdu_len);
739 if (subreq == NULL) {
740 status = NT_STATUS_NO_MEMORY;
743 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
748 status = NT_STATUS_OK;
750 if (NT_STATUS_IS_OK(status)) {
751 tevent_req_done(req);
753 tevent_req_nterror(req, status);
755 return tevent_req_post(req, ev);
758 static void get_complete_frag_got_header(struct tevent_req *subreq)
760 struct tevent_req *req = tevent_req_callback_data(
761 subreq, struct tevent_req);
762 struct get_complete_frag_state *state = tevent_req_data(
763 req, struct get_complete_frag_state);
766 status = rpc_read_recv(subreq);
768 if (!NT_STATUS_IS_OK(status)) {
769 tevent_req_nterror(req, status);
773 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
774 if (!NT_STATUS_IS_OK(status)) {
775 tevent_req_nterror(req, status);
779 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_length)) {
780 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
785 * We're here in this piece of code because we've read exactly
786 * RPC_HEADER_LEN bytes into state->pdu.
789 subreq = rpc_read_send(
790 state, state->ev, state->cli->transport,
791 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
792 state->prhdr->frag_length - RPC_HEADER_LEN);
793 if (tevent_req_nomem(subreq, req)) {
796 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
799 static void get_complete_frag_got_rest(struct tevent_req *subreq)
801 struct tevent_req *req = tevent_req_callback_data(
802 subreq, struct tevent_req);
805 status = rpc_read_recv(subreq);
807 if (!NT_STATUS_IS_OK(status)) {
808 tevent_req_nterror(req, status);
811 tevent_req_done(req);
814 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
816 return tevent_req_simple_recv_ntstatus(req);
819 /****************************************************************************
820 NTLMSSP specific sign/seal.
821 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
822 In fact I should probably abstract these into identical pieces of code... JRA.
823 ****************************************************************************/
825 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
826 struct ncacn_packet_header *prhdr,
827 prs_struct *current_pdu,
828 uint8 *p_ss_padding_len)
830 struct dcerpc_auth auth_info;
831 uint32 save_offset = prs_offset(current_pdu);
832 uint32_t auth_len = prhdr->auth_length;
833 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
834 unsigned char *data = NULL;
836 unsigned char *full_packet_data = NULL;
837 size_t full_packet_data_len;
842 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
843 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
847 if (!ntlmssp_state) {
848 return NT_STATUS_INVALID_PARAMETER;
851 /* Ensure there's enough data for an authenticated response. */
852 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
853 prhdr->frag_length < RPC_HEADER_LEN +
855 RPC_HDR_AUTH_LEN + auth_len) {
856 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
857 (unsigned int)auth_len ));
858 return NT_STATUS_BUFFER_TOO_SMALL;
862 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
863 * after the RPC header.
864 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
865 * functions as NTLMv2 checks the rpc headers also.
868 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
869 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
871 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
872 full_packet_data_len = prhdr->frag_length - auth_len;
874 /* Pull the auth header and the following data into a blob. */
875 /* NB. The offset of the auth_header is relative to the *end*
876 * of the packet, not the start. */
877 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
878 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
879 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
880 return NT_STATUS_BUFFER_TOO_SMALL;
883 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu),
884 prs_data_size(current_pdu) - prs_offset(current_pdu));
886 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
887 if (!NT_STATUS_IS_OK(status)) {
888 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
892 /* Ensure auth_pad_len fits into the packet. */
893 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
894 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
895 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
896 "too large (%u), auth_len (%u), frag_len = (%u).\n",
897 (unsigned int)auth_info.auth_pad_length,
898 (unsigned int)auth_len,
899 (unsigned int)prhdr->frag_length));
900 return NT_STATUS_BUFFER_TOO_SMALL;
904 auth_blob = auth_info.credentials;
906 switch (cli->auth->auth_level) {
907 case DCERPC_AUTH_LEVEL_PRIVACY:
908 /* Data is encrypted. */
909 status = ntlmssp_unseal_packet(ntlmssp_state,
912 full_packet_data_len,
914 if (!NT_STATUS_IS_OK(status)) {
915 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
916 "packet from %s. Error was %s.\n",
917 rpccli_pipe_txt(talloc_tos(), cli),
918 nt_errstr(status) ));
922 case DCERPC_AUTH_LEVEL_INTEGRITY:
923 /* Data is signed. */
924 status = ntlmssp_check_packet(ntlmssp_state,
927 full_packet_data_len,
929 if (!NT_STATUS_IS_OK(status)) {
930 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
931 "packet from %s. Error was %s.\n",
932 rpccli_pipe_txt(talloc_tos(), cli),
933 nt_errstr(status) ));
938 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
939 "auth level %d\n", cli->auth->auth_level));
940 return NT_STATUS_INVALID_INFO_CLASS;
944 * Return the current pointer to the data offset.
947 if(!prs_set_offset(current_pdu, save_offset)) {
948 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
949 (unsigned int)save_offset ));
950 return NT_STATUS_BUFFER_TOO_SMALL;
954 * Remember the padding length. We must remove it from the real data
955 * stream once the sign/seal is done.
958 *p_ss_padding_len = auth_info.auth_pad_length;
963 /****************************************************************************
964 schannel specific sign/seal.
965 ****************************************************************************/
967 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
968 struct ncacn_packet_header *prhdr,
969 prs_struct *current_pdu,
970 uint8 *p_ss_padding_len)
972 struct dcerpc_auth auth_info;
973 uint32_t auth_len = prhdr->auth_length;
974 uint32 save_offset = prs_offset(current_pdu);
975 struct schannel_state *schannel_auth =
976 cli->auth->a_u.schannel_auth;
982 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
983 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
987 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
988 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
989 return NT_STATUS_INVALID_PARAMETER;
992 if (!schannel_auth) {
993 return NT_STATUS_INVALID_PARAMETER;
996 /* Ensure there's enough data for an authenticated response. */
997 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
998 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length)) {
999 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
1000 (unsigned int)auth_len ));
1001 return NT_STATUS_INVALID_PARAMETER;
1004 data_len = prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
1006 /* Pull the auth header and the following data into a blob. */
1007 /* NB. The offset of the auth_header is relative to the *end*
1008 * of the packet, not the start. */
1009 if(!prs_set_offset(current_pdu,
1010 prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
1011 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
1013 (unsigned int)(prhdr->frag_length -
1014 RPC_HDR_AUTH_LEN - auth_len) ));
1015 return NT_STATUS_BUFFER_TOO_SMALL;
1018 blob = data_blob_const(prs_data_p(current_pdu)
1019 + prs_offset(current_pdu),
1020 prs_data_size(current_pdu)
1021 - prs_offset(current_pdu));
1023 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
1029 /* Ensure auth_pad_len fits into the packet. */
1030 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
1031 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
1032 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
1033 "too large (%u), auth_len (%u), frag_len = (%u).\n",
1034 (unsigned int)auth_info.auth_pad_length,
1035 (unsigned int)auth_len,
1036 (unsigned int)prhdr->frag_length));
1037 return NT_STATUS_BUFFER_TOO_SMALL;
1040 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1041 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
1042 auth_info.auth_type));
1043 return NT_STATUS_BUFFER_TOO_SMALL;
1046 blob = data_blob_const(prs_data_p(current_pdu) +
1047 prs_offset(current_pdu) +
1048 RPC_HDR_AUTH_LEN, auth_len);
1050 if (DEBUGLEVEL >= 10) {
1051 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1054 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1056 switch (cli->auth->auth_level) {
1057 case DCERPC_AUTH_LEVEL_PRIVACY:
1058 status = netsec_incoming_packet(schannel_auth,
1065 case DCERPC_AUTH_LEVEL_INTEGRITY:
1066 status = netsec_incoming_packet(schannel_auth,
1074 status = NT_STATUS_INTERNAL_ERROR;
1078 if (!NT_STATUS_IS_OK(status)) {
1079 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1080 "Connection to %s (%s).\n",
1081 rpccli_pipe_txt(talloc_tos(), cli),
1082 nt_errstr(status)));
1083 return NT_STATUS_INVALID_PARAMETER;
1087 * Return the current pointer to the data offset.
1090 if(!prs_set_offset(current_pdu, save_offset)) {
1091 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1092 (unsigned int)save_offset ));
1093 return NT_STATUS_BUFFER_TOO_SMALL;
1097 * Remember the padding length. We must remove it from the real data
1098 * stream once the sign/seal is done.
1101 *p_ss_padding_len = auth_info.auth_pad_length;
1103 return NT_STATUS_OK;
1106 /****************************************************************************
1107 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1108 ****************************************************************************/
1110 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1111 struct ncacn_packet_header *prhdr,
1112 prs_struct *current_pdu,
1113 uint8 *p_ss_padding_len)
1115 NTSTATUS ret = NT_STATUS_OK;
1117 /* Paranioa checks for auth_len. */
1118 if (prhdr->auth_length) {
1119 if (prhdr->auth_length > prhdr->frag_length) {
1120 return NT_STATUS_INVALID_PARAMETER;
1123 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1124 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1125 /* Integer wrap attempt. */
1126 return NT_STATUS_INVALID_PARAMETER;
1131 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1134 switch(cli->auth->auth_type) {
1135 case PIPE_AUTH_TYPE_NONE:
1136 if (prhdr->auth_length) {
1137 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1138 "Connection to %s - got non-zero "
1140 rpccli_pipe_txt(talloc_tos(), cli),
1141 (unsigned int)prhdr->auth_length));
1142 return NT_STATUS_INVALID_PARAMETER;
1146 case PIPE_AUTH_TYPE_NTLMSSP:
1147 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1148 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1149 if (!NT_STATUS_IS_OK(ret)) {
1154 case PIPE_AUTH_TYPE_SCHANNEL:
1155 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1156 if (!NT_STATUS_IS_OK(ret)) {
1161 case PIPE_AUTH_TYPE_KRB5:
1162 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1164 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1165 "to %s - unknown internal auth type %u.\n",
1166 rpccli_pipe_txt(talloc_tos(), cli),
1167 cli->auth->auth_type ));
1168 return NT_STATUS_INVALID_INFO_CLASS;
1171 return NT_STATUS_OK;
1174 /****************************************************************************
1175 Do basic authentication checks on an incoming pdu.
1176 ****************************************************************************/
1178 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1179 struct ncacn_packet_header *prhdr,
1180 prs_struct *current_pdu,
1181 uint8 expected_pkt_type,
1184 prs_struct *return_data)
1187 NTSTATUS ret = NT_STATUS_OK;
1188 uint32 current_pdu_len = prs_data_size(current_pdu);
1190 if (current_pdu_len != prhdr->frag_length) {
1191 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1192 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_length));
1193 return NT_STATUS_INVALID_PARAMETER;
1197 * Point the return values at the real data including the RPC
1198 * header. Just in case the caller wants it.
1200 *ppdata = prs_data_p(current_pdu);
1201 *pdata_len = current_pdu_len;
1203 /* Ensure we have the correct type. */
1204 switch (prhdr->ptype) {
1205 case DCERPC_PKT_ALTER_RESP:
1206 case DCERPC_PKT_BIND_ACK:
1208 /* Alter context and bind ack share the same packet definitions. */
1212 case DCERPC_PKT_RESPONSE:
1214 uint8 ss_padding_len = 0;
1216 struct ncacn_packet r;
1218 blob = data_blob_const(prs_data_p(current_pdu),
1219 prs_data_size(current_pdu));
1221 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1222 if (!NT_STATUS_IS_OK(ret)) {
1226 if (!prs_set_offset(current_pdu, prs_offset(current_pdu) + RPC_HDR_RESP_LEN)) {
1227 return NT_STATUS_BUFFER_TOO_SMALL;
1230 /* Here's where we deal with incoming sign/seal. */
1231 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1232 current_pdu, &ss_padding_len);
1233 if (!NT_STATUS_IS_OK(ret)) {
1237 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1238 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1240 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1241 return NT_STATUS_BUFFER_TOO_SMALL;
1244 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1246 /* Remember to remove the auth footer. */
1247 if (prhdr->auth_length) {
1248 /* We've already done integer wrap tests on auth_len in
1249 cli_pipe_validate_rpc_response(). */
1250 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_length) {
1251 return NT_STATUS_BUFFER_TOO_SMALL;
1253 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_length);
1256 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1257 current_pdu_len, *pdata_len, ss_padding_len ));
1260 * If this is the first reply, and the allocation hint is reasonably, try and
1261 * set up the return_data parse_struct to the correct size.
1264 if ((prs_data_size(return_data) == 0) && r.u.response.alloc_hint && (r.u.response.alloc_hint < 15*1024*1024)) {
1265 if (!prs_set_buffer_size(return_data, r.u.response.alloc_hint)) {
1266 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1267 "too large to allocate\n",
1268 (unsigned int)r.u.response.alloc_hint ));
1269 return NT_STATUS_NO_MEMORY;
1276 case DCERPC_PKT_BIND_NAK:
1277 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1278 "received from %s!\n",
1279 rpccli_pipe_txt(talloc_tos(), cli)));
1280 /* Use this for now... */
1281 return NT_STATUS_NETWORK_ACCESS_DENIED;
1283 case DCERPC_PKT_FAULT:
1286 struct ncacn_packet r;
1288 blob = data_blob_const(prs_data_p(current_pdu),
1289 prs_data_size(current_pdu));
1291 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1292 if (!NT_STATUS_IS_OK(ret)) {
1295 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1296 "code %s received from %s!\n",
1297 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1298 rpccli_pipe_txt(talloc_tos(), cli)));
1300 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1301 return NT_STATUS_UNSUCCESSFUL;
1303 return NT_STATUS(r.u.fault.status);
1308 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1310 (unsigned int)prhdr->ptype,
1311 rpccli_pipe_txt(talloc_tos(), cli)));
1312 return NT_STATUS_INVALID_INFO_CLASS;
1315 if (prhdr->ptype != expected_pkt_type) {
1316 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1317 "got an unexpected RPC packet type - %u, not %u\n",
1318 rpccli_pipe_txt(talloc_tos(), cli),
1320 expected_pkt_type));
1321 return NT_STATUS_INVALID_INFO_CLASS;
1324 /* Do this just before return - we don't want to modify any rpc header
1325 data before now as we may have needed to do cryptographic actions on
1328 if ((prhdr->ptype == DCERPC_PKT_BIND_ACK) && !(prhdr->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1329 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1330 "setting fragment first/last ON.\n"));
1331 prhdr->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1334 return NT_STATUS_OK;
1337 /****************************************************************************
1338 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1339 Normally the frag_len and buffer size will match, but on the first trans
1340 reply there is a theoretical chance that buffer size > frag_len, so we must
1342 ****************************************************************************/
1344 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1345 struct ncacn_packet_header *prhdr,
1346 prs_struct *current_pdu)
1348 uint32 current_pdu_len = prs_data_size(current_pdu);
1350 if (current_pdu_len < prhdr->frag_length) {
1351 return NT_STATUS_BUFFER_TOO_SMALL;
1355 if (current_pdu_len == (uint32)prhdr->frag_length) {
1356 prs_mem_free(current_pdu);
1357 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1358 /* Make current_pdu dynamic with no memory. */
1359 prs_give_memory(current_pdu, 0, 0, True);
1360 return NT_STATUS_OK;
1364 * Oh no ! More data in buffer than we processed in current pdu.
1365 * Cheat. Move the data down and shrink the buffer.
1368 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_length,
1369 current_pdu_len - prhdr->frag_length);
1371 /* Remember to set the read offset back to zero. */
1372 prs_set_offset(current_pdu, 0);
1374 /* Shrink the buffer. */
1375 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_length)) {
1376 return NT_STATUS_BUFFER_TOO_SMALL;
1379 return NT_STATUS_OK;
1382 /****************************************************************************
1383 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1384 ****************************************************************************/
1386 struct cli_api_pipe_state {
1387 struct event_context *ev;
1388 struct rpc_cli_transport *transport;
1393 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1394 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1395 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1397 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1398 struct event_context *ev,
1399 struct rpc_cli_transport *transport,
1400 uint8_t *data, size_t data_len,
1401 uint32_t max_rdata_len)
1403 struct tevent_req *req, *subreq;
1404 struct cli_api_pipe_state *state;
1407 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1412 state->transport = transport;
1414 if (max_rdata_len < RPC_HEADER_LEN) {
1416 * For a RPC reply we always need at least RPC_HEADER_LEN
1417 * bytes. We check this here because we will receive
1418 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1420 status = NT_STATUS_INVALID_PARAMETER;
1424 if (transport->trans_send != NULL) {
1425 subreq = transport->trans_send(state, ev, data, data_len,
1426 max_rdata_len, transport->priv);
1427 if (subreq == NULL) {
1430 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1435 * If the transport does not provide a "trans" routine, i.e. for
1436 * example the ncacn_ip_tcp transport, do the write/read step here.
1439 subreq = rpc_write_send(state, ev, transport, data, data_len);
1440 if (subreq == NULL) {
1443 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1447 tevent_req_nterror(req, status);
1448 return tevent_req_post(req, ev);
1454 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1456 struct tevent_req *req = tevent_req_callback_data(
1457 subreq, struct tevent_req);
1458 struct cli_api_pipe_state *state = tevent_req_data(
1459 req, struct cli_api_pipe_state);
1462 status = state->transport->trans_recv(subreq, state, &state->rdata,
1464 TALLOC_FREE(subreq);
1465 if (!NT_STATUS_IS_OK(status)) {
1466 tevent_req_nterror(req, status);
1469 tevent_req_done(req);
1472 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1474 struct tevent_req *req = tevent_req_callback_data(
1475 subreq, struct tevent_req);
1476 struct cli_api_pipe_state *state = tevent_req_data(
1477 req, struct cli_api_pipe_state);
1480 status = rpc_write_recv(subreq);
1481 TALLOC_FREE(subreq);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 tevent_req_nterror(req, status);
1487 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1488 if (tevent_req_nomem(state->rdata, req)) {
1493 * We don't need to use rpc_read_send here, the upper layer will cope
1494 * with a short read, transport->trans_send could also return less
1495 * than state->max_rdata_len.
1497 subreq = state->transport->read_send(state, state->ev, state->rdata,
1499 state->transport->priv);
1500 if (tevent_req_nomem(subreq, req)) {
1503 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1506 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1508 struct tevent_req *req = tevent_req_callback_data(
1509 subreq, struct tevent_req);
1510 struct cli_api_pipe_state *state = tevent_req_data(
1511 req, struct cli_api_pipe_state);
1515 status = state->transport->read_recv(subreq, &received);
1516 TALLOC_FREE(subreq);
1517 if (!NT_STATUS_IS_OK(status)) {
1518 tevent_req_nterror(req, status);
1521 state->rdata_len = received;
1522 tevent_req_done(req);
1525 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1526 uint8_t **prdata, uint32_t *prdata_len)
1528 struct cli_api_pipe_state *state = tevent_req_data(
1529 req, struct cli_api_pipe_state);
1532 if (tevent_req_is_nterror(req, &status)) {
1536 *prdata = talloc_move(mem_ctx, &state->rdata);
1537 *prdata_len = state->rdata_len;
1538 return NT_STATUS_OK;
1541 /****************************************************************************
1542 Send data on an rpc pipe via trans. The prs_struct data must be the last
1543 pdu fragment of an NDR data stream.
1545 Receive response data from an rpc pipe, which may be large...
1547 Read the first fragment: unfortunately have to use SMBtrans for the first
1548 bit, then SMBreadX for subsequent bits.
1550 If first fragment received also wasn't the last fragment, continue
1551 getting fragments until we _do_ receive the last fragment.
1553 Request/Response PDU's look like the following...
1555 |<------------------PDU len----------------------------------------------->|
1556 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1558 +------------+-----------------+-------------+---------------+-------------+
1559 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1560 +------------+-----------------+-------------+---------------+-------------+
1562 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1563 signing & sealing being negotiated.
1565 ****************************************************************************/
1567 struct rpc_api_pipe_state {
1568 struct event_context *ev;
1569 struct rpc_pipe_client *cli;
1570 uint8_t expected_pkt_type;
1572 prs_struct incoming_frag;
1573 struct ncacn_packet_header rhdr;
1575 prs_struct incoming_pdu; /* Incoming reply */
1576 uint32_t incoming_pdu_offset;
1579 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1580 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1582 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1583 struct event_context *ev,
1584 struct rpc_pipe_client *cli,
1585 prs_struct *data, /* Outgoing PDU */
1586 uint8_t expected_pkt_type)
1588 struct tevent_req *req, *subreq;
1589 struct rpc_api_pipe_state *state;
1590 uint16_t max_recv_frag;
1593 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1599 state->expected_pkt_type = expected_pkt_type;
1600 state->incoming_pdu_offset = 0;
1602 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1604 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1605 /* Make incoming_pdu dynamic with no memory. */
1606 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1609 * Ensure we're not sending too much.
1611 if (prs_offset(data) > cli->max_xmit_frag) {
1612 status = NT_STATUS_INVALID_PARAMETER;
1616 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1618 max_recv_frag = cli->max_recv_frag;
1621 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1624 subreq = cli_api_pipe_send(state, ev, cli->transport,
1625 (uint8_t *)prs_data_p(data),
1626 prs_offset(data), max_recv_frag);
1627 if (subreq == NULL) {
1630 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1634 tevent_req_nterror(req, status);
1635 return tevent_req_post(req, ev);
1641 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1643 struct tevent_req *req = tevent_req_callback_data(
1644 subreq, struct tevent_req);
1645 struct rpc_api_pipe_state *state = tevent_req_data(
1646 req, struct rpc_api_pipe_state);
1648 uint8_t *rdata = NULL;
1649 uint32_t rdata_len = 0;
1651 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1652 TALLOC_FREE(subreq);
1653 if (!NT_STATUS_IS_OK(status)) {
1654 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1655 tevent_req_nterror(req, status);
1659 if (rdata == NULL) {
1660 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1661 rpccli_pipe_txt(talloc_tos(), state->cli)));
1662 tevent_req_done(req);
1667 * This is equivalent to a talloc_steal - gives rdata to
1668 * the prs_struct state->incoming_frag.
1670 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1673 /* Ensure we have enough data for a pdu. */
1674 subreq = get_complete_frag_send(state, state->ev, state->cli,
1675 &state->rhdr, &state->incoming_frag);
1676 if (tevent_req_nomem(subreq, req)) {
1679 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1682 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1684 struct tevent_req *req = tevent_req_callback_data(
1685 subreq, struct tevent_req);
1686 struct rpc_api_pipe_state *state = tevent_req_data(
1687 req, struct rpc_api_pipe_state);
1690 uint32_t rdata_len = 0;
1692 status = get_complete_frag_recv(subreq);
1693 TALLOC_FREE(subreq);
1694 if (!NT_STATUS_IS_OK(status)) {
1695 DEBUG(5, ("get_complete_frag failed: %s\n",
1696 nt_errstr(status)));
1697 tevent_req_nterror(req, status);
1701 status = cli_pipe_validate_current_pdu(
1702 state->cli, &state->rhdr, &state->incoming_frag,
1703 state->expected_pkt_type, &rdata, &rdata_len,
1704 &state->incoming_pdu);
1706 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1707 (unsigned)prs_data_size(&state->incoming_frag),
1708 (unsigned)state->incoming_pdu_offset,
1709 nt_errstr(status)));
1711 if (!NT_STATUS_IS_OK(status)) {
1712 tevent_req_nterror(req, status);
1716 if ((state->rhdr.pfc_flags & DCERPC_PFC_FLAG_FIRST)
1717 && (state->rhdr.drep[0] == 0)) {
1719 * Set the data type correctly for big-endian data on the
1722 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1724 rpccli_pipe_txt(talloc_tos(), state->cli)));
1725 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1728 * Check endianness on subsequent packets.
1730 if (state->incoming_frag.bigendian_data
1731 != state->incoming_pdu.bigendian_data) {
1732 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1734 state->incoming_pdu.bigendian_data?"big":"little",
1735 state->incoming_frag.bigendian_data?"big":"little"));
1736 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1740 /* Now copy the data portion out of the pdu into rbuf. */
1741 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1742 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1746 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1747 rdata, (size_t)rdata_len);
1748 state->incoming_pdu_offset += rdata_len;
1750 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1751 &state->incoming_frag);
1752 if (!NT_STATUS_IS_OK(status)) {
1753 tevent_req_nterror(req, status);
1757 if (state->rhdr.pfc_flags & DCERPC_PFC_FLAG_LAST) {
1758 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1759 rpccli_pipe_txt(talloc_tos(), state->cli),
1760 (unsigned)prs_data_size(&state->incoming_pdu)));
1761 tevent_req_done(req);
1765 subreq = get_complete_frag_send(state, state->ev, state->cli,
1766 &state->rhdr, &state->incoming_frag);
1767 if (tevent_req_nomem(subreq, req)) {
1770 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1773 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1774 prs_struct *reply_pdu)
1776 struct rpc_api_pipe_state *state = tevent_req_data(
1777 req, struct rpc_api_pipe_state);
1780 if (tevent_req_is_nterror(req, &status)) {
1784 *reply_pdu = state->incoming_pdu;
1785 reply_pdu->mem_ctx = mem_ctx;
1788 * Prevent state->incoming_pdu from being freed
1789 * when state is freed.
1791 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1792 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1794 return NT_STATUS_OK;
1797 /*******************************************************************
1798 Creates an auth_data blob.
1799 ********************************************************************/
1801 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1802 enum dcerpc_AuthType auth_type,
1803 enum dcerpc_AuthLevel auth_level,
1804 uint8_t auth_pad_length,
1805 uint32_t auth_context_id,
1806 const DATA_BLOB *credentials,
1809 struct dcerpc_auth r;
1810 enum ndr_err_code ndr_err;
1812 r.auth_type = auth_type;
1813 r.auth_level = auth_level;
1814 r.auth_pad_length = auth_pad_length;
1815 r.auth_reserved = 0;
1816 r.auth_context_id = auth_context_id;
1817 r.credentials = *credentials;
1819 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1820 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1821 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1822 return ndr_map_error2ntstatus(ndr_err);
1825 if (DEBUGLEVEL >= 10) {
1826 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1829 return NT_STATUS_OK;
1832 /*******************************************************************
1833 Creates krb5 auth bind.
1834 ********************************************************************/
1836 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1837 enum dcerpc_AuthLevel auth_level,
1838 DATA_BLOB *auth_info)
1843 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1844 DATA_BLOB tkt = data_blob_null;
1845 DATA_BLOB tkt_wrapped = data_blob_null;
1847 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1848 a->service_principal ));
1850 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1852 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1853 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1856 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1858 a->service_principal,
1859 error_message(ret) ));
1861 data_blob_free(&tkt);
1862 return NT_STATUS_INVALID_PARAMETER;
1865 /* wrap that up in a nice GSS-API wrapping */
1866 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1868 data_blob_free(&tkt);
1870 status = dcerpc_push_dcerpc_auth(cli,
1871 DCERPC_AUTH_TYPE_KRB5,
1873 0, /* auth_pad_length */
1874 1, /* auth_context_id */
1877 if (!NT_STATUS_IS_OK(status)) {
1878 data_blob_free(&tkt_wrapped);
1882 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1883 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1885 return NT_STATUS_OK;
1887 return NT_STATUS_INVALID_PARAMETER;
1891 /*******************************************************************
1892 Creates SPNEGO NTLMSSP auth bind.
1893 ********************************************************************/
1895 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1896 enum dcerpc_AuthLevel auth_level,
1897 DATA_BLOB *auth_info)
1900 DATA_BLOB null_blob = data_blob_null;
1901 DATA_BLOB request = data_blob_null;
1902 DATA_BLOB spnego_msg = data_blob_null;
1904 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1905 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1909 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1910 data_blob_free(&request);
1914 /* Wrap this in SPNEGO. */
1915 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1917 data_blob_free(&request);
1919 status = dcerpc_push_dcerpc_auth(cli,
1920 DCERPC_AUTH_TYPE_SPNEGO,
1922 0, /* auth_pad_length */
1923 1, /* auth_context_id */
1926 if (!NT_STATUS_IS_OK(status)) {
1927 data_blob_free(&spnego_msg);
1931 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1932 dump_data(5, spnego_msg.data, spnego_msg.length);
1934 return NT_STATUS_OK;
1937 /*******************************************************************
1938 Creates NTLMSSP auth bind.
1939 ********************************************************************/
1941 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1942 enum dcerpc_AuthLevel auth_level,
1943 DATA_BLOB *auth_info)
1946 DATA_BLOB null_blob = data_blob_null;
1947 DATA_BLOB request = data_blob_null;
1949 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1950 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1954 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1955 data_blob_free(&request);
1959 status = dcerpc_push_dcerpc_auth(cli,
1960 DCERPC_AUTH_TYPE_NTLMSSP,
1962 0, /* auth_pad_length */
1963 1, /* auth_context_id */
1966 if (!NT_STATUS_IS_OK(status)) {
1967 data_blob_free(&request);
1971 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1972 dump_data(5, request.data, request.length);
1974 return NT_STATUS_OK;
1977 /*******************************************************************
1978 Creates schannel auth bind.
1979 ********************************************************************/
1981 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1982 enum dcerpc_AuthLevel auth_level,
1983 DATA_BLOB *auth_info)
1986 struct NL_AUTH_MESSAGE r;
1987 DATA_BLOB schannel_blob;
1989 /* Use lp_workgroup() if domain not specified */
1991 if (!cli->auth->domain || !cli->auth->domain[0]) {
1992 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1993 if (cli->auth->domain == NULL) {
1994 return NT_STATUS_NO_MEMORY;
1999 * Now marshall the data into the auth parse_struct.
2002 r.MessageType = NL_NEGOTIATE_REQUEST;
2003 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
2004 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
2005 r.oem_netbios_domain.a = cli->auth->domain;
2006 r.oem_netbios_computer.a = global_myname();
2008 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
2009 if (!NT_STATUS_IS_OK(status)) {
2013 status = dcerpc_push_dcerpc_auth(cli,
2014 DCERPC_AUTH_TYPE_SCHANNEL,
2016 0, /* auth_pad_length */
2017 1, /* auth_context_id */
2020 if (!NT_STATUS_IS_OK(status)) {
2024 return NT_STATUS_OK;
2027 /*******************************************************************
2028 ********************************************************************/
2030 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
2031 const struct ndr_syntax_id *abstract_syntax,
2032 const struct ndr_syntax_id *transfer_syntax,
2033 struct dcerpc_ctx_list **ctx_list_p)
2035 struct dcerpc_ctx_list *ctx_list;
2037 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
2038 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
2040 ctx_list[0].context_id = 0;
2041 ctx_list[0].num_transfer_syntaxes = 1;
2042 ctx_list[0].abstract_syntax = *abstract_syntax;
2043 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
2044 struct ndr_syntax_id,
2045 ctx_list[0].num_transfer_syntaxes);
2046 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
2047 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
2049 *ctx_list_p = ctx_list;
2051 return NT_STATUS_OK;
2054 /*******************************************************************
2055 Creates the internals of a DCE/RPC bind request or alter context PDU.
2056 ********************************************************************/
2058 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2059 prs_struct *rpc_out,
2061 const struct ndr_syntax_id *abstract,
2062 const struct ndr_syntax_id *transfer,
2063 const DATA_BLOB *auth_info)
2065 uint16 auth_len = auth_info->length;
2067 union dcerpc_payload u;
2069 struct dcerpc_ctx_list *ctx_list;
2071 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2073 if (!NT_STATUS_IS_OK(status)) {
2077 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2078 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2079 u.bind.assoc_group_id = 0x0;
2080 u.bind.num_contexts = 1;
2081 u.bind.ctx_list = ctx_list;
2082 u.bind.auth_info = *auth_info;
2084 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2086 DCERPC_PFC_FLAG_FIRST |
2087 DCERPC_PFC_FLAG_LAST,
2088 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2092 if (!NT_STATUS_IS_OK(status)) {
2093 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2097 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2098 return NT_STATUS_NO_MEMORY;
2101 return NT_STATUS_OK;
2104 /*******************************************************************
2105 Creates a DCE/RPC bind request.
2106 ********************************************************************/
2108 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2109 prs_struct *rpc_out,
2111 const struct ndr_syntax_id *abstract,
2112 const struct ndr_syntax_id *transfer,
2113 enum pipe_auth_type auth_type,
2114 enum dcerpc_AuthLevel auth_level)
2116 DATA_BLOB auth_info = data_blob_null;
2117 NTSTATUS ret = NT_STATUS_OK;
2119 switch (auth_type) {
2120 case PIPE_AUTH_TYPE_SCHANNEL:
2121 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2122 if (!NT_STATUS_IS_OK(ret)) {
2127 case PIPE_AUTH_TYPE_NTLMSSP:
2128 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2129 if (!NT_STATUS_IS_OK(ret)) {
2134 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2135 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2136 if (!NT_STATUS_IS_OK(ret)) {
2141 case PIPE_AUTH_TYPE_KRB5:
2142 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2143 if (!NT_STATUS_IS_OK(ret)) {
2148 case PIPE_AUTH_TYPE_NONE:
2152 /* "Can't" happen. */
2153 return NT_STATUS_INVALID_INFO_CLASS;
2156 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2165 /*******************************************************************
2166 Create and add the NTLMSSP sign/seal auth header and data.
2167 ********************************************************************/
2169 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2170 uint32 ss_padding_len,
2171 prs_struct *rpc_out)
2173 DATA_BLOB auth_info;
2175 DATA_BLOB auth_blob = data_blob_null;
2176 uint16_t data_and_pad_len =
2177 prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2179 if (!cli->auth->a_u.ntlmssp_state) {
2180 return NT_STATUS_INVALID_PARAMETER;
2183 /* marshall the dcerpc_auth with an actually empty auth_blob.
2184 * this is needed because the ntmlssp signature includes the
2186 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2187 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2188 cli->auth->auth_level,
2190 1 /* context id. */,
2193 if (!NT_STATUS_IS_OK(status)) {
2197 /* append the header */
2198 if (!prs_copy_data_in(rpc_out,
2199 (char *)auth_info.data,
2200 auth_info.length)) {
2201 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2202 (unsigned int)auth_info.length));
2203 return NT_STATUS_NO_MEMORY;
2206 switch (cli->auth->auth_level) {
2207 case DCERPC_AUTH_LEVEL_PRIVACY:
2208 /* Data portion is encrypted. */
2209 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2210 prs_get_mem_context(rpc_out),
2211 (unsigned char *)prs_data_p(rpc_out)
2215 (unsigned char *)prs_data_p(rpc_out),
2216 (size_t)prs_offset(rpc_out),
2218 if (!NT_STATUS_IS_OK(status)) {
2223 case DCERPC_AUTH_LEVEL_INTEGRITY:
2224 /* Data is signed. */
2225 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2226 prs_get_mem_context(rpc_out),
2227 (unsigned char *)prs_data_p(rpc_out)
2231 (unsigned char *)prs_data_p(rpc_out),
2232 (size_t)prs_offset(rpc_out),
2234 if (!NT_STATUS_IS_OK(status)) {
2241 smb_panic("bad auth level");
2243 return NT_STATUS_INVALID_PARAMETER;
2246 /* Finally attach the blob. */
2247 if (!prs_copy_data_in(rpc_out,
2248 (char *)auth_blob.data,
2249 auth_blob.length)) {
2250 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2251 (unsigned int)auth_info.length));
2252 return NT_STATUS_NO_MEMORY;
2255 return NT_STATUS_OK;
2258 /*******************************************************************
2259 Create and add the schannel sign/seal auth header and data.
2260 ********************************************************************/
2262 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2263 uint32 ss_padding_len,
2264 prs_struct *rpc_out)
2266 DATA_BLOB auth_info;
2267 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2268 char *data_p = prs_data_p(rpc_out) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2269 size_t data_and_pad_len = prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2274 return NT_STATUS_INVALID_PARAMETER;
2277 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2280 switch (cli->auth->auth_level) {
2281 case DCERPC_AUTH_LEVEL_PRIVACY:
2282 status = netsec_outgoing_packet(sas,
2289 case DCERPC_AUTH_LEVEL_INTEGRITY:
2290 status = netsec_outgoing_packet(sas,
2298 status = NT_STATUS_INTERNAL_ERROR;
2302 if (!NT_STATUS_IS_OK(status)) {
2303 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2304 nt_errstr(status)));
2308 if (DEBUGLEVEL >= 10) {
2309 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2312 /* Finally marshall the blob. */
2313 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2314 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2315 cli->auth->auth_level,
2317 1 /* context id. */,
2320 if (!NT_STATUS_IS_OK(status)) {
2324 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.length)) {
2325 return NT_STATUS_NO_MEMORY;
2328 return NT_STATUS_OK;
2331 /*******************************************************************
2332 Calculate how much data we're going to send in this packet, also
2333 work out any sign/seal padding length.
2334 ********************************************************************/
2336 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2340 uint32 *p_ss_padding)
2342 uint32 data_space, data_len;
2345 if ((data_left > 0) && (sys_random() % 2)) {
2346 data_left = MAX(data_left/2, 1);
2350 switch (cli->auth->auth_level) {
2351 case DCERPC_AUTH_LEVEL_NONE:
2352 case DCERPC_AUTH_LEVEL_CONNECT:
2353 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2354 data_len = MIN(data_space, data_left);
2357 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2360 case DCERPC_AUTH_LEVEL_INTEGRITY:
2361 case DCERPC_AUTH_LEVEL_PRIVACY:
2362 /* Treat the same for all authenticated rpc requests. */
2363 switch(cli->auth->auth_type) {
2364 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2365 case PIPE_AUTH_TYPE_NTLMSSP:
2366 *p_auth_len = NTLMSSP_SIG_SIZE;
2368 case PIPE_AUTH_TYPE_SCHANNEL:
2369 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2372 smb_panic("bad auth type");
2376 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2377 RPC_HDR_AUTH_LEN - *p_auth_len;
2379 data_len = MIN(data_space, data_left);
2381 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2382 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2384 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2385 data_len + *p_ss_padding + /* data plus padding. */
2386 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2390 smb_panic("bad auth level");
2396 /*******************************************************************
2398 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2399 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2400 and deals with signing/sealing details.
2401 ********************************************************************/
2403 struct rpc_api_pipe_req_state {
2404 struct event_context *ev;
2405 struct rpc_pipe_client *cli;
2408 prs_struct *req_data;
2409 uint32_t req_data_sent;
2410 prs_struct outgoing_frag;
2411 prs_struct reply_pdu;
2414 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2415 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2416 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2417 bool *is_last_frag);
2419 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2420 struct event_context *ev,
2421 struct rpc_pipe_client *cli,
2423 prs_struct *req_data)
2425 struct tevent_req *req, *subreq;
2426 struct rpc_api_pipe_req_state *state;
2430 req = tevent_req_create(mem_ctx, &state,
2431 struct rpc_api_pipe_req_state);
2437 state->op_num = op_num;
2438 state->req_data = req_data;
2439 state->req_data_sent = 0;
2440 state->call_id = get_rpc_call_id();
2442 if (cli->max_xmit_frag
2443 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2444 /* Server is screwed up ! */
2445 status = NT_STATUS_INVALID_PARAMETER;
2449 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2451 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2456 status = prepare_next_frag(state, &is_last_frag);
2457 if (!NT_STATUS_IS_OK(status)) {
2462 subreq = rpc_api_pipe_send(state, ev, state->cli,
2463 &state->outgoing_frag,
2464 DCERPC_PKT_RESPONSE);
2465 if (subreq == NULL) {
2468 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2470 subreq = rpc_write_send(
2471 state, ev, cli->transport,
2472 (uint8_t *)prs_data_p(&state->outgoing_frag),
2473 prs_offset(&state->outgoing_frag));
2474 if (subreq == NULL) {
2477 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2483 tevent_req_nterror(req, status);
2484 return tevent_req_post(req, ev);
2490 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2493 uint32_t data_sent_thistime;
2497 uint32_t ss_padding;
2499 char pad[8] = { 0, };
2501 union dcerpc_payload u;
2504 data_left = prs_offset(state->req_data) - state->req_data_sent;
2506 data_sent_thistime = calculate_data_len_tosend(
2507 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2509 if (state->req_data_sent == 0) {
2510 flags = DCERPC_PFC_FLAG_FIRST;
2513 if (data_sent_thistime == data_left) {
2514 flags |= DCERPC_PFC_FLAG_LAST;
2517 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2518 return NT_STATUS_NO_MEMORY;
2521 ZERO_STRUCT(u.request);
2523 u.request.alloc_hint = prs_offset(state->req_data);
2524 u.request.context_id = 0;
2525 u.request.opnum = state->op_num;
2527 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2534 if (!NT_STATUS_IS_OK(status)) {
2538 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
2539 * compute it right for requests */
2540 dcerpc_set_frag_length(&blob, frag_len);
2542 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2543 return NT_STATUS_NO_MEMORY;
2546 /* Copy in the data, plus any ss padding. */
2547 if (!prs_append_some_prs_data(&state->outgoing_frag,
2548 state->req_data, state->req_data_sent,
2549 data_sent_thistime)) {
2550 return NT_STATUS_NO_MEMORY;
2553 /* Copy the sign/seal padding data. */
2554 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2555 return NT_STATUS_NO_MEMORY;
2558 /* Generate any auth sign/seal and add the auth footer. */
2559 switch (state->cli->auth->auth_type) {
2560 case PIPE_AUTH_TYPE_NONE:
2561 status = NT_STATUS_OK;
2563 case PIPE_AUTH_TYPE_NTLMSSP:
2564 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2565 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2566 &state->outgoing_frag);
2568 case PIPE_AUTH_TYPE_SCHANNEL:
2569 status = add_schannel_auth_footer(state->cli, ss_padding,
2570 &state->outgoing_frag);
2573 status = NT_STATUS_INVALID_PARAMETER;
2577 state->req_data_sent += data_sent_thistime;
2578 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2583 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2585 struct tevent_req *req = tevent_req_callback_data(
2586 subreq, struct tevent_req);
2587 struct rpc_api_pipe_req_state *state = tevent_req_data(
2588 req, struct rpc_api_pipe_req_state);
2592 status = rpc_write_recv(subreq);
2593 TALLOC_FREE(subreq);
2594 if (!NT_STATUS_IS_OK(status)) {
2595 tevent_req_nterror(req, status);
2599 status = prepare_next_frag(state, &is_last_frag);
2600 if (!NT_STATUS_IS_OK(status)) {
2601 tevent_req_nterror(req, status);
2606 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2607 &state->outgoing_frag,
2608 DCERPC_PKT_RESPONSE);
2609 if (tevent_req_nomem(subreq, req)) {
2612 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2614 subreq = rpc_write_send(
2616 state->cli->transport,
2617 (uint8_t *)prs_data_p(&state->outgoing_frag),
2618 prs_offset(&state->outgoing_frag));
2619 if (tevent_req_nomem(subreq, req)) {
2622 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2627 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2629 struct tevent_req *req = tevent_req_callback_data(
2630 subreq, struct tevent_req);
2631 struct rpc_api_pipe_req_state *state = tevent_req_data(
2632 req, struct rpc_api_pipe_req_state);
2635 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2636 TALLOC_FREE(subreq);
2637 if (!NT_STATUS_IS_OK(status)) {
2638 tevent_req_nterror(req, status);
2641 tevent_req_done(req);
2644 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2645 prs_struct *reply_pdu)
2647 struct rpc_api_pipe_req_state *state = tevent_req_data(
2648 req, struct rpc_api_pipe_req_state);
2651 if (tevent_req_is_nterror(req, &status)) {
2653 * We always have to initialize to reply pdu, even if there is
2654 * none. The rpccli_* caller routines expect this.
2656 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2660 *reply_pdu = state->reply_pdu;
2661 reply_pdu->mem_ctx = mem_ctx;
2664 * Prevent state->req_pdu from being freed
2665 * when state is freed.
2667 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2668 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2670 return NT_STATUS_OK;
2674 /****************************************************************************
2675 Set the handle state.
2676 ****************************************************************************/
2678 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2679 const char *pipe_name, uint16 device_state)
2681 bool state_set = False;
2683 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2684 char *rparam = NULL;
2686 uint32 rparam_len, rdata_len;
2688 if (pipe_name == NULL)
2691 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2692 cli->fnum, pipe_name, device_state));
2694 /* create parameters: device state */
2695 SSVAL(param, 0, device_state);
2697 /* create setup parameters. */
2699 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2701 /* send the data on \PIPE\ */
2702 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2703 setup, 2, 0, /* setup, length, max */
2704 param, 2, 0, /* param, length, max */
2705 NULL, 0, 1024, /* data, length, max */
2706 &rparam, &rparam_len, /* return param, length */
2707 &rdata, &rdata_len)) /* return data, length */
2709 DEBUG(5, ("Set Handle state: return OK\n"));
2720 /****************************************************************************
2721 Check the rpc bind acknowledge response.
2722 ****************************************************************************/
2724 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2725 const struct ndr_syntax_id *transfer)
2727 struct dcerpc_ack_ctx ctx;
2729 if (r->secondary_address_size == 0) {
2730 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2733 if (r->num_results < 1 || !r->ctx_list) {
2737 ctx = r->ctx_list[0];
2739 /* check the transfer syntax */
2740 if ((ctx.syntax.if_version != transfer->if_version) ||
2741 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2742 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2746 if (r->num_results != 0x1 || ctx.result != 0) {
2747 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2748 r->num_results, ctx.reason));
2751 DEBUG(5,("check_bind_response: accepted!\n"));
2755 /*******************************************************************
2756 Creates a DCE/RPC bind authentication response.
2757 This is the packet that is sent back to the server once we
2758 have received a BIND-ACK, to finish the third leg of
2759 the authentication handshake.
2760 ********************************************************************/
2762 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2764 enum pipe_auth_type auth_type,
2765 enum dcerpc_AuthLevel auth_level,
2766 DATA_BLOB *pauth_blob,
2767 prs_struct *rpc_out)
2770 union dcerpc_payload u;
2775 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2776 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2778 0, /* auth_pad_length */
2779 1, /* auth_context_id */
2781 &u.auth3.auth_info);
2782 if (!NT_STATUS_IS_OK(status)) {
2786 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2788 DCERPC_PFC_FLAG_FIRST |
2789 DCERPC_PFC_FLAG_LAST,
2794 if (!NT_STATUS_IS_OK(status)) {
2795 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2799 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2800 return NT_STATUS_NO_MEMORY;
2803 return NT_STATUS_OK;
2806 /*******************************************************************
2807 Creates a DCE/RPC bind alter context authentication request which
2808 may contain a spnego auth blobl
2809 ********************************************************************/
2811 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2812 const struct ndr_syntax_id *abstract,
2813 const struct ndr_syntax_id *transfer,
2814 enum dcerpc_AuthLevel auth_level,
2815 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2816 prs_struct *rpc_out)
2818 DATA_BLOB auth_info;
2821 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2822 DCERPC_AUTH_TYPE_SPNEGO,
2824 0, /* auth_pad_length */
2825 1, /* auth_context_id */
2828 if (!NT_STATUS_IS_OK(status)) {
2833 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2839 if (!NT_STATUS_IS_OK(status)) {
2846 /****************************************************************************
2848 ****************************************************************************/
2850 struct rpc_pipe_bind_state {
2851 struct event_context *ev;
2852 struct rpc_pipe_client *cli;
2854 uint32_t rpc_call_id;
2857 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2858 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2859 struct rpc_pipe_bind_state *state,
2860 struct ncacn_packet *r,
2861 prs_struct *reply_pdu);
2862 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2863 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2864 struct rpc_pipe_bind_state *state,
2865 struct ncacn_packet *r,
2866 prs_struct *reply_pdu);
2867 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2869 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2870 struct event_context *ev,
2871 struct rpc_pipe_client *cli,
2872 struct cli_pipe_auth_data *auth)
2874 struct tevent_req *req, *subreq;
2875 struct rpc_pipe_bind_state *state;
2878 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2883 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2884 rpccli_pipe_txt(talloc_tos(), cli),
2885 (unsigned int)auth->auth_type,
2886 (unsigned int)auth->auth_level ));
2890 state->rpc_call_id = get_rpc_call_id();
2892 prs_init_empty(&state->rpc_out, state, MARSHALL);
2894 cli->auth = talloc_move(cli, &auth);
2896 /* Marshall the outgoing data. */
2897 status = create_rpc_bind_req(cli, &state->rpc_out,
2899 &cli->abstract_syntax,
2900 &cli->transfer_syntax,
2901 cli->auth->auth_type,
2902 cli->auth->auth_level);
2904 if (!NT_STATUS_IS_OK(status)) {
2908 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2909 DCERPC_PKT_BIND_ACK);
2910 if (subreq == NULL) {
2913 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2917 tevent_req_nterror(req, status);
2918 return tevent_req_post(req, ev);
2924 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2926 struct tevent_req *req = tevent_req_callback_data(
2927 subreq, struct tevent_req);
2928 struct rpc_pipe_bind_state *state = tevent_req_data(
2929 req, struct rpc_pipe_bind_state);
2930 prs_struct reply_pdu;
2932 struct ncacn_packet r;
2935 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2936 TALLOC_FREE(subreq);
2937 if (!NT_STATUS_IS_OK(status)) {
2938 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2939 rpccli_pipe_txt(talloc_tos(), state->cli),
2940 nt_errstr(status)));
2941 tevent_req_nterror(req, status);
2945 blob = data_blob_const(prs_data_p(&reply_pdu),
2946 prs_data_size(&reply_pdu));
2948 status = dcerpc_pull_ncacn_packet(talloc_tos(), &blob, &r);
2949 if (!NT_STATUS_IS_OK(status)) {
2950 tevent_req_nterror(req, status);
2954 if (!check_bind_response(&r.u.bind_ack, &state->cli->transfer_syntax)) {
2955 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2956 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2960 state->cli->max_xmit_frag = r.u.bind_ack.max_xmit_frag;
2961 state->cli->max_recv_frag = r.u.bind_ack.max_recv_frag;
2964 * For authenticated binds we may need to do 3 or 4 leg binds.
2967 switch(state->cli->auth->auth_type) {
2969 case PIPE_AUTH_TYPE_NONE:
2970 case PIPE_AUTH_TYPE_SCHANNEL:
2971 /* Bind complete. */
2972 tevent_req_done(req);
2975 case PIPE_AUTH_TYPE_NTLMSSP:
2976 /* Need to send AUTH3 packet - no reply. */
2977 status = rpc_finish_auth3_bind_send(req, state, &r,
2979 if (!NT_STATUS_IS_OK(status)) {
2980 tevent_req_nterror(req, status);
2984 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2985 /* Need to send alter context request and reply. */
2986 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &r,
2988 if (!NT_STATUS_IS_OK(status)) {
2989 tevent_req_nterror(req, status);
2993 case PIPE_AUTH_TYPE_KRB5:
2997 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2998 (unsigned int)state->cli->auth->auth_type));
2999 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3003 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
3004 struct rpc_pipe_bind_state *state,
3005 struct ncacn_packet *r,
3006 prs_struct *reply_pdu)
3008 DATA_BLOB server_response = data_blob_null;
3009 DATA_BLOB client_reply = data_blob_null;
3010 struct rpc_hdr_auth_info hdr_auth;
3011 struct tevent_req *subreq;
3014 if ((r->auth_length == 0)
3015 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3016 return NT_STATUS_INVALID_PARAMETER;
3019 if (!prs_set_offset(
3021 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3022 return NT_STATUS_INVALID_PARAMETER;
3025 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3026 return NT_STATUS_INVALID_PARAMETER;
3029 /* TODO - check auth_type/auth_level match. */
3031 server_response = data_blob_talloc(talloc_tos(), NULL, r->auth_length);
3032 prs_copy_data_out((char *)server_response.data, reply_pdu,
3035 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3036 server_response, &client_reply);
3038 if (!NT_STATUS_IS_OK(status)) {
3039 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
3040 "blob failed: %s.\n", nt_errstr(status)));
3044 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
3046 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
3047 state->cli->auth->auth_type,
3048 state->cli->auth->auth_level,
3049 &client_reply, &state->rpc_out);
3050 data_blob_free(&client_reply);
3052 if (!NT_STATUS_IS_OK(status)) {
3056 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3057 (uint8_t *)prs_data_p(&state->rpc_out),
3058 prs_offset(&state->rpc_out));
3059 if (subreq == NULL) {
3060 return NT_STATUS_NO_MEMORY;
3062 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3063 return NT_STATUS_OK;
3066 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3068 struct tevent_req *req = tevent_req_callback_data(
3069 subreq, struct tevent_req);
3072 status = rpc_write_recv(subreq);
3073 TALLOC_FREE(subreq);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 tevent_req_nterror(req, status);
3078 tevent_req_done(req);
3081 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3082 struct rpc_pipe_bind_state *state,
3083 struct ncacn_packet *r,
3086 DATA_BLOB server_ntlm_response = data_blob_null;
3087 DATA_BLOB client_reply = data_blob_null;
3088 DATA_BLOB tmp_blob = data_blob_null;
3089 struct dcerpc_auth auth_info;
3090 DATA_BLOB auth_blob;
3091 struct tevent_req *subreq;
3094 if ((r->auth_length == 0)
3095 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3096 return NT_STATUS_INVALID_PARAMETER;
3099 /* Process the returned NTLMSSP blob first. */
3100 if (!prs_set_offset(
3102 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3103 return NT_STATUS_INVALID_PARAMETER;
3106 auth_blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in),
3107 prs_data_size(rpc_in) - prs_offset(rpc_in));
3109 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
3110 if (!NT_STATUS_IS_OK(status)) {
3111 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
3116 * The server might give us back two challenges - tmp_blob is for the
3119 if (!spnego_parse_challenge(auth_info.credentials,
3120 &server_ntlm_response, &tmp_blob)) {
3121 data_blob_free(&server_ntlm_response);
3122 data_blob_free(&tmp_blob);
3123 return NT_STATUS_INVALID_PARAMETER;
3126 /* We're finished with the server spnego response and the tmp_blob. */
3127 data_blob_free(&tmp_blob);
3129 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3130 server_ntlm_response, &client_reply);
3132 /* Finished with the server_ntlm response */
3133 data_blob_free(&server_ntlm_response);
3135 if (!NT_STATUS_IS_OK(status)) {
3136 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3137 "using server blob failed.\n"));
3138 data_blob_free(&client_reply);
3142 /* SPNEGO wrap the client reply. */
3143 tmp_blob = spnego_gen_auth(client_reply);
3144 data_blob_free(&client_reply);
3145 client_reply = tmp_blob;
3146 tmp_blob = data_blob_null;
3148 /* Now prepare the alter context pdu. */
3149 prs_init_empty(&state->rpc_out, state, MARSHALL);
3151 status = create_rpc_alter_context(state->rpc_call_id,
3152 &state->cli->abstract_syntax,
3153 &state->cli->transfer_syntax,
3154 state->cli->auth->auth_level,
3157 data_blob_free(&client_reply);
3159 if (!NT_STATUS_IS_OK(status)) {
3163 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3164 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3165 if (subreq == NULL) {
3166 return NT_STATUS_NO_MEMORY;
3168 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3169 return NT_STATUS_OK;
3172 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3174 struct tevent_req *req = tevent_req_callback_data(
3175 subreq, struct tevent_req);
3176 struct rpc_pipe_bind_state *state = tevent_req_data(
3177 req, struct rpc_pipe_bind_state);
3178 DATA_BLOB server_spnego_response = data_blob_null;
3179 DATA_BLOB tmp_blob = data_blob_null;
3180 prs_struct reply_pdu;
3181 struct ncacn_packet_header hdr;
3182 struct rpc_hdr_auth_info hdr_auth;
3185 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3186 TALLOC_FREE(subreq);
3187 if (!NT_STATUS_IS_OK(status)) {
3188 tevent_req_nterror(req, status);
3192 status = parse_rpc_header(state->cli, &hdr, &reply_pdu);
3193 if (!NT_STATUS_IS_OK(status)) {
3194 tevent_req_nterror(req, status);
3198 if (!prs_set_offset(
3200 hdr.frag_length - hdr.auth_length - RPC_HDR_AUTH_LEN)) {
3201 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3205 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3206 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3210 server_spnego_response = data_blob(NULL, hdr.auth_length);
3211 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3214 /* Check we got a valid auth response. */
3215 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3216 OID_NTLMSSP, &tmp_blob)) {
3217 data_blob_free(&server_spnego_response);
3218 data_blob_free(&tmp_blob);
3219 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3223 data_blob_free(&server_spnego_response);
3224 data_blob_free(&tmp_blob);
3226 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3227 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3228 tevent_req_done(req);
3231 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3233 return tevent_req_simple_recv_ntstatus(req);
3236 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3237 struct cli_pipe_auth_data *auth)
3239 TALLOC_CTX *frame = talloc_stackframe();
3240 struct event_context *ev;
3241 struct tevent_req *req;
3242 NTSTATUS status = NT_STATUS_OK;
3244 ev = event_context_init(frame);
3246 status = NT_STATUS_NO_MEMORY;
3250 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3252 status = NT_STATUS_NO_MEMORY;
3256 if (!tevent_req_poll(req, ev)) {
3257 status = map_nt_error_from_unix(errno);
3261 status = rpc_pipe_bind_recv(req);
3267 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3269 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3270 unsigned int timeout)
3274 if (rpc_cli->transport == NULL) {
3275 return RPCCLI_DEFAULT_TIMEOUT;
3278 if (rpc_cli->transport->set_timeout == NULL) {
3279 return RPCCLI_DEFAULT_TIMEOUT;
3282 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3284 return RPCCLI_DEFAULT_TIMEOUT;
3290 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3292 if (rpc_cli == NULL) {
3296 if (rpc_cli->transport == NULL) {
3300 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3303 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3305 struct cli_state *cli;
3307 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3308 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3309 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3313 cli = rpc_pipe_np_smb_conn(rpc_cli);
3317 E_md4hash(cli->password ? cli->password : "", nt_hash);
3321 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3322 struct cli_pipe_auth_data **presult)
3324 struct cli_pipe_auth_data *result;
3326 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3327 if (result == NULL) {
3328 return NT_STATUS_NO_MEMORY;
3331 result->auth_type = PIPE_AUTH_TYPE_NONE;
3332 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3334 result->user_name = talloc_strdup(result, "");
3335 result->domain = talloc_strdup(result, "");
3336 if ((result->user_name == NULL) || (result->domain == NULL)) {
3337 TALLOC_FREE(result);
3338 return NT_STATUS_NO_MEMORY;
3342 return NT_STATUS_OK;
3345 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3347 ntlmssp_end(&auth->a_u.ntlmssp_state);
3351 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3352 enum pipe_auth_type auth_type,
3353 enum dcerpc_AuthLevel auth_level,
3355 const char *username,
3356 const char *password,
3357 struct cli_pipe_auth_data **presult)
3359 struct cli_pipe_auth_data *result;
3362 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3363 if (result == NULL) {
3364 return NT_STATUS_NO_MEMORY;
3367 result->auth_type = auth_type;
3368 result->auth_level = auth_level;
3370 result->user_name = talloc_strdup(result, username);
3371 result->domain = talloc_strdup(result, domain);
3372 if ((result->user_name == NULL) || (result->domain == NULL)) {
3373 status = NT_STATUS_NO_MEMORY;
3377 status = ntlmssp_client_start(NULL,
3380 lp_client_ntlmv2_auth(),
3381 &result->a_u.ntlmssp_state);
3382 if (!NT_STATUS_IS_OK(status)) {
3386 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3388 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3389 if (!NT_STATUS_IS_OK(status)) {
3393 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3394 if (!NT_STATUS_IS_OK(status)) {
3398 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3399 if (!NT_STATUS_IS_OK(status)) {
3404 * Turn off sign+seal to allow selected auth level to turn it back on.
3406 result->a_u.ntlmssp_state->neg_flags &=
3407 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3409 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3410 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3411 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3412 result->a_u.ntlmssp_state->neg_flags
3413 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3417 return NT_STATUS_OK;
3420 TALLOC_FREE(result);
3424 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3425 enum dcerpc_AuthLevel auth_level,
3426 struct netlogon_creds_CredentialState *creds,
3427 struct cli_pipe_auth_data **presult)
3429 struct cli_pipe_auth_data *result;
3431 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3432 if (result == NULL) {
3433 return NT_STATUS_NO_MEMORY;
3436 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3437 result->auth_level = auth_level;
3439 result->user_name = talloc_strdup(result, "");
3440 result->domain = talloc_strdup(result, domain);
3441 if ((result->user_name == NULL) || (result->domain == NULL)) {
3445 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3446 if (result->a_u.schannel_auth == NULL) {
3450 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3451 result->a_u.schannel_auth->seq_num = 0;
3452 result->a_u.schannel_auth->initiator = true;
3453 result->a_u.schannel_auth->creds = creds;
3456 return NT_STATUS_OK;
3459 TALLOC_FREE(result);
3460 return NT_STATUS_NO_MEMORY;
3464 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3466 data_blob_free(&auth->session_key);
3471 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3472 enum dcerpc_AuthLevel auth_level,
3473 const char *service_princ,
3474 const char *username,
3475 const char *password,
3476 struct cli_pipe_auth_data **presult)
3479 struct cli_pipe_auth_data *result;
3481 if ((username != NULL) && (password != NULL)) {
3482 int ret = kerberos_kinit_password(username, password, 0, NULL);
3484 return NT_STATUS_ACCESS_DENIED;
3488 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3489 if (result == NULL) {
3490 return NT_STATUS_NO_MEMORY;
3493 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3494 result->auth_level = auth_level;
3497 * Username / domain need fixing!
3499 result->user_name = talloc_strdup(result, "");
3500 result->domain = talloc_strdup(result, "");
3501 if ((result->user_name == NULL) || (result->domain == NULL)) {
3505 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3506 result, struct kerberos_auth_struct);
3507 if (result->a_u.kerberos_auth == NULL) {
3510 talloc_set_destructor(result->a_u.kerberos_auth,
3511 cli_auth_kerberos_data_destructor);
3513 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3514 result, service_princ);
3515 if (result->a_u.kerberos_auth->service_principal == NULL) {
3520 return NT_STATUS_OK;
3523 TALLOC_FREE(result);
3524 return NT_STATUS_NO_MEMORY;
3526 return NT_STATUS_NOT_SUPPORTED;
3531 * Create an rpc pipe client struct, connecting to a tcp port.
3533 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3535 const struct ndr_syntax_id *abstract_syntax,
3536 struct rpc_pipe_client **presult)
3538 struct rpc_pipe_client *result;
3539 struct sockaddr_storage addr;
3543 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3544 if (result == NULL) {
3545 return NT_STATUS_NO_MEMORY;
3548 result->abstract_syntax = *abstract_syntax;
3549 result->transfer_syntax = ndr_transfer_syntax;
3550 result->dispatch = cli_do_rpc_ndr;
3551 result->dispatch_send = cli_do_rpc_ndr_send;
3552 result->dispatch_recv = cli_do_rpc_ndr_recv;
3554 result->desthost = talloc_strdup(result, host);
3555 result->srv_name_slash = talloc_asprintf_strupper_m(
3556 result, "\\\\%s", result->desthost);
3557 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3558 status = NT_STATUS_NO_MEMORY;
3562 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3563 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3565 if (!resolve_name(host, &addr, 0, false)) {
3566 status = NT_STATUS_NOT_FOUND;
3570 status = open_socket_out(&addr, port, 60, &fd);
3571 if (!NT_STATUS_IS_OK(status)) {
3574 set_socket_options(fd, lp_socket_options());
3576 status = rpc_transport_sock_init(result, fd, &result->transport);
3577 if (!NT_STATUS_IS_OK(status)) {
3582 result->transport->transport = NCACN_IP_TCP;
3585 return NT_STATUS_OK;
3588 TALLOC_FREE(result);
3593 * Determine the tcp port on which a dcerpc interface is listening
3594 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3597 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3598 const struct ndr_syntax_id *abstract_syntax,
3602 struct rpc_pipe_client *epm_pipe = NULL;
3603 struct cli_pipe_auth_data *auth = NULL;
3604 struct dcerpc_binding *map_binding = NULL;
3605 struct dcerpc_binding *res_binding = NULL;
3606 struct epm_twr_t *map_tower = NULL;
3607 struct epm_twr_t *res_towers = NULL;
3608 struct policy_handle *entry_handle = NULL;
3609 uint32_t num_towers = 0;
3610 uint32_t max_towers = 1;
3611 struct epm_twr_p_t towers;
3612 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3614 if (pport == NULL) {
3615 status = NT_STATUS_INVALID_PARAMETER;
3619 /* open the connection to the endpoint mapper */
3620 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3621 &ndr_table_epmapper.syntax_id,
3624 if (!NT_STATUS_IS_OK(status)) {
3628 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3629 if (!NT_STATUS_IS_OK(status)) {
3633 status = rpc_pipe_bind(epm_pipe, auth);
3634 if (!NT_STATUS_IS_OK(status)) {
3638 /* create tower for asking the epmapper */
3640 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3641 if (map_binding == NULL) {
3642 status = NT_STATUS_NO_MEMORY;
3646 map_binding->transport = NCACN_IP_TCP;
3647 map_binding->object = *abstract_syntax;
3648 map_binding->host = host; /* needed? */
3649 map_binding->endpoint = "0"; /* correct? needed? */
3651 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3652 if (map_tower == NULL) {
3653 status = NT_STATUS_NO_MEMORY;
3657 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3658 &(map_tower->tower));
3659 if (!NT_STATUS_IS_OK(status)) {
3663 /* allocate further parameters for the epm_Map call */
3665 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3666 if (res_towers == NULL) {
3667 status = NT_STATUS_NO_MEMORY;
3670 towers.twr = res_towers;
3672 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3673 if (entry_handle == NULL) {
3674 status = NT_STATUS_NO_MEMORY;
3678 /* ask the endpoint mapper for the port */
3680 status = rpccli_epm_Map(epm_pipe,
3682 CONST_DISCARD(struct GUID *,
3683 &(abstract_syntax->uuid)),
3690 if (!NT_STATUS_IS_OK(status)) {
3694 if (num_towers != 1) {
3695 status = NT_STATUS_UNSUCCESSFUL;
3699 /* extract the port from the answer */
3701 status = dcerpc_binding_from_tower(tmp_ctx,
3702 &(towers.twr->tower),
3704 if (!NT_STATUS_IS_OK(status)) {
3708 /* are further checks here necessary? */
3709 if (res_binding->transport != NCACN_IP_TCP) {
3710 status = NT_STATUS_UNSUCCESSFUL;
3714 *pport = (uint16_t)atoi(res_binding->endpoint);
3717 TALLOC_FREE(tmp_ctx);
3722 * Create a rpc pipe client struct, connecting to a host via tcp.
3723 * The port is determined by asking the endpoint mapper on the given
3726 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3727 const struct ndr_syntax_id *abstract_syntax,
3728 struct rpc_pipe_client **presult)
3733 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3734 if (!NT_STATUS_IS_OK(status)) {
3738 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3739 abstract_syntax, presult);
3742 /********************************************************************
3743 Create a rpc pipe client struct, connecting to a unix domain socket
3744 ********************************************************************/
3745 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3746 const struct ndr_syntax_id *abstract_syntax,
3747 struct rpc_pipe_client **presult)
3749 struct rpc_pipe_client *result;
3750 struct sockaddr_un addr;
3754 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3755 if (result == NULL) {
3756 return NT_STATUS_NO_MEMORY;
3759 result->abstract_syntax = *abstract_syntax;
3760 result->transfer_syntax = ndr_transfer_syntax;
3761 result->dispatch = cli_do_rpc_ndr;
3762 result->dispatch_send = cli_do_rpc_ndr_send;
3763 result->dispatch_recv = cli_do_rpc_ndr_recv;
3765 result->desthost = get_myname(result);
3766 result->srv_name_slash = talloc_asprintf_strupper_m(
3767 result, "\\\\%s", result->desthost);
3768 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3769 status = NT_STATUS_NO_MEMORY;
3773 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3774 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3776 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3778 status = map_nt_error_from_unix(errno);
3783 addr.sun_family = AF_UNIX;
3784 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3786 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3787 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3790 return map_nt_error_from_unix(errno);
3793 status = rpc_transport_sock_init(result, fd, &result->transport);
3794 if (!NT_STATUS_IS_OK(status)) {
3799 result->transport->transport = NCALRPC;
3802 return NT_STATUS_OK;
3805 TALLOC_FREE(result);
3809 struct rpc_pipe_client_np_ref {
3810 struct cli_state *cli;
3811 struct rpc_pipe_client *pipe;
3814 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3816 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3820 /****************************************************************************
3821 Open a named pipe over SMB to a remote server.
3823 * CAVEAT CALLER OF THIS FUNCTION:
3824 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3825 * so be sure that this function is called AFTER any structure (vs pointer)
3826 * assignment of the cli. In particular, libsmbclient does structure
3827 * assignments of cli, which invalidates the data in the returned
3828 * rpc_pipe_client if this function is called before the structure assignment
3831 ****************************************************************************/
3833 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3834 const struct ndr_syntax_id *abstract_syntax,
3835 struct rpc_pipe_client **presult)
3837 struct rpc_pipe_client *result;
3839 struct rpc_pipe_client_np_ref *np_ref;
3841 /* sanity check to protect against crashes */
3844 return NT_STATUS_INVALID_HANDLE;
3847 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3848 if (result == NULL) {
3849 return NT_STATUS_NO_MEMORY;
3852 result->abstract_syntax = *abstract_syntax;
3853 result->transfer_syntax = ndr_transfer_syntax;
3854 result->dispatch = cli_do_rpc_ndr;
3855 result->dispatch_send = cli_do_rpc_ndr_send;
3856 result->dispatch_recv = cli_do_rpc_ndr_recv;
3857 result->desthost = talloc_strdup(result, cli->desthost);
3858 result->srv_name_slash = talloc_asprintf_strupper_m(
3859 result, "\\\\%s", result->desthost);
3861 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3862 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3864 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3865 TALLOC_FREE(result);
3866 return NT_STATUS_NO_MEMORY;
3869 status = rpc_transport_np_init(result, cli, abstract_syntax,
3870 &result->transport);
3871 if (!NT_STATUS_IS_OK(status)) {
3872 TALLOC_FREE(result);
3876 result->transport->transport = NCACN_NP;
3878 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3879 if (np_ref == NULL) {
3880 TALLOC_FREE(result);
3881 return NT_STATUS_NO_MEMORY;
3884 np_ref->pipe = result;
3886 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3887 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3890 return NT_STATUS_OK;
3893 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3894 struct rpc_cli_smbd_conn *conn,
3895 const struct ndr_syntax_id *syntax,
3896 struct rpc_pipe_client **presult)
3898 struct rpc_pipe_client *result;
3899 struct cli_pipe_auth_data *auth;
3902 result = talloc(mem_ctx, struct rpc_pipe_client);
3903 if (result == NULL) {
3904 return NT_STATUS_NO_MEMORY;
3906 result->abstract_syntax = *syntax;
3907 result->transfer_syntax = ndr_transfer_syntax;
3908 result->dispatch = cli_do_rpc_ndr;
3909 result->dispatch_send = cli_do_rpc_ndr_send;
3910 result->dispatch_recv = cli_do_rpc_ndr_recv;
3911 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3912 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3914 result->desthost = talloc_strdup(result, global_myname());
3915 result->srv_name_slash = talloc_asprintf_strupper_m(
3916 result, "\\\\%s", global_myname());
3917 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3918 TALLOC_FREE(result);
3919 return NT_STATUS_NO_MEMORY;
3922 status = rpc_transport_smbd_init(result, conn, syntax,
3923 &result->transport);
3924 if (!NT_STATUS_IS_OK(status)) {
3925 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3926 nt_errstr(status)));
3927 TALLOC_FREE(result);
3931 status = rpccli_anon_bind_data(result, &auth);
3932 if (!NT_STATUS_IS_OK(status)) {
3933 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3934 nt_errstr(status)));
3935 TALLOC_FREE(result);
3939 status = rpc_pipe_bind(result, auth);
3940 if (!NT_STATUS_IS_OK(status)) {
3941 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3942 TALLOC_FREE(result);
3946 result->transport->transport = NCACN_INTERNAL;
3949 return NT_STATUS_OK;
3952 /****************************************************************************
3953 Open a pipe to a remote server.
3954 ****************************************************************************/
3956 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3957 enum dcerpc_transport_t transport,
3958 const struct ndr_syntax_id *interface,
3959 struct rpc_pipe_client **presult)
3961 switch (transport) {
3963 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3966 return rpc_pipe_open_np(cli, interface, presult);
3968 return NT_STATUS_NOT_IMPLEMENTED;
3972 /****************************************************************************
3973 Open a named pipe to an SMB server and bind anonymously.
3974 ****************************************************************************/
3976 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3977 enum dcerpc_transport_t transport,
3978 const struct ndr_syntax_id *interface,
3979 struct rpc_pipe_client **presult)
3981 struct rpc_pipe_client *result;
3982 struct cli_pipe_auth_data *auth;
3985 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3986 if (!NT_STATUS_IS_OK(status)) {
3990 status = rpccli_anon_bind_data(result, &auth);
3991 if (!NT_STATUS_IS_OK(status)) {
3992 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3993 nt_errstr(status)));
3994 TALLOC_FREE(result);
3999 * This is a bit of an abstraction violation due to the fact that an
4000 * anonymous bind on an authenticated SMB inherits the user/domain
4001 * from the enclosing SMB creds
4004 TALLOC_FREE(auth->user_name);
4005 TALLOC_FREE(auth->domain);
4007 auth->user_name = talloc_strdup(auth, cli->user_name);
4008 auth->domain = talloc_strdup(auth, cli->domain);
4009 auth->user_session_key = data_blob_talloc(auth,
4010 cli->user_session_key.data,
4011 cli->user_session_key.length);
4013 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
4014 TALLOC_FREE(result);
4015 return NT_STATUS_NO_MEMORY;
4018 status = rpc_pipe_bind(result, auth);
4019 if (!NT_STATUS_IS_OK(status)) {
4021 if (ndr_syntax_id_equal(interface,
4022 &ndr_table_dssetup.syntax_id)) {
4023 /* non AD domains just don't have this pipe, avoid
4024 * level 0 statement in that case - gd */
4027 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
4028 "%s failed with error %s\n",
4029 get_pipe_name_from_syntax(talloc_tos(), interface),
4030 nt_errstr(status) ));
4031 TALLOC_FREE(result);
4035 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
4036 "%s and bound anonymously.\n",
4037 get_pipe_name_from_syntax(talloc_tos(), interface),
4041 return NT_STATUS_OK;
4044 /****************************************************************************
4045 ****************************************************************************/
4047 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4048 const struct ndr_syntax_id *interface,
4049 struct rpc_pipe_client **presult)
4051 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4052 interface, presult);
4055 /****************************************************************************
4056 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4057 ****************************************************************************/
4059 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4060 const struct ndr_syntax_id *interface,
4061 enum dcerpc_transport_t transport,
4062 enum pipe_auth_type auth_type,
4063 enum dcerpc_AuthLevel auth_level,
4065 const char *username,
4066 const char *password,
4067 struct rpc_pipe_client **presult)
4069 struct rpc_pipe_client *result;
4070 struct cli_pipe_auth_data *auth;
4073 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4074 if (!NT_STATUS_IS_OK(status)) {
4078 status = rpccli_ntlmssp_bind_data(
4079 result, auth_type, auth_level, domain, username,
4081 if (!NT_STATUS_IS_OK(status)) {
4082 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4083 nt_errstr(status)));
4087 status = rpc_pipe_bind(result, auth);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4090 nt_errstr(status) ));
4094 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4095 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4096 get_pipe_name_from_syntax(talloc_tos(), interface),
4097 cli->desthost, domain, username ));
4100 return NT_STATUS_OK;
4104 TALLOC_FREE(result);
4108 /****************************************************************************
4110 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4111 ****************************************************************************/
4113 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4114 const struct ndr_syntax_id *interface,
4115 enum dcerpc_transport_t transport,
4116 enum dcerpc_AuthLevel auth_level,
4118 const char *username,
4119 const char *password,
4120 struct rpc_pipe_client **presult)
4122 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4125 PIPE_AUTH_TYPE_NTLMSSP,
4133 /****************************************************************************
4135 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4136 ****************************************************************************/
4138 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4139 const struct ndr_syntax_id *interface,
4140 enum dcerpc_transport_t transport,
4141 enum dcerpc_AuthLevel auth_level,
4143 const char *username,
4144 const char *password,
4145 struct rpc_pipe_client **presult)
4147 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4150 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4158 /****************************************************************************
4159 Get a the schannel session key out of an already opened netlogon pipe.
4160 ****************************************************************************/
4161 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4162 struct cli_state *cli,
4166 enum netr_SchannelType sec_chan_type = 0;
4167 unsigned char machine_pwd[16];
4168 const char *machine_account;
4171 /* Get the machine account credentials from secrets.tdb. */
4172 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4175 DEBUG(0, ("get_schannel_session_key: could not fetch "
4176 "trust account password for domain '%s'\n",
4178 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4181 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4182 cli->desthost, /* server name */
4183 domain, /* domain */
4184 global_myname(), /* client name */
4185 machine_account, /* machine account name */
4190 if (!NT_STATUS_IS_OK(status)) {
4191 DEBUG(3, ("get_schannel_session_key_common: "
4192 "rpccli_netlogon_setup_creds failed with result %s "
4193 "to server %s, domain %s, machine account %s.\n",
4194 nt_errstr(status), cli->desthost, domain,
4199 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4200 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4202 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4205 return NT_STATUS_OK;;
4208 /****************************************************************************
4209 Open a netlogon pipe and get the schannel session key.
4210 Now exposed to external callers.
4211 ****************************************************************************/
4214 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4217 struct rpc_pipe_client **presult)
4219 struct rpc_pipe_client *netlogon_pipe = NULL;
4222 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4224 if (!NT_STATUS_IS_OK(status)) {
4228 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4230 if (!NT_STATUS_IS_OK(status)) {
4231 TALLOC_FREE(netlogon_pipe);
4235 *presult = netlogon_pipe;
4236 return NT_STATUS_OK;
4239 /****************************************************************************
4241 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4242 using session_key. sign and seal.
4244 The *pdc will be stolen onto this new pipe
4245 ****************************************************************************/
4247 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4248 const struct ndr_syntax_id *interface,
4249 enum dcerpc_transport_t transport,
4250 enum dcerpc_AuthLevel auth_level,
4252 struct netlogon_creds_CredentialState **pdc,
4253 struct rpc_pipe_client **presult)
4255 struct rpc_pipe_client *result;
4256 struct cli_pipe_auth_data *auth;
4259 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4260 if (!NT_STATUS_IS_OK(status)) {
4264 status = rpccli_schannel_bind_data(result, domain, auth_level,
4266 if (!NT_STATUS_IS_OK(status)) {
4267 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4268 nt_errstr(status)));
4269 TALLOC_FREE(result);
4273 status = rpc_pipe_bind(result, auth);
4274 if (!NT_STATUS_IS_OK(status)) {
4275 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4276 "cli_rpc_pipe_bind failed with error %s\n",
4277 nt_errstr(status) ));
4278 TALLOC_FREE(result);
4283 * The credentials on a new netlogon pipe are the ones we are passed
4284 * in - reference them in
4286 result->dc = talloc_move(result, pdc);
4288 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4289 "for domain %s and bound using schannel.\n",
4290 get_pipe_name_from_syntax(talloc_tos(), interface),
4291 cli->desthost, domain ));
4294 return NT_STATUS_OK;
4297 /****************************************************************************
4298 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4299 Fetch the session key ourselves using a temporary netlogon pipe. This
4300 version uses an ntlmssp auth bound netlogon pipe to get the key.
4301 ****************************************************************************/
4303 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4305 const char *username,
4306 const char *password,
4308 struct rpc_pipe_client **presult)
4310 struct rpc_pipe_client *netlogon_pipe = NULL;
4313 status = cli_rpc_pipe_open_spnego_ntlmssp(
4314 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4315 DCERPC_AUTH_LEVEL_PRIVACY,
4316 domain, username, password, &netlogon_pipe);
4317 if (!NT_STATUS_IS_OK(status)) {
4321 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4323 if (!NT_STATUS_IS_OK(status)) {
4324 TALLOC_FREE(netlogon_pipe);
4328 *presult = netlogon_pipe;
4329 return NT_STATUS_OK;
4332 /****************************************************************************
4333 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4334 Fetch the session key ourselves using a temporary netlogon pipe. This version
4335 uses an ntlmssp bind to get the session key.
4336 ****************************************************************************/
4338 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4339 const struct ndr_syntax_id *interface,
4340 enum dcerpc_transport_t transport,
4341 enum dcerpc_AuthLevel auth_level,
4343 const char *username,
4344 const char *password,
4345 struct rpc_pipe_client **presult)
4347 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4348 struct rpc_pipe_client *netlogon_pipe = NULL;
4349 struct rpc_pipe_client *result = NULL;
4352 status = get_schannel_session_key_auth_ntlmssp(
4353 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4354 if (!NT_STATUS_IS_OK(status)) {
4355 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4356 "key from server %s for domain %s.\n",
4357 cli->desthost, domain ));
4361 status = cli_rpc_pipe_open_schannel_with_key(
4362 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4365 /* Now we've bound using the session key we can close the netlog pipe. */
4366 TALLOC_FREE(netlogon_pipe);
4368 if (NT_STATUS_IS_OK(status)) {
4374 /****************************************************************************
4375 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4376 Fetch the session key ourselves using a temporary netlogon pipe.
4377 ****************************************************************************/
4379 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4380 const struct ndr_syntax_id *interface,
4381 enum dcerpc_transport_t transport,
4382 enum dcerpc_AuthLevel auth_level,
4384 struct rpc_pipe_client **presult)
4386 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4387 struct rpc_pipe_client *netlogon_pipe = NULL;
4388 struct rpc_pipe_client *result = NULL;
4391 status = get_schannel_session_key(cli, domain, &neg_flags,
4393 if (!NT_STATUS_IS_OK(status)) {
4394 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4395 "key from server %s for domain %s.\n",
4396 cli->desthost, domain ));
4400 status = cli_rpc_pipe_open_schannel_with_key(
4401 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4404 /* Now we've bound using the session key we can close the netlog pipe. */
4405 TALLOC_FREE(netlogon_pipe);
4407 if (NT_STATUS_IS_OK(status)) {
4414 /****************************************************************************
4415 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4416 The idea is this can be called with service_princ, username and password all
4417 NULL so long as the caller has a TGT.
4418 ****************************************************************************/
4420 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4421 const struct ndr_syntax_id *interface,
4422 enum dcerpc_AuthLevel auth_level,
4423 const char *service_princ,
4424 const char *username,
4425 const char *password,
4426 struct rpc_pipe_client **presult)
4429 struct rpc_pipe_client *result;
4430 struct cli_pipe_auth_data *auth;
4433 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4434 if (!NT_STATUS_IS_OK(status)) {
4438 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4439 username, password, &auth);
4440 if (!NT_STATUS_IS_OK(status)) {
4441 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4442 nt_errstr(status)));
4443 TALLOC_FREE(result);
4447 status = rpc_pipe_bind(result, auth);
4448 if (!NT_STATUS_IS_OK(status)) {
4449 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4450 "with error %s\n", nt_errstr(status)));
4451 TALLOC_FREE(result);
4456 return NT_STATUS_OK;
4458 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4459 return NT_STATUS_NOT_IMPLEMENTED;
4463 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4464 struct rpc_pipe_client *cli,
4465 DATA_BLOB *session_key)
4467 if (!session_key || !cli) {
4468 return NT_STATUS_INVALID_PARAMETER;
4472 return NT_STATUS_INVALID_PARAMETER;
4475 switch (cli->auth->auth_type) {
4476 case PIPE_AUTH_TYPE_SCHANNEL:
4477 *session_key = data_blob_talloc(mem_ctx,
4478 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4480 case PIPE_AUTH_TYPE_NTLMSSP:
4481 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4482 *session_key = data_blob_talloc(mem_ctx,
4483 cli->auth->a_u.ntlmssp_state->session_key.data,
4484 cli->auth->a_u.ntlmssp_state->session_key.length);
4486 case PIPE_AUTH_TYPE_KRB5:
4487 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4488 *session_key = data_blob_talloc(mem_ctx,
4489 cli->auth->a_u.kerberos_auth->session_key.data,
4490 cli->auth->a_u.kerberos_auth->session_key.length);
4492 case PIPE_AUTH_TYPE_NONE:
4493 *session_key = data_blob_talloc(mem_ctx,
4494 cli->auth->user_session_key.data,
4495 cli->auth->user_session_key.length);
4498 return NT_STATUS_NO_USER_SESSION_KEY;
4501 return NT_STATUS_OK;