s3-dcerpc: Add sign/seal with gssapi
[Samba/vl.git] / source3 / rpc_client / cli_pipe.c
blob85888755069da4b85363ea4dc72827ef036de612
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Largely rewritten by Jeremy Allison 2005.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "librpc/gen_ndr/cli_epmapper.h"
22 #include "../librpc/gen_ndr/ndr_schannel.h"
23 #include "../librpc/gen_ndr/ndr_dssetup.h"
24 #include "../librpc/gen_ndr/ndr_netlogon.h"
25 #include "../libcli/auth/schannel.h"
26 #include "../libcli/auth/spnego.h"
27 #include "smb_krb5.h"
28 #include "../libcli/auth/ntlmssp.h"
29 #include "ntlmssp_wrap.h"
30 #include "rpc_client/cli_netlogon.h"
31 #include "librpc/gen_ndr/ndr_dcerpc.h"
32 #include "librpc/rpc/dcerpc.h"
33 #include "librpc/rpc/dcerpc_gssapi.h"
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_RPC_CLI
38 /********************************************************************
39 Pipe description for a DEBUG
40 ********************************************************************/
41 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
42 struct rpc_pipe_client *cli)
44 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
45 if (result == NULL) {
46 return "pipe";
48 return result;
51 /********************************************************************
52 Rpc pipe call id.
53 ********************************************************************/
55 static uint32 get_rpc_call_id(void)
57 static uint32 call_id = 0;
58 return ++call_id;
61 /*******************************************************************
62 Use SMBreadX to get rest of one fragment's worth of rpc data.
63 Reads the whole size or give an error message
64 ********************************************************************/
66 struct rpc_read_state {
67 struct event_context *ev;
68 struct rpc_cli_transport *transport;
69 uint8_t *data;
70 size_t size;
71 size_t num_read;
74 static void rpc_read_done(struct tevent_req *subreq);
76 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
77 struct event_context *ev,
78 struct rpc_cli_transport *transport,
79 uint8_t *data, size_t size)
81 struct tevent_req *req, *subreq;
82 struct rpc_read_state *state;
84 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
85 if (req == NULL) {
86 return NULL;
88 state->ev = ev;
89 state->transport = transport;
90 state->data = data;
91 state->size = size;
92 state->num_read = 0;
94 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
96 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
97 transport->priv);
98 if (subreq == NULL) {
99 goto fail;
101 tevent_req_set_callback(subreq, rpc_read_done, req);
102 return req;
104 fail:
105 TALLOC_FREE(req);
106 return NULL;
109 static void rpc_read_done(struct tevent_req *subreq)
111 struct tevent_req *req = tevent_req_callback_data(
112 subreq, struct tevent_req);
113 struct rpc_read_state *state = tevent_req_data(
114 req, struct rpc_read_state);
115 NTSTATUS status;
116 ssize_t received;
118 status = state->transport->read_recv(subreq, &received);
119 TALLOC_FREE(subreq);
120 if (!NT_STATUS_IS_OK(status)) {
121 tevent_req_nterror(req, status);
122 return;
125 state->num_read += received;
126 if (state->num_read == state->size) {
127 tevent_req_done(req);
128 return;
131 subreq = state->transport->read_send(state, state->ev,
132 state->data + state->num_read,
133 state->size - state->num_read,
134 state->transport->priv);
135 if (tevent_req_nomem(subreq, req)) {
136 return;
138 tevent_req_set_callback(subreq, rpc_read_done, req);
141 static NTSTATUS rpc_read_recv(struct tevent_req *req)
143 return tevent_req_simple_recv_ntstatus(req);
146 struct rpc_write_state {
147 struct event_context *ev;
148 struct rpc_cli_transport *transport;
149 const uint8_t *data;
150 size_t size;
151 size_t num_written;
154 static void rpc_write_done(struct tevent_req *subreq);
156 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
157 struct event_context *ev,
158 struct rpc_cli_transport *transport,
159 const uint8_t *data, size_t size)
161 struct tevent_req *req, *subreq;
162 struct rpc_write_state *state;
164 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
165 if (req == NULL) {
166 return NULL;
168 state->ev = ev;
169 state->transport = transport;
170 state->data = data;
171 state->size = size;
172 state->num_written = 0;
174 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
176 subreq = transport->write_send(state, ev, data, size, transport->priv);
177 if (subreq == NULL) {
178 goto fail;
180 tevent_req_set_callback(subreq, rpc_write_done, req);
181 return req;
182 fail:
183 TALLOC_FREE(req);
184 return NULL;
187 static void rpc_write_done(struct tevent_req *subreq)
189 struct tevent_req *req = tevent_req_callback_data(
190 subreq, struct tevent_req);
191 struct rpc_write_state *state = tevent_req_data(
192 req, struct rpc_write_state);
193 NTSTATUS status;
194 ssize_t written;
196 status = state->transport->write_recv(subreq, &written);
197 TALLOC_FREE(subreq);
198 if (!NT_STATUS_IS_OK(status)) {
199 tevent_req_nterror(req, status);
200 return;
203 state->num_written += written;
205 if (state->num_written == state->size) {
206 tevent_req_done(req);
207 return;
210 subreq = state->transport->write_send(state, state->ev,
211 state->data + state->num_written,
212 state->size - state->num_written,
213 state->transport->priv);
214 if (tevent_req_nomem(subreq, req)) {
215 return;
217 tevent_req_set_callback(subreq, rpc_write_done, req);
220 static NTSTATUS rpc_write_recv(struct tevent_req *req)
222 return tevent_req_simple_recv_ntstatus(req);
226 /****************************************************************************
227 Try and get a PDU's worth of data from current_pdu. If not, then read more
228 from the wire.
229 ****************************************************************************/
231 struct get_complete_frag_state {
232 struct event_context *ev;
233 struct rpc_pipe_client *cli;
234 uint16_t frag_len;
235 DATA_BLOB *pdu;
238 static void get_complete_frag_got_header(struct tevent_req *subreq);
239 static void get_complete_frag_got_rest(struct tevent_req *subreq);
241 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
242 struct event_context *ev,
243 struct rpc_pipe_client *cli,
244 DATA_BLOB *pdu)
246 struct tevent_req *req, *subreq;
247 struct get_complete_frag_state *state;
248 size_t received;
249 NTSTATUS status;
251 req = tevent_req_create(mem_ctx, &state,
252 struct get_complete_frag_state);
253 if (req == NULL) {
254 return NULL;
256 state->ev = ev;
257 state->cli = cli;
258 state->frag_len = RPC_HEADER_LEN;
259 state->pdu = pdu;
261 received = pdu->length;
262 if (received < RPC_HEADER_LEN) {
263 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
264 status = NT_STATUS_NO_MEMORY;
265 goto post_status;
267 subreq = rpc_read_send(state, state->ev,
268 state->cli->transport,
269 pdu->data + received,
270 RPC_HEADER_LEN - received);
271 if (subreq == NULL) {
272 status = NT_STATUS_NO_MEMORY;
273 goto post_status;
275 tevent_req_set_callback(subreq, get_complete_frag_got_header,
276 req);
277 return req;
280 state->frag_len = dcerpc_get_frag_length(pdu);
283 * Ensure we have frag_len bytes of data.
285 if (received < state->frag_len) {
286 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
287 status = NT_STATUS_NO_MEMORY;
288 goto post_status;
290 subreq = rpc_read_send(state, state->ev,
291 state->cli->transport,
292 pdu->data + received,
293 state->frag_len - received);
294 if (subreq == NULL) {
295 status = NT_STATUS_NO_MEMORY;
296 goto post_status;
298 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
299 req);
300 return req;
303 status = NT_STATUS_OK;
304 post_status:
305 if (NT_STATUS_IS_OK(status)) {
306 tevent_req_done(req);
307 } else {
308 tevent_req_nterror(req, status);
310 return tevent_req_post(req, ev);
313 static void get_complete_frag_got_header(struct tevent_req *subreq)
315 struct tevent_req *req = tevent_req_callback_data(
316 subreq, struct tevent_req);
317 struct get_complete_frag_state *state = tevent_req_data(
318 req, struct get_complete_frag_state);
319 NTSTATUS status;
321 status = rpc_read_recv(subreq);
322 TALLOC_FREE(subreq);
323 if (!NT_STATUS_IS_OK(status)) {
324 tevent_req_nterror(req, status);
325 return;
328 state->frag_len = dcerpc_get_frag_length(state->pdu);
330 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
331 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
332 return;
336 * We're here in this piece of code because we've read exactly
337 * RPC_HEADER_LEN bytes into state->pdu.
340 subreq = rpc_read_send(state, state->ev, state->cli->transport,
341 state->pdu->data + RPC_HEADER_LEN,
342 state->frag_len - RPC_HEADER_LEN);
343 if (tevent_req_nomem(subreq, req)) {
344 return;
346 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
349 static void get_complete_frag_got_rest(struct tevent_req *subreq)
351 struct tevent_req *req = tevent_req_callback_data(
352 subreq, struct tevent_req);
353 NTSTATUS status;
355 status = rpc_read_recv(subreq);
356 TALLOC_FREE(subreq);
357 if (!NT_STATUS_IS_OK(status)) {
358 tevent_req_nterror(req, status);
359 return;
361 tevent_req_done(req);
364 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
366 return tevent_req_simple_recv_ntstatus(req);
369 /****************************************************************************
370 Do basic authentication checks on an incoming pdu.
371 ****************************************************************************/
373 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
374 struct rpc_pipe_client *cli,
375 struct ncacn_packet *pkt,
376 DATA_BLOB *pdu,
377 uint8_t expected_pkt_type,
378 DATA_BLOB *rdata,
379 DATA_BLOB *reply_pdu)
381 NTSTATUS ret = NT_STATUS_OK;
382 size_t pad_len = 0;
384 ret = dcerpc_pull_ncacn_packet(cli, pdu, pkt, false);
385 if (!NT_STATUS_IS_OK(ret)) {
386 return ret;
389 if (pdu->length != pkt->frag_length) {
390 DEBUG(5, ("Incorrect pdu length %u, expected %u\n",
391 (unsigned int)pdu->length,
392 (unsigned int)pkt->frag_length));
393 return NT_STATUS_INVALID_PARAMETER;
397 * Point the return values at the real data including the RPC
398 * header. Just in case the caller wants it.
400 *rdata = *pdu;
402 /* Ensure we have the correct type. */
403 switch (pkt->ptype) {
404 case DCERPC_PKT_ALTER_RESP:
405 case DCERPC_PKT_BIND_ACK:
407 /* Alter context and bind ack share the same packet definitions. */
408 break;
411 case DCERPC_PKT_RESPONSE:
413 /* Here's where we deal with incoming sign/seal. */
414 ret = dcerpc_check_auth(cli->auth, pkt,
415 &pkt->u.response.stub_and_verifier,
416 DCERPC_RESPONSE_LENGTH,
417 pdu, &pad_len);
418 if (!NT_STATUS_IS_OK(ret)) {
419 return ret;
422 if (pdu->length < DCERPC_RESPONSE_LENGTH + pad_len) {
423 return NT_STATUS_BUFFER_TOO_SMALL;
426 /* Point the return values at the NDR data. */
427 rdata->data = pdu->data + DCERPC_RESPONSE_LENGTH;
429 if (pkt->auth_length) {
430 /* We've already done integer wrap tests in
431 * dcerpc_check_auth(). */
432 rdata->length = pdu->length
433 - DCERPC_RESPONSE_LENGTH
434 - pad_len
435 - DCERPC_AUTH_TRAILER_LENGTH
436 - pkt->auth_length;
437 } else {
438 rdata->length = pdu->length - DCERPC_RESPONSE_LENGTH;
441 DEBUG(10, ("Got pdu len %lu, data_len %lu, ss_len %u\n",
442 (long unsigned int)pdu->length,
443 (long unsigned int)rdata->length,
444 (unsigned int)pad_len));
447 * If this is the first reply, and the allocation hint is
448 * reasonable, try and set up the reply_pdu DATA_BLOB to the
449 * correct size.
452 if ((reply_pdu->length == 0) &&
453 pkt->u.response.alloc_hint &&
454 (pkt->u.response.alloc_hint < 15*1024*1024)) {
455 if (!data_blob_realloc(mem_ctx, reply_pdu,
456 pkt->u.response.alloc_hint)) {
457 DEBUG(0, ("reply alloc hint %d too "
458 "large to allocate\n",
459 (int)pkt->u.response.alloc_hint));
460 return NT_STATUS_NO_MEMORY;
464 break;
466 case DCERPC_PKT_BIND_NAK:
467 DEBUG(1, ("cli_pipe_validate_current_pdu: Bind NACK "
468 "received from %s!\n",
469 rpccli_pipe_txt(talloc_tos(), cli)));
470 /* Use this for now... */
471 return NT_STATUS_NETWORK_ACCESS_DENIED;
473 case DCERPC_PKT_FAULT:
475 DEBUG(1, ("cli_pipe_validate_current_pdu: RPC fault "
476 "code %s received from %s!\n",
477 dcerpc_errstr(talloc_tos(),
478 pkt->u.fault.status),
479 rpccli_pipe_txt(talloc_tos(), cli)));
481 if (NT_STATUS_IS_OK(NT_STATUS(pkt->u.fault.status))) {
482 return NT_STATUS_UNSUCCESSFUL;
483 } else {
484 return NT_STATUS(pkt->u.fault.status);
487 default:
488 DEBUG(0, ("Unknown packet type %u received from %s!\n",
489 (unsigned int)pkt->ptype,
490 rpccli_pipe_txt(talloc_tos(), cli)));
491 return NT_STATUS_INVALID_INFO_CLASS;
494 if (pkt->ptype != expected_pkt_type) {
495 DEBUG(3, ("cli_pipe_validate_current_pdu: Connection to %s "
496 "got an unexpected RPC packet type - %u, not %u\n",
497 rpccli_pipe_txt(talloc_tos(), cli),
498 pkt->ptype,
499 expected_pkt_type));
500 return NT_STATUS_INVALID_INFO_CLASS;
503 /* Do this just before return - we don't want to modify any rpc header
504 data before now as we may have needed to do cryptographic actions on
505 it before. */
507 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
508 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
509 DEBUG(5,("cli_pipe_validate_current_pdu: bug in server (AS/U?), "
510 "setting fragment first/last ON.\n"));
511 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST |
512 DCERPC_PFC_FLAG_LAST;
515 return NT_STATUS_OK;
518 /****************************************************************************
519 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
520 ****************************************************************************/
522 struct cli_api_pipe_state {
523 struct event_context *ev;
524 struct rpc_cli_transport *transport;
525 uint8_t *rdata;
526 uint32_t rdata_len;
529 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
530 static void cli_api_pipe_write_done(struct tevent_req *subreq);
531 static void cli_api_pipe_read_done(struct tevent_req *subreq);
533 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
534 struct event_context *ev,
535 struct rpc_cli_transport *transport,
536 uint8_t *data, size_t data_len,
537 uint32_t max_rdata_len)
539 struct tevent_req *req, *subreq;
540 struct cli_api_pipe_state *state;
541 NTSTATUS status;
543 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
544 if (req == NULL) {
545 return NULL;
547 state->ev = ev;
548 state->transport = transport;
550 if (max_rdata_len < RPC_HEADER_LEN) {
552 * For a RPC reply we always need at least RPC_HEADER_LEN
553 * bytes. We check this here because we will receive
554 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
556 status = NT_STATUS_INVALID_PARAMETER;
557 goto post_status;
560 if (transport->trans_send != NULL) {
561 subreq = transport->trans_send(state, ev, data, data_len,
562 max_rdata_len, transport->priv);
563 if (subreq == NULL) {
564 goto fail;
566 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
567 return req;
571 * If the transport does not provide a "trans" routine, i.e. for
572 * example the ncacn_ip_tcp transport, do the write/read step here.
575 subreq = rpc_write_send(state, ev, transport, data, data_len);
576 if (subreq == NULL) {
577 goto fail;
579 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
580 return req;
582 post_status:
583 tevent_req_nterror(req, status);
584 return tevent_req_post(req, ev);
585 fail:
586 TALLOC_FREE(req);
587 return NULL;
590 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
592 struct tevent_req *req = tevent_req_callback_data(
593 subreq, struct tevent_req);
594 struct cli_api_pipe_state *state = tevent_req_data(
595 req, struct cli_api_pipe_state);
596 NTSTATUS status;
598 status = state->transport->trans_recv(subreq, state, &state->rdata,
599 &state->rdata_len);
600 TALLOC_FREE(subreq);
601 if (!NT_STATUS_IS_OK(status)) {
602 tevent_req_nterror(req, status);
603 return;
605 tevent_req_done(req);
608 static void cli_api_pipe_write_done(struct tevent_req *subreq)
610 struct tevent_req *req = tevent_req_callback_data(
611 subreq, struct tevent_req);
612 struct cli_api_pipe_state *state = tevent_req_data(
613 req, struct cli_api_pipe_state);
614 NTSTATUS status;
616 status = rpc_write_recv(subreq);
617 TALLOC_FREE(subreq);
618 if (!NT_STATUS_IS_OK(status)) {
619 tevent_req_nterror(req, status);
620 return;
623 state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN);
624 if (tevent_req_nomem(state->rdata, req)) {
625 return;
629 * We don't need to use rpc_read_send here, the upper layer will cope
630 * with a short read, transport->trans_send could also return less
631 * than state->max_rdata_len.
633 subreq = state->transport->read_send(state, state->ev, state->rdata,
634 RPC_HEADER_LEN,
635 state->transport->priv);
636 if (tevent_req_nomem(subreq, req)) {
637 return;
639 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
642 static void cli_api_pipe_read_done(struct tevent_req *subreq)
644 struct tevent_req *req = tevent_req_callback_data(
645 subreq, struct tevent_req);
646 struct cli_api_pipe_state *state = tevent_req_data(
647 req, struct cli_api_pipe_state);
648 NTSTATUS status;
649 ssize_t received;
651 status = state->transport->read_recv(subreq, &received);
652 TALLOC_FREE(subreq);
653 if (!NT_STATUS_IS_OK(status)) {
654 tevent_req_nterror(req, status);
655 return;
657 state->rdata_len = received;
658 tevent_req_done(req);
661 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
662 uint8_t **prdata, uint32_t *prdata_len)
664 struct cli_api_pipe_state *state = tevent_req_data(
665 req, struct cli_api_pipe_state);
666 NTSTATUS status;
668 if (tevent_req_is_nterror(req, &status)) {
669 return status;
672 *prdata = talloc_move(mem_ctx, &state->rdata);
673 *prdata_len = state->rdata_len;
674 return NT_STATUS_OK;
677 /****************************************************************************
678 Send data on an rpc pipe via trans. The data must be the last
679 pdu fragment of an NDR data stream.
681 Receive response data from an rpc pipe, which may be large...
683 Read the first fragment: unfortunately have to use SMBtrans for the first
684 bit, then SMBreadX for subsequent bits.
686 If first fragment received also wasn't the last fragment, continue
687 getting fragments until we _do_ receive the last fragment.
689 Request/Response PDU's look like the following...
691 |<------------------PDU len----------------------------------------------->|
692 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
694 +------------+-----------------+-------------+---------------+-------------+
695 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
696 +------------+-----------------+-------------+---------------+-------------+
698 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
699 signing & sealing being negotiated.
701 ****************************************************************************/
703 struct rpc_api_pipe_state {
704 struct event_context *ev;
705 struct rpc_pipe_client *cli;
706 uint8_t expected_pkt_type;
708 DATA_BLOB incoming_frag;
709 struct ncacn_packet *pkt;
711 /* Incoming reply */
712 DATA_BLOB reply_pdu;
713 size_t reply_pdu_offset;
714 uint8_t endianess;
717 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
718 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
720 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
721 struct event_context *ev,
722 struct rpc_pipe_client *cli,
723 DATA_BLOB *data, /* Outgoing PDU */
724 uint8_t expected_pkt_type)
726 struct tevent_req *req, *subreq;
727 struct rpc_api_pipe_state *state;
728 uint16_t max_recv_frag;
729 NTSTATUS status;
731 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
732 if (req == NULL) {
733 return NULL;
735 state->ev = ev;
736 state->cli = cli;
737 state->expected_pkt_type = expected_pkt_type;
738 state->incoming_frag = data_blob_null;
739 state->reply_pdu = data_blob_null;
740 state->reply_pdu_offset = 0;
741 state->endianess = DCERPC_DREP_LE;
744 * Ensure we're not sending too much.
746 if (data->length > cli->max_xmit_frag) {
747 status = NT_STATUS_INVALID_PARAMETER;
748 goto post_status;
751 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
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_trans_done(struct tevent_req *subreq)
775 struct tevent_req *req = tevent_req_callback_data(
776 subreq, struct tevent_req);
777 struct rpc_api_pipe_state *state = tevent_req_data(
778 req, struct rpc_api_pipe_state);
779 NTSTATUS status;
780 uint8_t *rdata = NULL;
781 uint32_t rdata_len = 0;
783 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
784 TALLOC_FREE(subreq);
785 if (!NT_STATUS_IS_OK(status)) {
786 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
787 tevent_req_nterror(req, status);
788 return;
791 if (rdata == NULL) {
792 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
793 rpccli_pipe_txt(talloc_tos(), state->cli)));
794 tevent_req_done(req);
795 return;
799 * Move data on state->incoming_frag.
801 state->incoming_frag.data = talloc_move(state, &rdata);
802 state->incoming_frag.length = rdata_len;
803 if (!state->incoming_frag.data) {
804 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
805 return;
808 /* Ensure we have enough data for a pdu. */
809 subreq = get_complete_frag_send(state, state->ev, state->cli,
810 &state->incoming_frag);
811 if (tevent_req_nomem(subreq, req)) {
812 return;
814 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
817 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
819 struct tevent_req *req = tevent_req_callback_data(
820 subreq, struct tevent_req);
821 struct rpc_api_pipe_state *state = tevent_req_data(
822 req, struct rpc_api_pipe_state);
823 NTSTATUS status;
824 DATA_BLOB rdata = data_blob_null;
826 status = get_complete_frag_recv(subreq);
827 TALLOC_FREE(subreq);
828 if (!NT_STATUS_IS_OK(status)) {
829 DEBUG(5, ("get_complete_frag failed: %s\n",
830 nt_errstr(status)));
831 tevent_req_nterror(req, status);
832 return;
835 state->pkt = talloc(state, struct ncacn_packet);
836 if (!state->pkt) {
837 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
838 return;
841 status = cli_pipe_validate_current_pdu(state,
842 state->cli, state->pkt,
843 &state->incoming_frag,
844 state->expected_pkt_type,
845 &rdata,
846 &state->reply_pdu);
848 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
849 (unsigned)state->incoming_frag.length,
850 (unsigned)state->reply_pdu_offset,
851 nt_errstr(status)));
853 if (!NT_STATUS_IS_OK(status)) {
854 tevent_req_nterror(req, status);
855 return;
858 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
859 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
861 * Set the data type correctly for big-endian data on the
862 * first packet.
864 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
865 "big-endian.\n",
866 rpccli_pipe_txt(talloc_tos(), state->cli)));
867 state->endianess = 0x00; /* BIG ENDIAN */
870 * Check endianness on subsequent packets.
872 if (state->endianess != state->pkt->drep[0]) {
873 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
874 "%s\n",
875 state->endianess?"little":"big",
876 state->pkt->drep[0]?"little":"big"));
877 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
878 return;
881 /* Now copy the data portion out of the pdu into rbuf. */
882 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
883 if (!data_blob_realloc(NULL, &state->reply_pdu,
884 state->reply_pdu_offset + rdata.length)) {
885 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
886 return;
890 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
891 rdata.data, rdata.length);
892 state->reply_pdu_offset += rdata.length;
894 /* reset state->incoming_frag, there is no need to free it,
895 * it will be reallocated to the right size the next time
896 * it is used */
897 state->incoming_frag.length = 0;
899 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
900 /* make sure the pdu length is right now that we
901 * have all the data available (alloc hint may
902 * have allocated more than was actually used) */
903 state->reply_pdu.length = state->reply_pdu_offset;
904 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
905 rpccli_pipe_txt(talloc_tos(), state->cli),
906 (unsigned)state->reply_pdu.length));
907 tevent_req_done(req);
908 return;
911 subreq = get_complete_frag_send(state, state->ev, state->cli,
912 &state->incoming_frag);
913 if (tevent_req_nomem(subreq, req)) {
914 return;
916 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
919 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
920 struct ncacn_packet **pkt,
921 DATA_BLOB *reply_pdu)
923 struct rpc_api_pipe_state *state = tevent_req_data(
924 req, struct rpc_api_pipe_state);
925 NTSTATUS status;
927 if (tevent_req_is_nterror(req, &status)) {
928 return status;
931 /* return data to caller and assign it ownership of memory */
932 if (reply_pdu) {
933 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
934 reply_pdu->length = state->reply_pdu.length;
935 state->reply_pdu.length = 0;
936 } else {
937 data_blob_free(&state->reply_pdu);
940 if (pkt) {
941 *pkt = talloc_steal(mem_ctx, state->pkt);
944 return NT_STATUS_OK;
947 /*******************************************************************
948 Creates krb5 auth bind.
949 ********************************************************************/
951 static NTSTATUS create_gssapi_auth_bind_req(TALLOC_CTX *mem_ctx,
952 struct pipe_auth_data *auth,
953 DATA_BLOB *auth_info)
955 DATA_BLOB in_token = data_blob_null;
956 DATA_BLOB auth_token = data_blob_null;
957 NTSTATUS status;
959 /* Negotiate the initial auth token */
960 status = gse_get_client_auth_token(mem_ctx,
961 auth->a_u.gssapi_state,
962 &in_token,
963 &auth_token);
964 if (!NT_STATUS_IS_OK(status)) {
965 return status;
968 status = dcerpc_push_dcerpc_auth(mem_ctx,
969 auth->auth_type,
970 auth->auth_level,
971 0, /* auth_pad_length */
972 1, /* auth_context_id */
973 &auth_token,
974 auth_info);
975 if (!NT_STATUS_IS_OK(status)) {
976 data_blob_free(&auth_token);
977 return status;
980 DEBUG(5, ("Created GSS Authentication Token:\n"));
981 dump_data(5, auth_token.data, auth_token.length);
983 data_blob_free(&auth_token);
984 return NT_STATUS_OK;
987 /*******************************************************************
988 Creates SPNEGO NTLMSSP auth bind.
989 ********************************************************************/
991 static NTSTATUS create_spnego_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
992 enum dcerpc_AuthLevel auth_level,
993 DATA_BLOB *auth_info)
995 NTSTATUS status;
996 DATA_BLOB null_blob = data_blob_null;
997 DATA_BLOB request = data_blob_null;
998 DATA_BLOB spnego_msg = data_blob_null;
999 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL};
1001 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1002 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1003 null_blob,
1004 &request);
1006 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1007 data_blob_free(&request);
1008 return status;
1011 /* Wrap this in SPNEGO. */
1012 spnego_msg = spnego_gen_negTokenInit(talloc_tos(), OIDs_ntlm, &request, NULL);
1014 data_blob_free(&request);
1016 status = dcerpc_push_dcerpc_auth(cli,
1017 DCERPC_AUTH_TYPE_SPNEGO,
1018 auth_level,
1019 0, /* auth_pad_length */
1020 1, /* auth_context_id */
1021 &spnego_msg,
1022 auth_info);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 data_blob_free(&spnego_msg);
1026 return status;
1029 DEBUG(5, ("create_spnego_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1030 dump_data(5, spnego_msg.data, spnego_msg.length);
1031 data_blob_free(&spnego_msg);
1033 return NT_STATUS_OK;
1036 /*******************************************************************
1037 Creates NTLMSSP auth bind.
1038 ********************************************************************/
1040 static NTSTATUS create_ntlmssp_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1041 enum dcerpc_AuthLevel auth_level,
1042 DATA_BLOB *auth_info)
1044 NTSTATUS status;
1045 DATA_BLOB null_blob = data_blob_null;
1046 DATA_BLOB request = data_blob_null;
1048 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: Processing NTLMSSP Negotiate\n"));
1049 status = auth_ntlmssp_update(cli->auth->a_u.auth_ntlmssp_state,
1050 null_blob,
1051 &request);
1053 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1054 data_blob_free(&request);
1055 return status;
1058 status = dcerpc_push_dcerpc_auth(cli,
1059 DCERPC_AUTH_TYPE_NTLMSSP,
1060 auth_level,
1061 0, /* auth_pad_length */
1062 1, /* auth_context_id */
1063 &request,
1064 auth_info);
1065 if (!NT_STATUS_IS_OK(status)) {
1066 data_blob_free(&request);
1067 return status;
1070 DEBUG(5, ("create_ntlmssp_auth_rpc_bind_req: NTLMSSP Negotiate:\n"));
1071 dump_data(5, request.data, request.length);
1073 return NT_STATUS_OK;
1076 /*******************************************************************
1077 Creates schannel auth bind.
1078 ********************************************************************/
1080 static NTSTATUS create_schannel_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1081 enum dcerpc_AuthLevel auth_level,
1082 DATA_BLOB *auth_info)
1084 NTSTATUS status;
1085 struct NL_AUTH_MESSAGE r;
1086 DATA_BLOB schannel_blob;
1088 /* Use lp_workgroup() if domain not specified */
1090 if (!cli->auth->domain || !cli->auth->domain[0]) {
1091 cli->auth->domain = talloc_strdup(cli, lp_workgroup());
1092 if (cli->auth->domain == NULL) {
1093 return NT_STATUS_NO_MEMORY;
1098 * Now marshall the data into the auth parse_struct.
1101 r.MessageType = NL_NEGOTIATE_REQUEST;
1102 r.Flags = NL_FLAG_OEM_NETBIOS_DOMAIN_NAME |
1103 NL_FLAG_OEM_NETBIOS_COMPUTER_NAME;
1104 r.oem_netbios_domain.a = cli->auth->domain;
1105 r.oem_netbios_computer.a = global_myname();
1107 status = dcerpc_push_schannel_bind(cli, &r, &schannel_blob);
1108 if (!NT_STATUS_IS_OK(status)) {
1109 return status;
1112 status = dcerpc_push_dcerpc_auth(cli,
1113 DCERPC_AUTH_TYPE_SCHANNEL,
1114 auth_level,
1115 0, /* auth_pad_length */
1116 1, /* auth_context_id */
1117 &schannel_blob,
1118 auth_info);
1119 if (!NT_STATUS_IS_OK(status)) {
1120 return status;
1123 return NT_STATUS_OK;
1126 /*******************************************************************
1127 Creates the internals of a DCE/RPC bind request or alter context PDU.
1128 ********************************************************************/
1130 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1131 enum dcerpc_pkt_type ptype,
1132 uint32 rpc_call_id,
1133 const struct ndr_syntax_id *abstract,
1134 const struct ndr_syntax_id *transfer,
1135 const DATA_BLOB *auth_info,
1136 DATA_BLOB *blob)
1138 uint16 auth_len = auth_info->length;
1139 NTSTATUS status;
1140 union dcerpc_payload u;
1141 struct dcerpc_ctx_list ctx_list;
1143 if (auth_len) {
1144 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1147 ctx_list.context_id = 0;
1148 ctx_list.num_transfer_syntaxes = 1;
1149 ctx_list.abstract_syntax = *abstract;
1150 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1152 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1153 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1154 u.bind.assoc_group_id = 0x0;
1155 u.bind.num_contexts = 1;
1156 u.bind.ctx_list = &ctx_list;
1157 u.bind.auth_info = *auth_info;
1159 status = dcerpc_push_ncacn_packet(mem_ctx,
1160 ptype,
1161 DCERPC_PFC_FLAG_FIRST |
1162 DCERPC_PFC_FLAG_LAST,
1163 auth_len,
1164 rpc_call_id,
1166 blob);
1167 if (!NT_STATUS_IS_OK(status)) {
1168 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1169 return status;
1172 return NT_STATUS_OK;
1175 /*******************************************************************
1176 Creates a DCE/RPC bind request.
1177 ********************************************************************/
1179 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1180 struct rpc_pipe_client *cli,
1181 struct pipe_auth_data *auth,
1182 uint32 rpc_call_id,
1183 const struct ndr_syntax_id *abstract,
1184 const struct ndr_syntax_id *transfer,
1185 DATA_BLOB *rpc_out)
1187 DATA_BLOB auth_info = data_blob_null;
1188 NTSTATUS ret = NT_STATUS_OK;
1190 switch (auth->auth_type) {
1191 case DCERPC_AUTH_TYPE_SCHANNEL:
1192 ret = create_schannel_auth_rpc_bind_req(cli,
1193 auth->auth_level,
1194 &auth_info);
1195 if (!NT_STATUS_IS_OK(ret)) {
1196 return ret;
1198 break;
1200 case DCERPC_AUTH_TYPE_NTLMSSP:
1201 ret = create_ntlmssp_auth_rpc_bind_req(cli,
1202 auth->auth_level,
1203 &auth_info);
1204 if (!NT_STATUS_IS_OK(ret)) {
1205 return ret;
1207 break;
1209 case DCERPC_AUTH_TYPE_SPNEGO:
1210 if (auth->spnego_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1211 /* "Can't" happen. */
1212 return NT_STATUS_INVALID_INFO_CLASS;
1214 ret = create_spnego_ntlmssp_auth_rpc_bind_req(cli,
1215 auth->auth_level,
1216 &auth_info);
1217 if (!NT_STATUS_IS_OK(ret)) {
1218 return ret;
1220 break;
1222 case DCERPC_AUTH_TYPE_KRB5:
1223 ret = create_gssapi_auth_bind_req(mem_ctx, auth, &auth_info);
1224 if (!NT_STATUS_IS_OK(ret)) {
1225 return ret;
1227 break;
1229 case DCERPC_AUTH_TYPE_NONE:
1230 break;
1232 default:
1233 /* "Can't" happen. */
1234 return NT_STATUS_INVALID_INFO_CLASS;
1237 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1238 DCERPC_PKT_BIND,
1239 rpc_call_id,
1240 abstract,
1241 transfer,
1242 &auth_info,
1243 rpc_out);
1244 return ret;
1247 /*******************************************************************
1248 Calculate how much data we're going to send in this packet, also
1249 work out any sign/seal padding length.
1250 ********************************************************************/
1252 static NTSTATUS calculate_data_len_tosend(struct rpc_pipe_client *cli,
1253 uint32_t data_left,
1254 uint32_t *data_to_send,
1255 uint16_t *p_frag_len,
1256 uint16_t *p_auth_len,
1257 uint32_t *p_ss_padding)
1259 uint32_t data_space, data_len;
1260 size_t max_len;
1262 switch (cli->auth->auth_level) {
1263 case DCERPC_AUTH_LEVEL_NONE:
1264 case DCERPC_AUTH_LEVEL_CONNECT:
1265 case DCERPC_AUTH_LEVEL_PACKET:
1266 data_space = cli->max_xmit_frag - DCERPC_REQUEST_LENGTH;
1267 data_len = MIN(data_space, data_left);
1268 *p_ss_padding = 0;
1269 *p_auth_len = 0;
1270 *p_frag_len = DCERPC_REQUEST_LENGTH + data_len;
1271 *data_to_send = data_len;
1272 return NT_STATUS_OK;
1274 case DCERPC_AUTH_LEVEL_INTEGRITY:
1275 case DCERPC_AUTH_LEVEL_PRIVACY:
1276 max_len = cli->max_xmit_frag
1277 - DCERPC_REQUEST_LENGTH
1278 - DCERPC_AUTH_TRAILER_LENGTH;
1280 /* Treat the same for all authenticated rpc requests. */
1281 switch(cli->auth->auth_type) {
1282 case DCERPC_AUTH_TYPE_SPNEGO:
1283 switch (cli->auth->spnego_type) {
1284 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
1285 *p_auth_len = NTLMSSP_SIG_SIZE;
1286 break;
1287 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
1288 *p_auth_len = 0; /* TODO */
1289 break;
1290 default:
1291 return NT_STATUS_INVALID_PARAMETER;
1293 case DCERPC_AUTH_TYPE_NTLMSSP:
1294 *p_auth_len = NTLMSSP_SIG_SIZE;
1295 break;
1296 case DCERPC_AUTH_TYPE_SCHANNEL:
1297 *p_auth_len = NL_AUTH_SIGNATURE_SIZE;
1298 break;
1299 case DCERPC_AUTH_TYPE_KRB5:
1300 *p_auth_len = gse_get_signature_length(
1301 cli->auth->a_u.gssapi_state,
1302 (cli->auth->auth_level ==
1303 DCERPC_AUTH_LEVEL_PRIVACY),
1304 max_len);
1305 break;
1306 default:
1307 return NT_STATUS_INVALID_PARAMETER;
1310 data_space = max_len - *p_auth_len;
1312 data_len = MIN(data_space, data_left);
1313 *p_ss_padding = 0;
1314 if (data_len % CLIENT_NDR_PADDING_SIZE) {
1315 *p_ss_padding = CLIENT_NDR_PADDING_SIZE - (data_len % CLIENT_NDR_PADDING_SIZE);
1317 *p_frag_len = DCERPC_REQUEST_LENGTH
1318 + data_len + *p_ss_padding
1319 + DCERPC_AUTH_TRAILER_LENGTH
1320 + *p_auth_len;
1321 *data_to_send = data_len;
1322 return NT_STATUS_OK;
1324 default:
1325 break;
1328 return NT_STATUS_INVALID_PARAMETER;
1331 /*******************************************************************
1332 External interface.
1333 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1334 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1335 and deals with signing/sealing details.
1336 ********************************************************************/
1338 struct rpc_api_pipe_req_state {
1339 struct event_context *ev;
1340 struct rpc_pipe_client *cli;
1341 uint8_t op_num;
1342 uint32_t call_id;
1343 DATA_BLOB *req_data;
1344 uint32_t req_data_sent;
1345 DATA_BLOB rpc_out;
1346 DATA_BLOB reply_pdu;
1349 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1350 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1351 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1352 bool *is_last_frag);
1354 struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1355 struct event_context *ev,
1356 struct rpc_pipe_client *cli,
1357 uint8_t op_num,
1358 DATA_BLOB *req_data)
1360 struct tevent_req *req, *subreq;
1361 struct rpc_api_pipe_req_state *state;
1362 NTSTATUS status;
1363 bool is_last_frag;
1365 req = tevent_req_create(mem_ctx, &state,
1366 struct rpc_api_pipe_req_state);
1367 if (req == NULL) {
1368 return NULL;
1370 state->ev = ev;
1371 state->cli = cli;
1372 state->op_num = op_num;
1373 state->req_data = req_data;
1374 state->req_data_sent = 0;
1375 state->call_id = get_rpc_call_id();
1376 state->reply_pdu = data_blob_null;
1377 state->rpc_out = data_blob_null;
1379 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1380 + RPC_MAX_SIGN_SIZE) {
1381 /* Server is screwed up ! */
1382 status = NT_STATUS_INVALID_PARAMETER;
1383 goto post_status;
1386 status = prepare_next_frag(state, &is_last_frag);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 goto post_status;
1391 if (is_last_frag) {
1392 subreq = rpc_api_pipe_send(state, ev, state->cli,
1393 &state->rpc_out,
1394 DCERPC_PKT_RESPONSE);
1395 if (subreq == NULL) {
1396 goto fail;
1398 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1399 } else {
1400 subreq = rpc_write_send(state, ev, cli->transport,
1401 state->rpc_out.data,
1402 state->rpc_out.length);
1403 if (subreq == NULL) {
1404 goto fail;
1406 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1407 req);
1409 return req;
1411 post_status:
1412 tevent_req_nterror(req, status);
1413 return tevent_req_post(req, ev);
1414 fail:
1415 TALLOC_FREE(req);
1416 return NULL;
1419 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1420 bool *is_last_frag)
1422 uint32_t data_sent_thistime;
1423 uint16_t auth_len;
1424 uint16_t frag_len;
1425 uint8_t flags = 0;
1426 uint32_t pad_len;
1427 uint32_t data_left;
1428 NTSTATUS status;
1429 union dcerpc_payload u;
1431 data_left = state->req_data->length - state->req_data_sent;
1433 status = calculate_data_len_tosend(state->cli, data_left,
1434 &data_sent_thistime,
1435 &frag_len, &auth_len,
1436 &pad_len);
1437 if (!NT_STATUS_IS_OK(status)) {
1438 return status;
1441 if (state->req_data_sent == 0) {
1442 flags = DCERPC_PFC_FLAG_FIRST;
1445 if (data_sent_thistime == data_left) {
1446 flags |= DCERPC_PFC_FLAG_LAST;
1449 data_blob_free(&state->rpc_out);
1451 ZERO_STRUCT(u.request);
1453 u.request.alloc_hint = state->req_data->length;
1454 u.request.context_id = 0;
1455 u.request.opnum = state->op_num;
1457 status = dcerpc_push_ncacn_packet(state,
1458 DCERPC_PKT_REQUEST,
1459 flags,
1460 auth_len,
1461 state->call_id,
1463 &state->rpc_out);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 return status;
1468 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1469 * compute it right for requests because the auth trailer is missing
1470 * at this stage */
1471 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1473 /* Copy in the data. */
1474 if (!data_blob_append(NULL, &state->rpc_out,
1475 state->req_data->data + state->req_data_sent,
1476 data_sent_thistime)) {
1477 return NT_STATUS_NO_MEMORY;
1480 switch (state->cli->auth->auth_level) {
1481 case DCERPC_AUTH_LEVEL_NONE:
1482 case DCERPC_AUTH_LEVEL_CONNECT:
1483 case DCERPC_AUTH_LEVEL_PACKET:
1484 break;
1485 case DCERPC_AUTH_LEVEL_INTEGRITY:
1486 case DCERPC_AUTH_LEVEL_PRIVACY:
1487 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1488 &state->rpc_out);
1489 if (!NT_STATUS_IS_OK(status)) {
1490 return status;
1492 break;
1493 default:
1494 return NT_STATUS_INVALID_PARAMETER;
1497 state->req_data_sent += data_sent_thistime;
1498 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1500 return status;
1503 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1505 struct tevent_req *req = tevent_req_callback_data(
1506 subreq, struct tevent_req);
1507 struct rpc_api_pipe_req_state *state = tevent_req_data(
1508 req, struct rpc_api_pipe_req_state);
1509 NTSTATUS status;
1510 bool is_last_frag;
1512 status = rpc_write_recv(subreq);
1513 TALLOC_FREE(subreq);
1514 if (!NT_STATUS_IS_OK(status)) {
1515 tevent_req_nterror(req, status);
1516 return;
1519 status = prepare_next_frag(state, &is_last_frag);
1520 if (!NT_STATUS_IS_OK(status)) {
1521 tevent_req_nterror(req, status);
1522 return;
1525 if (is_last_frag) {
1526 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1527 &state->rpc_out,
1528 DCERPC_PKT_RESPONSE);
1529 if (tevent_req_nomem(subreq, req)) {
1530 return;
1532 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1533 } else {
1534 subreq = rpc_write_send(state, state->ev,
1535 state->cli->transport,
1536 state->rpc_out.data,
1537 state->rpc_out.length);
1538 if (tevent_req_nomem(subreq, req)) {
1539 return;
1541 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1542 req);
1546 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1548 struct tevent_req *req = tevent_req_callback_data(
1549 subreq, struct tevent_req);
1550 struct rpc_api_pipe_req_state *state = tevent_req_data(
1551 req, struct rpc_api_pipe_req_state);
1552 NTSTATUS status;
1554 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1555 TALLOC_FREE(subreq);
1556 if (!NT_STATUS_IS_OK(status)) {
1557 tevent_req_nterror(req, status);
1558 return;
1560 tevent_req_done(req);
1563 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1564 DATA_BLOB *reply_pdu)
1566 struct rpc_api_pipe_req_state *state = tevent_req_data(
1567 req, struct rpc_api_pipe_req_state);
1568 NTSTATUS status;
1570 if (tevent_req_is_nterror(req, &status)) {
1572 * We always have to initialize to reply pdu, even if there is
1573 * none. The rpccli_* caller routines expect this.
1575 *reply_pdu = data_blob_null;
1576 return status;
1579 /* return data to caller and assign it ownership of memory */
1580 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1581 reply_pdu->length = state->reply_pdu.length;
1582 state->reply_pdu.length = 0;
1584 return NT_STATUS_OK;
1587 #if 0
1588 /****************************************************************************
1589 Set the handle state.
1590 ****************************************************************************/
1592 static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli,
1593 const char *pipe_name, uint16 device_state)
1595 bool state_set = False;
1596 char param[2];
1597 uint16 setup[2]; /* only need 2 uint16 setup parameters */
1598 char *rparam = NULL;
1599 char *rdata = NULL;
1600 uint32 rparam_len, rdata_len;
1602 if (pipe_name == NULL)
1603 return False;
1605 DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
1606 cli->fnum, pipe_name, device_state));
1608 /* create parameters: device state */
1609 SSVAL(param, 0, device_state);
1611 /* create setup parameters. */
1612 setup[0] = 0x0001;
1613 setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */
1615 /* send the data on \PIPE\ */
1616 if (cli_api_pipe(cli->cli, "\\PIPE\\",
1617 setup, 2, 0, /* setup, length, max */
1618 param, 2, 0, /* param, length, max */
1619 NULL, 0, 1024, /* data, length, max */
1620 &rparam, &rparam_len, /* return param, length */
1621 &rdata, &rdata_len)) /* return data, length */
1623 DEBUG(5, ("Set Handle state: return OK\n"));
1624 state_set = True;
1627 SAFE_FREE(rparam);
1628 SAFE_FREE(rdata);
1630 return state_set;
1632 #endif
1634 /****************************************************************************
1635 Check the rpc bind acknowledge response.
1636 ****************************************************************************/
1638 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1639 const struct ndr_syntax_id *transfer)
1641 struct dcerpc_ack_ctx ctx;
1643 if (r->secondary_address_size == 0) {
1644 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1647 if (r->num_results < 1 || !r->ctx_list) {
1648 return false;
1651 ctx = r->ctx_list[0];
1653 /* check the transfer syntax */
1654 if ((ctx.syntax.if_version != transfer->if_version) ||
1655 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1656 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1657 return False;
1660 if (r->num_results != 0x1 || ctx.result != 0) {
1661 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1662 r->num_results, ctx.reason));
1665 DEBUG(5,("check_bind_response: accepted!\n"));
1666 return True;
1669 /*******************************************************************
1670 Creates a DCE/RPC bind authentication response.
1671 This is the packet that is sent back to the server once we
1672 have received a BIND-ACK, to finish the third leg of
1673 the authentication handshake.
1674 ********************************************************************/
1676 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1677 struct rpc_pipe_client *cli,
1678 uint32 rpc_call_id,
1679 enum dcerpc_AuthType auth_type,
1680 enum dcerpc_AuthLevel auth_level,
1681 DATA_BLOB *pauth_blob,
1682 DATA_BLOB *rpc_out)
1684 NTSTATUS status;
1685 union dcerpc_payload u;
1687 u.auth3._pad = 0;
1689 status = dcerpc_push_dcerpc_auth(mem_ctx,
1690 auth_type,
1691 auth_level,
1692 0, /* auth_pad_length */
1693 1, /* auth_context_id */
1694 pauth_blob,
1695 &u.auth3.auth_info);
1696 if (!NT_STATUS_IS_OK(status)) {
1697 return status;
1700 status = dcerpc_push_ncacn_packet(mem_ctx,
1701 DCERPC_PKT_AUTH3,
1702 DCERPC_PFC_FLAG_FIRST |
1703 DCERPC_PFC_FLAG_LAST,
1704 pauth_blob->length,
1705 rpc_call_id,
1707 rpc_out);
1708 data_blob_free(&u.auth3.auth_info);
1709 if (!NT_STATUS_IS_OK(status)) {
1710 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1711 return status;
1714 return NT_STATUS_OK;
1717 /*******************************************************************
1718 Creates a DCE/RPC bind alter context authentication request which
1719 may contain a spnego auth blobl
1720 ********************************************************************/
1722 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1723 enum dcerpc_AuthType auth_type,
1724 enum dcerpc_AuthLevel auth_level,
1725 uint32 rpc_call_id,
1726 const struct ndr_syntax_id *abstract,
1727 const struct ndr_syntax_id *transfer,
1728 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1729 DATA_BLOB *rpc_out)
1731 DATA_BLOB auth_info;
1732 NTSTATUS status;
1734 status = dcerpc_push_dcerpc_auth(mem_ctx,
1735 auth_type,
1736 auth_level,
1737 0, /* auth_pad_length */
1738 1, /* auth_context_id */
1739 pauth_blob,
1740 &auth_info);
1741 if (!NT_STATUS_IS_OK(status)) {
1742 return status;
1745 status = create_bind_or_alt_ctx_internal(mem_ctx,
1746 DCERPC_PKT_ALTER,
1747 rpc_call_id,
1748 abstract,
1749 transfer,
1750 &auth_info,
1751 rpc_out);
1752 data_blob_free(&auth_info);
1753 return status;
1756 /****************************************************************************
1757 Do an rpc bind.
1758 ****************************************************************************/
1760 struct rpc_pipe_bind_state {
1761 struct event_context *ev;
1762 struct rpc_pipe_client *cli;
1763 DATA_BLOB rpc_out;
1764 uint32_t rpc_call_id;
1767 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1768 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1769 struct rpc_pipe_bind_state *state,
1770 DATA_BLOB *credentials);
1771 static void rpc_bind_auth3_write_done(struct tevent_req *subreq);
1772 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
1773 struct rpc_pipe_bind_state *state,
1774 DATA_BLOB *credentials);
1775 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq);
1776 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1777 struct rpc_pipe_bind_state *state,
1778 DATA_BLOB *credentials);
1779 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1780 struct rpc_pipe_bind_state *state,
1781 DATA_BLOB *credentials);
1783 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1784 struct event_context *ev,
1785 struct rpc_pipe_client *cli,
1786 struct pipe_auth_data *auth)
1788 struct tevent_req *req, *subreq;
1789 struct rpc_pipe_bind_state *state;
1790 NTSTATUS status;
1792 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1793 if (req == NULL) {
1794 return NULL;
1797 DEBUG(5,("Bind RPC Pipe: %s auth_type %u(%u), auth_level %u\n",
1798 rpccli_pipe_txt(talloc_tos(), cli),
1799 (unsigned int)auth->auth_type,
1800 (unsigned int)auth->spnego_type,
1801 (unsigned int)auth->auth_level ));
1803 state->ev = ev;
1804 state->cli = cli;
1805 state->rpc_call_id = get_rpc_call_id();
1806 state->rpc_out = data_blob_null;
1808 cli->auth = talloc_move(cli, &auth);
1810 /* Marshall the outgoing data. */
1811 status = create_rpc_bind_req(state, cli,
1812 cli->auth,
1813 state->rpc_call_id,
1814 &cli->abstract_syntax,
1815 &cli->transfer_syntax,
1816 &state->rpc_out);
1818 if (!NT_STATUS_IS_OK(status)) {
1819 goto post_status;
1822 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1823 DCERPC_PKT_BIND_ACK);
1824 if (subreq == NULL) {
1825 goto fail;
1827 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1828 return req;
1830 post_status:
1831 tevent_req_nterror(req, status);
1832 return tevent_req_post(req, ev);
1833 fail:
1834 TALLOC_FREE(req);
1835 return NULL;
1838 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1840 struct tevent_req *req = tevent_req_callback_data(
1841 subreq, struct tevent_req);
1842 struct rpc_pipe_bind_state *state = tevent_req_data(
1843 req, struct rpc_pipe_bind_state);
1844 struct pipe_auth_data *pauth = state->cli->auth;
1845 DATA_BLOB reply_pdu;
1846 struct ncacn_packet *pkt;
1847 struct dcerpc_auth auth;
1848 DATA_BLOB auth_token = data_blob_null;
1849 NTSTATUS status;
1851 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu);
1852 TALLOC_FREE(subreq);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1855 rpccli_pipe_txt(talloc_tos(), state->cli),
1856 nt_errstr(status)));
1857 tevent_req_nterror(req, status);
1858 return;
1861 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1862 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1863 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1864 return;
1867 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1868 state->cli->max_recv_frag = pkt->u.bind_ack.max_recv_frag;
1870 switch(state->cli->auth->auth_type) {
1872 case DCERPC_AUTH_TYPE_NONE:
1873 case DCERPC_AUTH_TYPE_SCHANNEL:
1874 /* Bind complete. */
1875 tevent_req_done(req);
1876 return;
1878 case DCERPC_AUTH_TYPE_NTLMSSP:
1879 case DCERPC_AUTH_TYPE_SPNEGO:
1880 case DCERPC_AUTH_TYPE_KRB5:
1881 /* Paranoid lenght checks */
1882 if (pkt->frag_length < DCERPC_AUTH_TRAILER_LENGTH
1883 + pkt->auth_length) {
1884 tevent_req_nterror(req,
1885 NT_STATUS_INFO_LENGTH_MISMATCH);
1886 return;
1888 /* get auth credentials */
1889 status = dcerpc_pull_dcerpc_auth(talloc_tos(),
1890 &pkt->u.bind_ack.auth_info,
1891 &auth, false);
1892 if (!NT_STATUS_IS_OK(status)) {
1893 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1894 nt_errstr(status)));
1895 tevent_req_nterror(req, status);
1896 return;
1898 break;
1900 default:
1901 goto err_out;
1905 * For authenticated binds we may need to do 3 or 4 leg binds.
1908 switch(state->cli->auth->auth_type) {
1910 case DCERPC_AUTH_TYPE_NONE:
1911 case DCERPC_AUTH_TYPE_SCHANNEL:
1912 /* Bind complete. */
1913 tevent_req_done(req);
1914 return;
1916 case DCERPC_AUTH_TYPE_NTLMSSP:
1917 /* Need to send AUTH3 packet - no reply. */
1918 status = rpc_finish_auth3_bind_send(req, state,
1919 &auth.credentials);
1920 break;
1922 case DCERPC_AUTH_TYPE_SPNEGO:
1923 if (state->cli->auth->spnego_type !=
1924 PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1925 goto err_out;
1927 /* Need to send alter context request and reply. */
1928 status = rpc_finish_spnego_ntlmssp_bind_send(req, state,
1929 &auth.credentials);
1930 break;
1932 case DCERPC_AUTH_TYPE_KRB5:
1933 status = gse_get_client_auth_token(state,
1934 pauth->a_u.gssapi_state,
1935 &auth.credentials,
1936 &auth_token);
1937 if (!NT_STATUS_IS_OK(status)) {
1938 break;
1941 if (gse_require_more_processing(pauth->a_u.gssapi_state)) {
1942 status = rpc_bind_next_send(req, state, &auth_token);
1943 } else {
1944 status = rpc_bind_finish_send(req, state, &auth_token);
1946 break;
1948 default:
1949 goto err_out;
1952 if (!NT_STATUS_IS_OK(status)) {
1953 tevent_req_nterror(req, status);
1955 return;
1957 err_out:
1958 DEBUG(0,("cli_finish_bind_auth: unknown auth type %u(%u)\n",
1959 (unsigned int)state->cli->auth->auth_type,
1960 (unsigned int)state->cli->auth->spnego_type));
1961 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
1964 static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req,
1965 struct rpc_pipe_bind_state *state,
1966 DATA_BLOB *credentials)
1968 struct pipe_auth_data *auth = state->cli->auth;
1969 DATA_BLOB client_reply = data_blob_null;
1970 struct tevent_req *subreq;
1971 NTSTATUS status;
1973 /* TODO - check auth_type/auth_level match. */
1975 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
1976 *credentials, &client_reply);
1978 if (!NT_STATUS_IS_OK(status)) {
1979 DEBUG(0, ("rpc_finish_auth3_bind: NTLMSSP update using server "
1980 "blob failed: %s.\n", nt_errstr(status)));
1981 return status;
1984 data_blob_free(&state->rpc_out);
1986 status = create_rpc_bind_auth3(state, state->cli,
1987 state->rpc_call_id,
1988 auth->auth_type,
1989 auth->auth_level,
1990 &client_reply,
1991 &state->rpc_out);
1992 data_blob_free(&client_reply);
1994 if (!NT_STATUS_IS_OK(status)) {
1995 return status;
1998 subreq = rpc_write_send(state, state->ev, state->cli->transport,
1999 state->rpc_out.data, state->rpc_out.length);
2000 if (subreq == NULL) {
2001 return NT_STATUS_NO_MEMORY;
2003 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2004 return NT_STATUS_OK;
2007 static void rpc_bind_auth3_write_done(struct tevent_req *subreq)
2009 struct tevent_req *req = tevent_req_callback_data(
2010 subreq, struct tevent_req);
2011 NTSTATUS status;
2013 status = rpc_write_recv(subreq);
2014 TALLOC_FREE(subreq);
2015 if (!NT_STATUS_IS_OK(status)) {
2016 tevent_req_nterror(req, status);
2017 return;
2019 tevent_req_done(req);
2022 static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req,
2023 struct rpc_pipe_bind_state *state,
2024 DATA_BLOB *credentials)
2026 struct pipe_auth_data *auth = state->cli->auth;
2027 DATA_BLOB server_ntlm_response = data_blob_null;
2028 DATA_BLOB client_reply = data_blob_null;
2029 DATA_BLOB tmp_blob = data_blob_null;
2030 struct tevent_req *subreq;
2031 NTSTATUS status;
2034 * The server might give us back two challenges - tmp_blob is for the
2035 * second.
2037 if (!spnego_parse_challenge(state, *credentials,
2038 &server_ntlm_response,
2039 &tmp_blob)) {
2040 data_blob_free(&server_ntlm_response);
2041 data_blob_free(&tmp_blob);
2042 return NT_STATUS_INVALID_PARAMETER;
2045 /* We're finished with the server spnego response and the tmp_blob. */
2046 data_blob_free(&tmp_blob);
2048 status = auth_ntlmssp_update(auth->a_u.auth_ntlmssp_state,
2049 server_ntlm_response, &client_reply);
2051 /* Finished with the server_ntlm response */
2052 data_blob_free(&server_ntlm_response);
2054 if (!NT_STATUS_IS_OK(status)) {
2055 DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: NTLMSSP update "
2056 "using server blob failed.\n"));
2057 data_blob_free(&client_reply);
2058 return status;
2061 /* SPNEGO wrap the client reply. */
2062 tmp_blob = spnego_gen_auth(state, client_reply);
2063 data_blob_free(&client_reply);
2064 client_reply = tmp_blob;
2065 tmp_blob = data_blob_null;
2067 /* Now prepare the alter context pdu. */
2068 data_blob_free(&state->rpc_out);
2070 status = create_rpc_alter_context(state,
2071 auth->auth_type,
2072 auth->auth_level,
2073 state->rpc_call_id,
2074 &state->cli->abstract_syntax,
2075 &state->cli->transfer_syntax,
2076 &client_reply,
2077 &state->rpc_out);
2078 data_blob_free(&client_reply);
2080 if (!NT_STATUS_IS_OK(status)) {
2081 return status;
2084 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2085 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2086 if (subreq == NULL) {
2087 return NT_STATUS_NO_MEMORY;
2089 tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req);
2090 return NT_STATUS_OK;
2093 static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq)
2095 struct tevent_req *req = tevent_req_callback_data(
2096 subreq, struct tevent_req);
2097 struct rpc_pipe_bind_state *state = tevent_req_data(
2098 req, struct rpc_pipe_bind_state);
2099 DATA_BLOB tmp_blob = data_blob_null;
2100 struct ncacn_packet *pkt;
2101 struct dcerpc_auth auth;
2102 NTSTATUS status;
2104 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2105 TALLOC_FREE(subreq);
2106 if (!NT_STATUS_IS_OK(status)) {
2107 tevent_req_nterror(req, status);
2108 return;
2111 status = dcerpc_pull_dcerpc_auth(pkt,
2112 &pkt->u.alter_resp.auth_info,
2113 &auth, false);
2114 if (!NT_STATUS_IS_OK(status)) {
2115 tevent_req_nterror(req, status);
2116 return;
2119 /* Check we got a valid auth response. */
2120 if (!spnego_parse_auth_response(talloc_tos(), auth.credentials,
2121 NT_STATUS_OK,
2122 OID_NTLMSSP, &tmp_blob)) {
2123 data_blob_free(&tmp_blob);
2124 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
2125 return;
2128 data_blob_free(&tmp_blob);
2130 DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to "
2131 "%s.\n", rpccli_pipe_txt(talloc_tos(), state->cli)));
2132 tevent_req_done(req);
2135 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2136 struct rpc_pipe_bind_state *state,
2137 DATA_BLOB *auth_token)
2139 struct pipe_auth_data *auth = state->cli->auth;
2140 struct tevent_req *subreq;
2141 NTSTATUS status;
2143 /* Now prepare the alter context pdu. */
2144 data_blob_free(&state->rpc_out);
2146 status = create_rpc_alter_context(state,
2147 auth->auth_type,
2148 auth->auth_level,
2149 state->rpc_call_id,
2150 &state->cli->abstract_syntax,
2151 &state->cli->transfer_syntax,
2152 auth_token,
2153 &state->rpc_out);
2154 if (!NT_STATUS_IS_OK(status)) {
2155 return status;
2158 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2159 &state->rpc_out, DCERPC_PKT_ALTER_RESP);
2160 if (subreq == NULL) {
2161 return NT_STATUS_NO_MEMORY;
2163 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2164 return NT_STATUS_OK;
2167 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2168 struct rpc_pipe_bind_state *state,
2169 DATA_BLOB *auth_token)
2171 struct pipe_auth_data *auth = state->cli->auth;
2172 struct tevent_req *subreq;
2173 NTSTATUS status;
2175 /* Now prepare the auth3 context pdu. */
2176 data_blob_free(&state->rpc_out);
2178 status = create_rpc_bind_auth3(state, state->cli,
2179 state->rpc_call_id,
2180 auth->auth_type,
2181 auth->auth_level,
2182 auth_token,
2183 &state->rpc_out);
2184 if (!NT_STATUS_IS_OK(status)) {
2185 return status;
2188 subreq = rpc_write_send(state, state->ev, state->cli->transport,
2189 state->rpc_out.data, state->rpc_out.length);
2190 if (subreq == NULL) {
2191 return NT_STATUS_NO_MEMORY;
2193 tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req);
2194 return NT_STATUS_OK;
2197 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2199 return tevent_req_simple_recv_ntstatus(req);
2202 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2203 struct pipe_auth_data *auth)
2205 TALLOC_CTX *frame = talloc_stackframe();
2206 struct event_context *ev;
2207 struct tevent_req *req;
2208 NTSTATUS status = NT_STATUS_OK;
2210 ev = event_context_init(frame);
2211 if (ev == NULL) {
2212 status = NT_STATUS_NO_MEMORY;
2213 goto fail;
2216 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2217 if (req == NULL) {
2218 status = NT_STATUS_NO_MEMORY;
2219 goto fail;
2222 if (!tevent_req_poll(req, ev)) {
2223 status = map_nt_error_from_unix(errno);
2224 goto fail;
2227 status = rpc_pipe_bind_recv(req);
2228 fail:
2229 TALLOC_FREE(frame);
2230 return status;
2233 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2235 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2236 unsigned int timeout)
2238 unsigned int old;
2240 if (rpc_cli->transport == NULL) {
2241 return RPCCLI_DEFAULT_TIMEOUT;
2244 if (rpc_cli->transport->set_timeout == NULL) {
2245 return RPCCLI_DEFAULT_TIMEOUT;
2248 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2249 if (old == 0) {
2250 return RPCCLI_DEFAULT_TIMEOUT;
2253 return old;
2256 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2258 if (rpc_cli == NULL) {
2259 return false;
2262 if (rpc_cli->transport == NULL) {
2263 return false;
2266 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2269 bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
2271 struct cli_state *cli;
2273 if ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_NTLMSSP)
2274 || ((rpc_cli->auth->auth_type == DCERPC_AUTH_TYPE_SPNEGO
2275 && rpc_cli->auth->spnego_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) {
2276 memcpy(nt_hash, auth_ntlmssp_get_nt_hash(rpc_cli->auth->a_u.auth_ntlmssp_state), 16);
2277 return true;
2280 cli = rpc_pipe_np_smb_conn(rpc_cli);
2281 if (cli == NULL) {
2282 return false;
2284 E_md4hash(cli->password ? cli->password : "", nt_hash);
2285 return true;
2288 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2289 struct pipe_auth_data **presult)
2291 struct pipe_auth_data *result;
2293 result = talloc(mem_ctx, struct pipe_auth_data);
2294 if (result == NULL) {
2295 return NT_STATUS_NO_MEMORY;
2298 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2299 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2300 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2302 result->user_name = talloc_strdup(result, "");
2303 result->domain = talloc_strdup(result, "");
2304 if ((result->user_name == NULL) || (result->domain == NULL)) {
2305 TALLOC_FREE(result);
2306 return NT_STATUS_NO_MEMORY;
2309 *presult = result;
2310 return NT_STATUS_OK;
2313 static int cli_auth_ntlmssp_data_destructor(struct pipe_auth_data *auth)
2315 TALLOC_FREE(auth->a_u.auth_ntlmssp_state);
2316 return 0;
2319 static NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx,
2320 enum dcerpc_AuthType auth_type,
2321 enum pipe_auth_type_spnego spnego_type,
2322 enum dcerpc_AuthLevel auth_level,
2323 const char *domain,
2324 const char *username,
2325 const char *password,
2326 struct pipe_auth_data **presult)
2328 struct pipe_auth_data *result;
2329 NTSTATUS status;
2331 result = talloc(mem_ctx, struct pipe_auth_data);
2332 if (result == NULL) {
2333 return NT_STATUS_NO_MEMORY;
2336 result->auth_type = auth_type;
2337 result->spnego_type = spnego_type;
2338 result->auth_level = auth_level;
2340 result->user_name = talloc_strdup(result, username);
2341 result->domain = talloc_strdup(result, domain);
2342 if ((result->user_name == NULL) || (result->domain == NULL)) {
2343 status = NT_STATUS_NO_MEMORY;
2344 goto fail;
2347 status = auth_ntlmssp_client_start(NULL,
2348 global_myname(),
2349 lp_workgroup(),
2350 lp_client_ntlmv2_auth(),
2351 &result->a_u.auth_ntlmssp_state);
2352 if (!NT_STATUS_IS_OK(status)) {
2353 goto fail;
2356 talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor);
2358 status = auth_ntlmssp_set_username(result->a_u.auth_ntlmssp_state,
2359 username);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 goto fail;
2364 status = auth_ntlmssp_set_domain(result->a_u.auth_ntlmssp_state,
2365 domain);
2366 if (!NT_STATUS_IS_OK(status)) {
2367 goto fail;
2370 status = auth_ntlmssp_set_password(result->a_u.auth_ntlmssp_state,
2371 password);
2372 if (!NT_STATUS_IS_OK(status)) {
2373 goto fail;
2377 * Turn off sign+seal to allow selected auth level to turn it back on.
2379 auth_ntlmssp_and_flags(result->a_u.auth_ntlmssp_state,
2380 ~(NTLMSSP_NEGOTIATE_SIGN |
2381 NTLMSSP_NEGOTIATE_SEAL));
2383 if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
2384 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2385 NTLMSSP_NEGOTIATE_SIGN);
2386 } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
2387 auth_ntlmssp_or_flags(result->a_u.auth_ntlmssp_state,
2388 NTLMSSP_NEGOTIATE_SEAL |
2389 NTLMSSP_NEGOTIATE_SIGN);
2392 *presult = result;
2393 return NT_STATUS_OK;
2395 fail:
2396 TALLOC_FREE(result);
2397 return status;
2400 NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
2401 enum dcerpc_AuthLevel auth_level,
2402 struct netlogon_creds_CredentialState *creds,
2403 struct pipe_auth_data **presult)
2405 struct pipe_auth_data *result;
2407 result = talloc(mem_ctx, struct pipe_auth_data);
2408 if (result == NULL) {
2409 return NT_STATUS_NO_MEMORY;
2412 result->auth_type = DCERPC_AUTH_TYPE_SCHANNEL;
2413 result->spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2414 result->auth_level = auth_level;
2416 result->user_name = talloc_strdup(result, "");
2417 result->domain = talloc_strdup(result, domain);
2418 if ((result->user_name == NULL) || (result->domain == NULL)) {
2419 goto fail;
2422 result->a_u.schannel_auth = talloc(result, struct schannel_state);
2423 if (result->a_u.schannel_auth == NULL) {
2424 goto fail;
2427 result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
2428 result->a_u.schannel_auth->seq_num = 0;
2429 result->a_u.schannel_auth->initiator = true;
2430 result->a_u.schannel_auth->creds = creds;
2432 *presult = result;
2433 return NT_STATUS_OK;
2435 fail:
2436 TALLOC_FREE(result);
2437 return NT_STATUS_NO_MEMORY;
2441 * Create an rpc pipe client struct, connecting to a tcp port.
2443 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2444 uint16_t port,
2445 const struct ndr_syntax_id *abstract_syntax,
2446 struct rpc_pipe_client **presult)
2448 struct rpc_pipe_client *result;
2449 struct sockaddr_storage addr;
2450 NTSTATUS status;
2451 int fd;
2453 result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client);
2454 if (result == NULL) {
2455 return NT_STATUS_NO_MEMORY;
2458 result->abstract_syntax = *abstract_syntax;
2459 result->transfer_syntax = ndr_transfer_syntax;
2460 result->dispatch = cli_do_rpc_ndr;
2461 result->dispatch_send = cli_do_rpc_ndr_send;
2462 result->dispatch_recv = cli_do_rpc_ndr_recv;
2464 result->desthost = talloc_strdup(result, host);
2465 result->srv_name_slash = talloc_asprintf_strupper_m(
2466 result, "\\\\%s", result->desthost);
2467 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2468 status = NT_STATUS_NO_MEMORY;
2469 goto fail;
2472 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2473 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2475 if (!resolve_name(host, &addr, 0, false)) {
2476 status = NT_STATUS_NOT_FOUND;
2477 goto fail;
2480 status = open_socket_out(&addr, port, 60, &fd);
2481 if (!NT_STATUS_IS_OK(status)) {
2482 goto fail;
2484 set_socket_options(fd, lp_socket_options());
2486 status = rpc_transport_sock_init(result, fd, &result->transport);
2487 if (!NT_STATUS_IS_OK(status)) {
2488 close(fd);
2489 goto fail;
2492 result->transport->transport = NCACN_IP_TCP;
2494 *presult = result;
2495 return NT_STATUS_OK;
2497 fail:
2498 TALLOC_FREE(result);
2499 return status;
2503 * Determine the tcp port on which a dcerpc interface is listening
2504 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2505 * target host.
2507 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2508 const struct ndr_syntax_id *abstract_syntax,
2509 uint16_t *pport)
2511 NTSTATUS status;
2512 struct rpc_pipe_client *epm_pipe = NULL;
2513 struct pipe_auth_data *auth = NULL;
2514 struct dcerpc_binding *map_binding = NULL;
2515 struct dcerpc_binding *res_binding = NULL;
2516 struct epm_twr_t *map_tower = NULL;
2517 struct epm_twr_t *res_towers = NULL;
2518 struct policy_handle *entry_handle = NULL;
2519 uint32_t num_towers = 0;
2520 uint32_t max_towers = 1;
2521 struct epm_twr_p_t towers;
2522 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2524 if (pport == NULL) {
2525 status = NT_STATUS_INVALID_PARAMETER;
2526 goto done;
2529 /* open the connection to the endpoint mapper */
2530 status = rpc_pipe_open_tcp_port(tmp_ctx, host, 135,
2531 &ndr_table_epmapper.syntax_id,
2532 &epm_pipe);
2534 if (!NT_STATUS_IS_OK(status)) {
2535 goto done;
2538 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2539 if (!NT_STATUS_IS_OK(status)) {
2540 goto done;
2543 status = rpc_pipe_bind(epm_pipe, auth);
2544 if (!NT_STATUS_IS_OK(status)) {
2545 goto done;
2548 /* create tower for asking the epmapper */
2550 map_binding = TALLOC_ZERO_P(tmp_ctx, struct dcerpc_binding);
2551 if (map_binding == NULL) {
2552 status = NT_STATUS_NO_MEMORY;
2553 goto done;
2556 map_binding->transport = NCACN_IP_TCP;
2557 map_binding->object = *abstract_syntax;
2558 map_binding->host = host; /* needed? */
2559 map_binding->endpoint = "0"; /* correct? needed? */
2561 map_tower = TALLOC_ZERO_P(tmp_ctx, struct epm_twr_t);
2562 if (map_tower == NULL) {
2563 status = NT_STATUS_NO_MEMORY;
2564 goto done;
2567 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2568 &(map_tower->tower));
2569 if (!NT_STATUS_IS_OK(status)) {
2570 goto done;
2573 /* allocate further parameters for the epm_Map call */
2575 res_towers = TALLOC_ARRAY(tmp_ctx, struct epm_twr_t, max_towers);
2576 if (res_towers == NULL) {
2577 status = NT_STATUS_NO_MEMORY;
2578 goto done;
2580 towers.twr = res_towers;
2582 entry_handle = TALLOC_ZERO_P(tmp_ctx, struct policy_handle);
2583 if (entry_handle == NULL) {
2584 status = NT_STATUS_NO_MEMORY;
2585 goto done;
2588 /* ask the endpoint mapper for the port */
2590 status = rpccli_epm_Map(epm_pipe,
2591 tmp_ctx,
2592 CONST_DISCARD(struct GUID *,
2593 &(abstract_syntax->uuid)),
2594 map_tower,
2595 entry_handle,
2596 max_towers,
2597 &num_towers,
2598 &towers);
2600 if (!NT_STATUS_IS_OK(status)) {
2601 goto done;
2604 if (num_towers != 1) {
2605 status = NT_STATUS_UNSUCCESSFUL;
2606 goto done;
2609 /* extract the port from the answer */
2611 status = dcerpc_binding_from_tower(tmp_ctx,
2612 &(towers.twr->tower),
2613 &res_binding);
2614 if (!NT_STATUS_IS_OK(status)) {
2615 goto done;
2618 /* are further checks here necessary? */
2619 if (res_binding->transport != NCACN_IP_TCP) {
2620 status = NT_STATUS_UNSUCCESSFUL;
2621 goto done;
2624 *pport = (uint16_t)atoi(res_binding->endpoint);
2626 done:
2627 TALLOC_FREE(tmp_ctx);
2628 return status;
2632 * Create a rpc pipe client struct, connecting to a host via tcp.
2633 * The port is determined by asking the endpoint mapper on the given
2634 * host.
2636 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2637 const struct ndr_syntax_id *abstract_syntax,
2638 struct rpc_pipe_client **presult)
2640 NTSTATUS status;
2641 uint16_t port = 0;
2643 status = rpc_pipe_get_tcp_port(host, abstract_syntax, &port);
2644 if (!NT_STATUS_IS_OK(status)) {
2645 return status;
2648 return rpc_pipe_open_tcp_port(mem_ctx, host, port,
2649 abstract_syntax, presult);
2652 /********************************************************************
2653 Create a rpc pipe client struct, connecting to a unix domain socket
2654 ********************************************************************/
2655 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2656 const struct ndr_syntax_id *abstract_syntax,
2657 struct rpc_pipe_client **presult)
2659 struct rpc_pipe_client *result;
2660 struct sockaddr_un addr;
2661 NTSTATUS status;
2662 int fd;
2664 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2665 if (result == NULL) {
2666 return NT_STATUS_NO_MEMORY;
2669 result->abstract_syntax = *abstract_syntax;
2670 result->transfer_syntax = ndr_transfer_syntax;
2671 result->dispatch = cli_do_rpc_ndr;
2672 result->dispatch_send = cli_do_rpc_ndr_send;
2673 result->dispatch_recv = cli_do_rpc_ndr_recv;
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 *presult = result;
2712 return NT_STATUS_OK;
2714 fail:
2715 TALLOC_FREE(result);
2716 return status;
2719 struct rpc_pipe_client_np_ref {
2720 struct cli_state *cli;
2721 struct rpc_pipe_client *pipe;
2724 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2726 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2727 return 0;
2730 /****************************************************************************
2731 Open a named pipe over SMB to a remote server.
2733 * CAVEAT CALLER OF THIS FUNCTION:
2734 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2735 * so be sure that this function is called AFTER any structure (vs pointer)
2736 * assignment of the cli. In particular, libsmbclient does structure
2737 * assignments of cli, which invalidates the data in the returned
2738 * rpc_pipe_client if this function is called before the structure assignment
2739 * of cli.
2741 ****************************************************************************/
2743 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2744 const struct ndr_syntax_id *abstract_syntax,
2745 struct rpc_pipe_client **presult)
2747 struct rpc_pipe_client *result;
2748 NTSTATUS status;
2749 struct rpc_pipe_client_np_ref *np_ref;
2751 /* sanity check to protect against crashes */
2753 if ( !cli ) {
2754 return NT_STATUS_INVALID_HANDLE;
2757 result = TALLOC_ZERO_P(NULL, struct rpc_pipe_client);
2758 if (result == NULL) {
2759 return NT_STATUS_NO_MEMORY;
2762 result->abstract_syntax = *abstract_syntax;
2763 result->transfer_syntax = ndr_transfer_syntax;
2764 result->dispatch = cli_do_rpc_ndr;
2765 result->dispatch_send = cli_do_rpc_ndr_send;
2766 result->dispatch_recv = cli_do_rpc_ndr_recv;
2767 result->desthost = talloc_strdup(result, cli->desthost);
2768 result->srv_name_slash = talloc_asprintf_strupper_m(
2769 result, "\\\\%s", result->desthost);
2771 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2772 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2774 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2775 TALLOC_FREE(result);
2776 return NT_STATUS_NO_MEMORY;
2779 status = rpc_transport_np_init(result, cli, abstract_syntax,
2780 &result->transport);
2781 if (!NT_STATUS_IS_OK(status)) {
2782 TALLOC_FREE(result);
2783 return status;
2786 result->transport->transport = NCACN_NP;
2788 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
2789 if (np_ref == NULL) {
2790 TALLOC_FREE(result);
2791 return NT_STATUS_NO_MEMORY;
2793 np_ref->cli = cli;
2794 np_ref->pipe = result;
2796 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
2797 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
2799 *presult = result;
2800 return NT_STATUS_OK;
2803 NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx,
2804 struct rpc_cli_smbd_conn *conn,
2805 const struct ndr_syntax_id *syntax,
2806 struct rpc_pipe_client **presult)
2808 struct rpc_pipe_client *result;
2809 struct pipe_auth_data *auth;
2810 NTSTATUS status;
2812 result = talloc(mem_ctx, struct rpc_pipe_client);
2813 if (result == NULL) {
2814 return NT_STATUS_NO_MEMORY;
2816 result->abstract_syntax = *syntax;
2817 result->transfer_syntax = ndr_transfer_syntax;
2818 result->dispatch = cli_do_rpc_ndr;
2819 result->dispatch_send = cli_do_rpc_ndr_send;
2820 result->dispatch_recv = cli_do_rpc_ndr_recv;
2821 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2822 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
2824 result->desthost = talloc_strdup(result, global_myname());
2825 result->srv_name_slash = talloc_asprintf_strupper_m(
2826 result, "\\\\%s", global_myname());
2827 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2828 TALLOC_FREE(result);
2829 return NT_STATUS_NO_MEMORY;
2832 status = rpc_transport_smbd_init(result, conn, syntax,
2833 &result->transport);
2834 if (!NT_STATUS_IS_OK(status)) {
2835 DEBUG(1, ("rpc_transport_smbd_init failed: %s\n",
2836 nt_errstr(status)));
2837 TALLOC_FREE(result);
2838 return status;
2841 status = rpccli_anon_bind_data(result, &auth);
2842 if (!NT_STATUS_IS_OK(status)) {
2843 DEBUG(1, ("rpccli_anon_bind_data failed: %s\n",
2844 nt_errstr(status)));
2845 TALLOC_FREE(result);
2846 return status;
2849 status = rpc_pipe_bind(result, auth);
2850 if (!NT_STATUS_IS_OK(status)) {
2851 DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status)));
2852 TALLOC_FREE(result);
2853 return status;
2856 result->transport->transport = NCACN_INTERNAL;
2858 *presult = result;
2859 return NT_STATUS_OK;
2862 /****************************************************************************
2863 Open a pipe to a remote server.
2864 ****************************************************************************/
2866 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
2867 enum dcerpc_transport_t transport,
2868 const struct ndr_syntax_id *interface,
2869 struct rpc_pipe_client **presult)
2871 switch (transport) {
2872 case NCACN_IP_TCP:
2873 return rpc_pipe_open_tcp(NULL, cli->desthost, interface,
2874 presult);
2875 case NCACN_NP:
2876 return rpc_pipe_open_np(cli, interface, presult);
2877 default:
2878 return NT_STATUS_NOT_IMPLEMENTED;
2882 /****************************************************************************
2883 Open a named pipe to an SMB server and bind anonymously.
2884 ****************************************************************************/
2886 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
2887 enum dcerpc_transport_t transport,
2888 const struct ndr_syntax_id *interface,
2889 struct rpc_pipe_client **presult)
2891 struct rpc_pipe_client *result;
2892 struct pipe_auth_data *auth;
2893 NTSTATUS status;
2895 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2896 if (!NT_STATUS_IS_OK(status)) {
2897 return status;
2900 status = rpccli_anon_bind_data(result, &auth);
2901 if (!NT_STATUS_IS_OK(status)) {
2902 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
2903 nt_errstr(status)));
2904 TALLOC_FREE(result);
2905 return status;
2909 * This is a bit of an abstraction violation due to the fact that an
2910 * anonymous bind on an authenticated SMB inherits the user/domain
2911 * from the enclosing SMB creds
2914 TALLOC_FREE(auth->user_name);
2915 TALLOC_FREE(auth->domain);
2917 auth->user_name = talloc_strdup(auth, cli->user_name);
2918 auth->domain = talloc_strdup(auth, cli->domain);
2919 auth->user_session_key = data_blob_talloc(auth,
2920 cli->user_session_key.data,
2921 cli->user_session_key.length);
2923 if ((auth->user_name == NULL) || (auth->domain == NULL)) {
2924 TALLOC_FREE(result);
2925 return NT_STATUS_NO_MEMORY;
2928 status = rpc_pipe_bind(result, auth);
2929 if (!NT_STATUS_IS_OK(status)) {
2930 int lvl = 0;
2931 if (ndr_syntax_id_equal(interface,
2932 &ndr_table_dssetup.syntax_id)) {
2933 /* non AD domains just don't have this pipe, avoid
2934 * level 0 statement in that case - gd */
2935 lvl = 3;
2937 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
2938 "%s failed with error %s\n",
2939 get_pipe_name_from_syntax(talloc_tos(), interface),
2940 nt_errstr(status) ));
2941 TALLOC_FREE(result);
2942 return status;
2945 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
2946 "%s and bound anonymously.\n",
2947 get_pipe_name_from_syntax(talloc_tos(), interface),
2948 cli->desthost));
2950 *presult = result;
2951 return NT_STATUS_OK;
2954 /****************************************************************************
2955 ****************************************************************************/
2957 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
2958 const struct ndr_syntax_id *interface,
2959 struct rpc_pipe_client **presult)
2961 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
2962 interface, presult);
2965 /****************************************************************************
2966 Open a named pipe to an SMB server and bind using NTLMSSP or SPNEGO NTLMSSP
2967 ****************************************************************************/
2969 static NTSTATUS cli_rpc_pipe_open_ntlmssp_internal(struct cli_state *cli,
2970 const struct ndr_syntax_id *interface,
2971 enum dcerpc_transport_t transport,
2972 bool use_spnego,
2973 enum dcerpc_AuthLevel auth_level,
2974 const char *domain,
2975 const char *username,
2976 const char *password,
2977 struct rpc_pipe_client **presult)
2979 struct rpc_pipe_client *result;
2980 struct pipe_auth_data *auth;
2981 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
2982 enum pipe_auth_type_spnego spnego_type = PIPE_AUTH_TYPE_SPNEGO_NONE;
2983 NTSTATUS status;
2985 status = cli_rpc_pipe_open(cli, transport, interface, &result);
2986 if (!NT_STATUS_IS_OK(status)) {
2987 return status;
2990 if (use_spnego) {
2991 auth_type = DCERPC_AUTH_TYPE_SPNEGO;
2992 spnego_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
2995 status = rpccli_ntlmssp_bind_data(result,
2996 auth_type, spnego_type, auth_level,
2997 domain, username, password,
2998 &auth);
2999 if (!NT_STATUS_IS_OK(status)) {
3000 DEBUG(0, ("rpccli_ntlmssp_bind_data returned %s\n",
3001 nt_errstr(status)));
3002 goto err;
3005 status = rpc_pipe_bind(result, auth);
3006 if (!NT_STATUS_IS_OK(status)) {
3007 DEBUG(0, ("cli_rpc_pipe_open_ntlmssp_internal: cli_rpc_pipe_bind failed with error %s\n",
3008 nt_errstr(status) ));
3009 goto err;
3012 DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
3013 "machine %s and bound NTLMSSP as user %s\\%s.\n",
3014 get_pipe_name_from_syntax(talloc_tos(), interface),
3015 cli->desthost, domain, username ));
3017 *presult = result;
3018 return NT_STATUS_OK;
3020 err:
3022 TALLOC_FREE(result);
3023 return status;
3026 /****************************************************************************
3027 External interface.
3028 Open a named pipe to an SMB server and bind using NTLMSSP (bind type 10)
3029 ****************************************************************************/
3031 NTSTATUS cli_rpc_pipe_open_ntlmssp(struct cli_state *cli,
3032 const struct ndr_syntax_id *interface,
3033 enum dcerpc_transport_t transport,
3034 enum dcerpc_AuthLevel auth_level,
3035 const char *domain,
3036 const char *username,
3037 const char *password,
3038 struct rpc_pipe_client **presult)
3040 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3041 interface,
3042 transport,
3043 false,
3044 auth_level,
3045 domain,
3046 username,
3047 password,
3048 presult);
3051 /****************************************************************************
3052 External interface.
3053 Open a named pipe to an SMB server and bind using spnego NTLMSSP (bind type 9)
3054 ****************************************************************************/
3056 NTSTATUS cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
3057 const struct ndr_syntax_id *interface,
3058 enum dcerpc_transport_t transport,
3059 enum dcerpc_AuthLevel auth_level,
3060 const char *domain,
3061 const char *username,
3062 const char *password,
3063 struct rpc_pipe_client **presult)
3065 return cli_rpc_pipe_open_ntlmssp_internal(cli,
3066 interface,
3067 transport,
3068 true,
3069 auth_level,
3070 domain,
3071 username,
3072 password,
3073 presult);
3076 /****************************************************************************
3077 Get a the schannel session key out of an already opened netlogon pipe.
3078 ****************************************************************************/
3079 static NTSTATUS get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
3080 struct cli_state *cli,
3081 const char *domain,
3082 uint32 *pneg_flags)
3084 enum netr_SchannelType sec_chan_type = 0;
3085 unsigned char machine_pwd[16];
3086 const char *machine_account;
3087 NTSTATUS status;
3089 /* Get the machine account credentials from secrets.tdb. */
3090 if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
3091 &sec_chan_type))
3093 DEBUG(0, ("get_schannel_session_key: could not fetch "
3094 "trust account password for domain '%s'\n",
3095 domain));
3096 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3099 status = rpccli_netlogon_setup_creds(netlogon_pipe,
3100 cli->desthost, /* server name */
3101 domain, /* domain */
3102 global_myname(), /* client name */
3103 machine_account, /* machine account name */
3104 machine_pwd,
3105 sec_chan_type,
3106 pneg_flags);
3108 if (!NT_STATUS_IS_OK(status)) {
3109 DEBUG(3, ("get_schannel_session_key_common: "
3110 "rpccli_netlogon_setup_creds failed with result %s "
3111 "to server %s, domain %s, machine account %s.\n",
3112 nt_errstr(status), cli->desthost, domain,
3113 machine_account ));
3114 return status;
3117 if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
3118 DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
3119 cli->desthost));
3120 return NT_STATUS_INVALID_NETWORK_RESPONSE;
3123 return NT_STATUS_OK;;
3126 /****************************************************************************
3127 Open a netlogon pipe and get the schannel session key.
3128 Now exposed to external callers.
3129 ****************************************************************************/
3132 NTSTATUS get_schannel_session_key(struct cli_state *cli,
3133 const char *domain,
3134 uint32 *pneg_flags,
3135 struct rpc_pipe_client **presult)
3137 struct rpc_pipe_client *netlogon_pipe = NULL;
3138 NTSTATUS status;
3140 status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
3141 &netlogon_pipe);
3142 if (!NT_STATUS_IS_OK(status)) {
3143 return status;
3146 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3147 pneg_flags);
3148 if (!NT_STATUS_IS_OK(status)) {
3149 TALLOC_FREE(netlogon_pipe);
3150 return status;
3153 *presult = netlogon_pipe;
3154 return NT_STATUS_OK;
3157 /****************************************************************************
3158 External interface.
3159 Open a named pipe to an SMB server and bind using schannel (bind type 68)
3160 using session_key. sign and seal.
3162 The *pdc will be stolen onto this new pipe
3163 ****************************************************************************/
3165 NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
3166 const struct ndr_syntax_id *interface,
3167 enum dcerpc_transport_t transport,
3168 enum dcerpc_AuthLevel auth_level,
3169 const char *domain,
3170 struct netlogon_creds_CredentialState **pdc,
3171 struct rpc_pipe_client **presult)
3173 struct rpc_pipe_client *result;
3174 struct pipe_auth_data *auth;
3175 NTSTATUS status;
3177 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 return status;
3182 status = rpccli_schannel_bind_data(result, domain, auth_level,
3183 *pdc, &auth);
3184 if (!NT_STATUS_IS_OK(status)) {
3185 DEBUG(0, ("rpccli_schannel_bind_data returned %s\n",
3186 nt_errstr(status)));
3187 TALLOC_FREE(result);
3188 return status;
3191 status = rpc_pipe_bind(result, auth);
3192 if (!NT_STATUS_IS_OK(status)) {
3193 DEBUG(0, ("cli_rpc_pipe_open_schannel_with_key: "
3194 "cli_rpc_pipe_bind failed with error %s\n",
3195 nt_errstr(status) ));
3196 TALLOC_FREE(result);
3197 return status;
3201 * The credentials on a new netlogon pipe are the ones we are passed
3202 * in - reference them in
3204 result->dc = talloc_move(result, pdc);
3206 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
3207 "for domain %s and bound using schannel.\n",
3208 get_pipe_name_from_syntax(talloc_tos(), interface),
3209 cli->desthost, domain ));
3211 *presult = result;
3212 return NT_STATUS_OK;
3215 /****************************************************************************
3216 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3217 Fetch the session key ourselves using a temporary netlogon pipe. This
3218 version uses an ntlmssp auth bound netlogon pipe to get the key.
3219 ****************************************************************************/
3221 static NTSTATUS get_schannel_session_key_auth_ntlmssp(struct cli_state *cli,
3222 const char *domain,
3223 const char *username,
3224 const char *password,
3225 uint32 *pneg_flags,
3226 struct rpc_pipe_client **presult)
3228 struct rpc_pipe_client *netlogon_pipe = NULL;
3229 NTSTATUS status;
3231 status = cli_rpc_pipe_open_spnego_ntlmssp(
3232 cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
3233 DCERPC_AUTH_LEVEL_PRIVACY,
3234 domain, username, password, &netlogon_pipe);
3235 if (!NT_STATUS_IS_OK(status)) {
3236 return status;
3239 status = get_schannel_session_key_common(netlogon_pipe, cli, domain,
3240 pneg_flags);
3241 if (!NT_STATUS_IS_OK(status)) {
3242 TALLOC_FREE(netlogon_pipe);
3243 return status;
3246 *presult = netlogon_pipe;
3247 return NT_STATUS_OK;
3250 /****************************************************************************
3251 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3252 Fetch the session key ourselves using a temporary netlogon pipe. This version
3253 uses an ntlmssp bind to get the session key.
3254 ****************************************************************************/
3256 NTSTATUS cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state *cli,
3257 const struct ndr_syntax_id *interface,
3258 enum dcerpc_transport_t transport,
3259 enum dcerpc_AuthLevel auth_level,
3260 const char *domain,
3261 const char *username,
3262 const char *password,
3263 struct rpc_pipe_client **presult)
3265 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3266 struct rpc_pipe_client *netlogon_pipe = NULL;
3267 struct rpc_pipe_client *result = NULL;
3268 NTSTATUS status;
3270 status = get_schannel_session_key_auth_ntlmssp(
3271 cli, domain, username, password, &neg_flags, &netlogon_pipe);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 DEBUG(0,("cli_rpc_pipe_open_ntlmssp_auth_schannel: failed to get schannel session "
3274 "key from server %s for domain %s.\n",
3275 cli->desthost, domain ));
3276 return status;
3279 status = cli_rpc_pipe_open_schannel_with_key(
3280 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3281 &result);
3283 /* Now we've bound using the session key we can close the netlog pipe. */
3284 TALLOC_FREE(netlogon_pipe);
3286 if (NT_STATUS_IS_OK(status)) {
3287 *presult = result;
3289 return status;
3292 /****************************************************************************
3293 Open a named pipe to an SMB server and bind using schannel (bind type 68).
3294 Fetch the session key ourselves using a temporary netlogon pipe.
3295 ****************************************************************************/
3297 NTSTATUS cli_rpc_pipe_open_schannel(struct cli_state *cli,
3298 const struct ndr_syntax_id *interface,
3299 enum dcerpc_transport_t transport,
3300 enum dcerpc_AuthLevel auth_level,
3301 const char *domain,
3302 struct rpc_pipe_client **presult)
3304 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
3305 struct rpc_pipe_client *netlogon_pipe = NULL;
3306 struct rpc_pipe_client *result = NULL;
3307 NTSTATUS status;
3309 status = get_schannel_session_key(cli, domain, &neg_flags,
3310 &netlogon_pipe);
3311 if (!NT_STATUS_IS_OK(status)) {
3312 DEBUG(0,("cli_rpc_pipe_open_schannel: failed to get schannel session "
3313 "key from server %s for domain %s.\n",
3314 cli->desthost, domain ));
3315 return status;
3318 status = cli_rpc_pipe_open_schannel_with_key(
3319 cli, interface, transport, auth_level, domain, &netlogon_pipe->dc,
3320 &result);
3322 /* Now we've bound using the session key we can close the netlog pipe. */
3323 TALLOC_FREE(netlogon_pipe);
3325 if (NT_STATUS_IS_OK(status)) {
3326 *presult = result;
3329 return status;
3332 /****************************************************************************
3333 Open a named pipe to an SMB server and bind using krb5 (bind type 16).
3334 The idea is this can be called with service_princ, username and password all
3335 NULL so long as the caller has a TGT.
3336 ****************************************************************************/
3338 NTSTATUS cli_rpc_pipe_open_krb5(struct cli_state *cli,
3339 const struct ndr_syntax_id *interface,
3340 enum dcerpc_transport_t transport,
3341 enum dcerpc_AuthLevel auth_level,
3342 const char *server,
3343 const char *username,
3344 const char *password,
3345 struct rpc_pipe_client **presult)
3347 #ifdef HAVE_GSSAPI_H
3348 struct rpc_pipe_client *result;
3349 struct pipe_auth_data *auth;
3350 NTSTATUS status;
3352 status = cli_rpc_pipe_open(cli, transport, interface, &result);
3353 if (!NT_STATUS_IS_OK(status)) {
3354 return status;
3357 status = gse_init_client(result, DCERPC_AUTH_TYPE_KRB5, auth_level,
3358 NULL, server, "cifs", username, password,
3359 GSS_C_DCE_STYLE, &auth);
3361 if (!NT_STATUS_IS_OK(status)) {
3362 DEBUG(0, ("gse_init_client returned %s\n",
3363 nt_errstr(status)));
3364 TALLOC_FREE(result);
3365 return status;
3368 status = rpc_pipe_bind(result, auth);
3369 if (!NT_STATUS_IS_OK(status)) {
3370 DEBUG(0, ("cli_rpc_pipe_open_krb5: cli_rpc_pipe_bind failed "
3371 "with error %s\n", nt_errstr(status)));
3372 TALLOC_FREE(result);
3373 return status;
3376 *presult = result;
3377 return NT_STATUS_OK;
3378 #else
3379 DEBUG(0,("cli_rpc_pipe_open_krb5: kerberos not found at compile time.\n"));
3380 return NT_STATUS_NOT_IMPLEMENTED;
3381 #endif
3384 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3385 struct rpc_pipe_client *cli,
3386 DATA_BLOB *session_key)
3388 struct pipe_auth_data *a = cli->auth;
3389 DATA_BLOB sk;
3391 if (!session_key || !cli) {
3392 return NT_STATUS_INVALID_PARAMETER;
3395 if (!cli->auth) {
3396 return NT_STATUS_INVALID_PARAMETER;
3399 switch (cli->auth->auth_type) {
3400 case DCERPC_AUTH_TYPE_SCHANNEL:
3401 sk = data_blob_const(a->a_u.schannel_auth->creds->session_key,
3402 16);
3403 break;
3404 case DCERPC_AUTH_TYPE_SPNEGO:
3405 switch (cli->auth->spnego_type) {
3406 case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
3407 sk = auth_ntlmssp_get_session_key(
3408 a->a_u.auth_ntlmssp_state);
3409 break;
3410 case PIPE_AUTH_TYPE_SPNEGO_KRB5:
3411 sk = gse_get_session_key(a->a_u.gssapi_state);
3412 break;
3413 default:
3414 return NT_STATUS_NO_USER_SESSION_KEY;
3416 break;
3417 case DCERPC_AUTH_TYPE_NTLMSSP:
3418 sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state);
3419 break;
3420 case DCERPC_AUTH_TYPE_KRB5:
3421 sk = gse_get_session_key(a->a_u.gssapi_state);
3422 break;
3423 case DCERPC_AUTH_TYPE_NONE:
3424 sk = data_blob_const(a->user_session_key.data,
3425 a->user_session_key.length);
3426 break;
3427 default:
3428 return NT_STATUS_NO_USER_SESSION_KEY;
3431 *session_key = data_blob_dup_talloc(mem_ctx, &sk);
3432 return NT_STATUS_OK;