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"
45 #define DBGC_CLASS DBGC_RPC_CLI
47 static const char *get_pipe_name_from_iface(
48 TALLOC_CTX *mem_ctx, const struct ndr_interface_table *interface)
51 const struct ndr_interface_string_array *ep = interface->endpoints;
54 for (i=0; i<ep->count; i++) {
55 if (strncmp(ep->names[i], "ncacn_np:[\\pipe\\", 16) == 0) {
64 * extract the pipe name without \\pipe from for example
65 * ncacn_np:[\\pipe\\epmapper]
67 p = strchr(ep->names[i]+15, ']');
71 return talloc_strndup(mem_ctx, ep->names[i]+15, p - ep->names[i] - 15);
74 static const struct ndr_interface_table **interfaces;
76 bool smb_register_ndr_interface(const struct ndr_interface_table *interface)
78 int num_interfaces = talloc_array_length(interfaces);
79 const struct ndr_interface_table **tmp;
82 for (i=0; i<num_interfaces; i++) {
83 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id,
84 &interface->syntax_id)) {
89 tmp = talloc_realloc(NULL, interfaces,
90 const struct ndr_interface_table *,
93 DEBUG(1, ("smb_register_ndr_interface: talloc failed\n"));
97 interfaces[num_interfaces] = interface;
101 static bool initialize_interfaces(void)
103 if (!smb_register_ndr_interface(&ndr_table_lsarpc)) {
106 if (!smb_register_ndr_interface(&ndr_table_dssetup)) {
109 if (!smb_register_ndr_interface(&ndr_table_samr)) {
112 if (!smb_register_ndr_interface(&ndr_table_netlogon)) {
115 if (!smb_register_ndr_interface(&ndr_table_srvsvc)) {
118 if (!smb_register_ndr_interface(&ndr_table_wkssvc)) {
121 if (!smb_register_ndr_interface(&ndr_table_winreg)) {
124 if (!smb_register_ndr_interface(&ndr_table_spoolss)) {
127 if (!smb_register_ndr_interface(&ndr_table_netdfs)) {
130 if (!smb_register_ndr_interface(&ndr_table_rpcecho)) {
133 if (!smb_register_ndr_interface(&ndr_table_initshutdown)) {
136 if (!smb_register_ndr_interface(&ndr_table_svcctl)) {
139 if (!smb_register_ndr_interface(&ndr_table_eventlog)) {
142 if (!smb_register_ndr_interface(&ndr_table_ntsvcs)) {
145 if (!smb_register_ndr_interface(&ndr_table_epmapper)) {
148 if (!smb_register_ndr_interface(&ndr_table_drsuapi)) {
154 const struct ndr_interface_table *get_iface_from_syntax(
155 const struct ndr_syntax_id *syntax)
160 if (interfaces == NULL) {
161 if (!initialize_interfaces()) {
165 num_interfaces = talloc_array_length(interfaces);
167 for (i=0; i<num_interfaces; i++) {
168 if (ndr_syntax_id_equal(&interfaces[i]->syntax_id, syntax)) {
169 return interfaces[i];
176 /****************************************************************************
177 Return the pipe name from the interface.
178 ****************************************************************************/
180 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
181 const struct ndr_syntax_id *syntax)
183 const struct ndr_interface_table *interface;
187 interface = get_iface_from_syntax(syntax);
188 if (interface != NULL) {
189 result = get_pipe_name_from_iface(mem_ctx, interface);
190 if (result != NULL) {
196 * Here we should ask \\epmapper, but for now our code is only
197 * interested in the known pipes mentioned in pipe_names[]
200 guid_str = GUID_string(talloc_tos(), &syntax->uuid);
201 if (guid_str == NULL) {
204 result = talloc_asprintf(mem_ctx, "Interface %s.%d", guid_str,
205 (int)syntax->if_version);
206 TALLOC_FREE(guid_str);
208 if (result == NULL) {
214 /********************************************************************
215 Map internal value to wire value.
216 ********************************************************************/
218 static int map_pipe_auth_type_to_rpc_auth_type(enum pipe_auth_type auth_type)
222 case PIPE_AUTH_TYPE_NONE:
223 return DCERPC_AUTH_TYPE_NONE;
225 case PIPE_AUTH_TYPE_NTLMSSP:
226 return DCERPC_AUTH_TYPE_NTLMSSP;
228 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
229 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
230 return DCERPC_AUTH_TYPE_SPNEGO;
232 case PIPE_AUTH_TYPE_SCHANNEL:
233 return DCERPC_AUTH_TYPE_SCHANNEL;
235 case PIPE_AUTH_TYPE_KRB5:
236 return DCERPC_AUTH_TYPE_KRB5;
239 DEBUG(0,("map_pipe_auth_type_to_rpc_type: unknown pipe "
241 (unsigned int)auth_type ));
247 /********************************************************************
248 Pipe description for a DEBUG
249 ********************************************************************/
250 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
251 struct rpc_pipe_client *cli)
253 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
254 if (result == NULL) {
260 /********************************************************************
262 ********************************************************************/
264 static uint32 get_rpc_call_id(void)
266 static uint32 call_id = 0;
271 * Realloc pdu to have a least "size" bytes
274 static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
278 if (prs_data_size(pdu) >= size) {
282 extra_size = size - prs_data_size(pdu);
284 if (!prs_force_grow(pdu, extra_size)) {
285 DEBUG(0, ("rpc_grow_buffer: Failed to grow parse struct by "
286 "%d bytes.\n", (int)extra_size));
290 DEBUG(5, ("rpc_grow_buffer: grew buffer by %d bytes to %u\n",
291 (int)extra_size, prs_data_size(pdu)));
296 /*******************************************************************
297 Use SMBreadX to get rest of one fragment's worth of rpc data.
298 Reads the whole size or give an error message
299 ********************************************************************/
301 struct rpc_read_state {
302 struct event_context *ev;
303 struct rpc_cli_transport *transport;
309 static void rpc_read_done(struct tevent_req *subreq);
311 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
312 struct event_context *ev,
313 struct rpc_cli_transport *transport,
314 uint8_t *data, size_t size)
316 struct tevent_req *req, *subreq;
317 struct rpc_read_state *state;
319 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
324 state->transport = transport;
329 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
331 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
333 if (subreq == NULL) {
336 tevent_req_set_callback(subreq, rpc_read_done, req);
344 static void rpc_read_done(struct tevent_req *subreq)
346 struct tevent_req *req = tevent_req_callback_data(
347 subreq, struct tevent_req);
348 struct rpc_read_state *state = tevent_req_data(
349 req, struct rpc_read_state);
353 status = state->transport->read_recv(subreq, &received);
355 if (!NT_STATUS_IS_OK(status)) {
356 tevent_req_nterror(req, status);
360 state->num_read += received;
361 if (state->num_read == state->size) {
362 tevent_req_done(req);
366 subreq = state->transport->read_send(state, state->ev,
367 state->data + state->num_read,
368 state->size - state->num_read,
369 state->transport->priv);
370 if (tevent_req_nomem(subreq, req)) {
373 tevent_req_set_callback(subreq, rpc_read_done, req);
376 static NTSTATUS rpc_read_recv(struct tevent_req *req)
378 return tevent_req_simple_recv_ntstatus(req);
381 struct rpc_write_state {
382 struct event_context *ev;
383 struct rpc_cli_transport *transport;
389 static void rpc_write_done(struct tevent_req *subreq);
391 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
392 struct event_context *ev,
393 struct rpc_cli_transport *transport,
394 const uint8_t *data, size_t size)
396 struct tevent_req *req, *subreq;
397 struct rpc_write_state *state;
399 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
404 state->transport = transport;
407 state->num_written = 0;
409 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
411 subreq = transport->write_send(state, ev, data, size, transport->priv);
412 if (subreq == NULL) {
415 tevent_req_set_callback(subreq, rpc_write_done, req);
422 static void rpc_write_done(struct tevent_req *subreq)
424 struct tevent_req *req = tevent_req_callback_data(
425 subreq, struct tevent_req);
426 struct rpc_write_state *state = tevent_req_data(
427 req, struct rpc_write_state);
431 status = state->transport->write_recv(subreq, &written);
433 if (!NT_STATUS_IS_OK(status)) {
434 tevent_req_nterror(req, status);
438 state->num_written += written;
440 if (state->num_written == state->size) {
441 tevent_req_done(req);
445 subreq = state->transport->write_send(state, state->ev,
446 state->data + state->num_written,
447 state->size - state->num_written,
448 state->transport->priv);
449 if (tevent_req_nomem(subreq, req)) {
452 tevent_req_set_callback(subreq, rpc_write_done, req);
455 static NTSTATUS rpc_write_recv(struct tevent_req *req)
457 return tevent_req_simple_recv_ntstatus(req);
461 static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
462 struct rpc_hdr_info *prhdr,
466 * This next call sets the endian bit correctly in current_pdu. We
467 * will propagate this to rbuf later.
470 if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
471 DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
472 return NT_STATUS_BUFFER_TOO_SMALL;
475 if (prhdr->frag_len > cli->max_recv_frag) {
476 DEBUG(0, ("cli_pipe_get_current_pdu: Server sent fraglen %d,"
477 " we only allow %d\n", (int)prhdr->frag_len,
478 (int)cli->max_recv_frag));
479 return NT_STATUS_BUFFER_TOO_SMALL;
485 /****************************************************************************
486 Try and get a PDU's worth of data from current_pdu. If not, then read more
488 ****************************************************************************/
490 struct get_complete_frag_state {
491 struct event_context *ev;
492 struct rpc_pipe_client *cli;
493 struct rpc_hdr_info *prhdr;
497 static void get_complete_frag_got_header(struct tevent_req *subreq);
498 static void get_complete_frag_got_rest(struct tevent_req *subreq);
500 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
501 struct event_context *ev,
502 struct rpc_pipe_client *cli,
503 struct rpc_hdr_info *prhdr,
506 struct tevent_req *req, *subreq;
507 struct get_complete_frag_state *state;
511 req = tevent_req_create(mem_ctx, &state,
512 struct get_complete_frag_state);
518 state->prhdr = prhdr;
521 pdu_len = prs_data_size(pdu);
522 if (pdu_len < RPC_HEADER_LEN) {
523 if (!rpc_grow_buffer(pdu, RPC_HEADER_LEN)) {
524 status = NT_STATUS_NO_MEMORY;
527 subreq = rpc_read_send(
529 state->cli->transport,
530 (uint8_t *)(prs_data_p(state->pdu) + pdu_len),
531 RPC_HEADER_LEN - pdu_len);
532 if (subreq == NULL) {
533 status = NT_STATUS_NO_MEMORY;
536 tevent_req_set_callback(subreq, get_complete_frag_got_header,
541 status = parse_rpc_header(cli, prhdr, pdu);
542 if (!NT_STATUS_IS_OK(status)) {
547 * Ensure we have frag_len bytes of data.
549 if (pdu_len < prhdr->frag_len) {
550 if (!rpc_grow_buffer(pdu, prhdr->frag_len)) {
551 status = NT_STATUS_NO_MEMORY;
554 subreq = rpc_read_send(state, state->ev,
555 state->cli->transport,
556 (uint8_t *)(prs_data_p(pdu) + pdu_len),
557 prhdr->frag_len - pdu_len);
558 if (subreq == NULL) {
559 status = NT_STATUS_NO_MEMORY;
562 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
567 status = NT_STATUS_OK;
569 if (NT_STATUS_IS_OK(status)) {
570 tevent_req_done(req);
572 tevent_req_nterror(req, status);
574 return tevent_req_post(req, ev);
577 static void get_complete_frag_got_header(struct tevent_req *subreq)
579 struct tevent_req *req = tevent_req_callback_data(
580 subreq, struct tevent_req);
581 struct get_complete_frag_state *state = tevent_req_data(
582 req, struct get_complete_frag_state);
585 status = rpc_read_recv(subreq);
587 if (!NT_STATUS_IS_OK(status)) {
588 tevent_req_nterror(req, status);
592 status = parse_rpc_header(state->cli, state->prhdr, state->pdu);
593 if (!NT_STATUS_IS_OK(status)) {
594 tevent_req_nterror(req, status);
598 if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) {
599 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
604 * We're here in this piece of code because we've read exactly
605 * RPC_HEADER_LEN bytes into state->pdu.
608 subreq = rpc_read_send(
609 state, state->ev, state->cli->transport,
610 (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN),
611 state->prhdr->frag_len - RPC_HEADER_LEN);
612 if (tevent_req_nomem(subreq, req)) {
615 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
618 static void get_complete_frag_got_rest(struct tevent_req *subreq)
620 struct tevent_req *req = tevent_req_callback_data(
621 subreq, struct tevent_req);
624 status = rpc_read_recv(subreq);
626 if (!NT_STATUS_IS_OK(status)) {
627 tevent_req_nterror(req, status);
630 tevent_req_done(req);
633 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
635 return tevent_req_simple_recv_ntstatus(req);
638 /****************************************************************************
639 NTLMSSP specific sign/seal.
640 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
641 In fact I should probably abstract these into identical pieces of code... JRA.
642 ****************************************************************************/
644 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
645 prs_struct *current_pdu,
646 uint8 *p_ss_padding_len)
648 RPC_HDR_AUTH auth_info;
649 uint32 save_offset = prs_offset(current_pdu);
650 uint32 auth_len = prhdr->auth_len;
651 struct ntlmssp_state *ntlmssp_state = cli->auth->a_u.ntlmssp_state;
652 unsigned char *data = NULL;
654 unsigned char *full_packet_data = NULL;
655 size_t full_packet_data_len;
659 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
660 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
664 if (!ntlmssp_state) {
665 return NT_STATUS_INVALID_PARAMETER;
668 /* Ensure there's enough data for an authenticated response. */
669 if (auth_len > RPC_MAX_PDU_FRAG_LEN ||
670 prhdr->frag_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
671 RPC_HDR_AUTH_LEN + auth_len) {
672 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
673 (unsigned int)auth_len ));
674 return NT_STATUS_BUFFER_TOO_SMALL;
678 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
679 * after the RPC header.
680 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
681 * functions as NTLMv2 checks the rpc headers also.
684 data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
685 data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
687 full_packet_data = (unsigned char *)prs_data_p(current_pdu);
688 full_packet_data_len = prhdr->frag_len - auth_len;
690 /* Pull the auth header and the following data into a blob. */
691 /* NB. The offset of the auth_header is relative to the *end*
692 * of the packet, not the start. */
693 if(!prs_set_offset(current_pdu, prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
694 DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
695 (unsigned int)RPC_HEADER_LEN + (unsigned int)RPC_HDR_RESP_LEN + (unsigned int)data_len ));
696 return NT_STATUS_BUFFER_TOO_SMALL;
699 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
700 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall RPC_HDR_AUTH.\n"));
701 return NT_STATUS_BUFFER_TOO_SMALL;
704 /* Ensure auth_pad_len fits into the packet. */
705 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
706 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
707 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
708 "too large (%u), auth_len (%u), frag_len = (%u).\n",
709 (unsigned int)auth_info.auth_pad_len,
710 (unsigned int)auth_len,
711 (unsigned int)prhdr->frag_len ));
712 return NT_STATUS_BUFFER_TOO_SMALL;
716 auth_blob.data = (unsigned char *)prs_data_p(current_pdu) + prs_offset(current_pdu);
717 auth_blob.length = auth_len;
719 switch (cli->auth->auth_level) {
720 case DCERPC_AUTH_LEVEL_PRIVACY:
721 /* Data is encrypted. */
722 status = ntlmssp_unseal_packet(ntlmssp_state,
725 full_packet_data_len,
727 if (!NT_STATUS_IS_OK(status)) {
728 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unseal "
729 "packet from %s. Error was %s.\n",
730 rpccli_pipe_txt(talloc_tos(), cli),
731 nt_errstr(status) ));
735 case DCERPC_AUTH_LEVEL_INTEGRITY:
736 /* Data is signed. */
737 status = ntlmssp_check_packet(ntlmssp_state,
740 full_packet_data_len,
742 if (!NT_STATUS_IS_OK(status)) {
743 DEBUG(0,("cli_pipe_verify_ntlmssp: check signing failed on "
744 "packet from %s. Error was %s.\n",
745 rpccli_pipe_txt(talloc_tos(), cli),
746 nt_errstr(status) ));
751 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
752 "auth level %d\n", cli->auth->auth_level));
753 return NT_STATUS_INVALID_INFO_CLASS;
757 * Return the current pointer to the data offset.
760 if(!prs_set_offset(current_pdu, save_offset)) {
761 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
762 (unsigned int)save_offset ));
763 return NT_STATUS_BUFFER_TOO_SMALL;
767 * Remember the padding length. We must remove it from the real data
768 * stream once the sign/seal is done.
771 *p_ss_padding_len = auth_info.auth_pad_len;
776 /****************************************************************************
777 schannel specific sign/seal.
778 ****************************************************************************/
780 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
781 prs_struct *current_pdu,
782 uint8 *p_ss_padding_len)
784 RPC_HDR_AUTH auth_info;
785 uint32 auth_len = prhdr->auth_len;
786 uint32 save_offset = prs_offset(current_pdu);
787 struct schannel_state *schannel_auth =
788 cli->auth->a_u.schannel_auth;
794 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
795 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
799 if (auth_len < RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) {
800 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u.\n", (unsigned int)auth_len ));
801 return NT_STATUS_INVALID_PARAMETER;
804 if (!schannel_auth) {
805 return NT_STATUS_INVALID_PARAMETER;
808 /* Ensure there's enough data for an authenticated response. */
809 if ((auth_len > RPC_MAX_PDU_FRAG_LEN) ||
810 (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
811 DEBUG(0,("cli_pipe_verify_schannel: auth_len %u is too large.\n",
812 (unsigned int)auth_len ));
813 return NT_STATUS_INVALID_PARAMETER;
816 data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
818 /* Pull the auth header and the following data into a blob. */
819 /* NB. The offset of the auth_header is relative to the *end*
820 * of the packet, not the start. */
821 if(!prs_set_offset(current_pdu,
822 prhdr->frag_len - RPC_HDR_AUTH_LEN - auth_len)) {
823 DEBUG(0,("cli_pipe_verify_schannel: cannot move "
825 (unsigned int)(prhdr->frag_len -
826 RPC_HDR_AUTH_LEN - auth_len) ));
827 return NT_STATUS_BUFFER_TOO_SMALL;
830 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, current_pdu, 0)) {
831 DEBUG(0,("cli_pipe_verify_schannel: failed to unmarshall RPC_HDR_AUTH.\n"));
832 return NT_STATUS_BUFFER_TOO_SMALL;
835 /* Ensure auth_pad_len fits into the packet. */
836 if (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + auth_info.auth_pad_len +
837 RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len) {
838 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
839 "too large (%u), auth_len (%u), frag_len = (%u).\n",
840 (unsigned int)auth_info.auth_pad_len,
841 (unsigned int)auth_len,
842 (unsigned int)prhdr->frag_len ));
843 return NT_STATUS_BUFFER_TOO_SMALL;
846 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
847 DEBUG(0,("cli_pipe_verify_schannel: Invalid auth info %d on schannel\n",
848 auth_info.auth_type));
849 return NT_STATUS_BUFFER_TOO_SMALL;
852 blob = data_blob_const(prs_data_p(current_pdu) + prs_offset(current_pdu), auth_len);
854 if (DEBUGLEVEL >= 10) {
855 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
858 data = (uint8_t *)prs_data_p(current_pdu)+RPC_HEADER_LEN+RPC_HDR_RESP_LEN;
860 switch (cli->auth->auth_level) {
861 case DCERPC_AUTH_LEVEL_PRIVACY:
862 status = netsec_incoming_packet(schannel_auth,
869 case DCERPC_AUTH_LEVEL_INTEGRITY:
870 status = netsec_incoming_packet(schannel_auth,
878 status = NT_STATUS_INTERNAL_ERROR;
882 if (!NT_STATUS_IS_OK(status)) {
883 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
884 "Connection to %s (%s).\n",
885 rpccli_pipe_txt(talloc_tos(), cli),
887 return NT_STATUS_INVALID_PARAMETER;
891 * Return the current pointer to the data offset.
894 if(!prs_set_offset(current_pdu, save_offset)) {
895 DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
896 (unsigned int)save_offset ));
897 return NT_STATUS_BUFFER_TOO_SMALL;
901 * Remember the padding length. We must remove it from the real data
902 * stream once the sign/seal is done.
905 *p_ss_padding_len = auth_info.auth_pad_len;
910 /****************************************************************************
911 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
912 ****************************************************************************/
914 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
915 prs_struct *current_pdu,
916 uint8 *p_ss_padding_len)
918 NTSTATUS ret = NT_STATUS_OK;
920 /* Paranioa checks for auth_len. */
921 if (prhdr->auth_len) {
922 if (prhdr->auth_len > prhdr->frag_len) {
923 return NT_STATUS_INVALID_PARAMETER;
926 if (prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < prhdr->auth_len ||
927 prhdr->auth_len + (unsigned int)RPC_HDR_AUTH_LEN < (unsigned int)RPC_HDR_AUTH_LEN) {
928 /* Integer wrap attempt. */
929 return NT_STATUS_INVALID_PARAMETER;
934 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
937 switch(cli->auth->auth_type) {
938 case PIPE_AUTH_TYPE_NONE:
939 if (prhdr->auth_len) {
940 DEBUG(3, ("cli_pipe_validate_rpc_response: "
941 "Connection to %s - got non-zero "
943 rpccli_pipe_txt(talloc_tos(), cli),
944 (unsigned int)prhdr->auth_len ));
945 return NT_STATUS_INVALID_PARAMETER;
949 case PIPE_AUTH_TYPE_NTLMSSP:
950 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
951 ret = cli_pipe_verify_ntlmssp(cli, prhdr, current_pdu, p_ss_padding_len);
952 if (!NT_STATUS_IS_OK(ret)) {
957 case PIPE_AUTH_TYPE_SCHANNEL:
958 ret = cli_pipe_verify_schannel(cli, prhdr, current_pdu, p_ss_padding_len);
959 if (!NT_STATUS_IS_OK(ret)) {
964 case PIPE_AUTH_TYPE_KRB5:
965 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
967 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
968 "to %s - unknown internal auth type %u.\n",
969 rpccli_pipe_txt(talloc_tos(), cli),
970 cli->auth->auth_type ));
971 return NT_STATUS_INVALID_INFO_CLASS;
977 /****************************************************************************
978 Do basic authentication checks on an incoming pdu.
979 ****************************************************************************/
981 static NTSTATUS cli_pipe_validate_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr,
982 prs_struct *current_pdu,
983 uint8 expected_pkt_type,
986 prs_struct *return_data)
989 NTSTATUS ret = NT_STATUS_OK;
990 uint32 current_pdu_len = prs_data_size(current_pdu);
992 if (current_pdu_len != prhdr->frag_len) {
993 DEBUG(5,("cli_pipe_validate_current_pdu: incorrect pdu length %u, expected %u\n",
994 (unsigned int)current_pdu_len, (unsigned int)prhdr->frag_len ));
995 return NT_STATUS_INVALID_PARAMETER;
999 * Point the return values at the real data including the RPC
1000 * header. Just in case the caller wants it.
1002 *ppdata = prs_data_p(current_pdu);
1003 *pdata_len = current_pdu_len;
1005 /* Ensure we have the correct type. */
1006 switch (prhdr->pkt_type) {
1007 case DCERPC_PKT_ALTER_RESP:
1008 case DCERPC_PKT_BIND_ACK:
1010 /* Alter context and bind ack share the same packet definitions. */
1014 case DCERPC_PKT_RESPONSE:
1016 RPC_HDR_RESP rhdr_resp;
1017 uint8 ss_padding_len = 0;
1019 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1020 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1021 return NT_STATUS_BUFFER_TOO_SMALL;
1024 /* Here's where we deal with incoming sign/seal. */
1025 ret = cli_pipe_validate_rpc_response(cli, prhdr,
1026 current_pdu, &ss_padding_len);
1027 if (!NT_STATUS_IS_OK(ret)) {
1031 /* Point the return values at the NDR data. Remember to remove any ss padding. */
1032 *ppdata = prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
1034 if (current_pdu_len < RPC_HEADER_LEN + RPC_HDR_RESP_LEN + ss_padding_len) {
1035 return NT_STATUS_BUFFER_TOO_SMALL;
1038 *pdata_len = current_pdu_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - ss_padding_len;
1040 /* Remember to remove the auth footer. */
1041 if (prhdr->auth_len) {
1042 /* We've already done integer wrap tests on auth_len in
1043 cli_pipe_validate_rpc_response(). */
1044 if (*pdata_len < RPC_HDR_AUTH_LEN + prhdr->auth_len) {
1045 return NT_STATUS_BUFFER_TOO_SMALL;
1047 *pdata_len -= (RPC_HDR_AUTH_LEN + prhdr->auth_len);
1050 DEBUG(10,("cli_pipe_validate_current_pdu: got pdu len %u, data_len %u, ss_len %u\n",
1051 current_pdu_len, *pdata_len, ss_padding_len ));
1054 * If this is the first reply, and the allocation hint is reasonably, try and
1055 * set up the return_data parse_struct to the correct size.
1058 if ((prs_data_size(return_data) == 0) && rhdr_resp.alloc_hint && (rhdr_resp.alloc_hint < 15*1024*1024)) {
1059 if (!prs_set_buffer_size(return_data, rhdr_resp.alloc_hint)) {
1060 DEBUG(0,("cli_pipe_validate_current_pdu: reply alloc hint %u "
1061 "too large to allocate\n",
1062 (unsigned int)rhdr_resp.alloc_hint ));
1063 return NT_STATUS_NO_MEMORY;
1070 case DCERPC_PKT_BIND_NAK:
1071 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
1072 "received from %s!\n",
1073 rpccli_pipe_txt(talloc_tos(), cli)));
1074 /* Use this for now... */
1075 return NT_STATUS_NETWORK_ACCESS_DENIED;
1077 case DCERPC_PKT_FAULT:
1079 RPC_HDR_RESP rhdr_resp;
1080 RPC_HDR_FAULT fault_resp;
1082 if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, current_pdu, 0)) {
1083 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_RESP.\n"));
1084 return NT_STATUS_BUFFER_TOO_SMALL;
1087 if(!smb_io_rpc_hdr_fault("fault", &fault_resp, current_pdu, 0)) {
1088 DEBUG(5,("cli_pipe_validate_current_pdu: failed to unmarshal RPC_HDR_FAULT.\n"));
1089 return NT_STATUS_BUFFER_TOO_SMALL;
1092 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
1093 "code %s received from %s!\n",
1094 dcerpc_errstr(talloc_tos(), NT_STATUS_V(fault_resp.status)),
1095 rpccli_pipe_txt(talloc_tos(), cli)));
1096 if (NT_STATUS_IS_OK(fault_resp.status)) {
1097 return NT_STATUS_UNSUCCESSFUL;
1099 return fault_resp.status;
1104 DEBUG(0, ("cli_pipe_validate_current_pdu: unknown packet type %u received "
1106 (unsigned int)prhdr->pkt_type,
1107 rpccli_pipe_txt(talloc_tos(), cli)));
1108 return NT_STATUS_INVALID_INFO_CLASS;
1111 if (prhdr->pkt_type != expected_pkt_type) {
1112 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
1113 "got an unexpected RPC packet type - %u, not %u\n",
1114 rpccli_pipe_txt(talloc_tos(), cli),
1116 expected_pkt_type));
1117 return NT_STATUS_INVALID_INFO_CLASS;
1120 /* Do this just before return - we don't want to modify any rpc header
1121 data before now as we may have needed to do cryptographic actions on
1124 if ((prhdr->pkt_type == DCERPC_PKT_BIND_ACK) && !(prhdr->flags & DCERPC_PFC_FLAG_LAST)) {
1125 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
1126 "setting fragment first/last ON.\n"));
1127 prhdr->flags |= DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST;
1130 return NT_STATUS_OK;
1133 /****************************************************************************
1134 Ensure we eat the just processed pdu from the current_pdu prs_struct.
1135 Normally the frag_len and buffer size will match, but on the first trans
1136 reply there is a theoretical chance that buffer size > frag_len, so we must
1138 ****************************************************************************/
1140 static NTSTATUS cli_pipe_reset_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
1142 uint32 current_pdu_len = prs_data_size(current_pdu);
1144 if (current_pdu_len < prhdr->frag_len) {
1145 return NT_STATUS_BUFFER_TOO_SMALL;
1149 if (current_pdu_len == (uint32)prhdr->frag_len) {
1150 prs_mem_free(current_pdu);
1151 prs_init_empty(current_pdu, prs_get_mem_context(current_pdu), UNMARSHALL);
1152 /* Make current_pdu dynamic with no memory. */
1153 prs_give_memory(current_pdu, 0, 0, True);
1154 return NT_STATUS_OK;
1158 * Oh no ! More data in buffer than we processed in current pdu.
1159 * Cheat. Move the data down and shrink the buffer.
1162 memcpy(prs_data_p(current_pdu), prs_data_p(current_pdu) + prhdr->frag_len,
1163 current_pdu_len - prhdr->frag_len);
1165 /* Remember to set the read offset back to zero. */
1166 prs_set_offset(current_pdu, 0);
1168 /* Shrink the buffer. */
1169 if (!prs_set_buffer_size(current_pdu, current_pdu_len - prhdr->frag_len)) {
1170 return NT_STATUS_BUFFER_TOO_SMALL;
1173 return NT_STATUS_OK;
1176 /****************************************************************************
1177 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
1178 ****************************************************************************/
1180 struct cli_api_pipe_state {
1181 struct event_context *ev;
1182 struct rpc_cli_transport *transport;
1187 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
1188 static void cli_api_pipe_write_done(struct tevent_req *subreq);
1189 static void cli_api_pipe_read_done(struct tevent_req *subreq);
1191 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
1192 struct event_context *ev,
1193 struct rpc_cli_transport *transport,
1194 uint8_t *data, size_t data_len,
1195 uint32_t max_rdata_len)
1197 struct tevent_req *req, *subreq;
1198 struct cli_api_pipe_state *state;
1201 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
1206 state->transport = transport;
1208 if (max_rdata_len < RPC_HEADER_LEN) {
1210 * For a RPC reply we always need at least RPC_HEADER_LEN
1211 * bytes. We check this here because we will receive
1212 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
1214 status = NT_STATUS_INVALID_PARAMETER;
1218 if (transport->trans_send != NULL) {
1219 subreq = transport->trans_send(state, ev, data, data_len,
1220 max_rdata_len, transport->priv);
1221 if (subreq == NULL) {
1224 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
1229 * If the transport does not provide a "trans" routine, i.e. for
1230 * example the ncacn_ip_tcp transport, do the write/read step here.
1233 subreq = rpc_write_send(state, ev, transport, data, data_len);
1234 if (subreq == NULL) {
1237 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
1240 status = NT_STATUS_INVALID_PARAMETER;
1243 tevent_req_nterror(req, status);
1244 return tevent_req_post(req, ev);
1250 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
1252 struct tevent_req *req = tevent_req_callback_data(
1253 subreq, struct tevent_req);
1254 struct cli_api_pipe_state *state = tevent_req_data(
1255 req, struct cli_api_pipe_state);
1258 status = state->transport->trans_recv(subreq, state, &state->rdata,
1260 TALLOC_FREE(subreq);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 tevent_req_nterror(req, status);
1265 tevent_req_done(req);
1268 static void cli_api_pipe_write_done(struct tevent_req *subreq)
1270 struct tevent_req *req = tevent_req_callback_data(
1271 subreq, struct tevent_req);
1272 struct cli_api_pipe_state *state = tevent_req_data(
1273 req, struct cli_api_pipe_state);
1276 status = rpc_write_recv(subreq);
1277 TALLOC_FREE(subreq);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 tevent_req_nterror(req, status);
1283 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
1284 if (tevent_req_nomem(state->rdata, req)) {
1289 * We don't need to use rpc_read_send here, the upper layer will cope
1290 * with a short read, transport->trans_send could also return less
1291 * than state->max_rdata_len.
1293 subreq = state->transport->read_send(state, state->ev, state->rdata,
1295 state->transport->priv);
1296 if (tevent_req_nomem(subreq, req)) {
1299 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
1302 static void cli_api_pipe_read_done(struct tevent_req *subreq)
1304 struct tevent_req *req = tevent_req_callback_data(
1305 subreq, struct tevent_req);
1306 struct cli_api_pipe_state *state = tevent_req_data(
1307 req, struct cli_api_pipe_state);
1311 status = state->transport->read_recv(subreq, &received);
1312 TALLOC_FREE(subreq);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 tevent_req_nterror(req, status);
1317 state->rdata_len = received;
1318 tevent_req_done(req);
1321 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1322 uint8_t **prdata, uint32_t *prdata_len)
1324 struct cli_api_pipe_state *state = tevent_req_data(
1325 req, struct cli_api_pipe_state);
1328 if (tevent_req_is_nterror(req, &status)) {
1332 *prdata = talloc_move(mem_ctx, &state->rdata);
1333 *prdata_len = state->rdata_len;
1334 return NT_STATUS_OK;
1337 /****************************************************************************
1338 Send data on an rpc pipe via trans. The prs_struct data must be the last
1339 pdu fragment of an NDR data stream.
1341 Receive response data from an rpc pipe, which may be large...
1343 Read the first fragment: unfortunately have to use SMBtrans for the first
1344 bit, then SMBreadX for subsequent bits.
1346 If first fragment received also wasn't the last fragment, continue
1347 getting fragments until we _do_ receive the last fragment.
1349 Request/Response PDU's look like the following...
1351 |<------------------PDU len----------------------------------------------->|
1352 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1354 +------------+-----------------+-------------+---------------+-------------+
1355 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1356 +------------+-----------------+-------------+---------------+-------------+
1358 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1359 signing & sealing being negotiated.
1361 ****************************************************************************/
1363 struct rpc_api_pipe_state {
1364 struct event_context *ev;
1365 struct rpc_pipe_client *cli;
1366 uint8_t expected_pkt_type;
1368 prs_struct incoming_frag;
1369 struct rpc_hdr_info rhdr;
1371 prs_struct incoming_pdu; /* Incoming reply */
1372 uint32_t incoming_pdu_offset;
1375 static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state)
1377 prs_mem_free(&state->incoming_frag);
1378 prs_mem_free(&state->incoming_pdu);
1382 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1383 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1385 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1386 struct event_context *ev,
1387 struct rpc_pipe_client *cli,
1388 prs_struct *data, /* Outgoing PDU */
1389 uint8_t expected_pkt_type)
1391 struct tevent_req *req, *subreq;
1392 struct rpc_api_pipe_state *state;
1393 uint16_t max_recv_frag;
1396 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1402 state->expected_pkt_type = expected_pkt_type;
1403 state->incoming_pdu_offset = 0;
1405 prs_init_empty(&state->incoming_frag, state, UNMARSHALL);
1407 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1408 /* Make incoming_pdu dynamic with no memory. */
1409 prs_give_memory(&state->incoming_pdu, NULL, 0, true);
1411 talloc_set_destructor(state, rpc_api_pipe_state_destructor);
1414 * Ensure we're not sending too much.
1416 if (prs_offset(data) > cli->max_xmit_frag) {
1417 status = NT_STATUS_INVALID_PARAMETER;
1421 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1423 max_recv_frag = cli->max_recv_frag;
1426 max_recv_frag = RPC_HEADER_LEN + 10 + (sys_random() % 32);
1429 subreq = cli_api_pipe_send(state, ev, cli->transport,
1430 (uint8_t *)prs_data_p(data),
1431 prs_offset(data), max_recv_frag);
1432 if (subreq == NULL) {
1435 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1439 tevent_req_nterror(req, status);
1440 return tevent_req_post(req, ev);
1446 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1448 struct tevent_req *req = tevent_req_callback_data(
1449 subreq, struct tevent_req);
1450 struct rpc_api_pipe_state *state = tevent_req_data(
1451 req, struct rpc_api_pipe_state);
1453 uint8_t *rdata = NULL;
1454 uint32_t rdata_len = 0;
1457 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1458 TALLOC_FREE(subreq);
1459 if (!NT_STATUS_IS_OK(status)) {
1460 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1461 tevent_req_nterror(req, status);
1465 if (rdata == NULL) {
1466 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1467 rpccli_pipe_txt(talloc_tos(), state->cli)));
1468 tevent_req_done(req);
1473 * Give the memory received from cli_trans as dynamic to the current
1474 * pdu. Duplicating it sucks, but prs_struct doesn't know about talloc
1477 rdata_copy = (char *)memdup(rdata, rdata_len);
1479 if (tevent_req_nomem(rdata_copy, req)) {
1482 prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true);
1484 /* Ensure we have enough data for a pdu. */
1485 subreq = get_complete_frag_send(state, state->ev, state->cli,
1486 &state->rhdr, &state->incoming_frag);
1487 if (tevent_req_nomem(subreq, req)) {
1490 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1493 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1495 struct tevent_req *req = tevent_req_callback_data(
1496 subreq, struct tevent_req);
1497 struct rpc_api_pipe_state *state = tevent_req_data(
1498 req, struct rpc_api_pipe_state);
1501 uint32_t rdata_len = 0;
1503 status = get_complete_frag_recv(subreq);
1504 TALLOC_FREE(subreq);
1505 if (!NT_STATUS_IS_OK(status)) {
1506 DEBUG(5, ("get_complete_frag failed: %s\n",
1507 nt_errstr(status)));
1508 tevent_req_nterror(req, status);
1512 status = cli_pipe_validate_current_pdu(
1513 state->cli, &state->rhdr, &state->incoming_frag,
1514 state->expected_pkt_type, &rdata, &rdata_len,
1515 &state->incoming_pdu);
1517 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1518 (unsigned)prs_data_size(&state->incoming_frag),
1519 (unsigned)state->incoming_pdu_offset,
1520 nt_errstr(status)));
1522 if (!NT_STATUS_IS_OK(status)) {
1523 tevent_req_nterror(req, status);
1527 if ((state->rhdr.flags & DCERPC_PFC_FLAG_FIRST)
1528 && (state->rhdr.pack_type[0] == 0)) {
1530 * Set the data type correctly for big-endian data on the
1533 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1535 rpccli_pipe_txt(talloc_tos(), state->cli)));
1536 prs_set_endian_data(&state->incoming_pdu, RPC_BIG_ENDIAN);
1539 * Check endianness on subsequent packets.
1541 if (state->incoming_frag.bigendian_data
1542 != state->incoming_pdu.bigendian_data) {
1543 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1545 state->incoming_pdu.bigendian_data?"big":"little",
1546 state->incoming_frag.bigendian_data?"big":"little"));
1547 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1551 /* Now copy the data portion out of the pdu into rbuf. */
1552 if (!prs_force_grow(&state->incoming_pdu, rdata_len)) {
1553 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1557 memcpy(prs_data_p(&state->incoming_pdu) + state->incoming_pdu_offset,
1558 rdata, (size_t)rdata_len);
1559 state->incoming_pdu_offset += rdata_len;
1561 status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr,
1562 &state->incoming_frag);
1563 if (!NT_STATUS_IS_OK(status)) {
1564 tevent_req_nterror(req, status);
1568 if (state->rhdr.flags & DCERPC_PFC_FLAG_LAST) {
1569 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1570 rpccli_pipe_txt(talloc_tos(), state->cli),
1571 (unsigned)prs_data_size(&state->incoming_pdu)));
1572 tevent_req_done(req);
1576 subreq = get_complete_frag_send(state, state->ev, state->cli,
1577 &state->rhdr, &state->incoming_frag);
1578 if (tevent_req_nomem(subreq, req)) {
1581 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1584 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1585 prs_struct *reply_pdu)
1587 struct rpc_api_pipe_state *state = tevent_req_data(
1588 req, struct rpc_api_pipe_state);
1591 if (tevent_req_is_nterror(req, &status)) {
1595 *reply_pdu = state->incoming_pdu;
1596 reply_pdu->mem_ctx = mem_ctx;
1599 * Prevent state->incoming_pdu from being freed in
1600 * rpc_api_pipe_state_destructor()
1602 prs_init_empty(&state->incoming_pdu, state, UNMARSHALL);
1604 return NT_STATUS_OK;
1607 /*******************************************************************
1608 Creates krb5 auth bind.
1609 ********************************************************************/
1611 static NTSTATUS create_krb5_auth_bind_req( struct rpc_pipe_client *cli,
1612 enum dcerpc_AuthLevel auth_level,
1613 RPC_HDR_AUTH *pauth_out,
1614 prs_struct *auth_data)
1618 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1619 DATA_BLOB tkt = data_blob_null;
1620 DATA_BLOB tkt_wrapped = data_blob_null;
1622 /* We may change the pad length before marshalling. */
1623 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_KRB5, (int)auth_level, 0, 1);
1625 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1626 a->service_principal ));
1628 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1630 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1631 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1634 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1636 a->service_principal,
1637 error_message(ret) ));
1639 data_blob_free(&tkt);
1640 prs_mem_free(auth_data);
1641 return NT_STATUS_INVALID_PARAMETER;
1644 /* wrap that up in a nice GSS-API wrapping */
1645 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1647 data_blob_free(&tkt);
1649 /* Auth len in the rpc header doesn't include auth_header. */
1650 if (!prs_copy_data_in(auth_data, (char *)tkt_wrapped.data, tkt_wrapped.length)) {
1651 data_blob_free(&tkt_wrapped);
1652 prs_mem_free(auth_data);
1653 return NT_STATUS_NO_MEMORY;
1656 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1657 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1659 data_blob_free(&tkt_wrapped);
1660 return NT_STATUS_OK;
1662 return NT_STATUS_INVALID_PARAMETER;
1666 /*******************************************************************
1667 Creates SPNEGO NTLMSSP auth bind.
1668 ********************************************************************/
1670 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1671 enum dcerpc_AuthLevel auth_level,
1672 RPC_HDR_AUTH *pauth_out,
1673 prs_struct *auth_data)
1676 DATA_BLOB null_blob = data_blob_null;
1677 DATA_BLOB request = data_blob_null;
1678 DATA_BLOB spnego_msg = data_blob_null;
1680 /* We may change the pad length before marshalling. */
1681 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
1683 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1684 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1688 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1689 data_blob_free(&request);
1690 prs_mem_free(auth_data);
1694 /* Wrap this in SPNEGO. */
1695 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1697 data_blob_free(&request);
1699 /* Auth len in the rpc header doesn't include auth_header. */
1700 if (!prs_copy_data_in(auth_data, (char *)spnego_msg.data, spnego_msg.length)) {
1701 data_blob_free(&spnego_msg);
1702 prs_mem_free(auth_data);
1703 return NT_STATUS_NO_MEMORY;
1706 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1707 dump_data(5, spnego_msg.data, spnego_msg.length);
1709 data_blob_free(&spnego_msg);
1710 return NT_STATUS_OK;
1713 /*******************************************************************
1714 Creates NTLMSSP auth bind.
1715 ********************************************************************/
1717 static NTSTATUS create_ntlmssp_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1718 enum dcerpc_AuthLevel auth_level,
1719 RPC_HDR_AUTH *pauth_out,
1720 prs_struct *auth_data)
1723 DATA_BLOB null_blob = data_blob_null;
1724 DATA_BLOB request = data_blob_null;
1726 /* We may change the pad length before marshalling. */
1727 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_NTLMSSP, (int)auth_level, 0, 1);
1729 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1730 nt_status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1734 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1735 data_blob_free(&request);
1736 prs_mem_free(auth_data);
1740 /* Auth len in the rpc header doesn't include auth_header. */
1741 if (!prs_copy_data_in(auth_data, (char *)request.data, request.length)) {
1742 data_blob_free(&request);
1743 prs_mem_free(auth_data);
1744 return NT_STATUS_NO_MEMORY;
1747 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1748 dump_data(5, request.data, request.length);
1750 data_blob_free(&request);
1751 return NT_STATUS_OK;
1754 /*******************************************************************
1755 Creates schannel auth bind.
1756 ********************************************************************/
1758 static NTSTATUS create_schannel_auth_rpc_bind_req( struct rpc_pipe_client *cli,
1759 enum dcerpc_AuthLevel auth_level,
1760 RPC_HDR_AUTH *pauth_out,
1761 prs_struct *auth_data)
1763 struct NL_AUTH_MESSAGE r;
1764 enum ndr_err_code ndr_err;
1767 /* We may change the pad length before marshalling. */
1768 init_rpc_hdr_auth(pauth_out, DCERPC_AUTH_TYPE_SCHANNEL, (int)auth_level, 0, 1);
1770 /* Use lp_workgroup() if domain not specified */
1772 if (!cli->auth->domain || !cli->auth->domain[0]) {
1773 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1774 if (cli->auth->domain == NULL) {
1775 return NT_STATUS_NO_MEMORY;
1780 * Now marshall the data into the auth parse_struct.
1783 r.MessageType = NL_NEGOTIATE_REQUEST;
1784 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1785 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1786 r.oem_netbios_domain.a = cli->auth->domain;
1787 r.oem_netbios_computer.a = global_myname();
1789 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(), &r,
1790 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
1791 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1792 DEBUG(0,("Failed to marshall NL_AUTH_MESSAGE.\n"));
1793 prs_mem_free(auth_data);
1794 return ndr_map_error2ntstatus(ndr_err);
1797 if (DEBUGLEVEL >= 10) {
1798 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, &r);
1801 if (!prs_copy_data_in(auth_data, (const char *)blob.data, blob.length))
1803 prs_mem_free(auth_data);
1804 return NT_STATUS_NO_MEMORY;
1807 return NT_STATUS_OK;
1810 /*******************************************************************
1811 Creates the internals of a DCE/RPC bind request or alter context PDU.
1812 ********************************************************************/
1814 static NTSTATUS create_bind_or_alt_ctx_internal(enum dcerpc_pkt_type pkt_type,
1815 prs_struct *rpc_out,
1817 const struct ndr_syntax_id *abstract,
1818 const struct ndr_syntax_id *transfer,
1819 RPC_HDR_AUTH *phdr_auth,
1820 prs_struct *pauth_info)
1824 RPC_CONTEXT rpc_ctx;
1825 uint16 auth_len = prs_offset(pauth_info);
1826 uint8 ss_padding_len = 0;
1827 uint16 frag_len = 0;
1829 /* create the RPC context. */
1830 init_rpc_context(&rpc_ctx, 0 /* context id */, abstract, transfer);
1832 /* create the bind request RPC_HDR_RB */
1833 init_rpc_hdr_rb(&hdr_rb, RPC_MAX_PDU_FRAG_LEN, RPC_MAX_PDU_FRAG_LEN, 0x0, &rpc_ctx);
1835 /* Start building the frag length. */
1836 frag_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1838 /* Do we need to pad ? */
1840 uint16 data_len = RPC_HEADER_LEN + RPC_HDR_RB_LEN(&hdr_rb);
1841 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1842 ss_padding_len = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1843 phdr_auth->auth_pad_len = ss_padding_len;
1845 frag_len += RPC_HDR_AUTH_LEN + auth_len + ss_padding_len;
1848 /* Create the request RPC_HDR */
1849 init_rpc_hdr(&hdr, pkt_type, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id, frag_len, auth_len);
1851 /* Marshall the RPC header */
1852 if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
1853 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR.\n"));
1854 return NT_STATUS_NO_MEMORY;
1857 /* Marshall the bind request data */
1858 if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
1859 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1860 return NT_STATUS_NO_MEMORY;
1864 * Grow the outgoing buffer to store any auth info.
1868 if (ss_padding_len) {
1869 char pad[CLIENT_NDR_PADDING_SIZE];
1870 memset(pad, '\0', CLIENT_NDR_PADDING_SIZE);
1871 if (!prs_copy_data_in(rpc_out, pad, ss_padding_len)) {
1872 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall padding.\n"));
1873 return NT_STATUS_NO_MEMORY;
1877 if(!smb_io_rpc_hdr_auth("hdr_auth", phdr_auth, rpc_out, 0)) {
1878 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_AUTH.\n"));
1879 return NT_STATUS_NO_MEMORY;
1883 if(!prs_append_prs_data( rpc_out, pauth_info)) {
1884 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to grow parse struct to add auth.\n"));
1885 return NT_STATUS_NO_MEMORY;
1889 return NT_STATUS_OK;
1892 /*******************************************************************
1893 Creates a DCE/RPC bind request.
1894 ********************************************************************/
1896 static NTSTATUS create_rpc_bind_req(struct rpc_pipe_client *cli,
1897 prs_struct *rpc_out,
1899 const struct ndr_syntax_id *abstract,
1900 const struct ndr_syntax_id *transfer,
1901 enum pipe_auth_type auth_type,
1902 enum dcerpc_AuthLevel auth_level)
1904 RPC_HDR_AUTH hdr_auth;
1905 prs_struct auth_info;
1906 NTSTATUS ret = NT_STATUS_OK;
1908 ZERO_STRUCT(hdr_auth);
1909 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
1910 return NT_STATUS_NO_MEMORY;
1912 switch (auth_type) {
1913 case PIPE_AUTH_TYPE_SCHANNEL:
1914 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1915 if (!NT_STATUS_IS_OK(ret)) {
1916 prs_mem_free(&auth_info);
1921 case PIPE_AUTH_TYPE_NTLMSSP:
1922 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1923 if (!NT_STATUS_IS_OK(ret)) {
1924 prs_mem_free(&auth_info);
1929 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1930 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1931 if (!NT_STATUS_IS_OK(ret)) {
1932 prs_mem_free(&auth_info);
1937 case PIPE_AUTH_TYPE_KRB5:
1938 ret = create_krb5_auth_bind_req(cli, auth_level, &hdr_auth, &auth_info);
1939 if (!NT_STATUS_IS_OK(ret)) {
1940 prs_mem_free(&auth_info);
1945 case PIPE_AUTH_TYPE_NONE:
1949 /* "Can't" happen. */
1950 return NT_STATUS_INVALID_INFO_CLASS;
1953 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_BIND,
1961 prs_mem_free(&auth_info);
1965 /*******************************************************************
1966 Create and add the NTLMSSP sign/seal auth header and data.
1967 ********************************************************************/
1969 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1971 uint32 ss_padding_len,
1972 prs_struct *outgoing_pdu)
1974 RPC_HDR_AUTH auth_info;
1976 DATA_BLOB auth_blob = data_blob_null;
1977 uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
1979 if (!cli->auth->a_u.ntlmssp_state) {
1980 return NT_STATUS_INVALID_PARAMETER;
1983 /* Init and marshall the auth header. */
1984 init_rpc_hdr_auth(&auth_info,
1985 map_pipe_auth_type_to_rpc_auth_type(
1986 cli->auth->auth_type),
1987 cli->auth->auth_level,
1989 1 /* context id. */);
1991 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
1992 DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
1993 data_blob_free(&auth_blob);
1994 return NT_STATUS_NO_MEMORY;
1997 switch (cli->auth->auth_level) {
1998 case DCERPC_AUTH_LEVEL_PRIVACY:
1999 /* Data portion is encrypted. */
2000 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
2001 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2003 (unsigned char *)prs_data_p(outgoing_pdu),
2004 (size_t)prs_offset(outgoing_pdu),
2006 if (!NT_STATUS_IS_OK(status)) {
2007 data_blob_free(&auth_blob);
2012 case DCERPC_AUTH_LEVEL_INTEGRITY:
2013 /* Data is signed. */
2014 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
2015 (unsigned char *)prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
2017 (unsigned char *)prs_data_p(outgoing_pdu),
2018 (size_t)prs_offset(outgoing_pdu),
2020 if (!NT_STATUS_IS_OK(status)) {
2021 data_blob_free(&auth_blob);
2028 smb_panic("bad auth level");
2030 return NT_STATUS_INVALID_PARAMETER;
2033 /* Finally marshall the blob. */
2035 if (!prs_copy_data_in(outgoing_pdu, (const char *)auth_blob.data, NTLMSSP_SIG_SIZE)) {
2036 DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
2037 (unsigned int)NTLMSSP_SIG_SIZE));
2038 data_blob_free(&auth_blob);
2039 return NT_STATUS_NO_MEMORY;
2042 data_blob_free(&auth_blob);
2043 return NT_STATUS_OK;
2046 /*******************************************************************
2047 Create and add the schannel sign/seal auth header and data.
2048 ********************************************************************/
2050 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
2052 uint32 ss_padding_len,
2053 prs_struct *outgoing_pdu)
2055 RPC_HDR_AUTH auth_info;
2056 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
2057 char *data_p = prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN;
2058 size_t data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
2063 return NT_STATUS_INVALID_PARAMETER;
2066 /* Init and marshall the auth header. */
2067 init_rpc_hdr_auth(&auth_info,
2068 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
2069 cli->auth->auth_level,
2071 1 /* context id. */);
2073 if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
2074 DEBUG(0,("add_schannel_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
2075 return NT_STATUS_NO_MEMORY;
2078 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
2081 switch (cli->auth->auth_level) {
2082 case DCERPC_AUTH_LEVEL_PRIVACY:
2083 status = netsec_outgoing_packet(sas,
2090 case DCERPC_AUTH_LEVEL_INTEGRITY:
2091 status = netsec_outgoing_packet(sas,
2099 status = NT_STATUS_INTERNAL_ERROR;
2103 if (!NT_STATUS_IS_OK(status)) {
2104 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
2105 nt_errstr(status)));
2109 if (DEBUGLEVEL >= 10) {
2110 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
2113 /* Finally marshall the blob. */
2114 if (!prs_copy_data_in(outgoing_pdu, (const char *)blob.data, blob.length)) {
2115 return NT_STATUS_NO_MEMORY;
2118 return NT_STATUS_OK;
2121 /*******************************************************************
2122 Calculate how much data we're going to send in this packet, also
2123 work out any sign/seal padding length.
2124 ********************************************************************/
2126 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
2130 uint32 *p_ss_padding)
2132 uint32 data_space, data_len;
2135 if ((data_left > 0) && (sys_random() % 2)) {
2136 data_left = MAX(data_left/2, 1);
2140 switch (cli->auth->auth_level) {
2141 case DCERPC_AUTH_LEVEL_NONE:
2142 case DCERPC_AUTH_LEVEL_CONNECT:
2143 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN;
2144 data_len = MIN(data_space, data_left);
2147 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + data_len;
2150 case DCERPC_AUTH_LEVEL_INTEGRITY:
2151 case DCERPC_AUTH_LEVEL_PRIVACY:
2152 /* Treat the same for all authenticated rpc requests. */
2153 switch(cli->auth->auth_type) {
2154 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2155 case PIPE_AUTH_TYPE_NTLMSSP:
2156 *p_auth_len = NTLMSSP_SIG_SIZE;
2158 case PIPE_AUTH_TYPE_SCHANNEL:
2159 *p_auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN;
2162 smb_panic("bad auth type");
2166 data_space = cli->max_xmit_frag - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
2167 RPC_HDR_AUTH_LEN - *p_auth_len;
2169 data_len = MIN(data_space, data_left);
2171 if (data_len % CLIENT_NDR_PADDING_SIZE) {
2172 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
2174 *p_frag_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + /* Normal headers. */
2175 data_len + *p_ss_padding + /* data plus padding. */
2176 RPC_HDR_AUTH_LEN + *p_auth_len; /* Auth header and auth data. */
2180 smb_panic("bad auth level");
2186 /*******************************************************************
2188 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
2189 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
2190 and deals with signing/sealing details.
2191 ********************************************************************/
2193 struct rpc_api_pipe_req_state {
2194 struct event_context *ev;
2195 struct rpc_pipe_client *cli;
2198 prs_struct *req_data;
2199 uint32_t req_data_sent;
2200 prs_struct outgoing_frag;
2201 prs_struct reply_pdu;
2204 static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s)
2206 prs_mem_free(&s->outgoing_frag);
2207 prs_mem_free(&s->reply_pdu);
2211 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
2212 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
2213 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2214 bool *is_last_frag);
2216 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
2217 struct event_context *ev,
2218 struct rpc_pipe_client *cli,
2220 prs_struct *req_data)
2222 struct tevent_req *req, *subreq;
2223 struct rpc_api_pipe_req_state *state;
2227 req = tevent_req_create(mem_ctx, &state,
2228 struct rpc_api_pipe_req_state);
2234 state->op_num = op_num;
2235 state->req_data = req_data;
2236 state->req_data_sent = 0;
2237 state->call_id = get_rpc_call_id();
2239 if (cli->max_xmit_frag
2240 < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_MAX_SIGN_SIZE) {
2241 /* Server is screwed up ! */
2242 status = NT_STATUS_INVALID_PARAMETER;
2246 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2248 if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag,
2253 talloc_set_destructor(state, rpc_api_pipe_req_state_destructor);
2255 status = prepare_next_frag(state, &is_last_frag);
2256 if (!NT_STATUS_IS_OK(status)) {
2261 subreq = rpc_api_pipe_send(state, ev, state->cli,
2262 &state->outgoing_frag,
2263 DCERPC_PKT_RESPONSE);
2264 if (subreq == NULL) {
2267 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2269 subreq = rpc_write_send(
2270 state, ev, cli->transport,
2271 (uint8_t *)prs_data_p(&state->outgoing_frag),
2272 prs_offset(&state->outgoing_frag));
2273 if (subreq == NULL) {
2276 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2282 tevent_req_nterror(req, status);
2283 return tevent_req_post(req, ev);
2289 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
2293 RPC_HDR_REQ hdr_req;
2294 uint32_t data_sent_thistime;
2298 uint32_t ss_padding;
2300 char pad[8] = { 0, };
2303 data_left = prs_offset(state->req_data) - state->req_data_sent;
2305 data_sent_thistime = calculate_data_len_tosend(
2306 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
2308 if (state->req_data_sent == 0) {
2309 flags = DCERPC_PFC_FLAG_FIRST;
2312 if (data_sent_thistime == data_left) {
2313 flags |= DCERPC_PFC_FLAG_LAST;
2316 if (!prs_set_offset(&state->outgoing_frag, 0)) {
2317 return NT_STATUS_NO_MEMORY;
2320 /* Create and marshall the header and request header. */
2321 init_rpc_hdr(&hdr, DCERPC_PKT_REQUEST, flags, state->call_id, frag_len,
2324 if (!smb_io_rpc_hdr("hdr ", &hdr, &state->outgoing_frag, 0)) {
2325 return NT_STATUS_NO_MEMORY;
2328 /* Create the rpc request RPC_HDR_REQ */
2329 init_rpc_hdr_req(&hdr_req, prs_offset(state->req_data),
2332 if (!smb_io_rpc_hdr_req("hdr_req", &hdr_req,
2333 &state->outgoing_frag, 0)) {
2334 return NT_STATUS_NO_MEMORY;
2337 /* Copy in the data, plus any ss padding. */
2338 if (!prs_append_some_prs_data(&state->outgoing_frag,
2339 state->req_data, state->req_data_sent,
2340 data_sent_thistime)) {
2341 return NT_STATUS_NO_MEMORY;
2344 /* Copy the sign/seal padding data. */
2345 if (!prs_copy_data_in(&state->outgoing_frag, pad, ss_padding)) {
2346 return NT_STATUS_NO_MEMORY;
2349 /* Generate any auth sign/seal and add the auth footer. */
2350 switch (state->cli->auth->auth_type) {
2351 case PIPE_AUTH_TYPE_NONE:
2352 status = NT_STATUS_OK;
2354 case PIPE_AUTH_TYPE_NTLMSSP:
2355 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2356 status = add_ntlmssp_auth_footer(state->cli, &hdr, ss_padding,
2357 &state->outgoing_frag);
2359 case PIPE_AUTH_TYPE_SCHANNEL:
2360 status = add_schannel_auth_footer(state->cli, &hdr, ss_padding,
2361 &state->outgoing_frag);
2364 status = NT_STATUS_INVALID_PARAMETER;
2368 state->req_data_sent += data_sent_thistime;
2369 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2374 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2376 struct tevent_req *req = tevent_req_callback_data(
2377 subreq, struct tevent_req);
2378 struct rpc_api_pipe_req_state *state = tevent_req_data(
2379 req, struct rpc_api_pipe_req_state);
2383 status = rpc_write_recv(subreq);
2384 TALLOC_FREE(subreq);
2385 if (!NT_STATUS_IS_OK(status)) {
2386 tevent_req_nterror(req, status);
2390 status = prepare_next_frag(state, &is_last_frag);
2391 if (!NT_STATUS_IS_OK(status)) {
2392 tevent_req_nterror(req, status);
2397 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2398 &state->outgoing_frag,
2399 DCERPC_PKT_RESPONSE);
2400 if (tevent_req_nomem(subreq, req)) {
2403 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2405 subreq = rpc_write_send(
2407 state->cli->transport,
2408 (uint8_t *)prs_data_p(&state->outgoing_frag),
2409 prs_offset(&state->outgoing_frag));
2410 if (tevent_req_nomem(subreq, req)) {
2413 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2418 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2420 struct tevent_req *req = tevent_req_callback_data(
2421 subreq, struct tevent_req);
2422 struct rpc_api_pipe_req_state *state = tevent_req_data(
2423 req, struct rpc_api_pipe_req_state);
2426 status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu);
2427 TALLOC_FREE(subreq);
2428 if (!NT_STATUS_IS_OK(status)) {
2429 tevent_req_nterror(req, status);
2432 tevent_req_done(req);
2435 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2436 prs_struct *reply_pdu)
2438 struct rpc_api_pipe_req_state *state = tevent_req_data(
2439 req, struct rpc_api_pipe_req_state);
2442 if (tevent_req_is_nterror(req, &status)) {
2444 * We always have to initialize to reply pdu, even if there is
2445 * none. The rpccli_* caller routines expect this.
2447 prs_init_empty(reply_pdu, mem_ctx, UNMARSHALL);
2451 *reply_pdu = state->reply_pdu;
2452 reply_pdu->mem_ctx = mem_ctx;
2455 * Prevent state->req_pdu from being freed in
2456 * rpc_api_pipe_req_state_destructor()
2458 prs_init_empty(&state->reply_pdu, state, UNMARSHALL);
2460 return NT_STATUS_OK;
2464 /****************************************************************************
2465 Set the handle state.
2466 ****************************************************************************/
2468 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2469 const char *pipe_name, uint16 device_state)
2471 bool state_set = False;
2473 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2474 char *rparam = NULL;
2476 uint32 rparam_len, rdata_len;
2478 if (pipe_name == NULL)
2481 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2482 cli->fnum, pipe_name, device_state));
2484 /* create parameters: device state */
2485 SSVAL(param, 0, device_state);
2487 /* create setup parameters. */
2489 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2491 /* send the data on \PIPE\ */
2492 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2493 setup, 2, 0, /* setup, length, max */
2494 param, 2, 0, /* param, length, max */
2495 NULL, 0, 1024, /* data, length, max */
2496 &rparam, &rparam_len, /* return param, length */
2497 &rdata, &rdata_len)) /* return data, length */
2499 DEBUG(5, ("Set Handle state: return OK\n"));
2510 /****************************************************************************
2511 Check the rpc bind acknowledge response.
2512 ****************************************************************************/
2514 static bool check_bind_response(RPC_HDR_BA *hdr_ba,
2515 const struct ndr_syntax_id *transfer)
2517 if ( hdr_ba->addr.len == 0) {
2518 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2521 /* check the transfer syntax */
2522 if ((hdr_ba->transfer.if_version != transfer->if_version) ||
2523 (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2524 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2528 if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
2529 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2530 hdr_ba->res.num_results, hdr_ba->res.reason));
2533 DEBUG(5,("check_bind_response: accepted!\n"));
2537 /*******************************************************************
2538 Creates a DCE/RPC bind authentication response.
2539 This is the packet that is sent back to the server once we
2540 have received a BIND-ACK, to finish the third leg of
2541 the authentication handshake.
2542 ********************************************************************/
2544 static NTSTATUS create_rpc_bind_auth3(struct rpc_pipe_client *cli,
2546 enum pipe_auth_type auth_type,
2547 enum dcerpc_AuthLevel auth_level,
2548 DATA_BLOB *pauth_blob,
2549 prs_struct *rpc_out)
2552 RPC_HDR_AUTH hdr_auth;
2555 /* Create the request RPC_HDR */
2556 init_rpc_hdr(&hdr, DCERPC_PKT_AUTH3, DCERPC_PFC_FLAG_FIRST|DCERPC_PFC_FLAG_LAST, rpc_call_id,
2557 RPC_HEADER_LEN + 4 /* pad */ + RPC_HDR_AUTH_LEN + pauth_blob->length,
2558 pauth_blob->length );
2561 if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
2562 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR.\n"));
2563 return NT_STATUS_NO_MEMORY;
2567 I'm puzzled about this - seems to violate the DCE RPC auth rules,
2568 about padding - shouldn't this pad to length CLIENT_NDR_PADDING_SIZE ? JRA.
2571 /* 4 bytes padding. */
2572 if (!prs_uint32("pad", rpc_out, 0, &pad)) {
2573 DEBUG(0,("create_rpc_bind_auth3: failed to marshall 4 byte pad.\n"));
2574 return NT_STATUS_NO_MEMORY;
2577 /* Create the request RPC_HDR_AUTHA */
2578 init_rpc_hdr_auth(&hdr_auth,
2579 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2582 if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, rpc_out, 0)) {
2583 DEBUG(0,("create_rpc_bind_auth3: failed to marshall RPC_HDR_AUTHA.\n"));
2584 return NT_STATUS_NO_MEMORY;
2588 * Append the auth data to the outgoing buffer.
2591 if(!prs_copy_data_in(rpc_out, (char *)pauth_blob->data, pauth_blob->length)) {
2592 DEBUG(0,("create_rpc_bind_auth3: failed to marshall auth blob.\n"));
2593 return NT_STATUS_NO_MEMORY;
2596 return NT_STATUS_OK;
2599 /*******************************************************************
2600 Creates a DCE/RPC bind alter context authentication request which
2601 may contain a spnego auth blobl
2602 ********************************************************************/
2604 static NTSTATUS create_rpc_alter_context(uint32 rpc_call_id,
2605 const struct ndr_syntax_id *abstract,
2606 const struct ndr_syntax_id *transfer,
2607 enum dcerpc_AuthLevel auth_level,
2608 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2609 prs_struct *rpc_out)
2611 RPC_HDR_AUTH hdr_auth;
2612 prs_struct auth_info;
2613 NTSTATUS ret = NT_STATUS_OK;
2615 ZERO_STRUCT(hdr_auth);
2616 if (!prs_init(&auth_info, RPC_HDR_AUTH_LEN, prs_get_mem_context(rpc_out), MARSHALL))
2617 return NT_STATUS_NO_MEMORY;
2619 /* We may change the pad length before marshalling. */
2620 init_rpc_hdr_auth(&hdr_auth, DCERPC_AUTH_TYPE_SPNEGO, (int)auth_level, 0, 1);
2622 if (pauth_blob->length) {
2623 if (!prs_copy_data_in(&auth_info, (const char *)pauth_blob->data, pauth_blob->length)) {
2624 prs_mem_free(&auth_info);
2625 return NT_STATUS_NO_MEMORY;
2629 ret = create_bind_or_alt_ctx_internal(DCERPC_PKT_ALTER,
2636 prs_mem_free(&auth_info);
2640 /****************************************************************************
2642 ****************************************************************************/
2644 struct rpc_pipe_bind_state {
2645 struct event_context *ev;
2646 struct rpc_pipe_client *cli;
2648 uint32_t rpc_call_id;
2651 static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state)
2653 prs_mem_free(&state->rpc_out);
2657 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2658 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2659 struct rpc_pipe_bind_state *state,
2660 struct rpc_hdr_info *phdr,
2661 prs_struct *reply_pdu);
2662 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2663 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2664 struct rpc_pipe_bind_state *state,
2665 struct rpc_hdr_info *phdr,
2666 prs_struct *reply_pdu);
2667 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2669 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2670 struct event_context *ev,
2671 struct rpc_pipe_client *cli,
2672 struct cli_pipe_auth_data *auth)
2674 struct tevent_req *req, *subreq;
2675 struct rpc_pipe_bind_state *state;
2678 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2683 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2684 rpccli_pipe_txt(talloc_tos(), cli),
2685 (unsigned int)auth->auth_type,
2686 (unsigned int)auth->auth_level ));
2690 state->rpc_call_id = get_rpc_call_id();
2692 prs_init_empty(&state->rpc_out, state, MARSHALL);
2693 talloc_set_destructor(state, rpc_pipe_bind_state_destructor);
2695 cli->auth = talloc_move(cli, &auth);
2697 /* Marshall the outgoing data. */
2698 status = create_rpc_bind_req(cli, &state->rpc_out,
2700 &cli->abstract_syntax,
2701 &cli->transfer_syntax,
2702 cli->auth->auth_type,
2703 cli->auth->auth_level);
2705 if (!NT_STATUS_IS_OK(status)) {
2709 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2710 DCERPC_PKT_BIND_ACK);
2711 if (subreq == NULL) {
2714 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2718 tevent_req_nterror(req, status);
2719 return tevent_req_post(req, ev);
2725 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2727 struct tevent_req *req = tevent_req_callback_data(
2728 subreq, struct tevent_req);
2729 struct rpc_pipe_bind_state *state = tevent_req_data(
2730 req, struct rpc_pipe_bind_state);
2731 prs_struct reply_pdu;
2732 struct rpc_hdr_info hdr;
2733 struct rpc_hdr_ba_info hdr_ba;
2736 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
2737 TALLOC_FREE(subreq);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2740 rpccli_pipe_txt(talloc_tos(), state->cli),
2741 nt_errstr(status)));
2742 tevent_req_nterror(req, status);
2746 /* Unmarshall the RPC header */
2747 if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) {
2748 DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n"));
2749 prs_mem_free(&reply_pdu);
2750 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2754 if (!smb_io_rpc_hdr_ba("", &hdr_ba, &reply_pdu, 0)) {
2755 DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall "
2757 prs_mem_free(&reply_pdu);
2758 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2762 if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) {
2763 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2764 prs_mem_free(&reply_pdu);
2765 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2769 state->cli->max_xmit_frag = hdr_ba.bba.max_tsize;
2770 state->cli->max_recv_frag = hdr_ba.bba.max_rsize;
2773 * For authenticated binds we may need to do 3 or 4 leg binds.
2776 switch(state->cli->auth->auth_type) {
2778 case PIPE_AUTH_TYPE_NONE:
2779 case PIPE_AUTH_TYPE_SCHANNEL:
2780 /* Bind complete. */
2781 prs_mem_free(&reply_pdu);
2782 tevent_req_done(req);
2785 case PIPE_AUTH_TYPE_NTLMSSP:
2786 /* Need to send AUTH3 packet - no reply. */
2787 status = rpc_finish_auth3_bind_send(req, state, &hdr,
2789 prs_mem_free(&reply_pdu);
2790 if (!NT_STATUS_IS_OK(status)) {
2791 tevent_req_nterror(req, status);
2795 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2796 /* Need to send alter context request and reply. */
2797 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, &hdr,
2799 prs_mem_free(&reply_pdu);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 tevent_req_nterror(req, status);
2805 case PIPE_AUTH_TYPE_KRB5:
2809 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2810 (unsigned int)state->cli->auth->auth_type));
2811 prs_mem_free(&reply_pdu);
2812 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2816 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2817 struct rpc_pipe_bind_state *state,
2818 struct rpc_hdr_info *phdr,
2819 prs_struct *reply_pdu)
2821 DATA_BLOB server_response = data_blob_null;
2822 DATA_BLOB client_reply = data_blob_null;
2823 struct rpc_hdr_auth_info hdr_auth;
2824 struct tevent_req *subreq;
2827 if ((phdr->auth_len == 0)
2828 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2829 return NT_STATUS_INVALID_PARAMETER;
2832 if (!prs_set_offset(
2834 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2835 return NT_STATUS_INVALID_PARAMETER;
2838 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2839 return NT_STATUS_INVALID_PARAMETER;
2842 /* TODO - check auth_type/auth_level match. */
2844 server_response = data_blob_talloc(talloc_tos(), NULL, phdr->auth_len);
2845 prs_copy_data_out((char *)server_response.data, reply_pdu,
2848 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2849 server_response, &client_reply);
2851 if (!NT_STATUS_IS_OK(status)) {
2852 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2853 "blob failed: %s.\n", nt_errstr(status)));
2857 prs_init_empty(&state->rpc_out, talloc_tos(), MARSHALL);
2859 status = create_rpc_bind_auth3(state->cli, state->rpc_call_id,
2860 state->cli->auth->auth_type,
2861 state->cli->auth->auth_level,
2862 &client_reply, &state->rpc_out);
2863 data_blob_free(&client_reply);
2865 if (!NT_STATUS_IS_OK(status)) {
2869 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2870 (uint8_t *)prs_data_p(&state->rpc_out),
2871 prs_offset(&state->rpc_out));
2872 if (subreq == NULL) {
2873 return NT_STATUS_NO_MEMORY;
2875 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2876 return NT_STATUS_OK;
2879 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2881 struct tevent_req *req = tevent_req_callback_data(
2882 subreq, struct tevent_req);
2885 status = rpc_write_recv(subreq);
2886 TALLOC_FREE(subreq);
2887 if (!NT_STATUS_IS_OK(status)) {
2888 tevent_req_nterror(req, status);
2891 tevent_req_done(req);
2894 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2895 struct rpc_pipe_bind_state *state,
2896 struct rpc_hdr_info *phdr,
2897 prs_struct *reply_pdu)
2899 DATA_BLOB server_spnego_response = data_blob_null;
2900 DATA_BLOB server_ntlm_response = data_blob_null;
2901 DATA_BLOB client_reply = data_blob_null;
2902 DATA_BLOB tmp_blob = data_blob_null;
2903 RPC_HDR_AUTH hdr_auth;
2904 struct tevent_req *subreq;
2907 if ((phdr->auth_len == 0)
2908 || (phdr->frag_len < phdr->auth_len + RPC_HDR_AUTH_LEN)) {
2909 return NT_STATUS_INVALID_PARAMETER;
2912 /* Process the returned NTLMSSP blob first. */
2913 if (!prs_set_offset(
2915 phdr->frag_len - phdr->auth_len - RPC_HDR_AUTH_LEN)) {
2916 return NT_STATUS_INVALID_PARAMETER;
2919 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, reply_pdu, 0)) {
2920 return NT_STATUS_INVALID_PARAMETER;
2923 server_spnego_response = data_blob(NULL, phdr->auth_len);
2924 prs_copy_data_out((char *)server_spnego_response.data,
2925 reply_pdu, phdr->auth_len);
2928 * The server might give us back two challenges - tmp_blob is for the
2931 if (!spnego_parse_challenge(server_spnego_response,
2932 &server_ntlm_response, &tmp_blob)) {
2933 data_blob_free(&server_spnego_response);
2934 data_blob_free(&server_ntlm_response);
2935 data_blob_free(&tmp_blob);
2936 return NT_STATUS_INVALID_PARAMETER;
2939 /* We're finished with the server spnego response and the tmp_blob. */
2940 data_blob_free(&server_spnego_response);
2941 data_blob_free(&tmp_blob);
2943 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2944 server_ntlm_response, &client_reply);
2946 /* Finished with the server_ntlm response */
2947 data_blob_free(&server_ntlm_response);
2949 if (!NT_STATUS_IS_OK(status)) {
2950 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2951 "using server blob failed.\n"));
2952 data_blob_free(&client_reply);
2956 /* SPNEGO wrap the client reply. */
2957 tmp_blob = spnego_gen_auth(client_reply);
2958 data_blob_free(&client_reply);
2959 client_reply = tmp_blob;
2960 tmp_blob = data_blob_null;
2962 /* Now prepare the alter context pdu. */
2963 prs_init_empty(&state->rpc_out, state, MARSHALL);
2965 status = create_rpc_alter_context(state->rpc_call_id,
2966 &state->cli->abstract_syntax,
2967 &state->cli->transfer_syntax,
2968 state->cli->auth->auth_level,
2971 data_blob_free(&client_reply);
2973 if (!NT_STATUS_IS_OK(status)) {
2977 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2978 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2979 if (subreq == NULL) {
2980 return NT_STATUS_NO_MEMORY;
2982 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2983 return NT_STATUS_OK;
2986 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2988 struct tevent_req *req = tevent_req_callback_data(
2989 subreq, struct tevent_req);
2990 struct rpc_pipe_bind_state *state = tevent_req_data(
2991 req, struct rpc_pipe_bind_state);
2992 DATA_BLOB server_spnego_response = data_blob_null;
2993 DATA_BLOB tmp_blob = data_blob_null;
2994 prs_struct reply_pdu;
2995 struct rpc_hdr_info hdr;
2996 struct rpc_hdr_auth_info hdr_auth;
2999 status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu);
3000 TALLOC_FREE(subreq);
3001 if (!NT_STATUS_IS_OK(status)) {
3002 tevent_req_nterror(req, status);
3006 /* Get the auth blob from the reply. */
3007 if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) {
3008 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to "
3009 "unmarshall RPC_HDR.\n"));
3010 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
3014 if (!prs_set_offset(
3016 hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) {
3017 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3021 if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) {
3022 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3026 server_spnego_response = data_blob(NULL, hdr.auth_len);
3027 prs_copy_data_out((char *)server_spnego_response.data, &reply_pdu,
3030 /* Check we got a valid auth response. */
3031 if (!spnego_parse_auth_response(server_spnego_response, NT_STATUS_OK,
3032 OID_NTLMSSP, &tmp_blob)) {
3033 data_blob_free(&server_spnego_response);
3034 data_blob_free(&tmp_blob);
3035 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3039 data_blob_free(&server_spnego_response);
3040 data_blob_free(&tmp_blob);
3042 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
3043 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
3044 tevent_req_done(req);
3047 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
3049 return tevent_req_simple_recv_ntstatus(req);
3052 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
3053 struct cli_pipe_auth_data *auth)
3055 TALLOC_CTX *frame = talloc_stackframe();
3056 struct event_context *ev;
3057 struct tevent_req *req;
3058 NTSTATUS status = NT_STATUS_OK;
3060 ev = event_context_init(frame);
3062 status = NT_STATUS_NO_MEMORY;
3066 req = rpc_pipe_bind_send(frame, ev, cli, auth);
3068 status = NT_STATUS_NO_MEMORY;
3072 if (!tevent_req_poll(req, ev)) {
3073 status = map_nt_error_from_unix(errno);
3077 status = rpc_pipe_bind_recv(req);
3083 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
3085 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
3086 unsigned int timeout)
3090 if (rpc_cli->transport == NULL) {
3091 return RPCCLI_DEFAULT_TIMEOUT;
3094 if (rpc_cli->transport->set_timeout == NULL) {
3095 return RPCCLI_DEFAULT_TIMEOUT;
3098 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
3100 return RPCCLI_DEFAULT_TIMEOUT;
3106 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
3108 if (rpc_cli == NULL) {
3112 if (rpc_cli->transport == NULL) {
3116 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
3119 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
3121 struct cli_state *cli;
3123 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
3124 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
3125 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
3129 cli = rpc_pipe_np_smb_conn(rpc_cli);
3133 E_md4hash(cli->password ? cli->password : "", nt_hash);
3137 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
3138 struct cli_pipe_auth_data **presult)
3140 struct cli_pipe_auth_data *result;
3142 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3143 if (result == NULL) {
3144 return NT_STATUS_NO_MEMORY;
3147 result->auth_type = PIPE_AUTH_TYPE_NONE;
3148 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
3150 result->user_name = talloc_strdup(result, "");
3151 result->domain = talloc_strdup(result, "");
3152 if ((result->user_name == NULL) || (result->domain == NULL)) {
3153 TALLOC_FREE(result);
3154 return NT_STATUS_NO_MEMORY;
3158 return NT_STATUS_OK;
3161 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
3163 ntlmssp_end(&auth->a_u.ntlmssp_state);
3167 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
3168 enum pipe_auth_type auth_type,
3169 enum dcerpc_AuthLevel auth_level,
3171 const char *username,
3172 const char *password,
3173 struct cli_pipe_auth_data **presult)
3175 struct cli_pipe_auth_data *result;
3178 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3179 if (result == NULL) {
3180 return NT_STATUS_NO_MEMORY;
3183 result->auth_type = auth_type;
3184 result->auth_level = auth_level;
3186 result->user_name = talloc_strdup(result, username);
3187 result->domain = talloc_strdup(result, domain);
3188 if ((result->user_name == NULL) || (result->domain == NULL)) {
3189 status = NT_STATUS_NO_MEMORY;
3193 status = ntlmssp_client_start(NULL,
3196 lp_client_ntlmv2_auth(),
3197 &result->a_u.ntlmssp_state);
3198 if (!NT_STATUS_IS_OK(status)) {
3202 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
3204 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
3205 if (!NT_STATUS_IS_OK(status)) {
3209 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
3210 if (!NT_STATUS_IS_OK(status)) {
3214 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
3215 if (!NT_STATUS_IS_OK(status)) {
3220 * Turn off sign+seal to allow selected auth level to turn it back on.
3222 result->a_u.ntlmssp_state->neg_flags &=
3223 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
3225 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
3226 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
3227 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
3228 result->a_u.ntlmssp_state->neg_flags
3229 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
3233 return NT_STATUS_OK;
3236 TALLOC_FREE(result);
3240 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
3241 enum dcerpc_AuthLevel auth_level,
3242 struct netlogon_creds_CredentialState *creds,
3243 struct cli_pipe_auth_data **presult)
3245 struct cli_pipe_auth_data *result;
3247 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3248 if (result == NULL) {
3249 return NT_STATUS_NO_MEMORY;
3252 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
3253 result->auth_level = auth_level;
3255 result->user_name = talloc_strdup(result, "");
3256 result->domain = talloc_strdup(result, domain);
3257 if ((result->user_name == NULL) || (result->domain == NULL)) {
3261 result->a_u.schannel_auth = talloc(result, struct schannel_state);
3262 if (result->a_u.schannel_auth == NULL) {
3266 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
3267 result->a_u.schannel_auth->seq_num = 0;
3268 result->a_u.schannel_auth->initiator = true;
3269 result->a_u.schannel_auth->creds = creds;
3272 return NT_STATUS_OK;
3275 TALLOC_FREE(result);
3276 return NT_STATUS_NO_MEMORY;
3280 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
3282 data_blob_free(&auth->session_key);
3287 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
3288 enum dcerpc_AuthLevel auth_level,
3289 const char *service_princ,
3290 const char *username,
3291 const char *password,
3292 struct cli_pipe_auth_data **presult)
3295 struct cli_pipe_auth_data *result;
3297 if ((username != NULL) && (password != NULL)) {
3298 int ret = kerberos_kinit_password(username, password, 0, NULL);
3300 return NT_STATUS_ACCESS_DENIED;
3304 result = talloc(mem_ctx, struct cli_pipe_auth_data);
3305 if (result == NULL) {
3306 return NT_STATUS_NO_MEMORY;
3309 result->auth_type = PIPE_AUTH_TYPE_KRB5;
3310 result->auth_level = auth_level;
3313 * Username / domain need fixing!
3315 result->user_name = talloc_strdup(result, "");
3316 result->domain = talloc_strdup(result, "");
3317 if ((result->user_name == NULL) || (result->domain == NULL)) {
3321 result->a_u.kerberos_auth = TALLOC_ZERO_P(
3322 result, struct kerberos_auth_struct);
3323 if (result->a_u.kerberos_auth == NULL) {
3326 talloc_set_destructor(result->a_u.kerberos_auth,
3327 cli_auth_kerberos_data_destructor);
3329 result->a_u.kerberos_auth->service_principal = talloc_strdup(
3330 result, service_princ);
3331 if (result->a_u.kerberos_auth->service_principal == NULL) {
3336 return NT_STATUS_OK;
3339 TALLOC_FREE(result);
3340 return NT_STATUS_NO_MEMORY;
3342 return NT_STATUS_NOT_SUPPORTED;
3347 * Create an rpc pipe client struct, connecting to a tcp port.
3349 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
3351 const struct ndr_syntax_id *abstract_syntax,
3352 struct rpc_pipe_client **presult)
3354 struct rpc_pipe_client *result;
3355 struct sockaddr_storage addr;
3359 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
3360 if (result == NULL) {
3361 return NT_STATUS_NO_MEMORY;
3364 result->abstract_syntax = *abstract_syntax;
3365 result->transfer_syntax = ndr_transfer_syntax;
3366 result->dispatch = cli_do_rpc_ndr;
3367 result->dispatch_send = cli_do_rpc_ndr_send;
3368 result->dispatch_recv = cli_do_rpc_ndr_recv;
3370 result->desthost = talloc_strdup(result, host);
3371 result->srv_name_slash = talloc_asprintf_strupper_m(
3372 result, "\\\\%s", result->desthost);
3373 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3374 status = NT_STATUS_NO_MEMORY;
3378 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3379 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3381 if (!resolve_name(host, &addr, 0, false)) {
3382 status = NT_STATUS_NOT_FOUND;
3386 status = open_socket_out(&addr, port, 60, &fd);
3387 if (!NT_STATUS_IS_OK(status)) {
3390 set_socket_options(fd, lp_socket_options());
3392 status = rpc_transport_sock_init(result, fd, &result->transport);
3393 if (!NT_STATUS_IS_OK(status)) {
3398 result->transport->transport = NCACN_IP_TCP;
3401 return NT_STATUS_OK;
3404 TALLOC_FREE(result);
3409 * Determine the tcp port on which a dcerpc interface is listening
3410 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3413 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3414 const struct ndr_syntax_id *abstract_syntax,
3418 struct rpc_pipe_client *epm_pipe = NULL;
3419 struct cli_pipe_auth_data *auth = NULL;
3420 struct dcerpc_binding *map_binding = NULL;
3421 struct dcerpc_binding *res_binding = NULL;
3422 struct epm_twr_t *map_tower = NULL;
3423 struct epm_twr_t *res_towers = NULL;
3424 struct policy_handle *entry_handle = NULL;
3425 uint32_t num_towers = 0;
3426 uint32_t max_towers = 1;
3427 struct epm_twr_p_t towers;
3428 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3430 if (pport == NULL) {
3431 status = NT_STATUS_INVALID_PARAMETER;
3435 /* open the connection to the endpoint mapper */
3436 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3437 &ndr_table_epmapper.syntax_id,
3440 if (!NT_STATUS_IS_OK(status)) {
3444 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3445 if (!NT_STATUS_IS_OK(status)) {
3449 status = rpc_pipe_bind(epm_pipe, auth);
3450 if (!NT_STATUS_IS_OK(status)) {
3454 /* create tower for asking the epmapper */
3456 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3457 if (map_binding == NULL) {
3458 status = NT_STATUS_NO_MEMORY;
3462 map_binding->transport = NCACN_IP_TCP;
3463 map_binding->object = *abstract_syntax;
3464 map_binding->host = host; /* needed? */
3465 map_binding->endpoint = "0"; /* correct? needed? */
3467 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3468 if (map_tower == NULL) {
3469 status = NT_STATUS_NO_MEMORY;
3473 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3474 &(map_tower->tower));
3475 if (!NT_STATUS_IS_OK(status)) {
3479 /* allocate further parameters for the epm_Map call */
3481 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3482 if (res_towers == NULL) {
3483 status = NT_STATUS_NO_MEMORY;
3486 towers.twr = res_towers;
3488 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3489 if (entry_handle == NULL) {
3490 status = NT_STATUS_NO_MEMORY;
3494 /* ask the endpoint mapper for the port */
3496 status = rpccli_epm_Map(epm_pipe,
3498 CONST_DISCARD(struct GUID *,
3499 &(abstract_syntax->uuid)),
3506 if (!NT_STATUS_IS_OK(status)) {
3510 if (num_towers != 1) {
3511 status = NT_STATUS_UNSUCCESSFUL;
3515 /* extract the port from the answer */
3517 status = dcerpc_binding_from_tower(tmp_ctx,
3518 &(towers.twr->tower),
3520 if (!NT_STATUS_IS_OK(status)) {
3524 /* are further checks here necessary? */
3525 if (res_binding->transport != NCACN_IP_TCP) {
3526 status = NT_STATUS_UNSUCCESSFUL;
3530 *pport = (uint16_t)atoi(res_binding->endpoint);
3533 TALLOC_FREE(tmp_ctx);
3538 * Create a rpc pipe client struct, connecting to a host via tcp.
3539 * The port is determined by asking the endpoint mapper on the given
3542 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3543 const struct ndr_syntax_id *abstract_syntax,
3544 struct rpc_pipe_client **presult)
3549 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3550 if (!NT_STATUS_IS_OK(status)) {
3554 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3555 abstract_syntax, presult);
3558 /********************************************************************
3559 Create a rpc pipe client struct, connecting to a unix domain socket
3560 ********************************************************************/
3561 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3562 const struct ndr_syntax_id *abstract_syntax,
3563 struct rpc_pipe_client **presult)
3565 struct rpc_pipe_client *result;
3566 struct sockaddr_un addr;
3570 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3571 if (result == NULL) {
3572 return NT_STATUS_NO_MEMORY;
3575 result->abstract_syntax = *abstract_syntax;
3576 result->transfer_syntax = ndr_transfer_syntax;
3577 result->dispatch = cli_do_rpc_ndr;
3578 result->dispatch_send = cli_do_rpc_ndr_send;
3579 result->dispatch_recv = cli_do_rpc_ndr_recv;
3581 result->desthost = get_myname(result);
3582 result->srv_name_slash = talloc_asprintf_strupper_m(
3583 result, "\\\\%s", result->desthost);
3584 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3585 status = NT_STATUS_NO_MEMORY;
3589 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3590 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3592 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3594 status = map_nt_error_from_unix(errno);
3599 addr.sun_family = AF_UNIX;
3600 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3602 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3603 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3606 return map_nt_error_from_unix(errno);
3609 status = rpc_transport_sock_init(result, fd, &result->transport);
3610 if (!NT_STATUS_IS_OK(status)) {
3615 result->transport->transport = NCALRPC;
3618 return NT_STATUS_OK;
3621 TALLOC_FREE(result);
3625 struct rpc_pipe_client_np_ref {
3626 struct cli_state *cli;
3627 struct rpc_pipe_client *pipe;
3630 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3632 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3636 /****************************************************************************
3637 Open a named pipe over SMB to a remote server.
3639 * CAVEAT CALLER OF THIS FUNCTION:
3640 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3641 * so be sure that this function is called AFTER any structure (vs pointer)
3642 * assignment of the cli. In particular, libsmbclient does structure
3643 * assignments of cli, which invalidates the data in the returned
3644 * rpc_pipe_client if this function is called before the structure assignment
3647 ****************************************************************************/
3649 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3650 const struct ndr_syntax_id *abstract_syntax,
3651 struct rpc_pipe_client **presult)
3653 struct rpc_pipe_client *result;
3655 struct rpc_pipe_client_np_ref *np_ref;
3657 /* sanity check to protect against crashes */
3660 return NT_STATUS_INVALID_HANDLE;
3663 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3664 if (result == NULL) {
3665 return NT_STATUS_NO_MEMORY;
3668 result->abstract_syntax = *abstract_syntax;
3669 result->transfer_syntax = ndr_transfer_syntax;
3670 result->dispatch = cli_do_rpc_ndr;
3671 result->dispatch_send = cli_do_rpc_ndr_send;
3672 result->dispatch_recv = cli_do_rpc_ndr_recv;
3673 result->desthost = talloc_strdup(result, cli->desthost);
3674 result->srv_name_slash = talloc_asprintf_strupper_m(
3675 result, "\\\\%s", result->desthost);
3677 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3678 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3680 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3681 TALLOC_FREE(result);
3682 return NT_STATUS_NO_MEMORY;
3685 status = rpc_transport_np_init(result, cli, abstract_syntax,
3686 &result->transport);
3687 if (!NT_STATUS_IS_OK(status)) {
3688 TALLOC_FREE(result);
3692 result->transport->transport = NCACN_NP;
3694 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3695 if (np_ref == NULL) {
3696 TALLOC_FREE(result);
3697 return NT_STATUS_NO_MEMORY;
3700 np_ref->pipe = result;
3702 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3703 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3706 return NT_STATUS_OK;
3709 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3710 struct rpc_cli_smbd_conn *conn,
3711 const struct ndr_syntax_id *syntax,
3712 struct rpc_pipe_client **presult)
3714 struct rpc_pipe_client *result;
3715 struct cli_pipe_auth_data *auth;
3718 result = talloc(mem_ctx, struct rpc_pipe_client);
3719 if (result == NULL) {
3720 return NT_STATUS_NO_MEMORY;
3722 result->abstract_syntax = *syntax;
3723 result->transfer_syntax = ndr_transfer_syntax;
3724 result->dispatch = cli_do_rpc_ndr;
3725 result->dispatch_send = cli_do_rpc_ndr_send;
3726 result->dispatch_recv = cli_do_rpc_ndr_recv;
3727 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3728 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3730 result->desthost = talloc_strdup(result, global_myname());
3731 result->srv_name_slash = talloc_asprintf_strupper_m(
3732 result, "\\\\%s", global_myname());
3733 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3734 TALLOC_FREE(result);
3735 return NT_STATUS_NO_MEMORY;
3738 status = rpc_transport_smbd_init(result, conn, syntax,
3739 &result->transport);
3740 if (!NT_STATUS_IS_OK(status)) {
3741 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3742 nt_errstr(status)));
3743 TALLOC_FREE(result);
3747 status = rpccli_anon_bind_data(result, &auth);
3748 if (!NT_STATUS_IS_OK(status)) {
3749 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3750 nt_errstr(status)));
3751 TALLOC_FREE(result);
3755 status = rpc_pipe_bind(result, auth);
3756 if (!NT_STATUS_IS_OK(status)) {
3757 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3758 TALLOC_FREE(result);
3762 result->transport->transport = NCACN_INTERNAL;
3765 return NT_STATUS_OK;
3768 /****************************************************************************
3769 Open a pipe to a remote server.
3770 ****************************************************************************/
3772 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3773 enum dcerpc_transport_t transport,
3774 const struct ndr_syntax_id *interface,
3775 struct rpc_pipe_client **presult)
3777 switch (transport) {
3779 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3782 return rpc_pipe_open_np(cli, interface, presult);
3784 return NT_STATUS_NOT_IMPLEMENTED;
3788 /****************************************************************************
3789 Open a named pipe to an SMB server and bind anonymously.
3790 ****************************************************************************/
3792 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3793 enum dcerpc_transport_t transport,
3794 const struct ndr_syntax_id *interface,
3795 struct rpc_pipe_client **presult)
3797 struct rpc_pipe_client *result;
3798 struct cli_pipe_auth_data *auth;
3801 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3802 if (!NT_STATUS_IS_OK(status)) {
3806 status = rpccli_anon_bind_data(result, &auth);
3807 if (!NT_STATUS_IS_OK(status)) {
3808 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3809 nt_errstr(status)));
3810 TALLOC_FREE(result);
3815 * This is a bit of an abstraction violation due to the fact that an
3816 * anonymous bind on an authenticated SMB inherits the user/domain
3817 * from the enclosing SMB creds
3820 TALLOC_FREE(auth->user_name);
3821 TALLOC_FREE(auth->domain);
3823 auth->user_name = talloc_strdup(auth, cli->user_name);
3824 auth->domain = talloc_strdup(auth, cli->domain);
3825 auth->user_session_key = data_blob_talloc(auth,
3826 cli->user_session_key.data,
3827 cli->user_session_key.length);
3829 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3830 TALLOC_FREE(result);
3831 return NT_STATUS_NO_MEMORY;
3834 status = rpc_pipe_bind(result, auth);
3835 if (!NT_STATUS_IS_OK(status)) {
3837 if (ndr_syntax_id_equal(interface,
3838 &ndr_table_dssetup.syntax_id)) {
3839 /* non AD domains just don't have this pipe, avoid
3840 * level 0 statement in that case - gd */
3843 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3844 "%s failed with error %s\n",
3845 get_pipe_name_from_syntax(talloc_tos(), interface),
3846 nt_errstr(status) ));
3847 TALLOC_FREE(result);
3851 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3852 "%s and bound anonymously.\n",
3853 get_pipe_name_from_syntax(talloc_tos(), interface),
3857 return NT_STATUS_OK;
3860 /****************************************************************************
3861 ****************************************************************************/
3863 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3864 const struct ndr_syntax_id *interface,
3865 struct rpc_pipe_client **presult)
3867 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3868 interface, presult);
3871 /****************************************************************************
3872 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3873 ****************************************************************************/
3875 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3876 const struct ndr_syntax_id *interface,
3877 enum dcerpc_transport_t transport,
3878 enum pipe_auth_type auth_type,
3879 enum dcerpc_AuthLevel auth_level,
3881 const char *username,
3882 const char *password,
3883 struct rpc_pipe_client **presult)
3885 struct rpc_pipe_client *result;
3886 struct cli_pipe_auth_data *auth;
3889 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3890 if (!NT_STATUS_IS_OK(status)) {
3894 status = rpccli_ntlmssp_bind_data(
3895 result, auth_type, auth_level, domain, username,
3897 if (!NT_STATUS_IS_OK(status)) {
3898 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3899 nt_errstr(status)));
3903 status = rpc_pipe_bind(result, auth);
3904 if (!NT_STATUS_IS_OK(status)) {
3905 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3906 nt_errstr(status) ));
3910 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3911 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3912 get_pipe_name_from_syntax(talloc_tos(), interface),
3913 cli->desthost, domain, username ));
3916 return NT_STATUS_OK;
3920 TALLOC_FREE(result);
3924 /****************************************************************************
3926 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3927 ****************************************************************************/
3929 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3930 const struct ndr_syntax_id *interface,
3931 enum dcerpc_transport_t transport,
3932 enum dcerpc_AuthLevel auth_level,
3934 const char *username,
3935 const char *password,
3936 struct rpc_pipe_client **presult)
3938 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3941 PIPE_AUTH_TYPE_NTLMSSP,
3949 /****************************************************************************
3951 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3952 ****************************************************************************/
3954 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3955 const struct ndr_syntax_id *interface,
3956 enum dcerpc_transport_t transport,
3957 enum dcerpc_AuthLevel auth_level,
3959 const char *username,
3960 const char *password,
3961 struct rpc_pipe_client **presult)
3963 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3966 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3974 /****************************************************************************
3975 Get a the schannel session key out of an already opened netlogon pipe.
3976 ****************************************************************************/
3977 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3978 struct cli_state *cli,
3982 enum netr_SchannelType sec_chan_type = 0;
3983 unsigned char machine_pwd[16];
3984 const char *machine_account;
3987 /* Get the machine account credentials from secrets.tdb. */
3988 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3991 DEBUG(0, ("get_schannel_session_key: could not fetch "
3992 "trust account password for domain '%s'\n",
3994 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3997 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3998 cli->desthost, /* server name */
3999 domain, /* domain */
4000 global_myname(), /* client name */
4001 machine_account, /* machine account name */
4006 if (!NT_STATUS_IS_OK(status)) {
4007 DEBUG(3, ("get_schannel_session_key_common: "
4008 "rpccli_netlogon_setup_creds failed with result %s "
4009 "to server %s, domain %s, machine account %s.\n",
4010 nt_errstr(status), cli->desthost, domain,
4015 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
4016 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
4018 return NT_STATUS_INVALID_NETWORK_RESPONSE;
4021 return NT_STATUS_OK;;
4024 /****************************************************************************
4025 Open a netlogon pipe and get the schannel session key.
4026 Now exposed to external callers.
4027 ****************************************************************************/
4030 NTSTATUS get_schannel_session_key(struct cli_state *cli,
4033 struct rpc_pipe_client **presult)
4035 struct rpc_pipe_client *netlogon_pipe = NULL;
4038 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
4040 if (!NT_STATUS_IS_OK(status)) {
4044 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4046 if (!NT_STATUS_IS_OK(status)) {
4047 TALLOC_FREE(netlogon_pipe);
4051 *presult = netlogon_pipe;
4052 return NT_STATUS_OK;
4055 /****************************************************************************
4057 Open a named pipe to an SMB server and bind using schannel (bind type 68)
4058 using session_key. sign and seal.
4060 The *pdc will be stolen onto this new pipe
4061 ****************************************************************************/
4063 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
4064 const struct ndr_syntax_id *interface,
4065 enum dcerpc_transport_t transport,
4066 enum dcerpc_AuthLevel auth_level,
4068 struct netlogon_creds_CredentialState **pdc,
4069 struct rpc_pipe_client **presult)
4071 struct rpc_pipe_client *result;
4072 struct cli_pipe_auth_data *auth;
4075 status = cli_rpc_pipe_open(cli, transport, interface, &result);
4076 if (!NT_STATUS_IS_OK(status)) {
4080 status = rpccli_schannel_bind_data(result, domain, auth_level,
4082 if (!NT_STATUS_IS_OK(status)) {
4083 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
4084 nt_errstr(status)));
4085 TALLOC_FREE(result);
4089 status = rpc_pipe_bind(result, auth);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
4092 "cli_rpc_pipe_bind failed with error %s\n",
4093 nt_errstr(status) ));
4094 TALLOC_FREE(result);
4099 * The credentials on a new netlogon pipe are the ones we are passed
4100 * in - reference them in
4102 result->dc = talloc_move(result, pdc);
4104 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
4105 "for domain %s and bound using schannel.\n",
4106 get_pipe_name_from_syntax(talloc_tos(), interface),
4107 cli->desthost, domain ));
4110 return NT_STATUS_OK;
4113 /****************************************************************************
4114 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4115 Fetch the session key ourselves using a temporary netlogon pipe. This
4116 version uses an ntlmssp auth bound netlogon pipe to get the key.
4117 ****************************************************************************/
4119 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
4121 const char *username,
4122 const char *password,
4124 struct rpc_pipe_client **presult)
4126 struct rpc_pipe_client *netlogon_pipe = NULL;
4129 status = cli_rpc_pipe_open_spnego_ntlmssp(
4130 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
4131 DCERPC_AUTH_LEVEL_PRIVACY,
4132 domain, username, password, &netlogon_pipe);
4133 if (!NT_STATUS_IS_OK(status)) {
4137 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
4139 if (!NT_STATUS_IS_OK(status)) {
4140 TALLOC_FREE(netlogon_pipe);
4144 *presult = netlogon_pipe;
4145 return NT_STATUS_OK;
4148 /****************************************************************************
4149 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4150 Fetch the session key ourselves using a temporary netlogon pipe. This version
4151 uses an ntlmssp bind to get the session key.
4152 ****************************************************************************/
4154 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
4155 const struct ndr_syntax_id *interface,
4156 enum dcerpc_transport_t transport,
4157 enum dcerpc_AuthLevel auth_level,
4159 const char *username,
4160 const char *password,
4161 struct rpc_pipe_client **presult)
4163 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4164 struct rpc_pipe_client *netlogon_pipe = NULL;
4165 struct rpc_pipe_client *result = NULL;
4168 status = get_schannel_session_key_auth_ntlmssp(
4169 cli, domain, username, password, &neg_flags, &netlogon_pipe);
4170 if (!NT_STATUS_IS_OK(status)) {
4171 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
4172 "key from server %s for domain %s.\n",
4173 cli->desthost, domain ));
4177 status = cli_rpc_pipe_open_schannel_with_key(
4178 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4181 /* Now we've bound using the session key we can close the netlog pipe. */
4182 TALLOC_FREE(netlogon_pipe);
4184 if (NT_STATUS_IS_OK(status)) {
4190 /****************************************************************************
4191 Open a named pipe to an SMB server and bind using schannel (bind type 68).
4192 Fetch the session key ourselves using a temporary netlogon pipe.
4193 ****************************************************************************/
4195 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
4196 const struct ndr_syntax_id *interface,
4197 enum dcerpc_transport_t transport,
4198 enum dcerpc_AuthLevel auth_level,
4200 struct rpc_pipe_client **presult)
4202 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
4203 struct rpc_pipe_client *netlogon_pipe = NULL;
4204 struct rpc_pipe_client *result = NULL;
4207 status = get_schannel_session_key(cli, domain, &neg_flags,
4209 if (!NT_STATUS_IS_OK(status)) {
4210 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
4211 "key from server %s for domain %s.\n",
4212 cli->desthost, domain ));
4216 status = cli_rpc_pipe_open_schannel_with_key(
4217 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
4220 /* Now we've bound using the session key we can close the netlog pipe. */
4221 TALLOC_FREE(netlogon_pipe);
4223 if (NT_STATUS_IS_OK(status)) {
4230 /****************************************************************************
4231 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
4232 The idea is this can be called with service_princ, username and password all
4233 NULL so long as the caller has a TGT.
4234 ****************************************************************************/
4236 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
4237 const struct ndr_syntax_id *interface,
4238 enum dcerpc_AuthLevel auth_level,
4239 const char *service_princ,
4240 const char *username,
4241 const char *password,
4242 struct rpc_pipe_client **presult)
4245 struct rpc_pipe_client *result;
4246 struct cli_pipe_auth_data *auth;
4249 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
4250 if (!NT_STATUS_IS_OK(status)) {
4254 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
4255 username, password, &auth);
4256 if (!NT_STATUS_IS_OK(status)) {
4257 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
4258 nt_errstr(status)));
4259 TALLOC_FREE(result);
4263 status = rpc_pipe_bind(result, auth);
4264 if (!NT_STATUS_IS_OK(status)) {
4265 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
4266 "with error %s\n", nt_errstr(status)));
4267 TALLOC_FREE(result);
4272 return NT_STATUS_OK;
4274 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
4275 return NT_STATUS_NOT_IMPLEMENTED;
4279 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
4280 struct rpc_pipe_client *cli,
4281 DATA_BLOB *session_key)
4283 if (!session_key || !cli) {
4284 return NT_STATUS_INVALID_PARAMETER;
4288 return NT_STATUS_INVALID_PARAMETER;
4291 switch (cli->auth->auth_type) {
4292 case PIPE_AUTH_TYPE_SCHANNEL:
4293 *session_key = data_blob_talloc(mem_ctx,
4294 cli->auth->a_u.schannel_auth->creds->session_key, 16);
4296 case PIPE_AUTH_TYPE_NTLMSSP:
4297 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
4298 *session_key = data_blob_talloc(mem_ctx,
4299 cli->auth->a_u.ntlmssp_state->session_key.data,
4300 cli->auth->a_u.ntlmssp_state->session_key.length);
4302 case PIPE_AUTH_TYPE_KRB5:
4303 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
4304 *session_key = data_blob_talloc(mem_ctx,
4305 cli->auth->a_u.kerberos_auth->session_key.data,
4306 cli->auth->a_u.kerberos_auth->session_key.length);
4308 case PIPE_AUTH_TYPE_NONE:
4309 *session_key = data_blob_talloc(mem_ctx,
4310 cli->auth->user_session_key.data,
4311 cli->auth->user_session_key.length);
4314 return NT_STATUS_NO_USER_SESSION_KEY;
4317 return NT_STATUS_OK;