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, a->service_principal, 0,
1292 &tkt, &a->session_key,
1293 AP_OPTS_MUTUAL_REQUIRED, NULL,
1297 DEBUG(1,("create_krb5_auth_bind_req: cli_krb5_get_ticket for principal %s "
1299 a->service_principal,
1300 error_message(ret) ));
1302 data_blob_free(&tkt);
1303 return NT_STATUS_INVALID_PARAMETER;
1306 /* wrap that up in a nice GSS-API wrapping */
1307 tkt_wrapped = spnego_gen_krb5_wrap(talloc_tos(), tkt, TOK_ID_KRB_AP_REQ);
1309 data_blob_free(&tkt);
1311 status = dcerpc_push_dcerpc_auth(cli,
1312 DCERPC_AUTH_TYPE_KRB5,
1314 0, /* auth_pad_length */
1315 1, /* auth_context_id */
1318 if (!NT_STATUS_IS_OK(status)) {
1319 data_blob_free(&tkt_wrapped);
1323 DEBUG(5, ("create_krb5_auth_bind_req: Created krb5 GSS blob :\n"));
1324 dump_data(5, tkt_wrapped.data, tkt_wrapped.length);
1326 return NT_STATUS_OK;
1328 return NT_STATUS_INVALID_PARAMETER;
1332 /*******************************************************************
1333 Creates SPNEGO NTLMSSP auth bind.
1334 ********************************************************************/
1336 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1337 enum dcerpc_AuthLevel auth_level,
1338 DATA_BLOB *auth_info)
1341 DATA_BLOB null_blob = data_blob_null;
1342 DATA_BLOB request = data_blob_null;
1343 DATA_BLOB spnego_msg = data_blob_null;
1344 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1346 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1347 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1351 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1352 data_blob_free(&request);
1356 /* Wrap this in SPNEGO. */
1357 spnego_msg = spnego_gen_negTokenInit(talloc_tos(), OIDs_ntlm, &request, NULL);
1359 data_blob_free(&request);
1361 status = dcerpc_push_dcerpc_auth(cli,
1362 DCERPC_AUTH_TYPE_SPNEGO,
1364 0, /* auth_pad_length */
1365 1, /* auth_context_id */
1369 if (!NT_STATUS_IS_OK(status)) {
1370 data_blob_free(&spnego_msg);
1374 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1375 dump_data(5, spnego_msg.data, spnego_msg.length);
1376 data_blob_free(&spnego_msg);
1378 return NT_STATUS_OK;
1381 /*******************************************************************
1382 Creates NTLMSSP auth bind.
1383 ********************************************************************/
1385 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1386 enum dcerpc_AuthLevel auth_level,
1387 DATA_BLOB *auth_info)
1390 DATA_BLOB null_blob = data_blob_null;
1391 DATA_BLOB request = data_blob_null;
1393 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1394 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1398 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1399 data_blob_free(&request);
1403 status = dcerpc_push_dcerpc_auth(cli,
1404 DCERPC_AUTH_TYPE_NTLMSSP,
1406 0, /* auth_pad_length */
1407 1, /* auth_context_id */
1410 if (!NT_STATUS_IS_OK(status)) {
1411 data_blob_free(&request);
1415 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1416 dump_data(5, request.data, request.length);
1418 return NT_STATUS_OK;
1421 /*******************************************************************
1422 Creates schannel auth bind.
1423 ********************************************************************/
1425 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1426 enum dcerpc_AuthLevel auth_level,
1427 DATA_BLOB *auth_info)
1430 struct NL_AUTH_MESSAGE r;
1431 DATA_BLOB schannel_blob;
1433 /* Use lp_workgroup() if domain not specified */
1435 if (!cli->auth->domain || !cli->auth->domain[0]) {
1436 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1437 if (cli->auth->domain == NULL) {
1438 return NT_STATUS_NO_MEMORY;
1443 * Now marshall the data into the auth parse_struct.
1446 r.MessageType = NL_NEGOTIATE_REQUEST;
1447 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1448 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1449 r.oem_netbios_domain.a = cli->auth->domain;
1450 r.oem_netbios_computer.a = global_myname();
1452 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1453 if (!NT_STATUS_IS_OK(status)) {
1457 status = dcerpc_push_dcerpc_auth(cli,
1458 DCERPC_AUTH_TYPE_SCHANNEL,
1460 0, /* auth_pad_length */
1461 1, /* auth_context_id */
1464 if (!NT_STATUS_IS_OK(status)) {
1468 return NT_STATUS_OK;
1471 /*******************************************************************
1472 Creates the internals of a DCE/RPC bind request or alter context PDU.
1473 ********************************************************************/
1475 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1476 enum dcerpc_pkt_type ptype,
1478 const struct ndr_syntax_id *abstract,
1479 const struct ndr_syntax_id *transfer,
1480 const DATA_BLOB *auth_info,
1483 uint16 auth_len = auth_info->length;
1485 union dcerpc_payload u;
1486 struct dcerpc_ctx_list ctx_list;
1489 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1492 ctx_list.context_id = 0;
1493 ctx_list.num_transfer_syntaxes = 1;
1494 ctx_list.abstract_syntax = *abstract;
1495 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1497 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1498 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1499 u.bind.assoc_group_id = 0x0;
1500 u.bind.num_contexts = 1;
1501 u.bind.ctx_list = &ctx_list;
1502 u.bind.auth_info = *auth_info;
1504 status = dcerpc_push_ncacn_packet(mem_ctx,
1506 DCERPC_PFC_FLAG_FIRST |
1507 DCERPC_PFC_FLAG_LAST,
1512 if (!NT_STATUS_IS_OK(status)) {
1513 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1517 return NT_STATUS_OK;
1520 /*******************************************************************
1521 Creates a DCE/RPC bind request.
1522 ********************************************************************/
1524 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1525 struct rpc_pipe_client *cli,
1527 const struct ndr_syntax_id *abstract,
1528 const struct ndr_syntax_id *transfer,
1529 enum pipe_auth_type auth_type,
1530 enum dcerpc_AuthLevel auth_level,
1533 DATA_BLOB auth_info = data_blob_null;
1534 NTSTATUS ret = NT_STATUS_OK;
1536 switch (auth_type) {
1537 case PIPE_AUTH_TYPE_SCHANNEL:
1538 ret = create_schannel_auth_rpc_bind_req(cli, auth_level, &auth_info);
1539 if (!NT_STATUS_IS_OK(ret)) {
1544 case PIPE_AUTH_TYPE_NTLMSSP:
1545 ret = create_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1546 if (!NT_STATUS_IS_OK(ret)) {
1551 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1552 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli, auth_level, &auth_info);
1553 if (!NT_STATUS_IS_OK(ret)) {
1558 case PIPE_AUTH_TYPE_KRB5:
1559 ret = create_krb5_auth_bind_req(cli, auth_level, &auth_info);
1560 if (!NT_STATUS_IS_OK(ret)) {
1565 case PIPE_AUTH_TYPE_NONE:
1569 /* "Can't" happen. */
1570 return NT_STATUS_INVALID_INFO_CLASS;
1573 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1583 /*******************************************************************
1584 Create and add the NTLMSSP sign/seal auth header and data.
1585 ********************************************************************/
1587 static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state,
1588 enum dcerpc_AuthLevel auth_level,
1591 uint16_t data_and_pad_len = rpc_out->length
1592 - DCERPC_RESPONSE_LENGTH
1593 - DCERPC_AUTH_TRAILER_LENGTH;
1594 DATA_BLOB auth_blob;
1598 return NT_STATUS_INVALID_PARAMETER;
1601 switch (auth_level) {
1602 case DCERPC_AUTH_LEVEL_PRIVACY:
1603 /* Data portion is encrypted. */
1604 status = auth_ntlmssp_seal_packet(auth_state,
1607 + DCERPC_RESPONSE_LENGTH,
1612 if (!NT_STATUS_IS_OK(status)) {
1617 case DCERPC_AUTH_LEVEL_INTEGRITY:
1618 /* Data is signed. */
1619 status = auth_ntlmssp_sign_packet(auth_state,
1622 + DCERPC_RESPONSE_LENGTH,
1627 if (!NT_STATUS_IS_OK(status)) {
1634 smb_panic("bad auth level");
1636 return NT_STATUS_INVALID_PARAMETER;
1639 /* Finally attach the blob. */
1640 if (!data_blob_append(NULL, rpc_out,
1641 auth_blob.data, auth_blob.length)) {
1642 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1643 (unsigned int)auth_blob.length));
1644 return NT_STATUS_NO_MEMORY;
1646 data_blob_free(&auth_blob);
1648 return NT_STATUS_OK;
1651 /*******************************************************************
1652 Create and add the schannel sign/seal auth header and data.
1653 ********************************************************************/
1655 static NTSTATUS add_schannel_auth_footer(struct schannel_state *sas,
1656 enum dcerpc_AuthLevel auth_level,
1659 uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH;
1660 size_t data_and_pad_len = rpc_out->length
1661 - DCERPC_RESPONSE_LENGTH
1662 - DCERPC_AUTH_TRAILER_LENGTH;
1663 DATA_BLOB auth_blob;
1667 return NT_STATUS_INVALID_PARAMETER;
1670 DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
1673 switch (auth_level) {
1674 case DCERPC_AUTH_LEVEL_PRIVACY:
1675 status = netsec_outgoing_packet(sas,
1682 case DCERPC_AUTH_LEVEL_INTEGRITY:
1683 status = netsec_outgoing_packet(sas,
1691 status = NT_STATUS_INTERNAL_ERROR;
1695 if (!NT_STATUS_IS_OK(status)) {
1696 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
1697 nt_errstr(status)));
1701 if (DEBUGLEVEL >= 10) {
1702 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob);
1705 /* Finally attach the blob. */
1706 if (!data_blob_append(NULL, rpc_out,
1707 auth_blob.data, auth_blob.length)) {
1708 return NT_STATUS_NO_MEMORY;
1710 data_blob_free(&auth_blob);
1712 return NT_STATUS_OK;
1715 static NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
1719 enum dcerpc_AuthType auth_type;
1720 char pad[CLIENT_NDR_PADDING_SIZE] = { 0, };
1721 DATA_BLOB auth_info;
1722 DATA_BLOB auth_blob;
1725 if (auth->auth_type == PIPE_AUTH_TYPE_NONE) {
1726 return NT_STATUS_OK;
1730 /* Copy the sign/seal padding data. */
1731 if (!data_blob_append(NULL, rpc_out, pad, pad_len)) {
1732 return NT_STATUS_NO_MEMORY;
1736 auth_type = map_pipe_auth_type_to_rpc_auth_type(auth->auth_type);
1738 /* marshall the dcerpc_auth with an actually empty auth_blob.
1739 * This is needed because the ntmlssp signature includes the
1740 * auth header. We will append the actual blob later. */
1741 auth_blob = data_blob_null;
1742 status = dcerpc_push_dcerpc_auth(rpc_out->data,
1746 1 /* context id. */,
1749 if (!NT_STATUS_IS_OK(status)) {
1753 /* append the header */
1754 if (!data_blob_append(NULL, rpc_out,
1755 auth_info.data, auth_info.length)) {
1756 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
1757 (unsigned int)auth_info.length));
1758 return NT_STATUS_NO_MEMORY;
1760 data_blob_free(&auth_info);
1762 /* Generate any auth sign/seal and add the auth footer. */
1763 switch (auth->auth_type) {
1764 case PIPE_AUTH_TYPE_NONE:
1765 status = NT_STATUS_OK;
1767 case PIPE_AUTH_TYPE_NTLMSSP:
1768 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1769 status = add_ntlmssp_auth_footer(auth->a_u.auth_ntlmssp_state,
1773 case PIPE_AUTH_TYPE_SCHANNEL:
1774 status = add_schannel_auth_footer(auth->a_u.schannel_auth,
1779 status = NT_STATUS_INVALID_PARAMETER;
1786 /*******************************************************************
1787 Calculate how much data we're going to send in this packet, also
1788 work out any sign/seal padding length.
1789 ********************************************************************/
1791 static uint32 calculate_data_len_tosend(struct rpc_pipe_client *cli,
1795 uint32 *p_ss_padding)
1797 uint32 data_space, data_len;
1800 if ((data_left > 0) && (sys_random() % 2)) {
1801 data_left = MAX(data_left/2, 1);
1805 switch (cli->auth->auth_level) {
1806 case DCERPC_AUTH_LEVEL_NONE:
1807 case DCERPC_AUTH_LEVEL_CONNECT:
1808 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1809 data_len = MIN(data_space, data_left);
1812 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1815 case DCERPC_AUTH_LEVEL_INTEGRITY:
1816 case DCERPC_AUTH_LEVEL_PRIVACY:
1817 /* Treat the same for all authenticated rpc requests. */
1818 switch(cli->auth->auth_type) {
1819 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1820 case PIPE_AUTH_TYPE_NTLMSSP:
1821 *p_auth_len = NTLMSSP_SIG_SIZE;
1823 case PIPE_AUTH_TYPE_SCHANNEL:
1824 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1827 smb_panic("bad auth type");
1831 data_space = cli->max_xmit_frag
1832 - DCERPC_REQUEST_LENGTH
1833 - DCERPC_AUTH_TRAILER_LENGTH
1836 data_len = MIN(data_space, data_left);
1838 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1839 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1841 *p_frag_len = DCERPC_REQUEST_LENGTH
1842 + data_len + *p_ss_padding
1843 + DCERPC_AUTH_TRAILER_LENGTH
1848 smb_panic("bad auth level");
1854 /*******************************************************************
1856 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1857 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1858 and deals with signing/sealing details.
1859 ********************************************************************/
1861 struct rpc_api_pipe_req_state {
1862 struct event_context *ev;
1863 struct rpc_pipe_client *cli;
1866 DATA_BLOB *req_data;
1867 uint32_t req_data_sent;
1869 DATA_BLOB reply_pdu;
1872 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1873 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1874 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1875 bool *is_last_frag);
1877 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1878 struct event_context *ev,
1879 struct rpc_pipe_client *cli,
1881 DATA_BLOB *req_data)
1883 struct tevent_req *req, *subreq;
1884 struct rpc_api_pipe_req_state *state;
1888 req = tevent_req_create(mem_ctx, &state,
1889 struct rpc_api_pipe_req_state);
1895 state->op_num = op_num;
1896 state->req_data = req_data;
1897 state->req_data_sent = 0;
1898 state->call_id = get_rpc_call_id();
1899 state->reply_pdu = data_blob_null;
1900 state->rpc_out = data_blob_null;
1902 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1903 + RPC_MAX_SIGN_SIZE) {
1904 /* Server is screwed up ! */
1905 status = NT_STATUS_INVALID_PARAMETER;
1909 status = prepare_next_frag(state, &is_last_frag);
1910 if (!NT_STATUS_IS_OK(status)) {
1915 subreq = rpc_api_pipe_send(state, ev, state->cli,
1917 DCERPC_PKT_RESPONSE);
1918 if (subreq == NULL) {
1921 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1923 subreq = rpc_write_send(state, ev, cli->transport,
1924 state->rpc_out.data,
1925 state->rpc_out.length);
1926 if (subreq == NULL) {
1929 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1935 tevent_req_nterror(req, status);
1936 return tevent_req_post(req, ev);
1942 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1945 uint32_t data_sent_thistime;
1949 uint32_t ss_padding;
1952 union dcerpc_payload u;
1954 data_left = state->req_data->length - state->req_data_sent;
1956 data_sent_thistime = calculate_data_len_tosend(
1957 state->cli, data_left, &frag_len, &auth_len, &ss_padding);
1959 if (state->req_data_sent == 0) {
1960 flags = DCERPC_PFC_FLAG_FIRST;
1963 if (data_sent_thistime == data_left) {
1964 flags |= DCERPC_PFC_FLAG_LAST;
1967 data_blob_free(&state->rpc_out);
1969 ZERO_STRUCT(u.request);
1971 u.request.alloc_hint = state->req_data->length;
1972 u.request.context_id = 0;
1973 u.request.opnum = state->op_num;
1975 status = dcerpc_push_ncacn_packet(state,
1982 if (!NT_STATUS_IS_OK(status)) {
1986 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1987 * compute it right for requests because the auth trailer is missing
1989 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1991 /* Copy in the data. */
1992 if (!data_blob_append(NULL, &state->rpc_out,
1993 state->req_data->data + state->req_data_sent,
1994 data_sent_thistime)) {
1995 return NT_STATUS_NO_MEMORY;
1998 status = dcerpc_add_auth_footer(state->cli->auth, ss_padding,
2000 if (!NT_STATUS_IS_OK(status)) {
2004 state->req_data_sent += data_sent_thistime;
2005 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
2010 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
2012 struct tevent_req *req = tevent_req_callback_data(
2013 subreq, struct tevent_req);
2014 struct rpc_api_pipe_req_state *state = tevent_req_data(
2015 req, struct rpc_api_pipe_req_state);
2019 status = rpc_write_recv(subreq);
2020 TALLOC_FREE(subreq);
2021 if (!NT_STATUS_IS_OK(status)) {
2022 tevent_req_nterror(req, status);
2026 status = prepare_next_frag(state, &is_last_frag);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 tevent_req_nterror(req, status);
2033 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2035 DCERPC_PKT_RESPONSE);
2036 if (tevent_req_nomem(subreq, req)) {
2039 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
2041 subreq = rpc_write_send(state, state->ev,
2042 state->cli->transport,
2043 state->rpc_out.data,
2044 state->rpc_out.length);
2045 if (tevent_req_nomem(subreq, req)) {
2048 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
2053 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
2055 struct tevent_req *req = tevent_req_callback_data(
2056 subreq, struct tevent_req);
2057 struct rpc_api_pipe_req_state *state = tevent_req_data(
2058 req, struct rpc_api_pipe_req_state);
2061 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
2062 TALLOC_FREE(subreq);
2063 if (!NT_STATUS_IS_OK(status)) {
2064 tevent_req_nterror(req, status);
2067 tevent_req_done(req);
2070 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
2071 DATA_BLOB *reply_pdu)
2073 struct rpc_api_pipe_req_state *state = tevent_req_data(
2074 req, struct rpc_api_pipe_req_state);
2077 if (tevent_req_is_nterror(req, &status)) {
2079 * We always have to initialize to reply pdu, even if there is
2080 * none. The rpccli_* caller routines expect this.
2082 *reply_pdu = data_blob_null;
2086 /* return data to caller and assign it ownership of memory */
2087 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
2088 reply_pdu->length = state->reply_pdu.length;
2089 state->reply_pdu.length = 0;
2091 return NT_STATUS_OK;
2095 /****************************************************************************
2096 Set the handle state.
2097 ****************************************************************************/
2099 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
2100 const char *pipe_name, uint16 device_state)
2102 bool state_set = False;
2104 uint16 setup[2]; /* only need 2 uint16 setup parameters */
2105 char *rparam = NULL;
2107 uint32 rparam_len, rdata_len;
2109 if (pipe_name == NULL)
2112 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
2113 cli->fnum, pipe_name, device_state));
2115 /* create parameters: device state */
2116 SSVAL(param, 0, device_state);
2118 /* create setup parameters. */
2120 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
2122 /* send the data on \PIPE\ */
2123 if (cli_api_pipe(cli->cli, "\\PIPE\\",
2124 setup, 2, 0, /* setup, length, max */
2125 param, 2, 0, /* param, length, max */
2126 NULL, 0, 1024, /* data, length, max */
2127 &rparam, &rparam_len, /* return param, length */
2128 &rdata, &rdata_len)) /* return data, length */
2130 DEBUG(5, ("Set Handle state: return OK\n"));
2141 /****************************************************************************
2142 Check the rpc bind acknowledge response.
2143 ****************************************************************************/
2145 static bool check_bind_response(const struct dcerpc_bind_ack *r,
2146 const struct ndr_syntax_id *transfer)
2148 struct dcerpc_ack_ctx ctx;
2150 if (r->secondary_address_size == 0) {
2151 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
2154 if (r->num_results < 1 || !r->ctx_list) {
2158 ctx = r->ctx_list[0];
2160 /* check the transfer syntax */
2161 if ((ctx.syntax.if_version != transfer->if_version) ||
2162 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
2163 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
2167 if (r->num_results != 0x1 || ctx.result != 0) {
2168 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
2169 r->num_results, ctx.reason));
2172 DEBUG(5,("check_bind_response: accepted!\n"));
2176 /*******************************************************************
2177 Creates a DCE/RPC bind authentication response.
2178 This is the packet that is sent back to the server once we
2179 have received a BIND-ACK, to finish the third leg of
2180 the authentication handshake.
2181 ********************************************************************/
2183 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
2184 struct rpc_pipe_client *cli,
2186 enum pipe_auth_type auth_type,
2187 enum dcerpc_AuthLevel auth_level,
2188 DATA_BLOB *pauth_blob,
2192 union dcerpc_payload u;
2196 status = dcerpc_push_dcerpc_auth(mem_ctx,
2197 map_pipe_auth_type_to_rpc_auth_type(auth_type),
2199 0, /* auth_pad_length */
2200 1, /* auth_context_id */
2202 &u.auth3.auth_info);
2203 if (!NT_STATUS_IS_OK(status)) {
2207 status = dcerpc_push_ncacn_packet(mem_ctx,
2209 DCERPC_PFC_FLAG_FIRST |
2210 DCERPC_PFC_FLAG_LAST,
2215 data_blob_free(&u.auth3.auth_info);
2216 if (!NT_STATUS_IS_OK(status)) {
2217 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2221 return NT_STATUS_OK;
2224 /*******************************************************************
2225 Creates a DCE/RPC bind alter context authentication request which
2226 may contain a spnego auth blobl
2227 ********************************************************************/
2229 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
2231 const struct ndr_syntax_id *abstract,
2232 const struct ndr_syntax_id *transfer,
2233 enum dcerpc_AuthLevel auth_level,
2234 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2237 DATA_BLOB auth_info;
2240 status = dcerpc_push_dcerpc_auth(mem_ctx,
2241 DCERPC_AUTH_TYPE_SPNEGO,
2243 0, /* auth_pad_length */
2244 1, /* auth_context_id */
2247 if (!NT_STATUS_IS_OK(status)) {
2251 status = create_bind_or_alt_ctx_internal(mem_ctx,
2258 data_blob_free(&auth_info);
2262 /****************************************************************************
2264 ****************************************************************************/
2266 struct rpc_pipe_bind_state {
2267 struct event_context *ev;
2268 struct rpc_pipe_client *cli;
2270 uint32_t rpc_call_id;
2273 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2274 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2275 struct rpc_pipe_bind_state *state,
2276 struct ncacn_packet *r);
2277 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
2278 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2279 struct rpc_pipe_bind_state *state,
2280 struct ncacn_packet *r,
2281 DATA_BLOB *reply_pdu);
2282 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
2284 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2285 struct event_context *ev,
2286 struct rpc_pipe_client *cli,
2287 struct pipe_auth_data *auth)
2289 struct tevent_req *req, *subreq;
2290 struct rpc_pipe_bind_state *state;
2293 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2298 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2299 rpccli_pipe_txt(talloc_tos(), cli),
2300 (unsigned int)auth->auth_type,
2301 (unsigned int)auth->auth_level ));
2305 state->rpc_call_id = get_rpc_call_id();
2306 state->rpc_out = data_blob_null;
2308 cli->auth = talloc_move(cli, &auth);
2310 /* Marshall the outgoing data. */
2311 status = create_rpc_bind_req(state, cli,
2313 &cli->abstract_syntax,
2314 &cli->transfer_syntax,
2315 cli->auth->auth_type,
2316 cli->auth->auth_level,
2319 if (!NT_STATUS_IS_OK(status)) {
2323 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2324 DCERPC_PKT_BIND_ACK);
2325 if (subreq == NULL) {
2328 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2332 tevent_req_nterror(req, status);
2333 return tevent_req_post(req, ev);
2339 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2341 struct tevent_req *req = tevent_req_callback_data(
2342 subreq, struct tevent_req);
2343 struct rpc_pipe_bind_state *state = tevent_req_data(
2344 req, struct rpc_pipe_bind_state);
2345 DATA_BLOB reply_pdu;
2346 struct ncacn_packet *pkt;
2349 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
2350 TALLOC_FREE(subreq);
2351 if (!NT_STATUS_IS_OK(status)) {
2352 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2353 rpccli_pipe_txt(talloc_tos(), state->cli),
2354 nt_errstr(status)));
2355 tevent_req_nterror(req, status);
2359 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
2360 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2361 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2365 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
2366 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
2369 * For authenticated binds we may need to do 3 or 4 leg binds.
2372 switch(state->cli->auth->auth_type) {
2374 case PIPE_AUTH_TYPE_NONE:
2375 case PIPE_AUTH_TYPE_SCHANNEL:
2376 /* Bind complete. */
2377 tevent_req_done(req);
2380 case PIPE_AUTH_TYPE_NTLMSSP:
2381 /* Need to send AUTH3 packet - no reply. */
2382 status = rpc_finish_auth3_bind_send(req, state, pkt);
2383 if (!NT_STATUS_IS_OK(status)) {
2384 tevent_req_nterror(req, status);
2388 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
2389 /* Need to send alter context request and reply. */
2390 status = rpc_finish_spnego_ntlmssp_bind_send(req, state, pkt,
2392 if (!NT_STATUS_IS_OK(status)) {
2393 tevent_req_nterror(req, status);
2397 case PIPE_AUTH_TYPE_KRB5:
2401 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
2402 (unsigned int)state->cli->auth->auth_type));
2403 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
2407 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
2408 struct rpc_pipe_bind_state *state,
2409 struct ncacn_packet *r)
2411 DATA_BLOB client_reply = data_blob_null;
2412 struct dcerpc_auth auth;
2413 struct tevent_req *subreq;
2416 if ((r->auth_length == 0)
2417 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2418 + r->auth_length)) {
2419 return NT_STATUS_INVALID_PARAMETER;
2422 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
2423 &r->u.bind_ack.auth_info,
2425 if (!NT_STATUS_IS_OK(status)) {
2426 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2427 nt_errstr(status)));
2431 /* TODO - check auth_type/auth_level match. */
2433 status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state,
2434 auth.credentials, &client_reply);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
2438 "blob failed: %s.\n", nt_errstr(status)));
2442 data_blob_free(&state->rpc_out);
2444 status = create_rpc_bind_auth3(state,
2445 state->cli, state->rpc_call_id,
2446 state->cli->auth->auth_type,
2447 state->cli->auth->auth_level,
2448 &client_reply, &state->rpc_out);
2449 data_blob_free(&client_reply);
2451 if (!NT_STATUS_IS_OK(status)) {
2455 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2456 state->rpc_out.data, state->rpc_out.length);
2457 if (subreq == NULL) {
2458 return NT_STATUS_NO_MEMORY;
2460 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2461 return NT_STATUS_OK;
2464 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2466 struct tevent_req *req = tevent_req_callback_data(
2467 subreq, struct tevent_req);
2470 status = rpc_write_recv(subreq);
2471 TALLOC_FREE(subreq);
2472 if (!NT_STATUS_IS_OK(status)) {
2473 tevent_req_nterror(req, status);
2476 tevent_req_done(req);
2479 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2480 struct rpc_pipe_bind_state *state,
2481 struct ncacn_packet *r,
2482 DATA_BLOB *reply_pdu)
2484 DATA_BLOB server_ntlm_response = data_blob_null;
2485 DATA_BLOB client_reply = data_blob_null;
2486 DATA_BLOB tmp_blob = data_blob_null;
2487 struct dcerpc_auth auth_info;
2488 DATA_BLOB auth_blob;
2489 struct tevent_req *subreq;
2492 if ((r->auth_length == 0)
2493 || (r->frag_length < DCERPC_AUTH_TRAILER_LENGTH
2494 + r->auth_length)) {
2495 return NT_STATUS_INVALID_PARAMETER;
2498 /* Process the returned NTLMSSP blob first. */
2499 auth_blob = data_blob_const(reply_pdu->data
2501 - DCERPC_AUTH_TRAILER_LENGTH
2503 DCERPC_AUTH_TRAILER_LENGTH
2506 status = dcerpc_pull_dcerpc_auth(state, &auth_blob, &auth_info, false);
2507 if (!NT_STATUS_IS_OK(status)) {
2508 DEBUG(0, ("Failed to unmarshall dcerpc_auth.\n"));
2513 * The server might give us back two challenges - tmp_blob is for the
2516 if (!spnego_parse_challenge(state, auth_info.credentials,
2517 &server_ntlm_response, &tmp_blob)) {
2518 data_blob_free(&server_ntlm_response);
2519 data_blob_free(&tmp_blob);
2520 return NT_STATUS_INVALID_PARAMETER;
2523 /* We're finished with the server spnego response and the tmp_blob. */
2524 data_blob_free(&tmp_blob);
2526 status = auth_ntlmssp_update(state->cli->auth->a_u.auth_ntlmssp_state,
2527 server_ntlm_response, &client_reply);
2529 /* Finished with the server_ntlm response */
2530 data_blob_free(&server_ntlm_response);
2532 if (!NT_STATUS_IS_OK(status)) {
2533 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2534 "using server blob failed.\n"));
2535 data_blob_free(&client_reply);
2539 /* SPNEGO wrap the client reply. */
2540 tmp_blob = spnego_gen_auth(state, client_reply);
2541 data_blob_free(&client_reply);
2542 client_reply = tmp_blob;
2543 tmp_blob = data_blob_null;
2545 /* Now prepare the alter context pdu. */
2546 data_blob_free(&state->rpc_out);
2548 status = create_rpc_alter_context(state,
2550 &state->cli->abstract_syntax,
2551 &state->cli->transfer_syntax,
2552 state->cli->auth->auth_level,
2555 data_blob_free(&client_reply);
2557 if (!NT_STATUS_IS_OK(status)) {
2561 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2562 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2563 if (subreq == NULL) {
2564 return NT_STATUS_NO_MEMORY;
2566 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2567 return NT_STATUS_OK;
2570 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2572 struct tevent_req *req = tevent_req_callback_data(
2573 subreq, struct tevent_req);
2574 struct rpc_pipe_bind_state *state = tevent_req_data(
2575 req, struct rpc_pipe_bind_state);
2576 DATA_BLOB tmp_blob = data_blob_null;
2577 struct ncacn_packet *pkt;
2578 struct dcerpc_auth auth;
2581 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2582 TALLOC_FREE(subreq);
2583 if (!NT_STATUS_IS_OK(status)) {
2584 tevent_req_nterror(req, status);
2588 status = dcerpc_pull_dcerpc_auth(pkt,
2589 &pkt->u.alter_resp.auth_info,
2591 if (!NT_STATUS_IS_OK(status)) {
2592 tevent_req_nterror(req, status);
2596 /* Check we got a valid auth response. */
2597 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2599 OID_NTLMSSP, &tmp_blob)) {
2600 data_blob_free(&tmp_blob);
2601 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2605 data_blob_free(&tmp_blob);
2607 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2608 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2609 tevent_req_done(req);
2612 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2614 return tevent_req_simple_recv_ntstatus(req);
2617 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2618 struct pipe_auth_data *auth)
2620 TALLOC_CTX *frame = talloc_stackframe();
2621 struct event_context *ev;
2622 struct tevent_req *req;
2623 NTSTATUS status = NT_STATUS_OK;
2625 ev = event_context_init(frame);
2627 status = NT_STATUS_NO_MEMORY;
2631 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2633 status = NT_STATUS_NO_MEMORY;
2637 if (!tevent_req_poll(req, ev)) {
2638 status = map_nt_error_from_unix(errno);
2642 status = rpc_pipe_bind_recv(req);
2648 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2650 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2651 unsigned int timeout)
2655 if (rpc_cli->transport == NULL) {
2656 return RPCCLI_DEFAULT_TIMEOUT;
2659 if (rpc_cli->transport->set_timeout == NULL) {
2660 return RPCCLI_DEFAULT_TIMEOUT;
2663 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2665 return RPCCLI_DEFAULT_TIMEOUT;
2671 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2673 if (rpc_cli == NULL) {
2677 if (rpc_cli->transport == NULL) {
2681 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2684 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2686 struct cli_state *cli;
2688 if ((rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_NTLMSSP)
2689 || (rpc_cli->auth->auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP)) {
2690 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2694 cli = rpc_pipe_np_smb_conn(rpc_cli);
2698 E_md4hash(cli->password ? cli->password : "", nt_hash);
2702 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2703 struct pipe_auth_data **presult)
2705 struct pipe_auth_data *result;
2707 result = talloc(mem_ctx, struct pipe_auth_data);
2708 if (result == NULL) {
2709 return NT_STATUS_NO_MEMORY;
2712 result->auth_type = PIPE_AUTH_TYPE_NONE;
2713 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2715 result->user_name = talloc_strdup(result, "");
2716 result->domain = talloc_strdup(result, "");
2717 if ((result->user_name == NULL) || (result->domain == NULL)) {
2718 TALLOC_FREE(result);
2719 return NT_STATUS_NO_MEMORY;
2723 return NT_STATUS_OK;
2726 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2728 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2732 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2733 enum pipe_auth_type auth_type,
2734 enum dcerpc_AuthLevel auth_level,
2736 const char *username,
2737 const char *password,
2738 struct pipe_auth_data **presult)
2740 struct pipe_auth_data *result;
2743 result = talloc(mem_ctx, struct pipe_auth_data);
2744 if (result == NULL) {
2745 return NT_STATUS_NO_MEMORY;
2748 result->auth_type = auth_type;
2749 result->auth_level = auth_level;
2751 result->user_name = talloc_strdup(result, username);
2752 result->domain = talloc_strdup(result, domain);
2753 if ((result->user_name == NULL) || (result->domain == NULL)) {
2754 status = NT_STATUS_NO_MEMORY;
2758 status = auth_ntlmssp_client_start(NULL,
2761 lp_client_ntlmv2_auth(),
2762 &result->a_u.auth_ntlmssp_state);
2763 if (!NT_STATUS_IS_OK(status)) {
2767 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2769 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2771 if (!NT_STATUS_IS_OK(status)) {
2775 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2777 if (!NT_STATUS_IS_OK(status)) {
2781 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2783 if (!NT_STATUS_IS_OK(status)) {
2788 * Turn off sign+seal to allow selected auth level to turn it back on.
2790 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2791 ~(NTLMSSP_NEGOTIATE_SIGN |
2792 NTLMSSP_NEGOTIATE_SEAL));
2794 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2795 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2796 NTLMSSP_NEGOTIATE_SIGN);
2797 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2798 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2799 NTLMSSP_NEGOTIATE_SEAL |
2800 NTLMSSP_NEGOTIATE_SIGN);
2804 return NT_STATUS_OK;
2807 TALLOC_FREE(result);
2811 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2812 enum dcerpc_AuthLevel auth_level,
2813 struct netlogon_creds_CredentialState *creds,
2814 struct pipe_auth_data **presult)
2816 struct pipe_auth_data *result;
2818 result = talloc(mem_ctx, struct pipe_auth_data);
2819 if (result == NULL) {
2820 return NT_STATUS_NO_MEMORY;
2823 result->auth_type = PIPE_AUTH_TYPE_SCHANNEL;
2824 result->auth_level = auth_level;
2826 result->user_name = talloc_strdup(result, "");
2827 result->domain = talloc_strdup(result, domain);
2828 if ((result->user_name == NULL) || (result->domain == NULL)) {
2832 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2833 if (result->a_u.schannel_auth == NULL) {
2837 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2838 result->a_u.schannel_auth->seq_num = 0;
2839 result->a_u.schannel_auth->initiator = true;
2840 result->a_u.schannel_auth->creds = creds;
2843 return NT_STATUS_OK;
2846 TALLOC_FREE(result);
2847 return NT_STATUS_NO_MEMORY;
2851 static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth)
2853 data_blob_free(&auth->session_key);
2858 static NTSTATUS rpccli_kerberos_bind_data(TALLOC_CTX *mem_ctx,
2859 enum dcerpc_AuthLevel auth_level,
2860 const char *service_princ,
2861 const char *username,
2862 const char *password,
2863 struct pipe_auth_data **presult)
2866 struct pipe_auth_data *result;
2868 if ((username != NULL) && (password != NULL)) {
2869 int ret = kerberos_kinit_password(username, password, 0, NULL);
2871 return NT_STATUS_ACCESS_DENIED;
2875 result = talloc(mem_ctx, struct pipe_auth_data);
2876 if (result == NULL) {
2877 return NT_STATUS_NO_MEMORY;
2880 result->auth_type = PIPE_AUTH_TYPE_KRB5;
2881 result->auth_level = auth_level;
2884 * Username / domain need fixing!
2886 result->user_name = talloc_strdup(result, "");
2887 result->domain = talloc_strdup(result, "");
2888 if ((result->user_name == NULL) || (result->domain == NULL)) {
2892 result->a_u.kerberos_auth = TALLOC_ZERO_P(
2893 result, struct kerberos_auth_struct);
2894 if (result->a_u.kerberos_auth == NULL) {
2897 talloc_set_destructor(result->a_u.kerberos_auth,
2898 cli_auth_kerberos_data_destructor);
2900 result->a_u.kerberos_auth->service_principal = talloc_strdup(
2901 result, service_princ);
2902 if (result->a_u.kerberos_auth->service_principal == NULL) {
2907 return NT_STATUS_OK;
2910 TALLOC_FREE(result);
2911 return NT_STATUS_NO_MEMORY;
2913 return NT_STATUS_NOT_SUPPORTED;
2918 * Create an rpc pipe client struct, connecting to a tcp port.
2920 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2922 const struct ndr_syntax_id *abstract_syntax,
2923 struct rpc_pipe_client **presult)
2925 struct rpc_pipe_client *result;
2926 struct sockaddr_storage addr;
2930 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2931 if (result == NULL) {
2932 return NT_STATUS_NO_MEMORY;
2935 result->abstract_syntax = *abstract_syntax;
2936 result->transfer_syntax = ndr_transfer_syntax;
2937 result->dispatch = cli_do_rpc_ndr;
2938 result->dispatch_send = cli_do_rpc_ndr_send;
2939 result->dispatch_recv = cli_do_rpc_ndr_recv;
2941 result->desthost = talloc_strdup(result, host);
2942 result->srv_name_slash = talloc_asprintf_strupper_m(
2943 result, "\\\\%s", result->desthost);
2944 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2945 status = NT_STATUS_NO_MEMORY;
2949 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2950 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2952 if (!resolve_name(host, &addr, 0, false)) {
2953 status = NT_STATUS_NOT_FOUND;
2957 status = open_socket_out(&addr, port, 60, &fd);
2958 if (!NT_STATUS_IS_OK(status)) {
2961 set_socket_options(fd, lp_socket_options());
2963 status = rpc_transport_sock_init(result, fd, &result->transport);
2964 if (!NT_STATUS_IS_OK(status)) {
2969 result->transport->transport = NCACN_IP_TCP;
2972 return NT_STATUS_OK;
2975 TALLOC_FREE(result);
2980 * Determine the tcp port on which a dcerpc interface is listening
2981 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2984 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2985 const struct ndr_syntax_id *abstract_syntax,
2989 struct rpc_pipe_client *epm_pipe = NULL;
2990 struct pipe_auth_data *auth = NULL;
2991 struct dcerpc_binding *map_binding = NULL;
2992 struct dcerpc_binding *res_binding = NULL;
2993 struct epm_twr_t *map_tower = NULL;
2994 struct epm_twr_t *res_towers = NULL;
2995 struct policy_handle *entry_handle = NULL;
2996 uint32_t num_towers = 0;
2997 uint32_t max_towers = 1;
2998 struct epm_twr_p_t towers;
2999 TALLOC_CTX *tmp_ctx = talloc_stackframe();
3001 if (pport == NULL) {
3002 status = NT_STATUS_INVALID_PARAMETER;
3006 /* open the connection to the endpoint mapper */
3007 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
3008 &ndr_table_epmapper.syntax_id,
3011 if (!NT_STATUS_IS_OK(status)) {
3015 status = rpccli_anon_bind_data(tmp_ctx, &auth);
3016 if (!NT_STATUS_IS_OK(status)) {
3020 status = rpc_pipe_bind(epm_pipe, auth);
3021 if (!NT_STATUS_IS_OK(status)) {
3025 /* create tower for asking the epmapper */
3027 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
3028 if (map_binding == NULL) {
3029 status = NT_STATUS_NO_MEMORY;
3033 map_binding->transport = NCACN_IP_TCP;
3034 map_binding->object = *abstract_syntax;
3035 map_binding->host = host; /* needed? */
3036 map_binding->endpoint = "0"; /* correct? needed? */
3038 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
3039 if (map_tower == NULL) {
3040 status = NT_STATUS_NO_MEMORY;
3044 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
3045 &(map_tower->tower));
3046 if (!NT_STATUS_IS_OK(status)) {
3050 /* allocate further parameters for the epm_Map call */
3052 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
3053 if (res_towers == NULL) {
3054 status = NT_STATUS_NO_MEMORY;
3057 towers.twr = res_towers;
3059 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
3060 if (entry_handle == NULL) {
3061 status = NT_STATUS_NO_MEMORY;
3065 /* ask the endpoint mapper for the port */
3067 status = rpccli_epm_Map(epm_pipe,
3069 CONST_DISCARD(struct GUID *,
3070 &(abstract_syntax->uuid)),
3077 if (!NT_STATUS_IS_OK(status)) {
3081 if (num_towers != 1) {
3082 status = NT_STATUS_UNSUCCESSFUL;
3086 /* extract the port from the answer */
3088 status = dcerpc_binding_from_tower(tmp_ctx,
3089 &(towers.twr->tower),
3091 if (!NT_STATUS_IS_OK(status)) {
3095 /* are further checks here necessary? */
3096 if (res_binding->transport != NCACN_IP_TCP) {
3097 status = NT_STATUS_UNSUCCESSFUL;
3101 *pport = (uint16_t)atoi(res_binding->endpoint);
3104 TALLOC_FREE(tmp_ctx);
3109 * Create a rpc pipe client struct, connecting to a host via tcp.
3110 * The port is determined by asking the endpoint mapper on the given
3113 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
3114 const struct ndr_syntax_id *abstract_syntax,
3115 struct rpc_pipe_client **presult)
3120 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
3121 if (!NT_STATUS_IS_OK(status)) {
3125 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
3126 abstract_syntax, presult);
3129 /********************************************************************
3130 Create a rpc pipe client struct, connecting to a unix domain socket
3131 ********************************************************************/
3132 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
3133 const struct ndr_syntax_id *abstract_syntax,
3134 struct rpc_pipe_client **presult)
3136 struct rpc_pipe_client *result;
3137 struct sockaddr_un addr;
3141 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3142 if (result == NULL) {
3143 return NT_STATUS_NO_MEMORY;
3146 result->abstract_syntax = *abstract_syntax;
3147 result->transfer_syntax = ndr_transfer_syntax;
3148 result->dispatch = cli_do_rpc_ndr;
3149 result->dispatch_send = cli_do_rpc_ndr_send;
3150 result->dispatch_recv = cli_do_rpc_ndr_recv;
3152 result->desthost = get_myname(result);
3153 result->srv_name_slash = talloc_asprintf_strupper_m(
3154 result, "\\\\%s", result->desthost);
3155 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3156 status = NT_STATUS_NO_MEMORY;
3160 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3161 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3163 fd = socket(AF_UNIX, SOCK_STREAM, 0);
3165 status = map_nt_error_from_unix(errno);
3170 addr.sun_family = AF_UNIX;
3171 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
3173 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
3174 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
3177 return map_nt_error_from_unix(errno);
3180 status = rpc_transport_sock_init(result, fd, &result->transport);
3181 if (!NT_STATUS_IS_OK(status)) {
3186 result->transport->transport = NCALRPC;
3189 return NT_STATUS_OK;
3192 TALLOC_FREE(result);
3196 struct rpc_pipe_client_np_ref {
3197 struct cli_state *cli;
3198 struct rpc_pipe_client *pipe;
3201 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3203 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3207 /****************************************************************************
3208 Open a named pipe over SMB to a remote server.
3210 * CAVEAT CALLER OF THIS FUNCTION:
3211 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3212 * so be sure that this function is called AFTER any structure (vs pointer)
3213 * assignment of the cli. In particular, libsmbclient does structure
3214 * assignments of cli, which invalidates the data in the returned
3215 * rpc_pipe_client if this function is called before the structure assignment
3218 ****************************************************************************/
3220 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3221 const struct ndr_syntax_id *abstract_syntax,
3222 struct rpc_pipe_client **presult)
3224 struct rpc_pipe_client *result;
3226 struct rpc_pipe_client_np_ref *np_ref;
3228 /* sanity check to protect against crashes */
3231 return NT_STATUS_INVALID_HANDLE;
3234 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
3235 if (result == NULL) {
3236 return NT_STATUS_NO_MEMORY;
3239 result->abstract_syntax = *abstract_syntax;
3240 result->transfer_syntax = ndr_transfer_syntax;
3241 result->dispatch = cli_do_rpc_ndr;
3242 result->dispatch_send = cli_do_rpc_ndr_send;
3243 result->dispatch_recv = cli_do_rpc_ndr_recv;
3244 result->desthost = talloc_strdup(result, cli->desthost);
3245 result->srv_name_slash = talloc_asprintf_strupper_m(
3246 result, "\\\\%s", result->desthost);
3248 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3249 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3251 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3252 TALLOC_FREE(result);
3253 return NT_STATUS_NO_MEMORY;
3256 status = rpc_transport_np_init(result, cli, abstract_syntax,
3257 &result->transport);
3258 if (!NT_STATUS_IS_OK(status)) {
3259 TALLOC_FREE(result);
3263 result->transport->transport = NCACN_NP;
3265 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3266 if (np_ref == NULL) {
3267 TALLOC_FREE(result);
3268 return NT_STATUS_NO_MEMORY;
3271 np_ref->pipe = result;
3273 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3274 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3277 return NT_STATUS_OK;
3280 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
3281 struct rpc_cli_smbd_conn *conn,
3282 const struct ndr_syntax_id *syntax,
3283 struct rpc_pipe_client **presult)
3285 struct rpc_pipe_client *result;
3286 struct pipe_auth_data *auth;
3289 result = talloc(mem_ctx, struct rpc_pipe_client);
3290 if (result == NULL) {
3291 return NT_STATUS_NO_MEMORY;
3293 result->abstract_syntax = *syntax;
3294 result->transfer_syntax = ndr_transfer_syntax;
3295 result->dispatch = cli_do_rpc_ndr;
3296 result->dispatch_send = cli_do_rpc_ndr_send;
3297 result->dispatch_recv = cli_do_rpc_ndr_recv;
3298 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3299 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
3301 result->desthost = talloc_strdup(result, global_myname());
3302 result->srv_name_slash = talloc_asprintf_strupper_m(
3303 result, "\\\\%s", global_myname());
3304 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
3305 TALLOC_FREE(result);
3306 return NT_STATUS_NO_MEMORY;
3309 status = rpc_transport_smbd_init(result, conn, syntax,
3310 &result->transport);
3311 if (!NT_STATUS_IS_OK(status)) {
3312 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
3313 nt_errstr(status)));
3314 TALLOC_FREE(result);
3318 status = rpccli_anon_bind_data(result, &auth);
3319 if (!NT_STATUS_IS_OK(status)) {
3320 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
3321 nt_errstr(status)));
3322 TALLOC_FREE(result);
3326 status = rpc_pipe_bind(result, auth);
3327 if (!NT_STATUS_IS_OK(status)) {
3328 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
3329 TALLOC_FREE(result);
3333 result->transport->transport = NCACN_INTERNAL;
3336 return NT_STATUS_OK;
3339 /****************************************************************************
3340 Open a pipe to a remote server.
3341 ****************************************************************************/
3343 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3344 enum dcerpc_transport_t transport,
3345 const struct ndr_syntax_id *interface,
3346 struct rpc_pipe_client **presult)
3348 switch (transport) {
3350 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
3353 return rpc_pipe_open_np(cli, interface, presult);
3355 return NT_STATUS_NOT_IMPLEMENTED;
3359 /****************************************************************************
3360 Open a named pipe to an SMB server and bind anonymously.
3361 ****************************************************************************/
3363 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3364 enum dcerpc_transport_t transport,
3365 const struct ndr_syntax_id *interface,
3366 struct rpc_pipe_client **presult)
3368 struct rpc_pipe_client *result;
3369 struct pipe_auth_data *auth;
3372 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3373 if (!NT_STATUS_IS_OK(status)) {
3377 status = rpccli_anon_bind_data(result, &auth);
3378 if (!NT_STATUS_IS_OK(status)) {
3379 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3380 nt_errstr(status)));
3381 TALLOC_FREE(result);
3386 * This is a bit of an abstraction violation due to the fact that an
3387 * anonymous bind on an authenticated SMB inherits the user/domain
3388 * from the enclosing SMB creds
3391 TALLOC_FREE(auth->user_name);
3392 TALLOC_FREE(auth->domain);
3394 auth->user_name = talloc_strdup(auth, cli->user_name);
3395 auth->domain = talloc_strdup(auth, cli->domain);
3396 auth->user_session_key = data_blob_talloc(auth,
3397 cli->user_session_key.data,
3398 cli->user_session_key.length);
3400 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
3401 TALLOC_FREE(result);
3402 return NT_STATUS_NO_MEMORY;
3405 status = rpc_pipe_bind(result, auth);
3406 if (!NT_STATUS_IS_OK(status)) {
3408 if (ndr_syntax_id_equal(interface,
3409 &ndr_table_dssetup.syntax_id)) {
3410 /* non AD domains just don't have this pipe, avoid
3411 * level 0 statement in that case - gd */
3414 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3415 "%s failed with error %s\n",
3416 get_pipe_name_from_syntax(talloc_tos(), interface),
3417 nt_errstr(status) ));
3418 TALLOC_FREE(result);
3422 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3423 "%s and bound anonymously.\n",
3424 get_pipe_name_from_syntax(talloc_tos(), interface),
3428 return NT_STATUS_OK;
3431 /****************************************************************************
3432 ****************************************************************************/
3434 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3435 const struct ndr_syntax_id *interface,
3436 struct rpc_pipe_client **presult)
3438 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3439 interface, presult);
3442 /****************************************************************************
3443 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
3444 ****************************************************************************/
3446 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
3447 const struct ndr_syntax_id *interface,
3448 enum dcerpc_transport_t transport,
3449 enum pipe_auth_type auth_type,
3450 enum dcerpc_AuthLevel auth_level,
3452 const char *username,
3453 const char *password,
3454 struct rpc_pipe_client **presult)
3456 struct rpc_pipe_client *result;
3457 struct pipe_auth_data *auth;
3460 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3461 if (!NT_STATUS_IS_OK(status)) {
3465 status = rpccli_ntlmssp_bind_data(
3466 result, auth_type, auth_level, domain, username,
3468 if (!NT_STATUS_IS_OK(status)) {
3469 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3470 nt_errstr(status)));
3474 status = rpc_pipe_bind(result, auth);
3475 if (!NT_STATUS_IS_OK(status)) {
3476 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3477 nt_errstr(status) ));
3481 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3482 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3483 get_pipe_name_from_syntax(talloc_tos(), interface),
3484 cli->desthost, domain, username ));
3487 return NT_STATUS_OK;
3491 TALLOC_FREE(result);
3495 /****************************************************************************
3497 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3498 ****************************************************************************/
3500 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3501 const struct ndr_syntax_id *interface,
3502 enum dcerpc_transport_t transport,
3503 enum dcerpc_AuthLevel auth_level,
3505 const char *username,
3506 const char *password,
3507 struct rpc_pipe_client **presult)
3509 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3512 PIPE_AUTH_TYPE_NTLMSSP,
3520 /****************************************************************************
3522 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3523 ****************************************************************************/
3525 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3526 const struct ndr_syntax_id *interface,
3527 enum dcerpc_transport_t transport,
3528 enum dcerpc_AuthLevel auth_level,
3530 const char *username,
3531 const char *password,
3532 struct rpc_pipe_client **presult)
3534 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3537 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP,
3545 /****************************************************************************
3546 Get a the schannel session key out of an already opened netlogon pipe.
3547 ****************************************************************************/
3548 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3549 struct cli_state *cli,
3553 enum netr_SchannelType sec_chan_type = 0;
3554 unsigned char machine_pwd[16];
3555 const char *machine_account;
3558 /* Get the machine account credentials from secrets.tdb. */
3559 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3562 DEBUG(0, ("get_schannel_session_key: could not fetch "
3563 "trust account password for domain '%s'\n",
3565 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3568 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3569 cli->desthost, /* server name */
3570 domain, /* domain */
3571 global_myname(), /* client name */
3572 machine_account, /* machine account name */
3577 if (!NT_STATUS_IS_OK(status)) {
3578 DEBUG(3, ("get_schannel_session_key_common: "
3579 "rpccli_netlogon_setup_creds failed with result %s "
3580 "to server %s, domain %s, machine account %s.\n",
3581 nt_errstr(status), cli->desthost, domain,
3586 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3587 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3589 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3592 return NT_STATUS_OK;;
3595 /****************************************************************************
3596 Open a netlogon pipe and get the schannel session key.
3597 Now exposed to external callers.
3598 ****************************************************************************/
3601 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3604 struct rpc_pipe_client **presult)
3606 struct rpc_pipe_client *netlogon_pipe = NULL;
3609 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3611 if (!NT_STATUS_IS_OK(status)) {
3615 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3617 if (!NT_STATUS_IS_OK(status)) {
3618 TALLOC_FREE(netlogon_pipe);
3622 *presult = netlogon_pipe;
3623 return NT_STATUS_OK;
3626 /****************************************************************************
3628 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3629 using session_key. sign and seal.
3631 The *pdc will be stolen onto this new pipe
3632 ****************************************************************************/
3634 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3635 const struct ndr_syntax_id *interface,
3636 enum dcerpc_transport_t transport,
3637 enum dcerpc_AuthLevel auth_level,
3639 struct netlogon_creds_CredentialState **pdc,
3640 struct rpc_pipe_client **presult)
3642 struct rpc_pipe_client *result;
3643 struct pipe_auth_data *auth;
3646 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3647 if (!NT_STATUS_IS_OK(status)) {
3651 status = rpccli_schannel_bind_data(result, domain, auth_level,
3653 if (!NT_STATUS_IS_OK(status)) {
3654 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3655 nt_errstr(status)));
3656 TALLOC_FREE(result);
3660 status = rpc_pipe_bind(result, auth);
3661 if (!NT_STATUS_IS_OK(status)) {
3662 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3663 "cli_rpc_pipe_bind failed with error %s\n",
3664 nt_errstr(status) ));
3665 TALLOC_FREE(result);
3670 * The credentials on a new netlogon pipe are the ones we are passed
3671 * in - reference them in
3673 result->dc = talloc_move(result, pdc);
3675 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3676 "for domain %s and bound using schannel.\n",
3677 get_pipe_name_from_syntax(talloc_tos(), interface),
3678 cli->desthost, domain ));
3681 return NT_STATUS_OK;
3684 /****************************************************************************
3685 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3686 Fetch the session key ourselves using a temporary netlogon pipe. This
3687 version uses an ntlmssp auth bound netlogon pipe to get the key.
3688 ****************************************************************************/
3690 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3692 const char *username,
3693 const char *password,
3695 struct rpc_pipe_client **presult)
3697 struct rpc_pipe_client *netlogon_pipe = NULL;
3700 status = cli_rpc_pipe_open_spnego_ntlmssp(
3701 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3702 DCERPC_AUTH_LEVEL_PRIVACY,
3703 domain, username, password, &netlogon_pipe);
3704 if (!NT_STATUS_IS_OK(status)) {
3708 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3710 if (!NT_STATUS_IS_OK(status)) {
3711 TALLOC_FREE(netlogon_pipe);
3715 *presult = netlogon_pipe;
3716 return NT_STATUS_OK;
3719 /****************************************************************************
3720 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3721 Fetch the session key ourselves using a temporary netlogon pipe. This version
3722 uses an ntlmssp bind to get the session key.
3723 ****************************************************************************/
3725 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3726 const struct ndr_syntax_id *interface,
3727 enum dcerpc_transport_t transport,
3728 enum dcerpc_AuthLevel auth_level,
3730 const char *username,
3731 const char *password,
3732 struct rpc_pipe_client **presult)
3734 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3735 struct rpc_pipe_client *netlogon_pipe = NULL;
3736 struct rpc_pipe_client *result = NULL;
3739 status = get_schannel_session_key_auth_ntlmssp(
3740 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3741 if (!NT_STATUS_IS_OK(status)) {
3742 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3743 "key from server %s for domain %s.\n",
3744 cli->desthost, domain ));
3748 status = cli_rpc_pipe_open_schannel_with_key(
3749 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3752 /* Now we've bound using the session key we can close the netlog pipe. */
3753 TALLOC_FREE(netlogon_pipe);
3755 if (NT_STATUS_IS_OK(status)) {
3761 /****************************************************************************
3762 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3763 Fetch the session key ourselves using a temporary netlogon pipe.
3764 ****************************************************************************/
3766 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3767 const struct ndr_syntax_id *interface,
3768 enum dcerpc_transport_t transport,
3769 enum dcerpc_AuthLevel auth_level,
3771 struct rpc_pipe_client **presult)
3773 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3774 struct rpc_pipe_client *netlogon_pipe = NULL;
3775 struct rpc_pipe_client *result = NULL;
3778 status = get_schannel_session_key(cli, domain, &neg_flags,
3780 if (!NT_STATUS_IS_OK(status)) {
3781 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3782 "key from server %s for domain %s.\n",
3783 cli->desthost, domain ));
3787 status = cli_rpc_pipe_open_schannel_with_key(
3788 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3791 /* Now we've bound using the session key we can close the netlog pipe. */
3792 TALLOC_FREE(netlogon_pipe);
3794 if (NT_STATUS_IS_OK(status)) {
3801 /****************************************************************************
3802 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3803 The idea is this can be called with service_princ, username and password all
3804 NULL so long as the caller has a TGT.
3805 ****************************************************************************/
3807 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3808 const struct ndr_syntax_id *interface,
3809 enum dcerpc_AuthLevel auth_level,
3810 const char *service_princ,
3811 const char *username,
3812 const char *password,
3813 struct rpc_pipe_client **presult)
3816 struct rpc_pipe_client *result;
3817 struct pipe_auth_data *auth;
3820 status = cli_rpc_pipe_open(cli, NCACN_NP, interface, &result);
3821 if (!NT_STATUS_IS_OK(status)) {
3825 status = rpccli_kerberos_bind_data(result, auth_level, service_princ,
3826 username, password, &auth);
3827 if (!NT_STATUS_IS_OK(status)) {
3828 DEBUG(0, ("rpccli_kerberos_bind_data returned %s\n",
3829 nt_errstr(status)));
3830 TALLOC_FREE(result);
3834 status = rpc_pipe_bind(result, auth);
3835 if (!NT_STATUS_IS_OK(status)) {
3836 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3837 "with error %s\n", nt_errstr(status)));
3838 TALLOC_FREE(result);
3843 return NT_STATUS_OK;
3845 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3846 return NT_STATUS_NOT_IMPLEMENTED;
3850 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3851 struct rpc_pipe_client *cli,
3852 DATA_BLOB *session_key)
3854 struct pipe_auth_data *a = cli->auth;
3857 if (!session_key || !cli) {
3858 return NT_STATUS_INVALID_PARAMETER;
3862 return NT_STATUS_INVALID_PARAMETER;
3865 switch (cli->auth->auth_type) {
3866 case PIPE_AUTH_TYPE_SCHANNEL:
3867 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3870 case PIPE_AUTH_TYPE_NTLMSSP:
3871 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3872 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3874 case PIPE_AUTH_TYPE_KRB5:
3875 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3876 sk = data_blob_const(a->a_u.kerberos_auth->session_key.data,
3877 a->a_u.kerberos_auth->session_key.length);
3879 case PIPE_AUTH_TYPE_NONE:
3880 sk = data_blob_const(a->user_session_key.data,
3881 a->user_session_key.length);
3884 return NT_STATUS_NO_USER_SESSION_KEY;
3887 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3888 return NT_STATUS_OK;