Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : * RPC Pipe client routines
4 : * Largely rewritten by Jeremy Allison 2005.
5 : * Heavily modified by Simo Sorce 2010.
6 : * Copyright Andrew Bartlett 2011.
7 : *
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.
12 : *
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.
17 : *
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/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "libsmb/namequery.h"
24 : #include "../lib/util/tevent_ntstatus.h"
25 : #include "librpc/gen_ndr/ndr_epmapper_c.h"
26 : #include "../librpc/gen_ndr/ndr_dssetup.h"
27 : #include "../libcli/auth/schannel.h"
28 : #include "../libcli/auth/netlogon_creds_cli.h"
29 : #include "auth_generic.h"
30 : #include "librpc/gen_ndr/ndr_dcerpc.h"
31 : #include "librpc/gen_ndr/ndr_netlogon_c.h"
32 : #include "librpc/gen_ndr/auth.h"
33 : #include "librpc/rpc/dcerpc.h"
34 : #include "librpc/rpc/dcerpc_util.h"
35 : #include "rpc_dce.h"
36 : #include "cli_pipe.h"
37 : #include "libsmb/libsmb.h"
38 : #include "auth/gensec/gensec.h"
39 : #include "auth/credentials/credentials.h"
40 : #include "auth/auth_util.h"
41 : #include "../libcli/smb/smbXcli_base.h"
42 : #include "lib/tsocket/tsocket.h"
43 : #include "libcli/named_pipe_auth/npa_tstream.h"
44 : #include "librpc/gen_ndr/ndr_winreg.h"
45 : #include "local_np.h"
46 :
47 : #undef DBGC_CLASS
48 : #define DBGC_CLASS DBGC_RPC_CLI
49 :
50 : /********************************************************************
51 : Pipe description for a DEBUG
52 : ********************************************************************/
53 328 : static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
54 : struct rpc_pipe_client *cli)
55 : {
56 328 : char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
57 328 : if (result == NULL) {
58 0 : return "pipe";
59 : }
60 328 : return result;
61 : }
62 :
63 : /********************************************************************
64 : Rpc pipe call id.
65 : ********************************************************************/
66 :
67 588213 : static uint32_t get_rpc_call_id(void)
68 : {
69 0 : static uint32_t call_id = 0;
70 588213 : return ++call_id;
71 : }
72 :
73 : /*******************************************************************
74 : Use SMBreadX to get rest of one fragment's worth of rpc data.
75 : Reads the whole size or give an error message
76 : ********************************************************************/
77 :
78 : struct rpc_read_state {
79 : struct tevent_context *ev;
80 : struct rpc_cli_transport *transport;
81 : uint8_t *data;
82 : size_t size;
83 : size_t num_read;
84 : };
85 :
86 : static void rpc_read_done(struct tevent_req *subreq);
87 :
88 589144 : static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
89 : struct tevent_context *ev,
90 : struct rpc_cli_transport *transport,
91 : uint8_t *data, size_t size)
92 : {
93 0 : struct tevent_req *req, *subreq;
94 0 : struct rpc_read_state *state;
95 :
96 589144 : req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
97 589144 : if (req == NULL) {
98 0 : return NULL;
99 : }
100 589144 : state->ev = ev;
101 589144 : state->transport = transport;
102 589144 : state->data = data;
103 589144 : state->size = size;
104 589144 : state->num_read = 0;
105 :
106 589144 : DBG_INFO("data_to_read: %zu\n", size);
107 :
108 589144 : subreq = transport->read_send(state, ev, (uint8_t *)data, size,
109 : transport->priv);
110 589144 : if (subreq == NULL) {
111 0 : goto fail;
112 : }
113 589144 : tevent_req_set_callback(subreq, rpc_read_done, req);
114 589144 : return req;
115 :
116 0 : fail:
117 0 : TALLOC_FREE(req);
118 0 : return NULL;
119 : }
120 :
121 589144 : static void rpc_read_done(struct tevent_req *subreq)
122 : {
123 589144 : struct tevent_req *req = tevent_req_callback_data(
124 : subreq, struct tevent_req);
125 589144 : struct rpc_read_state *state = tevent_req_data(
126 : req, struct rpc_read_state);
127 0 : NTSTATUS status;
128 0 : ssize_t received;
129 :
130 589144 : status = state->transport->read_recv(subreq, &received);
131 589144 : TALLOC_FREE(subreq);
132 589144 : if (tevent_req_nterror(req, status)) {
133 589144 : return;
134 : }
135 :
136 589144 : state->num_read += received;
137 589144 : if (state->num_read == state->size) {
138 589144 : tevent_req_done(req);
139 589144 : return;
140 : }
141 :
142 0 : subreq = state->transport->read_send(state, state->ev,
143 0 : state->data + state->num_read,
144 0 : state->size - state->num_read,
145 0 : state->transport->priv);
146 0 : if (tevent_req_nomem(subreq, req)) {
147 0 : return;
148 : }
149 0 : tevent_req_set_callback(subreq, rpc_read_done, req);
150 : }
151 :
152 589144 : static NTSTATUS rpc_read_recv(struct tevent_req *req)
153 : {
154 589144 : return tevent_req_simple_recv_ntstatus(req);
155 : }
156 :
157 : struct rpc_write_state {
158 : struct tevent_context *ev;
159 : struct rpc_cli_transport *transport;
160 : const uint8_t *data;
161 : size_t size;
162 : size_t num_written;
163 : };
164 :
165 : static void rpc_write_done(struct tevent_req *subreq);
166 :
167 475086 : static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
168 : struct tevent_context *ev,
169 : struct rpc_cli_transport *transport,
170 : const uint8_t *data, size_t size)
171 : {
172 0 : struct tevent_req *req, *subreq;
173 0 : struct rpc_write_state *state;
174 :
175 475086 : req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
176 475086 : if (req == NULL) {
177 0 : return NULL;
178 : }
179 475086 : state->ev = ev;
180 475086 : state->transport = transport;
181 475086 : state->data = data;
182 475086 : state->size = size;
183 475086 : state->num_written = 0;
184 :
185 475086 : DBG_INFO("data_to_write: %zu\n", size);
186 :
187 475086 : subreq = transport->write_send(state, ev, data, size, transport->priv);
188 475086 : if (tevent_req_nomem(subreq, req)) {
189 0 : return tevent_req_post(req, ev);
190 : }
191 475086 : tevent_req_set_callback(subreq, rpc_write_done, req);
192 475086 : return req;
193 : }
194 :
195 475086 : static void rpc_write_done(struct tevent_req *subreq)
196 : {
197 475086 : struct tevent_req *req = tevent_req_callback_data(
198 : subreq, struct tevent_req);
199 475086 : struct rpc_write_state *state = tevent_req_data(
200 : req, struct rpc_write_state);
201 0 : NTSTATUS status;
202 0 : ssize_t written;
203 :
204 475086 : status = state->transport->write_recv(subreq, &written);
205 475086 : TALLOC_FREE(subreq);
206 475086 : if (tevent_req_nterror(req, status)) {
207 475086 : return;
208 : }
209 :
210 475086 : state->num_written += written;
211 :
212 475086 : if (state->num_written == state->size) {
213 475086 : tevent_req_done(req);
214 475086 : return;
215 : }
216 :
217 0 : subreq = state->transport->write_send(state, state->ev,
218 0 : state->data + state->num_written,
219 0 : state->size - state->num_written,
220 0 : state->transport->priv);
221 0 : if (tevent_req_nomem(subreq, req)) {
222 0 : return;
223 : }
224 0 : tevent_req_set_callback(subreq, rpc_write_done, req);
225 : }
226 :
227 475086 : static NTSTATUS rpc_write_recv(struct tevent_req *req)
228 : {
229 475086 : return tevent_req_simple_recv_ntstatus(req);
230 : }
231 :
232 :
233 : /****************************************************************************
234 : Try and get a PDU's worth of data from current_pdu. If not, then read more
235 : from the wire.
236 : ****************************************************************************/
237 :
238 : struct get_complete_frag_state {
239 : struct tevent_context *ev;
240 : struct rpc_pipe_client *cli;
241 : uint16_t frag_len;
242 : DATA_BLOB *pdu;
243 : };
244 :
245 : static void get_complete_frag_got_header(struct tevent_req *subreq);
246 : static void get_complete_frag_got_rest(struct tevent_req *subreq);
247 :
248 588758 : static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
249 : struct tevent_context *ev,
250 : struct rpc_pipe_client *cli,
251 : DATA_BLOB *pdu)
252 : {
253 0 : struct tevent_req *req, *subreq;
254 0 : struct get_complete_frag_state *state;
255 0 : size_t received;
256 :
257 588758 : req = tevent_req_create(mem_ctx, &state,
258 : struct get_complete_frag_state);
259 588758 : if (req == NULL) {
260 0 : return NULL;
261 : }
262 588758 : state->ev = ev;
263 588758 : state->cli = cli;
264 588758 : state->frag_len = RPC_HEADER_LEN;
265 588758 : state->pdu = pdu;
266 :
267 588758 : received = pdu->length;
268 588758 : if (received < RPC_HEADER_LEN) {
269 386 : if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
270 0 : tevent_req_oom(req);
271 0 : return tevent_req_post(req, ev);
272 : }
273 386 : subreq = rpc_read_send(state, state->ev,
274 386 : state->cli->transport,
275 386 : pdu->data + received,
276 : RPC_HEADER_LEN - received);
277 386 : if (tevent_req_nomem(subreq, req)) {
278 0 : return tevent_req_post(req, ev);
279 : }
280 386 : tevent_req_set_callback(subreq, get_complete_frag_got_header,
281 : req);
282 386 : return req;
283 : }
284 :
285 588372 : state->frag_len = dcerpc_get_frag_length(pdu);
286 588372 : if (state->frag_len < RPC_HEADER_LEN) {
287 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
288 0 : return tevent_req_post(req, ev);
289 : }
290 :
291 588372 : if (received >= state->frag_len) {
292 : /*
293 : * Got the whole fragment
294 : */
295 0 : tevent_req_done(req);
296 0 : return tevent_req_post(req, ev);
297 : }
298 :
299 588372 : if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
300 0 : tevent_req_oom(req);
301 0 : return tevent_req_post(req, ev);
302 : }
303 :
304 588372 : subreq = rpc_read_send(
305 : state,
306 588372 : state->ev,
307 588372 : state->cli->transport,
308 588372 : pdu->data + received,
309 588372 : state->frag_len - received);
310 588372 : if (tevent_req_nomem(subreq, req)) {
311 0 : return tevent_req_post(req, ev);
312 : }
313 588372 : tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
314 588372 : return req;
315 : }
316 :
317 386 : static void get_complete_frag_got_header(struct tevent_req *subreq)
318 : {
319 386 : struct tevent_req *req = tevent_req_callback_data(
320 : subreq, struct tevent_req);
321 386 : struct get_complete_frag_state *state = tevent_req_data(
322 : req, struct get_complete_frag_state);
323 0 : NTSTATUS status;
324 :
325 386 : status = rpc_read_recv(subreq);
326 386 : TALLOC_FREE(subreq);
327 386 : if (tevent_req_nterror(req, status)) {
328 0 : return;
329 : }
330 :
331 386 : state->frag_len = dcerpc_get_frag_length(state->pdu);
332 386 : if (state->frag_len < RPC_HEADER_LEN) {
333 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
334 0 : return;
335 : }
336 :
337 386 : if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
338 0 : tevent_req_oom(req);
339 0 : return;
340 : }
341 :
342 : /*
343 : * We're here in this piece of code because we've read exactly
344 : * RPC_HEADER_LEN bytes into state->pdu.
345 : */
346 :
347 386 : subreq = rpc_read_send(state, state->ev, state->cli->transport,
348 386 : state->pdu->data + RPC_HEADER_LEN,
349 386 : state->frag_len - RPC_HEADER_LEN);
350 386 : if (tevent_req_nomem(subreq, req)) {
351 0 : return;
352 : }
353 386 : tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
354 : }
355 :
356 588758 : static void get_complete_frag_got_rest(struct tevent_req *subreq)
357 : {
358 588758 : NTSTATUS status = rpc_read_recv(subreq);
359 588758 : return tevent_req_simple_finish_ntstatus(subreq, status);
360 : }
361 :
362 588758 : static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
363 : {
364 588758 : return tevent_req_simple_recv_ntstatus(req);
365 : }
366 :
367 : /****************************************************************************
368 : Do basic authentication checks on an incoming pdu.
369 : ****************************************************************************/
370 :
371 588758 : static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
372 : struct rpc_pipe_client *cli,
373 : struct ncacn_packet *pkt,
374 : DATA_BLOB *pdu,
375 : uint8_t expected_pkt_type,
376 : uint32_t call_id,
377 : DATA_BLOB *rdata,
378 : DATA_BLOB *reply_pdu)
379 : {
380 588758 : const struct dcerpc_response *r = NULL;
381 588758 : DATA_BLOB tmp_stub = { .data = NULL };
382 0 : NTSTATUS ret;
383 :
384 : /*
385 : * Point the return values at the real data including the RPC
386 : * header. Just in case the caller wants it.
387 : */
388 588758 : *rdata = *pdu;
389 :
390 588758 : if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
391 40968 : !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
392 : /*
393 : * TODO: do we still need this hack which was introduced
394 : * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
395 : *
396 : * I don't even know what AS/U might be...
397 : */
398 0 : DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
399 : "fragment first/last ON.\n"));
400 0 : pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
401 : }
402 :
403 : /* Ensure we have the correct type. */
404 588758 : switch (pkt->ptype) {
405 0 : case DCERPC_PKT_BIND_NAK:
406 0 : DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
407 : rpccli_pipe_txt(talloc_tos(), cli)));
408 :
409 0 : ret = dcerpc_verify_ncacn_packet_header(pkt,
410 : DCERPC_PKT_BIND_NAK,
411 : 0, /* max_auth_info */
412 : DCERPC_PFC_FLAG_FIRST |
413 : DCERPC_PFC_FLAG_LAST,
414 : 0); /* optional flags */
415 0 : if (!NT_STATUS_IS_OK(ret)) {
416 0 : DEBUG(1, (__location__ ": Connection to %s got an unexpected "
417 : "RPC packet type - %u, expected %u: %s\n",
418 : rpccli_pipe_txt(talloc_tos(), cli),
419 : pkt->ptype, expected_pkt_type,
420 : nt_errstr(ret)));
421 0 : NDR_PRINT_DEBUG(ncacn_packet, pkt);
422 222 : return ret;
423 : }
424 :
425 : /* Use this for now... */
426 0 : return NT_STATUS_NETWORK_ACCESS_DENIED;
427 :
428 40968 : case DCERPC_PKT_BIND_ACK:
429 40968 : ret = dcerpc_verify_ncacn_packet_header(pkt,
430 : expected_pkt_type,
431 : pkt->u.bind_ack.auth_info.length,
432 : DCERPC_PFC_FLAG_FIRST |
433 : DCERPC_PFC_FLAG_LAST,
434 : DCERPC_PFC_FLAG_CONC_MPX |
435 : DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
436 40968 : if (!NT_STATUS_IS_OK(ret)) {
437 0 : DEBUG(1, (__location__ ": Connection to %s got an unexpected "
438 : "RPC packet type - %u, expected %u: %s\n",
439 : rpccli_pipe_txt(talloc_tos(), cli),
440 : pkt->ptype, expected_pkt_type,
441 : nt_errstr(ret)));
442 0 : NDR_PRINT_DEBUG(ncacn_packet, pkt);
443 0 : return ret;
444 : }
445 :
446 40968 : break;
447 :
448 159 : case DCERPC_PKT_ALTER_RESP:
449 159 : ret = dcerpc_verify_ncacn_packet_header(pkt,
450 : expected_pkt_type,
451 : pkt->u.alter_resp.auth_info.length,
452 : DCERPC_PFC_FLAG_FIRST |
453 : DCERPC_PFC_FLAG_LAST,
454 : DCERPC_PFC_FLAG_CONC_MPX |
455 : DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
456 159 : if (!NT_STATUS_IS_OK(ret)) {
457 0 : DEBUG(1, (__location__ ": Connection to %s got an unexpected "
458 : "RPC packet type - %u, expected %u: %s\n",
459 : rpccli_pipe_txt(talloc_tos(), cli),
460 : pkt->ptype, expected_pkt_type,
461 : nt_errstr(ret)));
462 0 : NDR_PRINT_DEBUG(ncacn_packet, pkt);
463 0 : return ret;
464 : }
465 :
466 159 : break;
467 :
468 547409 : case DCERPC_PKT_RESPONSE:
469 :
470 547409 : r = &pkt->u.response;
471 :
472 547409 : ret = dcerpc_verify_ncacn_packet_header(pkt,
473 : expected_pkt_type,
474 547409 : r->stub_and_verifier.length,
475 : 0, /* required_flags */
476 : DCERPC_PFC_FLAG_FIRST |
477 : DCERPC_PFC_FLAG_LAST);
478 547409 : if (!NT_STATUS_IS_OK(ret)) {
479 0 : DEBUG(1, (__location__ ": Connection to %s got an unexpected "
480 : "RPC packet type - %u, expected %u: %s\n",
481 : rpccli_pipe_txt(talloc_tos(), cli),
482 : pkt->ptype, expected_pkt_type,
483 : nt_errstr(ret)));
484 0 : NDR_PRINT_DEBUG(ncacn_packet, pkt);
485 0 : return ret;
486 : }
487 :
488 547409 : tmp_stub.data = r->stub_and_verifier.data;
489 547409 : tmp_stub.length = r->stub_and_verifier.length;
490 :
491 : /* Here's where we deal with incoming sign/seal. */
492 547409 : ret = dcerpc_check_auth(cli->auth, pkt,
493 : &tmp_stub,
494 : DCERPC_RESPONSE_LENGTH,
495 : pdu);
496 547409 : if (!NT_STATUS_IS_OK(ret)) {
497 0 : DEBUG(1, (__location__ ": Connection to %s got an unexpected "
498 : "RPC packet type - %u, expected %u: %s\n",
499 : rpccli_pipe_txt(talloc_tos(), cli),
500 : pkt->ptype, expected_pkt_type,
501 : nt_errstr(ret)));
502 0 : NDR_PRINT_DEBUG(ncacn_packet, pkt);
503 0 : return ret;
504 : }
505 :
506 : /* Point the return values at the NDR data. */
507 547409 : *rdata = tmp_stub;
508 :
509 547409 : DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
510 : (long unsigned int)pdu->length,
511 : (long unsigned int)rdata->length));
512 :
513 : /*
514 : * If this is the first reply, and the allocation hint is
515 : * reasonable, try and set up the reply_pdu DATA_BLOB to the
516 : * correct size.
517 : */
518 :
519 547409 : if ((reply_pdu->length == 0) &&
520 547023 : r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
521 547023 : if (!data_blob_realloc(mem_ctx, reply_pdu,
522 547023 : r->alloc_hint)) {
523 0 : DEBUG(0, ("reply alloc hint %d too "
524 : "large to allocate\n",
525 : (int)r->alloc_hint));
526 0 : return NT_STATUS_NO_MEMORY;
527 : }
528 : }
529 :
530 547409 : break;
531 :
532 222 : case DCERPC_PKT_FAULT:
533 :
534 222 : ret = dcerpc_verify_ncacn_packet_header(pkt,
535 : DCERPC_PKT_FAULT,
536 : 0, /* max_auth_info */
537 : DCERPC_PFC_FLAG_FIRST |
538 : DCERPC_PFC_FLAG_LAST,
539 : DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
540 222 : if (!NT_STATUS_IS_OK(ret)) {
541 0 : DEBUG(1, (__location__ ": Connection to %s got an unexpected "
542 : "RPC packet type - %u, expected %u: %s\n",
543 : rpccli_pipe_txt(talloc_tos(), cli),
544 : pkt->ptype, expected_pkt_type,
545 : nt_errstr(ret)));
546 0 : NDR_PRINT_DEBUG(ncacn_packet, pkt);
547 0 : return ret;
548 : }
549 :
550 222 : DEBUG(1, (__location__ ": RPC fault code %s received "
551 : "from %s!\n",
552 : dcerpc_errstr(talloc_tos(),
553 : pkt->u.fault.status),
554 : rpccli_pipe_txt(talloc_tos(), cli)));
555 :
556 222 : return dcerpc_fault_to_nt_status(pkt->u.fault.status);
557 :
558 0 : default:
559 0 : DEBUG(0, (__location__ "Unknown packet type %u received "
560 : "from %s!\n",
561 : (unsigned int)pkt->ptype,
562 : rpccli_pipe_txt(talloc_tos(), cli)));
563 0 : return NT_STATUS_RPC_PROTOCOL_ERROR;
564 : }
565 :
566 :
567 588536 : if (pkt->call_id != call_id) {
568 0 : DEBUG(3, (__location__ ": Connection to %s got an unexpected "
569 : "RPC call_id - %u, not %u\n",
570 : rpccli_pipe_txt(talloc_tos(), cli),
571 : pkt->call_id, call_id));
572 0 : return NT_STATUS_RPC_PROTOCOL_ERROR;
573 : }
574 :
575 588536 : return NT_STATUS_OK;
576 : }
577 :
578 : /****************************************************************************
579 : Call a remote api on an arbitrary pipe. takes param, data and setup buffers.
580 : ****************************************************************************/
581 :
582 : struct cli_api_pipe_state {
583 : struct tevent_context *ev;
584 : struct rpc_cli_transport *transport;
585 : uint8_t *rdata;
586 : uint32_t rdata_len;
587 : };
588 :
589 : static void cli_api_pipe_trans_done(struct tevent_req *subreq);
590 : static void cli_api_pipe_write_done(struct tevent_req *subreq);
591 : static void cli_api_pipe_read_done(struct tevent_req *subreq);
592 :
593 588372 : static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
594 : struct tevent_context *ev,
595 : struct rpc_cli_transport *transport,
596 : uint8_t *data, size_t data_len,
597 : uint32_t max_rdata_len)
598 : {
599 0 : struct tevent_req *req, *subreq;
600 0 : struct cli_api_pipe_state *state;
601 :
602 588372 : req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
603 588372 : if (req == NULL) {
604 0 : return NULL;
605 : }
606 588372 : state->ev = ev;
607 588372 : state->transport = transport;
608 :
609 588372 : if (max_rdata_len < RPC_HEADER_LEN) {
610 : /*
611 : * For a RPC reply we always need at least RPC_HEADER_LEN
612 : * bytes. We check this here because we will receive
613 : * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
614 : */
615 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
616 0 : return tevent_req_post(req, ev);
617 : }
618 :
619 588372 : if (transport->trans_send != NULL) {
620 113360 : subreq = transport->trans_send(state, ev, data, data_len,
621 : max_rdata_len, transport->priv);
622 113360 : if (tevent_req_nomem(subreq, req)) {
623 0 : return tevent_req_post(req, ev);
624 : }
625 113360 : tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
626 113360 : return req;
627 : }
628 :
629 : /*
630 : * If the transport does not provide a "trans" routine, i.e. for
631 : * example the ncacn_ip_tcp transport, do the write/read step here.
632 : */
633 :
634 475012 : subreq = rpc_write_send(state, ev, transport, data, data_len);
635 475012 : if (tevent_req_nomem(subreq, req)) {
636 0 : return tevent_req_post(req, ev);
637 : }
638 475012 : tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
639 475012 : return req;
640 : }
641 :
642 113360 : static void cli_api_pipe_trans_done(struct tevent_req *subreq)
643 : {
644 113360 : struct tevent_req *req = tevent_req_callback_data(
645 : subreq, struct tevent_req);
646 113360 : struct cli_api_pipe_state *state = tevent_req_data(
647 : req, struct cli_api_pipe_state);
648 0 : NTSTATUS status;
649 :
650 113360 : status = state->transport->trans_recv(subreq, state, &state->rdata,
651 : &state->rdata_len);
652 113360 : TALLOC_FREE(subreq);
653 113360 : if (tevent_req_nterror(req, status)) {
654 0 : return;
655 : }
656 113360 : tevent_req_done(req);
657 : }
658 :
659 475012 : static void cli_api_pipe_write_done(struct tevent_req *subreq)
660 : {
661 475012 : struct tevent_req *req = tevent_req_callback_data(
662 : subreq, struct tevent_req);
663 475012 : struct cli_api_pipe_state *state = tevent_req_data(
664 : req, struct cli_api_pipe_state);
665 0 : NTSTATUS status;
666 :
667 475012 : status = rpc_write_recv(subreq);
668 475012 : TALLOC_FREE(subreq);
669 475012 : if (tevent_req_nterror(req, status)) {
670 0 : return;
671 : }
672 :
673 475012 : state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
674 475012 : if (tevent_req_nomem(state->rdata, req)) {
675 0 : return;
676 : }
677 :
678 : /*
679 : * We don't need to use rpc_read_send here, the upper layer will cope
680 : * with a short read, transport->trans_send could also return less
681 : * than state->max_rdata_len.
682 : */
683 475012 : subreq = state->transport->read_send(state, state->ev, state->rdata,
684 : RPC_HEADER_LEN,
685 475012 : state->transport->priv);
686 475012 : if (tevent_req_nomem(subreq, req)) {
687 0 : return;
688 : }
689 475012 : tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
690 : }
691 :
692 475012 : static void cli_api_pipe_read_done(struct tevent_req *subreq)
693 : {
694 475012 : struct tevent_req *req = tevent_req_callback_data(
695 : subreq, struct tevent_req);
696 475012 : struct cli_api_pipe_state *state = tevent_req_data(
697 : req, struct cli_api_pipe_state);
698 0 : NTSTATUS status;
699 0 : ssize_t received;
700 :
701 475012 : status = state->transport->read_recv(subreq, &received);
702 475012 : TALLOC_FREE(subreq);
703 475012 : if (tevent_req_nterror(req, status)) {
704 0 : return;
705 : }
706 475012 : state->rdata_len = received;
707 475012 : tevent_req_done(req);
708 : }
709 :
710 588372 : static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
711 : uint8_t **prdata, uint32_t *prdata_len)
712 : {
713 588372 : struct cli_api_pipe_state *state = tevent_req_data(
714 : req, struct cli_api_pipe_state);
715 0 : NTSTATUS status;
716 :
717 588372 : if (tevent_req_is_nterror(req, &status)) {
718 0 : return status;
719 : }
720 :
721 588372 : *prdata = talloc_move(mem_ctx, &state->rdata);
722 588372 : *prdata_len = state->rdata_len;
723 588372 : return NT_STATUS_OK;
724 : }
725 :
726 : /****************************************************************************
727 : Send data on an rpc pipe via trans. The data must be the last
728 : pdu fragment of an NDR data stream.
729 :
730 : Receive response data from an rpc pipe, which may be large...
731 :
732 : Read the first fragment: unfortunately have to use SMBtrans for the first
733 : bit, then SMBreadX for subsequent bits.
734 :
735 : If first fragment received also wasn't the last fragment, continue
736 : getting fragments until we _do_ receive the last fragment.
737 :
738 : Request/Response PDU's look like the following...
739 :
740 : |<------------------PDU len----------------------------------------------->|
741 : |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
742 :
743 : +------------+-----------------+-------------+---------------+-------------+
744 : | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
745 : +------------+-----------------+-------------+---------------+-------------+
746 :
747 : Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
748 : signing & sealing being negotiated.
749 :
750 : ****************************************************************************/
751 :
752 : struct rpc_api_pipe_state {
753 : struct tevent_context *ev;
754 : struct rpc_pipe_client *cli;
755 : uint8_t expected_pkt_type;
756 : uint32_t call_id;
757 :
758 : DATA_BLOB incoming_frag;
759 : struct ncacn_packet *pkt;
760 :
761 : /* Incoming reply */
762 : DATA_BLOB reply_pdu;
763 : size_t reply_pdu_offset;
764 : uint8_t endianness;
765 : };
766 :
767 : static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
768 : static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
769 : static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
770 :
771 588446 : static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
772 : struct tevent_context *ev,
773 : struct rpc_pipe_client *cli,
774 : DATA_BLOB *data, /* Outgoing PDU */
775 : uint8_t expected_pkt_type,
776 : uint32_t call_id)
777 : {
778 0 : struct tevent_req *req, *subreq;
779 0 : struct rpc_api_pipe_state *state;
780 0 : uint16_t max_recv_frag;
781 :
782 588446 : req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
783 588446 : if (req == NULL) {
784 0 : return NULL;
785 : }
786 588446 : state->ev = ev;
787 588446 : state->cli = cli;
788 588446 : state->expected_pkt_type = expected_pkt_type;
789 588446 : state->call_id = call_id;
790 588446 : state->endianness = DCERPC_DREP_LE;
791 :
792 : /*
793 : * Ensure we're not sending too much.
794 : */
795 588446 : if (data->length > cli->max_xmit_frag) {
796 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
797 0 : return tevent_req_post(req, ev);
798 : }
799 :
800 588446 : DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
801 :
802 588446 : if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
803 74 : subreq = rpc_write_send(state, ev, cli->transport,
804 74 : data->data, data->length);
805 74 : if (tevent_req_nomem(subreq, req)) {
806 0 : return tevent_req_post(req, ev);
807 : }
808 74 : tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
809 74 : return req;
810 : }
811 :
812 : /* get the header first, then fetch the rest once we have
813 : * the frag_length available */
814 588372 : max_recv_frag = RPC_HEADER_LEN;
815 :
816 588372 : subreq = cli_api_pipe_send(state, ev, cli->transport,
817 : data->data, data->length, max_recv_frag);
818 588372 : if (tevent_req_nomem(subreq, req)) {
819 0 : return tevent_req_post(req, ev);
820 : }
821 588372 : tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
822 588372 : return req;
823 : }
824 :
825 74 : static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
826 : {
827 74 : NTSTATUS status = rpc_write_recv(subreq);
828 74 : return tevent_req_simple_finish_ntstatus(subreq, status);
829 : }
830 :
831 588372 : static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
832 : {
833 588372 : struct tevent_req *req = tevent_req_callback_data(
834 : subreq, struct tevent_req);
835 588372 : struct rpc_api_pipe_state *state = tevent_req_data(
836 : req, struct rpc_api_pipe_state);
837 0 : NTSTATUS status;
838 588372 : uint8_t *rdata = NULL;
839 588372 : uint32_t rdata_len = 0;
840 :
841 588372 : status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
842 588372 : TALLOC_FREE(subreq);
843 588372 : if (tevent_req_nterror(req, status)) {;
844 0 : DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
845 0 : return;
846 : }
847 :
848 588372 : if (rdata == NULL) {
849 0 : DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
850 : rpccli_pipe_txt(talloc_tos(), state->cli)));
851 0 : tevent_req_done(req);
852 0 : return;
853 : }
854 :
855 : /*
856 : * Move data on state->incoming_frag.
857 : */
858 588372 : state->incoming_frag.data = talloc_move(state, &rdata);
859 588372 : state->incoming_frag.length = rdata_len;
860 588372 : if (!state->incoming_frag.data) {
861 0 : tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
862 0 : return;
863 : }
864 :
865 : /* Ensure we have enough data for a pdu. */
866 588372 : subreq = get_complete_frag_send(state, state->ev, state->cli,
867 : &state->incoming_frag);
868 588372 : if (tevent_req_nomem(subreq, req)) {
869 0 : return;
870 : }
871 588372 : tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
872 : }
873 :
874 588758 : static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
875 : {
876 588758 : struct tevent_req *req = tevent_req_callback_data(
877 : subreq, struct tevent_req);
878 588758 : struct rpc_api_pipe_state *state = tevent_req_data(
879 : req, struct rpc_api_pipe_state);
880 0 : NTSTATUS status;
881 588758 : DATA_BLOB rdata = { .data = NULL };
882 :
883 588758 : status = get_complete_frag_recv(subreq);
884 588758 : TALLOC_FREE(subreq);
885 588758 : if (tevent_req_nterror(req, status)) {
886 0 : DEBUG(5, ("get_complete_frag failed: %s\n",
887 : nt_errstr(status)));
888 588372 : return;
889 : }
890 :
891 588758 : state->pkt = talloc(state, struct ncacn_packet);
892 588758 : if (!state->pkt) {
893 : /*
894 : * TODO: do a real async disconnect ...
895 : *
896 : * For now do it sync...
897 : */
898 0 : TALLOC_FREE(state->cli->transport);
899 0 : tevent_req_oom(req);
900 0 : return;
901 : }
902 :
903 588758 : status = dcerpc_pull_ncacn_packet(state->pkt,
904 588758 : &state->incoming_frag,
905 : state->pkt);
906 588758 : if (tevent_req_nterror(req, status)) {
907 : /*
908 : * TODO: do a real async disconnect ...
909 : *
910 : * For now do it sync...
911 : */
912 0 : TALLOC_FREE(state->cli->transport);
913 0 : return;
914 : }
915 :
916 588758 : if (DEBUGLEVEL >= 10) {
917 98 : NDR_PRINT_DEBUG(ncacn_packet, state->pkt);
918 : }
919 :
920 588758 : status = cli_pipe_validate_current_pdu(state,
921 : state->cli, state->pkt,
922 : &state->incoming_frag,
923 588758 : state->expected_pkt_type,
924 : state->call_id,
925 : &rdata,
926 : &state->reply_pdu);
927 :
928 588758 : DBG_DEBUG("got frag len of %zu at offset %zu: %s\n",
929 : state->incoming_frag.length,
930 : state->reply_pdu_offset,
931 : nt_errstr(status));
932 :
933 588758 : if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) {
934 : /*
935 : * TODO: do a real async disconnect ...
936 : *
937 : * For now do it sync...
938 : */
939 0 : TALLOC_FREE(state->cli->transport);
940 588758 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
941 : /*
942 : * TODO: do a real async disconnect ...
943 : *
944 : * For now do it sync...
945 : */
946 0 : TALLOC_FREE(state->cli->transport);
947 588758 : } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
948 : /*
949 : * TODO: do a real async disconnect ...
950 : *
951 : * For now do it sync...
952 : */
953 0 : TALLOC_FREE(state->cli->transport);
954 : }
955 588758 : if (tevent_req_nterror(req, status)) {
956 222 : return;
957 : }
958 :
959 588536 : if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
960 588150 : && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
961 : /*
962 : * Set the data type correctly for big-endian data on the
963 : * first packet.
964 : */
965 0 : DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
966 : "big-endian.\n",
967 : rpccli_pipe_txt(talloc_tos(), state->cli)));
968 0 : state->endianness = 0x00; /* BIG ENDIAN */
969 : }
970 : /*
971 : * Check endianness on subsequent packets.
972 : */
973 588536 : if (state->endianness != state->pkt->drep[0]) {
974 0 : DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
975 : "%s\n",
976 : state->endianness?"little":"big",
977 : state->pkt->drep[0]?"little":"big"));
978 : /*
979 : * TODO: do a real async disconnect ...
980 : *
981 : * For now do it sync...
982 : */
983 0 : TALLOC_FREE(state->cli->transport);
984 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
985 0 : return;
986 : }
987 :
988 588536 : if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
989 : /*
990 : * TODO: do a real async disconnect ...
991 : *
992 : * For now do it sync...
993 : */
994 0 : TALLOC_FREE(state->cli->transport);
995 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
996 0 : return;
997 : }
998 :
999 : /* Now copy the data portion out of the pdu into rbuf. */
1000 588536 : if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1001 41127 : if (!data_blob_realloc(NULL, &state->reply_pdu,
1002 41127 : state->reply_pdu_offset + rdata.length)) {
1003 : /*
1004 : * TODO: do a real async disconnect ...
1005 : *
1006 : * For now do it sync...
1007 : */
1008 0 : TALLOC_FREE(state->cli->transport);
1009 0 : tevent_req_oom(req);
1010 0 : return;
1011 : }
1012 : }
1013 :
1014 588536 : memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1015 588536 : rdata.data, rdata.length);
1016 588536 : state->reply_pdu_offset += rdata.length;
1017 :
1018 : /* reset state->incoming_frag, there is no need to free it,
1019 : * it will be reallocated to the right size the next time
1020 : * it is used */
1021 588536 : state->incoming_frag.length = 0;
1022 :
1023 588536 : if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1024 : /* make sure the pdu length is right now that we
1025 : * have all the data available (alloc hint may
1026 : * have allocated more than was actually used) */
1027 588150 : state->reply_pdu.length = state->reply_pdu_offset;
1028 588150 : DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1029 : rpccli_pipe_txt(talloc_tos(), state->cli),
1030 : (unsigned)state->reply_pdu.length));
1031 588150 : tevent_req_done(req);
1032 588150 : return;
1033 : }
1034 :
1035 386 : subreq = get_complete_frag_send(state, state->ev, state->cli,
1036 : &state->incoming_frag);
1037 386 : if (subreq == NULL) {
1038 : /*
1039 : * TODO: do a real async disconnect ...
1040 : *
1041 : * For now do it sync...
1042 : */
1043 0 : TALLOC_FREE(state->cli->transport);
1044 : }
1045 386 : if (tevent_req_nomem(subreq, req)) {
1046 0 : return;
1047 : }
1048 386 : tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1049 : }
1050 :
1051 588446 : static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1052 : struct ncacn_packet **pkt,
1053 : DATA_BLOB *reply_pdu)
1054 : {
1055 588446 : struct rpc_api_pipe_state *state = tevent_req_data(
1056 : req, struct rpc_api_pipe_state);
1057 0 : NTSTATUS status;
1058 :
1059 588446 : if (tevent_req_is_nterror(req, &status)) {
1060 222 : return status;
1061 : }
1062 :
1063 : /* return data to caller and assign it ownership of memory */
1064 588224 : if (reply_pdu) {
1065 547023 : reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1066 547023 : reply_pdu->length = state->reply_pdu.length;
1067 547023 : state->reply_pdu.length = 0;
1068 : } else {
1069 41201 : data_blob_free(&state->reply_pdu);
1070 : }
1071 :
1072 588224 : if (pkt) {
1073 41201 : *pkt = talloc_steal(mem_ctx, state->pkt);
1074 : }
1075 :
1076 588224 : return NT_STATUS_OK;
1077 : }
1078 :
1079 : /*******************************************************************
1080 : Creates NTLMSSP auth bind.
1081 : ********************************************************************/
1082 :
1083 476 : static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1084 : TALLOC_CTX *mem_ctx,
1085 : DATA_BLOB *auth_token,
1086 : bool *client_hdr_signing)
1087 : {
1088 0 : struct gensec_security *gensec_security;
1089 476 : DATA_BLOB null_blob = { .data = NULL };
1090 0 : NTSTATUS status;
1091 :
1092 476 : gensec_security = cli->auth->auth_ctx;
1093 :
1094 476 : DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1095 476 : status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
1096 :
1097 476 : if (!NT_STATUS_IS_OK(status) &&
1098 476 : !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1099 : {
1100 0 : return status;
1101 : }
1102 :
1103 476 : if (client_hdr_signing == NULL) {
1104 0 : return status;
1105 : }
1106 :
1107 476 : if (cli->auth->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
1108 166 : *client_hdr_signing = false;
1109 166 : return status;
1110 : }
1111 :
1112 310 : *client_hdr_signing = gensec_have_feature(gensec_security,
1113 : GENSEC_FEATURE_SIGN_PKT_HEADER);
1114 :
1115 310 : return status;
1116 : }
1117 :
1118 : /*******************************************************************
1119 : Creates the internals of a DCE/RPC bind request or alter context PDU.
1120 : ********************************************************************/
1121 :
1122 41127 : static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1123 : enum dcerpc_pkt_type ptype,
1124 : uint32_t rpc_call_id,
1125 : const struct ndr_syntax_id *abstract,
1126 : const struct ndr_syntax_id *transfer,
1127 : const DATA_BLOB *auth_info,
1128 : bool client_hdr_signing,
1129 : DATA_BLOB *blob)
1130 : {
1131 41127 : uint16_t auth_len = auth_info->length;
1132 0 : NTSTATUS status;
1133 41127 : struct dcerpc_ctx_list ctx_list = {
1134 : .context_id = 0,
1135 : .num_transfer_syntaxes = 1,
1136 : .abstract_syntax = *abstract,
1137 : .transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer),
1138 : };
1139 41127 : union dcerpc_payload u = {
1140 : .bind.max_xmit_frag = RPC_MAX_PDU_FRAG_LEN,
1141 : .bind.max_recv_frag = RPC_MAX_PDU_FRAG_LEN,
1142 : .bind.num_contexts = 1,
1143 : .bind.ctx_list = &ctx_list,
1144 : .bind.auth_info = *auth_info,
1145 : };
1146 41127 : uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1147 :
1148 41127 : if (auth_len) {
1149 635 : auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1150 : }
1151 :
1152 41127 : if (client_hdr_signing) {
1153 310 : pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1154 : }
1155 :
1156 41127 : status = dcerpc_push_ncacn_packet(mem_ctx,
1157 : ptype, pfc_flags,
1158 : auth_len,
1159 : rpc_call_id,
1160 : &u,
1161 : blob);
1162 41127 : if (!NT_STATUS_IS_OK(status)) {
1163 0 : DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1164 0 : return status;
1165 : }
1166 :
1167 41127 : return NT_STATUS_OK;
1168 : }
1169 :
1170 : /*******************************************************************
1171 : Creates a DCE/RPC bind request.
1172 : ********************************************************************/
1173 :
1174 40968 : static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1175 : struct rpc_pipe_client *cli,
1176 : struct pipe_auth_data *auth,
1177 : uint32_t rpc_call_id,
1178 : const struct ndr_syntax_id *abstract,
1179 : const struct ndr_syntax_id *transfer,
1180 : DATA_BLOB *rpc_out)
1181 : {
1182 40968 : DATA_BLOB auth_token = { .data = NULL };
1183 40968 : DATA_BLOB auth_info = { .data = NULL };
1184 0 : NTSTATUS ret;
1185 :
1186 40968 : if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
1187 476 : ret = create_generic_auth_rpc_bind_req(
1188 : cli, mem_ctx, &auth_token, &auth->client_hdr_signing);
1189 :
1190 476 : if (!NT_STATUS_IS_OK(ret) &&
1191 476 : !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1192 0 : return ret;
1193 : }
1194 : }
1195 :
1196 40968 : if (auth_token.length != 0) {
1197 476 : ret = dcerpc_push_dcerpc_auth(cli,
1198 : auth->auth_type,
1199 : auth->auth_level,
1200 : 0, /* auth_pad_length */
1201 : auth->auth_context_id,
1202 : &auth_token,
1203 : &auth_info);
1204 476 : if (!NT_STATUS_IS_OK(ret)) {
1205 0 : return ret;
1206 : }
1207 476 : data_blob_free(&auth_token);
1208 : }
1209 :
1210 40968 : ret = create_bind_or_alt_ctx_internal(mem_ctx,
1211 : DCERPC_PKT_BIND,
1212 : rpc_call_id,
1213 : abstract,
1214 : transfer,
1215 : &auth_info,
1216 40968 : auth->client_hdr_signing,
1217 : rpc_out);
1218 40968 : data_blob_free(&auth_info);
1219 :
1220 40968 : return ret;
1221 : }
1222 :
1223 : /*******************************************************************
1224 : External interface.
1225 : Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1226 : Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1227 : and deals with signing/sealing details.
1228 : ********************************************************************/
1229 :
1230 : struct rpc_api_pipe_req_state {
1231 : struct tevent_context *ev;
1232 : struct rpc_pipe_client *cli;
1233 : uint8_t op_num;
1234 : uint32_t call_id;
1235 : const DATA_BLOB *req_data;
1236 : const struct GUID *object_uuid;
1237 : uint32_t req_data_sent;
1238 : DATA_BLOB req_trailer;
1239 : uint32_t req_trailer_sent;
1240 : bool verify_bitmask1;
1241 : bool verify_pcontext;
1242 : DATA_BLOB rpc_out;
1243 : DATA_BLOB reply_pdu;
1244 : };
1245 :
1246 : static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1247 : static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1248 : static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1249 : static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1250 : bool *is_last_frag);
1251 :
1252 547245 : static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1253 : struct tevent_context *ev,
1254 : struct rpc_pipe_client *cli,
1255 : uint8_t op_num,
1256 : const struct GUID *object_uuid,
1257 : const DATA_BLOB *req_data)
1258 : {
1259 0 : struct tevent_req *req, *subreq;
1260 0 : struct rpc_api_pipe_req_state *state;
1261 0 : NTSTATUS status;
1262 0 : bool is_last_frag;
1263 :
1264 547245 : req = tevent_req_create(mem_ctx, &state,
1265 : struct rpc_api_pipe_req_state);
1266 547245 : if (req == NULL) {
1267 0 : return NULL;
1268 : }
1269 547245 : state->ev = ev;
1270 547245 : state->cli = cli;
1271 547245 : state->op_num = op_num;
1272 547245 : state->object_uuid = object_uuid;
1273 547245 : state->req_data = req_data;
1274 547245 : state->call_id = get_rpc_call_id();
1275 :
1276 547245 : if (cli->max_xmit_frag < DCERPC_REQUEST_LENGTH
1277 : + RPC_MAX_SIGN_SIZE) {
1278 : /* Server is screwed up ! */
1279 0 : tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1280 0 : return tevent_req_post(req, ev);
1281 : }
1282 :
1283 547245 : status = prepare_verification_trailer(state);
1284 547245 : if (tevent_req_nterror(req, status)) {
1285 0 : return tevent_req_post(req, ev);
1286 : }
1287 :
1288 547245 : status = prepare_next_frag(state, &is_last_frag);
1289 547245 : if (tevent_req_nterror(req, status)) {
1290 0 : return tevent_req_post(req, ev);
1291 : }
1292 :
1293 547245 : if (is_last_frag) {
1294 547245 : subreq = rpc_api_pipe_send(state, ev, state->cli,
1295 547245 : &state->rpc_out,
1296 : DCERPC_PKT_RESPONSE,
1297 547245 : state->call_id);
1298 547245 : if (tevent_req_nomem(subreq, req)) {
1299 0 : return tevent_req_post(req, ev);
1300 : }
1301 547245 : tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1302 : } else {
1303 0 : subreq = rpc_write_send(state, ev, cli->transport,
1304 0 : state->rpc_out.data,
1305 0 : state->rpc_out.length);
1306 0 : if (tevent_req_nomem(subreq, req)) {
1307 0 : return tevent_req_post(req, ev);
1308 : }
1309 0 : tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1310 : req);
1311 : }
1312 547245 : return req;
1313 : }
1314 :
1315 547245 : static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1316 : {
1317 547245 : struct pipe_auth_data *a = state->cli->auth;
1318 0 : struct dcerpc_sec_verification_trailer *t;
1319 547245 : struct ndr_push *ndr = NULL;
1320 0 : enum ndr_err_code ndr_err;
1321 547245 : size_t align = 0;
1322 547245 : size_t pad = 0;
1323 :
1324 547245 : if (a == NULL) {
1325 0 : return NT_STATUS_OK;
1326 : }
1327 :
1328 547245 : if (a->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
1329 546879 : return NT_STATUS_OK;
1330 : }
1331 :
1332 366 : t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1333 366 : if (t == NULL) {
1334 0 : return NT_STATUS_NO_MEMORY;
1335 : }
1336 :
1337 366 : if (!a->verified_bitmask1) {
1338 310 : t->commands = talloc_realloc(t, t->commands,
1339 : struct dcerpc_sec_vt,
1340 : t->count.count + 1);
1341 310 : if (t->commands == NULL) {
1342 0 : return NT_STATUS_NO_MEMORY;
1343 : }
1344 310 : t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1345 : .command = DCERPC_SEC_VT_COMMAND_BITMASK1,
1346 310 : .u.bitmask1 = (a->client_hdr_signing) ?
1347 310 : DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING :
1348 : 0,
1349 : };
1350 310 : state->verify_bitmask1 = true;
1351 : }
1352 :
1353 366 : if (!state->cli->verified_pcontext) {
1354 310 : t->commands = talloc_realloc(t, t->commands,
1355 : struct dcerpc_sec_vt,
1356 : t->count.count + 1);
1357 310 : if (t->commands == NULL) {
1358 0 : return NT_STATUS_NO_MEMORY;
1359 : }
1360 310 : t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1361 : .command = DCERPC_SEC_VT_COMMAND_PCONTEXT,
1362 : .u.pcontext.abstract_syntax =
1363 310 : state->cli->abstract_syntax,
1364 : .u.pcontext.transfer_syntax =
1365 310 : state->cli->transfer_syntax,
1366 : };
1367 310 : state->verify_pcontext = true;
1368 : }
1369 :
1370 366 : if (!a->hdr_signing) {
1371 0 : t->commands = talloc_realloc(t, t->commands,
1372 : struct dcerpc_sec_vt,
1373 : t->count.count + 1);
1374 0 : if (t->commands == NULL) {
1375 0 : return NT_STATUS_NO_MEMORY;
1376 : }
1377 0 : t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1378 : .command = DCERPC_SEC_VT_COMMAND_HEADER2,
1379 : .u.header2.ptype = DCERPC_PKT_REQUEST,
1380 : .u.header2.drep[0] = DCERPC_DREP_LE,
1381 0 : .u.header2.call_id = state->call_id,
1382 : .u.header2.context_id = 0,
1383 0 : .u.header2.opnum = state->op_num,
1384 : };
1385 : }
1386 :
1387 366 : if (t->count.count == 0) {
1388 56 : TALLOC_FREE(t);
1389 56 : return NT_STATUS_OK;
1390 : }
1391 :
1392 310 : t->commands[t->count.count - 1].command |= DCERPC_SEC_VT_COMMAND_END;
1393 :
1394 310 : if (DEBUGLEVEL >= 10) {
1395 0 : NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1396 : }
1397 :
1398 310 : ndr = ndr_push_init_ctx(state);
1399 310 : if (ndr == NULL) {
1400 0 : return NT_STATUS_NO_MEMORY;
1401 : }
1402 :
1403 310 : ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1404 : NDR_SCALARS | NDR_BUFFERS,
1405 : t);
1406 310 : TALLOC_FREE(t);
1407 310 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1408 0 : return ndr_map_error2ntstatus(ndr_err);
1409 : }
1410 310 : state->req_trailer = ndr_push_blob(ndr);
1411 :
1412 310 : align = state->req_data->length & 0x3;
1413 310 : if (align > 0) {
1414 0 : pad = 4 - align;
1415 : }
1416 310 : if (pad > 0) {
1417 0 : bool ok;
1418 0 : uint8_t *p;
1419 0 : const uint8_t zeros[4] = { 0, };
1420 :
1421 0 : ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1422 0 : if (!ok) {
1423 0 : return NT_STATUS_NO_MEMORY;
1424 : }
1425 :
1426 : /* move the padding to the start */
1427 0 : p = state->req_trailer.data;
1428 0 : memmove(p + pad, p, state->req_trailer.length - pad);
1429 0 : memset(p, 0, pad);
1430 : }
1431 :
1432 310 : return NT_STATUS_OK;
1433 : }
1434 :
1435 547245 : static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1436 : bool *is_last_frag)
1437 : {
1438 0 : size_t auth_len;
1439 0 : size_t frag_len;
1440 547245 : uint8_t flags = 0;
1441 0 : size_t pad_len;
1442 0 : size_t data_left;
1443 0 : size_t data_thistime;
1444 0 : size_t trailer_left;
1445 547245 : size_t trailer_thistime = 0;
1446 0 : size_t total_left;
1447 0 : size_t total_thistime;
1448 0 : NTSTATUS status;
1449 0 : bool ok;
1450 0 : union dcerpc_payload u;
1451 :
1452 547245 : data_left = state->req_data->length - state->req_data_sent;
1453 547245 : trailer_left = state->req_trailer.length - state->req_trailer_sent;
1454 547245 : total_left = data_left + trailer_left;
1455 547245 : if ((total_left < data_left) || (total_left < trailer_left)) {
1456 : /*
1457 : * overflow
1458 : */
1459 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
1460 : }
1461 :
1462 547245 : status = dcerpc_guess_sizes(state->cli->auth,
1463 : DCERPC_REQUEST_LENGTH, total_left,
1464 547245 : state->cli->max_xmit_frag,
1465 : &total_thistime,
1466 : &frag_len, &auth_len, &pad_len);
1467 547245 : if (!NT_STATUS_IS_OK(status)) {
1468 0 : return status;
1469 : }
1470 :
1471 547245 : if (state->req_data_sent == 0) {
1472 547245 : flags = DCERPC_PFC_FLAG_FIRST;
1473 : }
1474 :
1475 547245 : if (total_thistime == total_left) {
1476 547245 : flags |= DCERPC_PFC_FLAG_LAST;
1477 : }
1478 :
1479 547245 : data_thistime = MIN(total_thistime, data_left);
1480 547245 : if (data_thistime < total_thistime) {
1481 310 : trailer_thistime = total_thistime - data_thistime;
1482 : }
1483 :
1484 547245 : data_blob_free(&state->rpc_out);
1485 :
1486 547245 : u = (union dcerpc_payload) {
1487 : .request.alloc_hint = total_left,
1488 : .request.context_id = 0,
1489 547245 : .request.opnum = state->op_num,
1490 : };
1491 :
1492 547245 : if (state->object_uuid) {
1493 0 : flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
1494 0 : u.request.object.object = *state->object_uuid;
1495 0 : frag_len += ndr_size_GUID(state->object_uuid, 0);
1496 : }
1497 :
1498 547245 : status = dcerpc_push_ncacn_packet(state,
1499 : DCERPC_PKT_REQUEST,
1500 : flags,
1501 : auth_len,
1502 : state->call_id,
1503 : &u,
1504 : &state->rpc_out);
1505 547245 : if (!NT_STATUS_IS_OK(status)) {
1506 0 : return status;
1507 : }
1508 :
1509 : /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1510 : * compute it right for requests because the auth trailer is missing
1511 : * at this stage */
1512 547245 : dcerpc_set_frag_length(&state->rpc_out, frag_len);
1513 :
1514 547245 : if (data_thistime > 0) {
1515 : /* Copy in the data. */
1516 547243 : ok = data_blob_append(NULL, &state->rpc_out,
1517 547243 : state->req_data->data + state->req_data_sent,
1518 : data_thistime);
1519 547243 : if (!ok) {
1520 0 : return NT_STATUS_NO_MEMORY;
1521 : }
1522 547243 : state->req_data_sent += data_thistime;
1523 : }
1524 :
1525 547245 : if (trailer_thistime > 0) {
1526 : /* Copy in the verification trailer. */
1527 310 : ok = data_blob_append(NULL, &state->rpc_out,
1528 310 : state->req_trailer.data + state->req_trailer_sent,
1529 : trailer_thistime);
1530 310 : if (!ok) {
1531 0 : return NT_STATUS_NO_MEMORY;
1532 : }
1533 310 : state->req_trailer_sent += trailer_thistime;
1534 : }
1535 :
1536 547245 : switch (state->cli->auth->auth_level) {
1537 546879 : case DCERPC_AUTH_LEVEL_NONE:
1538 : case DCERPC_AUTH_LEVEL_CONNECT:
1539 546879 : break;
1540 366 : case DCERPC_AUTH_LEVEL_PACKET:
1541 : case DCERPC_AUTH_LEVEL_INTEGRITY:
1542 : case DCERPC_AUTH_LEVEL_PRIVACY:
1543 366 : status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1544 : &state->rpc_out);
1545 366 : if (!NT_STATUS_IS_OK(status)) {
1546 0 : return status;
1547 : }
1548 366 : break;
1549 0 : default:
1550 0 : return NT_STATUS_INVALID_PARAMETER;
1551 : }
1552 :
1553 547245 : *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1554 :
1555 547245 : return status;
1556 : }
1557 :
1558 0 : static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1559 : {
1560 0 : struct tevent_req *req = tevent_req_callback_data(
1561 : subreq, struct tevent_req);
1562 0 : struct rpc_api_pipe_req_state *state = tevent_req_data(
1563 : req, struct rpc_api_pipe_req_state);
1564 0 : NTSTATUS status;
1565 0 : bool is_last_frag;
1566 :
1567 0 : status = rpc_write_recv(subreq);
1568 0 : TALLOC_FREE(subreq);
1569 0 : if (tevent_req_nterror(req, status)) {
1570 0 : return;
1571 : }
1572 :
1573 0 : status = prepare_next_frag(state, &is_last_frag);
1574 0 : if (tevent_req_nterror(req, status)) {
1575 0 : return;
1576 : }
1577 :
1578 0 : if (is_last_frag) {
1579 0 : subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1580 : &state->rpc_out,
1581 : DCERPC_PKT_RESPONSE,
1582 : state->call_id);
1583 0 : if (tevent_req_nomem(subreq, req)) {
1584 0 : return;
1585 : }
1586 0 : tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1587 : } else {
1588 0 : subreq = rpc_write_send(state, state->ev,
1589 0 : state->cli->transport,
1590 0 : state->rpc_out.data,
1591 : state->rpc_out.length);
1592 0 : if (tevent_req_nomem(subreq, req)) {
1593 0 : return;
1594 : }
1595 0 : tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1596 : req);
1597 : }
1598 : }
1599 :
1600 547245 : static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1601 : {
1602 547245 : struct tevent_req *req = tevent_req_callback_data(
1603 : subreq, struct tevent_req);
1604 547245 : struct rpc_api_pipe_req_state *state = tevent_req_data(
1605 : req, struct rpc_api_pipe_req_state);
1606 0 : NTSTATUS status;
1607 :
1608 547245 : status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1609 547245 : TALLOC_FREE(subreq);
1610 547245 : if (tevent_req_nterror(req, status)) {
1611 222 : return;
1612 : }
1613 :
1614 547023 : if (state->cli->auth == NULL) {
1615 0 : tevent_req_done(req);
1616 0 : return;
1617 : }
1618 :
1619 547023 : if (state->verify_bitmask1) {
1620 310 : state->cli->auth->verified_bitmask1 = true;
1621 : }
1622 :
1623 547023 : if (state->verify_pcontext) {
1624 310 : state->cli->verified_pcontext = true;
1625 : }
1626 :
1627 547023 : tevent_req_done(req);
1628 : }
1629 :
1630 547245 : static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1631 : DATA_BLOB *reply_pdu)
1632 : {
1633 547245 : struct rpc_api_pipe_req_state *state = tevent_req_data(
1634 : req, struct rpc_api_pipe_req_state);
1635 0 : NTSTATUS status;
1636 :
1637 547245 : if (tevent_req_is_nterror(req, &status)) {
1638 : /*
1639 : * We always have to initialize to reply pdu, even if there is
1640 : * none. The rpccli_* caller routines expect this.
1641 : */
1642 222 : *reply_pdu = data_blob_null;
1643 222 : return status;
1644 : }
1645 :
1646 : /* return data to caller and assign it ownership of memory */
1647 547023 : reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1648 547023 : reply_pdu->length = state->reply_pdu.length;
1649 547023 : state->reply_pdu.length = 0;
1650 :
1651 547023 : return NT_STATUS_OK;
1652 : }
1653 :
1654 : /****************************************************************************
1655 : Check the rpc bind acknowledge response.
1656 : ****************************************************************************/
1657 :
1658 41127 : static bool check_bind_response(const struct dcerpc_bind_ack *r,
1659 : const struct ndr_syntax_id *transfer)
1660 : {
1661 0 : struct dcerpc_ack_ctx ctx;
1662 0 : bool equal;
1663 :
1664 41127 : if (r->secondary_address_size == 0) {
1665 159 : DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)\n"));
1666 : }
1667 :
1668 41127 : if (r->num_results < 1 || !r->ctx_list) {
1669 0 : return false;
1670 : }
1671 :
1672 41127 : ctx = r->ctx_list[0];
1673 :
1674 : /* check the transfer syntax */
1675 41127 : equal = ndr_syntax_id_equal(&ctx.syntax, transfer);
1676 41127 : if (!equal) {
1677 0 : DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1678 0 : return False;
1679 : }
1680 :
1681 41127 : if (r->num_results != 0x1 || ctx.result != 0) {
1682 0 : DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
1683 : r->num_results, ctx.reason.value));
1684 : }
1685 :
1686 41127 : DEBUG(5,("check_bind_response: accepted!\n"));
1687 41127 : return True;
1688 : }
1689 :
1690 : /*******************************************************************
1691 : Creates a DCE/RPC bind authentication response.
1692 : This is the packet that is sent back to the server once we
1693 : have received a BIND-ACK, to finish the third leg of
1694 : the authentication handshake.
1695 : ********************************************************************/
1696 :
1697 74 : static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1698 : struct rpc_pipe_client *cli,
1699 : struct pipe_auth_data *auth,
1700 : uint32_t rpc_call_id,
1701 : DATA_BLOB *pauth_blob,
1702 : DATA_BLOB *rpc_out)
1703 : {
1704 0 : NTSTATUS status;
1705 74 : union dcerpc_payload u = { .auth3._pad = 0, };
1706 :
1707 74 : status = dcerpc_push_dcerpc_auth(mem_ctx,
1708 : auth->auth_type,
1709 : auth->auth_level,
1710 : 0, /* auth_pad_length */
1711 : auth->auth_context_id,
1712 : pauth_blob,
1713 : &u.auth3.auth_info);
1714 74 : if (!NT_STATUS_IS_OK(status)) {
1715 0 : return status;
1716 : }
1717 :
1718 74 : status = dcerpc_push_ncacn_packet(mem_ctx,
1719 : DCERPC_PKT_AUTH3,
1720 : DCERPC_PFC_FLAG_FIRST |
1721 : DCERPC_PFC_FLAG_LAST,
1722 74 : pauth_blob->length,
1723 : rpc_call_id,
1724 : &u,
1725 : rpc_out);
1726 74 : data_blob_free(&u.auth3.auth_info);
1727 74 : if (!NT_STATUS_IS_OK(status)) {
1728 0 : DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
1729 0 : return status;
1730 : }
1731 :
1732 74 : return NT_STATUS_OK;
1733 : }
1734 :
1735 : /*******************************************************************
1736 : Creates a DCE/RPC bind alter context authentication request which
1737 : may contain a spnego auth blob
1738 : ********************************************************************/
1739 :
1740 159 : static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
1741 : struct pipe_auth_data *auth,
1742 : uint32_t rpc_call_id,
1743 : const struct ndr_syntax_id *abstract,
1744 : const struct ndr_syntax_id *transfer,
1745 : const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
1746 : DATA_BLOB *rpc_out)
1747 : {
1748 0 : DATA_BLOB auth_info;
1749 0 : NTSTATUS status;
1750 :
1751 159 : status = dcerpc_push_dcerpc_auth(mem_ctx,
1752 : auth->auth_type,
1753 : auth->auth_level,
1754 : 0, /* auth_pad_length */
1755 : auth->auth_context_id,
1756 : pauth_blob,
1757 : &auth_info);
1758 159 : if (!NT_STATUS_IS_OK(status)) {
1759 0 : return status;
1760 : }
1761 :
1762 159 : status = create_bind_or_alt_ctx_internal(mem_ctx,
1763 : DCERPC_PKT_ALTER,
1764 : rpc_call_id,
1765 : abstract,
1766 : transfer,
1767 : &auth_info,
1768 : false, /* client_hdr_signing */
1769 : rpc_out);
1770 159 : data_blob_free(&auth_info);
1771 159 : return status;
1772 : }
1773 :
1774 : /****************************************************************************
1775 : Do an rpc bind.
1776 : ****************************************************************************/
1777 :
1778 : struct rpc_pipe_bind_state {
1779 : struct tevent_context *ev;
1780 : struct rpc_pipe_client *cli;
1781 : DATA_BLOB rpc_out;
1782 : bool auth3;
1783 : uint32_t rpc_call_id;
1784 : };
1785 :
1786 : static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
1787 : static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1788 : struct rpc_pipe_bind_state *state,
1789 : DATA_BLOB *credentials);
1790 : static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
1791 : struct rpc_pipe_bind_state *state,
1792 : DATA_BLOB *credentials);
1793 :
1794 40968 : struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
1795 : struct tevent_context *ev,
1796 : struct rpc_pipe_client *cli,
1797 : struct pipe_auth_data *auth)
1798 : {
1799 0 : struct tevent_req *req, *subreq;
1800 0 : struct rpc_pipe_bind_state *state;
1801 0 : NTSTATUS status;
1802 :
1803 40968 : req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
1804 40968 : if (req == NULL) {
1805 0 : return NULL;
1806 : }
1807 :
1808 40968 : DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
1809 : rpccli_pipe_txt(talloc_tos(), cli),
1810 : (unsigned int)auth->auth_type,
1811 : (unsigned int)auth->auth_level ));
1812 :
1813 40968 : state->ev = ev;
1814 40968 : state->cli = cli;
1815 40968 : state->rpc_call_id = get_rpc_call_id();
1816 :
1817 40968 : cli->auth = talloc_move(cli, &auth);
1818 :
1819 : /* Marshall the outgoing data. */
1820 40968 : status = create_rpc_bind_req(state, cli,
1821 : cli->auth,
1822 40968 : state->rpc_call_id,
1823 40968 : &cli->abstract_syntax,
1824 40968 : &cli->transfer_syntax,
1825 40968 : &state->rpc_out);
1826 :
1827 40968 : if (!NT_STATUS_IS_OK(status) &&
1828 0 : !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1829 0 : tevent_req_nterror(req, status);
1830 0 : return tevent_req_post(req, ev);
1831 : }
1832 :
1833 40968 : subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
1834 40968 : DCERPC_PKT_BIND_ACK, state->rpc_call_id);
1835 40968 : if (tevent_req_nomem(subreq, req)) {
1836 0 : return tevent_req_post(req, ev);
1837 : }
1838 40968 : tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1839 40968 : return req;
1840 : }
1841 :
1842 41201 : static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
1843 : {
1844 41201 : struct tevent_req *req = tevent_req_callback_data(
1845 : subreq, struct tevent_req);
1846 41201 : struct rpc_pipe_bind_state *state = tevent_req_data(
1847 : req, struct rpc_pipe_bind_state);
1848 41201 : struct pipe_auth_data *pauth = state->cli->auth;
1849 0 : struct gensec_security *gensec_security;
1850 41201 : struct ncacn_packet *pkt = NULL;
1851 0 : struct dcerpc_auth auth;
1852 41201 : DATA_BLOB auth_token = { .data = NULL };
1853 0 : NTSTATUS status;
1854 :
1855 41201 : status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
1856 41201 : TALLOC_FREE(subreq);
1857 41201 : if (tevent_req_nterror(req, status)) {
1858 0 : DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
1859 : rpccli_pipe_txt(talloc_tos(), state->cli),
1860 : nt_errstr(status)));
1861 0 : return;
1862 : }
1863 :
1864 41201 : if (state->auth3) {
1865 74 : tevent_req_done(req);
1866 74 : return;
1867 : }
1868 :
1869 41127 : if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) {
1870 0 : DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
1871 0 : tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
1872 0 : return;
1873 : }
1874 :
1875 41127 : if (pkt->ptype == DCERPC_PKT_BIND_ACK) {
1876 40968 : if (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) {
1877 310 : if (pauth->client_hdr_signing) {
1878 310 : pauth->hdr_signing = true;
1879 : }
1880 : }
1881 : }
1882 :
1883 41127 : state->cli->max_xmit_frag = pkt->u.bind_ack.max_xmit_frag;
1884 :
1885 41127 : if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
1886 : /* Bind complete. */
1887 40492 : tevent_req_done(req);
1888 40492 : return;
1889 : }
1890 :
1891 635 : if (pkt->auth_length == 0) {
1892 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1893 0 : return;
1894 : }
1895 :
1896 : /* get auth credentials */
1897 635 : status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
1898 635 : &pkt->u.bind_ack.auth_info,
1899 : &auth, NULL, true);
1900 635 : if (tevent_req_nterror(req, status)) {
1901 0 : DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
1902 : nt_errstr(status)));
1903 0 : return;
1904 : }
1905 :
1906 635 : if (auth.auth_type != pauth->auth_type) {
1907 0 : DBG_ERR("Auth type %u mismatch expected %u.\n",
1908 : auth.auth_type, pauth->auth_type);
1909 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1910 0 : return;
1911 : }
1912 :
1913 635 : if (auth.auth_level != pauth->auth_level) {
1914 0 : DBG_ERR("Auth level %u mismatch expected %u.\n",
1915 : auth.auth_level, pauth->auth_level);
1916 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1917 0 : return;
1918 : }
1919 :
1920 635 : if (auth.auth_context_id != pauth->auth_context_id) {
1921 0 : DBG_ERR("Auth context id %"PRIu32" mismatch "
1922 : "expected %"PRIu32".\n",
1923 : auth.auth_context_id,
1924 : pauth->auth_context_id);
1925 0 : tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1926 0 : return;
1927 : }
1928 :
1929 : /*
1930 : * For authenticated binds we may need to do 3 or 4 leg binds.
1931 : */
1932 :
1933 635 : if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
1934 : /* Bind complete. */
1935 0 : tevent_req_done(req);
1936 0 : return;
1937 : }
1938 :
1939 635 : gensec_security = pauth->auth_ctx;
1940 :
1941 635 : status = gensec_update(gensec_security, state,
1942 : auth.credentials, &auth_token);
1943 635 : if (NT_STATUS_EQUAL(status,
1944 : NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1945 159 : status = rpc_bind_next_send(req, state,
1946 : &auth_token);
1947 476 : } else if (NT_STATUS_IS_OK(status)) {
1948 476 : if (pauth->hdr_signing) {
1949 310 : gensec_want_feature(gensec_security,
1950 : GENSEC_FEATURE_SIGN_PKT_HEADER);
1951 : }
1952 :
1953 476 : if (auth_token.length == 0) {
1954 : /* Bind complete. */
1955 402 : tevent_req_done(req);
1956 402 : return;
1957 : }
1958 74 : status = rpc_bind_finish_send(req, state,
1959 : &auth_token);
1960 : }
1961 :
1962 233 : if (!NT_STATUS_IS_OK(status)) {
1963 0 : tevent_req_nterror(req, status);
1964 : }
1965 233 : return;
1966 : }
1967 :
1968 159 : static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
1969 : struct rpc_pipe_bind_state *state,
1970 : DATA_BLOB *auth_token)
1971 : {
1972 159 : struct pipe_auth_data *auth = state->cli->auth;
1973 0 : struct tevent_req *subreq;
1974 0 : NTSTATUS status;
1975 :
1976 : /* Now prepare the alter context pdu. */
1977 159 : data_blob_free(&state->rpc_out);
1978 :
1979 159 : status = create_rpc_alter_context(state, auth,
1980 : state->rpc_call_id,
1981 159 : &state->cli->abstract_syntax,
1982 159 : &state->cli->transfer_syntax,
1983 : auth_token,
1984 : &state->rpc_out);
1985 159 : if (!NT_STATUS_IS_OK(status)) {
1986 0 : return status;
1987 : }
1988 :
1989 159 : subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1990 : &state->rpc_out, DCERPC_PKT_ALTER_RESP,
1991 : state->rpc_call_id);
1992 159 : if (subreq == NULL) {
1993 0 : return NT_STATUS_NO_MEMORY;
1994 : }
1995 159 : tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
1996 159 : return NT_STATUS_OK;
1997 : }
1998 :
1999 74 : static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2000 : struct rpc_pipe_bind_state *state,
2001 : DATA_BLOB *auth_token)
2002 : {
2003 74 : struct pipe_auth_data *auth = state->cli->auth;
2004 0 : struct tevent_req *subreq;
2005 0 : NTSTATUS status;
2006 :
2007 74 : state->auth3 = true;
2008 :
2009 : /* Now prepare the auth3 context pdu. */
2010 74 : data_blob_free(&state->rpc_out);
2011 :
2012 74 : status = create_rpc_bind_auth3(state, state->cli, auth,
2013 : state->rpc_call_id,
2014 : auth_token,
2015 : &state->rpc_out);
2016 74 : if (!NT_STATUS_IS_OK(status)) {
2017 0 : return status;
2018 : }
2019 :
2020 74 : subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2021 : &state->rpc_out, DCERPC_PKT_AUTH3,
2022 : state->rpc_call_id);
2023 74 : if (subreq == NULL) {
2024 0 : return NT_STATUS_NO_MEMORY;
2025 : }
2026 74 : tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2027 74 : return NT_STATUS_OK;
2028 : }
2029 :
2030 40968 : NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2031 : {
2032 40968 : return tevent_req_simple_recv_ntstatus(req);
2033 : }
2034 :
2035 40968 : NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2036 : struct pipe_auth_data *auth)
2037 : {
2038 40968 : TALLOC_CTX *frame = talloc_stackframe();
2039 0 : struct tevent_context *ev;
2040 0 : struct tevent_req *req;
2041 40968 : NTSTATUS status = NT_STATUS_OK;
2042 :
2043 40968 : ev = samba_tevent_context_init(frame);
2044 40968 : if (ev == NULL) {
2045 0 : status = NT_STATUS_NO_MEMORY;
2046 0 : goto fail;
2047 : }
2048 :
2049 40968 : req = rpc_pipe_bind_send(frame, ev, cli, auth);
2050 40968 : if (req == NULL) {
2051 0 : status = NT_STATUS_NO_MEMORY;
2052 0 : goto fail;
2053 : }
2054 :
2055 40968 : if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2056 0 : goto fail;
2057 : }
2058 :
2059 40968 : status = rpc_pipe_bind_recv(req);
2060 40968 : fail:
2061 40968 : TALLOC_FREE(frame);
2062 40968 : return status;
2063 : }
2064 :
2065 : #define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2066 :
2067 700 : unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2068 : unsigned int timeout)
2069 : {
2070 700 : if (rpc_cli == NULL) {
2071 0 : return RPCCLI_DEFAULT_TIMEOUT;
2072 : }
2073 :
2074 700 : if (rpc_cli->binding_handle == NULL) {
2075 0 : return RPCCLI_DEFAULT_TIMEOUT;
2076 : }
2077 :
2078 700 : return dcerpc_binding_handle_set_timeout(rpc_cli->binding_handle,
2079 : timeout);
2080 : }
2081 :
2082 169 : bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2083 : {
2084 169 : if (rpc_cli == NULL) {
2085 84 : return false;
2086 : }
2087 :
2088 85 : if (rpc_cli->binding_handle == NULL) {
2089 0 : return false;
2090 : }
2091 :
2092 85 : return dcerpc_binding_handle_is_connected(rpc_cli->binding_handle);
2093 : }
2094 :
2095 : struct rpccli_bh_state {
2096 : struct rpc_pipe_client *rpc_cli;
2097 : };
2098 :
2099 547330 : static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2100 : {
2101 547330 : struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2102 : struct rpccli_bh_state);
2103 547330 : struct rpc_cli_transport *transport = hs->rpc_cli->transport;
2104 :
2105 547330 : if (transport == NULL) {
2106 0 : return false;
2107 : }
2108 :
2109 547330 : if (transport->is_connected == NULL) {
2110 0 : return false;
2111 : }
2112 :
2113 547330 : return transport->is_connected(transport->priv);
2114 : }
2115 :
2116 716 : static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2117 : uint32_t timeout)
2118 : {
2119 716 : struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2120 : struct rpccli_bh_state);
2121 716 : struct rpc_cli_transport *transport = hs->rpc_cli->transport;
2122 0 : unsigned int old;
2123 :
2124 716 : if (transport == NULL) {
2125 0 : return RPCCLI_DEFAULT_TIMEOUT;
2126 : }
2127 :
2128 716 : if (transport->set_timeout == NULL) {
2129 0 : return RPCCLI_DEFAULT_TIMEOUT;
2130 : }
2131 :
2132 716 : old = transport->set_timeout(transport->priv, timeout);
2133 716 : if (old == 0) {
2134 0 : return RPCCLI_DEFAULT_TIMEOUT;
2135 : }
2136 :
2137 716 : return old;
2138 : }
2139 :
2140 171 : static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2141 : enum dcerpc_AuthType *auth_type,
2142 : enum dcerpc_AuthLevel *auth_level)
2143 : {
2144 171 : struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2145 : struct rpccli_bh_state);
2146 :
2147 171 : if (hs->rpc_cli == NULL) {
2148 0 : return;
2149 : }
2150 :
2151 171 : if (hs->rpc_cli->auth == NULL) {
2152 0 : return;
2153 : }
2154 :
2155 171 : *auth_type = hs->rpc_cli->auth->auth_type;
2156 171 : *auth_level = hs->rpc_cli->auth->auth_level;
2157 : }
2158 :
2159 : struct rpccli_bh_raw_call_state {
2160 : DATA_BLOB in_data;
2161 : DATA_BLOB out_data;
2162 : uint32_t out_flags;
2163 : };
2164 :
2165 : static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2166 :
2167 547245 : static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2168 : struct tevent_context *ev,
2169 : struct dcerpc_binding_handle *h,
2170 : const struct GUID *object,
2171 : uint32_t opnum,
2172 : uint32_t in_flags,
2173 : const uint8_t *in_data,
2174 : size_t in_length)
2175 : {
2176 547245 : struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2177 : struct rpccli_bh_state);
2178 0 : struct tevent_req *req;
2179 0 : struct rpccli_bh_raw_call_state *state;
2180 0 : bool ok;
2181 0 : struct tevent_req *subreq;
2182 :
2183 547245 : req = tevent_req_create(mem_ctx, &state,
2184 : struct rpccli_bh_raw_call_state);
2185 547245 : if (req == NULL) {
2186 0 : return NULL;
2187 : }
2188 547245 : state->in_data.data = discard_const_p(uint8_t, in_data);
2189 547245 : state->in_data.length = in_length;
2190 :
2191 547245 : ok = rpccli_bh_is_connected(h);
2192 547245 : if (!ok) {
2193 0 : tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2194 0 : return tevent_req_post(req, ev);
2195 : }
2196 :
2197 547245 : subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2198 547245 : opnum, object, &state->in_data);
2199 547245 : if (tevent_req_nomem(subreq, req)) {
2200 0 : return tevent_req_post(req, ev);
2201 : }
2202 547245 : tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2203 :
2204 547245 : return req;
2205 : }
2206 :
2207 547245 : static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2208 : {
2209 0 : struct tevent_req *req =
2210 547245 : tevent_req_callback_data(subreq,
2211 : struct tevent_req);
2212 0 : struct rpccli_bh_raw_call_state *state =
2213 547245 : tevent_req_data(req,
2214 : struct rpccli_bh_raw_call_state);
2215 0 : NTSTATUS status;
2216 :
2217 547245 : state->out_flags = 0;
2218 :
2219 : /* TODO: support bigendian responses */
2220 :
2221 547245 : status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2222 547245 : TALLOC_FREE(subreq);
2223 547245 : if (tevent_req_nterror(req, status)) {
2224 222 : return;
2225 : }
2226 :
2227 547023 : tevent_req_done(req);
2228 : }
2229 :
2230 547245 : static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2231 : TALLOC_CTX *mem_ctx,
2232 : uint8_t **out_data,
2233 : size_t *out_length,
2234 : uint32_t *out_flags)
2235 : {
2236 0 : struct rpccli_bh_raw_call_state *state =
2237 547245 : tevent_req_data(req,
2238 : struct rpccli_bh_raw_call_state);
2239 0 : NTSTATUS status;
2240 :
2241 547245 : if (tevent_req_is_nterror(req, &status)) {
2242 222 : tevent_req_received(req);
2243 222 : return status;
2244 : }
2245 :
2246 547023 : *out_data = talloc_move(mem_ctx, &state->out_data.data);
2247 547023 : *out_length = state->out_data.length;
2248 547023 : *out_flags = state->out_flags;
2249 547023 : tevent_req_received(req);
2250 547023 : return NT_STATUS_OK;
2251 : }
2252 :
2253 : struct rpccli_bh_disconnect_state {
2254 : uint8_t _dummy;
2255 : };
2256 :
2257 0 : static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2258 : struct tevent_context *ev,
2259 : struct dcerpc_binding_handle *h)
2260 : {
2261 0 : struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2262 : struct rpccli_bh_state);
2263 0 : struct tevent_req *req;
2264 0 : struct rpccli_bh_disconnect_state *state;
2265 0 : bool ok;
2266 :
2267 0 : req = tevent_req_create(mem_ctx, &state,
2268 : struct rpccli_bh_disconnect_state);
2269 0 : if (req == NULL) {
2270 0 : return NULL;
2271 : }
2272 :
2273 0 : ok = rpccli_bh_is_connected(h);
2274 0 : if (!ok) {
2275 0 : tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2276 0 : return tevent_req_post(req, ev);
2277 : }
2278 :
2279 : /*
2280 : * TODO: do a real async disconnect ...
2281 : *
2282 : * For now we do it sync...
2283 : */
2284 0 : TALLOC_FREE(hs->rpc_cli->transport);
2285 0 : hs->rpc_cli = NULL;
2286 :
2287 0 : tevent_req_done(req);
2288 0 : return tevent_req_post(req, ev);
2289 : }
2290 :
2291 0 : static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2292 : {
2293 0 : return tevent_req_simple_recv_ntstatus(req);
2294 : }
2295 :
2296 547245 : static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2297 : {
2298 547245 : return true;
2299 : }
2300 :
2301 1094268 : static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2302 : ndr_flags_type ndr_flags,
2303 : const void *_struct_ptr,
2304 : const struct ndr_interface_call *call)
2305 : {
2306 1094268 : void *struct_ptr = discard_const(_struct_ptr);
2307 :
2308 1094268 : if (DEBUGLEVEL < 10) {
2309 1094080 : return;
2310 : }
2311 :
2312 188 : if (ndr_flags & NDR_IN) {
2313 94 : ndr_print_function_debug(call->ndr_print,
2314 94 : call->name,
2315 : ndr_flags,
2316 : struct_ptr);
2317 : }
2318 188 : if (ndr_flags & NDR_OUT) {
2319 94 : ndr_print_function_debug(call->ndr_print,
2320 94 : call->name,
2321 : ndr_flags,
2322 : struct_ptr);
2323 : }
2324 : }
2325 :
2326 : static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2327 : .name = "rpccli",
2328 : .is_connected = rpccli_bh_is_connected,
2329 : .set_timeout = rpccli_bh_set_timeout,
2330 : .auth_info = rpccli_bh_auth_info,
2331 : .raw_call_send = rpccli_bh_raw_call_send,
2332 : .raw_call_recv = rpccli_bh_raw_call_recv,
2333 : .disconnect_send = rpccli_bh_disconnect_send,
2334 : .disconnect_recv = rpccli_bh_disconnect_recv,
2335 :
2336 : .ref_alloc = rpccli_bh_ref_alloc,
2337 : .do_ndr_print = rpccli_bh_do_ndr_print,
2338 : };
2339 :
2340 : /* initialise a rpc_pipe_client binding handle */
2341 40968 : struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2342 : const struct GUID *object,
2343 : const struct ndr_interface_table *table)
2344 : {
2345 0 : struct dcerpc_binding_handle *h;
2346 0 : struct rpccli_bh_state *hs;
2347 :
2348 40968 : h = dcerpc_binding_handle_create(c,
2349 : &rpccli_bh_ops,
2350 : object,
2351 : table,
2352 : &hs,
2353 : struct rpccli_bh_state,
2354 : __location__);
2355 40968 : if (h == NULL) {
2356 0 : return NULL;
2357 : }
2358 40968 : hs->rpc_cli = c;
2359 :
2360 40968 : return h;
2361 : }
2362 :
2363 40492 : NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2364 : struct pipe_auth_data **presult)
2365 : {
2366 0 : struct pipe_auth_data *result;
2367 0 : struct auth_generic_state *auth_generic_ctx;
2368 0 : NTSTATUS status;
2369 :
2370 40492 : result = talloc_zero(mem_ctx, struct pipe_auth_data);
2371 40492 : if (result == NULL) {
2372 0 : return NT_STATUS_NO_MEMORY;
2373 : }
2374 :
2375 40492 : result->auth_type = DCERPC_AUTH_TYPE_NONE;
2376 40492 : result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2377 40492 : result->auth_context_id = 0;
2378 :
2379 40492 : status = auth_generic_client_prepare(result,
2380 : &auth_generic_ctx);
2381 40492 : if (!NT_STATUS_IS_OK(status)) {
2382 0 : DEBUG(1, ("Failed to create auth_generic context: %s\n",
2383 : nt_errstr(status)));
2384 : }
2385 :
2386 40492 : status = auth_generic_set_username(auth_generic_ctx, "");
2387 40492 : if (!NT_STATUS_IS_OK(status)) {
2388 0 : DEBUG(1, ("Failed to set username: %s\n",
2389 : nt_errstr(status)));
2390 : }
2391 :
2392 40492 : status = auth_generic_set_domain(auth_generic_ctx, "");
2393 40492 : if (!NT_STATUS_IS_OK(status)) {
2394 0 : DEBUG(1, ("Failed to set domain: %s\n",
2395 : nt_errstr(status)));
2396 0 : return status;
2397 : }
2398 :
2399 40492 : status = gensec_set_credentials(auth_generic_ctx->gensec_security,
2400 40492 : auth_generic_ctx->credentials);
2401 40492 : if (!NT_STATUS_IS_OK(status)) {
2402 0 : DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2403 : nt_errstr(status)));
2404 0 : return status;
2405 : }
2406 40492 : talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
2407 40492 : auth_generic_ctx->credentials = NULL;
2408 :
2409 40492 : result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2410 40492 : talloc_free(auth_generic_ctx);
2411 40492 : *presult = result;
2412 40492 : return NT_STATUS_OK;
2413 : }
2414 :
2415 136 : static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2416 : enum dcerpc_AuthType auth_type,
2417 : enum dcerpc_AuthLevel auth_level,
2418 : const char *server,
2419 : const char *target_service,
2420 : const char *domain,
2421 : const char *username,
2422 : const char *password,
2423 : enum credentials_use_kerberos use_kerberos,
2424 : struct netlogon_creds_CredentialState *creds,
2425 : struct pipe_auth_data **presult)
2426 : {
2427 0 : struct auth_generic_state *auth_generic_ctx;
2428 0 : struct pipe_auth_data *result;
2429 0 : NTSTATUS status;
2430 :
2431 136 : result = talloc_zero(mem_ctx, struct pipe_auth_data);
2432 136 : if (result == NULL) {
2433 0 : return NT_STATUS_NO_MEMORY;
2434 : }
2435 :
2436 136 : result->auth_type = auth_type;
2437 136 : result->auth_level = auth_level;
2438 136 : result->auth_context_id = 1;
2439 :
2440 136 : status = auth_generic_client_prepare(result,
2441 : &auth_generic_ctx);
2442 136 : if (!NT_STATUS_IS_OK(status)) {
2443 0 : goto fail;
2444 : }
2445 :
2446 136 : status = auth_generic_set_username(auth_generic_ctx, username);
2447 136 : if (!NT_STATUS_IS_OK(status)) {
2448 0 : goto fail;
2449 : }
2450 :
2451 136 : status = auth_generic_set_domain(auth_generic_ctx, domain);
2452 136 : if (!NT_STATUS_IS_OK(status)) {
2453 0 : goto fail;
2454 : }
2455 :
2456 136 : status = auth_generic_set_password(auth_generic_ctx, password);
2457 136 : if (!NT_STATUS_IS_OK(status)) {
2458 0 : goto fail;
2459 : }
2460 :
2461 136 : status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2462 136 : if (!NT_STATUS_IS_OK(status)) {
2463 0 : goto fail;
2464 : }
2465 :
2466 136 : status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2467 136 : if (!NT_STATUS_IS_OK(status)) {
2468 0 : goto fail;
2469 : }
2470 :
2471 136 : cli_credentials_set_kerberos_state(auth_generic_ctx->credentials,
2472 : use_kerberos,
2473 : CRED_SPECIFIED);
2474 136 : cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2475 :
2476 136 : status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2477 136 : if (!NT_STATUS_IS_OK(status)) {
2478 0 : goto fail;
2479 : }
2480 :
2481 136 : result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2482 136 : talloc_free(auth_generic_ctx);
2483 136 : *presult = result;
2484 136 : return NT_STATUS_OK;
2485 :
2486 0 : fail:
2487 0 : TALLOC_FREE(result);
2488 0 : return status;
2489 : }
2490 :
2491 : /* This routine steals the creds pointer that is passed in */
2492 340 : static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
2493 : enum dcerpc_AuthType auth_type,
2494 : enum dcerpc_AuthLevel auth_level,
2495 : const char *server,
2496 : const char *target_service,
2497 : struct cli_credentials *creds,
2498 : struct pipe_auth_data **presult)
2499 : {
2500 0 : struct auth_generic_state *auth_generic_ctx;
2501 0 : struct pipe_auth_data *result;
2502 0 : NTSTATUS status;
2503 :
2504 340 : result = talloc_zero(mem_ctx, struct pipe_auth_data);
2505 340 : if (result == NULL) {
2506 0 : return NT_STATUS_NO_MEMORY;
2507 : }
2508 :
2509 340 : result->auth_type = auth_type;
2510 340 : result->auth_level = auth_level;
2511 340 : result->auth_context_id = 1;
2512 :
2513 340 : status = auth_generic_client_prepare(result,
2514 : &auth_generic_ctx);
2515 340 : if (!NT_STATUS_IS_OK(status)) {
2516 0 : goto fail;
2517 : }
2518 :
2519 340 : status = auth_generic_set_creds(auth_generic_ctx, creds);
2520 340 : if (!NT_STATUS_IS_OK(status)) {
2521 0 : goto fail;
2522 : }
2523 :
2524 340 : status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2525 340 : if (!NT_STATUS_IS_OK(status)) {
2526 0 : goto fail;
2527 : }
2528 :
2529 340 : status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2530 340 : if (!NT_STATUS_IS_OK(status)) {
2531 0 : goto fail;
2532 : }
2533 :
2534 340 : status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2535 340 : if (!NT_STATUS_IS_OK(status)) {
2536 0 : goto fail;
2537 : }
2538 :
2539 340 : result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2540 340 : talloc_free(auth_generic_ctx);
2541 340 : *presult = result;
2542 340 : return NT_STATUS_OK;
2543 :
2544 0 : fail:
2545 0 : TALLOC_FREE(result);
2546 0 : return status;
2547 : }
2548 :
2549 136 : NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
2550 : struct pipe_auth_data **presult)
2551 : {
2552 136 : return rpccli_generic_bind_data(mem_ctx,
2553 : DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
2554 : DCERPC_AUTH_LEVEL_CONNECT,
2555 : NULL, /* server */
2556 : "host", /* target_service */
2557 : NAME_NT_AUTHORITY, /* domain */
2558 : "SYSTEM",
2559 : NULL, /* password */
2560 : CRED_USE_KERBEROS_DISABLED,
2561 : NULL, /* netlogon_creds_CredentialState */
2562 : presult);
2563 : }
2564 :
2565 : /**
2566 : * Create an rpc pipe client struct, connecting to a tcp port.
2567 : */
2568 100 : static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx, const char *host,
2569 : const struct sockaddr_storage *ss_addr,
2570 : uint16_t port,
2571 : const struct ndr_interface_table *table,
2572 : struct rpc_pipe_client **presult)
2573 : {
2574 0 : struct rpc_pipe_client *result;
2575 0 : struct sockaddr_storage addr;
2576 0 : NTSTATUS status;
2577 0 : int fd;
2578 :
2579 100 : result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2580 100 : if (result == NULL) {
2581 0 : return NT_STATUS_NO_MEMORY;
2582 : }
2583 :
2584 100 : result->abstract_syntax = table->syntax_id;
2585 100 : result->transfer_syntax = ndr_transfer_syntax_ndr;
2586 :
2587 100 : result->desthost = talloc_strdup(result, host);
2588 100 : if (result->desthost == NULL) {
2589 0 : status = NT_STATUS_NO_MEMORY;
2590 0 : goto fail;
2591 : }
2592 :
2593 100 : result->srv_name_slash = talloc_asprintf_strupper_m(
2594 : result, "\\\\%s", result->desthost);
2595 100 : if (result->srv_name_slash == NULL) {
2596 0 : status = NT_STATUS_NO_MEMORY;
2597 0 : goto fail;
2598 : }
2599 :
2600 100 : result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
2601 :
2602 100 : if (ss_addr == NULL) {
2603 0 : if (!resolve_name(host, &addr, NBT_NAME_SERVER, false)) {
2604 0 : status = NT_STATUS_NOT_FOUND;
2605 0 : goto fail;
2606 : }
2607 : } else {
2608 100 : addr = *ss_addr;
2609 : }
2610 :
2611 100 : status = open_socket_out(&addr, port, 60*1000, &fd);
2612 100 : if (!NT_STATUS_IS_OK(status)) {
2613 0 : goto fail;
2614 : }
2615 100 : set_socket_options(fd, lp_socket_options());
2616 :
2617 100 : status = rpc_transport_sock_init(result, fd, &result->transport);
2618 100 : if (!NT_STATUS_IS_OK(status)) {
2619 0 : close(fd);
2620 0 : goto fail;
2621 : }
2622 :
2623 100 : result->transport->transport = NCACN_IP_TCP;
2624 :
2625 100 : result->binding_handle = rpccli_bh_create(result, NULL, table);
2626 100 : if (result->binding_handle == NULL) {
2627 0 : TALLOC_FREE(result);
2628 0 : return NT_STATUS_NO_MEMORY;
2629 : }
2630 :
2631 100 : *presult = result;
2632 100 : return NT_STATUS_OK;
2633 :
2634 0 : fail:
2635 0 : TALLOC_FREE(result);
2636 0 : return status;
2637 : }
2638 :
2639 2 : static NTSTATUS rpccli_epm_map_binding(
2640 : struct dcerpc_binding_handle *epm_connection,
2641 : struct dcerpc_binding *binding,
2642 : TALLOC_CTX *mem_ctx,
2643 : char **pendpoint)
2644 : {
2645 2 : TALLOC_CTX *frame = talloc_stackframe();
2646 0 : enum dcerpc_transport_t transport =
2647 2 : dcerpc_binding_get_transport(binding);
2648 0 : enum dcerpc_transport_t res_transport;
2649 2 : struct dcerpc_binding *res_binding = NULL;
2650 2 : struct epm_twr_t *map_tower = NULL;
2651 2 : struct epm_twr_p_t res_towers = { .twr = NULL };
2652 2 : struct policy_handle *entry_handle = NULL;
2653 2 : uint32_t num_towers = 0;
2654 2 : const uint32_t max_towers = 1;
2655 2 : const char *endpoint = NULL;
2656 2 : char *tmp = NULL;
2657 0 : uint32_t result;
2658 0 : NTSTATUS status;
2659 :
2660 2 : map_tower = talloc_zero(frame, struct epm_twr_t);
2661 2 : if (map_tower == NULL) {
2662 0 : goto nomem;
2663 : }
2664 :
2665 2 : status = dcerpc_binding_build_tower(
2666 : frame, binding, &(map_tower->tower));
2667 2 : if (!NT_STATUS_IS_OK(status)) {
2668 0 : DBG_DEBUG("dcerpc_binding_build_tower failed: %s\n",
2669 : nt_errstr(status));
2670 0 : goto done;
2671 : }
2672 :
2673 2 : res_towers.twr = talloc_array(frame, struct epm_twr_t, max_towers);
2674 2 : if (res_towers.twr == NULL) {
2675 0 : goto nomem;
2676 : }
2677 :
2678 2 : entry_handle = talloc_zero(frame, struct policy_handle);
2679 2 : if (entry_handle == NULL) {
2680 0 : goto nomem;
2681 : }
2682 :
2683 2 : status = dcerpc_epm_Map(
2684 : epm_connection,
2685 : frame,
2686 : NULL,
2687 : map_tower,
2688 : entry_handle,
2689 : max_towers,
2690 : &num_towers,
2691 : &res_towers,
2692 : &result);
2693 :
2694 2 : if (!NT_STATUS_IS_OK(status)) {
2695 0 : DBG_DEBUG("dcerpc_epm_Map failed: %s\n", nt_errstr(status));
2696 0 : goto done;
2697 : }
2698 :
2699 2 : if (result != EPMAPPER_STATUS_OK) {
2700 0 : DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32"\n", result);
2701 0 : status = NT_STATUS_NOT_FOUND;
2702 0 : goto done;
2703 : }
2704 :
2705 2 : if (num_towers != 1) {
2706 0 : DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32" towers\n",
2707 : num_towers);
2708 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2709 0 : goto done;
2710 : }
2711 :
2712 2 : status = dcerpc_binding_from_tower(
2713 2 : frame, &(res_towers.twr->tower), &res_binding);
2714 2 : if (!NT_STATUS_IS_OK(status)) {
2715 0 : DBG_DEBUG("dcerpc_binding_from_tower failed: %s\n",
2716 : nt_errstr(status));
2717 0 : goto done;
2718 : }
2719 :
2720 2 : res_transport = dcerpc_binding_get_transport(res_binding);
2721 2 : if (res_transport != transport) {
2722 0 : DBG_DEBUG("dcerpc_epm_Map returned transport %d, "
2723 : "expected %d\n",
2724 : (int)res_transport,
2725 : (int)transport);
2726 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2727 0 : goto done;
2728 : }
2729 :
2730 2 : endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
2731 2 : if (endpoint == NULL) {
2732 0 : DBG_DEBUG("dcerpc_epm_Map returned no endpoint\n");
2733 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
2734 0 : goto done;
2735 : }
2736 :
2737 2 : tmp = talloc_strdup(mem_ctx, endpoint);
2738 2 : if (tmp == NULL) {
2739 0 : goto nomem;
2740 : }
2741 2 : *pendpoint = tmp;
2742 :
2743 2 : status = NT_STATUS_OK;
2744 2 : goto done;
2745 :
2746 0 : nomem:
2747 0 : status = NT_STATUS_NO_MEMORY;
2748 2 : done:
2749 2 : TALLOC_FREE(frame);
2750 2 : return status;
2751 : }
2752 :
2753 2 : static NTSTATUS rpccli_epm_map_interface(
2754 : struct dcerpc_binding_handle *epm_connection,
2755 : enum dcerpc_transport_t transport,
2756 : const struct ndr_syntax_id *iface,
2757 : TALLOC_CTX *mem_ctx,
2758 : char **pendpoint)
2759 : {
2760 2 : struct dcerpc_binding *binding = NULL;
2761 2 : char *endpoint = NULL;
2762 0 : NTSTATUS status;
2763 :
2764 2 : status = dcerpc_parse_binding(mem_ctx, "", &binding);
2765 2 : if (!NT_STATUS_IS_OK(status)) {
2766 0 : DBG_DEBUG("dcerpc_parse_binding failed: %s\n",
2767 : nt_errstr(status));
2768 0 : goto done;
2769 : }
2770 :
2771 2 : status = dcerpc_binding_set_transport(binding, transport);
2772 2 : if (!NT_STATUS_IS_OK(status)) {
2773 0 : DBG_DEBUG("dcerpc_binding_set_transport failed: %s\n",
2774 : nt_errstr(status));
2775 0 : goto done;
2776 : }
2777 :
2778 2 : status = dcerpc_binding_set_abstract_syntax(binding, iface);
2779 2 : if (!NT_STATUS_IS_OK(status)) {
2780 0 : DBG_DEBUG("dcerpc_binding_set_abstract_syntax failed: %s\n",
2781 : nt_errstr(status));
2782 0 : goto done;
2783 : }
2784 :
2785 2 : status = rpccli_epm_map_binding(
2786 : epm_connection, binding, mem_ctx, &endpoint);
2787 2 : if (!NT_STATUS_IS_OK(status)) {
2788 0 : DBG_DEBUG("rpccli_epm_map_binding failed: %s\n",
2789 : nt_errstr(status));
2790 0 : goto done;
2791 : }
2792 2 : *pendpoint = endpoint;
2793 :
2794 2 : done:
2795 2 : TALLOC_FREE(binding);
2796 2 : return status;
2797 : }
2798 :
2799 : /**
2800 : * Determine the tcp port on which a dcerpc interface is listening
2801 : * for the ncacn_ip_tcp transport via the endpoint mapper of the
2802 : * target host.
2803 : */
2804 98 : static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
2805 : const struct sockaddr_storage *addr,
2806 : const struct ndr_interface_table *table,
2807 : uint16_t *pport)
2808 : {
2809 0 : NTSTATUS status;
2810 98 : struct rpc_pipe_client *epm_pipe = NULL;
2811 98 : struct pipe_auth_data *auth = NULL;
2812 98 : char *endpoint = NULL;
2813 98 : TALLOC_CTX *tmp_ctx = talloc_stackframe();
2814 :
2815 98 : if (pport == NULL) {
2816 0 : status = NT_STATUS_INVALID_PARAMETER;
2817 0 : goto done;
2818 : }
2819 :
2820 98 : if (ndr_syntax_id_equal(&table->syntax_id,
2821 : &ndr_table_epmapper.syntax_id)) {
2822 96 : *pport = 135;
2823 96 : status = NT_STATUS_OK;
2824 96 : goto done;
2825 : }
2826 :
2827 : /* open the connection to the endpoint mapper */
2828 2 : status = rpc_pipe_open_tcp_port(tmp_ctx, host, addr, 135,
2829 : &ndr_table_epmapper,
2830 : &epm_pipe);
2831 :
2832 2 : if (!NT_STATUS_IS_OK(status)) {
2833 0 : goto done;
2834 : }
2835 :
2836 2 : status = rpccli_anon_bind_data(tmp_ctx, &auth);
2837 2 : if (!NT_STATUS_IS_OK(status)) {
2838 0 : goto done;
2839 : }
2840 :
2841 2 : status = rpc_pipe_bind(epm_pipe, auth);
2842 2 : if (!NT_STATUS_IS_OK(status)) {
2843 0 : goto done;
2844 : }
2845 :
2846 2 : status = rpccli_epm_map_interface(
2847 2 : epm_pipe->binding_handle,
2848 : NCACN_IP_TCP,
2849 : &table->syntax_id,
2850 : tmp_ctx,
2851 : &endpoint);
2852 2 : if (!NT_STATUS_IS_OK(status)) {
2853 0 : DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2854 : nt_errstr(status));
2855 0 : goto done;
2856 : }
2857 :
2858 2 : *pport = (uint16_t)atoi(endpoint);
2859 :
2860 98 : done:
2861 98 : TALLOC_FREE(tmp_ctx);
2862 98 : return status;
2863 : }
2864 :
2865 : /**
2866 : * Create a rpc pipe client struct, connecting to a host via tcp.
2867 : * The port is determined by asking the endpoint mapper on the given
2868 : * host.
2869 : */
2870 98 : static NTSTATUS rpc_pipe_open_tcp(
2871 : TALLOC_CTX *mem_ctx,
2872 : const char *host,
2873 : const struct sockaddr_storage *addr,
2874 : const struct ndr_interface_table *table,
2875 : struct rpc_pipe_client **presult)
2876 : {
2877 0 : NTSTATUS status;
2878 98 : uint16_t port = 0;
2879 :
2880 98 : status = rpc_pipe_get_tcp_port(host, addr, table, &port);
2881 98 : if (!NT_STATUS_IS_OK(status)) {
2882 0 : return status;
2883 : }
2884 :
2885 98 : return rpc_pipe_open_tcp_port(mem_ctx, host, addr, port,
2886 : table, presult);
2887 : }
2888 :
2889 152 : static NTSTATUS rpc_pipe_get_ncalrpc_name(
2890 : const struct ndr_syntax_id *iface,
2891 : TALLOC_CTX *mem_ctx,
2892 : char **psocket_name)
2893 : {
2894 152 : TALLOC_CTX *frame = talloc_stackframe();
2895 152 : struct rpc_pipe_client *epm_pipe = NULL;
2896 152 : struct pipe_auth_data *auth = NULL;
2897 152 : NTSTATUS status = NT_STATUS_OK;
2898 0 : bool is_epm;
2899 :
2900 152 : is_epm = ndr_syntax_id_equal(iface, &ndr_table_epmapper.syntax_id);
2901 152 : if (is_epm) {
2902 152 : char *endpoint = talloc_strdup(mem_ctx, "EPMAPPER");
2903 152 : if (endpoint == NULL) {
2904 0 : status = NT_STATUS_NO_MEMORY;
2905 0 : goto done;
2906 : }
2907 152 : *psocket_name = endpoint;
2908 152 : goto done;
2909 : }
2910 :
2911 0 : status = rpc_pipe_open_ncalrpc(
2912 : frame, &ndr_table_epmapper, &epm_pipe);
2913 0 : if (!NT_STATUS_IS_OK(status)) {
2914 0 : DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
2915 : nt_errstr(status));
2916 0 : goto done;
2917 : }
2918 :
2919 0 : status = rpccli_anon_bind_data(epm_pipe, &auth);
2920 0 : if (!NT_STATUS_IS_OK(status)) {
2921 0 : DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
2922 : nt_errstr(status));
2923 0 : goto done;
2924 : }
2925 :
2926 0 : status = rpc_pipe_bind(epm_pipe, auth);
2927 0 : if (!NT_STATUS_IS_OK(status)) {
2928 0 : DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
2929 0 : goto done;
2930 : }
2931 :
2932 0 : status = rpccli_epm_map_interface(
2933 0 : epm_pipe->binding_handle,
2934 : NCALRPC,
2935 : iface,
2936 : mem_ctx,
2937 : psocket_name);
2938 0 : if (!NT_STATUS_IS_OK(status)) {
2939 0 : DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
2940 : nt_errstr(status));
2941 : }
2942 :
2943 0 : done:
2944 152 : TALLOC_FREE(frame);
2945 152 : return status;
2946 : }
2947 :
2948 : /********************************************************************
2949 : Create a rpc pipe client struct, connecting to a unix domain socket
2950 : ********************************************************************/
2951 152 : NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx,
2952 : const struct ndr_interface_table *table,
2953 : struct rpc_pipe_client **presult)
2954 : {
2955 152 : char *socket_name = NULL;
2956 0 : struct rpc_pipe_client *result;
2957 152 : struct sockaddr_un addr = { .sun_family = AF_UNIX };
2958 152 : socklen_t salen = sizeof(addr);
2959 0 : int pathlen;
2960 0 : NTSTATUS status;
2961 152 : int fd = -1;
2962 :
2963 152 : result = talloc_zero(mem_ctx, struct rpc_pipe_client);
2964 152 : if (result == NULL) {
2965 0 : return NT_STATUS_NO_MEMORY;
2966 : }
2967 :
2968 152 : status = rpc_pipe_get_ncalrpc_name(
2969 : &table->syntax_id, result, &socket_name);
2970 152 : if (!NT_STATUS_IS_OK(status)) {
2971 0 : DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n",
2972 : nt_errstr(status));
2973 0 : goto fail;
2974 : }
2975 :
2976 152 : pathlen = snprintf(
2977 : addr.sun_path,
2978 : sizeof(addr.sun_path),
2979 : "%s/%s",
2980 : lp_ncalrpc_dir(),
2981 : socket_name);
2982 152 : if ((pathlen < 0) || ((size_t)pathlen >= sizeof(addr.sun_path))) {
2983 0 : DBG_DEBUG("socket_path for %s too long\n", socket_name);
2984 0 : status = NT_STATUS_NAME_TOO_LONG;
2985 0 : goto fail;
2986 : }
2987 152 : TALLOC_FREE(socket_name);
2988 :
2989 152 : result->abstract_syntax = table->syntax_id;
2990 152 : result->transfer_syntax = ndr_transfer_syntax_ndr;
2991 :
2992 152 : result->desthost = get_myname(result);
2993 152 : if (result->desthost == NULL) {
2994 0 : status = NT_STATUS_NO_MEMORY;
2995 0 : goto fail;
2996 : }
2997 :
2998 152 : result->srv_name_slash = talloc_asprintf_strupper_m(
2999 : result, "\\\\%s", result->desthost);
3000 152 : if (result->srv_name_slash == NULL) {
3001 0 : status = NT_STATUS_NO_MEMORY;
3002 0 : goto fail;
3003 : }
3004 :
3005 152 : result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3006 :
3007 152 : fd = socket(AF_UNIX, SOCK_STREAM, 0);
3008 152 : if (fd == -1) {
3009 0 : status = map_nt_error_from_unix(errno);
3010 0 : goto fail;
3011 : }
3012 :
3013 152 : if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) {
3014 16 : DBG_WARNING("connect(%s) failed: %s\n",
3015 : addr.sun_path,
3016 : strerror(errno));
3017 16 : status = map_nt_error_from_unix(errno);
3018 16 : goto fail;
3019 : }
3020 :
3021 136 : status = rpc_transport_sock_init(result, fd, &result->transport);
3022 136 : if (!NT_STATUS_IS_OK(status)) {
3023 0 : goto fail;
3024 : }
3025 136 : fd = -1;
3026 :
3027 136 : result->transport->transport = NCALRPC;
3028 :
3029 136 : result->binding_handle = rpccli_bh_create(result, NULL, table);
3030 136 : if (result->binding_handle == NULL) {
3031 0 : status = NT_STATUS_NO_MEMORY;
3032 0 : goto fail;
3033 : }
3034 :
3035 136 : *presult = result;
3036 136 : return NT_STATUS_OK;
3037 :
3038 16 : fail:
3039 16 : if (fd != -1) {
3040 16 : close(fd);
3041 : }
3042 16 : TALLOC_FREE(result);
3043 16 : return status;
3044 : }
3045 :
3046 30672 : NTSTATUS rpc_pipe_open_local_np(
3047 : TALLOC_CTX *mem_ctx,
3048 : const struct ndr_interface_table *table,
3049 : const char *remote_client_name,
3050 : const struct tsocket_address *remote_client_addr,
3051 : const char *local_server_name,
3052 : const struct tsocket_address *local_server_addr,
3053 : const struct auth_session_info *session_info,
3054 : struct rpc_pipe_client **presult)
3055 : {
3056 30672 : struct rpc_pipe_client *result = NULL;
3057 30672 : struct pipe_auth_data *auth = NULL;
3058 30672 : const char *pipe_name = NULL;
3059 30672 : struct tstream_context *npa_stream = NULL;
3060 30672 : NTSTATUS status = NT_STATUS_NO_MEMORY;
3061 0 : int ret;
3062 :
3063 30672 : result = talloc_zero(mem_ctx, struct rpc_pipe_client);
3064 30672 : if (result == NULL) {
3065 0 : goto fail;
3066 : }
3067 30672 : result->abstract_syntax = table->syntax_id;
3068 30672 : result->transfer_syntax = ndr_transfer_syntax_ndr;
3069 30672 : result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3070 :
3071 30672 : pipe_name = dcerpc_default_transport_endpoint(
3072 : result, NCACN_NP, table);
3073 30672 : if (pipe_name == NULL) {
3074 0 : DBG_DEBUG("dcerpc_default_transport_endpoint failed\n");
3075 0 : status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
3076 0 : goto fail;
3077 : }
3078 :
3079 30672 : if (local_server_name == NULL) {
3080 30672 : result->desthost = get_myname(result);
3081 : } else {
3082 0 : result->desthost = talloc_strdup(result, local_server_name);
3083 : }
3084 30672 : if (result->desthost == NULL) {
3085 0 : goto fail;
3086 : }
3087 30672 : result->srv_name_slash = talloc_asprintf_strupper_m(
3088 : result, "\\\\%s", result->desthost);
3089 30672 : if (result->srv_name_slash == NULL) {
3090 0 : goto fail;
3091 : }
3092 :
3093 30672 : ret = local_np_connect(
3094 : pipe_name,
3095 : NCALRPC,
3096 : remote_client_name,
3097 : remote_client_addr,
3098 : local_server_name,
3099 : local_server_addr,
3100 : session_info,
3101 : true,
3102 : result,
3103 : &npa_stream);
3104 30672 : if (ret != 0) {
3105 0 : DBG_DEBUG("local_np_connect for %s and "
3106 : "user %s\\%s failed: %s\n",
3107 : pipe_name,
3108 : session_info->info->domain_name,
3109 : session_info->info->account_name,
3110 : strerror(ret));
3111 0 : status = map_nt_error_from_unix(ret);
3112 0 : goto fail;
3113 : }
3114 :
3115 30672 : status = rpc_transport_tstream_init(
3116 : result, &npa_stream, &result->transport);
3117 30672 : if (!NT_STATUS_IS_OK(status)) {
3118 0 : DBG_DEBUG("rpc_transport_tstream_init failed: %s\n",
3119 : nt_errstr(status));
3120 0 : goto fail;
3121 : }
3122 :
3123 30672 : result->binding_handle = rpccli_bh_create(result, NULL, table);
3124 30672 : if (result->binding_handle == NULL) {
3125 0 : status = NT_STATUS_NO_MEMORY;
3126 0 : DBG_DEBUG("Failed to create binding handle.\n");
3127 0 : goto fail;
3128 : }
3129 :
3130 30672 : status = rpccli_anon_bind_data(result, &auth);
3131 30672 : if (!NT_STATUS_IS_OK(status)) {
3132 0 : DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3133 : nt_errstr(status));
3134 0 : goto fail;
3135 : }
3136 :
3137 30672 : status = rpc_pipe_bind(result, auth);
3138 30672 : if (!NT_STATUS_IS_OK(status)) {
3139 0 : DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
3140 0 : goto fail;
3141 : }
3142 :
3143 30672 : *presult = result;
3144 30672 : return NT_STATUS_OK;
3145 :
3146 0 : fail:
3147 0 : TALLOC_FREE(result);
3148 0 : return status;
3149 : }
3150 :
3151 : struct rpc_pipe_client_np_ref {
3152 : struct cli_state *cli;
3153 : struct rpc_pipe_client *pipe;
3154 : };
3155 :
3156 10042 : static int rpc_pipe_client_np_ref_destructor(struct rpc_pipe_client_np_ref *np_ref)
3157 : {
3158 10042 : DLIST_REMOVE(np_ref->cli->pipe_list, np_ref->pipe);
3159 10042 : return 0;
3160 : }
3161 :
3162 : /****************************************************************************
3163 : Open a named pipe over SMB to a remote server.
3164 : *
3165 : * CAVEAT CALLER OF THIS FUNCTION:
3166 : * The returned rpc_pipe_client saves a copy of the cli_state cli pointer,
3167 : * so be sure that this function is called AFTER any structure (vs pointer)
3168 : * assignment of the cli. In particular, libsmbclient does structure
3169 : * assignments of cli, which invalidates the data in the returned
3170 : * rpc_pipe_client if this function is called before the structure assignment
3171 : * of cli.
3172 : *
3173 : ****************************************************************************/
3174 :
3175 : struct rpc_pipe_open_np_state {
3176 : struct cli_state *cli;
3177 : const struct ndr_interface_table *table;
3178 : struct rpc_pipe_client *result;
3179 : };
3180 :
3181 : static void rpc_pipe_open_np_done(struct tevent_req *subreq);
3182 :
3183 10060 : struct tevent_req *rpc_pipe_open_np_send(
3184 : TALLOC_CTX *mem_ctx,
3185 : struct tevent_context *ev,
3186 : struct cli_state *cli,
3187 : const struct ndr_interface_table *table)
3188 : {
3189 10060 : struct tevent_req *req = NULL, *subreq = NULL;
3190 10060 : struct rpc_pipe_open_np_state *state = NULL;
3191 10060 : struct rpc_pipe_client *result = NULL;
3192 :
3193 10060 : req = tevent_req_create(
3194 : mem_ctx, &state, struct rpc_pipe_open_np_state);
3195 10060 : if (req == NULL) {
3196 0 : return NULL;
3197 : }
3198 10060 : state->cli = cli;
3199 10060 : state->table = table;
3200 :
3201 10060 : state->result = talloc_zero(state, struct rpc_pipe_client);
3202 10060 : if (tevent_req_nomem(state->result, req)) {
3203 0 : return tevent_req_post(req, ev);
3204 : }
3205 10060 : result = state->result;
3206 :
3207 10060 : result->abstract_syntax = table->syntax_id;
3208 10060 : result->transfer_syntax = ndr_transfer_syntax_ndr;
3209 :
3210 10060 : result->desthost = talloc_strdup(
3211 : result, smbXcli_conn_remote_name(cli->conn));
3212 10060 : if (tevent_req_nomem(result->desthost, req)) {
3213 0 : return tevent_req_post(req, ev);
3214 : }
3215 :
3216 10060 : result->srv_name_slash = talloc_asprintf_strupper_m(
3217 : result, "\\\\%s", result->desthost);
3218 10060 : if (tevent_req_nomem(result->srv_name_slash, req)) {
3219 0 : return tevent_req_post(req, ev);
3220 : }
3221 :
3222 10060 : result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN;
3223 :
3224 10060 : subreq = rpc_transport_np_init_send(state, ev, cli, table);
3225 10060 : if (tevent_req_nomem(subreq, req)) {
3226 0 : return tevent_req_post(req, ev);
3227 : }
3228 10060 : tevent_req_set_callback(subreq, rpc_pipe_open_np_done, req);
3229 10060 : return req;
3230 : }
3231 :
3232 10060 : static void rpc_pipe_open_np_done(struct tevent_req *subreq)
3233 : {
3234 10060 : struct tevent_req *req = tevent_req_callback_data(
3235 : subreq, struct tevent_req);
3236 10060 : struct rpc_pipe_open_np_state *state = tevent_req_data(
3237 : req, struct rpc_pipe_open_np_state);
3238 10060 : struct rpc_pipe_client *result = state->result;
3239 10060 : struct rpc_pipe_client_np_ref *np_ref = NULL;
3240 0 : NTSTATUS status;
3241 :
3242 10060 : status = rpc_transport_np_init_recv(
3243 : subreq, result, &result->transport);
3244 10060 : TALLOC_FREE(subreq);
3245 10060 : if (tevent_req_nterror(req, status)) {
3246 0 : return;
3247 : }
3248 :
3249 10060 : result->transport->transport = NCACN_NP;
3250 :
3251 10060 : np_ref = talloc(result->transport, struct rpc_pipe_client_np_ref);
3252 10060 : if (tevent_req_nomem(np_ref, req)) {
3253 0 : return;
3254 : }
3255 10060 : np_ref->cli = state->cli;
3256 10060 : np_ref->pipe = result;
3257 :
3258 10060 : DLIST_ADD(np_ref->cli->pipe_list, np_ref->pipe);
3259 10060 : talloc_set_destructor(np_ref, rpc_pipe_client_np_ref_destructor);
3260 :
3261 10060 : result->binding_handle = rpccli_bh_create(result, NULL, state->table);
3262 10060 : if (tevent_req_nomem(result->binding_handle, req)) {
3263 0 : return;
3264 : }
3265 :
3266 10060 : tevent_req_done(req);
3267 : }
3268 :
3269 10060 : NTSTATUS rpc_pipe_open_np_recv(
3270 : struct tevent_req *req,
3271 : TALLOC_CTX *mem_ctx,
3272 : struct rpc_pipe_client **_result)
3273 : {
3274 10060 : struct rpc_pipe_open_np_state *state = tevent_req_data(
3275 : req, struct rpc_pipe_open_np_state);
3276 0 : NTSTATUS status;
3277 :
3278 10060 : if (tevent_req_is_nterror(req, &status)) {
3279 0 : return status;
3280 : }
3281 10060 : *_result = talloc_move(mem_ctx, &state->result);
3282 10060 : return NT_STATUS_OK;
3283 : }
3284 :
3285 10060 : NTSTATUS rpc_pipe_open_np(struct cli_state *cli,
3286 : const struct ndr_interface_table *table,
3287 : struct rpc_pipe_client **presult)
3288 : {
3289 10060 : struct tevent_context *ev = NULL;
3290 10060 : struct tevent_req *req = NULL;
3291 10060 : NTSTATUS status = NT_STATUS_NO_MEMORY;
3292 :
3293 10060 : ev = samba_tevent_context_init(cli);
3294 10060 : if (ev == NULL) {
3295 0 : goto fail;
3296 : }
3297 10060 : req = rpc_pipe_open_np_send(ev, ev, cli, table);
3298 10060 : if (req == NULL) {
3299 0 : goto fail;
3300 : }
3301 10060 : if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3302 0 : goto fail;
3303 : }
3304 10060 : status = rpc_pipe_open_np_recv(req, NULL, presult);
3305 10060 : fail:
3306 10060 : TALLOC_FREE(req);
3307 10060 : TALLOC_FREE(ev);
3308 10060 : return status;
3309 : }
3310 :
3311 : /****************************************************************************
3312 : Open a pipe to a remote server.
3313 : ****************************************************************************/
3314 :
3315 10158 : static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3316 : enum dcerpc_transport_t transport,
3317 : const struct ndr_interface_table *table,
3318 : const char *remote_name,
3319 : const struct sockaddr_storage *remote_sockaddr,
3320 : struct rpc_pipe_client **presult)
3321 : {
3322 10158 : switch (transport) {
3323 98 : case NCACN_IP_TCP:
3324 98 : return rpc_pipe_open_tcp(NULL,
3325 : remote_name,
3326 : remote_sockaddr,
3327 : table, presult);
3328 10060 : case NCACN_NP:
3329 10060 : return rpc_pipe_open_np(cli, table, presult);
3330 0 : default:
3331 0 : return NT_STATUS_NOT_IMPLEMENTED;
3332 : }
3333 : }
3334 :
3335 : /****************************************************************************
3336 : Open a named pipe to an SMB server and bind anonymously.
3337 : ****************************************************************************/
3338 :
3339 9818 : NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
3340 : enum dcerpc_transport_t transport,
3341 : const struct ndr_interface_table *table,
3342 : const char *remote_name,
3343 : const struct sockaddr_storage *remote_sockaddr,
3344 : struct rpc_pipe_client **presult)
3345 : {
3346 0 : struct rpc_pipe_client *result;
3347 0 : struct pipe_auth_data *auth;
3348 0 : NTSTATUS status;
3349 :
3350 9818 : status = cli_rpc_pipe_open(cli,
3351 : transport,
3352 : table,
3353 : remote_name,
3354 : remote_sockaddr,
3355 : &result);
3356 9818 : if (!NT_STATUS_IS_OK(status)) {
3357 0 : return status;
3358 : }
3359 :
3360 9818 : status = rpccli_anon_bind_data(result, &auth);
3361 9818 : if (!NT_STATUS_IS_OK(status)) {
3362 0 : DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
3363 : nt_errstr(status)));
3364 0 : TALLOC_FREE(result);
3365 0 : return status;
3366 : }
3367 :
3368 : /*
3369 : * This is a bit of an abstraction violation due to the fact that an
3370 : * anonymous bind on an authenticated SMB inherits the user/domain
3371 : * from the enclosing SMB creds
3372 : */
3373 :
3374 9818 : if (transport == NCACN_NP) {
3375 0 : struct smbXcli_session *session;
3376 :
3377 9810 : if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
3378 9666 : session = cli->smb2.session;
3379 : } else {
3380 144 : session = cli->smb1.session;
3381 : }
3382 :
3383 9810 : status = smbXcli_session_application_key(session, auth,
3384 9810 : &auth->transport_session_key);
3385 9810 : if (!NT_STATUS_IS_OK(status)) {
3386 167 : auth->transport_session_key = data_blob_null;
3387 : }
3388 : }
3389 :
3390 9818 : status = rpc_pipe_bind(result, auth);
3391 9818 : if (!NT_STATUS_IS_OK(status)) {
3392 0 : int lvl = 0;
3393 0 : if (ndr_syntax_id_equal(&table->syntax_id,
3394 : &ndr_table_dssetup.syntax_id)) {
3395 : /* non AD domains just don't have this pipe, avoid
3396 : * level 0 statement in that case - gd */
3397 0 : lvl = 3;
3398 : }
3399 0 : DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
3400 : "%s failed with error %s\n",
3401 : table->name,
3402 : nt_errstr(status) ));
3403 0 : TALLOC_FREE(result);
3404 0 : return status;
3405 : }
3406 :
3407 9818 : DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
3408 : "%s and bound anonymously.\n",
3409 : table->name,
3410 : result->desthost));
3411 :
3412 9818 : *presult = result;
3413 9818 : return NT_STATUS_OK;
3414 : }
3415 :
3416 : /****************************************************************************
3417 : ****************************************************************************/
3418 :
3419 9424 : NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
3420 : const struct ndr_interface_table *table,
3421 : struct rpc_pipe_client **presult)
3422 : {
3423 9424 : const char *remote_name = smbXcli_conn_remote_name(cli->conn);
3424 0 : const struct sockaddr_storage *remote_sockaddr =
3425 9424 : smbXcli_conn_remote_sockaddr(cli->conn);
3426 :
3427 9424 : return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
3428 : table,
3429 : remote_name,
3430 : remote_sockaddr,
3431 : presult);
3432 : }
3433 :
3434 : /****************************************************************************
3435 : Open a named pipe to an SMB server and bind using the mech specified
3436 :
3437 : This routine references the creds pointer that is passed in
3438 : ****************************************************************************/
3439 :
3440 233 : NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
3441 : const struct ndr_interface_table *table,
3442 : enum dcerpc_transport_t transport,
3443 : enum dcerpc_AuthType auth_type,
3444 : enum dcerpc_AuthLevel auth_level,
3445 : const char *server,
3446 : const struct sockaddr_storage *remote_sockaddr,
3447 : struct cli_credentials *creds,
3448 : struct rpc_pipe_client **presult)
3449 : {
3450 0 : struct rpc_pipe_client *result;
3451 233 : struct pipe_auth_data *auth = NULL;
3452 233 : const char *target_service = table->authservices->names[0];
3453 0 : NTSTATUS status;
3454 :
3455 233 : status = cli_rpc_pipe_open(cli,
3456 : transport,
3457 : table,
3458 : server,
3459 : remote_sockaddr,
3460 : &result);
3461 233 : if (!NT_STATUS_IS_OK(status)) {
3462 0 : return status;
3463 : }
3464 :
3465 233 : status = rpccli_generic_bind_data_from_creds(result,
3466 : auth_type, auth_level,
3467 : server, target_service,
3468 : creds,
3469 : &auth);
3470 233 : if (!NT_STATUS_IS_OK(status)) {
3471 0 : DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
3472 : nt_errstr(status));
3473 0 : goto err;
3474 : }
3475 :
3476 233 : status = rpc_pipe_bind(result, auth);
3477 233 : if (!NT_STATUS_IS_OK(status)) {
3478 0 : DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
3479 : nt_errstr(status));
3480 0 : goto err;
3481 : }
3482 :
3483 233 : DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
3484 : table->name,
3485 : result->desthost,
3486 : cli_credentials_get_unparsed_name(creds, talloc_tos()));
3487 :
3488 233 : *presult = result;
3489 233 : return NT_STATUS_OK;
3490 :
3491 0 : err:
3492 :
3493 0 : TALLOC_FREE(result);
3494 0 : return status;
3495 : }
3496 :
3497 107 : NTSTATUS cli_rpc_pipe_open_bind_schannel(
3498 : struct cli_state *cli,
3499 : const struct ndr_interface_table *table,
3500 : enum dcerpc_transport_t transport,
3501 : struct netlogon_creds_cli_context *netlogon_creds,
3502 : const char *remote_name,
3503 : const struct sockaddr_storage *remote_sockaddr,
3504 : struct rpc_pipe_client **_rpccli)
3505 : {
3506 0 : struct rpc_pipe_client *rpccli;
3507 0 : struct pipe_auth_data *rpcauth;
3508 107 : const char *target_service = table->authservices->names[0];
3509 0 : struct cli_credentials *cli_creds;
3510 0 : enum dcerpc_AuthLevel auth_level;
3511 0 : NTSTATUS status;
3512 :
3513 107 : status = cli_rpc_pipe_open(cli,
3514 : transport,
3515 : table,
3516 : remote_name,
3517 : remote_sockaddr,
3518 : &rpccli);
3519 107 : if (!NT_STATUS_IS_OK(status)) {
3520 0 : return status;
3521 : }
3522 :
3523 107 : auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
3524 :
3525 107 : status = netlogon_creds_bind_cli_credentials(
3526 : netlogon_creds, rpccli, &cli_creds);
3527 107 : if (!NT_STATUS_IS_OK(status)) {
3528 0 : DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
3529 : nt_errstr(status));
3530 0 : TALLOC_FREE(rpccli);
3531 0 : return status;
3532 : }
3533 :
3534 107 : status = rpccli_generic_bind_data_from_creds(rpccli,
3535 : DCERPC_AUTH_TYPE_SCHANNEL,
3536 : auth_level,
3537 107 : rpccli->desthost,
3538 : target_service,
3539 : cli_creds,
3540 : &rpcauth);
3541 107 : if (!NT_STATUS_IS_OK(status)) {
3542 0 : DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
3543 : nt_errstr(status)));
3544 0 : TALLOC_FREE(rpccli);
3545 0 : return status;
3546 : }
3547 :
3548 107 : status = rpc_pipe_bind(rpccli, rpcauth);
3549 :
3550 : /* No TALLOC_FREE, gensec takes references */
3551 107 : talloc_unlink(rpccli, cli_creds);
3552 107 : cli_creds = NULL;
3553 :
3554 107 : if (!NT_STATUS_IS_OK(status)) {
3555 0 : DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
3556 : nt_errstr(status));
3557 0 : TALLOC_FREE(rpccli);
3558 0 : return status;
3559 : }
3560 :
3561 107 : *_rpccli = rpccli;
3562 :
3563 107 : return NT_STATUS_OK;
3564 : }
3565 :
3566 107 : NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
3567 : const struct ndr_interface_table *table,
3568 : enum dcerpc_transport_t transport,
3569 : struct netlogon_creds_cli_context *netlogon_creds,
3570 : const char *remote_name,
3571 : const struct sockaddr_storage *remote_sockaddr,
3572 : struct rpc_pipe_client **_rpccli)
3573 : {
3574 107 : TALLOC_CTX *frame = talloc_stackframe();
3575 0 : struct rpc_pipe_client *rpccli;
3576 0 : struct netlogon_creds_cli_lck *lck;
3577 0 : NTSTATUS status;
3578 :
3579 107 : status = netlogon_creds_cli_lck(
3580 : netlogon_creds, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
3581 : frame, &lck);
3582 107 : if (!NT_STATUS_IS_OK(status)) {
3583 0 : DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
3584 : nt_errstr(status));
3585 0 : TALLOC_FREE(frame);
3586 0 : return status;
3587 : }
3588 :
3589 107 : status = cli_rpc_pipe_open_bind_schannel(cli,
3590 : table,
3591 : transport,
3592 : netlogon_creds,
3593 : remote_name,
3594 : remote_sockaddr,
3595 : &rpccli);
3596 107 : if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3597 0 : netlogon_creds_cli_delete_lck(netlogon_creds);
3598 : }
3599 107 : if (!NT_STATUS_IS_OK(status)) {
3600 0 : DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
3601 : nt_errstr(status));
3602 0 : TALLOC_FREE(frame);
3603 0 : return status;
3604 : }
3605 :
3606 107 : if (ndr_syntax_id_equal(&table->syntax_id,
3607 : &ndr_table_netlogon.syntax_id)) {
3608 103 : status = netlogon_creds_cli_check(netlogon_creds,
3609 103 : rpccli->binding_handle,
3610 : NULL);
3611 103 : if (!NT_STATUS_IS_OK(status)) {
3612 0 : DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
3613 : nt_errstr(status)));
3614 0 : TALLOC_FREE(frame);
3615 0 : return status;
3616 : }
3617 : }
3618 :
3619 107 : DBG_DEBUG("opened pipe %s to machine %s with key %s "
3620 : "and bound using schannel.\n",
3621 : table->name, rpccli->desthost,
3622 : netlogon_creds_cli_debug_string(netlogon_creds, lck));
3623 :
3624 107 : TALLOC_FREE(frame);
3625 :
3626 107 : *_rpccli = rpccli;
3627 107 : return NT_STATUS_OK;
3628 : }
3629 :
3630 21 : NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
3631 : struct rpc_pipe_client *cli,
3632 : DATA_BLOB *session_key)
3633 : {
3634 0 : NTSTATUS status;
3635 0 : struct pipe_auth_data *a;
3636 0 : struct gensec_security *gensec_security;
3637 21 : DATA_BLOB sk = { .data = NULL };
3638 21 : bool make_dup = false;
3639 :
3640 21 : if (!session_key || !cli) {
3641 0 : return NT_STATUS_INVALID_PARAMETER;
3642 : }
3643 :
3644 21 : a = cli->auth;
3645 :
3646 21 : if (a == NULL) {
3647 0 : return NT_STATUS_INVALID_PARAMETER;
3648 : }
3649 :
3650 21 : switch (cli->auth->auth_type) {
3651 21 : case DCERPC_AUTH_TYPE_NONE:
3652 21 : sk = data_blob_const(a->transport_session_key.data,
3653 : a->transport_session_key.length);
3654 21 : make_dup = true;
3655 21 : break;
3656 0 : default:
3657 0 : gensec_security = a->auth_ctx;
3658 0 : status = gensec_session_key(gensec_security, mem_ctx, &sk);
3659 0 : if (!NT_STATUS_IS_OK(status)) {
3660 0 : return status;
3661 : }
3662 0 : make_dup = false;
3663 0 : break;
3664 : }
3665 :
3666 21 : if (!sk.data) {
3667 0 : return NT_STATUS_NO_USER_SESSION_KEY;
3668 : }
3669 :
3670 21 : if (make_dup) {
3671 21 : *session_key = data_blob_dup_talloc(mem_ctx, sk);
3672 : } else {
3673 0 : *session_key = sk;
3674 : }
3675 :
3676 21 : return NT_STATUS_OK;
3677 : }
|