s3-rpc_client: Added DCERPC_AUTH_TYPE_NCALRPC bind.
[Samba.git] / source3 / rpc_client / cli_pipe.c
blob26a00547c3738665c23660536f9b63e10e914e25
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 "librpc/gen_ndr/ndr_epmapper_c.h"
23 #include "../librpc/gen_ndr/ndr_schannel.h"
24 #include "../librpc/gen_ndr/ndr_dssetup.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
27 #include "smb_krb5.h"
28 #include "../libcli/auth/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"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_RPC_CLI
40 /********************************************************************
41 Pipe description for a DEBUG
42 ********************************************************************/
43 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
44 struct rpc_pipe_client *cli)
46 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
47 if (result == NULL) {
48 return "pipe";
50 return result;
53 /********************************************************************
54 Rpc pipe call id.
55 ********************************************************************/
57 static uint32 get_rpc_call_id(void)
59 static uint32 call_id = 0;
60 return ++call_id;
63 /*******************************************************************
64 Use SMBreadX to get rest of one fragment's worth of rpc data.
65 Reads the whole size or give an error message
66 ********************************************************************/
68 struct rpc_read_state {
69 struct event_context *ev;
70 struct rpc_cli_transport *transport;
71 uint8_t *data;
72 size_t size;
73 size_t num_read;
76 static void rpc_read_done(struct tevent_req *subreq);
78 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
79 struct event_context *ev,
80 struct rpc_cli_transport *transport,
81 uint8_t *data, size_t size)
83 struct tevent_req *req, *subreq;
84 struct rpc_read_state *state;
86 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
87 if (req == NULL) {
88 return NULL;
90 state->ev = ev;
91 state->transport = transport;
92 state->data = data;
93 state->size = size;
94 state->num_read = 0;
96 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
98 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
99 transport->priv);
100 if (subreq == NULL) {
101 goto fail;
103 tevent_req_set_callback(subreq, rpc_read_done, req);
104 return req;
106 fail:
107 TALLOC_FREE(req);
108 return NULL;
111 static void rpc_read_done(struct tevent_req *subreq)
113 struct tevent_req *req = tevent_req_callback_data(
114 subreq, struct tevent_req);
115 struct rpc_read_state *state = tevent_req_data(
116 req, struct rpc_read_state);
117 NTSTATUS status;
118 ssize_t received;
120 status = state->transport->read_recv(subreq, &received);
121 TALLOC_FREE(subreq);
122 if (!NT_STATUS_IS_OK(status)) {
123 tevent_req_nterror(req, status);
124 return;
127 state->num_read += received;
128 if (state->num_read == state->size) {
129 tevent_req_done(req);
130 return;
133 subreq = state->transport->read_send(state, state->ev,
134 state->data + state->num_read,
135 state->size - state->num_read,
136 state->transport->priv);
137 if (tevent_req_nomem(subreq, req)) {
138 return;
140 tevent_req_set_callback(subreq, rpc_read_done, req);
143 static NTSTATUS rpc_read_recv(struct tevent_req *req)
145 return tevent_req_simple_recv_ntstatus(req);
148 struct rpc_write_state {
149 struct event_context *ev;
150 struct rpc_cli_transport *transport;
151 const uint8_t *data;
152 size_t size;
153 size_t num_written;
156 static void rpc_write_done(struct tevent_req *subreq);
158 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
159 struct event_context *ev,
160 struct rpc_cli_transport *transport,
161 const uint8_t *data, size_t size)
163 struct tevent_req *req, *subreq;
164 struct rpc_write_state *state;
166 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
167 if (req == NULL) {
168 return NULL;
170 state->ev = ev;
171 state->transport = transport;
172 state->data = data;
173 state->size = size;
174 state->num_written = 0;
176 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
178 subreq = transport->write_send(state, ev, data, size, transport->priv);
179 if (subreq == NULL) {
180 goto fail;
182 tevent_req_set_callback(subreq, rpc_write_done, req);
183 return req;
184 fail:
185 TALLOC_FREE(req);
186 return NULL;
189 static void rpc_write_done(struct tevent_req *subreq)
191 struct tevent_req *req = tevent_req_callback_data(
192 subreq, struct tevent_req);
193 struct rpc_write_state *state = tevent_req_data(
194 req, struct rpc_write_state);
195 NTSTATUS status;
196 ssize_t written;
198 status = state->transport->write_recv(subreq, &written);
199 TALLOC_FREE(subreq);
200 if (!NT_STATUS_IS_OK(status)) {
201 tevent_req_nterror(req, status);
202 return;
205 state->num_written += written;
207 if (state->num_written == state->size) {
208 tevent_req_done(req);
209 return;
212 subreq = state->transport->write_send(state, state->ev,
213 state->data + state->num_written,
214 state->size - state->num_written,
215 state->transport->priv);
216 if (tevent_req_nomem(subreq, req)) {
217 return;
219 tevent_req_set_callback(subreq, rpc_write_done, req);
222 static NTSTATUS rpc_write_recv(struct tevent_req *req)
224 return tevent_req_simple_recv_ntstatus(req);
228 /****************************************************************************
229 Try and get a PDU's worth of data from current_pdu. If not, then read more
230 from the wire.
231 ****************************************************************************/
233 struct get_complete_frag_state {
234 struct event_context *ev;
235 struct rpc_pipe_client *cli;
236 uint16_t frag_len;
237 DATA_BLOB *pdu;
240 static void get_complete_frag_got_header(struct tevent_req *subreq);
241 static void get_complete_frag_got_rest(struct tevent_req *subreq);
243 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
244 struct event_context *ev,
245 struct rpc_pipe_client *cli,
246 DATA_BLOB *pdu)
248 struct tevent_req *req, *subreq;
249 struct get_complete_frag_state *state;
250 size_t received;
251 NTSTATUS status;
253 req = tevent_req_create(mem_ctx, &state,
254 struct get_complete_frag_state);
255 if (req == NULL) {
256 return NULL;
258 state->ev = ev;
259 state->cli = cli;
260 state->frag_len = RPC_HEADER_LEN;
261 state->pdu = pdu;
263 received = pdu->length;
264 if (received < RPC_HEADER_LEN) {
265 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
266 status = NT_STATUS_NO_MEMORY;
267 goto post_status;
269 subreq = rpc_read_send(state, state->ev,
270 state->cli->transport,
271 pdu->data + received,
272 RPC_HEADER_LEN - received);
273 if (subreq == NULL) {
274 status = NT_STATUS_NO_MEMORY;
275 goto post_status;
277 tevent_req_set_callback(subreq, get_complete_frag_got_header,
278 req);
279 return req;
282 state->frag_len = dcerpc_get_frag_length(pdu);
285 * Ensure we have frag_len bytes of data.
287 if (received < state->frag_len) {
288 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
289 status = NT_STATUS_NO_MEMORY;
290 goto post_status;
292 subreq = rpc_read_send(state, state->ev,
293 state->cli->transport,
294 pdu->data + received,
295 state->frag_len - received);
296 if (subreq == NULL) {
297 status = NT_STATUS_NO_MEMORY;
298 goto post_status;
300 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
301 req);
302 return req;
305 status = NT_STATUS_OK;
306 post_status:
307 if (NT_STATUS_IS_OK(status)) {
308 tevent_req_done(req);
309 } else {
310 tevent_req_nterror(req, status);
312 return tevent_req_post(req, ev);
315 static void get_complete_frag_got_header(struct tevent_req *subreq)
317 struct tevent_req *req = tevent_req_callback_data(
318 subreq, struct tevent_req);
319 struct get_complete_frag_state *state = tevent_req_data(
320 req, struct get_complete_frag_state);
321 NTSTATUS status;
323 status = rpc_read_recv(subreq);
324 TALLOC_FREE(subreq);
325 if (!NT_STATUS_IS_OK(status)) {
326 tevent_req_nterror(req, status);
327 return;
330 state->frag_len = dcerpc_get_frag_length(state->pdu);
332 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
333 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
334 return;
338 * We're here in this piece of code because we've read exactly
339 * RPC_HEADER_LEN bytes into state->pdu.
342 subreq = rpc_read_send(state, state->ev, state->cli->transport,
343 state->pdu->data + RPC_HEADER_LEN,
344 state->frag_len - RPC_HEADER_LEN);
345 if (tevent_req_nomem(subreq, req)) {
346 return;
348 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
351 static void get_complete_frag_got_rest(struct tevent_req *subreq)
353 struct tevent_req *req = tevent_req_callback_data(
354 subreq, struct tevent_req);
355 NTSTATUS status;
357 status = rpc_read_recv(subreq);
358 TALLOC_FREE(subreq);
359 if (!NT_STATUS_IS_OK(status)) {
360 tevent_req_nterror(req, status);
361 return;
363 tevent_req_done(req);
366 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
368 return tevent_req_simple_recv_ntstatus(req);
371 /****************************************************************************
372 Do basic authentication checks on an incoming pdu.
373 ****************************************************************************/
375 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
376 struct rpc_pipe_client *cli,
377 struct ncacn_packet *pkt,
378 DATA_BLOB *pdu,
379 uint8_t expected_pkt_type,
380 DATA_BLOB *rdata,
381 DATA_BLOB *reply_pdu)
383 struct dcerpc_response *r;
384 NTSTATUS ret = NT_STATUS_OK;
385 size_t pad_len = 0;
388 * Point the return values at the real data including the RPC
389 * header. Just in case the caller wants it.
391 *rdata = *pdu;
393 /* Ensure we have the correct type. */
394 switch (pkt->ptype) {
395 case DCERPC_PKT_ALTER_RESP:
396 case DCERPC_PKT_BIND_ACK:
398 /* Client code never receives this kind of packets */
399 break;
402 case DCERPC_PKT_RESPONSE:
404 r = &pkt->u.response;
406 /* Here's where we deal with incoming sign/seal. */
407 ret = dcerpc_check_auth(cli->auth, pkt,
408 &r->stub_and_verifier,
409 DCERPC_RESPONSE_LENGTH,
410 pdu, &pad_len);
411 if (!NT_STATUS_IS_OK(ret)) {
412 return ret;
415 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
416 return NT_STATUS_BUFFER_TOO_SMALL;
419 /* Point the return values at the NDR data. */
420 rdata->data = r->stub_and_verifier.data;
422 if (pkt->auth_length) {
423 /* We've already done integer wrap tests in
424 * dcerpc_check_auth(). */
425 rdata->length = r->stub_and_verifier.length
426 - pad_len
427 - DCERPC_AUTH_TRAILER_LENGTH
428 - pkt->auth_length;
429 } else {
430 rdata->length = r->stub_and_verifier.length;
433 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
434 (long unsigned int)pdu->length,
435 (long unsigned int)rdata->length,
436 (unsigned int)pad_len));
439 * If this is the first reply, and the allocation hint is
440 * reasonable, try and set up the reply_pdu DATA_BLOB to the
441 * correct size.
444 if ((reply_pdu->length == 0) &&
445 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
446 if (!data_blob_realloc(mem_ctx, reply_pdu,
447 r->alloc_hint)) {
448 DEBUG(0, ("reply alloc hint %d too "
449 "large to allocate\n",
450 (int)r->alloc_hint));
451 return NT_STATUS_NO_MEMORY;
455 break;
457 case DCERPC_PKT_BIND_NAK:
458 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
459 rpccli_pipe_txt(talloc_tos(), cli)));
460 /* Use this for now... */
461 return NT_STATUS_NETWORK_ACCESS_DENIED;
463 case DCERPC_PKT_FAULT:
465 DEBUG(1, (__location__ ": RPC fault code %s received "
466 "from %s!\n",
467 dcerpc_errstr(talloc_tos(),
468 pkt->u.fault.status),
469 rpccli_pipe_txt(talloc_tos(), cli)));
471 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
472 return NT_STATUS_UNSUCCESSFUL;
473 } else {
474 return NT_STATUS(pkt->u.fault.status);
477 default:
478 DEBUG(0, (__location__ "Unknown packet type %u received "
479 "from %s!\n",
480 (unsigned int)pkt->ptype,
481 rpccli_pipe_txt(talloc_tos(), cli)));
482 return NT_STATUS_INVALID_INFO_CLASS;
485 if (pkt->ptype != expected_pkt_type) {
486 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
487 "RPC packet type - %u, not %u\n",
488 rpccli_pipe_txt(talloc_tos(), cli),
489 pkt->ptype, expected_pkt_type));
490 return NT_STATUS_INVALID_INFO_CLASS;
493 /* Do this just before return - we don't want to modify any rpc header
494 data before now as we may have needed to do cryptographic actions on
495 it before. */
497 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
498 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
499 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
500 "fragment first/last ON.\n"));
501 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
504 return NT_STATUS_OK;
507 /****************************************************************************
508 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
509 ****************************************************************************/
511 struct cli_api_pipe_state {
512 struct event_context *ev;
513 struct rpc_cli_transport *transport;
514 uint8_t *rdata;
515 uint32_t rdata_len;
518 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
519 static void cli_api_pipe_write_done(struct tevent_req *subreq);
520 static void cli_api_pipe_read_done(struct tevent_req *subreq);
522 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
523 struct event_context *ev,
524 struct rpc_cli_transport *transport,
525 uint8_t *data, size_t data_len,
526 uint32_t max_rdata_len)
528 struct tevent_req *req, *subreq;
529 struct cli_api_pipe_state *state;
530 NTSTATUS status;
532 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
533 if (req == NULL) {
534 return NULL;
536 state->ev = ev;
537 state->transport = transport;
539 if (max_rdata_len < RPC_HEADER_LEN) {
541 * For a RPC reply we always need at least RPC_HEADER_LEN
542 * bytes. We check this here because we will receive
543 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
545 status = NT_STATUS_INVALID_PARAMETER;
546 goto post_status;
549 if (transport->trans_send != NULL) {
550 subreq = transport->trans_send(state, ev, data, data_len,
551 max_rdata_len, transport->priv);
552 if (subreq == NULL) {
553 goto fail;
555 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
556 return req;
560 * If the transport does not provide a "trans" routine, i.e. for
561 * example the ncacn_ip_tcp transport, do the write/read step here.
564 subreq = rpc_write_send(state, ev, transport, data, data_len);
565 if (subreq == NULL) {
566 goto fail;
568 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
569 return req;
571 post_status:
572 tevent_req_nterror(req, status);
573 return tevent_req_post(req, ev);
574 fail:
575 TALLOC_FREE(req);
576 return NULL;
579 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
581 struct tevent_req *req = tevent_req_callback_data(
582 subreq, struct tevent_req);
583 struct cli_api_pipe_state *state = tevent_req_data(
584 req, struct cli_api_pipe_state);
585 NTSTATUS status;
587 status = state->transport->trans_recv(subreq, state, &state->rdata,
588 &state->rdata_len);
589 TALLOC_FREE(subreq);
590 if (!NT_STATUS_IS_OK(status)) {
591 tevent_req_nterror(req, status);
592 return;
594 tevent_req_done(req);
597 static void cli_api_pipe_write_done(struct tevent_req *subreq)
599 struct tevent_req *req = tevent_req_callback_data(
600 subreq, struct tevent_req);
601 struct cli_api_pipe_state *state = tevent_req_data(
602 req, struct cli_api_pipe_state);
603 NTSTATUS status;
605 status = rpc_write_recv(subreq);
606 TALLOC_FREE(subreq);
607 if (!NT_STATUS_IS_OK(status)) {
608 tevent_req_nterror(req, status);
609 return;
612 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
613 if (tevent_req_nomem(state->rdata, req)) {
614 return;
618 * We don't need to use rpc_read_send here, the upper layer will cope
619 * with a short read, transport->trans_send could also return less
620 * than state->max_rdata_len.
622 subreq = state->transport->read_send(state, state->ev, state->rdata,
623 RPC_HEADER_LEN,
624 state->transport->priv);
625 if (tevent_req_nomem(subreq, req)) {
626 return;
628 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
631 static void cli_api_pipe_read_done(struct tevent_req *subreq)
633 struct tevent_req *req = tevent_req_callback_data(
634 subreq, struct tevent_req);
635 struct cli_api_pipe_state *state = tevent_req_data(
636 req, struct cli_api_pipe_state);
637 NTSTATUS status;
638 ssize_t received;
640 status = state->transport->read_recv(subreq, &received);
641 TALLOC_FREE(subreq);
642 if (!NT_STATUS_IS_OK(status)) {
643 tevent_req_nterror(req, status);
644 return;
646 state->rdata_len = received;
647 tevent_req_done(req);
650 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
651 uint8_t **prdata, uint32_t *prdata_len)
653 struct cli_api_pipe_state *state = tevent_req_data(
654 req, struct cli_api_pipe_state);
655 NTSTATUS status;
657 if (tevent_req_is_nterror(req, &status)) {
658 return status;
661 *prdata = talloc_move(mem_ctx, &state->rdata);
662 *prdata_len = state->rdata_len;
663 return NT_STATUS_OK;
666 /****************************************************************************
667 Send data on an rpc pipe via trans. The data must be the last
668 pdu fragment of an NDR data stream.
670 Receive response data from an rpc pipe, which may be large...
672 Read the first fragment: unfortunately have to use SMBtrans for the first
673 bit, then SMBreadX for subsequent bits.
675 If first fragment received also wasn't the last fragment, continue
676 getting fragments until we _do_ receive the last fragment.
678 Request/Response PDU's look like the following...
680 |<------------------PDU len----------------------------------------------->|
681 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
683 +------------+-----------------+-------------+---------------+-------------+
684 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
685 +------------+-----------------+-------------+---------------+-------------+
687 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
688 signing & sealing being negotiated.
690 ****************************************************************************/
692 struct rpc_api_pipe_state {
693 struct event_context *ev;
694 struct rpc_pipe_client *cli;
695 uint8_t expected_pkt_type;
697 DATA_BLOB incoming_frag;
698 struct ncacn_packet *pkt;
700 /* Incoming reply */
701 DATA_BLOB reply_pdu;
702 size_t reply_pdu_offset;
703 uint8_t endianess;
706 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
707 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
708 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
710 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
711 struct event_context *ev,
712 struct rpc_pipe_client *cli,
713 DATA_BLOB *data, /* Outgoing PDU */
714 uint8_t expected_pkt_type)
716 struct tevent_req *req, *subreq;
717 struct rpc_api_pipe_state *state;
718 uint16_t max_recv_frag;
719 NTSTATUS status;
721 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
722 if (req == NULL) {
723 return NULL;
725 state->ev = ev;
726 state->cli = cli;
727 state->expected_pkt_type = expected_pkt_type;
728 state->incoming_frag = data_blob_null;
729 state->reply_pdu = data_blob_null;
730 state->reply_pdu_offset = 0;
731 state->endianess = DCERPC_DREP_LE;
734 * Ensure we're not sending too much.
736 if (data->length > cli->max_xmit_frag) {
737 status = NT_STATUS_INVALID_PARAMETER;
738 goto post_status;
741 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
743 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
744 subreq = rpc_write_send(state, ev, cli->transport,
745 data->data, data->length);
746 if (subreq == NULL) {
747 goto fail;
749 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
750 return req;
753 /* get the header first, then fetch the rest once we have
754 * the frag_length available */
755 max_recv_frag = RPC_HEADER_LEN;
757 subreq = cli_api_pipe_send(state, ev, cli->transport,
758 data->data, data->length, max_recv_frag);
759 if (subreq == NULL) {
760 goto fail;
762 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
763 return req;
765 post_status:
766 tevent_req_nterror(req, status);
767 return tevent_req_post(req, ev);
768 fail:
769 TALLOC_FREE(req);
770 return NULL;
773 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
775 struct tevent_req *req =
776 tevent_req_callback_data(subreq,
777 struct tevent_req);
778 NTSTATUS status;
780 status = rpc_write_recv(subreq);
781 TALLOC_FREE(subreq);
782 if (!NT_STATUS_IS_OK(status)) {
783 tevent_req_nterror(req, status);
784 return;
787 tevent_req_done(req);
790 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
792 struct tevent_req *req = tevent_req_callback_data(
793 subreq, struct tevent_req);
794 struct rpc_api_pipe_state *state = tevent_req_data(
795 req, struct rpc_api_pipe_state);
796 NTSTATUS status;
797 uint8_t *rdata = NULL;
798 uint32_t rdata_len = 0;
800 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
801 TALLOC_FREE(subreq);
802 if (!NT_STATUS_IS_OK(status)) {
803 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
804 tevent_req_nterror(req, status);
805 return;
808 if (rdata == NULL) {
809 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
810 rpccli_pipe_txt(talloc_tos(), state->cli)));
811 tevent_req_done(req);
812 return;
816 * Move data on state->incoming_frag.
818 state->incoming_frag.data = talloc_move(state, &rdata);
819 state->incoming_frag.length = rdata_len;
820 if (!state->incoming_frag.data) {
821 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
822 return;
825 /* Ensure we have enough data for a pdu. */
826 subreq = get_complete_frag_send(state, state->ev, state->cli,
827 &state->incoming_frag);
828 if (tevent_req_nomem(subreq, req)) {
829 return;
831 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
834 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
836 struct tevent_req *req = tevent_req_callback_data(
837 subreq, struct tevent_req);
838 struct rpc_api_pipe_state *state = tevent_req_data(
839 req, struct rpc_api_pipe_state);
840 NTSTATUS status;
841 DATA_BLOB rdata = data_blob_null;
843 status = get_complete_frag_recv(subreq);
844 TALLOC_FREE(subreq);
845 if (!NT_STATUS_IS_OK(status)) {
846 DEBUG(5, ("get_complete_frag failed: %s\n",
847 nt_errstr(status)));
848 tevent_req_nterror(req, status);
849 return;
852 state->pkt = talloc(state, struct ncacn_packet);
853 if (!state->pkt) {
854 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
855 return;
858 status = dcerpc_pull_ncacn_packet(state->pkt,
859 &state->incoming_frag,
860 state->pkt,
861 !state->endianess);
862 if (!NT_STATUS_IS_OK(status)) {
863 tevent_req_nterror(req, status);
864 return;
867 if (state->incoming_frag.length != state->pkt->frag_length) {
868 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
869 (unsigned int)state->incoming_frag.length,
870 (unsigned int)state->pkt->frag_length));
871 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
872 return;
875 status = cli_pipe_validate_current_pdu(state,
876 state->cli, state->pkt,
877 &state->incoming_frag,
878 state->expected_pkt_type,
879 &rdata,
880 &state->reply_pdu);
882 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
883 (unsigned)state->incoming_frag.length,
884 (unsigned)state->reply_pdu_offset,
885 nt_errstr(status)));
887 if (!NT_STATUS_IS_OK(status)) {
888 tevent_req_nterror(req, status);
889 return;
892 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
893 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
895 * Set the data type correctly for big-endian data on the
896 * first packet.
898 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
899 "big-endian.\n",
900 rpccli_pipe_txt(talloc_tos(), state->cli)));
901 state->endianess = 0x00; /* BIG ENDIAN */
904 * Check endianness on subsequent packets.
906 if (state->endianess != state->pkt->drep[0]) {
907 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
908 "%s\n",
909 state->endianess?"little":"big",
910 state->pkt->drep[0]?"little":"big"));
911 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
912 return;
915 /* Now copy the data portion out of the pdu into rbuf. */
916 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
917 if (!data_blob_realloc(NULL, &state->reply_pdu,
918 state->reply_pdu_offset + rdata.length)) {
919 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
920 return;
924 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
925 rdata.data, rdata.length);
926 state->reply_pdu_offset += rdata.length;
928 /* reset state->incoming_frag, there is no need to free it,
929 * it will be reallocated to the right size the next time
930 * it is used */
931 state->incoming_frag.length = 0;
933 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
934 /* make sure the pdu length is right now that we
935 * have all the data available (alloc hint may
936 * have allocated more than was actually used) */
937 state->reply_pdu.length = state->reply_pdu_offset;
938 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
939 rpccli_pipe_txt(talloc_tos(), state->cli),
940 (unsigned)state->reply_pdu.length));
941 tevent_req_done(req);
942 return;
945 subreq = get_complete_frag_send(state, state->ev, state->cli,
946 &state->incoming_frag);
947 if (tevent_req_nomem(subreq, req)) {
948 return;
950 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
953 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
954 struct ncacn_packet **pkt,
955 DATA_BLOB *reply_pdu)
957 struct rpc_api_pipe_state *state = tevent_req_data(
958 req, struct rpc_api_pipe_state);
959 NTSTATUS status;
961 if (tevent_req_is_nterror(req, &status)) {
962 return status;
965 /* return data to caller and assign it ownership of memory */
966 if (reply_pdu) {
967 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
968 reply_pdu->length = state->reply_pdu.length;
969 state->reply_pdu.length = 0;
970 } else {
971 data_blob_free(&state->reply_pdu);
974 if (pkt) {
975 *pkt = talloc_steal(mem_ctx, state->pkt);
978 return NT_STATUS_OK;
981 /*******************************************************************
982 Creates spnego auth bind.
983 ********************************************************************/
985 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
986 struct pipe_auth_data *auth,
987 DATA_BLOB *auth_token)
989 struct spnego_context *spnego_ctx;
990 DATA_BLOB in_token = data_blob_null;
991 NTSTATUS status;
993 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
994 struct spnego_context);
996 /* Negotiate the initial auth token */
997 status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
998 &in_token, auth_token);
999 if (!NT_STATUS_IS_OK(status)) {
1000 return status;
1003 DEBUG(5, ("Created GSS Authentication Token:\n"));
1004 dump_data(5, auth_token->data, auth_token->length);
1006 return NT_STATUS_OK;
1009 /*******************************************************************
1010 Creates krb5 auth bind.
1011 ********************************************************************/
1013 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
1014 struct pipe_auth_data *auth,
1015 DATA_BLOB *auth_token)
1017 struct gse_context *gse_ctx;
1018 DATA_BLOB in_token = data_blob_null;
1019 NTSTATUS status;
1021 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
1022 struct gse_context);
1024 /* Negotiate the initial auth token */
1025 status = gse_get_client_auth_token(mem_ctx, gse_ctx,
1026 &in_token,
1027 auth_token);
1028 if (!NT_STATUS_IS_OK(status)) {
1029 return status;
1032 DEBUG(5, ("Created GSS Authentication Token:\n"));
1033 dump_data(5, auth_token->data, auth_token->length);
1035 return NT_STATUS_OK;
1038 /*******************************************************************
1039 Creates NTLMSSP auth bind.
1040 ********************************************************************/
1042 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1043 DATA_BLOB *auth_token)
1045 struct auth_ntlmssp_state *ntlmssp_ctx;
1046 DATA_BLOB null_blob = data_blob_null;
1047 NTSTATUS status;
1049 ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx,
1050 struct auth_ntlmssp_state);
1052 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1053 status = auth_ntlmssp_update(ntlmssp_ctx, null_blob, auth_token);
1055 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1056 data_blob_free(auth_token);
1057 return status;
1060 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1061 dump_data(5, auth_token->data, auth_token->length);
1063 return NT_STATUS_OK;
1066 /*******************************************************************
1067 Creates schannel auth bind.
1068 ********************************************************************/
1070 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1071 DATA_BLOB *auth_token)
1073 NTSTATUS status;
1074 struct NL_AUTH_MESSAGE r;
1076 /* Use lp_workgroup() if domain not specified */
1078 if (!cli->auth->domain || !cli->auth->domain[0]) {
1079 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1080 if (cli->auth->domain == NULL) {
1081 return NT_STATUS_NO_MEMORY;
1086 * Now marshall the data into the auth parse_struct.
1089 r.MessageType = NL_NEGOTIATE_REQUEST;
1090 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1091 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1092 r.oem_netbios_domain.a = cli->auth->domain;
1093 r.oem_netbios_computer.a = global_myname();
1095 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1096 if (!NT_STATUS_IS_OK(status)) {
1097 return status;
1100 return NT_STATUS_OK;
1103 /*******************************************************************
1104 Creates the internals of a DCE/RPC bind request or alter context PDU.
1105 ********************************************************************/
1107 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1108 enum dcerpc_pkt_type ptype,
1109 uint32 rpc_call_id,
1110 const struct ndr_syntax_id *abstract,
1111 const struct ndr_syntax_id *transfer,
1112 const DATA_BLOB *auth_info,
1113 DATA_BLOB *blob)
1115 uint16 auth_len = auth_info->length;
1116 NTSTATUS status;
1117 union dcerpc_payload u;
1118 struct dcerpc_ctx_list ctx_list;
1120 if (auth_len) {
1121 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1124 ctx_list.context_id = 0;
1125 ctx_list.num_transfer_syntaxes = 1;
1126 ctx_list.abstract_syntax = *abstract;
1127 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1129 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1130 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1131 u.bind.assoc_group_id = 0x0;
1132 u.bind.num_contexts = 1;
1133 u.bind.ctx_list = &ctx_list;
1134 u.bind.auth_info = *auth_info;
1136 status = dcerpc_push_ncacn_packet(mem_ctx,
1137 ptype,
1138 DCERPC_PFC_FLAG_FIRST |
1139 DCERPC_PFC_FLAG_LAST,
1140 auth_len,
1141 rpc_call_id,
1143 blob);
1144 if (!NT_STATUS_IS_OK(status)) {
1145 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1146 return status;
1149 return NT_STATUS_OK;
1152 /*******************************************************************
1153 Creates a DCE/RPC bind request.
1154 ********************************************************************/
1156 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1157 struct rpc_pipe_client *cli,
1158 struct pipe_auth_data *auth,
1159 uint32 rpc_call_id,
1160 const struct ndr_syntax_id *abstract,
1161 const struct ndr_syntax_id *transfer,
1162 DATA_BLOB *rpc_out)
1164 DATA_BLOB auth_token = data_blob_null;
1165 DATA_BLOB auth_info = data_blob_null;
1166 NTSTATUS ret = NT_STATUS_OK;
1168 switch (auth->auth_type) {
1169 case DCERPC_AUTH_TYPE_SCHANNEL:
1170 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1171 if (!NT_STATUS_IS_OK(ret)) {
1172 return ret;
1174 break;
1176 case DCERPC_AUTH_TYPE_NTLMSSP:
1177 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
1178 if (!NT_STATUS_IS_OK(ret)) {
1179 return ret;
1181 break;
1183 case DCERPC_AUTH_TYPE_SPNEGO:
1184 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1185 if (!NT_STATUS_IS_OK(ret)) {
1186 return ret;
1188 break;
1190 case DCERPC_AUTH_TYPE_KRB5:
1191 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1192 if (!NT_STATUS_IS_OK(ret)) {
1193 return ret;
1195 break;
1197 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1198 auth_token = data_blob_talloc(mem_ctx,
1199 "NCALRPC_AUTH_TOKEN",
1200 18);
1201 break;
1203 case DCERPC_AUTH_TYPE_NONE:
1204 break;
1206 default:
1207 /* "Can't" happen. */
1208 return NT_STATUS_INVALID_INFO_CLASS;
1211 if (auth_token.length != 0) {
1212 ret = dcerpc_push_dcerpc_auth(cli,
1213 auth->auth_type,
1214 auth->auth_level,
1215 0, /* auth_pad_length */
1216 1, /* auth_context_id */
1217 &auth_token,
1218 &auth_info);
1219 if (!NT_STATUS_IS_OK(ret)) {
1220 return ret;
1222 data_blob_free(&auth_token);
1225 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1226 DCERPC_PKT_BIND,
1227 rpc_call_id,
1228 abstract,
1229 transfer,
1230 &auth_info,
1231 rpc_out);
1232 return ret;
1235 /*******************************************************************
1236 External interface.
1237 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1238 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1239 and deals with signing/sealing details.
1240 ********************************************************************/
1242 struct rpc_api_pipe_req_state {
1243 struct event_context *ev;
1244 struct rpc_pipe_client *cli;
1245 uint8_t op_num;
1246 uint32_t call_id;
1247 DATA_BLOB *req_data;
1248 uint32_t req_data_sent;
1249 DATA_BLOB rpc_out;
1250 DATA_BLOB reply_pdu;
1253 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1254 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1255 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1256 bool *is_last_frag);
1258 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1259 struct event_context *ev,
1260 struct rpc_pipe_client *cli,
1261 uint8_t op_num,
1262 DATA_BLOB *req_data)
1264 struct tevent_req *req, *subreq;
1265 struct rpc_api_pipe_req_state *state;
1266 NTSTATUS status;
1267 bool is_last_frag;
1269 req = tevent_req_create(mem_ctx, &state,
1270 struct rpc_api_pipe_req_state);
1271 if (req == NULL) {
1272 return NULL;
1274 state->ev = ev;
1275 state->cli = cli;
1276 state->op_num = op_num;
1277 state->req_data = req_data;
1278 state->req_data_sent = 0;
1279 state->call_id = get_rpc_call_id();
1280 state->reply_pdu = data_blob_null;
1281 state->rpc_out = data_blob_null;
1283 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1284 + RPC_MAX_SIGN_SIZE) {
1285 /* Server is screwed up ! */
1286 status = NT_STATUS_INVALID_PARAMETER;
1287 goto post_status;
1290 status = prepare_next_frag(state, &is_last_frag);
1291 if (!NT_STATUS_IS_OK(status)) {
1292 goto post_status;
1295 if (is_last_frag) {
1296 subreq = rpc_api_pipe_send(state, ev, state->cli,
1297 &state->rpc_out,
1298 DCERPC_PKT_RESPONSE);
1299 if (subreq == NULL) {
1300 goto fail;
1302 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1303 } else {
1304 subreq = rpc_write_send(state, ev, cli->transport,
1305 state->rpc_out.data,
1306 state->rpc_out.length);
1307 if (subreq == NULL) {
1308 goto fail;
1310 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1311 req);
1313 return req;
1315 post_status:
1316 tevent_req_nterror(req, status);
1317 return tevent_req_post(req, ev);
1318 fail:
1319 TALLOC_FREE(req);
1320 return NULL;
1323 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1324 bool *is_last_frag)
1326 size_t data_sent_thistime;
1327 size_t auth_len;
1328 size_t frag_len;
1329 uint8_t flags = 0;
1330 size_t pad_len;
1331 size_t data_left;
1332 NTSTATUS status;
1333 union dcerpc_payload u;
1335 data_left = state->req_data->length - state->req_data_sent;
1337 status = dcerpc_guess_sizes(state->cli->auth,
1338 DCERPC_REQUEST_LENGTH, data_left,
1339 state->cli->max_xmit_frag,
1340 CLIENT_NDR_PADDING_SIZE,
1341 &data_sent_thistime,
1342 &frag_len, &auth_len, &pad_len);
1343 if (!NT_STATUS_IS_OK(status)) {
1344 return status;
1347 if (state->req_data_sent == 0) {
1348 flags = DCERPC_PFC_FLAG_FIRST;
1351 if (data_sent_thistime == data_left) {
1352 flags |= DCERPC_PFC_FLAG_LAST;
1355 data_blob_free(&state->rpc_out);
1357 ZERO_STRUCT(u.request);
1359 u.request.alloc_hint = state->req_data->length;
1360 u.request.context_id = 0;
1361 u.request.opnum = state->op_num;
1363 status = dcerpc_push_ncacn_packet(state,
1364 DCERPC_PKT_REQUEST,
1365 flags,
1366 auth_len,
1367 state->call_id,
1369 &state->rpc_out);
1370 if (!NT_STATUS_IS_OK(status)) {
1371 return status;
1374 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1375 * compute it right for requests because the auth trailer is missing
1376 * at this stage */
1377 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1379 /* Copy in the data. */
1380 if (!data_blob_append(NULL, &state->rpc_out,
1381 state->req_data->data + state->req_data_sent,
1382 data_sent_thistime)) {
1383 return NT_STATUS_NO_MEMORY;
1386 switch (state->cli->auth->auth_level) {
1387 case DCERPC_AUTH_LEVEL_NONE:
1388 case DCERPC_AUTH_LEVEL_CONNECT:
1389 case DCERPC_AUTH_LEVEL_PACKET:
1390 break;
1391 case DCERPC_AUTH_LEVEL_INTEGRITY:
1392 case DCERPC_AUTH_LEVEL_PRIVACY:
1393 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1394 &state->rpc_out);
1395 if (!NT_STATUS_IS_OK(status)) {
1396 return status;
1398 break;
1399 default:
1400 return NT_STATUS_INVALID_PARAMETER;
1403 state->req_data_sent += data_sent_thistime;
1404 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1406 return status;
1409 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1411 struct tevent_req *req = tevent_req_callback_data(
1412 subreq, struct tevent_req);
1413 struct rpc_api_pipe_req_state *state = tevent_req_data(
1414 req, struct rpc_api_pipe_req_state);
1415 NTSTATUS status;
1416 bool is_last_frag;
1418 status = rpc_write_recv(subreq);
1419 TALLOC_FREE(subreq);
1420 if (!NT_STATUS_IS_OK(status)) {
1421 tevent_req_nterror(req, status);
1422 return;
1425 status = prepare_next_frag(state, &is_last_frag);
1426 if (!NT_STATUS_IS_OK(status)) {
1427 tevent_req_nterror(req, status);
1428 return;
1431 if (is_last_frag) {
1432 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1433 &state->rpc_out,
1434 DCERPC_PKT_RESPONSE);
1435 if (tevent_req_nomem(subreq, req)) {
1436 return;
1438 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1439 } else {
1440 subreq = rpc_write_send(state, state->ev,
1441 state->cli->transport,
1442 state->rpc_out.data,
1443 state->rpc_out.length);
1444 if (tevent_req_nomem(subreq, req)) {
1445 return;
1447 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1448 req);
1452 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1454 struct tevent_req *req = tevent_req_callback_data(
1455 subreq, struct tevent_req);
1456 struct rpc_api_pipe_req_state *state = tevent_req_data(
1457 req, struct rpc_api_pipe_req_state);
1458 NTSTATUS status;
1460 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1461 TALLOC_FREE(subreq);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 tevent_req_nterror(req, status);
1464 return;
1466 tevent_req_done(req);
1469 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1470 DATA_BLOB *reply_pdu)
1472 struct rpc_api_pipe_req_state *state = tevent_req_data(
1473 req, struct rpc_api_pipe_req_state);
1474 NTSTATUS status;
1476 if (tevent_req_is_nterror(req, &status)) {
1478 * We always have to initialize to reply pdu, even if there is
1479 * none. The rpccli_* caller routines expect this.
1481 *reply_pdu = data_blob_null;
1482 return status;
1485 /* return data to caller and assign it ownership of memory */
1486 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1487 reply_pdu->length = state->reply_pdu.length;
1488 state->reply_pdu.length = 0;
1490 return NT_STATUS_OK;
1493 /****************************************************************************
1494 Check the rpc bind acknowledge response.
1495 ****************************************************************************/
1497 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1498 const struct ndr_syntax_id *transfer)
1500 struct dcerpc_ack_ctx ctx;
1502 if (r->secondary_address_size == 0) {
1503 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1506 if (r->num_results < 1 || !r->ctx_list) {
1507 return false;
1510 ctx = r->ctx_list[0];
1512 /* check the transfer syntax */
1513 if ((ctx.syntax.if_version != transfer->if_version) ||
1514 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1515 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1516 return False;
1519 if (r->num_results != 0x1 || ctx.result != 0) {
1520 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1521 r->num_results, ctx.reason));
1524 DEBUG(5,("check_bind_response: accepted!\n"));
1525 return True;
1528 /*******************************************************************
1529 Creates a DCE/RPC bind authentication response.
1530 This is the packet that is sent back to the server once we
1531 have received a BIND-ACK, to finish the third leg of
1532 the authentication handshake.
1533 ********************************************************************/
1535 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1536 struct rpc_pipe_client *cli,
1537 uint32 rpc_call_id,
1538 enum dcerpc_AuthType auth_type,
1539 enum dcerpc_AuthLevel auth_level,
1540 DATA_BLOB *pauth_blob,
1541 DATA_BLOB *rpc_out)
1543 NTSTATUS status;
1544 union dcerpc_payload u;
1546 u.auth3._pad = 0;
1548 status = dcerpc_push_dcerpc_auth(mem_ctx,
1549 auth_type,
1550 auth_level,
1551 0, /* auth_pad_length */
1552 1, /* auth_context_id */
1553 pauth_blob,
1554 &u.auth3.auth_info);
1555 if (!NT_STATUS_IS_OK(status)) {
1556 return status;
1559 status = dcerpc_push_ncacn_packet(mem_ctx,
1560 DCERPC_PKT_AUTH3,
1561 DCERPC_PFC_FLAG_FIRST |
1562 DCERPC_PFC_FLAG_LAST,
1563 pauth_blob->length,
1564 rpc_call_id,
1566 rpc_out);
1567 data_blob_free(&u.auth3.auth_info);
1568 if (!NT_STATUS_IS_OK(status)) {
1569 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1570 return status;
1573 return NT_STATUS_OK;
1576 /*******************************************************************
1577 Creates a DCE/RPC bind alter context authentication request which
1578 may contain a spnego auth blobl
1579 ********************************************************************/
1581 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1582 enum dcerpc_AuthType auth_type,
1583 enum dcerpc_AuthLevel auth_level,
1584 uint32 rpc_call_id,
1585 const struct ndr_syntax_id *abstract,
1586 const struct ndr_syntax_id *transfer,
1587 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1588 DATA_BLOB *rpc_out)
1590 DATA_BLOB auth_info;
1591 NTSTATUS status;
1593 status = dcerpc_push_dcerpc_auth(mem_ctx,
1594 auth_type,
1595 auth_level,
1596 0, /* auth_pad_length */
1597 1, /* auth_context_id */
1598 pauth_blob,
1599 &auth_info);
1600 if (!NT_STATUS_IS_OK(status)) {
1601 return status;
1604 status = create_bind_or_alt_ctx_internal(mem_ctx,
1605 DCERPC_PKT_ALTER,
1606 rpc_call_id,
1607 abstract,
1608 transfer,
1609 &auth_info,
1610 rpc_out);
1611 data_blob_free(&auth_info);
1612 return status;
1615 /****************************************************************************
1616 Do an rpc bind.
1617 ****************************************************************************/
1619 struct rpc_pipe_bind_state {
1620 struct event_context *ev;
1621 struct rpc_pipe_client *cli;
1622 DATA_BLOB rpc_out;
1623 bool auth3;
1624 uint32_t rpc_call_id;
1627 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1628 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1629 struct rpc_pipe_bind_state *state,
1630 DATA_BLOB *credentials);
1631 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1632 struct rpc_pipe_bind_state *state,
1633 DATA_BLOB *credentials);
1635 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1636 struct event_context *ev,
1637 struct rpc_pipe_client *cli,
1638 struct pipe_auth_data *auth)
1640 struct tevent_req *req, *subreq;
1641 struct rpc_pipe_bind_state *state;
1642 NTSTATUS status;
1644 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1645 if (req == NULL) {
1646 return NULL;
1649 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1650 rpccli_pipe_txt(talloc_tos(), cli),
1651 (unsigned int)auth->auth_type,
1652 (unsigned int)auth->auth_level ));
1654 state->ev = ev;
1655 state->cli = cli;
1656 state->rpc_call_id = get_rpc_call_id();
1658 cli->auth = talloc_move(cli, &auth);
1660 /* Marshall the outgoing data. */
1661 status = create_rpc_bind_req(state, cli,
1662 cli->auth,
1663 state->rpc_call_id,
1664 &cli->abstract_syntax,
1665 &cli->transfer_syntax,
1666 &state->rpc_out);
1668 if (!NT_STATUS_IS_OK(status)) {
1669 goto post_status;
1672 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1673 DCERPC_PKT_BIND_ACK);
1674 if (subreq == NULL) {
1675 goto fail;
1677 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1678 return req;
1680 post_status:
1681 tevent_req_nterror(req, status);
1682 return tevent_req_post(req, ev);
1683 fail:
1684 TALLOC_FREE(req);
1685 return NULL;
1688 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1690 struct tevent_req *req = tevent_req_callback_data(
1691 subreq, struct tevent_req);
1692 struct rpc_pipe_bind_state *state = tevent_req_data(
1693 req, struct rpc_pipe_bind_state);
1694 struct pipe_auth_data *pauth = state->cli->auth;
1695 struct auth_ntlmssp_state *ntlmssp_ctx;
1696 struct spnego_context *spnego_ctx;
1697 struct gse_context *gse_ctx;
1698 struct ncacn_packet *pkt = NULL;
1699 struct dcerpc_auth auth;
1700 DATA_BLOB auth_token = data_blob_null;
1701 NTSTATUS status;
1703 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1704 TALLOC_FREE(subreq);
1705 if (!NT_STATUS_IS_OK(status)) {
1706 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1707 rpccli_pipe_txt(talloc_tos(), state->cli),
1708 nt_errstr(status)));
1709 tevent_req_nterror(req, status);
1710 return;
1713 if (state->auth3) {
1714 tevent_req_done(req);
1715 return;
1718 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1719 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1720 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1721 return;
1724 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1725 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1727 switch(pauth->auth_type) {
1729 case DCERPC_AUTH_TYPE_NONE:
1730 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1731 case DCERPC_AUTH_TYPE_SCHANNEL:
1732 /* Bind complete. */
1733 tevent_req_done(req);
1734 return;
1736 case DCERPC_AUTH_TYPE_NTLMSSP:
1737 case DCERPC_AUTH_TYPE_SPNEGO:
1738 case DCERPC_AUTH_TYPE_KRB5:
1739 /* Paranoid lenght checks */
1740 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1741 + pkt->auth_length) {
1742 tevent_req_nterror(req,
1743 NT_STATUS_INFO_LENGTH_MISMATCH);
1744 return;
1746 /* get auth credentials */
1747 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1748 &pkt->u.bind_ack.auth_info,
1749 &auth, false);
1750 if (!NT_STATUS_IS_OK(status)) {
1751 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1752 nt_errstr(status)));
1753 tevent_req_nterror(req, status);
1754 return;
1756 break;
1758 default:
1759 goto err_out;
1763 * For authenticated binds we may need to do 3 or 4 leg binds.
1766 switch(pauth->auth_type) {
1768 case DCERPC_AUTH_TYPE_NONE:
1769 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1770 case DCERPC_AUTH_TYPE_SCHANNEL:
1771 /* Bind complete. */
1772 tevent_req_done(req);
1773 return;
1775 case DCERPC_AUTH_TYPE_NTLMSSP:
1776 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
1777 struct auth_ntlmssp_state);
1778 status = auth_ntlmssp_update(ntlmssp_ctx,
1779 auth.credentials, &auth_token);
1780 if (NT_STATUS_EQUAL(status,
1781 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1782 status = rpc_bind_next_send(req, state,
1783 &auth_token);
1784 } else if (NT_STATUS_IS_OK(status)) {
1785 status = rpc_bind_finish_send(req, state,
1786 &auth_token);
1788 break;
1790 case DCERPC_AUTH_TYPE_SPNEGO:
1791 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1792 struct spnego_context);
1793 status = spnego_get_client_auth_token(state,
1794 spnego_ctx,
1795 &auth.credentials,
1796 &auth_token);
1797 if (!NT_STATUS_IS_OK(status)) {
1798 break;
1800 if (auth_token.length == 0) {
1801 /* Bind complete. */
1802 tevent_req_done(req);
1803 return;
1805 if (spnego_require_more_processing(spnego_ctx)) {
1806 status = rpc_bind_next_send(req, state,
1807 &auth_token);
1808 } else {
1809 status = rpc_bind_finish_send(req, state,
1810 &auth_token);
1812 break;
1814 case DCERPC_AUTH_TYPE_KRB5:
1815 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
1816 struct gse_context);
1817 status = gse_get_client_auth_token(state,
1818 gse_ctx,
1819 &auth.credentials,
1820 &auth_token);
1821 if (!NT_STATUS_IS_OK(status)) {
1822 break;
1825 if (gse_require_more_processing(gse_ctx)) {
1826 status = rpc_bind_next_send(req, state, &auth_token);
1827 } else {
1828 status = rpc_bind_finish_send(req, state, &auth_token);
1830 break;
1832 default:
1833 goto err_out;
1836 if (!NT_STATUS_IS_OK(status)) {
1837 tevent_req_nterror(req, status);
1839 return;
1841 err_out:
1842 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1843 (unsigned int)state->cli->auth->auth_type));
1844 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1847 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1848 struct rpc_pipe_bind_state *state,
1849 DATA_BLOB *auth_token)
1851 struct pipe_auth_data *auth = state->cli->auth;
1852 struct tevent_req *subreq;
1853 NTSTATUS status;
1855 /* Now prepare the alter context pdu. */
1856 data_blob_free(&state->rpc_out);
1858 status = create_rpc_alter_context(state,
1859 auth->auth_type,
1860 auth->auth_level,
1861 state->rpc_call_id,
1862 &state->cli->abstract_syntax,
1863 &state->cli->transfer_syntax,
1864 auth_token,
1865 &state->rpc_out);
1866 if (!NT_STATUS_IS_OK(status)) {
1867 return status;
1870 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1871 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1872 if (subreq == NULL) {
1873 return NT_STATUS_NO_MEMORY;
1875 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1876 return NT_STATUS_OK;
1879 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1880 struct rpc_pipe_bind_state *state,
1881 DATA_BLOB *auth_token)
1883 struct pipe_auth_data *auth = state->cli->auth;
1884 struct tevent_req *subreq;
1885 NTSTATUS status;
1887 state->auth3 = true;
1889 /* Now prepare the auth3 context pdu. */
1890 data_blob_free(&state->rpc_out);
1892 status = create_rpc_bind_auth3(state, state->cli,
1893 state->rpc_call_id,
1894 auth->auth_type,
1895 auth->auth_level,
1896 auth_token,
1897 &state->rpc_out);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 return status;
1902 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1903 &state->rpc_out, DCERPC_PKT_AUTH3);
1904 if (subreq == NULL) {
1905 return NT_STATUS_NO_MEMORY;
1907 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1908 return NT_STATUS_OK;
1911 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1913 return tevent_req_simple_recv_ntstatus(req);
1916 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1917 struct pipe_auth_data *auth)
1919 TALLOC_CTX *frame = talloc_stackframe();
1920 struct event_context *ev;
1921 struct tevent_req *req;
1922 NTSTATUS status = NT_STATUS_OK;
1924 ev = event_context_init(frame);
1925 if (ev == NULL) {
1926 status = NT_STATUS_NO_MEMORY;
1927 goto fail;
1930 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1931 if (req == NULL) {
1932 status = NT_STATUS_NO_MEMORY;
1933 goto fail;
1936 if (!tevent_req_poll(req, ev)) {
1937 status = map_nt_error_from_unix(errno);
1938 goto fail;
1941 status = rpc_pipe_bind_recv(req);
1942 fail:
1943 TALLOC_FREE(frame);
1944 return status;
1947 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1949 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1950 unsigned int timeout)
1952 unsigned int old;
1954 if (rpc_cli->transport == NULL) {
1955 return RPCCLI_DEFAULT_TIMEOUT;
1958 if (rpc_cli->transport->set_timeout == NULL) {
1959 return RPCCLI_DEFAULT_TIMEOUT;
1962 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1963 if (old == 0) {
1964 return RPCCLI_DEFAULT_TIMEOUT;
1967 return old;
1970 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1972 if (rpc_cli == NULL) {
1973 return false;
1976 if (rpc_cli->transport == NULL) {
1977 return false;
1980 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1983 struct rpccli_bh_state {
1984 struct rpc_pipe_client *rpc_cli;
1987 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1989 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1990 struct rpccli_bh_state);
1992 return rpccli_is_connected(hs->rpc_cli);
1995 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1996 uint32_t timeout)
1998 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1999 struct rpccli_bh_state);
2001 return rpccli_set_timeout(hs->rpc_cli, timeout);
2004 struct rpccli_bh_raw_call_state {
2005 DATA_BLOB in_data;
2006 DATA_BLOB out_data;
2007 uint32_t out_flags;
2010 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2012 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2013 struct tevent_context *ev,
2014 struct dcerpc_binding_handle *h,
2015 const struct GUID *object,
2016 uint32_t opnum,
2017 uint32_t in_flags,
2018 const uint8_t *in_data,
2019 size_t in_length)
2021 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2022 struct rpccli_bh_state);
2023 struct tevent_req *req;
2024 struct rpccli_bh_raw_call_state *state;
2025 bool ok;
2026 struct tevent_req *subreq;
2028 req = tevent_req_create(mem_ctx, &state,
2029 struct rpccli_bh_raw_call_state);
2030 if (req == NULL) {
2031 return NULL;
2033 state->in_data.data = discard_const_p(uint8_t, in_data);
2034 state->in_data.length = in_length;
2036 ok = rpccli_bh_is_connected(h);
2037 if (!ok) {
2038 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2039 return tevent_req_post(req, ev);
2042 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2043 opnum, &state->in_data);
2044 if (tevent_req_nomem(subreq, req)) {
2045 return tevent_req_post(req, ev);
2047 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2049 return req;
2052 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2054 struct tevent_req *req =
2055 tevent_req_callback_data(subreq,
2056 struct tevent_req);
2057 struct rpccli_bh_raw_call_state *state =
2058 tevent_req_data(req,
2059 struct rpccli_bh_raw_call_state);
2060 NTSTATUS status;
2062 state->out_flags = 0;
2064 /* TODO: support bigendian responses */
2066 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2067 TALLOC_FREE(subreq);
2068 if (!NT_STATUS_IS_OK(status)) {
2069 tevent_req_nterror(req, status);
2070 return;
2073 tevent_req_done(req);
2076 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2077 TALLOC_CTX *mem_ctx,
2078 uint8_t **out_data,
2079 size_t *out_length,
2080 uint32_t *out_flags)
2082 struct rpccli_bh_raw_call_state *state =
2083 tevent_req_data(req,
2084 struct rpccli_bh_raw_call_state);
2085 NTSTATUS status;
2087 if (tevent_req_is_nterror(req, &status)) {
2088 tevent_req_received(req);
2089 return status;
2092 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2093 *out_length = state->out_data.length;
2094 *out_flags = state->out_flags;
2095 tevent_req_received(req);
2096 return NT_STATUS_OK;
2099 struct rpccli_bh_disconnect_state {
2100 uint8_t _dummy;
2103 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2104 struct tevent_context *ev,
2105 struct dcerpc_binding_handle *h)
2107 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2108 struct rpccli_bh_state);
2109 struct tevent_req *req;
2110 struct rpccli_bh_disconnect_state *state;
2111 bool ok;
2113 req = tevent_req_create(mem_ctx, &state,
2114 struct rpccli_bh_disconnect_state);
2115 if (req == NULL) {
2116 return NULL;
2119 ok = rpccli_bh_is_connected(h);
2120 if (!ok) {
2121 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2122 return tevent_req_post(req, ev);
2126 * TODO: do a real async disconnect ...
2128 * For now the caller needs to free rpc_cli
2130 hs->rpc_cli = NULL;
2132 tevent_req_done(req);
2133 return tevent_req_post(req, ev);
2136 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2138 NTSTATUS status;
2140 if (tevent_req_is_nterror(req, &status)) {
2141 tevent_req_received(req);
2142 return status;
2145 tevent_req_received(req);
2146 return NT_STATUS_OK;
2149 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2151 return true;
2154 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2155 int ndr_flags,
2156 const void *_struct_ptr,
2157 const struct ndr_interface_call *call)
2159 void *struct_ptr = discard_const(_struct_ptr);
2161 if (DEBUGLEVEL < 10) {
2162 return;
2165 if (ndr_flags & NDR_IN) {
2166 ndr_print_function_debug(call->ndr_print,
2167 call->name,
2168 ndr_flags,
2169 struct_ptr);
2171 if (ndr_flags & NDR_OUT) {
2172 ndr_print_function_debug(call->ndr_print,
2173 call->name,
2174 ndr_flags,
2175 struct_ptr);
2179 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2180 .name = "rpccli",
2181 .is_connected = rpccli_bh_is_connected,
2182 .set_timeout = rpccli_bh_set_timeout,
2183 .raw_call_send = rpccli_bh_raw_call_send,
2184 .raw_call_recv = rpccli_bh_raw_call_recv,
2185 .disconnect_send = rpccli_bh_disconnect_send,
2186 .disconnect_recv = rpccli_bh_disconnect_recv,
2188 .ref_alloc = rpccli_bh_ref_alloc,
2189 .do_ndr_print = rpccli_bh_do_ndr_print,
2192 /* initialise a rpc_pipe_client binding handle */
2193 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2195 struct dcerpc_binding_handle *h;
2196 struct rpccli_bh_state *hs;
2198 h = dcerpc_binding_handle_create(c,
2199 &rpccli_bh_ops,
2200 NULL,
2201 NULL, /* TODO */
2202 &hs,
2203 struct rpccli_bh_state,
2204 __location__);
2205 if (h == NULL) {
2206 return NULL;
2208 hs->rpc_cli = c;
2210 return h;
2213 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2215 struct auth_ntlmssp_state *a = NULL;
2216 struct cli_state *cli;
2218 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2219 a = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2220 struct auth_ntlmssp_state);
2221 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2222 struct spnego_context *spnego_ctx;
2223 enum spnego_mech auth_type;
2224 void *auth_ctx;
2225 NTSTATUS status;
2227 spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2228 struct spnego_context);
2229 status = spnego_get_negotiated_mech(spnego_ctx,
2230 &auth_type, &auth_ctx);
2231 if (!NT_STATUS_IS_OK(status)) {
2232 return false;
2235 if (auth_type == SPNEGO_NTLMSSP) {
2236 a = talloc_get_type_abort(auth_ctx,
2237 struct auth_ntlmssp_state);
2241 if (a) {
2242 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2243 return true;
2246 cli = rpc_pipe_np_smb_conn(rpc_cli);
2247 if (cli == NULL) {
2248 return false;
2250 E_md4hash(cli->password ? cli->password : "", nt_hash);
2251 return true;
2254 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2255 struct pipe_auth_data **presult)
2257 struct pipe_auth_data *result;
2259 result = talloc(mem_ctx, struct pipe_auth_data);
2260 if (result == NULL) {
2261 return NT_STATUS_NO_MEMORY;
2264 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2265 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2267 result->user_name = talloc_strdup(result, "");
2268 result->domain = talloc_strdup(result, "");
2269 if ((result->user_name == NULL) || (result->domain == NULL)) {
2270 TALLOC_FREE(result);
2271 return NT_STATUS_NO_MEMORY;
2274 *presult = result;
2275 return NT_STATUS_OK;
2278 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2279 struct pipe_auth_data **presult)
2281 struct pipe_auth_data *result;
2283 result = talloc(mem_ctx, struct pipe_auth_data);
2284 if (result == NULL) {
2285 return NT_STATUS_NO_MEMORY;
2288 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2289 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2291 result->user_name = talloc_strdup(result, "");
2292 result->domain = talloc_strdup(result, "");
2293 if ((result->user_name == NULL) || (result->domain == NULL)) {
2294 TALLOC_FREE(result);
2295 return NT_STATUS_NO_MEMORY;
2298 *presult = result;
2299 return NT_STATUS_OK;
2302 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2304 TALLOC_FREE(auth->auth_ctx);
2305 return 0;
2308 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2309 enum dcerpc_AuthType auth_type,
2310 enum dcerpc_AuthLevel auth_level,
2311 const char *domain,
2312 const char *username,
2313 const char *password,
2314 struct pipe_auth_data **presult)
2316 struct auth_ntlmssp_state *ntlmssp_ctx;
2317 struct pipe_auth_data *result;
2318 NTSTATUS status;
2320 result = talloc(mem_ctx, struct pipe_auth_data);
2321 if (result == NULL) {
2322 return NT_STATUS_NO_MEMORY;
2325 result->auth_type = auth_type;
2326 result->auth_level = auth_level;
2328 result->user_name = talloc_strdup(result, username);
2329 result->domain = talloc_strdup(result, domain);
2330 if ((result->user_name == NULL) || (result->domain == NULL)) {
2331 status = NT_STATUS_NO_MEMORY;
2332 goto fail;
2335 status = auth_ntlmssp_client_start(NULL,
2336 global_myname(),
2337 lp_workgroup(),
2338 lp_client_ntlmv2_auth(),
2339 &ntlmssp_ctx);
2340 if (!NT_STATUS_IS_OK(status)) {
2341 goto fail;
2344 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2346 status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 goto fail;
2351 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
2352 if (!NT_STATUS_IS_OK(status)) {
2353 goto fail;
2356 status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 goto fail;
2362 * Turn off sign+seal to allow selected auth level to turn it back on.
2364 auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN |
2365 NTLMSSP_NEGOTIATE_SEAL));
2367 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2368 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN);
2369 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2370 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL |
2371 NTLMSSP_NEGOTIATE_SIGN);
2374 result->auth_ctx = ntlmssp_ctx;
2375 *presult = result;
2376 return NT_STATUS_OK;
2378 fail:
2379 TALLOC_FREE(result);
2380 return status;
2383 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2384 enum dcerpc_AuthLevel auth_level,
2385 struct netlogon_creds_CredentialState *creds,
2386 struct pipe_auth_data **presult)
2388 struct schannel_state *schannel_auth;
2389 struct pipe_auth_data *result;
2391 result = talloc(mem_ctx, struct pipe_auth_data);
2392 if (result == NULL) {
2393 return NT_STATUS_NO_MEMORY;
2396 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2397 result->auth_level = auth_level;
2399 result->user_name = talloc_strdup(result, "");
2400 result->domain = talloc_strdup(result, domain);
2401 if ((result->user_name == NULL) || (result->domain == NULL)) {
2402 goto fail;
2405 schannel_auth = talloc(result, struct schannel_state);
2406 if (schannel_auth == NULL) {
2407 goto fail;
2410 schannel_auth->state = SCHANNEL_STATE_START;
2411 schannel_auth->seq_num = 0;
2412 schannel_auth->initiator = true;
2413 schannel_auth->creds = netlogon_creds_copy(result, creds);
2415 result->auth_ctx = schannel_auth;
2416 *presult = result;
2417 return NT_STATUS_OK;
2419 fail:
2420 TALLOC_FREE(result);
2421 return NT_STATUS_NO_MEMORY;
2425 * Create an rpc pipe client struct, connecting to a tcp port.
2427 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2428 uint16_t port,
2429 const struct ndr_syntax_id *abstract_syntax,
2430 struct rpc_pipe_client **presult)
2432 struct rpc_pipe_client *result;
2433 struct sockaddr_storage addr;
2434 NTSTATUS status;
2435 int fd;
2437 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2438 if (result == NULL) {
2439 return NT_STATUS_NO_MEMORY;
2442 result->abstract_syntax = *abstract_syntax;
2443 result->transfer_syntax = ndr_transfer_syntax;
2445 result->desthost = talloc_strdup(result, host);
2446 result->srv_name_slash = talloc_asprintf_strupper_m(
2447 result, "\\\\%s", result->desthost);
2448 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2449 status = NT_STATUS_NO_MEMORY;
2450 goto fail;
2453 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2454 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2456 if (!resolve_name(host, &addr, 0, false)) {
2457 status = NT_STATUS_NOT_FOUND;
2458 goto fail;
2461 status = open_socket_out(&addr, port, 60, &fd);
2462 if (!NT_STATUS_IS_OK(status)) {
2463 goto fail;
2465 set_socket_options(fd, lp_socket_options());
2467 status = rpc_transport_sock_init(result, fd, &result->transport);
2468 if (!NT_STATUS_IS_OK(status)) {
2469 close(fd);
2470 goto fail;
2473 result->transport->transport = NCACN_IP_TCP;
2475 result->binding_handle = rpccli_bh_create(result);
2476 if (result->binding_handle == NULL) {
2477 TALLOC_FREE(result);
2478 return NT_STATUS_NO_MEMORY;
2481 *presult = result;
2482 return NT_STATUS_OK;
2484 fail:
2485 TALLOC_FREE(result);
2486 return status;
2490 * Determine the tcp port on which a dcerpc interface is listening
2491 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2492 * target host.
2494 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2495 const struct ndr_syntax_id *abstract_syntax,
2496 uint16_t *pport)
2498 NTSTATUS status;
2499 struct rpc_pipe_client *epm_pipe = NULL;
2500 struct dcerpc_binding_handle *epm_handle = NULL;
2501 struct pipe_auth_data *auth = NULL;
2502 struct dcerpc_binding *map_binding = NULL;
2503 struct dcerpc_binding *res_binding = NULL;
2504 struct epm_twr_t *map_tower = NULL;
2505 struct epm_twr_t *res_towers = NULL;
2506 struct policy_handle *entry_handle = NULL;
2507 uint32_t num_towers = 0;
2508 uint32_t max_towers = 1;
2509 struct epm_twr_p_t towers;
2510 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2511 uint32_t result = 0;
2513 if (pport == NULL) {
2514 status = NT_STATUS_INVALID_PARAMETER;
2515 goto done;
2518 /* open the connection to the endpoint mapper */
2519 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2520 &ndr_table_epmapper.syntax_id,
2521 &epm_pipe);
2523 if (!NT_STATUS_IS_OK(status)) {
2524 goto done;
2526 epm_handle = epm_pipe->binding_handle;
2528 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2529 if (!NT_STATUS_IS_OK(status)) {
2530 goto done;
2533 status = rpc_pipe_bind(epm_pipe, auth);
2534 if (!NT_STATUS_IS_OK(status)) {
2535 goto done;
2538 /* create tower for asking the epmapper */
2540 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2541 if (map_binding == NULL) {
2542 status = NT_STATUS_NO_MEMORY;
2543 goto done;
2546 map_binding->transport = NCACN_IP_TCP;
2547 map_binding->object = *abstract_syntax;
2548 map_binding->host = host; /* needed? */
2549 map_binding->endpoint = "0"; /* correct? needed? */
2551 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2552 if (map_tower == NULL) {
2553 status = NT_STATUS_NO_MEMORY;
2554 goto done;
2557 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2558 &(map_tower->tower));
2559 if (!NT_STATUS_IS_OK(status)) {
2560 goto done;
2563 /* allocate further parameters for the epm_Map call */
2565 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2566 if (res_towers == NULL) {
2567 status = NT_STATUS_NO_MEMORY;
2568 goto done;
2570 towers.twr = res_towers;
2572 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2573 if (entry_handle == NULL) {
2574 status = NT_STATUS_NO_MEMORY;
2575 goto done;
2578 /* ask the endpoint mapper for the port */
2580 status = dcerpc_epm_Map(epm_handle,
2581 tmp_ctx,
2582 CONST_DISCARD(struct GUID *,
2583 &(abstract_syntax->uuid)),
2584 map_tower,
2585 entry_handle,
2586 max_towers,
2587 &num_towers,
2588 &towers,
2589 &result);
2591 if (!NT_STATUS_IS_OK(status)) {
2592 goto done;
2595 if (result != EPMAPPER_STATUS_OK) {
2596 status = NT_STATUS_UNSUCCESSFUL;
2597 goto done;
2600 if (num_towers != 1) {
2601 status = NT_STATUS_UNSUCCESSFUL;
2602 goto done;
2605 /* extract the port from the answer */
2607 status = dcerpc_binding_from_tower(tmp_ctx,
2608 &(towers.twr->tower),
2609 &res_binding);
2610 if (!NT_STATUS_IS_OK(status)) {
2611 goto done;
2614 /* are further checks here necessary? */
2615 if (res_binding->transport != NCACN_IP_TCP) {
2616 status = NT_STATUS_UNSUCCESSFUL;
2617 goto done;
2620 *pport = (uint16_t)atoi(res_binding->endpoint);
2622 done:
2623 TALLOC_FREE(tmp_ctx);
2624 return status;
2628 * Create a rpc pipe client struct, connecting to a host via tcp.
2629 * The port is determined by asking the endpoint mapper on the given
2630 * host.
2632 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2633 const struct ndr_syntax_id *abstract_syntax,
2634 struct rpc_pipe_client **presult)
2636 NTSTATUS status;
2637 uint16_t port = 0;
2639 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2640 if (!NT_STATUS_IS_OK(status)) {
2641 return status;
2644 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2645 abstract_syntax, presult);
2648 /********************************************************************
2649 Create a rpc pipe client struct, connecting to a unix domain socket
2650 ********************************************************************/
2651 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2652 const struct ndr_syntax_id *abstract_syntax,
2653 struct rpc_pipe_client **presult)
2655 struct rpc_pipe_client *result;
2656 struct sockaddr_un addr;
2657 NTSTATUS status;
2658 int fd;
2660 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2661 if (result == NULL) {
2662 return NT_STATUS_NO_MEMORY;
2665 result->abstract_syntax = *abstract_syntax;
2666 result->transfer_syntax = ndr_transfer_syntax;
2668 result->desthost = get_myname(result);
2669 result->srv_name_slash = talloc_asprintf_strupper_m(
2670 result, "\\\\%s", result->desthost);
2671 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2672 status = NT_STATUS_NO_MEMORY;
2673 goto fail;
2676 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2677 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2679 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2680 if (fd == -1) {
2681 status = map_nt_error_from_unix(errno);
2682 goto fail;
2685 ZERO_STRUCT(addr);
2686 addr.sun_family = AF_UNIX;
2687 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2689 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2690 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2691 strerror(errno)));
2692 close(fd);
2693 return map_nt_error_from_unix(errno);
2696 status = rpc_transport_sock_init(result, fd, &result->transport);
2697 if (!NT_STATUS_IS_OK(status)) {
2698 close(fd);
2699 goto fail;
2702 result->transport->transport = NCALRPC;
2704 result->binding_handle = rpccli_bh_create(result);
2705 if (result->binding_handle == NULL) {
2706 TALLOC_FREE(result);
2707 return NT_STATUS_NO_MEMORY;
2710 *presult = result;
2711 return NT_STATUS_OK;
2713 fail:
2714 TALLOC_FREE(result);
2715 return status;
2718 struct rpc_pipe_client_np_ref {
2719 struct cli_state *cli;
2720 struct rpc_pipe_client *pipe;
2723 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2725 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2726 return 0;
2729 /****************************************************************************
2730 Open a named pipe over SMB to a remote server.
2732 * CAVEAT CALLER OF THIS FUNCTION:
2733 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2734 * so be sure that this function is called AFTER any structure (vs pointer)
2735 * assignment of the cli. In particular, libsmbclient does structure
2736 * assignments of cli, which invalidates the data in the returned
2737 * rpc_pipe_client if this function is called before the structure assignment
2738 * of cli.
2740 ****************************************************************************/
2742 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2743 const struct ndr_syntax_id *abstract_syntax,
2744 struct rpc_pipe_client **presult)
2746 struct rpc_pipe_client *result;
2747 NTSTATUS status;
2748 struct rpc_pipe_client_np_ref *np_ref;
2750 /* sanity check to protect against crashes */
2752 if ( !cli ) {
2753 return NT_STATUS_INVALID_HANDLE;
2756 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2757 if (result == NULL) {
2758 return NT_STATUS_NO_MEMORY;
2761 result->abstract_syntax = *abstract_syntax;
2762 result->transfer_syntax = ndr_transfer_syntax;
2763 result->desthost = talloc_strdup(result, cli->desthost);
2764 result->srv_name_slash = talloc_asprintf_strupper_m(
2765 result, "\\\\%s", result->desthost);
2767 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2768 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2770 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2771 TALLOC_FREE(result);
2772 return NT_STATUS_NO_MEMORY;
2775 status = rpc_transport_np_init(result, cli, abstract_syntax,
2776 &result->transport);
2777 if (!NT_STATUS_IS_OK(status)) {
2778 TALLOC_FREE(result);
2779 return status;
2782 result->transport->transport = NCACN_NP;
2784 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2785 if (np_ref == NULL) {
2786 TALLOC_FREE(result);
2787 return NT_STATUS_NO_MEMORY;
2789 np_ref->cli = cli;
2790 np_ref->pipe = result;
2792 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2793 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2795 result->binding_handle = rpccli_bh_create(result);
2796 if (result->binding_handle == NULL) {
2797 TALLOC_FREE(result);
2798 return NT_STATUS_NO_MEMORY;
2801 *presult = result;
2802 return NT_STATUS_OK;
2805 /****************************************************************************
2806 Open a pipe to a remote server.
2807 ****************************************************************************/
2809 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2810 enum dcerpc_transport_t transport,
2811 const struct ndr_syntax_id *interface,
2812 struct rpc_pipe_client **presult)
2814 switch (transport) {
2815 case NCACN_IP_TCP:
2816 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2817 presult);
2818 case NCACN_NP:
2819 return rpc_pipe_open_np(cli, interface, presult);
2820 default:
2821 return NT_STATUS_NOT_IMPLEMENTED;
2825 /****************************************************************************
2826 Open a named pipe to an SMB server and bind anonymously.
2827 ****************************************************************************/
2829 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2830 enum dcerpc_transport_t transport,
2831 const struct ndr_syntax_id *interface,
2832 struct rpc_pipe_client **presult)
2834 struct rpc_pipe_client *result;
2835 struct pipe_auth_data *auth;
2836 NTSTATUS status;
2838 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2839 if (!NT_STATUS_IS_OK(status)) {
2840 return status;
2843 status = rpccli_anon_bind_data(result, &auth);
2844 if (!NT_STATUS_IS_OK(status)) {
2845 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2846 nt_errstr(status)));
2847 TALLOC_FREE(result);
2848 return status;
2852 * This is a bit of an abstraction violation due to the fact that an
2853 * anonymous bind on an authenticated SMB inherits the user/domain
2854 * from the enclosing SMB creds
2857 TALLOC_FREE(auth->user_name);
2858 TALLOC_FREE(auth->domain);
2860 auth->user_name = talloc_strdup(auth, cli->user_name);
2861 auth->domain = talloc_strdup(auth, cli->domain);
2862 auth->user_session_key = data_blob_talloc(auth,
2863 cli->user_session_key.data,
2864 cli->user_session_key.length);
2866 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2867 TALLOC_FREE(result);
2868 return NT_STATUS_NO_MEMORY;
2871 status = rpc_pipe_bind(result, auth);
2872 if (!NT_STATUS_IS_OK(status)) {
2873 int lvl = 0;
2874 if (ndr_syntax_id_equal(interface,
2875 &ndr_table_dssetup.syntax_id)) {
2876 /* non AD domains just don't have this pipe, avoid
2877 * level 0 statement in that case - gd */
2878 lvl = 3;
2880 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2881 "%s failed with error %s\n",
2882 get_pipe_name_from_syntax(talloc_tos(), interface),
2883 nt_errstr(status) ));
2884 TALLOC_FREE(result);
2885 return status;
2888 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2889 "%s and bound anonymously.\n",
2890 get_pipe_name_from_syntax(talloc_tos(), interface),
2891 cli->desthost));
2893 *presult = result;
2894 return NT_STATUS_OK;
2897 /****************************************************************************
2898 ****************************************************************************/
2900 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2901 const struct ndr_syntax_id *interface,
2902 struct rpc_pipe_client **presult)
2904 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2905 interface, presult);
2908 /****************************************************************************
2909 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2910 ****************************************************************************/
2912 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2913 const struct ndr_syntax_id *interface,
2914 enum dcerpc_transport_t transport,
2915 enum dcerpc_AuthLevel auth_level,
2916 const char *domain,
2917 const char *username,
2918 const char *password,
2919 struct rpc_pipe_client **presult)
2921 struct rpc_pipe_client *result;
2922 struct pipe_auth_data *auth = NULL;
2923 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2924 NTSTATUS status;
2926 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2927 if (!NT_STATUS_IS_OK(status)) {
2928 return status;
2931 status = rpccli_ntlmssp_bind_data(result,
2932 auth_type, auth_level,
2933 domain, username, password,
2934 &auth);
2935 if (!NT_STATUS_IS_OK(status)) {
2936 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2937 nt_errstr(status)));
2938 goto err;
2941 status = rpc_pipe_bind(result, auth);
2942 if (!NT_STATUS_IS_OK(status)) {
2943 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2944 nt_errstr(status) ));
2945 goto err;
2948 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2949 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2950 get_pipe_name_from_syntax(talloc_tos(), interface),
2951 cli->desthost, domain, username ));
2953 *presult = result;
2954 return NT_STATUS_OK;
2956 err:
2958 TALLOC_FREE(result);
2959 return status;
2962 /****************************************************************************
2963 External interface.
2964 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2965 using session_key. sign and seal.
2967 The *pdc will be stolen onto this new pipe
2968 ****************************************************************************/
2970 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2971 const struct ndr_syntax_id *interface,
2972 enum dcerpc_transport_t transport,
2973 enum dcerpc_AuthLevel auth_level,
2974 const char *domain,
2975 struct netlogon_creds_CredentialState **pdc,
2976 struct rpc_pipe_client **presult)
2978 struct rpc_pipe_client *result;
2979 struct pipe_auth_data *auth;
2980 NTSTATUS status;
2982 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2983 if (!NT_STATUS_IS_OK(status)) {
2984 return status;
2987 status = rpccli_schannel_bind_data(result, domain, auth_level,
2988 *pdc, &auth);
2989 if (!NT_STATUS_IS_OK(status)) {
2990 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2991 nt_errstr(status)));
2992 TALLOC_FREE(result);
2993 return status;
2996 status = rpc_pipe_bind(result, auth);
2997 if (!NT_STATUS_IS_OK(status)) {
2998 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2999 "cli_rpc_pipe_bind failed with error %s\n",
3000 nt_errstr(status) ));
3001 TALLOC_FREE(result);
3002 return status;
3006 * The credentials on a new netlogon pipe are the ones we are passed
3007 * in - copy them over
3009 result->dc = netlogon_creds_copy(result, *pdc);
3010 if (result->dc == NULL) {
3011 TALLOC_FREE(result);
3012 return NT_STATUS_NO_MEMORY;
3015 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3016 "for domain %s and bound using schannel.\n",
3017 get_pipe_name_from_syntax(talloc_tos(), interface),
3018 cli->desthost, domain ));
3020 *presult = result;
3021 return NT_STATUS_OK;
3024 /****************************************************************************
3025 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3026 The idea is this can be called with service_princ, username and password all
3027 NULL so long as the caller has a TGT.
3028 ****************************************************************************/
3030 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3031 const struct ndr_syntax_id *interface,
3032 enum dcerpc_transport_t transport,
3033 enum dcerpc_AuthLevel auth_level,
3034 const char *server,
3035 const char *username,
3036 const char *password,
3037 struct rpc_pipe_client **presult)
3039 struct rpc_pipe_client *result;
3040 struct pipe_auth_data *auth;
3041 struct gse_context *gse_ctx;
3042 NTSTATUS status;
3044 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3045 if (!NT_STATUS_IS_OK(status)) {
3046 return status;
3049 auth = talloc(result, struct pipe_auth_data);
3050 if (auth == NULL) {
3051 status = NT_STATUS_NO_MEMORY;
3052 goto err_out;
3054 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3055 auth->auth_level = auth_level;
3057 if (!username) {
3058 username = "";
3060 auth->user_name = talloc_strdup(auth, username);
3061 if (!auth->user_name) {
3062 status = NT_STATUS_NO_MEMORY;
3063 goto err_out;
3066 /* Fixme, should we fetch/set the Realm ? */
3067 auth->domain = talloc_strdup(auth, "");
3068 if (!auth->domain) {
3069 status = NT_STATUS_NO_MEMORY;
3070 goto err_out;
3073 status = gse_init_client(auth,
3074 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3075 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3076 NULL, server, "cifs", username, password,
3077 GSS_C_DCE_STYLE, &gse_ctx);
3078 if (!NT_STATUS_IS_OK(status)) {
3079 DEBUG(0, ("gse_init_client returned %s\n",
3080 nt_errstr(status)));
3081 goto err_out;
3083 auth->auth_ctx = gse_ctx;
3085 status = rpc_pipe_bind(result, auth);
3086 if (!NT_STATUS_IS_OK(status)) {
3087 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3088 nt_errstr(status)));
3089 goto err_out;
3092 *presult = result;
3093 return NT_STATUS_OK;
3095 err_out:
3096 TALLOC_FREE(result);
3097 return status;
3100 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3101 const struct ndr_syntax_id *interface,
3102 enum dcerpc_transport_t transport,
3103 enum dcerpc_AuthLevel auth_level,
3104 const char *server,
3105 const char *username,
3106 const char *password,
3107 struct rpc_pipe_client **presult)
3109 struct rpc_pipe_client *result;
3110 struct pipe_auth_data *auth;
3111 struct spnego_context *spnego_ctx;
3112 NTSTATUS status;
3114 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3115 if (!NT_STATUS_IS_OK(status)) {
3116 return status;
3119 auth = talloc(result, struct pipe_auth_data);
3120 if (auth == NULL) {
3121 status = NT_STATUS_NO_MEMORY;
3122 goto err_out;
3124 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3125 auth->auth_level = auth_level;
3127 if (!username) {
3128 username = "";
3130 auth->user_name = talloc_strdup(auth, username);
3131 if (!auth->user_name) {
3132 status = NT_STATUS_NO_MEMORY;
3133 goto err_out;
3136 /* Fixme, should we fetch/set the Realm ? */
3137 auth->domain = talloc_strdup(auth, "");
3138 if (!auth->domain) {
3139 status = NT_STATUS_NO_MEMORY;
3140 goto err_out;
3143 status = spnego_gssapi_init_client(auth,
3144 (auth->auth_level ==
3145 DCERPC_AUTH_LEVEL_INTEGRITY),
3146 (auth->auth_level ==
3147 DCERPC_AUTH_LEVEL_PRIVACY),
3148 true,
3149 NULL, server, "cifs",
3150 username, password,
3151 &spnego_ctx);
3152 if (!NT_STATUS_IS_OK(status)) {
3153 DEBUG(0, ("spnego_init_client returned %s\n",
3154 nt_errstr(status)));
3155 goto err_out;
3157 auth->auth_ctx = spnego_ctx;
3159 status = rpc_pipe_bind(result, auth);
3160 if (!NT_STATUS_IS_OK(status)) {
3161 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3162 nt_errstr(status)));
3163 goto err_out;
3166 *presult = result;
3167 return NT_STATUS_OK;
3169 err_out:
3170 TALLOC_FREE(result);
3171 return status;
3174 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3175 const struct ndr_syntax_id *interface,
3176 enum dcerpc_transport_t transport,
3177 enum dcerpc_AuthLevel auth_level,
3178 const char *domain,
3179 const char *username,
3180 const char *password,
3181 struct rpc_pipe_client **presult)
3183 struct rpc_pipe_client *result;
3184 struct pipe_auth_data *auth;
3185 struct spnego_context *spnego_ctx;
3186 NTSTATUS status;
3188 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3189 if (!NT_STATUS_IS_OK(status)) {
3190 return status;
3193 auth = talloc(result, struct pipe_auth_data);
3194 if (auth == NULL) {
3195 status = NT_STATUS_NO_MEMORY;
3196 goto err_out;
3198 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3199 auth->auth_level = auth_level;
3201 if (!username) {
3202 username = "";
3204 auth->user_name = talloc_strdup(auth, username);
3205 if (!auth->user_name) {
3206 status = NT_STATUS_NO_MEMORY;
3207 goto err_out;
3210 if (!domain) {
3211 domain = "";
3213 auth->domain = talloc_strdup(auth, domain);
3214 if (!auth->domain) {
3215 status = NT_STATUS_NO_MEMORY;
3216 goto err_out;
3219 status = spnego_ntlmssp_init_client(auth,
3220 (auth->auth_level ==
3221 DCERPC_AUTH_LEVEL_INTEGRITY),
3222 (auth->auth_level ==
3223 DCERPC_AUTH_LEVEL_PRIVACY),
3224 true,
3225 domain, username, password,
3226 &spnego_ctx);
3227 if (!NT_STATUS_IS_OK(status)) {
3228 DEBUG(0, ("spnego_init_client returned %s\n",
3229 nt_errstr(status)));
3230 goto err_out;
3232 auth->auth_ctx = spnego_ctx;
3234 status = rpc_pipe_bind(result, auth);
3235 if (!NT_STATUS_IS_OK(status)) {
3236 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3237 nt_errstr(status)));
3238 goto err_out;
3241 *presult = result;
3242 return NT_STATUS_OK;
3244 err_out:
3245 TALLOC_FREE(result);
3246 return status;
3249 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3250 struct rpc_pipe_client *cli,
3251 DATA_BLOB *session_key)
3253 struct pipe_auth_data *a = cli->auth;
3254 struct schannel_state *schannel_auth;
3255 struct auth_ntlmssp_state *ntlmssp_ctx;
3256 struct spnego_context *spnego_ctx;
3257 struct gse_context *gse_ctx;
3258 DATA_BLOB sk = data_blob_null;
3259 bool make_dup = false;
3261 if (!session_key || !cli) {
3262 return NT_STATUS_INVALID_PARAMETER;
3265 if (!cli->auth) {
3266 return NT_STATUS_INVALID_PARAMETER;
3269 switch (cli->auth->auth_type) {
3270 case DCERPC_AUTH_TYPE_SCHANNEL:
3271 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3272 struct schannel_state);
3273 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3274 make_dup = true;
3275 break;
3276 case DCERPC_AUTH_TYPE_SPNEGO:
3277 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3278 struct spnego_context);
3279 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3280 make_dup = false;
3281 break;
3282 case DCERPC_AUTH_TYPE_NTLMSSP:
3283 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
3284 struct auth_ntlmssp_state);
3285 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx);
3286 make_dup = true;
3287 break;
3288 case DCERPC_AUTH_TYPE_KRB5:
3289 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3290 struct gse_context);
3291 sk = gse_get_session_key(mem_ctx, gse_ctx);
3292 make_dup = false;
3293 break;
3294 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3295 case DCERPC_AUTH_TYPE_NONE:
3296 sk = data_blob_const(a->user_session_key.data,
3297 a->user_session_key.length);
3298 make_dup = true;
3299 break;
3300 default:
3301 break;
3304 if (!sk.data) {
3305 return NT_STATUS_NO_USER_SESSION_KEY;
3308 if (make_dup) {
3309 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3310 } else {
3311 *session_key = sk;
3314 return NT_STATUS_OK;