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 "ntlmssp_wrap.h"
30 #include "rpc_client/cli_netlogon.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/rpc/dcerpc.h"
35 #define DBGC_CLASS DBGC_RPC_CLI
37 /********************************************************************
38 Pipe description for a DEBUG
39 ********************************************************************/
40 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
41 struct rpc_pipe_client *cli)
43 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
50 /********************************************************************
52 ********************************************************************/
54 static uint32 get_rpc_call_id(void)
56 static uint32 call_id = 0;
60 /*******************************************************************
61 Use SMBreadX to get rest of one fragment's worth of rpc data.
62 Reads the whole size or give an error message
63 ********************************************************************/
65 struct rpc_read_state {
66 struct event_context *ev;
67 struct rpc_cli_transport *transport;
73 static void rpc_read_done(struct tevent_req *subreq);
75 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
76 struct event_context *ev,
77 struct rpc_cli_transport *transport,
78 uint8_t *data, size_t size)
80 struct tevent_req *req, *subreq;
81 struct rpc_read_state *state;
83 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
88 state->transport = transport;
93 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
95 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
100 tevent_req_set_callback(subreq, rpc_read_done, req);
108 static void rpc_read_done(struct tevent_req *subreq)
110 struct tevent_req *req = tevent_req_callback_data(
111 subreq, struct tevent_req);
112 struct rpc_read_state *state = tevent_req_data(
113 req, struct rpc_read_state);
117 status = state->transport->read_recv(subreq, &received);
119 if (!NT_STATUS_IS_OK(status)) {
120 tevent_req_nterror(req, status);
124 state->num_read += received;
125 if (state->num_read == state->size) {
126 tevent_req_done(req);
130 subreq = state->transport->read_send(state, state->ev,
131 state->data + state->num_read,
132 state->size - state->num_read,
133 state->transport->priv);
134 if (tevent_req_nomem(subreq, req)) {
137 tevent_req_set_callback(subreq, rpc_read_done, req);
140 static NTSTATUS rpc_read_recv(struct tevent_req *req)
142 return tevent_req_simple_recv_ntstatus(req);
145 struct rpc_write_state {
146 struct event_context *ev;
147 struct rpc_cli_transport *transport;
153 static void rpc_write_done(struct tevent_req *subreq);
155 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
156 struct event_context *ev,
157 struct rpc_cli_transport *transport,
158 const uint8_t *data, size_t size)
160 struct tevent_req *req, *subreq;
161 struct rpc_write_state *state;
163 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
168 state->transport = transport;
171 state->num_written = 0;
173 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
175 subreq = transport->write_send(state, ev, data, size, transport->priv);
176 if (subreq == NULL) {
179 tevent_req_set_callback(subreq, rpc_write_done, req);
186 static void rpc_write_done(struct tevent_req *subreq)
188 struct tevent_req *req = tevent_req_callback_data(
189 subreq, struct tevent_req);
190 struct rpc_write_state *state = tevent_req_data(
191 req, struct rpc_write_state);
195 status = state->transport->write_recv(subreq, &written);
197 if (!NT_STATUS_IS_OK(status)) {
198 tevent_req_nterror(req, status);
202 state->num_written += written;
204 if (state->num_written == state->size) {
205 tevent_req_done(req);
209 subreq = state->transport->write_send(state, state->ev,
210 state->data + state->num_written,
211 state->size - state->num_written,
212 state->transport->priv);
213 if (tevent_req_nomem(subreq, req)) {
216 tevent_req_set_callback(subreq, rpc_write_done, req);
219 static NTSTATUS rpc_write_recv(struct tevent_req *req)
221 return tevent_req_simple_recv_ntstatus(req);
225 /****************************************************************************
226 Try and get a PDU's worth of data from current_pdu. If not, then read more
228 ****************************************************************************/
230 struct get_complete_frag_state {
231 struct event_context *ev;
232 struct rpc_pipe_client *cli;
237 static void get_complete_frag_got_header(struct tevent_req *subreq);
238 static void get_complete_frag_got_rest(struct tevent_req *subreq);
240 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
241 struct event_context *ev,
242 struct rpc_pipe_client *cli,
245 struct tevent_req *req, *subreq;
246 struct get_complete_frag_state *state;
250 req = tevent_req_create(mem_ctx, &state,
251 struct get_complete_frag_state);
257 state->frag_len = RPC_HEADER_LEN;
260 received = pdu->length;
261 if (received < RPC_HEADER_LEN) {
262 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
263 status = NT_STATUS_NO_MEMORY;
266 subreq = rpc_read_send(state, state->ev,
267 state->cli->transport,
268 pdu->data + received,
269 RPC_HEADER_LEN - received);
270 if (subreq == NULL) {
271 status = NT_STATUS_NO_MEMORY;
274 tevent_req_set_callback(subreq, get_complete_frag_got_header,
279 state->frag_len = dcerpc_get_frag_length(pdu);
282 * Ensure we have frag_len bytes of data.
284 if (received < state->frag_len) {
285 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
286 status = NT_STATUS_NO_MEMORY;
289 subreq = rpc_read_send(state, state->ev,
290 state->cli->transport,
291 pdu->data + received,
292 state->frag_len - received);
293 if (subreq == NULL) {
294 status = NT_STATUS_NO_MEMORY;
297 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
302 status = NT_STATUS_OK;
304 if (NT_STATUS_IS_OK(status)) {
305 tevent_req_done(req);
307 tevent_req_nterror(req, status);
309 return tevent_req_post(req, ev);
312 static void get_complete_frag_got_header(struct tevent_req *subreq)
314 struct tevent_req *req = tevent_req_callback_data(
315 subreq, struct tevent_req);
316 struct get_complete_frag_state *state = tevent_req_data(
317 req, struct get_complete_frag_state);
320 status = rpc_read_recv(subreq);
322 if (!NT_STATUS_IS_OK(status)) {
323 tevent_req_nterror(req, status);
327 state->frag_len = dcerpc_get_frag_length(state->pdu);
329 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
330 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
335 * We're here in this piece of code because we've read exactly
336 * RPC_HEADER_LEN bytes into state->pdu.
339 subreq = rpc_read_send(state, state->ev, state->cli->transport,
340 state->pdu->data + RPC_HEADER_LEN,
341 state->frag_len - RPC_HEADER_LEN);
342 if (tevent_req_nomem(subreq, req)) {
345 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
348 static void get_complete_frag_got_rest(struct tevent_req *subreq)
350 struct tevent_req *req = tevent_req_callback_data(
351 subreq, struct tevent_req);
354 status = rpc_read_recv(subreq);
356 if (!NT_STATUS_IS_OK(status)) {
357 tevent_req_nterror(req, status);
360 tevent_req_done(req);
363 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
365 return tevent_req_simple_recv_ntstatus(req);
368 /****************************************************************************
369 NTLMSSP specific sign/seal.
370 Virtually identical to rpc_server/srv_pipe.c:api_pipe_ntlmssp_auth_process.
371 In fact I should probably abstract these into identical pieces of code... JRA.
372 ****************************************************************************/
374 static NTSTATUS cli_pipe_verify_ntlmssp(struct rpc_pipe_client *cli,
375 struct ncacn_packet *pkt,
377 uint8 *p_ss_padding_len)
379 struct dcerpc_auth auth_info;
383 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
384 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
388 if (!cli->auth->a_u.auth_ntlmssp_state) {
389 return NT_STATUS_INVALID_PARAMETER;
392 /* Ensure there's enough data for an authenticated response. */
393 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
394 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
395 + DCERPC_AUTH_TRAILER_LENGTH
396 + pkt->auth_length)) {
397 DEBUG(0, ("auth_len %u is too long.\n",
398 (unsigned int)pkt->auth_length));
399 return NT_STATUS_BUFFER_TOO_SMALL;
402 /* get the auth blob at the end of the packet */
403 blob = data_blob_const(pdu->data + pkt->frag_length
404 - DCERPC_AUTH_TRAILER_LENGTH
406 DCERPC_AUTH_TRAILER_LENGTH
409 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
410 if (!NT_STATUS_IS_OK(status)) {
411 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
415 /* Ensure auth_pad_len fits into the packet. */
416 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
417 + auth_info.auth_pad_length
418 + DCERPC_AUTH_TRAILER_LENGTH
419 + pkt->auth_length) {
420 DEBUG(0,("cli_pipe_verify_ntlmssp: auth_info.auth_pad_len "
421 "too large (%u), auth_len (%u), frag_len = (%u).\n",
422 (unsigned int)auth_info.auth_pad_length,
423 (unsigned int)pkt->auth_length,
424 (unsigned int)pkt->frag_length));
425 return NT_STATUS_BUFFER_TOO_SMALL;
429 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
430 * after the RPC header.
431 * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
432 * functions as NTLMv2 checks the rpc headers also.
435 switch (cli->auth->auth_level) {
436 case DCERPC_AUTH_LEVEL_PRIVACY:
437 /* Data is encrypted. */
438 status = auth_ntlmssp_unseal_packet(
439 cli->auth->a_u.auth_ntlmssp_state,
440 pdu->data + DCERPC_RESPONSE_LENGTH,
442 - DCERPC_RESPONSE_LENGTH
443 - DCERPC_AUTH_TRAILER_LENGTH
446 pkt->frag_length - pkt->auth_length,
447 &auth_info.credentials);
448 if (!NT_STATUS_IS_OK(status)) {
449 DEBUG(0, ("failed to unseal packet from %s."
451 rpccli_pipe_txt(talloc_tos(), cli),
457 case DCERPC_AUTH_LEVEL_INTEGRITY:
458 /* Data is signed. */
459 status = auth_ntlmssp_check_packet(
460 cli->auth->a_u.auth_ntlmssp_state,
461 pdu->data + DCERPC_RESPONSE_LENGTH,
463 - DCERPC_RESPONSE_LENGTH
464 - DCERPC_AUTH_TRAILER_LENGTH
467 pkt->frag_length - pkt->auth_length,
468 &auth_info.credentials);
469 if (!NT_STATUS_IS_OK(status)) {
470 DEBUG(0, ("check signing failed on packet from %s."
472 rpccli_pipe_txt(talloc_tos(), cli),
479 DEBUG(0, ("cli_pipe_verify_ntlmssp: unknown internal "
480 "auth level %d\n", cli->auth->auth_level));
481 return NT_STATUS_INVALID_INFO_CLASS;
485 * Remember the padding length. We must remove it from the real data
486 * stream once the sign/seal is done.
489 *p_ss_padding_len = auth_info.auth_pad_length;
494 /****************************************************************************
495 schannel specific sign/seal.
496 ****************************************************************************/
498 static NTSTATUS cli_pipe_verify_schannel(struct rpc_pipe_client *cli,
499 struct ncacn_packet *pkt,
501 uint8 *p_ss_padding_len)
503 struct dcerpc_auth auth_info;
507 if (cli->auth->auth_level == DCERPC_AUTH_LEVEL_NONE
508 || cli->auth->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
512 if (pkt->auth_length < NL_AUTH_SIGNATURE_SIZE) {
513 DEBUG(0, ("auth_len %u.\n", (unsigned int)pkt->auth_length));
514 return NT_STATUS_INVALID_PARAMETER;
517 if (!cli->auth->a_u.schannel_auth) {
518 return NT_STATUS_INVALID_PARAMETER;
521 /* Ensure there's enough data for an authenticated response. */
522 if ((pkt->auth_length > RPC_MAX_PDU_FRAG_LEN) ||
523 (pkt->frag_length < DCERPC_RESPONSE_LENGTH
524 + DCERPC_AUTH_TRAILER_LENGTH
525 + pkt->auth_length)) {
526 DEBUG(0, ("auth_len %u is too long.\n",
527 (unsigned int)pkt->auth_length));
528 return NT_STATUS_INVALID_PARAMETER;
531 /* get the auth blob at the end of the packet */
532 blob = data_blob_const(pdu->data + pkt->frag_length
533 - DCERPC_AUTH_TRAILER_LENGTH
535 DCERPC_AUTH_TRAILER_LENGTH
539 status = dcerpc_pull_dcerpc_auth(cli, &blob, &auth_info, false);
540 if (!NT_STATUS_IS_OK(status)) {
541 DEBUG(0,("cli_pipe_verify_ntlmssp: failed to unmarshall dcerpc_auth.\n"));
545 /* Ensure auth_pad_len fits into the packet. */
546 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH
547 + auth_info.auth_pad_length
548 + DCERPC_AUTH_TRAILER_LENGTH
549 + pkt->auth_length) {
550 DEBUG(0,("cli_pipe_verify_schannel: auth_info.auth_pad_len "
551 "too large (%u), auth_len (%u), frag_len = (%u).\n",
552 (unsigned int)auth_info.auth_pad_length,
553 (unsigned int)pkt->auth_length,
554 (unsigned int)pkt->frag_length));
555 return NT_STATUS_BUFFER_TOO_SMALL;
558 if (auth_info.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
559 DEBUG(0, ("Invalid auth info %d on schannel\n",
560 auth_info.auth_type));
561 return NT_STATUS_BUFFER_TOO_SMALL;
564 if (DEBUGLEVEL >= 10) {
565 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_info.credentials);
568 switch (cli->auth->auth_level) {
569 case DCERPC_AUTH_LEVEL_PRIVACY:
570 status = netsec_incoming_packet(
571 cli->auth->a_u.schannel_auth,
574 pdu->data + DCERPC_RESPONSE_LENGTH,
576 - DCERPC_RESPONSE_LENGTH
577 - DCERPC_AUTH_TRAILER_LENGTH
579 &auth_info.credentials);
581 case DCERPC_AUTH_LEVEL_INTEGRITY:
582 status = netsec_incoming_packet(
583 cli->auth->a_u.schannel_auth,
586 pdu->data + DCERPC_RESPONSE_LENGTH,
588 - DCERPC_RESPONSE_LENGTH
589 - DCERPC_AUTH_TRAILER_LENGTH
591 &auth_info.credentials);
594 status = NT_STATUS_INTERNAL_ERROR;
598 if (!NT_STATUS_IS_OK(status)) {
599 DEBUG(3,("cli_pipe_verify_schannel: failed to decode PDU "
600 "Connection to %s (%s).\n",
601 rpccli_pipe_txt(talloc_tos(), cli),
603 return NT_STATUS_INVALID_PARAMETER;
607 * Remember the padding length. We must remove it from the real data
608 * stream once the sign/seal is done.
611 *p_ss_padding_len = auth_info.auth_pad_length;
616 /****************************************************************************
617 Do the authentication checks on an incoming pdu. Check sign and unseal etc.
618 ****************************************************************************/
620 static NTSTATUS cli_pipe_validate_rpc_response(struct rpc_pipe_client *cli,
621 struct ncacn_packet *pkt,
623 uint8 *p_ss_padding_len)
625 NTSTATUS ret = NT_STATUS_OK;
627 /* Paranioa checks for auth_len. */
628 if (pkt->auth_length) {
629 if (pkt->auth_length > pkt->frag_length) {
630 return NT_STATUS_INVALID_PARAMETER;
633 if ((pkt->auth_length
634 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
635 < pkt->auth_length) ||
637 + (unsigned int)DCERPC_AUTH_TRAILER_LENGTH
638 < (unsigned int)DCERPC_AUTH_TRAILER_LENGTH)) {
639 /* Integer wrap attempt. */
640 return NT_STATUS_INVALID_PARAMETER;
645 * Now we have a complete RPC request PDU fragment, try and verify any auth data.
648 switch(cli->auth->auth_type) {
649 case PIPE_AUTH_TYPE_NONE:
650 if (pkt->auth_length) {
651 DEBUG(3, ("cli_pipe_validate_rpc_response: "
652 "Connection to %s - got non-zero "
654 rpccli_pipe_txt(talloc_tos(), cli),
655 (unsigned int)pkt->auth_length));
656 return NT_STATUS_INVALID_PARAMETER;
660 case PIPE_AUTH_TYPE_NTLMSSP:
661 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
662 ret = cli_pipe_verify_ntlmssp(cli, pkt, pdu,
664 if (!NT_STATUS_IS_OK(ret)) {
669 case PIPE_AUTH_TYPE_SCHANNEL:
670 ret = cli_pipe_verify_schannel(cli, pkt, pdu,
672 if (!NT_STATUS_IS_OK(ret)) {
677 case PIPE_AUTH_TYPE_KRB5:
678 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
680 DEBUG(3, ("cli_pipe_validate_rpc_response: Connection "
681 "to %s - unknown internal auth type %u.\n",
682 rpccli_pipe_txt(talloc_tos(), cli),
683 cli->auth->auth_type ));
684 return NT_STATUS_INVALID_INFO_CLASS;
690 /****************************************************************************
691 Do basic authentication checks on an incoming pdu.
692 ****************************************************************************/
694 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
695 struct rpc_pipe_client *cli,
696 struct ncacn_packet *pkt,
698 uint8_t expected_pkt_type,
700 DATA_BLOB *reply_pdu)
702 NTSTATUS ret = NT_STATUS_OK;
703 uint8 ss_padding_len = 0;
705 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
706 if (!NT_STATUS_IS_OK(ret)) {
710 if (pdu->length != pkt->frag_length) {
711 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
712 (unsigned int)pdu->length,
713 (unsigned int)pkt->frag_length));
714 return NT_STATUS_INVALID_PARAMETER;
718 * Point the return values at the real data including the RPC
719 * header. Just in case the caller wants it.
723 /* Ensure we have the correct type. */
724 switch (pkt->ptype) {
725 case DCERPC_PKT_ALTER_RESP:
726 case DCERPC_PKT_BIND_ACK:
728 /* Alter context and bind ack share the same packet definitions. */
732 case DCERPC_PKT_RESPONSE:
734 /* Here's where we deal with incoming sign/seal. */
735 ret = cli_pipe_validate_rpc_response(cli, pkt, pdu,
737 if (!NT_STATUS_IS_OK(ret)) {
741 /* Point the return values at the NDR data.
742 * Remember to remove any ss padding. */
743 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
745 if (pdu->length < DCERPC_RESPONSE_LENGTH + ss_padding_len) {
746 return NT_STATUS_BUFFER_TOO_SMALL;
749 rdata->length = pdu->length
750 - DCERPC_RESPONSE_LENGTH
753 /* Remember to remove the auth footer. */
754 if (pkt->auth_length) {
755 /* We've already done integer wrap tests on auth_len in
756 cli_pipe_validate_rpc_response(). */
757 if (rdata->length < DCERPC_AUTH_TRAILER_LENGTH
758 + pkt->auth_length) {
759 return NT_STATUS_BUFFER_TOO_SMALL;
761 rdata->length -= (DCERPC_AUTH_TRAILER_LENGTH
765 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
766 (long unsigned int)pdu->length,
767 (long unsigned int)rdata->length,
768 (unsigned int)ss_padding_len));
771 * If this is the first reply, and the allocation hint is
772 * reasonable, try and set up the reply_pdu DATA_BLOB to the
776 if ((reply_pdu->length == 0) &&
777 pkt->u.response.alloc_hint &&
778 (pkt->u.response.alloc_hint < 15*1024*1024)) {
779 if (!data_blob_realloc(mem_ctx, reply_pdu,
780 pkt->u.response.alloc_hint)) {
781 DEBUG(0, ("reply alloc hint %d too "
782 "large to allocate\n",
783 (int)pkt->u.response.alloc_hint));
784 return NT_STATUS_NO_MEMORY;
790 case DCERPC_PKT_BIND_NAK:
791 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
792 "received from %s!\n",
793 rpccli_pipe_txt(talloc_tos(), cli)));
794 /* Use this for now... */
795 return NT_STATUS_NETWORK_ACCESS_DENIED;
797 case DCERPC_PKT_FAULT:
799 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
800 "code %s received from %s!\n",
801 dcerpc_errstr(talloc_tos(),
802 pkt->u.fault.status),
803 rpccli_pipe_txt(talloc_tos(), cli)));
805 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
806 return NT_STATUS_UNSUCCESSFUL;
808 return NT_STATUS(pkt->u.fault.status);
812 DEBUG(0, ("Unknown packet type %u received from %s!\n",
813 (unsigned int)pkt->ptype,
814 rpccli_pipe_txt(talloc_tos(), cli)));
815 return NT_STATUS_INVALID_INFO_CLASS;
818 if (pkt->ptype != expected_pkt_type) {
819 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
820 "got an unexpected RPC packet type - %u, not %u\n",
821 rpccli_pipe_txt(talloc_tos(), cli),
824 return NT_STATUS_INVALID_INFO_CLASS;
827 /* Do this just before return - we don't want to modify any rpc header
828 data before now as we may have needed to do cryptographic actions on
831 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
832 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
833 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
834 "setting fragment first/last ON.\n"));
835 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
836 DCERPC_PFC_FLAG_LAST;
842 /****************************************************************************
843 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
844 ****************************************************************************/
846 struct cli_api_pipe_state {
847 struct event_context *ev;
848 struct rpc_cli_transport *transport;
853 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
854 static void cli_api_pipe_write_done(struct tevent_req *subreq);
855 static void cli_api_pipe_read_done(struct tevent_req *subreq);
857 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
858 struct event_context *ev,
859 struct rpc_cli_transport *transport,
860 uint8_t *data, size_t data_len,
861 uint32_t max_rdata_len)
863 struct tevent_req *req, *subreq;
864 struct cli_api_pipe_state *state;
867 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
872 state->transport = transport;
874 if (max_rdata_len < RPC_HEADER_LEN) {
876 * For a RPC reply we always need at least RPC_HEADER_LEN
877 * bytes. We check this here because we will receive
878 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
880 status = NT_STATUS_INVALID_PARAMETER;
884 if (transport->trans_send != NULL) {
885 subreq = transport->trans_send(state, ev, data, data_len,
886 max_rdata_len, transport->priv);
887 if (subreq == NULL) {
890 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
895 * If the transport does not provide a "trans" routine, i.e. for
896 * example the ncacn_ip_tcp transport, do the write/read step here.
899 subreq = rpc_write_send(state, ev, transport, data, data_len);
900 if (subreq == NULL) {
903 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
907 tevent_req_nterror(req, status);
908 return tevent_req_post(req, ev);
914 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
916 struct tevent_req *req = tevent_req_callback_data(
917 subreq, struct tevent_req);
918 struct cli_api_pipe_state *state = tevent_req_data(
919 req, struct cli_api_pipe_state);
922 status = state->transport->trans_recv(subreq, state, &state->rdata,
925 if (!NT_STATUS_IS_OK(status)) {
926 tevent_req_nterror(req, status);
929 tevent_req_done(req);
932 static void cli_api_pipe_write_done(struct tevent_req *subreq)
934 struct tevent_req *req = tevent_req_callback_data(
935 subreq, struct tevent_req);
936 struct cli_api_pipe_state *state = tevent_req_data(
937 req, struct cli_api_pipe_state);
940 status = rpc_write_recv(subreq);
942 if (!NT_STATUS_IS_OK(status)) {
943 tevent_req_nterror(req, status);
947 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
948 if (tevent_req_nomem(state->rdata, req)) {
953 * We don't need to use rpc_read_send here, the upper layer will cope
954 * with a short read, transport->trans_send could also return less
955 * than state->max_rdata_len.
957 subreq = state->transport->read_send(state, state->ev, state->rdata,
959 state->transport->priv);
960 if (tevent_req_nomem(subreq, req)) {
963 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
966 static void cli_api_pipe_read_done(struct tevent_req *subreq)
968 struct tevent_req *req = tevent_req_callback_data(
969 subreq, struct tevent_req);
970 struct cli_api_pipe_state *state = tevent_req_data(
971 req, struct cli_api_pipe_state);
975 status = state->transport->read_recv(subreq, &received);
977 if (!NT_STATUS_IS_OK(status)) {
978 tevent_req_nterror(req, status);
981 state->rdata_len = received;
982 tevent_req_done(req);
985 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
986 uint8_t **prdata, uint32_t *prdata_len)
988 struct cli_api_pipe_state *state = tevent_req_data(
989 req, struct cli_api_pipe_state);
992 if (tevent_req_is_nterror(req, &status)) {
996 *prdata = talloc_move(mem_ctx, &state->rdata);
997 *prdata_len = state->rdata_len;
1001 /****************************************************************************
1002 Send data on an rpc pipe via trans. The data must be the last
1003 pdu fragment of an NDR data stream.
1005 Receive response data from an rpc pipe, which may be large...
1007 Read the first fragment: unfortunately have to use SMBtrans for the first
1008 bit, then SMBreadX for subsequent bits.
1010 If first fragment received also wasn't the last fragment, continue
1011 getting fragments until we _do_ receive the last fragment.
1013 Request/Response PDU's look like the following...
1015 |<------------------PDU len----------------------------------------------->|
1016 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
1018 +------------+-----------------+-------------+---------------+-------------+
1019 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
1020 +------------+-----------------+-------------+---------------+-------------+
1022 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
1023 signing & sealing being negotiated.
1025 ****************************************************************************/
1027 struct rpc_api_pipe_state {
1028 struct event_context *ev;
1029 struct rpc_pipe_client *cli;
1030 uint8_t expected_pkt_type;
1032 DATA_BLOB incoming_frag;
1033 struct ncacn_packet *pkt;
1035 /* Incoming reply */
1036 DATA_BLOB reply_pdu;
1037 size_t reply_pdu_offset;
1041 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
1042 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
1044 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
1045 struct event_context *ev,
1046 struct rpc_pipe_client *cli,
1047 DATA_BLOB *data, /* Outgoing PDU */
1048 uint8_t expected_pkt_type)
1050 struct tevent_req *req, *subreq;
1051 struct rpc_api_pipe_state *state;
1052 uint16_t max_recv_frag;
1055 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
1061 state->expected_pkt_type = expected_pkt_type;
1062 state->incoming_frag = data_blob_null;
1063 state->reply_pdu = data_blob_null;
1064 state->reply_pdu_offset = 0;
1065 state->endianess = DCERPC_DREP_LE;
1068 * Ensure we're not sending too much.
1070 if (data->length > cli->max_xmit_frag) {
1071 status = NT_STATUS_INVALID_PARAMETER;
1075 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1077 /* get the header first, then fetch the rest once we have
1078 * the frag_length available */
1079 max_recv_frag = RPC_HEADER_LEN;
1081 subreq = cli_api_pipe_send(state, ev, cli->transport,
1082 data->data, data->length, max_recv_frag);
1083 if (subreq == NULL) {
1086 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1090 tevent_req_nterror(req, status);
1091 return tevent_req_post(req, ev);
1097 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1099 struct tevent_req *req = tevent_req_callback_data(
1100 subreq, struct tevent_req);
1101 struct rpc_api_pipe_state *state = tevent_req_data(
1102 req, struct rpc_api_pipe_state);
1104 uint8_t *rdata = NULL;
1105 uint32_t rdata_len = 0;
1107 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1108 TALLOC_FREE(subreq);
1109 if (!NT_STATUS_IS_OK(status)) {
1110 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1111 tevent_req_nterror(req, status);
1115 if (rdata == NULL) {
1116 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1117 rpccli_pipe_txt(talloc_tos(), state->cli)));
1118 tevent_req_done(req);
1123 * Move data on state->incoming_frag.
1125 state->incoming_frag.data = talloc_move(state, &rdata);
1126 state->incoming_frag.length = rdata_len;
1127 if (!state->incoming_frag.data) {
1128 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1132 /* Ensure we have enough data for a pdu. */
1133 subreq = get_complete_frag_send(state, state->ev, state->cli,
1134 &state->incoming_frag);
1135 if (tevent_req_nomem(subreq, req)) {
1138 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1141 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1143 struct tevent_req *req = tevent_req_callback_data(
1144 subreq, struct tevent_req);
1145 struct rpc_api_pipe_state *state = tevent_req_data(
1146 req, struct rpc_api_pipe_state);
1148 DATA_BLOB rdata = data_blob_null;
1150 status = get_complete_frag_recv(subreq);
1151 TALLOC_FREE(subreq);
1152 if (!NT_STATUS_IS_OK(status)) {
1153 DEBUG(5, ("get_complete_frag failed: %s\n",
1154 nt_errstr(status)));
1155 tevent_req_nterror(req, status);
1159 state->pkt = talloc(state, struct ncacn_packet);
1161 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1165 status = cli_pipe_validate_current_pdu(state,
1166 state->cli, state->pkt,
1167 &state->incoming_frag,
1168 state->expected_pkt_type,
1172 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
1173 (unsigned)state->incoming_frag.length,
1174 (unsigned)state->reply_pdu_offset,
1175 nt_errstr(status)));
1177 if (!NT_STATUS_IS_OK(status)) {
1178 tevent_req_nterror(req, status);
1182 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1183 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
1185 * Set the data type correctly for big-endian data on the
1188 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1190 rpccli_pipe_txt(talloc_tos(), state->cli)));
1191 state->endianess = 0x00; /* BIG ENDIAN */
1194 * Check endianness on subsequent packets.
1196 if (state->endianess != state->pkt->drep[0]) {
1197 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1199 state->endianess?"little":"big",
1200 state->pkt->drep[0]?"little":"big"));
1201 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1205 /* Now copy the data portion out of the pdu into rbuf. */
1206 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1207 if (!data_blob_realloc(NULL, &state->reply_pdu,
1208 state->reply_pdu_offset + rdata.length)) {
1209 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1214 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1215 rdata.data, rdata.length);
1216 state->reply_pdu_offset += rdata.length;
1218 /* reset state->incoming_frag, there is no need to free it,
1219 * it will be reallocated to the right size the next time
1221 state->incoming_frag.length = 0;
1223 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1224 /* make sure the pdu length is right now that we
1225 * have all the data available (alloc hint may
1226 * have allocated more than was actually used) */
1227 state->reply_pdu.length = state->reply_pdu_offset;
1228 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1229 rpccli_pipe_txt(talloc_tos(), state->cli),
1230 (unsigned)state->reply_pdu.length));
1231 tevent_req_done(req);
1235 subreq = get_complete_frag_send(state, state->ev, state->cli,
1236 &state->incoming_frag);
1237 if (tevent_req_nomem(subreq, req)) {
1240 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1243 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1244 struct ncacn_packet **pkt,
1245 DATA_BLOB *reply_pdu)
1247 struct rpc_api_pipe_state *state = tevent_req_data(
1248 req, struct rpc_api_pipe_state);
1251 if (tevent_req_is_nterror(req, &status)) {
1255 /* return data to caller and assign it ownership of memory */
1257 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1258 reply_pdu->length = state->reply_pdu.length;
1259 state->reply_pdu.length = 0;
1261 data_blob_free(&state->reply_pdu);
1265 *pkt = talloc_steal(mem_ctx, state->pkt);
1268 return NT_STATUS_OK;
1271 /*******************************************************************
1272 Creates krb5 auth bind.
1273 ********************************************************************/
1275 static NTSTATUS create_krb5_auth_bind_req(struct rpc_pipe_client *cli,
1276 enum dcerpc_AuthLevel auth_level,
1277 DATA_BLOB *auth_info)
1282 struct kerberos_auth_struct *a = cli->auth->a_u.kerberos_auth;
1283 DATA_BLOB tkt = data_blob_null;
1284 DATA_BLOB tkt_wrapped = data_blob_null;
1286 DEBUG(5, ("create_krb5_auth_bind_req: creating a service ticket for principal %s\n",
1287 a->service_principal ));
1289 /* Create the ticket for the service principal and return it in a gss-api wrapped blob. */
1291 ret = cli_krb5_get_ticket(a->service_principal, 0, &tkt,
1292 &a->session_key, (uint32)AP_OPTS_MUTUAL_REQUIRED, NULL, NULL, NULL);
1295 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1297 a->service_principal,
1298 error_message(ret) ));
1300 data_blob_free(&tkt);
1301 return NT_STATUS_INVALID_PARAMETER;
1304 /* wrap that up in a nice GSS-API wrapping */
1305 tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
1307 data_blob_free(&tkt);
1309 status = dcerpc_push_dcerpc_auth(cli,
1310 DCERPC_AUTH_TYPE_KRB5,
1312 0, /* auth_pad_length */
1313 1, /* auth_context_id */
1316 if (!NT_STATUS_IS_OK(status)) {
1317 data_blob_free(&tkt_wrapped);
1321 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1322 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1324 return NT_STATUS_OK;
1326 return NT_STATUS_INVALID_PARAMETER;
1330 /*******************************************************************
1331 Creates SPNEGO NTLMSSP auth bind.
1332 ********************************************************************/
1334 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1335 enum dcerpc_AuthLevel auth_level,
1336 DATA_BLOB *auth_info)
1339 DATA_BLOB null_blob = data_blob_null;
1340 DATA_BLOB request = data_blob_null;
1341 DATA_BLOB spnego_msg = data_blob_null;
1342 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1344 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1345 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1349 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1350 data_blob_free(&request);
1354 /* Wrap this in SPNEGO. */
1355 spnego_msg = spnego_gen_negTokenInit(OIDs_ntlm, &request, NULL);
1357 data_blob_free(&request);
1359 status = dcerpc_push_dcerpc_auth(cli,
1360 DCERPC_AUTH_TYPE_SPNEGO,
1362 0, /* auth_pad_length */
1363 1, /* auth_context_id */
1366 if (!NT_STATUS_IS_OK(status)) {
1367 data_blob_free(&spnego_msg);
1371 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1372 dump_data(5, spnego_msg.data, spnego_msg.length);
1374 return NT_STATUS_OK;
1377 /*******************************************************************
1378 Creates NTLMSSP auth bind.
1379 ********************************************************************/
1381 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1382 enum dcerpc_AuthLevel auth_level,
1383 DATA_BLOB *auth_info)
1386 DATA_BLOB null_blob = data_blob_null;
1387 DATA_BLOB request = data_blob_null;
1389 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1390 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1394 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1395 data_blob_free(&request);
1399 status = dcerpc_push_dcerpc_auth(cli,
1400 DCERPC_AUTH_TYPE_NTLMSSP,
1402 0, /* auth_pad_length */
1403 1, /* auth_context_id */
1406 if (!NT_STATUS_IS_OK(status)) {
1407 data_blob_free(&request);
1411 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1412 dump_data(5, request.data, request.length);
1414 return NT_STATUS_OK;
1417 /*******************************************************************
1418 Creates schannel auth bind.
1419 ********************************************************************/
1421 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1422 enum dcerpc_AuthLevel auth_level,
1423 DATA_BLOB *auth_info)
1426 struct NL_AUTH_MESSAGE r;
1427 DATA_BLOB schannel_blob;
1429 /* Use lp_workgroup() if domain not specified */
1431 if (!cli->auth->domain || !cli->auth->domain[0]) {
1432 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1433 if (cli->auth->domain == NULL) {
1434 return NT_STATUS_NO_MEMORY;
1439 * Now marshall the data into the auth parse_struct.
1442 r.MessageType = NL_NEGOTIATE_REQUEST;
1443 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1444 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1445 r.oem_netbios_domain.a = cli->auth->domain;
1446 r.oem_netbios_computer.a = global_myname();
1448 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1449 if (!NT_STATUS_IS_OK(status)) {
1453 status = dcerpc_push_dcerpc_auth(cli,
1454 DCERPC_AUTH_TYPE_SCHANNEL,
1456 0, /* auth_pad_length */
1457 1, /* auth_context_id */
1460 if (!NT_STATUS_IS_OK(status)) {
1464 return NT_STATUS_OK;
1467 /*******************************************************************
1468 Creates the internals of a DCE/RPC bind request or alter context PDU.
1469 ********************************************************************/
1471 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1472 enum dcerpc_pkt_type ptype,
1474 const struct ndr_syntax_id *abstract,
1475 const struct ndr_syntax_id *transfer,
1476 const DATA_BLOB *auth_info,
1479 uint16 auth_len = auth_info->length;
1481 union dcerpc_payload u;
1482 struct dcerpc_ctx_list ctx_list;
1485 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1488 ctx_list.context_id = 0;
1489 ctx_list.num_transfer_syntaxes = 1;
1490 ctx_list.abstract_syntax = *abstract;
1491 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1493 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1494 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1495 u.bind.assoc_group_id = 0x0;
1496 u.bind.num_contexts = 1;
1497 u.bind.ctx_list = &ctx_list;
1498 u.bind.auth_info = *auth_info;
1500 status = dcerpc_push_ncacn_packet(mem_ctx,
1502 DCERPC_PFC_FLAG_FIRST |
1503 DCERPC_PFC_FLAG_LAST,
1508 if (!NT_STATUS_IS_OK(status)) {
1509 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1513 return NT_STATUS_OK;
1516 /*******************************************************************
1517 Creates a DCE/RPC bind request.
1518 ********************************************************************/
1520 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1521 struct rpc_pipe_client *cli,
1523 const struct ndr_syntax_id *abstract,
1524 const struct ndr_syntax_id *transfer,
1525 enum pipe_auth_type auth_type,
1526 enum dcerpc_AuthLevel auth_level,
1529 DATA_BLOB auth_info = data_blob_null;
1530 NTSTATUS ret = NT_STATUS_OK;
1532 switch (auth_type) {
1533 case PIPE_AUTH_TYPE_SCHANNEL:
1534 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
1535 if (!NT_STATUS_IS_OK(ret)) {
1540 case PIPE_AUTH_TYPE_NTLMSSP:
1541 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1542 if (!NT_STATUS_IS_OK(ret)) {
1547 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1548 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1549 if (!NT_STATUS_IS_OK(ret)) {
1554 case PIPE_AUTH_TYPE_KRB5:
1555 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
1556 if (!NT_STATUS_IS_OK(ret)) {
1561 case PIPE_AUTH_TYPE_NONE:
1565 /* "Can't" happen. */
1566 return NT_STATUS_INVALID_INFO_CLASS;
1569 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1579 /*******************************************************************
1580 Create and add the NTLMSSP sign/seal auth header and data.
1581 ********************************************************************/
1583 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
1584 uint32 ss_padding_len,
1587 DATA_BLOB auth_info;
1589 DATA_BLOB auth_blob = data_blob_null;
1590 uint16_t data_and_pad_len = rpc_out->length - DCERPC_RESPONSE_LENGTH;
1592 if (!cli->auth->a_u.auth_ntlmssp_state) {
1593 return NT_STATUS_INVALID_PARAMETER;
1596 /* marshall the dcerpc_auth with an actually empty auth_blob.
1597 * this is needed because the ntmlssp signature includes the
1599 status = dcerpc_push_dcerpc_auth(rpc_out->data,
1600 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1601 cli->auth->auth_level,
1603 1 /* context id. */,
1606 if (!NT_STATUS_IS_OK(status)) {
1610 /* append the header */
1611 if (!data_blob_append(NULL, rpc_out,
1612 auth_info.data, auth_info.length)) {
1613 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1614 (unsigned int)auth_info.length));
1615 return NT_STATUS_NO_MEMORY;
1617 data_blob_free(&auth_info);
1619 switch (cli->auth->auth_level) {
1620 case DCERPC_AUTH_LEVEL_PRIVACY:
1621 /* Data portion is encrypted. */
1622 status = auth_ntlmssp_seal_packet(cli->auth->a_u.auth_ntlmssp_state,
1625 + DCERPC_RESPONSE_LENGTH,
1630 if (!NT_STATUS_IS_OK(status)) {
1635 case DCERPC_AUTH_LEVEL_INTEGRITY:
1636 /* Data is signed. */
1637 status = auth_ntlmssp_sign_packet(cli->auth->a_u.auth_ntlmssp_state,
1640 + DCERPC_RESPONSE_LENGTH,
1645 if (!NT_STATUS_IS_OK(status)) {
1652 smb_panic("bad auth level");
1654 return NT_STATUS_INVALID_PARAMETER;
1657 /* Finally attach the blob. */
1658 if (!data_blob_append(NULL, rpc_out,
1659 auth_blob.data, auth_blob.length)) {
1660 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1661 (unsigned int)auth_info.length));
1662 return NT_STATUS_NO_MEMORY;
1664 data_blob_free(&auth_blob);
1666 return NT_STATUS_OK;
1669 /*******************************************************************
1670 Create and add the schannel sign/seal auth header and data.
1671 ********************************************************************/
1673 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
1674 uint32 ss_padding_len,
1677 DATA_BLOB auth_info;
1678 struct schannel_state *sas = cli->auth->a_u.schannel_auth;
1679 uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH;
1680 size_t data_and_pad_len = rpc_out->length
1681 - DCERPC_RESPONSE_LENGTH;
1686 return NT_STATUS_INVALID_PARAMETER;
1689 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1692 switch (cli->auth->auth_level) {
1693 case DCERPC_AUTH_LEVEL_PRIVACY:
1694 status = netsec_outgoing_packet(sas,
1701 case DCERPC_AUTH_LEVEL_INTEGRITY:
1702 status = netsec_outgoing_packet(sas,
1710 status = NT_STATUS_INTERNAL_ERROR;
1714 if (!NT_STATUS_IS_OK(status)) {
1715 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1716 nt_errstr(status)));
1720 if (DEBUGLEVEL >= 10) {
1721 dump_NL_AUTH_SIGNATURE(talloc_tos(), &blob);
1724 /* Finally marshall the blob. */
1725 status = dcerpc_push_dcerpc_auth(rpc_out->data,
1726 map_pipe_auth_type_to_rpc_auth_type(cli->auth->auth_type),
1727 cli->auth->auth_level,
1729 1 /* context id. */,
1732 if (!NT_STATUS_IS_OK(status)) {
1735 data_blob_free(&blob);
1737 if (!data_blob_append(NULL, rpc_out,
1738 auth_info.data, auth_info.length)) {
1739 return NT_STATUS_NO_MEMORY;
1741 data_blob_free(&auth_info);
1743 return NT_STATUS_OK;
1746 /*******************************************************************
1747 Calculate how much data we're going to send in this packet, also
1748 work out any sign/seal padding length.
1749 ********************************************************************/
1751 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1755 uint32 *p_ss_padding)
1757 uint32 data_space, data_len;
1760 if ((data_left > 0) && (sys_random() % 2)) {
1761 data_left = MAX(data_left/2, 1);
1765 switch (cli->auth->auth_level) {
1766 case DCERPC_AUTH_LEVEL_NONE:
1767 case DCERPC_AUTH_LEVEL_CONNECT:
1768 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1769 data_len = MIN(data_space, data_left);
1772 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1775 case DCERPC_AUTH_LEVEL_INTEGRITY:
1776 case DCERPC_AUTH_LEVEL_PRIVACY:
1777 /* Treat the same for all authenticated rpc requests. */
1778 switch(cli->auth->auth_type) {
1779 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1780 case PIPE_AUTH_TYPE_NTLMSSP:
1781 *p_auth_len = NTLMSSP_SIG_SIZE;
1783 case PIPE_AUTH_TYPE_SCHANNEL:
1784 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1787 smb_panic("bad auth type");
1791 data_space = cli->max_xmit_frag
1792 - DCERPC_REQUEST_LENGTH
1793 - DCERPC_AUTH_TRAILER_LENGTH
1796 data_len = MIN(data_space, data_left);
1798 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1799 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1801 *p_frag_len = DCERPC_REQUEST_LENGTH
1802 + data_len + *p_ss_padding
1803 + DCERPC_AUTH_TRAILER_LENGTH
1808 smb_panic("bad auth level");
1814 /*******************************************************************
1816 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1817 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1818 and deals with signing/sealing details.
1819 ********************************************************************/
1821 struct rpc_api_pipe_req_state {
1822 struct event_context *ev;
1823 struct rpc_pipe_client *cli;
1826 DATA_BLOB *req_data;
1827 uint32_t req_data_sent;
1829 DATA_BLOB reply_pdu;
1832 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1833 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1834 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1835 bool *is_last_frag);
1837 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1838 struct event_context *ev,
1839 struct rpc_pipe_client *cli,
1841 DATA_BLOB *req_data)
1843 struct tevent_req *req, *subreq;
1844 struct rpc_api_pipe_req_state *state;
1848 req = tevent_req_create(mem_ctx, &state,
1849 struct rpc_api_pipe_req_state);
1855 state->op_num = op_num;
1856 state->req_data = req_data;
1857 state->req_data_sent = 0;
1858 state->call_id = get_rpc_call_id();
1859 state->reply_pdu = data_blob_null;
1860 state->rpc_out = data_blob_null;
1862 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1863 + RPC_MAX_SIGN_SIZE) {
1864 /* Server is screwed up ! */
1865 status = NT_STATUS_INVALID_PARAMETER;
1869 status = prepare_next_frag(state, &is_last_frag);
1870 if (!NT_STATUS_IS_OK(status)) {
1875 subreq = rpc_api_pipe_send(state, ev, state->cli,
1877 DCERPC_PKT_RESPONSE);
1878 if (subreq == NULL) {
1881 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1883 subreq = rpc_write_send(state, ev, cli->transport,
1884 state->rpc_out.data,
1885 state->rpc_out.length);
1886 if (subreq == NULL) {
1889 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1895 tevent_req_nterror(req, status);
1896 return tevent_req_post(req, ev);
1902 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1905 uint32_t data_sent_thistime;
1909 uint32_t ss_padding;
1911 char pad[8] = { 0, };
1913 union dcerpc_payload u;
1915 data_left = state->req_data->length - state->req_data_sent;
1917 data_sent_thistime = calculate_data_len_tosend(
1918 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
1920 if (state->req_data_sent == 0) {
1921 flags = DCERPC_PFC_FLAG_FIRST;
1924 if (data_sent_thistime == data_left) {
1925 flags |= DCERPC_PFC_FLAG_LAST;
1928 data_blob_free(&state->rpc_out);
1930 ZERO_STRUCT(u.request);
1932 u.request.alloc_hint = state->req_data->length;
1933 u.request.context_id = 0;
1934 u.request.opnum = state->op_num;
1936 status = dcerpc_push_ncacn_packet(state,
1943 if (!NT_STATUS_IS_OK(status)) {
1947 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1948 * compute it right for requests */
1949 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1951 /* Copy in the data, plus any ss padding. */
1952 if (!data_blob_append(NULL, &state->rpc_out,
1953 state->req_data->data + state->req_data_sent,
1954 data_sent_thistime)) {
1955 return NT_STATUS_NO_MEMORY;
1959 /* Copy the sign/seal padding data. */
1960 if (!data_blob_append(NULL, &state->rpc_out,
1962 return NT_STATUS_NO_MEMORY;
1966 /* Generate any auth sign/seal and add the auth footer. */
1967 switch (state->cli->auth->auth_type) {
1968 case PIPE_AUTH_TYPE_NONE:
1969 status = NT_STATUS_OK;
1971 case PIPE_AUTH_TYPE_NTLMSSP:
1972 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1973 status = add_ntlmssp_auth_footer(state->cli, ss_padding,
1976 case PIPE_AUTH_TYPE_SCHANNEL:
1977 status = add_schannel_auth_footer(state->cli, ss_padding,
1981 status = NT_STATUS_INVALID_PARAMETER;
1985 state->req_data_sent += data_sent_thistime;
1986 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1991 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1993 struct tevent_req *req = tevent_req_callback_data(
1994 subreq, struct tevent_req);
1995 struct rpc_api_pipe_req_state *state = tevent_req_data(
1996 req, struct rpc_api_pipe_req_state);
2000 status = rpc_write_recv(subreq);
2001 TALLOC_FREE(subreq);
2002 if (!NT_STATUS_IS_OK(status)) {
2003 tevent_req_nterror(req, status);
2007 status = prepare_next_frag(state, &is_last_frag);
2008 if (!NT_STATUS_IS_OK(status)) {
2009 tevent_req_nterror(req, status);
2014 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2016 DCERPC_PKT_RESPONSE);
2017 if (tevent_req_nomem(subreq, req)) {
2020 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2022 subreq = rpc_write_send(state, state->ev,
2023 state->cli->transport,
2024 state->rpc_out.data,
2025 state->rpc_out.length);
2026 if (tevent_req_nomem(subreq, req)) {
2029 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2034 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2036 struct tevent_req *req = tevent_req_callback_data(
2037 subreq, struct tevent_req);
2038 struct rpc_api_pipe_req_state *state = tevent_req_data(
2039 req, struct rpc_api_pipe_req_state);
2042 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
2043 TALLOC_FREE(subreq);
2044 if (!NT_STATUS_IS_OK(status)) {
2045 tevent_req_nterror(req, status);
2048 tevent_req_done(req);
2051 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2052 DATA_BLOB *reply_pdu)
2054 struct rpc_api_pipe_req_state *state = tevent_req_data(
2055 req, struct rpc_api_pipe_req_state);
2058 if (tevent_req_is_nterror(req, &status)) {
2060 * We always have to initialize to reply pdu, even if there is
2061 * none. The rpccli_* caller routines expect this.
2063 *reply_pdu = data_blob_null;
2067 /* return data to caller and assign it ownership of memory */
2068 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
2069 reply_pdu->length = state->reply_pdu.length;
2070 state->reply_pdu.length = 0;
2072 return NT_STATUS_OK;
2076 /****************************************************************************
2077 Set the handle state.
2078 ****************************************************************************/
2080 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2081 const char *pipe_name, uint16 device_state)
2083 bool state_set = False;
2085 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2086 char *rparam = NULL;
2088 uint32 rparam_len, rdata_len;
2090 if (pipe_name == NULL)
2093 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2094 cli->fnum, pipe_name, device_state));
2096 /* create parameters: device state */
2097 SSVAL(param, 0, device_state);
2099 /* create setup parameters. */
2101 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2103 /* send the data on \PIPE\ */
2104 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2105 setup, 2, 0, /* setup, length, max */
2106 param, 2, 0, /* param, length, max */
2107 NULL, 0, 1024, /* data, length, max */
2108 &rparam, &rparam_len, /* return param, length */
2109 &rdata, &rdata_len)) /* return data, length */
2111 DEBUG(5, ("Set Handle state: return OK\n"));
2122 /****************************************************************************
2123 Check the rpc bind acknowledge response.
2124 ****************************************************************************/
2126 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2127 const struct ndr_syntax_id *transfer)
2129 struct dcerpc_ack_ctx ctx;
2131 if (r->secondary_address_size == 0) {
2132 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2135 if (r->num_results < 1 || !r->ctx_list) {
2139 ctx = r->ctx_list[0];
2141 /* check the transfer syntax */
2142 if ((ctx.syntax.if_version != transfer->if_version) ||
2143 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2144 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2148 if (r->num_results != 0x1 || ctx.result != 0) {
2149 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2150 r->num_results, ctx.reason));
2153 DEBUG(5,("check_bind_response: accepted!\n"));
2157 /*******************************************************************
2158 Creates a DCE/RPC bind authentication response.
2159 This is the packet that is sent back to the server once we
2160 have received a BIND-ACK, to finish the third leg of
2161 the authentication handshake.
2162 ********************************************************************/
2164 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
2165 struct rpc_pipe_client *cli,
2167 enum pipe_auth_type auth_type,
2168 enum dcerpc_AuthLevel auth_level,
2169 DATA_BLOB *pauth_blob,
2173 union dcerpc_payload u;
2177 status = dcerpc_push_dcerpc_auth(mem_ctx,
2178 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2180 0, /* auth_pad_length */
2181 1, /* auth_context_id */
2183 &u.auth3.auth_info);
2184 if (!NT_STATUS_IS_OK(status)) {
2188 status = dcerpc_push_ncacn_packet(mem_ctx,
2190 DCERPC_PFC_FLAG_FIRST |
2191 DCERPC_PFC_FLAG_LAST,
2196 data_blob_free(&u.auth3.auth_info);
2197 if (!NT_STATUS_IS_OK(status)) {
2198 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2202 return NT_STATUS_OK;
2205 /*******************************************************************
2206 Creates a DCE/RPC bind alter context authentication request which
2207 may contain a spnego auth blobl
2208 ********************************************************************/
2210 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
2212 const struct ndr_syntax_id *abstract,
2213 const struct ndr_syntax_id *transfer,
2214 enum dcerpc_AuthLevel auth_level,
2215 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2218 DATA_BLOB auth_info;
2221 status = dcerpc_push_dcerpc_auth(mem_ctx,
2222 DCERPC_AUTH_TYPE_SPNEGO,
2224 0, /* auth_pad_length */
2225 1, /* auth_context_id */
2228 if (!NT_STATUS_IS_OK(status)) {
2232 status = create_bind_or_alt_ctx_internal(mem_ctx,
2239 data_blob_free(&auth_info);
2243 /****************************************************************************
2245 ****************************************************************************/
2247 struct rpc_pipe_bind_state {
2248 struct event_context *ev;
2249 struct rpc_pipe_client *cli;
2251 uint32_t rpc_call_id;
2254 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2255 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2256 struct rpc_pipe_bind_state *state,
2257 struct ncacn_packet *r);
2258 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2259 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2260 struct rpc_pipe_bind_state *state,
2261 struct ncacn_packet *r,
2262 DATA_BLOB *reply_pdu);
2263 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2265 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2266 struct event_context *ev,
2267 struct rpc_pipe_client *cli,
2268 struct pipe_auth_data *auth)
2270 struct tevent_req *req, *subreq;
2271 struct rpc_pipe_bind_state *state;
2274 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2279 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2280 rpccli_pipe_txt(talloc_tos(), cli),
2281 (unsigned int)auth->auth_type,
2282 (unsigned int)auth->auth_level ));
2286 state->rpc_call_id = get_rpc_call_id();
2287 state->rpc_out = data_blob_null;
2289 cli->auth = talloc_move(cli, &auth);
2291 /* Marshall the outgoing data. */
2292 status = create_rpc_bind_req(state, cli,
2294 &cli->abstract_syntax,
2295 &cli->transfer_syntax,
2296 cli->auth->auth_type,
2297 cli->auth->auth_level,
2300 if (!NT_STATUS_IS_OK(status)) {
2304 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2305 DCERPC_PKT_BIND_ACK);
2306 if (subreq == NULL) {
2309 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2313 tevent_req_nterror(req, status);
2314 return tevent_req_post(req, ev);
2320 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2322 struct tevent_req *req = tevent_req_callback_data(
2323 subreq, struct tevent_req);
2324 struct rpc_pipe_bind_state *state = tevent_req_data(
2325 req, struct rpc_pipe_bind_state);
2326 DATA_BLOB reply_pdu;
2327 struct ncacn_packet *pkt;
2330 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
2331 TALLOC_FREE(subreq);
2332 if (!NT_STATUS_IS_OK(status)) {
2333 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2334 rpccli_pipe_txt(talloc_tos(), state->cli),
2335 nt_errstr(status)));
2336 tevent_req_nterror(req, status);
2340 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
2341 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2342 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2346 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
2347 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
2350 * For authenticated binds we may need to do 3 or 4 leg binds.
2353 switch(state->cli->auth->auth_type) {
2355 case PIPE_AUTH_TYPE_NONE:
2356 case PIPE_AUTH_TYPE_SCHANNEL:
2357 /* Bind complete. */
2358 tevent_req_done(req);
2361 case PIPE_AUTH_TYPE_NTLMSSP:
2362 /* Need to send AUTH3 packet - no reply. */
2363 status = rpc_finish_auth3_bind_send(req, state, pkt);
2364 if (!NT_STATUS_IS_OK(status)) {
2365 tevent_req_nterror(req, status);
2369 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2370 /* Need to send alter context request and reply. */
2371 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt,
2373 if (!NT_STATUS_IS_OK(status)) {
2374 tevent_req_nterror(req, status);
2378 case PIPE_AUTH_TYPE_KRB5:
2382 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2383 (unsigned int)state->cli->auth->auth_type));
2384 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2388 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2389 struct rpc_pipe_bind_state *state,
2390 struct ncacn_packet *r)
2392 DATA_BLOB client_reply = data_blob_null;
2393 struct dcerpc_auth auth;
2394 struct tevent_req *subreq;
2397 if ((r->auth_length == 0)
2398 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2399 + r->auth_length)) {
2400 return NT_STATUS_INVALID_PARAMETER;
2403 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
2404 &r->u.bind_ack.auth_info,
2406 if (!NT_STATUS_IS_OK(status)) {
2407 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2408 nt_errstr(status)));
2412 /* TODO - check auth_type/auth_level match. */
2414 status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state,
2415 auth.credentials, &client_reply);
2417 if (!NT_STATUS_IS_OK(status)) {
2418 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2419 "blob failed: %s.\n", nt_errstr(status)));
2423 data_blob_free(&state->rpc_out);
2425 status = create_rpc_bind_auth3(state,
2426 state->cli, state->rpc_call_id,
2427 state->cli->auth->auth_type,
2428 state->cli->auth->auth_level,
2429 &client_reply, &state->rpc_out);
2430 data_blob_free(&client_reply);
2432 if (!NT_STATUS_IS_OK(status)) {
2436 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2437 state->rpc_out.data, state->rpc_out.length);
2438 if (subreq == NULL) {
2439 return NT_STATUS_NO_MEMORY;
2441 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2442 return NT_STATUS_OK;
2445 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2447 struct tevent_req *req = tevent_req_callback_data(
2448 subreq, struct tevent_req);
2451 status = rpc_write_recv(subreq);
2452 TALLOC_FREE(subreq);
2453 if (!NT_STATUS_IS_OK(status)) {
2454 tevent_req_nterror(req, status);
2457 tevent_req_done(req);
2460 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2461 struct rpc_pipe_bind_state *state,
2462 struct ncacn_packet *r,
2463 DATA_BLOB *reply_pdu)
2465 DATA_BLOB server_ntlm_response = data_blob_null;
2466 DATA_BLOB client_reply = data_blob_null;
2467 DATA_BLOB tmp_blob = data_blob_null;
2468 struct dcerpc_auth auth_info;
2469 DATA_BLOB auth_blob;
2470 struct tevent_req *subreq;
2473 if ((r->auth_length == 0)
2474 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2475 + r->auth_length)) {
2476 return NT_STATUS_INVALID_PARAMETER;
2479 /* Process the returned NTLMSSP blob first. */
2480 auth_blob = data_blob_const(reply_pdu->data
2482 - DCERPC_AUTH_TRAILER_LENGTH
2484 DCERPC_AUTH_TRAILER_LENGTH
2487 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info, false);
2488 if (!NT_STATUS_IS_OK(status)) {
2489 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
2494 * The server might give us back two challenges - tmp_blob is for the
2497 if (!spnego_parse_challenge(auth_info.credentials,
2498 &server_ntlm_response, &tmp_blob)) {
2499 data_blob_free(&server_ntlm_response);
2500 data_blob_free(&tmp_blob);
2501 return NT_STATUS_INVALID_PARAMETER;
2504 /* We're finished with the server spnego response and the tmp_blob. */
2505 data_blob_free(&tmp_blob);
2507 status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state,
2508 server_ntlm_response, &client_reply);
2510 /* Finished with the server_ntlm response */
2511 data_blob_free(&server_ntlm_response);
2513 if (!NT_STATUS_IS_OK(status)) {
2514 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2515 "using server blob failed.\n"));
2516 data_blob_free(&client_reply);
2520 /* SPNEGO wrap the client reply. */
2521 tmp_blob = spnego_gen_auth(client_reply);
2522 data_blob_free(&client_reply);
2523 client_reply = tmp_blob;
2524 tmp_blob = data_blob_null;
2526 /* Now prepare the alter context pdu. */
2527 data_blob_free(&state->rpc_out);
2529 status = create_rpc_alter_context(state,
2531 &state->cli->abstract_syntax,
2532 &state->cli->transfer_syntax,
2533 state->cli->auth->auth_level,
2536 data_blob_free(&client_reply);
2538 if (!NT_STATUS_IS_OK(status)) {
2542 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2543 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2544 if (subreq == NULL) {
2545 return NT_STATUS_NO_MEMORY;
2547 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2548 return NT_STATUS_OK;
2551 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2553 struct tevent_req *req = tevent_req_callback_data(
2554 subreq, struct tevent_req);
2555 struct rpc_pipe_bind_state *state = tevent_req_data(
2556 req, struct rpc_pipe_bind_state);
2557 DATA_BLOB tmp_blob = data_blob_null;
2558 struct ncacn_packet *pkt;
2559 struct dcerpc_auth auth;
2562 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2563 TALLOC_FREE(subreq);
2564 if (!NT_STATUS_IS_OK(status)) {
2565 tevent_req_nterror(req, status);
2569 status = dcerpc_pull_dcerpc_auth(pkt,
2570 &pkt->u.alter_resp.auth_info,
2572 if (!NT_STATUS_IS_OK(status)) {
2573 tevent_req_nterror(req, status);
2577 /* Check we got a valid auth response. */
2578 if (!spnego_parse_auth_response(auth.credentials,
2580 OID_NTLMSSP, &tmp_blob)) {
2581 data_blob_free(&tmp_blob);
2582 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2586 data_blob_free(&tmp_blob);
2588 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2589 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2590 tevent_req_done(req);
2593 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2595 return tevent_req_simple_recv_ntstatus(req);
2598 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2599 struct pipe_auth_data *auth)
2601 TALLOC_CTX *frame = talloc_stackframe();
2602 struct event_context *ev;
2603 struct tevent_req *req;
2604 NTSTATUS status = NT_STATUS_OK;
2606 ev = event_context_init(frame);
2608 status = NT_STATUS_NO_MEMORY;
2612 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2614 status = NT_STATUS_NO_MEMORY;
2618 if (!tevent_req_poll(req, ev)) {
2619 status = map_nt_error_from_unix(errno);
2623 status = rpc_pipe_bind_recv(req);
2629 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2631 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2632 unsigned int timeout)
2636 if (rpc_cli->transport == NULL) {
2637 return RPCCLI_DEFAULT_TIMEOUT;
2640 if (rpc_cli->transport->set_timeout == NULL) {
2641 return RPCCLI_DEFAULT_TIMEOUT;
2644 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2646 return RPCCLI_DEFAULT_TIMEOUT;
2652 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2654 if (rpc_cli == NULL) {
2658 if (rpc_cli->transport == NULL) {
2662 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2665 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2667 struct cli_state *cli;
2669 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2670 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2671 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2675 cli = rpc_pipe_np_smb_conn(rpc_cli);
2679 E_md4hash(cli->password ? cli->password : "", nt_hash);
2683 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2684 struct pipe_auth_data **presult)
2686 struct pipe_auth_data *result;
2688 result = talloc(mem_ctx, struct pipe_auth_data);
2689 if (result == NULL) {
2690 return NT_STATUS_NO_MEMORY;
2693 result->auth_type = PIPE_AUTH_TYPE_NONE;
2694 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2696 result->user_name = talloc_strdup(result, "");
2697 result->domain = talloc_strdup(result, "");
2698 if ((result->user_name == NULL) || (result->domain == NULL)) {
2699 TALLOC_FREE(result);
2700 return NT_STATUS_NO_MEMORY;
2704 return NT_STATUS_OK;
2707 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2709 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2713 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2714 enum pipe_auth_type auth_type,
2715 enum dcerpc_AuthLevel auth_level,
2717 const char *username,
2718 const char *password,
2719 struct pipe_auth_data **presult)
2721 struct pipe_auth_data *result;
2724 result = talloc(mem_ctx, struct pipe_auth_data);
2725 if (result == NULL) {
2726 return NT_STATUS_NO_MEMORY;
2729 result->auth_type = auth_type;
2730 result->auth_level = auth_level;
2732 result->user_name = talloc_strdup(result, username);
2733 result->domain = talloc_strdup(result, domain);
2734 if ((result->user_name == NULL) || (result->domain == NULL)) {
2735 status = NT_STATUS_NO_MEMORY;
2739 status = auth_ntlmssp_client_start(NULL,
2742 lp_client_ntlmv2_auth(),
2743 &result->a_u.auth_ntlmssp_state);
2744 if (!NT_STATUS_IS_OK(status)) {
2748 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2750 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2752 if (!NT_STATUS_IS_OK(status)) {
2756 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2758 if (!NT_STATUS_IS_OK(status)) {
2762 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2764 if (!NT_STATUS_IS_OK(status)) {
2769 * Turn off sign+seal to allow selected auth level to turn it back on.
2771 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2772 ~(NTLMSSP_NEGOTIATE_SIGN |
2773 NTLMSSP_NEGOTIATE_SEAL));
2775 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2776 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2777 NTLMSSP_NEGOTIATE_SIGN);
2778 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2779 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2780 NTLMSSP_NEGOTIATE_SEAL |
2781 NTLMSSP_NEGOTIATE_SIGN);
2785 return NT_STATUS_OK;
2788 TALLOC_FREE(result);
2792 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2793 enum dcerpc_AuthLevel auth_level,
2794 struct netlogon_creds_CredentialState *creds,
2795 struct pipe_auth_data **presult)
2797 struct pipe_auth_data *result;
2799 result = talloc(mem_ctx, struct pipe_auth_data);
2800 if (result == NULL) {
2801 return NT_STATUS_NO_MEMORY;
2804 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2805 result->auth_level = auth_level;
2807 result->user_name = talloc_strdup(result, "");
2808 result->domain = talloc_strdup(result, domain);
2809 if ((result->user_name == NULL) || (result->domain == NULL)) {
2813 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2814 if (result->a_u.schannel_auth == NULL) {
2818 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2819 result->a_u.schannel_auth->seq_num = 0;
2820 result->a_u.schannel_auth->initiator = true;
2821 result->a_u.schannel_auth->creds = creds;
2824 return NT_STATUS_OK;
2827 TALLOC_FREE(result);
2828 return NT_STATUS_NO_MEMORY;
2832 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2834 data_blob_free(&auth->session_key);
2839 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2840 enum dcerpc_AuthLevel auth_level,
2841 const char *service_princ,
2842 const char *username,
2843 const char *password,
2844 struct pipe_auth_data **presult)
2847 struct pipe_auth_data *result;
2849 if ((username != NULL) && (password != NULL)) {
2850 int ret = kerberos_kinit_password(username, password, 0, NULL);
2852 return NT_STATUS_ACCESS_DENIED;
2856 result = talloc(mem_ctx, struct pipe_auth_data);
2857 if (result == NULL) {
2858 return NT_STATUS_NO_MEMORY;
2861 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2862 result->auth_level = auth_level;
2865 * Username / domain need fixing!
2867 result->user_name = talloc_strdup(result, "");
2868 result->domain = talloc_strdup(result, "");
2869 if ((result->user_name == NULL) || (result->domain == NULL)) {
2873 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2874 result, struct kerberos_auth_struct);
2875 if (result->a_u.kerberos_auth == NULL) {
2878 talloc_set_destructor(result->a_u.kerberos_auth,
2879 cli_auth_kerberos_data_destructor);
2881 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2882 result, service_princ);
2883 if (result->a_u.kerberos_auth->service_principal == NULL) {
2888 return NT_STATUS_OK;
2891 TALLOC_FREE(result);
2892 return NT_STATUS_NO_MEMORY;
2894 return NT_STATUS_NOT_SUPPORTED;
2899 * Create an rpc pipe client struct, connecting to a tcp port.
2901 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2903 const struct ndr_syntax_id *abstract_syntax,
2904 struct rpc_pipe_client **presult)
2906 struct rpc_pipe_client *result;
2907 struct sockaddr_storage addr;
2911 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2912 if (result == NULL) {
2913 return NT_STATUS_NO_MEMORY;
2916 result->abstract_syntax = *abstract_syntax;
2917 result->transfer_syntax = ndr_transfer_syntax;
2918 result->dispatch = cli_do_rpc_ndr;
2919 result->dispatch_send = cli_do_rpc_ndr_send;
2920 result->dispatch_recv = cli_do_rpc_ndr_recv;
2922 result->desthost = talloc_strdup(result, host);
2923 result->srv_name_slash = talloc_asprintf_strupper_m(
2924 result, "\\\\%s", result->desthost);
2925 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2926 status = NT_STATUS_NO_MEMORY;
2930 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2931 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2933 if (!resolve_name(host, &addr, 0, false)) {
2934 status = NT_STATUS_NOT_FOUND;
2938 status = open_socket_out(&addr, port, 60, &fd);
2939 if (!NT_STATUS_IS_OK(status)) {
2942 set_socket_options(fd, lp_socket_options());
2944 status = rpc_transport_sock_init(result, fd, &result->transport);
2945 if (!NT_STATUS_IS_OK(status)) {
2950 result->transport->transport = NCACN_IP_TCP;
2953 return NT_STATUS_OK;
2956 TALLOC_FREE(result);
2961 * Determine the tcp port on which a dcerpc interface is listening
2962 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2965 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2966 const struct ndr_syntax_id *abstract_syntax,
2970 struct rpc_pipe_client *epm_pipe = NULL;
2971 struct pipe_auth_data *auth = NULL;
2972 struct dcerpc_binding *map_binding = NULL;
2973 struct dcerpc_binding *res_binding = NULL;
2974 struct epm_twr_t *map_tower = NULL;
2975 struct epm_twr_t *res_towers = NULL;
2976 struct policy_handle *entry_handle = NULL;
2977 uint32_t num_towers = 0;
2978 uint32_t max_towers = 1;
2979 struct epm_twr_p_t towers;
2980 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2982 if (pport == NULL) {
2983 status = NT_STATUS_INVALID_PARAMETER;
2987 /* open the connection to the endpoint mapper */
2988 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2989 &ndr_table_epmapper.syntax_id,
2992 if (!NT_STATUS_IS_OK(status)) {
2996 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2997 if (!NT_STATUS_IS_OK(status)) {
3001 status = rpc_pipe_bind(epm_pipe, auth);
3002 if (!NT_STATUS_IS_OK(status)) {
3006 /* create tower for asking the epmapper */
3008 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3009 if (map_binding == NULL) {
3010 status = NT_STATUS_NO_MEMORY;
3014 map_binding->transport = NCACN_IP_TCP;
3015 map_binding->object = *abstract_syntax;
3016 map_binding->host = host; /* needed? */
3017 map_binding->endpoint = "0"; /* correct? needed? */
3019 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3020 if (map_tower == NULL) {
3021 status = NT_STATUS_NO_MEMORY;
3025 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3026 &(map_tower->tower));
3027 if (!NT_STATUS_IS_OK(status)) {
3031 /* allocate further parameters for the epm_Map call */
3033 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3034 if (res_towers == NULL) {
3035 status = NT_STATUS_NO_MEMORY;
3038 towers.twr = res_towers;
3040 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3041 if (entry_handle == NULL) {
3042 status = NT_STATUS_NO_MEMORY;
3046 /* ask the endpoint mapper for the port */
3048 status = rpccli_epm_Map(epm_pipe,
3050 CONST_DISCARD(struct GUID *,
3051 &(abstract_syntax->uuid)),
3058 if (!NT_STATUS_IS_OK(status)) {
3062 if (num_towers != 1) {
3063 status = NT_STATUS_UNSUCCESSFUL;
3067 /* extract the port from the answer */
3069 status = dcerpc_binding_from_tower(tmp_ctx,
3070 &(towers.twr->tower),
3072 if (!NT_STATUS_IS_OK(status)) {
3076 /* are further checks here necessary? */
3077 if (res_binding->transport != NCACN_IP_TCP) {
3078 status = NT_STATUS_UNSUCCESSFUL;
3082 *pport = (uint16_t)atoi(res_binding->endpoint);
3085 TALLOC_FREE(tmp_ctx);
3090 * Create a rpc pipe client struct, connecting to a host via tcp.
3091 * The port is determined by asking the endpoint mapper on the given
3094 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3095 const struct ndr_syntax_id *abstract_syntax,
3096 struct rpc_pipe_client **presult)
3101 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3102 if (!NT_STATUS_IS_OK(status)) {
3106 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3107 abstract_syntax, presult);
3110 /********************************************************************
3111 Create a rpc pipe client struct, connecting to a unix domain socket
3112 ********************************************************************/
3113 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3114 const struct ndr_syntax_id *abstract_syntax,
3115 struct rpc_pipe_client **presult)
3117 struct rpc_pipe_client *result;
3118 struct sockaddr_un addr;
3122 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3123 if (result == NULL) {
3124 return NT_STATUS_NO_MEMORY;
3127 result->abstract_syntax = *abstract_syntax;
3128 result->transfer_syntax = ndr_transfer_syntax;
3129 result->dispatch = cli_do_rpc_ndr;
3130 result->dispatch_send = cli_do_rpc_ndr_send;
3131 result->dispatch_recv = cli_do_rpc_ndr_recv;
3133 result->desthost = get_myname(result);
3134 result->srv_name_slash = talloc_asprintf_strupper_m(
3135 result, "\\\\%s", result->desthost);
3136 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3137 status = NT_STATUS_NO_MEMORY;
3141 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3142 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3144 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3146 status = map_nt_error_from_unix(errno);
3151 addr.sun_family = AF_UNIX;
3152 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3154 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3155 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3158 return map_nt_error_from_unix(errno);
3161 status = rpc_transport_sock_init(result, fd, &result->transport);
3162 if (!NT_STATUS_IS_OK(status)) {
3167 result->transport->transport = NCALRPC;
3170 return NT_STATUS_OK;
3173 TALLOC_FREE(result);
3177 struct rpc_pipe_client_np_ref {
3178 struct cli_state *cli;
3179 struct rpc_pipe_client *pipe;
3182 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3184 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3188 /****************************************************************************
3189 Open a named pipe over SMB to a remote server.
3191 * CAVEAT CALLER OF THIS FUNCTION:
3192 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3193 * so be sure that this function is called AFTER any structure (vs pointer)
3194 * assignment of the cli. In particular, libsmbclient does structure
3195 * assignments of cli, which invalidates the data in the returned
3196 * rpc_pipe_client if this function is called before the structure assignment
3199 ****************************************************************************/
3201 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3202 const struct ndr_syntax_id *abstract_syntax,
3203 struct rpc_pipe_client **presult)
3205 struct rpc_pipe_client *result;
3207 struct rpc_pipe_client_np_ref *np_ref;
3209 /* sanity check to protect against crashes */
3212 return NT_STATUS_INVALID_HANDLE;
3215 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3216 if (result == NULL) {
3217 return NT_STATUS_NO_MEMORY;
3220 result->abstract_syntax = *abstract_syntax;
3221 result->transfer_syntax = ndr_transfer_syntax;
3222 result->dispatch = cli_do_rpc_ndr;
3223 result->dispatch_send = cli_do_rpc_ndr_send;
3224 result->dispatch_recv = cli_do_rpc_ndr_recv;
3225 result->desthost = talloc_strdup(result, cli->desthost);
3226 result->srv_name_slash = talloc_asprintf_strupper_m(
3227 result, "\\\\%s", result->desthost);
3229 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3230 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3232 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3233 TALLOC_FREE(result);
3234 return NT_STATUS_NO_MEMORY;
3237 status = rpc_transport_np_init(result, cli, abstract_syntax,
3238 &result->transport);
3239 if (!NT_STATUS_IS_OK(status)) {
3240 TALLOC_FREE(result);
3244 result->transport->transport = NCACN_NP;
3246 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3247 if (np_ref == NULL) {
3248 TALLOC_FREE(result);
3249 return NT_STATUS_NO_MEMORY;
3252 np_ref->pipe = result;
3254 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3255 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3258 return NT_STATUS_OK;
3261 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3262 struct rpc_cli_smbd_conn *conn,
3263 const struct ndr_syntax_id *syntax,
3264 struct rpc_pipe_client **presult)
3266 struct rpc_pipe_client *result;
3267 struct pipe_auth_data *auth;
3270 result = talloc(mem_ctx, struct rpc_pipe_client);
3271 if (result == NULL) {
3272 return NT_STATUS_NO_MEMORY;
3274 result->abstract_syntax = *syntax;
3275 result->transfer_syntax = ndr_transfer_syntax;
3276 result->dispatch = cli_do_rpc_ndr;
3277 result->dispatch_send = cli_do_rpc_ndr_send;
3278 result->dispatch_recv = cli_do_rpc_ndr_recv;
3279 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3280 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3282 result->desthost = talloc_strdup(result, global_myname());
3283 result->srv_name_slash = talloc_asprintf_strupper_m(
3284 result, "\\\\%s", global_myname());
3285 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3286 TALLOC_FREE(result);
3287 return NT_STATUS_NO_MEMORY;
3290 status = rpc_transport_smbd_init(result, conn, syntax,
3291 &result->transport);
3292 if (!NT_STATUS_IS_OK(status)) {
3293 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3294 nt_errstr(status)));
3295 TALLOC_FREE(result);
3299 status = rpccli_anon_bind_data(result, &auth);
3300 if (!NT_STATUS_IS_OK(status)) {
3301 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3302 nt_errstr(status)));
3303 TALLOC_FREE(result);
3307 status = rpc_pipe_bind(result, auth);
3308 if (!NT_STATUS_IS_OK(status)) {
3309 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3310 TALLOC_FREE(result);
3314 result->transport->transport = NCACN_INTERNAL;
3317 return NT_STATUS_OK;
3320 /****************************************************************************
3321 Open a pipe to a remote server.
3322 ****************************************************************************/
3324 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3325 enum dcerpc_transport_t transport,
3326 const struct ndr_syntax_id *interface,
3327 struct rpc_pipe_client **presult)
3329 switch (transport) {
3331 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3334 return rpc_pipe_open_np(cli, interface, presult);
3336 return NT_STATUS_NOT_IMPLEMENTED;
3340 /****************************************************************************
3341 Open a named pipe to an SMB server and bind anonymously.
3342 ****************************************************************************/
3344 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3345 enum dcerpc_transport_t transport,
3346 const struct ndr_syntax_id *interface,
3347 struct rpc_pipe_client **presult)
3349 struct rpc_pipe_client *result;
3350 struct pipe_auth_data *auth;
3353 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3354 if (!NT_STATUS_IS_OK(status)) {
3358 status = rpccli_anon_bind_data(result, &auth);
3359 if (!NT_STATUS_IS_OK(status)) {
3360 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3361 nt_errstr(status)));
3362 TALLOC_FREE(result);
3367 * This is a bit of an abstraction violation due to the fact that an
3368 * anonymous bind on an authenticated SMB inherits the user/domain
3369 * from the enclosing SMB creds
3372 TALLOC_FREE(auth->user_name);
3373 TALLOC_FREE(auth->domain);
3375 auth->user_name = talloc_strdup(auth, cli->user_name);
3376 auth->domain = talloc_strdup(auth, cli->domain);
3377 auth->user_session_key = data_blob_talloc(auth,
3378 cli->user_session_key.data,
3379 cli->user_session_key.length);
3381 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3382 TALLOC_FREE(result);
3383 return NT_STATUS_NO_MEMORY;
3386 status = rpc_pipe_bind(result, auth);
3387 if (!NT_STATUS_IS_OK(status)) {
3389 if (ndr_syntax_id_equal(interface,
3390 &ndr_table_dssetup.syntax_id)) {
3391 /* non AD domains just don't have this pipe, avoid
3392 * level 0 statement in that case - gd */
3395 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3396 "%s failed with error %s\n",
3397 get_pipe_name_from_syntax(talloc_tos(), interface),
3398 nt_errstr(status) ));
3399 TALLOC_FREE(result);
3403 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3404 "%s and bound anonymously.\n",
3405 get_pipe_name_from_syntax(talloc_tos(), interface),
3409 return NT_STATUS_OK;
3412 /****************************************************************************
3413 ****************************************************************************/
3415 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3416 const struct ndr_syntax_id *interface,
3417 struct rpc_pipe_client **presult)
3419 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3420 interface, presult);
3423 /****************************************************************************
3424 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3425 ****************************************************************************/
3427 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3428 const struct ndr_syntax_id *interface,
3429 enum dcerpc_transport_t transport,
3430 enum pipe_auth_type auth_type,
3431 enum dcerpc_AuthLevel auth_level,
3433 const char *username,
3434 const char *password,
3435 struct rpc_pipe_client **presult)
3437 struct rpc_pipe_client *result;
3438 struct pipe_auth_data *auth;
3441 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3442 if (!NT_STATUS_IS_OK(status)) {
3446 status = rpccli_ntlmssp_bind_data(
3447 result, auth_type, auth_level, domain, username,
3449 if (!NT_STATUS_IS_OK(status)) {
3450 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3451 nt_errstr(status)));
3455 status = rpc_pipe_bind(result, auth);
3456 if (!NT_STATUS_IS_OK(status)) {
3457 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3458 nt_errstr(status) ));
3462 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3463 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3464 get_pipe_name_from_syntax(talloc_tos(), interface),
3465 cli->desthost, domain, username ));
3468 return NT_STATUS_OK;
3472 TALLOC_FREE(result);
3476 /****************************************************************************
3478 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3479 ****************************************************************************/
3481 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3482 const struct ndr_syntax_id *interface,
3483 enum dcerpc_transport_t transport,
3484 enum dcerpc_AuthLevel auth_level,
3486 const char *username,
3487 const char *password,
3488 struct rpc_pipe_client **presult)
3490 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3493 PIPE_AUTH_TYPE_NTLMSSP,
3501 /****************************************************************************
3503 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3504 ****************************************************************************/
3506 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3507 const struct ndr_syntax_id *interface,
3508 enum dcerpc_transport_t transport,
3509 enum dcerpc_AuthLevel auth_level,
3511 const char *username,
3512 const char *password,
3513 struct rpc_pipe_client **presult)
3515 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3518 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3526 /****************************************************************************
3527 Get a the schannel session key out of an already opened netlogon pipe.
3528 ****************************************************************************/
3529 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3530 struct cli_state *cli,
3534 enum netr_SchannelType sec_chan_type = 0;
3535 unsigned char machine_pwd[16];
3536 const char *machine_account;
3539 /* Get the machine account credentials from secrets.tdb. */
3540 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3543 DEBUG(0, ("get_schannel_session_key: could not fetch "
3544 "trust account password for domain '%s'\n",
3546 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3549 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3550 cli->desthost, /* server name */
3551 domain, /* domain */
3552 global_myname(), /* client name */
3553 machine_account, /* machine account name */
3558 if (!NT_STATUS_IS_OK(status)) {
3559 DEBUG(3, ("get_schannel_session_key_common: "
3560 "rpccli_netlogon_setup_creds failed with result %s "
3561 "to server %s, domain %s, machine account %s.\n",
3562 nt_errstr(status), cli->desthost, domain,
3567 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3568 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3570 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3573 return NT_STATUS_OK;;
3576 /****************************************************************************
3577 Open a netlogon pipe and get the schannel session key.
3578 Now exposed to external callers.
3579 ****************************************************************************/
3582 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3585 struct rpc_pipe_client **presult)
3587 struct rpc_pipe_client *netlogon_pipe = NULL;
3590 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3592 if (!NT_STATUS_IS_OK(status)) {
3596 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3598 if (!NT_STATUS_IS_OK(status)) {
3599 TALLOC_FREE(netlogon_pipe);
3603 *presult = netlogon_pipe;
3604 return NT_STATUS_OK;
3607 /****************************************************************************
3609 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3610 using session_key. sign and seal.
3612 The *pdc will be stolen onto this new pipe
3613 ****************************************************************************/
3615 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3616 const struct ndr_syntax_id *interface,
3617 enum dcerpc_transport_t transport,
3618 enum dcerpc_AuthLevel auth_level,
3620 struct netlogon_creds_CredentialState **pdc,
3621 struct rpc_pipe_client **presult)
3623 struct rpc_pipe_client *result;
3624 struct pipe_auth_data *auth;
3627 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3628 if (!NT_STATUS_IS_OK(status)) {
3632 status = rpccli_schannel_bind_data(result, domain, auth_level,
3634 if (!NT_STATUS_IS_OK(status)) {
3635 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3636 nt_errstr(status)));
3637 TALLOC_FREE(result);
3641 status = rpc_pipe_bind(result, auth);
3642 if (!NT_STATUS_IS_OK(status)) {
3643 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3644 "cli_rpc_pipe_bind failed with error %s\n",
3645 nt_errstr(status) ));
3646 TALLOC_FREE(result);
3651 * The credentials on a new netlogon pipe are the ones we are passed
3652 * in - reference them in
3654 result->dc = talloc_move(result, pdc);
3656 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3657 "for domain %s and bound using schannel.\n",
3658 get_pipe_name_from_syntax(talloc_tos(), interface),
3659 cli->desthost, domain ));
3662 return NT_STATUS_OK;
3665 /****************************************************************************
3666 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3667 Fetch the session key ourselves using a temporary netlogon pipe. This
3668 version uses an ntlmssp auth bound netlogon pipe to get the key.
3669 ****************************************************************************/
3671 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3673 const char *username,
3674 const char *password,
3676 struct rpc_pipe_client **presult)
3678 struct rpc_pipe_client *netlogon_pipe = NULL;
3681 status = cli_rpc_pipe_open_spnego_ntlmssp(
3682 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3683 DCERPC_AUTH_LEVEL_PRIVACY,
3684 domain, username, password, &netlogon_pipe);
3685 if (!NT_STATUS_IS_OK(status)) {
3689 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3691 if (!NT_STATUS_IS_OK(status)) {
3692 TALLOC_FREE(netlogon_pipe);
3696 *presult = netlogon_pipe;
3697 return NT_STATUS_OK;
3700 /****************************************************************************
3701 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3702 Fetch the session key ourselves using a temporary netlogon pipe. This version
3703 uses an ntlmssp bind to get the session key.
3704 ****************************************************************************/
3706 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3707 const struct ndr_syntax_id *interface,
3708 enum dcerpc_transport_t transport,
3709 enum dcerpc_AuthLevel auth_level,
3711 const char *username,
3712 const char *password,
3713 struct rpc_pipe_client **presult)
3715 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3716 struct rpc_pipe_client *netlogon_pipe = NULL;
3717 struct rpc_pipe_client *result = NULL;
3720 status = get_schannel_session_key_auth_ntlmssp(
3721 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3722 if (!NT_STATUS_IS_OK(status)) {
3723 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3724 "key from server %s for domain %s.\n",
3725 cli->desthost, domain ));
3729 status = cli_rpc_pipe_open_schannel_with_key(
3730 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3733 /* Now we've bound using the session key we can close the netlog pipe. */
3734 TALLOC_FREE(netlogon_pipe);
3736 if (NT_STATUS_IS_OK(status)) {
3742 /****************************************************************************
3743 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3744 Fetch the session key ourselves using a temporary netlogon pipe.
3745 ****************************************************************************/
3747 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3748 const struct ndr_syntax_id *interface,
3749 enum dcerpc_transport_t transport,
3750 enum dcerpc_AuthLevel auth_level,
3752 struct rpc_pipe_client **presult)
3754 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3755 struct rpc_pipe_client *netlogon_pipe = NULL;
3756 struct rpc_pipe_client *result = NULL;
3759 status = get_schannel_session_key(cli, domain, &neg_flags,
3761 if (!NT_STATUS_IS_OK(status)) {
3762 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3763 "key from server %s for domain %s.\n",
3764 cli->desthost, domain ));
3768 status = cli_rpc_pipe_open_schannel_with_key(
3769 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3772 /* Now we've bound using the session key we can close the netlog pipe. */
3773 TALLOC_FREE(netlogon_pipe);
3775 if (NT_STATUS_IS_OK(status)) {
3782 /****************************************************************************
3783 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3784 The idea is this can be called with service_princ, username and password all
3785 NULL so long as the caller has a TGT.
3786 ****************************************************************************/
3788 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3789 const struct ndr_syntax_id *interface,
3790 enum dcerpc_AuthLevel auth_level,
3791 const char *service_princ,
3792 const char *username,
3793 const char *password,
3794 struct rpc_pipe_client **presult)
3797 struct rpc_pipe_client *result;
3798 struct pipe_auth_data *auth;
3801 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
3802 if (!NT_STATUS_IS_OK(status)) {
3806 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3807 username, password, &auth);
3808 if (!NT_STATUS_IS_OK(status)) {
3809 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3810 nt_errstr(status)));
3811 TALLOC_FREE(result);
3815 status = rpc_pipe_bind(result, auth);
3816 if (!NT_STATUS_IS_OK(status)) {
3817 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3818 "with error %s\n", nt_errstr(status)));
3819 TALLOC_FREE(result);
3824 return NT_STATUS_OK;
3826 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3827 return NT_STATUS_NOT_IMPLEMENTED;
3831 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3832 struct rpc_pipe_client *cli,
3833 DATA_BLOB *session_key)
3837 if (!session_key || !cli) {
3838 return NT_STATUS_INVALID_PARAMETER;
3842 return NT_STATUS_INVALID_PARAMETER;
3845 switch (cli->auth->auth_type) {
3846 case PIPE_AUTH_TYPE_SCHANNEL:
3847 *session_key = data_blob_talloc(mem_ctx,
3848 cli->auth->a_u.schannel_auth->creds->session_key, 16);
3850 case PIPE_AUTH_TYPE_NTLMSSP:
3851 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3852 sk = auth_ntlmssp_get_session_key(cli->auth->a_u.auth_ntlmssp_state);
3853 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3855 case PIPE_AUTH_TYPE_KRB5:
3856 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3857 *session_key = data_blob_talloc(mem_ctx,
3858 cli->auth->a_u.kerberos_auth->session_key.data,
3859 cli->auth->a_u.kerberos_auth->session_key.length);
3861 case PIPE_AUTH_TYPE_NONE:
3862 *session_key = data_blob_talloc(mem_ctx,
3863 cli->auth->user_session_key.data,
3864 cli->auth->user_session_key.length);
3867 return NT_STATUS_NO_USER_SESSION_KEY;
3870 return NT_STATUS_OK;