s4-vampire: Fix the output of fetched object for the schema-dn
[Samba/gebeck_regimport.git] / source3 / rpc_client / cli_pipe.c
blob8ee14d62621ad4d41cff3acbaed3354560ef7edb
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client routines
4 * Largely rewritten by Jeremy Allison 2005.
5 * Heavily modified by Simo Sorce 2010.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "../lib/util/tevent_ntstatus.h"
23 #include "librpc/gen_ndr/ndr_epmapper_c.h"
24 #include "../librpc/gen_ndr/ndr_schannel.h"
25 #include "../librpc/gen_ndr/ndr_dssetup.h"
26 #include "../libcli/auth/schannel.h"
27 #include "../libcli/auth/spnego.h"
28 #include "../auth/ntlmssp/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "librpc/gen_ndr/ndr_dcerpc.h"
31 #include "librpc/rpc/dcerpc.h"
32 #include "librpc/crypto/gse.h"
33 #include "librpc/crypto/spnego.h"
34 #include "rpc_dce.h"
35 #include "cli_pipe.h"
36 #include "libsmb/libsmb.h"
37 #include "auth/gensec/gensec.h"
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_RPC_CLI
42 /********************************************************************
43 Pipe description for a DEBUG
44 ********************************************************************/
45 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
46 struct rpc_pipe_client *cli)
48 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
49 if (result == NULL) {
50 return "pipe";
52 return result;
55 /********************************************************************
56 Rpc pipe call id.
57 ********************************************************************/
59 static uint32 get_rpc_call_id(void)
61 static uint32 call_id = 0;
62 return ++call_id;
65 /*******************************************************************
66 Use SMBreadX to get rest of one fragment's worth of rpc data.
67 Reads the whole size or give an error message
68 ********************************************************************/
70 struct rpc_read_state {
71 struct event_context *ev;
72 struct rpc_cli_transport *transport;
73 uint8_t *data;
74 size_t size;
75 size_t num_read;
78 static void rpc_read_done(struct tevent_req *subreq);
80 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
81 struct event_context *ev,
82 struct rpc_cli_transport *transport,
83 uint8_t *data, size_t size)
85 struct tevent_req *req, *subreq;
86 struct rpc_read_state *state;
88 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
89 if (req == NULL) {
90 return NULL;
92 state->ev = ev;
93 state->transport = transport;
94 state->data = data;
95 state->size = size;
96 state->num_read = 0;
98 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
100 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
101 transport->priv);
102 if (subreq == NULL) {
103 goto fail;
105 tevent_req_set_callback(subreq, rpc_read_done, req);
106 return req;
108 fail:
109 TALLOC_FREE(req);
110 return NULL;
113 static void rpc_read_done(struct tevent_req *subreq)
115 struct tevent_req *req = tevent_req_callback_data(
116 subreq, struct tevent_req);
117 struct rpc_read_state *state = tevent_req_data(
118 req, struct rpc_read_state);
119 NTSTATUS status;
120 ssize_t received;
122 status = state->transport->read_recv(subreq, &received);
123 TALLOC_FREE(subreq);
124 if (!NT_STATUS_IS_OK(status)) {
125 tevent_req_nterror(req, status);
126 return;
129 state->num_read += received;
130 if (state->num_read == state->size) {
131 tevent_req_done(req);
132 return;
135 subreq = state->transport->read_send(state, state->ev,
136 state->data + state->num_read,
137 state->size - state->num_read,
138 state->transport->priv);
139 if (tevent_req_nomem(subreq, req)) {
140 return;
142 tevent_req_set_callback(subreq, rpc_read_done, req);
145 static NTSTATUS rpc_read_recv(struct tevent_req *req)
147 return tevent_req_simple_recv_ntstatus(req);
150 struct rpc_write_state {
151 struct event_context *ev;
152 struct rpc_cli_transport *transport;
153 const uint8_t *data;
154 size_t size;
155 size_t num_written;
158 static void rpc_write_done(struct tevent_req *subreq);
160 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
161 struct event_context *ev,
162 struct rpc_cli_transport *transport,
163 const uint8_t *data, size_t size)
165 struct tevent_req *req, *subreq;
166 struct rpc_write_state *state;
168 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
169 if (req == NULL) {
170 return NULL;
172 state->ev = ev;
173 state->transport = transport;
174 state->data = data;
175 state->size = size;
176 state->num_written = 0;
178 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
180 subreq = transport->write_send(state, ev, data, size, transport->priv);
181 if (subreq == NULL) {
182 goto fail;
184 tevent_req_set_callback(subreq, rpc_write_done, req);
185 return req;
186 fail:
187 TALLOC_FREE(req);
188 return NULL;
191 static void rpc_write_done(struct tevent_req *subreq)
193 struct tevent_req *req = tevent_req_callback_data(
194 subreq, struct tevent_req);
195 struct rpc_write_state *state = tevent_req_data(
196 req, struct rpc_write_state);
197 NTSTATUS status;
198 ssize_t written;
200 status = state->transport->write_recv(subreq, &written);
201 TALLOC_FREE(subreq);
202 if (!NT_STATUS_IS_OK(status)) {
203 tevent_req_nterror(req, status);
204 return;
207 state->num_written += written;
209 if (state->num_written == state->size) {
210 tevent_req_done(req);
211 return;
214 subreq = state->transport->write_send(state, state->ev,
215 state->data + state->num_written,
216 state->size - state->num_written,
217 state->transport->priv);
218 if (tevent_req_nomem(subreq, req)) {
219 return;
221 tevent_req_set_callback(subreq, rpc_write_done, req);
224 static NTSTATUS rpc_write_recv(struct tevent_req *req)
226 return tevent_req_simple_recv_ntstatus(req);
230 /****************************************************************************
231 Try and get a PDU's worth of data from current_pdu. If not, then read more
232 from the wire.
233 ****************************************************************************/
235 struct get_complete_frag_state {
236 struct event_context *ev;
237 struct rpc_pipe_client *cli;
238 uint16_t frag_len;
239 DATA_BLOB *pdu;
242 static void get_complete_frag_got_header(struct tevent_req *subreq);
243 static void get_complete_frag_got_rest(struct tevent_req *subreq);
245 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
246 struct event_context *ev,
247 struct rpc_pipe_client *cli,
248 DATA_BLOB *pdu)
250 struct tevent_req *req, *subreq;
251 struct get_complete_frag_state *state;
252 size_t received;
253 NTSTATUS status;
255 req = tevent_req_create(mem_ctx, &state,
256 struct get_complete_frag_state);
257 if (req == NULL) {
258 return NULL;
260 state->ev = ev;
261 state->cli = cli;
262 state->frag_len = RPC_HEADER_LEN;
263 state->pdu = pdu;
265 received = pdu->length;
266 if (received < RPC_HEADER_LEN) {
267 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
268 status = NT_STATUS_NO_MEMORY;
269 goto post_status;
271 subreq = rpc_read_send(state, state->ev,
272 state->cli->transport,
273 pdu->data + received,
274 RPC_HEADER_LEN - received);
275 if (subreq == NULL) {
276 status = NT_STATUS_NO_MEMORY;
277 goto post_status;
279 tevent_req_set_callback(subreq, get_complete_frag_got_header,
280 req);
281 return req;
284 state->frag_len = dcerpc_get_frag_length(pdu);
287 * Ensure we have frag_len bytes of data.
289 if (received < state->frag_len) {
290 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
291 status = NT_STATUS_NO_MEMORY;
292 goto post_status;
294 subreq = rpc_read_send(state, state->ev,
295 state->cli->transport,
296 pdu->data + received,
297 state->frag_len - received);
298 if (subreq == NULL) {
299 status = NT_STATUS_NO_MEMORY;
300 goto post_status;
302 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
303 req);
304 return req;
307 status = NT_STATUS_OK;
308 post_status:
309 if (NT_STATUS_IS_OK(status)) {
310 tevent_req_done(req);
311 } else {
312 tevent_req_nterror(req, status);
314 return tevent_req_post(req, ev);
317 static void get_complete_frag_got_header(struct tevent_req *subreq)
319 struct tevent_req *req = tevent_req_callback_data(
320 subreq, struct tevent_req);
321 struct get_complete_frag_state *state = tevent_req_data(
322 req, struct get_complete_frag_state);
323 NTSTATUS status;
325 status = rpc_read_recv(subreq);
326 TALLOC_FREE(subreq);
327 if (!NT_STATUS_IS_OK(status)) {
328 tevent_req_nterror(req, status);
329 return;
332 state->frag_len = dcerpc_get_frag_length(state->pdu);
334 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
335 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
336 return;
340 * We're here in this piece of code because we've read exactly
341 * RPC_HEADER_LEN bytes into state->pdu.
344 subreq = rpc_read_send(state, state->ev, state->cli->transport,
345 state->pdu->data + RPC_HEADER_LEN,
346 state->frag_len - RPC_HEADER_LEN);
347 if (tevent_req_nomem(subreq, req)) {
348 return;
350 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
353 static void get_complete_frag_got_rest(struct tevent_req *subreq)
355 struct tevent_req *req = tevent_req_callback_data(
356 subreq, struct tevent_req);
357 NTSTATUS status;
359 status = rpc_read_recv(subreq);
360 TALLOC_FREE(subreq);
361 if (!NT_STATUS_IS_OK(status)) {
362 tevent_req_nterror(req, status);
363 return;
365 tevent_req_done(req);
368 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
370 return tevent_req_simple_recv_ntstatus(req);
373 /****************************************************************************
374 Do basic authentication checks on an incoming pdu.
375 ****************************************************************************/
377 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
378 struct rpc_pipe_client *cli,
379 struct ncacn_packet *pkt,
380 DATA_BLOB *pdu,
381 uint8_t expected_pkt_type,
382 DATA_BLOB *rdata,
383 DATA_BLOB *reply_pdu)
385 struct dcerpc_response *r;
386 NTSTATUS ret = NT_STATUS_OK;
387 size_t pad_len = 0;
390 * Point the return values at the real data including the RPC
391 * header. Just in case the caller wants it.
393 *rdata = *pdu;
395 /* Ensure we have the correct type. */
396 switch (pkt->ptype) {
397 case DCERPC_PKT_ALTER_RESP:
398 case DCERPC_PKT_BIND_ACK:
400 /* Client code never receives this kind of packets */
401 break;
404 case DCERPC_PKT_RESPONSE:
406 r = &pkt->u.response;
408 /* Here's where we deal with incoming sign/seal. */
409 ret = dcerpc_check_auth(cli->auth, pkt,
410 &r->stub_and_verifier,
411 DCERPC_RESPONSE_LENGTH,
412 pdu, &pad_len);
413 if (!NT_STATUS_IS_OK(ret)) {
414 return ret;
417 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
418 return NT_STATUS_BUFFER_TOO_SMALL;
421 /* Point the return values at the NDR data. */
422 rdata->data = r->stub_and_verifier.data;
424 if (pkt->auth_length) {
425 /* We've already done integer wrap tests in
426 * dcerpc_check_auth(). */
427 rdata->length = r->stub_and_verifier.length
428 - pad_len
429 - DCERPC_AUTH_TRAILER_LENGTH
430 - pkt->auth_length;
431 } else {
432 rdata->length = r->stub_and_verifier.length;
435 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
436 (long unsigned int)pdu->length,
437 (long unsigned int)rdata->length,
438 (unsigned int)pad_len));
441 * If this is the first reply, and the allocation hint is
442 * reasonable, try and set up the reply_pdu DATA_BLOB to the
443 * correct size.
446 if ((reply_pdu->length == 0) &&
447 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
448 if (!data_blob_realloc(mem_ctx, reply_pdu,
449 r->alloc_hint)) {
450 DEBUG(0, ("reply alloc hint %d too "
451 "large to allocate\n",
452 (int)r->alloc_hint));
453 return NT_STATUS_NO_MEMORY;
457 break;
459 case DCERPC_PKT_BIND_NAK:
460 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
461 rpccli_pipe_txt(talloc_tos(), cli)));
462 /* Use this for now... */
463 return NT_STATUS_NETWORK_ACCESS_DENIED;
465 case DCERPC_PKT_FAULT:
467 DEBUG(1, (__location__ ": RPC fault code %s received "
468 "from %s!\n",
469 dcerpc_errstr(talloc_tos(),
470 pkt->u.fault.status),
471 rpccli_pipe_txt(talloc_tos(), cli)));
473 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
475 default:
476 DEBUG(0, (__location__ "Unknown packet type %u received "
477 "from %s!\n",
478 (unsigned int)pkt->ptype,
479 rpccli_pipe_txt(talloc_tos(), cli)));
480 return NT_STATUS_INVALID_INFO_CLASS;
483 if (pkt->ptype != expected_pkt_type) {
484 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
485 "RPC packet type - %u, not %u\n",
486 rpccli_pipe_txt(talloc_tos(), cli),
487 pkt->ptype, expected_pkt_type));
488 return NT_STATUS_INVALID_INFO_CLASS;
491 /* Do this just before return - we don't want to modify any rpc header
492 data before now as we may have needed to do cryptographic actions on
493 it before. */
495 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
496 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
497 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
498 "fragment first/last ON.\n"));
499 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
502 return NT_STATUS_OK;
505 /****************************************************************************
506 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
507 ****************************************************************************/
509 struct cli_api_pipe_state {
510 struct event_context *ev;
511 struct rpc_cli_transport *transport;
512 uint8_t *rdata;
513 uint32_t rdata_len;
516 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
517 static void cli_api_pipe_write_done(struct tevent_req *subreq);
518 static void cli_api_pipe_read_done(struct tevent_req *subreq);
520 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
521 struct event_context *ev,
522 struct rpc_cli_transport *transport,
523 uint8_t *data, size_t data_len,
524 uint32_t max_rdata_len)
526 struct tevent_req *req, *subreq;
527 struct cli_api_pipe_state *state;
528 NTSTATUS status;
530 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
531 if (req == NULL) {
532 return NULL;
534 state->ev = ev;
535 state->transport = transport;
537 if (max_rdata_len < RPC_HEADER_LEN) {
539 * For a RPC reply we always need at least RPC_HEADER_LEN
540 * bytes. We check this here because we will receive
541 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
543 status = NT_STATUS_INVALID_PARAMETER;
544 goto post_status;
547 if (transport->trans_send != NULL) {
548 subreq = transport->trans_send(state, ev, data, data_len,
549 max_rdata_len, transport->priv);
550 if (subreq == NULL) {
551 goto fail;
553 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
554 return req;
558 * If the transport does not provide a "trans" routine, i.e. for
559 * example the ncacn_ip_tcp transport, do the write/read step here.
562 subreq = rpc_write_send(state, ev, transport, data, data_len);
563 if (subreq == NULL) {
564 goto fail;
566 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
567 return req;
569 post_status:
570 tevent_req_nterror(req, status);
571 return tevent_req_post(req, ev);
572 fail:
573 TALLOC_FREE(req);
574 return NULL;
577 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
579 struct tevent_req *req = tevent_req_callback_data(
580 subreq, struct tevent_req);
581 struct cli_api_pipe_state *state = tevent_req_data(
582 req, struct cli_api_pipe_state);
583 NTSTATUS status;
585 status = state->transport->trans_recv(subreq, state, &state->rdata,
586 &state->rdata_len);
587 TALLOC_FREE(subreq);
588 if (!NT_STATUS_IS_OK(status)) {
589 tevent_req_nterror(req, status);
590 return;
592 tevent_req_done(req);
595 static void cli_api_pipe_write_done(struct tevent_req *subreq)
597 struct tevent_req *req = tevent_req_callback_data(
598 subreq, struct tevent_req);
599 struct cli_api_pipe_state *state = tevent_req_data(
600 req, struct cli_api_pipe_state);
601 NTSTATUS status;
603 status = rpc_write_recv(subreq);
604 TALLOC_FREE(subreq);
605 if (!NT_STATUS_IS_OK(status)) {
606 tevent_req_nterror(req, status);
607 return;
610 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
611 if (tevent_req_nomem(state->rdata, req)) {
612 return;
616 * We don't need to use rpc_read_send here, the upper layer will cope
617 * with a short read, transport->trans_send could also return less
618 * than state->max_rdata_len.
620 subreq = state->transport->read_send(state, state->ev, state->rdata,
621 RPC_HEADER_LEN,
622 state->transport->priv);
623 if (tevent_req_nomem(subreq, req)) {
624 return;
626 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
629 static void cli_api_pipe_read_done(struct tevent_req *subreq)
631 struct tevent_req *req = tevent_req_callback_data(
632 subreq, struct tevent_req);
633 struct cli_api_pipe_state *state = tevent_req_data(
634 req, struct cli_api_pipe_state);
635 NTSTATUS status;
636 ssize_t received;
638 status = state->transport->read_recv(subreq, &received);
639 TALLOC_FREE(subreq);
640 if (!NT_STATUS_IS_OK(status)) {
641 tevent_req_nterror(req, status);
642 return;
644 state->rdata_len = received;
645 tevent_req_done(req);
648 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
649 uint8_t **prdata, uint32_t *prdata_len)
651 struct cli_api_pipe_state *state = tevent_req_data(
652 req, struct cli_api_pipe_state);
653 NTSTATUS status;
655 if (tevent_req_is_nterror(req, &status)) {
656 return status;
659 *prdata = talloc_move(mem_ctx, &state->rdata);
660 *prdata_len = state->rdata_len;
661 return NT_STATUS_OK;
664 /****************************************************************************
665 Send data on an rpc pipe via trans. The data must be the last
666 pdu fragment of an NDR data stream.
668 Receive response data from an rpc pipe, which may be large...
670 Read the first fragment: unfortunately have to use SMBtrans for the first
671 bit, then SMBreadX for subsequent bits.
673 If first fragment received also wasn't the last fragment, continue
674 getting fragments until we _do_ receive the last fragment.
676 Request/Response PDU's look like the following...
678 |<------------------PDU len----------------------------------------------->|
679 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
681 +------------+-----------------+-------------+---------------+-------------+
682 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
683 +------------+-----------------+-------------+---------------+-------------+
685 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
686 signing & sealing being negotiated.
688 ****************************************************************************/
690 struct rpc_api_pipe_state {
691 struct event_context *ev;
692 struct rpc_pipe_client *cli;
693 uint8_t expected_pkt_type;
695 DATA_BLOB incoming_frag;
696 struct ncacn_packet *pkt;
698 /* Incoming reply */
699 DATA_BLOB reply_pdu;
700 size_t reply_pdu_offset;
701 uint8_t endianess;
704 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
705 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
706 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
708 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
709 struct event_context *ev,
710 struct rpc_pipe_client *cli,
711 DATA_BLOB *data, /* Outgoing PDU */
712 uint8_t expected_pkt_type)
714 struct tevent_req *req, *subreq;
715 struct rpc_api_pipe_state *state;
716 uint16_t max_recv_frag;
717 NTSTATUS status;
719 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
720 if (req == NULL) {
721 return NULL;
723 state->ev = ev;
724 state->cli = cli;
725 state->expected_pkt_type = expected_pkt_type;
726 state->incoming_frag = data_blob_null;
727 state->reply_pdu = data_blob_null;
728 state->reply_pdu_offset = 0;
729 state->endianess = DCERPC_DREP_LE;
732 * Ensure we're not sending too much.
734 if (data->length > cli->max_xmit_frag) {
735 status = NT_STATUS_INVALID_PARAMETER;
736 goto post_status;
739 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
741 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
742 subreq = rpc_write_send(state, ev, cli->transport,
743 data->data, data->length);
744 if (subreq == NULL) {
745 goto fail;
747 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
748 return req;
751 /* get the header first, then fetch the rest once we have
752 * the frag_length available */
753 max_recv_frag = RPC_HEADER_LEN;
755 subreq = cli_api_pipe_send(state, ev, cli->transport,
756 data->data, data->length, max_recv_frag);
757 if (subreq == NULL) {
758 goto fail;
760 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
761 return req;
763 post_status:
764 tevent_req_nterror(req, status);
765 return tevent_req_post(req, ev);
766 fail:
767 TALLOC_FREE(req);
768 return NULL;
771 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
773 struct tevent_req *req =
774 tevent_req_callback_data(subreq,
775 struct tevent_req);
776 NTSTATUS status;
778 status = rpc_write_recv(subreq);
779 TALLOC_FREE(subreq);
780 if (!NT_STATUS_IS_OK(status)) {
781 tevent_req_nterror(req, status);
782 return;
785 tevent_req_done(req);
788 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
790 struct tevent_req *req = tevent_req_callback_data(
791 subreq, struct tevent_req);
792 struct rpc_api_pipe_state *state = tevent_req_data(
793 req, struct rpc_api_pipe_state);
794 NTSTATUS status;
795 uint8_t *rdata = NULL;
796 uint32_t rdata_len = 0;
798 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
799 TALLOC_FREE(subreq);
800 if (!NT_STATUS_IS_OK(status)) {
801 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
802 tevent_req_nterror(req, status);
803 return;
806 if (rdata == NULL) {
807 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
808 rpccli_pipe_txt(talloc_tos(), state->cli)));
809 tevent_req_done(req);
810 return;
814 * Move data on state->incoming_frag.
816 state->incoming_frag.data = talloc_move(state, &rdata);
817 state->incoming_frag.length = rdata_len;
818 if (!state->incoming_frag.data) {
819 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
820 return;
823 /* Ensure we have enough data for a pdu. */
824 subreq = get_complete_frag_send(state, state->ev, state->cli,
825 &state->incoming_frag);
826 if (tevent_req_nomem(subreq, req)) {
827 return;
829 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
832 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
834 struct tevent_req *req = tevent_req_callback_data(
835 subreq, struct tevent_req);
836 struct rpc_api_pipe_state *state = tevent_req_data(
837 req, struct rpc_api_pipe_state);
838 NTSTATUS status;
839 DATA_BLOB rdata = data_blob_null;
841 status = get_complete_frag_recv(subreq);
842 TALLOC_FREE(subreq);
843 if (!NT_STATUS_IS_OK(status)) {
844 DEBUG(5, ("get_complete_frag failed: %s\n",
845 nt_errstr(status)));
846 tevent_req_nterror(req, status);
847 return;
850 state->pkt = talloc(state, struct ncacn_packet);
851 if (!state->pkt) {
852 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
853 return;
856 status = dcerpc_pull_ncacn_packet(state->pkt,
857 &state->incoming_frag,
858 state->pkt,
859 !state->endianess);
860 if (!NT_STATUS_IS_OK(status)) {
861 tevent_req_nterror(req, status);
862 return;
865 if (state->incoming_frag.length != state->pkt->frag_length) {
866 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
867 (unsigned int)state->incoming_frag.length,
868 (unsigned int)state->pkt->frag_length));
869 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
870 return;
873 status = cli_pipe_validate_current_pdu(state,
874 state->cli, state->pkt,
875 &state->incoming_frag,
876 state->expected_pkt_type,
877 &rdata,
878 &state->reply_pdu);
880 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
881 (unsigned)state->incoming_frag.length,
882 (unsigned)state->reply_pdu_offset,
883 nt_errstr(status)));
885 if (!NT_STATUS_IS_OK(status)) {
886 tevent_req_nterror(req, status);
887 return;
890 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
891 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
893 * Set the data type correctly for big-endian data on the
894 * first packet.
896 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
897 "big-endian.\n",
898 rpccli_pipe_txt(talloc_tos(), state->cli)));
899 state->endianess = 0x00; /* BIG ENDIAN */
902 * Check endianness on subsequent packets.
904 if (state->endianess != state->pkt->drep[0]) {
905 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
906 "%s\n",
907 state->endianess?"little":"big",
908 state->pkt->drep[0]?"little":"big"));
909 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
910 return;
913 /* Now copy the data portion out of the pdu into rbuf. */
914 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
915 if (!data_blob_realloc(NULL, &state->reply_pdu,
916 state->reply_pdu_offset + rdata.length)) {
917 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
918 return;
922 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
923 rdata.data, rdata.length);
924 state->reply_pdu_offset += rdata.length;
926 /* reset state->incoming_frag, there is no need to free it,
927 * it will be reallocated to the right size the next time
928 * it is used */
929 state->incoming_frag.length = 0;
931 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
932 /* make sure the pdu length is right now that we
933 * have all the data available (alloc hint may
934 * have allocated more than was actually used) */
935 state->reply_pdu.length = state->reply_pdu_offset;
936 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
937 rpccli_pipe_txt(talloc_tos(), state->cli),
938 (unsigned)state->reply_pdu.length));
939 tevent_req_done(req);
940 return;
943 subreq = get_complete_frag_send(state, state->ev, state->cli,
944 &state->incoming_frag);
945 if (tevent_req_nomem(subreq, req)) {
946 return;
948 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
951 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
952 struct ncacn_packet **pkt,
953 DATA_BLOB *reply_pdu)
955 struct rpc_api_pipe_state *state = tevent_req_data(
956 req, struct rpc_api_pipe_state);
957 NTSTATUS status;
959 if (tevent_req_is_nterror(req, &status)) {
960 return status;
963 /* return data to caller and assign it ownership of memory */
964 if (reply_pdu) {
965 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
966 reply_pdu->length = state->reply_pdu.length;
967 state->reply_pdu.length = 0;
968 } else {
969 data_blob_free(&state->reply_pdu);
972 if (pkt) {
973 *pkt = talloc_steal(mem_ctx, state->pkt);
976 return NT_STATUS_OK;
979 /*******************************************************************
980 Creates spnego auth bind.
981 ********************************************************************/
983 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
984 struct pipe_auth_data *auth,
985 DATA_BLOB *auth_token)
987 struct spnego_context *spnego_ctx;
988 DATA_BLOB in_token = data_blob_null;
989 NTSTATUS status;
991 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
992 struct spnego_context);
994 /* Negotiate the initial auth token */
995 status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
996 &in_token, auth_token);
997 if (!NT_STATUS_IS_OK(status)) {
998 return status;
1001 DEBUG(5, ("Created GSS Authentication Token:\n"));
1002 dump_data(5, auth_token->data, auth_token->length);
1004 return NT_STATUS_OK;
1007 /*******************************************************************
1008 Creates krb5 auth bind.
1009 ********************************************************************/
1011 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
1012 struct pipe_auth_data *auth,
1013 DATA_BLOB *auth_token)
1015 struct gse_context *gse_ctx;
1016 DATA_BLOB in_token = data_blob_null;
1017 NTSTATUS status;
1019 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
1020 struct gse_context);
1022 /* Negotiate the initial auth token */
1023 status = gse_get_client_auth_token(mem_ctx, gse_ctx,
1024 &in_token,
1025 auth_token);
1026 if (!NT_STATUS_IS_OK(status)) {
1027 return status;
1030 DEBUG(5, ("Created GSS Authentication Token:\n"));
1031 dump_data(5, auth_token->data, auth_token->length);
1033 return NT_STATUS_OK;
1036 /*******************************************************************
1037 Creates NTLMSSP auth bind.
1038 ********************************************************************/
1040 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1041 TALLOC_CTX *mem_ctx,
1042 DATA_BLOB *auth_token)
1044 struct gensec_security *gensec_security;
1045 DATA_BLOB null_blob = data_blob_null;
1046 NTSTATUS status;
1048 gensec_security = talloc_get_type_abort(cli->auth->auth_ctx,
1049 struct gensec_security);
1051 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1052 status = gensec_update(gensec_security, mem_ctx, NULL, null_blob, auth_token);
1054 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1055 data_blob_free(auth_token);
1056 return status;
1059 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1060 dump_data(5, auth_token->data, auth_token->length);
1062 return NT_STATUS_OK;
1065 /*******************************************************************
1066 Creates schannel auth bind.
1067 ********************************************************************/
1069 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1070 DATA_BLOB *auth_token)
1072 NTSTATUS status;
1073 struct NL_AUTH_MESSAGE r;
1075 /* Use lp_workgroup() if domain not specified */
1077 if (!cli->auth->domain || !cli->auth->domain[0]) {
1078 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1079 if (cli->auth->domain == NULL) {
1080 return NT_STATUS_NO_MEMORY;
1085 * Now marshall the data into the auth parse_struct.
1088 r.MessageType = NL_NEGOTIATE_REQUEST;
1089 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1090 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1091 r.oem_netbios_domain.a = cli->auth->domain;
1092 r.oem_netbios_computer.a = lp_netbios_name();
1094 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1095 if (!NT_STATUS_IS_OK(status)) {
1096 return status;
1099 return NT_STATUS_OK;
1102 /*******************************************************************
1103 Creates the internals of a DCE/RPC bind request or alter context PDU.
1104 ********************************************************************/
1106 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1107 enum dcerpc_pkt_type ptype,
1108 uint32 rpc_call_id,
1109 const struct ndr_syntax_id *abstract,
1110 const struct ndr_syntax_id *transfer,
1111 const DATA_BLOB *auth_info,
1112 DATA_BLOB *blob)
1114 uint16 auth_len = auth_info->length;
1115 NTSTATUS status;
1116 union dcerpc_payload u;
1117 struct dcerpc_ctx_list ctx_list;
1119 if (auth_len) {
1120 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1123 ctx_list.context_id = 0;
1124 ctx_list.num_transfer_syntaxes = 1;
1125 ctx_list.abstract_syntax = *abstract;
1126 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1128 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1129 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1130 u.bind.assoc_group_id = 0x0;
1131 u.bind.num_contexts = 1;
1132 u.bind.ctx_list = &ctx_list;
1133 u.bind.auth_info = *auth_info;
1135 status = dcerpc_push_ncacn_packet(mem_ctx,
1136 ptype,
1137 DCERPC_PFC_FLAG_FIRST |
1138 DCERPC_PFC_FLAG_LAST,
1139 auth_len,
1140 rpc_call_id,
1142 blob);
1143 if (!NT_STATUS_IS_OK(status)) {
1144 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1145 return status;
1148 return NT_STATUS_OK;
1151 /*******************************************************************
1152 Creates a DCE/RPC bind request.
1153 ********************************************************************/
1155 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1156 struct rpc_pipe_client *cli,
1157 struct pipe_auth_data *auth,
1158 uint32 rpc_call_id,
1159 const struct ndr_syntax_id *abstract,
1160 const struct ndr_syntax_id *transfer,
1161 DATA_BLOB *rpc_out)
1163 DATA_BLOB auth_token = data_blob_null;
1164 DATA_BLOB auth_info = data_blob_null;
1165 NTSTATUS ret = NT_STATUS_OK;
1167 switch (auth->auth_type) {
1168 case DCERPC_AUTH_TYPE_SCHANNEL:
1169 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1170 if (!NT_STATUS_IS_OK(ret)) {
1171 return ret;
1173 break;
1175 case DCERPC_AUTH_TYPE_NTLMSSP:
1176 ret = create_ntlmssp_auth_rpc_bind_req(cli, mem_ctx, &auth_token);
1177 if (!NT_STATUS_IS_OK(ret)) {
1178 return ret;
1180 break;
1182 case DCERPC_AUTH_TYPE_SPNEGO:
1183 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1184 if (!NT_STATUS_IS_OK(ret)) {
1185 return ret;
1187 break;
1189 case DCERPC_AUTH_TYPE_KRB5:
1190 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1191 if (!NT_STATUS_IS_OK(ret)) {
1192 return ret;
1194 break;
1196 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1197 auth_token = data_blob_talloc(mem_ctx,
1198 "NCALRPC_AUTH_TOKEN",
1199 18);
1200 break;
1202 case DCERPC_AUTH_TYPE_NONE:
1203 break;
1205 default:
1206 /* "Can't" happen. */
1207 return NT_STATUS_INVALID_INFO_CLASS;
1210 if (auth_token.length != 0) {
1211 ret = dcerpc_push_dcerpc_auth(cli,
1212 auth->auth_type,
1213 auth->auth_level,
1214 0, /* auth_pad_length */
1215 1, /* auth_context_id */
1216 &auth_token,
1217 &auth_info);
1218 if (!NT_STATUS_IS_OK(ret)) {
1219 return ret;
1221 data_blob_free(&auth_token);
1224 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1225 DCERPC_PKT_BIND,
1226 rpc_call_id,
1227 abstract,
1228 transfer,
1229 &auth_info,
1230 rpc_out);
1231 return ret;
1234 /*******************************************************************
1235 External interface.
1236 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1237 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1238 and deals with signing/sealing details.
1239 ********************************************************************/
1241 struct rpc_api_pipe_req_state {
1242 struct event_context *ev;
1243 struct rpc_pipe_client *cli;
1244 uint8_t op_num;
1245 uint32_t call_id;
1246 DATA_BLOB *req_data;
1247 uint32_t req_data_sent;
1248 DATA_BLOB rpc_out;
1249 DATA_BLOB reply_pdu;
1252 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1253 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1254 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1255 bool *is_last_frag);
1257 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1258 struct event_context *ev,
1259 struct rpc_pipe_client *cli,
1260 uint8_t op_num,
1261 DATA_BLOB *req_data)
1263 struct tevent_req *req, *subreq;
1264 struct rpc_api_pipe_req_state *state;
1265 NTSTATUS status;
1266 bool is_last_frag;
1268 req = tevent_req_create(mem_ctx, &state,
1269 struct rpc_api_pipe_req_state);
1270 if (req == NULL) {
1271 return NULL;
1273 state->ev = ev;
1274 state->cli = cli;
1275 state->op_num = op_num;
1276 state->req_data = req_data;
1277 state->req_data_sent = 0;
1278 state->call_id = get_rpc_call_id();
1279 state->reply_pdu = data_blob_null;
1280 state->rpc_out = data_blob_null;
1282 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1283 + RPC_MAX_SIGN_SIZE) {
1284 /* Server is screwed up ! */
1285 status = NT_STATUS_INVALID_PARAMETER;
1286 goto post_status;
1289 status = prepare_next_frag(state, &is_last_frag);
1290 if (!NT_STATUS_IS_OK(status)) {
1291 goto post_status;
1294 if (is_last_frag) {
1295 subreq = rpc_api_pipe_send(state, ev, state->cli,
1296 &state->rpc_out,
1297 DCERPC_PKT_RESPONSE);
1298 if (subreq == NULL) {
1299 goto fail;
1301 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1302 } else {
1303 subreq = rpc_write_send(state, ev, cli->transport,
1304 state->rpc_out.data,
1305 state->rpc_out.length);
1306 if (subreq == NULL) {
1307 goto fail;
1309 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1310 req);
1312 return req;
1314 post_status:
1315 tevent_req_nterror(req, status);
1316 return tevent_req_post(req, ev);
1317 fail:
1318 TALLOC_FREE(req);
1319 return NULL;
1322 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1323 bool *is_last_frag)
1325 size_t data_sent_thistime;
1326 size_t auth_len;
1327 size_t frag_len;
1328 uint8_t flags = 0;
1329 size_t pad_len;
1330 size_t data_left;
1331 NTSTATUS status;
1332 union dcerpc_payload u;
1334 data_left = state->req_data->length - state->req_data_sent;
1336 status = dcerpc_guess_sizes(state->cli->auth,
1337 DCERPC_REQUEST_LENGTH, data_left,
1338 state->cli->max_xmit_frag,
1339 CLIENT_NDR_PADDING_SIZE,
1340 &data_sent_thistime,
1341 &frag_len, &auth_len, &pad_len);
1342 if (!NT_STATUS_IS_OK(status)) {
1343 return status;
1346 if (state->req_data_sent == 0) {
1347 flags = DCERPC_PFC_FLAG_FIRST;
1350 if (data_sent_thistime == data_left) {
1351 flags |= DCERPC_PFC_FLAG_LAST;
1354 data_blob_free(&state->rpc_out);
1356 ZERO_STRUCT(u.request);
1358 u.request.alloc_hint = state->req_data->length;
1359 u.request.context_id = 0;
1360 u.request.opnum = state->op_num;
1362 status = dcerpc_push_ncacn_packet(state,
1363 DCERPC_PKT_REQUEST,
1364 flags,
1365 auth_len,
1366 state->call_id,
1368 &state->rpc_out);
1369 if (!NT_STATUS_IS_OK(status)) {
1370 return status;
1373 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1374 * compute it right for requests because the auth trailer is missing
1375 * at this stage */
1376 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1378 /* Copy in the data. */
1379 if (!data_blob_append(NULL, &state->rpc_out,
1380 state->req_data->data + state->req_data_sent,
1381 data_sent_thistime)) {
1382 return NT_STATUS_NO_MEMORY;
1385 switch (state->cli->auth->auth_level) {
1386 case DCERPC_AUTH_LEVEL_NONE:
1387 case DCERPC_AUTH_LEVEL_CONNECT:
1388 case DCERPC_AUTH_LEVEL_PACKET:
1389 break;
1390 case DCERPC_AUTH_LEVEL_INTEGRITY:
1391 case DCERPC_AUTH_LEVEL_PRIVACY:
1392 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1393 &state->rpc_out);
1394 if (!NT_STATUS_IS_OK(status)) {
1395 return status;
1397 break;
1398 default:
1399 return NT_STATUS_INVALID_PARAMETER;
1402 state->req_data_sent += data_sent_thistime;
1403 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1405 return status;
1408 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1410 struct tevent_req *req = tevent_req_callback_data(
1411 subreq, struct tevent_req);
1412 struct rpc_api_pipe_req_state *state = tevent_req_data(
1413 req, struct rpc_api_pipe_req_state);
1414 NTSTATUS status;
1415 bool is_last_frag;
1417 status = rpc_write_recv(subreq);
1418 TALLOC_FREE(subreq);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 tevent_req_nterror(req, status);
1421 return;
1424 status = prepare_next_frag(state, &is_last_frag);
1425 if (!NT_STATUS_IS_OK(status)) {
1426 tevent_req_nterror(req, status);
1427 return;
1430 if (is_last_frag) {
1431 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1432 &state->rpc_out,
1433 DCERPC_PKT_RESPONSE);
1434 if (tevent_req_nomem(subreq, req)) {
1435 return;
1437 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1438 } else {
1439 subreq = rpc_write_send(state, state->ev,
1440 state->cli->transport,
1441 state->rpc_out.data,
1442 state->rpc_out.length);
1443 if (tevent_req_nomem(subreq, req)) {
1444 return;
1446 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1447 req);
1451 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1453 struct tevent_req *req = tevent_req_callback_data(
1454 subreq, struct tevent_req);
1455 struct rpc_api_pipe_req_state *state = tevent_req_data(
1456 req, struct rpc_api_pipe_req_state);
1457 NTSTATUS status;
1459 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1460 TALLOC_FREE(subreq);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 tevent_req_nterror(req, status);
1463 return;
1465 tevent_req_done(req);
1468 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1469 DATA_BLOB *reply_pdu)
1471 struct rpc_api_pipe_req_state *state = tevent_req_data(
1472 req, struct rpc_api_pipe_req_state);
1473 NTSTATUS status;
1475 if (tevent_req_is_nterror(req, &status)) {
1477 * We always have to initialize to reply pdu, even if there is
1478 * none. The rpccli_* caller routines expect this.
1480 *reply_pdu = data_blob_null;
1481 return status;
1484 /* return data to caller and assign it ownership of memory */
1485 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1486 reply_pdu->length = state->reply_pdu.length;
1487 state->reply_pdu.length = 0;
1489 return NT_STATUS_OK;
1492 /****************************************************************************
1493 Check the rpc bind acknowledge response.
1494 ****************************************************************************/
1496 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1497 const struct ndr_syntax_id *transfer)
1499 struct dcerpc_ack_ctx ctx;
1501 if (r->secondary_address_size == 0) {
1502 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1505 if (r->num_results < 1 || !r->ctx_list) {
1506 return false;
1509 ctx = r->ctx_list[0];
1511 /* check the transfer syntax */
1512 if ((ctx.syntax.if_version != transfer->if_version) ||
1513 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1514 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1515 return False;
1518 if (r->num_results != 0x1 || ctx.result != 0) {
1519 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1520 r->num_results, ctx.reason));
1523 DEBUG(5,("check_bind_response: accepted!\n"));
1524 return True;
1527 /*******************************************************************
1528 Creates a DCE/RPC bind authentication response.
1529 This is the packet that is sent back to the server once we
1530 have received a BIND-ACK, to finish the third leg of
1531 the authentication handshake.
1532 ********************************************************************/
1534 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1535 struct rpc_pipe_client *cli,
1536 uint32 rpc_call_id,
1537 enum dcerpc_AuthType auth_type,
1538 enum dcerpc_AuthLevel auth_level,
1539 DATA_BLOB *pauth_blob,
1540 DATA_BLOB *rpc_out)
1542 NTSTATUS status;
1543 union dcerpc_payload u;
1545 u.auth3._pad = 0;
1547 status = dcerpc_push_dcerpc_auth(mem_ctx,
1548 auth_type,
1549 auth_level,
1550 0, /* auth_pad_length */
1551 1, /* auth_context_id */
1552 pauth_blob,
1553 &u.auth3.auth_info);
1554 if (!NT_STATUS_IS_OK(status)) {
1555 return status;
1558 status = dcerpc_push_ncacn_packet(mem_ctx,
1559 DCERPC_PKT_AUTH3,
1560 DCERPC_PFC_FLAG_FIRST |
1561 DCERPC_PFC_FLAG_LAST,
1562 pauth_blob->length,
1563 rpc_call_id,
1565 rpc_out);
1566 data_blob_free(&u.auth3.auth_info);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1569 return status;
1572 return NT_STATUS_OK;
1575 /*******************************************************************
1576 Creates a DCE/RPC bind alter context authentication request which
1577 may contain a spnego auth blobl
1578 ********************************************************************/
1580 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1581 enum dcerpc_AuthType auth_type,
1582 enum dcerpc_AuthLevel auth_level,
1583 uint32 rpc_call_id,
1584 const struct ndr_syntax_id *abstract,
1585 const struct ndr_syntax_id *transfer,
1586 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1587 DATA_BLOB *rpc_out)
1589 DATA_BLOB auth_info;
1590 NTSTATUS status;
1592 status = dcerpc_push_dcerpc_auth(mem_ctx,
1593 auth_type,
1594 auth_level,
1595 0, /* auth_pad_length */
1596 1, /* auth_context_id */
1597 pauth_blob,
1598 &auth_info);
1599 if (!NT_STATUS_IS_OK(status)) {
1600 return status;
1603 status = create_bind_or_alt_ctx_internal(mem_ctx,
1604 DCERPC_PKT_ALTER,
1605 rpc_call_id,
1606 abstract,
1607 transfer,
1608 &auth_info,
1609 rpc_out);
1610 data_blob_free(&auth_info);
1611 return status;
1614 /****************************************************************************
1615 Do an rpc bind.
1616 ****************************************************************************/
1618 struct rpc_pipe_bind_state {
1619 struct event_context *ev;
1620 struct rpc_pipe_client *cli;
1621 DATA_BLOB rpc_out;
1622 bool auth3;
1623 uint32_t rpc_call_id;
1626 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1627 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1628 struct rpc_pipe_bind_state *state,
1629 DATA_BLOB *credentials);
1630 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1631 struct rpc_pipe_bind_state *state,
1632 DATA_BLOB *credentials);
1634 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1635 struct event_context *ev,
1636 struct rpc_pipe_client *cli,
1637 struct pipe_auth_data *auth)
1639 struct tevent_req *req, *subreq;
1640 struct rpc_pipe_bind_state *state;
1641 NTSTATUS status;
1643 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1644 if (req == NULL) {
1645 return NULL;
1648 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1649 rpccli_pipe_txt(talloc_tos(), cli),
1650 (unsigned int)auth->auth_type,
1651 (unsigned int)auth->auth_level ));
1653 state->ev = ev;
1654 state->cli = cli;
1655 state->rpc_call_id = get_rpc_call_id();
1657 cli->auth = talloc_move(cli, &auth);
1659 /* Marshall the outgoing data. */
1660 status = create_rpc_bind_req(state, cli,
1661 cli->auth,
1662 state->rpc_call_id,
1663 &cli->abstract_syntax,
1664 &cli->transfer_syntax,
1665 &state->rpc_out);
1667 if (!NT_STATUS_IS_OK(status)) {
1668 goto post_status;
1671 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1672 DCERPC_PKT_BIND_ACK);
1673 if (subreq == NULL) {
1674 goto fail;
1676 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1677 return req;
1679 post_status:
1680 tevent_req_nterror(req, status);
1681 return tevent_req_post(req, ev);
1682 fail:
1683 TALLOC_FREE(req);
1684 return NULL;
1687 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1689 struct tevent_req *req = tevent_req_callback_data(
1690 subreq, struct tevent_req);
1691 struct rpc_pipe_bind_state *state = tevent_req_data(
1692 req, struct rpc_pipe_bind_state);
1693 struct pipe_auth_data *pauth = state->cli->auth;
1694 struct gensec_security *gensec_security;
1695 struct spnego_context *spnego_ctx;
1696 struct gse_context *gse_ctx;
1697 struct ncacn_packet *pkt = NULL;
1698 struct dcerpc_auth auth;
1699 DATA_BLOB auth_token = data_blob_null;
1700 NTSTATUS status;
1702 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1703 TALLOC_FREE(subreq);
1704 if (!NT_STATUS_IS_OK(status)) {
1705 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1706 rpccli_pipe_txt(talloc_tos(), state->cli),
1707 nt_errstr(status)));
1708 tevent_req_nterror(req, status);
1709 return;
1712 if (state->auth3) {
1713 tevent_req_done(req);
1714 return;
1717 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1718 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1719 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1720 return;
1723 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1724 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1726 switch(pauth->auth_type) {
1728 case DCERPC_AUTH_TYPE_NONE:
1729 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1730 case DCERPC_AUTH_TYPE_SCHANNEL:
1731 /* Bind complete. */
1732 tevent_req_done(req);
1733 return;
1735 case DCERPC_AUTH_TYPE_NTLMSSP:
1736 case DCERPC_AUTH_TYPE_SPNEGO:
1737 case DCERPC_AUTH_TYPE_KRB5:
1738 /* Paranoid lenght checks */
1739 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1740 + pkt->auth_length) {
1741 tevent_req_nterror(req,
1742 NT_STATUS_INFO_LENGTH_MISMATCH);
1743 return;
1745 /* get auth credentials */
1746 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1747 &pkt->u.bind_ack.auth_info,
1748 &auth, false);
1749 if (!NT_STATUS_IS_OK(status)) {
1750 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1751 nt_errstr(status)));
1752 tevent_req_nterror(req, status);
1753 return;
1755 break;
1757 default:
1758 goto err_out;
1762 * For authenticated binds we may need to do 3 or 4 leg binds.
1765 switch(pauth->auth_type) {
1767 case DCERPC_AUTH_TYPE_NONE:
1768 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1769 case DCERPC_AUTH_TYPE_SCHANNEL:
1770 /* Bind complete. */
1771 tevent_req_done(req);
1772 return;
1774 case DCERPC_AUTH_TYPE_NTLMSSP:
1775 gensec_security = talloc_get_type_abort(pauth->auth_ctx,
1776 struct gensec_security);
1777 status = gensec_update(gensec_security, state, NULL,
1778 auth.credentials, &auth_token);
1779 if (NT_STATUS_EQUAL(status,
1780 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1781 status = rpc_bind_next_send(req, state,
1782 &auth_token);
1783 } else if (NT_STATUS_IS_OK(status)) {
1784 status = rpc_bind_finish_send(req, state,
1785 &auth_token);
1787 break;
1789 case DCERPC_AUTH_TYPE_SPNEGO:
1790 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1791 struct spnego_context);
1792 status = spnego_get_client_auth_token(state,
1793 spnego_ctx,
1794 &auth.credentials,
1795 &auth_token);
1796 if (!NT_STATUS_IS_OK(status)) {
1797 break;
1799 if (auth_token.length == 0) {
1800 /* Bind complete. */
1801 tevent_req_done(req);
1802 return;
1804 if (spnego_require_more_processing(spnego_ctx)) {
1805 status = rpc_bind_next_send(req, state,
1806 &auth_token);
1807 } else {
1808 status = rpc_bind_finish_send(req, state,
1809 &auth_token);
1811 break;
1813 case DCERPC_AUTH_TYPE_KRB5:
1814 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
1815 struct gse_context);
1816 status = gse_get_client_auth_token(state,
1817 gse_ctx,
1818 &auth.credentials,
1819 &auth_token);
1820 if (!NT_STATUS_IS_OK(status)) {
1821 break;
1824 if (gse_require_more_processing(gse_ctx)) {
1825 status = rpc_bind_next_send(req, state, &auth_token);
1826 } else {
1827 status = rpc_bind_finish_send(req, state, &auth_token);
1829 break;
1831 default:
1832 goto err_out;
1835 if (!NT_STATUS_IS_OK(status)) {
1836 tevent_req_nterror(req, status);
1838 return;
1840 err_out:
1841 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1842 (unsigned int)state->cli->auth->auth_type));
1843 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1846 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1847 struct rpc_pipe_bind_state *state,
1848 DATA_BLOB *auth_token)
1850 struct pipe_auth_data *auth = state->cli->auth;
1851 struct tevent_req *subreq;
1852 NTSTATUS status;
1854 /* Now prepare the alter context pdu. */
1855 data_blob_free(&state->rpc_out);
1857 status = create_rpc_alter_context(state,
1858 auth->auth_type,
1859 auth->auth_level,
1860 state->rpc_call_id,
1861 &state->cli->abstract_syntax,
1862 &state->cli->transfer_syntax,
1863 auth_token,
1864 &state->rpc_out);
1865 if (!NT_STATUS_IS_OK(status)) {
1866 return status;
1869 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1870 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1871 if (subreq == NULL) {
1872 return NT_STATUS_NO_MEMORY;
1874 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1875 return NT_STATUS_OK;
1878 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1879 struct rpc_pipe_bind_state *state,
1880 DATA_BLOB *auth_token)
1882 struct pipe_auth_data *auth = state->cli->auth;
1883 struct tevent_req *subreq;
1884 NTSTATUS status;
1886 state->auth3 = true;
1888 /* Now prepare the auth3 context pdu. */
1889 data_blob_free(&state->rpc_out);
1891 status = create_rpc_bind_auth3(state, state->cli,
1892 state->rpc_call_id,
1893 auth->auth_type,
1894 auth->auth_level,
1895 auth_token,
1896 &state->rpc_out);
1897 if (!NT_STATUS_IS_OK(status)) {
1898 return status;
1901 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1902 &state->rpc_out, DCERPC_PKT_AUTH3);
1903 if (subreq == NULL) {
1904 return NT_STATUS_NO_MEMORY;
1906 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1907 return NT_STATUS_OK;
1910 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1912 return tevent_req_simple_recv_ntstatus(req);
1915 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1916 struct pipe_auth_data *auth)
1918 TALLOC_CTX *frame = talloc_stackframe();
1919 struct event_context *ev;
1920 struct tevent_req *req;
1921 NTSTATUS status = NT_STATUS_OK;
1923 ev = event_context_init(frame);
1924 if (ev == NULL) {
1925 status = NT_STATUS_NO_MEMORY;
1926 goto fail;
1929 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1930 if (req == NULL) {
1931 status = NT_STATUS_NO_MEMORY;
1932 goto fail;
1935 if (!tevent_req_poll(req, ev)) {
1936 status = map_nt_error_from_unix(errno);
1937 goto fail;
1940 status = rpc_pipe_bind_recv(req);
1941 fail:
1942 TALLOC_FREE(frame);
1943 return status;
1946 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1948 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1949 unsigned int timeout)
1951 unsigned int old;
1953 if (rpc_cli->transport == NULL) {
1954 return RPCCLI_DEFAULT_TIMEOUT;
1957 if (rpc_cli->transport->set_timeout == NULL) {
1958 return RPCCLI_DEFAULT_TIMEOUT;
1961 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1962 if (old == 0) {
1963 return RPCCLI_DEFAULT_TIMEOUT;
1966 return old;
1969 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1971 if (rpc_cli == NULL) {
1972 return false;
1975 if (rpc_cli->transport == NULL) {
1976 return false;
1979 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1982 struct rpccli_bh_state {
1983 struct rpc_pipe_client *rpc_cli;
1986 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1988 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1989 struct rpccli_bh_state);
1991 return rpccli_is_connected(hs->rpc_cli);
1994 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1995 uint32_t timeout)
1997 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1998 struct rpccli_bh_state);
2000 return rpccli_set_timeout(hs->rpc_cli, timeout);
2003 struct rpccli_bh_raw_call_state {
2004 DATA_BLOB in_data;
2005 DATA_BLOB out_data;
2006 uint32_t out_flags;
2009 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2011 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2012 struct tevent_context *ev,
2013 struct dcerpc_binding_handle *h,
2014 const struct GUID *object,
2015 uint32_t opnum,
2016 uint32_t in_flags,
2017 const uint8_t *in_data,
2018 size_t in_length)
2020 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2021 struct rpccli_bh_state);
2022 struct tevent_req *req;
2023 struct rpccli_bh_raw_call_state *state;
2024 bool ok;
2025 struct tevent_req *subreq;
2027 req = tevent_req_create(mem_ctx, &state,
2028 struct rpccli_bh_raw_call_state);
2029 if (req == NULL) {
2030 return NULL;
2032 state->in_data.data = discard_const_p(uint8_t, in_data);
2033 state->in_data.length = in_length;
2035 ok = rpccli_bh_is_connected(h);
2036 if (!ok) {
2037 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2038 return tevent_req_post(req, ev);
2041 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2042 opnum, &state->in_data);
2043 if (tevent_req_nomem(subreq, req)) {
2044 return tevent_req_post(req, ev);
2046 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2048 return req;
2051 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2053 struct tevent_req *req =
2054 tevent_req_callback_data(subreq,
2055 struct tevent_req);
2056 struct rpccli_bh_raw_call_state *state =
2057 tevent_req_data(req,
2058 struct rpccli_bh_raw_call_state);
2059 NTSTATUS status;
2061 state->out_flags = 0;
2063 /* TODO: support bigendian responses */
2065 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2066 TALLOC_FREE(subreq);
2067 if (!NT_STATUS_IS_OK(status)) {
2068 tevent_req_nterror(req, status);
2069 return;
2072 tevent_req_done(req);
2075 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2076 TALLOC_CTX *mem_ctx,
2077 uint8_t **out_data,
2078 size_t *out_length,
2079 uint32_t *out_flags)
2081 struct rpccli_bh_raw_call_state *state =
2082 tevent_req_data(req,
2083 struct rpccli_bh_raw_call_state);
2084 NTSTATUS status;
2086 if (tevent_req_is_nterror(req, &status)) {
2087 tevent_req_received(req);
2088 return status;
2091 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2092 *out_length = state->out_data.length;
2093 *out_flags = state->out_flags;
2094 tevent_req_received(req);
2095 return NT_STATUS_OK;
2098 struct rpccli_bh_disconnect_state {
2099 uint8_t _dummy;
2102 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2103 struct tevent_context *ev,
2104 struct dcerpc_binding_handle *h)
2106 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2107 struct rpccli_bh_state);
2108 struct tevent_req *req;
2109 struct rpccli_bh_disconnect_state *state;
2110 bool ok;
2112 req = tevent_req_create(mem_ctx, &state,
2113 struct rpccli_bh_disconnect_state);
2114 if (req == NULL) {
2115 return NULL;
2118 ok = rpccli_bh_is_connected(h);
2119 if (!ok) {
2120 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2121 return tevent_req_post(req, ev);
2125 * TODO: do a real async disconnect ...
2127 * For now the caller needs to free rpc_cli
2129 hs->rpc_cli = NULL;
2131 tevent_req_done(req);
2132 return tevent_req_post(req, ev);
2135 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2137 NTSTATUS status;
2139 if (tevent_req_is_nterror(req, &status)) {
2140 tevent_req_received(req);
2141 return status;
2144 tevent_req_received(req);
2145 return NT_STATUS_OK;
2148 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2150 return true;
2153 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2154 int ndr_flags,
2155 const void *_struct_ptr,
2156 const struct ndr_interface_call *call)
2158 void *struct_ptr = discard_const(_struct_ptr);
2160 if (DEBUGLEVEL < 10) {
2161 return;
2164 if (ndr_flags & NDR_IN) {
2165 ndr_print_function_debug(call->ndr_print,
2166 call->name,
2167 ndr_flags,
2168 struct_ptr);
2170 if (ndr_flags & NDR_OUT) {
2171 ndr_print_function_debug(call->ndr_print,
2172 call->name,
2173 ndr_flags,
2174 struct_ptr);
2178 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2179 .name = "rpccli",
2180 .is_connected = rpccli_bh_is_connected,
2181 .set_timeout = rpccli_bh_set_timeout,
2182 .raw_call_send = rpccli_bh_raw_call_send,
2183 .raw_call_recv = rpccli_bh_raw_call_recv,
2184 .disconnect_send = rpccli_bh_disconnect_send,
2185 .disconnect_recv = rpccli_bh_disconnect_recv,
2187 .ref_alloc = rpccli_bh_ref_alloc,
2188 .do_ndr_print = rpccli_bh_do_ndr_print,
2191 /* initialise a rpc_pipe_client binding handle */
2192 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2194 struct dcerpc_binding_handle *h;
2195 struct rpccli_bh_state *hs;
2197 h = dcerpc_binding_handle_create(c,
2198 &rpccli_bh_ops,
2199 NULL,
2200 NULL, /* TODO */
2201 &hs,
2202 struct rpccli_bh_state,
2203 __location__);
2204 if (h == NULL) {
2205 return NULL;
2207 hs->rpc_cli = c;
2209 return h;
2212 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2213 struct pipe_auth_data **presult)
2215 struct pipe_auth_data *result;
2217 result = talloc(mem_ctx, struct pipe_auth_data);
2218 if (result == NULL) {
2219 return NT_STATUS_NO_MEMORY;
2222 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2223 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2225 result->user_name = talloc_strdup(result, "");
2226 result->domain = talloc_strdup(result, "");
2227 if ((result->user_name == NULL) || (result->domain == NULL)) {
2228 TALLOC_FREE(result);
2229 return NT_STATUS_NO_MEMORY;
2232 *presult = result;
2233 return NT_STATUS_OK;
2236 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2237 struct pipe_auth_data **presult)
2239 struct pipe_auth_data *result;
2241 result = talloc(mem_ctx, struct pipe_auth_data);
2242 if (result == NULL) {
2243 return NT_STATUS_NO_MEMORY;
2246 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2247 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2249 result->user_name = talloc_strdup(result, "");
2250 result->domain = talloc_strdup(result, "");
2251 if ((result->user_name == NULL) || (result->domain == NULL)) {
2252 TALLOC_FREE(result);
2253 return NT_STATUS_NO_MEMORY;
2256 *presult = result;
2257 return NT_STATUS_OK;
2260 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2261 enum dcerpc_AuthType auth_type,
2262 enum dcerpc_AuthLevel auth_level,
2263 const char *domain,
2264 const char *username,
2265 const char *password,
2266 struct pipe_auth_data **presult)
2268 struct auth_ntlmssp_state *ntlmssp_ctx;
2269 struct pipe_auth_data *result;
2270 NTSTATUS status;
2272 result = talloc(mem_ctx, struct pipe_auth_data);
2273 if (result == NULL) {
2274 return NT_STATUS_NO_MEMORY;
2277 result->auth_type = auth_type;
2278 result->auth_level = auth_level;
2280 result->user_name = talloc_strdup(result, username);
2281 result->domain = talloc_strdup(result, domain);
2282 if ((result->user_name == NULL) || (result->domain == NULL)) {
2283 status = NT_STATUS_NO_MEMORY;
2284 goto fail;
2287 status = auth_ntlmssp_client_prepare(result,
2288 &ntlmssp_ctx);
2289 if (!NT_STATUS_IS_OK(status)) {
2290 goto fail;
2293 status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
2294 if (!NT_STATUS_IS_OK(status)) {
2295 goto fail;
2298 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
2299 if (!NT_STATUS_IS_OK(status)) {
2300 goto fail;
2303 status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
2304 if (!NT_STATUS_IS_OK(status)) {
2305 goto fail;
2308 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2309 gensec_want_feature(ntlmssp_ctx->gensec_security, GENSEC_FEATURE_SIGN);
2310 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2311 gensec_want_feature(ntlmssp_ctx->gensec_security, GENSEC_FEATURE_SEAL);
2314 status = auth_ntlmssp_client_start(ntlmssp_ctx);
2315 if (!NT_STATUS_IS_OK(status)) {
2316 goto fail;
2319 result->auth_ctx = talloc_move(result, &ntlmssp_ctx->gensec_security);
2320 talloc_free(ntlmssp_ctx);
2321 *presult = result;
2322 return NT_STATUS_OK;
2324 fail:
2325 TALLOC_FREE(result);
2326 return status;
2329 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2330 enum dcerpc_AuthLevel auth_level,
2331 struct netlogon_creds_CredentialState *creds,
2332 struct pipe_auth_data **presult)
2334 struct schannel_state *schannel_auth;
2335 struct pipe_auth_data *result;
2337 result = talloc(mem_ctx, struct pipe_auth_data);
2338 if (result == NULL) {
2339 return NT_STATUS_NO_MEMORY;
2342 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2343 result->auth_level = auth_level;
2345 result->user_name = talloc_strdup(result, "");
2346 result->domain = talloc_strdup(result, domain);
2347 if ((result->user_name == NULL) || (result->domain == NULL)) {
2348 goto fail;
2351 schannel_auth = talloc(result, struct schannel_state);
2352 if (schannel_auth == NULL) {
2353 goto fail;
2356 schannel_auth->state = SCHANNEL_STATE_START;
2357 schannel_auth->seq_num = 0;
2358 schannel_auth->initiator = true;
2359 schannel_auth->creds = netlogon_creds_copy(result, creds);
2361 result->auth_ctx = schannel_auth;
2362 *presult = result;
2363 return NT_STATUS_OK;
2365 fail:
2366 TALLOC_FREE(result);
2367 return NT_STATUS_NO_MEMORY;
2371 * Create an rpc pipe client struct, connecting to a tcp port.
2373 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2374 uint16_t port,
2375 const struct ndr_syntax_id *abstract_syntax,
2376 struct rpc_pipe_client **presult)
2378 struct rpc_pipe_client *result;
2379 struct sockaddr_storage addr;
2380 NTSTATUS status;
2381 int fd;
2383 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2384 if (result == NULL) {
2385 return NT_STATUS_NO_MEMORY;
2388 result->abstract_syntax = *abstract_syntax;
2389 result->transfer_syntax = ndr_transfer_syntax;
2391 result->desthost = talloc_strdup(result, host);
2392 result->srv_name_slash = talloc_asprintf_strupper_m(
2393 result, "\\\\%s", result->desthost);
2394 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2395 status = NT_STATUS_NO_MEMORY;
2396 goto fail;
2399 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2400 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2402 if (!resolve_name(host, &addr, 0, false)) {
2403 status = NT_STATUS_NOT_FOUND;
2404 goto fail;
2407 status = open_socket_out(&addr, port, 60*1000, &fd);
2408 if (!NT_STATUS_IS_OK(status)) {
2409 goto fail;
2411 set_socket_options(fd, lp_socket_options());
2413 status = rpc_transport_sock_init(result, fd, &result->transport);
2414 if (!NT_STATUS_IS_OK(status)) {
2415 close(fd);
2416 goto fail;
2419 result->transport->transport = NCACN_IP_TCP;
2421 result->binding_handle = rpccli_bh_create(result);
2422 if (result->binding_handle == NULL) {
2423 TALLOC_FREE(result);
2424 return NT_STATUS_NO_MEMORY;
2427 *presult = result;
2428 return NT_STATUS_OK;
2430 fail:
2431 TALLOC_FREE(result);
2432 return status;
2436 * Determine the tcp port on which a dcerpc interface is listening
2437 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2438 * target host.
2440 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2441 const struct ndr_syntax_id *abstract_syntax,
2442 uint16_t *pport)
2444 NTSTATUS status;
2445 struct rpc_pipe_client *epm_pipe = NULL;
2446 struct dcerpc_binding_handle *epm_handle = NULL;
2447 struct pipe_auth_data *auth = NULL;
2448 struct dcerpc_binding *map_binding = NULL;
2449 struct dcerpc_binding *res_binding = NULL;
2450 struct epm_twr_t *map_tower = NULL;
2451 struct epm_twr_t *res_towers = NULL;
2452 struct policy_handle *entry_handle = NULL;
2453 uint32_t num_towers = 0;
2454 uint32_t max_towers = 1;
2455 struct epm_twr_p_t towers;
2456 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2457 uint32_t result = 0;
2459 if (pport == NULL) {
2460 status = NT_STATUS_INVALID_PARAMETER;
2461 goto done;
2464 if (ndr_syntax_id_equal(abstract_syntax,
2465 &ndr_table_epmapper.syntax_id)) {
2466 *pport = 135;
2467 return NT_STATUS_OK;
2470 /* open the connection to the endpoint mapper */
2471 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2472 &ndr_table_epmapper.syntax_id,
2473 &epm_pipe);
2475 if (!NT_STATUS_IS_OK(status)) {
2476 goto done;
2478 epm_handle = epm_pipe->binding_handle;
2480 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2481 if (!NT_STATUS_IS_OK(status)) {
2482 goto done;
2485 status = rpc_pipe_bind(epm_pipe, auth);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 goto done;
2490 /* create tower for asking the epmapper */
2492 map_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
2493 if (map_binding == NULL) {
2494 status = NT_STATUS_NO_MEMORY;
2495 goto done;
2498 map_binding->transport = NCACN_IP_TCP;
2499 map_binding->object = *abstract_syntax;
2500 map_binding->host = host; /* needed? */
2501 map_binding->endpoint = "0"; /* correct? needed? */
2503 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2504 if (map_tower == NULL) {
2505 status = NT_STATUS_NO_MEMORY;
2506 goto done;
2509 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2510 &(map_tower->tower));
2511 if (!NT_STATUS_IS_OK(status)) {
2512 goto done;
2515 /* allocate further parameters for the epm_Map call */
2517 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2518 if (res_towers == NULL) {
2519 status = NT_STATUS_NO_MEMORY;
2520 goto done;
2522 towers.twr = res_towers;
2524 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2525 if (entry_handle == NULL) {
2526 status = NT_STATUS_NO_MEMORY;
2527 goto done;
2530 /* ask the endpoint mapper for the port */
2532 status = dcerpc_epm_Map(epm_handle,
2533 tmp_ctx,
2534 discard_const_p(struct GUID,
2535 &(abstract_syntax->uuid)),
2536 map_tower,
2537 entry_handle,
2538 max_towers,
2539 &num_towers,
2540 &towers,
2541 &result);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 goto done;
2547 if (result != EPMAPPER_STATUS_OK) {
2548 status = NT_STATUS_UNSUCCESSFUL;
2549 goto done;
2552 if (num_towers != 1) {
2553 status = NT_STATUS_UNSUCCESSFUL;
2554 goto done;
2557 /* extract the port from the answer */
2559 status = dcerpc_binding_from_tower(tmp_ctx,
2560 &(towers.twr->tower),
2561 &res_binding);
2562 if (!NT_STATUS_IS_OK(status)) {
2563 goto done;
2566 /* are further checks here necessary? */
2567 if (res_binding->transport != NCACN_IP_TCP) {
2568 status = NT_STATUS_UNSUCCESSFUL;
2569 goto done;
2572 *pport = (uint16_t)atoi(res_binding->endpoint);
2574 done:
2575 TALLOC_FREE(tmp_ctx);
2576 return status;
2580 * Create a rpc pipe client struct, connecting to a host via tcp.
2581 * The port is determined by asking the endpoint mapper on the given
2582 * host.
2584 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2585 const struct ndr_syntax_id *abstract_syntax,
2586 struct rpc_pipe_client **presult)
2588 NTSTATUS status;
2589 uint16_t port = 0;
2591 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2592 if (!NT_STATUS_IS_OK(status)) {
2593 return status;
2596 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2597 abstract_syntax, presult);
2600 /********************************************************************
2601 Create a rpc pipe client struct, connecting to a unix domain socket
2602 ********************************************************************/
2603 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2604 const struct ndr_syntax_id *abstract_syntax,
2605 struct rpc_pipe_client **presult)
2607 struct rpc_pipe_client *result;
2608 struct sockaddr_un addr;
2609 NTSTATUS status;
2610 int fd;
2612 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2613 if (result == NULL) {
2614 return NT_STATUS_NO_MEMORY;
2617 result->abstract_syntax = *abstract_syntax;
2618 result->transfer_syntax = ndr_transfer_syntax;
2620 result->desthost = get_myname(result);
2621 result->srv_name_slash = talloc_asprintf_strupper_m(
2622 result, "\\\\%s", result->desthost);
2623 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2624 status = NT_STATUS_NO_MEMORY;
2625 goto fail;
2628 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2629 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2631 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2632 if (fd == -1) {
2633 status = map_nt_error_from_unix(errno);
2634 goto fail;
2637 ZERO_STRUCT(addr);
2638 addr.sun_family = AF_UNIX;
2639 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2641 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2642 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2643 strerror(errno)));
2644 close(fd);
2645 return map_nt_error_from_unix(errno);
2648 status = rpc_transport_sock_init(result, fd, &result->transport);
2649 if (!NT_STATUS_IS_OK(status)) {
2650 close(fd);
2651 goto fail;
2654 result->transport->transport = NCALRPC;
2656 result->binding_handle = rpccli_bh_create(result);
2657 if (result->binding_handle == NULL) {
2658 TALLOC_FREE(result);
2659 return NT_STATUS_NO_MEMORY;
2662 *presult = result;
2663 return NT_STATUS_OK;
2665 fail:
2666 TALLOC_FREE(result);
2667 return status;
2670 struct rpc_pipe_client_np_ref {
2671 struct cli_state *cli;
2672 struct rpc_pipe_client *pipe;
2675 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2677 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2678 return 0;
2681 /****************************************************************************
2682 Open a named pipe over SMB to a remote server.
2684 * CAVEAT CALLER OF THIS FUNCTION:
2685 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2686 * so be sure that this function is called AFTER any structure (vs pointer)
2687 * assignment of the cli. In particular, libsmbclient does structure
2688 * assignments of cli, which invalidates the data in the returned
2689 * rpc_pipe_client if this function is called before the structure assignment
2690 * of cli.
2692 ****************************************************************************/
2694 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2695 const struct ndr_syntax_id *abstract_syntax,
2696 struct rpc_pipe_client **presult)
2698 struct rpc_pipe_client *result;
2699 NTSTATUS status;
2700 struct rpc_pipe_client_np_ref *np_ref;
2702 /* sanity check to protect against crashes */
2704 if ( !cli ) {
2705 return NT_STATUS_INVALID_HANDLE;
2708 result = talloc_zero(NULL, struct rpc_pipe_client);
2709 if (result == NULL) {
2710 return NT_STATUS_NO_MEMORY;
2713 result->abstract_syntax = *abstract_syntax;
2714 result->transfer_syntax = ndr_transfer_syntax;
2715 result->desthost = talloc_strdup(result, cli_state_remote_name(cli));
2716 result->srv_name_slash = talloc_asprintf_strupper_m(
2717 result, "\\\\%s", result->desthost);
2719 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2720 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2722 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2723 TALLOC_FREE(result);
2724 return NT_STATUS_NO_MEMORY;
2727 status = rpc_transport_np_init(result, cli, abstract_syntax,
2728 &result->transport);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 TALLOC_FREE(result);
2731 return status;
2734 result->transport->transport = NCACN_NP;
2736 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2737 if (np_ref == NULL) {
2738 TALLOC_FREE(result);
2739 return NT_STATUS_NO_MEMORY;
2741 np_ref->cli = cli;
2742 np_ref->pipe = result;
2744 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2745 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2747 result->binding_handle = rpccli_bh_create(result);
2748 if (result->binding_handle == NULL) {
2749 TALLOC_FREE(result);
2750 return NT_STATUS_NO_MEMORY;
2753 *presult = result;
2754 return NT_STATUS_OK;
2757 /****************************************************************************
2758 Open a pipe to a remote server.
2759 ****************************************************************************/
2761 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2762 enum dcerpc_transport_t transport,
2763 const struct ndr_syntax_id *interface,
2764 struct rpc_pipe_client **presult)
2766 switch (transport) {
2767 case NCACN_IP_TCP:
2768 return rpc_pipe_open_tcp(NULL, cli_state_remote_name(cli),
2769 interface, presult);
2770 case NCACN_NP:
2771 return rpc_pipe_open_np(cli, interface, presult);
2772 default:
2773 return NT_STATUS_NOT_IMPLEMENTED;
2777 /****************************************************************************
2778 Open a named pipe to an SMB server and bind anonymously.
2779 ****************************************************************************/
2781 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2782 enum dcerpc_transport_t transport,
2783 const struct ndr_syntax_id *interface,
2784 struct rpc_pipe_client **presult)
2786 struct rpc_pipe_client *result;
2787 struct pipe_auth_data *auth;
2788 NTSTATUS status;
2790 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2791 if (!NT_STATUS_IS_OK(status)) {
2792 return status;
2795 status = rpccli_anon_bind_data(result, &auth);
2796 if (!NT_STATUS_IS_OK(status)) {
2797 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2798 nt_errstr(status)));
2799 TALLOC_FREE(result);
2800 return status;
2804 * This is a bit of an abstraction violation due to the fact that an
2805 * anonymous bind on an authenticated SMB inherits the user/domain
2806 * from the enclosing SMB creds
2809 TALLOC_FREE(auth->user_name);
2810 TALLOC_FREE(auth->domain);
2812 auth->user_name = talloc_strdup(auth, cli->user_name);
2813 auth->domain = talloc_strdup(auth, cli->domain);
2814 auth->user_session_key = data_blob_talloc(auth,
2815 cli->user_session_key.data,
2816 cli->user_session_key.length);
2818 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2819 TALLOC_FREE(result);
2820 return NT_STATUS_NO_MEMORY;
2823 status = rpc_pipe_bind(result, auth);
2824 if (!NT_STATUS_IS_OK(status)) {
2825 int lvl = 0;
2826 if (ndr_syntax_id_equal(interface,
2827 &ndr_table_dssetup.syntax_id)) {
2828 /* non AD domains just don't have this pipe, avoid
2829 * level 0 statement in that case - gd */
2830 lvl = 3;
2832 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2833 "%s failed with error %s\n",
2834 get_pipe_name_from_syntax(talloc_tos(), interface),
2835 nt_errstr(status) ));
2836 TALLOC_FREE(result);
2837 return status;
2840 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2841 "%s and bound anonymously.\n",
2842 get_pipe_name_from_syntax(talloc_tos(), interface),
2843 result->desthost));
2845 *presult = result;
2846 return NT_STATUS_OK;
2849 /****************************************************************************
2850 ****************************************************************************/
2852 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2853 const struct ndr_syntax_id *interface,
2854 struct rpc_pipe_client **presult)
2856 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2857 interface, presult);
2860 /****************************************************************************
2861 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2862 ****************************************************************************/
2864 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2865 const struct ndr_syntax_id *interface,
2866 enum dcerpc_transport_t transport,
2867 enum dcerpc_AuthLevel auth_level,
2868 const char *domain,
2869 const char *username,
2870 const char *password,
2871 struct rpc_pipe_client **presult)
2873 struct rpc_pipe_client *result;
2874 struct pipe_auth_data *auth = NULL;
2875 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2876 NTSTATUS status;
2878 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2879 if (!NT_STATUS_IS_OK(status)) {
2880 return status;
2883 status = rpccli_ntlmssp_bind_data(result,
2884 auth_type, auth_level,
2885 domain, username, password,
2886 &auth);
2887 if (!NT_STATUS_IS_OK(status)) {
2888 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2889 nt_errstr(status)));
2890 goto err;
2893 status = rpc_pipe_bind(result, auth);
2894 if (!NT_STATUS_IS_OK(status)) {
2895 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2896 nt_errstr(status) ));
2897 goto err;
2900 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2901 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2902 get_pipe_name_from_syntax(talloc_tos(), interface),
2903 result->desthost, domain, username));
2905 *presult = result;
2906 return NT_STATUS_OK;
2908 err:
2910 TALLOC_FREE(result);
2911 return status;
2914 /****************************************************************************
2915 External interface.
2916 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2917 using session_key. sign and seal.
2919 The *pdc will be stolen onto this new pipe
2920 ****************************************************************************/
2922 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2923 const struct ndr_syntax_id *interface,
2924 enum dcerpc_transport_t transport,
2925 enum dcerpc_AuthLevel auth_level,
2926 const char *domain,
2927 struct netlogon_creds_CredentialState **pdc,
2928 struct rpc_pipe_client **presult)
2930 struct rpc_pipe_client *result;
2931 struct pipe_auth_data *auth;
2932 NTSTATUS status;
2934 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2935 if (!NT_STATUS_IS_OK(status)) {
2936 return status;
2939 status = rpccli_schannel_bind_data(result, domain, auth_level,
2940 *pdc, &auth);
2941 if (!NT_STATUS_IS_OK(status)) {
2942 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2943 nt_errstr(status)));
2944 TALLOC_FREE(result);
2945 return status;
2948 status = rpc_pipe_bind(result, auth);
2949 if (!NT_STATUS_IS_OK(status)) {
2950 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2951 "cli_rpc_pipe_bind failed with error %s\n",
2952 nt_errstr(status) ));
2953 TALLOC_FREE(result);
2954 return status;
2958 * The credentials on a new netlogon pipe are the ones we are passed
2959 * in - copy them over
2961 result->dc = netlogon_creds_copy(result, *pdc);
2962 if (result->dc == NULL) {
2963 TALLOC_FREE(result);
2964 return NT_STATUS_NO_MEMORY;
2967 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2968 "for domain %s and bound using schannel.\n",
2969 get_pipe_name_from_syntax(talloc_tos(), interface),
2970 result->desthost, domain));
2972 *presult = result;
2973 return NT_STATUS_OK;
2976 /****************************************************************************
2977 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2978 The idea is this can be called with service_princ, username and password all
2979 NULL so long as the caller has a TGT.
2980 ****************************************************************************/
2982 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
2983 const struct ndr_syntax_id *interface,
2984 enum dcerpc_transport_t transport,
2985 enum dcerpc_AuthLevel auth_level,
2986 const char *server,
2987 const char *username,
2988 const char *password,
2989 struct rpc_pipe_client **presult)
2991 struct rpc_pipe_client *result;
2992 struct pipe_auth_data *auth;
2993 struct gse_context *gse_ctx;
2994 NTSTATUS status;
2996 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2997 if (!NT_STATUS_IS_OK(status)) {
2998 return status;
3001 auth = talloc(result, struct pipe_auth_data);
3002 if (auth == NULL) {
3003 status = NT_STATUS_NO_MEMORY;
3004 goto err_out;
3006 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3007 auth->auth_level = auth_level;
3009 if (!username) {
3010 username = "";
3012 auth->user_name = talloc_strdup(auth, username);
3013 if (!auth->user_name) {
3014 status = NT_STATUS_NO_MEMORY;
3015 goto err_out;
3018 /* Fixme, should we fetch/set the Realm ? */
3019 auth->domain = talloc_strdup(auth, "");
3020 if (!auth->domain) {
3021 status = NT_STATUS_NO_MEMORY;
3022 goto err_out;
3025 status = gse_init_client(auth,
3026 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3027 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3028 NULL, server, "cifs", username, password,
3029 GSS_C_DCE_STYLE, &gse_ctx);
3030 if (!NT_STATUS_IS_OK(status)) {
3031 DEBUG(0, ("gse_init_client returned %s\n",
3032 nt_errstr(status)));
3033 goto err_out;
3035 auth->auth_ctx = gse_ctx;
3037 status = rpc_pipe_bind(result, auth);
3038 if (!NT_STATUS_IS_OK(status)) {
3039 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3040 nt_errstr(status)));
3041 goto err_out;
3044 *presult = result;
3045 return NT_STATUS_OK;
3047 err_out:
3048 TALLOC_FREE(result);
3049 return status;
3052 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3053 const struct ndr_syntax_id *interface,
3054 enum dcerpc_transport_t transport,
3055 enum dcerpc_AuthLevel auth_level,
3056 const char *server,
3057 const char *username,
3058 const char *password,
3059 struct rpc_pipe_client **presult)
3061 struct rpc_pipe_client *result;
3062 struct pipe_auth_data *auth;
3063 struct spnego_context *spnego_ctx;
3064 NTSTATUS status;
3066 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3067 if (!NT_STATUS_IS_OK(status)) {
3068 return status;
3071 auth = talloc(result, struct pipe_auth_data);
3072 if (auth == NULL) {
3073 status = NT_STATUS_NO_MEMORY;
3074 goto err_out;
3076 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3077 auth->auth_level = auth_level;
3079 if (!username) {
3080 username = "";
3082 auth->user_name = talloc_strdup(auth, username);
3083 if (!auth->user_name) {
3084 status = NT_STATUS_NO_MEMORY;
3085 goto err_out;
3088 /* Fixme, should we fetch/set the Realm ? */
3089 auth->domain = talloc_strdup(auth, "");
3090 if (!auth->domain) {
3091 status = NT_STATUS_NO_MEMORY;
3092 goto err_out;
3095 status = spnego_gssapi_init_client(auth,
3096 (auth->auth_level ==
3097 DCERPC_AUTH_LEVEL_INTEGRITY),
3098 (auth->auth_level ==
3099 DCERPC_AUTH_LEVEL_PRIVACY),
3100 true,
3101 NULL, server, "cifs",
3102 username, password,
3103 &spnego_ctx);
3104 if (!NT_STATUS_IS_OK(status)) {
3105 DEBUG(0, ("spnego_init_client returned %s\n",
3106 nt_errstr(status)));
3107 goto err_out;
3109 auth->auth_ctx = spnego_ctx;
3111 status = rpc_pipe_bind(result, auth);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3114 nt_errstr(status)));
3115 goto err_out;
3118 *presult = result;
3119 return NT_STATUS_OK;
3121 err_out:
3122 TALLOC_FREE(result);
3123 return status;
3126 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3127 const struct ndr_syntax_id *interface,
3128 enum dcerpc_transport_t transport,
3129 enum dcerpc_AuthLevel auth_level,
3130 const char *domain,
3131 const char *username,
3132 const char *password,
3133 struct rpc_pipe_client **presult)
3135 struct rpc_pipe_client *result;
3136 struct pipe_auth_data *auth;
3137 struct spnego_context *spnego_ctx;
3138 NTSTATUS status;
3140 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3141 if (!NT_STATUS_IS_OK(status)) {
3142 return status;
3145 auth = talloc(result, struct pipe_auth_data);
3146 if (auth == NULL) {
3147 status = NT_STATUS_NO_MEMORY;
3148 goto err_out;
3150 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3151 auth->auth_level = auth_level;
3153 if (!username) {
3154 username = "";
3156 auth->user_name = talloc_strdup(auth, username);
3157 if (!auth->user_name) {
3158 status = NT_STATUS_NO_MEMORY;
3159 goto err_out;
3162 if (!domain) {
3163 domain = "";
3165 auth->domain = talloc_strdup(auth, domain);
3166 if (!auth->domain) {
3167 status = NT_STATUS_NO_MEMORY;
3168 goto err_out;
3171 status = spnego_ntlmssp_init_client(auth,
3172 (auth->auth_level ==
3173 DCERPC_AUTH_LEVEL_INTEGRITY),
3174 (auth->auth_level ==
3175 DCERPC_AUTH_LEVEL_PRIVACY),
3176 true,
3177 domain, username, password,
3178 &spnego_ctx);
3179 if (!NT_STATUS_IS_OK(status)) {
3180 DEBUG(0, ("spnego_init_client returned %s\n",
3181 nt_errstr(status)));
3182 goto err_out;
3184 auth->auth_ctx = spnego_ctx;
3186 status = rpc_pipe_bind(result, auth);
3187 if (!NT_STATUS_IS_OK(status)) {
3188 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3189 nt_errstr(status)));
3190 goto err_out;
3193 *presult = result;
3194 return NT_STATUS_OK;
3196 err_out:
3197 TALLOC_FREE(result);
3198 return status;
3201 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3202 struct rpc_pipe_client *cli,
3203 DATA_BLOB *session_key)
3205 NTSTATUS status;
3206 struct pipe_auth_data *a;
3207 struct schannel_state *schannel_auth;
3208 struct gensec_security *gensec_security;
3209 struct spnego_context *spnego_ctx;
3210 struct gse_context *gse_ctx;
3211 DATA_BLOB sk = data_blob_null;
3212 bool make_dup = false;
3214 if (!session_key || !cli) {
3215 return NT_STATUS_INVALID_PARAMETER;
3218 a = cli->auth;
3220 if (a == NULL) {
3221 return NT_STATUS_INVALID_PARAMETER;
3224 switch (cli->auth->auth_type) {
3225 case DCERPC_AUTH_TYPE_SCHANNEL:
3226 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3227 struct schannel_state);
3228 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3229 make_dup = true;
3230 break;
3231 case DCERPC_AUTH_TYPE_SPNEGO:
3232 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3233 struct spnego_context);
3234 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3235 make_dup = false;
3236 break;
3237 case DCERPC_AUTH_TYPE_NTLMSSP:
3238 gensec_security = talloc_get_type_abort(a->auth_ctx,
3239 struct gensec_security);
3240 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3241 if (!NT_STATUS_IS_OK(status)) {
3242 return status;
3244 make_dup = false;
3245 break;
3246 case DCERPC_AUTH_TYPE_KRB5:
3247 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3248 struct gse_context);
3249 sk = gse_get_session_key(mem_ctx, gse_ctx);
3250 make_dup = false;
3251 break;
3252 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3253 case DCERPC_AUTH_TYPE_NONE:
3254 sk = data_blob_const(a->user_session_key.data,
3255 a->user_session_key.length);
3256 make_dup = true;
3257 break;
3258 default:
3259 break;
3262 if (!sk.data) {
3263 return NT_STATUS_NO_USER_SESSION_KEY;
3266 if (make_dup) {
3267 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3268 } else {
3269 *session_key = sk;
3272 return NT_STATUS_OK;