s3: Remove unused args from nss_get_info_cached
[Samba.git] / source3 / rpc_client / cli_pipe.c
blobaac47f34a83e5dcddbfa0be99679ad70d5f7b76d
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_NONE:
1198 break;
1200 default:
1201 /* "Can't" happen. */
1202 return NT_STATUS_INVALID_INFO_CLASS;
1205 if (auth_token.length != 0) {
1206 ret = dcerpc_push_dcerpc_auth(cli,
1207 auth->auth_type,
1208 auth->auth_level,
1209 0, /* auth_pad_length */
1210 1, /* auth_context_id */
1211 &auth_token,
1212 &auth_info);
1213 if (!NT_STATUS_IS_OK(ret)) {
1214 return ret;
1216 data_blob_free(&auth_token);
1219 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1220 DCERPC_PKT_BIND,
1221 rpc_call_id,
1222 abstract,
1223 transfer,
1224 &auth_info,
1225 rpc_out);
1226 return ret;
1229 /*******************************************************************
1230 External interface.
1231 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1232 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1233 and deals with signing/sealing details.
1234 ********************************************************************/
1236 struct rpc_api_pipe_req_state {
1237 struct event_context *ev;
1238 struct rpc_pipe_client *cli;
1239 uint8_t op_num;
1240 uint32_t call_id;
1241 DATA_BLOB *req_data;
1242 uint32_t req_data_sent;
1243 DATA_BLOB rpc_out;
1244 DATA_BLOB reply_pdu;
1247 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1248 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1249 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1250 bool *is_last_frag);
1252 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1253 struct event_context *ev,
1254 struct rpc_pipe_client *cli,
1255 uint8_t op_num,
1256 DATA_BLOB *req_data)
1258 struct tevent_req *req, *subreq;
1259 struct rpc_api_pipe_req_state *state;
1260 NTSTATUS status;
1261 bool is_last_frag;
1263 req = tevent_req_create(mem_ctx, &state,
1264 struct rpc_api_pipe_req_state);
1265 if (req == NULL) {
1266 return NULL;
1268 state->ev = ev;
1269 state->cli = cli;
1270 state->op_num = op_num;
1271 state->req_data = req_data;
1272 state->req_data_sent = 0;
1273 state->call_id = get_rpc_call_id();
1274 state->reply_pdu = data_blob_null;
1275 state->rpc_out = data_blob_null;
1277 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1278 + RPC_MAX_SIGN_SIZE) {
1279 /* Server is screwed up ! */
1280 status = NT_STATUS_INVALID_PARAMETER;
1281 goto post_status;
1284 status = prepare_next_frag(state, &is_last_frag);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 goto post_status;
1289 if (is_last_frag) {
1290 subreq = rpc_api_pipe_send(state, ev, state->cli,
1291 &state->rpc_out,
1292 DCERPC_PKT_RESPONSE);
1293 if (subreq == NULL) {
1294 goto fail;
1296 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1297 } else {
1298 subreq = rpc_write_send(state, ev, cli->transport,
1299 state->rpc_out.data,
1300 state->rpc_out.length);
1301 if (subreq == NULL) {
1302 goto fail;
1304 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1305 req);
1307 return req;
1309 post_status:
1310 tevent_req_nterror(req, status);
1311 return tevent_req_post(req, ev);
1312 fail:
1313 TALLOC_FREE(req);
1314 return NULL;
1317 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1318 bool *is_last_frag)
1320 size_t data_sent_thistime;
1321 size_t auth_len;
1322 size_t frag_len;
1323 uint8_t flags = 0;
1324 size_t pad_len;
1325 size_t data_left;
1326 NTSTATUS status;
1327 union dcerpc_payload u;
1329 data_left = state->req_data->length - state->req_data_sent;
1331 status = dcerpc_guess_sizes(state->cli->auth,
1332 DCERPC_REQUEST_LENGTH, data_left,
1333 state->cli->max_xmit_frag,
1334 CLIENT_NDR_PADDING_SIZE,
1335 &data_sent_thistime,
1336 &frag_len, &auth_len, &pad_len);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 return status;
1341 if (state->req_data_sent == 0) {
1342 flags = DCERPC_PFC_FLAG_FIRST;
1345 if (data_sent_thistime == data_left) {
1346 flags |= DCERPC_PFC_FLAG_LAST;
1349 data_blob_free(&state->rpc_out);
1351 ZERO_STRUCT(u.request);
1353 u.request.alloc_hint = state->req_data->length;
1354 u.request.context_id = 0;
1355 u.request.opnum = state->op_num;
1357 status = dcerpc_push_ncacn_packet(state,
1358 DCERPC_PKT_REQUEST,
1359 flags,
1360 auth_len,
1361 state->call_id,
1363 &state->rpc_out);
1364 if (!NT_STATUS_IS_OK(status)) {
1365 return status;
1368 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1369 * compute it right for requests because the auth trailer is missing
1370 * at this stage */
1371 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1373 /* Copy in the data. */
1374 if (!data_blob_append(NULL, &state->rpc_out,
1375 state->req_data->data + state->req_data_sent,
1376 data_sent_thistime)) {
1377 return NT_STATUS_NO_MEMORY;
1380 switch (state->cli->auth->auth_level) {
1381 case DCERPC_AUTH_LEVEL_NONE:
1382 case DCERPC_AUTH_LEVEL_CONNECT:
1383 case DCERPC_AUTH_LEVEL_PACKET:
1384 break;
1385 case DCERPC_AUTH_LEVEL_INTEGRITY:
1386 case DCERPC_AUTH_LEVEL_PRIVACY:
1387 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1388 &state->rpc_out);
1389 if (!NT_STATUS_IS_OK(status)) {
1390 return status;
1392 break;
1393 default:
1394 return NT_STATUS_INVALID_PARAMETER;
1397 state->req_data_sent += data_sent_thistime;
1398 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1400 return status;
1403 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1405 struct tevent_req *req = tevent_req_callback_data(
1406 subreq, struct tevent_req);
1407 struct rpc_api_pipe_req_state *state = tevent_req_data(
1408 req, struct rpc_api_pipe_req_state);
1409 NTSTATUS status;
1410 bool is_last_frag;
1412 status = rpc_write_recv(subreq);
1413 TALLOC_FREE(subreq);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 tevent_req_nterror(req, status);
1416 return;
1419 status = prepare_next_frag(state, &is_last_frag);
1420 if (!NT_STATUS_IS_OK(status)) {
1421 tevent_req_nterror(req, status);
1422 return;
1425 if (is_last_frag) {
1426 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1427 &state->rpc_out,
1428 DCERPC_PKT_RESPONSE);
1429 if (tevent_req_nomem(subreq, req)) {
1430 return;
1432 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1433 } else {
1434 subreq = rpc_write_send(state, state->ev,
1435 state->cli->transport,
1436 state->rpc_out.data,
1437 state->rpc_out.length);
1438 if (tevent_req_nomem(subreq, req)) {
1439 return;
1441 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1442 req);
1446 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1448 struct tevent_req *req = tevent_req_callback_data(
1449 subreq, struct tevent_req);
1450 struct rpc_api_pipe_req_state *state = tevent_req_data(
1451 req, struct rpc_api_pipe_req_state);
1452 NTSTATUS status;
1454 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1455 TALLOC_FREE(subreq);
1456 if (!NT_STATUS_IS_OK(status)) {
1457 tevent_req_nterror(req, status);
1458 return;
1460 tevent_req_done(req);
1463 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1464 DATA_BLOB *reply_pdu)
1466 struct rpc_api_pipe_req_state *state = tevent_req_data(
1467 req, struct rpc_api_pipe_req_state);
1468 NTSTATUS status;
1470 if (tevent_req_is_nterror(req, &status)) {
1472 * We always have to initialize to reply pdu, even if there is
1473 * none. The rpccli_* caller routines expect this.
1475 *reply_pdu = data_blob_null;
1476 return status;
1479 /* return data to caller and assign it ownership of memory */
1480 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1481 reply_pdu->length = state->reply_pdu.length;
1482 state->reply_pdu.length = 0;
1484 return NT_STATUS_OK;
1487 /****************************************************************************
1488 Check the rpc bind acknowledge response.
1489 ****************************************************************************/
1491 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1492 const struct ndr_syntax_id *transfer)
1494 struct dcerpc_ack_ctx ctx;
1496 if (r->secondary_address_size == 0) {
1497 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1500 if (r->num_results < 1 || !r->ctx_list) {
1501 return false;
1504 ctx = r->ctx_list[0];
1506 /* check the transfer syntax */
1507 if ((ctx.syntax.if_version != transfer->if_version) ||
1508 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1509 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1510 return False;
1513 if (r->num_results != 0x1 || ctx.result != 0) {
1514 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1515 r->num_results, ctx.reason));
1518 DEBUG(5,("check_bind_response: accepted!\n"));
1519 return True;
1522 /*******************************************************************
1523 Creates a DCE/RPC bind authentication response.
1524 This is the packet that is sent back to the server once we
1525 have received a BIND-ACK, to finish the third leg of
1526 the authentication handshake.
1527 ********************************************************************/
1529 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1530 struct rpc_pipe_client *cli,
1531 uint32 rpc_call_id,
1532 enum dcerpc_AuthType auth_type,
1533 enum dcerpc_AuthLevel auth_level,
1534 DATA_BLOB *pauth_blob,
1535 DATA_BLOB *rpc_out)
1537 NTSTATUS status;
1538 union dcerpc_payload u;
1540 u.auth3._pad = 0;
1542 status = dcerpc_push_dcerpc_auth(mem_ctx,
1543 auth_type,
1544 auth_level,
1545 0, /* auth_pad_length */
1546 1, /* auth_context_id */
1547 pauth_blob,
1548 &u.auth3.auth_info);
1549 if (!NT_STATUS_IS_OK(status)) {
1550 return status;
1553 status = dcerpc_push_ncacn_packet(mem_ctx,
1554 DCERPC_PKT_AUTH3,
1555 DCERPC_PFC_FLAG_FIRST |
1556 DCERPC_PFC_FLAG_LAST,
1557 pauth_blob->length,
1558 rpc_call_id,
1560 rpc_out);
1561 data_blob_free(&u.auth3.auth_info);
1562 if (!NT_STATUS_IS_OK(status)) {
1563 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1564 return status;
1567 return NT_STATUS_OK;
1570 /*******************************************************************
1571 Creates a DCE/RPC bind alter context authentication request which
1572 may contain a spnego auth blobl
1573 ********************************************************************/
1575 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1576 enum dcerpc_AuthType auth_type,
1577 enum dcerpc_AuthLevel auth_level,
1578 uint32 rpc_call_id,
1579 const struct ndr_syntax_id *abstract,
1580 const struct ndr_syntax_id *transfer,
1581 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1582 DATA_BLOB *rpc_out)
1584 DATA_BLOB auth_info;
1585 NTSTATUS status;
1587 status = dcerpc_push_dcerpc_auth(mem_ctx,
1588 auth_type,
1589 auth_level,
1590 0, /* auth_pad_length */
1591 1, /* auth_context_id */
1592 pauth_blob,
1593 &auth_info);
1594 if (!NT_STATUS_IS_OK(status)) {
1595 return status;
1598 status = create_bind_or_alt_ctx_internal(mem_ctx,
1599 DCERPC_PKT_ALTER,
1600 rpc_call_id,
1601 abstract,
1602 transfer,
1603 &auth_info,
1604 rpc_out);
1605 data_blob_free(&auth_info);
1606 return status;
1609 /****************************************************************************
1610 Do an rpc bind.
1611 ****************************************************************************/
1613 struct rpc_pipe_bind_state {
1614 struct event_context *ev;
1615 struct rpc_pipe_client *cli;
1616 DATA_BLOB rpc_out;
1617 bool auth3;
1618 uint32_t rpc_call_id;
1621 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1622 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1623 struct rpc_pipe_bind_state *state,
1624 DATA_BLOB *credentials);
1625 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1626 struct rpc_pipe_bind_state *state,
1627 DATA_BLOB *credentials);
1629 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1630 struct event_context *ev,
1631 struct rpc_pipe_client *cli,
1632 struct pipe_auth_data *auth)
1634 struct tevent_req *req, *subreq;
1635 struct rpc_pipe_bind_state *state;
1636 NTSTATUS status;
1638 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1639 if (req == NULL) {
1640 return NULL;
1643 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1644 rpccli_pipe_txt(talloc_tos(), cli),
1645 (unsigned int)auth->auth_type,
1646 (unsigned int)auth->auth_level ));
1648 state->ev = ev;
1649 state->cli = cli;
1650 state->rpc_call_id = get_rpc_call_id();
1652 cli->auth = talloc_move(cli, &auth);
1654 /* Marshall the outgoing data. */
1655 status = create_rpc_bind_req(state, cli,
1656 cli->auth,
1657 state->rpc_call_id,
1658 &cli->abstract_syntax,
1659 &cli->transfer_syntax,
1660 &state->rpc_out);
1662 if (!NT_STATUS_IS_OK(status)) {
1663 goto post_status;
1666 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1667 DCERPC_PKT_BIND_ACK);
1668 if (subreq == NULL) {
1669 goto fail;
1671 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1672 return req;
1674 post_status:
1675 tevent_req_nterror(req, status);
1676 return tevent_req_post(req, ev);
1677 fail:
1678 TALLOC_FREE(req);
1679 return NULL;
1682 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1684 struct tevent_req *req = tevent_req_callback_data(
1685 subreq, struct tevent_req);
1686 struct rpc_pipe_bind_state *state = tevent_req_data(
1687 req, struct rpc_pipe_bind_state);
1688 struct pipe_auth_data *pauth = state->cli->auth;
1689 struct auth_ntlmssp_state *ntlmssp_ctx;
1690 struct spnego_context *spnego_ctx;
1691 struct gse_context *gse_ctx;
1692 struct ncacn_packet *pkt = NULL;
1693 struct dcerpc_auth auth;
1694 DATA_BLOB auth_token = data_blob_null;
1695 NTSTATUS status;
1697 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1698 TALLOC_FREE(subreq);
1699 if (!NT_STATUS_IS_OK(status)) {
1700 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1701 rpccli_pipe_txt(talloc_tos(), state->cli),
1702 nt_errstr(status)));
1703 tevent_req_nterror(req, status);
1704 return;
1707 if (state->auth3) {
1708 tevent_req_done(req);
1709 return;
1712 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1713 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1714 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1715 return;
1718 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1719 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1721 switch(pauth->auth_type) {
1723 case DCERPC_AUTH_TYPE_NONE:
1724 case DCERPC_AUTH_TYPE_SCHANNEL:
1725 /* Bind complete. */
1726 tevent_req_done(req);
1727 return;
1729 case DCERPC_AUTH_TYPE_NTLMSSP:
1730 case DCERPC_AUTH_TYPE_SPNEGO:
1731 case DCERPC_AUTH_TYPE_KRB5:
1732 /* Paranoid lenght checks */
1733 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1734 + pkt->auth_length) {
1735 tevent_req_nterror(req,
1736 NT_STATUS_INFO_LENGTH_MISMATCH);
1737 return;
1739 /* get auth credentials */
1740 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1741 &pkt->u.bind_ack.auth_info,
1742 &auth, false);
1743 if (!NT_STATUS_IS_OK(status)) {
1744 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1745 nt_errstr(status)));
1746 tevent_req_nterror(req, status);
1747 return;
1749 break;
1751 default:
1752 goto err_out;
1756 * For authenticated binds we may need to do 3 or 4 leg binds.
1759 switch(pauth->auth_type) {
1761 case DCERPC_AUTH_TYPE_NONE:
1762 case DCERPC_AUTH_TYPE_SCHANNEL:
1763 /* Bind complete. */
1764 tevent_req_done(req);
1765 return;
1767 case DCERPC_AUTH_TYPE_NTLMSSP:
1768 ntlmssp_ctx = talloc_get_type_abort(pauth->auth_ctx,
1769 struct auth_ntlmssp_state);
1770 status = auth_ntlmssp_update(ntlmssp_ctx,
1771 auth.credentials, &auth_token);
1772 if (NT_STATUS_EQUAL(status,
1773 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1774 status = rpc_bind_next_send(req, state,
1775 &auth_token);
1776 } else if (NT_STATUS_IS_OK(status)) {
1777 status = rpc_bind_finish_send(req, state,
1778 &auth_token);
1780 break;
1782 case DCERPC_AUTH_TYPE_SPNEGO:
1783 spnego_ctx = talloc_get_type_abort(pauth->auth_ctx,
1784 struct spnego_context);
1785 status = spnego_get_client_auth_token(state,
1786 spnego_ctx,
1787 &auth.credentials,
1788 &auth_token);
1789 if (!NT_STATUS_IS_OK(status)) {
1790 break;
1792 if (auth_token.length == 0) {
1793 /* Bind complete. */
1794 tevent_req_done(req);
1795 return;
1797 if (spnego_require_more_processing(spnego_ctx)) {
1798 status = rpc_bind_next_send(req, state,
1799 &auth_token);
1800 } else {
1801 status = rpc_bind_finish_send(req, state,
1802 &auth_token);
1804 break;
1806 case DCERPC_AUTH_TYPE_KRB5:
1807 gse_ctx = talloc_get_type_abort(pauth->auth_ctx,
1808 struct gse_context);
1809 status = gse_get_client_auth_token(state,
1810 gse_ctx,
1811 &auth.credentials,
1812 &auth_token);
1813 if (!NT_STATUS_IS_OK(status)) {
1814 break;
1817 if (gse_require_more_processing(gse_ctx)) {
1818 status = rpc_bind_next_send(req, state, &auth_token);
1819 } else {
1820 status = rpc_bind_finish_send(req, state, &auth_token);
1822 break;
1824 default:
1825 goto err_out;
1828 if (!NT_STATUS_IS_OK(status)) {
1829 tevent_req_nterror(req, status);
1831 return;
1833 err_out:
1834 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n",
1835 (unsigned int)state->cli->auth->auth_type));
1836 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1839 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1840 struct rpc_pipe_bind_state *state,
1841 DATA_BLOB *auth_token)
1843 struct pipe_auth_data *auth = state->cli->auth;
1844 struct tevent_req *subreq;
1845 NTSTATUS status;
1847 /* Now prepare the alter context pdu. */
1848 data_blob_free(&state->rpc_out);
1850 status = create_rpc_alter_context(state,
1851 auth->auth_type,
1852 auth->auth_level,
1853 state->rpc_call_id,
1854 &state->cli->abstract_syntax,
1855 &state->cli->transfer_syntax,
1856 auth_token,
1857 &state->rpc_out);
1858 if (!NT_STATUS_IS_OK(status)) {
1859 return status;
1862 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1863 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
1864 if (subreq == NULL) {
1865 return NT_STATUS_NO_MEMORY;
1867 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1868 return NT_STATUS_OK;
1871 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1872 struct rpc_pipe_bind_state *state,
1873 DATA_BLOB *auth_token)
1875 struct pipe_auth_data *auth = state->cli->auth;
1876 struct tevent_req *subreq;
1877 NTSTATUS status;
1879 state->auth3 = true;
1881 /* Now prepare the auth3 context pdu. */
1882 data_blob_free(&state->rpc_out);
1884 status = create_rpc_bind_auth3(state, state->cli,
1885 state->rpc_call_id,
1886 auth->auth_type,
1887 auth->auth_level,
1888 auth_token,
1889 &state->rpc_out);
1890 if (!NT_STATUS_IS_OK(status)) {
1891 return status;
1894 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1895 &state->rpc_out, DCERPC_PKT_AUTH3);
1896 if (subreq == NULL) {
1897 return NT_STATUS_NO_MEMORY;
1899 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1900 return NT_STATUS_OK;
1903 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
1905 return tevent_req_simple_recv_ntstatus(req);
1908 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
1909 struct pipe_auth_data *auth)
1911 TALLOC_CTX *frame = talloc_stackframe();
1912 struct event_context *ev;
1913 struct tevent_req *req;
1914 NTSTATUS status = NT_STATUS_OK;
1916 ev = event_context_init(frame);
1917 if (ev == NULL) {
1918 status = NT_STATUS_NO_MEMORY;
1919 goto fail;
1922 req = rpc_pipe_bind_send(frame, ev, cli, auth);
1923 if (req == NULL) {
1924 status = NT_STATUS_NO_MEMORY;
1925 goto fail;
1928 if (!tevent_req_poll(req, ev)) {
1929 status = map_nt_error_from_unix(errno);
1930 goto fail;
1933 status = rpc_pipe_bind_recv(req);
1934 fail:
1935 TALLOC_FREE(frame);
1936 return status;
1939 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
1941 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
1942 unsigned int timeout)
1944 unsigned int old;
1946 if (rpc_cli->transport == NULL) {
1947 return RPCCLI_DEFAULT_TIMEOUT;
1950 if (rpc_cli->transport->set_timeout == NULL) {
1951 return RPCCLI_DEFAULT_TIMEOUT;
1954 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
1955 if (old == 0) {
1956 return RPCCLI_DEFAULT_TIMEOUT;
1959 return old;
1962 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
1964 if (rpc_cli == NULL) {
1965 return false;
1968 if (rpc_cli->transport == NULL) {
1969 return false;
1972 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
1975 struct rpccli_bh_state {
1976 struct rpc_pipe_client *rpc_cli;
1979 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
1981 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1982 struct rpccli_bh_state);
1984 return rpccli_is_connected(hs->rpc_cli);
1987 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
1988 uint32_t timeout)
1990 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
1991 struct rpccli_bh_state);
1993 return rpccli_set_timeout(hs->rpc_cli, timeout);
1996 struct rpccli_bh_raw_call_state {
1997 DATA_BLOB in_data;
1998 DATA_BLOB out_data;
1999 uint32_t out_flags;
2002 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2004 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2005 struct tevent_context *ev,
2006 struct dcerpc_binding_handle *h,
2007 const struct GUID *object,
2008 uint32_t opnum,
2009 uint32_t in_flags,
2010 const uint8_t *in_data,
2011 size_t in_length)
2013 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2014 struct rpccli_bh_state);
2015 struct tevent_req *req;
2016 struct rpccli_bh_raw_call_state *state;
2017 bool ok;
2018 struct tevent_req *subreq;
2020 req = tevent_req_create(mem_ctx, &state,
2021 struct rpccli_bh_raw_call_state);
2022 if (req == NULL) {
2023 return NULL;
2025 state->in_data.data = discard_const_p(uint8_t, in_data);
2026 state->in_data.length = in_length;
2028 ok = rpccli_bh_is_connected(h);
2029 if (!ok) {
2030 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2031 return tevent_req_post(req, ev);
2034 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2035 opnum, &state->in_data);
2036 if (tevent_req_nomem(subreq, req)) {
2037 return tevent_req_post(req, ev);
2039 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2041 return req;
2044 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2046 struct tevent_req *req =
2047 tevent_req_callback_data(subreq,
2048 struct tevent_req);
2049 struct rpccli_bh_raw_call_state *state =
2050 tevent_req_data(req,
2051 struct rpccli_bh_raw_call_state);
2052 NTSTATUS status;
2054 state->out_flags = 0;
2056 /* TODO: support bigendian responses */
2058 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2059 TALLOC_FREE(subreq);
2060 if (!NT_STATUS_IS_OK(status)) {
2061 tevent_req_nterror(req, status);
2062 return;
2065 tevent_req_done(req);
2068 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2069 TALLOC_CTX *mem_ctx,
2070 uint8_t **out_data,
2071 size_t *out_length,
2072 uint32_t *out_flags)
2074 struct rpccli_bh_raw_call_state *state =
2075 tevent_req_data(req,
2076 struct rpccli_bh_raw_call_state);
2077 NTSTATUS status;
2079 if (tevent_req_is_nterror(req, &status)) {
2080 tevent_req_received(req);
2081 return status;
2084 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2085 *out_length = state->out_data.length;
2086 *out_flags = state->out_flags;
2087 tevent_req_received(req);
2088 return NT_STATUS_OK;
2091 struct rpccli_bh_disconnect_state {
2092 uint8_t _dummy;
2095 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2096 struct tevent_context *ev,
2097 struct dcerpc_binding_handle *h)
2099 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2100 struct rpccli_bh_state);
2101 struct tevent_req *req;
2102 struct rpccli_bh_disconnect_state *state;
2103 bool ok;
2105 req = tevent_req_create(mem_ctx, &state,
2106 struct rpccli_bh_disconnect_state);
2107 if (req == NULL) {
2108 return NULL;
2111 ok = rpccli_bh_is_connected(h);
2112 if (!ok) {
2113 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION);
2114 return tevent_req_post(req, ev);
2118 * TODO: do a real async disconnect ...
2120 * For now the caller needs to free rpc_cli
2122 hs->rpc_cli = NULL;
2124 tevent_req_done(req);
2125 return tevent_req_post(req, ev);
2128 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2130 NTSTATUS status;
2132 if (tevent_req_is_nterror(req, &status)) {
2133 tevent_req_received(req);
2134 return status;
2137 tevent_req_received(req);
2138 return NT_STATUS_OK;
2141 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2143 return true;
2146 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2147 int ndr_flags,
2148 const void *_struct_ptr,
2149 const struct ndr_interface_call *call)
2151 void *struct_ptr = discard_const(_struct_ptr);
2153 if (DEBUGLEVEL < 10) {
2154 return;
2157 if (ndr_flags & NDR_IN) {
2158 ndr_print_function_debug(call->ndr_print,
2159 call->name,
2160 ndr_flags,
2161 struct_ptr);
2163 if (ndr_flags & NDR_OUT) {
2164 ndr_print_function_debug(call->ndr_print,
2165 call->name,
2166 ndr_flags,
2167 struct_ptr);
2171 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2172 .name = "rpccli",
2173 .is_connected = rpccli_bh_is_connected,
2174 .set_timeout = rpccli_bh_set_timeout,
2175 .raw_call_send = rpccli_bh_raw_call_send,
2176 .raw_call_recv = rpccli_bh_raw_call_recv,
2177 .disconnect_send = rpccli_bh_disconnect_send,
2178 .disconnect_recv = rpccli_bh_disconnect_recv,
2180 .ref_alloc = rpccli_bh_ref_alloc,
2181 .do_ndr_print = rpccli_bh_do_ndr_print,
2184 /* initialise a rpc_pipe_client binding handle */
2185 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c)
2187 struct dcerpc_binding_handle *h;
2188 struct rpccli_bh_state *hs;
2190 h = dcerpc_binding_handle_create(c,
2191 &rpccli_bh_ops,
2192 NULL,
2193 NULL, /* TODO */
2194 &hs,
2195 struct rpccli_bh_state,
2196 __location__);
2197 if (h == NULL) {
2198 return NULL;
2200 hs->rpc_cli = c;
2202 return h;
2205 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2207 struct auth_ntlmssp_state *a = NULL;
2208 struct cli_state *cli;
2210 if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP) {
2211 a = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2212 struct auth_ntlmssp_state);
2213 } else if (rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
2214 struct spnego_context *spnego_ctx;
2215 enum spnego_mech auth_type;
2216 void *auth_ctx;
2217 NTSTATUS status;
2219 spnego_ctx = talloc_get_type_abort(rpc_cli->auth->auth_ctx,
2220 struct spnego_context);
2221 status = spnego_get_negotiated_mech(spnego_ctx,
2222 &auth_type, &auth_ctx);
2223 if (!NT_STATUS_IS_OK(status)) {
2224 return false;
2227 if (auth_type == SPNEGO_NTLMSSP) {
2228 a = talloc_get_type_abort(auth_ctx,
2229 struct auth_ntlmssp_state);
2233 if (a) {
2234 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(a), 16);
2235 return true;
2238 cli = rpc_pipe_np_smb_conn(rpc_cli);
2239 if (cli == NULL) {
2240 return false;
2242 E_md4hash(cli->password ? cli->password : "", nt_hash);
2243 return true;
2246 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2247 struct pipe_auth_data **presult)
2249 struct pipe_auth_data *result;
2251 result = talloc(mem_ctx, struct pipe_auth_data);
2252 if (result == NULL) {
2253 return NT_STATUS_NO_MEMORY;
2256 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2257 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2259 result->user_name = talloc_strdup(result, "");
2260 result->domain = talloc_strdup(result, "");
2261 if ((result->user_name == NULL) || (result->domain == NULL)) {
2262 TALLOC_FREE(result);
2263 return NT_STATUS_NO_MEMORY;
2266 *presult = result;
2267 return NT_STATUS_OK;
2270 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2272 TALLOC_FREE(auth->auth_ctx);
2273 return 0;
2276 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2277 enum dcerpc_AuthType auth_type,
2278 enum dcerpc_AuthLevel auth_level,
2279 const char *domain,
2280 const char *username,
2281 const char *password,
2282 struct pipe_auth_data **presult)
2284 struct auth_ntlmssp_state *ntlmssp_ctx;
2285 struct pipe_auth_data *result;
2286 NTSTATUS status;
2288 result = talloc(mem_ctx, struct pipe_auth_data);
2289 if (result == NULL) {
2290 return NT_STATUS_NO_MEMORY;
2293 result->auth_type = auth_type;
2294 result->auth_level = auth_level;
2296 result->user_name = talloc_strdup(result, username);
2297 result->domain = talloc_strdup(result, domain);
2298 if ((result->user_name == NULL) || (result->domain == NULL)) {
2299 status = NT_STATUS_NO_MEMORY;
2300 goto fail;
2303 status = auth_ntlmssp_client_start(NULL,
2304 global_myname(),
2305 lp_workgroup(),
2306 lp_client_ntlmv2_auth(),
2307 &ntlmssp_ctx);
2308 if (!NT_STATUS_IS_OK(status)) {
2309 goto fail;
2312 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2314 status = auth_ntlmssp_set_username(ntlmssp_ctx, username);
2315 if (!NT_STATUS_IS_OK(status)) {
2316 goto fail;
2319 status = auth_ntlmssp_set_domain(ntlmssp_ctx, domain);
2320 if (!NT_STATUS_IS_OK(status)) {
2321 goto fail;
2324 status = auth_ntlmssp_set_password(ntlmssp_ctx, password);
2325 if (!NT_STATUS_IS_OK(status)) {
2326 goto fail;
2330 * Turn off sign+seal to allow selected auth level to turn it back on.
2332 auth_ntlmssp_and_flags(ntlmssp_ctx, ~(NTLMSSP_NEGOTIATE_SIGN |
2333 NTLMSSP_NEGOTIATE_SEAL));
2335 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2336 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SIGN);
2337 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2338 auth_ntlmssp_or_flags(ntlmssp_ctx, NTLMSSP_NEGOTIATE_SEAL |
2339 NTLMSSP_NEGOTIATE_SIGN);
2342 result->auth_ctx = ntlmssp_ctx;
2343 *presult = result;
2344 return NT_STATUS_OK;
2346 fail:
2347 TALLOC_FREE(result);
2348 return status;
2351 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2352 enum dcerpc_AuthLevel auth_level,
2353 struct netlogon_creds_CredentialState *creds,
2354 struct pipe_auth_data **presult)
2356 struct schannel_state *schannel_auth;
2357 struct pipe_auth_data *result;
2359 result = talloc(mem_ctx, struct pipe_auth_data);
2360 if (result == NULL) {
2361 return NT_STATUS_NO_MEMORY;
2364 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2365 result->auth_level = auth_level;
2367 result->user_name = talloc_strdup(result, "");
2368 result->domain = talloc_strdup(result, domain);
2369 if ((result->user_name == NULL) || (result->domain == NULL)) {
2370 goto fail;
2373 schannel_auth = talloc(result, struct schannel_state);
2374 if (schannel_auth == NULL) {
2375 goto fail;
2378 schannel_auth->state = SCHANNEL_STATE_START;
2379 schannel_auth->seq_num = 0;
2380 schannel_auth->initiator = true;
2381 schannel_auth->creds = netlogon_creds_copy(result, creds);
2383 result->auth_ctx = schannel_auth;
2384 *presult = result;
2385 return NT_STATUS_OK;
2387 fail:
2388 TALLOC_FREE(result);
2389 return NT_STATUS_NO_MEMORY;
2393 * Create an rpc pipe client struct, connecting to a tcp port.
2395 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2396 uint16_t port,
2397 const struct ndr_syntax_id *abstract_syntax,
2398 struct rpc_pipe_client **presult)
2400 struct rpc_pipe_client *result;
2401 struct sockaddr_storage addr;
2402 NTSTATUS status;
2403 int fd;
2405 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2406 if (result == NULL) {
2407 return NT_STATUS_NO_MEMORY;
2410 result->abstract_syntax = *abstract_syntax;
2411 result->transfer_syntax = ndr_transfer_syntax;
2413 result->desthost = talloc_strdup(result, host);
2414 result->srv_name_slash = talloc_asprintf_strupper_m(
2415 result, "\\\\%s", result->desthost);
2416 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2417 status = NT_STATUS_NO_MEMORY;
2418 goto fail;
2421 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2422 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2424 if (!resolve_name(host, &addr, 0, false)) {
2425 status = NT_STATUS_NOT_FOUND;
2426 goto fail;
2429 status = open_socket_out(&addr, port, 60, &fd);
2430 if (!NT_STATUS_IS_OK(status)) {
2431 goto fail;
2433 set_socket_options(fd, lp_socket_options());
2435 status = rpc_transport_sock_init(result, fd, &result->transport);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 close(fd);
2438 goto fail;
2441 result->transport->transport = NCACN_IP_TCP;
2443 result->binding_handle = rpccli_bh_create(result);
2444 if (result->binding_handle == NULL) {
2445 TALLOC_FREE(result);
2446 return NT_STATUS_NO_MEMORY;
2449 *presult = result;
2450 return NT_STATUS_OK;
2452 fail:
2453 TALLOC_FREE(result);
2454 return status;
2458 * Determine the tcp port on which a dcerpc interface is listening
2459 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2460 * target host.
2462 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2463 const struct ndr_syntax_id *abstract_syntax,
2464 uint16_t *pport)
2466 NTSTATUS status;
2467 struct rpc_pipe_client *epm_pipe = NULL;
2468 struct dcerpc_binding_handle *epm_handle = NULL;
2469 struct pipe_auth_data *auth = NULL;
2470 struct dcerpc_binding *map_binding = NULL;
2471 struct dcerpc_binding *res_binding = NULL;
2472 struct epm_twr_t *map_tower = NULL;
2473 struct epm_twr_t *res_towers = NULL;
2474 struct policy_handle *entry_handle = NULL;
2475 uint32_t num_towers = 0;
2476 uint32_t max_towers = 1;
2477 struct epm_twr_p_t towers;
2478 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2479 uint32_t result = 0;
2481 if (pport == NULL) {
2482 status = NT_STATUS_INVALID_PARAMETER;
2483 goto done;
2486 /* open the connection to the endpoint mapper */
2487 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2488 &ndr_table_epmapper.syntax_id,
2489 &epm_pipe);
2491 if (!NT_STATUS_IS_OK(status)) {
2492 goto done;
2494 epm_handle = epm_pipe->binding_handle;
2496 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2497 if (!NT_STATUS_IS_OK(status)) {
2498 goto done;
2501 status = rpc_pipe_bind(epm_pipe, auth);
2502 if (!NT_STATUS_IS_OK(status)) {
2503 goto done;
2506 /* create tower for asking the epmapper */
2508 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2509 if (map_binding == NULL) {
2510 status = NT_STATUS_NO_MEMORY;
2511 goto done;
2514 map_binding->transport = NCACN_IP_TCP;
2515 map_binding->object = *abstract_syntax;
2516 map_binding->host = host; /* needed? */
2517 map_binding->endpoint = "0"; /* correct? needed? */
2519 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2520 if (map_tower == NULL) {
2521 status = NT_STATUS_NO_MEMORY;
2522 goto done;
2525 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2526 &(map_tower->tower));
2527 if (!NT_STATUS_IS_OK(status)) {
2528 goto done;
2531 /* allocate further parameters for the epm_Map call */
2533 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2534 if (res_towers == NULL) {
2535 status = NT_STATUS_NO_MEMORY;
2536 goto done;
2538 towers.twr = res_towers;
2540 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2541 if (entry_handle == NULL) {
2542 status = NT_STATUS_NO_MEMORY;
2543 goto done;
2546 /* ask the endpoint mapper for the port */
2548 status = dcerpc_epm_Map(epm_handle,
2549 tmp_ctx,
2550 CONST_DISCARD(struct GUID *,
2551 &(abstract_syntax->uuid)),
2552 map_tower,
2553 entry_handle,
2554 max_towers,
2555 &num_towers,
2556 &towers,
2557 &result);
2559 if (!NT_STATUS_IS_OK(status)) {
2560 goto done;
2563 if (result != EPMAPPER_STATUS_OK) {
2564 status = NT_STATUS_UNSUCCESSFUL;
2565 goto done;
2568 if (num_towers != 1) {
2569 status = NT_STATUS_UNSUCCESSFUL;
2570 goto done;
2573 /* extract the port from the answer */
2575 status = dcerpc_binding_from_tower(tmp_ctx,
2576 &(towers.twr->tower),
2577 &res_binding);
2578 if (!NT_STATUS_IS_OK(status)) {
2579 goto done;
2582 /* are further checks here necessary? */
2583 if (res_binding->transport != NCACN_IP_TCP) {
2584 status = NT_STATUS_UNSUCCESSFUL;
2585 goto done;
2588 *pport = (uint16_t)atoi(res_binding->endpoint);
2590 done:
2591 TALLOC_FREE(tmp_ctx);
2592 return status;
2596 * Create a rpc pipe client struct, connecting to a host via tcp.
2597 * The port is determined by asking the endpoint mapper on the given
2598 * host.
2600 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2601 const struct ndr_syntax_id *abstract_syntax,
2602 struct rpc_pipe_client **presult)
2604 NTSTATUS status;
2605 uint16_t port = 0;
2607 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2608 if (!NT_STATUS_IS_OK(status)) {
2609 return status;
2612 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2613 abstract_syntax, presult);
2616 /********************************************************************
2617 Create a rpc pipe client struct, connecting to a unix domain socket
2618 ********************************************************************/
2619 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2620 const struct ndr_syntax_id *abstract_syntax,
2621 struct rpc_pipe_client **presult)
2623 struct rpc_pipe_client *result;
2624 struct sockaddr_un addr;
2625 NTSTATUS status;
2626 int fd;
2628 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2629 if (result == NULL) {
2630 return NT_STATUS_NO_MEMORY;
2633 result->abstract_syntax = *abstract_syntax;
2634 result->transfer_syntax = ndr_transfer_syntax;
2636 result->desthost = get_myname(result);
2637 result->srv_name_slash = talloc_asprintf_strupper_m(
2638 result, "\\\\%s", result->desthost);
2639 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2640 status = NT_STATUS_NO_MEMORY;
2641 goto fail;
2644 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2645 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2647 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2648 if (fd == -1) {
2649 status = map_nt_error_from_unix(errno);
2650 goto fail;
2653 ZERO_STRUCT(addr);
2654 addr.sun_family = AF_UNIX;
2655 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2657 if (sys_connect(fd, (struct sockaddr *)(void *)&addr) == -1) {
2658 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2659 strerror(errno)));
2660 close(fd);
2661 return map_nt_error_from_unix(errno);
2664 status = rpc_transport_sock_init(result, fd, &result->transport);
2665 if (!NT_STATUS_IS_OK(status)) {
2666 close(fd);
2667 goto fail;
2670 result->transport->transport = NCALRPC;
2672 result->binding_handle = rpccli_bh_create(result);
2673 if (result->binding_handle == NULL) {
2674 TALLOC_FREE(result);
2675 return NT_STATUS_NO_MEMORY;
2678 *presult = result;
2679 return NT_STATUS_OK;
2681 fail:
2682 TALLOC_FREE(result);
2683 return status;
2686 struct rpc_pipe_client_np_ref {
2687 struct cli_state *cli;
2688 struct rpc_pipe_client *pipe;
2691 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2693 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2694 return 0;
2697 /****************************************************************************
2698 Open a named pipe over SMB to a remote server.
2700 * CAVEAT CALLER OF THIS FUNCTION:
2701 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2702 * so be sure that this function is called AFTER any structure (vs pointer)
2703 * assignment of the cli. In particular, libsmbclient does structure
2704 * assignments of cli, which invalidates the data in the returned
2705 * rpc_pipe_client if this function is called before the structure assignment
2706 * of cli.
2708 ****************************************************************************/
2710 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2711 const struct ndr_syntax_id *abstract_syntax,
2712 struct rpc_pipe_client **presult)
2714 struct rpc_pipe_client *result;
2715 NTSTATUS status;
2716 struct rpc_pipe_client_np_ref *np_ref;
2718 /* sanity check to protect against crashes */
2720 if ( !cli ) {
2721 return NT_STATUS_INVALID_HANDLE;
2724 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2725 if (result == NULL) {
2726 return NT_STATUS_NO_MEMORY;
2729 result->abstract_syntax = *abstract_syntax;
2730 result->transfer_syntax = ndr_transfer_syntax;
2731 result->desthost = talloc_strdup(result, cli->desthost);
2732 result->srv_name_slash = talloc_asprintf_strupper_m(
2733 result, "\\\\%s", result->desthost);
2735 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2736 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2738 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2739 TALLOC_FREE(result);
2740 return NT_STATUS_NO_MEMORY;
2743 status = rpc_transport_np_init(result, cli, abstract_syntax,
2744 &result->transport);
2745 if (!NT_STATUS_IS_OK(status)) {
2746 TALLOC_FREE(result);
2747 return status;
2750 result->transport->transport = NCACN_NP;
2752 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2753 if (np_ref == NULL) {
2754 TALLOC_FREE(result);
2755 return NT_STATUS_NO_MEMORY;
2757 np_ref->cli = cli;
2758 np_ref->pipe = result;
2760 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2761 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2763 result->binding_handle = rpccli_bh_create(result);
2764 if (result->binding_handle == NULL) {
2765 TALLOC_FREE(result);
2766 return NT_STATUS_NO_MEMORY;
2769 *presult = result;
2770 return NT_STATUS_OK;
2773 /****************************************************************************
2774 Open a pipe to a remote server.
2775 ****************************************************************************/
2777 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2778 enum dcerpc_transport_t transport,
2779 const struct ndr_syntax_id *interface,
2780 struct rpc_pipe_client **presult)
2782 switch (transport) {
2783 case NCACN_IP_TCP:
2784 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2785 presult);
2786 case NCACN_NP:
2787 return rpc_pipe_open_np(cli, interface, presult);
2788 default:
2789 return NT_STATUS_NOT_IMPLEMENTED;
2793 /****************************************************************************
2794 Open a named pipe to an SMB server and bind anonymously.
2795 ****************************************************************************/
2797 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2798 enum dcerpc_transport_t transport,
2799 const struct ndr_syntax_id *interface,
2800 struct rpc_pipe_client **presult)
2802 struct rpc_pipe_client *result;
2803 struct pipe_auth_data *auth;
2804 NTSTATUS status;
2806 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2807 if (!NT_STATUS_IS_OK(status)) {
2808 return status;
2811 status = rpccli_anon_bind_data(result, &auth);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2814 nt_errstr(status)));
2815 TALLOC_FREE(result);
2816 return status;
2820 * This is a bit of an abstraction violation due to the fact that an
2821 * anonymous bind on an authenticated SMB inherits the user/domain
2822 * from the enclosing SMB creds
2825 TALLOC_FREE(auth->user_name);
2826 TALLOC_FREE(auth->domain);
2828 auth->user_name = talloc_strdup(auth, cli->user_name);
2829 auth->domain = talloc_strdup(auth, cli->domain);
2830 auth->user_session_key = data_blob_talloc(auth,
2831 cli->user_session_key.data,
2832 cli->user_session_key.length);
2834 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2835 TALLOC_FREE(result);
2836 return NT_STATUS_NO_MEMORY;
2839 status = rpc_pipe_bind(result, auth);
2840 if (!NT_STATUS_IS_OK(status)) {
2841 int lvl = 0;
2842 if (ndr_syntax_id_equal(interface,
2843 &ndr_table_dssetup.syntax_id)) {
2844 /* non AD domains just don't have this pipe, avoid
2845 * level 0 statement in that case - gd */
2846 lvl = 3;
2848 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2849 "%s failed with error %s\n",
2850 get_pipe_name_from_syntax(talloc_tos(), interface),
2851 nt_errstr(status) ));
2852 TALLOC_FREE(result);
2853 return status;
2856 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2857 "%s and bound anonymously.\n",
2858 get_pipe_name_from_syntax(talloc_tos(), interface),
2859 cli->desthost));
2861 *presult = result;
2862 return NT_STATUS_OK;
2865 /****************************************************************************
2866 ****************************************************************************/
2868 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2869 const struct ndr_syntax_id *interface,
2870 struct rpc_pipe_client **presult)
2872 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2873 interface, presult);
2876 /****************************************************************************
2877 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2878 ****************************************************************************/
2880 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
2881 const struct ndr_syntax_id *interface,
2882 enum dcerpc_transport_t transport,
2883 enum dcerpc_AuthLevel auth_level,
2884 const char *domain,
2885 const char *username,
2886 const char *password,
2887 struct rpc_pipe_client **presult)
2889 struct rpc_pipe_client *result;
2890 struct pipe_auth_data *auth = NULL;
2891 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2892 NTSTATUS status;
2894 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2895 if (!NT_STATUS_IS_OK(status)) {
2896 return status;
2899 status = rpccli_ntlmssp_bind_data(result,
2900 auth_type, auth_level,
2901 domain, username, password,
2902 &auth);
2903 if (!NT_STATUS_IS_OK(status)) {
2904 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
2905 nt_errstr(status)));
2906 goto err;
2909 status = rpc_pipe_bind(result, auth);
2910 if (!NT_STATUS_IS_OK(status)) {
2911 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
2912 nt_errstr(status) ));
2913 goto err;
2916 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
2917 "machine %s and bound NTLMSSP as user %s\\%s.\n",
2918 get_pipe_name_from_syntax(talloc_tos(), interface),
2919 cli->desthost, domain, username ));
2921 *presult = result;
2922 return NT_STATUS_OK;
2924 err:
2926 TALLOC_FREE(result);
2927 return status;
2930 /****************************************************************************
2931 External interface.
2932 Open a named pipe to an SMB server and bind using schannel (bind type 68)
2933 using session_key. sign and seal.
2935 The *pdc will be stolen onto this new pipe
2936 ****************************************************************************/
2938 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
2939 const struct ndr_syntax_id *interface,
2940 enum dcerpc_transport_t transport,
2941 enum dcerpc_AuthLevel auth_level,
2942 const char *domain,
2943 struct netlogon_creds_CredentialState **pdc,
2944 struct rpc_pipe_client **presult)
2946 struct rpc_pipe_client *result;
2947 struct pipe_auth_data *auth;
2948 NTSTATUS status;
2950 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2951 if (!NT_STATUS_IS_OK(status)) {
2952 return status;
2955 status = rpccli_schannel_bind_data(result, domain, auth_level,
2956 *pdc, &auth);
2957 if (!NT_STATUS_IS_OK(status)) {
2958 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
2959 nt_errstr(status)));
2960 TALLOC_FREE(result);
2961 return status;
2964 status = rpc_pipe_bind(result, auth);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
2967 "cli_rpc_pipe_bind failed with error %s\n",
2968 nt_errstr(status) ));
2969 TALLOC_FREE(result);
2970 return status;
2974 * The credentials on a new netlogon pipe are the ones we are passed
2975 * in - copy them over
2977 result->dc = netlogon_creds_copy(result, *pdc);
2978 if (result->dc == NULL) {
2979 TALLOC_FREE(result);
2980 return NT_STATUS_NO_MEMORY;
2983 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
2984 "for domain %s and bound using schannel.\n",
2985 get_pipe_name_from_syntax(talloc_tos(), interface),
2986 cli->desthost, domain ));
2988 *presult = result;
2989 return NT_STATUS_OK;
2992 /****************************************************************************
2993 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
2994 The idea is this can be called with service_princ, username and password all
2995 NULL so long as the caller has a TGT.
2996 ****************************************************************************/
2998 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
2999 const struct ndr_syntax_id *interface,
3000 enum dcerpc_transport_t transport,
3001 enum dcerpc_AuthLevel auth_level,
3002 const char *server,
3003 const char *username,
3004 const char *password,
3005 struct rpc_pipe_client **presult)
3007 struct rpc_pipe_client *result;
3008 struct pipe_auth_data *auth;
3009 struct gse_context *gse_ctx;
3010 NTSTATUS status;
3012 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3013 if (!NT_STATUS_IS_OK(status)) {
3014 return status;
3017 auth = talloc(result, struct pipe_auth_data);
3018 if (auth == NULL) {
3019 status = NT_STATUS_NO_MEMORY;
3020 goto err_out;
3022 auth->auth_type = DCERPC_AUTH_TYPE_KRB5;
3023 auth->auth_level = auth_level;
3025 if (!username) {
3026 username = "";
3028 auth->user_name = talloc_strdup(auth, username);
3029 if (!auth->user_name) {
3030 status = NT_STATUS_NO_MEMORY;
3031 goto err_out;
3034 /* Fixme, should we fetch/set the Realm ? */
3035 auth->domain = talloc_strdup(auth, "");
3036 if (!auth->domain) {
3037 status = NT_STATUS_NO_MEMORY;
3038 goto err_out;
3041 status = gse_init_client(auth,
3042 (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY),
3043 (auth_level == DCERPC_AUTH_LEVEL_PRIVACY),
3044 NULL, server, "cifs", username, password,
3045 GSS_C_DCE_STYLE, &gse_ctx);
3046 if (!NT_STATUS_IS_OK(status)) {
3047 DEBUG(0, ("gse_init_client returned %s\n",
3048 nt_errstr(status)));
3049 goto err_out;
3051 auth->auth_ctx = gse_ctx;
3053 status = rpc_pipe_bind(result, auth);
3054 if (!NT_STATUS_IS_OK(status)) {
3055 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3056 nt_errstr(status)));
3057 goto err_out;
3060 *presult = result;
3061 return NT_STATUS_OK;
3063 err_out:
3064 TALLOC_FREE(result);
3065 return status;
3068 NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli,
3069 const struct ndr_syntax_id *interface,
3070 enum dcerpc_transport_t transport,
3071 enum dcerpc_AuthLevel auth_level,
3072 const char *server,
3073 const char *username,
3074 const char *password,
3075 struct rpc_pipe_client **presult)
3077 struct rpc_pipe_client *result;
3078 struct pipe_auth_data *auth;
3079 struct spnego_context *spnego_ctx;
3080 NTSTATUS status;
3082 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3083 if (!NT_STATUS_IS_OK(status)) {
3084 return status;
3087 auth = talloc(result, struct pipe_auth_data);
3088 if (auth == NULL) {
3089 status = NT_STATUS_NO_MEMORY;
3090 goto err_out;
3092 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3093 auth->auth_level = auth_level;
3095 if (!username) {
3096 username = "";
3098 auth->user_name = talloc_strdup(auth, username);
3099 if (!auth->user_name) {
3100 status = NT_STATUS_NO_MEMORY;
3101 goto err_out;
3104 /* Fixme, should we fetch/set the Realm ? */
3105 auth->domain = talloc_strdup(auth, "");
3106 if (!auth->domain) {
3107 status = NT_STATUS_NO_MEMORY;
3108 goto err_out;
3111 status = spnego_gssapi_init_client(auth,
3112 (auth->auth_level ==
3113 DCERPC_AUTH_LEVEL_INTEGRITY),
3114 (auth->auth_level ==
3115 DCERPC_AUTH_LEVEL_PRIVACY),
3116 true,
3117 NULL, server, "cifs",
3118 username, password,
3119 &spnego_ctx);
3120 if (!NT_STATUS_IS_OK(status)) {
3121 DEBUG(0, ("spnego_init_client returned %s\n",
3122 nt_errstr(status)));
3123 goto err_out;
3125 auth->auth_ctx = spnego_ctx;
3127 status = rpc_pipe_bind(result, auth);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3130 nt_errstr(status)));
3131 goto err_out;
3134 *presult = result;
3135 return NT_STATUS_OK;
3137 err_out:
3138 TALLOC_FREE(result);
3139 return status;
3142 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3143 const struct ndr_syntax_id *interface,
3144 enum dcerpc_transport_t transport,
3145 enum dcerpc_AuthLevel auth_level,
3146 const char *domain,
3147 const char *username,
3148 const char *password,
3149 struct rpc_pipe_client **presult)
3151 struct rpc_pipe_client *result;
3152 struct pipe_auth_data *auth;
3153 struct spnego_context *spnego_ctx;
3154 NTSTATUS status;
3156 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3157 if (!NT_STATUS_IS_OK(status)) {
3158 return status;
3161 auth = talloc(result, struct pipe_auth_data);
3162 if (auth == NULL) {
3163 status = NT_STATUS_NO_MEMORY;
3164 goto err_out;
3166 auth->auth_type = DCERPC_AUTH_TYPE_SPNEGO;
3167 auth->auth_level = auth_level;
3169 if (!username) {
3170 username = "";
3172 auth->user_name = talloc_strdup(auth, username);
3173 if (!auth->user_name) {
3174 status = NT_STATUS_NO_MEMORY;
3175 goto err_out;
3178 if (!domain) {
3179 domain = "";
3181 auth->domain = talloc_strdup(auth, domain);
3182 if (!auth->domain) {
3183 status = NT_STATUS_NO_MEMORY;
3184 goto err_out;
3187 status = spnego_ntlmssp_init_client(auth,
3188 (auth->auth_level ==
3189 DCERPC_AUTH_LEVEL_INTEGRITY),
3190 (auth->auth_level ==
3191 DCERPC_AUTH_LEVEL_PRIVACY),
3192 true,
3193 domain, username, password,
3194 &spnego_ctx);
3195 if (!NT_STATUS_IS_OK(status)) {
3196 DEBUG(0, ("spnego_init_client returned %s\n",
3197 nt_errstr(status)));
3198 goto err_out;
3200 auth->auth_ctx = spnego_ctx;
3202 status = rpc_pipe_bind(result, auth);
3203 if (!NT_STATUS_IS_OK(status)) {
3204 DEBUG(0, ("cli_rpc_pipe_bind failed with error %s\n",
3205 nt_errstr(status)));
3206 goto err_out;
3209 *presult = result;
3210 return NT_STATUS_OK;
3212 err_out:
3213 TALLOC_FREE(result);
3214 return status;
3217 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3218 struct rpc_pipe_client *cli,
3219 DATA_BLOB *session_key)
3221 struct pipe_auth_data *a = cli->auth;
3222 struct schannel_state *schannel_auth;
3223 struct auth_ntlmssp_state *ntlmssp_ctx;
3224 struct spnego_context *spnego_ctx;
3225 struct gse_context *gse_ctx;
3226 DATA_BLOB sk = data_blob_null;
3227 bool make_dup = false;
3229 if (!session_key || !cli) {
3230 return NT_STATUS_INVALID_PARAMETER;
3233 if (!cli->auth) {
3234 return NT_STATUS_INVALID_PARAMETER;
3237 switch (cli->auth->auth_type) {
3238 case DCERPC_AUTH_TYPE_SCHANNEL:
3239 schannel_auth = talloc_get_type_abort(a->auth_ctx,
3240 struct schannel_state);
3241 sk = data_blob_const(schannel_auth->creds->session_key, 16);
3242 make_dup = true;
3243 break;
3244 case DCERPC_AUTH_TYPE_SPNEGO:
3245 spnego_ctx = talloc_get_type_abort(a->auth_ctx,
3246 struct spnego_context);
3247 sk = spnego_get_session_key(mem_ctx, spnego_ctx);
3248 make_dup = false;
3249 break;
3250 case DCERPC_AUTH_TYPE_NTLMSSP:
3251 ntlmssp_ctx = talloc_get_type_abort(a->auth_ctx,
3252 struct auth_ntlmssp_state);
3253 sk = auth_ntlmssp_get_session_key(ntlmssp_ctx);
3254 make_dup = true;
3255 break;
3256 case DCERPC_AUTH_TYPE_KRB5:
3257 gse_ctx = talloc_get_type_abort(a->auth_ctx,
3258 struct gse_context);
3259 sk = gse_get_session_key(mem_ctx, gse_ctx);
3260 make_dup = false;
3261 break;
3262 case DCERPC_AUTH_TYPE_NONE:
3263 sk = data_blob_const(a->user_session_key.data,
3264 a->user_session_key.length);
3265 make_dup = true;
3266 break;
3267 default:
3268 break;
3271 if (!sk.data) {
3272 return NT_STATUS_NO_USER_SESSION_KEY;
3275 if (make_dup) {
3276 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3277 } else {
3278 *session_key = sk;
3281 return NT_STATUS_OK;