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_dssetup.h"
24 #include "../librpc/gen_ndr/ndr_netlogon.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "rpc_client/cli_netlogon.h"
30 #include "librpc/gen_ndr/ndr_dcerpc.h"
31 #include "librpc/rpc/dcerpc.h"
34 #define DBGC_CLASS DBGC_RPC_CLI
36 /********************************************************************
37 Pipe description for a DEBUG
38 ********************************************************************/
39 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
40 struct rpc_pipe_client *cli)
42 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
49 /********************************************************************
51 ********************************************************************/
53 static uint32 get_rpc_call_id(void)
55 static uint32 call_id = 0;
59 /*******************************************************************
60 Use SMBreadX to get rest of one fragment's worth of rpc data.
61 Reads the whole size or give an error message
62 ********************************************************************/
64 struct rpc_read_state {
65 struct event_context *ev;
66 struct rpc_cli_transport *transport;
72 static void rpc_read_done(struct tevent_req *subreq);
74 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
75 struct event_context *ev,
76 struct rpc_cli_transport *transport,
77 uint8_t *data, size_t size)
79 struct tevent_req *req, *subreq;
80 struct rpc_read_state *state;
82 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
87 state->transport = transport;
92 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
94 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
99 tevent_req_set_callback(subreq, rpc_read_done, req);
107 static void rpc_read_done(struct tevent_req *subreq)
109 struct tevent_req *req = tevent_req_callback_data(
110 subreq, struct tevent_req);
111 struct rpc_read_state *state = tevent_req_data(
112 req, struct rpc_read_state);
116 status = state->transport->read_recv(subreq, &received);
118 if (!NT_STATUS_IS_OK(status)) {
119 tevent_req_nterror(req, status);
123 state->num_read += received;
124 if (state->num_read == state->size) {
125 tevent_req_done(req);
129 subreq = state->transport->read_send(state, state->ev,
130 state->data + state->num_read,
131 state->size - state->num_read,
132 state->transport->priv);
133 if (tevent_req_nomem(subreq, req)) {
136 tevent_req_set_callback(subreq, rpc_read_done, req);
139 static NTSTATUS rpc_read_recv(struct tevent_req *req)
141 return tevent_req_simple_recv_ntstatus(req);
144 struct rpc_write_state {
145 struct event_context *ev;
146 struct rpc_cli_transport *transport;
152 static void rpc_write_done(struct tevent_req *subreq);
154 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
155 struct event_context *ev,
156 struct rpc_cli_transport *transport,
157 const uint8_t *data, size_t size)
159 struct tevent_req *req, *subreq;
160 struct rpc_write_state *state;
162 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
167 state->transport = transport;
170 state->num_written = 0;
172 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
174 subreq = transport->write_send(state, ev, data, size, transport->priv);
175 if (subreq == NULL) {
178 tevent_req_set_callback(subreq, rpc_write_done, req);
185 static void rpc_write_done(struct tevent_req *subreq)
187 struct tevent_req *req = tevent_req_callback_data(
188 subreq, struct tevent_req);
189 struct rpc_write_state *state = tevent_req_data(
190 req, struct rpc_write_state);
194 status = state->transport->write_recv(subreq, &written);
196 if (!NT_STATUS_IS_OK(status)) {
197 tevent_req_nterror(req, status);
201 state->num_written += written;
203 if (state->num_written == state->size) {
204 tevent_req_done(req);
208 subreq = state->transport->write_send(state, state->ev,
209 state->data + state->num_written,
210 state->size - state->num_written,
211 state->transport->priv);
212 if (tevent_req_nomem(subreq, req)) {
215 tevent_req_set_callback(subreq, rpc_write_done, req);
218 static NTSTATUS rpc_write_recv(struct tevent_req *req)
220 return tevent_req_simple_recv_ntstatus(req);
224 /****************************************************************************
225 Try and get a PDU's worth of data from current_pdu. If not, then read more
227 ****************************************************************************/
229 struct get_complete_frag_state {
230 struct event_context *ev;
231 struct rpc_pipe_client *cli;
236 static void get_complete_frag_got_header(struct tevent_req *subreq);
237 static void get_complete_frag_got_rest(struct tevent_req *subreq);
239 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
240 struct event_context *ev,
241 struct rpc_pipe_client *cli,
244 struct tevent_req *req, *subreq;
245 struct get_complete_frag_state *state;
249 req = tevent_req_create(mem_ctx, &state,
250 struct get_complete_frag_state);
256 state->frag_len = RPC_HEADER_LEN;
259 received = pdu->length;
260 if (received < RPC_HEADER_LEN) {
261 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
262 status = NT_STATUS_NO_MEMORY;
265 subreq = rpc_read_send(state, state->ev,
266 state->cli->transport,
267 pdu->data + received,
268 RPC_HEADER_LEN - received);
269 if (subreq == NULL) {
270 status = NT_STATUS_NO_MEMORY;
273 tevent_req_set_callback(subreq, get_complete_frag_got_header,
278 state->frag_len = dcerpc_get_frag_length(pdu);
281 * Ensure we have frag_len bytes of data.
283 if (received < state->frag_len) {
284 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
285 status = NT_STATUS_NO_MEMORY;
288 subreq = rpc_read_send(state, state->ev,
289 state->cli->transport,
290 pdu->data + received,
291 state->frag_len - received);
292 if (subreq == NULL) {
293 status = NT_STATUS_NO_MEMORY;
296 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
301 status = NT_STATUS_OK;
303 if (NT_STATUS_IS_OK(status)) {
304 tevent_req_done(req);
306 tevent_req_nterror(req, status);
308 return tevent_req_post(req, ev);
311 static void get_complete_frag_got_header(struct tevent_req *subreq)
313 struct tevent_req *req = tevent_req_callback_data(
314 subreq, struct tevent_req);
315 struct get_complete_frag_state *state = tevent_req_data(
316 req, struct get_complete_frag_state);
319 status = rpc_read_recv(subreq);
321 if (!NT_STATUS_IS_OK(status)) {
322 tevent_req_nterror(req, status);
326 state->frag_len = dcerpc_get_frag_length(state->pdu);
328 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
329 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
334 * We're here in this piece of code because we've read exactly
335 * RPC_HEADER_LEN bytes into state->pdu.
338 subreq = rpc_read_send(state, state->ev, state->cli->transport,
339 state->pdu->data + RPC_HEADER_LEN,
340 state->frag_len - RPC_HEADER_LEN);
341 if (tevent_req_nomem(subreq, req)) {
344 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
347 static void get_complete_frag_got_rest(struct tevent_req *subreq)
349 struct tevent_req *req = tevent_req_callback_data(
350 subreq, struct tevent_req);
353 status = rpc_read_recv(subreq);
355 if (!NT_STATUS_IS_OK(status)) {
356 tevent_req_nterror(req, status);
359 tevent_req_done(req);
362 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
364 return tevent_req_simple_recv_ntstatus(req);
367 /****************************************************************************
368 NTLMSSP specific sign/seal.
369 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
370 In fact I should probably abstract these into identical pieces of code... JRA.
371 ****************************************************************************/
373 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
374 struct ncacn_packet *pkt,
376 uint8 *p_ss_padding_len)
378 struct dcerpc_auth auth_info;
382 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
383 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
387 if (!cli->auth->a_u.ntlmssp_state) {
388 return NT_STATUS_INVALID_PARAMETER;
391 /* Ensure there's enough data for an authenticated response. */
392 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
393 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
394 + DCERPC_AUTH_TRAILER_LENGTH
395 + pkt->auth_length)) {
396 DEBUG(0, ("auth_len %u is too long.\n",
397 (unsigned int)pkt->auth_length));
398 return NT_STATUS_BUFFER_TOO_SMALL;
401 /* get the auth blob at the end of the packet */
402 blob = data_blob_const(pdu->data + pkt->frag_length
403 - DCERPC_AUTH_TRAILER_LENGTH
405 DCERPC_AUTH_TRAILER_LENGTH
408 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
409 if (!NT_STATUS_IS_OK(status)) {
410 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
414 /* Ensure auth_pad_len fits into the packet. */
415 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
416 + auth_info.auth_pad_length
417 + DCERPC_AUTH_TRAILER_LENGTH
418 + pkt->auth_length) {
419 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
420 "too large (%u), auth_len (%u), frag_len = (%u).\n",
421 (unsigned int)auth_info.auth_pad_length,
422 (unsigned int)pkt->auth_length,
423 (unsigned int)pkt->frag_length));
424 return NT_STATUS_BUFFER_TOO_SMALL;
428 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
429 * after the RPC header.
430 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
431 * functions as NTLMv2 checks the rpc headers also.
434 switch (cli->auth->auth_level) {
435 case DCERPC_AUTH_LEVEL_PRIVACY:
436 /* Data is encrypted. */
437 status = ntlmssp_unseal_packet(
438 cli->auth->a_u.ntlmssp_state,
439 pdu->data + DCERPC_RESPONSE_LENGTH,
441 - DCERPC_RESPONSE_LENGTH
442 - DCERPC_AUTH_TRAILER_LENGTH
445 pkt->frag_length - pkt->auth_length,
446 &auth_info.credentials);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(0, ("failed to unseal packet from %s."
450 rpccli_pipe_txt(talloc_tos(), cli),
456 case DCERPC_AUTH_LEVEL_INTEGRITY:
457 /* Data is signed. */
458 status = ntlmssp_check_packet(
459 cli->auth->a_u.ntlmssp_state,
460 pdu->data + DCERPC_RESPONSE_LENGTH,
462 - DCERPC_RESPONSE_LENGTH
463 - DCERPC_AUTH_TRAILER_LENGTH
466 pkt->frag_length - pkt->auth_length,
467 &auth_info.credentials);
468 if (!NT_STATUS_IS_OK(status)) {
469 DEBUG(0, ("check signing failed on packet from %s."
471 rpccli_pipe_txt(talloc_tos(), cli),
478 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
479 "auth level %d\n", cli->auth->auth_level));
480 return NT_STATUS_INVALID_INFO_CLASS;
484 * Remember the padding length. We must remove it from the real data
485 * stream once the sign/seal is done.
488 *p_ss_padding_len = auth_info.auth_pad_length;
493 /****************************************************************************
494 schannel specific sign/seal.
495 ****************************************************************************/
497 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
498 struct ncacn_packet *pkt,
500 uint8 *p_ss_padding_len)
502 struct dcerpc_auth auth_info;
506 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
507 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
511 if (pkt->auth_length < NL_AUTH_SIGNATURE_SIZE) {
512 DEBUG(0, ("auth_len %u.\n", (unsigned int)pkt->auth_length));
513 return NT_STATUS_INVALID_PARAMETER;
516 if (!cli->auth->a_u.schannel_auth) {
517 return NT_STATUS_INVALID_PARAMETER;
520 /* Ensure there's enough data for an authenticated response. */
521 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
522 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
523 + DCERPC_AUTH_TRAILER_LENGTH
524 + pkt->auth_length)) {
525 DEBUG(0, ("auth_len %u is too long.\n",
526 (unsigned int)pkt->auth_length));
527 return NT_STATUS_INVALID_PARAMETER;
530 /* get the auth blob at the end of the packet */
531 blob = data_blob_const(pdu->data + pkt->frag_length
532 - DCERPC_AUTH_TRAILER_LENGTH
534 DCERPC_AUTH_TRAILER_LENGTH
538 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
539 if (!NT_STATUS_IS_OK(status)) {
540 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
544 /* Ensure auth_pad_len fits into the packet. */
545 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
546 + auth_info.auth_pad_length
547 + DCERPC_AUTH_TRAILER_LENGTH
548 + pkt->auth_length) {
549 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
550 "too large (%u), auth_len (%u), frag_len = (%u).\n",
551 (unsigned int)auth_info.auth_pad_length,
552 (unsigned int)pkt->auth_length,
553 (unsigned int)pkt->frag_length));
554 return NT_STATUS_BUFFER_TOO_SMALL;
557 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
558 DEBUG(0, ("Invalid auth info %d on schannel\n",
559 auth_info.auth_type));
560 return NT_STATUS_BUFFER_TOO_SMALL;
563 if (DEBUGLEVEL >= 10) {
564 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_info.credentials);
567 switch (cli->auth->auth_level) {
568 case DCERPC_AUTH_LEVEL_PRIVACY:
569 status = netsec_incoming_packet(
570 cli->auth->a_u.schannel_auth,
573 pdu->data + DCERPC_RESPONSE_LENGTH,
575 - DCERPC_RESPONSE_LENGTH
576 - DCERPC_AUTH_TRAILER_LENGTH
578 &auth_info.credentials);
580 case DCERPC_AUTH_LEVEL_INTEGRITY:
581 status = netsec_incoming_packet(
582 cli->auth->a_u.schannel_auth,
585 pdu->data + DCERPC_RESPONSE_LENGTH,
587 - DCERPC_RESPONSE_LENGTH
588 - DCERPC_AUTH_TRAILER_LENGTH
590 &auth_info.credentials);
593 status = NT_STATUS_INTERNAL_ERROR;
597 if (!NT_STATUS_IS_OK(status)) {
598 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
599 "Connection to %s (%s).\n",
600 rpccli_pipe_txt(talloc_tos(), cli),
602 return NT_STATUS_INVALID_PARAMETER;
606 * Remember the padding length. We must remove it from the real data
607 * stream once the sign/seal is done.
610 *p_ss_padding_len = auth_info.auth_pad_length;
615 /****************************************************************************
616 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
617 ****************************************************************************/
619 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
620 struct ncacn_packet *pkt,
622 uint8 *p_ss_padding_len)
624 NTSTATUS ret = NT_STATUS_OK;
626 /* Paranioa checks for auth_len. */
627 if (pkt->auth_length) {
628 if (pkt->auth_length > pkt->frag_length) {
629 return NT_STATUS_INVALID_PARAMETER;
632 if ((pkt->auth_length
633 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
634 < pkt->auth_length) ||
636 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
637 < (unsigned int)DCERPC_AUTH_TRAILER_LENGTH)) {
638 /* Integer wrap attempt. */
639 return NT_STATUS_INVALID_PARAMETER;
644 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
647 switch(cli->auth->auth_type) {
648 case PIPE_AUTH_TYPE_NONE:
649 if (pkt->auth_length) {
650 DEBUG(3, ("cli_pipe_validate_rpc_response: "
651 "Connection to %s - got non-zero "
653 rpccli_pipe_txt(talloc_tos(), cli),
654 (unsigned int)pkt->auth_length));
655 return NT_STATUS_INVALID_PARAMETER;
659 case PIPE_AUTH_TYPE_NTLMSSP:
660 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
661 ret = cli_pipe_verify_ntlmssp(cli, pkt, pdu,
663 if (!NT_STATUS_IS_OK(ret)) {
668 case PIPE_AUTH_TYPE_SCHANNEL:
669 ret = cli_pipe_verify_schannel(cli, pkt, pdu,
671 if (!NT_STATUS_IS_OK(ret)) {
676 case PIPE_AUTH_TYPE_KRB5:
677 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
679 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
680 "to %s - unknown internal auth type %u.\n",
681 rpccli_pipe_txt(talloc_tos(), cli),
682 cli->auth->auth_type ));
683 return NT_STATUS_INVALID_INFO_CLASS;
689 /****************************************************************************
690 Do basic authentication checks on an incoming pdu.
691 ****************************************************************************/
693 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
694 struct rpc_pipe_client *cli,
695 struct ncacn_packet *pkt,
697 uint8_t expected_pkt_type,
699 DATA_BLOB *reply_pdu)
701 NTSTATUS ret = NT_STATUS_OK;
702 uint8 ss_padding_len = 0;
704 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
705 if (!NT_STATUS_IS_OK(ret)) {
709 if (pdu->length != pkt->frag_length) {
710 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
711 (unsigned int)pdu->length,
712 (unsigned int)pkt->frag_length));
713 return NT_STATUS_INVALID_PARAMETER;
717 * Point the return values at the real data including the RPC
718 * header. Just in case the caller wants it.
722 /* Ensure we have the correct type. */
723 switch (pkt->ptype) {
724 case DCERPC_PKT_ALTER_RESP:
725 case DCERPC_PKT_BIND_ACK:
727 /* Alter context and bind ack share the same packet definitions. */
731 case DCERPC_PKT_RESPONSE:
733 /* Here's where we deal with incoming sign/seal. */
734 ret = cli_pipe_validate_rpc_response(cli, pkt, pdu,
736 if (!NT_STATUS_IS_OK(ret)) {
740 /* Point the return values at the NDR data.
741 * Remember to remove any ss padding. */
742 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
744 if (pdu->length < DCERPC_RESPONSE_LENGTH + ss_padding_len) {
745 return NT_STATUS_BUFFER_TOO_SMALL;
748 rdata->length = pdu->length
749 - DCERPC_RESPONSE_LENGTH
752 /* Remember to remove the auth footer. */
753 if (pkt->auth_length) {
754 /* We've already done integer wrap tests on auth_len in
755 cli_pipe_validate_rpc_response(). */
756 if (rdata->length < DCERPC_AUTH_TRAILER_LENGTH
757 + pkt->auth_length) {
758 return NT_STATUS_BUFFER_TOO_SMALL;
760 rdata->length -= (DCERPC_AUTH_TRAILER_LENGTH
764 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
765 (long unsigned int)pdu->length,
766 (long unsigned int)rdata->length,
767 (unsigned int)ss_padding_len));
770 * If this is the first reply, and the allocation hint is
771 * reasonable, try and set up the reply_pdu DATA_BLOB to the
775 if ((reply_pdu->length == 0) &&
776 pkt->u.response.alloc_hint &&
777 (pkt->u.response.alloc_hint < 15*1024*1024)) {
778 if (!data_blob_realloc(mem_ctx, reply_pdu,
779 pkt->u.response.alloc_hint)) {
780 DEBUG(0, ("reply alloc hint %d too "
781 "large to allocate\n",
782 (int)pkt->u.response.alloc_hint));
783 return NT_STATUS_NO_MEMORY;
789 case DCERPC_PKT_BIND_NAK:
790 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
791 "received from %s!\n",
792 rpccli_pipe_txt(talloc_tos(), cli)));
793 /* Use this for now... */
794 return NT_STATUS_NETWORK_ACCESS_DENIED;
796 case DCERPC_PKT_FAULT:
798 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
799 "code %s received from %s!\n",
800 dcerpc_errstr(talloc_tos(),
801 pkt->u.fault.status),
802 rpccli_pipe_txt(talloc_tos(), cli)));
804 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
805 return NT_STATUS_UNSUCCESSFUL;
807 return NT_STATUS(pkt->u.fault.status);
811 DEBUG(0, ("Unknown packet type %u received from %s!\n",
812 (unsigned int)pkt->ptype,
813 rpccli_pipe_txt(talloc_tos(), cli)));
814 return NT_STATUS_INVALID_INFO_CLASS;
817 if (pkt->ptype != expected_pkt_type) {
818 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
819 "got an unexpected RPC packet type - %u, not %u\n",
820 rpccli_pipe_txt(talloc_tos(), cli),
823 return NT_STATUS_INVALID_INFO_CLASS;
826 /* Do this just before return - we don't want to modify any rpc header
827 data before now as we may have needed to do cryptographic actions on
830 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
831 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
832 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
833 "setting fragment first/last ON.\n"));
834 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
835 DCERPC_PFC_FLAG_LAST;
841 /****************************************************************************
842 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
843 ****************************************************************************/
845 struct cli_api_pipe_state {
846 struct event_context *ev;
847 struct rpc_cli_transport *transport;
852 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
853 static void cli_api_pipe_write_done(struct tevent_req *subreq);
854 static void cli_api_pipe_read_done(struct tevent_req *subreq);
856 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
857 struct event_context *ev,
858 struct rpc_cli_transport *transport,
859 uint8_t *data, size_t data_len,
860 uint32_t max_rdata_len)
862 struct tevent_req *req, *subreq;
863 struct cli_api_pipe_state *state;
866 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
871 state->transport = transport;
873 if (max_rdata_len < RPC_HEADER_LEN) {
875 * For a RPC reply we always need at least RPC_HEADER_LEN
876 * bytes. We check this here because we will receive
877 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
879 status = NT_STATUS_INVALID_PARAMETER;
883 if (transport->trans_send != NULL) {
884 subreq = transport->trans_send(state, ev, data, data_len,
885 max_rdata_len, transport->priv);
886 if (subreq == NULL) {
889 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
894 * If the transport does not provide a "trans" routine, i.e. for
895 * example the ncacn_ip_tcp transport, do the write/read step here.
898 subreq = rpc_write_send(state, ev, transport, data, data_len);
899 if (subreq == NULL) {
902 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
906 tevent_req_nterror(req, status);
907 return tevent_req_post(req, ev);
913 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
915 struct tevent_req *req = tevent_req_callback_data(
916 subreq, struct tevent_req);
917 struct cli_api_pipe_state *state = tevent_req_data(
918 req, struct cli_api_pipe_state);
921 status = state->transport->trans_recv(subreq, state, &state->rdata,
924 if (!NT_STATUS_IS_OK(status)) {
925 tevent_req_nterror(req, status);
928 tevent_req_done(req);
931 static void cli_api_pipe_write_done(struct tevent_req *subreq)
933 struct tevent_req *req = tevent_req_callback_data(
934 subreq, struct tevent_req);
935 struct cli_api_pipe_state *state = tevent_req_data(
936 req, struct cli_api_pipe_state);
939 status = rpc_write_recv(subreq);
941 if (!NT_STATUS_IS_OK(status)) {
942 tevent_req_nterror(req, status);
946 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
947 if (tevent_req_nomem(state->rdata, req)) {
952 * We don't need to use rpc_read_send here, the upper layer will cope
953 * with a short read, transport->trans_send could also return less
954 * than state->max_rdata_len.
956 subreq = state->transport->read_send(state, state->ev, state->rdata,
958 state->transport->priv);
959 if (tevent_req_nomem(subreq, req)) {
962 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
965 static void cli_api_pipe_read_done(struct tevent_req *subreq)
967 struct tevent_req *req = tevent_req_callback_data(
968 subreq, struct tevent_req);
969 struct cli_api_pipe_state *state = tevent_req_data(
970 req, struct cli_api_pipe_state);
974 status = state->transport->read_recv(subreq, &received);
976 if (!NT_STATUS_IS_OK(status)) {
977 tevent_req_nterror(req, status);
980 state->rdata_len = received;
981 tevent_req_done(req);
984 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
985 uint8_t **prdata, uint32_t *prdata_len)
987 struct cli_api_pipe_state *state = tevent_req_data(
988 req, struct cli_api_pipe_state);
991 if (tevent_req_is_nterror(req, &status)) {
995 *prdata = talloc_move(mem_ctx, &state->rdata);
996 *prdata_len = state->rdata_len;
1000 /****************************************************************************
1001 Send data on an rpc pipe via trans. The data must be the last
1002 pdu fragment of an NDR data stream.
1004 Receive response data from an rpc pipe, which may be large...
1006 Read the first fragment: unfortunately have to use SMBtrans for the first
1007 bit, then SMBreadX for subsequent bits.
1009 If first fragment received also wasn't the last fragment, continue
1010 getting fragments until we _do_ receive the last fragment.
1012 Request/Response PDU's look like the following...
1014 |<------------------PDU len----------------------------------------------->|
1015 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1017 +------------+-----------------+-------------+---------------+-------------+
1018 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1019 +------------+-----------------+-------------+---------------+-------------+
1021 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1022 signing & sealing being negotiated.
1024 ****************************************************************************/
1026 struct rpc_api_pipe_state {
1027 struct event_context *ev;
1028 struct rpc_pipe_client *cli;
1029 uint8_t expected_pkt_type;
1031 DATA_BLOB incoming_frag;
1032 struct ncacn_packet *pkt;
1034 /* Incoming reply */
1035 DATA_BLOB reply_pdu;
1036 size_t reply_pdu_offset;
1040 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1041 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1043 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1044 struct event_context *ev,
1045 struct rpc_pipe_client *cli,
1046 DATA_BLOB *data, /* Outgoing PDU */
1047 uint8_t expected_pkt_type)
1049 struct tevent_req *req, *subreq;
1050 struct rpc_api_pipe_state *state;
1051 uint16_t max_recv_frag;
1054 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1060 state->expected_pkt_type = expected_pkt_type;
1061 state->incoming_frag = data_blob_null;
1062 state->reply_pdu = data_blob_null;
1063 state->reply_pdu_offset = 0;
1064 state->endianess = DCERPC_DREP_LE;
1067 * Ensure we're not sending too much.
1069 if (data->length > cli->max_xmit_frag) {
1070 status = NT_STATUS_INVALID_PARAMETER;
1074 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1076 /* get the header first, then fetch the rest once we have
1077 * the frag_length available */
1078 max_recv_frag = RPC_HEADER_LEN;
1080 subreq = cli_api_pipe_send(state, ev, cli->transport,
1081 data->data, data->length, max_recv_frag);
1082 if (subreq == NULL) {
1085 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1089 tevent_req_nterror(req, status);
1090 return tevent_req_post(req, ev);
1096 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1098 struct tevent_req *req = tevent_req_callback_data(
1099 subreq, struct tevent_req);
1100 struct rpc_api_pipe_state *state = tevent_req_data(
1101 req, struct rpc_api_pipe_state);
1103 uint8_t *rdata = NULL;
1104 uint32_t rdata_len = 0;
1106 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1107 TALLOC_FREE(subreq);
1108 if (!NT_STATUS_IS_OK(status)) {
1109 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1110 tevent_req_nterror(req, status);
1114 if (rdata == NULL) {
1115 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1116 rpccli_pipe_txt(talloc_tos(), state->cli)));
1117 tevent_req_done(req);
1122 * Move data on state->incoming_frag.
1124 state->incoming_frag.data = talloc_move(state, &rdata);
1125 state->incoming_frag.length = rdata_len;
1126 if (!state->incoming_frag.data) {
1127 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1131 /* Ensure we have enough data for a pdu. */
1132 subreq = get_complete_frag_send(state, state->ev, state->cli,
1133 &state->incoming_frag);
1134 if (tevent_req_nomem(subreq, req)) {
1137 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1140 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1142 struct tevent_req *req = tevent_req_callback_data(
1143 subreq, struct tevent_req);
1144 struct rpc_api_pipe_state *state = tevent_req_data(
1145 req, struct rpc_api_pipe_state);
1147 DATA_BLOB rdata = data_blob_null;
1149 status = get_complete_frag_recv(subreq);
1150 TALLOC_FREE(subreq);
1151 if (!NT_STATUS_IS_OK(status)) {
1152 DEBUG(5, ("get_complete_frag failed: %s\n",
1153 nt_errstr(status)));
1154 tevent_req_nterror(req, status);
1158 state->pkt = talloc(state, struct ncacn_packet);
1160 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1164 status = cli_pipe_validate_current_pdu(state,
1165 state->cli, state->pkt,
1166 &state->incoming_frag,
1167 state->expected_pkt_type,
1171 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1172 (unsigned)state->incoming_frag.length,
1173 (unsigned)state->reply_pdu_offset,
1174 nt_errstr(status)));
1176 if (!NT_STATUS_IS_OK(status)) {
1177 tevent_req_nterror(req, status);
1181 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1182 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
1184 * Set the data type correctly for big-endian data on the
1187 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1189 rpccli_pipe_txt(talloc_tos(), state->cli)));
1190 state->endianess = 0x00; /* BIG ENDIAN */
1193 * Check endianness on subsequent packets.
1195 if (state->endianess != state->pkt->drep[0]) {
1196 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1198 state->endianess?"little":"big",
1199 state->pkt->drep[0]?"little":"big"));
1200 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1204 /* Now copy the data portion out of the pdu into rbuf. */
1205 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1206 if (!data_blob_realloc(NULL, &state->reply_pdu,
1207 state->reply_pdu_offset + rdata.length)) {
1208 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1213 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1214 rdata.data, rdata.length);
1215 state->reply_pdu_offset += rdata.length;
1217 /* reset state->incoming_frag, there is no need to free it,
1218 * it will be reallocated to the right size the next time
1220 state->incoming_frag.length = 0;
1222 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1223 /* make sure the pdu length is right now that we
1224 * have all the data available (alloc hint may
1225 * have allocated more than was actually used) */
1226 state->reply_pdu.length = state->reply_pdu_offset;
1227 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1228 rpccli_pipe_txt(talloc_tos(), state->cli),
1229 (unsigned)state->reply_pdu.length));
1230 tevent_req_done(req);
1234 subreq = get_complete_frag_send(state, state->ev, state->cli,
1235 &state->incoming_frag);
1236 if (tevent_req_nomem(subreq, req)) {
1239 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1242 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1243 struct ncacn_packet **pkt,
1244 DATA_BLOB *reply_pdu)
1246 struct rpc_api_pipe_state *state = tevent_req_data(
1247 req, struct rpc_api_pipe_state);
1250 if (tevent_req_is_nterror(req, &status)) {
1254 /* return data to caller and assign it ownership of memory */
1256 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1257 reply_pdu->length = state->reply_pdu.length;
1258 state->reply_pdu.length = 0;
1260 data_blob_free(&state->reply_pdu);
1264 *pkt = talloc_steal(mem_ctx, state->pkt);
1267 return NT_STATUS_OK;
1270 /*******************************************************************
1271 Creates krb5 auth bind.
1272 ********************************************************************/
1274 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1275 enum dcerpc_AuthLevel auth_level,
1276 DATA_BLOB *auth_info)
1281 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1282 DATA_BLOB tkt = data_blob_null;
1283 DATA_BLOB tkt_wrapped = data_blob_null;
1285 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1286 a->service_principal ));
1288 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1290 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1291 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1294 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1296 a->service_principal,
1297 error_message(ret) ));
1299 data_blob_free(&tkt);
1300 return NT_STATUS_INVALID_PARAMETER;
1303 /* wrap that up in a nice GSS-API wrapping */
1304 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1306 data_blob_free(&tkt);
1308 status = dcerpc_push_dcerpc_auth(cli,
1309 DCERPC_AUTH_TYPE_KRB5,
1311 0, /* auth_pad_length */
1312 1, /* auth_context_id */
1315 if (!NT_STATUS_IS_OK(status)) {
1316 data_blob_free(&tkt_wrapped);
1320 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1321 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1323 return NT_STATUS_OK;
1325 return NT_STATUS_INVALID_PARAMETER;
1329 /*******************************************************************
1330 Creates SPNEGO NTLMSSP auth bind.
1331 ********************************************************************/
1333 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1334 enum dcerpc_AuthLevel auth_level,
1335 DATA_BLOB *auth_info)
1338 DATA_BLOB null_blob = data_blob_null;
1339 DATA_BLOB request = data_blob_null;
1340 DATA_BLOB spnego_msg = data_blob_null;
1342 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1343 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1347 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1348 data_blob_free(&request);
1352 /* Wrap this in SPNEGO. */
1353 spnego_msg = gen_negTokenInit(OID_NTLMSSP, request);
1355 data_blob_free(&request);
1357 status = dcerpc_push_dcerpc_auth(cli,
1358 DCERPC_AUTH_TYPE_SPNEGO,
1360 0, /* auth_pad_length */
1361 1, /* auth_context_id */
1364 if (!NT_STATUS_IS_OK(status)) {
1365 data_blob_free(&spnego_msg);
1369 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1370 dump_data(5, spnego_msg.data, spnego_msg.length);
1372 return NT_STATUS_OK;
1375 /*******************************************************************
1376 Creates NTLMSSP auth bind.
1377 ********************************************************************/
1379 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1380 enum dcerpc_AuthLevel auth_level,
1381 DATA_BLOB *auth_info)
1384 DATA_BLOB null_blob = data_blob_null;
1385 DATA_BLOB request = data_blob_null;
1387 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1388 status = ntlmssp_update(cli->auth->a_u.ntlmssp_state,
1392 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1393 data_blob_free(&request);
1397 status = dcerpc_push_dcerpc_auth(cli,
1398 DCERPC_AUTH_TYPE_NTLMSSP,
1400 0, /* auth_pad_length */
1401 1, /* auth_context_id */
1404 if (!NT_STATUS_IS_OK(status)) {
1405 data_blob_free(&request);
1409 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1410 dump_data(5, request.data, request.length);
1412 return NT_STATUS_OK;
1415 /*******************************************************************
1416 Creates schannel auth bind.
1417 ********************************************************************/
1419 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1420 enum dcerpc_AuthLevel auth_level,
1421 DATA_BLOB *auth_info)
1424 struct NL_AUTH_MESSAGE r;
1425 DATA_BLOB schannel_blob;
1427 /* Use lp_workgroup() if domain not specified */
1429 if (!cli->auth->domain || !cli->auth->domain[0]) {
1430 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1431 if (cli->auth->domain == NULL) {
1432 return NT_STATUS_NO_MEMORY;
1437 * Now marshall the data into the auth parse_struct.
1440 r.MessageType = NL_NEGOTIATE_REQUEST;
1441 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1442 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1443 r.oem_netbios_domain.a = cli->auth->domain;
1444 r.oem_netbios_computer.a = global_myname();
1446 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1447 if (!NT_STATUS_IS_OK(status)) {
1451 status = dcerpc_push_dcerpc_auth(cli,
1452 DCERPC_AUTH_TYPE_SCHANNEL,
1454 0, /* auth_pad_length */
1455 1, /* auth_context_id */
1458 if (!NT_STATUS_IS_OK(status)) {
1462 return NT_STATUS_OK;
1465 /*******************************************************************
1466 Creates the internals of a DCE/RPC bind request or alter context PDU.
1467 ********************************************************************/
1469 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1470 enum dcerpc_pkt_type ptype,
1472 const struct ndr_syntax_id *abstract,
1473 const struct ndr_syntax_id *transfer,
1474 const DATA_BLOB *auth_info,
1477 uint16 auth_len = auth_info->length;
1479 union dcerpc_payload u;
1480 struct dcerpc_ctx_list ctx_list;
1483 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1486 ctx_list.context_id = 0;
1487 ctx_list.num_transfer_syntaxes = 1;
1488 ctx_list.abstract_syntax = *abstract;
1489 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1491 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1492 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1493 u.bind.assoc_group_id = 0x0;
1494 u.bind.num_contexts = 1;
1495 u.bind.ctx_list = &ctx_list;
1496 u.bind.auth_info = *auth_info;
1498 status = dcerpc_push_ncacn_packet(mem_ctx,
1500 DCERPC_PFC_FLAG_FIRST |
1501 DCERPC_PFC_FLAG_LAST,
1506 if (!NT_STATUS_IS_OK(status)) {
1507 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1511 return NT_STATUS_OK;
1514 /*******************************************************************
1515 Creates a DCE/RPC bind request.
1516 ********************************************************************/
1518 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1519 struct rpc_pipe_client *cli,
1521 const struct ndr_syntax_id *abstract,
1522 const struct ndr_syntax_id *transfer,
1523 enum pipe_auth_type auth_type,
1524 enum dcerpc_AuthLevel auth_level,
1527 DATA_BLOB auth_info = data_blob_null;
1528 NTSTATUS ret = NT_STATUS_OK;
1530 switch (auth_type) {
1531 case PIPE_AUTH_TYPE_SCHANNEL:
1532 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
1533 if (!NT_STATUS_IS_OK(ret)) {
1538 case PIPE_AUTH_TYPE_NTLMSSP:
1539 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1540 if (!NT_STATUS_IS_OK(ret)) {
1545 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1546 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1547 if (!NT_STATUS_IS_OK(ret)) {
1552 case PIPE_AUTH_TYPE_KRB5:
1553 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
1554 if (!NT_STATUS_IS_OK(ret)) {
1559 case PIPE_AUTH_TYPE_NONE:
1563 /* "Can't" happen. */
1564 return NT_STATUS_INVALID_INFO_CLASS;
1567 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1577 /*******************************************************************
1578 Create and add the NTLMSSP sign/seal auth header and data.
1579 ********************************************************************/
1581 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1582 uint32 ss_padding_len,
1585 DATA_BLOB auth_info;
1587 DATA_BLOB auth_blob = data_blob_null;
1588 uint16_t data_and_pad_len = rpc_out->length - DCERPC_RESPONSE_LENGTH;
1590 if (!cli->auth->a_u.ntlmssp_state) {
1591 return NT_STATUS_INVALID_PARAMETER;
1594 /* marshall the dcerpc_auth with an actually empty auth_blob.
1595 * this is needed because the ntmlssp signature includes the
1597 status = dcerpc_push_dcerpc_auth(rpc_out->data,
1598 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1599 cli->auth->auth_level,
1601 1 /* context id. */,
1604 if (!NT_STATUS_IS_OK(status)) {
1608 /* append the header */
1609 if (!data_blob_append(NULL, rpc_out,
1610 auth_info.data, auth_info.length)) {
1611 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1612 (unsigned int)auth_info.length));
1613 return NT_STATUS_NO_MEMORY;
1615 data_blob_free(&auth_info);
1617 switch (cli->auth->auth_level) {
1618 case DCERPC_AUTH_LEVEL_PRIVACY:
1619 /* Data portion is encrypted. */
1620 status = ntlmssp_seal_packet(cli->auth->a_u.ntlmssp_state,
1623 + DCERPC_RESPONSE_LENGTH,
1628 if (!NT_STATUS_IS_OK(status)) {
1633 case DCERPC_AUTH_LEVEL_INTEGRITY:
1634 /* Data is signed. */
1635 status = ntlmssp_sign_packet(cli->auth->a_u.ntlmssp_state,
1638 + DCERPC_RESPONSE_LENGTH,
1643 if (!NT_STATUS_IS_OK(status)) {
1650 smb_panic("bad auth level");
1652 return NT_STATUS_INVALID_PARAMETER;
1655 /* Finally attach the blob. */
1656 if (!data_blob_append(NULL, rpc_out,
1657 auth_blob.data, auth_blob.length)) {
1658 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1659 (unsigned int)auth_info.length));
1660 return NT_STATUS_NO_MEMORY;
1662 data_blob_free(&auth_blob);
1664 return NT_STATUS_OK;
1667 /*******************************************************************
1668 Create and add the schannel sign/seal auth header and data.
1669 ********************************************************************/
1671 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1672 uint32 ss_padding_len,
1675 DATA_BLOB auth_info;
1676 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
1677 uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH;
1678 size_t data_and_pad_len = rpc_out->length
1679 - DCERPC_RESPONSE_LENGTH;
1684 return NT_STATUS_INVALID_PARAMETER;
1687 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1690 switch (cli->auth->auth_level) {
1691 case DCERPC_AUTH_LEVEL_PRIVACY:
1692 status = netsec_outgoing_packet(sas,
1699 case DCERPC_AUTH_LEVEL_INTEGRITY:
1700 status = netsec_outgoing_packet(sas,
1708 status = NT_STATUS_INTERNAL_ERROR;
1712 if (!NT_STATUS_IS_OK(status)) {
1713 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1714 nt_errstr(status)));
1718 if (DEBUGLEVEL >= 10) {
1719 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1722 /* Finally marshall the blob. */
1723 status = dcerpc_push_dcerpc_auth(rpc_out->data,
1724 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1725 cli->auth->auth_level,
1727 1 /* context id. */,
1730 if (!NT_STATUS_IS_OK(status)) {
1733 data_blob_free(&blob);
1735 if (!data_blob_append(NULL, rpc_out,
1736 auth_info.data, auth_info.length)) {
1737 return NT_STATUS_NO_MEMORY;
1739 data_blob_free(&auth_info);
1741 return NT_STATUS_OK;
1744 /*******************************************************************
1745 Calculate how much data we're going to send in this packet, also
1746 work out any sign/seal padding length.
1747 ********************************************************************/
1749 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1753 uint32 *p_ss_padding)
1755 uint32 data_space, data_len;
1758 if ((data_left > 0) && (sys_random() % 2)) {
1759 data_left = MAX(data_left/2, 1);
1763 switch (cli->auth->auth_level) {
1764 case DCERPC_AUTH_LEVEL_NONE:
1765 case DCERPC_AUTH_LEVEL_CONNECT:
1766 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1767 data_len = MIN(data_space, data_left);
1770 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1773 case DCERPC_AUTH_LEVEL_INTEGRITY:
1774 case DCERPC_AUTH_LEVEL_PRIVACY:
1775 /* Treat the same for all authenticated rpc requests. */
1776 switch(cli->auth->auth_type) {
1777 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1778 case PIPE_AUTH_TYPE_NTLMSSP:
1779 *p_auth_len = NTLMSSP_SIG_SIZE;
1781 case PIPE_AUTH_TYPE_SCHANNEL:
1782 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1785 smb_panic("bad auth type");
1789 data_space = cli->max_xmit_frag
1790 - DCERPC_REQUEST_LENGTH
1791 - DCERPC_AUTH_TRAILER_LENGTH
1794 data_len = MIN(data_space, data_left);
1796 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1797 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1799 *p_frag_len = DCERPC_REQUEST_LENGTH
1800 + data_len + *p_ss_padding
1801 + DCERPC_AUTH_TRAILER_LENGTH
1806 smb_panic("bad auth level");
1812 /*******************************************************************
1814 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1815 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1816 and deals with signing/sealing details.
1817 ********************************************************************/
1819 struct rpc_api_pipe_req_state {
1820 struct event_context *ev;
1821 struct rpc_pipe_client *cli;
1824 DATA_BLOB *req_data;
1825 uint32_t req_data_sent;
1827 DATA_BLOB reply_pdu;
1830 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1831 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1832 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1833 bool *is_last_frag);
1835 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1836 struct event_context *ev,
1837 struct rpc_pipe_client *cli,
1839 DATA_BLOB *req_data)
1841 struct tevent_req *req, *subreq;
1842 struct rpc_api_pipe_req_state *state;
1846 req = tevent_req_create(mem_ctx, &state,
1847 struct rpc_api_pipe_req_state);
1853 state->op_num = op_num;
1854 state->req_data = req_data;
1855 state->req_data_sent = 0;
1856 state->call_id = get_rpc_call_id();
1857 state->reply_pdu = data_blob_null;
1858 state->rpc_out = data_blob_null;
1860 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1861 + RPC_MAX_SIGN_SIZE) {
1862 /* Server is screwed up ! */
1863 status = NT_STATUS_INVALID_PARAMETER;
1867 status = prepare_next_frag(state, &is_last_frag);
1868 if (!NT_STATUS_IS_OK(status)) {
1873 subreq = rpc_api_pipe_send(state, ev, state->cli,
1875 DCERPC_PKT_RESPONSE);
1876 if (subreq == NULL) {
1879 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1881 subreq = rpc_write_send(state, ev, cli->transport,
1882 state->rpc_out.data,
1883 state->rpc_out.length);
1884 if (subreq == NULL) {
1887 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1893 tevent_req_nterror(req, status);
1894 return tevent_req_post(req, ev);
1900 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1903 uint32_t data_sent_thistime;
1907 uint32_t ss_padding;
1909 char pad[8] = { 0, };
1911 union dcerpc_payload u;
1913 data_left = state->req_data->length - state->req_data_sent;
1915 data_sent_thistime = calculate_data_len_tosend(
1916 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
1918 if (state->req_data_sent == 0) {
1919 flags = DCERPC_PFC_FLAG_FIRST;
1922 if (data_sent_thistime == data_left) {
1923 flags |= DCERPC_PFC_FLAG_LAST;
1926 data_blob_free(&state->rpc_out);
1928 ZERO_STRUCT(u.request);
1930 u.request.alloc_hint = state->req_data->length;
1931 u.request.context_id = 0;
1932 u.request.opnum = state->op_num;
1934 status = dcerpc_push_ncacn_packet(state,
1941 if (!NT_STATUS_IS_OK(status)) {
1945 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1946 * compute it right for requests */
1947 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1949 /* Copy in the data, plus any ss padding. */
1950 if (!data_blob_append(NULL, &state->rpc_out,
1951 state->req_data->data + state->req_data_sent,
1952 data_sent_thistime)) {
1953 return NT_STATUS_NO_MEMORY;
1957 /* Copy the sign/seal padding data. */
1958 if (!data_blob_append(NULL, &state->rpc_out,
1960 return NT_STATUS_NO_MEMORY;
1964 /* Generate any auth sign/seal and add the auth footer. */
1965 switch (state->cli->auth->auth_type) {
1966 case PIPE_AUTH_TYPE_NONE:
1967 status = NT_STATUS_OK;
1969 case PIPE_AUTH_TYPE_NTLMSSP:
1970 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1971 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
1974 case PIPE_AUTH_TYPE_SCHANNEL:
1975 status = add_schannel_auth_footer(state->cli, ss_padding,
1979 status = NT_STATUS_INVALID_PARAMETER;
1983 state->req_data_sent += data_sent_thistime;
1984 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1989 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1991 struct tevent_req *req = tevent_req_callback_data(
1992 subreq, struct tevent_req);
1993 struct rpc_api_pipe_req_state *state = tevent_req_data(
1994 req, struct rpc_api_pipe_req_state);
1998 status = rpc_write_recv(subreq);
1999 TALLOC_FREE(subreq);
2000 if (!NT_STATUS_IS_OK(status)) {
2001 tevent_req_nterror(req, status);
2005 status = prepare_next_frag(state, &is_last_frag);
2006 if (!NT_STATUS_IS_OK(status)) {
2007 tevent_req_nterror(req, status);
2012 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2014 DCERPC_PKT_RESPONSE);
2015 if (tevent_req_nomem(subreq, req)) {
2018 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2020 subreq = rpc_write_send(state, state->ev,
2021 state->cli->transport,
2022 state->rpc_out.data,
2023 state->rpc_out.length);
2024 if (tevent_req_nomem(subreq, req)) {
2027 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2032 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2034 struct tevent_req *req = tevent_req_callback_data(
2035 subreq, struct tevent_req);
2036 struct rpc_api_pipe_req_state *state = tevent_req_data(
2037 req, struct rpc_api_pipe_req_state);
2040 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
2041 TALLOC_FREE(subreq);
2042 if (!NT_STATUS_IS_OK(status)) {
2043 tevent_req_nterror(req, status);
2046 tevent_req_done(req);
2049 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2050 DATA_BLOB *reply_pdu)
2052 struct rpc_api_pipe_req_state *state = tevent_req_data(
2053 req, struct rpc_api_pipe_req_state);
2056 if (tevent_req_is_nterror(req, &status)) {
2058 * We always have to initialize to reply pdu, even if there is
2059 * none. The rpccli_* caller routines expect this.
2061 *reply_pdu = data_blob_null;
2065 /* return data to caller and assign it ownership of memory */
2066 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
2067 reply_pdu->length = state->reply_pdu.length;
2068 state->reply_pdu.length = 0;
2070 return NT_STATUS_OK;
2074 /****************************************************************************
2075 Set the handle state.
2076 ****************************************************************************/
2078 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2079 const char *pipe_name, uint16 device_state)
2081 bool state_set = False;
2083 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2084 char *rparam = NULL;
2086 uint32 rparam_len, rdata_len;
2088 if (pipe_name == NULL)
2091 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2092 cli->fnum, pipe_name, device_state));
2094 /* create parameters: device state */
2095 SSVAL(param, 0, device_state);
2097 /* create setup parameters. */
2099 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2101 /* send the data on \PIPE\ */
2102 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2103 setup, 2, 0, /* setup, length, max */
2104 param, 2, 0, /* param, length, max */
2105 NULL, 0, 1024, /* data, length, max */
2106 &rparam, &rparam_len, /* return param, length */
2107 &rdata, &rdata_len)) /* return data, length */
2109 DEBUG(5, ("Set Handle state: return OK\n"));
2120 /****************************************************************************
2121 Check the rpc bind acknowledge response.
2122 ****************************************************************************/
2124 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2125 const struct ndr_syntax_id *transfer)
2127 struct dcerpc_ack_ctx ctx;
2129 if (r->secondary_address_size == 0) {
2130 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2133 if (r->num_results < 1 || !r->ctx_list) {
2137 ctx = r->ctx_list[0];
2139 /* check the transfer syntax */
2140 if ((ctx.syntax.if_version != transfer->if_version) ||
2141 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2142 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2146 if (r->num_results != 0x1 || ctx.result != 0) {
2147 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2148 r->num_results, ctx.reason));
2151 DEBUG(5,("check_bind_response: accepted!\n"));
2155 /*******************************************************************
2156 Creates a DCE/RPC bind authentication response.
2157 This is the packet that is sent back to the server once we
2158 have received a BIND-ACK, to finish the third leg of
2159 the authentication handshake.
2160 ********************************************************************/
2162 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
2163 struct rpc_pipe_client *cli,
2165 enum pipe_auth_type auth_type,
2166 enum dcerpc_AuthLevel auth_level,
2167 DATA_BLOB *pauth_blob,
2171 union dcerpc_payload u;
2175 status = dcerpc_push_dcerpc_auth(mem_ctx,
2176 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2178 0, /* auth_pad_length */
2179 1, /* auth_context_id */
2181 &u.auth3.auth_info);
2182 if (!NT_STATUS_IS_OK(status)) {
2186 status = dcerpc_push_ncacn_packet(mem_ctx,
2188 DCERPC_PFC_FLAG_FIRST |
2189 DCERPC_PFC_FLAG_LAST,
2194 data_blob_free(&u.auth3.auth_info);
2195 if (!NT_STATUS_IS_OK(status)) {
2196 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2200 return NT_STATUS_OK;
2203 /*******************************************************************
2204 Creates a DCE/RPC bind alter context authentication request which
2205 may contain a spnego auth blobl
2206 ********************************************************************/
2208 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
2210 const struct ndr_syntax_id *abstract,
2211 const struct ndr_syntax_id *transfer,
2212 enum dcerpc_AuthLevel auth_level,
2213 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2216 DATA_BLOB auth_info;
2219 status = dcerpc_push_dcerpc_auth(mem_ctx,
2220 DCERPC_AUTH_TYPE_SPNEGO,
2222 0, /* auth_pad_length */
2223 1, /* auth_context_id */
2226 if (!NT_STATUS_IS_OK(status)) {
2230 status = create_bind_or_alt_ctx_internal(mem_ctx,
2237 data_blob_free(&auth_info);
2241 /****************************************************************************
2243 ****************************************************************************/
2245 struct rpc_pipe_bind_state {
2246 struct event_context *ev;
2247 struct rpc_pipe_client *cli;
2249 uint32_t rpc_call_id;
2252 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2253 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2254 struct rpc_pipe_bind_state *state,
2255 struct ncacn_packet *r);
2256 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2257 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2258 struct rpc_pipe_bind_state *state,
2259 struct ncacn_packet *r,
2260 DATA_BLOB *reply_pdu);
2261 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2263 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2264 struct event_context *ev,
2265 struct rpc_pipe_client *cli,
2266 struct cli_pipe_auth_data *auth)
2268 struct tevent_req *req, *subreq;
2269 struct rpc_pipe_bind_state *state;
2272 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2277 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2278 rpccli_pipe_txt(talloc_tos(), cli),
2279 (unsigned int)auth->auth_type,
2280 (unsigned int)auth->auth_level ));
2284 state->rpc_call_id = get_rpc_call_id();
2285 state->rpc_out = data_blob_null;
2287 cli->auth = talloc_move(cli, &auth);
2289 /* Marshall the outgoing data. */
2290 status = create_rpc_bind_req(state, cli,
2292 &cli->abstract_syntax,
2293 &cli->transfer_syntax,
2294 cli->auth->auth_type,
2295 cli->auth->auth_level,
2298 if (!NT_STATUS_IS_OK(status)) {
2302 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2303 DCERPC_PKT_BIND_ACK);
2304 if (subreq == NULL) {
2307 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2311 tevent_req_nterror(req, status);
2312 return tevent_req_post(req, ev);
2318 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2320 struct tevent_req *req = tevent_req_callback_data(
2321 subreq, struct tevent_req);
2322 struct rpc_pipe_bind_state *state = tevent_req_data(
2323 req, struct rpc_pipe_bind_state);
2324 DATA_BLOB reply_pdu;
2325 struct ncacn_packet *pkt;
2328 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
2329 TALLOC_FREE(subreq);
2330 if (!NT_STATUS_IS_OK(status)) {
2331 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2332 rpccli_pipe_txt(talloc_tos(), state->cli),
2333 nt_errstr(status)));
2334 tevent_req_nterror(req, status);
2338 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
2339 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2340 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2344 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
2345 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
2348 * For authenticated binds we may need to do 3 or 4 leg binds.
2351 switch(state->cli->auth->auth_type) {
2353 case PIPE_AUTH_TYPE_NONE:
2354 case PIPE_AUTH_TYPE_SCHANNEL:
2355 /* Bind complete. */
2356 tevent_req_done(req);
2359 case PIPE_AUTH_TYPE_NTLMSSP:
2360 /* Need to send AUTH3 packet - no reply. */
2361 status = rpc_finish_auth3_bind_send(req, state, pkt);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 tevent_req_nterror(req, status);
2367 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2368 /* Need to send alter context request and reply. */
2369 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt,
2371 if (!NT_STATUS_IS_OK(status)) {
2372 tevent_req_nterror(req, status);
2376 case PIPE_AUTH_TYPE_KRB5:
2380 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2381 (unsigned int)state->cli->auth->auth_type));
2382 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2386 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2387 struct rpc_pipe_bind_state *state,
2388 struct ncacn_packet *r)
2390 DATA_BLOB client_reply = data_blob_null;
2391 struct dcerpc_auth auth;
2392 struct tevent_req *subreq;
2395 if ((r->auth_length == 0)
2396 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2397 + r->auth_length)) {
2398 return NT_STATUS_INVALID_PARAMETER;
2401 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
2402 &r->u.bind_ack.auth_info,
2404 if (!NT_STATUS_IS_OK(status)) {
2405 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2406 nt_errstr(status)));
2410 /* TODO - check auth_type/auth_level match. */
2412 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2413 auth.credentials, &client_reply);
2415 if (!NT_STATUS_IS_OK(status)) {
2416 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2417 "blob failed: %s.\n", nt_errstr(status)));
2421 data_blob_free(&state->rpc_out);
2423 status = create_rpc_bind_auth3(state,
2424 state->cli, state->rpc_call_id,
2425 state->cli->auth->auth_type,
2426 state->cli->auth->auth_level,
2427 &client_reply, &state->rpc_out);
2428 data_blob_free(&client_reply);
2430 if (!NT_STATUS_IS_OK(status)) {
2434 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2435 state->rpc_out.data, state->rpc_out.length);
2436 if (subreq == NULL) {
2437 return NT_STATUS_NO_MEMORY;
2439 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2440 return NT_STATUS_OK;
2443 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2445 struct tevent_req *req = tevent_req_callback_data(
2446 subreq, struct tevent_req);
2449 status = rpc_write_recv(subreq);
2450 TALLOC_FREE(subreq);
2451 if (!NT_STATUS_IS_OK(status)) {
2452 tevent_req_nterror(req, status);
2455 tevent_req_done(req);
2458 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2459 struct rpc_pipe_bind_state *state,
2460 struct ncacn_packet *r,
2461 DATA_BLOB *reply_pdu)
2463 DATA_BLOB server_ntlm_response = data_blob_null;
2464 DATA_BLOB client_reply = data_blob_null;
2465 DATA_BLOB tmp_blob = data_blob_null;
2466 struct dcerpc_auth auth_info;
2467 DATA_BLOB auth_blob;
2468 struct tevent_req *subreq;
2471 if ((r->auth_length == 0)
2472 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2473 + r->auth_length)) {
2474 return NT_STATUS_INVALID_PARAMETER;
2477 /* Process the returned NTLMSSP blob first. */
2478 auth_blob = data_blob_const(reply_pdu->data
2480 - DCERPC_AUTH_TRAILER_LENGTH
2482 DCERPC_AUTH_TRAILER_LENGTH
2485 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info, false);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
2492 * The server might give us back two challenges - tmp_blob is for the
2495 if (!spnego_parse_challenge(auth_info.credentials,
2496 &server_ntlm_response, &tmp_blob)) {
2497 data_blob_free(&server_ntlm_response);
2498 data_blob_free(&tmp_blob);
2499 return NT_STATUS_INVALID_PARAMETER;
2502 /* We're finished with the server spnego response and the tmp_blob. */
2503 data_blob_free(&tmp_blob);
2505 status = ntlmssp_update(state->cli->auth->a_u.ntlmssp_state,
2506 server_ntlm_response, &client_reply);
2508 /* Finished with the server_ntlm response */
2509 data_blob_free(&server_ntlm_response);
2511 if (!NT_STATUS_IS_OK(status)) {
2512 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2513 "using server blob failed.\n"));
2514 data_blob_free(&client_reply);
2518 /* SPNEGO wrap the client reply. */
2519 tmp_blob = spnego_gen_auth(client_reply);
2520 data_blob_free(&client_reply);
2521 client_reply = tmp_blob;
2522 tmp_blob = data_blob_null;
2524 /* Now prepare the alter context pdu. */
2525 data_blob_free(&state->rpc_out);
2527 status = create_rpc_alter_context(state,
2529 &state->cli->abstract_syntax,
2530 &state->cli->transfer_syntax,
2531 state->cli->auth->auth_level,
2534 data_blob_free(&client_reply);
2536 if (!NT_STATUS_IS_OK(status)) {
2540 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2541 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2542 if (subreq == NULL) {
2543 return NT_STATUS_NO_MEMORY;
2545 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2546 return NT_STATUS_OK;
2549 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2551 struct tevent_req *req = tevent_req_callback_data(
2552 subreq, struct tevent_req);
2553 struct rpc_pipe_bind_state *state = tevent_req_data(
2554 req, struct rpc_pipe_bind_state);
2555 DATA_BLOB tmp_blob = data_blob_null;
2556 struct ncacn_packet *pkt;
2557 struct dcerpc_auth auth;
2560 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2561 TALLOC_FREE(subreq);
2562 if (!NT_STATUS_IS_OK(status)) {
2563 tevent_req_nterror(req, status);
2567 status = dcerpc_pull_dcerpc_auth(pkt,
2568 &pkt->u.alter_resp.auth_info,
2570 if (!NT_STATUS_IS_OK(status)) {
2571 tevent_req_nterror(req, status);
2575 /* Check we got a valid auth response. */
2576 if (!spnego_parse_auth_response(auth.credentials,
2578 OID_NTLMSSP, &tmp_blob)) {
2579 data_blob_free(&tmp_blob);
2580 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2584 data_blob_free(&tmp_blob);
2586 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2587 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2588 tevent_req_done(req);
2591 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2593 return tevent_req_simple_recv_ntstatus(req);
2596 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2597 struct cli_pipe_auth_data *auth)
2599 TALLOC_CTX *frame = talloc_stackframe();
2600 struct event_context *ev;
2601 struct tevent_req *req;
2602 NTSTATUS status = NT_STATUS_OK;
2604 ev = event_context_init(frame);
2606 status = NT_STATUS_NO_MEMORY;
2610 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2612 status = NT_STATUS_NO_MEMORY;
2616 if (!tevent_req_poll(req, ev)) {
2617 status = map_nt_error_from_unix(errno);
2621 status = rpc_pipe_bind_recv(req);
2627 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2629 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2630 unsigned int timeout)
2634 if (rpc_cli->transport == NULL) {
2635 return RPCCLI_DEFAULT_TIMEOUT;
2638 if (rpc_cli->transport->set_timeout == NULL) {
2639 return RPCCLI_DEFAULT_TIMEOUT;
2642 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2644 return RPCCLI_DEFAULT_TIMEOUT;
2650 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2652 if (rpc_cli == NULL) {
2656 if (rpc_cli->transport == NULL) {
2660 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2663 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2665 struct cli_state *cli;
2667 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2668 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2669 memcpy(nt_hash, rpc_cli->auth->a_u.ntlmssp_state->nt_hash, 16);
2673 cli = rpc_pipe_np_smb_conn(rpc_cli);
2677 E_md4hash(cli->password ? cli->password : "", nt_hash);
2681 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2682 struct cli_pipe_auth_data **presult)
2684 struct cli_pipe_auth_data *result;
2686 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2687 if (result == NULL) {
2688 return NT_STATUS_NO_MEMORY;
2691 result->auth_type = PIPE_AUTH_TYPE_NONE;
2692 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2694 result->user_name = talloc_strdup(result, "");
2695 result->domain = talloc_strdup(result, "");
2696 if ((result->user_name == NULL) || (result->domain == NULL)) {
2697 TALLOC_FREE(result);
2698 return NT_STATUS_NO_MEMORY;
2702 return NT_STATUS_OK;
2705 static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth)
2707 TALLOC_FREE(auth->a_u.ntlmssp_state);
2711 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2712 enum pipe_auth_type auth_type,
2713 enum dcerpc_AuthLevel auth_level,
2715 const char *username,
2716 const char *password,
2717 struct cli_pipe_auth_data **presult)
2719 struct cli_pipe_auth_data *result;
2722 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2723 if (result == NULL) {
2724 return NT_STATUS_NO_MEMORY;
2727 result->auth_type = auth_type;
2728 result->auth_level = auth_level;
2730 result->user_name = talloc_strdup(result, username);
2731 result->domain = talloc_strdup(result, domain);
2732 if ((result->user_name == NULL) || (result->domain == NULL)) {
2733 status = NT_STATUS_NO_MEMORY;
2737 status = ntlmssp_client_start(NULL,
2740 lp_client_ntlmv2_auth(),
2741 &result->a_u.ntlmssp_state);
2742 if (!NT_STATUS_IS_OK(status)) {
2746 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2748 status = ntlmssp_set_username(result->a_u.ntlmssp_state, username);
2749 if (!NT_STATUS_IS_OK(status)) {
2753 status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain);
2754 if (!NT_STATUS_IS_OK(status)) {
2758 status = ntlmssp_set_password(result->a_u.ntlmssp_state, password);
2759 if (!NT_STATUS_IS_OK(status)) {
2764 * Turn off sign+seal to allow selected auth level to turn it back on.
2766 result->a_u.ntlmssp_state->neg_flags &=
2767 ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL);
2769 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2770 result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
2771 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2772 result->a_u.ntlmssp_state->neg_flags
2773 |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN;
2777 return NT_STATUS_OK;
2780 TALLOC_FREE(result);
2784 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2785 enum dcerpc_AuthLevel auth_level,
2786 struct netlogon_creds_CredentialState *creds,
2787 struct cli_pipe_auth_data **presult)
2789 struct cli_pipe_auth_data *result;
2791 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2792 if (result == NULL) {
2793 return NT_STATUS_NO_MEMORY;
2796 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2797 result->auth_level = auth_level;
2799 result->user_name = talloc_strdup(result, "");
2800 result->domain = talloc_strdup(result, domain);
2801 if ((result->user_name == NULL) || (result->domain == NULL)) {
2805 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2806 if (result->a_u.schannel_auth == NULL) {
2810 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2811 result->a_u.schannel_auth->seq_num = 0;
2812 result->a_u.schannel_auth->initiator = true;
2813 result->a_u.schannel_auth->creds = creds;
2816 return NT_STATUS_OK;
2819 TALLOC_FREE(result);
2820 return NT_STATUS_NO_MEMORY;
2824 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2826 data_blob_free(&auth->session_key);
2831 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2832 enum dcerpc_AuthLevel auth_level,
2833 const char *service_princ,
2834 const char *username,
2835 const char *password,
2836 struct cli_pipe_auth_data **presult)
2839 struct cli_pipe_auth_data *result;
2841 if ((username != NULL) && (password != NULL)) {
2842 int ret = kerberos_kinit_password(username, password, 0, NULL);
2844 return NT_STATUS_ACCESS_DENIED;
2848 result = talloc(mem_ctx, struct cli_pipe_auth_data);
2849 if (result == NULL) {
2850 return NT_STATUS_NO_MEMORY;
2853 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2854 result->auth_level = auth_level;
2857 * Username / domain need fixing!
2859 result->user_name = talloc_strdup(result, "");
2860 result->domain = talloc_strdup(result, "");
2861 if ((result->user_name == NULL) || (result->domain == NULL)) {
2865 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2866 result, struct kerberos_auth_struct);
2867 if (result->a_u.kerberos_auth == NULL) {
2870 talloc_set_destructor(result->a_u.kerberos_auth,
2871 cli_auth_kerberos_data_destructor);
2873 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2874 result, service_princ);
2875 if (result->a_u.kerberos_auth->service_principal == NULL) {
2880 return NT_STATUS_OK;
2883 TALLOC_FREE(result);
2884 return NT_STATUS_NO_MEMORY;
2886 return NT_STATUS_NOT_SUPPORTED;
2891 * Create an rpc pipe client struct, connecting to a tcp port.
2893 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2895 const struct ndr_syntax_id *abstract_syntax,
2896 struct rpc_pipe_client **presult)
2898 struct rpc_pipe_client *result;
2899 struct sockaddr_storage addr;
2903 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2904 if (result == NULL) {
2905 return NT_STATUS_NO_MEMORY;
2908 result->abstract_syntax = *abstract_syntax;
2909 result->transfer_syntax = ndr_transfer_syntax;
2910 result->dispatch = cli_do_rpc_ndr;
2911 result->dispatch_send = cli_do_rpc_ndr_send;
2912 result->dispatch_recv = cli_do_rpc_ndr_recv;
2914 result->desthost = talloc_strdup(result, host);
2915 result->srv_name_slash = talloc_asprintf_strupper_m(
2916 result, "\\\\%s", result->desthost);
2917 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2918 status = NT_STATUS_NO_MEMORY;
2922 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2923 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2925 if (!resolve_name(host, &addr, 0, false)) {
2926 status = NT_STATUS_NOT_FOUND;
2930 status = open_socket_out(&addr, port, 60, &fd);
2931 if (!NT_STATUS_IS_OK(status)) {
2934 set_socket_options(fd, lp_socket_options());
2936 status = rpc_transport_sock_init(result, fd, &result->transport);
2937 if (!NT_STATUS_IS_OK(status)) {
2942 result->transport->transport = NCACN_IP_TCP;
2945 return NT_STATUS_OK;
2948 TALLOC_FREE(result);
2953 * Determine the tcp port on which a dcerpc interface is listening
2954 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2957 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2958 const struct ndr_syntax_id *abstract_syntax,
2962 struct rpc_pipe_client *epm_pipe = NULL;
2963 struct cli_pipe_auth_data *auth = NULL;
2964 struct dcerpc_binding *map_binding = NULL;
2965 struct dcerpc_binding *res_binding = NULL;
2966 struct epm_twr_t *map_tower = NULL;
2967 struct epm_twr_t *res_towers = NULL;
2968 struct policy_handle *entry_handle = NULL;
2969 uint32_t num_towers = 0;
2970 uint32_t max_towers = 1;
2971 struct epm_twr_p_t towers;
2972 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2974 if (pport == NULL) {
2975 status = NT_STATUS_INVALID_PARAMETER;
2979 /* open the connection to the endpoint mapper */
2980 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2981 &ndr_table_epmapper.syntax_id,
2984 if (!NT_STATUS_IS_OK(status)) {
2988 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2989 if (!NT_STATUS_IS_OK(status)) {
2993 status = rpc_pipe_bind(epm_pipe, auth);
2994 if (!NT_STATUS_IS_OK(status)) {
2998 /* create tower for asking the epmapper */
3000 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3001 if (map_binding == NULL) {
3002 status = NT_STATUS_NO_MEMORY;
3006 map_binding->transport = NCACN_IP_TCP;
3007 map_binding->object = *abstract_syntax;
3008 map_binding->host = host; /* needed? */
3009 map_binding->endpoint = "0"; /* correct? needed? */
3011 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3012 if (map_tower == NULL) {
3013 status = NT_STATUS_NO_MEMORY;
3017 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3018 &(map_tower->tower));
3019 if (!NT_STATUS_IS_OK(status)) {
3023 /* allocate further parameters for the epm_Map call */
3025 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3026 if (res_towers == NULL) {
3027 status = NT_STATUS_NO_MEMORY;
3030 towers.twr = res_towers;
3032 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3033 if (entry_handle == NULL) {
3034 status = NT_STATUS_NO_MEMORY;
3038 /* ask the endpoint mapper for the port */
3040 status = rpccli_epm_Map(epm_pipe,
3042 CONST_DISCARD(struct GUID *,
3043 &(abstract_syntax->uuid)),
3050 if (!NT_STATUS_IS_OK(status)) {
3054 if (num_towers != 1) {
3055 status = NT_STATUS_UNSUCCESSFUL;
3059 /* extract the port from the answer */
3061 status = dcerpc_binding_from_tower(tmp_ctx,
3062 &(towers.twr->tower),
3064 if (!NT_STATUS_IS_OK(status)) {
3068 /* are further checks here necessary? */
3069 if (res_binding->transport != NCACN_IP_TCP) {
3070 status = NT_STATUS_UNSUCCESSFUL;
3074 *pport = (uint16_t)atoi(res_binding->endpoint);
3077 TALLOC_FREE(tmp_ctx);
3082 * Create a rpc pipe client struct, connecting to a host via tcp.
3083 * The port is determined by asking the endpoint mapper on the given
3086 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3087 const struct ndr_syntax_id *abstract_syntax,
3088 struct rpc_pipe_client **presult)
3093 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3094 if (!NT_STATUS_IS_OK(status)) {
3098 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3099 abstract_syntax, presult);
3102 /********************************************************************
3103 Create a rpc pipe client struct, connecting to a unix domain socket
3104 ********************************************************************/
3105 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3106 const struct ndr_syntax_id *abstract_syntax,
3107 struct rpc_pipe_client **presult)
3109 struct rpc_pipe_client *result;
3110 struct sockaddr_un addr;
3114 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3115 if (result == NULL) {
3116 return NT_STATUS_NO_MEMORY;
3119 result->abstract_syntax = *abstract_syntax;
3120 result->transfer_syntax = ndr_transfer_syntax;
3121 result->dispatch = cli_do_rpc_ndr;
3122 result->dispatch_send = cli_do_rpc_ndr_send;
3123 result->dispatch_recv = cli_do_rpc_ndr_recv;
3125 result->desthost = get_myname(result);
3126 result->srv_name_slash = talloc_asprintf_strupper_m(
3127 result, "\\\\%s", result->desthost);
3128 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3129 status = NT_STATUS_NO_MEMORY;
3133 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3134 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3136 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3138 status = map_nt_error_from_unix(errno);
3143 addr.sun_family = AF_UNIX;
3144 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3146 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3147 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3150 return map_nt_error_from_unix(errno);
3153 status = rpc_transport_sock_init(result, fd, &result->transport);
3154 if (!NT_STATUS_IS_OK(status)) {
3159 result->transport->transport = NCALRPC;
3162 return NT_STATUS_OK;
3165 TALLOC_FREE(result);
3169 struct rpc_pipe_client_np_ref {
3170 struct cli_state *cli;
3171 struct rpc_pipe_client *pipe;
3174 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3176 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3180 /****************************************************************************
3181 Open a named pipe over SMB to a remote server.
3183 * CAVEAT CALLER OF THIS FUNCTION:
3184 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3185 * so be sure that this function is called AFTER any structure (vs pointer)
3186 * assignment of the cli. In particular, libsmbclient does structure
3187 * assignments of cli, which invalidates the data in the returned
3188 * rpc_pipe_client if this function is called before the structure assignment
3191 ****************************************************************************/
3193 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3194 const struct ndr_syntax_id *abstract_syntax,
3195 struct rpc_pipe_client **presult)
3197 struct rpc_pipe_client *result;
3199 struct rpc_pipe_client_np_ref *np_ref;
3201 /* sanity check to protect against crashes */
3204 return NT_STATUS_INVALID_HANDLE;
3207 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3208 if (result == NULL) {
3209 return NT_STATUS_NO_MEMORY;
3212 result->abstract_syntax = *abstract_syntax;
3213 result->transfer_syntax = ndr_transfer_syntax;
3214 result->dispatch = cli_do_rpc_ndr;
3215 result->dispatch_send = cli_do_rpc_ndr_send;
3216 result->dispatch_recv = cli_do_rpc_ndr_recv;
3217 result->desthost = talloc_strdup(result, cli->desthost);
3218 result->srv_name_slash = talloc_asprintf_strupper_m(
3219 result, "\\\\%s", result->desthost);
3221 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3222 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3224 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3225 TALLOC_FREE(result);
3226 return NT_STATUS_NO_MEMORY;
3229 status = rpc_transport_np_init(result, cli, abstract_syntax,
3230 &result->transport);
3231 if (!NT_STATUS_IS_OK(status)) {
3232 TALLOC_FREE(result);
3236 result->transport->transport = NCACN_NP;
3238 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3239 if (np_ref == NULL) {
3240 TALLOC_FREE(result);
3241 return NT_STATUS_NO_MEMORY;
3244 np_ref->pipe = result;
3246 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3247 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3250 return NT_STATUS_OK;
3253 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3254 struct rpc_cli_smbd_conn *conn,
3255 const struct ndr_syntax_id *syntax,
3256 struct rpc_pipe_client **presult)
3258 struct rpc_pipe_client *result;
3259 struct cli_pipe_auth_data *auth;
3262 result = talloc(mem_ctx, struct rpc_pipe_client);
3263 if (result == NULL) {
3264 return NT_STATUS_NO_MEMORY;
3266 result->abstract_syntax = *syntax;
3267 result->transfer_syntax = ndr_transfer_syntax;
3268 result->dispatch = cli_do_rpc_ndr;
3269 result->dispatch_send = cli_do_rpc_ndr_send;
3270 result->dispatch_recv = cli_do_rpc_ndr_recv;
3271 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3272 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3274 result->desthost = talloc_strdup(result, global_myname());
3275 result->srv_name_slash = talloc_asprintf_strupper_m(
3276 result, "\\\\%s", global_myname());
3277 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3278 TALLOC_FREE(result);
3279 return NT_STATUS_NO_MEMORY;
3282 status = rpc_transport_smbd_init(result, conn, syntax,
3283 &result->transport);
3284 if (!NT_STATUS_IS_OK(status)) {
3285 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3286 nt_errstr(status)));
3287 TALLOC_FREE(result);
3291 status = rpccli_anon_bind_data(result, &auth);
3292 if (!NT_STATUS_IS_OK(status)) {
3293 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3294 nt_errstr(status)));
3295 TALLOC_FREE(result);
3299 status = rpc_pipe_bind(result, auth);
3300 if (!NT_STATUS_IS_OK(status)) {
3301 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3302 TALLOC_FREE(result);
3306 result->transport->transport = NCACN_INTERNAL;
3309 return NT_STATUS_OK;
3312 /****************************************************************************
3313 Open a pipe to a remote server.
3314 ****************************************************************************/
3316 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3317 enum dcerpc_transport_t transport,
3318 const struct ndr_syntax_id *interface,
3319 struct rpc_pipe_client **presult)
3321 switch (transport) {
3323 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3326 return rpc_pipe_open_np(cli, interface, presult);
3328 return NT_STATUS_NOT_IMPLEMENTED;
3332 /****************************************************************************
3333 Open a named pipe to an SMB server and bind anonymously.
3334 ****************************************************************************/
3336 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3337 enum dcerpc_transport_t transport,
3338 const struct ndr_syntax_id *interface,
3339 struct rpc_pipe_client **presult)
3341 struct rpc_pipe_client *result;
3342 struct cli_pipe_auth_data *auth;
3345 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3346 if (!NT_STATUS_IS_OK(status)) {
3350 status = rpccli_anon_bind_data(result, &auth);
3351 if (!NT_STATUS_IS_OK(status)) {
3352 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3353 nt_errstr(status)));
3354 TALLOC_FREE(result);
3359 * This is a bit of an abstraction violation due to the fact that an
3360 * anonymous bind on an authenticated SMB inherits the user/domain
3361 * from the enclosing SMB creds
3364 TALLOC_FREE(auth->user_name);
3365 TALLOC_FREE(auth->domain);
3367 auth->user_name = talloc_strdup(auth, cli->user_name);
3368 auth->domain = talloc_strdup(auth, cli->domain);
3369 auth->user_session_key = data_blob_talloc(auth,
3370 cli->user_session_key.data,
3371 cli->user_session_key.length);
3373 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3374 TALLOC_FREE(result);
3375 return NT_STATUS_NO_MEMORY;
3378 status = rpc_pipe_bind(result, auth);
3379 if (!NT_STATUS_IS_OK(status)) {
3381 if (ndr_syntax_id_equal(interface,
3382 &ndr_table_dssetup.syntax_id)) {
3383 /* non AD domains just don't have this pipe, avoid
3384 * level 0 statement in that case - gd */
3387 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3388 "%s failed with error %s\n",
3389 get_pipe_name_from_syntax(talloc_tos(), interface),
3390 nt_errstr(status) ));
3391 TALLOC_FREE(result);
3395 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3396 "%s and bound anonymously.\n",
3397 get_pipe_name_from_syntax(talloc_tos(), interface),
3401 return NT_STATUS_OK;
3404 /****************************************************************************
3405 ****************************************************************************/
3407 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3408 const struct ndr_syntax_id *interface,
3409 struct rpc_pipe_client **presult)
3411 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3412 interface, presult);
3415 /****************************************************************************
3416 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3417 ****************************************************************************/
3419 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3420 const struct ndr_syntax_id *interface,
3421 enum dcerpc_transport_t transport,
3422 enum pipe_auth_type auth_type,
3423 enum dcerpc_AuthLevel auth_level,
3425 const char *username,
3426 const char *password,
3427 struct rpc_pipe_client **presult)
3429 struct rpc_pipe_client *result;
3430 struct cli_pipe_auth_data *auth;
3433 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3434 if (!NT_STATUS_IS_OK(status)) {
3438 status = rpccli_ntlmssp_bind_data(
3439 result, auth_type, auth_level, domain, username,
3441 if (!NT_STATUS_IS_OK(status)) {
3442 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3443 nt_errstr(status)));
3447 status = rpc_pipe_bind(result, auth);
3448 if (!NT_STATUS_IS_OK(status)) {
3449 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3450 nt_errstr(status) ));
3454 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3455 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3456 get_pipe_name_from_syntax(talloc_tos(), interface),
3457 cli->desthost, domain, username ));
3460 return NT_STATUS_OK;
3464 TALLOC_FREE(result);
3468 /****************************************************************************
3470 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3471 ****************************************************************************/
3473 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3474 const struct ndr_syntax_id *interface,
3475 enum dcerpc_transport_t transport,
3476 enum dcerpc_AuthLevel auth_level,
3478 const char *username,
3479 const char *password,
3480 struct rpc_pipe_client **presult)
3482 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3485 PIPE_AUTH_TYPE_NTLMSSP,
3493 /****************************************************************************
3495 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3496 ****************************************************************************/
3498 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3499 const struct ndr_syntax_id *interface,
3500 enum dcerpc_transport_t transport,
3501 enum dcerpc_AuthLevel auth_level,
3503 const char *username,
3504 const char *password,
3505 struct rpc_pipe_client **presult)
3507 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3510 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3518 /****************************************************************************
3519 Get a the schannel session key out of an already opened netlogon pipe.
3520 ****************************************************************************/
3521 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3522 struct cli_state *cli,
3526 enum netr_SchannelType sec_chan_type = 0;
3527 unsigned char machine_pwd[16];
3528 const char *machine_account;
3531 /* Get the machine account credentials from secrets.tdb. */
3532 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3535 DEBUG(0, ("get_schannel_session_key: could not fetch "
3536 "trust account password for domain '%s'\n",
3538 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3541 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3542 cli->desthost, /* server name */
3543 domain, /* domain */
3544 global_myname(), /* client name */
3545 machine_account, /* machine account name */
3550 if (!NT_STATUS_IS_OK(status)) {
3551 DEBUG(3, ("get_schannel_session_key_common: "
3552 "rpccli_netlogon_setup_creds failed with result %s "
3553 "to server %s, domain %s, machine account %s.\n",
3554 nt_errstr(status), cli->desthost, domain,
3559 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3560 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3562 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3565 return NT_STATUS_OK;;
3568 /****************************************************************************
3569 Open a netlogon pipe and get the schannel session key.
3570 Now exposed to external callers.
3571 ****************************************************************************/
3574 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3577 struct rpc_pipe_client **presult)
3579 struct rpc_pipe_client *netlogon_pipe = NULL;
3582 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3584 if (!NT_STATUS_IS_OK(status)) {
3588 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3590 if (!NT_STATUS_IS_OK(status)) {
3591 TALLOC_FREE(netlogon_pipe);
3595 *presult = netlogon_pipe;
3596 return NT_STATUS_OK;
3599 /****************************************************************************
3601 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3602 using session_key. sign and seal.
3604 The *pdc will be stolen onto this new pipe
3605 ****************************************************************************/
3607 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3608 const struct ndr_syntax_id *interface,
3609 enum dcerpc_transport_t transport,
3610 enum dcerpc_AuthLevel auth_level,
3612 struct netlogon_creds_CredentialState **pdc,
3613 struct rpc_pipe_client **presult)
3615 struct rpc_pipe_client *result;
3616 struct cli_pipe_auth_data *auth;
3619 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3620 if (!NT_STATUS_IS_OK(status)) {
3624 status = rpccli_schannel_bind_data(result, domain, auth_level,
3626 if (!NT_STATUS_IS_OK(status)) {
3627 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3628 nt_errstr(status)));
3629 TALLOC_FREE(result);
3633 status = rpc_pipe_bind(result, auth);
3634 if (!NT_STATUS_IS_OK(status)) {
3635 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3636 "cli_rpc_pipe_bind failed with error %s\n",
3637 nt_errstr(status) ));
3638 TALLOC_FREE(result);
3643 * The credentials on a new netlogon pipe are the ones we are passed
3644 * in - reference them in
3646 result->dc = talloc_move(result, pdc);
3648 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3649 "for domain %s and bound using schannel.\n",
3650 get_pipe_name_from_syntax(talloc_tos(), interface),
3651 cli->desthost, domain ));
3654 return NT_STATUS_OK;
3657 /****************************************************************************
3658 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3659 Fetch the session key ourselves using a temporary netlogon pipe. This
3660 version uses an ntlmssp auth bound netlogon pipe to get the key.
3661 ****************************************************************************/
3663 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3665 const char *username,
3666 const char *password,
3668 struct rpc_pipe_client **presult)
3670 struct rpc_pipe_client *netlogon_pipe = NULL;
3673 status = cli_rpc_pipe_open_spnego_ntlmssp(
3674 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3675 DCERPC_AUTH_LEVEL_PRIVACY,
3676 domain, username, password, &netlogon_pipe);
3677 if (!NT_STATUS_IS_OK(status)) {
3681 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3683 if (!NT_STATUS_IS_OK(status)) {
3684 TALLOC_FREE(netlogon_pipe);
3688 *presult = netlogon_pipe;
3689 return NT_STATUS_OK;
3692 /****************************************************************************
3693 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3694 Fetch the session key ourselves using a temporary netlogon pipe. This version
3695 uses an ntlmssp bind to get the session key.
3696 ****************************************************************************/
3698 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3699 const struct ndr_syntax_id *interface,
3700 enum dcerpc_transport_t transport,
3701 enum dcerpc_AuthLevel auth_level,
3703 const char *username,
3704 const char *password,
3705 struct rpc_pipe_client **presult)
3707 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3708 struct rpc_pipe_client *netlogon_pipe = NULL;
3709 struct rpc_pipe_client *result = NULL;
3712 status = get_schannel_session_key_auth_ntlmssp(
3713 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3714 if (!NT_STATUS_IS_OK(status)) {
3715 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3716 "key from server %s for domain %s.\n",
3717 cli->desthost, domain ));
3721 status = cli_rpc_pipe_open_schannel_with_key(
3722 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3725 /* Now we've bound using the session key we can close the netlog pipe. */
3726 TALLOC_FREE(netlogon_pipe);
3728 if (NT_STATUS_IS_OK(status)) {
3734 /****************************************************************************
3735 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3736 Fetch the session key ourselves using a temporary netlogon pipe.
3737 ****************************************************************************/
3739 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3740 const struct ndr_syntax_id *interface,
3741 enum dcerpc_transport_t transport,
3742 enum dcerpc_AuthLevel auth_level,
3744 struct rpc_pipe_client **presult)
3746 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3747 struct rpc_pipe_client *netlogon_pipe = NULL;
3748 struct rpc_pipe_client *result = NULL;
3751 status = get_schannel_session_key(cli, domain, &neg_flags,
3753 if (!NT_STATUS_IS_OK(status)) {
3754 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3755 "key from server %s for domain %s.\n",
3756 cli->desthost, domain ));
3760 status = cli_rpc_pipe_open_schannel_with_key(
3761 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3764 /* Now we've bound using the session key we can close the netlog pipe. */
3765 TALLOC_FREE(netlogon_pipe);
3767 if (NT_STATUS_IS_OK(status)) {
3774 /****************************************************************************
3775 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3776 The idea is this can be called with service_princ, username and password all
3777 NULL so long as the caller has a TGT.
3778 ****************************************************************************/
3780 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3781 const struct ndr_syntax_id *interface,
3782 enum dcerpc_AuthLevel auth_level,
3783 const char *service_princ,
3784 const char *username,
3785 const char *password,
3786 struct rpc_pipe_client **presult)
3789 struct rpc_pipe_client *result;
3790 struct cli_pipe_auth_data *auth;
3793 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
3794 if (!NT_STATUS_IS_OK(status)) {
3798 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3799 username, password, &auth);
3800 if (!NT_STATUS_IS_OK(status)) {
3801 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3802 nt_errstr(status)));
3803 TALLOC_FREE(result);
3807 status = rpc_pipe_bind(result, auth);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3810 "with error %s\n", nt_errstr(status)));
3811 TALLOC_FREE(result);
3816 return NT_STATUS_OK;
3818 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3819 return NT_STATUS_NOT_IMPLEMENTED;
3823 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3824 struct rpc_pipe_client *cli,
3825 DATA_BLOB *session_key)
3827 if (!session_key || !cli) {
3828 return NT_STATUS_INVALID_PARAMETER;
3832 return NT_STATUS_INVALID_PARAMETER;
3835 switch (cli->auth->auth_type) {
3836 case PIPE_AUTH_TYPE_SCHANNEL:
3837 *session_key = data_blob_talloc(mem_ctx,
3838 cli->auth->a_u.schannel_auth->creds->session_key, 16);
3840 case PIPE_AUTH_TYPE_NTLMSSP:
3841 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3842 *session_key = data_blob_talloc(mem_ctx,
3843 cli->auth->a_u.ntlmssp_state->session_key.data,
3844 cli->auth->a_u.ntlmssp_state->session_key.length);
3846 case PIPE_AUTH_TYPE_KRB5:
3847 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3848 *session_key = data_blob_talloc(mem_ctx,
3849 cli->auth->a_u.kerberos_auth->session_key.data,
3850 cli->auth->a_u.kerberos_auth->session_key.length);
3852 case PIPE_AUTH_TYPE_NONE:
3853 *session_key = data_blob_talloc(mem_ctx,
3854 cli->auth->user_session_key.data,
3855 cli->auth->user_session_key.length);
3858 return NT_STATUS_NO_USER_SESSION_KEY;
3861 return NT_STATUS_OK;