source: trunk/server/source3/rpc_client/cli_pipe.c

Last change on this file was 920, checked in by Silvan Scherrer, 9 years ago

Samba Server: apply latest security patches to trunk

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