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 void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1377 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1379 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1380 struct event_context *ev,
1381 struct rpc_pipe_client *cli,
1382 prs_struct *data, /* Outgoing PDU */
1383 uint8_t expected_pkt_type)
1385 struct tevent_req *req, *subreq;
1386 struct rpc_api_pipe_state *state;
1387 uint16_t max_recv_frag;
1390 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1396 state->expected_pkt_type = expected_pkt_type;
1397 state->incoming_pdu_offset = 0;
1399 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1401 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1402 /* Make incoming_pdu dynamic with no memory. */
1403 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1406 * Ensure we're not sending too much.
1408 if (prs_offset(data) > cli->max_xmit_frag) {
1409 status = NT_STATUS_INVALID_PARAMETER;
1413 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1415 max_recv_frag = cli->max_recv_frag;
1418 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1421 subreq = cli_api_pipe_send(state, ev, cli->transport,
1422 (uint8_t *)prs_data_p(data),
1423 prs_offset(data), max_recv_frag);
1424 if (subreq == NULL) {
1427 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1431 tevent_req_nterror(req, status);
1432 return tevent_req_post(req, ev);
1438 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1440 struct tevent_req *req = tevent_req_callback_data(
1441 subreq, struct tevent_req);
1442 struct rpc_api_pipe_state *state = tevent_req_data(
1443 req, struct rpc_api_pipe_state);
1445 uint8_t *rdata = NULL;
1446 uint32_t rdata_len = 0;
1448 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1449 TALLOC_FREE(subreq);
1450 if (!NT_STATUS_IS_OK(status)) {
1451 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1452 tevent_req_nterror(req, status);
1456 if (rdata == NULL) {
1457 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1458 rpccli_pipe_txt(talloc_tos(), state->cli)));
1459 tevent_req_done(req);
1464 * This is equivalent to a talloc_steal - gives rdata to
1465 * the prs_struct state->incoming_frag.
1467 prs_give_memory(&state->incoming_frag, (char *)rdata, rdata_len, true);
1470 /* Ensure we have enough data for a pdu. */
1471 subreq = get_complete_frag_send(state, state->ev, state->cli,
1472 &state->rhdr, &state->incoming_frag);
1473 if (tevent_req_nomem(subreq, req)) {
1476 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1479 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1481 struct tevent_req *req = tevent_req_callback_data(
1482 subreq, struct tevent_req);
1483 struct rpc_api_pipe_state *state = tevent_req_data(
1484 req, struct rpc_api_pipe_state);
1487 uint32_t rdata_len = 0;
1489 status = get_complete_frag_recv(subreq);
1490 TALLOC_FREE(subreq);
1491 if (!NT_STATUS_IS_OK(status)) {
1492 DEBUG(5, ("get_complete_frag failed: %s\n",
1493 nt_errstr(status)));
1494 tevent_req_nterror(req, status);
1498 status = cli_pipe_validate_current_pdu(
1499 state->cli, &state->rhdr, &state->incoming_frag,
1500 state->expected_pkt_type, &rdata, &rdata_len,
1501 &state->incoming_pdu);
1503 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1504 (unsigned)prs_data_size(&state->incoming_frag),
1505 (unsigned)state->incoming_pdu_offset,
1506 nt_errstr(status)));
1508 if (!NT_STATUS_IS_OK(status)) {
1509 tevent_req_nterror(req, status);
1513 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1514 && (state->rhdr.pack_type[0] == 0)) {
1516 * Set the data type correctly for big-endian data on the
1519 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1521 rpccli_pipe_txt(talloc_tos(), state->cli)));
1522 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1525 * Check endianness on subsequent packets.
1527 if (state->incoming_frag.bigendian_data
1528 != state->incoming_pdu.bigendian_data) {
1529 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1531 state->incoming_pdu.bigendian_data?"big":"little",
1532 state->incoming_frag.bigendian_data?"big":"little"));
1533 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1537 /* Now copy the data portion out of the pdu into rbuf. */
1538 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1539 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1543 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1544 rdata, (size_t)rdata_len);
1545 state->incoming_pdu_offset += rdata_len;
1547 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1548 &state->incoming_frag);
1549 if (!NT_STATUS_IS_OK(status)) {
1550 tevent_req_nterror(req, status);
1554 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1555 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1556 rpccli_pipe_txt(talloc_tos(), state->cli),
1557 (unsigned)prs_data_size(&state->incoming_pdu)));
1558 tevent_req_done(req);
1562 subreq = get_complete_frag_send(state, state->ev, state->cli,
1563 &state->rhdr, &state->incoming_frag);
1564 if (tevent_req_nomem(subreq, req)) {
1567 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1570 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1571 prs_struct *reply_pdu)
1573 struct rpc_api_pipe_state *state = tevent_req_data(
1574 req, struct rpc_api_pipe_state);
1577 if (tevent_req_is_nterror(req, &status)) {
1581 *reply_pdu = state->incoming_pdu;
1582 reply_pdu->mem_ctx = mem_ctx;
1585 * Prevent state->incoming_pdu from being freed
1586 * when state is freed.
1588 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
1589 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1591 return NT_STATUS_OK;
1594 /*******************************************************************
1595 Creates krb5 auth bind.
1596 ********************************************************************/
1598 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1599 enum dcerpc_AuthLevel auth_level,
1600 RPC_HDR_AUTH *pauth_out,
1601 prs_struct *auth_data)
1605 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1606 DATA_BLOB tkt = data_blob_null;
1607 DATA_BLOB tkt_wrapped = data_blob_null;
1609 /* We may change the pad length before marshalling. */
1610 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1612 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1613 a->service_principal ));
1615 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1617 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1618 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1621 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1623 a->service_principal,
1624 error_message(ret) ));
1626 data_blob_free(&tkt);
1627 return NT_STATUS_INVALID_PARAMETER;
1630 /* wrap that up in a nice GSS-API wrapping */
1631 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1633 data_blob_free(&tkt);
1635 /* Auth len in the rpc header doesn't include auth_header. */
1636 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1637 data_blob_free(&tkt_wrapped);
1638 return NT_STATUS_NO_MEMORY;
1641 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1642 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1644 data_blob_free(&tkt_wrapped);
1645 return NT_STATUS_OK;
1647 return NT_STATUS_INVALID_PARAMETER;
1651 /*******************************************************************
1652 Creates SPNEGO NTLMSSP auth bind.
1653 ********************************************************************/
1655 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1656 enum dcerpc_AuthLevel auth_level,
1657 RPC_HDR_AUTH *pauth_out,
1658 prs_struct *auth_data)
1661 DATA_BLOB null_blob = data_blob_null;
1662 DATA_BLOB request = data_blob_null;
1663 DATA_BLOB spnego_msg = data_blob_null;
1665 /* We may change the pad length before marshalling. */
1666 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1668 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1669 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1673 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1674 data_blob_free(&request);
1678 /* Wrap this in SPNEGO. */
1679 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1681 data_blob_free(&request);
1683 /* Auth len in the rpc header doesn't include auth_header. */
1684 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1685 data_blob_free(&spnego_msg);
1686 return NT_STATUS_NO_MEMORY;
1689 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1690 dump_data(5, spnego_msg.data, spnego_msg.length);
1692 data_blob_free(&spnego_msg);
1693 return NT_STATUS_OK;
1696 /*******************************************************************
1697 Creates NTLMSSP auth bind.
1698 ********************************************************************/
1700 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1701 enum dcerpc_AuthLevel auth_level,
1702 RPC_HDR_AUTH *pauth_out,
1703 prs_struct *auth_data)
1706 DATA_BLOB null_blob = data_blob_null;
1707 DATA_BLOB request = data_blob_null;
1709 /* We may change the pad length before marshalling. */
1710 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1712 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1713 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1717 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1718 data_blob_free(&request);
1722 /* Auth len in the rpc header doesn't include auth_header. */
1723 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1724 data_blob_free(&request);
1725 return NT_STATUS_NO_MEMORY;
1728 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1729 dump_data(5, request.data, request.length);
1731 data_blob_free(&request);
1732 return NT_STATUS_OK;
1735 /*******************************************************************
1736 Creates schannel auth bind.
1737 ********************************************************************/
1739 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1740 enum dcerpc_AuthLevel auth_level,
1741 RPC_HDR_AUTH *pauth_out,
1742 prs_struct *auth_data)
1744 struct NL_AUTH_MESSAGE r;
1745 enum ndr_err_code ndr_err;
1748 /* We may change the pad length before marshalling. */
1749 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1751 /* Use lp_workgroup() if domain not specified */
1753 if (!cli->auth->domain || !cli->auth->domain[0]) {
1754 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1755 if (cli->auth->domain == NULL) {
1756 return NT_STATUS_NO_MEMORY;
1761 * Now marshall the data into the auth parse_struct.
1764 r.MessageType = NL_NEGOTIATE_REQUEST;
1765 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1766 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1767 r.oem_netbios_domain.a = cli->auth->domain;
1768 r.oem_netbios_computer.a = global_myname();
1770 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &r,
1771 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1772 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1773 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1774 return ndr_map_error2ntstatus(ndr_err);
1777 if (DEBUGLEVEL >= 10) {
1778 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1781 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1783 return NT_STATUS_NO_MEMORY;
1786 return NT_STATUS_OK;
1789 /*******************************************************************
1790 Creates the internals of a DCE/RPC bind request or alter context PDU.
1791 ********************************************************************/
1793 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1794 prs_struct *rpc_out,
1796 const struct ndr_syntax_id *abstract,
1797 const struct ndr_syntax_id *transfer,
1798 RPC_HDR_AUTH *phdr_auth,
1799 prs_struct *pauth_info)
1803 RPC_CONTEXT rpc_ctx;
1804 uint16 auth_len = prs_offset(pauth_info);
1805 uint8 ss_padding_len = 0;
1806 uint16 frag_len = 0;
1808 /* create the RPC context. */
1809 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1811 /* create the bind request RPC_HDR_RB */
1812 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1814 /* Start building the frag length. */
1815 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1817 /* Do we need to pad ? */
1819 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1820 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1821 ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1822 phdr_auth->auth_pad_len = ss_padding_len;
1824 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1827 /* Create the request RPC_HDR */
1828 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1830 /* Marshall the RPC header */
1831 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1832 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1833 return NT_STATUS_NO_MEMORY;
1836 /* Marshall the bind request data */
1837 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1838 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1839 return NT_STATUS_NO_MEMORY;
1843 * Grow the outgoing buffer to store any auth info.
1847 if (ss_padding_len) {
1848 char pad[CLIENT_NDR_PADDING_SIZE];
1849 memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1850 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1851 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1852 return NT_STATUS_NO_MEMORY;
1856 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1857 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1858 return NT_STATUS_NO_MEMORY;
1862 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1863 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1864 return NT_STATUS_NO_MEMORY;
1868 return NT_STATUS_OK;
1871 /*******************************************************************
1872 Creates a DCE/RPC bind request.
1873 ********************************************************************/
1875 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1876 prs_struct *rpc_out,
1878 const struct ndr_syntax_id *abstract,
1879 const struct ndr_syntax_id *transfer,
1880 enum pipe_auth_type auth_type,
1881 enum dcerpc_AuthLevel auth_level)
1883 RPC_HDR_AUTH hdr_auth;
1884 prs_struct auth_info;
1885 NTSTATUS ret = NT_STATUS_OK;
1887 ZERO_STRUCT(hdr_auth);
1888 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1889 return NT_STATUS_NO_MEMORY;
1891 switch (auth_type) {
1892 case PIPE_AUTH_TYPE_SCHANNEL:
1893 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1894 if (!NT_STATUS_IS_OK(ret)) {
1899 case PIPE_AUTH_TYPE_NTLMSSP:
1900 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1901 if (!NT_STATUS_IS_OK(ret)) {
1906 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1907 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1908 if (!NT_STATUS_IS_OK(ret)) {
1913 case PIPE_AUTH_TYPE_KRB5:
1914 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1915 if (!NT_STATUS_IS_OK(ret)) {
1920 case PIPE_AUTH_TYPE_NONE:
1924 /* "Can't" happen. */
1925 return NT_STATUS_INVALID_INFO_CLASS;
1928 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1939 /*******************************************************************
1940 Create and add the NTLMSSP sign/seal auth header and data.
1941 ********************************************************************/
1943 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1945 uint32 ss_padding_len,
1946 prs_struct *outgoing_pdu)
1948 RPC_HDR_AUTH auth_info;
1950 DATA_BLOB auth_blob = data_blob_null;
1951 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1954 if (!cli->auth->a_u.ntlmssp_state) {
1955 return NT_STATUS_INVALID_PARAMETER;
1958 frame = talloc_stackframe();
1960 /* Init and marshall the auth header. */
1961 init_rpc_hdr_auth(&auth_info,
1962 map_pipe_auth_type_to_rpc_auth_type(
1963 cli->auth->auth_type),
1964 cli->auth->auth_level,
1966 1 /* context id. */);
1968 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1969 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1971 return NT_STATUS_NO_MEMORY;
1974 switch (cli->auth->auth_level) {
1975 case DCERPC_AUTH_LEVEL_PRIVACY:
1976 /* Data portion is encrypted. */
1977 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1979 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1981 (unsigned char *)prs_data_p(outgoing_pdu),
1982 (size_t)prs_offset(outgoing_pdu),
1984 if (!NT_STATUS_IS_OK(status)) {
1990 case DCERPC_AUTH_LEVEL_INTEGRITY:
1991 /* Data is signed. */
1992 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1994 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
1996 (unsigned char *)prs_data_p(outgoing_pdu),
1997 (size_t)prs_offset(outgoing_pdu),
1999 if (!NT_STATUS_IS_OK(status)) {
2007 smb_panic("bad auth level");
2009 return NT_STATUS_INVALID_PARAMETER;
2012 /* Finally marshall the blob. */
2014 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2015 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2016 (unsigned int)NTLMSSP_SIG_SIZE));
2018 return NT_STATUS_NO_MEMORY;
2022 return NT_STATUS_OK;
2025 /*******************************************************************
2026 Create and add the schannel sign/seal auth header and data.
2027 ********************************************************************/
2029 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2031 uint32 ss_padding_len,
2032 prs_struct *outgoing_pdu)
2034 RPC_HDR_AUTH auth_info;
2035 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2036 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2037 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2042 return NT_STATUS_INVALID_PARAMETER;
2045 /* Init and marshall the auth header. */
2046 init_rpc_hdr_auth(&auth_info,
2047 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2048 cli->auth->auth_level,
2050 1 /* context id. */);
2052 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2053 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2054 return NT_STATUS_NO_MEMORY;
2057 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2060 switch (cli->auth->auth_level) {
2061 case DCERPC_AUTH_LEVEL_PRIVACY:
2062 status = netsec_outgoing_packet(sas,
2069 case DCERPC_AUTH_LEVEL_INTEGRITY:
2070 status = netsec_outgoing_packet(sas,
2078 status = NT_STATUS_INTERNAL_ERROR;
2082 if (!NT_STATUS_IS_OK(status)) {
2083 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2084 nt_errstr(status)));
2088 if (DEBUGLEVEL >= 10) {
2089 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2092 /* Finally marshall the blob. */
2093 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2094 return NT_STATUS_NO_MEMORY;
2097 return NT_STATUS_OK;
2100 /*******************************************************************
2101 Calculate how much data we're going to send in this packet, also
2102 work out any sign/seal padding length.
2103 ********************************************************************/
2105 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2109 uint32 *p_ss_padding)
2111 uint32 data_space, data_len;
2114 if ((data_left > 0) && (sys_random() % 2)) {
2115 data_left = MAX(data_left/2, 1);
2119 switch (cli->auth->auth_level) {
2120 case DCERPC_AUTH_LEVEL_NONE:
2121 case DCERPC_AUTH_LEVEL_CONNECT:
2122 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2123 data_len = MIN(data_space, data_left);
2126 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2129 case DCERPC_AUTH_LEVEL_INTEGRITY:
2130 case DCERPC_AUTH_LEVEL_PRIVACY:
2131 /* Treat the same for all authenticated rpc requests. */
2132 switch(cli->auth->auth_type) {
2133 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2134 case PIPE_AUTH_TYPE_NTLMSSP:
2135 *p_auth_len = NTLMSSP_SIG_SIZE;
2137 case PIPE_AUTH_TYPE_SCHANNEL:
2138 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2141 smb_panic("bad auth type");
2145 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2146 RPC_HDR_AUTH_LEN - *p_auth_len;
2148 data_len = MIN(data_space, data_left);
2150 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2151 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2153 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2154 data_len + *p_ss_padding + /* data plus padding. */
2155 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2159 smb_panic("bad auth level");
2165 /*******************************************************************
2167 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2168 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2169 and deals with signing/sealing details.
2170 ********************************************************************/
2172 struct rpc_api_pipe_req_state {
2173 struct event_context *ev;
2174 struct rpc_pipe_client *cli;
2177 prs_struct *req_data;
2178 uint32_t req_data_sent;
2179 prs_struct outgoing_frag;
2180 prs_struct reply_pdu;
2183 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2184 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2185 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2186 bool *is_last_frag);
2188 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2189 struct event_context *ev,
2190 struct rpc_pipe_client *cli,
2192 prs_struct *req_data)
2194 struct tevent_req *req, *subreq;
2195 struct rpc_api_pipe_req_state *state;
2199 req = tevent_req_create(mem_ctx, &state,
2200 struct rpc_api_pipe_req_state);
2206 state->op_num = op_num;
2207 state->req_data = req_data;
2208 state->req_data_sent = 0;
2209 state->call_id = get_rpc_call_id();
2211 if (cli->max_xmit_frag
2212 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2213 /* Server is screwed up ! */
2214 status = NT_STATUS_INVALID_PARAMETER;
2218 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2220 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2225 status = prepare_next_frag(state, &is_last_frag);
2226 if (!NT_STATUS_IS_OK(status)) {
2231 subreq = rpc_api_pipe_send(state, ev, state->cli,
2232 &state->outgoing_frag,
2233 DCERPC_PKT_RESPONSE);
2234 if (subreq == NULL) {
2237 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2239 subreq = rpc_write_send(
2240 state, ev, cli->transport,
2241 (uint8_t *)prs_data_p(&state->outgoing_frag),
2242 prs_offset(&state->outgoing_frag));
2243 if (subreq == NULL) {
2246 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2252 tevent_req_nterror(req, status);
2253 return tevent_req_post(req, ev);
2259 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2263 RPC_HDR_REQ hdr_req;
2264 uint32_t data_sent_thistime;
2268 uint32_t ss_padding;
2270 char pad[8] = { 0, };
2273 data_left = prs_offset(state->req_data) - state->req_data_sent;
2275 data_sent_thistime = calculate_data_len_tosend(
2276 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2278 if (state->req_data_sent == 0) {
2279 flags = DCERPC_PFC_FLAG_FIRST;
2282 if (data_sent_thistime == data_left) {
2283 flags |= DCERPC_PFC_FLAG_LAST;
2286 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2287 return NT_STATUS_NO_MEMORY;
2290 /* Create and marshall the header and request header. */
2291 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2294 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2295 return NT_STATUS_NO_MEMORY;
2298 /* Create the rpc request RPC_HDR_REQ */
2299 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2302 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2303 &state->outgoing_frag, 0)) {
2304 return NT_STATUS_NO_MEMORY;
2307 /* Copy in the data, plus any ss padding. */
2308 if (!prs_append_some_prs_data(&state->outgoing_frag,
2309 state->req_data, state->req_data_sent,
2310 data_sent_thistime)) {
2311 return NT_STATUS_NO_MEMORY;
2314 /* Copy the sign/seal padding data. */
2315 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2316 return NT_STATUS_NO_MEMORY;
2319 /* Generate any auth sign/seal and add the auth footer. */
2320 switch (state->cli->auth->auth_type) {
2321 case PIPE_AUTH_TYPE_NONE:
2322 status = NT_STATUS_OK;
2324 case PIPE_AUTH_TYPE_NTLMSSP:
2325 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2326 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2327 &state->outgoing_frag);
2329 case PIPE_AUTH_TYPE_SCHANNEL:
2330 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2331 &state->outgoing_frag);
2334 status = NT_STATUS_INVALID_PARAMETER;
2338 state->req_data_sent += data_sent_thistime;
2339 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2344 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2346 struct tevent_req *req = tevent_req_callback_data(
2347 subreq, struct tevent_req);
2348 struct rpc_api_pipe_req_state *state = tevent_req_data(
2349 req, struct rpc_api_pipe_req_state);
2353 status = rpc_write_recv(subreq);
2354 TALLOC_FREE(subreq);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 tevent_req_nterror(req, status);
2360 status = prepare_next_frag(state, &is_last_frag);
2361 if (!NT_STATUS_IS_OK(status)) {
2362 tevent_req_nterror(req, status);
2367 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2368 &state->outgoing_frag,
2369 DCERPC_PKT_RESPONSE);
2370 if (tevent_req_nomem(subreq, req)) {
2373 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2375 subreq = rpc_write_send(
2377 state->cli->transport,
2378 (uint8_t *)prs_data_p(&state->outgoing_frag),
2379 prs_offset(&state->outgoing_frag));
2380 if (tevent_req_nomem(subreq, req)) {
2383 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2388 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2390 struct tevent_req *req = tevent_req_callback_data(
2391 subreq, struct tevent_req);
2392 struct rpc_api_pipe_req_state *state = tevent_req_data(
2393 req, struct rpc_api_pipe_req_state);
2396 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2397 TALLOC_FREE(subreq);
2398 if (!NT_STATUS_IS_OK(status)) {
2399 tevent_req_nterror(req, status);
2402 tevent_req_done(req);
2405 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2406 prs_struct *reply_pdu)
2408 struct rpc_api_pipe_req_state *state = tevent_req_data(
2409 req, struct rpc_api_pipe_req_state);
2412 if (tevent_req_is_nterror(req, &status)) {
2414 * We always have to initialize to reply pdu, even if there is
2415 * none. The rpccli_* caller routines expect this.
2417 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2421 *reply_pdu = state->reply_pdu;
2422 reply_pdu->mem_ctx = mem_ctx;
2425 * Prevent state->req_pdu from being freed
2426 * when state is freed.
2428 talloc_steal(mem_ctx, prs_data_p(reply_pdu));
2429 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2431 return NT_STATUS_OK;
2435 /****************************************************************************
2436 Set the handle state.
2437 ****************************************************************************/
2439 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2440 const char *pipe_name, uint16 device_state)
2442 bool state_set = False;
2444 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2445 char *rparam = NULL;
2447 uint32 rparam_len, rdata_len;
2449 if (pipe_name == NULL)
2452 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2453 cli->fnum, pipe_name, device_state));
2455 /* create parameters: device state */
2456 SSVAL(param, 0, device_state);
2458 /* create setup parameters. */
2460 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2462 /* send the data on \PIPE\ */
2463 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2464 setup, 2, 0, /* setup, length, max */
2465 param, 2, 0, /* param, length, max */
2466 NULL, 0, 1024, /* data, length, max */
2467 &rparam, &rparam_len, /* return param, length */
2468 &rdata, &rdata_len)) /* return data, length */
2470 DEBUG(5, ("Set Handle state: return OK\n"));
2481 /****************************************************************************
2482 Check the rpc bind acknowledge response.
2483 ****************************************************************************/
2485 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2486 const struct ndr_syntax_id *transfer)
2488 if ( hdr_ba->addr.len == 0) {
2489 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2492 /* check the transfer syntax */
2493 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2494 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2495 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2499 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2500 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2501 hdr_ba->res.num_results, hdr_ba->res.reason));
2504 DEBUG(5,("check_bind_response: accepted!\n"));
2508 /*******************************************************************
2509 Creates a DCE/RPC bind authentication response.
2510 This is the packet that is sent back to the server once we
2511 have received a BIND-ACK, to finish the third leg of
2512 the authentication handshake.
2513 ********************************************************************/
2515 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2517 enum pipe_auth_type auth_type,
2518 enum dcerpc_AuthLevel auth_level,
2519 DATA_BLOB *pauth_blob,
2520 prs_struct *rpc_out)
2523 RPC_HDR_AUTH hdr_auth;
2526 /* Create the request RPC_HDR */
2527 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2528 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2529 pauth_blob->length );
2532 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2533 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2534 return NT_STATUS_NO_MEMORY;
2538 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2539 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2542 /* 4 bytes padding. */
2543 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2544 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2545 return NT_STATUS_NO_MEMORY;
2548 /* Create the request RPC_HDR_AUTHA */
2549 init_rpc_hdr_auth(&hdr_auth,
2550 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2553 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2554 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2555 return NT_STATUS_NO_MEMORY;
2559 * Append the auth data to the outgoing buffer.
2562 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2563 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2564 return NT_STATUS_NO_MEMORY;
2567 return NT_STATUS_OK;
2570 /*******************************************************************
2571 Creates a DCE/RPC bind alter context authentication request which
2572 may contain a spnego auth blobl
2573 ********************************************************************/
2575 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2576 const struct ndr_syntax_id *abstract,
2577 const struct ndr_syntax_id *transfer,
2578 enum dcerpc_AuthLevel auth_level,
2579 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2580 prs_struct *rpc_out)
2582 RPC_HDR_AUTH hdr_auth;
2583 prs_struct auth_info;
2584 NTSTATUS ret = NT_STATUS_OK;
2586 ZERO_STRUCT(hdr_auth);
2587 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2588 return NT_STATUS_NO_MEMORY;
2590 /* We may change the pad length before marshalling. */
2591 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2593 if (pauth_blob->length) {
2594 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2595 return NT_STATUS_NO_MEMORY;
2599 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2609 /****************************************************************************
2611 ****************************************************************************/
2613 struct rpc_pipe_bind_state {
2614 struct event_context *ev;
2615 struct rpc_pipe_client *cli;
2617 uint32_t rpc_call_id;
2620 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2621 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2622 struct rpc_pipe_bind_state *state,
2623 struct rpc_hdr_info *phdr,
2624 prs_struct *reply_pdu);
2625 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2626 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2627 struct rpc_pipe_bind_state *state,
2628 struct rpc_hdr_info *phdr,
2629 prs_struct *reply_pdu);
2630 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2632 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2633 struct event_context *ev,
2634 struct rpc_pipe_client *cli,
2635 struct cli_pipe_auth_data *auth)
2637 struct tevent_req *req, *subreq;
2638 struct rpc_pipe_bind_state *state;
2641 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2646 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2647 rpccli_pipe_txt(talloc_tos(), cli),
2648 (unsigned int)auth->auth_type,
2649 (unsigned int)auth->auth_level ));
2653 state->rpc_call_id = get_rpc_call_id();
2655 prs_init_empty(&state->rpc_out, state, MARSHALL);
2657 cli->auth = talloc_move(cli, &auth);
2659 /* Marshall the outgoing data. */
2660 status = create_rpc_bind_req(cli, &state->rpc_out,
2662 &cli->abstract_syntax,
2663 &cli->transfer_syntax,
2664 cli->auth->auth_type,
2665 cli->auth->auth_level);
2667 if (!NT_STATUS_IS_OK(status)) {
2671 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2672 DCERPC_PKT_BIND_ACK);
2673 if (subreq == NULL) {
2676 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2680 tevent_req_nterror(req, status);
2681 return tevent_req_post(req, ev);
2687 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2689 struct tevent_req *req = tevent_req_callback_data(
2690 subreq, struct tevent_req);
2691 struct rpc_pipe_bind_state *state = tevent_req_data(
2692 req, struct rpc_pipe_bind_state);
2693 prs_struct reply_pdu;
2694 struct rpc_hdr_info hdr;
2695 struct rpc_hdr_ba_info hdr_ba;
2698 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2699 TALLOC_FREE(subreq);
2700 if (!NT_STATUS_IS_OK(status)) {
2701 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2702 rpccli_pipe_txt(talloc_tos(), state->cli),
2703 nt_errstr(status)));
2704 tevent_req_nterror(req, status);
2708 /* Unmarshall the RPC header */
2709 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2710 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2711 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2715 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2716 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2718 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2722 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2723 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2724 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2728 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2729 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2732 * For authenticated binds we may need to do 3 or 4 leg binds.
2735 switch(state->cli->auth->auth_type) {
2737 case PIPE_AUTH_TYPE_NONE:
2738 case PIPE_AUTH_TYPE_SCHANNEL:
2739 /* Bind complete. */
2740 tevent_req_done(req);
2743 case PIPE_AUTH_TYPE_NTLMSSP:
2744 /* Need to send AUTH3 packet - no reply. */
2745 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2747 if (!NT_STATUS_IS_OK(status)) {
2748 tevent_req_nterror(req, status);
2752 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2753 /* Need to send alter context request and reply. */
2754 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2756 if (!NT_STATUS_IS_OK(status)) {
2757 tevent_req_nterror(req, status);
2761 case PIPE_AUTH_TYPE_KRB5:
2765 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2766 (unsigned int)state->cli->auth->auth_type));
2767 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2771 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2772 struct rpc_pipe_bind_state *state,
2773 struct rpc_hdr_info *phdr,
2774 prs_struct *reply_pdu)
2776 DATA_BLOB server_response = data_blob_null;
2777 DATA_BLOB client_reply = data_blob_null;
2778 struct rpc_hdr_auth_info hdr_auth;
2779 struct tevent_req *subreq;
2782 if ((phdr->auth_len == 0)
2783 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2784 return NT_STATUS_INVALID_PARAMETER;
2787 if (!prs_set_offset(
2789 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2790 return NT_STATUS_INVALID_PARAMETER;
2793 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2794 return NT_STATUS_INVALID_PARAMETER;
2797 /* TODO - check auth_type/auth_level match. */
2799 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2800 prs_copy_data_out((char *)server_response.data, reply_pdu,
2803 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2804 server_response, &client_reply);
2806 if (!NT_STATUS_IS_OK(status)) {
2807 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2808 "blob failed: %s.\n", nt_errstr(status)));
2812 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2814 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2815 state->cli->auth->auth_type,
2816 state->cli->auth->auth_level,
2817 &client_reply, &state->rpc_out);
2818 data_blob_free(&client_reply);
2820 if (!NT_STATUS_IS_OK(status)) {
2824 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2825 (uint8_t *)prs_data_p(&state->rpc_out),
2826 prs_offset(&state->rpc_out));
2827 if (subreq == NULL) {
2828 return NT_STATUS_NO_MEMORY;
2830 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2831 return NT_STATUS_OK;
2834 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2836 struct tevent_req *req = tevent_req_callback_data(
2837 subreq, struct tevent_req);
2840 status = rpc_write_recv(subreq);
2841 TALLOC_FREE(subreq);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 tevent_req_nterror(req, status);
2846 tevent_req_done(req);
2849 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2850 struct rpc_pipe_bind_state *state,
2851 struct rpc_hdr_info *phdr,
2852 prs_struct *reply_pdu)
2854 DATA_BLOB server_spnego_response = data_blob_null;
2855 DATA_BLOB server_ntlm_response = data_blob_null;
2856 DATA_BLOB client_reply = data_blob_null;
2857 DATA_BLOB tmp_blob = data_blob_null;
2858 RPC_HDR_AUTH hdr_auth;
2859 struct tevent_req *subreq;
2862 if ((phdr->auth_len == 0)
2863 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2864 return NT_STATUS_INVALID_PARAMETER;
2867 /* Process the returned NTLMSSP blob first. */
2868 if (!prs_set_offset(
2870 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2871 return NT_STATUS_INVALID_PARAMETER;
2874 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2875 return NT_STATUS_INVALID_PARAMETER;
2878 server_spnego_response = data_blob(NULL, phdr->auth_len);
2879 prs_copy_data_out((char *)server_spnego_response.data,
2880 reply_pdu, phdr->auth_len);
2883 * The server might give us back two challenges - tmp_blob is for the
2886 if (!spnego_parse_challenge(server_spnego_response,
2887 &server_ntlm_response, &tmp_blob)) {
2888 data_blob_free(&server_spnego_response);
2889 data_blob_free(&server_ntlm_response);
2890 data_blob_free(&tmp_blob);
2891 return NT_STATUS_INVALID_PARAMETER;
2894 /* We're finished with the server spnego response and the tmp_blob. */
2895 data_blob_free(&server_spnego_response);
2896 data_blob_free(&tmp_blob);
2898 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2899 server_ntlm_response, &client_reply);
2901 /* Finished with the server_ntlm response */
2902 data_blob_free(&server_ntlm_response);
2904 if (!NT_STATUS_IS_OK(status)) {
2905 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2906 "using server blob failed.\n"));
2907 data_blob_free(&client_reply);
2911 /* SPNEGO wrap the client reply. */
2912 tmp_blob = spnego_gen_auth(client_reply);
2913 data_blob_free(&client_reply);
2914 client_reply = tmp_blob;
2915 tmp_blob = data_blob_null;
2917 /* Now prepare the alter context pdu. */
2918 prs_init_empty(&state->rpc_out, state, MARSHALL);
2920 status = create_rpc_alter_context(state->rpc_call_id,
2921 &state->cli->abstract_syntax,
2922 &state->cli->transfer_syntax,
2923 state->cli->auth->auth_level,
2926 data_blob_free(&client_reply);
2928 if (!NT_STATUS_IS_OK(status)) {
2932 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2933 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2934 if (subreq == NULL) {
2935 return NT_STATUS_NO_MEMORY;
2937 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2938 return NT_STATUS_OK;
2941 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2943 struct tevent_req *req = tevent_req_callback_data(
2944 subreq, struct tevent_req);
2945 struct rpc_pipe_bind_state *state = tevent_req_data(
2946 req, struct rpc_pipe_bind_state);
2947 DATA_BLOB server_spnego_response = data_blob_null;
2948 DATA_BLOB tmp_blob = data_blob_null;
2949 prs_struct reply_pdu;
2950 struct rpc_hdr_info hdr;
2951 struct rpc_hdr_auth_info hdr_auth;
2954 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2955 TALLOC_FREE(subreq);
2956 if (!NT_STATUS_IS_OK(status)) {
2957 tevent_req_nterror(req, status);
2961 /* Get the auth blob from the reply. */
2962 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
2963 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
2964 "unmarshall RPC_HDR.\n"));
2965 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2969 if (!prs_set_offset(
2971 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
2972 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2976 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
2977 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2981 server_spnego_response = data_blob(NULL, hdr.auth_len);
2982 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
2985 /* Check we got a valid auth response. */
2986 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
2987 OID_NTLMSSP, &tmp_blob)) {
2988 data_blob_free(&server_spnego_response);
2989 data_blob_free(&tmp_blob);
2990 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2994 data_blob_free(&server_spnego_response);
2995 data_blob_free(&tmp_blob);
2997 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2998 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2999 tevent_req_done(req);
3002 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3004 return tevent_req_simple_recv_ntstatus(req);
3007 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3008 struct cli_pipe_auth_data *auth)
3010 TALLOC_CTX *frame = talloc_stackframe();
3011 struct event_context *ev;
3012 struct tevent_req *req;
3013 NTSTATUS status = NT_STATUS_OK;
3015 ev = event_context_init(frame);
3017 status = NT_STATUS_NO_MEMORY;
3021 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3023 status = NT_STATUS_NO_MEMORY;
3027 if (!tevent_req_poll(req, ev)) {
3028 status = map_nt_error_from_unix(errno);
3032 status = rpc_pipe_bind_recv(req);
3038 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3040 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3041 unsigned int timeout)
3045 if (rpc_cli->transport == NULL) {
3046 return RPCCLI_DEFAULT_TIMEOUT;
3049 if (rpc_cli->transport->set_timeout == NULL) {
3050 return RPCCLI_DEFAULT_TIMEOUT;
3053 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3055 return RPCCLI_DEFAULT_TIMEOUT;
3061 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3063 if (rpc_cli == NULL) {
3067 if (rpc_cli->transport == NULL) {
3071 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3074 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3076 struct cli_state *cli;
3078 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3079 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3080 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3084 cli = rpc_pipe_np_smb_conn(rpc_cli);
3088 E_md4hash(cli->password ? cli->password : "", nt_hash);
3092 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3093 struct cli_pipe_auth_data **presult)
3095 struct cli_pipe_auth_data *result;
3097 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3098 if (result == NULL) {
3099 return NT_STATUS_NO_MEMORY;
3102 result->auth_type = PIPE_AUTH_TYPE_NONE;
3103 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3105 result->user_name = talloc_strdup(result, "");
3106 result->domain = talloc_strdup(result, "");
3107 if ((result->user_name == NULL) || (result->domain == NULL)) {
3108 TALLOC_FREE(result);
3109 return NT_STATUS_NO_MEMORY;
3113 return NT_STATUS_OK;
3116 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3118 ntlmssp_end(&auth->a_u.ntlmssp_state);
3122 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3123 enum pipe_auth_type auth_type,
3124 enum dcerpc_AuthLevel auth_level,
3126 const char *username,
3127 const char *password,
3128 struct cli_pipe_auth_data **presult)
3130 struct cli_pipe_auth_data *result;
3133 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3134 if (result == NULL) {
3135 return NT_STATUS_NO_MEMORY;
3138 result->auth_type = auth_type;
3139 result->auth_level = auth_level;
3141 result->user_name = talloc_strdup(result, username);
3142 result->domain = talloc_strdup(result, domain);
3143 if ((result->user_name == NULL) || (result->domain == NULL)) {
3144 status = NT_STATUS_NO_MEMORY;
3148 status = ntlmssp_client_start(NULL,
3151 lp_client_ntlmv2_auth(),
3152 &result->a_u.ntlmssp_state);
3153 if (!NT_STATUS_IS_OK(status)) {
3157 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3159 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3160 if (!NT_STATUS_IS_OK(status)) {
3164 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3165 if (!NT_STATUS_IS_OK(status)) {
3169 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3170 if (!NT_STATUS_IS_OK(status)) {
3175 * Turn off sign+seal to allow selected auth level to turn it back on.
3177 result->a_u.ntlmssp_state->neg_flags &=
3178 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3180 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3181 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3182 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3183 result->a_u.ntlmssp_state->neg_flags
3184 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3188 return NT_STATUS_OK;
3191 TALLOC_FREE(result);
3195 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3196 enum dcerpc_AuthLevel auth_level,
3197 struct netlogon_creds_CredentialState *creds,
3198 struct cli_pipe_auth_data **presult)
3200 struct cli_pipe_auth_data *result;
3202 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3203 if (result == NULL) {
3204 return NT_STATUS_NO_MEMORY;
3207 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3208 result->auth_level = auth_level;
3210 result->user_name = talloc_strdup(result, "");
3211 result->domain = talloc_strdup(result, domain);
3212 if ((result->user_name == NULL) || (result->domain == NULL)) {
3216 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3217 if (result->a_u.schannel_auth == NULL) {
3221 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3222 result->a_u.schannel_auth->seq_num = 0;
3223 result->a_u.schannel_auth->initiator = true;
3224 result->a_u.schannel_auth->creds = creds;
3227 return NT_STATUS_OK;
3230 TALLOC_FREE(result);
3231 return NT_STATUS_NO_MEMORY;
3235 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3237 data_blob_free(&auth->session_key);
3242 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3243 enum dcerpc_AuthLevel auth_level,
3244 const char *service_princ,
3245 const char *username,
3246 const char *password,
3247 struct cli_pipe_auth_data **presult)
3250 struct cli_pipe_auth_data *result;
3252 if ((username != NULL) && (password != NULL)) {
3253 int ret = kerberos_kinit_password(username, password, 0, NULL);
3255 return NT_STATUS_ACCESS_DENIED;
3259 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3260 if (result == NULL) {
3261 return NT_STATUS_NO_MEMORY;
3264 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3265 result->auth_level = auth_level;
3268 * Username / domain need fixing!
3270 result->user_name = talloc_strdup(result, "");
3271 result->domain = talloc_strdup(result, "");
3272 if ((result->user_name == NULL) || (result->domain == NULL)) {
3276 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3277 result, struct kerberos_auth_struct);
3278 if (result->a_u.kerberos_auth == NULL) {
3281 talloc_set_destructor(result->a_u.kerberos_auth,
3282 cli_auth_kerberos_data_destructor);
3284 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3285 result, service_princ);
3286 if (result->a_u.kerberos_auth->service_principal == NULL) {
3291 return NT_STATUS_OK;
3294 TALLOC_FREE(result);
3295 return NT_STATUS_NO_MEMORY;
3297 return NT_STATUS_NOT_SUPPORTED;
3302 * Create an rpc pipe client struct, connecting to a tcp port.
3304 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3306 const struct ndr_syntax_id *abstract_syntax,
3307 struct rpc_pipe_client **presult)
3309 struct rpc_pipe_client *result;
3310 struct sockaddr_storage addr;
3314 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3315 if (result == NULL) {
3316 return NT_STATUS_NO_MEMORY;
3319 result->abstract_syntax = *abstract_syntax;
3320 result->transfer_syntax = ndr_transfer_syntax;
3321 result->dispatch = cli_do_rpc_ndr;
3322 result->dispatch_send = cli_do_rpc_ndr_send;
3323 result->dispatch_recv = cli_do_rpc_ndr_recv;
3325 result->desthost = talloc_strdup(result, host);
3326 result->srv_name_slash = talloc_asprintf_strupper_m(
3327 result, "\\\\%s", result->desthost);
3328 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3329 status = NT_STATUS_NO_MEMORY;
3333 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3334 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3336 if (!resolve_name(host, &addr, 0, false)) {
3337 status = NT_STATUS_NOT_FOUND;
3341 status = open_socket_out(&addr, port, 60, &fd);
3342 if (!NT_STATUS_IS_OK(status)) {
3345 set_socket_options(fd, lp_socket_options());
3347 status = rpc_transport_sock_init(result, fd, &result->transport);
3348 if (!NT_STATUS_IS_OK(status)) {
3353 result->transport->transport = NCACN_IP_TCP;
3356 return NT_STATUS_OK;
3359 TALLOC_FREE(result);
3364 * Determine the tcp port on which a dcerpc interface is listening
3365 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3368 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3369 const struct ndr_syntax_id *abstract_syntax,
3373 struct rpc_pipe_client *epm_pipe = NULL;
3374 struct cli_pipe_auth_data *auth = NULL;
3375 struct dcerpc_binding *map_binding = NULL;
3376 struct dcerpc_binding *res_binding = NULL;
3377 struct epm_twr_t *map_tower = NULL;
3378 struct epm_twr_t *res_towers = NULL;
3379 struct policy_handle *entry_handle = NULL;
3380 uint32_t num_towers = 0;
3381 uint32_t max_towers = 1;
3382 struct epm_twr_p_t towers;
3383 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3385 if (pport == NULL) {
3386 status = NT_STATUS_INVALID_PARAMETER;
3390 /* open the connection to the endpoint mapper */
3391 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3392 &ndr_table_epmapper.syntax_id,
3395 if (!NT_STATUS_IS_OK(status)) {
3399 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3400 if (!NT_STATUS_IS_OK(status)) {
3404 status = rpc_pipe_bind(epm_pipe, auth);
3405 if (!NT_STATUS_IS_OK(status)) {
3409 /* create tower for asking the epmapper */
3411 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3412 if (map_binding == NULL) {
3413 status = NT_STATUS_NO_MEMORY;
3417 map_binding->transport = NCACN_IP_TCP;
3418 map_binding->object = *abstract_syntax;
3419 map_binding->host = host; /* needed? */
3420 map_binding->endpoint = "0"; /* correct? needed? */
3422 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3423 if (map_tower == NULL) {
3424 status = NT_STATUS_NO_MEMORY;
3428 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3429 &(map_tower->tower));
3430 if (!NT_STATUS_IS_OK(status)) {
3434 /* allocate further parameters for the epm_Map call */
3436 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3437 if (res_towers == NULL) {
3438 status = NT_STATUS_NO_MEMORY;
3441 towers.twr = res_towers;
3443 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3444 if (entry_handle == NULL) {
3445 status = NT_STATUS_NO_MEMORY;
3449 /* ask the endpoint mapper for the port */
3451 status = rpccli_epm_Map(epm_pipe,
3453 CONST_DISCARD(struct GUID *,
3454 &(abstract_syntax->uuid)),
3461 if (!NT_STATUS_IS_OK(status)) {
3465 if (num_towers != 1) {
3466 status = NT_STATUS_UNSUCCESSFUL;
3470 /* extract the port from the answer */
3472 status = dcerpc_binding_from_tower(tmp_ctx,
3473 &(towers.twr->tower),
3475 if (!NT_STATUS_IS_OK(status)) {
3479 /* are further checks here necessary? */
3480 if (res_binding->transport != NCACN_IP_TCP) {
3481 status = NT_STATUS_UNSUCCESSFUL;
3485 *pport = (uint16_t)atoi(res_binding->endpoint);
3488 TALLOC_FREE(tmp_ctx);
3493 * Create a rpc pipe client struct, connecting to a host via tcp.
3494 * The port is determined by asking the endpoint mapper on the given
3497 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3498 const struct ndr_syntax_id *abstract_syntax,
3499 struct rpc_pipe_client **presult)
3504 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3505 if (!NT_STATUS_IS_OK(status)) {
3509 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3510 abstract_syntax, presult);
3513 /********************************************************************
3514 Create a rpc pipe client struct, connecting to a unix domain socket
3515 ********************************************************************/
3516 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3517 const struct ndr_syntax_id *abstract_syntax,
3518 struct rpc_pipe_client **presult)
3520 struct rpc_pipe_client *result;
3521 struct sockaddr_un addr;
3525 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3526 if (result == NULL) {
3527 return NT_STATUS_NO_MEMORY;
3530 result->abstract_syntax = *abstract_syntax;
3531 result->transfer_syntax = ndr_transfer_syntax;
3532 result->dispatch = cli_do_rpc_ndr;
3533 result->dispatch_send = cli_do_rpc_ndr_send;
3534 result->dispatch_recv = cli_do_rpc_ndr_recv;
3536 result->desthost = get_myname(result);
3537 result->srv_name_slash = talloc_asprintf_strupper_m(
3538 result, "\\\\%s", result->desthost);
3539 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3540 status = NT_STATUS_NO_MEMORY;
3544 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3545 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3547 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3549 status = map_nt_error_from_unix(errno);
3554 addr.sun_family = AF_UNIX;
3555 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3557 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3558 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3561 return map_nt_error_from_unix(errno);
3564 status = rpc_transport_sock_init(result, fd, &result->transport);
3565 if (!NT_STATUS_IS_OK(status)) {
3570 result->transport->transport = NCALRPC;
3573 return NT_STATUS_OK;
3576 TALLOC_FREE(result);
3580 struct rpc_pipe_client_np_ref {
3581 struct cli_state *cli;
3582 struct rpc_pipe_client *pipe;
3585 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3587 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3591 /****************************************************************************
3592 Open a named pipe over SMB to a remote server.
3594 * CAVEAT CALLER OF THIS FUNCTION:
3595 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3596 * so be sure that this function is called AFTER any structure (vs pointer)
3597 * assignment of the cli. In particular, libsmbclient does structure
3598 * assignments of cli, which invalidates the data in the returned
3599 * rpc_pipe_client if this function is called before the structure assignment
3602 ****************************************************************************/
3604 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3605 const struct ndr_syntax_id *abstract_syntax,
3606 struct rpc_pipe_client **presult)
3608 struct rpc_pipe_client *result;
3610 struct rpc_pipe_client_np_ref *np_ref;
3612 /* sanity check to protect against crashes */
3615 return NT_STATUS_INVALID_HANDLE;
3618 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3619 if (result == NULL) {
3620 return NT_STATUS_NO_MEMORY;
3623 result->abstract_syntax = *abstract_syntax;
3624 result->transfer_syntax = ndr_transfer_syntax;
3625 result->dispatch = cli_do_rpc_ndr;
3626 result->dispatch_send = cli_do_rpc_ndr_send;
3627 result->dispatch_recv = cli_do_rpc_ndr_recv;
3628 result->desthost = talloc_strdup(result, cli->desthost);
3629 result->srv_name_slash = talloc_asprintf_strupper_m(
3630 result, "\\\\%s", result->desthost);
3632 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3633 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3635 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3636 TALLOC_FREE(result);
3637 return NT_STATUS_NO_MEMORY;
3640 status = rpc_transport_np_init(result, cli, abstract_syntax,
3641 &result->transport);
3642 if (!NT_STATUS_IS_OK(status)) {
3643 TALLOC_FREE(result);
3647 result->transport->transport = NCACN_NP;
3649 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3650 if (np_ref == NULL) {
3651 TALLOC_FREE(result);
3652 return NT_STATUS_NO_MEMORY;
3655 np_ref->pipe = result;
3657 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3658 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3661 return NT_STATUS_OK;
3664 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3665 struct rpc_cli_smbd_conn *conn,
3666 const struct ndr_syntax_id *syntax,
3667 struct rpc_pipe_client **presult)
3669 struct rpc_pipe_client *result;
3670 struct cli_pipe_auth_data *auth;
3673 result = talloc(mem_ctx, struct rpc_pipe_client);
3674 if (result == NULL) {
3675 return NT_STATUS_NO_MEMORY;
3677 result->abstract_syntax = *syntax;
3678 result->transfer_syntax = ndr_transfer_syntax;
3679 result->dispatch = cli_do_rpc_ndr;
3680 result->dispatch_send = cli_do_rpc_ndr_send;
3681 result->dispatch_recv = cli_do_rpc_ndr_recv;
3682 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3683 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3685 result->desthost = talloc_strdup(result, global_myname());
3686 result->srv_name_slash = talloc_asprintf_strupper_m(
3687 result, "\\\\%s", global_myname());
3688 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3689 TALLOC_FREE(result);
3690 return NT_STATUS_NO_MEMORY;
3693 status = rpc_transport_smbd_init(result, conn, syntax,
3694 &result->transport);
3695 if (!NT_STATUS_IS_OK(status)) {
3696 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3697 nt_errstr(status)));
3698 TALLOC_FREE(result);
3702 status = rpccli_anon_bind_data(result, &auth);
3703 if (!NT_STATUS_IS_OK(status)) {
3704 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3705 nt_errstr(status)));
3706 TALLOC_FREE(result);
3710 status = rpc_pipe_bind(result, auth);
3711 if (!NT_STATUS_IS_OK(status)) {
3712 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3713 TALLOC_FREE(result);
3717 result->transport->transport = NCACN_INTERNAL;
3720 return NT_STATUS_OK;
3723 /****************************************************************************
3724 Open a pipe to a remote server.
3725 ****************************************************************************/
3727 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3728 enum dcerpc_transport_t transport,
3729 const struct ndr_syntax_id *interface,
3730 struct rpc_pipe_client **presult)
3732 switch (transport) {
3734 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3737 return rpc_pipe_open_np(cli, interface, presult);
3739 return NT_STATUS_NOT_IMPLEMENTED;
3743 /****************************************************************************
3744 Open a named pipe to an SMB server and bind anonymously.
3745 ****************************************************************************/
3747 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3748 enum dcerpc_transport_t transport,
3749 const struct ndr_syntax_id *interface,
3750 struct rpc_pipe_client **presult)
3752 struct rpc_pipe_client *result;
3753 struct cli_pipe_auth_data *auth;
3756 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3757 if (!NT_STATUS_IS_OK(status)) {
3761 status = rpccli_anon_bind_data(result, &auth);
3762 if (!NT_STATUS_IS_OK(status)) {
3763 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3764 nt_errstr(status)));
3765 TALLOC_FREE(result);
3770 * This is a bit of an abstraction violation due to the fact that an
3771 * anonymous bind on an authenticated SMB inherits the user/domain
3772 * from the enclosing SMB creds
3775 TALLOC_FREE(auth->user_name);
3776 TALLOC_FREE(auth->domain);
3778 auth->user_name = talloc_strdup(auth, cli->user_name);
3779 auth->domain = talloc_strdup(auth, cli->domain);
3780 auth->user_session_key = data_blob_talloc(auth,
3781 cli->user_session_key.data,
3782 cli->user_session_key.length);
3784 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3785 TALLOC_FREE(result);
3786 return NT_STATUS_NO_MEMORY;
3789 status = rpc_pipe_bind(result, auth);
3790 if (!NT_STATUS_IS_OK(status)) {
3792 if (ndr_syntax_id_equal(interface,
3793 &ndr_table_dssetup.syntax_id)) {
3794 /* non AD domains just don't have this pipe, avoid
3795 * level 0 statement in that case - gd */
3798 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3799 "%s failed with error %s\n",
3800 get_pipe_name_from_syntax(talloc_tos(), interface),
3801 nt_errstr(status) ));
3802 TALLOC_FREE(result);
3806 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3807 "%s and bound anonymously.\n",
3808 get_pipe_name_from_syntax(talloc_tos(), interface),
3812 return NT_STATUS_OK;
3815 /****************************************************************************
3816 ****************************************************************************/
3818 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3819 const struct ndr_syntax_id *interface,
3820 struct rpc_pipe_client **presult)
3822 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3823 interface, presult);
3826 /****************************************************************************
3827 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3828 ****************************************************************************/
3830 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3831 const struct ndr_syntax_id *interface,
3832 enum dcerpc_transport_t transport,
3833 enum pipe_auth_type auth_type,
3834 enum dcerpc_AuthLevel auth_level,
3836 const char *username,
3837 const char *password,
3838 struct rpc_pipe_client **presult)
3840 struct rpc_pipe_client *result;
3841 struct cli_pipe_auth_data *auth;
3844 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3845 if (!NT_STATUS_IS_OK(status)) {
3849 status = rpccli_ntlmssp_bind_data(
3850 result, auth_type, auth_level, domain, username,
3852 if (!NT_STATUS_IS_OK(status)) {
3853 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3854 nt_errstr(status)));
3858 status = rpc_pipe_bind(result, auth);
3859 if (!NT_STATUS_IS_OK(status)) {
3860 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3861 nt_errstr(status) ));
3865 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3866 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3867 get_pipe_name_from_syntax(talloc_tos(), interface),
3868 cli->desthost, domain, username ));
3871 return NT_STATUS_OK;
3875 TALLOC_FREE(result);
3879 /****************************************************************************
3881 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3882 ****************************************************************************/
3884 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3885 const struct ndr_syntax_id *interface,
3886 enum dcerpc_transport_t transport,
3887 enum dcerpc_AuthLevel auth_level,
3889 const char *username,
3890 const char *password,
3891 struct rpc_pipe_client **presult)
3893 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3896 PIPE_AUTH_TYPE_NTLMSSP,
3904 /****************************************************************************
3906 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3907 ****************************************************************************/
3909 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3910 const struct ndr_syntax_id *interface,
3911 enum dcerpc_transport_t transport,
3912 enum dcerpc_AuthLevel auth_level,
3914 const char *username,
3915 const char *password,
3916 struct rpc_pipe_client **presult)
3918 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3921 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3929 /****************************************************************************
3930 Get a the schannel session key out of an already opened netlogon pipe.
3931 ****************************************************************************/
3932 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3933 struct cli_state *cli,
3937 enum netr_SchannelType sec_chan_type = 0;
3938 unsigned char machine_pwd[16];
3939 const char *machine_account;
3942 /* Get the machine account credentials from secrets.tdb. */
3943 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3946 DEBUG(0, ("get_schannel_session_key: could not fetch "
3947 "trust account password for domain '%s'\n",
3949 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3952 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3953 cli->desthost, /* server name */
3954 domain, /* domain */
3955 global_myname(), /* client name */
3956 machine_account, /* machine account name */
3961 if (!NT_STATUS_IS_OK(status)) {
3962 DEBUG(3, ("get_schannel_session_key_common: "
3963 "rpccli_netlogon_setup_creds failed with result %s "
3964 "to server %s, domain %s, machine account %s.\n",
3965 nt_errstr(status), cli->desthost, domain,
3970 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3971 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3973 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3976 return NT_STATUS_OK;;
3979 /****************************************************************************
3980 Open a netlogon pipe and get the schannel session key.
3981 Now exposed to external callers.
3982 ****************************************************************************/
3985 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3988 struct rpc_pipe_client **presult)
3990 struct rpc_pipe_client *netlogon_pipe = NULL;
3993 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3995 if (!NT_STATUS_IS_OK(status)) {
3999 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4001 if (!NT_STATUS_IS_OK(status)) {
4002 TALLOC_FREE(netlogon_pipe);
4006 *presult = netlogon_pipe;
4007 return NT_STATUS_OK;
4010 /****************************************************************************
4012 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4013 using session_key. sign and seal.
4015 The *pdc will be stolen onto this new pipe
4016 ****************************************************************************/
4018 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4019 const struct ndr_syntax_id *interface,
4020 enum dcerpc_transport_t transport,
4021 enum dcerpc_AuthLevel auth_level,
4023 struct netlogon_creds_CredentialState **pdc,
4024 struct rpc_pipe_client **presult)
4026 struct rpc_pipe_client *result;
4027 struct cli_pipe_auth_data *auth;
4030 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4031 if (!NT_STATUS_IS_OK(status)) {
4035 status = rpccli_schannel_bind_data(result, domain, auth_level,
4037 if (!NT_STATUS_IS_OK(status)) {
4038 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4039 nt_errstr(status)));
4040 TALLOC_FREE(result);
4044 status = rpc_pipe_bind(result, auth);
4045 if (!NT_STATUS_IS_OK(status)) {
4046 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4047 "cli_rpc_pipe_bind failed with error %s\n",
4048 nt_errstr(status) ));
4049 TALLOC_FREE(result);
4054 * The credentials on a new netlogon pipe are the ones we are passed
4055 * in - reference them in
4057 result->dc = talloc_move(result, pdc);
4059 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4060 "for domain %s and bound using schannel.\n",
4061 get_pipe_name_from_syntax(talloc_tos(), interface),
4062 cli->desthost, domain ));
4065 return NT_STATUS_OK;
4068 /****************************************************************************
4069 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4070 Fetch the session key ourselves using a temporary netlogon pipe. This
4071 version uses an ntlmssp auth bound netlogon pipe to get the key.
4072 ****************************************************************************/
4074 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4076 const char *username,
4077 const char *password,
4079 struct rpc_pipe_client **presult)
4081 struct rpc_pipe_client *netlogon_pipe = NULL;
4084 status = cli_rpc_pipe_open_spnego_ntlmssp(
4085 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4086 DCERPC_AUTH_LEVEL_PRIVACY,
4087 domain, username, password, &netlogon_pipe);
4088 if (!NT_STATUS_IS_OK(status)) {
4092 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4094 if (!NT_STATUS_IS_OK(status)) {
4095 TALLOC_FREE(netlogon_pipe);
4099 *presult = netlogon_pipe;
4100 return NT_STATUS_OK;
4103 /****************************************************************************
4104 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4105 Fetch the session key ourselves using a temporary netlogon pipe. This version
4106 uses an ntlmssp bind to get the session key.
4107 ****************************************************************************/
4109 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4110 const struct ndr_syntax_id *interface,
4111 enum dcerpc_transport_t transport,
4112 enum dcerpc_AuthLevel auth_level,
4114 const char *username,
4115 const char *password,
4116 struct rpc_pipe_client **presult)
4118 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4119 struct rpc_pipe_client *netlogon_pipe = NULL;
4120 struct rpc_pipe_client *result = NULL;
4123 status = get_schannel_session_key_auth_ntlmssp(
4124 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4125 if (!NT_STATUS_IS_OK(status)) {
4126 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4127 "key from server %s for domain %s.\n",
4128 cli->desthost, domain ));
4132 status = cli_rpc_pipe_open_schannel_with_key(
4133 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4136 /* Now we've bound using the session key we can close the netlog pipe. */
4137 TALLOC_FREE(netlogon_pipe);
4139 if (NT_STATUS_IS_OK(status)) {
4145 /****************************************************************************
4146 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4147 Fetch the session key ourselves using a temporary netlogon pipe.
4148 ****************************************************************************/
4150 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4151 const struct ndr_syntax_id *interface,
4152 enum dcerpc_transport_t transport,
4153 enum dcerpc_AuthLevel auth_level,
4155 struct rpc_pipe_client **presult)
4157 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4158 struct rpc_pipe_client *netlogon_pipe = NULL;
4159 struct rpc_pipe_client *result = NULL;
4162 status = get_schannel_session_key(cli, domain, &neg_flags,
4164 if (!NT_STATUS_IS_OK(status)) {
4165 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4166 "key from server %s for domain %s.\n",
4167 cli->desthost, domain ));
4171 status = cli_rpc_pipe_open_schannel_with_key(
4172 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4175 /* Now we've bound using the session key we can close the netlog pipe. */
4176 TALLOC_FREE(netlogon_pipe);
4178 if (NT_STATUS_IS_OK(status)) {
4185 /****************************************************************************
4186 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4187 The idea is this can be called with service_princ, username and password all
4188 NULL so long as the caller has a TGT.
4189 ****************************************************************************/
4191 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4192 const struct ndr_syntax_id *interface,
4193 enum dcerpc_AuthLevel auth_level,
4194 const char *service_princ,
4195 const char *username,
4196 const char *password,
4197 struct rpc_pipe_client **presult)
4200 struct rpc_pipe_client *result;
4201 struct cli_pipe_auth_data *auth;
4204 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4205 if (!NT_STATUS_IS_OK(status)) {
4209 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4210 username, password, &auth);
4211 if (!NT_STATUS_IS_OK(status)) {
4212 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4213 nt_errstr(status)));
4214 TALLOC_FREE(result);
4218 status = rpc_pipe_bind(result, auth);
4219 if (!NT_STATUS_IS_OK(status)) {
4220 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4221 "with error %s\n", nt_errstr(status)));
4222 TALLOC_FREE(result);
4227 return NT_STATUS_OK;
4229 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4230 return NT_STATUS_NOT_IMPLEMENTED;
4234 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4235 struct rpc_pipe_client *cli,
4236 DATA_BLOB *session_key)
4238 if (!session_key || !cli) {
4239 return NT_STATUS_INVALID_PARAMETER;
4243 return NT_STATUS_INVALID_PARAMETER;
4246 switch (cli->auth->auth_type) {
4247 case PIPE_AUTH_TYPE_SCHANNEL:
4248 *session_key = data_blob_talloc(mem_ctx,
4249 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4251 case PIPE_AUTH_TYPE_NTLMSSP:
4252 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4253 *session_key = data_blob_talloc(mem_ctx,
4254 cli->auth->a_u.ntlmssp_state->session_key.data,
4255 cli->auth->a_u.ntlmssp_state->session_key.length);
4257 case PIPE_AUTH_TYPE_KRB5:
4258 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4259 *session_key = data_blob_talloc(mem_ctx,
4260 cli->auth->a_u.kerberos_auth->session_key.data,
4261 cli->auth->a_u.kerberos_auth->session_key.length);
4263 case PIPE_AUTH_TYPE_NONE:
4264 *session_key = data_blob_talloc(mem_ctx,
4265 cli->auth->user_session_key.data,
4266 cli->auth->user_session_key.length);
4269 return NT_STATUS_NO_USER_SESSION_KEY;
4272 return NT_STATUS_OK;