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 Creates krb5 auth bind.
1655 ********************************************************************/
1657 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1658 enum dcerpc_AuthLevel auth_level,
1659 RPC_HDR_AUTH *pauth_out,
1660 prs_struct *auth_data)
1664 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1665 DATA_BLOB tkt = data_blob_null;
1666 DATA_BLOB tkt_wrapped = data_blob_null;
1668 /* We may change the pad length before marshalling. */
1669 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1671 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1672 a->service_principal ));
1674 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1676 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1677 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1680 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1682 a->service_principal,
1683 error_message(ret) ));
1685 data_blob_free(&tkt);
1686 return NT_STATUS_INVALID_PARAMETER;
1689 /* wrap that up in a nice GSS-API wrapping */
1690 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1692 data_blob_free(&tkt);
1694 /* Auth len in the rpc header doesn't include auth_header. */
1695 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1696 data_blob_free(&tkt_wrapped);
1697 return NT_STATUS_NO_MEMORY;
1700 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1701 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1703 data_blob_free(&tkt_wrapped);
1704 return NT_STATUS_OK;
1706 return NT_STATUS_INVALID_PARAMETER;
1710 /*******************************************************************
1711 Creates SPNEGO NTLMSSP auth bind.
1712 ********************************************************************/
1714 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1715 enum dcerpc_AuthLevel auth_level,
1716 RPC_HDR_AUTH *pauth_out,
1717 prs_struct *auth_data)
1720 DATA_BLOB null_blob = data_blob_null;
1721 DATA_BLOB request = data_blob_null;
1722 DATA_BLOB spnego_msg = data_blob_null;
1724 /* We may change the pad length before marshalling. */
1725 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1727 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1728 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1732 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1733 data_blob_free(&request);
1737 /* Wrap this in SPNEGO. */
1738 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1740 data_blob_free(&request);
1742 /* Auth len in the rpc header doesn't include auth_header. */
1743 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1744 data_blob_free(&spnego_msg);
1745 return NT_STATUS_NO_MEMORY;
1748 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1749 dump_data(5, spnego_msg.data, spnego_msg.length);
1751 data_blob_free(&spnego_msg);
1752 return NT_STATUS_OK;
1755 /*******************************************************************
1756 Creates NTLMSSP auth bind.
1757 ********************************************************************/
1759 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1760 enum dcerpc_AuthLevel auth_level,
1761 RPC_HDR_AUTH *pauth_out,
1762 prs_struct *auth_data)
1765 DATA_BLOB null_blob = data_blob_null;
1766 DATA_BLOB request = data_blob_null;
1768 /* We may change the pad length before marshalling. */
1769 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1771 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1772 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1776 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1777 data_blob_free(&request);
1781 /* Auth len in the rpc header doesn't include auth_header. */
1782 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1783 data_blob_free(&request);
1784 return NT_STATUS_NO_MEMORY;
1787 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1788 dump_data(5, request.data, request.length);
1790 data_blob_free(&request);
1791 return NT_STATUS_OK;
1794 /*******************************************************************
1795 Creates schannel auth bind.
1796 ********************************************************************/
1798 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1799 enum dcerpc_AuthLevel auth_level,
1800 RPC_HDR_AUTH *pauth_out,
1801 prs_struct *auth_data)
1803 struct NL_AUTH_MESSAGE r;
1804 enum ndr_err_code ndr_err;
1807 /* We may change the pad length before marshalling. */
1808 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1810 /* Use lp_workgroup() if domain not specified */
1812 if (!cli->auth->domain || !cli->auth->domain[0]) {
1813 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1814 if (cli->auth->domain == NULL) {
1815 return NT_STATUS_NO_MEMORY;
1820 * Now marshall the data into the auth parse_struct.
1823 r.MessageType = NL_NEGOTIATE_REQUEST;
1824 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1825 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1826 r.oem_netbios_domain.a = cli->auth->domain;
1827 r.oem_netbios_computer.a = global_myname();
1829 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &r,
1830 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1831 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1832 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1833 return ndr_map_error2ntstatus(ndr_err);
1836 if (DEBUGLEVEL >= 10) {
1837 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1840 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1842 return NT_STATUS_NO_MEMORY;
1845 return NT_STATUS_OK;
1848 /*******************************************************************
1849 Creates the internals of a DCE/RPC bind request or alter context PDU.
1850 ********************************************************************/
1852 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1853 prs_struct *rpc_out,
1855 const struct ndr_syntax_id *abstract,
1856 const struct ndr_syntax_id *transfer,
1857 RPC_HDR_AUTH *phdr_auth,
1858 prs_struct *pauth_info)
1862 RPC_CONTEXT rpc_ctx;
1863 uint16 auth_len = prs_offset(pauth_info);
1864 uint8 ss_padding_len = 0;
1865 uint16 frag_len = 0;
1867 /* create the RPC context. */
1868 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1870 /* create the bind request RPC_HDR_RB */
1871 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1873 /* Start building the frag length. */
1874 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1876 /* Do we need to pad ? */
1878 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1879 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1880 ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1881 phdr_auth->auth_pad_len = ss_padding_len;
1883 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1886 /* Create the request RPC_HDR */
1887 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1889 /* Marshall the RPC header */
1890 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1891 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1892 return NT_STATUS_NO_MEMORY;
1895 /* Marshall the bind request data */
1896 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1897 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1898 return NT_STATUS_NO_MEMORY;
1902 * Grow the outgoing buffer to store any auth info.
1906 if (ss_padding_len) {
1907 char pad[CLIENT_NDR_PADDING_SIZE];
1908 memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1909 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1910 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1911 return NT_STATUS_NO_MEMORY;
1915 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1916 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1917 return NT_STATUS_NO_MEMORY;
1921 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1922 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1923 return NT_STATUS_NO_MEMORY;
1927 return NT_STATUS_OK;
1930 /*******************************************************************
1931 Creates a DCE/RPC bind request.
1932 ********************************************************************/
1934 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1935 prs_struct *rpc_out,
1937 const struct ndr_syntax_id *abstract,
1938 const struct ndr_syntax_id *transfer,
1939 enum pipe_auth_type auth_type,
1940 enum dcerpc_AuthLevel auth_level)
1942 RPC_HDR_AUTH hdr_auth;
1943 prs_struct auth_info;
1944 NTSTATUS ret = NT_STATUS_OK;
1946 ZERO_STRUCT(hdr_auth);
1947 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1948 return NT_STATUS_NO_MEMORY;
1950 switch (auth_type) {
1951 case PIPE_AUTH_TYPE_SCHANNEL:
1952 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1953 if (!NT_STATUS_IS_OK(ret)) {
1958 case PIPE_AUTH_TYPE_NTLMSSP:
1959 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1960 if (!NT_STATUS_IS_OK(ret)) {
1965 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1966 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1967 if (!NT_STATUS_IS_OK(ret)) {
1972 case PIPE_AUTH_TYPE_KRB5:
1973 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1974 if (!NT_STATUS_IS_OK(ret)) {
1979 case PIPE_AUTH_TYPE_NONE:
1983 /* "Can't" happen. */
1984 return NT_STATUS_INVALID_INFO_CLASS;
1987 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1998 /*******************************************************************
1999 Create and add the NTLMSSP sign/seal auth header and data.
2000 ********************************************************************/
2002 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2004 uint32 ss_padding_len,
2005 prs_struct *outgoing_pdu)
2007 RPC_HDR_AUTH auth_info;
2009 DATA_BLOB auth_blob = data_blob_null;
2010 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2013 if (!cli->auth->a_u.ntlmssp_state) {
2014 return NT_STATUS_INVALID_PARAMETER;
2017 frame = talloc_stackframe();
2019 /* Init and marshall the auth header. */
2020 init_rpc_hdr_auth(&auth_info,
2021 map_pipe_auth_type_to_rpc_auth_type(
2022 cli->auth->auth_type),
2023 cli->auth->auth_level,
2025 1 /* context id. */);
2027 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2028 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2030 return NT_STATUS_NO_MEMORY;
2033 switch (cli->auth->auth_level) {
2034 case DCERPC_AUTH_LEVEL_PRIVACY:
2035 /* Data portion is encrypted. */
2036 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2038 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2040 (unsigned char *)prs_data_p(outgoing_pdu),
2041 (size_t)prs_offset(outgoing_pdu),
2043 if (!NT_STATUS_IS_OK(status)) {
2049 case DCERPC_AUTH_LEVEL_INTEGRITY:
2050 /* Data is signed. */
2051 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2053 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2055 (unsigned char *)prs_data_p(outgoing_pdu),
2056 (size_t)prs_offset(outgoing_pdu),
2058 if (!NT_STATUS_IS_OK(status)) {
2066 smb_panic("bad auth level");
2068 return NT_STATUS_INVALID_PARAMETER;
2071 /* Finally marshall the blob. */
2073 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2074 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2075 (unsigned int)NTLMSSP_SIG_SIZE));
2077 return NT_STATUS_NO_MEMORY;
2081 return NT_STATUS_OK;
2084 /*******************************************************************
2085 Create and add the schannel sign/seal auth header and data.
2086 ********************************************************************/
2088 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2090 uint32 ss_padding_len,
2091 prs_struct *outgoing_pdu)
2093 RPC_HDR_AUTH auth_info;
2094 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2095 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2096 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2101 return NT_STATUS_INVALID_PARAMETER;
2104 /* Init and marshall the auth header. */
2105 init_rpc_hdr_auth(&auth_info,
2106 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2107 cli->auth->auth_level,
2109 1 /* context id. */);
2111 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2112 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2113 return NT_STATUS_NO_MEMORY;
2116 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2119 switch (cli->auth->auth_level) {
2120 case DCERPC_AUTH_LEVEL_PRIVACY:
2121 status = netsec_outgoing_packet(sas,
2128 case DCERPC_AUTH_LEVEL_INTEGRITY:
2129 status = netsec_outgoing_packet(sas,
2137 status = NT_STATUS_INTERNAL_ERROR;
2141 if (!NT_STATUS_IS_OK(status)) {
2142 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2143 nt_errstr(status)));
2147 if (DEBUGLEVEL >= 10) {
2148 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2151 /* Finally marshall the blob. */
2152 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2153 return NT_STATUS_NO_MEMORY;
2156 return NT_STATUS_OK;
2159 /*******************************************************************
2160 Calculate how much data we're going to send in this packet, also
2161 work out any sign/seal padding length.
2162 ********************************************************************/
2164 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2168 uint32 *p_ss_padding)
2170 uint32 data_space, data_len;
2173 if ((data_left > 0) && (sys_random() % 2)) {
2174 data_left = MAX(data_left/2, 1);
2178 switch (cli->auth->auth_level) {
2179 case DCERPC_AUTH_LEVEL_NONE:
2180 case DCERPC_AUTH_LEVEL_CONNECT:
2181 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2182 data_len = MIN(data_space, data_left);
2185 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2188 case DCERPC_AUTH_LEVEL_INTEGRITY:
2189 case DCERPC_AUTH_LEVEL_PRIVACY:
2190 /* Treat the same for all authenticated rpc requests. */
2191 switch(cli->auth->auth_type) {
2192 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2193 case PIPE_AUTH_TYPE_NTLMSSP:
2194 *p_auth_len = NTLMSSP_SIG_SIZE;
2196 case PIPE_AUTH_TYPE_SCHANNEL:
2197 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2200 smb_panic("bad auth type");
2204 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2205 RPC_HDR_AUTH_LEN - *p_auth_len;
2207 data_len = MIN(data_space, data_left);
2209 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2210 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2212 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2213 data_len + *p_ss_padding + /* data plus padding. */
2214 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2218 smb_panic("bad auth level");
2224 /*******************************************************************
2226 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2227 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2228 and deals with signing/sealing details.
2229 ********************************************************************/
2231 struct rpc_api_pipe_req_state {
2232 struct event_context *ev;
2233 struct rpc_pipe_client *cli;
2236 prs_struct *req_data;
2237 uint32_t req_data_sent;
2238 prs_struct outgoing_frag;
2239 prs_struct reply_pdu;
2242 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2243 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2244 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2245 bool *is_last_frag);
2247 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2248 struct event_context *ev,
2249 struct rpc_pipe_client *cli,
2251 prs_struct *req_data)
2253 struct tevent_req *req, *subreq;
2254 struct rpc_api_pipe_req_state *state;
2258 req = tevent_req_create(mem_ctx, &state,
2259 struct rpc_api_pipe_req_state);
2265 state->op_num = op_num;
2266 state->req_data = req_data;
2267 state->req_data_sent = 0;
2268 state->call_id = get_rpc_call_id();
2270 if (cli->max_xmit_frag
2271 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2272 /* Server is screwed up ! */
2273 status = NT_STATUS_INVALID_PARAMETER;
2277 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2279 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2284 status = prepare_next_frag(state, &is_last_frag);
2285 if (!NT_STATUS_IS_OK(status)) {
2290 subreq = rpc_api_pipe_send(state, ev, state->cli,
2291 &state->outgoing_frag,
2292 DCERPC_PKT_RESPONSE);
2293 if (subreq == NULL) {
2296 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2298 subreq = rpc_write_send(
2299 state, ev, cli->transport,
2300 (uint8_t *)prs_data_p(&state->outgoing_frag),
2301 prs_offset(&state->outgoing_frag));
2302 if (subreq == NULL) {
2305 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2311 tevent_req_nterror(req, status);
2312 return tevent_req_post(req, ev);
2318 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2322 RPC_HDR_REQ hdr_req;
2323 uint32_t data_sent_thistime;
2327 uint32_t ss_padding;
2329 char pad[8] = { 0, };
2332 data_left = prs_offset(state->req_data) - state->req_data_sent;
2334 data_sent_thistime = calculate_data_len_tosend(
2335 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2337 if (state->req_data_sent == 0) {
2338 flags = DCERPC_PFC_FLAG_FIRST;
2341 if (data_sent_thistime == data_left) {
2342 flags |= DCERPC_PFC_FLAG_LAST;
2345 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2346 return NT_STATUS_NO_MEMORY;
2349 /* Create and marshall the header and request header. */
2350 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2353 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2354 return NT_STATUS_NO_MEMORY;
2357 /* Create the rpc request RPC_HDR_REQ */
2358 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2361 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2362 &state->outgoing_frag, 0)) {
2363 return NT_STATUS_NO_MEMORY;
2366 /* Copy in the data, plus any ss padding. */
2367 if (!prs_append_some_prs_data(&state->outgoing_frag,
2368 state->req_data, state->req_data_sent,
2369 data_sent_thistime)) {
2370 return NT_STATUS_NO_MEMORY;
2373 /* Copy the sign/seal padding data. */
2374 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2375 return NT_STATUS_NO_MEMORY;
2378 /* Generate any auth sign/seal and add the auth footer. */
2379 switch (state->cli->auth->auth_type) {
2380 case PIPE_AUTH_TYPE_NONE:
2381 status = NT_STATUS_OK;
2383 case PIPE_AUTH_TYPE_NTLMSSP:
2384 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2385 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2386 &state->outgoing_frag);
2388 case PIPE_AUTH_TYPE_SCHANNEL:
2389 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2390 &state->outgoing_frag);
2393 status = NT_STATUS_INVALID_PARAMETER;
2397 state->req_data_sent += data_sent_thistime;
2398 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2403 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2405 struct tevent_req *req = tevent_req_callback_data(
2406 subreq, struct tevent_req);
2407 struct rpc_api_pipe_req_state *state = tevent_req_data(
2408 req, struct rpc_api_pipe_req_state);
2412 status = rpc_write_recv(subreq);
2413 TALLOC_FREE(subreq);
2414 if (!NT_STATUS_IS_OK(status)) {
2415 tevent_req_nterror(req, status);
2419 status = prepare_next_frag(state, &is_last_frag);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 tevent_req_nterror(req, status);
2426 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2427 &state->outgoing_frag,
2428 DCERPC_PKT_RESPONSE);
2429 if (tevent_req_nomem(subreq, req)) {
2432 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2434 subreq = rpc_write_send(
2436 state->cli->transport,
2437 (uint8_t *)prs_data_p(&state->outgoing_frag),
2438 prs_offset(&state->outgoing_frag));
2439 if (tevent_req_nomem(subreq, req)) {
2442 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2447 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2449 struct tevent_req *req = tevent_req_callback_data(
2450 subreq, struct tevent_req);
2451 struct rpc_api_pipe_req_state *state = tevent_req_data(
2452 req, struct rpc_api_pipe_req_state);
2455 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2456 TALLOC_FREE(subreq);
2457 if (!NT_STATUS_IS_OK(status)) {
2458 tevent_req_nterror(req, status);
2461 tevent_req_done(req);
2464 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2465 prs_struct *reply_pdu)
2467 struct rpc_api_pipe_req_state *state = tevent_req_data(
2468 req, struct rpc_api_pipe_req_state);
2471 if (tevent_req_is_nterror(req, &status)) {
2473 * We always have to initialize to reply pdu, even if there is
2474 * none. The rpccli_* caller routines expect this.
2476 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2480 *reply_pdu = state->reply_pdu;
2481 reply_pdu->mem_ctx = mem_ctx;
2484 * Prevent state->req_pdu from being freed
2485 * when state is freed.
2487 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2488 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2490 return NT_STATUS_OK;
2494 /****************************************************************************
2495 Set the handle state.
2496 ****************************************************************************/
2498 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2499 const char *pipe_name, uint16 device_state)
2501 bool state_set = False;
2503 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2504 char *rparam = NULL;
2506 uint32 rparam_len, rdata_len;
2508 if (pipe_name == NULL)
2511 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2512 cli->fnum, pipe_name, device_state));
2514 /* create parameters: device state */
2515 SSVAL(param, 0, device_state);
2517 /* create setup parameters. */
2519 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2521 /* send the data on \PIPE\ */
2522 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2523 setup, 2, 0, /* setup, length, max */
2524 param, 2, 0, /* param, length, max */
2525 NULL, 0, 1024, /* data, length, max */
2526 &rparam, &rparam_len, /* return param, length */
2527 &rdata, &rdata_len)) /* return data, length */
2529 DEBUG(5, ("Set Handle state: return OK\n"));
2540 /****************************************************************************
2541 Check the rpc bind acknowledge response.
2542 ****************************************************************************/
2544 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2545 const struct ndr_syntax_id *transfer)
2547 if ( hdr_ba->addr.len == 0) {
2548 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2551 /* check the transfer syntax */
2552 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2553 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2554 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2558 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2559 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2560 hdr_ba->res.num_results, hdr_ba->res.reason));
2563 DEBUG(5,("check_bind_response: accepted!\n"));
2567 /*******************************************************************
2568 Creates a DCE/RPC bind authentication response.
2569 This is the packet that is sent back to the server once we
2570 have received a BIND-ACK, to finish the third leg of
2571 the authentication handshake.
2572 ********************************************************************/
2574 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2576 enum pipe_auth_type auth_type,
2577 enum dcerpc_AuthLevel auth_level,
2578 DATA_BLOB *pauth_blob,
2579 prs_struct *rpc_out)
2582 RPC_HDR_AUTH hdr_auth;
2585 /* Create the request RPC_HDR */
2586 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2587 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2588 pauth_blob->length );
2591 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2592 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2593 return NT_STATUS_NO_MEMORY;
2597 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2598 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2601 /* 4 bytes padding. */
2602 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2603 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2604 return NT_STATUS_NO_MEMORY;
2607 /* Create the request RPC_HDR_AUTHA */
2608 init_rpc_hdr_auth(&hdr_auth,
2609 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2612 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2613 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2614 return NT_STATUS_NO_MEMORY;
2618 * Append the auth data to the outgoing buffer.
2621 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2622 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2623 return NT_STATUS_NO_MEMORY;
2626 return NT_STATUS_OK;
2629 /*******************************************************************
2630 Creates a DCE/RPC bind alter context authentication request which
2631 may contain a spnego auth blobl
2632 ********************************************************************/
2634 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2635 const struct ndr_syntax_id *abstract,
2636 const struct ndr_syntax_id *transfer,
2637 enum dcerpc_AuthLevel auth_level,
2638 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2639 prs_struct *rpc_out)
2641 RPC_HDR_AUTH hdr_auth;
2642 prs_struct auth_info;
2643 NTSTATUS ret = NT_STATUS_OK;
2645 ZERO_STRUCT(hdr_auth);
2646 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2647 return NT_STATUS_NO_MEMORY;
2649 /* We may change the pad length before marshalling. */
2650 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2652 if (pauth_blob->length) {
2653 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2654 return NT_STATUS_NO_MEMORY;
2658 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2668 /****************************************************************************
2670 ****************************************************************************/
2672 struct rpc_pipe_bind_state {
2673 struct event_context *ev;
2674 struct rpc_pipe_client *cli;
2676 uint32_t rpc_call_id;
2679 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2680 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2681 struct rpc_pipe_bind_state *state,
2682 struct rpc_hdr_info *phdr,
2683 prs_struct *reply_pdu);
2684 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2685 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2686 struct rpc_pipe_bind_state *state,
2687 struct rpc_hdr_info *phdr,
2688 prs_struct *reply_pdu);
2689 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2691 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2692 struct event_context *ev,
2693 struct rpc_pipe_client *cli,
2694 struct cli_pipe_auth_data *auth)
2696 struct tevent_req *req, *subreq;
2697 struct rpc_pipe_bind_state *state;
2700 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2705 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2706 rpccli_pipe_txt(talloc_tos(), cli),
2707 (unsigned int)auth->auth_type,
2708 (unsigned int)auth->auth_level ));
2712 state->rpc_call_id = get_rpc_call_id();
2714 prs_init_empty(&state->rpc_out, state, MARSHALL);
2716 cli->auth = talloc_move(cli, &auth);
2718 /* Marshall the outgoing data. */
2719 status = create_rpc_bind_req(cli, &state->rpc_out,
2721 &cli->abstract_syntax,
2722 &cli->transfer_syntax,
2723 cli->auth->auth_type,
2724 cli->auth->auth_level);
2726 if (!NT_STATUS_IS_OK(status)) {
2730 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2731 DCERPC_PKT_BIND_ACK);
2732 if (subreq == NULL) {
2735 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2739 tevent_req_nterror(req, status);
2740 return tevent_req_post(req, ev);
2746 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2748 struct tevent_req *req = tevent_req_callback_data(
2749 subreq, struct tevent_req);
2750 struct rpc_pipe_bind_state *state = tevent_req_data(
2751 req, struct rpc_pipe_bind_state);
2752 prs_struct reply_pdu;
2753 struct rpc_hdr_info hdr;
2754 struct rpc_hdr_ba_info hdr_ba;
2757 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2758 TALLOC_FREE(subreq);
2759 if (!NT_STATUS_IS_OK(status)) {
2760 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2761 rpccli_pipe_txt(talloc_tos(), state->cli),
2762 nt_errstr(status)));
2763 tevent_req_nterror(req, status);
2767 /* Unmarshall the RPC header */
2768 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2769 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2770 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2774 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2775 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2777 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2781 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2782 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2783 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2787 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2788 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2791 * For authenticated binds we may need to do 3 or 4 leg binds.
2794 switch(state->cli->auth->auth_type) {
2796 case PIPE_AUTH_TYPE_NONE:
2797 case PIPE_AUTH_TYPE_SCHANNEL:
2798 /* Bind complete. */
2799 tevent_req_done(req);
2802 case PIPE_AUTH_TYPE_NTLMSSP:
2803 /* Need to send AUTH3 packet - no reply. */
2804 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2806 if (!NT_STATUS_IS_OK(status)) {
2807 tevent_req_nterror(req, status);
2811 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2812 /* Need to send alter context request and reply. */
2813 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2815 if (!NT_STATUS_IS_OK(status)) {
2816 tevent_req_nterror(req, status);
2820 case PIPE_AUTH_TYPE_KRB5:
2824 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2825 (unsigned int)state->cli->auth->auth_type));
2826 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2830 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2831 struct rpc_pipe_bind_state *state,
2832 struct rpc_hdr_info *phdr,
2833 prs_struct *reply_pdu)
2835 DATA_BLOB server_response = data_blob_null;
2836 DATA_BLOB client_reply = data_blob_null;
2837 struct rpc_hdr_auth_info hdr_auth;
2838 struct tevent_req *subreq;
2841 if ((phdr->auth_len == 0)
2842 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2843 return NT_STATUS_INVALID_PARAMETER;
2846 if (!prs_set_offset(
2848 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2849 return NT_STATUS_INVALID_PARAMETER;
2852 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2853 return NT_STATUS_INVALID_PARAMETER;
2856 /* TODO - check auth_type/auth_level match. */
2858 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2859 prs_copy_data_out((char *)server_response.data, reply_pdu,
2862 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2863 server_response, &client_reply);
2865 if (!NT_STATUS_IS_OK(status)) {
2866 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2867 "blob failed: %s.\n", nt_errstr(status)));
2871 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2873 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2874 state->cli->auth->auth_type,
2875 state->cli->auth->auth_level,
2876 &client_reply, &state->rpc_out);
2877 data_blob_free(&client_reply);
2879 if (!NT_STATUS_IS_OK(status)) {
2883 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2884 (uint8_t *)prs_data_p(&state->rpc_out),
2885 prs_offset(&state->rpc_out));
2886 if (subreq == NULL) {
2887 return NT_STATUS_NO_MEMORY;
2889 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2890 return NT_STATUS_OK;
2893 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2895 struct tevent_req *req = tevent_req_callback_data(
2896 subreq, struct tevent_req);
2899 status = rpc_write_recv(subreq);
2900 TALLOC_FREE(subreq);
2901 if (!NT_STATUS_IS_OK(status)) {
2902 tevent_req_nterror(req, status);
2905 tevent_req_done(req);
2908 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2909 struct rpc_pipe_bind_state *state,
2910 struct rpc_hdr_info *phdr,
2911 prs_struct *reply_pdu)
2913 DATA_BLOB server_spnego_response = data_blob_null;
2914 DATA_BLOB server_ntlm_response = data_blob_null;
2915 DATA_BLOB client_reply = data_blob_null;
2916 DATA_BLOB tmp_blob = data_blob_null;
2917 RPC_HDR_AUTH hdr_auth;
2918 struct tevent_req *subreq;
2921 if ((phdr->auth_len == 0)
2922 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2923 return NT_STATUS_INVALID_PARAMETER;
2926 /* Process the returned NTLMSSP blob first. */
2927 if (!prs_set_offset(
2929 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2930 return NT_STATUS_INVALID_PARAMETER;
2933 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2934 return NT_STATUS_INVALID_PARAMETER;
2937 server_spnego_response = data_blob(NULL, phdr->auth_len);
2938 prs_copy_data_out((char *)server_spnego_response.data,
2939 reply_pdu, phdr->auth_len);
2942 * The server might give us back two challenges - tmp_blob is for the
2945 if (!spnego_parse_challenge(server_spnego_response,
2946 &server_ntlm_response, &tmp_blob)) {
2947 data_blob_free(&server_spnego_response);
2948 data_blob_free(&server_ntlm_response);
2949 data_blob_free(&tmp_blob);
2950 return NT_STATUS_INVALID_PARAMETER;
2953 /* We're finished with the server spnego response and the tmp_blob. */
2954 data_blob_free(&server_spnego_response);
2955 data_blob_free(&tmp_blob);
2957 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2958 server_ntlm_response, &client_reply);
2960 /* Finished with the server_ntlm response */
2961 data_blob_free(&server_ntlm_response);
2963 if (!NT_STATUS_IS_OK(status)) {
2964 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2965 "using server blob failed.\n"));
2966 data_blob_free(&client_reply);
2970 /* SPNEGO wrap the client reply. */
2971 tmp_blob = spnego_gen_auth(client_reply);
2972 data_blob_free(&client_reply);
2973 client_reply = tmp_blob;
2974 tmp_blob = data_blob_null;
2976 /* Now prepare the alter context pdu. */
2977 prs_init_empty(&state->rpc_out, state, MARSHALL);
2979 status = create_rpc_alter_context(state->rpc_call_id,
2980 &state->cli->abstract_syntax,
2981 &state->cli->transfer_syntax,
2982 state->cli->auth->auth_level,
2985 data_blob_free(&client_reply);
2987 if (!NT_STATUS_IS_OK(status)) {
2991 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2992 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2993 if (subreq == NULL) {
2994 return NT_STATUS_NO_MEMORY;
2996 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2997 return NT_STATUS_OK;
3000 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3002 struct tevent_req *req = tevent_req_callback_data(
3003 subreq, struct tevent_req);
3004 struct rpc_pipe_bind_state *state = tevent_req_data(
3005 req, struct rpc_pipe_bind_state);
3006 DATA_BLOB server_spnego_response = data_blob_null;
3007 DATA_BLOB tmp_blob = data_blob_null;
3008 prs_struct reply_pdu;
3009 struct rpc_hdr_info hdr;
3010 struct rpc_hdr_auth_info hdr_auth;
3013 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3014 TALLOC_FREE(subreq);
3015 if (!NT_STATUS_IS_OK(status)) {
3016 tevent_req_nterror(req, status);
3020 /* Get the auth blob from the reply. */
3021 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3022 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3023 "unmarshall RPC_HDR.\n"));
3024 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3028 if (!prs_set_offset(
3030 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3031 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3035 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3036 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3040 server_spnego_response = data_blob(NULL, hdr.auth_len);
3041 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3044 /* Check we got a valid auth response. */
3045 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3046 OID_NTLMSSP, &tmp_blob)) {
3047 data_blob_free(&server_spnego_response);
3048 data_blob_free(&tmp_blob);
3049 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3053 data_blob_free(&server_spnego_response);
3054 data_blob_free(&tmp_blob);
3056 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3057 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3058 tevent_req_done(req);
3061 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3063 return tevent_req_simple_recv_ntstatus(req);
3066 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3067 struct cli_pipe_auth_data *auth)
3069 TALLOC_CTX *frame = talloc_stackframe();
3070 struct event_context *ev;
3071 struct tevent_req *req;
3072 NTSTATUS status = NT_STATUS_OK;
3074 ev = event_context_init(frame);
3076 status = NT_STATUS_NO_MEMORY;
3080 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3082 status = NT_STATUS_NO_MEMORY;
3086 if (!tevent_req_poll(req, ev)) {
3087 status = map_nt_error_from_unix(errno);
3091 status = rpc_pipe_bind_recv(req);
3097 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3099 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3100 unsigned int timeout)
3104 if (rpc_cli->transport == NULL) {
3105 return RPCCLI_DEFAULT_TIMEOUT;
3108 if (rpc_cli->transport->set_timeout == NULL) {
3109 return RPCCLI_DEFAULT_TIMEOUT;
3112 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3114 return RPCCLI_DEFAULT_TIMEOUT;
3120 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3122 if (rpc_cli == NULL) {
3126 if (rpc_cli->transport == NULL) {
3130 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3133 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3135 struct cli_state *cli;
3137 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3138 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3139 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3143 cli = rpc_pipe_np_smb_conn(rpc_cli);
3147 E_md4hash(cli->password ? cli->password : "", nt_hash);
3151 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3152 struct cli_pipe_auth_data **presult)
3154 struct cli_pipe_auth_data *result;
3156 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3157 if (result == NULL) {
3158 return NT_STATUS_NO_MEMORY;
3161 result->auth_type = PIPE_AUTH_TYPE_NONE;
3162 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3164 result->user_name = talloc_strdup(result, "");
3165 result->domain = talloc_strdup(result, "");
3166 if ((result->user_name == NULL) || (result->domain == NULL)) {
3167 TALLOC_FREE(result);
3168 return NT_STATUS_NO_MEMORY;
3172 return NT_STATUS_OK;
3175 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3177 ntlmssp_end(&auth->a_u.ntlmssp_state);
3181 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3182 enum pipe_auth_type auth_type,
3183 enum dcerpc_AuthLevel auth_level,
3185 const char *username,
3186 const char *password,
3187 struct cli_pipe_auth_data **presult)
3189 struct cli_pipe_auth_data *result;
3192 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3193 if (result == NULL) {
3194 return NT_STATUS_NO_MEMORY;
3197 result->auth_type = auth_type;
3198 result->auth_level = auth_level;
3200 result->user_name = talloc_strdup(result, username);
3201 result->domain = talloc_strdup(result, domain);
3202 if ((result->user_name == NULL) || (result->domain == NULL)) {
3203 status = NT_STATUS_NO_MEMORY;
3207 status = ntlmssp_client_start(NULL,
3210 lp_client_ntlmv2_auth(),
3211 &result->a_u.ntlmssp_state);
3212 if (!NT_STATUS_IS_OK(status)) {
3216 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3218 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3219 if (!NT_STATUS_IS_OK(status)) {
3223 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3224 if (!NT_STATUS_IS_OK(status)) {
3228 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3229 if (!NT_STATUS_IS_OK(status)) {
3234 * Turn off sign+seal to allow selected auth level to turn it back on.
3236 result->a_u.ntlmssp_state->neg_flags &=
3237 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3239 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3240 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3241 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3242 result->a_u.ntlmssp_state->neg_flags
3243 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3247 return NT_STATUS_OK;
3250 TALLOC_FREE(result);
3254 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3255 enum dcerpc_AuthLevel auth_level,
3256 struct netlogon_creds_CredentialState *creds,
3257 struct cli_pipe_auth_data **presult)
3259 struct cli_pipe_auth_data *result;
3261 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3262 if (result == NULL) {
3263 return NT_STATUS_NO_MEMORY;
3266 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3267 result->auth_level = auth_level;
3269 result->user_name = talloc_strdup(result, "");
3270 result->domain = talloc_strdup(result, domain);
3271 if ((result->user_name == NULL) || (result->domain == NULL)) {
3275 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3276 if (result->a_u.schannel_auth == NULL) {
3280 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3281 result->a_u.schannel_auth->seq_num = 0;
3282 result->a_u.schannel_auth->initiator = true;
3283 result->a_u.schannel_auth->creds = creds;
3286 return NT_STATUS_OK;
3289 TALLOC_FREE(result);
3290 return NT_STATUS_NO_MEMORY;
3294 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3296 data_blob_free(&auth->session_key);
3301 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3302 enum dcerpc_AuthLevel auth_level,
3303 const char *service_princ,
3304 const char *username,
3305 const char *password,
3306 struct cli_pipe_auth_data **presult)
3309 struct cli_pipe_auth_data *result;
3311 if ((username != NULL) && (password != NULL)) {
3312 int ret = kerberos_kinit_password(username, password, 0, NULL);
3314 return NT_STATUS_ACCESS_DENIED;
3318 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3319 if (result == NULL) {
3320 return NT_STATUS_NO_MEMORY;
3323 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3324 result->auth_level = auth_level;
3327 * Username / domain need fixing!
3329 result->user_name = talloc_strdup(result, "");
3330 result->domain = talloc_strdup(result, "");
3331 if ((result->user_name == NULL) || (result->domain == NULL)) {
3335 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3336 result, struct kerberos_auth_struct);
3337 if (result->a_u.kerberos_auth == NULL) {
3340 talloc_set_destructor(result->a_u.kerberos_auth,
3341 cli_auth_kerberos_data_destructor);
3343 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3344 result, service_princ);
3345 if (result->a_u.kerberos_auth->service_principal == NULL) {
3350 return NT_STATUS_OK;
3353 TALLOC_FREE(result);
3354 return NT_STATUS_NO_MEMORY;
3356 return NT_STATUS_NOT_SUPPORTED;
3361 * Create an rpc pipe client struct, connecting to a tcp port.
3363 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3365 const struct ndr_syntax_id *abstract_syntax,
3366 struct rpc_pipe_client **presult)
3368 struct rpc_pipe_client *result;
3369 struct sockaddr_storage addr;
3373 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3374 if (result == NULL) {
3375 return NT_STATUS_NO_MEMORY;
3378 result->abstract_syntax = *abstract_syntax;
3379 result->transfer_syntax = ndr_transfer_syntax;
3380 result->dispatch = cli_do_rpc_ndr;
3381 result->dispatch_send = cli_do_rpc_ndr_send;
3382 result->dispatch_recv = cli_do_rpc_ndr_recv;
3384 result->desthost = talloc_strdup(result, host);
3385 result->srv_name_slash = talloc_asprintf_strupper_m(
3386 result, "\\\\%s", result->desthost);
3387 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3388 status = NT_STATUS_NO_MEMORY;
3392 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3393 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3395 if (!resolve_name(host, &addr, 0, false)) {
3396 status = NT_STATUS_NOT_FOUND;
3400 status = open_socket_out(&addr, port, 60, &fd);
3401 if (!NT_STATUS_IS_OK(status)) {
3404 set_socket_options(fd, lp_socket_options());
3406 status = rpc_transport_sock_init(result, fd, &result->transport);
3407 if (!NT_STATUS_IS_OK(status)) {
3412 result->transport->transport = NCACN_IP_TCP;
3415 return NT_STATUS_OK;
3418 TALLOC_FREE(result);
3423 * Determine the tcp port on which a dcerpc interface is listening
3424 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3427 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3428 const struct ndr_syntax_id *abstract_syntax,
3432 struct rpc_pipe_client *epm_pipe = NULL;
3433 struct cli_pipe_auth_data *auth = NULL;
3434 struct dcerpc_binding *map_binding = NULL;
3435 struct dcerpc_binding *res_binding = NULL;
3436 struct epm_twr_t *map_tower = NULL;
3437 struct epm_twr_t *res_towers = NULL;
3438 struct policy_handle *entry_handle = NULL;
3439 uint32_t num_towers = 0;
3440 uint32_t max_towers = 1;
3441 struct epm_twr_p_t towers;
3442 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3444 if (pport == NULL) {
3445 status = NT_STATUS_INVALID_PARAMETER;
3449 /* open the connection to the endpoint mapper */
3450 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3451 &ndr_table_epmapper.syntax_id,
3454 if (!NT_STATUS_IS_OK(status)) {
3458 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3459 if (!NT_STATUS_IS_OK(status)) {
3463 status = rpc_pipe_bind(epm_pipe, auth);
3464 if (!NT_STATUS_IS_OK(status)) {
3468 /* create tower for asking the epmapper */
3470 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3471 if (map_binding == NULL) {
3472 status = NT_STATUS_NO_MEMORY;
3476 map_binding->transport = NCACN_IP_TCP;
3477 map_binding->object = *abstract_syntax;
3478 map_binding->host = host; /* needed? */
3479 map_binding->endpoint = "0"; /* correct? needed? */
3481 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3482 if (map_tower == NULL) {
3483 status = NT_STATUS_NO_MEMORY;
3487 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3488 &(map_tower->tower));
3489 if (!NT_STATUS_IS_OK(status)) {
3493 /* allocate further parameters for the epm_Map call */
3495 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3496 if (res_towers == NULL) {
3497 status = NT_STATUS_NO_MEMORY;
3500 towers.twr = res_towers;
3502 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3503 if (entry_handle == NULL) {
3504 status = NT_STATUS_NO_MEMORY;
3508 /* ask the endpoint mapper for the port */
3510 status = rpccli_epm_Map(epm_pipe,
3512 CONST_DISCARD(struct GUID *,
3513 &(abstract_syntax->uuid)),
3520 if (!NT_STATUS_IS_OK(status)) {
3524 if (num_towers != 1) {
3525 status = NT_STATUS_UNSUCCESSFUL;
3529 /* extract the port from the answer */
3531 status = dcerpc_binding_from_tower(tmp_ctx,
3532 &(towers.twr->tower),
3534 if (!NT_STATUS_IS_OK(status)) {
3538 /* are further checks here necessary? */
3539 if (res_binding->transport != NCACN_IP_TCP) {
3540 status = NT_STATUS_UNSUCCESSFUL;
3544 *pport = (uint16_t)atoi(res_binding->endpoint);
3547 TALLOC_FREE(tmp_ctx);
3552 * Create a rpc pipe client struct, connecting to a host via tcp.
3553 * The port is determined by asking the endpoint mapper on the given
3556 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3557 const struct ndr_syntax_id *abstract_syntax,
3558 struct rpc_pipe_client **presult)
3563 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3564 if (!NT_STATUS_IS_OK(status)) {
3568 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3569 abstract_syntax, presult);
3572 /********************************************************************
3573 Create a rpc pipe client struct, connecting to a unix domain socket
3574 ********************************************************************/
3575 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3576 const struct ndr_syntax_id *abstract_syntax,
3577 struct rpc_pipe_client **presult)
3579 struct rpc_pipe_client *result;
3580 struct sockaddr_un addr;
3584 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3585 if (result == NULL) {
3586 return NT_STATUS_NO_MEMORY;
3589 result->abstract_syntax = *abstract_syntax;
3590 result->transfer_syntax = ndr_transfer_syntax;
3591 result->dispatch = cli_do_rpc_ndr;
3592 result->dispatch_send = cli_do_rpc_ndr_send;
3593 result->dispatch_recv = cli_do_rpc_ndr_recv;
3595 result->desthost = get_myname(result);
3596 result->srv_name_slash = talloc_asprintf_strupper_m(
3597 result, "\\\\%s", result->desthost);
3598 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3599 status = NT_STATUS_NO_MEMORY;
3603 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3604 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3606 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3608 status = map_nt_error_from_unix(errno);
3613 addr.sun_family = AF_UNIX;
3614 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3616 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3617 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3620 return map_nt_error_from_unix(errno);
3623 status = rpc_transport_sock_init(result, fd, &result->transport);
3624 if (!NT_STATUS_IS_OK(status)) {
3629 result->transport->transport = NCALRPC;
3632 return NT_STATUS_OK;
3635 TALLOC_FREE(result);
3639 struct rpc_pipe_client_np_ref {
3640 struct cli_state *cli;
3641 struct rpc_pipe_client *pipe;
3644 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3646 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3650 /****************************************************************************
3651 Open a named pipe over SMB to a remote server.
3653 * CAVEAT CALLER OF THIS FUNCTION:
3654 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3655 * so be sure that this function is called AFTER any structure (vs pointer)
3656 * assignment of the cli. In particular, libsmbclient does structure
3657 * assignments of cli, which invalidates the data in the returned
3658 * rpc_pipe_client if this function is called before the structure assignment
3661 ****************************************************************************/
3663 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3664 const struct ndr_syntax_id *abstract_syntax,
3665 struct rpc_pipe_client **presult)
3667 struct rpc_pipe_client *result;
3669 struct rpc_pipe_client_np_ref *np_ref;
3671 /* sanity check to protect against crashes */
3674 return NT_STATUS_INVALID_HANDLE;
3677 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3678 if (result == NULL) {
3679 return NT_STATUS_NO_MEMORY;
3682 result->abstract_syntax = *abstract_syntax;
3683 result->transfer_syntax = ndr_transfer_syntax;
3684 result->dispatch = cli_do_rpc_ndr;
3685 result->dispatch_send = cli_do_rpc_ndr_send;
3686 result->dispatch_recv = cli_do_rpc_ndr_recv;
3687 result->desthost = talloc_strdup(result, cli->desthost);
3688 result->srv_name_slash = talloc_asprintf_strupper_m(
3689 result, "\\\\%s", result->desthost);
3691 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3692 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3694 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3695 TALLOC_FREE(result);
3696 return NT_STATUS_NO_MEMORY;
3699 status = rpc_transport_np_init(result, cli, abstract_syntax,
3700 &result->transport);
3701 if (!NT_STATUS_IS_OK(status)) {
3702 TALLOC_FREE(result);
3706 result->transport->transport = NCACN_NP;
3708 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3709 if (np_ref == NULL) {
3710 TALLOC_FREE(result);
3711 return NT_STATUS_NO_MEMORY;
3714 np_ref->pipe = result;
3716 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3717 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3720 return NT_STATUS_OK;
3723 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3724 struct rpc_cli_smbd_conn *conn,
3725 const struct ndr_syntax_id *syntax,
3726 struct rpc_pipe_client **presult)
3728 struct rpc_pipe_client *result;
3729 struct cli_pipe_auth_data *auth;
3732 result = talloc(mem_ctx, struct rpc_pipe_client);
3733 if (result == NULL) {
3734 return NT_STATUS_NO_MEMORY;
3736 result->abstract_syntax = *syntax;
3737 result->transfer_syntax = ndr_transfer_syntax;
3738 result->dispatch = cli_do_rpc_ndr;
3739 result->dispatch_send = cli_do_rpc_ndr_send;
3740 result->dispatch_recv = cli_do_rpc_ndr_recv;
3741 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3742 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3744 result->desthost = talloc_strdup(result, global_myname());
3745 result->srv_name_slash = talloc_asprintf_strupper_m(
3746 result, "\\\\%s", global_myname());
3747 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3748 TALLOC_FREE(result);
3749 return NT_STATUS_NO_MEMORY;
3752 status = rpc_transport_smbd_init(result, conn, syntax,
3753 &result->transport);
3754 if (!NT_STATUS_IS_OK(status)) {
3755 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3756 nt_errstr(status)));
3757 TALLOC_FREE(result);
3761 status = rpccli_anon_bind_data(result, &auth);
3762 if (!NT_STATUS_IS_OK(status)) {
3763 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3764 nt_errstr(status)));
3765 TALLOC_FREE(result);
3769 status = rpc_pipe_bind(result, auth);
3770 if (!NT_STATUS_IS_OK(status)) {
3771 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3772 TALLOC_FREE(result);
3776 result->transport->transport = NCACN_INTERNAL;
3779 return NT_STATUS_OK;
3782 /****************************************************************************
3783 Open a pipe to a remote server.
3784 ****************************************************************************/
3786 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3787 enum dcerpc_transport_t transport,
3788 const struct ndr_syntax_id *interface,
3789 struct rpc_pipe_client **presult)
3791 switch (transport) {
3793 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3796 return rpc_pipe_open_np(cli, interface, presult);
3798 return NT_STATUS_NOT_IMPLEMENTED;
3802 /****************************************************************************
3803 Open a named pipe to an SMB server and bind anonymously.
3804 ****************************************************************************/
3806 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3807 enum dcerpc_transport_t transport,
3808 const struct ndr_syntax_id *interface,
3809 struct rpc_pipe_client **presult)
3811 struct rpc_pipe_client *result;
3812 struct cli_pipe_auth_data *auth;
3815 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3816 if (!NT_STATUS_IS_OK(status)) {
3820 status = rpccli_anon_bind_data(result, &auth);
3821 if (!NT_STATUS_IS_OK(status)) {
3822 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3823 nt_errstr(status)));
3824 TALLOC_FREE(result);
3829 * This is a bit of an abstraction violation due to the fact that an
3830 * anonymous bind on an authenticated SMB inherits the user/domain
3831 * from the enclosing SMB creds
3834 TALLOC_FREE(auth->user_name);
3835 TALLOC_FREE(auth->domain);
3837 auth->user_name = talloc_strdup(auth, cli->user_name);
3838 auth->domain = talloc_strdup(auth, cli->domain);
3839 auth->user_session_key = data_blob_talloc(auth,
3840 cli->user_session_key.data,
3841 cli->user_session_key.length);
3843 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3844 TALLOC_FREE(result);
3845 return NT_STATUS_NO_MEMORY;
3848 status = rpc_pipe_bind(result, auth);
3849 if (!NT_STATUS_IS_OK(status)) {
3851 if (ndr_syntax_id_equal(interface,
3852 &ndr_table_dssetup.syntax_id)) {
3853 /* non AD domains just don't have this pipe, avoid
3854 * level 0 statement in that case - gd */
3857 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3858 "%s failed with error %s\n",
3859 get_pipe_name_from_syntax(talloc_tos(), interface),
3860 nt_errstr(status) ));
3861 TALLOC_FREE(result);
3865 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3866 "%s and bound anonymously.\n",
3867 get_pipe_name_from_syntax(talloc_tos(), interface),
3871 return NT_STATUS_OK;
3874 /****************************************************************************
3875 ****************************************************************************/
3877 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3878 const struct ndr_syntax_id *interface,
3879 struct rpc_pipe_client **presult)
3881 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3882 interface, presult);
3885 /****************************************************************************
3886 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3887 ****************************************************************************/
3889 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3890 const struct ndr_syntax_id *interface,
3891 enum dcerpc_transport_t transport,
3892 enum pipe_auth_type auth_type,
3893 enum dcerpc_AuthLevel auth_level,
3895 const char *username,
3896 const char *password,
3897 struct rpc_pipe_client **presult)
3899 struct rpc_pipe_client *result;
3900 struct cli_pipe_auth_data *auth;
3903 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3904 if (!NT_STATUS_IS_OK(status)) {
3908 status = rpccli_ntlmssp_bind_data(
3909 result, auth_type, auth_level, domain, username,
3911 if (!NT_STATUS_IS_OK(status)) {
3912 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3913 nt_errstr(status)));
3917 status = rpc_pipe_bind(result, auth);
3918 if (!NT_STATUS_IS_OK(status)) {
3919 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3920 nt_errstr(status) ));
3924 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3925 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3926 get_pipe_name_from_syntax(talloc_tos(), interface),
3927 cli->desthost, domain, username ));
3930 return NT_STATUS_OK;
3934 TALLOC_FREE(result);
3938 /****************************************************************************
3940 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3941 ****************************************************************************/
3943 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3944 const struct ndr_syntax_id *interface,
3945 enum dcerpc_transport_t transport,
3946 enum dcerpc_AuthLevel auth_level,
3948 const char *username,
3949 const char *password,
3950 struct rpc_pipe_client **presult)
3952 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3955 PIPE_AUTH_TYPE_NTLMSSP,
3963 /****************************************************************************
3965 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3966 ****************************************************************************/
3968 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3969 const struct ndr_syntax_id *interface,
3970 enum dcerpc_transport_t transport,
3971 enum dcerpc_AuthLevel auth_level,
3973 const char *username,
3974 const char *password,
3975 struct rpc_pipe_client **presult)
3977 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3980 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3988 /****************************************************************************
3989 Get a the schannel session key out of an already opened netlogon pipe.
3990 ****************************************************************************/
3991 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3992 struct cli_state *cli,
3996 enum netr_SchannelType sec_chan_type = 0;
3997 unsigned char machine_pwd[16];
3998 const char *machine_account;
4001 /* Get the machine account credentials from secrets.tdb. */
4002 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4005 DEBUG(0, ("get_schannel_session_key: could not fetch "
4006 "trust account password for domain '%s'\n",
4008 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4011 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4012 cli->desthost, /* server name */
4013 domain, /* domain */
4014 global_myname(), /* client name */
4015 machine_account, /* machine account name */
4020 if (!NT_STATUS_IS_OK(status)) {
4021 DEBUG(3, ("get_schannel_session_key_common: "
4022 "rpccli_netlogon_setup_creds failed with result %s "
4023 "to server %s, domain %s, machine account %s.\n",
4024 nt_errstr(status), cli->desthost, domain,
4029 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4030 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4032 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4035 return NT_STATUS_OK;;
4038 /****************************************************************************
4039 Open a netlogon pipe and get the schannel session key.
4040 Now exposed to external callers.
4041 ****************************************************************************/
4044 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4047 struct rpc_pipe_client **presult)
4049 struct rpc_pipe_client *netlogon_pipe = NULL;
4052 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4054 if (!NT_STATUS_IS_OK(status)) {
4058 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4060 if (!NT_STATUS_IS_OK(status)) {
4061 TALLOC_FREE(netlogon_pipe);
4065 *presult = netlogon_pipe;
4066 return NT_STATUS_OK;
4069 /****************************************************************************
4071 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4072 using session_key. sign and seal.
4074 The *pdc will be stolen onto this new pipe
4075 ****************************************************************************/
4077 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4078 const struct ndr_syntax_id *interface,
4079 enum dcerpc_transport_t transport,
4080 enum dcerpc_AuthLevel auth_level,
4082 struct netlogon_creds_CredentialState **pdc,
4083 struct rpc_pipe_client **presult)
4085 struct rpc_pipe_client *result;
4086 struct cli_pipe_auth_data *auth;
4089 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4090 if (!NT_STATUS_IS_OK(status)) {
4094 status = rpccli_schannel_bind_data(result, domain, auth_level,
4096 if (!NT_STATUS_IS_OK(status)) {
4097 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4098 nt_errstr(status)));
4099 TALLOC_FREE(result);
4103 status = rpc_pipe_bind(result, auth);
4104 if (!NT_STATUS_IS_OK(status)) {
4105 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4106 "cli_rpc_pipe_bind failed with error %s\n",
4107 nt_errstr(status) ));
4108 TALLOC_FREE(result);
4113 * The credentials on a new netlogon pipe are the ones we are passed
4114 * in - reference them in
4116 result->dc = talloc_move(result, pdc);
4118 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4119 "for domain %s and bound using schannel.\n",
4120 get_pipe_name_from_syntax(talloc_tos(), interface),
4121 cli->desthost, domain ));
4124 return NT_STATUS_OK;
4127 /****************************************************************************
4128 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4129 Fetch the session key ourselves using a temporary netlogon pipe. This
4130 version uses an ntlmssp auth bound netlogon pipe to get the key.
4131 ****************************************************************************/
4133 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4135 const char *username,
4136 const char *password,
4138 struct rpc_pipe_client **presult)
4140 struct rpc_pipe_client *netlogon_pipe = NULL;
4143 status = cli_rpc_pipe_open_spnego_ntlmssp(
4144 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4145 DCERPC_AUTH_LEVEL_PRIVACY,
4146 domain, username, password, &netlogon_pipe);
4147 if (!NT_STATUS_IS_OK(status)) {
4151 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4153 if (!NT_STATUS_IS_OK(status)) {
4154 TALLOC_FREE(netlogon_pipe);
4158 *presult = netlogon_pipe;
4159 return NT_STATUS_OK;
4162 /****************************************************************************
4163 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4164 Fetch the session key ourselves using a temporary netlogon pipe. This version
4165 uses an ntlmssp bind to get the session key.
4166 ****************************************************************************/
4168 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4169 const struct ndr_syntax_id *interface,
4170 enum dcerpc_transport_t transport,
4171 enum dcerpc_AuthLevel auth_level,
4173 const char *username,
4174 const char *password,
4175 struct rpc_pipe_client **presult)
4177 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4178 struct rpc_pipe_client *netlogon_pipe = NULL;
4179 struct rpc_pipe_client *result = NULL;
4182 status = get_schannel_session_key_auth_ntlmssp(
4183 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4184 if (!NT_STATUS_IS_OK(status)) {
4185 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4186 "key from server %s for domain %s.\n",
4187 cli->desthost, domain ));
4191 status = cli_rpc_pipe_open_schannel_with_key(
4192 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4195 /* Now we've bound using the session key we can close the netlog pipe. */
4196 TALLOC_FREE(netlogon_pipe);
4198 if (NT_STATUS_IS_OK(status)) {
4204 /****************************************************************************
4205 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4206 Fetch the session key ourselves using a temporary netlogon pipe.
4207 ****************************************************************************/
4209 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4210 const struct ndr_syntax_id *interface,
4211 enum dcerpc_transport_t transport,
4212 enum dcerpc_AuthLevel auth_level,
4214 struct rpc_pipe_client **presult)
4216 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4217 struct rpc_pipe_client *netlogon_pipe = NULL;
4218 struct rpc_pipe_client *result = NULL;
4221 status = get_schannel_session_key(cli, domain, &neg_flags,
4223 if (!NT_STATUS_IS_OK(status)) {
4224 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4225 "key from server %s for domain %s.\n",
4226 cli->desthost, domain ));
4230 status = cli_rpc_pipe_open_schannel_with_key(
4231 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4234 /* Now we've bound using the session key we can close the netlog pipe. */
4235 TALLOC_FREE(netlogon_pipe);
4237 if (NT_STATUS_IS_OK(status)) {
4244 /****************************************************************************
4245 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4246 The idea is this can be called with service_princ, username and password all
4247 NULL so long as the caller has a TGT.
4248 ****************************************************************************/
4250 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4251 const struct ndr_syntax_id *interface,
4252 enum dcerpc_AuthLevel auth_level,
4253 const char *service_princ,
4254 const char *username,
4255 const char *password,
4256 struct rpc_pipe_client **presult)
4259 struct rpc_pipe_client *result;
4260 struct cli_pipe_auth_data *auth;
4263 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4264 if (!NT_STATUS_IS_OK(status)) {
4268 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4269 username, password, &auth);
4270 if (!NT_STATUS_IS_OK(status)) {
4271 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4272 nt_errstr(status)));
4273 TALLOC_FREE(result);
4277 status = rpc_pipe_bind(result, auth);
4278 if (!NT_STATUS_IS_OK(status)) {
4279 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4280 "with error %s\n", nt_errstr(status)));
4281 TALLOC_FREE(result);
4286 return NT_STATUS_OK;
4288 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4289 return NT_STATUS_NOT_IMPLEMENTED;
4293 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4294 struct rpc_pipe_client *cli,
4295 DATA_BLOB *session_key)
4297 if (!session_key || !cli) {
4298 return NT_STATUS_INVALID_PARAMETER;
4302 return NT_STATUS_INVALID_PARAMETER;
4305 switch (cli->auth->auth_type) {
4306 case PIPE_AUTH_TYPE_SCHANNEL:
4307 *session_key = data_blob_talloc(mem_ctx,
4308 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4310 case PIPE_AUTH_TYPE_NTLMSSP:
4311 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4312 *session_key = data_blob_talloc(mem_ctx,
4313 cli->auth->a_u.ntlmssp_state->session_key.data,
4314 cli->auth->a_u.ntlmssp_state->session_key.length);
4316 case PIPE_AUTH_TYPE_KRB5:
4317 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4318 *session_key = data_blob_talloc(mem_ctx,
4319 cli->auth->a_u.kerberos_auth->session_key.data,
4320 cli->auth->a_u.kerberos_auth->session_key.length);
4322 case PIPE_AUTH_TYPE_NONE:
4323 *session_key = data_blob_talloc(mem_ctx,
4324 cli->auth->user_session_key.data,
4325 cli->auth->user_session_key.length);
4328 return NT_STATUS_NO_USER_SESSION_KEY;
4331 return NT_STATUS_OK;