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"
46 #define DBGC_CLASS DBGC_RPC_CLI
48 static const char *get_pipe_name_from_iface(
49 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
52 const struct ndr_interface_string_array *ep = interface->endpoints;
55 for (i=0; i<ep->count; i++) {
56 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
65 * extract the pipe name without \\pipe from for example
66 * ncacn_np:[\\pipe\\epmapper]
68 p = strchr(ep->names[i]+15, ']');
72 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
75 static const struct ndr_interface_table **interfaces;
77 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
79 int num_interfaces = talloc_array_length(interfaces);
80 const struct ndr_interface_table **tmp;
83 for (i=0; i<num_interfaces; i++) {
84 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
85 &interface->syntax_id)) {
90 tmp = talloc_realloc(NULL, interfaces,
91 const struct ndr_interface_table *,
94 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
98 interfaces[num_interfaces] = interface;
102 static bool initialize_interfaces(void)
104 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
107 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
110 if (!smb_register_ndr_interface(&ndr_table_samr)) {
113 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
116 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
119 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
122 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
125 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
128 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
131 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
134 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
137 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
140 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
143 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
146 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
149 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
155 const struct ndr_interface_table *get_iface_from_syntax(
156 const struct ndr_syntax_id *syntax)
161 if (interfaces == NULL) {
162 if (!initialize_interfaces()) {
166 num_interfaces = talloc_array_length(interfaces);
168 for (i=0; i<num_interfaces; i++) {
169 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
170 return interfaces[i];
177 /****************************************************************************
178 Return the pipe name from the interface.
179 ****************************************************************************/
181 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
182 const struct ndr_syntax_id *syntax)
184 const struct ndr_interface_table *interface;
188 interface = get_iface_from_syntax(syntax);
189 if (interface != NULL) {
190 result = get_pipe_name_from_iface(mem_ctx, interface);
191 if (result != NULL) {
197 * Here we should ask \\epmapper, but for now our code is only
198 * interested in the known pipes mentioned in pipe_names[]
201 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
202 if (guid_str == NULL) {
205 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
206 (int)syntax->if_version);
207 TALLOC_FREE(guid_str);
209 if (result == NULL) {
215 /********************************************************************
216 Map internal value to wire value.
217 ********************************************************************/
219 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
223 case PIPE_AUTH_TYPE_NONE:
224 return DCERPC_AUTH_TYPE_NONE;
226 case PIPE_AUTH_TYPE_NTLMSSP:
227 return DCERPC_AUTH_TYPE_NTLMSSP;
229 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
230 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
231 return DCERPC_AUTH_TYPE_SPNEGO;
233 case PIPE_AUTH_TYPE_SCHANNEL:
234 return DCERPC_AUTH_TYPE_SCHANNEL;
236 case PIPE_AUTH_TYPE_KRB5:
237 return DCERPC_AUTH_TYPE_KRB5;
240 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
242 (unsigned int)auth_type ));
248 /********************************************************************
249 Pipe description for a DEBUG
250 ********************************************************************/
251 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
252 struct rpc_pipe_client *cli)
254 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
255 if (result == NULL) {
261 /********************************************************************
263 ********************************************************************/
265 static uint32 get_rpc_call_id(void)
267 static uint32 call_id = 0;
272 * Realloc pdu to have a least "size" bytes
275 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
279 if (prs_data_size(pdu) >= size) {
283 extra_size = size - prs_data_size(pdu);
285 if (!prs_force_grow(pdu, extra_size)) {
286 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
287 "%d bytes.\n", (int)extra_size));
291 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
292 (int)extra_size, prs_data_size(pdu)));
297 /*******************************************************************
298 Use SMBreadX to get rest of one fragment's worth of rpc data.
299 Reads the whole size or give an error message
300 ********************************************************************/
302 struct rpc_read_state {
303 struct event_context *ev;
304 struct rpc_cli_transport *transport;
310 static void rpc_read_done(struct tevent_req *subreq);
312 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
313 struct event_context *ev,
314 struct rpc_cli_transport *transport,
315 uint8_t *data, size_t size)
317 struct tevent_req *req, *subreq;
318 struct rpc_read_state *state;
320 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
325 state->transport = transport;
330 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
332 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
334 if (subreq == NULL) {
337 tevent_req_set_callback(subreq, rpc_read_done, req);
345 static void rpc_read_done(struct tevent_req *subreq)
347 struct tevent_req *req = tevent_req_callback_data(
348 subreq, struct tevent_req);
349 struct rpc_read_state *state = tevent_req_data(
350 req, struct rpc_read_state);
354 status = state->transport->read_recv(subreq, &received);
356 if (!NT_STATUS_IS_OK(status)) {
357 tevent_req_nterror(req, status);
361 state->num_read += received;
362 if (state->num_read == state->size) {
363 tevent_req_done(req);
367 subreq = state->transport->read_send(state, state->ev,
368 state->data + state->num_read,
369 state->size - state->num_read,
370 state->transport->priv);
371 if (tevent_req_nomem(subreq, req)) {
374 tevent_req_set_callback(subreq, rpc_read_done, req);
377 static NTSTATUS rpc_read_recv(struct tevent_req *req)
379 return tevent_req_simple_recv_ntstatus(req);
382 struct rpc_write_state {
383 struct event_context *ev;
384 struct rpc_cli_transport *transport;
390 static void rpc_write_done(struct tevent_req *subreq);
392 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
393 struct event_context *ev,
394 struct rpc_cli_transport *transport,
395 const uint8_t *data, size_t size)
397 struct tevent_req *req, *subreq;
398 struct rpc_write_state *state;
400 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
405 state->transport = transport;
408 state->num_written = 0;
410 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
412 subreq = transport->write_send(state, ev, data, size, transport->priv);
413 if (subreq == NULL) {
416 tevent_req_set_callback(subreq, rpc_write_done, req);
423 static void rpc_write_done(struct tevent_req *subreq)
425 struct tevent_req *req = tevent_req_callback_data(
426 subreq, struct tevent_req);
427 struct rpc_write_state *state = tevent_req_data(
428 req, struct rpc_write_state);
432 status = state->transport->write_recv(subreq, &written);
434 if (!NT_STATUS_IS_OK(status)) {
435 tevent_req_nterror(req, status);
439 state->num_written += written;
441 if (state->num_written == state->size) {
442 tevent_req_done(req);
446 subreq = state->transport->write_send(state, state->ev,
447 state->data + state->num_written,
448 state->size - state->num_written,
449 state->transport->priv);
450 if (tevent_req_nomem(subreq, req)) {
453 tevent_req_set_callback(subreq, rpc_write_done, req);
456 static NTSTATUS rpc_write_recv(struct tevent_req *req)
458 return tevent_req_simple_recv_ntstatus(req);
462 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
463 struct rpc_hdr_info *prhdr,
467 * This next call sets the endian bit correctly in current_pdu. We
468 * will propagate this to rbuf later.
471 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
472 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
473 return NT_STATUS_BUFFER_TOO_SMALL;
476 if (prhdr->frag_len > cli->max_recv_frag) {
477 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
478 " we only allow %d\n", (int)prhdr->frag_len,
479 (int)cli->max_recv_frag));
480 return NT_STATUS_BUFFER_TOO_SMALL;
486 /****************************************************************************
487 Try and get a PDU's worth of data from current_pdu. If not, then read more
489 ****************************************************************************/
491 struct get_complete_frag_state {
492 struct event_context *ev;
493 struct rpc_pipe_client *cli;
494 struct rpc_hdr_info *prhdr;
498 static void get_complete_frag_got_header(struct tevent_req *subreq);
499 static void get_complete_frag_got_rest(struct tevent_req *subreq);
501 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
502 struct event_context *ev,
503 struct rpc_pipe_client *cli,
504 struct rpc_hdr_info *prhdr,
507 struct tevent_req *req, *subreq;
508 struct get_complete_frag_state *state;
512 req = tevent_req_create(mem_ctx, &state,
513 struct get_complete_frag_state);
519 state->prhdr = prhdr;
522 pdu_len = prs_data_size(pdu);
523 if (pdu_len < RPC_HEADER_LEN) {
524 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
525 status = NT_STATUS_NO_MEMORY;
528 subreq = rpc_read_send(
530 state->cli->transport,
531 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
532 RPC_HEADER_LEN - pdu_len);
533 if (subreq == NULL) {
534 status = NT_STATUS_NO_MEMORY;
537 tevent_req_set_callback(subreq, get_complete_frag_got_header,
542 status = parse_rpc_header(cli, prhdr, pdu);
543 if (!NT_STATUS_IS_OK(status)) {
548 * Ensure we have frag_len bytes of data.
550 if (pdu_len < prhdr->frag_len) {
551 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
552 status = NT_STATUS_NO_MEMORY;
555 subreq = rpc_read_send(state, state->ev,
556 state->cli->transport,
557 (uint8_t *)(prs_data_p(pdu) + pdu_len),
558 prhdr->frag_len - pdu_len);
559 if (subreq == NULL) {
560 status = NT_STATUS_NO_MEMORY;
563 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
568 status = NT_STATUS_OK;
570 if (NT_STATUS_IS_OK(status)) {
571 tevent_req_done(req);
573 tevent_req_nterror(req, status);
575 return tevent_req_post(req, ev);
578 static void get_complete_frag_got_header(struct tevent_req *subreq)
580 struct tevent_req *req = tevent_req_callback_data(
581 subreq, struct tevent_req);
582 struct get_complete_frag_state *state = tevent_req_data(
583 req, struct get_complete_frag_state);
586 status = rpc_read_recv(subreq);
588 if (!NT_STATUS_IS_OK(status)) {
589 tevent_req_nterror(req, status);
593 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
594 if (!NT_STATUS_IS_OK(status)) {
595 tevent_req_nterror(req, status);
599 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
600 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
605 * We're here in this piece of code because we've read exactly
606 * RPC_HEADER_LEN bytes into state->pdu.
609 subreq = rpc_read_send(
610 state, state->ev, state->cli->transport,
611 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
612 state->prhdr->frag_len - RPC_HEADER_LEN);
613 if (tevent_req_nomem(subreq, req)) {
616 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
619 static void get_complete_frag_got_rest(struct tevent_req *subreq)
621 struct tevent_req *req = tevent_req_callback_data(
622 subreq, struct tevent_req);
625 status = rpc_read_recv(subreq);
627 if (!NT_STATUS_IS_OK(status)) {
628 tevent_req_nterror(req, status);
631 tevent_req_done(req);
634 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
636 return tevent_req_simple_recv_ntstatus(req);
639 /****************************************************************************
640 NTLMSSP specific sign/seal.
641 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
642 In fact I should probably abstract these into identical pieces of code... JRA.
643 ****************************************************************************/
645 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
646 prs_struct *current_pdu,
647 uint8 *p_ss_padding_len)
649 RPC_HDR_AUTH auth_info;
650 uint32 save_offset = prs_offset(current_pdu);
651 uint32 auth_len = prhdr->auth_len;
652 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
653 unsigned char *data = NULL;
655 unsigned char *full_packet_data = NULL;
656 size_t full_packet_data_len;
660 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
661 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
665 if (!ntlmssp_state) {
666 return NT_STATUS_INVALID_PARAMETER;
669 /* Ensure there's enough data for an authenticated response. */
670 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
671 prhdr->frag_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
672 RPC_HDR_AUTH_LEN + auth_len) {
673 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
674 (unsigned int)auth_len ));
675 return NT_STATUS_BUFFER_TOO_SMALL;
679 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
680 * after the RPC header.
681 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
682 * functions as NTLMv2 checks the rpc headers also.
685 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
686 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
688 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
689 full_packet_data_len = prhdr->frag_len - auth_len;
691 /* Pull the auth header and the following data into a blob. */
692 /* NB. The offset of the auth_header is relative to the *end*
693 * of the packet, not the start. */
694 if(!prs_set_offset(current_pdu, prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
695 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
696 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
697 return NT_STATUS_BUFFER_TOO_SMALL;
700 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
701 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
702 return NT_STATUS_BUFFER_TOO_SMALL;
705 /* Ensure auth_pad_len fits into the packet. */
706 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
707 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
708 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
709 "too large (%u), auth_len (%u), frag_len = (%u).\n",
710 (unsigned int)auth_info.auth_pad_len,
711 (unsigned int)auth_len,
712 (unsigned int)prhdr->frag_len ));
713 return NT_STATUS_BUFFER_TOO_SMALL;
717 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
718 auth_blob.length = auth_len;
720 switch (cli->auth->auth_level) {
721 case DCERPC_AUTH_LEVEL_PRIVACY:
722 /* Data is encrypted. */
723 status = ntlmssp_unseal_packet(ntlmssp_state,
726 full_packet_data_len,
728 if (!NT_STATUS_IS_OK(status)) {
729 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
730 "packet from %s. Error was %s.\n",
731 rpccli_pipe_txt(talloc_tos(), cli),
732 nt_errstr(status) ));
736 case DCERPC_AUTH_LEVEL_INTEGRITY:
737 /* Data is signed. */
738 status = ntlmssp_check_packet(ntlmssp_state,
741 full_packet_data_len,
743 if (!NT_STATUS_IS_OK(status)) {
744 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
745 "packet from %s. Error was %s.\n",
746 rpccli_pipe_txt(talloc_tos(), cli),
747 nt_errstr(status) ));
752 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
753 "auth level %d\n", cli->auth->auth_level));
754 return NT_STATUS_INVALID_INFO_CLASS;
758 * Return the current pointer to the data offset.
761 if(!prs_set_offset(current_pdu, save_offset)) {
762 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
763 (unsigned int)save_offset ));
764 return NT_STATUS_BUFFER_TOO_SMALL;
768 * Remember the padding length. We must remove it from the real data
769 * stream once the sign/seal is done.
772 *p_ss_padding_len = auth_info.auth_pad_len;
777 /****************************************************************************
778 schannel specific sign/seal.
779 ****************************************************************************/
781 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
782 prs_struct *current_pdu,
783 uint8 *p_ss_padding_len)
785 RPC_HDR_AUTH auth_info;
786 uint32 auth_len = prhdr->auth_len;
787 uint32 save_offset = prs_offset(current_pdu);
788 struct schannel_state *schannel_auth =
789 cli->auth->a_u.schannel_auth;
795 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
796 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
800 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
801 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
802 return NT_STATUS_INVALID_PARAMETER;
805 if (!schannel_auth) {
806 return NT_STATUS_INVALID_PARAMETER;
809 /* Ensure there's enough data for an authenticated response. */
810 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
811 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
812 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
813 (unsigned int)auth_len ));
814 return NT_STATUS_INVALID_PARAMETER;
817 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
819 /* Pull the auth header and the following data into a blob. */
820 /* NB. The offset of the auth_header is relative to the *end*
821 * of the packet, not the start. */
822 if(!prs_set_offset(current_pdu,
823 prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
824 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
826 (unsigned int)(prhdr->frag_len -
827 RPC_HDR_AUTH_LEN - auth_len) ));
828 return NT_STATUS_BUFFER_TOO_SMALL;
831 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
832 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
833 return NT_STATUS_BUFFER_TOO_SMALL;
836 /* Ensure auth_pad_len fits into the packet. */
837 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
838 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
839 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
840 "too large (%u), auth_len (%u), frag_len = (%u).\n",
841 (unsigned int)auth_info.auth_pad_len,
842 (unsigned int)auth_len,
843 (unsigned int)prhdr->frag_len ));
844 return NT_STATUS_BUFFER_TOO_SMALL;
847 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
848 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
849 auth_info.auth_type));
850 return NT_STATUS_BUFFER_TOO_SMALL;
853 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
855 if (DEBUGLEVEL >= 10) {
856 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
859 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
861 switch (cli->auth->auth_level) {
862 case DCERPC_AUTH_LEVEL_PRIVACY:
863 status = netsec_incoming_packet(schannel_auth,
870 case DCERPC_AUTH_LEVEL_INTEGRITY:
871 status = netsec_incoming_packet(schannel_auth,
879 status = NT_STATUS_INTERNAL_ERROR;
883 if (!NT_STATUS_IS_OK(status)) {
884 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
885 "Connection to %s (%s).\n",
886 rpccli_pipe_txt(talloc_tos(), cli),
888 return NT_STATUS_INVALID_PARAMETER;
892 * Return the current pointer to the data offset.
895 if(!prs_set_offset(current_pdu, save_offset)) {
896 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
897 (unsigned int)save_offset ));
898 return NT_STATUS_BUFFER_TOO_SMALL;
902 * Remember the padding length. We must remove it from the real data
903 * stream once the sign/seal is done.
906 *p_ss_padding_len = auth_info.auth_pad_len;
911 /****************************************************************************
912 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
913 ****************************************************************************/
915 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
916 prs_struct *current_pdu,
917 uint8 *p_ss_padding_len)
919 NTSTATUS ret = NT_STATUS_OK;
921 /* Paranioa checks for auth_len. */
922 if (prhdr->auth_len) {
923 if (prhdr->auth_len > prhdr->frag_len) {
924 return NT_STATUS_INVALID_PARAMETER;
927 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
928 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
929 /* Integer wrap attempt. */
930 return NT_STATUS_INVALID_PARAMETER;
935 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
938 switch(cli->auth->auth_type) {
939 case PIPE_AUTH_TYPE_NONE:
940 if (prhdr->auth_len) {
941 DEBUG(3, ("cli_pipe_validate_rpc_response: "
942 "Connection to %s - got non-zero "
944 rpccli_pipe_txt(talloc_tos(), cli),
945 (unsigned int)prhdr->auth_len ));
946 return NT_STATUS_INVALID_PARAMETER;
950 case PIPE_AUTH_TYPE_NTLMSSP:
951 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
952 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
953 if (!NT_STATUS_IS_OK(ret)) {
958 case PIPE_AUTH_TYPE_SCHANNEL:
959 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
960 if (!NT_STATUS_IS_OK(ret)) {
965 case PIPE_AUTH_TYPE_KRB5:
966 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
968 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
969 "to %s - unknown internal auth type %u.\n",
970 rpccli_pipe_txt(talloc_tos(), cli),
971 cli->auth->auth_type ));
972 return NT_STATUS_INVALID_INFO_CLASS;
978 /****************************************************************************
979 Do basic authentication checks on an incoming pdu.
980 ****************************************************************************/
982 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
983 prs_struct *current_pdu,
984 uint8 expected_pkt_type,
987 prs_struct *return_data)
990 NTSTATUS ret = NT_STATUS_OK;
991 uint32 current_pdu_len = prs_data_size(current_pdu);
993 if (current_pdu_len != prhdr->frag_len) {
994 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
995 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
996 return NT_STATUS_INVALID_PARAMETER;
1000 * Point the return values at the real data including the RPC
1001 * header. Just in case the caller wants it.
1003 *ppdata = prs_data_p(current_pdu);
1004 *pdata_len = current_pdu_len;
1006 /* Ensure we have the correct type. */
1007 switch (prhdr->pkt_type) {
1008 case DCERPC_PKT_ALTER_RESP:
1009 case DCERPC_PKT_BIND_ACK:
1011 /* Alter context and bind ack share the same packet definitions. */
1015 case DCERPC_PKT_RESPONSE:
1017 RPC_HDR_RESP rhdr_resp;
1018 uint8 ss_padding_len = 0;
1020 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1021 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1022 return NT_STATUS_BUFFER_TOO_SMALL;
1025 /* Here's where we deal with incoming sign/seal. */
1026 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1027 current_pdu, &ss_padding_len);
1028 if (!NT_STATUS_IS_OK(ret)) {
1032 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1033 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1035 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1036 return NT_STATUS_BUFFER_TOO_SMALL;
1039 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1041 /* Remember to remove the auth footer. */
1042 if (prhdr->auth_len) {
1043 /* We've already done integer wrap tests on auth_len in
1044 cli_pipe_validate_rpc_response(). */
1045 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
1046 return NT_STATUS_BUFFER_TOO_SMALL;
1048 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1051 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1052 current_pdu_len, *pdata_len, ss_padding_len ));
1055 * If this is the first reply, and the allocation hint is reasonably, try and
1056 * set up the return_data parse_struct to the correct size.
1059 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1060 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1061 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1062 "too large to allocate\n",
1063 (unsigned int)rhdr_resp.alloc_hint ));
1064 return NT_STATUS_NO_MEMORY;
1071 case DCERPC_PKT_BIND_NAK:
1072 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1073 "received from %s!\n",
1074 rpccli_pipe_txt(talloc_tos(), cli)));
1075 /* Use this for now... */
1076 return NT_STATUS_NETWORK_ACCESS_DENIED;
1078 case DCERPC_PKT_FAULT:
1080 RPC_HDR_RESP rhdr_resp;
1081 RPC_HDR_FAULT fault_resp;
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 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
1089 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1090 return NT_STATUS_BUFFER_TOO_SMALL;
1093 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1094 "code %s received from %s!\n",
1095 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
1096 rpccli_pipe_txt(talloc_tos(), cli)));
1097 if (NT_STATUS_IS_OK(fault_resp.status)) {
1098 return NT_STATUS_UNSUCCESSFUL;
1100 return fault_resp.status;
1105 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1107 (unsigned int)prhdr->pkt_type,
1108 rpccli_pipe_txt(talloc_tos(), cli)));
1109 return NT_STATUS_INVALID_INFO_CLASS;
1112 if (prhdr->pkt_type != expected_pkt_type) {
1113 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1114 "got an unexpected RPC packet type - %u, not %u\n",
1115 rpccli_pipe_txt(talloc_tos(), cli),
1117 expected_pkt_type));
1118 return NT_STATUS_INVALID_INFO_CLASS;
1121 /* Do this just before return - we don't want to modify any rpc header
1122 data before now as we may have needed to do cryptographic actions on
1125 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1126 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1127 "setting fragment first/last ON.\n"));
1128 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1131 return NT_STATUS_OK;
1134 /****************************************************************************
1135 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1136 Normally the frag_len and buffer size will match, but on the first trans
1137 reply there is a theoretical chance that buffer size > frag_len, so we must
1139 ****************************************************************************/
1141 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1143 uint32 current_pdu_len = prs_data_size(current_pdu);
1145 if (current_pdu_len < prhdr->frag_len) {
1146 return NT_STATUS_BUFFER_TOO_SMALL;
1150 if (current_pdu_len == (uint32)prhdr->frag_len) {
1151 prs_mem_free(current_pdu);
1152 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1153 /* Make current_pdu dynamic with no memory. */
1154 prs_give_memory(current_pdu, 0, 0, True);
1155 return NT_STATUS_OK;
1159 * Oh no ! More data in buffer than we processed in current pdu.
1160 * Cheat. Move the data down and shrink the buffer.
1163 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1164 current_pdu_len - prhdr->frag_len);
1166 /* Remember to set the read offset back to zero. */
1167 prs_set_offset(current_pdu, 0);
1169 /* Shrink the buffer. */
1170 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1171 return NT_STATUS_BUFFER_TOO_SMALL;
1174 return NT_STATUS_OK;
1177 /****************************************************************************
1178 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1179 ****************************************************************************/
1181 struct cli_api_pipe_state {
1182 struct event_context *ev;
1183 struct rpc_cli_transport *transport;
1188 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1189 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1190 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1192 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1193 struct event_context *ev,
1194 struct rpc_cli_transport *transport,
1195 uint8_t *data, size_t data_len,
1196 uint32_t max_rdata_len)
1198 struct tevent_req *req, *subreq;
1199 struct cli_api_pipe_state *state;
1202 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1207 state->transport = transport;
1209 if (max_rdata_len < RPC_HEADER_LEN) {
1211 * For a RPC reply we always need at least RPC_HEADER_LEN
1212 * bytes. We check this here because we will receive
1213 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1215 status = NT_STATUS_INVALID_PARAMETER;
1219 if (transport->trans_send != NULL) {
1220 subreq = transport->trans_send(state, ev, data, data_len,
1221 max_rdata_len, transport->priv);
1222 if (subreq == NULL) {
1225 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1230 * If the transport does not provide a "trans" routine, i.e. for
1231 * example the ncacn_ip_tcp transport, do the write/read step here.
1234 subreq = rpc_write_send(state, ev, transport, data, data_len);
1235 if (subreq == NULL) {
1238 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1241 status = NT_STATUS_INVALID_PARAMETER;
1244 tevent_req_nterror(req, status);
1245 return tevent_req_post(req, ev);
1251 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1253 struct tevent_req *req = tevent_req_callback_data(
1254 subreq, struct tevent_req);
1255 struct cli_api_pipe_state *state = tevent_req_data(
1256 req, struct cli_api_pipe_state);
1259 status = state->transport->trans_recv(subreq, state, &state->rdata,
1261 TALLOC_FREE(subreq);
1262 if (!NT_STATUS_IS_OK(status)) {
1263 tevent_req_nterror(req, status);
1266 tevent_req_done(req);
1269 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1271 struct tevent_req *req = tevent_req_callback_data(
1272 subreq, struct tevent_req);
1273 struct cli_api_pipe_state *state = tevent_req_data(
1274 req, struct cli_api_pipe_state);
1277 status = rpc_write_recv(subreq);
1278 TALLOC_FREE(subreq);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 tevent_req_nterror(req, status);
1284 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1285 if (tevent_req_nomem(state->rdata, req)) {
1290 * We don't need to use rpc_read_send here, the upper layer will cope
1291 * with a short read, transport->trans_send could also return less
1292 * than state->max_rdata_len.
1294 subreq = state->transport->read_send(state, state->ev, state->rdata,
1296 state->transport->priv);
1297 if (tevent_req_nomem(subreq, req)) {
1300 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1303 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1305 struct tevent_req *req = tevent_req_callback_data(
1306 subreq, struct tevent_req);
1307 struct cli_api_pipe_state *state = tevent_req_data(
1308 req, struct cli_api_pipe_state);
1312 status = state->transport->read_recv(subreq, &received);
1313 TALLOC_FREE(subreq);
1314 if (!NT_STATUS_IS_OK(status)) {
1315 tevent_req_nterror(req, status);
1318 state->rdata_len = received;
1319 tevent_req_done(req);
1322 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1323 uint8_t **prdata, uint32_t *prdata_len)
1325 struct cli_api_pipe_state *state = tevent_req_data(
1326 req, struct cli_api_pipe_state);
1329 if (tevent_req_is_nterror(req, &status)) {
1333 *prdata = talloc_move(mem_ctx, &state->rdata);
1334 *prdata_len = state->rdata_len;
1335 return NT_STATUS_OK;
1338 /****************************************************************************
1339 Send data on an rpc pipe via trans. The prs_struct data must be the last
1340 pdu fragment of an NDR data stream.
1342 Receive response data from an rpc pipe, which may be large...
1344 Read the first fragment: unfortunately have to use SMBtrans for the first
1345 bit, then SMBreadX for subsequent bits.
1347 If first fragment received also wasn't the last fragment, continue
1348 getting fragments until we _do_ receive the last fragment.
1350 Request/Response PDU's look like the following...
1352 |<------------------PDU len----------------------------------------------->|
1353 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1355 +------------+-----------------+-------------+---------------+-------------+
1356 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1357 +------------+-----------------+-------------+---------------+-------------+
1359 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1360 signing & sealing being negotiated.
1362 ****************************************************************************/
1364 struct rpc_api_pipe_state {
1365 struct event_context *ev;
1366 struct rpc_pipe_client *cli;
1367 uint8_t expected_pkt_type;
1369 prs_struct incoming_frag;
1370 struct rpc_hdr_info rhdr;
1372 prs_struct incoming_pdu; /* Incoming reply */
1373 uint32_t incoming_pdu_offset;
1376 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1378 prs_mem_free(&state->incoming_frag);
1379 prs_mem_free(&state->incoming_pdu);
1383 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1384 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1386 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1387 struct event_context *ev,
1388 struct rpc_pipe_client *cli,
1389 prs_struct *data, /* Outgoing PDU */
1390 uint8_t expected_pkt_type)
1392 struct tevent_req *req, *subreq;
1393 struct rpc_api_pipe_state *state;
1394 uint16_t max_recv_frag;
1397 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1403 state->expected_pkt_type = expected_pkt_type;
1404 state->incoming_pdu_offset = 0;
1406 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1408 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1409 /* Make incoming_pdu dynamic with no memory. */
1410 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1412 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1415 * Ensure we're not sending too much.
1417 if (prs_offset(data) > cli->max_xmit_frag) {
1418 status = NT_STATUS_INVALID_PARAMETER;
1422 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1424 max_recv_frag = cli->max_recv_frag;
1427 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1430 subreq = cli_api_pipe_send(state, ev, cli->transport,
1431 (uint8_t *)prs_data_p(data),
1432 prs_offset(data), max_recv_frag);
1433 if (subreq == NULL) {
1436 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1440 tevent_req_nterror(req, status);
1441 return tevent_req_post(req, ev);
1447 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1449 struct tevent_req *req = tevent_req_callback_data(
1450 subreq, struct tevent_req);
1451 struct rpc_api_pipe_state *state = tevent_req_data(
1452 req, struct rpc_api_pipe_state);
1454 uint8_t *rdata = NULL;
1455 uint32_t rdata_len = 0;
1457 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1458 TALLOC_FREE(subreq);
1459 if (!NT_STATUS_IS_OK(status)) {
1460 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1461 tevent_req_nterror(req, status);
1465 if (rdata == NULL) {
1466 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1467 rpccli_pipe_txt(talloc_tos(), state->cli)));
1468 tevent_req_done(req);
1473 * This is equivalent to a talloc_steal - gives rdata to
1474 * the prs_struct state->incoming_frag.
1476 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1479 /* Ensure we have enough data for a pdu. */
1480 subreq = get_complete_frag_send(state, state->ev, state->cli,
1481 &state->rhdr, &state->incoming_frag);
1482 if (tevent_req_nomem(subreq, req)) {
1485 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1488 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1490 struct tevent_req *req = tevent_req_callback_data(
1491 subreq, struct tevent_req);
1492 struct rpc_api_pipe_state *state = tevent_req_data(
1493 req, struct rpc_api_pipe_state);
1496 uint32_t rdata_len = 0;
1498 status = get_complete_frag_recv(subreq);
1499 TALLOC_FREE(subreq);
1500 if (!NT_STATUS_IS_OK(status)) {
1501 DEBUG(5, ("get_complete_frag failed: %s\n",
1502 nt_errstr(status)));
1503 tevent_req_nterror(req, status);
1507 status = cli_pipe_validate_current_pdu(
1508 state->cli, &state->rhdr, &state->incoming_frag,
1509 state->expected_pkt_type, &rdata, &rdata_len,
1510 &state->incoming_pdu);
1512 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1513 (unsigned)prs_data_size(&state->incoming_frag),
1514 (unsigned)state->incoming_pdu_offset,
1515 nt_errstr(status)));
1517 if (!NT_STATUS_IS_OK(status)) {
1518 tevent_req_nterror(req, status);
1522 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1523 && (state->rhdr.pack_type[0] == 0)) {
1525 * Set the data type correctly for big-endian data on the
1528 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1530 rpccli_pipe_txt(talloc_tos(), state->cli)));
1531 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1534 * Check endianness on subsequent packets.
1536 if (state->incoming_frag.bigendian_data
1537 != state->incoming_pdu.bigendian_data) {
1538 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1540 state->incoming_pdu.bigendian_data?"big":"little",
1541 state->incoming_frag.bigendian_data?"big":"little"));
1542 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1546 /* Now copy the data portion out of the pdu into rbuf. */
1547 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1548 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1552 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1553 rdata, (size_t)rdata_len);
1554 state->incoming_pdu_offset += rdata_len;
1556 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1557 &state->incoming_frag);
1558 if (!NT_STATUS_IS_OK(status)) {
1559 tevent_req_nterror(req, status);
1563 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1564 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1565 rpccli_pipe_txt(talloc_tos(), state->cli),
1566 (unsigned)prs_data_size(&state->incoming_pdu)));
1567 tevent_req_done(req);
1571 subreq = get_complete_frag_send(state, state->ev, state->cli,
1572 &state->rhdr, &state->incoming_frag);
1573 if (tevent_req_nomem(subreq, req)) {
1576 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1579 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1580 prs_struct *reply_pdu)
1582 struct rpc_api_pipe_state *state = tevent_req_data(
1583 req, struct rpc_api_pipe_state);
1586 if (tevent_req_is_nterror(req, &status)) {
1590 *reply_pdu = state->incoming_pdu;
1591 reply_pdu->mem_ctx = mem_ctx;
1594 * Prevent state->incoming_pdu from being freed
1595 * when state is freed.
1597 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1598 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1600 return NT_STATUS_OK;
1603 /*******************************************************************
1604 Creates krb5 auth bind.
1605 ********************************************************************/
1607 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1608 enum dcerpc_AuthLevel auth_level,
1609 RPC_HDR_AUTH *pauth_out,
1610 prs_struct *auth_data)
1614 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1615 DATA_BLOB tkt = data_blob_null;
1616 DATA_BLOB tkt_wrapped = data_blob_null;
1618 /* We may change the pad length before marshalling. */
1619 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1621 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1622 a->service_principal ));
1624 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1626 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1627 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1630 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1632 a->service_principal,
1633 error_message(ret) ));
1635 data_blob_free(&tkt);
1636 prs_mem_free(auth_data);
1637 return NT_STATUS_INVALID_PARAMETER;
1640 /* wrap that up in a nice GSS-API wrapping */
1641 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1643 data_blob_free(&tkt);
1645 /* Auth len in the rpc header doesn't include auth_header. */
1646 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1647 data_blob_free(&tkt_wrapped);
1648 prs_mem_free(auth_data);
1649 return NT_STATUS_NO_MEMORY;
1652 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1653 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1655 data_blob_free(&tkt_wrapped);
1656 return NT_STATUS_OK;
1658 return NT_STATUS_INVALID_PARAMETER;
1662 /*******************************************************************
1663 Creates SPNEGO NTLMSSP auth bind.
1664 ********************************************************************/
1666 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1667 enum dcerpc_AuthLevel auth_level,
1668 RPC_HDR_AUTH *pauth_out,
1669 prs_struct *auth_data)
1672 DATA_BLOB null_blob = data_blob_null;
1673 DATA_BLOB request = data_blob_null;
1674 DATA_BLOB spnego_msg = data_blob_null;
1676 /* We may change the pad length before marshalling. */
1677 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1679 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1680 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1684 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1685 data_blob_free(&request);
1686 prs_mem_free(auth_data);
1690 /* Wrap this in SPNEGO. */
1691 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1693 data_blob_free(&request);
1695 /* Auth len in the rpc header doesn't include auth_header. */
1696 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1697 data_blob_free(&spnego_msg);
1698 prs_mem_free(auth_data);
1699 return NT_STATUS_NO_MEMORY;
1702 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1703 dump_data(5, spnego_msg.data, spnego_msg.length);
1705 data_blob_free(&spnego_msg);
1706 return NT_STATUS_OK;
1709 /*******************************************************************
1710 Creates NTLMSSP auth bind.
1711 ********************************************************************/
1713 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1714 enum dcerpc_AuthLevel auth_level,
1715 RPC_HDR_AUTH *pauth_out,
1716 prs_struct *auth_data)
1719 DATA_BLOB null_blob = data_blob_null;
1720 DATA_BLOB request = data_blob_null;
1722 /* We may change the pad length before marshalling. */
1723 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1725 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1726 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1730 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1731 data_blob_free(&request);
1732 prs_mem_free(auth_data);
1736 /* Auth len in the rpc header doesn't include auth_header. */
1737 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1738 data_blob_free(&request);
1739 prs_mem_free(auth_data);
1740 return NT_STATUS_NO_MEMORY;
1743 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1744 dump_data(5, request.data, request.length);
1746 data_blob_free(&request);
1747 return NT_STATUS_OK;
1750 /*******************************************************************
1751 Creates schannel auth bind.
1752 ********************************************************************/
1754 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1755 enum dcerpc_AuthLevel auth_level,
1756 RPC_HDR_AUTH *pauth_out,
1757 prs_struct *auth_data)
1759 struct NL_AUTH_MESSAGE r;
1760 enum ndr_err_code ndr_err;
1763 /* We may change the pad length before marshalling. */
1764 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1766 /* Use lp_workgroup() if domain not specified */
1768 if (!cli->auth->domain || !cli->auth->domain[0]) {
1769 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1770 if (cli->auth->domain == NULL) {
1771 return NT_STATUS_NO_MEMORY;
1776 * Now marshall the data into the auth parse_struct.
1779 r.MessageType = NL_NEGOTIATE_REQUEST;
1780 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1781 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1782 r.oem_netbios_domain.a = cli->auth->domain;
1783 r.oem_netbios_computer.a = global_myname();
1785 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &r,
1786 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1787 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1788 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1789 prs_mem_free(auth_data);
1790 return ndr_map_error2ntstatus(ndr_err);
1793 if (DEBUGLEVEL >= 10) {
1794 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1797 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1799 prs_mem_free(auth_data);
1800 return NT_STATUS_NO_MEMORY;
1803 return NT_STATUS_OK;
1806 /*******************************************************************
1807 Creates the internals of a DCE/RPC bind request or alter context PDU.
1808 ********************************************************************/
1810 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1811 prs_struct *rpc_out,
1813 const struct ndr_syntax_id *abstract,
1814 const struct ndr_syntax_id *transfer,
1815 RPC_HDR_AUTH *phdr_auth,
1816 prs_struct *pauth_info)
1820 RPC_CONTEXT rpc_ctx;
1821 uint16 auth_len = prs_offset(pauth_info);
1822 uint8 ss_padding_len = 0;
1823 uint16 frag_len = 0;
1825 /* create the RPC context. */
1826 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1828 /* create the bind request RPC_HDR_RB */
1829 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1831 /* Start building the frag length. */
1832 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1834 /* Do we need to pad ? */
1836 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1837 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1838 ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1839 phdr_auth->auth_pad_len = ss_padding_len;
1841 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1844 /* Create the request RPC_HDR */
1845 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1847 /* Marshall the RPC header */
1848 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1849 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1850 return NT_STATUS_NO_MEMORY;
1853 /* Marshall the bind request data */
1854 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1855 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1856 return NT_STATUS_NO_MEMORY;
1860 * Grow the outgoing buffer to store any auth info.
1864 if (ss_padding_len) {
1865 char pad[CLIENT_NDR_PADDING_SIZE];
1866 memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1867 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1868 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1869 return NT_STATUS_NO_MEMORY;
1873 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1874 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1875 return NT_STATUS_NO_MEMORY;
1879 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1880 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1881 return NT_STATUS_NO_MEMORY;
1885 return NT_STATUS_OK;
1888 /*******************************************************************
1889 Creates a DCE/RPC bind request.
1890 ********************************************************************/
1892 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1893 prs_struct *rpc_out,
1895 const struct ndr_syntax_id *abstract,
1896 const struct ndr_syntax_id *transfer,
1897 enum pipe_auth_type auth_type,
1898 enum dcerpc_AuthLevel auth_level)
1900 RPC_HDR_AUTH hdr_auth;
1901 prs_struct auth_info;
1902 NTSTATUS ret = NT_STATUS_OK;
1904 ZERO_STRUCT(hdr_auth);
1905 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1906 return NT_STATUS_NO_MEMORY;
1908 switch (auth_type) {
1909 case PIPE_AUTH_TYPE_SCHANNEL:
1910 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1911 if (!NT_STATUS_IS_OK(ret)) {
1912 prs_mem_free(&auth_info);
1917 case PIPE_AUTH_TYPE_NTLMSSP:
1918 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1919 if (!NT_STATUS_IS_OK(ret)) {
1920 prs_mem_free(&auth_info);
1925 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1926 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1927 if (!NT_STATUS_IS_OK(ret)) {
1928 prs_mem_free(&auth_info);
1933 case PIPE_AUTH_TYPE_KRB5:
1934 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1935 if (!NT_STATUS_IS_OK(ret)) {
1936 prs_mem_free(&auth_info);
1941 case PIPE_AUTH_TYPE_NONE:
1945 /* "Can't" happen. */
1946 return NT_STATUS_INVALID_INFO_CLASS;
1949 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1957 prs_mem_free(&auth_info);
1961 /*******************************************************************
1962 Create and add the NTLMSSP sign/seal auth header and data.
1963 ********************************************************************/
1965 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1967 uint32 ss_padding_len,
1968 prs_struct *outgoing_pdu)
1970 RPC_HDR_AUTH auth_info;
1972 DATA_BLOB auth_blob = data_blob_null;
1973 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1976 if (!cli->auth->a_u.ntlmssp_state) {
1977 return NT_STATUS_INVALID_PARAMETER;
1980 frame = talloc_stackframe();
1982 /* Init and marshall the auth header. */
1983 init_rpc_hdr_auth(&auth_info,
1984 map_pipe_auth_type_to_rpc_auth_type(
1985 cli->auth->auth_type),
1986 cli->auth->auth_level,
1988 1 /* context id. */);
1990 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1991 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1993 return NT_STATUS_NO_MEMORY;
1996 switch (cli->auth->auth_level) {
1997 case DCERPC_AUTH_LEVEL_PRIVACY:
1998 /* Data portion is encrypted. */
1999 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2001 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2003 (unsigned char *)prs_data_p(outgoing_pdu),
2004 (size_t)prs_offset(outgoing_pdu),
2006 if (!NT_STATUS_IS_OK(status)) {
2012 case DCERPC_AUTH_LEVEL_INTEGRITY:
2013 /* Data is signed. */
2014 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2016 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2018 (unsigned char *)prs_data_p(outgoing_pdu),
2019 (size_t)prs_offset(outgoing_pdu),
2021 if (!NT_STATUS_IS_OK(status)) {
2029 smb_panic("bad auth level");
2031 return NT_STATUS_INVALID_PARAMETER;
2034 /* Finally marshall the blob. */
2036 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2037 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2038 (unsigned int)NTLMSSP_SIG_SIZE));
2040 return NT_STATUS_NO_MEMORY;
2044 return NT_STATUS_OK;
2047 /*******************************************************************
2048 Create and add the schannel sign/seal auth header and data.
2049 ********************************************************************/
2051 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2053 uint32 ss_padding_len,
2054 prs_struct *outgoing_pdu)
2056 RPC_HDR_AUTH auth_info;
2057 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2058 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2059 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2064 return NT_STATUS_INVALID_PARAMETER;
2067 /* Init and marshall the auth header. */
2068 init_rpc_hdr_auth(&auth_info,
2069 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2070 cli->auth->auth_level,
2072 1 /* context id. */);
2074 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2075 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2076 return NT_STATUS_NO_MEMORY;
2079 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2082 switch (cli->auth->auth_level) {
2083 case DCERPC_AUTH_LEVEL_PRIVACY:
2084 status = netsec_outgoing_packet(sas,
2091 case DCERPC_AUTH_LEVEL_INTEGRITY:
2092 status = netsec_outgoing_packet(sas,
2100 status = NT_STATUS_INTERNAL_ERROR;
2104 if (!NT_STATUS_IS_OK(status)) {
2105 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2106 nt_errstr(status)));
2110 if (DEBUGLEVEL >= 10) {
2111 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2114 /* Finally marshall the blob. */
2115 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2116 return NT_STATUS_NO_MEMORY;
2119 return NT_STATUS_OK;
2122 /*******************************************************************
2123 Calculate how much data we're going to send in this packet, also
2124 work out any sign/seal padding length.
2125 ********************************************************************/
2127 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2131 uint32 *p_ss_padding)
2133 uint32 data_space, data_len;
2136 if ((data_left > 0) && (sys_random() % 2)) {
2137 data_left = MAX(data_left/2, 1);
2141 switch (cli->auth->auth_level) {
2142 case DCERPC_AUTH_LEVEL_NONE:
2143 case DCERPC_AUTH_LEVEL_CONNECT:
2144 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2145 data_len = MIN(data_space, data_left);
2148 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2151 case DCERPC_AUTH_LEVEL_INTEGRITY:
2152 case DCERPC_AUTH_LEVEL_PRIVACY:
2153 /* Treat the same for all authenticated rpc requests. */
2154 switch(cli->auth->auth_type) {
2155 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2156 case PIPE_AUTH_TYPE_NTLMSSP:
2157 *p_auth_len = NTLMSSP_SIG_SIZE;
2159 case PIPE_AUTH_TYPE_SCHANNEL:
2160 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2163 smb_panic("bad auth type");
2167 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2168 RPC_HDR_AUTH_LEN - *p_auth_len;
2170 data_len = MIN(data_space, data_left);
2172 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2173 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2175 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2176 data_len + *p_ss_padding + /* data plus padding. */
2177 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2181 smb_panic("bad auth level");
2187 /*******************************************************************
2189 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2190 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2191 and deals with signing/sealing details.
2192 ********************************************************************/
2194 struct rpc_api_pipe_req_state {
2195 struct event_context *ev;
2196 struct rpc_pipe_client *cli;
2199 prs_struct *req_data;
2200 uint32_t req_data_sent;
2201 prs_struct outgoing_frag;
2202 prs_struct reply_pdu;
2205 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2207 prs_mem_free(&s->outgoing_frag);
2208 prs_mem_free(&s->reply_pdu);
2212 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2213 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2214 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2215 bool *is_last_frag);
2217 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2218 struct event_context *ev,
2219 struct rpc_pipe_client *cli,
2221 prs_struct *req_data)
2223 struct tevent_req *req, *subreq;
2224 struct rpc_api_pipe_req_state *state;
2228 req = tevent_req_create(mem_ctx, &state,
2229 struct rpc_api_pipe_req_state);
2235 state->op_num = op_num;
2236 state->req_data = req_data;
2237 state->req_data_sent = 0;
2238 state->call_id = get_rpc_call_id();
2240 if (cli->max_xmit_frag
2241 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2242 /* Server is screwed up ! */
2243 status = NT_STATUS_INVALID_PARAMETER;
2247 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2249 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2254 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2256 status = prepare_next_frag(state, &is_last_frag);
2257 if (!NT_STATUS_IS_OK(status)) {
2262 subreq = rpc_api_pipe_send(state, ev, state->cli,
2263 &state->outgoing_frag,
2264 DCERPC_PKT_RESPONSE);
2265 if (subreq == NULL) {
2268 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2270 subreq = rpc_write_send(
2271 state, ev, cli->transport,
2272 (uint8_t *)prs_data_p(&state->outgoing_frag),
2273 prs_offset(&state->outgoing_frag));
2274 if (subreq == NULL) {
2277 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2283 tevent_req_nterror(req, status);
2284 return tevent_req_post(req, ev);
2290 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2294 RPC_HDR_REQ hdr_req;
2295 uint32_t data_sent_thistime;
2299 uint32_t ss_padding;
2301 char pad[8] = { 0, };
2304 data_left = prs_offset(state->req_data) - state->req_data_sent;
2306 data_sent_thistime = calculate_data_len_tosend(
2307 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2309 if (state->req_data_sent == 0) {
2310 flags = DCERPC_PFC_FLAG_FIRST;
2313 if (data_sent_thistime == data_left) {
2314 flags |= DCERPC_PFC_FLAG_LAST;
2317 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2318 return NT_STATUS_NO_MEMORY;
2321 /* Create and marshall the header and request header. */
2322 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2325 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2326 return NT_STATUS_NO_MEMORY;
2329 /* Create the rpc request RPC_HDR_REQ */
2330 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2333 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2334 &state->outgoing_frag, 0)) {
2335 return NT_STATUS_NO_MEMORY;
2338 /* Copy in the data, plus any ss padding. */
2339 if (!prs_append_some_prs_data(&state->outgoing_frag,
2340 state->req_data, state->req_data_sent,
2341 data_sent_thistime)) {
2342 return NT_STATUS_NO_MEMORY;
2345 /* Copy the sign/seal padding data. */
2346 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2347 return NT_STATUS_NO_MEMORY;
2350 /* Generate any auth sign/seal and add the auth footer. */
2351 switch (state->cli->auth->auth_type) {
2352 case PIPE_AUTH_TYPE_NONE:
2353 status = NT_STATUS_OK;
2355 case PIPE_AUTH_TYPE_NTLMSSP:
2356 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2357 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2358 &state->outgoing_frag);
2360 case PIPE_AUTH_TYPE_SCHANNEL:
2361 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2362 &state->outgoing_frag);
2365 status = NT_STATUS_INVALID_PARAMETER;
2369 state->req_data_sent += data_sent_thistime;
2370 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2375 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2377 struct tevent_req *req = tevent_req_callback_data(
2378 subreq, struct tevent_req);
2379 struct rpc_api_pipe_req_state *state = tevent_req_data(
2380 req, struct rpc_api_pipe_req_state);
2384 status = rpc_write_recv(subreq);
2385 TALLOC_FREE(subreq);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 tevent_req_nterror(req, status);
2391 status = prepare_next_frag(state, &is_last_frag);
2392 if (!NT_STATUS_IS_OK(status)) {
2393 tevent_req_nterror(req, status);
2398 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2399 &state->outgoing_frag,
2400 DCERPC_PKT_RESPONSE);
2401 if (tevent_req_nomem(subreq, req)) {
2404 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2406 subreq = rpc_write_send(
2408 state->cli->transport,
2409 (uint8_t *)prs_data_p(&state->outgoing_frag),
2410 prs_offset(&state->outgoing_frag));
2411 if (tevent_req_nomem(subreq, req)) {
2414 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2419 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2421 struct tevent_req *req = tevent_req_callback_data(
2422 subreq, struct tevent_req);
2423 struct rpc_api_pipe_req_state *state = tevent_req_data(
2424 req, struct rpc_api_pipe_req_state);
2427 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2428 TALLOC_FREE(subreq);
2429 if (!NT_STATUS_IS_OK(status)) {
2430 tevent_req_nterror(req, status);
2433 tevent_req_done(req);
2436 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2437 prs_struct *reply_pdu)
2439 struct rpc_api_pipe_req_state *state = tevent_req_data(
2440 req, struct rpc_api_pipe_req_state);
2443 if (tevent_req_is_nterror(req, &status)) {
2445 * We always have to initialize to reply pdu, even if there is
2446 * none. The rpccli_* caller routines expect this.
2448 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2452 *reply_pdu = state->reply_pdu;
2453 reply_pdu->mem_ctx = mem_ctx;
2456 * Prevent state->req_pdu from being freed
2457 * when state is freed.
2459 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2460 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2462 return NT_STATUS_OK;
2466 /****************************************************************************
2467 Set the handle state.
2468 ****************************************************************************/
2470 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2471 const char *pipe_name, uint16 device_state)
2473 bool state_set = False;
2475 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2476 char *rparam = NULL;
2478 uint32 rparam_len, rdata_len;
2480 if (pipe_name == NULL)
2483 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2484 cli->fnum, pipe_name, device_state));
2486 /* create parameters: device state */
2487 SSVAL(param, 0, device_state);
2489 /* create setup parameters. */
2491 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2493 /* send the data on \PIPE\ */
2494 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2495 setup, 2, 0, /* setup, length, max */
2496 param, 2, 0, /* param, length, max */
2497 NULL, 0, 1024, /* data, length, max */
2498 &rparam, &rparam_len, /* return param, length */
2499 &rdata, &rdata_len)) /* return data, length */
2501 DEBUG(5, ("Set Handle state: return OK\n"));
2512 /****************************************************************************
2513 Check the rpc bind acknowledge response.
2514 ****************************************************************************/
2516 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2517 const struct ndr_syntax_id *transfer)
2519 if ( hdr_ba->addr.len == 0) {
2520 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2523 /* check the transfer syntax */
2524 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2525 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2526 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2530 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2531 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2532 hdr_ba->res.num_results, hdr_ba->res.reason));
2535 DEBUG(5,("check_bind_response: accepted!\n"));
2539 /*******************************************************************
2540 Creates a DCE/RPC bind authentication response.
2541 This is the packet that is sent back to the server once we
2542 have received a BIND-ACK, to finish the third leg of
2543 the authentication handshake.
2544 ********************************************************************/
2546 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2548 enum pipe_auth_type auth_type,
2549 enum dcerpc_AuthLevel auth_level,
2550 DATA_BLOB *pauth_blob,
2551 prs_struct *rpc_out)
2554 RPC_HDR_AUTH hdr_auth;
2557 /* Create the request RPC_HDR */
2558 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2559 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2560 pauth_blob->length );
2563 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2564 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2565 return NT_STATUS_NO_MEMORY;
2569 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2570 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2573 /* 4 bytes padding. */
2574 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2575 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2576 return NT_STATUS_NO_MEMORY;
2579 /* Create the request RPC_HDR_AUTHA */
2580 init_rpc_hdr_auth(&hdr_auth,
2581 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2584 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2585 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2586 return NT_STATUS_NO_MEMORY;
2590 * Append the auth data to the outgoing buffer.
2593 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2594 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2595 return NT_STATUS_NO_MEMORY;
2598 return NT_STATUS_OK;
2601 /*******************************************************************
2602 Creates a DCE/RPC bind alter context authentication request which
2603 may contain a spnego auth blobl
2604 ********************************************************************/
2606 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2607 const struct ndr_syntax_id *abstract,
2608 const struct ndr_syntax_id *transfer,
2609 enum dcerpc_AuthLevel auth_level,
2610 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2611 prs_struct *rpc_out)
2613 RPC_HDR_AUTH hdr_auth;
2614 prs_struct auth_info;
2615 NTSTATUS ret = NT_STATUS_OK;
2617 ZERO_STRUCT(hdr_auth);
2618 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2619 return NT_STATUS_NO_MEMORY;
2621 /* We may change the pad length before marshalling. */
2622 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2624 if (pauth_blob->length) {
2625 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2626 prs_mem_free(&auth_info);
2627 return NT_STATUS_NO_MEMORY;
2631 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2638 prs_mem_free(&auth_info);
2642 /****************************************************************************
2644 ****************************************************************************/
2646 struct rpc_pipe_bind_state {
2647 struct event_context *ev;
2648 struct rpc_pipe_client *cli;
2650 uint32_t rpc_call_id;
2653 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2655 prs_mem_free(&state->rpc_out);
2659 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2660 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2661 struct rpc_pipe_bind_state *state,
2662 struct rpc_hdr_info *phdr,
2663 prs_struct *reply_pdu);
2664 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2665 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2666 struct rpc_pipe_bind_state *state,
2667 struct rpc_hdr_info *phdr,
2668 prs_struct *reply_pdu);
2669 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2671 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2672 struct event_context *ev,
2673 struct rpc_pipe_client *cli,
2674 struct cli_pipe_auth_data *auth)
2676 struct tevent_req *req, *subreq;
2677 struct rpc_pipe_bind_state *state;
2680 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2685 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2686 rpccli_pipe_txt(talloc_tos(), cli),
2687 (unsigned int)auth->auth_type,
2688 (unsigned int)auth->auth_level ));
2692 state->rpc_call_id = get_rpc_call_id();
2694 prs_init_empty(&state->rpc_out, state, MARSHALL);
2695 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2697 cli->auth = talloc_move(cli, &auth);
2699 /* Marshall the outgoing data. */
2700 status = create_rpc_bind_req(cli, &state->rpc_out,
2702 &cli->abstract_syntax,
2703 &cli->transfer_syntax,
2704 cli->auth->auth_type,
2705 cli->auth->auth_level);
2707 if (!NT_STATUS_IS_OK(status)) {
2711 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2712 DCERPC_PKT_BIND_ACK);
2713 if (subreq == NULL) {
2716 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2720 tevent_req_nterror(req, status);
2721 return tevent_req_post(req, ev);
2727 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2729 struct tevent_req *req = tevent_req_callback_data(
2730 subreq, struct tevent_req);
2731 struct rpc_pipe_bind_state *state = tevent_req_data(
2732 req, struct rpc_pipe_bind_state);
2733 prs_struct reply_pdu;
2734 struct rpc_hdr_info hdr;
2735 struct rpc_hdr_ba_info hdr_ba;
2738 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2739 TALLOC_FREE(subreq);
2740 if (!NT_STATUS_IS_OK(status)) {
2741 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2742 rpccli_pipe_txt(talloc_tos(), state->cli),
2743 nt_errstr(status)));
2744 tevent_req_nterror(req, status);
2748 /* Unmarshall the RPC header */
2749 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2750 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2751 prs_mem_free(&reply_pdu);
2752 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2756 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2757 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2759 prs_mem_free(&reply_pdu);
2760 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2764 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2765 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2766 prs_mem_free(&reply_pdu);
2767 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2771 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2772 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2775 * For authenticated binds we may need to do 3 or 4 leg binds.
2778 switch(state->cli->auth->auth_type) {
2780 case PIPE_AUTH_TYPE_NONE:
2781 case PIPE_AUTH_TYPE_SCHANNEL:
2782 /* Bind complete. */
2783 prs_mem_free(&reply_pdu);
2784 tevent_req_done(req);
2787 case PIPE_AUTH_TYPE_NTLMSSP:
2788 /* Need to send AUTH3 packet - no reply. */
2789 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2791 prs_mem_free(&reply_pdu);
2792 if (!NT_STATUS_IS_OK(status)) {
2793 tevent_req_nterror(req, status);
2797 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2798 /* Need to send alter context request and reply. */
2799 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2801 prs_mem_free(&reply_pdu);
2802 if (!NT_STATUS_IS_OK(status)) {
2803 tevent_req_nterror(req, status);
2807 case PIPE_AUTH_TYPE_KRB5:
2811 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2812 (unsigned int)state->cli->auth->auth_type));
2813 prs_mem_free(&reply_pdu);
2814 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2818 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2819 struct rpc_pipe_bind_state *state,
2820 struct rpc_hdr_info *phdr,
2821 prs_struct *reply_pdu)
2823 DATA_BLOB server_response = data_blob_null;
2824 DATA_BLOB client_reply = data_blob_null;
2825 struct rpc_hdr_auth_info hdr_auth;
2826 struct tevent_req *subreq;
2829 if ((phdr->auth_len == 0)
2830 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2831 return NT_STATUS_INVALID_PARAMETER;
2834 if (!prs_set_offset(
2836 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2837 return NT_STATUS_INVALID_PARAMETER;
2840 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2841 return NT_STATUS_INVALID_PARAMETER;
2844 /* TODO - check auth_type/auth_level match. */
2846 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2847 prs_copy_data_out((char *)server_response.data, reply_pdu,
2850 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2851 server_response, &client_reply);
2853 if (!NT_STATUS_IS_OK(status)) {
2854 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2855 "blob failed: %s.\n", nt_errstr(status)));
2859 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2861 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2862 state->cli->auth->auth_type,
2863 state->cli->auth->auth_level,
2864 &client_reply, &state->rpc_out);
2865 data_blob_free(&client_reply);
2867 if (!NT_STATUS_IS_OK(status)) {
2871 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2872 (uint8_t *)prs_data_p(&state->rpc_out),
2873 prs_offset(&state->rpc_out));
2874 if (subreq == NULL) {
2875 return NT_STATUS_NO_MEMORY;
2877 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2878 return NT_STATUS_OK;
2881 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2883 struct tevent_req *req = tevent_req_callback_data(
2884 subreq, struct tevent_req);
2887 status = rpc_write_recv(subreq);
2888 TALLOC_FREE(subreq);
2889 if (!NT_STATUS_IS_OK(status)) {
2890 tevent_req_nterror(req, status);
2893 tevent_req_done(req);
2896 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2897 struct rpc_pipe_bind_state *state,
2898 struct rpc_hdr_info *phdr,
2899 prs_struct *reply_pdu)
2901 DATA_BLOB server_spnego_response = data_blob_null;
2902 DATA_BLOB server_ntlm_response = data_blob_null;
2903 DATA_BLOB client_reply = data_blob_null;
2904 DATA_BLOB tmp_blob = data_blob_null;
2905 RPC_HDR_AUTH hdr_auth;
2906 struct tevent_req *subreq;
2909 if ((phdr->auth_len == 0)
2910 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2911 return NT_STATUS_INVALID_PARAMETER;
2914 /* Process the returned NTLMSSP blob first. */
2915 if (!prs_set_offset(
2917 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2918 return NT_STATUS_INVALID_PARAMETER;
2921 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2922 return NT_STATUS_INVALID_PARAMETER;
2925 server_spnego_response = data_blob(NULL, phdr->auth_len);
2926 prs_copy_data_out((char *)server_spnego_response.data,
2927 reply_pdu, phdr->auth_len);
2930 * The server might give us back two challenges - tmp_blob is for the
2933 if (!spnego_parse_challenge(server_spnego_response,
2934 &server_ntlm_response, &tmp_blob)) {
2935 data_blob_free(&server_spnego_response);
2936 data_blob_free(&server_ntlm_response);
2937 data_blob_free(&tmp_blob);
2938 return NT_STATUS_INVALID_PARAMETER;
2941 /* We're finished with the server spnego response and the tmp_blob. */
2942 data_blob_free(&server_spnego_response);
2943 data_blob_free(&tmp_blob);
2945 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2946 server_ntlm_response, &client_reply);
2948 /* Finished with the server_ntlm response */
2949 data_blob_free(&server_ntlm_response);
2951 if (!NT_STATUS_IS_OK(status)) {
2952 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2953 "using server blob failed.\n"));
2954 data_blob_free(&client_reply);
2958 /* SPNEGO wrap the client reply. */
2959 tmp_blob = spnego_gen_auth(client_reply);
2960 data_blob_free(&client_reply);
2961 client_reply = tmp_blob;
2962 tmp_blob = data_blob_null;
2964 /* Now prepare the alter context pdu. */
2965 prs_init_empty(&state->rpc_out, state, MARSHALL);
2967 status = create_rpc_alter_context(state->rpc_call_id,
2968 &state->cli->abstract_syntax,
2969 &state->cli->transfer_syntax,
2970 state->cli->auth->auth_level,
2973 data_blob_free(&client_reply);
2975 if (!NT_STATUS_IS_OK(status)) {
2979 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2980 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2981 if (subreq == NULL) {
2982 return NT_STATUS_NO_MEMORY;
2984 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2985 return NT_STATUS_OK;
2988 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2990 struct tevent_req *req = tevent_req_callback_data(
2991 subreq, struct tevent_req);
2992 struct rpc_pipe_bind_state *state = tevent_req_data(
2993 req, struct rpc_pipe_bind_state);
2994 DATA_BLOB server_spnego_response = data_blob_null;
2995 DATA_BLOB tmp_blob = data_blob_null;
2996 prs_struct reply_pdu;
2997 struct rpc_hdr_info hdr;
2998 struct rpc_hdr_auth_info hdr_auth;
3001 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3002 TALLOC_FREE(subreq);
3003 if (!NT_STATUS_IS_OK(status)) {
3004 tevent_req_nterror(req, status);
3008 /* Get the auth blob from the reply. */
3009 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3010 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3011 "unmarshall RPC_HDR.\n"));
3012 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3016 if (!prs_set_offset(
3018 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3019 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3023 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3024 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3028 server_spnego_response = data_blob(NULL, hdr.auth_len);
3029 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3032 /* Check we got a valid auth response. */
3033 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3034 OID_NTLMSSP, &tmp_blob)) {
3035 data_blob_free(&server_spnego_response);
3036 data_blob_free(&tmp_blob);
3037 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3041 data_blob_free(&server_spnego_response);
3042 data_blob_free(&tmp_blob);
3044 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3045 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3046 tevent_req_done(req);
3049 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3051 return tevent_req_simple_recv_ntstatus(req);
3054 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3055 struct cli_pipe_auth_data *auth)
3057 TALLOC_CTX *frame = talloc_stackframe();
3058 struct event_context *ev;
3059 struct tevent_req *req;
3060 NTSTATUS status = NT_STATUS_OK;
3062 ev = event_context_init(frame);
3064 status = NT_STATUS_NO_MEMORY;
3068 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3070 status = NT_STATUS_NO_MEMORY;
3074 if (!tevent_req_poll(req, ev)) {
3075 status = map_nt_error_from_unix(errno);
3079 status = rpc_pipe_bind_recv(req);
3085 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3087 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3088 unsigned int timeout)
3092 if (rpc_cli->transport == NULL) {
3093 return RPCCLI_DEFAULT_TIMEOUT;
3096 if (rpc_cli->transport->set_timeout == NULL) {
3097 return RPCCLI_DEFAULT_TIMEOUT;
3100 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3102 return RPCCLI_DEFAULT_TIMEOUT;
3108 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3110 if (rpc_cli == NULL) {
3114 if (rpc_cli->transport == NULL) {
3118 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3121 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3123 struct cli_state *cli;
3125 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3126 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3127 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3131 cli = rpc_pipe_np_smb_conn(rpc_cli);
3135 E_md4hash(cli->password ? cli->password : "", nt_hash);
3139 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3140 struct cli_pipe_auth_data **presult)
3142 struct cli_pipe_auth_data *result;
3144 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3145 if (result == NULL) {
3146 return NT_STATUS_NO_MEMORY;
3149 result->auth_type = PIPE_AUTH_TYPE_NONE;
3150 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3152 result->user_name = talloc_strdup(result, "");
3153 result->domain = talloc_strdup(result, "");
3154 if ((result->user_name == NULL) || (result->domain == NULL)) {
3155 TALLOC_FREE(result);
3156 return NT_STATUS_NO_MEMORY;
3160 return NT_STATUS_OK;
3163 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3165 ntlmssp_end(&auth->a_u.ntlmssp_state);
3169 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3170 enum pipe_auth_type auth_type,
3171 enum dcerpc_AuthLevel auth_level,
3173 const char *username,
3174 const char *password,
3175 struct cli_pipe_auth_data **presult)
3177 struct cli_pipe_auth_data *result;
3180 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3181 if (result == NULL) {
3182 return NT_STATUS_NO_MEMORY;
3185 result->auth_type = auth_type;
3186 result->auth_level = auth_level;
3188 result->user_name = talloc_strdup(result, username);
3189 result->domain = talloc_strdup(result, domain);
3190 if ((result->user_name == NULL) || (result->domain == NULL)) {
3191 status = NT_STATUS_NO_MEMORY;
3195 status = ntlmssp_client_start(NULL,
3198 lp_client_ntlmv2_auth(),
3199 &result->a_u.ntlmssp_state);
3200 if (!NT_STATUS_IS_OK(status)) {
3204 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3206 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3207 if (!NT_STATUS_IS_OK(status)) {
3211 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3212 if (!NT_STATUS_IS_OK(status)) {
3216 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3217 if (!NT_STATUS_IS_OK(status)) {
3222 * Turn off sign+seal to allow selected auth level to turn it back on.
3224 result->a_u.ntlmssp_state->neg_flags &=
3225 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3227 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3228 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3229 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3230 result->a_u.ntlmssp_state->neg_flags
3231 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3235 return NT_STATUS_OK;
3238 TALLOC_FREE(result);
3242 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3243 enum dcerpc_AuthLevel auth_level,
3244 struct netlogon_creds_CredentialState *creds,
3245 struct cli_pipe_auth_data **presult)
3247 struct cli_pipe_auth_data *result;
3249 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3250 if (result == NULL) {
3251 return NT_STATUS_NO_MEMORY;
3254 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3255 result->auth_level = auth_level;
3257 result->user_name = talloc_strdup(result, "");
3258 result->domain = talloc_strdup(result, domain);
3259 if ((result->user_name == NULL) || (result->domain == NULL)) {
3263 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3264 if (result->a_u.schannel_auth == NULL) {
3268 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3269 result->a_u.schannel_auth->seq_num = 0;
3270 result->a_u.schannel_auth->initiator = true;
3271 result->a_u.schannel_auth->creds = creds;
3274 return NT_STATUS_OK;
3277 TALLOC_FREE(result);
3278 return NT_STATUS_NO_MEMORY;
3282 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3284 data_blob_free(&auth->session_key);
3289 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3290 enum dcerpc_AuthLevel auth_level,
3291 const char *service_princ,
3292 const char *username,
3293 const char *password,
3294 struct cli_pipe_auth_data **presult)
3297 struct cli_pipe_auth_data *result;
3299 if ((username != NULL) && (password != NULL)) {
3300 int ret = kerberos_kinit_password(username, password, 0, NULL);
3302 return NT_STATUS_ACCESS_DENIED;
3306 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3307 if (result == NULL) {
3308 return NT_STATUS_NO_MEMORY;
3311 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3312 result->auth_level = auth_level;
3315 * Username / domain need fixing!
3317 result->user_name = talloc_strdup(result, "");
3318 result->domain = talloc_strdup(result, "");
3319 if ((result->user_name == NULL) || (result->domain == NULL)) {
3323 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3324 result, struct kerberos_auth_struct);
3325 if (result->a_u.kerberos_auth == NULL) {
3328 talloc_set_destructor(result->a_u.kerberos_auth,
3329 cli_auth_kerberos_data_destructor);
3331 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3332 result, service_princ);
3333 if (result->a_u.kerberos_auth->service_principal == NULL) {
3338 return NT_STATUS_OK;
3341 TALLOC_FREE(result);
3342 return NT_STATUS_NO_MEMORY;
3344 return NT_STATUS_NOT_SUPPORTED;
3349 * Create an rpc pipe client struct, connecting to a tcp port.
3351 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3353 const struct ndr_syntax_id *abstract_syntax,
3354 struct rpc_pipe_client **presult)
3356 struct rpc_pipe_client *result;
3357 struct sockaddr_storage addr;
3361 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3362 if (result == NULL) {
3363 return NT_STATUS_NO_MEMORY;
3366 result->abstract_syntax = *abstract_syntax;
3367 result->transfer_syntax = ndr_transfer_syntax;
3368 result->dispatch = cli_do_rpc_ndr;
3369 result->dispatch_send = cli_do_rpc_ndr_send;
3370 result->dispatch_recv = cli_do_rpc_ndr_recv;
3372 result->desthost = talloc_strdup(result, host);
3373 result->srv_name_slash = talloc_asprintf_strupper_m(
3374 result, "\\\\%s", result->desthost);
3375 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3376 status = NT_STATUS_NO_MEMORY;
3380 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3381 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3383 if (!resolve_name(host, &addr, 0, false)) {
3384 status = NT_STATUS_NOT_FOUND;
3388 status = open_socket_out(&addr, port, 60, &fd);
3389 if (!NT_STATUS_IS_OK(status)) {
3392 set_socket_options(fd, lp_socket_options());
3394 status = rpc_transport_sock_init(result, fd, &result->transport);
3395 if (!NT_STATUS_IS_OK(status)) {
3400 result->transport->transport = NCACN_IP_TCP;
3403 return NT_STATUS_OK;
3406 TALLOC_FREE(result);
3411 * Determine the tcp port on which a dcerpc interface is listening
3412 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3415 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3416 const struct ndr_syntax_id *abstract_syntax,
3420 struct rpc_pipe_client *epm_pipe = NULL;
3421 struct cli_pipe_auth_data *auth = NULL;
3422 struct dcerpc_binding *map_binding = NULL;
3423 struct dcerpc_binding *res_binding = NULL;
3424 struct epm_twr_t *map_tower = NULL;
3425 struct epm_twr_t *res_towers = NULL;
3426 struct policy_handle *entry_handle = NULL;
3427 uint32_t num_towers = 0;
3428 uint32_t max_towers = 1;
3429 struct epm_twr_p_t towers;
3430 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3432 if (pport == NULL) {
3433 status = NT_STATUS_INVALID_PARAMETER;
3437 /* open the connection to the endpoint mapper */
3438 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3439 &ndr_table_epmapper.syntax_id,
3442 if (!NT_STATUS_IS_OK(status)) {
3446 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3447 if (!NT_STATUS_IS_OK(status)) {
3451 status = rpc_pipe_bind(epm_pipe, auth);
3452 if (!NT_STATUS_IS_OK(status)) {
3456 /* create tower for asking the epmapper */
3458 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3459 if (map_binding == NULL) {
3460 status = NT_STATUS_NO_MEMORY;
3464 map_binding->transport = NCACN_IP_TCP;
3465 map_binding->object = *abstract_syntax;
3466 map_binding->host = host; /* needed? */
3467 map_binding->endpoint = "0"; /* correct? needed? */
3469 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3470 if (map_tower == NULL) {
3471 status = NT_STATUS_NO_MEMORY;
3475 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3476 &(map_tower->tower));
3477 if (!NT_STATUS_IS_OK(status)) {
3481 /* allocate further parameters for the epm_Map call */
3483 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3484 if (res_towers == NULL) {
3485 status = NT_STATUS_NO_MEMORY;
3488 towers.twr = res_towers;
3490 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3491 if (entry_handle == NULL) {
3492 status = NT_STATUS_NO_MEMORY;
3496 /* ask the endpoint mapper for the port */
3498 status = rpccli_epm_Map(epm_pipe,
3500 CONST_DISCARD(struct GUID *,
3501 &(abstract_syntax->uuid)),
3508 if (!NT_STATUS_IS_OK(status)) {
3512 if (num_towers != 1) {
3513 status = NT_STATUS_UNSUCCESSFUL;
3517 /* extract the port from the answer */
3519 status = dcerpc_binding_from_tower(tmp_ctx,
3520 &(towers.twr->tower),
3522 if (!NT_STATUS_IS_OK(status)) {
3526 /* are further checks here necessary? */
3527 if (res_binding->transport != NCACN_IP_TCP) {
3528 status = NT_STATUS_UNSUCCESSFUL;
3532 *pport = (uint16_t)atoi(res_binding->endpoint);
3535 TALLOC_FREE(tmp_ctx);
3540 * Create a rpc pipe client struct, connecting to a host via tcp.
3541 * The port is determined by asking the endpoint mapper on the given
3544 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3545 const struct ndr_syntax_id *abstract_syntax,
3546 struct rpc_pipe_client **presult)
3551 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3552 if (!NT_STATUS_IS_OK(status)) {
3556 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3557 abstract_syntax, presult);
3560 /********************************************************************
3561 Create a rpc pipe client struct, connecting to a unix domain socket
3562 ********************************************************************/
3563 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3564 const struct ndr_syntax_id *abstract_syntax,
3565 struct rpc_pipe_client **presult)
3567 struct rpc_pipe_client *result;
3568 struct sockaddr_un addr;
3572 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3573 if (result == NULL) {
3574 return NT_STATUS_NO_MEMORY;
3577 result->abstract_syntax = *abstract_syntax;
3578 result->transfer_syntax = ndr_transfer_syntax;
3579 result->dispatch = cli_do_rpc_ndr;
3580 result->dispatch_send = cli_do_rpc_ndr_send;
3581 result->dispatch_recv = cli_do_rpc_ndr_recv;
3583 result->desthost = get_myname(result);
3584 result->srv_name_slash = talloc_asprintf_strupper_m(
3585 result, "\\\\%s", result->desthost);
3586 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3587 status = NT_STATUS_NO_MEMORY;
3591 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3592 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3594 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3596 status = map_nt_error_from_unix(errno);
3601 addr.sun_family = AF_UNIX;
3602 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3604 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3605 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3608 return map_nt_error_from_unix(errno);
3611 status = rpc_transport_sock_init(result, fd, &result->transport);
3612 if (!NT_STATUS_IS_OK(status)) {
3617 result->transport->transport = NCALRPC;
3620 return NT_STATUS_OK;
3623 TALLOC_FREE(result);
3627 struct rpc_pipe_client_np_ref {
3628 struct cli_state *cli;
3629 struct rpc_pipe_client *pipe;
3632 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3634 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3638 /****************************************************************************
3639 Open a named pipe over SMB to a remote server.
3641 * CAVEAT CALLER OF THIS FUNCTION:
3642 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3643 * so be sure that this function is called AFTER any structure (vs pointer)
3644 * assignment of the cli. In particular, libsmbclient does structure
3645 * assignments of cli, which invalidates the data in the returned
3646 * rpc_pipe_client if this function is called before the structure assignment
3649 ****************************************************************************/
3651 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3652 const struct ndr_syntax_id *abstract_syntax,
3653 struct rpc_pipe_client **presult)
3655 struct rpc_pipe_client *result;
3657 struct rpc_pipe_client_np_ref *np_ref;
3659 /* sanity check to protect against crashes */
3662 return NT_STATUS_INVALID_HANDLE;
3665 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3666 if (result == NULL) {
3667 return NT_STATUS_NO_MEMORY;
3670 result->abstract_syntax = *abstract_syntax;
3671 result->transfer_syntax = ndr_transfer_syntax;
3672 result->dispatch = cli_do_rpc_ndr;
3673 result->dispatch_send = cli_do_rpc_ndr_send;
3674 result->dispatch_recv = cli_do_rpc_ndr_recv;
3675 result->desthost = talloc_strdup(result, cli->desthost);
3676 result->srv_name_slash = talloc_asprintf_strupper_m(
3677 result, "\\\\%s", result->desthost);
3679 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3680 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3682 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3683 TALLOC_FREE(result);
3684 return NT_STATUS_NO_MEMORY;
3687 status = rpc_transport_np_init(result, cli, abstract_syntax,
3688 &result->transport);
3689 if (!NT_STATUS_IS_OK(status)) {
3690 TALLOC_FREE(result);
3694 result->transport->transport = NCACN_NP;
3696 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3697 if (np_ref == NULL) {
3698 TALLOC_FREE(result);
3699 return NT_STATUS_NO_MEMORY;
3702 np_ref->pipe = result;
3704 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3705 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3708 return NT_STATUS_OK;
3711 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3712 struct rpc_cli_smbd_conn *conn,
3713 const struct ndr_syntax_id *syntax,
3714 struct rpc_pipe_client **presult)
3716 struct rpc_pipe_client *result;
3717 struct cli_pipe_auth_data *auth;
3720 result = talloc(mem_ctx, struct rpc_pipe_client);
3721 if (result == NULL) {
3722 return NT_STATUS_NO_MEMORY;
3724 result->abstract_syntax = *syntax;
3725 result->transfer_syntax = ndr_transfer_syntax;
3726 result->dispatch = cli_do_rpc_ndr;
3727 result->dispatch_send = cli_do_rpc_ndr_send;
3728 result->dispatch_recv = cli_do_rpc_ndr_recv;
3729 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3730 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3732 result->desthost = talloc_strdup(result, global_myname());
3733 result->srv_name_slash = talloc_asprintf_strupper_m(
3734 result, "\\\\%s", global_myname());
3735 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3736 TALLOC_FREE(result);
3737 return NT_STATUS_NO_MEMORY;
3740 status = rpc_transport_smbd_init(result, conn, syntax,
3741 &result->transport);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3744 nt_errstr(status)));
3745 TALLOC_FREE(result);
3749 status = rpccli_anon_bind_data(result, &auth);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3752 nt_errstr(status)));
3753 TALLOC_FREE(result);
3757 status = rpc_pipe_bind(result, auth);
3758 if (!NT_STATUS_IS_OK(status)) {
3759 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3760 TALLOC_FREE(result);
3764 result->transport->transport = NCACN_INTERNAL;
3767 return NT_STATUS_OK;
3770 /****************************************************************************
3771 Open a pipe to a remote server.
3772 ****************************************************************************/
3774 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3775 enum dcerpc_transport_t transport,
3776 const struct ndr_syntax_id *interface,
3777 struct rpc_pipe_client **presult)
3779 switch (transport) {
3781 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3784 return rpc_pipe_open_np(cli, interface, presult);
3786 return NT_STATUS_NOT_IMPLEMENTED;
3790 /****************************************************************************
3791 Open a named pipe to an SMB server and bind anonymously.
3792 ****************************************************************************/
3794 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3795 enum dcerpc_transport_t transport,
3796 const struct ndr_syntax_id *interface,
3797 struct rpc_pipe_client **presult)
3799 struct rpc_pipe_client *result;
3800 struct cli_pipe_auth_data *auth;
3803 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3804 if (!NT_STATUS_IS_OK(status)) {
3808 status = rpccli_anon_bind_data(result, &auth);
3809 if (!NT_STATUS_IS_OK(status)) {
3810 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3811 nt_errstr(status)));
3812 TALLOC_FREE(result);
3817 * This is a bit of an abstraction violation due to the fact that an
3818 * anonymous bind on an authenticated SMB inherits the user/domain
3819 * from the enclosing SMB creds
3822 TALLOC_FREE(auth->user_name);
3823 TALLOC_FREE(auth->domain);
3825 auth->user_name = talloc_strdup(auth, cli->user_name);
3826 auth->domain = talloc_strdup(auth, cli->domain);
3827 auth->user_session_key = data_blob_talloc(auth,
3828 cli->user_session_key.data,
3829 cli->user_session_key.length);
3831 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3832 TALLOC_FREE(result);
3833 return NT_STATUS_NO_MEMORY;
3836 status = rpc_pipe_bind(result, auth);
3837 if (!NT_STATUS_IS_OK(status)) {
3839 if (ndr_syntax_id_equal(interface,
3840 &ndr_table_dssetup.syntax_id)) {
3841 /* non AD domains just don't have this pipe, avoid
3842 * level 0 statement in that case - gd */
3845 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3846 "%s failed with error %s\n",
3847 get_pipe_name_from_syntax(talloc_tos(), interface),
3848 nt_errstr(status) ));
3849 TALLOC_FREE(result);
3853 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3854 "%s and bound anonymously.\n",
3855 get_pipe_name_from_syntax(talloc_tos(), interface),
3859 return NT_STATUS_OK;
3862 /****************************************************************************
3863 ****************************************************************************/
3865 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3866 const struct ndr_syntax_id *interface,
3867 struct rpc_pipe_client **presult)
3869 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3870 interface, presult);
3873 /****************************************************************************
3874 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3875 ****************************************************************************/
3877 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3878 const struct ndr_syntax_id *interface,
3879 enum dcerpc_transport_t transport,
3880 enum pipe_auth_type auth_type,
3881 enum dcerpc_AuthLevel auth_level,
3883 const char *username,
3884 const char *password,
3885 struct rpc_pipe_client **presult)
3887 struct rpc_pipe_client *result;
3888 struct cli_pipe_auth_data *auth;
3891 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3892 if (!NT_STATUS_IS_OK(status)) {
3896 status = rpccli_ntlmssp_bind_data(
3897 result, auth_type, auth_level, domain, username,
3899 if (!NT_STATUS_IS_OK(status)) {
3900 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3901 nt_errstr(status)));
3905 status = rpc_pipe_bind(result, auth);
3906 if (!NT_STATUS_IS_OK(status)) {
3907 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3908 nt_errstr(status) ));
3912 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3913 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3914 get_pipe_name_from_syntax(talloc_tos(), interface),
3915 cli->desthost, domain, username ));
3918 return NT_STATUS_OK;
3922 TALLOC_FREE(result);
3926 /****************************************************************************
3928 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3929 ****************************************************************************/
3931 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3932 const struct ndr_syntax_id *interface,
3933 enum dcerpc_transport_t transport,
3934 enum dcerpc_AuthLevel auth_level,
3936 const char *username,
3937 const char *password,
3938 struct rpc_pipe_client **presult)
3940 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3943 PIPE_AUTH_TYPE_NTLMSSP,
3951 /****************************************************************************
3953 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3954 ****************************************************************************/
3956 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3957 const struct ndr_syntax_id *interface,
3958 enum dcerpc_transport_t transport,
3959 enum dcerpc_AuthLevel auth_level,
3961 const char *username,
3962 const char *password,
3963 struct rpc_pipe_client **presult)
3965 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3968 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3976 /****************************************************************************
3977 Get a the schannel session key out of an already opened netlogon pipe.
3978 ****************************************************************************/
3979 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3980 struct cli_state *cli,
3984 enum netr_SchannelType sec_chan_type = 0;
3985 unsigned char machine_pwd[16];
3986 const char *machine_account;
3989 /* Get the machine account credentials from secrets.tdb. */
3990 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3993 DEBUG(0, ("get_schannel_session_key: could not fetch "
3994 "trust account password for domain '%s'\n",
3996 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3999 status = rpccli_netlogon_setup_creds(netlogon_pipe,
4000 cli->desthost, /* server name */
4001 domain, /* domain */
4002 global_myname(), /* client name */
4003 machine_account, /* machine account name */
4008 if (!NT_STATUS_IS_OK(status)) {
4009 DEBUG(3, ("get_schannel_session_key_common: "
4010 "rpccli_netlogon_setup_creds failed with result %s "
4011 "to server %s, domain %s, machine account %s.\n",
4012 nt_errstr(status), cli->desthost, domain,
4017 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4018 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4020 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4023 return NT_STATUS_OK;;
4026 /****************************************************************************
4027 Open a netlogon pipe and get the schannel session key.
4028 Now exposed to external callers.
4029 ****************************************************************************/
4032 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4035 struct rpc_pipe_client **presult)
4037 struct rpc_pipe_client *netlogon_pipe = NULL;
4040 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4042 if (!NT_STATUS_IS_OK(status)) {
4046 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4048 if (!NT_STATUS_IS_OK(status)) {
4049 TALLOC_FREE(netlogon_pipe);
4053 *presult = netlogon_pipe;
4054 return NT_STATUS_OK;
4057 /****************************************************************************
4059 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4060 using session_key. sign and seal.
4062 The *pdc will be stolen onto this new pipe
4063 ****************************************************************************/
4065 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4066 const struct ndr_syntax_id *interface,
4067 enum dcerpc_transport_t transport,
4068 enum dcerpc_AuthLevel auth_level,
4070 struct netlogon_creds_CredentialState **pdc,
4071 struct rpc_pipe_client **presult)
4073 struct rpc_pipe_client *result;
4074 struct cli_pipe_auth_data *auth;
4077 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4078 if (!NT_STATUS_IS_OK(status)) {
4082 status = rpccli_schannel_bind_data(result, domain, auth_level,
4084 if (!NT_STATUS_IS_OK(status)) {
4085 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4086 nt_errstr(status)));
4087 TALLOC_FREE(result);
4091 status = rpc_pipe_bind(result, auth);
4092 if (!NT_STATUS_IS_OK(status)) {
4093 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4094 "cli_rpc_pipe_bind failed with error %s\n",
4095 nt_errstr(status) ));
4096 TALLOC_FREE(result);
4101 * The credentials on a new netlogon pipe are the ones we are passed
4102 * in - reference them in
4104 result->dc = talloc_move(result, pdc);
4106 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4107 "for domain %s and bound using schannel.\n",
4108 get_pipe_name_from_syntax(talloc_tos(), interface),
4109 cli->desthost, domain ));
4112 return NT_STATUS_OK;
4115 /****************************************************************************
4116 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4117 Fetch the session key ourselves using a temporary netlogon pipe. This
4118 version uses an ntlmssp auth bound netlogon pipe to get the key.
4119 ****************************************************************************/
4121 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4123 const char *username,
4124 const char *password,
4126 struct rpc_pipe_client **presult)
4128 struct rpc_pipe_client *netlogon_pipe = NULL;
4131 status = cli_rpc_pipe_open_spnego_ntlmssp(
4132 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4133 DCERPC_AUTH_LEVEL_PRIVACY,
4134 domain, username, password, &netlogon_pipe);
4135 if (!NT_STATUS_IS_OK(status)) {
4139 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4141 if (!NT_STATUS_IS_OK(status)) {
4142 TALLOC_FREE(netlogon_pipe);
4146 *presult = netlogon_pipe;
4147 return NT_STATUS_OK;
4150 /****************************************************************************
4151 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4152 Fetch the session key ourselves using a temporary netlogon pipe. This version
4153 uses an ntlmssp bind to get the session key.
4154 ****************************************************************************/
4156 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4157 const struct ndr_syntax_id *interface,
4158 enum dcerpc_transport_t transport,
4159 enum dcerpc_AuthLevel auth_level,
4161 const char *username,
4162 const char *password,
4163 struct rpc_pipe_client **presult)
4165 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4166 struct rpc_pipe_client *netlogon_pipe = NULL;
4167 struct rpc_pipe_client *result = NULL;
4170 status = get_schannel_session_key_auth_ntlmssp(
4171 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4172 if (!NT_STATUS_IS_OK(status)) {
4173 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4174 "key from server %s for domain %s.\n",
4175 cli->desthost, domain ));
4179 status = cli_rpc_pipe_open_schannel_with_key(
4180 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4183 /* Now we've bound using the session key we can close the netlog pipe. */
4184 TALLOC_FREE(netlogon_pipe);
4186 if (NT_STATUS_IS_OK(status)) {
4192 /****************************************************************************
4193 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4194 Fetch the session key ourselves using a temporary netlogon pipe.
4195 ****************************************************************************/
4197 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4198 const struct ndr_syntax_id *interface,
4199 enum dcerpc_transport_t transport,
4200 enum dcerpc_AuthLevel auth_level,
4202 struct rpc_pipe_client **presult)
4204 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4205 struct rpc_pipe_client *netlogon_pipe = NULL;
4206 struct rpc_pipe_client *result = NULL;
4209 status = get_schannel_session_key(cli, domain, &neg_flags,
4211 if (!NT_STATUS_IS_OK(status)) {
4212 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4213 "key from server %s for domain %s.\n",
4214 cli->desthost, domain ));
4218 status = cli_rpc_pipe_open_schannel_with_key(
4219 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4222 /* Now we've bound using the session key we can close the netlog pipe. */
4223 TALLOC_FREE(netlogon_pipe);
4225 if (NT_STATUS_IS_OK(status)) {
4232 /****************************************************************************
4233 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4234 The idea is this can be called with service_princ, username and password all
4235 NULL so long as the caller has a TGT.
4236 ****************************************************************************/
4238 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4239 const struct ndr_syntax_id *interface,
4240 enum dcerpc_AuthLevel auth_level,
4241 const char *service_princ,
4242 const char *username,
4243 const char *password,
4244 struct rpc_pipe_client **presult)
4247 struct rpc_pipe_client *result;
4248 struct cli_pipe_auth_data *auth;
4251 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4252 if (!NT_STATUS_IS_OK(status)) {
4256 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4257 username, password, &auth);
4258 if (!NT_STATUS_IS_OK(status)) {
4259 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4260 nt_errstr(status)));
4261 TALLOC_FREE(result);
4265 status = rpc_pipe_bind(result, auth);
4266 if (!NT_STATUS_IS_OK(status)) {
4267 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4268 "with error %s\n", nt_errstr(status)));
4269 TALLOC_FREE(result);
4274 return NT_STATUS_OK;
4276 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4277 return NT_STATUS_NOT_IMPLEMENTED;
4281 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4282 struct rpc_pipe_client *cli,
4283 DATA_BLOB *session_key)
4285 if (!session_key || !cli) {
4286 return NT_STATUS_INVALID_PARAMETER;
4290 return NT_STATUS_INVALID_PARAMETER;
4293 switch (cli->auth->auth_type) {
4294 case PIPE_AUTH_TYPE_SCHANNEL:
4295 *session_key = data_blob_talloc(mem_ctx,
4296 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4298 case PIPE_AUTH_TYPE_NTLMSSP:
4299 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4300 *session_key = data_blob_talloc(mem_ctx,
4301 cli->auth->a_u.ntlmssp_state->session_key.data,
4302 cli->auth->a_u.ntlmssp_state->session_key.length);
4304 case PIPE_AUTH_TYPE_KRB5:
4305 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4306 *session_key = data_blob_talloc(mem_ctx,
4307 cli->auth->a_u.kerberos_auth->session_key.data,
4308 cli->auth->a_u.kerberos_auth->session_key.length);
4310 case PIPE_AUTH_TYPE_NONE:
4311 *session_key = data_blob_talloc(mem_ctx,
4312 cli->auth->user_session_key.data,
4313 cli->auth->user_session_key.length);
4316 return NT_STATUS_NO_USER_SESSION_KEY;
4319 return NT_STATUS_OK;