2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_lsa.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../librpc/gen_ndr/ndr_samr.h"
26 #include "../librpc/gen_ndr/ndr_netlogon.h"
27 #include "../librpc/gen_ndr/ndr_srvsvc.h"
28 #include "../librpc/gen_ndr/ndr_wkssvc.h"
29 #include "../librpc/gen_ndr/ndr_winreg.h"
30 #include "../librpc/gen_ndr/ndr_spoolss.h"
31 #include "../librpc/gen_ndr/ndr_dfs.h"
32 #include "../librpc/gen_ndr/ndr_echo.h"
33 #include "../librpc/gen_ndr/ndr_initshutdown.h"
34 #include "../librpc/gen_ndr/ndr_svcctl.h"
35 #include "../librpc/gen_ndr/ndr_eventlog.h"
36 #include "../librpc/gen_ndr/ndr_ntsvcs.h"
37 #include "../librpc/gen_ndr/ndr_epmapper.h"
38 #include "../librpc/gen_ndr/ndr_drsuapi.h"
39 #include "../libcli/auth/schannel.h"
40 #include "../libcli/auth/spnego.h"
42 #include "../libcli/auth/ntlmssp.h"
43 #include "rpc_client/cli_netlogon.h"
44 #include "librpc/gen_ndr/ndr_dcerpc.h"
47 #define DBGC_CLASS DBGC_RPC_CLI
49 static const char *get_pipe_name_from_iface(
50 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
53 const struct ndr_interface_string_array *ep = interface->endpoints;
56 for (i=0; i<ep->count; i++) {
57 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
66 * extract the pipe name without \\pipe from for example
67 * ncacn_np:[\\pipe\\epmapper]
69 p = strchr(ep->names[i]+15, ']');
73 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
76 static const struct ndr_interface_table **interfaces;
78 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
80 int num_interfaces = talloc_array_length(interfaces);
81 const struct ndr_interface_table **tmp;
84 for (i=0; i<num_interfaces; i++) {
85 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
86 &interface->syntax_id)) {
91 tmp = talloc_realloc(NULL, interfaces,
92 const struct ndr_interface_table *,
95 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
99 interfaces[num_interfaces] = interface;
103 static bool initialize_interfaces(void)
105 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
108 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
111 if (!smb_register_ndr_interface(&ndr_table_samr)) {
114 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
117 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
120 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
123 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
126 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
129 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
132 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
135 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
138 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
141 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
144 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
147 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
150 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
156 const struct ndr_interface_table *get_iface_from_syntax(
157 const struct ndr_syntax_id *syntax)
162 if (interfaces == NULL) {
163 if (!initialize_interfaces()) {
167 num_interfaces = talloc_array_length(interfaces);
169 for (i=0; i<num_interfaces; i++) {
170 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
171 return interfaces[i];
178 /****************************************************************************
179 Return the pipe name from the interface.
180 ****************************************************************************/
182 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
183 const struct ndr_syntax_id *syntax)
185 const struct ndr_interface_table *interface;
189 interface = get_iface_from_syntax(syntax);
190 if (interface != NULL) {
191 result = get_pipe_name_from_iface(mem_ctx, interface);
192 if (result != NULL) {
198 * Here we should ask \\epmapper, but for now our code is only
199 * interested in the known pipes mentioned in pipe_names[]
202 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
203 if (guid_str == NULL) {
206 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
207 (int)syntax->if_version);
208 TALLOC_FREE(guid_str);
210 if (result == NULL) {
216 /********************************************************************
217 Map internal value to wire value.
218 ********************************************************************/
220 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
224 case PIPE_AUTH_TYPE_NONE:
225 return DCERPC_AUTH_TYPE_NONE;
227 case PIPE_AUTH_TYPE_NTLMSSP:
228 return DCERPC_AUTH_TYPE_NTLMSSP;
230 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
231 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
232 return DCERPC_AUTH_TYPE_SPNEGO;
234 case PIPE_AUTH_TYPE_SCHANNEL:
235 return DCERPC_AUTH_TYPE_SCHANNEL;
237 case PIPE_AUTH_TYPE_KRB5:
238 return DCERPC_AUTH_TYPE_KRB5;
241 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
243 (unsigned int)auth_type ));
249 /********************************************************************
250 Pipe description for a DEBUG
251 ********************************************************************/
252 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
253 struct rpc_pipe_client *cli)
255 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
256 if (result == NULL) {
262 /********************************************************************
264 ********************************************************************/
266 static uint32 get_rpc_call_id(void)
268 static uint32 call_id = 0;
273 * Realloc pdu to have a least "size" bytes
276 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
280 if (prs_data_size(pdu) >= size) {
284 extra_size = size - prs_data_size(pdu);
286 if (!prs_force_grow(pdu, extra_size)) {
287 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
288 "%d bytes.\n", (int)extra_size));
292 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
293 (int)extra_size, prs_data_size(pdu)));
297 /*******************************************************************
298 *******************************************************************/
300 NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
301 enum dcerpc_pkt_type ptype,
303 uint16_t auth_length,
305 union dcerpc_payload *u,
308 struct ncacn_packet r;
309 enum ndr_err_code ndr_err;
312 r.rpc_vers_minor = 0;
314 r.pfc_flags = pfc_flags;
315 r.drep[0] = DCERPC_DREP_LE;
319 r.auth_length = auth_length;
323 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
324 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
325 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
326 return ndr_map_error2ntstatus(ndr_err);
329 dcerpc_set_frag_length(blob, blob->length);
332 if (DEBUGLEVEL >= 10) {
333 /* set frag len for print function */
334 r.frag_length = blob->length;
335 NDR_PRINT_DEBUG(ncacn_packet, &r);
341 NTSTATUS dcerpc_push_ncacn_packet_header(TALLOC_CTX *mem_ctx,
342 enum dcerpc_pkt_type ptype,
344 uint16_t frag_length,
345 uint16_t auth_length,
349 struct ncacn_packet_header r;
350 enum ndr_err_code ndr_err;
353 r.rpc_vers_minor = 0;
355 r.pfc_flags = pfc_flags;
356 r.drep[0] = DCERPC_DREP_LE;
360 r.frag_length = frag_length;
361 r.auth_length = auth_length;
364 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
365 (ndr_push_flags_fn_t)ndr_push_ncacn_packet_header);
366 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
367 return ndr_map_error2ntstatus(ndr_err);
370 if (DEBUGLEVEL >= 10) {
371 NDR_PRINT_DEBUG(ncacn_packet_header, &r);
377 /*******************************************************************
378 *******************************************************************/
380 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
381 const DATA_BLOB *blob,
382 struct ncacn_packet *r)
384 enum ndr_err_code ndr_err;
386 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
387 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
388 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
389 return ndr_map_error2ntstatus(ndr_err);
392 if (DEBUGLEVEL >= 10) {
393 NDR_PRINT_DEBUG(ncacn_packet, r);
399 /*******************************************************************
400 *******************************************************************/
402 NTSTATUS dcerpc_pull_ncacn_packet_header(TALLOC_CTX *mem_ctx,
403 const DATA_BLOB *blob,
404 struct ncacn_packet_header *r)
406 enum ndr_err_code ndr_err;
408 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
409 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet_header);
410 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
411 return ndr_map_error2ntstatus(ndr_err);
414 if (DEBUGLEVEL >= 10) {
415 NDR_PRINT_DEBUG(ncacn_packet_header, r);
421 /*******************************************************************
422 ********************************************************************/
424 static NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
425 struct NL_AUTH_MESSAGE *r,
428 enum ndr_err_code ndr_err;
430 ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
431 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
432 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
433 return ndr_map_error2ntstatus(ndr_err);
436 if (DEBUGLEVEL >= 10) {
437 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
443 /*******************************************************************
444 ********************************************************************/
446 NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
447 const DATA_BLOB *blob,
448 struct dcerpc_auth *r)
450 enum ndr_err_code ndr_err;
452 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
453 (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
454 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
455 return ndr_map_error2ntstatus(ndr_err);
458 if (DEBUGLEVEL >= 10) {
459 NDR_PRINT_DEBUG(dcerpc_auth, r);
465 /*******************************************************************
466 Use SMBreadX to get rest of one fragment's worth of rpc data.
467 Reads the whole size or give an error message
468 ********************************************************************/
470 struct rpc_read_state {
471 struct event_context *ev;
472 struct rpc_cli_transport *transport;
478 static void rpc_read_done(struct tevent_req *subreq);
480 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
481 struct event_context *ev,
482 struct rpc_cli_transport *transport,
483 uint8_t *data, size_t size)
485 struct tevent_req *req, *subreq;
486 struct rpc_read_state *state;
488 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
493 state->transport = transport;
498 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
500 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
502 if (subreq == NULL) {
505 tevent_req_set_callback(subreq, rpc_read_done, req);
513 static void rpc_read_done(struct tevent_req *subreq)
515 struct tevent_req *req = tevent_req_callback_data(
516 subreq, struct tevent_req);
517 struct rpc_read_state *state = tevent_req_data(
518 req, struct rpc_read_state);
522 status = state->transport->read_recv(subreq, &received);
524 if (!NT_STATUS_IS_OK(status)) {
525 tevent_req_nterror(req, status);
529 state->num_read += received;
530 if (state->num_read == state->size) {
531 tevent_req_done(req);
535 subreq = state->transport->read_send(state, state->ev,
536 state->data + state->num_read,
537 state->size - state->num_read,
538 state->transport->priv);
539 if (tevent_req_nomem(subreq, req)) {
542 tevent_req_set_callback(subreq, rpc_read_done, req);
545 static NTSTATUS rpc_read_recv(struct tevent_req *req)
547 return tevent_req_simple_recv_ntstatus(req);
550 struct rpc_write_state {
551 struct event_context *ev;
552 struct rpc_cli_transport *transport;
558 static void rpc_write_done(struct tevent_req *subreq);
560 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
561 struct event_context *ev,
562 struct rpc_cli_transport *transport,
563 const uint8_t *data, size_t size)
565 struct tevent_req *req, *subreq;
566 struct rpc_write_state *state;
568 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
573 state->transport = transport;
576 state->num_written = 0;
578 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
580 subreq = transport->write_send(state, ev, data, size, transport->priv);
581 if (subreq == NULL) {
584 tevent_req_set_callback(subreq, rpc_write_done, req);
591 static void rpc_write_done(struct tevent_req *subreq)
593 struct tevent_req *req = tevent_req_callback_data(
594 subreq, struct tevent_req);
595 struct rpc_write_state *state = tevent_req_data(
596 req, struct rpc_write_state);
600 status = state->transport->write_recv(subreq, &written);
602 if (!NT_STATUS_IS_OK(status)) {
603 tevent_req_nterror(req, status);
607 state->num_written += written;
609 if (state->num_written == state->size) {
610 tevent_req_done(req);
614 subreq = state->transport->write_send(state, state->ev,
615 state->data + state->num_written,
616 state->size - state->num_written,
617 state->transport->priv);
618 if (tevent_req_nomem(subreq, req)) {
621 tevent_req_set_callback(subreq, rpc_write_done, req);
624 static NTSTATUS rpc_write_recv(struct tevent_req *req)
626 return tevent_req_simple_recv_ntstatus(req);
630 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
631 struct ncacn_packet_header *prhdr,
635 DATA_BLOB blob = data_blob_const(prs_data_p(pdu), prs_data_size(pdu));
638 * This next call sets the endian bit correctly in current_pdu. We
639 * will propagate this to rbuf later.
642 status = dcerpc_pull_ncacn_packet_header(cli, &blob, prhdr);
643 if (!NT_STATUS_IS_OK(status)) {
647 if (!prs_set_offset(pdu, prs_offset(pdu) + RPC_HEADER_LEN)) {
648 return NT_STATUS_BUFFER_TOO_SMALL;
651 if (UNMARSHALLING(pdu) && prhdr->drep[0] == 0) {
652 DEBUG(10,("parse_rpc_header: PDU data format is big-endian. Setting flag.\n"));
653 prs_set_endian_data(pdu, RPC_BIG_ENDIAN);
656 if (prhdr->frag_length > cli->max_recv_frag) {
657 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
658 " we only allow %d\n", (int)prhdr->frag_length,
659 (int)cli->max_recv_frag));
660 return NT_STATUS_BUFFER_TOO_SMALL;
666 /****************************************************************************
667 Try and get a PDU's worth of data from current_pdu. If not, then read more
669 ****************************************************************************/
671 struct get_complete_frag_state {
672 struct event_context *ev;
673 struct rpc_pipe_client *cli;
678 static void get_complete_frag_got_header(struct tevent_req *subreq);
679 static void get_complete_frag_got_rest(struct tevent_req *subreq);
681 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
682 struct event_context *ev,
683 struct rpc_pipe_client *cli,
686 struct tevent_req *req, *subreq;
687 struct get_complete_frag_state *state;
692 req = tevent_req_create(mem_ctx, &state,
693 struct get_complete_frag_state);
699 state->frag_len = RPC_HEADER_LEN;
702 pdu_len = prs_data_size(pdu);
703 if (pdu_len < RPC_HEADER_LEN) {
704 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
705 status = NT_STATUS_NO_MEMORY;
708 subreq = rpc_read_send(
710 state->cli->transport,
711 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
712 RPC_HEADER_LEN - pdu_len);
713 if (subreq == NULL) {
714 status = NT_STATUS_NO_MEMORY;
717 tevent_req_set_callback(subreq, get_complete_frag_got_header,
722 blob = data_blob_const(prs_data_p(state->pdu), pdu_len);
723 state->frag_len = dcerpc_get_frag_length(&blob);
726 * Ensure we have frag_len bytes of data.
728 if (pdu_len < state->frag_len) {
729 if (!rpc_grow_buffer(pdu, state->frag_len)) {
730 status = NT_STATUS_NO_MEMORY;
733 subreq = rpc_read_send(state, state->ev,
734 state->cli->transport,
735 (uint8_t *)(prs_data_p(pdu) + pdu_len),
736 state->frag_len - pdu_len);
737 if (subreq == NULL) {
738 status = NT_STATUS_NO_MEMORY;
741 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
746 status = NT_STATUS_OK;
748 if (NT_STATUS_IS_OK(status)) {
749 tevent_req_done(req);
751 tevent_req_nterror(req, status);
753 return tevent_req_post(req, ev);
756 static void get_complete_frag_got_header(struct tevent_req *subreq)
758 struct tevent_req *req = tevent_req_callback_data(
759 subreq, struct tevent_req);
760 struct get_complete_frag_state *state = tevent_req_data(
761 req, struct get_complete_frag_state);
765 status = rpc_read_recv(subreq);
767 if (!NT_STATUS_IS_OK(status)) {
768 tevent_req_nterror(req, status);
772 pdu = data_blob_const(prs_data_p(state->pdu),
773 prs_data_size(state->pdu));
774 state->frag_len = dcerpc_get_frag_length(&pdu);
776 if (!rpc_grow_buffer(state->pdu, state->frag_len)) {
777 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
782 * We're here in this piece of code because we've read exactly
783 * RPC_HEADER_LEN bytes into state->pdu.
786 subreq = rpc_read_send(
787 state, state->ev, state->cli->transport,
788 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
789 state->frag_len - RPC_HEADER_LEN);
790 if (tevent_req_nomem(subreq, req)) {
793 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
796 static void get_complete_frag_got_rest(struct tevent_req *subreq)
798 struct tevent_req *req = tevent_req_callback_data(
799 subreq, struct tevent_req);
802 status = rpc_read_recv(subreq);
804 if (!NT_STATUS_IS_OK(status)) {
805 tevent_req_nterror(req, status);
808 tevent_req_done(req);
811 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
813 return tevent_req_simple_recv_ntstatus(req);
816 /****************************************************************************
817 NTLMSSP specific sign/seal.
818 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
819 In fact I should probably abstract these into identical pieces of code... JRA.
820 ****************************************************************************/
822 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
823 struct ncacn_packet_header *prhdr,
824 prs_struct *current_pdu,
825 uint8 *p_ss_padding_len)
827 struct dcerpc_auth auth_info;
828 uint32 save_offset = prs_offset(current_pdu);
829 uint32_t auth_len = prhdr->auth_length;
830 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
831 unsigned char *data = NULL;
833 unsigned char *full_packet_data = NULL;
834 size_t full_packet_data_len;
839 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
840 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
844 if (!ntlmssp_state) {
845 return NT_STATUS_INVALID_PARAMETER;
848 /* Ensure there's enough data for an authenticated response. */
849 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
850 prhdr->frag_length < RPC_HEADER_LEN +
852 RPC_HDR_AUTH_LEN + auth_len) {
853 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
854 (unsigned int)auth_len ));
855 return NT_STATUS_BUFFER_TOO_SMALL;
859 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
860 * after the RPC header.
861 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
862 * functions as NTLMv2 checks the rpc headers also.
865 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
866 data_len = (size_t)(prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
868 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
869 full_packet_data_len = prhdr->frag_length - auth_len;
871 /* Pull the auth header and the following data into a blob. */
872 /* NB. The offset of the auth_header is relative to the *end*
873 * of the packet, not the start. */
874 if(!prs_set_offset(current_pdu, prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
875 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
876 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
877 return NT_STATUS_BUFFER_TOO_SMALL;
880 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu),
881 prs_data_size(current_pdu) - prs_offset(current_pdu));
883 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
884 if (!NT_STATUS_IS_OK(status)) {
885 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
889 /* Ensure auth_pad_len fits into the packet. */
890 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
891 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
892 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
893 "too large (%u), auth_len (%u), frag_len = (%u).\n",
894 (unsigned int)auth_info.auth_pad_length,
895 (unsigned int)auth_len,
896 (unsigned int)prhdr->frag_length));
897 return NT_STATUS_BUFFER_TOO_SMALL;
901 auth_blob = auth_info.credentials;
903 switch (cli->auth->auth_level) {
904 case DCERPC_AUTH_LEVEL_PRIVACY:
905 /* Data is encrypted. */
906 status = ntlmssp_unseal_packet(ntlmssp_state,
909 full_packet_data_len,
911 if (!NT_STATUS_IS_OK(status)) {
912 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
913 "packet from %s. Error was %s.\n",
914 rpccli_pipe_txt(talloc_tos(), cli),
915 nt_errstr(status) ));
919 case DCERPC_AUTH_LEVEL_INTEGRITY:
920 /* Data is signed. */
921 status = ntlmssp_check_packet(ntlmssp_state,
924 full_packet_data_len,
926 if (!NT_STATUS_IS_OK(status)) {
927 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
928 "packet from %s. Error was %s.\n",
929 rpccli_pipe_txt(talloc_tos(), cli),
930 nt_errstr(status) ));
935 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
936 "auth level %d\n", cli->auth->auth_level));
937 return NT_STATUS_INVALID_INFO_CLASS;
941 * Return the current pointer to the data offset.
944 if(!prs_set_offset(current_pdu, save_offset)) {
945 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
946 (unsigned int)save_offset ));
947 return NT_STATUS_BUFFER_TOO_SMALL;
951 * Remember the padding length. We must remove it from the real data
952 * stream once the sign/seal is done.
955 *p_ss_padding_len = auth_info.auth_pad_length;
960 /****************************************************************************
961 schannel specific sign/seal.
962 ****************************************************************************/
964 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
965 struct ncacn_packet_header *prhdr,
966 prs_struct *current_pdu,
967 uint8 *p_ss_padding_len)
969 struct dcerpc_auth auth_info;
970 uint32_t auth_len = prhdr->auth_length;
971 uint32 save_offset = prs_offset(current_pdu);
972 struct schannel_state *schannel_auth =
973 cli->auth->a_u.schannel_auth;
979 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
980 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
984 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
985 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
986 return NT_STATUS_INVALID_PARAMETER;
989 if (!schannel_auth) {
990 return NT_STATUS_INVALID_PARAMETER;
993 /* Ensure there's enough data for an authenticated response. */
994 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
995 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length)) {
996 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
997 (unsigned int)auth_len ));
998 return NT_STATUS_INVALID_PARAMETER;
1001 data_len = prhdr->frag_length - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
1003 /* Pull the auth header and the following data into a blob. */
1004 /* NB. The offset of the auth_header is relative to the *end*
1005 * of the packet, not the start. */
1006 if(!prs_set_offset(current_pdu,
1007 prhdr->frag_length - RPC_HDR_AUTH_LEN - auth_len)) {
1008 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
1010 (unsigned int)(prhdr->frag_length -
1011 RPC_HDR_AUTH_LEN - auth_len) ));
1012 return NT_STATUS_BUFFER_TOO_SMALL;
1015 blob = data_blob_const(prs_data_p(current_pdu)
1016 + prs_offset(current_pdu),
1017 prs_data_size(current_pdu)
1018 - prs_offset(current_pdu));
1020 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info);
1021 if (!NT_STATUS_IS_OK(status)) {
1022 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
1026 /* Ensure auth_pad_len fits into the packet. */
1027 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_length +
1028 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_length) {
1029 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
1030 "too large (%u), auth_len (%u), frag_len = (%u).\n",
1031 (unsigned int)auth_info.auth_pad_length,
1032 (unsigned int)auth_len,
1033 (unsigned int)prhdr->frag_length));
1034 return NT_STATUS_BUFFER_TOO_SMALL;
1037 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1038 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
1039 auth_info.auth_type));
1040 return NT_STATUS_BUFFER_TOO_SMALL;
1043 blob = data_blob_const(prs_data_p(current_pdu) +
1044 prs_offset(current_pdu) +
1045 RPC_HDR_AUTH_LEN, auth_len);
1047 if (DEBUGLEVEL >= 10) {
1048 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1051 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
1053 switch (cli->auth->auth_level) {
1054 case DCERPC_AUTH_LEVEL_PRIVACY:
1055 status = netsec_incoming_packet(schannel_auth,
1062 case DCERPC_AUTH_LEVEL_INTEGRITY:
1063 status = netsec_incoming_packet(schannel_auth,
1071 status = NT_STATUS_INTERNAL_ERROR;
1075 if (!NT_STATUS_IS_OK(status)) {
1076 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
1077 "Connection to %s (%s).\n",
1078 rpccli_pipe_txt(talloc_tos(), cli),
1079 nt_errstr(status)));
1080 return NT_STATUS_INVALID_PARAMETER;
1084 * Return the current pointer to the data offset.
1087 if(!prs_set_offset(current_pdu, save_offset)) {
1088 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
1089 (unsigned int)save_offset ));
1090 return NT_STATUS_BUFFER_TOO_SMALL;
1094 * Remember the padding length. We must remove it from the real data
1095 * stream once the sign/seal is done.
1098 *p_ss_padding_len = auth_info.auth_pad_length;
1100 return NT_STATUS_OK;
1103 /****************************************************************************
1104 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
1105 ****************************************************************************/
1107 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
1108 struct ncacn_packet_header *prhdr,
1109 prs_struct *current_pdu,
1110 uint8 *p_ss_padding_len)
1112 NTSTATUS ret = NT_STATUS_OK;
1114 /* Paranioa checks for auth_len. */
1115 if (prhdr->auth_length) {
1116 if (prhdr->auth_length > prhdr->frag_length) {
1117 return NT_STATUS_INVALID_PARAMETER;
1120 if (prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_length ||
1121 prhdr->auth_length + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
1122 /* Integer wrap attempt. */
1123 return NT_STATUS_INVALID_PARAMETER;
1128 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1131 switch(cli->auth->auth_type) {
1132 case PIPE_AUTH_TYPE_NONE:
1133 if (prhdr->auth_length) {
1134 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1135 "Connection to %s - got non-zero "
1137 rpccli_pipe_txt(talloc_tos(), cli),
1138 (unsigned int)prhdr->auth_length));
1139 return NT_STATUS_INVALID_PARAMETER;
1143 case PIPE_AUTH_TYPE_NTLMSSP:
1144 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1145 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1146 if (!NT_STATUS_IS_OK(ret)) {
1151 case PIPE_AUTH_TYPE_SCHANNEL:
1152 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1153 if (!NT_STATUS_IS_OK(ret)) {
1158 case PIPE_AUTH_TYPE_KRB5:
1159 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1161 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1162 "to %s - unknown internal auth type %u.\n",
1163 rpccli_pipe_txt(talloc_tos(), cli),
1164 cli->auth->auth_type ));
1165 return NT_STATUS_INVALID_INFO_CLASS;
1168 return NT_STATUS_OK;
1171 /****************************************************************************
1172 Do basic authentication checks on an incoming pdu.
1173 ****************************************************************************/
1175 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli,
1176 struct ncacn_packet *pkt,
1177 prs_struct *current_pdu,
1178 uint8 expected_pkt_type,
1181 prs_struct *return_data)
1183 struct ncacn_packet_header prhdr;
1184 NTSTATUS ret = NT_STATUS_OK;
1185 uint32 current_pdu_len = prs_data_size(current_pdu);
1186 DATA_BLOB blob = data_blob_const(prs_data_p(current_pdu),
1187 prs_data_size(current_pdu));
1189 ret = dcerpc_pull_ncacn_packet(cli, &blob, pkt);
1190 if (!NT_STATUS_IS_OK(ret)) {
1194 /* FIXME: although we already unmarshalled the whole packet,
1195 * set the offset of the pdu to right after the header
1196 * until the rest of the code downstream is changed
1197 * to always use the already decoded packet and not try
1198 * to unmarshall bits of the packet.
1200 if (!prs_set_offset(current_pdu,
1201 prs_offset(current_pdu) + RPC_HEADER_LEN)) {
1202 return NT_STATUS_BUFFER_TOO_SMALL;
1205 /* FIXME: until all functions are converted to take in
1206 * a fully decoded packet
1208 memcpy(&prhdr, pkt, sizeof(prhdr));
1211 if (current_pdu_len != pkt->frag_length) {
1212 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
1213 (unsigned int)current_pdu_len,
1214 (unsigned int)pkt->frag_length));
1215 return NT_STATUS_INVALID_PARAMETER;
1219 * Point the return values at the real data including the RPC
1220 * header. Just in case the caller wants it.
1222 *ppdata = prs_data_p(current_pdu);
1223 *pdata_len = current_pdu_len;
1225 /* Ensure we have the correct type. */
1226 switch (pkt->ptype) {
1227 case DCERPC_PKT_ALTER_RESP:
1228 case DCERPC_PKT_BIND_ACK:
1230 /* Alter context and bind ack share the same packet definitions. */
1234 case DCERPC_PKT_RESPONSE:
1236 uint8 ss_padding_len = 0;
1238 if (!prs_set_offset(current_pdu, prs_offset(current_pdu) + RPC_HDR_RESP_LEN)) {
1239 return NT_STATUS_BUFFER_TOO_SMALL;
1242 /* Here's where we deal with incoming sign/seal. */
1243 ret = cli_pipe_validate_rpc_response(cli, &prhdr,
1244 current_pdu, &ss_padding_len);
1245 if (!NT_STATUS_IS_OK(ret)) {
1249 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1250 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1252 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1253 return NT_STATUS_BUFFER_TOO_SMALL;
1256 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1258 /* Remember to remove the auth footer. */
1259 if (pkt->auth_length) {
1260 /* We've already done integer wrap tests on auth_len in
1261 cli_pipe_validate_rpc_response(). */
1262 if (*pdata_len < RPC_HDR_AUTH_LEN + pkt->auth_length) {
1263 return NT_STATUS_BUFFER_TOO_SMALL;
1265 *pdata_len -= (RPC_HDR_AUTH_LEN + pkt->auth_length);
1268 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1269 current_pdu_len, *pdata_len, ss_padding_len ));
1272 * If this is the first reply, and the allocation hint is reasonably, try and
1273 * set up the return_data parse_struct to the correct size.
1276 if ((prs_data_size(return_data) == 0) &&
1277 pkt->u.response.alloc_hint &&
1278 (pkt->u.response.alloc_hint < 15*1024*1024)) {
1279 if (!prs_set_buffer_size(return_data,
1280 pkt->u.response.alloc_hint)) {
1281 DEBUG(0, ("reply alloc hint %d too "
1282 "large to allocate\n",
1283 (int)pkt->u.response.alloc_hint));
1284 return NT_STATUS_NO_MEMORY;
1291 case DCERPC_PKT_BIND_NAK:
1292 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1293 "received from %s!\n",
1294 rpccli_pipe_txt(talloc_tos(), cli)));
1295 /* Use this for now... */
1296 return NT_STATUS_NETWORK_ACCESS_DENIED;
1298 case DCERPC_PKT_FAULT:
1300 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1301 "code %s received from %s!\n",
1302 dcerpc_errstr(talloc_tos(),
1303 pkt->u.fault.status),
1304 rpccli_pipe_txt(talloc_tos(), cli)));
1306 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
1307 return NT_STATUS_UNSUCCESSFUL;
1309 return NT_STATUS(pkt->u.fault.status);
1313 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1315 (unsigned int)pkt->ptype,
1316 rpccli_pipe_txt(talloc_tos(), cli)));
1317 return NT_STATUS_INVALID_INFO_CLASS;
1320 if (pkt->ptype != expected_pkt_type) {
1321 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1322 "got an unexpected RPC packet type - %u, not %u\n",
1323 rpccli_pipe_txt(talloc_tos(), cli),
1325 expected_pkt_type));
1326 return NT_STATUS_INVALID_INFO_CLASS;
1329 /* Do this just before return - we don't want to modify any rpc header
1330 data before now as we may have needed to do cryptographic actions on
1333 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
1334 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1335 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1336 "setting fragment first/last ON.\n"));
1337 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
1338 DCERPC_PFC_FLAG_LAST;
1341 return NT_STATUS_OK;
1344 /****************************************************************************
1345 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1346 Normally the frag_len and buffer size will match, but on the first trans
1347 reply there is a theoretical chance that buffer size > frag_len, so we must
1349 ****************************************************************************/
1351 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli,
1352 struct ncacn_packet *pkt,
1353 prs_struct *current_pdu)
1355 uint32 current_pdu_len = prs_data_size(current_pdu);
1357 if (current_pdu_len < pkt->frag_length) {
1358 return NT_STATUS_BUFFER_TOO_SMALL;
1362 if (current_pdu_len == (uint32)pkt->frag_length) {
1363 prs_mem_free(current_pdu);
1364 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1365 /* Make current_pdu dynamic with no memory. */
1366 prs_give_memory(current_pdu, 0, 0, True);
1367 return NT_STATUS_OK;
1371 * Oh no ! More data in buffer than we processed in current pdu.
1372 * Cheat. Move the data down and shrink the buffer.
1375 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + pkt->frag_length,
1376 current_pdu_len - pkt->frag_length);
1378 /* Remember to set the read offset back to zero. */
1379 prs_set_offset(current_pdu, 0);
1381 /* Shrink the buffer. */
1382 if (!prs_set_buffer_size(current_pdu, current_pdu_len - pkt->frag_length)) {
1383 return NT_STATUS_BUFFER_TOO_SMALL;
1386 return NT_STATUS_OK;
1389 /****************************************************************************
1390 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1391 ****************************************************************************/
1393 struct cli_api_pipe_state {
1394 struct event_context *ev;
1395 struct rpc_cli_transport *transport;
1400 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1401 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1402 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1404 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1405 struct event_context *ev,
1406 struct rpc_cli_transport *transport,
1407 uint8_t *data, size_t data_len,
1408 uint32_t max_rdata_len)
1410 struct tevent_req *req, *subreq;
1411 struct cli_api_pipe_state *state;
1414 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1419 state->transport = transport;
1421 if (max_rdata_len < RPC_HEADER_LEN) {
1423 * For a RPC reply we always need at least RPC_HEADER_LEN
1424 * bytes. We check this here because we will receive
1425 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1427 status = NT_STATUS_INVALID_PARAMETER;
1431 if (transport->trans_send != NULL) {
1432 subreq = transport->trans_send(state, ev, data, data_len,
1433 max_rdata_len, transport->priv);
1434 if (subreq == NULL) {
1437 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1442 * If the transport does not provide a "trans" routine, i.e. for
1443 * example the ncacn_ip_tcp transport, do the write/read step here.
1446 subreq = rpc_write_send(state, ev, transport, data, data_len);
1447 if (subreq == NULL) {
1450 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1454 tevent_req_nterror(req, status);
1455 return tevent_req_post(req, ev);
1461 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1463 struct tevent_req *req = tevent_req_callback_data(
1464 subreq, struct tevent_req);
1465 struct cli_api_pipe_state *state = tevent_req_data(
1466 req, struct cli_api_pipe_state);
1469 status = state->transport->trans_recv(subreq, state, &state->rdata,
1471 TALLOC_FREE(subreq);
1472 if (!NT_STATUS_IS_OK(status)) {
1473 tevent_req_nterror(req, status);
1476 tevent_req_done(req);
1479 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1481 struct tevent_req *req = tevent_req_callback_data(
1482 subreq, struct tevent_req);
1483 struct cli_api_pipe_state *state = tevent_req_data(
1484 req, struct cli_api_pipe_state);
1487 status = rpc_write_recv(subreq);
1488 TALLOC_FREE(subreq);
1489 if (!NT_STATUS_IS_OK(status)) {
1490 tevent_req_nterror(req, status);
1494 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1495 if (tevent_req_nomem(state->rdata, req)) {
1500 * We don't need to use rpc_read_send here, the upper layer will cope
1501 * with a short read, transport->trans_send could also return less
1502 * than state->max_rdata_len.
1504 subreq = state->transport->read_send(state, state->ev, state->rdata,
1506 state->transport->priv);
1507 if (tevent_req_nomem(subreq, req)) {
1510 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1513 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1515 struct tevent_req *req = tevent_req_callback_data(
1516 subreq, struct tevent_req);
1517 struct cli_api_pipe_state *state = tevent_req_data(
1518 req, struct cli_api_pipe_state);
1522 status = state->transport->read_recv(subreq, &received);
1523 TALLOC_FREE(subreq);
1524 if (!NT_STATUS_IS_OK(status)) {
1525 tevent_req_nterror(req, status);
1528 state->rdata_len = received;
1529 tevent_req_done(req);
1532 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1533 uint8_t **prdata, uint32_t *prdata_len)
1535 struct cli_api_pipe_state *state = tevent_req_data(
1536 req, struct cli_api_pipe_state);
1539 if (tevent_req_is_nterror(req, &status)) {
1543 *prdata = talloc_move(mem_ctx, &state->rdata);
1544 *prdata_len = state->rdata_len;
1545 return NT_STATUS_OK;
1548 /****************************************************************************
1549 Send data on an rpc pipe via trans. The prs_struct data must be the last
1550 pdu fragment of an NDR data stream.
1552 Receive response data from an rpc pipe, which may be large...
1554 Read the first fragment: unfortunately have to use SMBtrans for the first
1555 bit, then SMBreadX for subsequent bits.
1557 If first fragment received also wasn't the last fragment, continue
1558 getting fragments until we _do_ receive the last fragment.
1560 Request/Response PDU's look like the following...
1562 |<------------------PDU len----------------------------------------------->|
1563 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1565 +------------+-----------------+-------------+---------------+-------------+
1566 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1567 +------------+-----------------+-------------+---------------+-------------+
1569 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1570 signing & sealing being negotiated.
1572 ****************************************************************************/
1574 struct rpc_api_pipe_state {
1575 struct event_context *ev;
1576 struct rpc_pipe_client *cli;
1577 uint8_t expected_pkt_type;
1579 prs_struct incoming_frag;
1580 struct ncacn_packet *pkt;
1582 prs_struct incoming_pdu; /* Incoming reply */
1583 uint32_t incoming_pdu_offset;
1586 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1587 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1589 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1590 struct event_context *ev,
1591 struct rpc_pipe_client *cli,
1592 prs_struct *data, /* Outgoing PDU */
1593 uint8_t expected_pkt_type)
1595 struct tevent_req *req, *subreq;
1596 struct rpc_api_pipe_state *state;
1597 uint16_t max_recv_frag;
1600 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1606 state->expected_pkt_type = expected_pkt_type;
1607 state->incoming_pdu_offset = 0;
1609 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1611 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1612 /* Make incoming_pdu dynamic with no memory. */
1613 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1616 * Ensure we're not sending too much.
1618 if (prs_offset(data) > cli->max_xmit_frag) {
1619 status = NT_STATUS_INVALID_PARAMETER;
1623 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1625 max_recv_frag = cli->max_recv_frag;
1628 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1631 subreq = cli_api_pipe_send(state, ev, cli->transport,
1632 (uint8_t *)prs_data_p(data),
1633 prs_offset(data), max_recv_frag);
1634 if (subreq == NULL) {
1637 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1641 tevent_req_nterror(req, status);
1642 return tevent_req_post(req, ev);
1648 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1650 struct tevent_req *req = tevent_req_callback_data(
1651 subreq, struct tevent_req);
1652 struct rpc_api_pipe_state *state = tevent_req_data(
1653 req, struct rpc_api_pipe_state);
1655 uint8_t *rdata = NULL;
1656 uint32_t rdata_len = 0;
1658 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1659 TALLOC_FREE(subreq);
1660 if (!NT_STATUS_IS_OK(status)) {
1661 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1662 tevent_req_nterror(req, status);
1666 if (rdata == NULL) {
1667 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1668 rpccli_pipe_txt(talloc_tos(), state->cli)));
1669 tevent_req_done(req);
1674 * This is equivalent to a talloc_steal - gives rdata to
1675 * the prs_struct state->incoming_frag.
1677 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1680 /* Ensure we have enough data for a pdu. */
1681 subreq = get_complete_frag_send(state, state->ev, state->cli,
1682 &state->incoming_frag);
1683 if (tevent_req_nomem(subreq, req)) {
1686 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1689 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1691 struct tevent_req *req = tevent_req_callback_data(
1692 subreq, struct tevent_req);
1693 struct rpc_api_pipe_state *state = tevent_req_data(
1694 req, struct rpc_api_pipe_state);
1697 uint32_t rdata_len = 0;
1699 status = get_complete_frag_recv(subreq);
1700 TALLOC_FREE(subreq);
1701 if (!NT_STATUS_IS_OK(status)) {
1702 DEBUG(5, ("get_complete_frag failed: %s\n",
1703 nt_errstr(status)));
1704 tevent_req_nterror(req, status);
1708 state->pkt = talloc(state, struct ncacn_packet);
1710 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1714 status = cli_pipe_validate_current_pdu(
1715 state->cli, state->pkt, &state->incoming_frag,
1716 state->expected_pkt_type, &rdata, &rdata_len,
1717 &state->incoming_pdu);
1719 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1720 (unsigned)prs_data_size(&state->incoming_frag),
1721 (unsigned)state->incoming_pdu_offset,
1722 nt_errstr(status)));
1724 if (!NT_STATUS_IS_OK(status)) {
1725 tevent_req_nterror(req, status);
1729 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1730 && (state->pkt->drep[0] == 0)) {
1732 * Set the data type correctly for big-endian data on the
1735 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1737 rpccli_pipe_txt(talloc_tos(), state->cli)));
1738 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1741 * Check endianness on subsequent packets.
1743 if (state->incoming_frag.bigendian_data
1744 != state->incoming_pdu.bigendian_data) {
1745 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1747 state->incoming_pdu.bigendian_data?"big":"little",
1748 state->incoming_frag.bigendian_data?"big":"little"));
1749 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1753 /* Now copy the data portion out of the pdu into rbuf. */
1754 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1755 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1759 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1760 rdata, (size_t)rdata_len);
1761 state->incoming_pdu_offset += rdata_len;
1763 status = cli_pipe_reset_current_pdu(state->cli, state->pkt,
1764 &state->incoming_frag);
1765 if (!NT_STATUS_IS_OK(status)) {
1766 tevent_req_nterror(req, status);
1770 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1771 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1772 rpccli_pipe_txt(talloc_tos(), state->cli),
1773 (unsigned)prs_data_size(&state->incoming_pdu)));
1774 tevent_req_done(req);
1778 subreq = get_complete_frag_send(state, state->ev, state->cli,
1779 &state->incoming_frag);
1780 if (tevent_req_nomem(subreq, req)) {
1783 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1786 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1787 prs_struct *reply_pdu)
1789 struct rpc_api_pipe_state *state = tevent_req_data(
1790 req, struct rpc_api_pipe_state);
1793 if (tevent_req_is_nterror(req, &status)) {
1797 *reply_pdu = state->incoming_pdu;
1798 reply_pdu->mem_ctx = mem_ctx;
1801 * Prevent state->incoming_pdu from being freed
1802 * when state is freed.
1804 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1805 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1807 return NT_STATUS_OK;
1810 /*******************************************************************
1811 Creates an auth_data blob.
1812 ********************************************************************/
1814 NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1815 enum dcerpc_AuthType auth_type,
1816 enum dcerpc_AuthLevel auth_level,
1817 uint8_t auth_pad_length,
1818 uint32_t auth_context_id,
1819 const DATA_BLOB *credentials,
1822 struct dcerpc_auth r;
1823 enum ndr_err_code ndr_err;
1825 r.auth_type = auth_type;
1826 r.auth_level = auth_level;
1827 r.auth_pad_length = auth_pad_length;
1828 r.auth_reserved = 0;
1829 r.auth_context_id = auth_context_id;
1830 r.credentials = *credentials;
1832 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1833 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1834 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1835 return ndr_map_error2ntstatus(ndr_err);
1838 if (DEBUGLEVEL >= 10) {
1839 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1842 return NT_STATUS_OK;
1845 /*******************************************************************
1846 Creates krb5 auth bind.
1847 ********************************************************************/
1849 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1850 enum dcerpc_AuthLevel auth_level,
1851 DATA_BLOB *auth_info)
1856 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1857 DATA_BLOB tkt = data_blob_null;
1858 DATA_BLOB tkt_wrapped = data_blob_null;
1860 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1861 a->service_principal ));
1863 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1865 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1866 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1869 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1871 a->service_principal,
1872 error_message(ret) ));
1874 data_blob_free(&tkt);
1875 return NT_STATUS_INVALID_PARAMETER;
1878 /* wrap that up in a nice GSS-API wrapping */
1879 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1881 data_blob_free(&tkt);
1883 status = dcerpc_push_dcerpc_auth(cli,
1884 DCERPC_AUTH_TYPE_KRB5,
1886 0, /* auth_pad_length */
1887 1, /* auth_context_id */
1890 if (!NT_STATUS_IS_OK(status)) {
1891 data_blob_free(&tkt_wrapped);
1895 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1896 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1898 return NT_STATUS_OK;
1900 return NT_STATUS_INVALID_PARAMETER;
1904 /*******************************************************************
1905 Creates SPNEGO NTLMSSP auth bind.
1906 ********************************************************************/
1908 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1909 enum dcerpc_AuthLevel auth_level,
1910 DATA_BLOB *auth_info)
1913 DATA_BLOB null_blob = data_blob_null;
1914 DATA_BLOB request = data_blob_null;
1915 DATA_BLOB spnego_msg = data_blob_null;
1917 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1918 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1922 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1923 data_blob_free(&request);
1927 /* Wrap this in SPNEGO. */
1928 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1930 data_blob_free(&request);
1932 status = dcerpc_push_dcerpc_auth(cli,
1933 DCERPC_AUTH_TYPE_SPNEGO,
1935 0, /* auth_pad_length */
1936 1, /* auth_context_id */
1939 if (!NT_STATUS_IS_OK(status)) {
1940 data_blob_free(&spnego_msg);
1944 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1945 dump_data(5, spnego_msg.data, spnego_msg.length);
1947 return NT_STATUS_OK;
1950 /*******************************************************************
1951 Creates NTLMSSP auth bind.
1952 ********************************************************************/
1954 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1955 enum dcerpc_AuthLevel auth_level,
1956 DATA_BLOB *auth_info)
1959 DATA_BLOB null_blob = data_blob_null;
1960 DATA_BLOB request = data_blob_null;
1962 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1963 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1967 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1968 data_blob_free(&request);
1972 status = dcerpc_push_dcerpc_auth(cli,
1973 DCERPC_AUTH_TYPE_NTLMSSP,
1975 0, /* auth_pad_length */
1976 1, /* auth_context_id */
1979 if (!NT_STATUS_IS_OK(status)) {
1980 data_blob_free(&request);
1984 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1985 dump_data(5, request.data, request.length);
1987 return NT_STATUS_OK;
1990 /*******************************************************************
1991 Creates schannel auth bind.
1992 ********************************************************************/
1994 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1995 enum dcerpc_AuthLevel auth_level,
1996 DATA_BLOB *auth_info)
1999 struct NL_AUTH_MESSAGE r;
2000 DATA_BLOB schannel_blob;
2002 /* Use lp_workgroup() if domain not specified */
2004 if (!cli->auth->domain || !cli->auth->domain[0]) {
2005 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
2006 if (cli->auth->domain == NULL) {
2007 return NT_STATUS_NO_MEMORY;
2012 * Now marshall the data into the auth parse_struct.
2015 r.MessageType = NL_NEGOTIATE_REQUEST;
2016 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
2017 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
2018 r.oem_netbios_domain.a = cli->auth->domain;
2019 r.oem_netbios_computer.a = global_myname();
2021 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
2022 if (!NT_STATUS_IS_OK(status)) {
2026 status = dcerpc_push_dcerpc_auth(cli,
2027 DCERPC_AUTH_TYPE_SCHANNEL,
2029 0, /* auth_pad_length */
2030 1, /* auth_context_id */
2033 if (!NT_STATUS_IS_OK(status)) {
2037 return NT_STATUS_OK;
2040 /*******************************************************************
2041 ********************************************************************/
2043 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
2044 const struct ndr_syntax_id *abstract_syntax,
2045 const struct ndr_syntax_id *transfer_syntax,
2046 struct dcerpc_ctx_list **ctx_list_p)
2048 struct dcerpc_ctx_list *ctx_list;
2050 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
2051 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
2053 ctx_list[0].context_id = 0;
2054 ctx_list[0].num_transfer_syntaxes = 1;
2055 ctx_list[0].abstract_syntax = *abstract_syntax;
2056 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
2057 struct ndr_syntax_id,
2058 ctx_list[0].num_transfer_syntaxes);
2059 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
2060 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
2062 *ctx_list_p = ctx_list;
2064 return NT_STATUS_OK;
2067 /*******************************************************************
2068 Creates the internals of a DCE/RPC bind request or alter context PDU.
2069 ********************************************************************/
2071 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
2072 prs_struct *rpc_out,
2074 const struct ndr_syntax_id *abstract,
2075 const struct ndr_syntax_id *transfer,
2076 const DATA_BLOB *auth_info)
2078 uint16 auth_len = auth_info->length;
2080 union dcerpc_payload u;
2082 struct dcerpc_ctx_list *ctx_list;
2084 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
2086 if (!NT_STATUS_IS_OK(status)) {
2090 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2091 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2092 u.bind.assoc_group_id = 0x0;
2093 u.bind.num_contexts = 1;
2094 u.bind.ctx_list = ctx_list;
2095 u.bind.auth_info = *auth_info;
2097 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
2099 DCERPC_PFC_FLAG_FIRST |
2100 DCERPC_PFC_FLAG_LAST,
2101 auth_len ? auth_len - RPC_HDR_AUTH_LEN : 0,
2105 if (!NT_STATUS_IS_OK(status)) {
2106 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2110 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2111 return NT_STATUS_NO_MEMORY;
2114 return NT_STATUS_OK;
2117 /*******************************************************************
2118 Creates a DCE/RPC bind request.
2119 ********************************************************************/
2121 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2122 prs_struct *rpc_out,
2124 const struct ndr_syntax_id *abstract,
2125 const struct ndr_syntax_id *transfer,
2126 enum pipe_auth_type auth_type,
2127 enum dcerpc_AuthLevel auth_level)
2129 DATA_BLOB auth_info = data_blob_null;
2130 NTSTATUS ret = NT_STATUS_OK;
2132 switch (auth_type) {
2133 case PIPE_AUTH_TYPE_SCHANNEL:
2134 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
2135 if (!NT_STATUS_IS_OK(ret)) {
2140 case PIPE_AUTH_TYPE_NTLMSSP:
2141 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2142 if (!NT_STATUS_IS_OK(ret)) {
2147 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2148 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
2149 if (!NT_STATUS_IS_OK(ret)) {
2154 case PIPE_AUTH_TYPE_KRB5:
2155 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
2156 if (!NT_STATUS_IS_OK(ret)) {
2161 case PIPE_AUTH_TYPE_NONE:
2165 /* "Can't" happen. */
2166 return NT_STATUS_INVALID_INFO_CLASS;
2169 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2178 /*******************************************************************
2179 Create and add the NTLMSSP sign/seal auth header and data.
2180 ********************************************************************/
2182 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2183 uint32 ss_padding_len,
2184 prs_struct *rpc_out)
2186 DATA_BLOB auth_info;
2188 DATA_BLOB auth_blob = data_blob_null;
2189 uint16_t data_and_pad_len =
2190 prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2192 if (!cli->auth->a_u.ntlmssp_state) {
2193 return NT_STATUS_INVALID_PARAMETER;
2196 /* marshall the dcerpc_auth with an actually empty auth_blob.
2197 * this is needed because the ntmlssp signature includes the
2199 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2200 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2201 cli->auth->auth_level,
2203 1 /* context id. */,
2206 if (!NT_STATUS_IS_OK(status)) {
2210 /* append the header */
2211 if (!prs_copy_data_in(rpc_out,
2212 (char *)auth_info.data,
2213 auth_info.length)) {
2214 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2215 (unsigned int)auth_info.length));
2216 return NT_STATUS_NO_MEMORY;
2219 switch (cli->auth->auth_level) {
2220 case DCERPC_AUTH_LEVEL_PRIVACY:
2221 /* Data portion is encrypted. */
2222 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2223 prs_get_mem_context(rpc_out),
2224 (unsigned char *)prs_data_p(rpc_out)
2228 (unsigned char *)prs_data_p(rpc_out),
2229 (size_t)prs_offset(rpc_out),
2231 if (!NT_STATUS_IS_OK(status)) {
2236 case DCERPC_AUTH_LEVEL_INTEGRITY:
2237 /* Data is signed. */
2238 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2239 prs_get_mem_context(rpc_out),
2240 (unsigned char *)prs_data_p(rpc_out)
2244 (unsigned char *)prs_data_p(rpc_out),
2245 (size_t)prs_offset(rpc_out),
2247 if (!NT_STATUS_IS_OK(status)) {
2254 smb_panic("bad auth level");
2256 return NT_STATUS_INVALID_PARAMETER;
2259 /* Finally attach the blob. */
2260 if (!prs_copy_data_in(rpc_out,
2261 (char *)auth_blob.data,
2262 auth_blob.length)) {
2263 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
2264 (unsigned int)auth_info.length));
2265 return NT_STATUS_NO_MEMORY;
2268 return NT_STATUS_OK;
2271 /*******************************************************************
2272 Create and add the schannel sign/seal auth header and data.
2273 ********************************************************************/
2275 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2276 uint32 ss_padding_len,
2277 prs_struct *rpc_out)
2279 DATA_BLOB auth_info;
2280 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2281 char *data_p = prs_data_p(rpc_out) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2282 size_t data_and_pad_len = prs_offset(rpc_out) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2287 return NT_STATUS_INVALID_PARAMETER;
2290 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2293 switch (cli->auth->auth_level) {
2294 case DCERPC_AUTH_LEVEL_PRIVACY:
2295 status = netsec_outgoing_packet(sas,
2302 case DCERPC_AUTH_LEVEL_INTEGRITY:
2303 status = netsec_outgoing_packet(sas,
2311 status = NT_STATUS_INTERNAL_ERROR;
2315 if (!NT_STATUS_IS_OK(status)) {
2316 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2317 nt_errstr(status)));
2321 if (DEBUGLEVEL >= 10) {
2322 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2325 /* Finally marshall the blob. */
2326 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2327 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2328 cli->auth->auth_level,
2330 1 /* context id. */,
2333 if (!NT_STATUS_IS_OK(status)) {
2337 if (!prs_copy_data_in(rpc_out, (const char *)auth_info.data, auth_info.length)) {
2338 return NT_STATUS_NO_MEMORY;
2341 return NT_STATUS_OK;
2344 /*******************************************************************
2345 Calculate how much data we're going to send in this packet, also
2346 work out any sign/seal padding length.
2347 ********************************************************************/
2349 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2353 uint32 *p_ss_padding)
2355 uint32 data_space, data_len;
2358 if ((data_left > 0) && (sys_random() % 2)) {
2359 data_left = MAX(data_left/2, 1);
2363 switch (cli->auth->auth_level) {
2364 case DCERPC_AUTH_LEVEL_NONE:
2365 case DCERPC_AUTH_LEVEL_CONNECT:
2366 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2367 data_len = MIN(data_space, data_left);
2370 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2373 case DCERPC_AUTH_LEVEL_INTEGRITY:
2374 case DCERPC_AUTH_LEVEL_PRIVACY:
2375 /* Treat the same for all authenticated rpc requests. */
2376 switch(cli->auth->auth_type) {
2377 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2378 case PIPE_AUTH_TYPE_NTLMSSP:
2379 *p_auth_len = NTLMSSP_SIG_SIZE;
2381 case PIPE_AUTH_TYPE_SCHANNEL:
2382 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2385 smb_panic("bad auth type");
2389 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2390 RPC_HDR_AUTH_LEN - *p_auth_len;
2392 data_len = MIN(data_space, data_left);
2394 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2395 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2397 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2398 data_len + *p_ss_padding + /* data plus padding. */
2399 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2403 smb_panic("bad auth level");
2409 /*******************************************************************
2411 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2412 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2413 and deals with signing/sealing details.
2414 ********************************************************************/
2416 struct rpc_api_pipe_req_state {
2417 struct event_context *ev;
2418 struct rpc_pipe_client *cli;
2421 prs_struct *req_data;
2422 uint32_t req_data_sent;
2423 prs_struct outgoing_frag;
2424 prs_struct reply_pdu;
2427 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2428 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2429 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2430 bool *is_last_frag);
2432 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2433 struct event_context *ev,
2434 struct rpc_pipe_client *cli,
2436 prs_struct *req_data)
2438 struct tevent_req *req, *subreq;
2439 struct rpc_api_pipe_req_state *state;
2443 req = tevent_req_create(mem_ctx, &state,
2444 struct rpc_api_pipe_req_state);
2450 state->op_num = op_num;
2451 state->req_data = req_data;
2452 state->req_data_sent = 0;
2453 state->call_id = get_rpc_call_id();
2455 if (cli->max_xmit_frag
2456 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2457 /* Server is screwed up ! */
2458 status = NT_STATUS_INVALID_PARAMETER;
2462 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2464 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2469 status = prepare_next_frag(state, &is_last_frag);
2470 if (!NT_STATUS_IS_OK(status)) {
2475 subreq = rpc_api_pipe_send(state, ev, state->cli,
2476 &state->outgoing_frag,
2477 DCERPC_PKT_RESPONSE);
2478 if (subreq == NULL) {
2481 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2483 subreq = rpc_write_send(
2484 state, ev, cli->transport,
2485 (uint8_t *)prs_data_p(&state->outgoing_frag),
2486 prs_offset(&state->outgoing_frag));
2487 if (subreq == NULL) {
2490 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2496 tevent_req_nterror(req, status);
2497 return tevent_req_post(req, ev);
2503 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2506 uint32_t data_sent_thistime;
2510 uint32_t ss_padding;
2512 char pad[8] = { 0, };
2514 union dcerpc_payload u;
2517 data_left = prs_offset(state->req_data) - state->req_data_sent;
2519 data_sent_thistime = calculate_data_len_tosend(
2520 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2522 if (state->req_data_sent == 0) {
2523 flags = DCERPC_PFC_FLAG_FIRST;
2526 if (data_sent_thistime == data_left) {
2527 flags |= DCERPC_PFC_FLAG_LAST;
2530 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2531 return NT_STATUS_NO_MEMORY;
2534 ZERO_STRUCT(u.request);
2536 u.request.alloc_hint = prs_offset(state->req_data);
2537 u.request.context_id = 0;
2538 u.request.opnum = state->op_num;
2540 status = dcerpc_push_ncacn_packet(prs_get_mem_context(&state->outgoing_frag),
2547 if (!NT_STATUS_IS_OK(status)) {
2551 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
2552 * compute it right for requests */
2553 dcerpc_set_frag_length(&blob, frag_len);
2555 if (!prs_copy_data_in(&state->outgoing_frag, (const char *)blob.data, blob.length)) {
2556 return NT_STATUS_NO_MEMORY;
2559 /* Copy in the data, plus any ss padding. */
2560 if (!prs_append_some_prs_data(&state->outgoing_frag,
2561 state->req_data, state->req_data_sent,
2562 data_sent_thistime)) {
2563 return NT_STATUS_NO_MEMORY;
2566 /* Copy the sign/seal padding data. */
2567 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2568 return NT_STATUS_NO_MEMORY;
2571 /* Generate any auth sign/seal and add the auth footer. */
2572 switch (state->cli->auth->auth_type) {
2573 case PIPE_AUTH_TYPE_NONE:
2574 status = NT_STATUS_OK;
2576 case PIPE_AUTH_TYPE_NTLMSSP:
2577 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2578 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
2579 &state->outgoing_frag);
2581 case PIPE_AUTH_TYPE_SCHANNEL:
2582 status = add_schannel_auth_footer(state->cli, ss_padding,
2583 &state->outgoing_frag);
2586 status = NT_STATUS_INVALID_PARAMETER;
2590 state->req_data_sent += data_sent_thistime;
2591 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2596 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2598 struct tevent_req *req = tevent_req_callback_data(
2599 subreq, struct tevent_req);
2600 struct rpc_api_pipe_req_state *state = tevent_req_data(
2601 req, struct rpc_api_pipe_req_state);
2605 status = rpc_write_recv(subreq);
2606 TALLOC_FREE(subreq);
2607 if (!NT_STATUS_IS_OK(status)) {
2608 tevent_req_nterror(req, status);
2612 status = prepare_next_frag(state, &is_last_frag);
2613 if (!NT_STATUS_IS_OK(status)) {
2614 tevent_req_nterror(req, status);
2619 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2620 &state->outgoing_frag,
2621 DCERPC_PKT_RESPONSE);
2622 if (tevent_req_nomem(subreq, req)) {
2625 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2627 subreq = rpc_write_send(
2629 state->cli->transport,
2630 (uint8_t *)prs_data_p(&state->outgoing_frag),
2631 prs_offset(&state->outgoing_frag));
2632 if (tevent_req_nomem(subreq, req)) {
2635 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2640 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2642 struct tevent_req *req = tevent_req_callback_data(
2643 subreq, struct tevent_req);
2644 struct rpc_api_pipe_req_state *state = tevent_req_data(
2645 req, struct rpc_api_pipe_req_state);
2648 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2649 TALLOC_FREE(subreq);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 tevent_req_nterror(req, status);
2654 tevent_req_done(req);
2657 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2658 prs_struct *reply_pdu)
2660 struct rpc_api_pipe_req_state *state = tevent_req_data(
2661 req, struct rpc_api_pipe_req_state);
2664 if (tevent_req_is_nterror(req, &status)) {
2666 * We always have to initialize to reply pdu, even if there is
2667 * none. The rpccli_* caller routines expect this.
2669 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2673 *reply_pdu = state->reply_pdu;
2674 reply_pdu->mem_ctx = mem_ctx;
2677 * Prevent state->req_pdu from being freed
2678 * when state is freed.
2680 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2681 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2683 return NT_STATUS_OK;
2687 /****************************************************************************
2688 Set the handle state.
2689 ****************************************************************************/
2691 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2692 const char *pipe_name, uint16 device_state)
2694 bool state_set = False;
2696 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2697 char *rparam = NULL;
2699 uint32 rparam_len, rdata_len;
2701 if (pipe_name == NULL)
2704 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2705 cli->fnum, pipe_name, device_state));
2707 /* create parameters: device state */
2708 SSVAL(param, 0, device_state);
2710 /* create setup parameters. */
2712 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2714 /* send the data on \PIPE\ */
2715 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2716 setup, 2, 0, /* setup, length, max */
2717 param, 2, 0, /* param, length, max */
2718 NULL, 0, 1024, /* data, length, max */
2719 &rparam, &rparam_len, /* return param, length */
2720 &rdata, &rdata_len)) /* return data, length */
2722 DEBUG(5, ("Set Handle state: return OK\n"));
2733 /****************************************************************************
2734 Check the rpc bind acknowledge response.
2735 ****************************************************************************/
2737 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2738 const struct ndr_syntax_id *transfer)
2740 struct dcerpc_ack_ctx ctx;
2742 if (r->secondary_address_size == 0) {
2743 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2746 if (r->num_results < 1 || !r->ctx_list) {
2750 ctx = r->ctx_list[0];
2752 /* check the transfer syntax */
2753 if ((ctx.syntax.if_version != transfer->if_version) ||
2754 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2755 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2759 if (r->num_results != 0x1 || ctx.result != 0) {
2760 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2761 r->num_results, ctx.reason));
2764 DEBUG(5,("check_bind_response: accepted!\n"));
2768 /*******************************************************************
2769 Creates a DCE/RPC bind authentication response.
2770 This is the packet that is sent back to the server once we
2771 have received a BIND-ACK, to finish the third leg of
2772 the authentication handshake.
2773 ********************************************************************/
2775 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2777 enum pipe_auth_type auth_type,
2778 enum dcerpc_AuthLevel auth_level,
2779 DATA_BLOB *pauth_blob,
2780 prs_struct *rpc_out)
2783 union dcerpc_payload u;
2788 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2789 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2791 0, /* auth_pad_length */
2792 1, /* auth_context_id */
2794 &u.auth3.auth_info);
2795 if (!NT_STATUS_IS_OK(status)) {
2799 status = dcerpc_push_ncacn_packet(prs_get_mem_context(rpc_out),
2801 DCERPC_PFC_FLAG_FIRST |
2802 DCERPC_PFC_FLAG_LAST,
2807 if (!NT_STATUS_IS_OK(status)) {
2808 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2812 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
2813 return NT_STATUS_NO_MEMORY;
2816 return NT_STATUS_OK;
2819 /*******************************************************************
2820 Creates a DCE/RPC bind alter context authentication request which
2821 may contain a spnego auth blobl
2822 ********************************************************************/
2824 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2825 const struct ndr_syntax_id *abstract,
2826 const struct ndr_syntax_id *transfer,
2827 enum dcerpc_AuthLevel auth_level,
2828 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2829 prs_struct *rpc_out)
2831 DATA_BLOB auth_info;
2834 status = dcerpc_push_dcerpc_auth(prs_get_mem_context(rpc_out),
2835 DCERPC_AUTH_TYPE_SPNEGO,
2837 0, /* auth_pad_length */
2838 1, /* auth_context_id */
2841 if (!NT_STATUS_IS_OK(status)) {
2846 status = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2852 if (!NT_STATUS_IS_OK(status)) {
2859 /****************************************************************************
2861 ****************************************************************************/
2863 struct rpc_pipe_bind_state {
2864 struct event_context *ev;
2865 struct rpc_pipe_client *cli;
2867 uint32_t rpc_call_id;
2870 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2871 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2872 struct rpc_pipe_bind_state *state,
2873 struct ncacn_packet *r,
2874 prs_struct *reply_pdu);
2875 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2876 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2877 struct rpc_pipe_bind_state *state,
2878 struct ncacn_packet *r,
2879 prs_struct *reply_pdu);
2880 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2882 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2883 struct event_context *ev,
2884 struct rpc_pipe_client *cli,
2885 struct cli_pipe_auth_data *auth)
2887 struct tevent_req *req, *subreq;
2888 struct rpc_pipe_bind_state *state;
2891 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2896 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2897 rpccli_pipe_txt(talloc_tos(), cli),
2898 (unsigned int)auth->auth_type,
2899 (unsigned int)auth->auth_level ));
2903 state->rpc_call_id = get_rpc_call_id();
2905 prs_init_empty(&state->rpc_out, state, MARSHALL);
2907 cli->auth = talloc_move(cli, &auth);
2909 /* Marshall the outgoing data. */
2910 status = create_rpc_bind_req(cli, &state->rpc_out,
2912 &cli->abstract_syntax,
2913 &cli->transfer_syntax,
2914 cli->auth->auth_type,
2915 cli->auth->auth_level);
2917 if (!NT_STATUS_IS_OK(status)) {
2921 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2922 DCERPC_PKT_BIND_ACK);
2923 if (subreq == NULL) {
2926 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2930 tevent_req_nterror(req, status);
2931 return tevent_req_post(req, ev);
2937 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2939 struct tevent_req *req = tevent_req_callback_data(
2940 subreq, struct tevent_req);
2941 struct rpc_pipe_bind_state *state = tevent_req_data(
2942 req, struct rpc_pipe_bind_state);
2943 prs_struct reply_pdu;
2945 struct ncacn_packet r;
2948 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2949 TALLOC_FREE(subreq);
2950 if (!NT_STATUS_IS_OK(status)) {
2951 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2952 rpccli_pipe_txt(talloc_tos(), state->cli),
2953 nt_errstr(status)));
2954 tevent_req_nterror(req, status);
2958 blob = data_blob_const(prs_data_p(&reply_pdu),
2959 prs_data_size(&reply_pdu));
2961 status = dcerpc_pull_ncacn_packet(talloc_tos(), &blob, &r);
2962 if (!NT_STATUS_IS_OK(status)) {
2963 tevent_req_nterror(req, status);
2967 if (!check_bind_response(&r.u.bind_ack, &state->cli->transfer_syntax)) {
2968 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2969 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2973 state->cli->max_xmit_frag = r.u.bind_ack.max_xmit_frag;
2974 state->cli->max_recv_frag = r.u.bind_ack.max_recv_frag;
2977 * For authenticated binds we may need to do 3 or 4 leg binds.
2980 switch(state->cli->auth->auth_type) {
2982 case PIPE_AUTH_TYPE_NONE:
2983 case PIPE_AUTH_TYPE_SCHANNEL:
2984 /* Bind complete. */
2985 tevent_req_done(req);
2988 case PIPE_AUTH_TYPE_NTLMSSP:
2989 /* Need to send AUTH3 packet - no reply. */
2990 status = rpc_finish_auth3_bind_send(req, state, &r,
2992 if (!NT_STATUS_IS_OK(status)) {
2993 tevent_req_nterror(req, status);
2997 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2998 /* Need to send alter context request and reply. */
2999 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &r,
3001 if (!NT_STATUS_IS_OK(status)) {
3002 tevent_req_nterror(req, status);
3006 case PIPE_AUTH_TYPE_KRB5:
3010 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
3011 (unsigned int)state->cli->auth->auth_type));
3012 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
3016 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
3017 struct rpc_pipe_bind_state *state,
3018 struct ncacn_packet *r,
3019 prs_struct *reply_pdu)
3021 DATA_BLOB server_response = data_blob_null;
3022 DATA_BLOB client_reply = data_blob_null;
3023 struct rpc_hdr_auth_info hdr_auth;
3024 struct tevent_req *subreq;
3027 if ((r->auth_length == 0)
3028 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3029 return NT_STATUS_INVALID_PARAMETER;
3032 if (!prs_set_offset(
3034 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3035 return NT_STATUS_INVALID_PARAMETER;
3038 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3039 return NT_STATUS_INVALID_PARAMETER;
3042 /* TODO - check auth_type/auth_level match. */
3044 server_response = data_blob_talloc(talloc_tos(), NULL, r->auth_length);
3045 prs_copy_data_out((char *)server_response.data, reply_pdu,
3048 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3049 server_response, &client_reply);
3051 if (!NT_STATUS_IS_OK(status)) {
3052 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
3053 "blob failed: %s.\n", nt_errstr(status)));
3057 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
3059 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
3060 state->cli->auth->auth_type,
3061 state->cli->auth->auth_level,
3062 &client_reply, &state->rpc_out);
3063 data_blob_free(&client_reply);
3065 if (!NT_STATUS_IS_OK(status)) {
3069 subreq = rpc_write_send(state, state->ev, state->cli->transport,
3070 (uint8_t *)prs_data_p(&state->rpc_out),
3071 prs_offset(&state->rpc_out));
3072 if (subreq == NULL) {
3073 return NT_STATUS_NO_MEMORY;
3075 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
3076 return NT_STATUS_OK;
3079 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
3081 struct tevent_req *req = tevent_req_callback_data(
3082 subreq, struct tevent_req);
3085 status = rpc_write_recv(subreq);
3086 TALLOC_FREE(subreq);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 tevent_req_nterror(req, status);
3091 tevent_req_done(req);
3094 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
3095 struct rpc_pipe_bind_state *state,
3096 struct ncacn_packet *r,
3099 DATA_BLOB server_ntlm_response = data_blob_null;
3100 DATA_BLOB client_reply = data_blob_null;
3101 DATA_BLOB tmp_blob = data_blob_null;
3102 struct dcerpc_auth auth_info;
3103 DATA_BLOB auth_blob;
3104 struct tevent_req *subreq;
3107 if ((r->auth_length == 0)
3108 || (r->frag_length < r->auth_length + RPC_HDR_AUTH_LEN)) {
3109 return NT_STATUS_INVALID_PARAMETER;
3112 /* Process the returned NTLMSSP blob first. */
3113 if (!prs_set_offset(
3115 r->frag_length - r->auth_length - RPC_HDR_AUTH_LEN)) {
3116 return NT_STATUS_INVALID_PARAMETER;
3119 auth_blob = data_blob_const(prs_data_p(rpc_in) + prs_offset(rpc_in),
3120 prs_data_size(rpc_in) - prs_offset(rpc_in));
3122 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info);
3123 if (!NT_STATUS_IS_OK(status)) {
3124 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
3129 * The server might give us back two challenges - tmp_blob is for the
3132 if (!spnego_parse_challenge(auth_info.credentials,
3133 &server_ntlm_response, &tmp_blob)) {
3134 data_blob_free(&server_ntlm_response);
3135 data_blob_free(&tmp_blob);
3136 return NT_STATUS_INVALID_PARAMETER;
3139 /* We're finished with the server spnego response and the tmp_blob. */
3140 data_blob_free(&tmp_blob);
3142 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3143 server_ntlm_response, &client_reply);
3145 /* Finished with the server_ntlm response */
3146 data_blob_free(&server_ntlm_response);
3148 if (!NT_STATUS_IS_OK(status)) {
3149 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3150 "using server blob failed.\n"));
3151 data_blob_free(&client_reply);
3155 /* SPNEGO wrap the client reply. */
3156 tmp_blob = spnego_gen_auth(client_reply);
3157 data_blob_free(&client_reply);
3158 client_reply = tmp_blob;
3159 tmp_blob = data_blob_null;
3161 /* Now prepare the alter context pdu. */
3162 prs_init_empty(&state->rpc_out, state, MARSHALL);
3164 status = create_rpc_alter_context(state->rpc_call_id,
3165 &state->cli->abstract_syntax,
3166 &state->cli->transfer_syntax,
3167 state->cli->auth->auth_level,
3170 data_blob_free(&client_reply);
3172 if (!NT_STATUS_IS_OK(status)) {
3176 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3177 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3178 if (subreq == NULL) {
3179 return NT_STATUS_NO_MEMORY;
3181 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3182 return NT_STATUS_OK;
3185 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3187 struct tevent_req *req = tevent_req_callback_data(
3188 subreq, struct tevent_req);
3189 struct rpc_pipe_bind_state *state = tevent_req_data(
3190 req, struct rpc_pipe_bind_state);
3191 DATA_BLOB server_spnego_response = data_blob_null;
3192 DATA_BLOB tmp_blob = data_blob_null;
3193 prs_struct reply_pdu;
3194 struct ncacn_packet_header hdr;
3195 struct rpc_hdr_auth_info hdr_auth;
3198 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3199 TALLOC_FREE(subreq);
3200 if (!NT_STATUS_IS_OK(status)) {
3201 tevent_req_nterror(req, status);
3205 status = parse_rpc_header(state->cli, &hdr, &reply_pdu);
3206 if (!NT_STATUS_IS_OK(status)) {
3207 tevent_req_nterror(req, status);
3211 if (!prs_set_offset(
3213 hdr.frag_length - hdr.auth_length - RPC_HDR_AUTH_LEN)) {
3214 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3218 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3219 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3223 server_spnego_response = data_blob(NULL, hdr.auth_length);
3224 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3227 /* Check we got a valid auth response. */
3228 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3229 OID_NTLMSSP, &tmp_blob)) {
3230 data_blob_free(&server_spnego_response);
3231 data_blob_free(&tmp_blob);
3232 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3236 data_blob_free(&server_spnego_response);
3237 data_blob_free(&tmp_blob);
3239 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3240 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3241 tevent_req_done(req);
3244 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3246 return tevent_req_simple_recv_ntstatus(req);
3249 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3250 struct cli_pipe_auth_data *auth)
3252 TALLOC_CTX *frame = talloc_stackframe();
3253 struct event_context *ev;
3254 struct tevent_req *req;
3255 NTSTATUS status = NT_STATUS_OK;
3257 ev = event_context_init(frame);
3259 status = NT_STATUS_NO_MEMORY;
3263 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3265 status = NT_STATUS_NO_MEMORY;
3269 if (!tevent_req_poll(req, ev)) {
3270 status = map_nt_error_from_unix(errno);
3274 status = rpc_pipe_bind_recv(req);
3280 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3282 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3283 unsigned int timeout)
3287 if (rpc_cli->transport == NULL) {
3288 return RPCCLI_DEFAULT_TIMEOUT;
3291 if (rpc_cli->transport->set_timeout == NULL) {
3292 return RPCCLI_DEFAULT_TIMEOUT;
3295 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3297 return RPCCLI_DEFAULT_TIMEOUT;
3303 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3305 if (rpc_cli == NULL) {
3309 if (rpc_cli->transport == NULL) {
3313 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3316 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3318 struct cli_state *cli;
3320 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3321 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3322 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3326 cli = rpc_pipe_np_smb_conn(rpc_cli);
3330 E_md4hash(cli->password ? cli->password : "", nt_hash);
3334 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3335 struct cli_pipe_auth_data **presult)
3337 struct cli_pipe_auth_data *result;
3339 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3340 if (result == NULL) {
3341 return NT_STATUS_NO_MEMORY;
3344 result->auth_type = PIPE_AUTH_TYPE_NONE;
3345 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3347 result->user_name = talloc_strdup(result, "");
3348 result->domain = talloc_strdup(result, "");
3349 if ((result->user_name == NULL) || (result->domain == NULL)) {
3350 TALLOC_FREE(result);
3351 return NT_STATUS_NO_MEMORY;
3355 return NT_STATUS_OK;
3358 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3360 ntlmssp_end(&auth->a_u.ntlmssp_state);
3364 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3365 enum pipe_auth_type auth_type,
3366 enum dcerpc_AuthLevel auth_level,
3368 const char *username,
3369 const char *password,
3370 struct cli_pipe_auth_data **presult)
3372 struct cli_pipe_auth_data *result;
3375 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3376 if (result == NULL) {
3377 return NT_STATUS_NO_MEMORY;
3380 result->auth_type = auth_type;
3381 result->auth_level = auth_level;
3383 result->user_name = talloc_strdup(result, username);
3384 result->domain = talloc_strdup(result, domain);
3385 if ((result->user_name == NULL) || (result->domain == NULL)) {
3386 status = NT_STATUS_NO_MEMORY;
3390 status = ntlmssp_client_start(NULL,
3393 lp_client_ntlmv2_auth(),
3394 &result->a_u.ntlmssp_state);
3395 if (!NT_STATUS_IS_OK(status)) {
3399 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3401 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3402 if (!NT_STATUS_IS_OK(status)) {
3406 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3407 if (!NT_STATUS_IS_OK(status)) {
3411 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3412 if (!NT_STATUS_IS_OK(status)) {
3417 * Turn off sign+seal to allow selected auth level to turn it back on.
3419 result->a_u.ntlmssp_state->neg_flags &=
3420 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3422 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3423 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3424 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3425 result->a_u.ntlmssp_state->neg_flags
3426 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3430 return NT_STATUS_OK;
3433 TALLOC_FREE(result);
3437 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3438 enum dcerpc_AuthLevel auth_level,
3439 struct netlogon_creds_CredentialState *creds,
3440 struct cli_pipe_auth_data **presult)
3442 struct cli_pipe_auth_data *result;
3444 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3445 if (result == NULL) {
3446 return NT_STATUS_NO_MEMORY;
3449 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3450 result->auth_level = auth_level;
3452 result->user_name = talloc_strdup(result, "");
3453 result->domain = talloc_strdup(result, domain);
3454 if ((result->user_name == NULL) || (result->domain == NULL)) {
3458 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3459 if (result->a_u.schannel_auth == NULL) {
3463 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3464 result->a_u.schannel_auth->seq_num = 0;
3465 result->a_u.schannel_auth->initiator = true;
3466 result->a_u.schannel_auth->creds = creds;
3469 return NT_STATUS_OK;
3472 TALLOC_FREE(result);
3473 return NT_STATUS_NO_MEMORY;
3477 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3479 data_blob_free(&auth->session_key);
3484 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3485 enum dcerpc_AuthLevel auth_level,
3486 const char *service_princ,
3487 const char *username,
3488 const char *password,
3489 struct cli_pipe_auth_data **presult)
3492 struct cli_pipe_auth_data *result;
3494 if ((username != NULL) && (password != NULL)) {
3495 int ret = kerberos_kinit_password(username, password, 0, NULL);
3497 return NT_STATUS_ACCESS_DENIED;
3501 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3502 if (result == NULL) {
3503 return NT_STATUS_NO_MEMORY;
3506 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3507 result->auth_level = auth_level;
3510 * Username / domain need fixing!
3512 result->user_name = talloc_strdup(result, "");
3513 result->domain = talloc_strdup(result, "");
3514 if ((result->user_name == NULL) || (result->domain == NULL)) {
3518 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3519 result, struct kerberos_auth_struct);
3520 if (result->a_u.kerberos_auth == NULL) {
3523 talloc_set_destructor(result->a_u.kerberos_auth,
3524 cli_auth_kerberos_data_destructor);
3526 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3527 result, service_princ);
3528 if (result->a_u.kerberos_auth->service_principal == NULL) {
3533 return NT_STATUS_OK;
3536 TALLOC_FREE(result);
3537 return NT_STATUS_NO_MEMORY;
3539 return NT_STATUS_NOT_SUPPORTED;
3544 * Create an rpc pipe client struct, connecting to a tcp port.
3546 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3548 const struct ndr_syntax_id *abstract_syntax,
3549 struct rpc_pipe_client **presult)
3551 struct rpc_pipe_client *result;
3552 struct sockaddr_storage addr;
3556 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3557 if (result == NULL) {
3558 return NT_STATUS_NO_MEMORY;
3561 result->abstract_syntax = *abstract_syntax;
3562 result->transfer_syntax = ndr_transfer_syntax;
3563 result->dispatch = cli_do_rpc_ndr;
3564 result->dispatch_send = cli_do_rpc_ndr_send;
3565 result->dispatch_recv = cli_do_rpc_ndr_recv;
3567 result->desthost = talloc_strdup(result, host);
3568 result->srv_name_slash = talloc_asprintf_strupper_m(
3569 result, "\\\\%s", result->desthost);
3570 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3571 status = NT_STATUS_NO_MEMORY;
3575 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3576 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3578 if (!resolve_name(host, &addr, 0, false)) {
3579 status = NT_STATUS_NOT_FOUND;
3583 status = open_socket_out(&addr, port, 60, &fd);
3584 if (!NT_STATUS_IS_OK(status)) {
3587 set_socket_options(fd, lp_socket_options());
3589 status = rpc_transport_sock_init(result, fd, &result->transport);
3590 if (!NT_STATUS_IS_OK(status)) {
3595 result->transport->transport = NCACN_IP_TCP;
3598 return NT_STATUS_OK;
3601 TALLOC_FREE(result);
3606 * Determine the tcp port on which a dcerpc interface is listening
3607 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3610 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3611 const struct ndr_syntax_id *abstract_syntax,
3615 struct rpc_pipe_client *epm_pipe = NULL;
3616 struct cli_pipe_auth_data *auth = NULL;
3617 struct dcerpc_binding *map_binding = NULL;
3618 struct dcerpc_binding *res_binding = NULL;
3619 struct epm_twr_t *map_tower = NULL;
3620 struct epm_twr_t *res_towers = NULL;
3621 struct policy_handle *entry_handle = NULL;
3622 uint32_t num_towers = 0;
3623 uint32_t max_towers = 1;
3624 struct epm_twr_p_t towers;
3625 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3627 if (pport == NULL) {
3628 status = NT_STATUS_INVALID_PARAMETER;
3632 /* open the connection to the endpoint mapper */
3633 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3634 &ndr_table_epmapper.syntax_id,
3637 if (!NT_STATUS_IS_OK(status)) {
3641 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3642 if (!NT_STATUS_IS_OK(status)) {
3646 status = rpc_pipe_bind(epm_pipe, auth);
3647 if (!NT_STATUS_IS_OK(status)) {
3651 /* create tower for asking the epmapper */
3653 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3654 if (map_binding == NULL) {
3655 status = NT_STATUS_NO_MEMORY;
3659 map_binding->transport = NCACN_IP_TCP;
3660 map_binding->object = *abstract_syntax;
3661 map_binding->host = host; /* needed? */
3662 map_binding->endpoint = "0"; /* correct? needed? */
3664 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3665 if (map_tower == NULL) {
3666 status = NT_STATUS_NO_MEMORY;
3670 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3671 &(map_tower->tower));
3672 if (!NT_STATUS_IS_OK(status)) {
3676 /* allocate further parameters for the epm_Map call */
3678 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3679 if (res_towers == NULL) {
3680 status = NT_STATUS_NO_MEMORY;
3683 towers.twr = res_towers;
3685 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3686 if (entry_handle == NULL) {
3687 status = NT_STATUS_NO_MEMORY;
3691 /* ask the endpoint mapper for the port */
3693 status = rpccli_epm_Map(epm_pipe,
3695 CONST_DISCARD(struct GUID *,
3696 &(abstract_syntax->uuid)),
3703 if (!NT_STATUS_IS_OK(status)) {
3707 if (num_towers != 1) {
3708 status = NT_STATUS_UNSUCCESSFUL;
3712 /* extract the port from the answer */
3714 status = dcerpc_binding_from_tower(tmp_ctx,
3715 &(towers.twr->tower),
3717 if (!NT_STATUS_IS_OK(status)) {
3721 /* are further checks here necessary? */
3722 if (res_binding->transport != NCACN_IP_TCP) {
3723 status = NT_STATUS_UNSUCCESSFUL;
3727 *pport = (uint16_t)atoi(res_binding->endpoint);
3730 TALLOC_FREE(tmp_ctx);
3735 * Create a rpc pipe client struct, connecting to a host via tcp.
3736 * The port is determined by asking the endpoint mapper on the given
3739 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3740 const struct ndr_syntax_id *abstract_syntax,
3741 struct rpc_pipe_client **presult)
3746 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3747 if (!NT_STATUS_IS_OK(status)) {
3751 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3752 abstract_syntax, presult);
3755 /********************************************************************
3756 Create a rpc pipe client struct, connecting to a unix domain socket
3757 ********************************************************************/
3758 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3759 const struct ndr_syntax_id *abstract_syntax,
3760 struct rpc_pipe_client **presult)
3762 struct rpc_pipe_client *result;
3763 struct sockaddr_un addr;
3767 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3768 if (result == NULL) {
3769 return NT_STATUS_NO_MEMORY;
3772 result->abstract_syntax = *abstract_syntax;
3773 result->transfer_syntax = ndr_transfer_syntax;
3774 result->dispatch = cli_do_rpc_ndr;
3775 result->dispatch_send = cli_do_rpc_ndr_send;
3776 result->dispatch_recv = cli_do_rpc_ndr_recv;
3778 result->desthost = get_myname(result);
3779 result->srv_name_slash = talloc_asprintf_strupper_m(
3780 result, "\\\\%s", result->desthost);
3781 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3782 status = NT_STATUS_NO_MEMORY;
3786 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3787 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3789 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3791 status = map_nt_error_from_unix(errno);
3796 addr.sun_family = AF_UNIX;
3797 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3799 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3800 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3803 return map_nt_error_from_unix(errno);
3806 status = rpc_transport_sock_init(result, fd, &result->transport);
3807 if (!NT_STATUS_IS_OK(status)) {
3812 result->transport->transport = NCALRPC;
3815 return NT_STATUS_OK;
3818 TALLOC_FREE(result);
3822 struct rpc_pipe_client_np_ref {
3823 struct cli_state *cli;
3824 struct rpc_pipe_client *pipe;
3827 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3829 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3833 /****************************************************************************
3834 Open a named pipe over SMB to a remote server.
3836 * CAVEAT CALLER OF THIS FUNCTION:
3837 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3838 * so be sure that this function is called AFTER any structure (vs pointer)
3839 * assignment of the cli. In particular, libsmbclient does structure
3840 * assignments of cli, which invalidates the data in the returned
3841 * rpc_pipe_client if this function is called before the structure assignment
3844 ****************************************************************************/
3846 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3847 const struct ndr_syntax_id *abstract_syntax,
3848 struct rpc_pipe_client **presult)
3850 struct rpc_pipe_client *result;
3852 struct rpc_pipe_client_np_ref *np_ref;
3854 /* sanity check to protect against crashes */
3857 return NT_STATUS_INVALID_HANDLE;
3860 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3861 if (result == NULL) {
3862 return NT_STATUS_NO_MEMORY;
3865 result->abstract_syntax = *abstract_syntax;
3866 result->transfer_syntax = ndr_transfer_syntax;
3867 result->dispatch = cli_do_rpc_ndr;
3868 result->dispatch_send = cli_do_rpc_ndr_send;
3869 result->dispatch_recv = cli_do_rpc_ndr_recv;
3870 result->desthost = talloc_strdup(result, cli->desthost);
3871 result->srv_name_slash = talloc_asprintf_strupper_m(
3872 result, "\\\\%s", result->desthost);
3874 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3875 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3877 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3878 TALLOC_FREE(result);
3879 return NT_STATUS_NO_MEMORY;
3882 status = rpc_transport_np_init(result, cli, abstract_syntax,
3883 &result->transport);
3884 if (!NT_STATUS_IS_OK(status)) {
3885 TALLOC_FREE(result);
3889 result->transport->transport = NCACN_NP;
3891 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3892 if (np_ref == NULL) {
3893 TALLOC_FREE(result);
3894 return NT_STATUS_NO_MEMORY;
3897 np_ref->pipe = result;
3899 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3900 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3903 return NT_STATUS_OK;
3906 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3907 struct rpc_cli_smbd_conn *conn,
3908 const struct ndr_syntax_id *syntax,
3909 struct rpc_pipe_client **presult)
3911 struct rpc_pipe_client *result;
3912 struct cli_pipe_auth_data *auth;
3915 result = talloc(mem_ctx, struct rpc_pipe_client);
3916 if (result == NULL) {
3917 return NT_STATUS_NO_MEMORY;
3919 result->abstract_syntax = *syntax;
3920 result->transfer_syntax = ndr_transfer_syntax;
3921 result->dispatch = cli_do_rpc_ndr;
3922 result->dispatch_send = cli_do_rpc_ndr_send;
3923 result->dispatch_recv = cli_do_rpc_ndr_recv;
3924 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3925 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3927 result->desthost = talloc_strdup(result, global_myname());
3928 result->srv_name_slash = talloc_asprintf_strupper_m(
3929 result, "\\\\%s", global_myname());
3930 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3931 TALLOC_FREE(result);
3932 return NT_STATUS_NO_MEMORY;
3935 status = rpc_transport_smbd_init(result, conn, syntax,
3936 &result->transport);
3937 if (!NT_STATUS_IS_OK(status)) {
3938 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3939 nt_errstr(status)));
3940 TALLOC_FREE(result);
3944 status = rpccli_anon_bind_data(result, &auth);
3945 if (!NT_STATUS_IS_OK(status)) {
3946 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3947 nt_errstr(status)));
3948 TALLOC_FREE(result);
3952 status = rpc_pipe_bind(result, auth);
3953 if (!NT_STATUS_IS_OK(status)) {
3954 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3955 TALLOC_FREE(result);
3959 result->transport->transport = NCACN_INTERNAL;
3962 return NT_STATUS_OK;
3965 /****************************************************************************
3966 Open a pipe to a remote server.
3967 ****************************************************************************/
3969 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3970 enum dcerpc_transport_t transport,
3971 const struct ndr_syntax_id *interface,
3972 struct rpc_pipe_client **presult)
3974 switch (transport) {
3976 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3979 return rpc_pipe_open_np(cli, interface, presult);
3981 return NT_STATUS_NOT_IMPLEMENTED;
3985 /****************************************************************************
3986 Open a named pipe to an SMB server and bind anonymously.
3987 ****************************************************************************/
3989 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3990 enum dcerpc_transport_t transport,
3991 const struct ndr_syntax_id *interface,
3992 struct rpc_pipe_client **presult)
3994 struct rpc_pipe_client *result;
3995 struct cli_pipe_auth_data *auth;
3998 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3999 if (!NT_STATUS_IS_OK(status)) {
4003 status = rpccli_anon_bind_data(result, &auth);
4004 if (!NT_STATUS_IS_OK(status)) {
4005 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
4006 nt_errstr(status)));
4007 TALLOC_FREE(result);
4012 * This is a bit of an abstraction violation due to the fact that an
4013 * anonymous bind on an authenticated SMB inherits the user/domain
4014 * from the enclosing SMB creds
4017 TALLOC_FREE(auth->user_name);
4018 TALLOC_FREE(auth->domain);
4020 auth->user_name = talloc_strdup(auth, cli->user_name);
4021 auth->domain = talloc_strdup(auth, cli->domain);
4022 auth->user_session_key = data_blob_talloc(auth,
4023 cli->user_session_key.data,
4024 cli->user_session_key.length);
4026 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
4027 TALLOC_FREE(result);
4028 return NT_STATUS_NO_MEMORY;
4031 status = rpc_pipe_bind(result, auth);
4032 if (!NT_STATUS_IS_OK(status)) {
4034 if (ndr_syntax_id_equal(interface,
4035 &ndr_table_dssetup.syntax_id)) {
4036 /* non AD domains just don't have this pipe, avoid
4037 * level 0 statement in that case - gd */
4040 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
4041 "%s failed with error %s\n",
4042 get_pipe_name_from_syntax(talloc_tos(), interface),
4043 nt_errstr(status) ));
4044 TALLOC_FREE(result);
4048 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
4049 "%s and bound anonymously.\n",
4050 get_pipe_name_from_syntax(talloc_tos(), interface),
4054 return NT_STATUS_OK;
4057 /****************************************************************************
4058 ****************************************************************************/
4060 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4061 const struct ndr_syntax_id *interface,
4062 struct rpc_pipe_client **presult)
4064 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4065 interface, presult);
4068 /****************************************************************************
4069 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
4070 ****************************************************************************/
4072 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
4073 const struct ndr_syntax_id *interface,
4074 enum dcerpc_transport_t transport,
4075 enum pipe_auth_type auth_type,
4076 enum dcerpc_AuthLevel auth_level,
4078 const char *username,
4079 const char *password,
4080 struct rpc_pipe_client **presult)
4082 struct rpc_pipe_client *result;
4083 struct cli_pipe_auth_data *auth;
4086 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4087 if (!NT_STATUS_IS_OK(status)) {
4091 status = rpccli_ntlmssp_bind_data(
4092 result, auth_type, auth_level, domain, username,
4094 if (!NT_STATUS_IS_OK(status)) {
4095 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
4096 nt_errstr(status)));
4100 status = rpc_pipe_bind(result, auth);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
4103 nt_errstr(status) ));
4107 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
4108 "machine %s and bound NTLMSSP as user %s\\%s.\n",
4109 get_pipe_name_from_syntax(talloc_tos(), interface),
4110 cli->desthost, domain, username ));
4113 return NT_STATUS_OK;
4117 TALLOC_FREE(result);
4121 /****************************************************************************
4123 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4124 ****************************************************************************/
4126 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4127 const struct ndr_syntax_id *interface,
4128 enum dcerpc_transport_t transport,
4129 enum dcerpc_AuthLevel auth_level,
4131 const char *username,
4132 const char *password,
4133 struct rpc_pipe_client **presult)
4135 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4138 PIPE_AUTH_TYPE_NTLMSSP,
4146 /****************************************************************************
4148 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4149 ****************************************************************************/
4151 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4152 const struct ndr_syntax_id *interface,
4153 enum dcerpc_transport_t transport,
4154 enum dcerpc_AuthLevel auth_level,
4156 const char *username,
4157 const char *password,
4158 struct rpc_pipe_client **presult)
4160 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4163 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4171 /****************************************************************************
4172 Get a the schannel session key out of an already opened netlogon pipe.
4173 ****************************************************************************/
4174 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4175 struct cli_state *cli,
4179 enum netr_SchannelType sec_chan_type = 0;
4180 unsigned char machine_pwd[16];
4181 const char *machine_account;
4184 /* Get the machine account credentials from secrets.tdb. */
4185 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4188 DEBUG(0, ("get_schannel_session_key: could not fetch "
4189 "trust account password for domain '%s'\n",
4191 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4194 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4195 cli->desthost, /* server name */
4196 domain, /* domain */
4197 global_myname(), /* client name */
4198 machine_account, /* machine account name */
4203 if (!NT_STATUS_IS_OK(status)) {
4204 DEBUG(3, ("get_schannel_session_key_common: "
4205 "rpccli_netlogon_setup_creds failed with result %s "
4206 "to server %s, domain %s, machine account %s.\n",
4207 nt_errstr(status), cli->desthost, domain,
4212 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4213 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4215 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4218 return NT_STATUS_OK;;
4221 /****************************************************************************
4222 Open a netlogon pipe and get the schannel session key.
4223 Now exposed to external callers.
4224 ****************************************************************************/
4227 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4230 struct rpc_pipe_client **presult)
4232 struct rpc_pipe_client *netlogon_pipe = NULL;
4235 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4237 if (!NT_STATUS_IS_OK(status)) {
4241 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4243 if (!NT_STATUS_IS_OK(status)) {
4244 TALLOC_FREE(netlogon_pipe);
4248 *presult = netlogon_pipe;
4249 return NT_STATUS_OK;
4252 /****************************************************************************
4254 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4255 using session_key. sign and seal.
4257 The *pdc will be stolen onto this new pipe
4258 ****************************************************************************/
4260 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4261 const struct ndr_syntax_id *interface,
4262 enum dcerpc_transport_t transport,
4263 enum dcerpc_AuthLevel auth_level,
4265 struct netlogon_creds_CredentialState **pdc,
4266 struct rpc_pipe_client **presult)
4268 struct rpc_pipe_client *result;
4269 struct cli_pipe_auth_data *auth;
4272 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4273 if (!NT_STATUS_IS_OK(status)) {
4277 status = rpccli_schannel_bind_data(result, domain, auth_level,
4279 if (!NT_STATUS_IS_OK(status)) {
4280 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4281 nt_errstr(status)));
4282 TALLOC_FREE(result);
4286 status = rpc_pipe_bind(result, auth);
4287 if (!NT_STATUS_IS_OK(status)) {
4288 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4289 "cli_rpc_pipe_bind failed with error %s\n",
4290 nt_errstr(status) ));
4291 TALLOC_FREE(result);
4296 * The credentials on a new netlogon pipe are the ones we are passed
4297 * in - reference them in
4299 result->dc = talloc_move(result, pdc);
4301 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4302 "for domain %s and bound using schannel.\n",
4303 get_pipe_name_from_syntax(talloc_tos(), interface),
4304 cli->desthost, domain ));
4307 return NT_STATUS_OK;
4310 /****************************************************************************
4311 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4312 Fetch the session key ourselves using a temporary netlogon pipe. This
4313 version uses an ntlmssp auth bound netlogon pipe to get the key.
4314 ****************************************************************************/
4316 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4318 const char *username,
4319 const char *password,
4321 struct rpc_pipe_client **presult)
4323 struct rpc_pipe_client *netlogon_pipe = NULL;
4326 status = cli_rpc_pipe_open_spnego_ntlmssp(
4327 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4328 DCERPC_AUTH_LEVEL_PRIVACY,
4329 domain, username, password, &netlogon_pipe);
4330 if (!NT_STATUS_IS_OK(status)) {
4334 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4336 if (!NT_STATUS_IS_OK(status)) {
4337 TALLOC_FREE(netlogon_pipe);
4341 *presult = netlogon_pipe;
4342 return NT_STATUS_OK;
4345 /****************************************************************************
4346 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4347 Fetch the session key ourselves using a temporary netlogon pipe. This version
4348 uses an ntlmssp bind to get the session key.
4349 ****************************************************************************/
4351 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4352 const struct ndr_syntax_id *interface,
4353 enum dcerpc_transport_t transport,
4354 enum dcerpc_AuthLevel auth_level,
4356 const char *username,
4357 const char *password,
4358 struct rpc_pipe_client **presult)
4360 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4361 struct rpc_pipe_client *netlogon_pipe = NULL;
4362 struct rpc_pipe_client *result = NULL;
4365 status = get_schannel_session_key_auth_ntlmssp(
4366 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4367 if (!NT_STATUS_IS_OK(status)) {
4368 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4369 "key from server %s for domain %s.\n",
4370 cli->desthost, domain ));
4374 status = cli_rpc_pipe_open_schannel_with_key(
4375 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4378 /* Now we've bound using the session key we can close the netlog pipe. */
4379 TALLOC_FREE(netlogon_pipe);
4381 if (NT_STATUS_IS_OK(status)) {
4387 /****************************************************************************
4388 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4389 Fetch the session key ourselves using a temporary netlogon pipe.
4390 ****************************************************************************/
4392 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4393 const struct ndr_syntax_id *interface,
4394 enum dcerpc_transport_t transport,
4395 enum dcerpc_AuthLevel auth_level,
4397 struct rpc_pipe_client **presult)
4399 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4400 struct rpc_pipe_client *netlogon_pipe = NULL;
4401 struct rpc_pipe_client *result = NULL;
4404 status = get_schannel_session_key(cli, domain, &neg_flags,
4406 if (!NT_STATUS_IS_OK(status)) {
4407 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4408 "key from server %s for domain %s.\n",
4409 cli->desthost, domain ));
4413 status = cli_rpc_pipe_open_schannel_with_key(
4414 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4417 /* Now we've bound using the session key we can close the netlog pipe. */
4418 TALLOC_FREE(netlogon_pipe);
4420 if (NT_STATUS_IS_OK(status)) {
4427 /****************************************************************************
4428 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4429 The idea is this can be called with service_princ, username and password all
4430 NULL so long as the caller has a TGT.
4431 ****************************************************************************/
4433 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4434 const struct ndr_syntax_id *interface,
4435 enum dcerpc_AuthLevel auth_level,
4436 const char *service_princ,
4437 const char *username,
4438 const char *password,
4439 struct rpc_pipe_client **presult)
4442 struct rpc_pipe_client *result;
4443 struct cli_pipe_auth_data *auth;
4446 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4447 if (!NT_STATUS_IS_OK(status)) {
4451 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4452 username, password, &auth);
4453 if (!NT_STATUS_IS_OK(status)) {
4454 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4455 nt_errstr(status)));
4456 TALLOC_FREE(result);
4460 status = rpc_pipe_bind(result, auth);
4461 if (!NT_STATUS_IS_OK(status)) {
4462 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4463 "with error %s\n", nt_errstr(status)));
4464 TALLOC_FREE(result);
4469 return NT_STATUS_OK;
4471 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4472 return NT_STATUS_NOT_IMPLEMENTED;
4476 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4477 struct rpc_pipe_client *cli,
4478 DATA_BLOB *session_key)
4480 if (!session_key || !cli) {
4481 return NT_STATUS_INVALID_PARAMETER;
4485 return NT_STATUS_INVALID_PARAMETER;
4488 switch (cli->auth->auth_type) {
4489 case PIPE_AUTH_TYPE_SCHANNEL:
4490 *session_key = data_blob_talloc(mem_ctx,
4491 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4493 case PIPE_AUTH_TYPE_NTLMSSP:
4494 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4495 *session_key = data_blob_talloc(mem_ctx,
4496 cli->auth->a_u.ntlmssp_state->session_key.data,
4497 cli->auth->a_u.ntlmssp_state->session_key.length);
4499 case PIPE_AUTH_TYPE_KRB5:
4500 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4501 *session_key = data_blob_talloc(mem_ctx,
4502 cli->auth->a_u.kerberos_auth->session_key.data,
4503 cli->auth->a_u.kerberos_auth->session_key.length);
4505 case PIPE_AUTH_TYPE_NONE:
4506 *session_key = data_blob_talloc(mem_ctx,
4507 cli->auth->user_session_key.data,
4508 cli->auth->user_session_key.length);
4511 return NT_STATUS_NO_USER_SESSION_KEY;
4514 return NT_STATUS_OK;