s4:ldb: change version to 1.1.0 after adding new functions:
[Samba.git] / source3 / rpc_client / cli_pipe.c
blob02103e16f3e82cbfc2fc4fae06fe5af30bcfe829
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"
36 #include "ntdomain.h"
38 #undef DBGC_CLASS
39 #define DBGC_CLASS DBGC_RPC_CLI
41 /********************************************************************
42 Pipe description for a DEBUG
43 ********************************************************************/
44 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
45 struct rpc_pipe_client *cli)
47 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
48 if (result == NULL) {
49 return "pipe";
51 return result;
54 /********************************************************************
55 Rpc pipe call id.
56 ********************************************************************/
58 static uint32 get_rpc_call_id(void)
60 static uint32 call_id = 0;
61 return ++call_id;
64 /*******************************************************************
65 Use SMBreadX to get rest of one fragment's worth of rpc data.
66 Reads the whole size or give an error message
67 ********************************************************************/
69 struct rpc_read_state {
70 struct event_context *ev;
71 struct rpc_cli_transport *transport;
72 uint8_t *data;
73 size_t size;
74 size_t num_read;
77 static void rpc_read_done(struct tevent_req *subreq);
79 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
80 struct event_context *ev,
81 struct rpc_cli_transport *transport,
82 uint8_t *data, size_t size)
84 struct tevent_req *req, *subreq;
85 struct rpc_read_state *state;
87 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
88 if (req == NULL) {
89 return NULL;
91 state->ev = ev;
92 state->transport = transport;
93 state->data = data;
94 state->size = size;
95 state->num_read = 0;
97 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
99 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
100 transport->priv);
101 if (subreq == NULL) {
102 goto fail;
104 tevent_req_set_callback(subreq, rpc_read_done, req);
105 return req;
107 fail:
108 TALLOC_FREE(req);
109 return NULL;
112 static void rpc_read_done(struct tevent_req *subreq)
114 struct tevent_req *req = tevent_req_callback_data(
115 subreq, struct tevent_req);
116 struct rpc_read_state *state = tevent_req_data(
117 req, struct rpc_read_state);
118 NTSTATUS status;
119 ssize_t received;
121 status = state->transport->read_recv(subreq, &received);
122 TALLOC_FREE(subreq);
123 if (!NT_STATUS_IS_OK(status)) {
124 tevent_req_nterror(req, status);
125 return;
128 state->num_read += received;
129 if (state->num_read == state->size) {
130 tevent_req_done(req);
131 return;
134 subreq = state->transport->read_send(state, state->ev,
135 state->data + state->num_read,
136 state->size - state->num_read,
137 state->transport->priv);
138 if (tevent_req_nomem(subreq, req)) {
139 return;
141 tevent_req_set_callback(subreq, rpc_read_done, req);
144 static NTSTATUS rpc_read_recv(struct tevent_req *req)
146 return tevent_req_simple_recv_ntstatus(req);
149 struct rpc_write_state {
150 struct event_context *ev;
151 struct rpc_cli_transport *transport;
152 const uint8_t *data;
153 size_t size;
154 size_t num_written;
157 static void rpc_write_done(struct tevent_req *subreq);
159 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
160 struct event_context *ev,
161 struct rpc_cli_transport *transport,
162 const uint8_t *data, size_t size)
164 struct tevent_req *req, *subreq;
165 struct rpc_write_state *state;
167 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
168 if (req == NULL) {
169 return NULL;
171 state->ev = ev;
172 state->transport = transport;
173 state->data = data;
174 state->size = size;
175 state->num_written = 0;
177 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
179 subreq = transport->write_send(state, ev, data, size, transport->priv);
180 if (subreq == NULL) {
181 goto fail;
183 tevent_req_set_callback(subreq, rpc_write_done, req);
184 return req;
185 fail:
186 TALLOC_FREE(req);
187 return NULL;
190 static void rpc_write_done(struct tevent_req *subreq)
192 struct tevent_req *req = tevent_req_callback_data(
193 subreq, struct tevent_req);
194 struct rpc_write_state *state = tevent_req_data(
195 req, struct rpc_write_state);
196 NTSTATUS status;
197 ssize_t written;
199 status = state->transport->write_recv(subreq, &written);
200 TALLOC_FREE(subreq);
201 if (!NT_STATUS_IS_OK(status)) {
202 tevent_req_nterror(req, status);
203 return;
206 state->num_written += written;
208 if (state->num_written == state->size) {
209 tevent_req_done(req);
210 return;
213 subreq = state->transport->write_send(state, state->ev,
214 state->data + state->num_written,
215 state->size - state->num_written,
216 state->transport->priv);
217 if (tevent_req_nomem(subreq, req)) {
218 return;
220 tevent_req_set_callback(subreq, rpc_write_done, req);
223 static NTSTATUS rpc_write_recv(struct tevent_req *req)
225 return tevent_req_simple_recv_ntstatus(req);
229 /****************************************************************************
230 Try and get a PDU's worth of data from current_pdu. If not, then read more
231 from the wire.
232 ****************************************************************************/
234 struct get_complete_frag_state {
235 struct event_context *ev;
236 struct rpc_pipe_client *cli;
237 uint16_t frag_len;
238 DATA_BLOB *pdu;
241 static void get_complete_frag_got_header(struct tevent_req *subreq);
242 static void get_complete_frag_got_rest(struct tevent_req *subreq);
244 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
245 struct event_context *ev,
246 struct rpc_pipe_client *cli,
247 DATA_BLOB *pdu)
249 struct tevent_req *req, *subreq;
250 struct get_complete_frag_state *state;
251 size_t received;
252 NTSTATUS status;
254 req = tevent_req_create(mem_ctx, &state,
255 struct get_complete_frag_state);
256 if (req == NULL) {
257 return NULL;
259 state->ev = ev;
260 state->cli = cli;
261 state->frag_len = RPC_HEADER_LEN;
262 state->pdu = pdu;
264 received = pdu->length;
265 if (received < RPC_HEADER_LEN) {
266 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
267 status = NT_STATUS_NO_MEMORY;
268 goto post_status;
270 subreq = rpc_read_send(state, state->ev,
271 state->cli->transport,
272 pdu->data + received,
273 RPC_HEADER_LEN - received);
274 if (subreq == NULL) {
275 status = NT_STATUS_NO_MEMORY;
276 goto post_status;
278 tevent_req_set_callback(subreq, get_complete_frag_got_header,
279 req);
280 return req;
283 state->frag_len = dcerpc_get_frag_length(pdu);
286 * Ensure we have frag_len bytes of data.
288 if (received < state->frag_len) {
289 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
290 status = NT_STATUS_NO_MEMORY;
291 goto post_status;
293 subreq = rpc_read_send(state, state->ev,
294 state->cli->transport,
295 pdu->data + received,
296 state->frag_len - received);
297 if (subreq == NULL) {
298 status = NT_STATUS_NO_MEMORY;
299 goto post_status;
301 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
302 req);
303 return req;
306 status = NT_STATUS_OK;
307 post_status:
308 if (NT_STATUS_IS_OK(status)) {
309 tevent_req_done(req);
310 } else {
311 tevent_req_nterror(req, status);
313 return tevent_req_post(req, ev);
316 static void get_complete_frag_got_header(struct tevent_req *subreq)
318 struct tevent_req *req = tevent_req_callback_data(
319 subreq, struct tevent_req);
320 struct get_complete_frag_state *state = tevent_req_data(
321 req, struct get_complete_frag_state);
322 NTSTATUS status;
324 status = rpc_read_recv(subreq);
325 TALLOC_FREE(subreq);
326 if (!NT_STATUS_IS_OK(status)) {
327 tevent_req_nterror(req, status);
328 return;
331 state->frag_len = dcerpc_get_frag_length(state->pdu);
333 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
334 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
335 return;
339 * We're here in this piece of code because we've read exactly
340 * RPC_HEADER_LEN bytes into state->pdu.
343 subreq = rpc_read_send(state, state->ev, state->cli->transport,
344 state->pdu->data + RPC_HEADER_LEN,
345 state->frag_len - RPC_HEADER_LEN);
346 if (tevent_req_nomem(subreq, req)) {
347 return;
349 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
352 static void get_complete_frag_got_rest(struct tevent_req *subreq)
354 struct tevent_req *req = tevent_req_callback_data(
355 subreq, struct tevent_req);
356 NTSTATUS status;
358 status = rpc_read_recv(subreq);
359 TALLOC_FREE(subreq);
360 if (!NT_STATUS_IS_OK(status)) {
361 tevent_req_nterror(req, status);
362 return;
364 tevent_req_done(req);
367 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
369 return tevent_req_simple_recv_ntstatus(req);
372 /****************************************************************************
373 Do basic authentication checks on an incoming pdu.
374 ****************************************************************************/
376 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
377 struct rpc_pipe_client *cli,
378 struct ncacn_packet *pkt,
379 DATA_BLOB *pdu,
380 uint8_t expected_pkt_type,
381 DATA_BLOB *rdata,
382 DATA_BLOB *reply_pdu)
384 struct dcerpc_response *r;
385 NTSTATUS ret = NT_STATUS_OK;
386 size_t pad_len = 0;
389 * Point the return values at the real data including the RPC
390 * header. Just in case the caller wants it.
392 *rdata = *pdu;
394 /* Ensure we have the correct type. */
395 switch (pkt->ptype) {
396 case DCERPC_PKT_ALTER_RESP:
397 case DCERPC_PKT_BIND_ACK:
399 /* Client code never receives this kind of packets */
400 break;
403 case DCERPC_PKT_RESPONSE:
405 r = &pkt->u.response;
407 /* Here's where we deal with incoming sign/seal. */
408 ret = dcerpc_check_auth(cli->auth, pkt,
409 &r->stub_and_verifier,
410 DCERPC_RESPONSE_LENGTH,
411 pdu, &pad_len);
412 if (!NT_STATUS_IS_OK(ret)) {
413 return ret;
416 if (pkt->frag_length < DCERPC_RESPONSE_LENGTH + pad_len) {
417 return NT_STATUS_BUFFER_TOO_SMALL;
420 /* Point the return values at the NDR data. */
421 rdata->data = r->stub_and_verifier.data;
423 if (pkt->auth_length) {
424 /* We've already done integer wrap tests in
425 * dcerpc_check_auth(). */
426 rdata->length = r->stub_and_verifier.length
427 - pad_len
428 - DCERPC_AUTH_TRAILER_LENGTH
429 - pkt->auth_length;
430 } else {
431 rdata->length = r->stub_and_verifier.length;
434 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
435 (long unsigned int)pdu->length,
436 (long unsigned int)rdata->length,
437 (unsigned int)pad_len));
440 * If this is the first reply, and the allocation hint is
441 * reasonable, try and set up the reply_pdu DATA_BLOB to the
442 * correct size.
445 if ((reply_pdu->length == 0) &&
446 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
447 if (!data_blob_realloc(mem_ctx, reply_pdu,
448 r->alloc_hint)) {
449 DEBUG(0, ("reply alloc hint %d too "
450 "large to allocate\n",
451 (int)r->alloc_hint));
452 return NT_STATUS_NO_MEMORY;
456 break;
458 case DCERPC_PKT_BIND_NAK:
459 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
460 rpccli_pipe_txt(talloc_tos(), cli)));
461 /* Use this for now... */
462 return NT_STATUS_NETWORK_ACCESS_DENIED;
464 case DCERPC_PKT_FAULT:
466 DEBUG(1, (__location__ ": RPC fault code %s received "
467 "from %s!\n",
468 dcerpc_errstr(talloc_tos(),
469 pkt->u.fault.status),
470 rpccli_pipe_txt(talloc_tos(), cli)));
472 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
473 return NT_STATUS_UNSUCCESSFUL;
474 } else {
475 return NT_STATUS(pkt->u.fault.status);
478 default:
479 DEBUG(0, (__location__ "Unknown packet type %u received "
480 "from %s!\n",
481 (unsigned int)pkt->ptype,
482 rpccli_pipe_txt(talloc_tos(), cli)));
483 return NT_STATUS_INVALID_INFO_CLASS;
486 if (pkt->ptype != expected_pkt_type) {
487 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
488 "RPC packet type - %u, not %u\n",
489 rpccli_pipe_txt(talloc_tos(), cli),
490 pkt->ptype, expected_pkt_type));
491 return NT_STATUS_INVALID_INFO_CLASS;
494 /* Do this just before return - we don't want to modify any rpc header
495 data before now as we may have needed to do cryptographic actions on
496 it before. */
498 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
499 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
500 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
501 "fragment first/last ON.\n"));
502 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
505 return NT_STATUS_OK;
508 /****************************************************************************
509 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
510 ****************************************************************************/
512 struct cli_api_pipe_state {
513 struct event_context *ev;
514 struct rpc_cli_transport *transport;
515 uint8_t *rdata;
516 uint32_t rdata_len;
519 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
520 static void cli_api_pipe_write_done(struct tevent_req *subreq);
521 static void cli_api_pipe_read_done(struct tevent_req *subreq);
523 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
524 struct event_context *ev,
525 struct rpc_cli_transport *transport,
526 uint8_t *data, size_t data_len,
527 uint32_t max_rdata_len)
529 struct tevent_req *req, *subreq;
530 struct cli_api_pipe_state *state;
531 NTSTATUS status;
533 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
534 if (req == NULL) {
535 return NULL;
537 state->ev = ev;
538 state->transport = transport;
540 if (max_rdata_len < RPC_HEADER_LEN) {
542 * For a RPC reply we always need at least RPC_HEADER_LEN
543 * bytes. We check this here because we will receive
544 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
546 status = NT_STATUS_INVALID_PARAMETER;
547 goto post_status;
550 if (transport->trans_send != NULL) {
551 subreq = transport->trans_send(state, ev, data, data_len,
552 max_rdata_len, transport->priv);
553 if (subreq == NULL) {
554 goto fail;
556 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
557 return req;
561 * If the transport does not provide a "trans" routine, i.e. for
562 * example the ncacn_ip_tcp transport, do the write/read step here.
565 subreq = rpc_write_send(state, ev, transport, data, data_len);
566 if (subreq == NULL) {
567 goto fail;
569 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
570 return req;
572 post_status:
573 tevent_req_nterror(req, status);
574 return tevent_req_post(req, ev);
575 fail:
576 TALLOC_FREE(req);
577 return NULL;
580 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
582 struct tevent_req *req = tevent_req_callback_data(
583 subreq, struct tevent_req);
584 struct cli_api_pipe_state *state = tevent_req_data(
585 req, struct cli_api_pipe_state);
586 NTSTATUS status;
588 status = state->transport->trans_recv(subreq, state, &state->rdata,
589 &state->rdata_len);
590 TALLOC_FREE(subreq);
591 if (!NT_STATUS_IS_OK(status)) {
592 tevent_req_nterror(req, status);
593 return;
595 tevent_req_done(req);
598 static void cli_api_pipe_write_done(struct tevent_req *subreq)
600 struct tevent_req *req = tevent_req_callback_data(
601 subreq, struct tevent_req);
602 struct cli_api_pipe_state *state = tevent_req_data(
603 req, struct cli_api_pipe_state);
604 NTSTATUS status;
606 status = rpc_write_recv(subreq);
607 TALLOC_FREE(subreq);
608 if (!NT_STATUS_IS_OK(status)) {
609 tevent_req_nterror(req, status);
610 return;
613 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
614 if (tevent_req_nomem(state->rdata, req)) {
615 return;
619 * We don't need to use rpc_read_send here, the upper layer will cope
620 * with a short read, transport->trans_send could also return less
621 * than state->max_rdata_len.
623 subreq = state->transport->read_send(state, state->ev, state->rdata,
624 RPC_HEADER_LEN,
625 state->transport->priv);
626 if (tevent_req_nomem(subreq, req)) {
627 return;
629 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
632 static void cli_api_pipe_read_done(struct tevent_req *subreq)
634 struct tevent_req *req = tevent_req_callback_data(
635 subreq, struct tevent_req);
636 struct cli_api_pipe_state *state = tevent_req_data(
637 req, struct cli_api_pipe_state);
638 NTSTATUS status;
639 ssize_t received;
641 status = state->transport->read_recv(subreq, &received);
642 TALLOC_FREE(subreq);
643 if (!NT_STATUS_IS_OK(status)) {
644 tevent_req_nterror(req, status);
645 return;
647 state->rdata_len = received;
648 tevent_req_done(req);
651 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
652 uint8_t **prdata, uint32_t *prdata_len)
654 struct cli_api_pipe_state *state = tevent_req_data(
655 req, struct cli_api_pipe_state);
656 NTSTATUS status;
658 if (tevent_req_is_nterror(req, &status)) {
659 return status;
662 *prdata = talloc_move(mem_ctx, &state->rdata);
663 *prdata_len = state->rdata_len;
664 return NT_STATUS_OK;
667 /****************************************************************************
668 Send data on an rpc pipe via trans. The data must be the last
669 pdu fragment of an NDR data stream.
671 Receive response data from an rpc pipe, which may be large...
673 Read the first fragment: unfortunately have to use SMBtrans for the first
674 bit, then SMBreadX for subsequent bits.
676 If first fragment received also wasn't the last fragment, continue
677 getting fragments until we _do_ receive the last fragment.
679 Request/Response PDU's look like the following...
681 |<------------------PDU len----------------------------------------------->|
682 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
684 +------------+-----------------+-------------+---------------+-------------+
685 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
686 +------------+-----------------+-------------+---------------+-------------+
688 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
689 signing & sealing being negotiated.
691 ****************************************************************************/
693 struct rpc_api_pipe_state {
694 struct event_context *ev;
695 struct rpc_pipe_client *cli;
696 uint8_t expected_pkt_type;
698 DATA_BLOB incoming_frag;
699 struct ncacn_packet *pkt;
701 /* Incoming reply */
702 DATA_BLOB reply_pdu;
703 size_t reply_pdu_offset;
704 uint8_t endianess;
707 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
708 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
709 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
711 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
712 struct event_context *ev,
713 struct rpc_pipe_client *cli,
714 DATA_BLOB *data, /* Outgoing PDU */
715 uint8_t expected_pkt_type)
717 struct tevent_req *req, *subreq;
718 struct rpc_api_pipe_state *state;
719 uint16_t max_recv_frag;
720 NTSTATUS status;
722 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
723 if (req == NULL) {
724 return NULL;
726 state->ev = ev;
727 state->cli = cli;
728 state->expected_pkt_type = expected_pkt_type;
729 state->incoming_frag = data_blob_null;
730 state->reply_pdu = data_blob_null;
731 state->reply_pdu_offset = 0;
732 state->endianess = DCERPC_DREP_LE;
735 * Ensure we're not sending too much.
737 if (data->length > cli->max_xmit_frag) {
738 status = NT_STATUS_INVALID_PARAMETER;
739 goto post_status;
742 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
744 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
745 subreq = rpc_write_send(state, ev, cli->transport,
746 data->data, data->length);
747 if (subreq == NULL) {
748 goto fail;
750 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
751 return req;
754 /* get the header first, then fetch the rest once we have
755 * the frag_length available */
756 max_recv_frag = RPC_HEADER_LEN;
758 subreq = cli_api_pipe_send(state, ev, cli->transport,
759 data->data, data->length, max_recv_frag);
760 if (subreq == NULL) {
761 goto fail;
763 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
764 return req;
766 post_status:
767 tevent_req_nterror(req, status);
768 return tevent_req_post(req, ev);
769 fail:
770 TALLOC_FREE(req);
771 return NULL;
774 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
776 struct tevent_req *req =
777 tevent_req_callback_data(subreq,
778 struct tevent_req);
779 NTSTATUS status;
781 status = rpc_write_recv(subreq);
782 TALLOC_FREE(subreq);
783 if (!NT_STATUS_IS_OK(status)) {
784 tevent_req_nterror(req, status);
785 return;
788 tevent_req_done(req);
791 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
793 struct tevent_req *req = tevent_req_callback_data(
794 subreq, struct tevent_req);
795 struct rpc_api_pipe_state *state = tevent_req_data(
796 req, struct rpc_api_pipe_state);
797 NTSTATUS status;
798 uint8_t *rdata = NULL;
799 uint32_t rdata_len = 0;
801 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
802 TALLOC_FREE(subreq);
803 if (!NT_STATUS_IS_OK(status)) {
804 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
805 tevent_req_nterror(req, status);
806 return;
809 if (rdata == NULL) {
810 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
811 rpccli_pipe_txt(talloc_tos(), state->cli)));
812 tevent_req_done(req);
813 return;
817 * Move data on state->incoming_frag.
819 state->incoming_frag.data = talloc_move(state, &rdata);
820 state->incoming_frag.length = rdata_len;
821 if (!state->incoming_frag.data) {
822 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
823 return;
826 /* Ensure we have enough data for a pdu. */
827 subreq = get_complete_frag_send(state, state->ev, state->cli,
828 &state->incoming_frag);
829 if (tevent_req_nomem(subreq, req)) {
830 return;
832 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
835 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
837 struct tevent_req *req = tevent_req_callback_data(
838 subreq, struct tevent_req);
839 struct rpc_api_pipe_state *state = tevent_req_data(
840 req, struct rpc_api_pipe_state);
841 NTSTATUS status;
842 DATA_BLOB rdata = data_blob_null;
844 status = get_complete_frag_recv(subreq);
845 TALLOC_FREE(subreq);
846 if (!NT_STATUS_IS_OK(status)) {
847 DEBUG(5, ("get_complete_frag failed: %s\n",
848 nt_errstr(status)));
849 tevent_req_nterror(req, status);
850 return;
853 state->pkt = talloc(state, struct ncacn_packet);
854 if (!state->pkt) {
855 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
856 return;
859 status = dcerpc_pull_ncacn_packet(state->pkt,
860 &state->incoming_frag,
861 state->pkt,
862 !state->endianess);
863 if (!NT_STATUS_IS_OK(status)) {
864 tevent_req_nterror(req, status);
865 return;
868 if (state->incoming_frag.length != state->pkt->frag_length) {
869 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
870 (unsigned int)state->incoming_frag.length,
871 (unsigned int)state->pkt->frag_length));
872 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
873 return;
876 status = cli_pipe_validate_current_pdu(state,
877 state->cli, state->pkt,
878 &state->incoming_frag,
879 state->expected_pkt_type,
880 &rdata,
881 &state->reply_pdu);
883 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
884 (unsigned)state->incoming_frag.length,
885 (unsigned)state->reply_pdu_offset,
886 nt_errstr(status)));
888 if (!NT_STATUS_IS_OK(status)) {
889 tevent_req_nterror(req, status);
890 return;
893 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
894 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
896 * Set the data type correctly for big-endian data on the
897 * first packet.
899 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
900 "big-endian.\n",
901 rpccli_pipe_txt(talloc_tos(), state->cli)));
902 state->endianess = 0x00; /* BIG ENDIAN */
905 * Check endianness on subsequent packets.
907 if (state->endianess != state->pkt->drep[0]) {
908 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
909 "%s\n",
910 state->endianess?"little":"big",
911 state->pkt->drep[0]?"little":"big"));
912 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
913 return;
916 /* Now copy the data portion out of the pdu into rbuf. */
917 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
918 if (!data_blob_realloc(NULL, &state->reply_pdu,
919 state->reply_pdu_offset + rdata.length)) {
920 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
921 return;
925 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
926 rdata.data, rdata.length);
927 state->reply_pdu_offset += rdata.length;
929 /* reset state->incoming_frag, there is no need to free it,
930 * it will be reallocated to the right size the next time
931 * it is used */
932 state->incoming_frag.length = 0;
934 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
935 /* make sure the pdu length is right now that we
936 * have all the data available (alloc hint may
937 * have allocated more than was actually used) */
938 state->reply_pdu.length = state->reply_pdu_offset;
939 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
940 rpccli_pipe_txt(talloc_tos(), state->cli),
941 (unsigned)state->reply_pdu.length));
942 tevent_req_done(req);
943 return;
946 subreq = get_complete_frag_send(state, state->ev, state->cli,
947 &state->incoming_frag);
948 if (tevent_req_nomem(subreq, req)) {
949 return;
951 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
954 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
955 struct ncacn_packet **pkt,
956 DATA_BLOB *reply_pdu)
958 struct rpc_api_pipe_state *state = tevent_req_data(
959 req, struct rpc_api_pipe_state);
960 NTSTATUS status;
962 if (tevent_req_is_nterror(req, &status)) {
963 return status;
966 /* return data to caller and assign it ownership of memory */
967 if (reply_pdu) {
968 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
969 reply_pdu->length = state->reply_pdu.length;
970 state->reply_pdu.length = 0;
971 } else {
972 data_blob_free(&state->reply_pdu);
975 if (pkt) {
976 *pkt = talloc_steal(mem_ctx, state->pkt);
979 return NT_STATUS_OK;
982 /*******************************************************************
983 Creates spnego auth bind.
984 ********************************************************************/
986 static NTSTATUS create_spnego_auth_bind_req(TALLOC_CTX *mem_ctx,
987 struct pipe_auth_data *auth,
988 DATA_BLOB *auth_token)
990 struct spnego_context *spnego_ctx;
991 DATA_BLOB in_token = data_blob_null;
992 NTSTATUS status;
994 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
995 struct spnego_context);
997 /* Negotiate the initial auth token */
998 status = spnego_get_client_auth_token(mem_ctx, spnego_ctx,
999 &in_token, auth_token);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 return status;
1004 DEBUG(5, ("Created GSS Authentication Token:\n"));
1005 dump_data(5, auth_token->data, auth_token->length);
1007 return NT_STATUS_OK;
1010 /*******************************************************************
1011 Creates krb5 auth bind.
1012 ********************************************************************/
1014 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
1015 struct pipe_auth_data *auth,
1016 DATA_BLOB *auth_token)
1018 struct gse_context *gse_ctx;
1019 DATA_BLOB in_token = data_blob_null;
1020 NTSTATUS status;
1022 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
1023 struct gse_context);
1025 /* Negotiate the initial auth token */
1026 status = gse_get_client_auth_token(mem_ctx, gse_ctx,
1027 &in_token,
1028 auth_token);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 return status;
1033 DEBUG(5, ("Created GSS Authentication Token:\n"));
1034 dump_data(5, auth_token->data, auth_token->length);
1036 return NT_STATUS_OK;
1039 /*******************************************************************
1040 Creates NTLMSSP auth bind.
1041 ********************************************************************/
1043 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1044 DATA_BLOB *auth_token)
1046 struct auth_ntlmssp_state *ntlmssp_ctx;
1047 DATA_BLOB null_blob = data_blob_null;
1048 NTSTATUS status;
1050 ntlmssp_ctx = talloc_get_type_abort(cli->auth->auth_ctx,
1051 struct auth_ntlmssp_state);
1053 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1054 status = auth_ntlmssp_update(ntlmssp_ctx, null_blob, auth_token);
1056 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1057 data_blob_free(auth_token);
1058 return status;
1061 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1062 dump_data(5, auth_token->data, auth_token->length);
1064 return NT_STATUS_OK;
1067 /*******************************************************************
1068 Creates schannel auth bind.
1069 ********************************************************************/
1071 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1072 DATA_BLOB *auth_token)
1074 NTSTATUS status;
1075 struct NL_AUTH_MESSAGE r;
1077 /* Use lp_workgroup() if domain not specified */
1079 if (!cli->auth->domain || !cli->auth->domain[0]) {
1080 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1081 if (cli->auth->domain == NULL) {
1082 return NT_STATUS_NO_MEMORY;
1087 * Now marshall the data into the auth parse_struct.
1090 r.MessageType = NL_NEGOTIATE_REQUEST;
1091 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1092 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1093 r.oem_netbios_domain.a = cli->auth->domain;
1094 r.oem_netbios_computer.a = global_myname();
1096 status = dcerpc_push_schannel_bind(cli, &r, auth_token);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 return status;
1101 return NT_STATUS_OK;
1104 /*******************************************************************
1105 Creates the internals of a DCE/RPC bind request or alter context PDU.
1106 ********************************************************************/
1108 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1109 enum dcerpc_pkt_type ptype,
1110 uint32 rpc_call_id,
1111 const struct ndr_syntax_id *abstract,
1112 const struct ndr_syntax_id *transfer,
1113 const DATA_BLOB *auth_info,
1114 DATA_BLOB *blob)
1116 uint16 auth_len = auth_info->length;
1117 NTSTATUS status;
1118 union dcerpc_payload u;
1119 struct dcerpc_ctx_list ctx_list;
1121 if (auth_len) {
1122 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1125 ctx_list.context_id = 0;
1126 ctx_list.num_transfer_syntaxes = 1;
1127 ctx_list.abstract_syntax = *abstract;
1128 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1130 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1131 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1132 u.bind.assoc_group_id = 0x0;
1133 u.bind.num_contexts = 1;
1134 u.bind.ctx_list = &ctx_list;
1135 u.bind.auth_info = *auth_info;
1137 status = dcerpc_push_ncacn_packet(mem_ctx,
1138 ptype,
1139 DCERPC_PFC_FLAG_FIRST |
1140 DCERPC_PFC_FLAG_LAST,
1141 auth_len,
1142 rpc_call_id,
1144 blob);
1145 if (!NT_STATUS_IS_OK(status)) {
1146 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1147 return status;
1150 return NT_STATUS_OK;
1153 /*******************************************************************
1154 Creates a DCE/RPC bind request.
1155 ********************************************************************/
1157 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1158 struct rpc_pipe_client *cli,
1159 struct pipe_auth_data *auth,
1160 uint32 rpc_call_id,
1161 const struct ndr_syntax_id *abstract,
1162 const struct ndr_syntax_id *transfer,
1163 DATA_BLOB *rpc_out)
1165 DATA_BLOB auth_token = data_blob_null;
1166 DATA_BLOB auth_info = data_blob_null;
1167 NTSTATUS ret = NT_STATUS_OK;
1169 switch (auth->auth_type) {
1170 case DCERPC_AUTH_TYPE_SCHANNEL:
1171 ret = create_schannel_auth_rpc_bind_req(cli, &auth_token);
1172 if (!NT_STATUS_IS_OK(ret)) {
1173 return ret;
1175 break;
1177 case DCERPC_AUTH_TYPE_NTLMSSP:
1178 ret = create_ntlmssp_auth_rpc_bind_req(cli, &auth_token);
1179 if (!NT_STATUS_IS_OK(ret)) {
1180 return ret;
1182 break;
1184 case DCERPC_AUTH_TYPE_SPNEGO:
1185 ret = create_spnego_auth_bind_req(cli, auth, &auth_token);
1186 if (!NT_STATUS_IS_OK(ret)) {
1187 return ret;
1189 break;
1191 case DCERPC_AUTH_TYPE_KRB5:
1192 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_token);
1193 if (!NT_STATUS_IS_OK(ret)) {
1194 return ret;
1196 break;
1198 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1199 auth_token = data_blob_talloc(mem_ctx,
1200 "NCALRPC_AUTH_TOKEN",
1201 18);
1202 break;
1204 case DCERPC_AUTH_TYPE_NONE:
1205 break;
1207 default:
1208 /* "Can't" happen. */
1209 return NT_STATUS_INVALID_INFO_CLASS;
1212 if (auth_token.length != 0) {
1213 ret = dcerpc_push_dcerpc_auth(cli,
1214 auth->auth_type,
1215 auth->auth_level,
1216 0, /* auth_pad_length */
1217 1, /* auth_context_id */
1218 &auth_token,
1219 &auth_info);
1220 if (!NT_STATUS_IS_OK(ret)) {
1221 return ret;
1223 data_blob_free(&auth_token);
1226 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1227 DCERPC_PKT_BIND,
1228 rpc_call_id,
1229 abstract,
1230 transfer,
1231 &auth_info,
1232 rpc_out);
1233 return ret;
1236 /*******************************************************************
1237 External interface.
1238 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1239 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1240 and deals with signing/sealing details.
1241 ********************************************************************/
1243 struct rpc_api_pipe_req_state {
1244 struct event_context *ev;
1245 struct rpc_pipe_client *cli;
1246 uint8_t op_num;
1247 uint32_t call_id;
1248 DATA_BLOB *req_data;
1249 uint32_t req_data_sent;
1250 DATA_BLOB rpc_out;
1251 DATA_BLOB reply_pdu;
1254 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1255 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1256 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1257 bool *is_last_frag);
1259 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1260 struct event_context *ev,
1261 struct rpc_pipe_client *cli,
1262 uint8_t op_num,
1263 DATA_BLOB *req_data)
1265 struct tevent_req *req, *subreq;
1266 struct rpc_api_pipe_req_state *state;
1267 NTSTATUS status;
1268 bool is_last_frag;
1270 req = tevent_req_create(mem_ctx, &state,
1271 struct rpc_api_pipe_req_state);
1272 if (req == NULL) {
1273 return NULL;
1275 state->ev = ev;
1276 state->cli = cli;
1277 state->op_num = op_num;
1278 state->req_data = req_data;
1279 state->req_data_sent = 0;
1280 state->call_id = get_rpc_call_id();
1281 state->reply_pdu = data_blob_null;
1282 state->rpc_out = data_blob_null;
1284 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1285 + RPC_MAX_SIGN_SIZE) {
1286 /* Server is screwed up ! */
1287 status = NT_STATUS_INVALID_PARAMETER;
1288 goto post_status;
1291 status = prepare_next_frag(state, &is_last_frag);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 goto post_status;
1296 if (is_last_frag) {
1297 subreq = rpc_api_pipe_send(state, ev, state->cli,
1298 &state->rpc_out,
1299 DCERPC_PKT_RESPONSE);
1300 if (subreq == NULL) {
1301 goto fail;
1303 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1304 } else {
1305 subreq = rpc_write_send(state, ev, cli->transport,
1306 state->rpc_out.data,
1307 state->rpc_out.length);
1308 if (subreq == NULL) {
1309 goto fail;
1311 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1312 req);
1314 return req;
1316 post_status:
1317 tevent_req_nterror(req, status);
1318 return tevent_req_post(req, ev);
1319 fail:
1320 TALLOC_FREE(req);
1321 return NULL;
1324 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1325 bool *is_last_frag)
1327 size_t data_sent_thistime;
1328 size_t auth_len;
1329 size_t frag_len;
1330 uint8_t flags = 0;
1331 size_t pad_len;
1332 size_t data_left;
1333 NTSTATUS status;
1334 union dcerpc_payload u;
1336 data_left = state->req_data->length - state->req_data_sent;
1338 status = dcerpc_guess_sizes(state->cli->auth,
1339 DCERPC_REQUEST_LENGTH, data_left,
1340 state->cli->max_xmit_frag,
1341 CLIENT_NDR_PADDING_SIZE,
1342 &data_sent_thistime,
1343 &frag_len, &auth_len, &pad_len);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 return status;
1348 if (state->req_data_sent == 0) {
1349 flags = DCERPC_PFC_FLAG_FIRST;
1352 if (data_sent_thistime == data_left) {
1353 flags |= DCERPC_PFC_FLAG_LAST;
1356 data_blob_free(&state->rpc_out);
1358 ZERO_STRUCT(u.request);
1360 u.request.alloc_hint = state->req_data->length;
1361 u.request.context_id = 0;
1362 u.request.opnum = state->op_num;
1364 status = dcerpc_push_ncacn_packet(state,
1365 DCERPC_PKT_REQUEST,
1366 flags,
1367 auth_len,
1368 state->call_id,
1370 &state->rpc_out);
1371 if (!NT_STATUS_IS_OK(status)) {
1372 return status;
1375 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1376 * compute it right for requests because the auth trailer is missing
1377 * at this stage */
1378 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1380 /* Copy in the data. */
1381 if (!data_blob_append(NULL, &state->rpc_out,
1382 state->req_data->data + state->req_data_sent,
1383 data_sent_thistime)) {
1384 return NT_STATUS_NO_MEMORY;
1387 switch (state->cli->auth->auth_level) {
1388 case DCERPC_AUTH_LEVEL_NONE:
1389 case DCERPC_AUTH_LEVEL_CONNECT:
1390 case DCERPC_AUTH_LEVEL_PACKET:
1391 break;
1392 case DCERPC_AUTH_LEVEL_INTEGRITY:
1393 case DCERPC_AUTH_LEVEL_PRIVACY:
1394 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1395 &state->rpc_out);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 return status;
1399 break;
1400 default:
1401 return NT_STATUS_INVALID_PARAMETER;
1404 state->req_data_sent += data_sent_thistime;
1405 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1407 return status;
1410 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1412 struct tevent_req *req = tevent_req_callback_data(
1413 subreq, struct tevent_req);
1414 struct rpc_api_pipe_req_state *state = tevent_req_data(
1415 req, struct rpc_api_pipe_req_state);
1416 NTSTATUS status;
1417 bool is_last_frag;
1419 status = rpc_write_recv(subreq);
1420 TALLOC_FREE(subreq);
1421 if (!NT_STATUS_IS_OK(status)) {
1422 tevent_req_nterror(req, status);
1423 return;
1426 status = prepare_next_frag(state, &is_last_frag);
1427 if (!NT_STATUS_IS_OK(status)) {
1428 tevent_req_nterror(req, status);
1429 return;
1432 if (is_last_frag) {
1433 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1434 &state->rpc_out,
1435 DCERPC_PKT_RESPONSE);
1436 if (tevent_req_nomem(subreq, req)) {
1437 return;
1439 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1440 } else {
1441 subreq = rpc_write_send(state, state->ev,
1442 state->cli->transport,
1443 state->rpc_out.data,
1444 state->rpc_out.length);
1445 if (tevent_req_nomem(subreq, req)) {
1446 return;
1448 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1449 req);
1453 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1455 struct tevent_req *req = tevent_req_callback_data(
1456 subreq, struct tevent_req);
1457 struct rpc_api_pipe_req_state *state = tevent_req_data(
1458 req, struct rpc_api_pipe_req_state);
1459 NTSTATUS status;
1461 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1462 TALLOC_FREE(subreq);
1463 if (!NT_STATUS_IS_OK(status)) {
1464 tevent_req_nterror(req, status);
1465 return;
1467 tevent_req_done(req);
1470 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1471 DATA_BLOB *reply_pdu)
1473 struct rpc_api_pipe_req_state *state = tevent_req_data(
1474 req, struct rpc_api_pipe_req_state);
1475 NTSTATUS status;
1477 if (tevent_req_is_nterror(req, &status)) {
1479 * We always have to initialize to reply pdu, even if there is
1480 * none. The rpccli_* caller routines expect this.
1482 *reply_pdu = data_blob_null;
1483 return status;
1486 /* return data to caller and assign it ownership of memory */
1487 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1488 reply_pdu->length = state->reply_pdu.length;
1489 state->reply_pdu.length = 0;
1491 return NT_STATUS_OK;
1494 /****************************************************************************
1495 Check the rpc bind acknowledge response.
1496 ****************************************************************************/
1498 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1499 const struct ndr_syntax_id *transfer)
1501 struct dcerpc_ack_ctx ctx;
1503 if (r->secondary_address_size == 0) {
1504 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1507 if (r->num_results < 1 || !r->ctx_list) {
1508 return false;
1511 ctx = r->ctx_list[0];
1513 /* check the transfer syntax */
1514 if ((ctx.syntax.if_version != transfer->if_version) ||
1515 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1516 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1517 return False;
1520 if (r->num_results != 0x1 || ctx.result != 0) {
1521 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1522 r->num_results, ctx.reason));
1525 DEBUG(5,("check_bind_response: accepted!\n"));
1526 return True;
1529 /*******************************************************************
1530 Creates a DCE/RPC bind authentication response.
1531 This is the packet that is sent back to the server once we
1532 have received a BIND-ACK, to finish the third leg of
1533 the authentication handshake.
1534 ********************************************************************/
1536 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1537 struct rpc_pipe_client *cli,
1538 uint32 rpc_call_id,
1539 enum dcerpc_AuthType auth_type,
1540 enum dcerpc_AuthLevel auth_level,
1541 DATA_BLOB *pauth_blob,
1542 DATA_BLOB *rpc_out)
1544 NTSTATUS status;
1545 union dcerpc_payload u;
1547 u.auth3._pad = 0;
1549 status = dcerpc_push_dcerpc_auth(mem_ctx,
1550 auth_type,
1551 auth_level,
1552 0, /* auth_pad_length */
1553 1, /* auth_context_id */
1554 pauth_blob,
1555 &u.auth3.auth_info);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 return status;
1560 status = dcerpc_push_ncacn_packet(mem_ctx,
1561 DCERPC_PKT_AUTH3,
1562 DCERPC_PFC_FLAG_FIRST |
1563 DCERPC_PFC_FLAG_LAST,
1564 pauth_blob->length,
1565 rpc_call_id,
1567 rpc_out);
1568 data_blob_free(&u.auth3.auth_info);
1569 if (!NT_STATUS_IS_OK(status)) {
1570 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1571 return status;
1574 return NT_STATUS_OK;
1577 /*******************************************************************
1578 Creates a DCE/RPC bind alter context authentication request which
1579 may contain a spnego auth blobl
1580 ********************************************************************/
1582 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1583 enum dcerpc_AuthType auth_type,
1584 enum dcerpc_AuthLevel auth_level,
1585 uint32 rpc_call_id,
1586 const struct ndr_syntax_id *abstract,
1587 const struct ndr_syntax_id *transfer,
1588 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1589 DATA_BLOB *rpc_out)
1591 DATA_BLOB auth_info;
1592 NTSTATUS status;
1594 status = dcerpc_push_dcerpc_auth(mem_ctx,
1595 auth_type,
1596 auth_level,
1597 0, /* auth_pad_length */
1598 1, /* auth_context_id */
1599 pauth_blob,
1600 &auth_info);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 return status;
1605 status = create_bind_or_alt_ctx_internal(mem_ctx,
1606 DCERPC_PKT_ALTER,
1607 rpc_call_id,
1608 abstract,
1609 transfer,
1610 &auth_info,
1611 rpc_out);
1612 data_blob_free(&auth_info);
1613 return status;
1616 /****************************************************************************
1617 Do an rpc bind.
1618 ****************************************************************************/
1620 struct rpc_pipe_bind_state {
1621 struct event_context *ev;
1622 struct rpc_pipe_client *cli;
1623 DATA_BLOB rpc_out;
1624 bool auth3;
1625 uint32_t rpc_call_id;
1628 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1629 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1630 struct rpc_pipe_bind_state *state,
1631 DATA_BLOB *credentials);
1632 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1633 struct rpc_pipe_bind_state *state,
1634 DATA_BLOB *credentials);
1636 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1637 struct event_context *ev,
1638 struct rpc_pipe_client *cli,
1639 struct pipe_auth_data *auth)
1641 struct tevent_req *req, *subreq;
1642 struct rpc_pipe_bind_state *state;
1643 NTSTATUS status;
1645 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1646 if (req == NULL) {
1647 return NULL;
1650 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1651 rpccli_pipe_txt(talloc_tos(), cli),
1652 (unsigned int)auth->auth_type,
1653 (unsigned int)auth->auth_level ));
1655 state->ev = ev;
1656 state->cli = cli;
1657 state->rpc_call_id = get_rpc_call_id();
1659 cli->auth = talloc_move(cli, &auth);
1661 /* Marshall the outgoing data. */
1662 status = create_rpc_bind_req(state, cli,
1663 cli->auth,
1664 state->rpc_call_id,
1665 &cli->abstract_syntax,
1666 &cli->transfer_syntax,
1667 &state->rpc_out);
1669 if (!NT_STATUS_IS_OK(status)) {
1670 goto post_status;
1673 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1674 DCERPC_PKT_BIND_ACK);
1675 if (subreq == NULL) {
1676 goto fail;
1678 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1679 return req;
1681 post_status:
1682 tevent_req_nterror(req, status);
1683 return tevent_req_post(req, ev);
1684 fail:
1685 TALLOC_FREE(req);
1686 return NULL;
1689 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1691 struct tevent_req *req = tevent_req_callback_data(
1692 subreq, struct tevent_req);
1693 struct rpc_pipe_bind_state *state = tevent_req_data(
1694 req, struct rpc_pipe_bind_state);
1695 struct pipe_auth_data *pauth = state->cli->auth;
1696 struct auth_ntlmssp_state *ntlmssp_ctx;
1697 struct spnego_context *spnego_ctx;
1698 struct gse_context *gse_ctx;
1699 struct ncacn_packet *pkt = NULL;
1700 struct dcerpc_auth auth;
1701 DATA_BLOB auth_token = data_blob_null;
1702 NTSTATUS status;
1704 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1705 TALLOC_FREE(subreq);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1708 rpccli_pipe_txt(talloc_tos(), state->cli),
1709 nt_errstr(status)));
1710 tevent_req_nterror(req, status);
1711 return;
1714 if (state->auth3) {
1715 tevent_req_done(req);
1716 return;
1719 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1720 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1721 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1722 return;
1725 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1726 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1728 switch(pauth->auth_type) {
1730 case DCERPC_AUTH_TYPE_NONE:
1731 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1732 case DCERPC_AUTH_TYPE_SCHANNEL:
1733 /* Bind complete. */
1734 tevent_req_done(req);
1735 return;
1737 case DCERPC_AUTH_TYPE_NTLMSSP:
1738 case DCERPC_AUTH_TYPE_SPNEGO:
1739 case DCERPC_AUTH_TYPE_KRB5:
1740 /* Paranoid lenght checks */
1741 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1742 + pkt->auth_length) {
1743 tevent_req_nterror(req,
1744 NT_STATUS_INFO_LENGTH_MISMATCH);
1745 return;
1747 /* get auth credentials */
1748 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1749 &pkt->u.bind_ack.auth_info,
1750 &auth, false);
1751 if (!NT_STATUS_IS_OK(status)) {
1752 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1753 nt_errstr(status)));
1754 tevent_req_nterror(req, status);
1755 return;
1757 break;
1759 default:
1760 goto err_out;
1764 * For authenticated binds we may need to do 3 or 4 leg binds.
1767 switch(pauth->auth_type) {
1769 case DCERPC_AUTH_TYPE_NONE:
1770 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
1771 case DCERPC_AUTH_TYPE_SCHANNEL:
1772 /* Bind complete. */
1773 tevent_req_done(req);
1774 return;
1776 case DCERPC_AUTH_TYPE_NTLMSSP:
1777 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
1778 struct auth_ntlmssp_state);
1779 status = auth_ntlmssp_update(ntlmssp_ctx,
1780 auth.credentials, &auth_token);
1781 if (NT_STATUS_EQUAL(status,
1782 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1783 status = rpc_bind_next_send(req, state,
1784 &auth_token);
1785 } else if (NT_STATUS_IS_OK(status)) {
1786 status = rpc_bind_finish_send(req, state,
1787 &auth_token);
1789 break;
1791 case DCERPC_AUTH_TYPE_SPNEGO:
1792 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1793 struct spnego_context);
1794 status = spnego_get_client_auth_token(state,
1795 spnego_ctx,
1796 &auth.credentials,
1797 &auth_token);
1798 if (!NT_STATUS_IS_OK(status)) {
1799 break;
1801 if (auth_token.length == 0) {
1802 /* Bind complete. */
1803 tevent_req_done(req);
1804 return;
1806 if (spnego_require_more_processing(spnego_ctx)) {
1807 status = rpc_bind_next_send(req, state,
1808 &auth_token);
1809 } else {
1810 status = rpc_bind_finish_send(req, state,
1811 &auth_token);
1813 break;
1815 case DCERPC_AUTH_TYPE_KRB5:
1816 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
1817 struct gse_context);
1818 status = gse_get_client_auth_token(state,
1819 gse_ctx,
1820 &auth.credentials,
1821 &auth_token);
1822 if (!NT_STATUS_IS_OK(status)) {
1823 break;
1826 if (gse_require_more_processing(gse_ctx)) {
1827 status = rpc_bind_next_send(req, state, &auth_token);
1828 } else {
1829 status = rpc_bind_finish_send(req, state, &auth_token);
1831 break;
1833 default:
1834 goto err_out;
1837 if (!NT_STATUS_IS_OK(status)) {
1838 tevent_req_nterror(req, status);
1840 return;
1842 err_out:
1843 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1844 (unsigned int)state->cli->auth->auth_type));
1845 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1848 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1849 struct rpc_pipe_bind_state *state,
1850 DATA_BLOB *auth_token)
1852 struct pipe_auth_data *auth = state->cli->auth;
1853 struct tevent_req *subreq;
1854 NTSTATUS status;
1856 /* Now prepare the alter context pdu. */
1857 data_blob_free(&state->rpc_out);
1859 status = create_rpc_alter_context(state,
1860 auth->auth_type,
1861 auth->auth_level,
1862 state->rpc_call_id,
1863 &state->cli->abstract_syntax,
1864 &state->cli->transfer_syntax,
1865 auth_token,
1866 &state->rpc_out);
1867 if (!NT_STATUS_IS_OK(status)) {
1868 return status;
1871 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1872 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1873 if (subreq == NULL) {
1874 return NT_STATUS_NO_MEMORY;
1876 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1877 return NT_STATUS_OK;
1880 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1881 struct rpc_pipe_bind_state *state,
1882 DATA_BLOB *auth_token)
1884 struct pipe_auth_data *auth = state->cli->auth;
1885 struct tevent_req *subreq;
1886 NTSTATUS status;
1888 state->auth3 = true;
1890 /* Now prepare the auth3 context pdu. */
1891 data_blob_free(&state->rpc_out);
1893 status = create_rpc_bind_auth3(state, state->cli,
1894 state->rpc_call_id,
1895 auth->auth_type,
1896 auth->auth_level,
1897 auth_token,
1898 &state->rpc_out);
1899 if (!NT_STATUS_IS_OK(status)) {
1900 return status;
1903 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1904 &state->rpc_out, DCERPC_PKT_AUTH3);
1905 if (subreq == NULL) {
1906 return NT_STATUS_NO_MEMORY;
1908 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1909 return NT_STATUS_OK;
1912 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1914 return tevent_req_simple_recv_ntstatus(req);
1917 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1918 struct pipe_auth_data *auth)
1920 TALLOC_CTX *frame = talloc_stackframe();
1921 struct event_context *ev;
1922 struct tevent_req *req;
1923 NTSTATUS status = NT_STATUS_OK;
1925 ev = event_context_init(frame);
1926 if (ev == NULL) {
1927 status = NT_STATUS_NO_MEMORY;
1928 goto fail;
1931 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1932 if (req == NULL) {
1933 status = NT_STATUS_NO_MEMORY;
1934 goto fail;
1937 if (!tevent_req_poll(req, ev)) {
1938 status = map_nt_error_from_unix(errno);
1939 goto fail;
1942 status = rpc_pipe_bind_recv(req);
1943 fail:
1944 TALLOC_FREE(frame);
1945 return status;
1948 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1950 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1951 unsigned int timeout)
1953 unsigned int old;
1955 if (rpc_cli->transport == NULL) {
1956 return RPCCLI_DEFAULT_TIMEOUT;
1959 if (rpc_cli->transport->set_timeout == NULL) {
1960 return RPCCLI_DEFAULT_TIMEOUT;
1963 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1964 if (old == 0) {
1965 return RPCCLI_DEFAULT_TIMEOUT;
1968 return old;
1971 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1973 if (rpc_cli == NULL) {
1974 return false;
1977 if (rpc_cli->transport == NULL) {
1978 return false;
1981 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1984 struct rpccli_bh_state {
1985 struct rpc_pipe_client *rpc_cli;
1988 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1990 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1991 struct rpccli_bh_state);
1993 return rpccli_is_connected(hs->rpc_cli);
1996 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1997 uint32_t timeout)
1999 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2000 struct rpccli_bh_state);
2002 return rpccli_set_timeout(hs->rpc_cli, timeout);
2005 struct rpccli_bh_raw_call_state {
2006 DATA_BLOB in_data;
2007 DATA_BLOB out_data;
2008 uint32_t out_flags;
2011 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2013 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2014 struct tevent_context *ev,
2015 struct dcerpc_binding_handle *h,
2016 const struct GUID *object,
2017 uint32_t opnum,
2018 uint32_t in_flags,
2019 const uint8_t *in_data,
2020 size_t in_length)
2022 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2023 struct rpccli_bh_state);
2024 struct tevent_req *req;
2025 struct rpccli_bh_raw_call_state *state;
2026 bool ok;
2027 struct tevent_req *subreq;
2029 req = tevent_req_create(mem_ctx, &state,
2030 struct rpccli_bh_raw_call_state);
2031 if (req == NULL) {
2032 return NULL;
2034 state->in_data.data = discard_const_p(uint8_t, in_data);
2035 state->in_data.length = in_length;
2037 ok = rpccli_bh_is_connected(h);
2038 if (!ok) {
2039 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2040 return tevent_req_post(req, ev);
2043 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2044 opnum, &state->in_data);
2045 if (tevent_req_nomem(subreq, req)) {
2046 return tevent_req_post(req, ev);
2048 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2050 return req;
2053 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2055 struct tevent_req *req =
2056 tevent_req_callback_data(subreq,
2057 struct tevent_req);
2058 struct rpccli_bh_raw_call_state *state =
2059 tevent_req_data(req,
2060 struct rpccli_bh_raw_call_state);
2061 NTSTATUS status;
2063 state->out_flags = 0;
2065 /* TODO: support bigendian responses */
2067 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2068 TALLOC_FREE(subreq);
2069 if (!NT_STATUS_IS_OK(status)) {
2070 tevent_req_nterror(req, status);
2071 return;
2074 tevent_req_done(req);
2077 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2078 TALLOC_CTX *mem_ctx,
2079 uint8_t **out_data,
2080 size_t *out_length,
2081 uint32_t *out_flags)
2083 struct rpccli_bh_raw_call_state *state =
2084 tevent_req_data(req,
2085 struct rpccli_bh_raw_call_state);
2086 NTSTATUS status;
2088 if (tevent_req_is_nterror(req, &status)) {
2089 tevent_req_received(req);
2090 return status;
2093 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2094 *out_length = state->out_data.length;
2095 *out_flags = state->out_flags;
2096 tevent_req_received(req);
2097 return NT_STATUS_OK;
2100 struct rpccli_bh_disconnect_state {
2101 uint8_t _dummy;
2104 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2105 struct tevent_context *ev,
2106 struct dcerpc_binding_handle *h)
2108 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2109 struct rpccli_bh_state);
2110 struct tevent_req *req;
2111 struct rpccli_bh_disconnect_state *state;
2112 bool ok;
2114 req = tevent_req_create(mem_ctx, &state,
2115 struct rpccli_bh_disconnect_state);
2116 if (req == NULL) {
2117 return NULL;
2120 ok = rpccli_bh_is_connected(h);
2121 if (!ok) {
2122 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2123 return tevent_req_post(req, ev);
2127 * TODO: do a real async disconnect ...
2129 * For now the caller needs to free rpc_cli
2131 hs->rpc_cli = NULL;
2133 tevent_req_done(req);
2134 return tevent_req_post(req, ev);
2137 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2139 NTSTATUS status;
2141 if (tevent_req_is_nterror(req, &status)) {
2142 tevent_req_received(req);
2143 return status;
2146 tevent_req_received(req);
2147 return NT_STATUS_OK;
2150 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2152 return true;
2155 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2156 int ndr_flags,
2157 const void *_struct_ptr,
2158 const struct ndr_interface_call *call)
2160 void *struct_ptr = discard_const(_struct_ptr);
2162 if (DEBUGLEVEL < 10) {
2163 return;
2166 if (ndr_flags & NDR_IN) {
2167 ndr_print_function_debug(call->ndr_print,
2168 call->name,
2169 ndr_flags,
2170 struct_ptr);
2172 if (ndr_flags & NDR_OUT) {
2173 ndr_print_function_debug(call->ndr_print,
2174 call->name,
2175 ndr_flags,
2176 struct_ptr);
2180 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2181 .name = "rpccli",
2182 .is_connected = rpccli_bh_is_connected,
2183 .set_timeout = rpccli_bh_set_timeout,
2184 .raw_call_send = rpccli_bh_raw_call_send,
2185 .raw_call_recv = rpccli_bh_raw_call_recv,
2186 .disconnect_send = rpccli_bh_disconnect_send,
2187 .disconnect_recv = rpccli_bh_disconnect_recv,
2189 .ref_alloc = rpccli_bh_ref_alloc,
2190 .do_ndr_print = rpccli_bh_do_ndr_print,
2193 /* initialise a rpc_pipe_client binding handle */
2194 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2196 struct dcerpc_binding_handle *h;
2197 struct rpccli_bh_state *hs;
2199 h = dcerpc_binding_handle_create(c,
2200 &rpccli_bh_ops,
2201 NULL,
2202 NULL, /* TODO */
2203 &hs,
2204 struct rpccli_bh_state,
2205 __location__);
2206 if (h == NULL) {
2207 return NULL;
2209 hs->rpc_cli = c;
2211 return h;
2214 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2216 struct auth_ntlmssp_state *a = NULL;
2217 struct cli_state *cli;
2219 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2220 a = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2221 struct auth_ntlmssp_state);
2222 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2223 struct spnego_context *spnego_ctx;
2224 enum spnego_mech auth_type;
2225 void *auth_ctx;
2226 NTSTATUS status;
2228 spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2229 struct spnego_context);
2230 status = spnego_get_negotiated_mech(spnego_ctx,
2231 &auth_type, &auth_ctx);
2232 if (!NT_STATUS_IS_OK(status)) {
2233 return false;
2236 if (auth_type == SPNEGO_NTLMSSP) {
2237 a = talloc_get_type_abort(auth_ctx,
2238 struct auth_ntlmssp_state);
2242 if (a) {
2243 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2244 return true;
2247 cli = rpc_pipe_np_smb_conn(rpc_cli);
2248 if (cli == NULL) {
2249 return false;
2251 E_md4hash(cli->password ? cli->password : "", nt_hash);
2252 return true;
2255 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2256 struct pipe_auth_data **presult)
2258 struct pipe_auth_data *result;
2260 result = talloc(mem_ctx, struct pipe_auth_data);
2261 if (result == NULL) {
2262 return NT_STATUS_NO_MEMORY;
2265 result->auth_type = DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM;
2266 result->auth_level = DCERPC_AUTH_LEVEL_CONNECT;
2268 result->user_name = talloc_strdup(result, "");
2269 result->domain = talloc_strdup(result, "");
2270 if ((result->user_name == NULL) || (result->domain == NULL)) {
2271 TALLOC_FREE(result);
2272 return NT_STATUS_NO_MEMORY;
2275 *presult = result;
2276 return NT_STATUS_OK;
2279 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2280 struct pipe_auth_data **presult)
2282 struct pipe_auth_data *result;
2284 result = talloc(mem_ctx, struct pipe_auth_data);
2285 if (result == NULL) {
2286 return NT_STATUS_NO_MEMORY;
2289 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2290 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2292 result->user_name = talloc_strdup(result, "");
2293 result->domain = talloc_strdup(result, "");
2294 if ((result->user_name == NULL) || (result->domain == NULL)) {
2295 TALLOC_FREE(result);
2296 return NT_STATUS_NO_MEMORY;
2299 *presult = result;
2300 return NT_STATUS_OK;
2303 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2305 TALLOC_FREE(auth->auth_ctx);
2306 return 0;
2309 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2310 enum dcerpc_AuthType auth_type,
2311 enum dcerpc_AuthLevel auth_level,
2312 const char *domain,
2313 const char *username,
2314 const char *password,
2315 struct pipe_auth_data **presult)
2317 struct auth_ntlmssp_state *ntlmssp_ctx;
2318 struct pipe_auth_data *result;
2319 NTSTATUS status;
2321 result = talloc(mem_ctx, struct pipe_auth_data);
2322 if (result == NULL) {
2323 return NT_STATUS_NO_MEMORY;
2326 result->auth_type = auth_type;
2327 result->auth_level = auth_level;
2329 result->user_name = talloc_strdup(result, username);
2330 result->domain = talloc_strdup(result, domain);
2331 if ((result->user_name == NULL) || (result->domain == NULL)) {
2332 status = NT_STATUS_NO_MEMORY;
2333 goto fail;
2336 status = auth_ntlmssp_client_start(NULL,
2337 global_myname(),
2338 lp_workgroup(),
2339 lp_client_ntlmv2_auth(),
2340 &ntlmssp_ctx);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 goto fail;
2345 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2347 status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
2348 if (!NT_STATUS_IS_OK(status)) {
2349 goto fail;
2352 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
2353 if (!NT_STATUS_IS_OK(status)) {
2354 goto fail;
2357 status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
2358 if (!NT_STATUS_IS_OK(status)) {
2359 goto fail;
2363 * Turn off sign+seal to allow selected auth level to turn it back on.
2365 auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN |
2366 NTLMSSP_NEGOTIATE_SEAL));
2368 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2369 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN);
2370 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2371 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL |
2372 NTLMSSP_NEGOTIATE_SIGN);
2375 result->auth_ctx = ntlmssp_ctx;
2376 *presult = result;
2377 return NT_STATUS_OK;
2379 fail:
2380 TALLOC_FREE(result);
2381 return status;
2384 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2385 enum dcerpc_AuthLevel auth_level,
2386 struct netlogon_creds_CredentialState *creds,
2387 struct pipe_auth_data **presult)
2389 struct schannel_state *schannel_auth;
2390 struct pipe_auth_data *result;
2392 result = talloc(mem_ctx, struct pipe_auth_data);
2393 if (result == NULL) {
2394 return NT_STATUS_NO_MEMORY;
2397 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2398 result->auth_level = auth_level;
2400 result->user_name = talloc_strdup(result, "");
2401 result->domain = talloc_strdup(result, domain);
2402 if ((result->user_name == NULL) || (result->domain == NULL)) {
2403 goto fail;
2406 schannel_auth = talloc(result, struct schannel_state);
2407 if (schannel_auth == NULL) {
2408 goto fail;
2411 schannel_auth->state = SCHANNEL_STATE_START;
2412 schannel_auth->seq_num = 0;
2413 schannel_auth->initiator = true;
2414 schannel_auth->creds = netlogon_creds_copy(result, creds);
2416 result->auth_ctx = schannel_auth;
2417 *presult = result;
2418 return NT_STATUS_OK;
2420 fail:
2421 TALLOC_FREE(result);
2422 return NT_STATUS_NO_MEMORY;
2426 * Create an rpc pipe client struct, connecting to a tcp port.
2428 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2429 uint16_t port,
2430 const struct ndr_syntax_id *abstract_syntax,
2431 struct rpc_pipe_client **presult)
2433 struct rpc_pipe_client *result;
2434 struct sockaddr_storage addr;
2435 NTSTATUS status;
2436 int fd;
2438 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2439 if (result == NULL) {
2440 return NT_STATUS_NO_MEMORY;
2443 result->abstract_syntax = *abstract_syntax;
2444 result->transfer_syntax = ndr_transfer_syntax;
2446 result->desthost = talloc_strdup(result, host);
2447 result->srv_name_slash = talloc_asprintf_strupper_m(
2448 result, "\\\\%s", result->desthost);
2449 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2450 status = NT_STATUS_NO_MEMORY;
2451 goto fail;
2454 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2455 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2457 if (!resolve_name(host, &addr, 0, false)) {
2458 status = NT_STATUS_NOT_FOUND;
2459 goto fail;
2462 status = open_socket_out(&addr, port, 60*1000, &fd);
2463 if (!NT_STATUS_IS_OK(status)) {
2464 goto fail;
2466 set_socket_options(fd, lp_socket_options());
2468 status = rpc_transport_sock_init(result, fd, &result->transport);
2469 if (!NT_STATUS_IS_OK(status)) {
2470 close(fd);
2471 goto fail;
2474 result->transport->transport = NCACN_IP_TCP;
2476 result->binding_handle = rpccli_bh_create(result);
2477 if (result->binding_handle == NULL) {
2478 TALLOC_FREE(result);
2479 return NT_STATUS_NO_MEMORY;
2482 *presult = result;
2483 return NT_STATUS_OK;
2485 fail:
2486 TALLOC_FREE(result);
2487 return status;
2491 * Determine the tcp port on which a dcerpc interface is listening
2492 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2493 * target host.
2495 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2496 const struct ndr_syntax_id *abstract_syntax,
2497 uint16_t *pport)
2499 NTSTATUS status;
2500 struct rpc_pipe_client *epm_pipe = NULL;
2501 struct dcerpc_binding_handle *epm_handle = NULL;
2502 struct pipe_auth_data *auth = NULL;
2503 struct dcerpc_binding *map_binding = NULL;
2504 struct dcerpc_binding *res_binding = NULL;
2505 struct epm_twr_t *map_tower = NULL;
2506 struct epm_twr_t *res_towers = NULL;
2507 struct policy_handle *entry_handle = NULL;
2508 uint32_t num_towers = 0;
2509 uint32_t max_towers = 1;
2510 struct epm_twr_p_t towers;
2511 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2512 uint32_t result = 0;
2514 if (pport == NULL) {
2515 status = NT_STATUS_INVALID_PARAMETER;
2516 goto done;
2519 if (ndr_syntax_id_equal(abstract_syntax,
2520 &ndr_table_epmapper.syntax_id)) {
2521 *pport = 135;
2522 return NT_STATUS_OK;
2525 /* open the connection to the endpoint mapper */
2526 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2527 &ndr_table_epmapper.syntax_id,
2528 &epm_pipe);
2530 if (!NT_STATUS_IS_OK(status)) {
2531 goto done;
2533 epm_handle = epm_pipe->binding_handle;
2535 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2536 if (!NT_STATUS_IS_OK(status)) {
2537 goto done;
2540 status = rpc_pipe_bind(epm_pipe, auth);
2541 if (!NT_STATUS_IS_OK(status)) {
2542 goto done;
2545 /* create tower for asking the epmapper */
2547 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2548 if (map_binding == NULL) {
2549 status = NT_STATUS_NO_MEMORY;
2550 goto done;
2553 map_binding->transport = NCACN_IP_TCP;
2554 map_binding->object = *abstract_syntax;
2555 map_binding->host = host; /* needed? */
2556 map_binding->endpoint = "0"; /* correct? needed? */
2558 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2559 if (map_tower == NULL) {
2560 status = NT_STATUS_NO_MEMORY;
2561 goto done;
2564 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2565 &(map_tower->tower));
2566 if (!NT_STATUS_IS_OK(status)) {
2567 goto done;
2570 /* allocate further parameters for the epm_Map call */
2572 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2573 if (res_towers == NULL) {
2574 status = NT_STATUS_NO_MEMORY;
2575 goto done;
2577 towers.twr = res_towers;
2579 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2580 if (entry_handle == NULL) {
2581 status = NT_STATUS_NO_MEMORY;
2582 goto done;
2585 /* ask the endpoint mapper for the port */
2587 status = dcerpc_epm_Map(epm_handle,
2588 tmp_ctx,
2589 CONST_DISCARD(struct GUID *,
2590 &(abstract_syntax->uuid)),
2591 map_tower,
2592 entry_handle,
2593 max_towers,
2594 &num_towers,
2595 &towers,
2596 &result);
2598 if (!NT_STATUS_IS_OK(status)) {
2599 goto done;
2602 if (result != EPMAPPER_STATUS_OK) {
2603 status = NT_STATUS_UNSUCCESSFUL;
2604 goto done;
2607 if (num_towers != 1) {
2608 status = NT_STATUS_UNSUCCESSFUL;
2609 goto done;
2612 /* extract the port from the answer */
2614 status = dcerpc_binding_from_tower(tmp_ctx,
2615 &(towers.twr->tower),
2616 &res_binding);
2617 if (!NT_STATUS_IS_OK(status)) {
2618 goto done;
2621 /* are further checks here necessary? */
2622 if (res_binding->transport != NCACN_IP_TCP) {
2623 status = NT_STATUS_UNSUCCESSFUL;
2624 goto done;
2627 *pport = (uint16_t)atoi(res_binding->endpoint);
2629 done:
2630 TALLOC_FREE(tmp_ctx);
2631 return status;
2635 * Create a rpc pipe client struct, connecting to a host via tcp.
2636 * The port is determined by asking the endpoint mapper on the given
2637 * host.
2639 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2640 const struct ndr_syntax_id *abstract_syntax,
2641 struct rpc_pipe_client **presult)
2643 NTSTATUS status;
2644 uint16_t port = 0;
2646 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2647 if (!NT_STATUS_IS_OK(status)) {
2648 return status;
2651 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2652 abstract_syntax, presult);
2655 /********************************************************************
2656 Create a rpc pipe client struct, connecting to a unix domain socket
2657 ********************************************************************/
2658 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2659 const struct ndr_syntax_id *abstract_syntax,
2660 struct rpc_pipe_client **presult)
2662 struct rpc_pipe_client *result;
2663 struct sockaddr_un addr;
2664 NTSTATUS status;
2665 int fd;
2667 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2668 if (result == NULL) {
2669 return NT_STATUS_NO_MEMORY;
2672 result->abstract_syntax = *abstract_syntax;
2673 result->transfer_syntax = ndr_transfer_syntax;
2675 result->desthost = get_myname(result);
2676 result->srv_name_slash = talloc_asprintf_strupper_m(
2677 result, "\\\\%s", result->desthost);
2678 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2679 status = NT_STATUS_NO_MEMORY;
2680 goto fail;
2683 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2684 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2686 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2687 if (fd == -1) {
2688 status = map_nt_error_from_unix(errno);
2689 goto fail;
2692 ZERO_STRUCT(addr);
2693 addr.sun_family = AF_UNIX;
2694 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2696 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2697 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2698 strerror(errno)));
2699 close(fd);
2700 return map_nt_error_from_unix(errno);
2703 status = rpc_transport_sock_init(result, fd, &result->transport);
2704 if (!NT_STATUS_IS_OK(status)) {
2705 close(fd);
2706 goto fail;
2709 result->transport->transport = NCALRPC;
2711 result->binding_handle = rpccli_bh_create(result);
2712 if (result->binding_handle == NULL) {
2713 TALLOC_FREE(result);
2714 return NT_STATUS_NO_MEMORY;
2717 *presult = result;
2718 return NT_STATUS_OK;
2720 fail:
2721 TALLOC_FREE(result);
2722 return status;
2725 struct rpc_pipe_client_np_ref {
2726 struct cli_state *cli;
2727 struct rpc_pipe_client *pipe;
2730 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2732 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2733 return 0;
2736 /****************************************************************************
2737 Open a named pipe over SMB to a remote server.
2739 * CAVEAT CALLER OF THIS FUNCTION:
2740 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2741 * so be sure that this function is called AFTER any structure (vs pointer)
2742 * assignment of the cli. In particular, libsmbclient does structure
2743 * assignments of cli, which invalidates the data in the returned
2744 * rpc_pipe_client if this function is called before the structure assignment
2745 * of cli.
2747 ****************************************************************************/
2749 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2750 const struct ndr_syntax_id *abstract_syntax,
2751 struct rpc_pipe_client **presult)
2753 struct rpc_pipe_client *result;
2754 NTSTATUS status;
2755 struct rpc_pipe_client_np_ref *np_ref;
2757 /* sanity check to protect against crashes */
2759 if ( !cli ) {
2760 return NT_STATUS_INVALID_HANDLE;
2763 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2764 if (result == NULL) {
2765 return NT_STATUS_NO_MEMORY;
2768 result->abstract_syntax = *abstract_syntax;
2769 result->transfer_syntax = ndr_transfer_syntax;
2770 result->desthost = talloc_strdup(result, cli->desthost);
2771 result->srv_name_slash = talloc_asprintf_strupper_m(
2772 result, "\\\\%s", result->desthost);
2774 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2775 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2777 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2778 TALLOC_FREE(result);
2779 return NT_STATUS_NO_MEMORY;
2782 status = rpc_transport_np_init(result, cli, abstract_syntax,
2783 &result->transport);
2784 if (!NT_STATUS_IS_OK(status)) {
2785 TALLOC_FREE(result);
2786 return status;
2789 result->transport->transport = NCACN_NP;
2791 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2792 if (np_ref == NULL) {
2793 TALLOC_FREE(result);
2794 return NT_STATUS_NO_MEMORY;
2796 np_ref->cli = cli;
2797 np_ref->pipe = result;
2799 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2800 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2802 result->binding_handle = rpccli_bh_create(result);
2803 if (result->binding_handle == NULL) {
2804 TALLOC_FREE(result);
2805 return NT_STATUS_NO_MEMORY;
2808 *presult = result;
2809 return NT_STATUS_OK;
2812 /****************************************************************************
2813 Open a pipe to a remote server.
2814 ****************************************************************************/
2816 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2817 enum dcerpc_transport_t transport,
2818 const struct ndr_syntax_id *interface,
2819 struct rpc_pipe_client **presult)
2821 switch (transport) {
2822 case NCACN_IP_TCP:
2823 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2824 presult);
2825 case NCACN_NP:
2826 return rpc_pipe_open_np(cli, interface, presult);
2827 default:
2828 return NT_STATUS_NOT_IMPLEMENTED;
2832 /****************************************************************************
2833 Open a named pipe to an SMB server and bind anonymously.
2834 ****************************************************************************/
2836 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2837 enum dcerpc_transport_t transport,
2838 const struct ndr_syntax_id *interface,
2839 struct rpc_pipe_client **presult)
2841 struct rpc_pipe_client *result;
2842 struct pipe_auth_data *auth;
2843 NTSTATUS status;
2845 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2846 if (!NT_STATUS_IS_OK(status)) {
2847 return status;
2850 status = rpccli_anon_bind_data(result, &auth);
2851 if (!NT_STATUS_IS_OK(status)) {
2852 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2853 nt_errstr(status)));
2854 TALLOC_FREE(result);
2855 return status;
2859 * This is a bit of an abstraction violation due to the fact that an
2860 * anonymous bind on an authenticated SMB inherits the user/domain
2861 * from the enclosing SMB creds
2864 TALLOC_FREE(auth->user_name);
2865 TALLOC_FREE(auth->domain);
2867 auth->user_name = talloc_strdup(auth, cli->user_name);
2868 auth->domain = talloc_strdup(auth, cli->domain);
2869 auth->user_session_key = data_blob_talloc(auth,
2870 cli->user_session_key.data,
2871 cli->user_session_key.length);
2873 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2874 TALLOC_FREE(result);
2875 return NT_STATUS_NO_MEMORY;
2878 status = rpc_pipe_bind(result, auth);
2879 if (!NT_STATUS_IS_OK(status)) {
2880 int lvl = 0;
2881 if (ndr_syntax_id_equal(interface,
2882 &ndr_table_dssetup.syntax_id)) {
2883 /* non AD domains just don't have this pipe, avoid
2884 * level 0 statement in that case - gd */
2885 lvl = 3;
2887 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2888 "%s failed with error %s\n",
2889 get_pipe_name_from_syntax(talloc_tos(), interface),
2890 nt_errstr(status) ));
2891 TALLOC_FREE(result);
2892 return status;
2895 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2896 "%s and bound anonymously.\n",
2897 get_pipe_name_from_syntax(talloc_tos(), interface),
2898 cli->desthost));
2900 *presult = result;
2901 return NT_STATUS_OK;
2904 /****************************************************************************
2905 ****************************************************************************/
2907 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2908 const struct ndr_syntax_id *interface,
2909 struct rpc_pipe_client **presult)
2911 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2912 interface, presult);
2915 /****************************************************************************
2916 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2917 ****************************************************************************/
2919 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2920 const struct ndr_syntax_id *interface,
2921 enum dcerpc_transport_t transport,
2922 enum dcerpc_AuthLevel auth_level,
2923 const char *domain,
2924 const char *username,
2925 const char *password,
2926 struct rpc_pipe_client **presult)
2928 struct rpc_pipe_client *result;
2929 struct pipe_auth_data *auth = NULL;
2930 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2931 NTSTATUS status;
2933 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2934 if (!NT_STATUS_IS_OK(status)) {
2935 return status;
2938 status = rpccli_ntlmssp_bind_data(result,
2939 auth_type, auth_level,
2940 domain, username, password,
2941 &auth);
2942 if (!NT_STATUS_IS_OK(status)) {
2943 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2944 nt_errstr(status)));
2945 goto err;
2948 status = rpc_pipe_bind(result, auth);
2949 if (!NT_STATUS_IS_OK(status)) {
2950 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2951 nt_errstr(status) ));
2952 goto err;
2955 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2956 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2957 get_pipe_name_from_syntax(talloc_tos(), interface),
2958 cli->desthost, domain, username ));
2960 *presult = result;
2961 return NT_STATUS_OK;
2963 err:
2965 TALLOC_FREE(result);
2966 return status;
2969 /****************************************************************************
2970 External interface.
2971 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2972 using session_key. sign and seal.
2974 The *pdc will be stolen onto this new pipe
2975 ****************************************************************************/
2977 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2978 const struct ndr_syntax_id *interface,
2979 enum dcerpc_transport_t transport,
2980 enum dcerpc_AuthLevel auth_level,
2981 const char *domain,
2982 struct netlogon_creds_CredentialState **pdc,
2983 struct rpc_pipe_client **presult)
2985 struct rpc_pipe_client *result;
2986 struct pipe_auth_data *auth;
2987 NTSTATUS status;
2989 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2990 if (!NT_STATUS_IS_OK(status)) {
2991 return status;
2994 status = rpccli_schannel_bind_data(result, domain, auth_level,
2995 *pdc, &auth);
2996 if (!NT_STATUS_IS_OK(status)) {
2997 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2998 nt_errstr(status)));
2999 TALLOC_FREE(result);
3000 return status;
3003 status = rpc_pipe_bind(result, auth);
3004 if (!NT_STATUS_IS_OK(status)) {
3005 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3006 "cli_rpc_pipe_bind failed with error %s\n",
3007 nt_errstr(status) ));
3008 TALLOC_FREE(result);
3009 return status;
3013 * The credentials on a new netlogon pipe are the ones we are passed
3014 * in - copy them over
3016 result->dc = netlogon_creds_copy(result, *pdc);
3017 if (result->dc == NULL) {
3018 TALLOC_FREE(result);
3019 return NT_STATUS_NO_MEMORY;
3022 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3023 "for domain %s and bound using schannel.\n",
3024 get_pipe_name_from_syntax(talloc_tos(), interface),
3025 cli->desthost, domain ));
3027 *presult = result;
3028 return NT_STATUS_OK;
3031 /****************************************************************************
3032 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3033 The idea is this can be called with service_princ, username and password all
3034 NULL so long as the caller has a TGT.
3035 ****************************************************************************/
3037 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3038 const struct ndr_syntax_id *interface,
3039 enum dcerpc_transport_t transport,
3040 enum dcerpc_AuthLevel auth_level,
3041 const char *server,
3042 const char *username,
3043 const char *password,
3044 struct rpc_pipe_client **presult)
3046 struct rpc_pipe_client *result;
3047 struct pipe_auth_data *auth;
3048 struct gse_context *gse_ctx;
3049 NTSTATUS status;
3051 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 return status;
3056 auth = talloc(result, struct pipe_auth_data);
3057 if (auth == NULL) {
3058 status = NT_STATUS_NO_MEMORY;
3059 goto err_out;
3061 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3062 auth->auth_level = auth_level;
3064 if (!username) {
3065 username = "";
3067 auth->user_name = talloc_strdup(auth, username);
3068 if (!auth->user_name) {
3069 status = NT_STATUS_NO_MEMORY;
3070 goto err_out;
3073 /* Fixme, should we fetch/set the Realm ? */
3074 auth->domain = talloc_strdup(auth, "");
3075 if (!auth->domain) {
3076 status = NT_STATUS_NO_MEMORY;
3077 goto err_out;
3080 status = gse_init_client(auth,
3081 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3082 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3083 NULL, server, "cifs", username, password,
3084 GSS_C_DCE_STYLE, &gse_ctx);
3085 if (!NT_STATUS_IS_OK(status)) {
3086 DEBUG(0, ("gse_init_client returned %s\n",
3087 nt_errstr(status)));
3088 goto err_out;
3090 auth->auth_ctx = gse_ctx;
3092 status = rpc_pipe_bind(result, auth);
3093 if (!NT_STATUS_IS_OK(status)) {
3094 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3095 nt_errstr(status)));
3096 goto err_out;
3099 *presult = result;
3100 return NT_STATUS_OK;
3102 err_out:
3103 TALLOC_FREE(result);
3104 return status;
3107 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3108 const struct ndr_syntax_id *interface,
3109 enum dcerpc_transport_t transport,
3110 enum dcerpc_AuthLevel auth_level,
3111 const char *server,
3112 const char *username,
3113 const char *password,
3114 struct rpc_pipe_client **presult)
3116 struct rpc_pipe_client *result;
3117 struct pipe_auth_data *auth;
3118 struct spnego_context *spnego_ctx;
3119 NTSTATUS status;
3121 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3122 if (!NT_STATUS_IS_OK(status)) {
3123 return status;
3126 auth = talloc(result, struct pipe_auth_data);
3127 if (auth == NULL) {
3128 status = NT_STATUS_NO_MEMORY;
3129 goto err_out;
3131 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3132 auth->auth_level = auth_level;
3134 if (!username) {
3135 username = "";
3137 auth->user_name = talloc_strdup(auth, username);
3138 if (!auth->user_name) {
3139 status = NT_STATUS_NO_MEMORY;
3140 goto err_out;
3143 /* Fixme, should we fetch/set the Realm ? */
3144 auth->domain = talloc_strdup(auth, "");
3145 if (!auth->domain) {
3146 status = NT_STATUS_NO_MEMORY;
3147 goto err_out;
3150 status = spnego_gssapi_init_client(auth,
3151 (auth->auth_level ==
3152 DCERPC_AUTH_LEVEL_INTEGRITY),
3153 (auth->auth_level ==
3154 DCERPC_AUTH_LEVEL_PRIVACY),
3155 true,
3156 NULL, server, "cifs",
3157 username, password,
3158 &spnego_ctx);
3159 if (!NT_STATUS_IS_OK(status)) {
3160 DEBUG(0, ("spnego_init_client returned %s\n",
3161 nt_errstr(status)));
3162 goto err_out;
3164 auth->auth_ctx = spnego_ctx;
3166 status = rpc_pipe_bind(result, auth);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3169 nt_errstr(status)));
3170 goto err_out;
3173 *presult = result;
3174 return NT_STATUS_OK;
3176 err_out:
3177 TALLOC_FREE(result);
3178 return status;
3181 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3182 const struct ndr_syntax_id *interface,
3183 enum dcerpc_transport_t transport,
3184 enum dcerpc_AuthLevel auth_level,
3185 const char *domain,
3186 const char *username,
3187 const char *password,
3188 struct rpc_pipe_client **presult)
3190 struct rpc_pipe_client *result;
3191 struct pipe_auth_data *auth;
3192 struct spnego_context *spnego_ctx;
3193 NTSTATUS status;
3195 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3196 if (!NT_STATUS_IS_OK(status)) {
3197 return status;
3200 auth = talloc(result, struct pipe_auth_data);
3201 if (auth == NULL) {
3202 status = NT_STATUS_NO_MEMORY;
3203 goto err_out;
3205 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3206 auth->auth_level = auth_level;
3208 if (!username) {
3209 username = "";
3211 auth->user_name = talloc_strdup(auth, username);
3212 if (!auth->user_name) {
3213 status = NT_STATUS_NO_MEMORY;
3214 goto err_out;
3217 if (!domain) {
3218 domain = "";
3220 auth->domain = talloc_strdup(auth, domain);
3221 if (!auth->domain) {
3222 status = NT_STATUS_NO_MEMORY;
3223 goto err_out;
3226 status = spnego_ntlmssp_init_client(auth,
3227 (auth->auth_level ==
3228 DCERPC_AUTH_LEVEL_INTEGRITY),
3229 (auth->auth_level ==
3230 DCERPC_AUTH_LEVEL_PRIVACY),
3231 true,
3232 domain, username, password,
3233 &spnego_ctx);
3234 if (!NT_STATUS_IS_OK(status)) {
3235 DEBUG(0, ("spnego_init_client returned %s\n",
3236 nt_errstr(status)));
3237 goto err_out;
3239 auth->auth_ctx = spnego_ctx;
3241 status = rpc_pipe_bind(result, auth);
3242 if (!NT_STATUS_IS_OK(status)) {
3243 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3244 nt_errstr(status)));
3245 goto err_out;
3248 *presult = result;
3249 return NT_STATUS_OK;
3251 err_out:
3252 TALLOC_FREE(result);
3253 return status;
3256 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3257 struct rpc_pipe_client *cli,
3258 DATA_BLOB *session_key)
3260 struct pipe_auth_data *a;
3261 struct schannel_state *schannel_auth;
3262 struct auth_ntlmssp_state *ntlmssp_ctx;
3263 struct spnego_context *spnego_ctx;
3264 struct gse_context *gse_ctx;
3265 DATA_BLOB sk = data_blob_null;
3266 bool make_dup = false;
3268 if (!session_key || !cli) {
3269 return NT_STATUS_INVALID_PARAMETER;
3272 a = cli->auth;
3274 if (a == NULL) {
3275 return NT_STATUS_INVALID_PARAMETER;
3278 switch (cli->auth->auth_type) {
3279 case DCERPC_AUTH_TYPE_SCHANNEL:
3280 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3281 struct schannel_state);
3282 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3283 make_dup = true;
3284 break;
3285 case DCERPC_AUTH_TYPE_SPNEGO:
3286 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3287 struct spnego_context);
3288 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3289 make_dup = false;
3290 break;
3291 case DCERPC_AUTH_TYPE_NTLMSSP:
3292 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
3293 struct auth_ntlmssp_state);
3294 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx);
3295 make_dup = true;
3296 break;
3297 case DCERPC_AUTH_TYPE_KRB5:
3298 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3299 struct gse_context);
3300 sk = gse_get_session_key(mem_ctx, gse_ctx);
3301 make_dup = false;
3302 break;
3303 case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
3304 case DCERPC_AUTH_TYPE_NONE:
3305 sk = data_blob_const(a->user_session_key.data,
3306 a->user_session_key.length);
3307 make_dup = true;
3308 break;
3309 default:
3310 break;
3313 if (!sk.data) {
3314 return NT_STATUS_NO_USER_SESSION_KEY;
3317 if (make_dup) {
3318 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3319 } else {
3320 *session_key = sk;
3323 return NT_STATUS_OK;