2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_lsa.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../librpc/gen_ndr/ndr_samr.h"
26 #include "../librpc/gen_ndr/ndr_netlogon.h"
27 #include "../librpc/gen_ndr/ndr_srvsvc.h"
28 #include "../librpc/gen_ndr/ndr_wkssvc.h"
29 #include "../librpc/gen_ndr/ndr_winreg.h"
30 #include "../librpc/gen_ndr/ndr_spoolss.h"
31 #include "../librpc/gen_ndr/ndr_dfs.h"
32 #include "../librpc/gen_ndr/ndr_echo.h"
33 #include "../librpc/gen_ndr/ndr_initshutdown.h"
34 #include "../librpc/gen_ndr/ndr_svcctl.h"
35 #include "../librpc/gen_ndr/ndr_eventlog.h"
36 #include "../librpc/gen_ndr/ndr_ntsvcs.h"
37 #include "../librpc/gen_ndr/ndr_epmapper.h"
38 #include "../librpc/gen_ndr/ndr_drsuapi.h"
39 #include "../libcli/auth/schannel.h"
40 #include "../libcli/auth/spnego.h"
42 #include "../libcli/auth/ntlmssp.h"
43 #include "rpc_client/cli_netlogon.h"
44 #include "librpc/gen_ndr/ndr_dcerpc.h"
47 #define DBGC_CLASS DBGC_RPC_CLI
49 static const char *get_pipe_name_from_iface(
50 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
53 const struct ndr_interface_string_array *ep = interface->endpoints;
56 for (i=0; i<ep->count; i++) {
57 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
66 * extract the pipe name without \\pipe from for example
67 * ncacn_np:[\\pipe\\epmapper]
69 p = strchr(ep->names[i]+15, ']');
73 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
76 static const struct ndr_interface_table **interfaces;
78 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
80 int num_interfaces = talloc_array_length(interfaces);
81 const struct ndr_interface_table **tmp;
84 for (i=0; i<num_interfaces; i++) {
85 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
86 &interface->syntax_id)) {
91 tmp = talloc_realloc(NULL, interfaces,
92 const struct ndr_interface_table *,
95 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
99 interfaces[num_interfaces] = interface;
103 static bool initialize_interfaces(void)
105 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
108 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
111 if (!smb_register_ndr_interface(&ndr_table_samr)) {
114 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
117 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
120 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
123 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
126 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
129 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
132 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
135 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
138 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
141 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
144 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
147 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
150 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
156 const struct ndr_interface_table *get_iface_from_syntax(
157 const struct ndr_syntax_id *syntax)
162 if (interfaces == NULL) {
163 if (!initialize_interfaces()) {
167 num_interfaces = talloc_array_length(interfaces);
169 for (i=0; i<num_interfaces; i++) {
170 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
171 return interfaces[i];
178 /****************************************************************************
179 Return the pipe name from the interface.
180 ****************************************************************************/
182 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
183 const struct ndr_syntax_id *syntax)
185 const struct ndr_interface_table *interface;
189 interface = get_iface_from_syntax(syntax);
190 if (interface != NULL) {
191 result = get_pipe_name_from_iface(mem_ctx, interface);
192 if (result != NULL) {
198 * Here we should ask \\epmapper, but for now our code is only
199 * interested in the known pipes mentioned in pipe_names[]
202 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
203 if (guid_str == NULL) {
206 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
207 (int)syntax->if_version);
208 TALLOC_FREE(guid_str);
210 if (result == NULL) {
216 /********************************************************************
217 Map internal value to wire value.
218 ********************************************************************/
220 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
224 case PIPE_AUTH_TYPE_NONE:
225 return DCERPC_AUTH_TYPE_NONE;
227 case PIPE_AUTH_TYPE_NTLMSSP:
228 return DCERPC_AUTH_TYPE_NTLMSSP;
230 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
231 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
232 return DCERPC_AUTH_TYPE_SPNEGO;
234 case PIPE_AUTH_TYPE_SCHANNEL:
235 return DCERPC_AUTH_TYPE_SCHANNEL;
237 case PIPE_AUTH_TYPE_KRB5:
238 return DCERPC_AUTH_TYPE_KRB5;
241 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
243 (unsigned int)auth_type ));
249 /********************************************************************
250 Pipe description for a DEBUG
251 ********************************************************************/
252 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
253 struct rpc_pipe_client *cli)
255 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
256 if (result == NULL) {
262 /********************************************************************
264 ********************************************************************/
266 static uint32 get_rpc_call_id(void)
268 static uint32 call_id = 0;
273 * Realloc pdu to have a least "size" bytes
276 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
280 if (prs_data_size(pdu) >= size) {
284 extra_size = size - prs_data_size(pdu);
286 if (!prs_force_grow(pdu, extra_size)) {
287 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
288 "%d bytes.\n", (int)extra_size));
292 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
293 (int)extra_size, prs_data_size(pdu)));
297 /*******************************************************************
298 *******************************************************************/
300 NTSTATUS dcerpc_push_ncacn_packet(TALLOC_CTX *mem_ctx,
301 enum dcerpc_pkt_type ptype,
303 uint16_t frag_length,
304 uint16_t auth_length,
306 union dcerpc_payload u,
309 struct ncacn_packet r;
310 enum ndr_err_code ndr_err;
313 r.rpc_vers_minor = 0;
315 r.pfc_flags = pfc_flags;
316 r.drep[0] = DCERPC_DREP_LE;
320 r.frag_length = frag_length;
321 r.auth_length = auth_length;
325 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
326 (ndr_push_flags_fn_t)ndr_push_ncacn_packet);
327 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
328 return ndr_map_error2ntstatus(ndr_err);
331 if (DEBUGLEVEL >= 10) {
332 NDR_PRINT_DEBUG(ncacn_packet, &r);
338 /*******************************************************************
339 *******************************************************************/
341 NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
342 const DATA_BLOB *blob,
343 struct ncacn_packet *r)
345 enum ndr_err_code ndr_err;
347 ndr_err = ndr_pull_struct_blob(blob, mem_ctx, r,
348 (ndr_pull_flags_fn_t)ndr_pull_ncacn_packet);
349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
350 return ndr_map_error2ntstatus(ndr_err);
353 if (DEBUGLEVEL >= 10) {
354 NDR_PRINT_DEBUG(ncacn_packet, r);
360 /*******************************************************************
361 Use SMBreadX to get rest of one fragment's worth of rpc data.
362 Reads the whole size or give an error message
363 ********************************************************************/
365 struct rpc_read_state {
366 struct event_context *ev;
367 struct rpc_cli_transport *transport;
373 static void rpc_read_done(struct tevent_req *subreq);
375 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
376 struct event_context *ev,
377 struct rpc_cli_transport *transport,
378 uint8_t *data, size_t size)
380 struct tevent_req *req, *subreq;
381 struct rpc_read_state *state;
383 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
388 state->transport = transport;
393 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
395 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
397 if (subreq == NULL) {
400 tevent_req_set_callback(subreq, rpc_read_done, req);
408 static void rpc_read_done(struct tevent_req *subreq)
410 struct tevent_req *req = tevent_req_callback_data(
411 subreq, struct tevent_req);
412 struct rpc_read_state *state = tevent_req_data(
413 req, struct rpc_read_state);
417 status = state->transport->read_recv(subreq, &received);
419 if (!NT_STATUS_IS_OK(status)) {
420 tevent_req_nterror(req, status);
424 state->num_read += received;
425 if (state->num_read == state->size) {
426 tevent_req_done(req);
430 subreq = state->transport->read_send(state, state->ev,
431 state->data + state->num_read,
432 state->size - state->num_read,
433 state->transport->priv);
434 if (tevent_req_nomem(subreq, req)) {
437 tevent_req_set_callback(subreq, rpc_read_done, req);
440 static NTSTATUS rpc_read_recv(struct tevent_req *req)
442 return tevent_req_simple_recv_ntstatus(req);
445 struct rpc_write_state {
446 struct event_context *ev;
447 struct rpc_cli_transport *transport;
453 static void rpc_write_done(struct tevent_req *subreq);
455 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
456 struct event_context *ev,
457 struct rpc_cli_transport *transport,
458 const uint8_t *data, size_t size)
460 struct tevent_req *req, *subreq;
461 struct rpc_write_state *state;
463 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
468 state->transport = transport;
471 state->num_written = 0;
473 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
475 subreq = transport->write_send(state, ev, data, size, transport->priv);
476 if (subreq == NULL) {
479 tevent_req_set_callback(subreq, rpc_write_done, req);
486 static void rpc_write_done(struct tevent_req *subreq)
488 struct tevent_req *req = tevent_req_callback_data(
489 subreq, struct tevent_req);
490 struct rpc_write_state *state = tevent_req_data(
491 req, struct rpc_write_state);
495 status = state->transport->write_recv(subreq, &written);
497 if (!NT_STATUS_IS_OK(status)) {
498 tevent_req_nterror(req, status);
502 state->num_written += written;
504 if (state->num_written == state->size) {
505 tevent_req_done(req);
509 subreq = state->transport->write_send(state, state->ev,
510 state->data + state->num_written,
511 state->size - state->num_written,
512 state->transport->priv);
513 if (tevent_req_nomem(subreq, req)) {
516 tevent_req_set_callback(subreq, rpc_write_done, req);
519 static NTSTATUS rpc_write_recv(struct tevent_req *req)
521 return tevent_req_simple_recv_ntstatus(req);
525 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
526 struct rpc_hdr_info *prhdr,
530 * This next call sets the endian bit correctly in current_pdu. We
531 * will propagate this to rbuf later.
534 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
535 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
536 return NT_STATUS_BUFFER_TOO_SMALL;
539 if (prhdr->frag_len > cli->max_recv_frag) {
540 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
541 " we only allow %d\n", (int)prhdr->frag_len,
542 (int)cli->max_recv_frag));
543 return NT_STATUS_BUFFER_TOO_SMALL;
549 /****************************************************************************
550 Try and get a PDU's worth of data from current_pdu. If not, then read more
552 ****************************************************************************/
554 struct get_complete_frag_state {
555 struct event_context *ev;
556 struct rpc_pipe_client *cli;
557 struct rpc_hdr_info *prhdr;
561 static void get_complete_frag_got_header(struct tevent_req *subreq);
562 static void get_complete_frag_got_rest(struct tevent_req *subreq);
564 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
565 struct event_context *ev,
566 struct rpc_pipe_client *cli,
567 struct rpc_hdr_info *prhdr,
570 struct tevent_req *req, *subreq;
571 struct get_complete_frag_state *state;
575 req = tevent_req_create(mem_ctx, &state,
576 struct get_complete_frag_state);
582 state->prhdr = prhdr;
585 pdu_len = prs_data_size(pdu);
586 if (pdu_len < RPC_HEADER_LEN) {
587 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
588 status = NT_STATUS_NO_MEMORY;
591 subreq = rpc_read_send(
593 state->cli->transport,
594 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
595 RPC_HEADER_LEN - pdu_len);
596 if (subreq == NULL) {
597 status = NT_STATUS_NO_MEMORY;
600 tevent_req_set_callback(subreq, get_complete_frag_got_header,
605 status = parse_rpc_header(cli, prhdr, pdu);
606 if (!NT_STATUS_IS_OK(status)) {
611 * Ensure we have frag_len bytes of data.
613 if (pdu_len < prhdr->frag_len) {
614 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
615 status = NT_STATUS_NO_MEMORY;
618 subreq = rpc_read_send(state, state->ev,
619 state->cli->transport,
620 (uint8_t *)(prs_data_p(pdu) + pdu_len),
621 prhdr->frag_len - pdu_len);
622 if (subreq == NULL) {
623 status = NT_STATUS_NO_MEMORY;
626 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
631 status = NT_STATUS_OK;
633 if (NT_STATUS_IS_OK(status)) {
634 tevent_req_done(req);
636 tevent_req_nterror(req, status);
638 return tevent_req_post(req, ev);
641 static void get_complete_frag_got_header(struct tevent_req *subreq)
643 struct tevent_req *req = tevent_req_callback_data(
644 subreq, struct tevent_req);
645 struct get_complete_frag_state *state = tevent_req_data(
646 req, struct get_complete_frag_state);
649 status = rpc_read_recv(subreq);
651 if (!NT_STATUS_IS_OK(status)) {
652 tevent_req_nterror(req, status);
656 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
657 if (!NT_STATUS_IS_OK(status)) {
658 tevent_req_nterror(req, status);
662 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
663 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
668 * We're here in this piece of code because we've read exactly
669 * RPC_HEADER_LEN bytes into state->pdu.
672 subreq = rpc_read_send(
673 state, state->ev, state->cli->transport,
674 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
675 state->prhdr->frag_len - RPC_HEADER_LEN);
676 if (tevent_req_nomem(subreq, req)) {
679 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
682 static void get_complete_frag_got_rest(struct tevent_req *subreq)
684 struct tevent_req *req = tevent_req_callback_data(
685 subreq, struct tevent_req);
688 status = rpc_read_recv(subreq);
690 if (!NT_STATUS_IS_OK(status)) {
691 tevent_req_nterror(req, status);
694 tevent_req_done(req);
697 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
699 return tevent_req_simple_recv_ntstatus(req);
702 /****************************************************************************
703 NTLMSSP specific sign/seal.
704 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
705 In fact I should probably abstract these into identical pieces of code... JRA.
706 ****************************************************************************/
708 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
709 prs_struct *current_pdu,
710 uint8 *p_ss_padding_len)
712 RPC_HDR_AUTH auth_info;
713 uint32 save_offset = prs_offset(current_pdu);
714 uint32 auth_len = prhdr->auth_len;
715 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
716 unsigned char *data = NULL;
718 unsigned char *full_packet_data = NULL;
719 size_t full_packet_data_len;
723 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
724 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
728 if (!ntlmssp_state) {
729 return NT_STATUS_INVALID_PARAMETER;
732 /* Ensure there's enough data for an authenticated response. */
733 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
734 prhdr->frag_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
735 RPC_HDR_AUTH_LEN + auth_len) {
736 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
737 (unsigned int)auth_len ));
738 return NT_STATUS_BUFFER_TOO_SMALL;
742 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
743 * after the RPC header.
744 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
745 * functions as NTLMv2 checks the rpc headers also.
748 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
749 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
751 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
752 full_packet_data_len = prhdr->frag_len - auth_len;
754 /* Pull the auth header and the following data into a blob. */
755 /* NB. The offset of the auth_header is relative to the *end*
756 * of the packet, not the start. */
757 if(!prs_set_offset(current_pdu, prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
758 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
759 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
760 return NT_STATUS_BUFFER_TOO_SMALL;
763 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
764 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
765 return NT_STATUS_BUFFER_TOO_SMALL;
768 /* Ensure auth_pad_len fits into the packet. */
769 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
770 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
771 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
772 "too large (%u), auth_len (%u), frag_len = (%u).\n",
773 (unsigned int)auth_info.auth_pad_len,
774 (unsigned int)auth_len,
775 (unsigned int)prhdr->frag_len ));
776 return NT_STATUS_BUFFER_TOO_SMALL;
780 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
781 auth_blob.length = auth_len;
783 switch (cli->auth->auth_level) {
784 case DCERPC_AUTH_LEVEL_PRIVACY:
785 /* Data is encrypted. */
786 status = ntlmssp_unseal_packet(ntlmssp_state,
789 full_packet_data_len,
791 if (!NT_STATUS_IS_OK(status)) {
792 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
793 "packet from %s. Error was %s.\n",
794 rpccli_pipe_txt(talloc_tos(), cli),
795 nt_errstr(status) ));
799 case DCERPC_AUTH_LEVEL_INTEGRITY:
800 /* Data is signed. */
801 status = ntlmssp_check_packet(ntlmssp_state,
804 full_packet_data_len,
806 if (!NT_STATUS_IS_OK(status)) {
807 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
808 "packet from %s. Error was %s.\n",
809 rpccli_pipe_txt(talloc_tos(), cli),
810 nt_errstr(status) ));
815 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
816 "auth level %d\n", cli->auth->auth_level));
817 return NT_STATUS_INVALID_INFO_CLASS;
821 * Return the current pointer to the data offset.
824 if(!prs_set_offset(current_pdu, save_offset)) {
825 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
826 (unsigned int)save_offset ));
827 return NT_STATUS_BUFFER_TOO_SMALL;
831 * Remember the padding length. We must remove it from the real data
832 * stream once the sign/seal is done.
835 *p_ss_padding_len = auth_info.auth_pad_len;
840 /****************************************************************************
841 schannel specific sign/seal.
842 ****************************************************************************/
844 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
845 prs_struct *current_pdu,
846 uint8 *p_ss_padding_len)
848 RPC_HDR_AUTH auth_info;
849 uint32 auth_len = prhdr->auth_len;
850 uint32 save_offset = prs_offset(current_pdu);
851 struct schannel_state *schannel_auth =
852 cli->auth->a_u.schannel_auth;
858 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
859 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
863 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
864 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
865 return NT_STATUS_INVALID_PARAMETER;
868 if (!schannel_auth) {
869 return NT_STATUS_INVALID_PARAMETER;
872 /* Ensure there's enough data for an authenticated response. */
873 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
874 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
875 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
876 (unsigned int)auth_len ));
877 return NT_STATUS_INVALID_PARAMETER;
880 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
882 /* Pull the auth header and the following data into a blob. */
883 /* NB. The offset of the auth_header is relative to the *end*
884 * of the packet, not the start. */
885 if(!prs_set_offset(current_pdu,
886 prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
887 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
889 (unsigned int)(prhdr->frag_len -
890 RPC_HDR_AUTH_LEN - auth_len) ));
891 return NT_STATUS_BUFFER_TOO_SMALL;
894 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
895 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
896 return NT_STATUS_BUFFER_TOO_SMALL;
899 /* Ensure auth_pad_len fits into the packet. */
900 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
901 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
902 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
903 "too large (%u), auth_len (%u), frag_len = (%u).\n",
904 (unsigned int)auth_info.auth_pad_len,
905 (unsigned int)auth_len,
906 (unsigned int)prhdr->frag_len ));
907 return NT_STATUS_BUFFER_TOO_SMALL;
910 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
911 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
912 auth_info.auth_type));
913 return NT_STATUS_BUFFER_TOO_SMALL;
916 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
918 if (DEBUGLEVEL >= 10) {
919 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
922 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
924 switch (cli->auth->auth_level) {
925 case DCERPC_AUTH_LEVEL_PRIVACY:
926 status = netsec_incoming_packet(schannel_auth,
933 case DCERPC_AUTH_LEVEL_INTEGRITY:
934 status = netsec_incoming_packet(schannel_auth,
942 status = NT_STATUS_INTERNAL_ERROR;
946 if (!NT_STATUS_IS_OK(status)) {
947 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
948 "Connection to %s (%s).\n",
949 rpccli_pipe_txt(talloc_tos(), cli),
951 return NT_STATUS_INVALID_PARAMETER;
955 * Return the current pointer to the data offset.
958 if(!prs_set_offset(current_pdu, save_offset)) {
959 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
960 (unsigned int)save_offset ));
961 return NT_STATUS_BUFFER_TOO_SMALL;
965 * Remember the padding length. We must remove it from the real data
966 * stream once the sign/seal is done.
969 *p_ss_padding_len = auth_info.auth_pad_len;
974 /****************************************************************************
975 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
976 ****************************************************************************/
978 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
979 prs_struct *current_pdu,
980 uint8 *p_ss_padding_len)
982 NTSTATUS ret = NT_STATUS_OK;
984 /* Paranioa checks for auth_len. */
985 if (prhdr->auth_len) {
986 if (prhdr->auth_len > prhdr->frag_len) {
987 return NT_STATUS_INVALID_PARAMETER;
990 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
991 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
992 /* Integer wrap attempt. */
993 return NT_STATUS_INVALID_PARAMETER;
998 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
1001 switch(cli->auth->auth_type) {
1002 case PIPE_AUTH_TYPE_NONE:
1003 if (prhdr->auth_len) {
1004 DEBUG(3, ("cli_pipe_validate_rpc_response: "
1005 "Connection to %s - got non-zero "
1007 rpccli_pipe_txt(talloc_tos(), cli),
1008 (unsigned int)prhdr->auth_len ));
1009 return NT_STATUS_INVALID_PARAMETER;
1013 case PIPE_AUTH_TYPE_NTLMSSP:
1014 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1015 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
1016 if (!NT_STATUS_IS_OK(ret)) {
1021 case PIPE_AUTH_TYPE_SCHANNEL:
1022 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
1023 if (!NT_STATUS_IS_OK(ret)) {
1028 case PIPE_AUTH_TYPE_KRB5:
1029 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1031 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
1032 "to %s - unknown internal auth type %u.\n",
1033 rpccli_pipe_txt(talloc_tos(), cli),
1034 cli->auth->auth_type ));
1035 return NT_STATUS_INVALID_INFO_CLASS;
1038 return NT_STATUS_OK;
1041 /****************************************************************************
1042 Do basic authentication checks on an incoming pdu.
1043 ****************************************************************************/
1045 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
1046 prs_struct *current_pdu,
1047 uint8 expected_pkt_type,
1050 prs_struct *return_data)
1053 NTSTATUS ret = NT_STATUS_OK;
1054 uint32 current_pdu_len = prs_data_size(current_pdu);
1056 if (current_pdu_len != prhdr->frag_len) {
1057 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
1058 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
1059 return NT_STATUS_INVALID_PARAMETER;
1063 * Point the return values at the real data including the RPC
1064 * header. Just in case the caller wants it.
1066 *ppdata = prs_data_p(current_pdu);
1067 *pdata_len = current_pdu_len;
1069 /* Ensure we have the correct type. */
1070 switch (prhdr->pkt_type) {
1071 case DCERPC_PKT_ALTER_RESP:
1072 case DCERPC_PKT_BIND_ACK:
1074 /* Alter context and bind ack share the same packet definitions. */
1078 case DCERPC_PKT_RESPONSE:
1080 RPC_HDR_RESP rhdr_resp;
1081 uint8 ss_padding_len = 0;
1083 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1084 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1085 return NT_STATUS_BUFFER_TOO_SMALL;
1088 /* Here's where we deal with incoming sign/seal. */
1089 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1090 current_pdu, &ss_padding_len);
1091 if (!NT_STATUS_IS_OK(ret)) {
1095 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1096 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1098 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1099 return NT_STATUS_BUFFER_TOO_SMALL;
1102 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1104 /* Remember to remove the auth footer. */
1105 if (prhdr->auth_len) {
1106 /* We've already done integer wrap tests on auth_len in
1107 cli_pipe_validate_rpc_response(). */
1108 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
1109 return NT_STATUS_BUFFER_TOO_SMALL;
1111 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1114 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1115 current_pdu_len, *pdata_len, ss_padding_len ));
1118 * If this is the first reply, and the allocation hint is reasonably, try and
1119 * set up the return_data parse_struct to the correct size.
1122 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1123 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1124 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1125 "too large to allocate\n",
1126 (unsigned int)rhdr_resp.alloc_hint ));
1127 return NT_STATUS_NO_MEMORY;
1134 case DCERPC_PKT_BIND_NAK:
1135 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1136 "received from %s!\n",
1137 rpccli_pipe_txt(talloc_tos(), cli)));
1138 /* Use this for now... */
1139 return NT_STATUS_NETWORK_ACCESS_DENIED;
1141 case DCERPC_PKT_FAULT:
1144 struct ncacn_packet r;
1146 blob = data_blob_const(prs_data_p(current_pdu),
1147 prs_data_size(current_pdu));
1149 ret = dcerpc_pull_ncacn_packet(cli, &blob, &r);
1150 if (!NT_STATUS_IS_OK(ret)) {
1153 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1154 "code %s received from %s!\n",
1155 dcerpc_errstr(talloc_tos(), r.u.fault.status),
1156 rpccli_pipe_txt(talloc_tos(), cli)));
1158 if (NT_STATUS_IS_OK(NT_STATUS(r.u.fault.status))) {
1159 return NT_STATUS_UNSUCCESSFUL;
1161 return NT_STATUS(r.u.fault.status);
1166 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1168 (unsigned int)prhdr->pkt_type,
1169 rpccli_pipe_txt(talloc_tos(), cli)));
1170 return NT_STATUS_INVALID_INFO_CLASS;
1173 if (prhdr->pkt_type != expected_pkt_type) {
1174 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1175 "got an unexpected RPC packet type - %u, not %u\n",
1176 rpccli_pipe_txt(talloc_tos(), cli),
1178 expected_pkt_type));
1179 return NT_STATUS_INVALID_INFO_CLASS;
1182 /* Do this just before return - we don't want to modify any rpc header
1183 data before now as we may have needed to do cryptographic actions on
1186 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1187 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1188 "setting fragment first/last ON.\n"));
1189 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1192 return NT_STATUS_OK;
1195 /****************************************************************************
1196 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1197 Normally the frag_len and buffer size will match, but on the first trans
1198 reply there is a theoretical chance that buffer size > frag_len, so we must
1200 ****************************************************************************/
1202 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1204 uint32 current_pdu_len = prs_data_size(current_pdu);
1206 if (current_pdu_len < prhdr->frag_len) {
1207 return NT_STATUS_BUFFER_TOO_SMALL;
1211 if (current_pdu_len == (uint32)prhdr->frag_len) {
1212 prs_mem_free(current_pdu);
1213 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1214 /* Make current_pdu dynamic with no memory. */
1215 prs_give_memory(current_pdu, 0, 0, True);
1216 return NT_STATUS_OK;
1220 * Oh no ! More data in buffer than we processed in current pdu.
1221 * Cheat. Move the data down and shrink the buffer.
1224 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1225 current_pdu_len - prhdr->frag_len);
1227 /* Remember to set the read offset back to zero. */
1228 prs_set_offset(current_pdu, 0);
1230 /* Shrink the buffer. */
1231 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1232 return NT_STATUS_BUFFER_TOO_SMALL;
1235 return NT_STATUS_OK;
1238 /****************************************************************************
1239 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1240 ****************************************************************************/
1242 struct cli_api_pipe_state {
1243 struct event_context *ev;
1244 struct rpc_cli_transport *transport;
1249 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1250 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1251 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1253 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1254 struct event_context *ev,
1255 struct rpc_cli_transport *transport,
1256 uint8_t *data, size_t data_len,
1257 uint32_t max_rdata_len)
1259 struct tevent_req *req, *subreq;
1260 struct cli_api_pipe_state *state;
1263 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1268 state->transport = transport;
1270 if (max_rdata_len < RPC_HEADER_LEN) {
1272 * For a RPC reply we always need at least RPC_HEADER_LEN
1273 * bytes. We check this here because we will receive
1274 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1276 status = NT_STATUS_INVALID_PARAMETER;
1280 if (transport->trans_send != NULL) {
1281 subreq = transport->trans_send(state, ev, data, data_len,
1282 max_rdata_len, transport->priv);
1283 if (subreq == NULL) {
1286 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1291 * If the transport does not provide a "trans" routine, i.e. for
1292 * example the ncacn_ip_tcp transport, do the write/read step here.
1295 subreq = rpc_write_send(state, ev, transport, data, data_len);
1296 if (subreq == NULL) {
1299 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1303 tevent_req_nterror(req, status);
1304 return tevent_req_post(req, ev);
1310 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1312 struct tevent_req *req = tevent_req_callback_data(
1313 subreq, struct tevent_req);
1314 struct cli_api_pipe_state *state = tevent_req_data(
1315 req, struct cli_api_pipe_state);
1318 status = state->transport->trans_recv(subreq, state, &state->rdata,
1320 TALLOC_FREE(subreq);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 tevent_req_nterror(req, status);
1325 tevent_req_done(req);
1328 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1330 struct tevent_req *req = tevent_req_callback_data(
1331 subreq, struct tevent_req);
1332 struct cli_api_pipe_state *state = tevent_req_data(
1333 req, struct cli_api_pipe_state);
1336 status = rpc_write_recv(subreq);
1337 TALLOC_FREE(subreq);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 tevent_req_nterror(req, status);
1343 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1344 if (tevent_req_nomem(state->rdata, req)) {
1349 * We don't need to use rpc_read_send here, the upper layer will cope
1350 * with a short read, transport->trans_send could also return less
1351 * than state->max_rdata_len.
1353 subreq = state->transport->read_send(state, state->ev, state->rdata,
1355 state->transport->priv);
1356 if (tevent_req_nomem(subreq, req)) {
1359 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1362 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1364 struct tevent_req *req = tevent_req_callback_data(
1365 subreq, struct tevent_req);
1366 struct cli_api_pipe_state *state = tevent_req_data(
1367 req, struct cli_api_pipe_state);
1371 status = state->transport->read_recv(subreq, &received);
1372 TALLOC_FREE(subreq);
1373 if (!NT_STATUS_IS_OK(status)) {
1374 tevent_req_nterror(req, status);
1377 state->rdata_len = received;
1378 tevent_req_done(req);
1381 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1382 uint8_t **prdata, uint32_t *prdata_len)
1384 struct cli_api_pipe_state *state = tevent_req_data(
1385 req, struct cli_api_pipe_state);
1388 if (tevent_req_is_nterror(req, &status)) {
1392 *prdata = talloc_move(mem_ctx, &state->rdata);
1393 *prdata_len = state->rdata_len;
1394 return NT_STATUS_OK;
1397 /****************************************************************************
1398 Send data on an rpc pipe via trans. The prs_struct data must be the last
1399 pdu fragment of an NDR data stream.
1401 Receive response data from an rpc pipe, which may be large...
1403 Read the first fragment: unfortunately have to use SMBtrans for the first
1404 bit, then SMBreadX for subsequent bits.
1406 If first fragment received also wasn't the last fragment, continue
1407 getting fragments until we _do_ receive the last fragment.
1409 Request/Response PDU's look like the following...
1411 |<------------------PDU len----------------------------------------------->|
1412 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1414 +------------+-----------------+-------------+---------------+-------------+
1415 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1416 +------------+-----------------+-------------+---------------+-------------+
1418 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1419 signing & sealing being negotiated.
1421 ****************************************************************************/
1423 struct rpc_api_pipe_state {
1424 struct event_context *ev;
1425 struct rpc_pipe_client *cli;
1426 uint8_t expected_pkt_type;
1428 prs_struct incoming_frag;
1429 struct rpc_hdr_info rhdr;
1431 prs_struct incoming_pdu; /* Incoming reply */
1432 uint32_t incoming_pdu_offset;
1435 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1436 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1438 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1439 struct event_context *ev,
1440 struct rpc_pipe_client *cli,
1441 prs_struct *data, /* Outgoing PDU */
1442 uint8_t expected_pkt_type)
1444 struct tevent_req *req, *subreq;
1445 struct rpc_api_pipe_state *state;
1446 uint16_t max_recv_frag;
1449 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1455 state->expected_pkt_type = expected_pkt_type;
1456 state->incoming_pdu_offset = 0;
1458 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1460 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1461 /* Make incoming_pdu dynamic with no memory. */
1462 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1465 * Ensure we're not sending too much.
1467 if (prs_offset(data) > cli->max_xmit_frag) {
1468 status = NT_STATUS_INVALID_PARAMETER;
1472 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1474 max_recv_frag = cli->max_recv_frag;
1477 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1480 subreq = cli_api_pipe_send(state, ev, cli->transport,
1481 (uint8_t *)prs_data_p(data),
1482 prs_offset(data), max_recv_frag);
1483 if (subreq == NULL) {
1486 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1490 tevent_req_nterror(req, status);
1491 return tevent_req_post(req, ev);
1497 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1499 struct tevent_req *req = tevent_req_callback_data(
1500 subreq, struct tevent_req);
1501 struct rpc_api_pipe_state *state = tevent_req_data(
1502 req, struct rpc_api_pipe_state);
1504 uint8_t *rdata = NULL;
1505 uint32_t rdata_len = 0;
1507 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1508 TALLOC_FREE(subreq);
1509 if (!NT_STATUS_IS_OK(status)) {
1510 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1511 tevent_req_nterror(req, status);
1515 if (rdata == NULL) {
1516 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1517 rpccli_pipe_txt(talloc_tos(), state->cli)));
1518 tevent_req_done(req);
1523 * This is equivalent to a talloc_steal - gives rdata to
1524 * the prs_struct state->incoming_frag.
1526 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1529 /* Ensure we have enough data for a pdu. */
1530 subreq = get_complete_frag_send(state, state->ev, state->cli,
1531 &state->rhdr, &state->incoming_frag);
1532 if (tevent_req_nomem(subreq, req)) {
1535 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1538 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1540 struct tevent_req *req = tevent_req_callback_data(
1541 subreq, struct tevent_req);
1542 struct rpc_api_pipe_state *state = tevent_req_data(
1543 req, struct rpc_api_pipe_state);
1546 uint32_t rdata_len = 0;
1548 status = get_complete_frag_recv(subreq);
1549 TALLOC_FREE(subreq);
1550 if (!NT_STATUS_IS_OK(status)) {
1551 DEBUG(5, ("get_complete_frag failed: %s\n",
1552 nt_errstr(status)));
1553 tevent_req_nterror(req, status);
1557 status = cli_pipe_validate_current_pdu(
1558 state->cli, &state->rhdr, &state->incoming_frag,
1559 state->expected_pkt_type, &rdata, &rdata_len,
1560 &state->incoming_pdu);
1562 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1563 (unsigned)prs_data_size(&state->incoming_frag),
1564 (unsigned)state->incoming_pdu_offset,
1565 nt_errstr(status)));
1567 if (!NT_STATUS_IS_OK(status)) {
1568 tevent_req_nterror(req, status);
1572 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1573 && (state->rhdr.pack_type[0] == 0)) {
1575 * Set the data type correctly for big-endian data on the
1578 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1580 rpccli_pipe_txt(talloc_tos(), state->cli)));
1581 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1584 * Check endianness on subsequent packets.
1586 if (state->incoming_frag.bigendian_data
1587 != state->incoming_pdu.bigendian_data) {
1588 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1590 state->incoming_pdu.bigendian_data?"big":"little",
1591 state->incoming_frag.bigendian_data?"big":"little"));
1592 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1596 /* Now copy the data portion out of the pdu into rbuf. */
1597 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1598 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1602 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1603 rdata, (size_t)rdata_len);
1604 state->incoming_pdu_offset += rdata_len;
1606 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1607 &state->incoming_frag);
1608 if (!NT_STATUS_IS_OK(status)) {
1609 tevent_req_nterror(req, status);
1613 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1614 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1615 rpccli_pipe_txt(talloc_tos(), state->cli),
1616 (unsigned)prs_data_size(&state->incoming_pdu)));
1617 tevent_req_done(req);
1621 subreq = get_complete_frag_send(state, state->ev, state->cli,
1622 &state->rhdr, &state->incoming_frag);
1623 if (tevent_req_nomem(subreq, req)) {
1626 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1629 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1630 prs_struct *reply_pdu)
1632 struct rpc_api_pipe_state *state = tevent_req_data(
1633 req, struct rpc_api_pipe_state);
1636 if (tevent_req_is_nterror(req, &status)) {
1640 *reply_pdu = state->incoming_pdu;
1641 reply_pdu->mem_ctx = mem_ctx;
1644 * Prevent state->incoming_pdu from being freed
1645 * when state is freed.
1647 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1648 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1650 return NT_STATUS_OK;
1653 /*******************************************************************
1654 ********************************************************************/
1656 static NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
1657 enum dcerpc_AuthType auth_type,
1658 enum dcerpc_AuthLevel auth_level,
1659 uint8_t auth_pad_length,
1660 uint32_t auth_context_id,
1661 const DATA_BLOB *credentials,
1664 struct dcerpc_auth r;
1665 enum ndr_err_code ndr_err;
1667 r.auth_type = auth_type;
1668 r.auth_level = auth_level;
1669 r.auth_pad_length = auth_pad_length;
1670 r.auth_reserved = 0;
1671 r.auth_context_id = auth_context_id;
1672 r.credentials = *credentials;
1674 ndr_err = ndr_push_struct_blob(blob, mem_ctx, &r,
1675 (ndr_push_flags_fn_t)ndr_push_dcerpc_auth);
1676 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1677 return ndr_map_error2ntstatus(ndr_err);
1680 if (DEBUGLEVEL >= 10) {
1681 NDR_PRINT_DEBUG(dcerpc_auth, &r);
1684 return NT_STATUS_OK;
1687 /*******************************************************************
1688 Creates krb5 auth bind.
1689 ********************************************************************/
1691 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1692 enum dcerpc_AuthLevel auth_level,
1693 RPC_HDR_AUTH *pauth_out,
1694 prs_struct *auth_data)
1698 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1699 DATA_BLOB tkt = data_blob_null;
1700 DATA_BLOB tkt_wrapped = data_blob_null;
1702 /* We may change the pad length before marshalling. */
1703 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1705 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1706 a->service_principal ));
1708 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1710 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1711 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1714 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1716 a->service_principal,
1717 error_message(ret) ));
1719 data_blob_free(&tkt);
1720 return NT_STATUS_INVALID_PARAMETER;
1723 /* wrap that up in a nice GSS-API wrapping */
1724 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1726 data_blob_free(&tkt);
1728 /* Auth len in the rpc header doesn't include auth_header. */
1729 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1730 data_blob_free(&tkt_wrapped);
1731 return NT_STATUS_NO_MEMORY;
1734 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1735 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1737 data_blob_free(&tkt_wrapped);
1738 return NT_STATUS_OK;
1740 return NT_STATUS_INVALID_PARAMETER;
1744 /*******************************************************************
1745 Creates SPNEGO NTLMSSP auth bind.
1746 ********************************************************************/
1748 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1749 enum dcerpc_AuthLevel auth_level,
1750 RPC_HDR_AUTH *pauth_out,
1751 prs_struct *auth_data)
1754 DATA_BLOB null_blob = data_blob_null;
1755 DATA_BLOB request = data_blob_null;
1756 DATA_BLOB spnego_msg = data_blob_null;
1758 /* We may change the pad length before marshalling. */
1759 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1761 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1762 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1766 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1767 data_blob_free(&request);
1771 /* Wrap this in SPNEGO. */
1772 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1774 data_blob_free(&request);
1776 /* Auth len in the rpc header doesn't include auth_header. */
1777 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1778 data_blob_free(&spnego_msg);
1779 return NT_STATUS_NO_MEMORY;
1782 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1783 dump_data(5, spnego_msg.data, spnego_msg.length);
1785 data_blob_free(&spnego_msg);
1786 return NT_STATUS_OK;
1789 /*******************************************************************
1790 Creates NTLMSSP auth bind.
1791 ********************************************************************/
1793 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1794 enum dcerpc_AuthLevel auth_level,
1795 RPC_HDR_AUTH *pauth_out,
1796 prs_struct *auth_data)
1799 DATA_BLOB null_blob = data_blob_null;
1800 DATA_BLOB request = data_blob_null;
1802 /* We may change the pad length before marshalling. */
1803 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1805 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1806 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1810 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1811 data_blob_free(&request);
1815 /* Auth len in the rpc header doesn't include auth_header. */
1816 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1817 data_blob_free(&request);
1818 return NT_STATUS_NO_MEMORY;
1821 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1822 dump_data(5, request.data, request.length);
1824 data_blob_free(&request);
1825 return NT_STATUS_OK;
1828 /*******************************************************************
1829 Creates schannel auth bind.
1830 ********************************************************************/
1832 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1833 enum dcerpc_AuthLevel auth_level,
1834 RPC_HDR_AUTH *pauth_out,
1835 prs_struct *auth_data)
1837 struct NL_AUTH_MESSAGE r;
1838 enum ndr_err_code ndr_err;
1841 /* We may change the pad length before marshalling. */
1842 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1844 /* Use lp_workgroup() if domain not specified */
1846 if (!cli->auth->domain || !cli->auth->domain[0]) {
1847 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1848 if (cli->auth->domain == NULL) {
1849 return NT_STATUS_NO_MEMORY;
1854 * Now marshall the data into the auth parse_struct.
1857 r.MessageType = NL_NEGOTIATE_REQUEST;
1858 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1859 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1860 r.oem_netbios_domain.a = cli->auth->domain;
1861 r.oem_netbios_computer.a = global_myname();
1863 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &r,
1864 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1865 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1866 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1867 return ndr_map_error2ntstatus(ndr_err);
1870 if (DEBUGLEVEL >= 10) {
1871 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1874 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1876 return NT_STATUS_NO_MEMORY;
1879 return NT_STATUS_OK;
1882 /*******************************************************************
1883 ********************************************************************/
1885 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1886 const struct ndr_syntax_id *abstract_syntax,
1887 const struct ndr_syntax_id *transfer_syntax,
1888 struct dcerpc_ctx_list **ctx_list_p)
1890 struct dcerpc_ctx_list *ctx_list;
1892 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1893 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1895 ctx_list[0].context_id = 0;
1896 ctx_list[0].num_transfer_syntaxes = 1;
1897 ctx_list[0].abstract_syntax = *abstract_syntax;
1898 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
1899 struct ndr_syntax_id,
1900 ctx_list[0].num_transfer_syntaxes);
1901 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1902 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
1904 *ctx_list_p = ctx_list;
1906 return NT_STATUS_OK;
1909 /*******************************************************************
1910 Creates the internals of a DCE/RPC bind request or alter context PDU.
1911 ********************************************************************/
1913 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
1914 prs_struct *rpc_out,
1916 const struct ndr_syntax_id *abstract,
1917 const struct ndr_syntax_id *transfer,
1918 RPC_HDR_AUTH *phdr_auth,
1919 prs_struct *pauth_info)
1921 uint16 auth_len = prs_offset(pauth_info);
1922 uint8 ss_padding_len = 0;
1923 uint16 frag_len = 0;
1925 union dcerpc_payload u;
1927 struct dcerpc_ctx_list *ctx_list;
1929 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
1931 if (!NT_STATUS_IS_OK(status)) {
1935 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1936 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1937 u.bind.assoc_group_id = 0x0;
1938 u.bind.num_contexts = 1;
1939 u.bind.ctx_list = ctx_list;
1940 u.bind.auth_info = data_blob_null;
1942 /* Start building the frag length. */
1943 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
1945 /* Do we need to pad ? */
1947 uint16_t data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
1948 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1949 ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1950 phdr_auth->auth_pad_len = ss_padding_len;
1952 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1955 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
1957 DCERPC_PFC_FLAG_FIRST |
1958 DCERPC_PFC_FLAG_LAST,
1964 if (!NT_STATUS_IS_OK(status)) {
1965 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1969 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
1970 return NT_STATUS_NO_MEMORY;
1974 * Grow the outgoing buffer to store any auth info.
1978 if (ss_padding_len) {
1979 char pad[CLIENT_NDR_PADDING_SIZE];
1980 memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1981 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1982 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1983 return NT_STATUS_NO_MEMORY;
1987 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1988 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1989 return NT_STATUS_NO_MEMORY;
1993 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1994 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1995 return NT_STATUS_NO_MEMORY;
1999 return NT_STATUS_OK;
2002 /*******************************************************************
2003 Creates a DCE/RPC bind request.
2004 ********************************************************************/
2006 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
2007 prs_struct *rpc_out,
2009 const struct ndr_syntax_id *abstract,
2010 const struct ndr_syntax_id *transfer,
2011 enum pipe_auth_type auth_type,
2012 enum dcerpc_AuthLevel auth_level)
2014 RPC_HDR_AUTH hdr_auth;
2015 prs_struct auth_info;
2016 NTSTATUS ret = NT_STATUS_OK;
2018 ZERO_STRUCT(hdr_auth);
2019 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2020 return NT_STATUS_NO_MEMORY;
2022 switch (auth_type) {
2023 case PIPE_AUTH_TYPE_SCHANNEL:
2024 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2025 if (!NT_STATUS_IS_OK(ret)) {
2030 case PIPE_AUTH_TYPE_NTLMSSP:
2031 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2032 if (!NT_STATUS_IS_OK(ret)) {
2037 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2038 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2039 if (!NT_STATUS_IS_OK(ret)) {
2044 case PIPE_AUTH_TYPE_KRB5:
2045 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2046 if (!NT_STATUS_IS_OK(ret)) {
2051 case PIPE_AUTH_TYPE_NONE:
2055 /* "Can't" happen. */
2056 return NT_STATUS_INVALID_INFO_CLASS;
2059 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2070 /*******************************************************************
2071 Create and add the NTLMSSP sign/seal auth header and data.
2072 ********************************************************************/
2074 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2076 uint32 ss_padding_len,
2077 prs_struct *outgoing_pdu)
2079 RPC_HDR_AUTH auth_info;
2081 DATA_BLOB auth_blob = data_blob_null;
2082 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2085 if (!cli->auth->a_u.ntlmssp_state) {
2086 return NT_STATUS_INVALID_PARAMETER;
2089 frame = talloc_stackframe();
2091 /* Init and marshall the auth header. */
2092 init_rpc_hdr_auth(&auth_info,
2093 map_pipe_auth_type_to_rpc_auth_type(
2094 cli->auth->auth_type),
2095 cli->auth->auth_level,
2097 1 /* context id. */);
2099 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2100 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2102 return NT_STATUS_NO_MEMORY;
2105 switch (cli->auth->auth_level) {
2106 case DCERPC_AUTH_LEVEL_PRIVACY:
2107 /* Data portion is encrypted. */
2108 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2110 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2112 (unsigned char *)prs_data_p(outgoing_pdu),
2113 (size_t)prs_offset(outgoing_pdu),
2115 if (!NT_STATUS_IS_OK(status)) {
2121 case DCERPC_AUTH_LEVEL_INTEGRITY:
2122 /* Data is signed. */
2123 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2125 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2127 (unsigned char *)prs_data_p(outgoing_pdu),
2128 (size_t)prs_offset(outgoing_pdu),
2130 if (!NT_STATUS_IS_OK(status)) {
2138 smb_panic("bad auth level");
2140 return NT_STATUS_INVALID_PARAMETER;
2143 /* Finally marshall the blob. */
2145 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2146 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2147 (unsigned int)NTLMSSP_SIG_SIZE));
2149 return NT_STATUS_NO_MEMORY;
2153 return NT_STATUS_OK;
2156 /*******************************************************************
2157 Create and add the schannel sign/seal auth header and data.
2158 ********************************************************************/
2160 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2162 uint32 ss_padding_len,
2163 prs_struct *outgoing_pdu)
2165 RPC_HDR_AUTH auth_info;
2166 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2167 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2168 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2173 return NT_STATUS_INVALID_PARAMETER;
2176 /* Init and marshall the auth header. */
2177 init_rpc_hdr_auth(&auth_info,
2178 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2179 cli->auth->auth_level,
2181 1 /* context id. */);
2183 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2184 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2185 return NT_STATUS_NO_MEMORY;
2188 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2191 switch (cli->auth->auth_level) {
2192 case DCERPC_AUTH_LEVEL_PRIVACY:
2193 status = netsec_outgoing_packet(sas,
2200 case DCERPC_AUTH_LEVEL_INTEGRITY:
2201 status = netsec_outgoing_packet(sas,
2209 status = NT_STATUS_INTERNAL_ERROR;
2213 if (!NT_STATUS_IS_OK(status)) {
2214 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2215 nt_errstr(status)));
2219 if (DEBUGLEVEL >= 10) {
2220 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2223 /* Finally marshall the blob. */
2224 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2225 return NT_STATUS_NO_MEMORY;
2228 return NT_STATUS_OK;
2231 /*******************************************************************
2232 Calculate how much data we're going to send in this packet, also
2233 work out any sign/seal padding length.
2234 ********************************************************************/
2236 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2240 uint32 *p_ss_padding)
2242 uint32 data_space, data_len;
2245 if ((data_left > 0) && (sys_random() % 2)) {
2246 data_left = MAX(data_left/2, 1);
2250 switch (cli->auth->auth_level) {
2251 case DCERPC_AUTH_LEVEL_NONE:
2252 case DCERPC_AUTH_LEVEL_CONNECT:
2253 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2254 data_len = MIN(data_space, data_left);
2257 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2260 case DCERPC_AUTH_LEVEL_INTEGRITY:
2261 case DCERPC_AUTH_LEVEL_PRIVACY:
2262 /* Treat the same for all authenticated rpc requests. */
2263 switch(cli->auth->auth_type) {
2264 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2265 case PIPE_AUTH_TYPE_NTLMSSP:
2266 *p_auth_len = NTLMSSP_SIG_SIZE;
2268 case PIPE_AUTH_TYPE_SCHANNEL:
2269 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2272 smb_panic("bad auth type");
2276 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2277 RPC_HDR_AUTH_LEN - *p_auth_len;
2279 data_len = MIN(data_space, data_left);
2281 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2282 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2284 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2285 data_len + *p_ss_padding + /* data plus padding. */
2286 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2290 smb_panic("bad auth level");
2296 /*******************************************************************
2298 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2299 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2300 and deals with signing/sealing details.
2301 ********************************************************************/
2303 struct rpc_api_pipe_req_state {
2304 struct event_context *ev;
2305 struct rpc_pipe_client *cli;
2308 prs_struct *req_data;
2309 uint32_t req_data_sent;
2310 prs_struct outgoing_frag;
2311 prs_struct reply_pdu;
2314 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2315 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2316 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2317 bool *is_last_frag);
2319 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2320 struct event_context *ev,
2321 struct rpc_pipe_client *cli,
2323 prs_struct *req_data)
2325 struct tevent_req *req, *subreq;
2326 struct rpc_api_pipe_req_state *state;
2330 req = tevent_req_create(mem_ctx, &state,
2331 struct rpc_api_pipe_req_state);
2337 state->op_num = op_num;
2338 state->req_data = req_data;
2339 state->req_data_sent = 0;
2340 state->call_id = get_rpc_call_id();
2342 if (cli->max_xmit_frag
2343 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2344 /* Server is screwed up ! */
2345 status = NT_STATUS_INVALID_PARAMETER;
2349 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2351 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2356 status = prepare_next_frag(state, &is_last_frag);
2357 if (!NT_STATUS_IS_OK(status)) {
2362 subreq = rpc_api_pipe_send(state, ev, state->cli,
2363 &state->outgoing_frag,
2364 DCERPC_PKT_RESPONSE);
2365 if (subreq == NULL) {
2368 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2370 subreq = rpc_write_send(
2371 state, ev, cli->transport,
2372 (uint8_t *)prs_data_p(&state->outgoing_frag),
2373 prs_offset(&state->outgoing_frag));
2374 if (subreq == NULL) {
2377 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2383 tevent_req_nterror(req, status);
2384 return tevent_req_post(req, ev);
2390 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2394 RPC_HDR_REQ hdr_req;
2395 uint32_t data_sent_thistime;
2399 uint32_t ss_padding;
2401 char pad[8] = { 0, };
2404 data_left = prs_offset(state->req_data) - state->req_data_sent;
2406 data_sent_thistime = calculate_data_len_tosend(
2407 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2409 if (state->req_data_sent == 0) {
2410 flags = DCERPC_PFC_FLAG_FIRST;
2413 if (data_sent_thistime == data_left) {
2414 flags |= DCERPC_PFC_FLAG_LAST;
2417 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2418 return NT_STATUS_NO_MEMORY;
2421 /* Create and marshall the header and request header. */
2422 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2425 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2426 return NT_STATUS_NO_MEMORY;
2429 /* Create the rpc request RPC_HDR_REQ */
2430 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2433 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2434 &state->outgoing_frag, 0)) {
2435 return NT_STATUS_NO_MEMORY;
2438 /* Copy in the data, plus any ss padding. */
2439 if (!prs_append_some_prs_data(&state->outgoing_frag,
2440 state->req_data, state->req_data_sent,
2441 data_sent_thistime)) {
2442 return NT_STATUS_NO_MEMORY;
2445 /* Copy the sign/seal padding data. */
2446 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2447 return NT_STATUS_NO_MEMORY;
2450 /* Generate any auth sign/seal and add the auth footer. */
2451 switch (state->cli->auth->auth_type) {
2452 case PIPE_AUTH_TYPE_NONE:
2453 status = NT_STATUS_OK;
2455 case PIPE_AUTH_TYPE_NTLMSSP:
2456 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2457 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2458 &state->outgoing_frag);
2460 case PIPE_AUTH_TYPE_SCHANNEL:
2461 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2462 &state->outgoing_frag);
2465 status = NT_STATUS_INVALID_PARAMETER;
2469 state->req_data_sent += data_sent_thistime;
2470 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2475 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2477 struct tevent_req *req = tevent_req_callback_data(
2478 subreq, struct tevent_req);
2479 struct rpc_api_pipe_req_state *state = tevent_req_data(
2480 req, struct rpc_api_pipe_req_state);
2484 status = rpc_write_recv(subreq);
2485 TALLOC_FREE(subreq);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 tevent_req_nterror(req, status);
2491 status = prepare_next_frag(state, &is_last_frag);
2492 if (!NT_STATUS_IS_OK(status)) {
2493 tevent_req_nterror(req, status);
2498 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2499 &state->outgoing_frag,
2500 DCERPC_PKT_RESPONSE);
2501 if (tevent_req_nomem(subreq, req)) {
2504 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2506 subreq = rpc_write_send(
2508 state->cli->transport,
2509 (uint8_t *)prs_data_p(&state->outgoing_frag),
2510 prs_offset(&state->outgoing_frag));
2511 if (tevent_req_nomem(subreq, req)) {
2514 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2519 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2521 struct tevent_req *req = tevent_req_callback_data(
2522 subreq, struct tevent_req);
2523 struct rpc_api_pipe_req_state *state = tevent_req_data(
2524 req, struct rpc_api_pipe_req_state);
2527 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2528 TALLOC_FREE(subreq);
2529 if (!NT_STATUS_IS_OK(status)) {
2530 tevent_req_nterror(req, status);
2533 tevent_req_done(req);
2536 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2537 prs_struct *reply_pdu)
2539 struct rpc_api_pipe_req_state *state = tevent_req_data(
2540 req, struct rpc_api_pipe_req_state);
2543 if (tevent_req_is_nterror(req, &status)) {
2545 * We always have to initialize to reply pdu, even if there is
2546 * none. The rpccli_* caller routines expect this.
2548 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2552 *reply_pdu = state->reply_pdu;
2553 reply_pdu->mem_ctx = mem_ctx;
2556 * Prevent state->req_pdu from being freed
2557 * when state is freed.
2559 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2560 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2562 return NT_STATUS_OK;
2566 /****************************************************************************
2567 Set the handle state.
2568 ****************************************************************************/
2570 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2571 const char *pipe_name, uint16 device_state)
2573 bool state_set = False;
2575 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2576 char *rparam = NULL;
2578 uint32 rparam_len, rdata_len;
2580 if (pipe_name == NULL)
2583 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2584 cli->fnum, pipe_name, device_state));
2586 /* create parameters: device state */
2587 SSVAL(param, 0, device_state);
2589 /* create setup parameters. */
2591 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2593 /* send the data on \PIPE\ */
2594 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2595 setup, 2, 0, /* setup, length, max */
2596 param, 2, 0, /* param, length, max */
2597 NULL, 0, 1024, /* data, length, max */
2598 &rparam, &rparam_len, /* return param, length */
2599 &rdata, &rdata_len)) /* return data, length */
2601 DEBUG(5, ("Set Handle state: return OK\n"));
2612 /****************************************************************************
2613 Check the rpc bind acknowledge response.
2614 ****************************************************************************/
2616 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2617 const struct ndr_syntax_id *transfer)
2619 if ( hdr_ba->addr.len == 0) {
2620 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2623 /* check the transfer syntax */
2624 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2625 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2626 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2630 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2631 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2632 hdr_ba->res.num_results, hdr_ba->res.reason));
2635 DEBUG(5,("check_bind_response: accepted!\n"));
2639 /*******************************************************************
2640 Creates a DCE/RPC bind authentication response.
2641 This is the packet that is sent back to the server once we
2642 have received a BIND-ACK, to finish the third leg of
2643 the authentication handshake.
2644 ********************************************************************/
2646 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2648 enum pipe_auth_type auth_type,
2649 enum dcerpc_AuthLevel auth_level,
2650 DATA_BLOB *pauth_blob,
2651 prs_struct *rpc_out)
2654 RPC_HDR_AUTH hdr_auth;
2657 /* Create the request RPC_HDR */
2658 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2659 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2660 pauth_blob->length );
2663 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2664 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2665 return NT_STATUS_NO_MEMORY;
2669 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2670 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2673 /* 4 bytes padding. */
2674 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2675 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2676 return NT_STATUS_NO_MEMORY;
2679 /* Create the request RPC_HDR_AUTHA */
2680 init_rpc_hdr_auth(&hdr_auth,
2681 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2684 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2685 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2686 return NT_STATUS_NO_MEMORY;
2690 * Append the auth data to the outgoing buffer.
2693 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2694 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2695 return NT_STATUS_NO_MEMORY;
2698 return NT_STATUS_OK;
2701 /*******************************************************************
2702 Creates a DCE/RPC bind alter context authentication request which
2703 may contain a spnego auth blobl
2704 ********************************************************************/
2706 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2707 const struct ndr_syntax_id *abstract,
2708 const struct ndr_syntax_id *transfer,
2709 enum dcerpc_AuthLevel auth_level,
2710 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2711 prs_struct *rpc_out)
2713 RPC_HDR_AUTH hdr_auth;
2714 prs_struct auth_info;
2715 NTSTATUS ret = NT_STATUS_OK;
2717 ZERO_STRUCT(hdr_auth);
2718 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2719 return NT_STATUS_NO_MEMORY;
2721 /* We may change the pad length before marshalling. */
2722 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2724 if (pauth_blob->length) {
2725 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2726 return NT_STATUS_NO_MEMORY;
2730 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2740 /****************************************************************************
2742 ****************************************************************************/
2744 struct rpc_pipe_bind_state {
2745 struct event_context *ev;
2746 struct rpc_pipe_client *cli;
2748 uint32_t rpc_call_id;
2751 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2752 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2753 struct rpc_pipe_bind_state *state,
2754 struct rpc_hdr_info *phdr,
2755 prs_struct *reply_pdu);
2756 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2757 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2758 struct rpc_pipe_bind_state *state,
2759 struct rpc_hdr_info *phdr,
2760 prs_struct *reply_pdu);
2761 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2763 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2764 struct event_context *ev,
2765 struct rpc_pipe_client *cli,
2766 struct cli_pipe_auth_data *auth)
2768 struct tevent_req *req, *subreq;
2769 struct rpc_pipe_bind_state *state;
2772 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2777 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2778 rpccli_pipe_txt(talloc_tos(), cli),
2779 (unsigned int)auth->auth_type,
2780 (unsigned int)auth->auth_level ));
2784 state->rpc_call_id = get_rpc_call_id();
2786 prs_init_empty(&state->rpc_out, state, MARSHALL);
2788 cli->auth = talloc_move(cli, &auth);
2790 /* Marshall the outgoing data. */
2791 status = create_rpc_bind_req(cli, &state->rpc_out,
2793 &cli->abstract_syntax,
2794 &cli->transfer_syntax,
2795 cli->auth->auth_type,
2796 cli->auth->auth_level);
2798 if (!NT_STATUS_IS_OK(status)) {
2802 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2803 DCERPC_PKT_BIND_ACK);
2804 if (subreq == NULL) {
2807 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2811 tevent_req_nterror(req, status);
2812 return tevent_req_post(req, ev);
2818 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2820 struct tevent_req *req = tevent_req_callback_data(
2821 subreq, struct tevent_req);
2822 struct rpc_pipe_bind_state *state = tevent_req_data(
2823 req, struct rpc_pipe_bind_state);
2824 prs_struct reply_pdu;
2825 struct rpc_hdr_info hdr;
2826 struct rpc_hdr_ba_info hdr_ba;
2829 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2830 TALLOC_FREE(subreq);
2831 if (!NT_STATUS_IS_OK(status)) {
2832 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2833 rpccli_pipe_txt(talloc_tos(), state->cli),
2834 nt_errstr(status)));
2835 tevent_req_nterror(req, status);
2839 /* Unmarshall the RPC header */
2840 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2841 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2842 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2846 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2847 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2849 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2853 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2854 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2855 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2859 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2860 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2863 * For authenticated binds we may need to do 3 or 4 leg binds.
2866 switch(state->cli->auth->auth_type) {
2868 case PIPE_AUTH_TYPE_NONE:
2869 case PIPE_AUTH_TYPE_SCHANNEL:
2870 /* Bind complete. */
2871 tevent_req_done(req);
2874 case PIPE_AUTH_TYPE_NTLMSSP:
2875 /* Need to send AUTH3 packet - no reply. */
2876 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2878 if (!NT_STATUS_IS_OK(status)) {
2879 tevent_req_nterror(req, status);
2883 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2884 /* Need to send alter context request and reply. */
2885 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2887 if (!NT_STATUS_IS_OK(status)) {
2888 tevent_req_nterror(req, status);
2892 case PIPE_AUTH_TYPE_KRB5:
2896 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2897 (unsigned int)state->cli->auth->auth_type));
2898 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2902 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2903 struct rpc_pipe_bind_state *state,
2904 struct rpc_hdr_info *phdr,
2905 prs_struct *reply_pdu)
2907 DATA_BLOB server_response = data_blob_null;
2908 DATA_BLOB client_reply = data_blob_null;
2909 struct rpc_hdr_auth_info hdr_auth;
2910 struct tevent_req *subreq;
2913 if ((phdr->auth_len == 0)
2914 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2915 return NT_STATUS_INVALID_PARAMETER;
2918 if (!prs_set_offset(
2920 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2921 return NT_STATUS_INVALID_PARAMETER;
2924 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2925 return NT_STATUS_INVALID_PARAMETER;
2928 /* TODO - check auth_type/auth_level match. */
2930 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2931 prs_copy_data_out((char *)server_response.data, reply_pdu,
2934 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2935 server_response, &client_reply);
2937 if (!NT_STATUS_IS_OK(status)) {
2938 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2939 "blob failed: %s.\n", nt_errstr(status)));
2943 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2945 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2946 state->cli->auth->auth_type,
2947 state->cli->auth->auth_level,
2948 &client_reply, &state->rpc_out);
2949 data_blob_free(&client_reply);
2951 if (!NT_STATUS_IS_OK(status)) {
2955 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2956 (uint8_t *)prs_data_p(&state->rpc_out),
2957 prs_offset(&state->rpc_out));
2958 if (subreq == NULL) {
2959 return NT_STATUS_NO_MEMORY;
2961 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2962 return NT_STATUS_OK;
2965 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2967 struct tevent_req *req = tevent_req_callback_data(
2968 subreq, struct tevent_req);
2971 status = rpc_write_recv(subreq);
2972 TALLOC_FREE(subreq);
2973 if (!NT_STATUS_IS_OK(status)) {
2974 tevent_req_nterror(req, status);
2977 tevent_req_done(req);
2980 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2981 struct rpc_pipe_bind_state *state,
2982 struct rpc_hdr_info *phdr,
2983 prs_struct *reply_pdu)
2985 DATA_BLOB server_spnego_response = data_blob_null;
2986 DATA_BLOB server_ntlm_response = data_blob_null;
2987 DATA_BLOB client_reply = data_blob_null;
2988 DATA_BLOB tmp_blob = data_blob_null;
2989 RPC_HDR_AUTH hdr_auth;
2990 struct tevent_req *subreq;
2993 if ((phdr->auth_len == 0)
2994 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2995 return NT_STATUS_INVALID_PARAMETER;
2998 /* Process the returned NTLMSSP blob first. */
2999 if (!prs_set_offset(
3001 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
3002 return NT_STATUS_INVALID_PARAMETER;
3005 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
3006 return NT_STATUS_INVALID_PARAMETER;
3009 server_spnego_response = data_blob(NULL, phdr->auth_len);
3010 prs_copy_data_out((char *)server_spnego_response.data,
3011 reply_pdu, phdr->auth_len);
3014 * The server might give us back two challenges - tmp_blob is for the
3017 if (!spnego_parse_challenge(server_spnego_response,
3018 &server_ntlm_response, &tmp_blob)) {
3019 data_blob_free(&server_spnego_response);
3020 data_blob_free(&server_ntlm_response);
3021 data_blob_free(&tmp_blob);
3022 return NT_STATUS_INVALID_PARAMETER;
3025 /* We're finished with the server spnego response and the tmp_blob. */
3026 data_blob_free(&server_spnego_response);
3027 data_blob_free(&tmp_blob);
3029 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
3030 server_ntlm_response, &client_reply);
3032 /* Finished with the server_ntlm response */
3033 data_blob_free(&server_ntlm_response);
3035 if (!NT_STATUS_IS_OK(status)) {
3036 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3037 "using server blob failed.\n"));
3038 data_blob_free(&client_reply);
3042 /* SPNEGO wrap the client reply. */
3043 tmp_blob = spnego_gen_auth(client_reply);
3044 data_blob_free(&client_reply);
3045 client_reply = tmp_blob;
3046 tmp_blob = data_blob_null;
3048 /* Now prepare the alter context pdu. */
3049 prs_init_empty(&state->rpc_out, state, MARSHALL);
3051 status = create_rpc_alter_context(state->rpc_call_id,
3052 &state->cli->abstract_syntax,
3053 &state->cli->transfer_syntax,
3054 state->cli->auth->auth_level,
3057 data_blob_free(&client_reply);
3059 if (!NT_STATUS_IS_OK(status)) {
3063 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3064 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3065 if (subreq == NULL) {
3066 return NT_STATUS_NO_MEMORY;
3068 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3069 return NT_STATUS_OK;
3072 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3074 struct tevent_req *req = tevent_req_callback_data(
3075 subreq, struct tevent_req);
3076 struct rpc_pipe_bind_state *state = tevent_req_data(
3077 req, struct rpc_pipe_bind_state);
3078 DATA_BLOB server_spnego_response = data_blob_null;
3079 DATA_BLOB tmp_blob = data_blob_null;
3080 prs_struct reply_pdu;
3081 struct rpc_hdr_info hdr;
3082 struct rpc_hdr_auth_info hdr_auth;
3085 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3086 TALLOC_FREE(subreq);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 tevent_req_nterror(req, status);
3092 /* Get the auth blob from the reply. */
3093 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3094 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3095 "unmarshall RPC_HDR.\n"));
3096 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3100 if (!prs_set_offset(
3102 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3103 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3107 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3108 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3112 server_spnego_response = data_blob(NULL, hdr.auth_len);
3113 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3116 /* Check we got a valid auth response. */
3117 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3118 OID_NTLMSSP, &tmp_blob)) {
3119 data_blob_free(&server_spnego_response);
3120 data_blob_free(&tmp_blob);
3121 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3125 data_blob_free(&server_spnego_response);
3126 data_blob_free(&tmp_blob);
3128 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3129 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3130 tevent_req_done(req);
3133 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3135 return tevent_req_simple_recv_ntstatus(req);
3138 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3139 struct cli_pipe_auth_data *auth)
3141 TALLOC_CTX *frame = talloc_stackframe();
3142 struct event_context *ev;
3143 struct tevent_req *req;
3144 NTSTATUS status = NT_STATUS_OK;
3146 ev = event_context_init(frame);
3148 status = NT_STATUS_NO_MEMORY;
3152 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3154 status = NT_STATUS_NO_MEMORY;
3158 if (!tevent_req_poll(req, ev)) {
3159 status = map_nt_error_from_unix(errno);
3163 status = rpc_pipe_bind_recv(req);
3169 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3171 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3172 unsigned int timeout)
3176 if (rpc_cli->transport == NULL) {
3177 return RPCCLI_DEFAULT_TIMEOUT;
3180 if (rpc_cli->transport->set_timeout == NULL) {
3181 return RPCCLI_DEFAULT_TIMEOUT;
3184 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3186 return RPCCLI_DEFAULT_TIMEOUT;
3192 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3194 if (rpc_cli == NULL) {
3198 if (rpc_cli->transport == NULL) {
3202 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3205 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3207 struct cli_state *cli;
3209 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3210 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3211 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3215 cli = rpc_pipe_np_smb_conn(rpc_cli);
3219 E_md4hash(cli->password ? cli->password : "", nt_hash);
3223 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3224 struct cli_pipe_auth_data **presult)
3226 struct cli_pipe_auth_data *result;
3228 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3229 if (result == NULL) {
3230 return NT_STATUS_NO_MEMORY;
3233 result->auth_type = PIPE_AUTH_TYPE_NONE;
3234 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3236 result->user_name = talloc_strdup(result, "");
3237 result->domain = talloc_strdup(result, "");
3238 if ((result->user_name == NULL) || (result->domain == NULL)) {
3239 TALLOC_FREE(result);
3240 return NT_STATUS_NO_MEMORY;
3244 return NT_STATUS_OK;
3247 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3249 ntlmssp_end(&auth->a_u.ntlmssp_state);
3253 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3254 enum pipe_auth_type auth_type,
3255 enum dcerpc_AuthLevel auth_level,
3257 const char *username,
3258 const char *password,
3259 struct cli_pipe_auth_data **presult)
3261 struct cli_pipe_auth_data *result;
3264 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3265 if (result == NULL) {
3266 return NT_STATUS_NO_MEMORY;
3269 result->auth_type = auth_type;
3270 result->auth_level = auth_level;
3272 result->user_name = talloc_strdup(result, username);
3273 result->domain = talloc_strdup(result, domain);
3274 if ((result->user_name == NULL) || (result->domain == NULL)) {
3275 status = NT_STATUS_NO_MEMORY;
3279 status = ntlmssp_client_start(NULL,
3282 lp_client_ntlmv2_auth(),
3283 &result->a_u.ntlmssp_state);
3284 if (!NT_STATUS_IS_OK(status)) {
3288 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3290 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3291 if (!NT_STATUS_IS_OK(status)) {
3295 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3296 if (!NT_STATUS_IS_OK(status)) {
3300 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3301 if (!NT_STATUS_IS_OK(status)) {
3306 * Turn off sign+seal to allow selected auth level to turn it back on.
3308 result->a_u.ntlmssp_state->neg_flags &=
3309 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3311 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3312 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3313 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3314 result->a_u.ntlmssp_state->neg_flags
3315 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3319 return NT_STATUS_OK;
3322 TALLOC_FREE(result);
3326 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3327 enum dcerpc_AuthLevel auth_level,
3328 struct netlogon_creds_CredentialState *creds,
3329 struct cli_pipe_auth_data **presult)
3331 struct cli_pipe_auth_data *result;
3333 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3334 if (result == NULL) {
3335 return NT_STATUS_NO_MEMORY;
3338 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3339 result->auth_level = auth_level;
3341 result->user_name = talloc_strdup(result, "");
3342 result->domain = talloc_strdup(result, domain);
3343 if ((result->user_name == NULL) || (result->domain == NULL)) {
3347 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3348 if (result->a_u.schannel_auth == NULL) {
3352 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3353 result->a_u.schannel_auth->seq_num = 0;
3354 result->a_u.schannel_auth->initiator = true;
3355 result->a_u.schannel_auth->creds = creds;
3358 return NT_STATUS_OK;
3361 TALLOC_FREE(result);
3362 return NT_STATUS_NO_MEMORY;
3366 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3368 data_blob_free(&auth->session_key);
3373 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3374 enum dcerpc_AuthLevel auth_level,
3375 const char *service_princ,
3376 const char *username,
3377 const char *password,
3378 struct cli_pipe_auth_data **presult)
3381 struct cli_pipe_auth_data *result;
3383 if ((username != NULL) && (password != NULL)) {
3384 int ret = kerberos_kinit_password(username, password, 0, NULL);
3386 return NT_STATUS_ACCESS_DENIED;
3390 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3391 if (result == NULL) {
3392 return NT_STATUS_NO_MEMORY;
3395 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3396 result->auth_level = auth_level;
3399 * Username / domain need fixing!
3401 result->user_name = talloc_strdup(result, "");
3402 result->domain = talloc_strdup(result, "");
3403 if ((result->user_name == NULL) || (result->domain == NULL)) {
3407 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3408 result, struct kerberos_auth_struct);
3409 if (result->a_u.kerberos_auth == NULL) {
3412 talloc_set_destructor(result->a_u.kerberos_auth,
3413 cli_auth_kerberos_data_destructor);
3415 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3416 result, service_princ);
3417 if (result->a_u.kerberos_auth->service_principal == NULL) {
3422 return NT_STATUS_OK;
3425 TALLOC_FREE(result);
3426 return NT_STATUS_NO_MEMORY;
3428 return NT_STATUS_NOT_SUPPORTED;
3433 * Create an rpc pipe client struct, connecting to a tcp port.
3435 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3437 const struct ndr_syntax_id *abstract_syntax,
3438 struct rpc_pipe_client **presult)
3440 struct rpc_pipe_client *result;
3441 struct sockaddr_storage addr;
3445 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3446 if (result == NULL) {
3447 return NT_STATUS_NO_MEMORY;
3450 result->abstract_syntax = *abstract_syntax;
3451 result->transfer_syntax = ndr_transfer_syntax;
3452 result->dispatch = cli_do_rpc_ndr;
3453 result->dispatch_send = cli_do_rpc_ndr_send;
3454 result->dispatch_recv = cli_do_rpc_ndr_recv;
3456 result->desthost = talloc_strdup(result, host);
3457 result->srv_name_slash = talloc_asprintf_strupper_m(
3458 result, "\\\\%s", result->desthost);
3459 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3460 status = NT_STATUS_NO_MEMORY;
3464 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3465 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3467 if (!resolve_name(host, &addr, 0, false)) {
3468 status = NT_STATUS_NOT_FOUND;
3472 status = open_socket_out(&addr, port, 60, &fd);
3473 if (!NT_STATUS_IS_OK(status)) {
3476 set_socket_options(fd, lp_socket_options());
3478 status = rpc_transport_sock_init(result, fd, &result->transport);
3479 if (!NT_STATUS_IS_OK(status)) {
3484 result->transport->transport = NCACN_IP_TCP;
3487 return NT_STATUS_OK;
3490 TALLOC_FREE(result);
3495 * Determine the tcp port on which a dcerpc interface is listening
3496 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3499 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3500 const struct ndr_syntax_id *abstract_syntax,
3504 struct rpc_pipe_client *epm_pipe = NULL;
3505 struct cli_pipe_auth_data *auth = NULL;
3506 struct dcerpc_binding *map_binding = NULL;
3507 struct dcerpc_binding *res_binding = NULL;
3508 struct epm_twr_t *map_tower = NULL;
3509 struct epm_twr_t *res_towers = NULL;
3510 struct policy_handle *entry_handle = NULL;
3511 uint32_t num_towers = 0;
3512 uint32_t max_towers = 1;
3513 struct epm_twr_p_t towers;
3514 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3516 if (pport == NULL) {
3517 status = NT_STATUS_INVALID_PARAMETER;
3521 /* open the connection to the endpoint mapper */
3522 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3523 &ndr_table_epmapper.syntax_id,
3526 if (!NT_STATUS_IS_OK(status)) {
3530 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3531 if (!NT_STATUS_IS_OK(status)) {
3535 status = rpc_pipe_bind(epm_pipe, auth);
3536 if (!NT_STATUS_IS_OK(status)) {
3540 /* create tower for asking the epmapper */
3542 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3543 if (map_binding == NULL) {
3544 status = NT_STATUS_NO_MEMORY;
3548 map_binding->transport = NCACN_IP_TCP;
3549 map_binding->object = *abstract_syntax;
3550 map_binding->host = host; /* needed? */
3551 map_binding->endpoint = "0"; /* correct? needed? */
3553 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3554 if (map_tower == NULL) {
3555 status = NT_STATUS_NO_MEMORY;
3559 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3560 &(map_tower->tower));
3561 if (!NT_STATUS_IS_OK(status)) {
3565 /* allocate further parameters for the epm_Map call */
3567 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3568 if (res_towers == NULL) {
3569 status = NT_STATUS_NO_MEMORY;
3572 towers.twr = res_towers;
3574 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3575 if (entry_handle == NULL) {
3576 status = NT_STATUS_NO_MEMORY;
3580 /* ask the endpoint mapper for the port */
3582 status = rpccli_epm_Map(epm_pipe,
3584 CONST_DISCARD(struct GUID *,
3585 &(abstract_syntax->uuid)),
3592 if (!NT_STATUS_IS_OK(status)) {
3596 if (num_towers != 1) {
3597 status = NT_STATUS_UNSUCCESSFUL;
3601 /* extract the port from the answer */
3603 status = dcerpc_binding_from_tower(tmp_ctx,
3604 &(towers.twr->tower),
3606 if (!NT_STATUS_IS_OK(status)) {
3610 /* are further checks here necessary? */
3611 if (res_binding->transport != NCACN_IP_TCP) {
3612 status = NT_STATUS_UNSUCCESSFUL;
3616 *pport = (uint16_t)atoi(res_binding->endpoint);
3619 TALLOC_FREE(tmp_ctx);
3624 * Create a rpc pipe client struct, connecting to a host via tcp.
3625 * The port is determined by asking the endpoint mapper on the given
3628 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3629 const struct ndr_syntax_id *abstract_syntax,
3630 struct rpc_pipe_client **presult)
3635 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3636 if (!NT_STATUS_IS_OK(status)) {
3640 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3641 abstract_syntax, presult);
3644 /********************************************************************
3645 Create a rpc pipe client struct, connecting to a unix domain socket
3646 ********************************************************************/
3647 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3648 const struct ndr_syntax_id *abstract_syntax,
3649 struct rpc_pipe_client **presult)
3651 struct rpc_pipe_client *result;
3652 struct sockaddr_un addr;
3656 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3657 if (result == NULL) {
3658 return NT_STATUS_NO_MEMORY;
3661 result->abstract_syntax = *abstract_syntax;
3662 result->transfer_syntax = ndr_transfer_syntax;
3663 result->dispatch = cli_do_rpc_ndr;
3664 result->dispatch_send = cli_do_rpc_ndr_send;
3665 result->dispatch_recv = cli_do_rpc_ndr_recv;
3667 result->desthost = get_myname(result);
3668 result->srv_name_slash = talloc_asprintf_strupper_m(
3669 result, "\\\\%s", result->desthost);
3670 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3671 status = NT_STATUS_NO_MEMORY;
3675 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3676 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3678 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3680 status = map_nt_error_from_unix(errno);
3685 addr.sun_family = AF_UNIX;
3686 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3688 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3689 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3692 return map_nt_error_from_unix(errno);
3695 status = rpc_transport_sock_init(result, fd, &result->transport);
3696 if (!NT_STATUS_IS_OK(status)) {
3701 result->transport->transport = NCALRPC;
3704 return NT_STATUS_OK;
3707 TALLOC_FREE(result);
3711 struct rpc_pipe_client_np_ref {
3712 struct cli_state *cli;
3713 struct rpc_pipe_client *pipe;
3716 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3718 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3722 /****************************************************************************
3723 Open a named pipe over SMB to a remote server.
3725 * CAVEAT CALLER OF THIS FUNCTION:
3726 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3727 * so be sure that this function is called AFTER any structure (vs pointer)
3728 * assignment of the cli. In particular, libsmbclient does structure
3729 * assignments of cli, which invalidates the data in the returned
3730 * rpc_pipe_client if this function is called before the structure assignment
3733 ****************************************************************************/
3735 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3736 const struct ndr_syntax_id *abstract_syntax,
3737 struct rpc_pipe_client **presult)
3739 struct rpc_pipe_client *result;
3741 struct rpc_pipe_client_np_ref *np_ref;
3743 /* sanity check to protect against crashes */
3746 return NT_STATUS_INVALID_HANDLE;
3749 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3750 if (result == NULL) {
3751 return NT_STATUS_NO_MEMORY;
3754 result->abstract_syntax = *abstract_syntax;
3755 result->transfer_syntax = ndr_transfer_syntax;
3756 result->dispatch = cli_do_rpc_ndr;
3757 result->dispatch_send = cli_do_rpc_ndr_send;
3758 result->dispatch_recv = cli_do_rpc_ndr_recv;
3759 result->desthost = talloc_strdup(result, cli->desthost);
3760 result->srv_name_slash = talloc_asprintf_strupper_m(
3761 result, "\\\\%s", result->desthost);
3763 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3764 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3766 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3767 TALLOC_FREE(result);
3768 return NT_STATUS_NO_MEMORY;
3771 status = rpc_transport_np_init(result, cli, abstract_syntax,
3772 &result->transport);
3773 if (!NT_STATUS_IS_OK(status)) {
3774 TALLOC_FREE(result);
3778 result->transport->transport = NCACN_NP;
3780 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3781 if (np_ref == NULL) {
3782 TALLOC_FREE(result);
3783 return NT_STATUS_NO_MEMORY;
3786 np_ref->pipe = result;
3788 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3789 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3792 return NT_STATUS_OK;
3795 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3796 struct rpc_cli_smbd_conn *conn,
3797 const struct ndr_syntax_id *syntax,
3798 struct rpc_pipe_client **presult)
3800 struct rpc_pipe_client *result;
3801 struct cli_pipe_auth_data *auth;
3804 result = talloc(mem_ctx, struct rpc_pipe_client);
3805 if (result == NULL) {
3806 return NT_STATUS_NO_MEMORY;
3808 result->abstract_syntax = *syntax;
3809 result->transfer_syntax = ndr_transfer_syntax;
3810 result->dispatch = cli_do_rpc_ndr;
3811 result->dispatch_send = cli_do_rpc_ndr_send;
3812 result->dispatch_recv = cli_do_rpc_ndr_recv;
3813 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3814 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3816 result->desthost = talloc_strdup(result, global_myname());
3817 result->srv_name_slash = talloc_asprintf_strupper_m(
3818 result, "\\\\%s", global_myname());
3819 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3820 TALLOC_FREE(result);
3821 return NT_STATUS_NO_MEMORY;
3824 status = rpc_transport_smbd_init(result, conn, syntax,
3825 &result->transport);
3826 if (!NT_STATUS_IS_OK(status)) {
3827 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3828 nt_errstr(status)));
3829 TALLOC_FREE(result);
3833 status = rpccli_anon_bind_data(result, &auth);
3834 if (!NT_STATUS_IS_OK(status)) {
3835 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3836 nt_errstr(status)));
3837 TALLOC_FREE(result);
3841 status = rpc_pipe_bind(result, auth);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3844 TALLOC_FREE(result);
3848 result->transport->transport = NCACN_INTERNAL;
3851 return NT_STATUS_OK;
3854 /****************************************************************************
3855 Open a pipe to a remote server.
3856 ****************************************************************************/
3858 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3859 enum dcerpc_transport_t transport,
3860 const struct ndr_syntax_id *interface,
3861 struct rpc_pipe_client **presult)
3863 switch (transport) {
3865 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3868 return rpc_pipe_open_np(cli, interface, presult);
3870 return NT_STATUS_NOT_IMPLEMENTED;
3874 /****************************************************************************
3875 Open a named pipe to an SMB server and bind anonymously.
3876 ****************************************************************************/
3878 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3879 enum dcerpc_transport_t transport,
3880 const struct ndr_syntax_id *interface,
3881 struct rpc_pipe_client **presult)
3883 struct rpc_pipe_client *result;
3884 struct cli_pipe_auth_data *auth;
3887 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3888 if (!NT_STATUS_IS_OK(status)) {
3892 status = rpccli_anon_bind_data(result, &auth);
3893 if (!NT_STATUS_IS_OK(status)) {
3894 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3895 nt_errstr(status)));
3896 TALLOC_FREE(result);
3901 * This is a bit of an abstraction violation due to the fact that an
3902 * anonymous bind on an authenticated SMB inherits the user/domain
3903 * from the enclosing SMB creds
3906 TALLOC_FREE(auth->user_name);
3907 TALLOC_FREE(auth->domain);
3909 auth->user_name = talloc_strdup(auth, cli->user_name);
3910 auth->domain = talloc_strdup(auth, cli->domain);
3911 auth->user_session_key = data_blob_talloc(auth,
3912 cli->user_session_key.data,
3913 cli->user_session_key.length);
3915 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3916 TALLOC_FREE(result);
3917 return NT_STATUS_NO_MEMORY;
3920 status = rpc_pipe_bind(result, auth);
3921 if (!NT_STATUS_IS_OK(status)) {
3923 if (ndr_syntax_id_equal(interface,
3924 &ndr_table_dssetup.syntax_id)) {
3925 /* non AD domains just don't have this pipe, avoid
3926 * level 0 statement in that case - gd */
3929 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3930 "%s failed with error %s\n",
3931 get_pipe_name_from_syntax(talloc_tos(), interface),
3932 nt_errstr(status) ));
3933 TALLOC_FREE(result);
3937 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3938 "%s and bound anonymously.\n",
3939 get_pipe_name_from_syntax(talloc_tos(), interface),
3943 return NT_STATUS_OK;
3946 /****************************************************************************
3947 ****************************************************************************/
3949 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3950 const struct ndr_syntax_id *interface,
3951 struct rpc_pipe_client **presult)
3953 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3954 interface, presult);
3957 /****************************************************************************
3958 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3959 ****************************************************************************/
3961 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3962 const struct ndr_syntax_id *interface,
3963 enum dcerpc_transport_t transport,
3964 enum pipe_auth_type auth_type,
3965 enum dcerpc_AuthLevel auth_level,
3967 const char *username,
3968 const char *password,
3969 struct rpc_pipe_client **presult)
3971 struct rpc_pipe_client *result;
3972 struct cli_pipe_auth_data *auth;
3975 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3976 if (!NT_STATUS_IS_OK(status)) {
3980 status = rpccli_ntlmssp_bind_data(
3981 result, auth_type, auth_level, domain, username,
3983 if (!NT_STATUS_IS_OK(status)) {
3984 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3985 nt_errstr(status)));
3989 status = rpc_pipe_bind(result, auth);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3992 nt_errstr(status) ));
3996 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3997 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3998 get_pipe_name_from_syntax(talloc_tos(), interface),
3999 cli->desthost, domain, username ));
4002 return NT_STATUS_OK;
4006 TALLOC_FREE(result);
4010 /****************************************************************************
4012 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
4013 ****************************************************************************/
4015 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
4016 const struct ndr_syntax_id *interface,
4017 enum dcerpc_transport_t transport,
4018 enum dcerpc_AuthLevel auth_level,
4020 const char *username,
4021 const char *password,
4022 struct rpc_pipe_client **presult)
4024 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4027 PIPE_AUTH_TYPE_NTLMSSP,
4035 /****************************************************************************
4037 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4038 ****************************************************************************/
4040 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4041 const struct ndr_syntax_id *interface,
4042 enum dcerpc_transport_t transport,
4043 enum dcerpc_AuthLevel auth_level,
4045 const char *username,
4046 const char *password,
4047 struct rpc_pipe_client **presult)
4049 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4052 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4060 /****************************************************************************
4061 Get a the schannel session key out of an already opened netlogon pipe.
4062 ****************************************************************************/
4063 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4064 struct cli_state *cli,
4068 enum netr_SchannelType sec_chan_type = 0;
4069 unsigned char machine_pwd[16];
4070 const char *machine_account;
4073 /* Get the machine account credentials from secrets.tdb. */
4074 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4077 DEBUG(0, ("get_schannel_session_key: could not fetch "
4078 "trust account password for domain '%s'\n",
4080 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4083 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4084 cli->desthost, /* server name */
4085 domain, /* domain */
4086 global_myname(), /* client name */
4087 machine_account, /* machine account name */
4092 if (!NT_STATUS_IS_OK(status)) {
4093 DEBUG(3, ("get_schannel_session_key_common: "
4094 "rpccli_netlogon_setup_creds failed with result %s "
4095 "to server %s, domain %s, machine account %s.\n",
4096 nt_errstr(status), cli->desthost, domain,
4101 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4102 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4104 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4107 return NT_STATUS_OK;;
4110 /****************************************************************************
4111 Open a netlogon pipe and get the schannel session key.
4112 Now exposed to external callers.
4113 ****************************************************************************/
4116 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4119 struct rpc_pipe_client **presult)
4121 struct rpc_pipe_client *netlogon_pipe = NULL;
4124 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4126 if (!NT_STATUS_IS_OK(status)) {
4130 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4132 if (!NT_STATUS_IS_OK(status)) {
4133 TALLOC_FREE(netlogon_pipe);
4137 *presult = netlogon_pipe;
4138 return NT_STATUS_OK;
4141 /****************************************************************************
4143 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4144 using session_key. sign and seal.
4146 The *pdc will be stolen onto this new pipe
4147 ****************************************************************************/
4149 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4150 const struct ndr_syntax_id *interface,
4151 enum dcerpc_transport_t transport,
4152 enum dcerpc_AuthLevel auth_level,
4154 struct netlogon_creds_CredentialState **pdc,
4155 struct rpc_pipe_client **presult)
4157 struct rpc_pipe_client *result;
4158 struct cli_pipe_auth_data *auth;
4161 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4162 if (!NT_STATUS_IS_OK(status)) {
4166 status = rpccli_schannel_bind_data(result, domain, auth_level,
4168 if (!NT_STATUS_IS_OK(status)) {
4169 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4170 nt_errstr(status)));
4171 TALLOC_FREE(result);
4175 status = rpc_pipe_bind(result, auth);
4176 if (!NT_STATUS_IS_OK(status)) {
4177 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4178 "cli_rpc_pipe_bind failed with error %s\n",
4179 nt_errstr(status) ));
4180 TALLOC_FREE(result);
4185 * The credentials on a new netlogon pipe are the ones we are passed
4186 * in - reference them in
4188 result->dc = talloc_move(result, pdc);
4190 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4191 "for domain %s and bound using schannel.\n",
4192 get_pipe_name_from_syntax(talloc_tos(), interface),
4193 cli->desthost, domain ));
4196 return NT_STATUS_OK;
4199 /****************************************************************************
4200 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4201 Fetch the session key ourselves using a temporary netlogon pipe. This
4202 version uses an ntlmssp auth bound netlogon pipe to get the key.
4203 ****************************************************************************/
4205 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4207 const char *username,
4208 const char *password,
4210 struct rpc_pipe_client **presult)
4212 struct rpc_pipe_client *netlogon_pipe = NULL;
4215 status = cli_rpc_pipe_open_spnego_ntlmssp(
4216 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4217 DCERPC_AUTH_LEVEL_PRIVACY,
4218 domain, username, password, &netlogon_pipe);
4219 if (!NT_STATUS_IS_OK(status)) {
4223 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4225 if (!NT_STATUS_IS_OK(status)) {
4226 TALLOC_FREE(netlogon_pipe);
4230 *presult = netlogon_pipe;
4231 return NT_STATUS_OK;
4234 /****************************************************************************
4235 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4236 Fetch the session key ourselves using a temporary netlogon pipe. This version
4237 uses an ntlmssp bind to get the session key.
4238 ****************************************************************************/
4240 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4241 const struct ndr_syntax_id *interface,
4242 enum dcerpc_transport_t transport,
4243 enum dcerpc_AuthLevel auth_level,
4245 const char *username,
4246 const char *password,
4247 struct rpc_pipe_client **presult)
4249 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4250 struct rpc_pipe_client *netlogon_pipe = NULL;
4251 struct rpc_pipe_client *result = NULL;
4254 status = get_schannel_session_key_auth_ntlmssp(
4255 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4256 if (!NT_STATUS_IS_OK(status)) {
4257 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4258 "key from server %s for domain %s.\n",
4259 cli->desthost, domain ));
4263 status = cli_rpc_pipe_open_schannel_with_key(
4264 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4267 /* Now we've bound using the session key we can close the netlog pipe. */
4268 TALLOC_FREE(netlogon_pipe);
4270 if (NT_STATUS_IS_OK(status)) {
4276 /****************************************************************************
4277 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4278 Fetch the session key ourselves using a temporary netlogon pipe.
4279 ****************************************************************************/
4281 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4282 const struct ndr_syntax_id *interface,
4283 enum dcerpc_transport_t transport,
4284 enum dcerpc_AuthLevel auth_level,
4286 struct rpc_pipe_client **presult)
4288 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4289 struct rpc_pipe_client *netlogon_pipe = NULL;
4290 struct rpc_pipe_client *result = NULL;
4293 status = get_schannel_session_key(cli, domain, &neg_flags,
4295 if (!NT_STATUS_IS_OK(status)) {
4296 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4297 "key from server %s for domain %s.\n",
4298 cli->desthost, domain ));
4302 status = cli_rpc_pipe_open_schannel_with_key(
4303 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4306 /* Now we've bound using the session key we can close the netlog pipe. */
4307 TALLOC_FREE(netlogon_pipe);
4309 if (NT_STATUS_IS_OK(status)) {
4316 /****************************************************************************
4317 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4318 The idea is this can be called with service_princ, username and password all
4319 NULL so long as the caller has a TGT.
4320 ****************************************************************************/
4322 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4323 const struct ndr_syntax_id *interface,
4324 enum dcerpc_AuthLevel auth_level,
4325 const char *service_princ,
4326 const char *username,
4327 const char *password,
4328 struct rpc_pipe_client **presult)
4331 struct rpc_pipe_client *result;
4332 struct cli_pipe_auth_data *auth;
4335 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4336 if (!NT_STATUS_IS_OK(status)) {
4340 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4341 username, password, &auth);
4342 if (!NT_STATUS_IS_OK(status)) {
4343 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4344 nt_errstr(status)));
4345 TALLOC_FREE(result);
4349 status = rpc_pipe_bind(result, auth);
4350 if (!NT_STATUS_IS_OK(status)) {
4351 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4352 "with error %s\n", nt_errstr(status)));
4353 TALLOC_FREE(result);
4358 return NT_STATUS_OK;
4360 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4361 return NT_STATUS_NOT_IMPLEMENTED;
4365 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4366 struct rpc_pipe_client *cli,
4367 DATA_BLOB *session_key)
4369 if (!session_key || !cli) {
4370 return NT_STATUS_INVALID_PARAMETER;
4374 return NT_STATUS_INVALID_PARAMETER;
4377 switch (cli->auth->auth_type) {
4378 case PIPE_AUTH_TYPE_SCHANNEL:
4379 *session_key = data_blob_talloc(mem_ctx,
4380 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4382 case PIPE_AUTH_TYPE_NTLMSSP:
4383 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4384 *session_key = data_blob_talloc(mem_ctx,
4385 cli->auth->a_u.ntlmssp_state->session_key.data,
4386 cli->auth->a_u.ntlmssp_state->session_key.length);
4388 case PIPE_AUTH_TYPE_KRB5:
4389 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4390 *session_key = data_blob_talloc(mem_ctx,
4391 cli->auth->a_u.kerberos_auth->session_key.data,
4392 cli->auth->a_u.kerberos_auth->session_key.length);
4394 case PIPE_AUTH_TYPE_NONE:
4395 *session_key = data_blob_talloc(mem_ctx,
4396 cli->auth->user_session_key.data,
4397 cli->auth->user_session_key.length);
4400 return NT_STATUS_NO_USER_SESSION_KEY;
4403 return NT_STATUS_OK;