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 ********************************************************************/
1851 static NTSTATUS init_dcerpc_ctx_list(TALLOC_CTX *mem_ctx,
1852 const struct ndr_syntax_id *abstract_syntax,
1853 const struct ndr_syntax_id *transfer_syntax,
1854 struct dcerpc_ctx_list **ctx_list_p)
1856 struct dcerpc_ctx_list *ctx_list;
1858 ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
1859 NT_STATUS_HAVE_NO_MEMORY(ctx_list);
1861 ctx_list[0].context_id = 0;
1862 ctx_list[0].num_transfer_syntaxes = 1;
1863 ctx_list[0].abstract_syntax = *abstract_syntax;
1864 ctx_list[0].transfer_syntaxes = talloc_array(ctx_list,
1865 struct ndr_syntax_id,
1866 ctx_list[0].num_transfer_syntaxes);
1867 NT_STATUS_HAVE_NO_MEMORY(ctx_list[0].transfer_syntaxes);
1868 ctx_list[0].transfer_syntaxes[0] = *transfer_syntax;
1870 *ctx_list_p = ctx_list;
1872 return NT_STATUS_OK;
1875 /*******************************************************************
1876 Creates the internals of a DCE/RPC bind request or alter context PDU.
1877 ********************************************************************/
1879 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type ptype,
1880 prs_struct *rpc_out,
1882 const struct ndr_syntax_id *abstract,
1883 const struct ndr_syntax_id *transfer,
1884 RPC_HDR_AUTH *phdr_auth,
1885 prs_struct *pauth_info)
1887 uint16 auth_len = prs_offset(pauth_info);
1888 uint8 ss_padding_len = 0;
1889 uint16 frag_len = 0;
1891 union dcerpc_payload u;
1893 struct dcerpc_ctx_list *ctx_list;
1895 status = init_dcerpc_ctx_list(rpc_out->mem_ctx, abstract, transfer,
1897 if (!NT_STATUS_IS_OK(status)) {
1901 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1902 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1903 u.bind.assoc_group_id = 0x0;
1904 u.bind.num_contexts = 1;
1905 u.bind.ctx_list = ctx_list;
1906 u.bind.auth_info = data_blob_null;
1908 /* Start building the frag length. */
1909 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
1911 /* Do we need to pad ? */
1913 uint16_t data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&u.bind);
1914 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1915 ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1916 phdr_auth->auth_pad_len = ss_padding_len;
1918 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1921 status = dcerpc_push_ncacn_packet(rpc_out->mem_ctx,
1923 DCERPC_PFC_FLAG_FIRST |
1924 DCERPC_PFC_FLAG_LAST,
1930 if (!NT_STATUS_IS_OK(status)) {
1931 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1935 if (!prs_copy_data_in(rpc_out, (char *)blob.data, blob.length)) {
1936 return NT_STATUS_NO_MEMORY;
1940 * Grow the outgoing buffer to store any auth info.
1944 if (ss_padding_len) {
1945 char pad[CLIENT_NDR_PADDING_SIZE];
1946 memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1947 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1948 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1949 return NT_STATUS_NO_MEMORY;
1953 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1954 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1955 return NT_STATUS_NO_MEMORY;
1959 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1960 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1961 return NT_STATUS_NO_MEMORY;
1965 return NT_STATUS_OK;
1968 /*******************************************************************
1969 Creates a DCE/RPC bind request.
1970 ********************************************************************/
1972 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1973 prs_struct *rpc_out,
1975 const struct ndr_syntax_id *abstract,
1976 const struct ndr_syntax_id *transfer,
1977 enum pipe_auth_type auth_type,
1978 enum dcerpc_AuthLevel auth_level)
1980 RPC_HDR_AUTH hdr_auth;
1981 prs_struct auth_info;
1982 NTSTATUS ret = NT_STATUS_OK;
1984 ZERO_STRUCT(hdr_auth);
1985 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1986 return NT_STATUS_NO_MEMORY;
1988 switch (auth_type) {
1989 case PIPE_AUTH_TYPE_SCHANNEL:
1990 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1991 if (!NT_STATUS_IS_OK(ret)) {
1996 case PIPE_AUTH_TYPE_NTLMSSP:
1997 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1998 if (!NT_STATUS_IS_OK(ret)) {
2003 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2004 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2005 if (!NT_STATUS_IS_OK(ret)) {
2010 case PIPE_AUTH_TYPE_KRB5:
2011 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
2012 if (!NT_STATUS_IS_OK(ret)) {
2017 case PIPE_AUTH_TYPE_NONE:
2021 /* "Can't" happen. */
2022 return NT_STATUS_INVALID_INFO_CLASS;
2025 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
2036 /*******************************************************************
2037 Create and add the NTLMSSP sign/seal auth header and data.
2038 ********************************************************************/
2040 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
2042 uint32 ss_padding_len,
2043 prs_struct *outgoing_pdu)
2045 RPC_HDR_AUTH auth_info;
2047 DATA_BLOB auth_blob = data_blob_null;
2048 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2051 if (!cli->auth->a_u.ntlmssp_state) {
2052 return NT_STATUS_INVALID_PARAMETER;
2055 frame = talloc_stackframe();
2057 /* Init and marshall the auth header. */
2058 init_rpc_hdr_auth(&auth_info,
2059 map_pipe_auth_type_to_rpc_auth_type(
2060 cli->auth->auth_type),
2061 cli->auth->auth_level,
2063 1 /* context id. */);
2065 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2066 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2068 return NT_STATUS_NO_MEMORY;
2071 switch (cli->auth->auth_level) {
2072 case DCERPC_AUTH_LEVEL_PRIVACY:
2073 /* Data portion is encrypted. */
2074 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2076 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2078 (unsigned char *)prs_data_p(outgoing_pdu),
2079 (size_t)prs_offset(outgoing_pdu),
2081 if (!NT_STATUS_IS_OK(status)) {
2087 case DCERPC_AUTH_LEVEL_INTEGRITY:
2088 /* Data is signed. */
2089 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2091 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2093 (unsigned char *)prs_data_p(outgoing_pdu),
2094 (size_t)prs_offset(outgoing_pdu),
2096 if (!NT_STATUS_IS_OK(status)) {
2104 smb_panic("bad auth level");
2106 return NT_STATUS_INVALID_PARAMETER;
2109 /* Finally marshall the blob. */
2111 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2112 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2113 (unsigned int)NTLMSSP_SIG_SIZE));
2115 return NT_STATUS_NO_MEMORY;
2119 return NT_STATUS_OK;
2122 /*******************************************************************
2123 Create and add the schannel sign/seal auth header and data.
2124 ********************************************************************/
2126 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2128 uint32 ss_padding_len,
2129 prs_struct *outgoing_pdu)
2131 RPC_HDR_AUTH auth_info;
2132 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2133 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2134 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2139 return NT_STATUS_INVALID_PARAMETER;
2142 /* Init and marshall the auth header. */
2143 init_rpc_hdr_auth(&auth_info,
2144 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2145 cli->auth->auth_level,
2147 1 /* context id. */);
2149 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2150 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2151 return NT_STATUS_NO_MEMORY;
2154 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2157 switch (cli->auth->auth_level) {
2158 case DCERPC_AUTH_LEVEL_PRIVACY:
2159 status = netsec_outgoing_packet(sas,
2166 case DCERPC_AUTH_LEVEL_INTEGRITY:
2167 status = netsec_outgoing_packet(sas,
2175 status = NT_STATUS_INTERNAL_ERROR;
2179 if (!NT_STATUS_IS_OK(status)) {
2180 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2181 nt_errstr(status)));
2185 if (DEBUGLEVEL >= 10) {
2186 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2189 /* Finally marshall the blob. */
2190 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2191 return NT_STATUS_NO_MEMORY;
2194 return NT_STATUS_OK;
2197 /*******************************************************************
2198 Calculate how much data we're going to send in this packet, also
2199 work out any sign/seal padding length.
2200 ********************************************************************/
2202 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2206 uint32 *p_ss_padding)
2208 uint32 data_space, data_len;
2211 if ((data_left > 0) && (sys_random() % 2)) {
2212 data_left = MAX(data_left/2, 1);
2216 switch (cli->auth->auth_level) {
2217 case DCERPC_AUTH_LEVEL_NONE:
2218 case DCERPC_AUTH_LEVEL_CONNECT:
2219 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2220 data_len = MIN(data_space, data_left);
2223 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2226 case DCERPC_AUTH_LEVEL_INTEGRITY:
2227 case DCERPC_AUTH_LEVEL_PRIVACY:
2228 /* Treat the same for all authenticated rpc requests. */
2229 switch(cli->auth->auth_type) {
2230 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2231 case PIPE_AUTH_TYPE_NTLMSSP:
2232 *p_auth_len = NTLMSSP_SIG_SIZE;
2234 case PIPE_AUTH_TYPE_SCHANNEL:
2235 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2238 smb_panic("bad auth type");
2242 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2243 RPC_HDR_AUTH_LEN - *p_auth_len;
2245 data_len = MIN(data_space, data_left);
2247 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2248 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2250 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2251 data_len + *p_ss_padding + /* data plus padding. */
2252 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2256 smb_panic("bad auth level");
2262 /*******************************************************************
2264 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2265 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2266 and deals with signing/sealing details.
2267 ********************************************************************/
2269 struct rpc_api_pipe_req_state {
2270 struct event_context *ev;
2271 struct rpc_pipe_client *cli;
2274 prs_struct *req_data;
2275 uint32_t req_data_sent;
2276 prs_struct outgoing_frag;
2277 prs_struct reply_pdu;
2280 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2281 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2282 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2283 bool *is_last_frag);
2285 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2286 struct event_context *ev,
2287 struct rpc_pipe_client *cli,
2289 prs_struct *req_data)
2291 struct tevent_req *req, *subreq;
2292 struct rpc_api_pipe_req_state *state;
2296 req = tevent_req_create(mem_ctx, &state,
2297 struct rpc_api_pipe_req_state);
2303 state->op_num = op_num;
2304 state->req_data = req_data;
2305 state->req_data_sent = 0;
2306 state->call_id = get_rpc_call_id();
2308 if (cli->max_xmit_frag
2309 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2310 /* Server is screwed up ! */
2311 status = NT_STATUS_INVALID_PARAMETER;
2315 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2317 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2322 status = prepare_next_frag(state, &is_last_frag);
2323 if (!NT_STATUS_IS_OK(status)) {
2328 subreq = rpc_api_pipe_send(state, ev, state->cli,
2329 &state->outgoing_frag,
2330 DCERPC_PKT_RESPONSE);
2331 if (subreq == NULL) {
2334 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2336 subreq = rpc_write_send(
2337 state, ev, cli->transport,
2338 (uint8_t *)prs_data_p(&state->outgoing_frag),
2339 prs_offset(&state->outgoing_frag));
2340 if (subreq == NULL) {
2343 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2349 tevent_req_nterror(req, status);
2350 return tevent_req_post(req, ev);
2356 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2360 RPC_HDR_REQ hdr_req;
2361 uint32_t data_sent_thistime;
2365 uint32_t ss_padding;
2367 char pad[8] = { 0, };
2370 data_left = prs_offset(state->req_data) - state->req_data_sent;
2372 data_sent_thistime = calculate_data_len_tosend(
2373 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2375 if (state->req_data_sent == 0) {
2376 flags = DCERPC_PFC_FLAG_FIRST;
2379 if (data_sent_thistime == data_left) {
2380 flags |= DCERPC_PFC_FLAG_LAST;
2383 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2384 return NT_STATUS_NO_MEMORY;
2387 /* Create and marshall the header and request header. */
2388 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2391 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2392 return NT_STATUS_NO_MEMORY;
2395 /* Create the rpc request RPC_HDR_REQ */
2396 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2399 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2400 &state->outgoing_frag, 0)) {
2401 return NT_STATUS_NO_MEMORY;
2404 /* Copy in the data, plus any ss padding. */
2405 if (!prs_append_some_prs_data(&state->outgoing_frag,
2406 state->req_data, state->req_data_sent,
2407 data_sent_thistime)) {
2408 return NT_STATUS_NO_MEMORY;
2411 /* Copy the sign/seal padding data. */
2412 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2413 return NT_STATUS_NO_MEMORY;
2416 /* Generate any auth sign/seal and add the auth footer. */
2417 switch (state->cli->auth->auth_type) {
2418 case PIPE_AUTH_TYPE_NONE:
2419 status = NT_STATUS_OK;
2421 case PIPE_AUTH_TYPE_NTLMSSP:
2422 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2423 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2424 &state->outgoing_frag);
2426 case PIPE_AUTH_TYPE_SCHANNEL:
2427 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2428 &state->outgoing_frag);
2431 status = NT_STATUS_INVALID_PARAMETER;
2435 state->req_data_sent += data_sent_thistime;
2436 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2441 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2443 struct tevent_req *req = tevent_req_callback_data(
2444 subreq, struct tevent_req);
2445 struct rpc_api_pipe_req_state *state = tevent_req_data(
2446 req, struct rpc_api_pipe_req_state);
2450 status = rpc_write_recv(subreq);
2451 TALLOC_FREE(subreq);
2452 if (!NT_STATUS_IS_OK(status)) {
2453 tevent_req_nterror(req, status);
2457 status = prepare_next_frag(state, &is_last_frag);
2458 if (!NT_STATUS_IS_OK(status)) {
2459 tevent_req_nterror(req, status);
2464 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2465 &state->outgoing_frag,
2466 DCERPC_PKT_RESPONSE);
2467 if (tevent_req_nomem(subreq, req)) {
2470 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2472 subreq = rpc_write_send(
2474 state->cli->transport,
2475 (uint8_t *)prs_data_p(&state->outgoing_frag),
2476 prs_offset(&state->outgoing_frag));
2477 if (tevent_req_nomem(subreq, req)) {
2480 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2485 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2487 struct tevent_req *req = tevent_req_callback_data(
2488 subreq, struct tevent_req);
2489 struct rpc_api_pipe_req_state *state = tevent_req_data(
2490 req, struct rpc_api_pipe_req_state);
2493 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2494 TALLOC_FREE(subreq);
2495 if (!NT_STATUS_IS_OK(status)) {
2496 tevent_req_nterror(req, status);
2499 tevent_req_done(req);
2502 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2503 prs_struct *reply_pdu)
2505 struct rpc_api_pipe_req_state *state = tevent_req_data(
2506 req, struct rpc_api_pipe_req_state);
2509 if (tevent_req_is_nterror(req, &status)) {
2511 * We always have to initialize to reply pdu, even if there is
2512 * none. The rpccli_* caller routines expect this.
2514 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2518 *reply_pdu = state->reply_pdu;
2519 reply_pdu->mem_ctx = mem_ctx;
2522 * Prevent state->req_pdu from being freed
2523 * when state is freed.
2525 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2526 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2528 return NT_STATUS_OK;
2532 /****************************************************************************
2533 Set the handle state.
2534 ****************************************************************************/
2536 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2537 const char *pipe_name, uint16 device_state)
2539 bool state_set = False;
2541 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2542 char *rparam = NULL;
2544 uint32 rparam_len, rdata_len;
2546 if (pipe_name == NULL)
2549 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2550 cli->fnum, pipe_name, device_state));
2552 /* create parameters: device state */
2553 SSVAL(param, 0, device_state);
2555 /* create setup parameters. */
2557 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2559 /* send the data on \PIPE\ */
2560 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2561 setup, 2, 0, /* setup, length, max */
2562 param, 2, 0, /* param, length, max */
2563 NULL, 0, 1024, /* data, length, max */
2564 &rparam, &rparam_len, /* return param, length */
2565 &rdata, &rdata_len)) /* return data, length */
2567 DEBUG(5, ("Set Handle state: return OK\n"));
2578 /****************************************************************************
2579 Check the rpc bind acknowledge response.
2580 ****************************************************************************/
2582 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2583 const struct ndr_syntax_id *transfer)
2585 if ( hdr_ba->addr.len == 0) {
2586 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2589 /* check the transfer syntax */
2590 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2591 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2592 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2596 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2597 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2598 hdr_ba->res.num_results, hdr_ba->res.reason));
2601 DEBUG(5,("check_bind_response: accepted!\n"));
2605 /*******************************************************************
2606 Creates a DCE/RPC bind authentication response.
2607 This is the packet that is sent back to the server once we
2608 have received a BIND-ACK, to finish the third leg of
2609 the authentication handshake.
2610 ********************************************************************/
2612 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2614 enum pipe_auth_type auth_type,
2615 enum dcerpc_AuthLevel auth_level,
2616 DATA_BLOB *pauth_blob,
2617 prs_struct *rpc_out)
2620 RPC_HDR_AUTH hdr_auth;
2623 /* Create the request RPC_HDR */
2624 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2625 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2626 pauth_blob->length );
2629 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2630 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2631 return NT_STATUS_NO_MEMORY;
2635 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2636 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2639 /* 4 bytes padding. */
2640 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2641 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2642 return NT_STATUS_NO_MEMORY;
2645 /* Create the request RPC_HDR_AUTHA */
2646 init_rpc_hdr_auth(&hdr_auth,
2647 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2650 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2651 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2652 return NT_STATUS_NO_MEMORY;
2656 * Append the auth data to the outgoing buffer.
2659 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2660 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2661 return NT_STATUS_NO_MEMORY;
2664 return NT_STATUS_OK;
2667 /*******************************************************************
2668 Creates a DCE/RPC bind alter context authentication request which
2669 may contain a spnego auth blobl
2670 ********************************************************************/
2672 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2673 const struct ndr_syntax_id *abstract,
2674 const struct ndr_syntax_id *transfer,
2675 enum dcerpc_AuthLevel auth_level,
2676 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2677 prs_struct *rpc_out)
2679 RPC_HDR_AUTH hdr_auth;
2680 prs_struct auth_info;
2681 NTSTATUS ret = NT_STATUS_OK;
2683 ZERO_STRUCT(hdr_auth);
2684 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2685 return NT_STATUS_NO_MEMORY;
2687 /* We may change the pad length before marshalling. */
2688 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2690 if (pauth_blob->length) {
2691 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2692 return NT_STATUS_NO_MEMORY;
2696 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2706 /****************************************************************************
2708 ****************************************************************************/
2710 struct rpc_pipe_bind_state {
2711 struct event_context *ev;
2712 struct rpc_pipe_client *cli;
2714 uint32_t rpc_call_id;
2717 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2718 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2719 struct rpc_pipe_bind_state *state,
2720 struct rpc_hdr_info *phdr,
2721 prs_struct *reply_pdu);
2722 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2723 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2724 struct rpc_pipe_bind_state *state,
2725 struct rpc_hdr_info *phdr,
2726 prs_struct *reply_pdu);
2727 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2729 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2730 struct event_context *ev,
2731 struct rpc_pipe_client *cli,
2732 struct cli_pipe_auth_data *auth)
2734 struct tevent_req *req, *subreq;
2735 struct rpc_pipe_bind_state *state;
2738 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2743 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2744 rpccli_pipe_txt(talloc_tos(), cli),
2745 (unsigned int)auth->auth_type,
2746 (unsigned int)auth->auth_level ));
2750 state->rpc_call_id = get_rpc_call_id();
2752 prs_init_empty(&state->rpc_out, state, MARSHALL);
2754 cli->auth = talloc_move(cli, &auth);
2756 /* Marshall the outgoing data. */
2757 status = create_rpc_bind_req(cli, &state->rpc_out,
2759 &cli->abstract_syntax,
2760 &cli->transfer_syntax,
2761 cli->auth->auth_type,
2762 cli->auth->auth_level);
2764 if (!NT_STATUS_IS_OK(status)) {
2768 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2769 DCERPC_PKT_BIND_ACK);
2770 if (subreq == NULL) {
2773 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2777 tevent_req_nterror(req, status);
2778 return tevent_req_post(req, ev);
2784 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2786 struct tevent_req *req = tevent_req_callback_data(
2787 subreq, struct tevent_req);
2788 struct rpc_pipe_bind_state *state = tevent_req_data(
2789 req, struct rpc_pipe_bind_state);
2790 prs_struct reply_pdu;
2791 struct rpc_hdr_info hdr;
2792 struct rpc_hdr_ba_info hdr_ba;
2795 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2796 TALLOC_FREE(subreq);
2797 if (!NT_STATUS_IS_OK(status)) {
2798 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2799 rpccli_pipe_txt(talloc_tos(), state->cli),
2800 nt_errstr(status)));
2801 tevent_req_nterror(req, status);
2805 /* Unmarshall the RPC header */
2806 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2807 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2808 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2812 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2813 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2815 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2819 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2820 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2821 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2825 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2826 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2829 * For authenticated binds we may need to do 3 or 4 leg binds.
2832 switch(state->cli->auth->auth_type) {
2834 case PIPE_AUTH_TYPE_NONE:
2835 case PIPE_AUTH_TYPE_SCHANNEL:
2836 /* Bind complete. */
2837 tevent_req_done(req);
2840 case PIPE_AUTH_TYPE_NTLMSSP:
2841 /* Need to send AUTH3 packet - no reply. */
2842 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2844 if (!NT_STATUS_IS_OK(status)) {
2845 tevent_req_nterror(req, status);
2849 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2850 /* Need to send alter context request and reply. */
2851 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2853 if (!NT_STATUS_IS_OK(status)) {
2854 tevent_req_nterror(req, status);
2858 case PIPE_AUTH_TYPE_KRB5:
2862 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2863 (unsigned int)state->cli->auth->auth_type));
2864 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2868 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2869 struct rpc_pipe_bind_state *state,
2870 struct rpc_hdr_info *phdr,
2871 prs_struct *reply_pdu)
2873 DATA_BLOB server_response = data_blob_null;
2874 DATA_BLOB client_reply = data_blob_null;
2875 struct rpc_hdr_auth_info hdr_auth;
2876 struct tevent_req *subreq;
2879 if ((phdr->auth_len == 0)
2880 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2881 return NT_STATUS_INVALID_PARAMETER;
2884 if (!prs_set_offset(
2886 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2887 return NT_STATUS_INVALID_PARAMETER;
2890 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2891 return NT_STATUS_INVALID_PARAMETER;
2894 /* TODO - check auth_type/auth_level match. */
2896 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2897 prs_copy_data_out((char *)server_response.data, reply_pdu,
2900 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2901 server_response, &client_reply);
2903 if (!NT_STATUS_IS_OK(status)) {
2904 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2905 "blob failed: %s.\n", nt_errstr(status)));
2909 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2911 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2912 state->cli->auth->auth_type,
2913 state->cli->auth->auth_level,
2914 &client_reply, &state->rpc_out);
2915 data_blob_free(&client_reply);
2917 if (!NT_STATUS_IS_OK(status)) {
2921 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2922 (uint8_t *)prs_data_p(&state->rpc_out),
2923 prs_offset(&state->rpc_out));
2924 if (subreq == NULL) {
2925 return NT_STATUS_NO_MEMORY;
2927 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2928 return NT_STATUS_OK;
2931 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2933 struct tevent_req *req = tevent_req_callback_data(
2934 subreq, struct tevent_req);
2937 status = rpc_write_recv(subreq);
2938 TALLOC_FREE(subreq);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 tevent_req_nterror(req, status);
2943 tevent_req_done(req);
2946 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2947 struct rpc_pipe_bind_state *state,
2948 struct rpc_hdr_info *phdr,
2949 prs_struct *reply_pdu)
2951 DATA_BLOB server_spnego_response = data_blob_null;
2952 DATA_BLOB server_ntlm_response = data_blob_null;
2953 DATA_BLOB client_reply = data_blob_null;
2954 DATA_BLOB tmp_blob = data_blob_null;
2955 RPC_HDR_AUTH hdr_auth;
2956 struct tevent_req *subreq;
2959 if ((phdr->auth_len == 0)
2960 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2961 return NT_STATUS_INVALID_PARAMETER;
2964 /* Process the returned NTLMSSP blob first. */
2965 if (!prs_set_offset(
2967 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2968 return NT_STATUS_INVALID_PARAMETER;
2971 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2972 return NT_STATUS_INVALID_PARAMETER;
2975 server_spnego_response = data_blob(NULL, phdr->auth_len);
2976 prs_copy_data_out((char *)server_spnego_response.data,
2977 reply_pdu, phdr->auth_len);
2980 * The server might give us back two challenges - tmp_blob is for the
2983 if (!spnego_parse_challenge(server_spnego_response,
2984 &server_ntlm_response, &tmp_blob)) {
2985 data_blob_free(&server_spnego_response);
2986 data_blob_free(&server_ntlm_response);
2987 data_blob_free(&tmp_blob);
2988 return NT_STATUS_INVALID_PARAMETER;
2991 /* We're finished with the server spnego response and the tmp_blob. */
2992 data_blob_free(&server_spnego_response);
2993 data_blob_free(&tmp_blob);
2995 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2996 server_ntlm_response, &client_reply);
2998 /* Finished with the server_ntlm response */
2999 data_blob_free(&server_ntlm_response);
3001 if (!NT_STATUS_IS_OK(status)) {
3002 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
3003 "using server blob failed.\n"));
3004 data_blob_free(&client_reply);
3008 /* SPNEGO wrap the client reply. */
3009 tmp_blob = spnego_gen_auth(client_reply);
3010 data_blob_free(&client_reply);
3011 client_reply = tmp_blob;
3012 tmp_blob = data_blob_null;
3014 /* Now prepare the alter context pdu. */
3015 prs_init_empty(&state->rpc_out, state, MARSHALL);
3017 status = create_rpc_alter_context(state->rpc_call_id,
3018 &state->cli->abstract_syntax,
3019 &state->cli->transfer_syntax,
3020 state->cli->auth->auth_level,
3023 data_blob_free(&client_reply);
3025 if (!NT_STATUS_IS_OK(status)) {
3029 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
3030 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
3031 if (subreq == NULL) {
3032 return NT_STATUS_NO_MEMORY;
3034 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
3035 return NT_STATUS_OK;
3038 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
3040 struct tevent_req *req = tevent_req_callback_data(
3041 subreq, struct tevent_req);
3042 struct rpc_pipe_bind_state *state = tevent_req_data(
3043 req, struct rpc_pipe_bind_state);
3044 DATA_BLOB server_spnego_response = data_blob_null;
3045 DATA_BLOB tmp_blob = data_blob_null;
3046 prs_struct reply_pdu;
3047 struct rpc_hdr_info hdr;
3048 struct rpc_hdr_auth_info hdr_auth;
3051 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3052 TALLOC_FREE(subreq);
3053 if (!NT_STATUS_IS_OK(status)) {
3054 tevent_req_nterror(req, status);
3058 /* Get the auth blob from the reply. */
3059 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3060 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3061 "unmarshall RPC_HDR.\n"));
3062 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3066 if (!prs_set_offset(
3068 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3069 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3073 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3074 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3078 server_spnego_response = data_blob(NULL, hdr.auth_len);
3079 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3082 /* Check we got a valid auth response. */
3083 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3084 OID_NTLMSSP, &tmp_blob)) {
3085 data_blob_free(&server_spnego_response);
3086 data_blob_free(&tmp_blob);
3087 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3091 data_blob_free(&server_spnego_response);
3092 data_blob_free(&tmp_blob);
3094 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3095 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3096 tevent_req_done(req);
3099 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3101 return tevent_req_simple_recv_ntstatus(req);
3104 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3105 struct cli_pipe_auth_data *auth)
3107 TALLOC_CTX *frame = talloc_stackframe();
3108 struct event_context *ev;
3109 struct tevent_req *req;
3110 NTSTATUS status = NT_STATUS_OK;
3112 ev = event_context_init(frame);
3114 status = NT_STATUS_NO_MEMORY;
3118 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3120 status = NT_STATUS_NO_MEMORY;
3124 if (!tevent_req_poll(req, ev)) {
3125 status = map_nt_error_from_unix(errno);
3129 status = rpc_pipe_bind_recv(req);
3135 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3137 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3138 unsigned int timeout)
3142 if (rpc_cli->transport == NULL) {
3143 return RPCCLI_DEFAULT_TIMEOUT;
3146 if (rpc_cli->transport->set_timeout == NULL) {
3147 return RPCCLI_DEFAULT_TIMEOUT;
3150 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3152 return RPCCLI_DEFAULT_TIMEOUT;
3158 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3160 if (rpc_cli == NULL) {
3164 if (rpc_cli->transport == NULL) {
3168 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3171 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3173 struct cli_state *cli;
3175 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3176 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3177 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3181 cli = rpc_pipe_np_smb_conn(rpc_cli);
3185 E_md4hash(cli->password ? cli->password : "", nt_hash);
3189 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3190 struct cli_pipe_auth_data **presult)
3192 struct cli_pipe_auth_data *result;
3194 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3195 if (result == NULL) {
3196 return NT_STATUS_NO_MEMORY;
3199 result->auth_type = PIPE_AUTH_TYPE_NONE;
3200 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3202 result->user_name = talloc_strdup(result, "");
3203 result->domain = talloc_strdup(result, "");
3204 if ((result->user_name == NULL) || (result->domain == NULL)) {
3205 TALLOC_FREE(result);
3206 return NT_STATUS_NO_MEMORY;
3210 return NT_STATUS_OK;
3213 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3215 ntlmssp_end(&auth->a_u.ntlmssp_state);
3219 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3220 enum pipe_auth_type auth_type,
3221 enum dcerpc_AuthLevel auth_level,
3223 const char *username,
3224 const char *password,
3225 struct cli_pipe_auth_data **presult)
3227 struct cli_pipe_auth_data *result;
3230 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3231 if (result == NULL) {
3232 return NT_STATUS_NO_MEMORY;
3235 result->auth_type = auth_type;
3236 result->auth_level = auth_level;
3238 result->user_name = talloc_strdup(result, username);
3239 result->domain = talloc_strdup(result, domain);
3240 if ((result->user_name == NULL) || (result->domain == NULL)) {
3241 status = NT_STATUS_NO_MEMORY;
3245 status = ntlmssp_client_start(NULL,
3248 lp_client_ntlmv2_auth(),
3249 &result->a_u.ntlmssp_state);
3250 if (!NT_STATUS_IS_OK(status)) {
3254 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3256 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3257 if (!NT_STATUS_IS_OK(status)) {
3261 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3262 if (!NT_STATUS_IS_OK(status)) {
3266 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3267 if (!NT_STATUS_IS_OK(status)) {
3272 * Turn off sign+seal to allow selected auth level to turn it back on.
3274 result->a_u.ntlmssp_state->neg_flags &=
3275 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3277 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3278 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3279 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3280 result->a_u.ntlmssp_state->neg_flags
3281 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3285 return NT_STATUS_OK;
3288 TALLOC_FREE(result);
3292 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3293 enum dcerpc_AuthLevel auth_level,
3294 struct netlogon_creds_CredentialState *creds,
3295 struct cli_pipe_auth_data **presult)
3297 struct cli_pipe_auth_data *result;
3299 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3300 if (result == NULL) {
3301 return NT_STATUS_NO_MEMORY;
3304 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3305 result->auth_level = auth_level;
3307 result->user_name = talloc_strdup(result, "");
3308 result->domain = talloc_strdup(result, domain);
3309 if ((result->user_name == NULL) || (result->domain == NULL)) {
3313 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3314 if (result->a_u.schannel_auth == NULL) {
3318 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3319 result->a_u.schannel_auth->seq_num = 0;
3320 result->a_u.schannel_auth->initiator = true;
3321 result->a_u.schannel_auth->creds = creds;
3324 return NT_STATUS_OK;
3327 TALLOC_FREE(result);
3328 return NT_STATUS_NO_MEMORY;
3332 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3334 data_blob_free(&auth->session_key);
3339 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3340 enum dcerpc_AuthLevel auth_level,
3341 const char *service_princ,
3342 const char *username,
3343 const char *password,
3344 struct cli_pipe_auth_data **presult)
3347 struct cli_pipe_auth_data *result;
3349 if ((username != NULL) && (password != NULL)) {
3350 int ret = kerberos_kinit_password(username, password, 0, NULL);
3352 return NT_STATUS_ACCESS_DENIED;
3356 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3357 if (result == NULL) {
3358 return NT_STATUS_NO_MEMORY;
3361 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3362 result->auth_level = auth_level;
3365 * Username / domain need fixing!
3367 result->user_name = talloc_strdup(result, "");
3368 result->domain = talloc_strdup(result, "");
3369 if ((result->user_name == NULL) || (result->domain == NULL)) {
3373 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3374 result, struct kerberos_auth_struct);
3375 if (result->a_u.kerberos_auth == NULL) {
3378 talloc_set_destructor(result->a_u.kerberos_auth,
3379 cli_auth_kerberos_data_destructor);
3381 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3382 result, service_princ);
3383 if (result->a_u.kerberos_auth->service_principal == NULL) {
3388 return NT_STATUS_OK;
3391 TALLOC_FREE(result);
3392 return NT_STATUS_NO_MEMORY;
3394 return NT_STATUS_NOT_SUPPORTED;
3399 * Create an rpc pipe client struct, connecting to a tcp port.
3401 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3403 const struct ndr_syntax_id *abstract_syntax,
3404 struct rpc_pipe_client **presult)
3406 struct rpc_pipe_client *result;
3407 struct sockaddr_storage addr;
3411 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3412 if (result == NULL) {
3413 return NT_STATUS_NO_MEMORY;
3416 result->abstract_syntax = *abstract_syntax;
3417 result->transfer_syntax = ndr_transfer_syntax;
3418 result->dispatch = cli_do_rpc_ndr;
3419 result->dispatch_send = cli_do_rpc_ndr_send;
3420 result->dispatch_recv = cli_do_rpc_ndr_recv;
3422 result->desthost = talloc_strdup(result, host);
3423 result->srv_name_slash = talloc_asprintf_strupper_m(
3424 result, "\\\\%s", result->desthost);
3425 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3426 status = NT_STATUS_NO_MEMORY;
3430 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3431 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3433 if (!resolve_name(host, &addr, 0, false)) {
3434 status = NT_STATUS_NOT_FOUND;
3438 status = open_socket_out(&addr, port, 60, &fd);
3439 if (!NT_STATUS_IS_OK(status)) {
3442 set_socket_options(fd, lp_socket_options());
3444 status = rpc_transport_sock_init(result, fd, &result->transport);
3445 if (!NT_STATUS_IS_OK(status)) {
3450 result->transport->transport = NCACN_IP_TCP;
3453 return NT_STATUS_OK;
3456 TALLOC_FREE(result);
3461 * Determine the tcp port on which a dcerpc interface is listening
3462 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3465 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3466 const struct ndr_syntax_id *abstract_syntax,
3470 struct rpc_pipe_client *epm_pipe = NULL;
3471 struct cli_pipe_auth_data *auth = NULL;
3472 struct dcerpc_binding *map_binding = NULL;
3473 struct dcerpc_binding *res_binding = NULL;
3474 struct epm_twr_t *map_tower = NULL;
3475 struct epm_twr_t *res_towers = NULL;
3476 struct policy_handle *entry_handle = NULL;
3477 uint32_t num_towers = 0;
3478 uint32_t max_towers = 1;
3479 struct epm_twr_p_t towers;
3480 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3482 if (pport == NULL) {
3483 status = NT_STATUS_INVALID_PARAMETER;
3487 /* open the connection to the endpoint mapper */
3488 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3489 &ndr_table_epmapper.syntax_id,
3492 if (!NT_STATUS_IS_OK(status)) {
3496 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3497 if (!NT_STATUS_IS_OK(status)) {
3501 status = rpc_pipe_bind(epm_pipe, auth);
3502 if (!NT_STATUS_IS_OK(status)) {
3506 /* create tower for asking the epmapper */
3508 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3509 if (map_binding == NULL) {
3510 status = NT_STATUS_NO_MEMORY;
3514 map_binding->transport = NCACN_IP_TCP;
3515 map_binding->object = *abstract_syntax;
3516 map_binding->host = host; /* needed? */
3517 map_binding->endpoint = "0"; /* correct? needed? */
3519 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3520 if (map_tower == NULL) {
3521 status = NT_STATUS_NO_MEMORY;
3525 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3526 &(map_tower->tower));
3527 if (!NT_STATUS_IS_OK(status)) {
3531 /* allocate further parameters for the epm_Map call */
3533 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3534 if (res_towers == NULL) {
3535 status = NT_STATUS_NO_MEMORY;
3538 towers.twr = res_towers;
3540 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3541 if (entry_handle == NULL) {
3542 status = NT_STATUS_NO_MEMORY;
3546 /* ask the endpoint mapper for the port */
3548 status = rpccli_epm_Map(epm_pipe,
3550 CONST_DISCARD(struct GUID *,
3551 &(abstract_syntax->uuid)),
3558 if (!NT_STATUS_IS_OK(status)) {
3562 if (num_towers != 1) {
3563 status = NT_STATUS_UNSUCCESSFUL;
3567 /* extract the port from the answer */
3569 status = dcerpc_binding_from_tower(tmp_ctx,
3570 &(towers.twr->tower),
3572 if (!NT_STATUS_IS_OK(status)) {
3576 /* are further checks here necessary? */
3577 if (res_binding->transport != NCACN_IP_TCP) {
3578 status = NT_STATUS_UNSUCCESSFUL;
3582 *pport = (uint16_t)atoi(res_binding->endpoint);
3585 TALLOC_FREE(tmp_ctx);
3590 * Create a rpc pipe client struct, connecting to a host via tcp.
3591 * The port is determined by asking the endpoint mapper on the given
3594 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3595 const struct ndr_syntax_id *abstract_syntax,
3596 struct rpc_pipe_client **presult)
3601 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3602 if (!NT_STATUS_IS_OK(status)) {
3606 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3607 abstract_syntax, presult);
3610 /********************************************************************
3611 Create a rpc pipe client struct, connecting to a unix domain socket
3612 ********************************************************************/
3613 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3614 const struct ndr_syntax_id *abstract_syntax,
3615 struct rpc_pipe_client **presult)
3617 struct rpc_pipe_client *result;
3618 struct sockaddr_un addr;
3622 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3623 if (result == NULL) {
3624 return NT_STATUS_NO_MEMORY;
3627 result->abstract_syntax = *abstract_syntax;
3628 result->transfer_syntax = ndr_transfer_syntax;
3629 result->dispatch = cli_do_rpc_ndr;
3630 result->dispatch_send = cli_do_rpc_ndr_send;
3631 result->dispatch_recv = cli_do_rpc_ndr_recv;
3633 result->desthost = get_myname(result);
3634 result->srv_name_slash = talloc_asprintf_strupper_m(
3635 result, "\\\\%s", result->desthost);
3636 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3637 status = NT_STATUS_NO_MEMORY;
3641 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3642 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3644 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3646 status = map_nt_error_from_unix(errno);
3651 addr.sun_family = AF_UNIX;
3652 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3654 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3655 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3658 return map_nt_error_from_unix(errno);
3661 status = rpc_transport_sock_init(result, fd, &result->transport);
3662 if (!NT_STATUS_IS_OK(status)) {
3667 result->transport->transport = NCALRPC;
3670 return NT_STATUS_OK;
3673 TALLOC_FREE(result);
3677 struct rpc_pipe_client_np_ref {
3678 struct cli_state *cli;
3679 struct rpc_pipe_client *pipe;
3682 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3684 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3688 /****************************************************************************
3689 Open a named pipe over SMB to a remote server.
3691 * CAVEAT CALLER OF THIS FUNCTION:
3692 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3693 * so be sure that this function is called AFTER any structure (vs pointer)
3694 * assignment of the cli. In particular, libsmbclient does structure
3695 * assignments of cli, which invalidates the data in the returned
3696 * rpc_pipe_client if this function is called before the structure assignment
3699 ****************************************************************************/
3701 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3702 const struct ndr_syntax_id *abstract_syntax,
3703 struct rpc_pipe_client **presult)
3705 struct rpc_pipe_client *result;
3707 struct rpc_pipe_client_np_ref *np_ref;
3709 /* sanity check to protect against crashes */
3712 return NT_STATUS_INVALID_HANDLE;
3715 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3716 if (result == NULL) {
3717 return NT_STATUS_NO_MEMORY;
3720 result->abstract_syntax = *abstract_syntax;
3721 result->transfer_syntax = ndr_transfer_syntax;
3722 result->dispatch = cli_do_rpc_ndr;
3723 result->dispatch_send = cli_do_rpc_ndr_send;
3724 result->dispatch_recv = cli_do_rpc_ndr_recv;
3725 result->desthost = talloc_strdup(result, cli->desthost);
3726 result->srv_name_slash = talloc_asprintf_strupper_m(
3727 result, "\\\\%s", result->desthost);
3729 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3730 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3732 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3733 TALLOC_FREE(result);
3734 return NT_STATUS_NO_MEMORY;
3737 status = rpc_transport_np_init(result, cli, abstract_syntax,
3738 &result->transport);
3739 if (!NT_STATUS_IS_OK(status)) {
3740 TALLOC_FREE(result);
3744 result->transport->transport = NCACN_NP;
3746 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3747 if (np_ref == NULL) {
3748 TALLOC_FREE(result);
3749 return NT_STATUS_NO_MEMORY;
3752 np_ref->pipe = result;
3754 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3755 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3758 return NT_STATUS_OK;
3761 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3762 struct rpc_cli_smbd_conn *conn,
3763 const struct ndr_syntax_id *syntax,
3764 struct rpc_pipe_client **presult)
3766 struct rpc_pipe_client *result;
3767 struct cli_pipe_auth_data *auth;
3770 result = talloc(mem_ctx, struct rpc_pipe_client);
3771 if (result == NULL) {
3772 return NT_STATUS_NO_MEMORY;
3774 result->abstract_syntax = *syntax;
3775 result->transfer_syntax = ndr_transfer_syntax;
3776 result->dispatch = cli_do_rpc_ndr;
3777 result->dispatch_send = cli_do_rpc_ndr_send;
3778 result->dispatch_recv = cli_do_rpc_ndr_recv;
3779 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3780 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3782 result->desthost = talloc_strdup(result, global_myname());
3783 result->srv_name_slash = talloc_asprintf_strupper_m(
3784 result, "\\\\%s", global_myname());
3785 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3786 TALLOC_FREE(result);
3787 return NT_STATUS_NO_MEMORY;
3790 status = rpc_transport_smbd_init(result, conn, syntax,
3791 &result->transport);
3792 if (!NT_STATUS_IS_OK(status)) {
3793 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3794 nt_errstr(status)));
3795 TALLOC_FREE(result);
3799 status = rpccli_anon_bind_data(result, &auth);
3800 if (!NT_STATUS_IS_OK(status)) {
3801 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3802 nt_errstr(status)));
3803 TALLOC_FREE(result);
3807 status = rpc_pipe_bind(result, auth);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3810 TALLOC_FREE(result);
3814 result->transport->transport = NCACN_INTERNAL;
3817 return NT_STATUS_OK;
3820 /****************************************************************************
3821 Open a pipe to a remote server.
3822 ****************************************************************************/
3824 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3825 enum dcerpc_transport_t transport,
3826 const struct ndr_syntax_id *interface,
3827 struct rpc_pipe_client **presult)
3829 switch (transport) {
3831 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3834 return rpc_pipe_open_np(cli, interface, presult);
3836 return NT_STATUS_NOT_IMPLEMENTED;
3840 /****************************************************************************
3841 Open a named pipe to an SMB server and bind anonymously.
3842 ****************************************************************************/
3844 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3845 enum dcerpc_transport_t transport,
3846 const struct ndr_syntax_id *interface,
3847 struct rpc_pipe_client **presult)
3849 struct rpc_pipe_client *result;
3850 struct cli_pipe_auth_data *auth;
3853 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3854 if (!NT_STATUS_IS_OK(status)) {
3858 status = rpccli_anon_bind_data(result, &auth);
3859 if (!NT_STATUS_IS_OK(status)) {
3860 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3861 nt_errstr(status)));
3862 TALLOC_FREE(result);
3867 * This is a bit of an abstraction violation due to the fact that an
3868 * anonymous bind on an authenticated SMB inherits the user/domain
3869 * from the enclosing SMB creds
3872 TALLOC_FREE(auth->user_name);
3873 TALLOC_FREE(auth->domain);
3875 auth->user_name = talloc_strdup(auth, cli->user_name);
3876 auth->domain = talloc_strdup(auth, cli->domain);
3877 auth->user_session_key = data_blob_talloc(auth,
3878 cli->user_session_key.data,
3879 cli->user_session_key.length);
3881 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3882 TALLOC_FREE(result);
3883 return NT_STATUS_NO_MEMORY;
3886 status = rpc_pipe_bind(result, auth);
3887 if (!NT_STATUS_IS_OK(status)) {
3889 if (ndr_syntax_id_equal(interface,
3890 &ndr_table_dssetup.syntax_id)) {
3891 /* non AD domains just don't have this pipe, avoid
3892 * level 0 statement in that case - gd */
3895 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3896 "%s failed with error %s\n",
3897 get_pipe_name_from_syntax(talloc_tos(), interface),
3898 nt_errstr(status) ));
3899 TALLOC_FREE(result);
3903 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3904 "%s and bound anonymously.\n",
3905 get_pipe_name_from_syntax(talloc_tos(), interface),
3909 return NT_STATUS_OK;
3912 /****************************************************************************
3913 ****************************************************************************/
3915 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3916 const struct ndr_syntax_id *interface,
3917 struct rpc_pipe_client **presult)
3919 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3920 interface, presult);
3923 /****************************************************************************
3924 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3925 ****************************************************************************/
3927 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3928 const struct ndr_syntax_id *interface,
3929 enum dcerpc_transport_t transport,
3930 enum pipe_auth_type auth_type,
3931 enum dcerpc_AuthLevel auth_level,
3933 const char *username,
3934 const char *password,
3935 struct rpc_pipe_client **presult)
3937 struct rpc_pipe_client *result;
3938 struct cli_pipe_auth_data *auth;
3941 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3942 if (!NT_STATUS_IS_OK(status)) {
3946 status = rpccli_ntlmssp_bind_data(
3947 result, auth_type, auth_level, domain, username,
3949 if (!NT_STATUS_IS_OK(status)) {
3950 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3951 nt_errstr(status)));
3955 status = rpc_pipe_bind(result, auth);
3956 if (!NT_STATUS_IS_OK(status)) {
3957 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3958 nt_errstr(status) ));
3962 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3963 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3964 get_pipe_name_from_syntax(talloc_tos(), interface),
3965 cli->desthost, domain, username ));
3968 return NT_STATUS_OK;
3972 TALLOC_FREE(result);
3976 /****************************************************************************
3978 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3979 ****************************************************************************/
3981 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3982 const struct ndr_syntax_id *interface,
3983 enum dcerpc_transport_t transport,
3984 enum dcerpc_AuthLevel auth_level,
3986 const char *username,
3987 const char *password,
3988 struct rpc_pipe_client **presult)
3990 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3993 PIPE_AUTH_TYPE_NTLMSSP,
4001 /****************************************************************************
4003 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
4004 ****************************************************************************/
4006 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
4007 const struct ndr_syntax_id *interface,
4008 enum dcerpc_transport_t transport,
4009 enum dcerpc_AuthLevel auth_level,
4011 const char *username,
4012 const char *password,
4013 struct rpc_pipe_client **presult)
4015 return cli_rpc_pipe_open_ntlmssp_internal(cli,
4018 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
4026 /****************************************************************************
4027 Get a the schannel session key out of an already opened netlogon pipe.
4028 ****************************************************************************/
4029 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
4030 struct cli_state *cli,
4034 enum netr_SchannelType sec_chan_type = 0;
4035 unsigned char machine_pwd[16];
4036 const char *machine_account;
4039 /* Get the machine account credentials from secrets.tdb. */
4040 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
4043 DEBUG(0, ("get_schannel_session_key: could not fetch "
4044 "trust account password for domain '%s'\n",
4046 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
4049 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4050 cli->desthost, /* server name */
4051 domain, /* domain */
4052 global_myname(), /* client name */
4053 machine_account, /* machine account name */
4058 if (!NT_STATUS_IS_OK(status)) {
4059 DEBUG(3, ("get_schannel_session_key_common: "
4060 "rpccli_netlogon_setup_creds failed with result %s "
4061 "to server %s, domain %s, machine account %s.\n",
4062 nt_errstr(status), cli->desthost, domain,
4067 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4068 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4070 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4073 return NT_STATUS_OK;;
4076 /****************************************************************************
4077 Open a netlogon pipe and get the schannel session key.
4078 Now exposed to external callers.
4079 ****************************************************************************/
4082 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4085 struct rpc_pipe_client **presult)
4087 struct rpc_pipe_client *netlogon_pipe = NULL;
4090 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4092 if (!NT_STATUS_IS_OK(status)) {
4096 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4098 if (!NT_STATUS_IS_OK(status)) {
4099 TALLOC_FREE(netlogon_pipe);
4103 *presult = netlogon_pipe;
4104 return NT_STATUS_OK;
4107 /****************************************************************************
4109 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4110 using session_key. sign and seal.
4112 The *pdc will be stolen onto this new pipe
4113 ****************************************************************************/
4115 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4116 const struct ndr_syntax_id *interface,
4117 enum dcerpc_transport_t transport,
4118 enum dcerpc_AuthLevel auth_level,
4120 struct netlogon_creds_CredentialState **pdc,
4121 struct rpc_pipe_client **presult)
4123 struct rpc_pipe_client *result;
4124 struct cli_pipe_auth_data *auth;
4127 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4128 if (!NT_STATUS_IS_OK(status)) {
4132 status = rpccli_schannel_bind_data(result, domain, auth_level,
4134 if (!NT_STATUS_IS_OK(status)) {
4135 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4136 nt_errstr(status)));
4137 TALLOC_FREE(result);
4141 status = rpc_pipe_bind(result, auth);
4142 if (!NT_STATUS_IS_OK(status)) {
4143 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4144 "cli_rpc_pipe_bind failed with error %s\n",
4145 nt_errstr(status) ));
4146 TALLOC_FREE(result);
4151 * The credentials on a new netlogon pipe are the ones we are passed
4152 * in - reference them in
4154 result->dc = talloc_move(result, pdc);
4156 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4157 "for domain %s and bound using schannel.\n",
4158 get_pipe_name_from_syntax(talloc_tos(), interface),
4159 cli->desthost, domain ));
4162 return NT_STATUS_OK;
4165 /****************************************************************************
4166 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4167 Fetch the session key ourselves using a temporary netlogon pipe. This
4168 version uses an ntlmssp auth bound netlogon pipe to get the key.
4169 ****************************************************************************/
4171 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4173 const char *username,
4174 const char *password,
4176 struct rpc_pipe_client **presult)
4178 struct rpc_pipe_client *netlogon_pipe = NULL;
4181 status = cli_rpc_pipe_open_spnego_ntlmssp(
4182 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4183 DCERPC_AUTH_LEVEL_PRIVACY,
4184 domain, username, password, &netlogon_pipe);
4185 if (!NT_STATUS_IS_OK(status)) {
4189 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4191 if (!NT_STATUS_IS_OK(status)) {
4192 TALLOC_FREE(netlogon_pipe);
4196 *presult = netlogon_pipe;
4197 return NT_STATUS_OK;
4200 /****************************************************************************
4201 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4202 Fetch the session key ourselves using a temporary netlogon pipe. This version
4203 uses an ntlmssp bind to get the session key.
4204 ****************************************************************************/
4206 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4207 const struct ndr_syntax_id *interface,
4208 enum dcerpc_transport_t transport,
4209 enum dcerpc_AuthLevel auth_level,
4211 const char *username,
4212 const char *password,
4213 struct rpc_pipe_client **presult)
4215 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4216 struct rpc_pipe_client *netlogon_pipe = NULL;
4217 struct rpc_pipe_client *result = NULL;
4220 status = get_schannel_session_key_auth_ntlmssp(
4221 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4222 if (!NT_STATUS_IS_OK(status)) {
4223 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4224 "key from server %s for domain %s.\n",
4225 cli->desthost, domain ));
4229 status = cli_rpc_pipe_open_schannel_with_key(
4230 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4233 /* Now we've bound using the session key we can close the netlog pipe. */
4234 TALLOC_FREE(netlogon_pipe);
4236 if (NT_STATUS_IS_OK(status)) {
4242 /****************************************************************************
4243 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4244 Fetch the session key ourselves using a temporary netlogon pipe.
4245 ****************************************************************************/
4247 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4248 const struct ndr_syntax_id *interface,
4249 enum dcerpc_transport_t transport,
4250 enum dcerpc_AuthLevel auth_level,
4252 struct rpc_pipe_client **presult)
4254 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4255 struct rpc_pipe_client *netlogon_pipe = NULL;
4256 struct rpc_pipe_client *result = NULL;
4259 status = get_schannel_session_key(cli, domain, &neg_flags,
4261 if (!NT_STATUS_IS_OK(status)) {
4262 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4263 "key from server %s for domain %s.\n",
4264 cli->desthost, domain ));
4268 status = cli_rpc_pipe_open_schannel_with_key(
4269 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4272 /* Now we've bound using the session key we can close the netlog pipe. */
4273 TALLOC_FREE(netlogon_pipe);
4275 if (NT_STATUS_IS_OK(status)) {
4282 /****************************************************************************
4283 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4284 The idea is this can be called with service_princ, username and password all
4285 NULL so long as the caller has a TGT.
4286 ****************************************************************************/
4288 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4289 const struct ndr_syntax_id *interface,
4290 enum dcerpc_AuthLevel auth_level,
4291 const char *service_princ,
4292 const char *username,
4293 const char *password,
4294 struct rpc_pipe_client **presult)
4297 struct rpc_pipe_client *result;
4298 struct cli_pipe_auth_data *auth;
4301 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4302 if (!NT_STATUS_IS_OK(status)) {
4306 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4307 username, password, &auth);
4308 if (!NT_STATUS_IS_OK(status)) {
4309 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4310 nt_errstr(status)));
4311 TALLOC_FREE(result);
4315 status = rpc_pipe_bind(result, auth);
4316 if (!NT_STATUS_IS_OK(status)) {
4317 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4318 "with error %s\n", nt_errstr(status)));
4319 TALLOC_FREE(result);
4324 return NT_STATUS_OK;
4326 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4327 return NT_STATUS_NOT_IMPLEMENTED;
4331 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4332 struct rpc_pipe_client *cli,
4333 DATA_BLOB *session_key)
4335 if (!session_key || !cli) {
4336 return NT_STATUS_INVALID_PARAMETER;
4340 return NT_STATUS_INVALID_PARAMETER;
4343 switch (cli->auth->auth_type) {
4344 case PIPE_AUTH_TYPE_SCHANNEL:
4345 *session_key = data_blob_talloc(mem_ctx,
4346 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4348 case PIPE_AUTH_TYPE_NTLMSSP:
4349 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4350 *session_key = data_blob_talloc(mem_ctx,
4351 cli->auth->a_u.ntlmssp_state->session_key.data,
4352 cli->auth->a_u.ntlmssp_state->session_key.length);
4354 case PIPE_AUTH_TYPE_KRB5:
4355 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4356 *session_key = data_blob_talloc(mem_ctx,
4357 cli->auth->a_u.kerberos_auth->session_key.data,
4358 cli->auth->a_u.kerberos_auth->session_key.length);
4360 case PIPE_AUTH_TYPE_NONE:
4361 *session_key = data_blob_talloc(mem_ctx,
4362 cli->auth->user_session_key.data,
4363 cli->auth->user_session_key.length);
4366 return NT_STATUS_NO_USER_SESSION_KEY;
4369 return NT_STATUS_OK;