2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client routines
4 * Largely rewritten by Jeremy Allison 2005.
5 * Heavily modified by Simo Sorce 2010.
6 * Copyright Andrew Bartlett 2011.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "librpc/gen_ndr/ndr_epmapper_c.h"
25 #include "../librpc/gen_ndr/ndr_dssetup.h"
26 #include "../libcli/auth/schannel.h"
27 #include "../libcli/auth/netlogon_creds_cli.h"
28 #include "auth_generic.h"
29 #include "librpc/gen_ndr/ndr_dcerpc.h"
30 #include "librpc/gen_ndr/ndr_netlogon_c.h"
31 #include "librpc/rpc/dcerpc.h"
34 #include "libsmb/libsmb.h"
35 #include "auth/gensec/gensec.h"
36 #include "auth/credentials/credentials.h"
37 #include "../libcli/smb/smbXcli_base.h"
40 #define DBGC_CLASS DBGC_RPC_CLI
42 /********************************************************************
43 Pipe description for a DEBUG
44 ********************************************************************/
45 static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
46 struct rpc_pipe_client *cli)
48 char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
55 /********************************************************************
57 ********************************************************************/
59 static uint32_t get_rpc_call_id(void)
61 static uint32_t call_id = 0;
65 /*******************************************************************
66 Use SMBreadX to get rest of one fragment's worth of rpc data.
67 Reads the whole size or give an error message
68 ********************************************************************/
70 struct rpc_read_state {
71 struct tevent_context *ev;
72 struct rpc_cli_transport *transport;
78 static void rpc_read_done(struct tevent_req *subreq);
80 static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
81 struct tevent_context *ev,
82 struct rpc_cli_transport *transport,
83 uint8_t *data, size_t size)
85 struct tevent_req *req, *subreq;
86 struct rpc_read_state *state;
88 req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
93 state->transport = transport;
98 DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
100 subreq = transport->read_send(state, ev, (uint8_t *)data, size,
102 if (subreq == NULL) {
105 tevent_req_set_callback(subreq, rpc_read_done, req);
113 static void rpc_read_done(struct tevent_req *subreq)
115 struct tevent_req *req = tevent_req_callback_data(
116 subreq, struct tevent_req);
117 struct rpc_read_state *state = tevent_req_data(
118 req, struct rpc_read_state);
122 status = state->transport->read_recv(subreq, &received);
124 if (!NT_STATUS_IS_OK(status)) {
125 tevent_req_nterror(req, status);
129 state->num_read += received;
130 if (state->num_read == state->size) {
131 tevent_req_done(req);
135 subreq = state->transport->read_send(state, state->ev,
136 state->data + state->num_read,
137 state->size - state->num_read,
138 state->transport->priv);
139 if (tevent_req_nomem(subreq, req)) {
142 tevent_req_set_callback(subreq, rpc_read_done, req);
145 static NTSTATUS rpc_read_recv(struct tevent_req *req)
147 return tevent_req_simple_recv_ntstatus(req);
150 struct rpc_write_state {
151 struct tevent_context *ev;
152 struct rpc_cli_transport *transport;
158 static void rpc_write_done(struct tevent_req *subreq);
160 static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
161 struct tevent_context *ev,
162 struct rpc_cli_transport *transport,
163 const uint8_t *data, size_t size)
165 struct tevent_req *req, *subreq;
166 struct rpc_write_state *state;
168 req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
173 state->transport = transport;
176 state->num_written = 0;
178 DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
180 subreq = transport->write_send(state, ev, data, size, transport->priv);
181 if (subreq == NULL) {
184 tevent_req_set_callback(subreq, rpc_write_done, req);
191 static void rpc_write_done(struct tevent_req *subreq)
193 struct tevent_req *req = tevent_req_callback_data(
194 subreq, struct tevent_req);
195 struct rpc_write_state *state = tevent_req_data(
196 req, struct rpc_write_state);
200 status = state->transport->write_recv(subreq, &written);
202 if (!NT_STATUS_IS_OK(status)) {
203 tevent_req_nterror(req, status);
207 state->num_written += written;
209 if (state->num_written == state->size) {
210 tevent_req_done(req);
214 subreq = state->transport->write_send(state, state->ev,
215 state->data + state->num_written,
216 state->size - state->num_written,
217 state->transport->priv);
218 if (tevent_req_nomem(subreq, req)) {
221 tevent_req_set_callback(subreq, rpc_write_done, req);
224 static NTSTATUS rpc_write_recv(struct tevent_req *req)
226 return tevent_req_simple_recv_ntstatus(req);
230 /****************************************************************************
231 Try and get a PDU's worth of data from current_pdu. If not, then read more
233 ****************************************************************************/
235 struct get_complete_frag_state {
236 struct tevent_context *ev;
237 struct rpc_pipe_client *cli;
242 static void get_complete_frag_got_header(struct tevent_req *subreq);
243 static void get_complete_frag_got_rest(struct tevent_req *subreq);
245 static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
246 struct tevent_context *ev,
247 struct rpc_pipe_client *cli,
250 struct tevent_req *req, *subreq;
251 struct get_complete_frag_state *state;
255 req = tevent_req_create(mem_ctx, &state,
256 struct get_complete_frag_state);
262 state->frag_len = RPC_HEADER_LEN;
265 received = pdu->length;
266 if (received < RPC_HEADER_LEN) {
267 if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
268 status = NT_STATUS_NO_MEMORY;
271 subreq = rpc_read_send(state, state->ev,
272 state->cli->transport,
273 pdu->data + received,
274 RPC_HEADER_LEN - received);
275 if (subreq == NULL) {
276 status = NT_STATUS_NO_MEMORY;
279 tevent_req_set_callback(subreq, get_complete_frag_got_header,
284 state->frag_len = dcerpc_get_frag_length(pdu);
285 if (state->frag_len < RPC_HEADER_LEN) {
286 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
287 return tevent_req_post(req, ev);
291 * Ensure we have frag_len bytes of data.
293 if (received < state->frag_len) {
294 if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
295 status = NT_STATUS_NO_MEMORY;
298 subreq = rpc_read_send(state, state->ev,
299 state->cli->transport,
300 pdu->data + received,
301 state->frag_len - received);
302 if (subreq == NULL) {
303 status = NT_STATUS_NO_MEMORY;
306 tevent_req_set_callback(subreq, get_complete_frag_got_rest,
311 status = NT_STATUS_OK;
313 if (NT_STATUS_IS_OK(status)) {
314 tevent_req_done(req);
316 tevent_req_nterror(req, status);
318 return tevent_req_post(req, ev);
321 static void get_complete_frag_got_header(struct tevent_req *subreq)
323 struct tevent_req *req = tevent_req_callback_data(
324 subreq, struct tevent_req);
325 struct get_complete_frag_state *state = tevent_req_data(
326 req, struct get_complete_frag_state);
329 status = rpc_read_recv(subreq);
331 if (!NT_STATUS_IS_OK(status)) {
332 tevent_req_nterror(req, status);
336 state->frag_len = dcerpc_get_frag_length(state->pdu);
337 if (state->frag_len < RPC_HEADER_LEN) {
338 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
342 if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
343 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
348 * We're here in this piece of code because we've read exactly
349 * RPC_HEADER_LEN bytes into state->pdu.
352 subreq = rpc_read_send(state, state->ev, state->cli->transport,
353 state->pdu->data + RPC_HEADER_LEN,
354 state->frag_len - RPC_HEADER_LEN);
355 if (tevent_req_nomem(subreq, req)) {
358 tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
361 static void get_complete_frag_got_rest(struct tevent_req *subreq)
363 struct tevent_req *req = tevent_req_callback_data(
364 subreq, struct tevent_req);
367 status = rpc_read_recv(subreq);
369 if (!NT_STATUS_IS_OK(status)) {
370 tevent_req_nterror(req, status);
373 tevent_req_done(req);
376 static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
378 return tevent_req_simple_recv_ntstatus(req);
381 /****************************************************************************
382 Do basic authentication checks on an incoming pdu.
383 ****************************************************************************/
385 static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
386 struct rpc_pipe_client *cli,
387 struct ncacn_packet *pkt,
389 uint8_t expected_pkt_type,
392 DATA_BLOB *reply_pdu)
394 const struct dcerpc_response *r = NULL;
395 DATA_BLOB tmp_stub = data_blob_null;
396 NTSTATUS ret = NT_STATUS_OK;
399 * Point the return values at the real data including the RPC
400 * header. Just in case the caller wants it.
404 if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
405 !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
407 * TODO: do we still need this hack which was introduced
408 * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
410 * I don't even know what AS/U might be...
412 DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
413 "fragment first/last ON.\n"));
414 pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
417 /* Ensure we have the correct type. */
418 switch (pkt->ptype) {
419 case DCERPC_PKT_BIND_NAK:
420 DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
421 rpccli_pipe_txt(talloc_tos(), cli)));
423 ret = dcerpc_verify_ncacn_packet_header(pkt,
425 0, /* max_auth_info */
426 DCERPC_PFC_FLAG_FIRST |
427 DCERPC_PFC_FLAG_LAST,
428 0); /* optional flags */
429 if (!NT_STATUS_IS_OK(ret)) {
430 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
431 "RPC packet type - %u, expected %u: %s\n",
432 rpccli_pipe_txt(talloc_tos(), cli),
433 pkt->ptype, expected_pkt_type,
435 NDR_PRINT_DEBUG(ncacn_packet, pkt);
439 /* Use this for now... */
440 return NT_STATUS_NETWORK_ACCESS_DENIED;
442 case DCERPC_PKT_BIND_ACK:
443 ret = dcerpc_verify_ncacn_packet_header(pkt,
445 pkt->u.bind_ack.auth_info.length,
446 DCERPC_PFC_FLAG_FIRST |
447 DCERPC_PFC_FLAG_LAST,
448 DCERPC_PFC_FLAG_CONC_MPX |
449 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
450 if (!NT_STATUS_IS_OK(ret)) {
451 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
452 "RPC packet type - %u, expected %u: %s\n",
453 rpccli_pipe_txt(talloc_tos(), cli),
454 pkt->ptype, expected_pkt_type,
456 NDR_PRINT_DEBUG(ncacn_packet, pkt);
462 case DCERPC_PKT_ALTER_RESP:
463 ret = dcerpc_verify_ncacn_packet_header(pkt,
465 pkt->u.alter_resp.auth_info.length,
466 DCERPC_PFC_FLAG_FIRST |
467 DCERPC_PFC_FLAG_LAST,
468 DCERPC_PFC_FLAG_CONC_MPX |
469 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
470 if (!NT_STATUS_IS_OK(ret)) {
471 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
472 "RPC packet type - %u, expected %u: %s\n",
473 rpccli_pipe_txt(talloc_tos(), cli),
474 pkt->ptype, expected_pkt_type,
476 NDR_PRINT_DEBUG(ncacn_packet, pkt);
482 case DCERPC_PKT_RESPONSE:
484 r = &pkt->u.response;
486 ret = dcerpc_verify_ncacn_packet_header(pkt,
488 r->stub_and_verifier.length,
489 0, /* required_flags */
490 DCERPC_PFC_FLAG_FIRST |
491 DCERPC_PFC_FLAG_LAST);
492 if (!NT_STATUS_IS_OK(ret)) {
493 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
494 "RPC packet type - %u, expected %u: %s\n",
495 rpccli_pipe_txt(talloc_tos(), cli),
496 pkt->ptype, expected_pkt_type,
498 NDR_PRINT_DEBUG(ncacn_packet, pkt);
502 tmp_stub.data = r->stub_and_verifier.data;
503 tmp_stub.length = r->stub_and_verifier.length;
505 /* Here's where we deal with incoming sign/seal. */
506 ret = dcerpc_check_auth(cli->auth, pkt,
508 DCERPC_RESPONSE_LENGTH,
510 if (!NT_STATUS_IS_OK(ret)) {
511 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
512 "RPC packet type - %u, expected %u: %s\n",
513 rpccli_pipe_txt(talloc_tos(), cli),
514 pkt->ptype, expected_pkt_type,
516 NDR_PRINT_DEBUG(ncacn_packet, pkt);
520 /* Point the return values at the NDR data. */
523 DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
524 (long unsigned int)pdu->length,
525 (long unsigned int)rdata->length));
528 * If this is the first reply, and the allocation hint is
529 * reasonable, try and set up the reply_pdu DATA_BLOB to the
533 if ((reply_pdu->length == 0) &&
534 r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
535 if (!data_blob_realloc(mem_ctx, reply_pdu,
537 DEBUG(0, ("reply alloc hint %d too "
538 "large to allocate\n",
539 (int)r->alloc_hint));
540 return NT_STATUS_NO_MEMORY;
546 case DCERPC_PKT_FAULT:
548 ret = dcerpc_verify_ncacn_packet_header(pkt,
550 0, /* max_auth_info */
551 DCERPC_PFC_FLAG_FIRST |
552 DCERPC_PFC_FLAG_LAST,
553 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
554 if (!NT_STATUS_IS_OK(ret)) {
555 DEBUG(1, (__location__ ": Connection to %s got an unexpected "
556 "RPC packet type - %u, expected %u: %s\n",
557 rpccli_pipe_txt(talloc_tos(), cli),
558 pkt->ptype, expected_pkt_type,
560 NDR_PRINT_DEBUG(ncacn_packet, pkt);
564 DEBUG(1, (__location__ ": RPC fault code %s received "
566 dcerpc_errstr(talloc_tos(),
567 pkt->u.fault.status),
568 rpccli_pipe_txt(talloc_tos(), cli)));
570 return dcerpc_fault_to_nt_status(pkt->u.fault.status);
573 DEBUG(0, (__location__ "Unknown packet type %u received "
575 (unsigned int)pkt->ptype,
576 rpccli_pipe_txt(talloc_tos(), cli)));
577 return NT_STATUS_RPC_PROTOCOL_ERROR;
581 if (pkt->call_id != call_id) {
582 DEBUG(3, (__location__ ": Connection to %s got an unexpected "
583 "RPC call_id - %u, not %u\n",
584 rpccli_pipe_txt(talloc_tos(), cli),
585 pkt->call_id, call_id));
586 return NT_STATUS_RPC_PROTOCOL_ERROR;
592 /****************************************************************************
593 Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
594 ****************************************************************************/
596 struct cli_api_pipe_state {
597 struct tevent_context *ev;
598 struct rpc_cli_transport *transport;
603 static void cli_api_pipe_trans_done(struct tevent_req *subreq);
604 static void cli_api_pipe_write_done(struct tevent_req *subreq);
605 static void cli_api_pipe_read_done(struct tevent_req *subreq);
607 static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
608 struct tevent_context *ev,
609 struct rpc_cli_transport *transport,
610 uint8_t *data, size_t data_len,
611 uint32_t max_rdata_len)
613 struct tevent_req *req, *subreq;
614 struct cli_api_pipe_state *state;
617 req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
622 state->transport = transport;
624 if (max_rdata_len < RPC_HEADER_LEN) {
626 * For a RPC reply we always need at least RPC_HEADER_LEN
627 * bytes. We check this here because we will receive
628 * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
630 status = NT_STATUS_INVALID_PARAMETER;
634 if (transport->trans_send != NULL) {
635 subreq = transport->trans_send(state, ev, data, data_len,
636 max_rdata_len, transport->priv);
637 if (subreq == NULL) {
640 tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
645 * If the transport does not provide a "trans" routine, i.e. for
646 * example the ncacn_ip_tcp transport, do the write/read step here.
649 subreq = rpc_write_send(state, ev, transport, data, data_len);
650 if (subreq == NULL) {
653 tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
657 tevent_req_nterror(req, status);
658 return tevent_req_post(req, ev);
664 static void cli_api_pipe_trans_done(struct tevent_req *subreq)
666 struct tevent_req *req = tevent_req_callback_data(
667 subreq, struct tevent_req);
668 struct cli_api_pipe_state *state = tevent_req_data(
669 req, struct cli_api_pipe_state);
672 status = state->transport->trans_recv(subreq, state, &state->rdata,
675 if (!NT_STATUS_IS_OK(status)) {
676 tevent_req_nterror(req, status);
679 tevent_req_done(req);
682 static void cli_api_pipe_write_done(struct tevent_req *subreq)
684 struct tevent_req *req = tevent_req_callback_data(
685 subreq, struct tevent_req);
686 struct cli_api_pipe_state *state = tevent_req_data(
687 req, struct cli_api_pipe_state);
690 status = rpc_write_recv(subreq);
692 if (!NT_STATUS_IS_OK(status)) {
693 tevent_req_nterror(req, status);
697 state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
698 if (tevent_req_nomem(state->rdata, req)) {
703 * We don't need to use rpc_read_send here, the upper layer will cope
704 * with a short read, transport->trans_send could also return less
705 * than state->max_rdata_len.
707 subreq = state->transport->read_send(state, state->ev, state->rdata,
709 state->transport->priv);
710 if (tevent_req_nomem(subreq, req)) {
713 tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
716 static void cli_api_pipe_read_done(struct tevent_req *subreq)
718 struct tevent_req *req = tevent_req_callback_data(
719 subreq, struct tevent_req);
720 struct cli_api_pipe_state *state = tevent_req_data(
721 req, struct cli_api_pipe_state);
725 status = state->transport->read_recv(subreq, &received);
727 if (!NT_STATUS_IS_OK(status)) {
728 tevent_req_nterror(req, status);
731 state->rdata_len = received;
732 tevent_req_done(req);
735 static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
736 uint8_t **prdata, uint32_t *prdata_len)
738 struct cli_api_pipe_state *state = tevent_req_data(
739 req, struct cli_api_pipe_state);
742 if (tevent_req_is_nterror(req, &status)) {
746 *prdata = talloc_move(mem_ctx, &state->rdata);
747 *prdata_len = state->rdata_len;
751 /****************************************************************************
752 Send data on an rpc pipe via trans. The data must be the last
753 pdu fragment of an NDR data stream.
755 Receive response data from an rpc pipe, which may be large...
757 Read the first fragment: unfortunately have to use SMBtrans for the first
758 bit, then SMBreadX for subsequent bits.
760 If first fragment received also wasn't the last fragment, continue
761 getting fragments until we _do_ receive the last fragment.
763 Request/Response PDU's look like the following...
765 |<------------------PDU len----------------------------------------------->|
766 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
768 +------------+-----------------+-------------+---------------+-------------+
769 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
770 +------------+-----------------+-------------+---------------+-------------+
772 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
773 signing & sealing being negotiated.
775 ****************************************************************************/
777 struct rpc_api_pipe_state {
778 struct tevent_context *ev;
779 struct rpc_pipe_client *cli;
780 uint8_t expected_pkt_type;
783 DATA_BLOB incoming_frag;
784 struct ncacn_packet *pkt;
788 size_t reply_pdu_offset;
792 static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
793 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
794 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
796 static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
797 struct tevent_context *ev,
798 struct rpc_pipe_client *cli,
799 DATA_BLOB *data, /* Outgoing PDU */
800 uint8_t expected_pkt_type,
803 struct tevent_req *req, *subreq;
804 struct rpc_api_pipe_state *state;
805 uint16_t max_recv_frag;
808 req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
814 state->expected_pkt_type = expected_pkt_type;
815 state->call_id = call_id;
816 state->endianess = DCERPC_DREP_LE;
819 * Ensure we're not sending too much.
821 if (data->length > cli->max_xmit_frag) {
822 status = NT_STATUS_INVALID_PARAMETER;
826 DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
828 if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
829 subreq = rpc_write_send(state, ev, cli->transport,
830 data->data, data->length);
831 if (subreq == NULL) {
834 tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
838 /* get the header first, then fetch the rest once we have
839 * the frag_length available */
840 max_recv_frag = RPC_HEADER_LEN;
842 subreq = cli_api_pipe_send(state, ev, cli->transport,
843 data->data, data->length, max_recv_frag);
844 if (subreq == NULL) {
847 tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
851 tevent_req_nterror(req, status);
852 return tevent_req_post(req, ev);
858 static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
860 struct tevent_req *req =
861 tevent_req_callback_data(subreq,
865 status = rpc_write_recv(subreq);
867 if (!NT_STATUS_IS_OK(status)) {
868 tevent_req_nterror(req, status);
872 tevent_req_done(req);
875 static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
877 struct tevent_req *req = tevent_req_callback_data(
878 subreq, struct tevent_req);
879 struct rpc_api_pipe_state *state = tevent_req_data(
880 req, struct rpc_api_pipe_state);
882 uint8_t *rdata = NULL;
883 uint32_t rdata_len = 0;
885 status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
887 if (!NT_STATUS_IS_OK(status)) {
888 DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
889 tevent_req_nterror(req, status);
894 DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
895 rpccli_pipe_txt(talloc_tos(), state->cli)));
896 tevent_req_done(req);
901 * Move data on state->incoming_frag.
903 state->incoming_frag.data = talloc_move(state, &rdata);
904 state->incoming_frag.length = rdata_len;
905 if (!state->incoming_frag.data) {
906 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
910 /* Ensure we have enough data for a pdu. */
911 subreq = get_complete_frag_send(state, state->ev, state->cli,
912 &state->incoming_frag);
913 if (tevent_req_nomem(subreq, req)) {
916 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
919 static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
921 struct tevent_req *req = tevent_req_callback_data(
922 subreq, struct tevent_req);
923 struct rpc_api_pipe_state *state = tevent_req_data(
924 req, struct rpc_api_pipe_state);
926 DATA_BLOB rdata = data_blob_null;
928 status = get_complete_frag_recv(subreq);
930 if (!NT_STATUS_IS_OK(status)) {
931 DEBUG(5, ("get_complete_frag failed: %s\n",
933 tevent_req_nterror(req, status);
937 state->pkt = talloc(state, struct ncacn_packet);
940 * TODO: do a real async disconnect ...
942 * For now do it sync...
944 TALLOC_FREE(state->cli->transport);
945 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
949 status = dcerpc_pull_ncacn_packet(state->pkt,
950 &state->incoming_frag,
953 if (!NT_STATUS_IS_OK(status)) {
955 * TODO: do a real async disconnect ...
957 * For now do it sync...
959 TALLOC_FREE(state->cli->transport);
960 tevent_req_nterror(req, status);
964 status = cli_pipe_validate_current_pdu(state,
965 state->cli, state->pkt,
966 &state->incoming_frag,
967 state->expected_pkt_type,
972 DEBUG(10,("rpc_api_pipe: got frag len of %u at offset %u: %s\n",
973 (unsigned)state->incoming_frag.length,
974 (unsigned)state->reply_pdu_offset,
977 if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) {
979 * TODO: do a real async disconnect ...
981 * For now do it sync...
983 TALLOC_FREE(state->cli->transport);
984 } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
986 * TODO: do a real async disconnect ...
988 * For now do it sync...
990 TALLOC_FREE(state->cli->transport);
991 } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
993 * TODO: do a real async disconnect ...
995 * For now do it sync...
997 TALLOC_FREE(state->cli->transport);
999 if (!NT_STATUS_IS_OK(status)) {
1000 tevent_req_nterror(req, status);
1004 if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1005 && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
1007 * Set the data type correctly for big-endian data on the
1010 DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1012 rpccli_pipe_txt(talloc_tos(), state->cli)));
1013 state->endianess = 0x00; /* BIG ENDIAN */
1016 * Check endianness on subsequent packets.
1018 if (state->endianess != state->pkt->drep[0]) {
1019 DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1021 state->endianess?"little":"big",
1022 state->pkt->drep[0]?"little":"big"));
1024 * TODO: do a real async disconnect ...
1026 * For now do it sync...
1028 TALLOC_FREE(state->cli->transport);
1029 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1033 if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
1035 * TODO: do a real async disconnect ...
1037 * For now do it sync...
1039 TALLOC_FREE(state->cli->transport);
1040 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1044 /* Now copy the data portion out of the pdu into rbuf. */
1045 if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1046 if (!data_blob_realloc(NULL, &state->reply_pdu,
1047 state->reply_pdu_offset + rdata.length)) {
1049 * TODO: do a real async disconnect ...
1051 * For now do it sync...
1053 TALLOC_FREE(state->cli->transport);
1054 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1059 memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1060 rdata.data, rdata.length);
1061 state->reply_pdu_offset += rdata.length;
1063 /* reset state->incoming_frag, there is no need to free it,
1064 * it will be reallocated to the right size the next time
1066 state->incoming_frag.length = 0;
1068 if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1069 /* make sure the pdu length is right now that we
1070 * have all the data available (alloc hint may
1071 * have allocated more than was actually used) */
1072 state->reply_pdu.length = state->reply_pdu_offset;
1073 DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1074 rpccli_pipe_txt(talloc_tos(), state->cli),
1075 (unsigned)state->reply_pdu.length));
1076 tevent_req_done(req);
1080 subreq = get_complete_frag_send(state, state->ev, state->cli,
1081 &state->incoming_frag);
1082 if (subreq == NULL) {
1084 * TODO: do a real async disconnect ...
1086 * For now do it sync...
1088 TALLOC_FREE(state->cli->transport);
1090 if (tevent_req_nomem(subreq, req)) {
1093 tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1096 static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1097 struct ncacn_packet **pkt,
1098 DATA_BLOB *reply_pdu)
1100 struct rpc_api_pipe_state *state = tevent_req_data(
1101 req, struct rpc_api_pipe_state);
1104 if (tevent_req_is_nterror(req, &status)) {
1108 /* return data to caller and assign it ownership of memory */
1110 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1111 reply_pdu->length = state->reply_pdu.length;
1112 state->reply_pdu.length = 0;
1114 data_blob_free(&state->reply_pdu);
1118 *pkt = talloc_steal(mem_ctx, state->pkt);
1121 return NT_STATUS_OK;
1124 /*******************************************************************
1125 Creates NTLMSSP auth bind.
1126 ********************************************************************/
1128 static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1129 TALLOC_CTX *mem_ctx,
1130 DATA_BLOB *auth_token,
1131 bool *client_hdr_signing)
1133 struct gensec_security *gensec_security;
1134 DATA_BLOB null_blob = data_blob_null;
1137 gensec_security = cli->auth->auth_ctx;
1139 DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1140 status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
1142 if (!NT_STATUS_IS_OK(status) &&
1143 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1148 if (client_hdr_signing == NULL) {
1152 if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1153 *client_hdr_signing = false;
1157 *client_hdr_signing = gensec_have_feature(gensec_security,
1158 GENSEC_FEATURE_SIGN_PKT_HEADER);
1163 /*******************************************************************
1164 Creates the internals of a DCE/RPC bind request or alter context PDU.
1165 ********************************************************************/
1167 static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1168 enum dcerpc_pkt_type ptype,
1169 uint32_t rpc_call_id,
1170 const struct ndr_syntax_id *abstract,
1171 const struct ndr_syntax_id *transfer,
1172 const DATA_BLOB *auth_info,
1173 bool client_hdr_signing,
1176 uint16_t auth_len = auth_info->length;
1178 union dcerpc_payload u;
1179 struct dcerpc_ctx_list ctx_list;
1180 uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1183 auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1186 if (client_hdr_signing) {
1187 pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1190 ctx_list.context_id = 0;
1191 ctx_list.num_transfer_syntaxes = 1;
1192 ctx_list.abstract_syntax = *abstract;
1193 ctx_list.transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer);
1195 u.bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
1196 u.bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN;
1197 u.bind.assoc_group_id = 0x0;
1198 u.bind.num_contexts = 1;
1199 u.bind.ctx_list = &ctx_list;
1200 u.bind.auth_info = *auth_info;
1202 status = dcerpc_push_ncacn_packet(mem_ctx,
1208 if (!NT_STATUS_IS_OK(status)) {
1209 DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1213 return NT_STATUS_OK;
1216 /*******************************************************************
1217 Creates a DCE/RPC bind request.
1218 ********************************************************************/
1220 static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1221 struct rpc_pipe_client *cli,
1222 struct pipe_auth_data *auth,
1223 uint32_t rpc_call_id,
1224 const struct ndr_syntax_id *abstract,
1225 const struct ndr_syntax_id *transfer,
1228 DATA_BLOB auth_token = data_blob_null;
1229 DATA_BLOB auth_info = data_blob_null;
1230 NTSTATUS ret = NT_STATUS_OK;
1232 switch (auth->auth_type) {
1233 case DCERPC_AUTH_TYPE_NONE:
1237 ret = create_generic_auth_rpc_bind_req(cli, mem_ctx,
1239 &auth->client_hdr_signing);
1241 if (!NT_STATUS_IS_OK(ret) &&
1242 !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1248 if (auth_token.length != 0) {
1249 ret = dcerpc_push_dcerpc_auth(cli,
1252 0, /* auth_pad_length */
1253 auth->auth_context_id,
1256 if (!NT_STATUS_IS_OK(ret)) {
1259 data_blob_free(&auth_token);
1262 ret = create_bind_or_alt_ctx_internal(mem_ctx,
1268 auth->client_hdr_signing,
1273 /*******************************************************************
1275 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1276 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1277 and deals with signing/sealing details.
1278 ********************************************************************/
1280 struct rpc_api_pipe_req_state {
1281 struct tevent_context *ev;
1282 struct rpc_pipe_client *cli;
1285 const DATA_BLOB *req_data;
1286 uint32_t req_data_sent;
1287 DATA_BLOB req_trailer;
1288 uint32_t req_trailer_sent;
1289 bool verify_bitmask1;
1290 bool verify_pcontext;
1292 DATA_BLOB reply_pdu;
1295 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1296 static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1297 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1298 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1299 bool *is_last_frag);
1301 static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1302 struct tevent_context *ev,
1303 struct rpc_pipe_client *cli,
1305 const DATA_BLOB *req_data)
1307 struct tevent_req *req, *subreq;
1308 struct rpc_api_pipe_req_state *state;
1312 req = tevent_req_create(mem_ctx, &state,
1313 struct rpc_api_pipe_req_state);
1319 state->op_num = op_num;
1320 state->req_data = req_data;
1321 state->req_data_sent = 0;
1322 state->call_id = get_rpc_call_id();
1323 state->reply_pdu = data_blob_null;
1324 state->rpc_out = data_blob_null;
1326 if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1327 + RPC_MAX_SIGN_SIZE) {
1328 /* Server is screwed up ! */
1329 status = NT_STATUS_INVALID_PARAMETER;
1333 status = prepare_verification_trailer(state);
1334 if (!NT_STATUS_IS_OK(status)) {
1338 status = prepare_next_frag(state, &is_last_frag);
1339 if (!NT_STATUS_IS_OK(status)) {
1344 subreq = rpc_api_pipe_send(state, ev, state->cli,
1346 DCERPC_PKT_RESPONSE,
1348 if (subreq == NULL) {
1351 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1353 subreq = rpc_write_send(state, ev, cli->transport,
1354 state->rpc_out.data,
1355 state->rpc_out.length);
1356 if (subreq == NULL) {
1359 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1365 tevent_req_nterror(req, status);
1366 return tevent_req_post(req, ev);
1372 static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1374 struct pipe_auth_data *a = state->cli->auth;
1375 struct dcerpc_sec_verification_trailer *t;
1376 struct dcerpc_sec_vt *c = NULL;
1377 struct ndr_push *ndr = NULL;
1378 enum ndr_err_code ndr_err;
1383 return NT_STATUS_OK;
1386 if (a->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
1387 return NT_STATUS_OK;
1390 t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1392 return NT_STATUS_NO_MEMORY;
1395 if (!a->verified_bitmask1) {
1396 t->commands = talloc_realloc(t, t->commands,
1397 struct dcerpc_sec_vt,
1398 t->count.count + 1);
1399 if (t->commands == NULL) {
1400 return NT_STATUS_NO_MEMORY;
1402 c = &t->commands[t->count.count++];
1405 c->command = DCERPC_SEC_VT_COMMAND_BITMASK1;
1406 if (a->client_hdr_signing) {
1407 c->u.bitmask1 = DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING;
1409 state->verify_bitmask1 = true;
1412 if (!state->cli->verified_pcontext) {
1413 t->commands = talloc_realloc(t, t->commands,
1414 struct dcerpc_sec_vt,
1415 t->count.count + 1);
1416 if (t->commands == NULL) {
1417 return NT_STATUS_NO_MEMORY;
1419 c = &t->commands[t->count.count++];
1422 c->command = DCERPC_SEC_VT_COMMAND_PCONTEXT;
1423 c->u.pcontext.abstract_syntax = state->cli->abstract_syntax;
1424 c->u.pcontext.transfer_syntax = state->cli->transfer_syntax;
1426 state->verify_pcontext = true;
1429 if (!a->hdr_signing) {
1430 t->commands = talloc_realloc(t, t->commands,
1431 struct dcerpc_sec_vt,
1432 t->count.count + 1);
1433 if (t->commands == NULL) {
1434 return NT_STATUS_NO_MEMORY;
1436 c = &t->commands[t->count.count++];
1439 c->command = DCERPC_SEC_VT_COMMAND_HEADER2;
1440 c->u.header2.ptype = DCERPC_PKT_REQUEST;
1441 c->u.header2.drep[0] = DCERPC_DREP_LE;
1442 c->u.header2.drep[1] = 0;
1443 c->u.header2.drep[2] = 0;
1444 c->u.header2.drep[3] = 0;
1445 c->u.header2.call_id = state->call_id;
1446 c->u.header2.context_id = 0;
1447 c->u.header2.opnum = state->op_num;
1450 if (t->count.count == 0) {
1452 return NT_STATUS_OK;
1455 c = &t->commands[t->count.count - 1];
1456 c->command |= DCERPC_SEC_VT_COMMAND_END;
1458 if (DEBUGLEVEL >= 10) {
1459 NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1462 ndr = ndr_push_init_ctx(state);
1464 return NT_STATUS_NO_MEMORY;
1467 ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1468 NDR_SCALARS | NDR_BUFFERS,
1470 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1471 return ndr_map_error2ntstatus(ndr_err);
1473 state->req_trailer = ndr_push_blob(ndr);
1475 align = state->req_data->length & 0x3;
1482 const uint8_t zeros[4] = { 0, };
1484 ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1486 return NT_STATUS_NO_MEMORY;
1489 /* move the padding to the start */
1490 p = state->req_trailer.data;
1491 memmove(p + pad, p, state->req_trailer.length - pad);
1495 return NT_STATUS_OK;
1498 static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1506 size_t data_thistime;
1507 size_t trailer_left;
1508 size_t trailer_thistime = 0;
1510 size_t total_thistime;
1513 union dcerpc_payload u;
1515 data_left = state->req_data->length - state->req_data_sent;
1516 trailer_left = state->req_trailer.length - state->req_trailer_sent;
1517 total_left = data_left + trailer_left;
1518 if ((total_left < data_left) || (total_left < trailer_left)) {
1522 return NT_STATUS_INVALID_PARAMETER_MIX;
1525 status = dcerpc_guess_sizes(state->cli->auth,
1526 DCERPC_REQUEST_LENGTH, total_left,
1527 state->cli->max_xmit_frag,
1529 &frag_len, &auth_len, &pad_len);
1530 if (!NT_STATUS_IS_OK(status)) {
1534 if (state->req_data_sent == 0) {
1535 flags = DCERPC_PFC_FLAG_FIRST;
1538 if (total_thistime == total_left) {
1539 flags |= DCERPC_PFC_FLAG_LAST;
1542 data_thistime = MIN(total_thistime, data_left);
1543 if (data_thistime < total_thistime) {
1544 trailer_thistime = total_thistime - data_thistime;
1547 data_blob_free(&state->rpc_out);
1549 ZERO_STRUCT(u.request);
1551 u.request.alloc_hint = total_left;
1552 u.request.context_id = 0;
1553 u.request.opnum = state->op_num;
1555 status = dcerpc_push_ncacn_packet(state,
1562 if (!NT_STATUS_IS_OK(status)) {
1566 /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1567 * compute it right for requests because the auth trailer is missing
1569 dcerpc_set_frag_length(&state->rpc_out, frag_len);
1571 if (data_thistime > 0) {
1572 /* Copy in the data. */
1573 ok = data_blob_append(NULL, &state->rpc_out,
1574 state->req_data->data + state->req_data_sent,
1577 return NT_STATUS_NO_MEMORY;
1579 state->req_data_sent += data_thistime;
1582 if (trailer_thistime > 0) {
1583 /* Copy in the verification trailer. */
1584 ok = data_blob_append(NULL, &state->rpc_out,
1585 state->req_trailer.data + state->req_trailer_sent,
1588 return NT_STATUS_NO_MEMORY;
1590 state->req_trailer_sent += trailer_thistime;
1593 switch (state->cli->auth->auth_level) {
1594 case DCERPC_AUTH_LEVEL_NONE:
1595 case DCERPC_AUTH_LEVEL_CONNECT:
1596 case DCERPC_AUTH_LEVEL_PACKET:
1598 case DCERPC_AUTH_LEVEL_INTEGRITY:
1599 case DCERPC_AUTH_LEVEL_PRIVACY:
1600 status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1602 if (!NT_STATUS_IS_OK(status)) {
1607 return NT_STATUS_INVALID_PARAMETER;
1610 *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1615 static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1617 struct tevent_req *req = tevent_req_callback_data(
1618 subreq, struct tevent_req);
1619 struct rpc_api_pipe_req_state *state = tevent_req_data(
1620 req, struct rpc_api_pipe_req_state);
1624 status = rpc_write_recv(subreq);
1625 TALLOC_FREE(subreq);
1626 if (!NT_STATUS_IS_OK(status)) {
1627 tevent_req_nterror(req, status);
1631 status = prepare_next_frag(state, &is_last_frag);
1632 if (!NT_STATUS_IS_OK(status)) {
1633 tevent_req_nterror(req, status);
1638 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1640 DCERPC_PKT_RESPONSE,
1642 if (tevent_req_nomem(subreq, req)) {
1645 tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1647 subreq = rpc_write_send(state, state->ev,
1648 state->cli->transport,
1649 state->rpc_out.data,
1650 state->rpc_out.length);
1651 if (tevent_req_nomem(subreq, req)) {
1654 tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1659 static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1661 struct tevent_req *req = tevent_req_callback_data(
1662 subreq, struct tevent_req);
1663 struct rpc_api_pipe_req_state *state = tevent_req_data(
1664 req, struct rpc_api_pipe_req_state);
1667 status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1668 TALLOC_FREE(subreq);
1669 if (!NT_STATUS_IS_OK(status)) {
1670 tevent_req_nterror(req, status);
1674 if (state->cli->auth == NULL) {
1675 tevent_req_done(req);
1679 if (state->verify_bitmask1) {
1680 state->cli->auth->verified_bitmask1 = true;
1683 if (state->verify_pcontext) {
1684 state->cli->verified_pcontext = true;
1687 tevent_req_done(req);
1690 static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1691 DATA_BLOB *reply_pdu)
1693 struct rpc_api_pipe_req_state *state = tevent_req_data(
1694 req, struct rpc_api_pipe_req_state);
1697 if (tevent_req_is_nterror(req, &status)) {
1699 * We always have to initialize to reply pdu, even if there is
1700 * none. The rpccli_* caller routines expect this.
1702 *reply_pdu = data_blob_null;
1706 /* return data to caller and assign it ownership of memory */
1707 reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1708 reply_pdu->length = state->reply_pdu.length;
1709 state->reply_pdu.length = 0;
1711 return NT_STATUS_OK;
1714 /****************************************************************************
1715 Check the rpc bind acknowledge response.
1716 ****************************************************************************/
1718 static bool check_bind_response(const struct dcerpc_bind_ack *r,
1719 const struct ndr_syntax_id *transfer)
1721 struct dcerpc_ack_ctx ctx;
1723 if (r->secondary_address_size == 0) {
1724 DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)"));
1727 if (r->num_results < 1 || !r->ctx_list) {
1731 ctx = r->ctx_list[0];
1733 /* check the transfer syntax */
1734 if ((ctx.syntax.if_version != transfer->if_version) ||
1735 (memcmp(&ctx.syntax.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
1736 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1740 if (r->num_results != 0x1 || ctx.result != 0) {
1741 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1742 r->num_results, ctx.reason.value));
1745 DEBUG(5,("check_bind_response: accepted!\n"));
1749 /*******************************************************************
1750 Creates a DCE/RPC bind authentication response.
1751 This is the packet that is sent back to the server once we
1752 have received a BIND-ACK, to finish the third leg of
1753 the authentication handshake.
1754 ********************************************************************/
1756 static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1757 struct rpc_pipe_client *cli,
1758 struct pipe_auth_data *auth,
1759 uint32_t rpc_call_id,
1760 DATA_BLOB *pauth_blob,
1764 union dcerpc_payload u;
1768 status = dcerpc_push_dcerpc_auth(mem_ctx,
1771 0, /* auth_pad_length */
1772 auth->auth_context_id,
1774 &u.auth3.auth_info);
1775 if (!NT_STATUS_IS_OK(status)) {
1779 status = dcerpc_push_ncacn_packet(mem_ctx,
1781 DCERPC_PFC_FLAG_FIRST |
1782 DCERPC_PFC_FLAG_LAST,
1787 data_blob_free(&u.auth3.auth_info);
1788 if (!NT_STATUS_IS_OK(status)) {
1789 DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1793 return NT_STATUS_OK;
1796 /*******************************************************************
1797 Creates a DCE/RPC bind alter context authentication request which
1798 may contain a spnego auth blobl
1799 ********************************************************************/
1801 static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1802 struct pipe_auth_data *auth,
1803 uint32_t rpc_call_id,
1804 const struct ndr_syntax_id *abstract,
1805 const struct ndr_syntax_id *transfer,
1806 const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1809 DATA_BLOB auth_info;
1812 status = dcerpc_push_dcerpc_auth(mem_ctx,
1815 0, /* auth_pad_length */
1816 auth->auth_context_id,
1819 if (!NT_STATUS_IS_OK(status)) {
1823 status = create_bind_or_alt_ctx_internal(mem_ctx,
1829 false, /* client_hdr_signing */
1831 data_blob_free(&auth_info);
1835 /****************************************************************************
1837 ****************************************************************************/
1839 struct rpc_pipe_bind_state {
1840 struct tevent_context *ev;
1841 struct rpc_pipe_client *cli;
1844 uint32_t rpc_call_id;
1847 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1848 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1849 struct rpc_pipe_bind_state *state,
1850 DATA_BLOB *credentials);
1851 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1852 struct rpc_pipe_bind_state *state,
1853 DATA_BLOB *credentials);
1855 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1856 struct tevent_context *ev,
1857 struct rpc_pipe_client *cli,
1858 struct pipe_auth_data *auth)
1860 struct tevent_req *req, *subreq;
1861 struct rpc_pipe_bind_state *state;
1864 req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1869 DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1870 rpccli_pipe_txt(talloc_tos(), cli),
1871 (unsigned int)auth->auth_type,
1872 (unsigned int)auth->auth_level ));
1876 state->rpc_call_id = get_rpc_call_id();
1878 cli->auth = talloc_move(cli, &auth);
1880 /* Marshall the outgoing data. */
1881 status = create_rpc_bind_req(state, cli,
1884 &cli->abstract_syntax,
1885 &cli->transfer_syntax,
1888 if (!NT_STATUS_IS_OK(status) &&
1889 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1893 subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1894 DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1895 if (subreq == NULL) {
1898 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1902 tevent_req_nterror(req, status);
1903 return tevent_req_post(req, ev);
1909 static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1911 struct tevent_req *req = tevent_req_callback_data(
1912 subreq, struct tevent_req);
1913 struct rpc_pipe_bind_state *state = tevent_req_data(
1914 req, struct rpc_pipe_bind_state);
1915 struct pipe_auth_data *pauth = state->cli->auth;
1916 struct gensec_security *gensec_security;
1917 struct ncacn_packet *pkt = NULL;
1918 struct dcerpc_auth auth;
1919 DATA_BLOB auth_token = data_blob_null;
1922 status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1923 TALLOC_FREE(subreq);
1924 if (!NT_STATUS_IS_OK(status)) {
1925 DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1926 rpccli_pipe_txt(talloc_tos(), state->cli),
1927 nt_errstr(status)));
1928 tevent_req_nterror(req, status);
1933 tevent_req_done(req);
1937 if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1938 DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1939 tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1943 state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1945 switch(pauth->auth_type) {
1947 case DCERPC_AUTH_TYPE_NONE:
1948 /* Bind complete. */
1949 tevent_req_done(req);
1953 if (pkt->auth_length == 0) {
1954 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1958 /* get auth credentials */
1959 status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
1960 &pkt->u.bind_ack.auth_info,
1962 if (!NT_STATUS_IS_OK(status)) {
1963 DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1964 nt_errstr(status)));
1965 tevent_req_nterror(req, status);
1969 if (auth.auth_type != pauth->auth_type) {
1970 DEBUG(0, (__location__ " Auth type %u mismatch expected %u.\n",
1971 auth.auth_type, pauth->auth_type));
1972 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1976 if (auth.auth_level != pauth->auth_level) {
1977 DEBUG(0, (__location__ " Auth level %u mismatch expected %u.\n",
1978 auth.auth_level, pauth->auth_level));
1979 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1983 if (auth.auth_context_id != pauth->auth_context_id) {
1984 DEBUG(0, (__location__ " Auth context id %u mismatch expected %u.\n",
1985 (unsigned)auth.auth_context_id,
1986 (unsigned)pauth->auth_context_id));
1987 tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1995 * For authenticated binds we may need to do 3 or 4 leg binds.
1998 switch(pauth->auth_type) {
2000 case DCERPC_AUTH_TYPE_NONE:
2001 /* Bind complete. */
2002 tevent_req_done(req);
2006 gensec_security = pauth->auth_ctx;
2008 if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
2009 if (pauth->client_hdr_signing) {
2010 pauth->hdr_signing = true;
2011 gensec_want_feature(gensec_security,
2012 GENSEC_FEATURE_SIGN_PKT_HEADER);
2016 status = gensec_update(gensec_security, state,
2017 auth.credentials, &auth_token);
2018 if (NT_STATUS_EQUAL(status,
2019 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2020 status = rpc_bind_next_send(req, state,
2022 } else if (NT_STATUS_IS_OK(status)) {
2023 if (auth_token.length == 0) {
2024 /* Bind complete. */
2025 tevent_req_done(req);
2028 status = rpc_bind_finish_send(req, state,
2034 if (!NT_STATUS_IS_OK(status)) {
2035 tevent_req_nterror(req, status);
2040 static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2041 struct rpc_pipe_bind_state *state,
2042 DATA_BLOB *auth_token)
2044 struct pipe_auth_data *auth = state->cli->auth;
2045 struct tevent_req *subreq;
2048 /* Now prepare the alter context pdu. */
2049 data_blob_free(&state->rpc_out);
2051 status = create_rpc_alter_context(state, auth,
2053 &state->cli->abstract_syntax,
2054 &state->cli->transfer_syntax,
2057 if (!NT_STATUS_IS_OK(status)) {
2061 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2062 &state->rpc_out, DCERPC_PKT_ALTER_RESP,
2063 state->rpc_call_id);
2064 if (subreq == NULL) {
2065 return NT_STATUS_NO_MEMORY;
2067 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2068 return NT_STATUS_OK;
2071 static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2072 struct rpc_pipe_bind_state *state,
2073 DATA_BLOB *auth_token)
2075 struct pipe_auth_data *auth = state->cli->auth;
2076 struct tevent_req *subreq;
2079 state->auth3 = true;
2081 /* Now prepare the auth3 context pdu. */
2082 data_blob_free(&state->rpc_out);
2084 status = create_rpc_bind_auth3(state, state->cli, auth,
2088 if (!NT_STATUS_IS_OK(status)) {
2092 subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2093 &state->rpc_out, DCERPC_PKT_AUTH3,
2094 state->rpc_call_id);
2095 if (subreq == NULL) {
2096 return NT_STATUS_NO_MEMORY;
2098 tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2099 return NT_STATUS_OK;
2102 NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2104 return tevent_req_simple_recv_ntstatus(req);
2107 NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2108 struct pipe_auth_data *auth)
2110 TALLOC_CTX *frame = talloc_stackframe();
2111 struct tevent_context *ev;
2112 struct tevent_req *req;
2113 NTSTATUS status = NT_STATUS_OK;
2115 ev = samba_tevent_context_init(frame);
2117 status = NT_STATUS_NO_MEMORY;
2121 req = rpc_pipe_bind_send(frame, ev, cli, auth);
2123 status = NT_STATUS_NO_MEMORY;
2127 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2131 status = rpc_pipe_bind_recv(req);
2137 #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2139 unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2140 unsigned int timeout)
2144 if (rpc_cli->transport == NULL) {
2145 return RPCCLI_DEFAULT_TIMEOUT;
2148 if (rpc_cli->transport->set_timeout == NULL) {
2149 return RPCCLI_DEFAULT_TIMEOUT;
2152 old = rpc_cli->transport->set_timeout(rpc_cli->transport->priv, timeout);
2154 return RPCCLI_DEFAULT_TIMEOUT;
2160 bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2162 if (rpc_cli == NULL) {
2166 if (rpc_cli->transport == NULL) {
2170 return rpc_cli->transport->is_connected(rpc_cli->transport->priv);
2173 struct rpccli_bh_state {
2174 struct rpc_pipe_client *rpc_cli;
2177 static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2179 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2180 struct rpccli_bh_state);
2182 return rpccli_is_connected(hs->rpc_cli);
2185 static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2188 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2189 struct rpccli_bh_state);
2191 return rpccli_set_timeout(hs->rpc_cli, timeout);
2194 static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2195 enum dcerpc_AuthType *auth_type,
2196 enum dcerpc_AuthLevel *auth_level)
2198 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2199 struct rpccli_bh_state);
2201 if (hs->rpc_cli == NULL) {
2205 if (hs->rpc_cli->auth == NULL) {
2209 *auth_type = hs->rpc_cli->auth->auth_type;
2210 *auth_level = hs->rpc_cli->auth->auth_level;
2213 struct rpccli_bh_raw_call_state {
2219 static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2221 static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2222 struct tevent_context *ev,
2223 struct dcerpc_binding_handle *h,
2224 const struct GUID *object,
2227 const uint8_t *in_data,
2230 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2231 struct rpccli_bh_state);
2232 struct tevent_req *req;
2233 struct rpccli_bh_raw_call_state *state;
2235 struct tevent_req *subreq;
2237 req = tevent_req_create(mem_ctx, &state,
2238 struct rpccli_bh_raw_call_state);
2242 state->in_data.data = discard_const_p(uint8_t, in_data);
2243 state->in_data.length = in_length;
2245 ok = rpccli_bh_is_connected(h);
2247 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2248 return tevent_req_post(req, ev);
2251 subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2252 opnum, &state->in_data);
2253 if (tevent_req_nomem(subreq, req)) {
2254 return tevent_req_post(req, ev);
2256 tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2261 static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2263 struct tevent_req *req =
2264 tevent_req_callback_data(subreq,
2266 struct rpccli_bh_raw_call_state *state =
2267 tevent_req_data(req,
2268 struct rpccli_bh_raw_call_state);
2271 state->out_flags = 0;
2273 /* TODO: support bigendian responses */
2275 status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2276 TALLOC_FREE(subreq);
2277 if (!NT_STATUS_IS_OK(status)) {
2278 tevent_req_nterror(req, status);
2282 tevent_req_done(req);
2285 static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2286 TALLOC_CTX *mem_ctx,
2289 uint32_t *out_flags)
2291 struct rpccli_bh_raw_call_state *state =
2292 tevent_req_data(req,
2293 struct rpccli_bh_raw_call_state);
2296 if (tevent_req_is_nterror(req, &status)) {
2297 tevent_req_received(req);
2301 *out_data = talloc_move(mem_ctx, &state->out_data.data);
2302 *out_length = state->out_data.length;
2303 *out_flags = state->out_flags;
2304 tevent_req_received(req);
2305 return NT_STATUS_OK;
2308 struct rpccli_bh_disconnect_state {
2312 static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2313 struct tevent_context *ev,
2314 struct dcerpc_binding_handle *h)
2316 struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2317 struct rpccli_bh_state);
2318 struct tevent_req *req;
2319 struct rpccli_bh_disconnect_state *state;
2322 req = tevent_req_create(mem_ctx, &state,
2323 struct rpccli_bh_disconnect_state);
2328 ok = rpccli_bh_is_connected(h);
2330 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2331 return tevent_req_post(req, ev);
2335 * TODO: do a real async disconnect ...
2337 * For now we do it sync...
2339 TALLOC_FREE(hs->rpc_cli->transport);
2342 tevent_req_done(req);
2343 return tevent_req_post(req, ev);
2346 static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2350 if (tevent_req_is_nterror(req, &status)) {
2351 tevent_req_received(req);
2355 tevent_req_received(req);
2356 return NT_STATUS_OK;
2359 static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2364 static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2366 const void *_struct_ptr,
2367 const struct ndr_interface_call *call)
2369 void *struct_ptr = discard_const(_struct_ptr);
2371 if (DEBUGLEVEL < 10) {
2375 if (ndr_flags & NDR_IN) {
2376 ndr_print_function_debug(call->ndr_print,
2381 if (ndr_flags & NDR_OUT) {
2382 ndr_print_function_debug(call->ndr_print,
2389 static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2391 .is_connected = rpccli_bh_is_connected,
2392 .set_timeout = rpccli_bh_set_timeout,
2393 .auth_info = rpccli_bh_auth_info,
2394 .raw_call_send = rpccli_bh_raw_call_send,
2395 .raw_call_recv = rpccli_bh_raw_call_recv,
2396 .disconnect_send = rpccli_bh_disconnect_send,
2397 .disconnect_recv = rpccli_bh_disconnect_recv,
2399 .ref_alloc = rpccli_bh_ref_alloc,
2400 .do_ndr_print = rpccli_bh_do_ndr_print,
2403 /* initialise a rpc_pipe_client binding handle */
2404 struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2405 const struct GUID *object,
2406 const struct ndr_interface_table *table)
2408 struct dcerpc_binding_handle *h;
2409 struct rpccli_bh_state *hs;
2411 h = dcerpc_binding_handle_create(c,
2416 struct rpccli_bh_state,
2426 NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2427 struct pipe_auth_data **presult)
2429 struct pipe_auth_data *result;
2430 struct auth_generic_state *auth_generic_ctx;
2433 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2434 if (result == NULL) {
2435 return NT_STATUS_NO_MEMORY;
2438 result->auth_type = DCERPC_AUTH_TYPE_NONE;
2439 result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2440 result->auth_context_id = 0;
2442 status = auth_generic_client_prepare(result,
2444 if (!NT_STATUS_IS_OK(status)) {
2445 DEBUG(1, ("Failed to create auth_generic context: %s\n",
2446 nt_errstr(status)));
2449 status = auth_generic_set_username(auth_generic_ctx, "");
2450 if (!NT_STATUS_IS_OK(status)) {
2451 DEBUG(1, ("Failed to set username: %s\n",
2452 nt_errstr(status)));
2455 status = auth_generic_set_domain(auth_generic_ctx, "");
2456 if (!NT_STATUS_IS_OK(status)) {
2457 DEBUG(1, ("Failed to set domain: %s\n",
2458 nt_errstr(status)));
2462 status = gensec_set_credentials(auth_generic_ctx->gensec_security,
2463 auth_generic_ctx->credentials);
2464 if (!NT_STATUS_IS_OK(status)) {
2465 DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2466 nt_errstr(status)));
2469 talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
2470 auth_generic_ctx->credentials = NULL;
2472 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2473 talloc_free(auth_generic_ctx);
2475 return NT_STATUS_OK;
2478 static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2479 enum dcerpc_AuthType auth_type,
2480 enum dcerpc_AuthLevel auth_level,
2482 const char *target_service,
2484 const char *username,
2485 const char *password,
2486 enum credentials_use_kerberos use_kerberos,
2487 struct netlogon_creds_CredentialState *creds,
2488 struct pipe_auth_data **presult)
2490 struct auth_generic_state *auth_generic_ctx;
2491 struct pipe_auth_data *result;
2494 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2495 if (result == NULL) {
2496 return NT_STATUS_NO_MEMORY;
2499 result->auth_type = auth_type;
2500 result->auth_level = auth_level;
2501 result->auth_context_id = 1;
2503 status = auth_generic_client_prepare(result,
2505 if (!NT_STATUS_IS_OK(status)) {
2509 status = auth_generic_set_username(auth_generic_ctx, username);
2510 if (!NT_STATUS_IS_OK(status)) {
2514 status = auth_generic_set_domain(auth_generic_ctx, domain);
2515 if (!NT_STATUS_IS_OK(status)) {
2519 status = auth_generic_set_password(auth_generic_ctx, password);
2520 if (!NT_STATUS_IS_OK(status)) {
2524 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2525 if (!NT_STATUS_IS_OK(status)) {
2529 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2530 if (!NT_STATUS_IS_OK(status)) {
2534 cli_credentials_set_kerberos_state(auth_generic_ctx->credentials, use_kerberos);
2535 cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2537 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2538 if (!NT_STATUS_IS_OK(status)) {
2542 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2543 talloc_free(auth_generic_ctx);
2545 return NT_STATUS_OK;
2548 TALLOC_FREE(result);
2552 /* This routine steals the creds pointer that is passed in */
2553 static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
2554 enum dcerpc_AuthType auth_type,
2555 enum dcerpc_AuthLevel auth_level,
2557 const char *target_service,
2558 struct cli_credentials *creds,
2559 struct pipe_auth_data **presult)
2561 struct auth_generic_state *auth_generic_ctx;
2562 struct pipe_auth_data *result;
2565 result = talloc_zero(mem_ctx, struct pipe_auth_data);
2566 if (result == NULL) {
2567 return NT_STATUS_NO_MEMORY;
2570 result->auth_type = auth_type;
2571 result->auth_level = auth_level;
2572 result->auth_context_id = 1;
2574 status = auth_generic_client_prepare(result,
2576 if (!NT_STATUS_IS_OK(status)) {
2580 status = auth_generic_set_creds(auth_generic_ctx, creds);
2581 if (!NT_STATUS_IS_OK(status)) {
2585 status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2586 if (!NT_STATUS_IS_OK(status)) {
2590 status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2591 if (!NT_STATUS_IS_OK(status)) {
2595 status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2596 if (!NT_STATUS_IS_OK(status)) {
2600 result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2601 talloc_free(auth_generic_ctx);
2603 return NT_STATUS_OK;
2606 TALLOC_FREE(result);
2610 NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2611 struct pipe_auth_data **presult)
2613 return rpccli_generic_bind_data(mem_ctx,
2614 DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
2615 DCERPC_AUTH_LEVEL_CONNECT,
2617 "host", /* target_service */
2618 NAME_NT_AUTHORITY, /* domain */
2621 CRED_DONT_USE_KERBEROS,
2622 NULL, /* netlogon_creds_CredentialState */
2627 * Create an rpc pipe client struct, connecting to a tcp port.
2629 static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2630 const struct sockaddr_storage *ss_addr,
2632 const struct ndr_interface_table *table,
2633 struct rpc_pipe_client **presult)
2635 struct rpc_pipe_client *result;
2636 struct sockaddr_storage addr;
2640 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2641 if (result == NULL) {
2642 return NT_STATUS_NO_MEMORY;
2645 result->abstract_syntax = table->syntax_id;
2646 result->transfer_syntax = ndr_transfer_syntax_ndr;
2648 result->desthost = talloc_strdup(result, host);
2649 result->srv_name_slash = talloc_asprintf_strupper_m(
2650 result, "\\\\%s", result->desthost);
2651 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2652 status = NT_STATUS_NO_MEMORY;
2656 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2658 if (ss_addr == NULL) {
2659 if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2660 status = NT_STATUS_NOT_FOUND;
2667 status = open_socket_out(&addr, port, 60*1000, &fd);
2668 if (!NT_STATUS_IS_OK(status)) {
2671 set_socket_options(fd, lp_socket_options());
2673 status = rpc_transport_sock_init(result, fd, &result->transport);
2674 if (!NT_STATUS_IS_OK(status)) {
2679 result->transport->transport = NCACN_IP_TCP;
2681 result->binding_handle = rpccli_bh_create(result, NULL, table);
2682 if (result->binding_handle == NULL) {
2683 TALLOC_FREE(result);
2684 return NT_STATUS_NO_MEMORY;
2688 return NT_STATUS_OK;
2691 TALLOC_FREE(result);
2696 * Determine the tcp port on which a dcerpc interface is listening
2697 * for the ncacn_ip_tcp transport via the endpoint mapper of the
2700 static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2701 const struct sockaddr_storage *addr,
2702 const struct ndr_interface_table *table,
2706 struct rpc_pipe_client *epm_pipe = NULL;
2707 struct dcerpc_binding_handle *epm_handle = NULL;
2708 struct pipe_auth_data *auth = NULL;
2709 struct dcerpc_binding *map_binding = NULL;
2710 struct dcerpc_binding *res_binding = NULL;
2711 enum dcerpc_transport_t transport;
2712 const char *endpoint = NULL;
2713 struct epm_twr_t *map_tower = NULL;
2714 struct epm_twr_t *res_towers = NULL;
2715 struct policy_handle *entry_handle = NULL;
2716 uint32_t num_towers = 0;
2717 uint32_t max_towers = 1;
2718 struct epm_twr_p_t towers;
2719 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2720 uint32_t result = 0;
2722 if (pport == NULL) {
2723 status = NT_STATUS_INVALID_PARAMETER;
2727 if (ndr_syntax_id_equal(&table->syntax_id,
2728 &ndr_table_epmapper.syntax_id)) {
2730 status = NT_STATUS_OK;
2734 /* open the connection to the endpoint mapper */
2735 status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2736 &ndr_table_epmapper,
2739 if (!NT_STATUS_IS_OK(status)) {
2742 epm_handle = epm_pipe->binding_handle;
2744 status = rpccli_anon_bind_data(tmp_ctx, &auth);
2745 if (!NT_STATUS_IS_OK(status)) {
2749 status = rpc_pipe_bind(epm_pipe, auth);
2750 if (!NT_STATUS_IS_OK(status)) {
2754 /* create tower for asking the epmapper */
2756 status = dcerpc_parse_binding(tmp_ctx, "ncacn_ip_tcp:[135]",
2758 if (!NT_STATUS_IS_OK(status)) {
2762 status = dcerpc_binding_set_abstract_syntax(map_binding,
2764 if (!NT_STATUS_IS_OK(status)) {
2768 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
2769 if (map_tower == NULL) {
2770 status = NT_STATUS_NO_MEMORY;
2774 status = dcerpc_binding_build_tower(tmp_ctx, map_binding,
2775 &(map_tower->tower));
2776 if (!NT_STATUS_IS_OK(status)) {
2780 /* allocate further parameters for the epm_Map call */
2782 res_towers = talloc_array(tmp_ctx, struct epm_twr_t, max_towers);
2783 if (res_towers == NULL) {
2784 status = NT_STATUS_NO_MEMORY;
2787 towers.twr = res_towers;
2789 entry_handle = talloc_zero(tmp_ctx, struct policy_handle);
2790 if (entry_handle == NULL) {
2791 status = NT_STATUS_NO_MEMORY;
2795 /* ask the endpoint mapper for the port */
2797 status = dcerpc_epm_Map(epm_handle,
2799 discard_const_p(struct GUID,
2800 &(table->syntax_id.uuid)),
2808 if (!NT_STATUS_IS_OK(status)) {
2812 if (result != EPMAPPER_STATUS_OK) {
2813 status = NT_STATUS_UNSUCCESSFUL;
2817 if (num_towers != 1) {
2818 status = NT_STATUS_UNSUCCESSFUL;
2822 /* extract the port from the answer */
2824 status = dcerpc_binding_from_tower(tmp_ctx,
2825 &(towers.twr->tower),
2827 if (!NT_STATUS_IS_OK(status)) {
2831 transport = dcerpc_binding_get_transport(res_binding);
2832 endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
2834 /* are further checks here necessary? */
2835 if (transport != NCACN_IP_TCP) {
2836 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2840 if (endpoint == NULL) {
2841 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2845 *pport = (uint16_t)atoi(endpoint);
2848 TALLOC_FREE(tmp_ctx);
2853 * Create a rpc pipe client struct, connecting to a host via tcp.
2854 * The port is determined by asking the endpoint mapper on the given
2857 NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host,
2858 const struct sockaddr_storage *addr,
2859 const struct ndr_interface_table *table,
2860 struct rpc_pipe_client **presult)
2865 status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2866 if (!NT_STATUS_IS_OK(status)) {
2870 return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2874 /********************************************************************
2875 Create a rpc pipe client struct, connecting to a unix domain socket
2876 ********************************************************************/
2877 NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path,
2878 const struct ndr_interface_table *table,
2879 struct rpc_pipe_client **presult)
2881 struct rpc_pipe_client *result;
2882 struct sockaddr_un addr;
2887 result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2888 if (result == NULL) {
2889 return NT_STATUS_NO_MEMORY;
2892 result->abstract_syntax = table->syntax_id;
2893 result->transfer_syntax = ndr_transfer_syntax_ndr;
2895 result->desthost = get_myname(result);
2896 result->srv_name_slash = talloc_asprintf_strupper_m(
2897 result, "\\\\%s", result->desthost);
2898 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2899 status = NT_STATUS_NO_MEMORY;
2903 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2905 fd = socket(AF_UNIX, SOCK_STREAM, 0);
2907 status = map_nt_error_from_unix(errno);
2912 addr.sun_family = AF_UNIX;
2913 strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path));
2914 salen = sizeof(struct sockaddr_un);
2916 if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
2917 DEBUG(0, ("connect(%s) failed: %s\n", socket_path,
2920 return map_nt_error_from_unix(errno);
2923 status = rpc_transport_sock_init(result, fd, &result->transport);
2924 if (!NT_STATUS_IS_OK(status)) {
2929 result->transport->transport = NCALRPC;
2931 result->binding_handle = rpccli_bh_create(result, NULL, table);
2932 if (result->binding_handle == NULL) {
2933 TALLOC_FREE(result);
2934 return NT_STATUS_NO_MEMORY;
2938 return NT_STATUS_OK;
2941 TALLOC_FREE(result);
2945 struct rpc_pipe_client_np_ref {
2946 struct cli_state *cli;
2947 struct rpc_pipe_client *pipe;
2950 static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
2952 DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
2956 /****************************************************************************
2957 Open a named pipe over SMB to a remote server.
2959 * CAVEAT CALLER OF THIS FUNCTION:
2960 * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
2961 * so be sure that this function is called AFTER any structure (vs pointer)
2962 * assignment of the cli. In particular, libsmbclient does structure
2963 * assignments of cli, which invalidates the data in the returned
2964 * rpc_pipe_client if this function is called before the structure assignment
2967 ****************************************************************************/
2969 static NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
2970 const struct ndr_interface_table *table,
2971 struct rpc_pipe_client **presult)
2973 struct rpc_pipe_client *result;
2975 struct rpc_pipe_client_np_ref *np_ref;
2977 /* sanity check to protect against crashes */
2980 return NT_STATUS_INVALID_HANDLE;
2983 result = talloc_zero(NULL, struct rpc_pipe_client);
2984 if (result == NULL) {
2985 return NT_STATUS_NO_MEMORY;
2988 result->abstract_syntax = table->syntax_id;
2989 result->transfer_syntax = ndr_transfer_syntax_ndr;
2990 result->desthost = talloc_strdup(result, smbXcli_conn_remote_name(cli->conn));
2991 result->srv_name_slash = talloc_asprintf_strupper_m(
2992 result, "\\\\%s", result->desthost);
2994 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2996 if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) {
2997 TALLOC_FREE(result);
2998 return NT_STATUS_NO_MEMORY;
3001 status = rpc_transport_np_init(result, cli, table,
3002 &result->transport);
3003 if (!NT_STATUS_IS_OK(status)) {
3004 TALLOC_FREE(result);
3008 result->transport->transport = NCACN_NP;
3010 np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3011 if (np_ref == NULL) {
3012 TALLOC_FREE(result);
3013 return NT_STATUS_NO_MEMORY;
3016 np_ref->pipe = result;
3018 DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3019 talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3021 result->binding_handle = rpccli_bh_create(result, NULL, table);
3022 if (result->binding_handle == NULL) {
3023 TALLOC_FREE(result);
3024 return NT_STATUS_NO_MEMORY;
3028 return NT_STATUS_OK;
3031 /****************************************************************************
3032 Open a pipe to a remote server.
3033 ****************************************************************************/
3035 static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3036 enum dcerpc_transport_t transport,
3037 const struct ndr_interface_table *table,
3038 struct rpc_pipe_client **presult)
3040 switch (transport) {
3042 return rpc_pipe_open_tcp(NULL,
3043 smbXcli_conn_remote_name(cli->conn),
3044 smbXcli_conn_remote_sockaddr(cli->conn),
3047 return rpc_pipe_open_np(cli, table, presult);
3049 return NT_STATUS_NOT_IMPLEMENTED;
3053 /****************************************************************************
3054 Open a named pipe to an SMB server and bind anonymously.
3055 ****************************************************************************/
3057 NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3058 enum dcerpc_transport_t transport,
3059 const struct ndr_interface_table *table,
3060 struct rpc_pipe_client **presult)
3062 struct rpc_pipe_client *result;
3063 struct pipe_auth_data *auth;
3066 status = cli_rpc_pipe_open(cli, transport, table, &result);
3067 if (!NT_STATUS_IS_OK(status)) {
3071 status = rpccli_anon_bind_data(result, &auth);
3072 if (!NT_STATUS_IS_OK(status)) {
3073 DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3074 nt_errstr(status)));
3075 TALLOC_FREE(result);
3080 * This is a bit of an abstraction violation due to the fact that an
3081 * anonymous bind on an authenticated SMB inherits the user/domain
3082 * from the enclosing SMB creds
3085 if (transport == NCACN_NP) {
3086 struct smbXcli_session *session;
3088 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
3089 session = cli->smb2.session;
3091 session = cli->smb1.session;
3094 status = smbXcli_session_application_key(session, auth,
3095 &auth->transport_session_key);
3096 if (!NT_STATUS_IS_OK(status)) {
3097 auth->transport_session_key = data_blob_null;
3101 status = rpc_pipe_bind(result, auth);
3102 if (!NT_STATUS_IS_OK(status)) {
3104 if (ndr_syntax_id_equal(&table->syntax_id,
3105 &ndr_table_dssetup.syntax_id)) {
3106 /* non AD domains just don't have this pipe, avoid
3107 * level 0 statement in that case - gd */
3110 DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3111 "%s failed with error %s\n",
3113 nt_errstr(status) ));
3114 TALLOC_FREE(result);
3118 DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3119 "%s and bound anonymously.\n",
3124 return NT_STATUS_OK;
3127 /****************************************************************************
3128 ****************************************************************************/
3130 NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3131 const struct ndr_interface_table *table,
3132 struct rpc_pipe_client **presult)
3134 return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3138 /****************************************************************************
3139 Open a named pipe to an SMB server and bind using the mech specified
3141 This routine references the creds pointer that is passed in
3142 ****************************************************************************/
3144 NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
3145 const struct ndr_interface_table *table,
3146 enum dcerpc_transport_t transport,
3147 enum dcerpc_AuthType auth_type,
3148 enum dcerpc_AuthLevel auth_level,
3150 struct cli_credentials *creds,
3151 struct rpc_pipe_client **presult)
3153 struct rpc_pipe_client *result;
3154 struct pipe_auth_data *auth = NULL;
3155 const char *target_service = table->authservices->names[0];
3159 status = cli_rpc_pipe_open(cli, transport, table, &result);
3160 if (!NT_STATUS_IS_OK(status)) {
3164 status = rpccli_generic_bind_data_from_creds(result,
3165 auth_type, auth_level,
3166 server, target_service,
3169 if (!NT_STATUS_IS_OK(status)) {
3170 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3171 nt_errstr(status)));
3175 status = rpc_pipe_bind(result, auth);
3176 if (!NT_STATUS_IS_OK(status)) {
3177 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3178 nt_errstr(status) ));
3182 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3183 "machine %s and bound as user %s.\n", table->name,
3184 result->desthost, cli_credentials_get_unparsed_name(creds, talloc_tos())));
3187 return NT_STATUS_OK;
3191 TALLOC_FREE(result);
3195 /****************************************************************************
3196 Open a named pipe to an SMB server and bind using the mech specified
3198 This routine steals the creds pointer that is passed in
3199 ****************************************************************************/
3201 NTSTATUS cli_rpc_pipe_open_generic_auth(struct cli_state *cli,
3202 const struct ndr_interface_table *table,
3203 enum dcerpc_transport_t transport,
3204 enum credentials_use_kerberos use_kerberos,
3205 enum dcerpc_AuthType auth_type,
3206 enum dcerpc_AuthLevel auth_level,
3209 const char *username,
3210 const char *password,
3211 struct rpc_pipe_client **presult)
3213 struct rpc_pipe_client *result;
3214 struct pipe_auth_data *auth = NULL;
3215 const char *target_service = table->authservices->names[0];
3219 status = cli_rpc_pipe_open(cli, transport, table, &result);
3220 if (!NT_STATUS_IS_OK(status)) {
3224 status = rpccli_generic_bind_data(result,
3225 auth_type, auth_level,
3226 server, target_service,
3227 domain, username, password,
3228 CRED_AUTO_USE_KERBEROS,
3231 if (!NT_STATUS_IS_OK(status)) {
3232 DEBUG(0, ("rpccli_generic_bind_data returned %s\n",
3233 nt_errstr(status)));
3237 status = rpc_pipe_bind(result, auth);
3238 if (!NT_STATUS_IS_OK(status)) {
3239 DEBUG(0, ("cli_rpc_pipe_open_generic_auth: cli_rpc_pipe_bind failed with error %s\n",
3240 nt_errstr(status) ));
3244 DEBUG(10,("cli_rpc_pipe_open_generic_auth: opened pipe %s to "
3245 "machine %s and bound as user %s\\%s.\n", table->name,
3246 result->desthost, domain, username));
3249 return NT_STATUS_OK;
3253 TALLOC_FREE(result);
3257 NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
3258 const struct ndr_interface_table *table,
3259 enum dcerpc_transport_t transport,
3260 struct cli_credentials *cli_creds,
3261 struct netlogon_creds_cli_context *netlogon_creds,
3262 struct rpc_pipe_client **_rpccli)
3264 struct rpc_pipe_client *rpccli;
3265 struct pipe_auth_data *rpcauth;
3266 const char *target_service = table->authservices->names[0];
3267 struct netlogon_creds_CredentialState *ncreds = NULL;
3268 enum dcerpc_AuthLevel auth_level;
3270 int rpc_pipe_bind_dbglvl = 0;
3272 status = cli_rpc_pipe_open(cli, transport, table, &rpccli);
3273 if (!NT_STATUS_IS_OK(status)) {
3277 status = netlogon_creds_cli_lock(netlogon_creds, rpccli, &ncreds);
3278 if (!NT_STATUS_IS_OK(status)) {
3279 DEBUG(0, ("netlogon_creds_cli_get returned %s\n",
3280 nt_errstr(status)));
3281 TALLOC_FREE(rpccli);
3285 auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3287 cli_credentials_set_netlogon_creds(cli_creds, ncreds);
3289 status = rpccli_generic_bind_data_from_creds(rpccli,
3290 DCERPC_AUTH_TYPE_SCHANNEL,
3296 if (!NT_STATUS_IS_OK(status)) {
3297 DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3298 nt_errstr(status)));
3299 TALLOC_FREE(rpccli);
3303 status = rpc_pipe_bind(rpccli, rpcauth);
3304 cli_credentials_set_netlogon_creds(cli_creds, NULL);
3305 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3306 rpc_pipe_bind_dbglvl = 1;
3307 netlogon_creds_cli_delete(netlogon_creds, &ncreds);
3309 if (!NT_STATUS_IS_OK(status)) {
3310 DEBUG(rpc_pipe_bind_dbglvl,
3311 ("%s: rpc_pipe_bind failed with error %s\n",
3312 __func__, nt_errstr(status)));
3313 TALLOC_FREE(rpccli);
3317 TALLOC_FREE(ncreds);
3319 if (!ndr_syntax_id_equal(&table->syntax_id, &ndr_table_netlogon.syntax_id)) {
3323 status = netlogon_creds_cli_check(netlogon_creds,
3324 rpccli->binding_handle);
3325 if (!NT_STATUS_IS_OK(status)) {
3326 DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3327 nt_errstr(status)));
3328 TALLOC_FREE(rpccli);
3334 DEBUG(10,("%s: opened pipe %s to machine %s "
3335 "for domain %s and bound using schannel.\n",
3336 __func__, table->name,
3337 rpccli->desthost, cli_credentials_get_domain(cli_creds)));
3340 return NT_STATUS_OK;
3343 NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3344 struct rpc_pipe_client *cli,
3345 DATA_BLOB *session_key)
3348 struct pipe_auth_data *a;
3349 struct gensec_security *gensec_security;
3350 DATA_BLOB sk = data_blob_null;
3351 bool make_dup = false;
3353 if (!session_key || !cli) {
3354 return NT_STATUS_INVALID_PARAMETER;
3360 return NT_STATUS_INVALID_PARAMETER;
3363 switch (cli->auth->auth_type) {
3364 case DCERPC_AUTH_TYPE_NONE:
3365 sk = data_blob_const(a->transport_session_key.data,
3366 a->transport_session_key.length);
3370 gensec_security = a->auth_ctx;
3371 status = gensec_session_key(gensec_security, mem_ctx, &sk);
3372 if (!NT_STATUS_IS_OK(status)) {
3380 return NT_STATUS_NO_USER_SESSION_KEY;
3384 *session_key = data_blob_dup_talloc(mem_ctx, sk);
3389 return NT_STATUS_OK;