Coverage Report

Created: 2026-01-16 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/rpc_client/cli_pipe.c
Line
Count
Source
1
/*
2
 *  Unix SMB/CIFS implementation.
3
 *  RPC Pipe client routines
4
 *  Largely rewritten by Jeremy Allison       2005.
5
 *  Heavily modified by Simo Sorce        2010.
6
 *  Copyright Andrew Bartlett                       2011.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 3 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#define SOURCE3_LIBRPC_INTERNALS 1
23
24
#include "includes.h"
25
#include "libsmb/namequery.h"
26
#include "../lib/util/tevent_ntstatus.h"
27
#include "librpc/gen_ndr/ndr_epmapper_c.h"
28
#include "../librpc/gen_ndr/ndr_dssetup.h"
29
#include "../libcli/auth/schannel.h"
30
#include "../libcli/auth/netlogon_creds_cli.h"
31
#include "auth_generic.h"
32
#include "librpc/gen_ndr/ndr_dcerpc.h"
33
#include "librpc/gen_ndr/ndr_netlogon_c.h"
34
#include "librpc/gen_ndr/auth.h"
35
#include "librpc/rpc/dcerpc.h"
36
#include "librpc/rpc/dcerpc_internal.h"
37
#include "librpc/rpc/dcerpc_util.h"
38
#include "rpc_dce.h"
39
#include "cli_pipe.h"
40
#include "source3/include/client.h"
41
#include "source3/libsmb/proto.h"
42
#include "auth/gensec/gensec.h"
43
#include "auth/credentials/credentials.h"
44
#include "auth/auth_util.h"
45
#include "../libcli/smb/smbXcli_base.h"
46
#include "lib/tsocket/tsocket.h"
47
#include "libcli/named_pipe_auth/npa_tstream.h"
48
#include "librpc/gen_ndr/ndr_winreg.h"
49
#include "local_np.h"
50
#include "libcli/smb/tstream_smbXcli_np.h"
51
52
#undef DBGC_CLASS
53
0
#define DBGC_CLASS DBGC_RPC_CLI
54
55
static const uint16_t default_bt_features =
56
  DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN |
57
  DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
58
59
struct rpc_client_association {
60
  struct dcerpc_binding *binding;
61
62
  struct {
63
    uint16_t client;
64
    uint16_t negotiated;
65
    bool negotiation_done;
66
  } features;
67
68
  struct samba_sockaddr addr;
69
70
  uint32_t next_call_id;
71
};
72
73
static NTSTATUS rpc_client_association_create(TALLOC_CTX *mem_ctx,
74
                uint16_t client_features,
75
                uint32_t flags,
76
                const char *target_hostname,
77
                enum dcerpc_transport_t transport,
78
                const struct samba_sockaddr *addr,
79
                const char *endpoint,
80
                struct rpc_client_association **passoc)
81
0
{
82
0
  struct rpc_client_association *assoc = NULL;
83
0
  struct dcerpc_binding *bd = NULL;
84
0
  char addrstr[INET6_ADDRSTRLEN] = { 0, };
85
0
  NTSTATUS status;
86
87
0
  assoc = talloc_zero(mem_ctx, struct rpc_client_association);
88
0
  if (assoc == NULL) {
89
0
    return NT_STATUS_NO_MEMORY;
90
0
  }
91
0
  assoc->features.client = client_features;
92
0
  if (client_features == 0) {
93
    /*
94
     * Without requested features there
95
     * is no point in trying to negotiate
96
     * something, so we are done...
97
     */
98
0
    assoc->features.negotiation_done = true;
99
0
  }
100
101
0
  status = dcerpc_parse_binding(assoc, "", &bd);
102
0
  if (!NT_STATUS_IS_OK(status)) {
103
0
    TALLOC_FREE(assoc);
104
0
    return status;
105
0
  }
106
0
  status = dcerpc_binding_set_transport(bd, transport);
107
0
  if (!NT_STATUS_IS_OK(status)) {
108
0
    TALLOC_FREE(assoc);
109
0
    return status;
110
0
  }
111
0
  switch (addr->u.sa.sa_family) {
112
0
  case AF_INET:
113
0
  case AF_INET6:
114
0
    print_sockaddr(addrstr,
115
0
             sizeof(addrstr),
116
0
             &addr->u.ss);
117
0
    status = dcerpc_binding_set_string_option(bd,
118
0
                "host",
119
0
                addrstr);
120
0
    if (!NT_STATUS_IS_OK(status)) {
121
0
      TALLOC_FREE(assoc);
122
0
      return status;
123
0
    }
124
0
    break;
125
0
  default:
126
0
    status = dcerpc_binding_set_string_option(bd,
127
0
                "host",
128
0
                target_hostname);
129
0
    if (!NT_STATUS_IS_OK(status)) {
130
0
      TALLOC_FREE(assoc);
131
0
      return status;
132
0
    }
133
0
    break;
134
0
  }
135
0
  status = dcerpc_binding_set_string_option(bd,
136
0
              "target_hostname",
137
0
              target_hostname);
138
0
  if (!NT_STATUS_IS_OK(status)) {
139
0
    TALLOC_FREE(assoc);
140
0
    return status;
141
0
  }
142
0
  status = dcerpc_binding_set_string_option(bd,
143
0
              "endpoint",
144
0
              endpoint);
145
0
  if (!NT_STATUS_IS_OK(status)) {
146
0
    TALLOC_FREE(assoc);
147
0
    return status;
148
0
  }
149
0
  status = dcerpc_binding_set_flags(bd, flags, 0);
150
0
  if (!NT_STATUS_IS_OK(status)) {
151
0
    TALLOC_FREE(assoc);
152
0
    return status;
153
0
  }
154
155
0
  assoc->binding = bd;
156
0
  assoc->addr = *addr;
157
158
0
  *passoc = assoc;
159
0
  return NT_STATUS_OK;
160
0
}
161
162
struct rpc_client_connection {
163
  DATA_BLOB transport_session_key;
164
  struct rpc_cli_transport *transport;
165
  struct samba_sockaddr localaddr;
166
167
  struct {
168
    uint16_t max_xmit_frag;
169
    uint16_t max_recv_frag;
170
    bool client_hdr_signing;
171
    bool hdr_signing;
172
    bool bind_done;
173
  } features;
174
175
  uint32_t next_auth_context_id;
176
  uint16_t next_pres_context_id;
177
};
178
179
static NTSTATUS rpc_client_connection_create(TALLOC_CTX *mem_ctx,
180
               const struct rpc_client_association *assoc,
181
               uint16_t max_frag,
182
               struct rpc_client_connection **pconn)
183
0
{
184
0
  struct rpc_client_connection *conn = NULL;
185
0
  uint32_t flags = dcerpc_binding_get_flags(assoc->binding);
186
0
  bool client_hdr_signing = (flags & DCERPC_PROPOSE_HEADER_SIGNING);
187
188
0
  conn = talloc_zero(mem_ctx, struct rpc_client_connection);
189
0
  if (conn == NULL) {
190
0
    return NT_STATUS_NO_MEMORY;
191
0
  }
192
0
  conn->features.max_xmit_frag = max_frag;
193
0
  conn->features.max_recv_frag = max_frag;
194
0
  conn->features.client_hdr_signing = client_hdr_signing;
195
196
0
  *pconn = conn;
197
0
  return NT_STATUS_OK;
198
0
}
199
200
static int rpc_pipe_client_wrap_destructor(struct rpc_pipe_client *p)
201
0
{
202
0
  if (p->np_cli != NULL) {
203
0
    DLIST_REMOVE(p->np_cli->pipe_list, p);
204
0
    p->np_cli = NULL;
205
0
  }
206
207
0
  return 0;
208
0
}
209
210
static NTSTATUS rpc_pipe_wrap_create(
211
  const struct ndr_interface_table *table,
212
  struct cli_state *np_cli,
213
  struct rpc_client_association **passoc,
214
  struct rpc_client_connection **pconn,
215
  TALLOC_CTX *mem_ctx,
216
  struct rpc_pipe_client **presult)
217
0
{
218
0
  struct rpc_pipe_client *result = NULL;
219
0
  const char *hostname = NULL;
220
221
0
  result = talloc_zero(mem_ctx, struct rpc_pipe_client);
222
0
  if (result == NULL) {
223
0
    return NT_STATUS_NO_MEMORY;
224
0
  }
225
0
  talloc_set_destructor(result, rpc_pipe_client_wrap_destructor);
226
227
0
  result->assoc = talloc_move(result, passoc);
228
0
  result->conn = talloc_move(result, pconn);
229
230
  /* rpc_pipe_bind_send should allocate an id... */
231
0
  result->pres_context_id = UINT16_MAX;
232
0
  result->table = table;
233
0
  result->transfer_syntax = ndr_transfer_syntax_ndr;
234
235
0
  hostname = dcerpc_binding_get_string_option(result->assoc->binding,
236
0
                "target_hostname");
237
0
  result->desthost = talloc_strdup(result, hostname);
238
0
  if (result->desthost == NULL) {
239
0
    TALLOC_FREE(result);
240
0
    return NT_STATUS_NO_MEMORY;
241
0
  }
242
243
0
  result->srv_name_slash = talloc_asprintf_strupper_m(
244
0
    result, "\\\\%s", result->desthost);
245
0
  if (result->srv_name_slash == NULL) {
246
0
    TALLOC_FREE(result);
247
0
    return NT_STATUS_NO_MEMORY;
248
0
  }
249
250
0
  if (np_cli != NULL) {
251
0
    result->np_cli = np_cli;
252
0
    DLIST_ADD_END(np_cli->pipe_list, result);
253
0
  }
254
255
0
  *presult = result;
256
0
  return NT_STATUS_OK;
257
0
}
258
259
/********************************************************************
260
 Pipe description for a DEBUG
261
 ********************************************************************/
262
static const char *rpccli_pipe_txt(TALLOC_CTX *mem_ctx,
263
           struct rpc_pipe_client *cli)
264
0
{
265
0
  char *result = talloc_asprintf(mem_ctx, "host %s", cli->desthost);
266
0
  if (result == NULL) {
267
0
    return "pipe";
268
0
  }
269
0
  return result;
270
0
}
271
272
/*******************************************************************
273
 Use SMBreadX to get rest of one fragment's worth of rpc data.
274
 Reads the whole size or give an error message
275
 ********************************************************************/
276
277
struct rpc_read_state {
278
  struct tevent_context *ev;
279
  struct rpc_cli_transport *transport;
280
  uint8_t *data;
281
  size_t size;
282
  size_t num_read;
283
};
284
285
static void rpc_read_done(struct tevent_req *subreq);
286
287
static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx,
288
          struct tevent_context *ev,
289
          struct rpc_cli_transport *transport,
290
          uint8_t *data, size_t size)
291
0
{
292
0
  struct tevent_req *req, *subreq;
293
0
  struct rpc_read_state *state;
294
295
0
  req = tevent_req_create(mem_ctx, &state, struct rpc_read_state);
296
0
  if (req == NULL) {
297
0
    return NULL;
298
0
  }
299
0
  state->ev = ev;
300
0
  state->transport = transport;
301
0
  state->data = data;
302
0
  state->size = size;
303
0
  state->num_read = 0;
304
305
0
  DBG_INFO("data_to_read: %zu\n", size);
306
307
0
  subreq = transport->read_send(state, ev, (uint8_t *)data, size,
308
0
              transport->priv);
309
0
  if (subreq == NULL) {
310
0
    goto fail;
311
0
  }
312
0
  tevent_req_set_callback(subreq, rpc_read_done, req);
313
0
  return req;
314
315
0
 fail:
316
0
  TALLOC_FREE(req);
317
0
  return NULL;
318
0
}
319
320
static void rpc_read_done(struct tevent_req *subreq)
321
0
{
322
0
  struct tevent_req *req = tevent_req_callback_data(
323
0
    subreq, struct tevent_req);
324
0
  struct rpc_read_state *state = tevent_req_data(
325
0
    req, struct rpc_read_state);
326
0
  NTSTATUS status;
327
0
  ssize_t received;
328
329
0
  status = state->transport->read_recv(subreq, &received);
330
0
  TALLOC_FREE(subreq);
331
0
  if (tevent_req_nterror(req, status)) {
332
0
    return;
333
0
  }
334
335
0
  state->num_read += received;
336
0
  if (state->num_read == state->size) {
337
0
    tevent_req_done(req);
338
0
    return;
339
0
  }
340
341
0
  subreq = state->transport->read_send(state, state->ev,
342
0
               state->data + state->num_read,
343
0
               state->size - state->num_read,
344
0
               state->transport->priv);
345
0
  if (tevent_req_nomem(subreq, req)) {
346
0
    return;
347
0
  }
348
0
  tevent_req_set_callback(subreq, rpc_read_done, req);
349
0
}
350
351
static NTSTATUS rpc_read_recv(struct tevent_req *req)
352
0
{
353
0
  return tevent_req_simple_recv_ntstatus(req);
354
0
}
355
356
struct rpc_write_state {
357
  struct tevent_context *ev;
358
  struct rpc_cli_transport *transport;
359
  const uint8_t *data;
360
  size_t size;
361
  size_t num_written;
362
};
363
364
static void rpc_write_done(struct tevent_req *subreq);
365
366
static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx,
367
           struct tevent_context *ev,
368
           struct rpc_cli_transport *transport,
369
           const uint8_t *data, size_t size)
370
0
{
371
0
  struct tevent_req *req, *subreq;
372
0
  struct rpc_write_state *state;
373
374
0
  req = tevent_req_create(mem_ctx, &state, struct rpc_write_state);
375
0
  if (req == NULL) {
376
0
    return NULL;
377
0
  }
378
0
  state->ev = ev;
379
0
  state->transport = transport;
380
0
  state->data = data;
381
0
  state->size = size;
382
0
  state->num_written = 0;
383
384
0
  DBG_INFO("data_to_write: %zu\n", size);
385
386
0
  subreq = transport->write_send(state, ev, data, size, transport->priv);
387
0
  if (tevent_req_nomem(subreq, req)) {
388
0
    return tevent_req_post(req, ev);
389
0
  }
390
0
  tevent_req_set_callback(subreq, rpc_write_done, req);
391
0
  return req;
392
0
}
393
394
static void rpc_write_done(struct tevent_req *subreq)
395
0
{
396
0
  struct tevent_req *req = tevent_req_callback_data(
397
0
    subreq, struct tevent_req);
398
0
  struct rpc_write_state *state = tevent_req_data(
399
0
    req, struct rpc_write_state);
400
0
  NTSTATUS status;
401
0
  ssize_t written;
402
403
0
  status = state->transport->write_recv(subreq, &written);
404
0
  TALLOC_FREE(subreq);
405
0
  if (tevent_req_nterror(req, status)) {
406
0
    return;
407
0
  }
408
409
0
  state->num_written += written;
410
411
0
  if (state->num_written == state->size) {
412
0
    tevent_req_done(req);
413
0
    return;
414
0
  }
415
416
0
  subreq = state->transport->write_send(state, state->ev,
417
0
                state->data + state->num_written,
418
0
                state->size - state->num_written,
419
0
                state->transport->priv);
420
0
  if (tevent_req_nomem(subreq, req)) {
421
0
    return;
422
0
  }
423
0
  tevent_req_set_callback(subreq, rpc_write_done, req);
424
0
}
425
426
static NTSTATUS rpc_write_recv(struct tevent_req *req)
427
0
{
428
0
  return tevent_req_simple_recv_ntstatus(req);
429
0
}
430
431
432
/****************************************************************************
433
 Try and get a PDU's worth of data from current_pdu. If not, then read more
434
 from the wire.
435
 ****************************************************************************/
436
437
struct get_complete_frag_state {
438
  struct tevent_context *ev;
439
  struct rpc_pipe_client *cli;
440
  uint16_t frag_len;
441
  DATA_BLOB *pdu;
442
};
443
444
static void get_complete_frag_got_header(struct tevent_req *subreq);
445
static void get_complete_frag_got_rest(struct tevent_req *subreq);
446
447
static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
448
             struct tevent_context *ev,
449
             struct rpc_pipe_client *cli,
450
             DATA_BLOB *pdu)
451
0
{
452
0
  struct tevent_req *req, *subreq;
453
0
  struct get_complete_frag_state *state;
454
0
  size_t received;
455
456
0
  req = tevent_req_create(mem_ctx, &state,
457
0
        struct get_complete_frag_state);
458
0
  if (req == NULL) {
459
0
    return NULL;
460
0
  }
461
0
  state->ev = ev;
462
0
  state->cli = cli;
463
0
  state->frag_len = RPC_HEADER_LEN;
464
0
  state->pdu = pdu;
465
466
0
  received = pdu->length;
467
0
  if (received < RPC_HEADER_LEN) {
468
0
    if (!data_blob_realloc(mem_ctx, pdu, RPC_HEADER_LEN)) {
469
0
      tevent_req_oom(req);
470
0
      return tevent_req_post(req, ev);
471
0
    }
472
0
    subreq = rpc_read_send(state, state->ev,
473
0
          state->cli->conn->transport,
474
0
          pdu->data + received,
475
0
          RPC_HEADER_LEN - received);
476
0
    if (tevent_req_nomem(subreq, req)) {
477
0
      return tevent_req_post(req, ev);
478
0
    }
479
0
    tevent_req_set_callback(subreq, get_complete_frag_got_header,
480
0
          req);
481
0
    return req;
482
0
  }
483
484
0
  state->frag_len = dcerpc_get_frag_length(pdu);
485
0
  if (state->frag_len < RPC_HEADER_LEN) {
486
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
487
0
    return tevent_req_post(req, ev);
488
0
  }
489
490
0
  if (received >= state->frag_len) {
491
    /*
492
     * Got the whole fragment
493
     */
494
0
    tevent_req_done(req);
495
0
    return tevent_req_post(req, ev);
496
0
  }
497
498
0
  if (!data_blob_realloc(NULL, pdu, state->frag_len)) {
499
0
    tevent_req_oom(req);
500
0
    return tevent_req_post(req, ev);
501
0
  }
502
503
0
  subreq = rpc_read_send(
504
0
    state,
505
0
    state->ev,
506
0
    state->cli->conn->transport,
507
0
    pdu->data + received,
508
0
    state->frag_len - received);
509
0
  if (tevent_req_nomem(subreq, req)) {
510
0
    return tevent_req_post(req, ev);
511
0
  }
512
0
  tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
513
0
  return req;
514
0
}
515
516
static void get_complete_frag_got_header(struct tevent_req *subreq)
517
0
{
518
0
  struct tevent_req *req = tevent_req_callback_data(
519
0
    subreq, struct tevent_req);
520
0
  struct get_complete_frag_state *state = tevent_req_data(
521
0
    req, struct get_complete_frag_state);
522
0
  NTSTATUS status;
523
524
0
  status = rpc_read_recv(subreq);
525
0
  TALLOC_FREE(subreq);
526
0
  if (tevent_req_nterror(req, status)) {
527
0
    return;
528
0
  }
529
530
0
  state->frag_len = dcerpc_get_frag_length(state->pdu);
531
0
  if (state->frag_len < RPC_HEADER_LEN) {
532
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
533
0
    return;
534
0
  }
535
536
0
  if (!data_blob_realloc(NULL, state->pdu, state->frag_len)) {
537
0
    tevent_req_oom(req);
538
0
    return;
539
0
  }
540
541
  /*
542
   * We're here in this piece of code because we've read exactly
543
   * RPC_HEADER_LEN bytes into state->pdu.
544
   */
545
546
0
  subreq = rpc_read_send(state, state->ev,
547
0
        state->cli->conn->transport,
548
0
        state->pdu->data + RPC_HEADER_LEN,
549
0
        state->frag_len - RPC_HEADER_LEN);
550
0
  if (tevent_req_nomem(subreq, req)) {
551
0
    return;
552
0
  }
553
0
  tevent_req_set_callback(subreq, get_complete_frag_got_rest, req);
554
0
}
555
556
static void get_complete_frag_got_rest(struct tevent_req *subreq)
557
0
{
558
0
  NTSTATUS status = rpc_read_recv(subreq);
559
0
  return tevent_req_simple_finish_ntstatus(subreq, status);
560
0
}
561
562
static NTSTATUS get_complete_frag_recv(struct tevent_req *req)
563
0
{
564
0
  return tevent_req_simple_recv_ntstatus(req);
565
0
}
566
567
/****************************************************************************
568
 Do basic authentication checks on an incoming pdu.
569
 ****************************************************************************/
570
571
static NTSTATUS cli_pipe_validate_current_pdu(TALLOC_CTX *mem_ctx,
572
            struct rpc_pipe_client *cli,
573
            struct ncacn_packet *pkt,
574
            DATA_BLOB *pdu,
575
            uint8_t expected_pkt_type,
576
            uint32_t call_id,
577
            DATA_BLOB *rdata,
578
            DATA_BLOB *reply_pdu)
579
0
{
580
0
  const struct dcerpc_response *r = NULL;
581
0
  DATA_BLOB tmp_stub = { .data = NULL };
582
0
  NTSTATUS ret;
583
584
  /*
585
   * Point the return values at the real data including the RPC
586
   * header. Just in case the caller wants it.
587
   */
588
0
  *rdata = *pdu;
589
590
0
  if ((pkt->ptype == DCERPC_PKT_BIND_ACK) &&
591
0
      !(pkt->pfc_flags & DCERPC_PFC_FLAG_LAST)) {
592
    /*
593
     * TODO: do we still need this hack which was introduced
594
     * in commit a42afcdcc7ab9aa9ed193ae36d3dbb10843447f0.
595
     *
596
     * I don't even know what AS/U might be...
597
     */
598
0
    DEBUG(5, (__location__ ": bug in server (AS/U?), setting "
599
0
        "fragment first/last ON.\n"));
600
0
    pkt->pfc_flags |= DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
601
0
  }
602
603
  /* Ensure we have the correct type. */
604
0
  switch (pkt->ptype) {
605
0
  case DCERPC_PKT_BIND_NAK:
606
0
    DEBUG(1, (__location__ ": Bind NACK received from %s!\n",
607
0
        rpccli_pipe_txt(talloc_tos(), cli)));
608
609
0
    ret = dcerpc_verify_ncacn_packet_header(pkt,
610
0
            DCERPC_PKT_BIND_NAK,
611
0
            0, /* max_auth_info */
612
0
            DCERPC_PFC_FLAG_FIRST |
613
0
            DCERPC_PFC_FLAG_LAST,
614
0
            0); /* optional flags */
615
0
    if (!NT_STATUS_IS_OK(ret)) {
616
0
      DEBUG(1, (__location__ ": Connection to %s got an unexpected "
617
0
          "RPC packet type - %u, expected %u: %s\n",
618
0
          rpccli_pipe_txt(talloc_tos(), cli),
619
0
          pkt->ptype, expected_pkt_type,
620
0
          nt_errstr(ret)));
621
0
      NDR_PRINT_DEBUG(ncacn_packet, pkt);
622
0
      return ret;
623
0
    }
624
625
    /* Use this for now... */
626
0
    return NT_STATUS_NETWORK_ACCESS_DENIED;
627
628
0
  case DCERPC_PKT_BIND_ACK:
629
0
    ret = dcerpc_verify_ncacn_packet_header(pkt,
630
0
          expected_pkt_type,
631
0
          pkt->u.bind_ack.auth_info.length,
632
0
          DCERPC_PFC_FLAG_FIRST |
633
0
          DCERPC_PFC_FLAG_LAST,
634
0
          DCERPC_PFC_FLAG_CONC_MPX |
635
0
          DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
636
0
    if (!NT_STATUS_IS_OK(ret)) {
637
0
      DEBUG(1, (__location__ ": Connection to %s got an unexpected "
638
0
          "RPC packet type - %u, expected %u: %s\n",
639
0
          rpccli_pipe_txt(talloc_tos(), cli),
640
0
          pkt->ptype, expected_pkt_type,
641
0
          nt_errstr(ret)));
642
0
      NDR_PRINT_DEBUG(ncacn_packet, pkt);
643
0
      return ret;
644
0
    }
645
646
0
    break;
647
648
0
  case DCERPC_PKT_ALTER_RESP:
649
0
    ret = dcerpc_verify_ncacn_packet_header(pkt,
650
0
          expected_pkt_type,
651
0
          pkt->u.alter_resp.auth_info.length,
652
0
          DCERPC_PFC_FLAG_FIRST |
653
0
          DCERPC_PFC_FLAG_LAST,
654
0
          DCERPC_PFC_FLAG_CONC_MPX |
655
0
          DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN);
656
0
    if (!NT_STATUS_IS_OK(ret)) {
657
0
      DEBUG(1, (__location__ ": Connection to %s got an unexpected "
658
0
          "RPC packet type - %u, expected %u: %s\n",
659
0
          rpccli_pipe_txt(talloc_tos(), cli),
660
0
          pkt->ptype, expected_pkt_type,
661
0
          nt_errstr(ret)));
662
0
      NDR_PRINT_DEBUG(ncacn_packet, pkt);
663
0
      return ret;
664
0
    }
665
666
0
    break;
667
668
0
  case DCERPC_PKT_RESPONSE:
669
670
0
    r = &pkt->u.response;
671
672
0
    ret = dcerpc_verify_ncacn_packet_header(pkt,
673
0
            expected_pkt_type,
674
0
            r->stub_and_verifier.length,
675
0
            0, /* required_flags */
676
0
            DCERPC_PFC_FLAG_FIRST |
677
0
            DCERPC_PFC_FLAG_LAST);
678
0
    if (!NT_STATUS_IS_OK(ret)) {
679
0
      DEBUG(1, (__location__ ": Connection to %s got an unexpected "
680
0
          "RPC packet type - %u, expected %u: %s\n",
681
0
          rpccli_pipe_txt(talloc_tos(), cli),
682
0
          pkt->ptype, expected_pkt_type,
683
0
          nt_errstr(ret)));
684
0
      NDR_PRINT_DEBUG(ncacn_packet, pkt);
685
0
      return ret;
686
0
    }
687
688
0
    tmp_stub.data = r->stub_and_verifier.data;
689
0
    tmp_stub.length = r->stub_and_verifier.length;
690
691
    /* Here's where we deal with incoming sign/seal. */
692
0
    ret = dcerpc_check_auth(cli->auth, pkt,
693
0
          &tmp_stub,
694
0
          DCERPC_RESPONSE_LENGTH,
695
0
          pdu);
696
0
    if (!NT_STATUS_IS_OK(ret)) {
697
0
      DEBUG(1, (__location__ ": Connection to %s got an unexpected "
698
0
          "RPC packet type - %u, expected %u: %s\n",
699
0
          rpccli_pipe_txt(talloc_tos(), cli),
700
0
          pkt->ptype, expected_pkt_type,
701
0
          nt_errstr(ret)));
702
0
      NDR_PRINT_DEBUG(ncacn_packet, pkt);
703
0
      return ret;
704
0
    }
705
706
    /* Point the return values at the NDR data. */
707
0
    *rdata = tmp_stub;
708
709
0
    DEBUG(10, ("Got pdu len %lu, data_len %lu\n",
710
0
         (long unsigned int)pdu->length,
711
0
         (long unsigned int)rdata->length));
712
713
    /*
714
     * If this is the first reply, and the allocation hint is
715
     * reasonable, try and set up the reply_pdu DATA_BLOB to the
716
     * correct size.
717
     */
718
719
0
    if ((reply_pdu->length == 0) &&
720
0
        r->alloc_hint && (r->alloc_hint < 15*1024*1024)) {
721
0
      if (!data_blob_realloc(mem_ctx, reply_pdu,
722
0
              r->alloc_hint)) {
723
0
        DEBUG(0, ("reply alloc hint %d too "
724
0
            "large to allocate\n",
725
0
            (int)r->alloc_hint));
726
0
        return NT_STATUS_NO_MEMORY;
727
0
      }
728
0
    }
729
730
0
    break;
731
732
0
  case DCERPC_PKT_FAULT:
733
734
0
    ret = dcerpc_verify_ncacn_packet_header(pkt,
735
0
            DCERPC_PKT_FAULT,
736
0
            0, /* max_auth_info */
737
0
            DCERPC_PFC_FLAG_FIRST |
738
0
            DCERPC_PFC_FLAG_LAST,
739
0
            DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
740
0
    if (!NT_STATUS_IS_OK(ret)) {
741
0
      DEBUG(1, (__location__ ": Connection to %s got an unexpected "
742
0
          "RPC packet type - %u, expected %u: %s\n",
743
0
          rpccli_pipe_txt(talloc_tos(), cli),
744
0
          pkt->ptype, expected_pkt_type,
745
0
          nt_errstr(ret)));
746
0
      NDR_PRINT_DEBUG(ncacn_packet, pkt);
747
0
      return ret;
748
0
    }
749
750
0
    DEBUG(1, (__location__ ": RPC fault code %s received "
751
0
        "from %s!\n",
752
0
        dcerpc_errstr(talloc_tos(),
753
0
        pkt->u.fault.status),
754
0
        rpccli_pipe_txt(talloc_tos(), cli)));
755
756
0
    return dcerpc_fault_to_nt_status(pkt->u.fault.status);
757
758
0
  default:
759
0
    DEBUG(0, (__location__ "Unknown packet type %u received "
760
0
        "from %s!\n",
761
0
        (unsigned int)pkt->ptype,
762
0
        rpccli_pipe_txt(talloc_tos(), cli)));
763
0
    return NT_STATUS_RPC_PROTOCOL_ERROR;
764
0
  }
765
766
767
0
  if (pkt->call_id != call_id) {
768
0
    DEBUG(3, (__location__ ": Connection to %s got an unexpected "
769
0
        "RPC call_id - %u, not %u\n",
770
0
        rpccli_pipe_txt(talloc_tos(), cli),
771
0
        pkt->call_id, call_id));
772
0
    return NT_STATUS_RPC_PROTOCOL_ERROR;
773
0
  }
774
775
0
  return NT_STATUS_OK;
776
0
}
777
778
/****************************************************************************
779
 Call a remote api on an arbitrary pipe.  takes param, data and setup buffers.
780
****************************************************************************/
781
782
struct cli_api_pipe_state {
783
  struct tevent_context *ev;
784
  struct rpc_cli_transport *transport;
785
  uint8_t *rdata;
786
  uint32_t rdata_len;
787
};
788
789
static void cli_api_pipe_trans_done(struct tevent_req *subreq);
790
static void cli_api_pipe_write_done(struct tevent_req *subreq);
791
static void cli_api_pipe_read_done(struct tevent_req *subreq);
792
793
static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx,
794
              struct tevent_context *ev,
795
              struct rpc_cli_transport *transport,
796
              uint8_t *data, size_t data_len,
797
              uint32_t max_rdata_len)
798
0
{
799
0
  struct tevent_req *req, *subreq;
800
0
  struct cli_api_pipe_state *state;
801
802
0
  req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state);
803
0
  if (req == NULL) {
804
0
    return NULL;
805
0
  }
806
0
  state->ev = ev;
807
0
  state->transport = transport;
808
809
0
  if (max_rdata_len < RPC_HEADER_LEN) {
810
    /*
811
     * For a RPC reply we always need at least RPC_HEADER_LEN
812
     * bytes. We check this here because we will receive
813
     * RPC_HEADER_LEN bytes in cli_trans_sock_send_done.
814
     */
815
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
816
0
    return tevent_req_post(req, ev);
817
0
  }
818
819
0
  if (transport->trans_send != NULL) {
820
0
    subreq = transport->trans_send(state, ev, data, data_len,
821
0
                 max_rdata_len, transport->priv);
822
0
    if (tevent_req_nomem(subreq, req)) {
823
0
      return tevent_req_post(req, ev);
824
0
    }
825
0
    tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req);
826
0
    return req;
827
0
  }
828
829
  /*
830
   * If the transport does not provide a "trans" routine, i.e. for
831
   * example the ncacn_ip_tcp transport, do the write/read step here.
832
   */
833
834
0
  subreq = rpc_write_send(state, ev, transport, data, data_len);
835
0
  if (tevent_req_nomem(subreq, req)) {
836
0
    return tevent_req_post(req, ev);
837
0
  }
838
0
  tevent_req_set_callback(subreq, cli_api_pipe_write_done, req);
839
0
  return req;
840
0
}
841
842
static void cli_api_pipe_trans_done(struct tevent_req *subreq)
843
0
{
844
0
  struct tevent_req *req = tevent_req_callback_data(
845
0
    subreq, struct tevent_req);
846
0
  struct cli_api_pipe_state *state = tevent_req_data(
847
0
    req, struct cli_api_pipe_state);
848
0
  NTSTATUS status;
849
850
0
  status = state->transport->trans_recv(subreq, state, &state->rdata,
851
0
                &state->rdata_len);
852
0
  TALLOC_FREE(subreq);
853
0
  if (tevent_req_nterror(req, status)) {
854
0
    return;
855
0
  }
856
0
  tevent_req_done(req);
857
0
}
858
859
static void cli_api_pipe_write_done(struct tevent_req *subreq)
860
0
{
861
0
  struct tevent_req *req = tevent_req_callback_data(
862
0
    subreq, struct tevent_req);
863
0
  struct cli_api_pipe_state *state = tevent_req_data(
864
0
    req, struct cli_api_pipe_state);
865
0
  NTSTATUS status;
866
867
0
  status = rpc_write_recv(subreq);
868
0
  TALLOC_FREE(subreq);
869
0
  if (tevent_req_nterror(req, status)) {
870
0
    return;
871
0
  }
872
873
0
  state->rdata = talloc_array(state, uint8_t, RPC_HEADER_LEN);
874
0
  if (tevent_req_nomem(state->rdata, req)) {
875
0
    return;
876
0
  }
877
878
  /*
879
   * We don't need to use rpc_read_send here, the upper layer will cope
880
   * with a short read, transport->trans_send could also return less
881
   * than state->max_rdata_len.
882
   */
883
0
  subreq = state->transport->read_send(state, state->ev, state->rdata,
884
0
               RPC_HEADER_LEN,
885
0
               state->transport->priv);
886
0
  if (tevent_req_nomem(subreq, req)) {
887
0
    return;
888
0
  }
889
0
  tevent_req_set_callback(subreq, cli_api_pipe_read_done, req);
890
0
}
891
892
static void cli_api_pipe_read_done(struct tevent_req *subreq)
893
0
{
894
0
  struct tevent_req *req = tevent_req_callback_data(
895
0
    subreq, struct tevent_req);
896
0
  struct cli_api_pipe_state *state = tevent_req_data(
897
0
    req, struct cli_api_pipe_state);
898
0
  NTSTATUS status;
899
0
  ssize_t received;
900
901
0
  status = state->transport->read_recv(subreq, &received);
902
0
  TALLOC_FREE(subreq);
903
0
  if (tevent_req_nterror(req, status)) {
904
0
    return;
905
0
  }
906
0
  state->rdata_len = received;
907
0
  tevent_req_done(req);
908
0
}
909
910
static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
911
          uint8_t **prdata, uint32_t *prdata_len)
912
0
{
913
0
  struct cli_api_pipe_state *state = tevent_req_data(
914
0
    req, struct cli_api_pipe_state);
915
0
  NTSTATUS status;
916
917
0
  if (tevent_req_is_nterror(req, &status)) {
918
0
    return status;
919
0
  }
920
921
0
  *prdata = talloc_move(mem_ctx, &state->rdata);
922
0
  *prdata_len = state->rdata_len;
923
0
  return NT_STATUS_OK;
924
0
}
925
926
/****************************************************************************
927
 Send data on an rpc pipe via trans. The data must be the last
928
 pdu fragment of an NDR data stream.
929
930
 Receive response data from an rpc pipe, which may be large...
931
932
 Read the first fragment: unfortunately have to use SMBtrans for the first
933
 bit, then SMBreadX for subsequent bits.
934
935
 If first fragment received also wasn't the last fragment, continue
936
 getting fragments until we _do_ receive the last fragment.
937
938
 Request/Response PDU's look like the following...
939
940
 |<------------------PDU len----------------------------------------------->|
941
 |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
942
943
 +------------+-----------------+-------------+---------------+-------------+
944
 | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR      | AUTH DATA   |
945
 +------------+-----------------+-------------+---------------+-------------+
946
947
 Where the presence of the AUTH_HDR and AUTH DATA are dependent on the
948
 signing & sealing being negotiated.
949
950
 ****************************************************************************/
951
952
struct rpc_api_pipe_state {
953
  struct tevent_context *ev;
954
  struct rpc_pipe_client *cli;
955
  uint8_t expected_pkt_type;
956
  uint32_t call_id;
957
958
  DATA_BLOB incoming_frag;
959
  struct ncacn_packet *pkt;
960
961
  /* Incoming reply */
962
  DATA_BLOB reply_pdu;
963
  size_t reply_pdu_offset;
964
  uint8_t endianness;
965
};
966
967
static void rpc_api_pipe_trans_done(struct tevent_req *subreq);
968
static void rpc_api_pipe_got_pdu(struct tevent_req *subreq);
969
static void rpc_api_pipe_auth3_done(struct tevent_req *subreq);
970
971
static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx,
972
              struct tevent_context *ev,
973
              struct rpc_pipe_client *cli,
974
              DATA_BLOB *data, /* Outgoing PDU */
975
              uint8_t expected_pkt_type,
976
              uint32_t call_id)
977
0
{
978
0
  struct tevent_req *req, *subreq;
979
0
  struct rpc_api_pipe_state *state;
980
0
  uint16_t max_recv_frag;
981
982
0
  req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state);
983
0
  if (req == NULL) {
984
0
    return NULL;
985
0
  }
986
0
  state->ev = ev;
987
0
  state->cli = cli;
988
0
  state->expected_pkt_type = expected_pkt_type;
989
0
  state->call_id = call_id;
990
0
  state->endianness = DCERPC_DREP_LE;
991
992
  /*
993
   * Ensure we're not sending too much.
994
   */
995
0
  if (data->length > cli->conn->features.max_xmit_frag) {
996
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
997
0
    return tevent_req_post(req, ev);
998
0
  }
999
1000
0
  DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli)));
1001
1002
0
  if (state->expected_pkt_type == DCERPC_PKT_AUTH3) {
1003
0
    subreq = rpc_write_send(state, ev, cli->conn->transport,
1004
0
          data->data, data->length);
1005
0
    if (tevent_req_nomem(subreq, req)) {
1006
0
      return tevent_req_post(req, ev);
1007
0
    }
1008
0
    tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req);
1009
0
    return req;
1010
0
  }
1011
1012
  /* get the header first, then fetch the rest once we have
1013
   * the frag_length available */
1014
0
  max_recv_frag = RPC_HEADER_LEN;
1015
1016
0
  subreq = cli_api_pipe_send(state, ev, cli->conn->transport,
1017
0
           data->data, data->length, max_recv_frag);
1018
0
  if (tevent_req_nomem(subreq, req)) {
1019
0
    return tevent_req_post(req, ev);
1020
0
  }
1021
0
  tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req);
1022
0
  return req;
1023
0
}
1024
1025
static void rpc_api_pipe_auth3_done(struct tevent_req *subreq)
1026
0
{
1027
0
  NTSTATUS status = rpc_write_recv(subreq);
1028
0
  return tevent_req_simple_finish_ntstatus(subreq, status);
1029
0
}
1030
1031
static void rpc_api_pipe_trans_done(struct tevent_req *subreq)
1032
0
{
1033
0
  struct tevent_req *req = tevent_req_callback_data(
1034
0
    subreq, struct tevent_req);
1035
0
  struct rpc_api_pipe_state *state = tevent_req_data(
1036
0
    req, struct rpc_api_pipe_state);
1037
0
  NTSTATUS status;
1038
0
  uint8_t *rdata = NULL;
1039
0
  uint32_t rdata_len = 0;
1040
1041
0
  status = cli_api_pipe_recv(subreq, state, &rdata, &rdata_len);
1042
0
  TALLOC_FREE(subreq);
1043
0
  if (tevent_req_nterror(req, status)) {;
1044
0
    DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status)));
1045
0
    return;
1046
0
  }
1047
1048
0
  if (rdata == NULL) {
1049
0
    DEBUG(3,("rpc_api_pipe: %s failed to return data.\n",
1050
0
       rpccli_pipe_txt(talloc_tos(), state->cli)));
1051
0
    tevent_req_done(req);
1052
0
    return;
1053
0
  }
1054
1055
  /*
1056
   * Move data on state->incoming_frag.
1057
   */
1058
0
  state->incoming_frag.data = talloc_move(state, &rdata);
1059
0
  state->incoming_frag.length = rdata_len;
1060
0
  if (!state->incoming_frag.data) {
1061
0
    tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
1062
0
    return;
1063
0
  }
1064
1065
  /* Ensure we have enough data for a pdu. */
1066
0
  subreq = get_complete_frag_send(state, state->ev, state->cli,
1067
0
          &state->incoming_frag);
1068
0
  if (tevent_req_nomem(subreq, req)) {
1069
0
    return;
1070
0
  }
1071
0
  tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1072
0
}
1073
1074
static void rpc_api_pipe_got_pdu(struct tevent_req *subreq)
1075
0
{
1076
0
  struct tevent_req *req = tevent_req_callback_data(
1077
0
    subreq, struct tevent_req);
1078
0
  struct rpc_api_pipe_state *state = tevent_req_data(
1079
0
    req, struct rpc_api_pipe_state);
1080
0
  NTSTATUS status;
1081
0
  DATA_BLOB rdata = { .data = NULL };
1082
1083
0
  status = get_complete_frag_recv(subreq);
1084
0
  TALLOC_FREE(subreq);
1085
0
  if (tevent_req_nterror(req, status)) {
1086
0
    DEBUG(5, ("get_complete_frag failed: %s\n",
1087
0
        nt_errstr(status)));
1088
0
    return;
1089
0
  }
1090
1091
0
  state->pkt = talloc(state, struct ncacn_packet);
1092
0
  if (!state->pkt) {
1093
    /*
1094
     * TODO: do a real async disconnect ...
1095
     *
1096
     * For now do it sync...
1097
     */
1098
0
    TALLOC_FREE(state->cli->conn);
1099
0
    tevent_req_oom(req);
1100
0
    return;
1101
0
  }
1102
1103
0
  status = dcerpc_pull_ncacn_packet(state->pkt,
1104
0
            &state->incoming_frag,
1105
0
            state->pkt);
1106
0
  if (tevent_req_nterror(req, status)) {
1107
    /*
1108
     * TODO: do a real async disconnect ...
1109
     *
1110
     * For now do it sync...
1111
     */
1112
0
    TALLOC_FREE(state->cli->conn);
1113
0
    return;
1114
0
  }
1115
1116
0
  if (DEBUGLEVEL >= 10) {
1117
0
    NDR_PRINT_DEBUG(ncacn_packet, state->pkt);
1118
0
  }
1119
1120
0
  status = cli_pipe_validate_current_pdu(state,
1121
0
            state->cli, state->pkt,
1122
0
            &state->incoming_frag,
1123
0
            state->expected_pkt_type,
1124
0
            state->call_id,
1125
0
            &rdata,
1126
0
            &state->reply_pdu);
1127
1128
0
  DBG_DEBUG("got frag len of %zu at offset %zu: %s\n",
1129
0
      state->incoming_frag.length,
1130
0
      state->reply_pdu_offset,
1131
0
      nt_errstr(status));
1132
1133
0
  if (state->pkt->ptype != DCERPC_PKT_FAULT && !NT_STATUS_IS_OK(status)) {
1134
    /*
1135
     * TODO: do a real async disconnect ...
1136
     *
1137
     * For now do it sync...
1138
     */
1139
0
    TALLOC_FREE(state->cli->conn);
1140
0
  } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1141
    /*
1142
     * TODO: do a real async disconnect ...
1143
     *
1144
     * For now do it sync...
1145
     */
1146
0
    TALLOC_FREE(state->cli->conn);
1147
0
  } else if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR)) {
1148
    /*
1149
     * TODO: do a real async disconnect ...
1150
     *
1151
     * For now do it sync...
1152
     */
1153
0
    TALLOC_FREE(state->cli->conn);
1154
0
  }
1155
0
  if (tevent_req_nterror(req, status)) {
1156
0
    return;
1157
0
  }
1158
1159
0
  if ((state->pkt->pfc_flags & DCERPC_PFC_FLAG_FIRST)
1160
0
      && (state->pkt->drep[0] != DCERPC_DREP_LE)) {
1161
    /*
1162
     * Set the data type correctly for big-endian data on the
1163
     * first packet.
1164
     */
1165
0
    DEBUG(10,("rpc_api_pipe: On %s PDU data format is "
1166
0
        "big-endian.\n",
1167
0
        rpccli_pipe_txt(talloc_tos(), state->cli)));
1168
0
    state->endianness = 0x00; /* BIG ENDIAN */
1169
0
  }
1170
  /*
1171
   * Check endianness on subsequent packets.
1172
   */
1173
0
  if (state->endianness != state->pkt->drep[0]) {
1174
0
    DEBUG(0,("rpc_api_pipe: Error : Endianness changed from %s to "
1175
0
       "%s\n",
1176
0
       state->endianness?"little":"big",
1177
0
       state->pkt->drep[0]?"little":"big"));
1178
    /*
1179
     * TODO: do a real async disconnect ...
1180
     *
1181
     * For now do it sync...
1182
     */
1183
0
    TALLOC_FREE(state->cli->conn);
1184
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1185
0
    return;
1186
0
  }
1187
1188
0
  if (state->reply_pdu_offset + rdata.length > MAX_RPC_DATA_SIZE) {
1189
    /*
1190
     * TODO: do a real async disconnect ...
1191
     *
1192
     * For now do it sync...
1193
     */
1194
0
    TALLOC_FREE(state->cli->conn);
1195
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
1196
0
    return;
1197
0
  }
1198
1199
  /* Now copy the data portion out of the pdu into rbuf. */
1200
0
  if (state->reply_pdu.length < state->reply_pdu_offset + rdata.length) {
1201
0
    if (!data_blob_realloc(NULL, &state->reply_pdu,
1202
0
        state->reply_pdu_offset + rdata.length)) {
1203
      /*
1204
       * TODO: do a real async disconnect ...
1205
       *
1206
       * For now do it sync...
1207
       */
1208
0
      TALLOC_FREE(state->cli->conn);
1209
0
      tevent_req_oom(req);
1210
0
      return;
1211
0
    }
1212
0
  }
1213
1214
0
  memcpy(state->reply_pdu.data + state->reply_pdu_offset,
1215
0
    rdata.data, rdata.length);
1216
0
  state->reply_pdu_offset += rdata.length;
1217
1218
  /* reset state->incoming_frag, there is no need to free it,
1219
   * it will be reallocated to the right size the next time
1220
   * it is used */
1221
0
  state->incoming_frag.length = 0;
1222
1223
0
  if (state->pkt->pfc_flags & DCERPC_PFC_FLAG_LAST) {
1224
    /* make sure the pdu length is right now that we
1225
     * have all the data available (alloc hint may
1226
     * have allocated more than was actually used) */
1227
0
    state->reply_pdu.length = state->reply_pdu_offset;
1228
0
    DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n",
1229
0
        rpccli_pipe_txt(talloc_tos(), state->cli),
1230
0
        (unsigned)state->reply_pdu.length));
1231
0
    tevent_req_done(req);
1232
0
    return;
1233
0
  }
1234
1235
0
  subreq = get_complete_frag_send(state, state->ev, state->cli,
1236
0
          &state->incoming_frag);
1237
0
  if (subreq == NULL) {
1238
    /*
1239
     * TODO: do a real async disconnect ...
1240
     *
1241
     * For now do it sync...
1242
     */
1243
0
    TALLOC_FREE(state->cli->conn);
1244
0
  }
1245
0
  if (tevent_req_nomem(subreq, req)) {
1246
0
    return;
1247
0
  }
1248
0
  tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req);
1249
0
}
1250
1251
static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1252
          struct ncacn_packet **pkt,
1253
          DATA_BLOB *reply_pdu)
1254
0
{
1255
0
  struct rpc_api_pipe_state *state = tevent_req_data(
1256
0
    req, struct rpc_api_pipe_state);
1257
0
  NTSTATUS status;
1258
1259
0
  if (tevent_req_is_nterror(req, &status)) {
1260
0
    return status;
1261
0
  }
1262
1263
  /* return data to caller and assign it ownership of memory */
1264
0
  if (reply_pdu) {
1265
0
    reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1266
0
    reply_pdu->length = state->reply_pdu.length;
1267
0
    state->reply_pdu.length = 0;
1268
0
  } else {
1269
0
    data_blob_free(&state->reply_pdu);
1270
0
  }
1271
1272
0
  if (pkt) {
1273
0
    *pkt = talloc_steal(mem_ctx, state->pkt);
1274
0
  }
1275
1276
0
  return NT_STATUS_OK;
1277
0
}
1278
1279
/*******************************************************************
1280
 Creates NTLMSSP auth bind.
1281
 ********************************************************************/
1282
1283
static NTSTATUS create_generic_auth_rpc_bind_req(struct rpc_pipe_client *cli,
1284
             TALLOC_CTX *mem_ctx,
1285
             DATA_BLOB *auth_token)
1286
0
{
1287
0
  struct gensec_security *gensec_security;
1288
0
  DATA_BLOB null_blob = { .data = NULL };
1289
0
  NTSTATUS status;
1290
1291
0
  gensec_security = cli->auth->auth_ctx;
1292
1293
0
  DEBUG(5, ("create_generic_auth_rpc_bind_req: generate first token\n"));
1294
0
  status = gensec_update(gensec_security, mem_ctx, null_blob, auth_token);
1295
1296
0
  if (!NT_STATUS_IS_OK(status) &&
1297
0
      !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED))
1298
0
  {
1299
0
    return status;
1300
0
  }
1301
1302
0
  return status;
1303
0
}
1304
1305
/*******************************************************************
1306
 Creates the internals of a DCE/RPC bind request or alter context PDU.
1307
 ********************************************************************/
1308
1309
static NTSTATUS create_bind_or_alt_ctx_internal(TALLOC_CTX *mem_ctx,
1310
            enum dcerpc_pkt_type ptype,
1311
            uint32_t rpc_call_id,
1312
            struct rpc_client_association *assoc,
1313
            struct rpc_client_connection *conn,
1314
            uint16_t pres_context_id,
1315
            const struct ndr_syntax_id *abstract,
1316
            const struct ndr_syntax_id *transfer,
1317
            const DATA_BLOB *auth_info,
1318
            DATA_BLOB *blob)
1319
0
{
1320
0
  uint16_t auth_len = auth_info->length;
1321
0
  NTSTATUS status;
1322
0
  struct ndr_syntax_id bind_time_features = dcerpc_construct_bind_time_features(
1323
0
      assoc->features.client);
1324
0
  struct dcerpc_ctx_list ctx_list[2] = {
1325
0
    [0] = {
1326
0
      .context_id = pres_context_id,
1327
0
      .num_transfer_syntaxes = 1,
1328
0
      .abstract_syntax = *abstract,
1329
0
      .transfer_syntaxes = (struct ndr_syntax_id *)discard_const(transfer),
1330
0
    },
1331
0
    [1] = {
1332
      /*
1333
       * For now we assume pres_context_id is 0
1334
       * because bind time feature negotiation
1335
       * only happens once per association,
1336
       * with the first DCERPC Bind.
1337
       *
1338
       * With that we use pres_context_id + 1,
1339
       * but only consume it from conn->next_pres_context_id
1340
       * in check_bind_response().
1341
       */
1342
0
      .context_id = pres_context_id + 1,
1343
0
      .num_transfer_syntaxes = 1,
1344
0
      .abstract_syntax = *abstract,
1345
0
      .transfer_syntaxes = &bind_time_features,
1346
0
    },
1347
0
  };
1348
0
  uint32_t assoc_group_id =
1349
0
    dcerpc_binding_get_assoc_group_id(assoc->binding);
1350
0
  union dcerpc_payload u = {
1351
0
    .bind.max_xmit_frag = conn->features.max_xmit_frag,
1352
0
    .bind.max_recv_frag = conn->features.max_recv_frag,
1353
0
    .bind.assoc_group_id  = assoc_group_id,
1354
0
    .bind.num_contexts  = assoc->features.negotiation_done ? 1 : 2,
1355
0
    .bind.ctx_list    = ctx_list,
1356
0
    .bind.auth_info   = *auth_info,
1357
0
  };
1358
0
  uint8_t pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
1359
1360
0
  if (conn->features.client_hdr_signing &&
1361
0
      auth_len != 0 &&
1362
0
      !conn->features.hdr_signing)
1363
0
  {
1364
    /*
1365
     * The first authenticated bind or alter_context
1366
     * negotiates header signing
1367
     */
1368
0
    pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
1369
0
  }
1370
1371
0
  if (auth_len) {
1372
0
    auth_len -= DCERPC_AUTH_TRAILER_LENGTH;
1373
0
  }
1374
1375
0
  status = dcerpc_push_ncacn_packet(mem_ctx,
1376
0
            ptype, pfc_flags,
1377
0
            auth_len,
1378
0
            rpc_call_id,
1379
0
            &u,
1380
0
            blob);
1381
0
  if (!NT_STATUS_IS_OK(status)) {
1382
0
    DEBUG(0, ("Failed to marshall bind/alter ncacn_packet.\n"));
1383
0
    return status;
1384
0
  }
1385
1386
0
  return NT_STATUS_OK;
1387
0
}
1388
1389
/*******************************************************************
1390
 Creates a DCE/RPC bind request.
1391
 ********************************************************************/
1392
1393
static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
1394
            struct rpc_pipe_client *cli,
1395
            struct pipe_auth_data *auth,
1396
            uint32_t rpc_call_id,
1397
            const struct ndr_syntax_id *abstract,
1398
            const struct ndr_syntax_id *transfer,
1399
            DATA_BLOB *rpc_out)
1400
0
{
1401
0
  enum dcerpc_pkt_type ptype = DCERPC_PKT_BIND;
1402
0
  DATA_BLOB auth_token = { .data = NULL };
1403
0
  DATA_BLOB auth_info = { .data = NULL };
1404
0
  NTSTATUS ret;
1405
1406
0
  if (cli->conn->features.bind_done) {
1407
0
    ptype = DCERPC_PKT_ALTER;
1408
0
  }
1409
1410
0
  if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
1411
0
    ret = create_generic_auth_rpc_bind_req(
1412
0
      cli, mem_ctx, &auth_token);
1413
1414
0
    if (!NT_STATUS_IS_OK(ret) &&
1415
0
        !NT_STATUS_EQUAL(ret, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1416
0
      return ret;
1417
0
    }
1418
0
  }
1419
1420
0
  if (auth_token.length != 0) {
1421
0
    ret = dcerpc_push_dcerpc_auth(cli,
1422
0
            auth->auth_type,
1423
0
            auth->auth_level,
1424
0
            0, /* auth_pad_length */
1425
0
            auth->auth_context_id,
1426
0
            &auth_token,
1427
0
            &auth_info);
1428
0
    if (!NT_STATUS_IS_OK(ret)) {
1429
0
      return ret;
1430
0
    }
1431
0
    data_blob_free(&auth_token);
1432
0
  }
1433
1434
0
  ret = create_bind_or_alt_ctx_internal(mem_ctx,
1435
0
                ptype,
1436
0
                rpc_call_id,
1437
0
                cli->assoc,
1438
0
                cli->conn,
1439
0
                cli->pres_context_id,
1440
0
                abstract,
1441
0
                transfer,
1442
0
                &auth_info,
1443
0
                rpc_out);
1444
0
  data_blob_free(&auth_info);
1445
1446
0
  return ret;
1447
0
}
1448
1449
/*******************************************************************
1450
 External interface.
1451
 Does an rpc request on a pipe. Incoming data is NDR encoded in in_data.
1452
 Reply is NDR encoded in out_data. Splits the data stream into RPC PDU's
1453
 and deals with signing/sealing details.
1454
 ********************************************************************/
1455
1456
struct rpc_api_pipe_req_state {
1457
  struct tevent_context *ev;
1458
  struct rpc_pipe_client *cli;
1459
  uint8_t op_num;
1460
  uint32_t call_id;
1461
  const DATA_BLOB *req_data;
1462
  const struct GUID *object_uuid;
1463
  uint32_t req_data_sent;
1464
  DATA_BLOB req_trailer;
1465
  uint32_t req_trailer_sent;
1466
  bool verify_bitmask1;
1467
  bool verify_pcontext;
1468
  DATA_BLOB rpc_out;
1469
  DATA_BLOB reply_pdu;
1470
};
1471
1472
static void rpc_api_pipe_req_write_done(struct tevent_req *subreq);
1473
static void rpc_api_pipe_req_done(struct tevent_req *subreq);
1474
static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state);
1475
static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1476
          bool *is_last_frag);
1477
1478
static struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
1479
           struct tevent_context *ev,
1480
           struct rpc_pipe_client *cli,
1481
           uint8_t op_num,
1482
           const struct GUID *object_uuid,
1483
           const DATA_BLOB *req_data)
1484
0
{
1485
0
  struct tevent_req *req, *subreq;
1486
0
  struct rpc_api_pipe_req_state *state;
1487
0
  NTSTATUS status;
1488
0
  bool is_last_frag;
1489
1490
0
  req = tevent_req_create(mem_ctx, &state,
1491
0
        struct rpc_api_pipe_req_state);
1492
0
  if (req == NULL) {
1493
0
    return NULL;
1494
0
  }
1495
0
  state->ev = ev;
1496
0
  state->cli = cli;
1497
0
  state->op_num = op_num;
1498
0
  state->object_uuid = object_uuid;
1499
0
  state->req_data = req_data;
1500
0
  state->call_id = ++cli->assoc->next_call_id;
1501
1502
0
  if (cli->conn->features.max_xmit_frag < DCERPC_REQUEST_LENGTH
1503
0
          + RPC_MAX_SIGN_SIZE) {
1504
    /* Server is screwed up ! */
1505
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
1506
0
    return tevent_req_post(req, ev);
1507
0
  }
1508
1509
0
  status = prepare_verification_trailer(state);
1510
0
  if (tevent_req_nterror(req, status)) {
1511
0
    return tevent_req_post(req, ev);
1512
0
  }
1513
1514
0
  status = prepare_next_frag(state, &is_last_frag);
1515
0
  if (tevent_req_nterror(req, status)) {
1516
0
    return tevent_req_post(req, ev);
1517
0
  }
1518
1519
0
  if (is_last_frag) {
1520
0
    subreq = rpc_api_pipe_send(state, ev, state->cli,
1521
0
             &state->rpc_out,
1522
0
             DCERPC_PKT_RESPONSE,
1523
0
             state->call_id);
1524
0
    if (tevent_req_nomem(subreq, req)) {
1525
0
      return tevent_req_post(req, ev);
1526
0
    }
1527
0
    tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1528
0
  } else {
1529
0
    subreq = rpc_write_send(state, ev, cli->conn->transport,
1530
0
          state->rpc_out.data,
1531
0
          state->rpc_out.length);
1532
0
    if (tevent_req_nomem(subreq, req)) {
1533
0
      return tevent_req_post(req, ev);
1534
0
    }
1535
0
    tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1536
0
          req);
1537
0
  }
1538
0
  return req;
1539
0
}
1540
1541
static NTSTATUS prepare_verification_trailer(struct rpc_api_pipe_req_state *state)
1542
0
{
1543
0
  struct pipe_auth_data *a = state->cli->auth;
1544
0
  struct dcerpc_sec_verification_trailer *t;
1545
0
  struct ndr_push *ndr = NULL;
1546
0
  enum ndr_err_code ndr_err;
1547
0
  size_t align = 0;
1548
0
  size_t pad = 0;
1549
1550
0
  if (a == NULL) {
1551
0
    return NT_STATUS_OK;
1552
0
  }
1553
1554
0
  if (a->auth_level < DCERPC_AUTH_LEVEL_PACKET) {
1555
0
    return NT_STATUS_OK;
1556
0
  }
1557
1558
0
  t = talloc_zero(state, struct dcerpc_sec_verification_trailer);
1559
0
  if (t == NULL) {
1560
0
    return NT_STATUS_NO_MEMORY;
1561
0
  }
1562
1563
0
  if (!a->verified_bitmask1) {
1564
0
    t->commands = talloc_realloc(t, t->commands,
1565
0
               struct dcerpc_sec_vt,
1566
0
               t->count.count + 1);
1567
0
    if (t->commands == NULL) {
1568
0
      return NT_STATUS_NO_MEMORY;
1569
0
    }
1570
0
    t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1571
0
      .command = DCERPC_SEC_VT_COMMAND_BITMASK1,
1572
0
      .u.bitmask1 = (state->cli->conn->features.client_hdr_signing) ?
1573
0
        DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING :
1574
0
        0,
1575
0
    };
1576
0
    state->verify_bitmask1 = true;
1577
0
  }
1578
1579
0
  if (!state->cli->verified_pcontext) {
1580
0
    t->commands = talloc_realloc(t, t->commands,
1581
0
               struct dcerpc_sec_vt,
1582
0
               t->count.count + 1);
1583
0
    if (t->commands == NULL) {
1584
0
      return NT_STATUS_NO_MEMORY;
1585
0
    }
1586
0
    t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1587
0
      .command = DCERPC_SEC_VT_COMMAND_PCONTEXT,
1588
0
      .u.pcontext.abstract_syntax =
1589
0
        state->cli->table->syntax_id,
1590
0
      .u.pcontext.transfer_syntax =
1591
0
        state->cli->transfer_syntax,
1592
0
    };
1593
0
    state->verify_pcontext = true;
1594
0
  }
1595
1596
0
  if (!a->hdr_signing) {
1597
0
    t->commands = talloc_realloc(t, t->commands,
1598
0
               struct dcerpc_sec_vt,
1599
0
               t->count.count + 1);
1600
0
    if (t->commands == NULL) {
1601
0
      return NT_STATUS_NO_MEMORY;
1602
0
    }
1603
0
    t->commands[t->count.count++] = (struct dcerpc_sec_vt) {
1604
0
      .command = DCERPC_SEC_VT_COMMAND_HEADER2,
1605
0
      .u.header2.ptype = DCERPC_PKT_REQUEST,
1606
0
      .u.header2.drep[0] = DCERPC_DREP_LE,
1607
0
      .u.header2.call_id = state->call_id,
1608
0
      .u.header2.context_id = state->cli->pres_context_id,
1609
0
      .u.header2.opnum = state->op_num,
1610
0
    };
1611
0
  }
1612
1613
0
  if (t->count.count == 0) {
1614
0
    TALLOC_FREE(t);
1615
0
    return NT_STATUS_OK;
1616
0
  }
1617
1618
0
  t->commands[t->count.count - 1].command |= DCERPC_SEC_VT_COMMAND_END;
1619
1620
0
  if (DEBUGLEVEL >= 10) {
1621
0
    NDR_PRINT_DEBUG(dcerpc_sec_verification_trailer, t);
1622
0
  }
1623
1624
0
  ndr = ndr_push_init_ctx(state);
1625
0
  if (ndr == NULL) {
1626
0
    return NT_STATUS_NO_MEMORY;
1627
0
  }
1628
1629
0
  ndr_err = ndr_push_dcerpc_sec_verification_trailer(ndr,
1630
0
            NDR_SCALARS | NDR_BUFFERS,
1631
0
            t);
1632
0
  TALLOC_FREE(t);
1633
0
  if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1634
0
    return ndr_map_error2ntstatus(ndr_err);
1635
0
  }
1636
0
  state->req_trailer = ndr_push_blob(ndr);
1637
1638
0
  align = state->req_data->length & 0x3;
1639
0
  if (align > 0) {
1640
0
    pad = 4 - align;
1641
0
  }
1642
0
  if (pad > 0) {
1643
0
    bool ok;
1644
0
    uint8_t *p;
1645
0
    const uint8_t zeros[4] = { 0, };
1646
1647
0
    ok = data_blob_append(ndr, &state->req_trailer, zeros, pad);
1648
0
    if (!ok) {
1649
0
      return NT_STATUS_NO_MEMORY;
1650
0
    }
1651
1652
    /* move the padding to the start */
1653
0
    p = state->req_trailer.data;
1654
0
    memmove(p + pad, p, state->req_trailer.length - pad);
1655
0
    memset(p, 0, pad);
1656
0
  }
1657
1658
0
  return NT_STATUS_OK;
1659
0
}
1660
1661
static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state,
1662
          bool *is_last_frag)
1663
0
{
1664
0
  size_t auth_len;
1665
0
  size_t frag_len;
1666
0
  uint8_t flags = 0;
1667
0
  size_t pad_len;
1668
0
  size_t data_left;
1669
0
  size_t data_thistime;
1670
0
  size_t trailer_left;
1671
0
  size_t trailer_thistime = 0;
1672
0
  size_t total_left;
1673
0
  size_t total_thistime;
1674
0
  NTSTATUS status;
1675
0
  bool ok;
1676
0
  union dcerpc_payload u;
1677
1678
0
  data_left = state->req_data->length - state->req_data_sent;
1679
0
  trailer_left = state->req_trailer.length - state->req_trailer_sent;
1680
0
  total_left = data_left + trailer_left;
1681
0
  if ((total_left < data_left) || (total_left < trailer_left)) {
1682
    /*
1683
     * overflow
1684
     */
1685
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
1686
0
  }
1687
1688
0
  status = dcerpc_guess_sizes(state->cli->auth,
1689
0
            DCERPC_REQUEST_LENGTH, total_left,
1690
0
            state->cli->conn->features.max_xmit_frag,
1691
0
            &total_thistime,
1692
0
            &frag_len, &auth_len, &pad_len);
1693
0
  if (!NT_STATUS_IS_OK(status)) {
1694
0
    return status;
1695
0
  }
1696
1697
0
  if (state->req_data_sent == 0) {
1698
0
    flags = DCERPC_PFC_FLAG_FIRST;
1699
0
  }
1700
1701
0
  if (total_thistime == total_left) {
1702
0
    flags |= DCERPC_PFC_FLAG_LAST;
1703
0
  }
1704
1705
0
  data_thistime = MIN(total_thistime, data_left);
1706
0
  if (data_thistime < total_thistime) {
1707
0
    trailer_thistime = total_thistime - data_thistime;
1708
0
  }
1709
1710
0
  data_blob_free(&state->rpc_out);
1711
1712
0
  u = (union dcerpc_payload) {
1713
0
    .request.alloc_hint = total_left,
1714
0
    .request.context_id = state->cli->pres_context_id,
1715
0
    .request.opnum    = state->op_num,
1716
0
  };
1717
1718
0
  if (state->object_uuid) {
1719
0
    flags |= DCERPC_PFC_FLAG_OBJECT_UUID;
1720
0
    u.request.object.object = *state->object_uuid;
1721
0
    frag_len += ndr_size_GUID(state->object_uuid, 0);
1722
0
  }
1723
1724
0
  status = dcerpc_push_ncacn_packet(state,
1725
0
            DCERPC_PKT_REQUEST,
1726
0
            flags,
1727
0
            auth_len,
1728
0
            state->call_id,
1729
0
            &u,
1730
0
            &state->rpc_out);
1731
0
  if (!NT_STATUS_IS_OK(status)) {
1732
0
    return status;
1733
0
  }
1734
1735
  /* explicitly set frag_len here as dcerpc_push_ncacn_packet() can't
1736
   * compute it right for requests because the auth trailer is missing
1737
   * at this stage */
1738
0
  dcerpc_set_frag_length(&state->rpc_out, frag_len);
1739
1740
0
  if (data_thistime > 0) {
1741
    /* Copy in the data. */
1742
0
    ok = data_blob_append(NULL, &state->rpc_out,
1743
0
        state->req_data->data + state->req_data_sent,
1744
0
        data_thistime);
1745
0
    if (!ok) {
1746
0
      return NT_STATUS_NO_MEMORY;
1747
0
    }
1748
0
    state->req_data_sent += data_thistime;
1749
0
  }
1750
1751
0
  if (trailer_thistime > 0) {
1752
    /* Copy in the verification trailer. */
1753
0
    ok = data_blob_append(NULL, &state->rpc_out,
1754
0
        state->req_trailer.data + state->req_trailer_sent,
1755
0
        trailer_thistime);
1756
0
    if (!ok) {
1757
0
      return NT_STATUS_NO_MEMORY;
1758
0
    }
1759
0
    state->req_trailer_sent += trailer_thistime;
1760
0
  }
1761
1762
0
  switch (state->cli->auth->auth_level) {
1763
0
  case DCERPC_AUTH_LEVEL_NONE:
1764
0
  case DCERPC_AUTH_LEVEL_CONNECT:
1765
0
    break;
1766
0
  case DCERPC_AUTH_LEVEL_PACKET:
1767
0
  case DCERPC_AUTH_LEVEL_INTEGRITY:
1768
0
  case DCERPC_AUTH_LEVEL_PRIVACY:
1769
0
    status = dcerpc_add_auth_footer(state->cli->auth, pad_len,
1770
0
            &state->rpc_out);
1771
0
    if (!NT_STATUS_IS_OK(status)) {
1772
0
      return status;
1773
0
    }
1774
0
    break;
1775
0
  default:
1776
0
    return NT_STATUS_INVALID_PARAMETER;
1777
0
  }
1778
1779
0
  *is_last_frag = ((flags & DCERPC_PFC_FLAG_LAST) != 0);
1780
1781
0
  return status;
1782
0
}
1783
1784
static void rpc_api_pipe_req_write_done(struct tevent_req *subreq)
1785
0
{
1786
0
  struct tevent_req *req = tevent_req_callback_data(
1787
0
    subreq, struct tevent_req);
1788
0
  struct rpc_api_pipe_req_state *state = tevent_req_data(
1789
0
    req, struct rpc_api_pipe_req_state);
1790
0
  NTSTATUS status;
1791
0
  bool is_last_frag;
1792
1793
0
  status = rpc_write_recv(subreq);
1794
0
  TALLOC_FREE(subreq);
1795
0
  if (tevent_req_nterror(req, status)) {
1796
0
    return;
1797
0
  }
1798
1799
0
  status = prepare_next_frag(state, &is_last_frag);
1800
0
  if (tevent_req_nterror(req, status)) {
1801
0
    return;
1802
0
  }
1803
1804
0
  if (is_last_frag) {
1805
0
    subreq = rpc_api_pipe_send(state, state->ev, state->cli,
1806
0
             &state->rpc_out,
1807
0
             DCERPC_PKT_RESPONSE,
1808
0
             state->call_id);
1809
0
    if (tevent_req_nomem(subreq, req)) {
1810
0
      return;
1811
0
    }
1812
0
    tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req);
1813
0
  } else {
1814
0
    subreq = rpc_write_send(state, state->ev,
1815
0
          state->cli->conn->transport,
1816
0
          state->rpc_out.data,
1817
0
          state->rpc_out.length);
1818
0
    if (tevent_req_nomem(subreq, req)) {
1819
0
      return;
1820
0
    }
1821
0
    tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done,
1822
0
          req);
1823
0
  }
1824
0
}
1825
1826
static void rpc_api_pipe_req_done(struct tevent_req *subreq)
1827
0
{
1828
0
  struct tevent_req *req = tevent_req_callback_data(
1829
0
    subreq, struct tevent_req);
1830
0
  struct rpc_api_pipe_req_state *state = tevent_req_data(
1831
0
    req, struct rpc_api_pipe_req_state);
1832
0
  NTSTATUS status;
1833
1834
0
  status = rpc_api_pipe_recv(subreq, state, NULL, &state->reply_pdu);
1835
0
  TALLOC_FREE(subreq);
1836
0
  if (tevent_req_nterror(req, status)) {
1837
0
    return;
1838
0
  }
1839
1840
0
  if (state->cli->auth == NULL) {
1841
0
    tevent_req_done(req);
1842
0
    return;
1843
0
  }
1844
1845
0
  if (state->verify_bitmask1) {
1846
0
    state->cli->auth->verified_bitmask1 = true;
1847
0
  }
1848
1849
0
  if (state->verify_pcontext) {
1850
0
    state->cli->verified_pcontext = true;
1851
0
  }
1852
1853
0
  tevent_req_done(req);
1854
0
}
1855
1856
static NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
1857
             DATA_BLOB *reply_pdu)
1858
0
{
1859
0
  struct rpc_api_pipe_req_state *state = tevent_req_data(
1860
0
    req, struct rpc_api_pipe_req_state);
1861
0
  NTSTATUS status;
1862
1863
0
  if (tevent_req_is_nterror(req, &status)) {
1864
    /*
1865
     * We always have to initialize to reply pdu, even if there is
1866
     * none. The rpccli_* caller routines expect this.
1867
     */
1868
0
    *reply_pdu = data_blob_null;
1869
0
    return status;
1870
0
  }
1871
1872
  /* return data to caller and assign it ownership of memory */
1873
0
  reply_pdu->data = talloc_move(mem_ctx, &state->reply_pdu.data);
1874
0
  reply_pdu->length = state->reply_pdu.length;
1875
0
  state->reply_pdu.length = 0;
1876
1877
0
  return NT_STATUS_OK;
1878
0
}
1879
1880
/****************************************************************************
1881
 Check the rpc bind acknowledge response.
1882
****************************************************************************/
1883
1884
static bool check_bind_response(const struct dcerpc_bind_ack *r,
1885
        struct rpc_pipe_client *cli)
1886
0
{
1887
0
  const struct ndr_syntax_id *transfer = &cli->transfer_syntax;
1888
0
  uint32_t assoc_group_id =
1889
0
    dcerpc_binding_get_assoc_group_id(cli->assoc->binding);
1890
0
  struct dcerpc_ack_ctx ctx;
1891
0
  bool equal;
1892
1893
0
  if (r->secondary_address_size == 0) {
1894
0
    DEBUG(4,("Ignoring length check -- ASU bug (server didn't fill in the pipe name correctly)\n"));
1895
0
  }
1896
1897
0
  if (assoc_group_id == 0) {
1898
0
    NTSTATUS status;
1899
1900
    /*
1901
     * We only capture the first assoc_group_id we're
1902
     * getting.
1903
     *
1904
     * Current samba releases may ignore the client value
1905
     * and return a different assoc_group_id if the
1906
     * client given one is not found in the preforked
1907
     * process. This applies to the source4 netlogon,
1908
     * which uses DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED.
1909
     */
1910
1911
0
    status = dcerpc_binding_set_assoc_group_id(cli->assoc->binding,
1912
0
                 r->assoc_group_id);
1913
0
    if (!NT_STATUS_IS_OK(status)) {
1914
0
      return false;
1915
0
    }
1916
0
  }
1917
1918
0
  if (!cli->conn->features.bind_done) {
1919
    /*
1920
     * DCE-RPC 1.1 (c706) specifies
1921
     * CONST_MUST_RCV_FRAG_SIZE as 1432
1922
     */
1923
1924
0
    if (r->max_xmit_frag < 1432) {
1925
0
      return false;
1926
0
    }
1927
0
    if (r->max_recv_frag < 1432) {
1928
0
      return false;
1929
0
    }
1930
1931
0
    cli->conn->features.max_xmit_frag =
1932
0
      MIN(cli->conn->features.max_xmit_frag, r->max_xmit_frag);
1933
0
    cli->conn->features.max_recv_frag =
1934
0
      MIN(cli->conn->features.max_recv_frag, r->max_recv_frag);
1935
1936
0
    cli->conn->features.bind_done = true;
1937
0
  }
1938
1939
0
  if (r->num_results < 1 || !r->ctx_list) {
1940
0
    return false;
1941
0
  }
1942
1943
0
  ctx = r->ctx_list[0];
1944
1945
  /* check the transfer syntax */
1946
0
  equal = ndr_syntax_id_equal(&ctx.syntax, transfer);
1947
0
  if (!equal) {
1948
0
    DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
1949
0
    return False;
1950
0
  }
1951
1952
0
  if (ctx.result != DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1953
0
    DBG_NOTICE("bind denied result: %d reason: %x\n",
1954
0
         ctx.result, ctx.reason.value);
1955
0
    return false;
1956
0
  }
1957
1958
0
  if (r->num_results >= 2) {
1959
0
    const struct dcerpc_ack_ctx *neg = &r->ctx_list[1];
1960
1961
0
    if (neg->result == DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK) {
1962
0
      cli->assoc->features.negotiated = neg->reason.negotiate;
1963
0
      cli->assoc->features.negotiation_done = true;
1964
      /*
1965
       * consume presentation context used for bind time
1966
       * feature negotiation
1967
       */
1968
0
      cli->conn->next_pres_context_id++;
1969
0
    } else {
1970
0
      DBG_DEBUG("bind_time_feature failed - "
1971
0
          "result: %d reason %x\n",
1972
0
          neg->result, neg->reason.value);
1973
0
    }
1974
0
  }
1975
1976
0
  DEBUG(5,("check_bind_response: accepted!\n"));
1977
0
  return True;
1978
0
}
1979
1980
/*******************************************************************
1981
 Creates a DCE/RPC bind authentication response.
1982
 This is the packet that is sent back to the server once we
1983
 have received a BIND-ACK, to finish the third leg of
1984
 the authentication handshake.
1985
 ********************************************************************/
1986
1987
static NTSTATUS create_rpc_bind_auth3(TALLOC_CTX *mem_ctx,
1988
        struct rpc_pipe_client *cli,
1989
        struct pipe_auth_data *auth,
1990
        uint32_t rpc_call_id,
1991
        DATA_BLOB *pauth_blob,
1992
        DATA_BLOB *rpc_out)
1993
0
{
1994
0
  NTSTATUS status;
1995
0
  union dcerpc_payload u = { .auth3._pad = 0, };
1996
1997
0
  status = dcerpc_push_dcerpc_auth(mem_ctx,
1998
0
           auth->auth_type,
1999
0
           auth->auth_level,
2000
0
           0, /* auth_pad_length */
2001
0
           auth->auth_context_id,
2002
0
           pauth_blob,
2003
0
           &u.auth3.auth_info);
2004
0
  if (!NT_STATUS_IS_OK(status)) {
2005
0
    return status;
2006
0
  }
2007
2008
0
  status = dcerpc_push_ncacn_packet(mem_ctx,
2009
0
            DCERPC_PKT_AUTH3,
2010
0
            DCERPC_PFC_FLAG_FIRST |
2011
0
            DCERPC_PFC_FLAG_LAST,
2012
0
            pauth_blob->length,
2013
0
            rpc_call_id,
2014
0
            &u,
2015
0
            rpc_out);
2016
0
  data_blob_free(&u.auth3.auth_info);
2017
0
  if (!NT_STATUS_IS_OK(status)) {
2018
0
    DEBUG(0,("create_bind_or_alt_ctx_internal: failed to marshall RPC_HDR_RB.\n"));
2019
0
    return status;
2020
0
  }
2021
2022
0
  return NT_STATUS_OK;
2023
0
}
2024
2025
/*******************************************************************
2026
 Creates a DCE/RPC bind alter context authentication request which
2027
 may contain a spnego auth blob
2028
 ********************************************************************/
2029
2030
static NTSTATUS create_rpc_alter_context(TALLOC_CTX *mem_ctx,
2031
          struct pipe_auth_data *auth,
2032
          uint32_t rpc_call_id,
2033
          struct rpc_client_association *assoc,
2034
          struct rpc_client_connection *conn,
2035
          uint16_t pres_context_id,
2036
          const struct ndr_syntax_id *abstract,
2037
          const struct ndr_syntax_id *transfer,
2038
          const DATA_BLOB *pauth_blob, /* spnego auth blob already created. */
2039
          DATA_BLOB *rpc_out)
2040
0
{
2041
0
  DATA_BLOB auth_info;
2042
0
  NTSTATUS status;
2043
2044
0
  status = dcerpc_push_dcerpc_auth(mem_ctx,
2045
0
           auth->auth_type,
2046
0
           auth->auth_level,
2047
0
           0, /* auth_pad_length */
2048
0
           auth->auth_context_id,
2049
0
           pauth_blob,
2050
0
           &auth_info);
2051
0
  if (!NT_STATUS_IS_OK(status)) {
2052
0
    return status;
2053
0
  }
2054
2055
0
  status = create_bind_or_alt_ctx_internal(mem_ctx,
2056
0
             DCERPC_PKT_ALTER,
2057
0
             rpc_call_id,
2058
0
             assoc,
2059
0
             conn,
2060
0
             pres_context_id,
2061
0
             abstract,
2062
0
             transfer,
2063
0
             &auth_info,
2064
0
             rpc_out);
2065
0
  data_blob_free(&auth_info);
2066
0
  return status;
2067
0
}
2068
2069
/****************************************************************************
2070
 Do an rpc bind.
2071
****************************************************************************/
2072
2073
struct rpc_pipe_bind_state {
2074
  struct tevent_context *ev;
2075
  struct rpc_pipe_client *cli;
2076
  DATA_BLOB rpc_out;
2077
  bool auth3;
2078
  uint32_t rpc_call_id;
2079
};
2080
2081
static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq);
2082
static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2083
           struct rpc_pipe_bind_state *state,
2084
           DATA_BLOB *credentials);
2085
static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2086
             struct rpc_pipe_bind_state *state,
2087
             DATA_BLOB *credentials);
2088
2089
struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
2090
              struct tevent_context *ev,
2091
              struct rpc_pipe_client *cli,
2092
              struct pipe_auth_data *auth)
2093
0
{
2094
0
  struct tevent_req *req, *subreq;
2095
0
  struct rpc_pipe_bind_state *state;
2096
0
  struct cli_credentials *creds = NULL;
2097
0
  const char *username = NULL;
2098
0
  enum dcerpc_pkt_type rep_ptype = DCERPC_PKT_BIND_ACK;
2099
0
  NTSTATUS status;
2100
2101
0
  if (cli->conn->features.bind_done) {
2102
0
    rep_ptype = DCERPC_PKT_ALTER_RESP;
2103
0
  }
2104
2105
0
  req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state);
2106
0
  if (req == NULL) {
2107
0
    return NULL;
2108
0
  }
2109
2110
0
  DEBUG(5,("Bind RPC Pipe: %s auth_type %u, auth_level %u\n",
2111
0
    rpccli_pipe_txt(talloc_tos(), cli),
2112
0
    (unsigned int)auth->auth_type,
2113
0
    (unsigned int)auth->auth_level ));
2114
2115
0
  state->ev = ev;
2116
0
  state->cli = cli;
2117
0
  state->rpc_call_id = ++cli->assoc->next_call_id;
2118
2119
0
  cli->auth = talloc_move(cli, &auth);
2120
0
  if (cli->auth->auth_context_id == UINT32_MAX) {
2121
0
    if (cli->conn->next_auth_context_id == UINT32_MAX) {
2122
0
      tevent_req_nterror(req, NT_STATUS_RPC_NO_MORE_BINDINGS);
2123
0
      return tevent_req_post(req, ev);
2124
0
    }
2125
0
    cli->auth->auth_context_id = cli->conn->next_auth_context_id++;
2126
0
  }
2127
0
  if (cli->pres_context_id == UINT16_MAX) {
2128
0
    if (cli->conn->next_pres_context_id == UINT16_MAX) {
2129
0
      tevent_req_nterror(req, NT_STATUS_RPC_NO_MORE_BINDINGS);
2130
0
      return tevent_req_post(req, ev);
2131
0
    }
2132
0
    cli->pres_context_id = cli->conn->next_pres_context_id++;
2133
0
  }
2134
2135
0
  cli->binding_handle = rpccli_bh_create(cli, NULL, cli->table);
2136
0
  if (tevent_req_nomem(cli->binding_handle, req)) {
2137
0
    return tevent_req_post(req, ev);
2138
0
  }
2139
2140
0
  creds = gensec_get_credentials(cli->auth->auth_ctx);
2141
0
  username = cli_credentials_get_username(creds);
2142
0
  cli->printer_username = talloc_strdup(cli, username);
2143
0
  if (tevent_req_nomem(cli->printer_username, req)) {
2144
0
    return tevent_req_post(req, ev);
2145
0
  }
2146
2147
  /* Marshall the outgoing data. */
2148
0
  status = create_rpc_bind_req(state, cli,
2149
0
             cli->auth,
2150
0
             state->rpc_call_id,
2151
0
             &cli->table->syntax_id,
2152
0
             &cli->transfer_syntax,
2153
0
             &state->rpc_out);
2154
2155
0
  if (!NT_STATUS_IS_OK(status) &&
2156
0
      !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2157
0
    tevent_req_nterror(req, status);
2158
0
    return tevent_req_post(req, ev);
2159
0
  }
2160
2161
0
  subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out,
2162
0
           rep_ptype, state->rpc_call_id);
2163
0
  if (tevent_req_nomem(subreq, req)) {
2164
0
    return tevent_req_post(req, ev);
2165
0
  }
2166
0
  tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2167
0
  return req;
2168
0
}
2169
2170
static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq)
2171
0
{
2172
0
  struct tevent_req *req = tevent_req_callback_data(
2173
0
    subreq, struct tevent_req);
2174
0
  struct rpc_pipe_bind_state *state = tevent_req_data(
2175
0
    req, struct rpc_pipe_bind_state);
2176
0
  struct pipe_auth_data *pauth = state->cli->auth;
2177
0
  struct gensec_security *gensec_security;
2178
0
  struct ncacn_packet *pkt = NULL;
2179
0
  struct dcerpc_auth auth;
2180
0
  DATA_BLOB auth_token = { .data = NULL };
2181
0
  NTSTATUS status;
2182
2183
0
  status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL);
2184
0
  TALLOC_FREE(subreq);
2185
0
  if (tevent_req_nterror(req, status)) {
2186
0
    DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n",
2187
0
        rpccli_pipe_txt(talloc_tos(), state->cli),
2188
0
        nt_errstr(status)));
2189
0
    return;
2190
0
  }
2191
2192
0
  if (state->auth3) {
2193
0
    tevent_req_done(req);
2194
0
    return;
2195
0
  }
2196
2197
0
  if (!check_bind_response(&pkt->u.bind_ack, state->cli)) {
2198
0
    DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n"));
2199
0
    tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL);
2200
0
    return;
2201
0
  }
2202
2203
0
  if (state->cli->conn->features.client_hdr_signing &&
2204
0
      pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)
2205
0
  {
2206
0
    state->cli->conn->features.hdr_signing = true;
2207
0
  }
2208
2209
0
  if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
2210
    /* Bind complete. */
2211
0
    tevent_req_done(req);
2212
0
    return;
2213
0
  }
2214
2215
0
  if (pkt->auth_length == 0) {
2216
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
2217
0
    return;
2218
0
  }
2219
2220
0
  pauth->hdr_signing = state->cli->conn->features.hdr_signing;
2221
2222
  /* get auth credentials */
2223
0
  status = dcerpc_pull_auth_trailer(pkt, talloc_tos(),
2224
0
            &pkt->u.bind_ack.auth_info,
2225
0
            &auth, NULL, true);
2226
0
  if (tevent_req_nterror(req, status)) {
2227
0
    DEBUG(0, ("Failed to pull dcerpc auth: %s.\n",
2228
0
        nt_errstr(status)));
2229
0
    return;
2230
0
  }
2231
2232
0
  if (auth.auth_type != pauth->auth_type) {
2233
0
    DBG_ERR("Auth type %u mismatch expected %u.\n",
2234
0
      auth.auth_type, pauth->auth_type);
2235
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
2236
0
    return;
2237
0
  }
2238
2239
0
  if (auth.auth_level != pauth->auth_level) {
2240
0
    DBG_ERR("Auth level %u mismatch expected %u.\n",
2241
0
      auth.auth_level, pauth->auth_level);
2242
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
2243
0
    return;
2244
0
  }
2245
2246
0
  if (auth.auth_context_id != pauth->auth_context_id) {
2247
0
    DBG_ERR("Auth context id %"PRIu32" mismatch "
2248
0
      "expected %"PRIu32".\n",
2249
0
      auth.auth_context_id,
2250
0
      pauth->auth_context_id);
2251
0
    tevent_req_nterror(req, NT_STATUS_RPC_PROTOCOL_ERROR);
2252
0
    return;
2253
0
  }
2254
2255
  /*
2256
   * For authenticated binds we may need to do 3 or 4 leg binds.
2257
   */
2258
2259
0
  if (pauth->auth_type == DCERPC_AUTH_TYPE_NONE) {
2260
    /* Bind complete. */
2261
0
    tevent_req_done(req);
2262
0
    return;
2263
0
  }
2264
2265
0
  gensec_security = pauth->auth_ctx;
2266
2267
0
  status = gensec_update(gensec_security, state,
2268
0
             auth.credentials, &auth_token);
2269
0
  if (NT_STATUS_EQUAL(status,
2270
0
          NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2271
0
    status = rpc_bind_next_send(req, state,
2272
0
              &auth_token);
2273
0
  } else if (NT_STATUS_IS_OK(status)) {
2274
0
    if (pauth->hdr_signing) {
2275
0
      gensec_want_feature(gensec_security,
2276
0
              GENSEC_FEATURE_SIGN_PKT_HEADER);
2277
0
    }
2278
2279
0
    if (auth_token.length == 0) {
2280
      /* Bind complete. */
2281
0
      tevent_req_done(req);
2282
0
      return;
2283
0
    }
2284
0
    status = rpc_bind_finish_send(req, state,
2285
0
                &auth_token);
2286
0
  }
2287
2288
0
  if (!NT_STATUS_IS_OK(status)) {
2289
0
    tevent_req_nterror(req, status);
2290
0
  }
2291
0
  return;
2292
0
}
2293
2294
static NTSTATUS rpc_bind_next_send(struct tevent_req *req,
2295
           struct rpc_pipe_bind_state *state,
2296
           DATA_BLOB *auth_token)
2297
0
{
2298
0
  struct pipe_auth_data *auth = state->cli->auth;
2299
0
  struct tevent_req *subreq;
2300
0
  NTSTATUS status;
2301
2302
  /* Now prepare the alter context pdu. */
2303
0
  data_blob_free(&state->rpc_out);
2304
2305
0
  status = create_rpc_alter_context(state, auth,
2306
0
            state->rpc_call_id,
2307
0
            state->cli->assoc,
2308
0
            state->cli->conn,
2309
0
            state->cli->pres_context_id,
2310
0
            &state->cli->table->syntax_id,
2311
0
            &state->cli->transfer_syntax,
2312
0
            auth_token,
2313
0
            &state->rpc_out);
2314
0
  if (!NT_STATUS_IS_OK(status)) {
2315
0
    return status;
2316
0
  }
2317
2318
0
  subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2319
0
           &state->rpc_out, DCERPC_PKT_ALTER_RESP,
2320
0
           state->rpc_call_id);
2321
0
  if (subreq == NULL) {
2322
0
    return NT_STATUS_NO_MEMORY;
2323
0
  }
2324
0
  tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2325
0
  return NT_STATUS_OK;
2326
0
}
2327
2328
static NTSTATUS rpc_bind_finish_send(struct tevent_req *req,
2329
             struct rpc_pipe_bind_state *state,
2330
             DATA_BLOB *auth_token)
2331
0
{
2332
0
  struct pipe_auth_data *auth = state->cli->auth;
2333
0
  struct tevent_req *subreq;
2334
0
  NTSTATUS status;
2335
2336
0
  state->auth3 = true;
2337
2338
  /* Now prepare the auth3 context pdu. */
2339
0
  data_blob_free(&state->rpc_out);
2340
2341
0
  status = create_rpc_bind_auth3(state, state->cli, auth,
2342
0
          state->rpc_call_id,
2343
0
          auth_token,
2344
0
          &state->rpc_out);
2345
0
  if (!NT_STATUS_IS_OK(status)) {
2346
0
    return status;
2347
0
  }
2348
2349
0
  subreq = rpc_api_pipe_send(state, state->ev, state->cli,
2350
0
           &state->rpc_out, DCERPC_PKT_AUTH3,
2351
0
           state->rpc_call_id);
2352
0
  if (subreq == NULL) {
2353
0
    return NT_STATUS_NO_MEMORY;
2354
0
  }
2355
0
  tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req);
2356
0
  return NT_STATUS_OK;
2357
0
}
2358
2359
NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req)
2360
0
{
2361
0
  return tevent_req_simple_recv_ntstatus(req);
2362
0
}
2363
2364
NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
2365
           struct pipe_auth_data *auth)
2366
0
{
2367
0
  TALLOC_CTX *frame = talloc_stackframe();
2368
0
  struct tevent_context *ev;
2369
0
  struct tevent_req *req;
2370
0
  NTSTATUS status = NT_STATUS_OK;
2371
2372
0
  ev = samba_tevent_context_init(frame);
2373
0
  if (ev == NULL) {
2374
0
    status = NT_STATUS_NO_MEMORY;
2375
0
    goto fail;
2376
0
  }
2377
2378
0
  req = rpc_pipe_bind_send(frame, ev, cli, auth);
2379
0
  if (req == NULL) {
2380
0
    status = NT_STATUS_NO_MEMORY;
2381
0
    goto fail;
2382
0
  }
2383
2384
0
  if (!tevent_req_poll_ntstatus(req, ev, &status)) {
2385
0
    goto fail;
2386
0
  }
2387
2388
0
  status = rpc_pipe_bind_recv(req);
2389
0
 fail:
2390
0
  TALLOC_FREE(frame);
2391
0
  return status;
2392
0
}
2393
2394
0
#define RPCCLI_DEFAULT_TIMEOUT 10000 /* 10 seconds. */
2395
2396
unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
2397
        unsigned int timeout)
2398
0
{
2399
0
  if (rpc_cli == NULL) {
2400
0
    return RPCCLI_DEFAULT_TIMEOUT;
2401
0
  }
2402
2403
0
  if (rpc_cli->binding_handle == NULL) {
2404
0
    return RPCCLI_DEFAULT_TIMEOUT;
2405
0
  }
2406
2407
0
  return dcerpc_binding_handle_set_timeout(rpc_cli->binding_handle,
2408
0
             timeout);
2409
0
}
2410
2411
bool rpccli_is_connected(struct rpc_pipe_client *rpc_cli)
2412
0
{
2413
0
  if (rpc_cli == NULL) {
2414
0
    return false;
2415
0
  }
2416
2417
0
  if (rpc_cli->binding_handle == NULL) {
2418
0
    return false;
2419
0
  }
2420
2421
0
  return dcerpc_binding_handle_is_connected(rpc_cli->binding_handle);
2422
0
}
2423
2424
struct rpccli_bh_state {
2425
  struct rpc_pipe_client *rpc_cli;
2426
  struct dcerpc_binding *binding;
2427
};
2428
2429
static const struct dcerpc_binding *rpccli_bh_get_binding(struct dcerpc_binding_handle *h)
2430
0
{
2431
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2432
0
             struct rpccli_bh_state);
2433
2434
0
  return hs->binding;
2435
0
}
2436
2437
static bool rpccli_bh_is_connected(struct dcerpc_binding_handle *h)
2438
0
{
2439
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2440
0
             struct rpccli_bh_state);
2441
0
  struct rpc_cli_transport *transport = NULL;
2442
2443
0
  if (hs->rpc_cli == NULL) {
2444
0
    return false;
2445
0
  }
2446
2447
0
  if (hs->rpc_cli->conn == NULL) {
2448
0
    return false;
2449
0
  }
2450
2451
0
  transport = hs->rpc_cli->conn->transport;
2452
0
  if (transport == NULL) {
2453
0
    return false;
2454
0
  }
2455
2456
0
  if (transport->is_connected == NULL) {
2457
0
    return false;
2458
0
  }
2459
2460
0
  return transport->is_connected(transport->priv);
2461
0
}
2462
2463
static uint32_t rpccli_bh_set_timeout(struct dcerpc_binding_handle *h,
2464
              uint32_t timeout)
2465
0
{
2466
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2467
0
             struct rpccli_bh_state);
2468
0
  struct rpc_cli_transport *transport = NULL;
2469
0
  unsigned int old;
2470
2471
0
  if (hs->rpc_cli->conn == NULL) {
2472
0
    return RPCCLI_DEFAULT_TIMEOUT;
2473
0
  }
2474
2475
0
  transport = hs->rpc_cli->conn->transport;
2476
0
  if (transport == NULL) {
2477
0
    return RPCCLI_DEFAULT_TIMEOUT;
2478
0
  }
2479
2480
0
  if (transport->set_timeout == NULL) {
2481
0
    return RPCCLI_DEFAULT_TIMEOUT;
2482
0
  }
2483
2484
0
  old = transport->set_timeout(transport->priv, timeout);
2485
0
  if (old == 0) {
2486
0
    return RPCCLI_DEFAULT_TIMEOUT;
2487
0
  }
2488
2489
0
  return old;
2490
0
}
2491
2492
static NTSTATUS rpccli_bh_transport_session_key(struct dcerpc_binding_handle *h,
2493
            TALLOC_CTX *mem_ctx,
2494
            DATA_BLOB *session_key)
2495
0
{
2496
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2497
0
             struct rpccli_bh_state);
2498
0
  DATA_BLOB sk = { .length = 0, };
2499
2500
0
  if (hs->rpc_cli == NULL) {
2501
0
    return NT_STATUS_NO_USER_SESSION_KEY;
2502
0
  }
2503
2504
0
  if (hs->rpc_cli->conn == NULL) {
2505
0
    return NT_STATUS_NO_USER_SESSION_KEY;
2506
0
  }
2507
2508
0
  if (hs->rpc_cli->conn->transport_session_key.length == 0) {
2509
0
    return NT_STATUS_NO_USER_SESSION_KEY;
2510
0
  }
2511
2512
0
  sk = hs->rpc_cli->conn->transport_session_key;
2513
0
  sk.length = MIN(sk.length, 16);
2514
2515
0
  *session_key = data_blob_dup_talloc_s(mem_ctx, sk);
2516
0
  if (session_key->length != sk.length) {
2517
0
    return NT_STATUS_NO_MEMORY;
2518
0
  }
2519
0
  return NT_STATUS_OK;
2520
0
}
2521
2522
static void rpccli_bh_auth_info(struct dcerpc_binding_handle *h,
2523
        enum dcerpc_AuthType *auth_type,
2524
        enum dcerpc_AuthLevel *auth_level)
2525
0
{
2526
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2527
0
             struct rpccli_bh_state);
2528
2529
0
  if (hs->rpc_cli == NULL) {
2530
0
    return;
2531
0
  }
2532
2533
0
  if (hs->rpc_cli->auth == NULL) {
2534
0
    return;
2535
0
  }
2536
2537
0
  *auth_type = hs->rpc_cli->auth->auth_type;
2538
0
  *auth_level = hs->rpc_cli->auth->auth_level;
2539
0
}
2540
2541
static NTSTATUS rpccli_bh_auth_session_key(struct dcerpc_binding_handle *h,
2542
             TALLOC_CTX *mem_ctx,
2543
             DATA_BLOB *session_key)
2544
0
{
2545
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2546
0
             struct rpccli_bh_state);
2547
0
  struct pipe_auth_data *auth = NULL;
2548
0
  NTSTATUS status;
2549
2550
0
  if (hs->rpc_cli == NULL) {
2551
0
    return NT_STATUS_NO_USER_SESSION_KEY;
2552
0
  }
2553
2554
0
  if (hs->rpc_cli->auth == NULL) {
2555
0
    return NT_STATUS_NO_USER_SESSION_KEY;
2556
0
  }
2557
2558
0
  auth = hs->rpc_cli->auth;
2559
2560
0
  if (auth->auth_type == DCERPC_AUTH_TYPE_NONE) {
2561
0
    return NT_STATUS_NO_USER_SESSION_KEY;
2562
0
  }
2563
2564
0
  if (auth->auth_ctx == NULL) {
2565
0
    return NT_STATUS_NO_USER_SESSION_KEY;
2566
0
  }
2567
2568
0
  status = gensec_session_key(auth->auth_ctx,
2569
0
            mem_ctx,
2570
0
            session_key);
2571
0
  if (!NT_STATUS_IS_OK(status)) {
2572
0
    return status;
2573
0
  }
2574
2575
0
  talloc_keep_secret(session_key->data);
2576
0
  return NT_STATUS_OK;
2577
0
}
2578
2579
struct rpccli_bh_raw_call_state {
2580
  DATA_BLOB in_data;
2581
  DATA_BLOB out_data;
2582
  uint32_t out_flags;
2583
};
2584
2585
static void rpccli_bh_raw_call_done(struct tevent_req *subreq);
2586
2587
static struct tevent_req *rpccli_bh_raw_call_send(TALLOC_CTX *mem_ctx,
2588
              struct tevent_context *ev,
2589
              struct dcerpc_binding_handle *h,
2590
              const struct GUID *object,
2591
              uint32_t opnum,
2592
              uint32_t in_flags,
2593
              const uint8_t *in_data,
2594
              size_t in_length)
2595
0
{
2596
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2597
0
             struct rpccli_bh_state);
2598
0
  struct tevent_req *req;
2599
0
  struct rpccli_bh_raw_call_state *state;
2600
0
  bool ok;
2601
0
  struct tevent_req *subreq;
2602
2603
0
  req = tevent_req_create(mem_ctx, &state,
2604
0
        struct rpccli_bh_raw_call_state);
2605
0
  if (req == NULL) {
2606
0
    return NULL;
2607
0
  }
2608
0
  state->in_data.data = discard_const_p(uint8_t, in_data);
2609
0
  state->in_data.length = in_length;
2610
2611
0
  ok = rpccli_bh_is_connected(h);
2612
0
  if (!ok) {
2613
0
    tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2614
0
    return tevent_req_post(req, ev);
2615
0
  }
2616
2617
0
  subreq = rpc_api_pipe_req_send(state, ev, hs->rpc_cli,
2618
0
               opnum, object, &state->in_data);
2619
0
  if (tevent_req_nomem(subreq, req)) {
2620
0
    return tevent_req_post(req, ev);
2621
0
  }
2622
0
  tevent_req_set_callback(subreq, rpccli_bh_raw_call_done, req);
2623
2624
0
  return req;
2625
0
}
2626
2627
static void rpccli_bh_raw_call_done(struct tevent_req *subreq)
2628
0
{
2629
0
  struct tevent_req *req =
2630
0
    tevent_req_callback_data(subreq,
2631
0
    struct tevent_req);
2632
0
  struct rpccli_bh_raw_call_state *state =
2633
0
    tevent_req_data(req,
2634
0
    struct rpccli_bh_raw_call_state);
2635
0
  NTSTATUS status;
2636
2637
0
  state->out_flags = 0;
2638
2639
  /* TODO: support bigendian responses */
2640
2641
0
  status = rpc_api_pipe_req_recv(subreq, state, &state->out_data);
2642
0
  TALLOC_FREE(subreq);
2643
0
  if (tevent_req_nterror(req, status)) {
2644
0
    return;
2645
0
  }
2646
2647
0
  tevent_req_done(req);
2648
0
}
2649
2650
static NTSTATUS rpccli_bh_raw_call_recv(struct tevent_req *req,
2651
          TALLOC_CTX *mem_ctx,
2652
          uint8_t **out_data,
2653
          size_t *out_length,
2654
          uint32_t *out_flags)
2655
0
{
2656
0
  struct rpccli_bh_raw_call_state *state =
2657
0
    tevent_req_data(req,
2658
0
    struct rpccli_bh_raw_call_state);
2659
0
  NTSTATUS status;
2660
2661
0
  if (tevent_req_is_nterror(req, &status)) {
2662
0
    tevent_req_received(req);
2663
0
    return status;
2664
0
  }
2665
2666
0
  *out_data = talloc_move(mem_ctx, &state->out_data.data);
2667
0
  *out_length = state->out_data.length;
2668
0
  *out_flags = state->out_flags;
2669
0
  tevent_req_received(req);
2670
0
  return NT_STATUS_OK;
2671
0
}
2672
2673
struct rpccli_bh_disconnect_state {
2674
  uint8_t _dummy;
2675
};
2676
2677
static struct tevent_req *rpccli_bh_disconnect_send(TALLOC_CTX *mem_ctx,
2678
            struct tevent_context *ev,
2679
            struct dcerpc_binding_handle *h)
2680
0
{
2681
0
  struct rpccli_bh_state *hs = dcerpc_binding_handle_data(h,
2682
0
             struct rpccli_bh_state);
2683
0
  struct tevent_req *req;
2684
0
  struct rpccli_bh_disconnect_state *state;
2685
0
  bool ok;
2686
2687
0
  req = tevent_req_create(mem_ctx, &state,
2688
0
        struct rpccli_bh_disconnect_state);
2689
0
  if (req == NULL) {
2690
0
    return NULL;
2691
0
  }
2692
2693
0
  ok = rpccli_bh_is_connected(h);
2694
0
  if (!ok) {
2695
0
    tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED);
2696
0
    return tevent_req_post(req, ev);
2697
0
  }
2698
2699
  /*
2700
   * TODO: do a real async disconnect ...
2701
   *
2702
   * For now we do it sync...
2703
   */
2704
0
  TALLOC_FREE(hs->rpc_cli->conn);
2705
0
  hs->rpc_cli = NULL;
2706
2707
0
  tevent_req_done(req);
2708
0
  return tevent_req_post(req, ev);
2709
0
}
2710
2711
static NTSTATUS rpccli_bh_disconnect_recv(struct tevent_req *req)
2712
0
{
2713
0
  return tevent_req_simple_recv_ntstatus(req);
2714
0
}
2715
2716
static bool rpccli_bh_ref_alloc(struct dcerpc_binding_handle *h)
2717
0
{
2718
0
  return true;
2719
0
}
2720
2721
static void rpccli_bh_do_ndr_print(struct dcerpc_binding_handle *h,
2722
           ndr_flags_type ndr_flags,
2723
           const void *_struct_ptr,
2724
           const struct ndr_interface_call *call)
2725
0
{
2726
0
  void *struct_ptr = discard_const(_struct_ptr);
2727
2728
0
  if (!CHECK_DEBUGLVLC(DBGC_RPC_PARSE, 10)) {
2729
0
    return;
2730
0
  }
2731
2732
0
  if (ndr_flags & NDR_IN) {
2733
0
    ndr_print_function_debug(call->ndr_print,
2734
0
           call->name,
2735
0
           ndr_flags,
2736
0
           struct_ptr);
2737
0
  }
2738
0
  if (ndr_flags & NDR_OUT) {
2739
0
    ndr_print_function_debug(call->ndr_print,
2740
0
           call->name,
2741
0
           ndr_flags,
2742
0
           struct_ptr);
2743
0
  }
2744
0
}
2745
2746
static const struct dcerpc_binding_handle_ops rpccli_bh_ops = {
2747
  .name     = "rpccli",
2748
  .get_binding    = rpccli_bh_get_binding,
2749
  .is_connected   = rpccli_bh_is_connected,
2750
  .set_timeout    = rpccli_bh_set_timeout,
2751
  .transport_session_key  = rpccli_bh_transport_session_key,
2752
  .auth_info    = rpccli_bh_auth_info,
2753
  .auth_session_key = rpccli_bh_auth_session_key,
2754
  .raw_call_send    = rpccli_bh_raw_call_send,
2755
  .raw_call_recv    = rpccli_bh_raw_call_recv,
2756
  .disconnect_send  = rpccli_bh_disconnect_send,
2757
  .disconnect_recv  = rpccli_bh_disconnect_recv,
2758
2759
  .ref_alloc    = rpccli_bh_ref_alloc,
2760
  .do_ndr_print   = rpccli_bh_do_ndr_print,
2761
};
2762
2763
/* initialise a rpc_pipe_client binding handle */
2764
struct dcerpc_binding_handle *rpccli_bh_create(struct rpc_pipe_client *c,
2765
          const struct GUID *object,
2766
          const struct ndr_interface_table *table)
2767
0
{
2768
0
  struct dcerpc_binding_handle *h = NULL;
2769
0
  struct rpccli_bh_state *hs = NULL;
2770
0
  struct dcerpc_binding *b = NULL;
2771
0
  char localaddr[INET6_ADDRSTRLEN] = { 0, };
2772
0
  uint32_t a_flags = 0;
2773
0
  uint32_t c_flags = 0;
2774
0
  NTSTATUS status;
2775
2776
0
  if (c->conn->features.hdr_signing) {
2777
0
    a_flags |= DCERPC_HEADER_SIGNING;
2778
0
  } else {
2779
0
    c_flags |= DCERPC_HEADER_SIGNING;
2780
0
  }
2781
2782
0
  switch (c->auth->auth_type) {
2783
0
  case DCERPC_AUTH_TYPE_KRB5:
2784
0
    a_flags |= DCERPC_AUTH_KRB5;
2785
0
    c_flags |= DCERPC_AUTH_NTLM;
2786
0
    c_flags |= DCERPC_AUTH_SPNEGO;
2787
0
    c_flags |= DCERPC_SCHANNEL;
2788
0
    break;
2789
0
  case DCERPC_AUTH_TYPE_NTLMSSP:
2790
0
    c_flags |= DCERPC_AUTH_KRB5;
2791
0
    a_flags |= DCERPC_AUTH_NTLM;
2792
0
    c_flags |= DCERPC_AUTH_SPNEGO;
2793
0
    c_flags |= DCERPC_SCHANNEL;
2794
0
    break;
2795
0
  case DCERPC_AUTH_TYPE_SPNEGO:
2796
0
    c_flags |= DCERPC_AUTH_KRB5;
2797
0
    c_flags |= DCERPC_AUTH_NTLM;
2798
0
    a_flags |= DCERPC_AUTH_SPNEGO;
2799
0
    c_flags |= DCERPC_SCHANNEL;
2800
0
    break;
2801
0
  case DCERPC_AUTH_TYPE_SCHANNEL:
2802
0
    c_flags |= DCERPC_AUTH_KRB5;
2803
0
    c_flags |= DCERPC_AUTH_NTLM;
2804
0
    c_flags |= DCERPC_AUTH_SPNEGO;
2805
0
    a_flags |= DCERPC_SCHANNEL;
2806
0
    break;
2807
0
  default:
2808
0
    c_flags |= DCERPC_AUTH_KRB5;
2809
0
    c_flags |= DCERPC_AUTH_NTLM;
2810
0
    c_flags |= DCERPC_AUTH_SPNEGO;
2811
0
    c_flags |= DCERPC_SCHANNEL;
2812
0
    break;
2813
0
  }
2814
2815
0
  if (c->auth->auth_level >= DCERPC_AUTH_LEVEL_PRIVACY) {
2816
0
    a_flags |= DCERPC_SEAL;
2817
0
    c_flags |= DCERPC_SIGN;
2818
0
    c_flags |= DCERPC_CONNECT;
2819
0
  } else if (c->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
2820
0
    c_flags |= DCERPC_SEAL;
2821
0
    a_flags |= DCERPC_SIGN;
2822
0
    c_flags |= DCERPC_CONNECT;
2823
0
  } else if (c->auth->auth_level >= DCERPC_AUTH_LEVEL_CONNECT) {
2824
0
    c_flags |= DCERPC_SEAL;
2825
0
    c_flags |= DCERPC_SIGN;
2826
0
    a_flags |= DCERPC_CONNECT;
2827
0
  } else {
2828
0
    c_flags |= DCERPC_SEAL;
2829
0
    c_flags |= DCERPC_SIGN;
2830
0
    c_flags |= DCERPC_CONNECT;
2831
0
  }
2832
2833
0
  h = dcerpc_binding_handle_create(c,
2834
0
           &rpccli_bh_ops,
2835
0
           object,
2836
0
           table,
2837
0
           &hs,
2838
0
           struct rpccli_bh_state,
2839
0
           __location__);
2840
0
  if (h == NULL) {
2841
0
    return NULL;
2842
0
  }
2843
0
  hs->rpc_cli = c;
2844
2845
0
  b = dcerpc_binding_dup(h, c->assoc->binding);
2846
0
  if (b == NULL) {
2847
0
    TALLOC_FREE(h);
2848
0
    return NULL;
2849
0
  }
2850
0
  status = dcerpc_binding_set_abstract_syntax(b, &table->syntax_id);
2851
0
  if (!NT_STATUS_IS_OK(status)) {
2852
0
    TALLOC_FREE(h);
2853
0
    return NULL;
2854
0
  }
2855
0
  status = dcerpc_binding_set_flags(b, a_flags, c_flags);
2856
0
  if (!NT_STATUS_IS_OK(status)) {
2857
0
    TALLOC_FREE(h);
2858
0
    return NULL;
2859
0
  }
2860
2861
0
  switch (c->conn->localaddr.u.sa.sa_family) {
2862
0
  case AF_INET:
2863
0
  case AF_INET6:
2864
0
    print_sockaddr(localaddr,
2865
0
             sizeof(localaddr),
2866
0
             &c->conn->localaddr.u.ss);
2867
0
    status = dcerpc_binding_set_string_option(b,
2868
0
                "localaddress",
2869
0
                localaddr);
2870
0
    if (!NT_STATUS_IS_OK(status)) {
2871
0
      TALLOC_FREE(h);
2872
0
      return NULL;
2873
0
    }
2874
0
    break;
2875
0
  }
2876
2877
0
  hs->binding = b;
2878
2879
0
  return h;
2880
0
}
2881
2882
NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx,
2883
             struct pipe_auth_data **presult)
2884
0
{
2885
0
  struct pipe_auth_data *result;
2886
0
  struct auth_generic_state *auth_generic_ctx;
2887
0
  NTSTATUS status;
2888
2889
0
  result = talloc_zero(mem_ctx, struct pipe_auth_data);
2890
0
  if (result == NULL) {
2891
0
    return NT_STATUS_NO_MEMORY;
2892
0
  }
2893
2894
0
  result->auth_type = DCERPC_AUTH_TYPE_NONE;
2895
0
  result->auth_level = DCERPC_AUTH_LEVEL_NONE;
2896
  /* rpc_pipe_bind_send should allocate an id... */
2897
0
  result->auth_context_id = UINT32_MAX;
2898
2899
0
  status = auth_generic_client_prepare(result,
2900
0
               &auth_generic_ctx);
2901
0
  if (!NT_STATUS_IS_OK(status)) {
2902
0
    DEBUG(1, ("Failed to create auth_generic context: %s\n",
2903
0
        nt_errstr(status)));
2904
0
  }
2905
2906
0
  status = auth_generic_set_username(auth_generic_ctx, "");
2907
0
  if (!NT_STATUS_IS_OK(status)) {
2908
0
    DEBUG(1, ("Failed to set username: %s\n",
2909
0
        nt_errstr(status)));
2910
0
  }
2911
2912
0
  status = auth_generic_set_domain(auth_generic_ctx, "");
2913
0
  if (!NT_STATUS_IS_OK(status)) {
2914
0
    DEBUG(1, ("Failed to set domain: %s\n",
2915
0
        nt_errstr(status)));
2916
0
    return status;
2917
0
  }
2918
2919
0
  status = gensec_set_credentials(auth_generic_ctx->gensec_security,
2920
0
          auth_generic_ctx->credentials);
2921
0
  if (!NT_STATUS_IS_OK(status)) {
2922
0
    DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
2923
0
        nt_errstr(status)));
2924
0
    return status;
2925
0
  }
2926
0
  talloc_unlink(auth_generic_ctx, auth_generic_ctx->credentials);
2927
0
  auth_generic_ctx->credentials = NULL;
2928
2929
0
  result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
2930
0
  talloc_free(auth_generic_ctx);
2931
0
  *presult = result;
2932
0
  return NT_STATUS_OK;
2933
0
}
2934
2935
static NTSTATUS rpccli_generic_bind_data(TALLOC_CTX *mem_ctx,
2936
           enum dcerpc_AuthType auth_type,
2937
           enum dcerpc_AuthLevel auth_level,
2938
           const char *server,
2939
           const char *target_service,
2940
           const char *domain,
2941
           const char *username,
2942
           const char *password,
2943
           enum credentials_use_kerberos use_kerberos,
2944
           struct netlogon_creds_CredentialState *creds,
2945
           struct pipe_auth_data **presult)
2946
0
{
2947
0
  struct auth_generic_state *auth_generic_ctx;
2948
0
  struct pipe_auth_data *result;
2949
0
  NTSTATUS status;
2950
2951
0
  result = talloc_zero(mem_ctx, struct pipe_auth_data);
2952
0
  if (result == NULL) {
2953
0
    return NT_STATUS_NO_MEMORY;
2954
0
  }
2955
2956
0
  result->auth_type = auth_type;
2957
0
  result->auth_level = auth_level;
2958
  /* rpc_pipe_bind_send should allocate an id... */
2959
0
  result->auth_context_id = UINT32_MAX;
2960
2961
0
  status = auth_generic_client_prepare(result,
2962
0
               &auth_generic_ctx);
2963
0
  if (!NT_STATUS_IS_OK(status)) {
2964
0
    goto fail;
2965
0
  }
2966
2967
0
  status = auth_generic_set_username(auth_generic_ctx, username);
2968
0
  if (!NT_STATUS_IS_OK(status)) {
2969
0
    goto fail;
2970
0
  }
2971
2972
0
  status = auth_generic_set_domain(auth_generic_ctx, domain);
2973
0
  if (!NT_STATUS_IS_OK(status)) {
2974
0
    goto fail;
2975
0
  }
2976
2977
0
  status = auth_generic_set_password(auth_generic_ctx, password);
2978
0
  if (!NT_STATUS_IS_OK(status)) {
2979
0
    goto fail;
2980
0
  }
2981
2982
0
  status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
2983
0
  if (!NT_STATUS_IS_OK(status)) {
2984
0
    goto fail;
2985
0
  }
2986
2987
0
  status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
2988
0
  if (!NT_STATUS_IS_OK(status)) {
2989
0
    goto fail;
2990
0
  }
2991
2992
0
  cli_credentials_set_kerberos_state(auth_generic_ctx->credentials,
2993
0
             use_kerberos,
2994
0
             CRED_SPECIFIED);
2995
0
  cli_credentials_set_netlogon_creds(auth_generic_ctx->credentials, creds);
2996
2997
0
  status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
2998
0
  if (!NT_STATUS_IS_OK(status)) {
2999
0
    goto fail;
3000
0
  }
3001
3002
0
  result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
3003
0
  talloc_free(auth_generic_ctx);
3004
0
  *presult = result;
3005
0
  return NT_STATUS_OK;
3006
3007
0
 fail:
3008
0
  TALLOC_FREE(result);
3009
0
  return status;
3010
0
}
3011
3012
/* This routine steals the creds pointer that is passed in */
3013
static NTSTATUS rpccli_generic_bind_data_from_creds(TALLOC_CTX *mem_ctx,
3014
                enum dcerpc_AuthType auth_type,
3015
                enum dcerpc_AuthLevel auth_level,
3016
                const char *server,
3017
                const char *target_service,
3018
                struct cli_credentials *creds,
3019
                struct pipe_auth_data **presult)
3020
0
{
3021
0
  struct auth_generic_state *auth_generic_ctx;
3022
0
  struct pipe_auth_data *result;
3023
0
  NTSTATUS status;
3024
3025
0
  result = talloc_zero(mem_ctx, struct pipe_auth_data);
3026
0
  if (result == NULL) {
3027
0
    return NT_STATUS_NO_MEMORY;
3028
0
  }
3029
3030
0
  result->auth_type = auth_type;
3031
0
  result->auth_level = auth_level;
3032
  /* rpc_pipe_bind_send should allocate an id... */
3033
0
  result->auth_context_id = UINT32_MAX;
3034
3035
0
  status = auth_generic_client_prepare(result,
3036
0
               &auth_generic_ctx);
3037
0
  if (!NT_STATUS_IS_OK(status)) {
3038
0
    goto fail;
3039
0
  }
3040
3041
0
  status = auth_generic_set_creds(auth_generic_ctx, creds);
3042
0
  if (!NT_STATUS_IS_OK(status)) {
3043
0
    goto fail;
3044
0
  }
3045
3046
0
  status = gensec_set_target_service(auth_generic_ctx->gensec_security, target_service);
3047
0
  if (!NT_STATUS_IS_OK(status)) {
3048
0
    goto fail;
3049
0
  }
3050
3051
0
  status = gensec_set_target_hostname(auth_generic_ctx->gensec_security, server);
3052
0
  if (!NT_STATUS_IS_OK(status)) {
3053
0
    goto fail;
3054
0
  }
3055
3056
0
  status = auth_generic_client_start_by_authtype(auth_generic_ctx, auth_type, auth_level);
3057
0
  if (!NT_STATUS_IS_OK(status)) {
3058
0
    goto fail;
3059
0
  }
3060
3061
0
  result->auth_ctx = talloc_move(result, &auth_generic_ctx->gensec_security);
3062
0
  talloc_free(auth_generic_ctx);
3063
0
  *presult = result;
3064
0
  return NT_STATUS_OK;
3065
3066
0
 fail:
3067
0
  TALLOC_FREE(result);
3068
0
  return status;
3069
0
}
3070
3071
NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
3072
          struct pipe_auth_data **presult)
3073
0
{
3074
0
  return rpccli_generic_bind_data(mem_ctx,
3075
0
          DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM,
3076
0
          DCERPC_AUTH_LEVEL_CONNECT,
3077
0
          NULL, /* server */
3078
0
          "host", /* target_service */
3079
0
          NAME_NT_AUTHORITY, /* domain */
3080
0
          "SYSTEM",
3081
0
          NULL, /* password */
3082
0
          CRED_USE_KERBEROS_DISABLED,
3083
0
          NULL, /* netlogon_creds_CredentialState */
3084
0
          presult);
3085
0
}
3086
3087
/**
3088
 * Create an rpc pipe client struct, connecting to a tcp port.
3089
 */
3090
static NTSTATUS rpc_pipe_open_tcp_port(TALLOC_CTX *mem_ctx,
3091
               const struct rpc_client_association *assoc,
3092
               struct rpc_client_connection **pconn)
3093
0
{
3094
0
  struct rpc_client_connection *conn = NULL;
3095
0
  enum dcerpc_transport_t transport;
3096
0
  const char *endpoint = NULL;
3097
0
  uint16_t port;
3098
0
  NTSTATUS status;
3099
0
  int fd;
3100
0
  int ret;
3101
3102
0
  transport = dcerpc_binding_get_transport(assoc->binding);
3103
0
  if (transport != NCACN_IP_TCP) {
3104
0
    return NT_STATUS_RPC_WRONG_KIND_OF_BINDING;
3105
0
  }
3106
3107
0
  endpoint = dcerpc_binding_get_string_option(assoc->binding,
3108
0
                "endpoint");
3109
0
  if (endpoint == NULL) {
3110
0
    return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT;
3111
0
  }
3112
0
  port = (uint16_t)atoi(endpoint);
3113
0
  if (port == 0) {
3114
0
    return NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT;
3115
0
  }
3116
3117
0
  status = rpc_client_connection_create(mem_ctx,
3118
0
                assoc,
3119
0
                DCERPC_FRAG_MAX_SIZE,
3120
0
                &conn);
3121
0
  if (!NT_STATUS_IS_OK(status)) {
3122
0
    return status;
3123
0
  }
3124
3125
0
  status = open_socket_out(&assoc->addr.u.ss, port, 60*1000, &fd);
3126
0
  if (!NT_STATUS_IS_OK(status)) {
3127
0
    TALLOC_FREE(conn);
3128
0
    return status;
3129
0
  }
3130
0
  set_socket_options(fd, lp_socket_options());
3131
3132
0
  conn->localaddr.sa_socklen = sizeof(conn->localaddr.u.ss);
3133
0
  ret = getsockname(fd, &conn->localaddr.u.sa, &conn->localaddr.sa_socklen);
3134
0
  if (ret != 0) {
3135
0
    status = map_nt_error_from_unix_common(errno);
3136
0
    close(fd);
3137
0
    TALLOC_FREE(conn);
3138
0
    return status;
3139
0
  }
3140
3141
0
  status = rpc_transport_sock_init(conn, fd, &conn->transport);
3142
0
  if (!NT_STATUS_IS_OK(status)) {
3143
0
    close(fd);
3144
0
    TALLOC_FREE(conn);
3145
0
    return status;
3146
0
  }
3147
3148
0
  conn->transport->transport = NCACN_IP_TCP;
3149
3150
0
  *pconn = conn;
3151
0
  return NT_STATUS_OK;
3152
0
}
3153
3154
static NTSTATUS rpccli_epm_map_binding(
3155
  struct dcerpc_binding_handle *epm_connection,
3156
  struct dcerpc_binding *binding,
3157
  TALLOC_CTX *mem_ctx,
3158
  char **pendpoint)
3159
0
{
3160
0
  TALLOC_CTX *frame = talloc_stackframe();
3161
0
  enum dcerpc_transport_t transport =
3162
0
    dcerpc_binding_get_transport(binding);
3163
0
  enum dcerpc_transport_t res_transport;
3164
0
  struct dcerpc_binding *res_binding = NULL;
3165
0
  struct epm_twr_t *map_tower = NULL;
3166
0
  struct epm_twr_p_t res_towers = { .twr = NULL };
3167
0
  struct policy_handle *entry_handle = NULL;
3168
0
  uint32_t num_towers = 0;
3169
0
  const uint32_t max_towers = 1;
3170
0
  const char *endpoint = NULL;
3171
0
  char *tmp = NULL;
3172
0
  uint32_t result;
3173
0
  NTSTATUS status;
3174
3175
0
  map_tower = talloc_zero(frame, struct epm_twr_t);
3176
0
  if (map_tower == NULL) {
3177
0
    goto nomem;
3178
0
  }
3179
3180
0
  status = dcerpc_binding_build_tower(
3181
0
    frame, binding, &(map_tower->tower));
3182
0
  if (!NT_STATUS_IS_OK(status)) {
3183
0
    DBG_DEBUG("dcerpc_binding_build_tower failed: %s\n",
3184
0
        nt_errstr(status));
3185
0
    goto done;
3186
0
  }
3187
3188
0
  res_towers.twr = talloc_array(frame, struct epm_twr_t, max_towers);
3189
0
  if (res_towers.twr == NULL) {
3190
0
    goto nomem;
3191
0
  }
3192
3193
0
  entry_handle = talloc_zero(frame, struct policy_handle);
3194
0
  if (entry_handle == NULL) {
3195
0
    goto nomem;
3196
0
  }
3197
3198
0
  status = dcerpc_epm_Map(
3199
0
    epm_connection,
3200
0
    frame,
3201
0
    NULL,
3202
0
    map_tower,
3203
0
    entry_handle,
3204
0
    max_towers,
3205
0
    &num_towers,
3206
0
    &res_towers,
3207
0
    &result);
3208
3209
0
  if (!NT_STATUS_IS_OK(status)) {
3210
0
    DBG_DEBUG("dcerpc_epm_Map failed: %s\n", nt_errstr(status));
3211
0
    goto done;
3212
0
  }
3213
3214
0
  if (result != EPMAPPER_STATUS_OK) {
3215
0
    DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32"\n", result);
3216
0
    status = NT_STATUS_NOT_FOUND;
3217
0
    goto done;
3218
0
  }
3219
3220
0
  if (num_towers != 1) {
3221
0
    DBG_DEBUG("dcerpc_epm_Map returned %"PRIu32" towers\n",
3222
0
        num_towers);
3223
0
    status = NT_STATUS_INVALID_NETWORK_RESPONSE;
3224
0
    goto done;
3225
0
  }
3226
3227
0
  status = dcerpc_binding_from_tower(
3228
0
    frame, &(res_towers.twr->tower), &res_binding);
3229
0
  if (!NT_STATUS_IS_OK(status)) {
3230
0
    DBG_DEBUG("dcerpc_binding_from_tower failed: %s\n",
3231
0
        nt_errstr(status));
3232
0
    goto done;
3233
0
  }
3234
3235
0
  res_transport = dcerpc_binding_get_transport(res_binding);
3236
0
  if (res_transport != transport) {
3237
0
    DBG_DEBUG("dcerpc_epm_Map returned transport %d, "
3238
0
        "expected %d\n",
3239
0
        (int)res_transport,
3240
0
        (int)transport);
3241
0
    status = NT_STATUS_INVALID_NETWORK_RESPONSE;
3242
0
    goto done;
3243
0
  }
3244
3245
0
  endpoint = dcerpc_binding_get_string_option(res_binding, "endpoint");
3246
0
  if (endpoint == NULL) {
3247
0
    DBG_DEBUG("dcerpc_epm_Map returned no endpoint\n");
3248
0
    status = NT_STATUS_INVALID_NETWORK_RESPONSE;
3249
0
    goto done;
3250
0
  }
3251
3252
0
  tmp = talloc_strdup(mem_ctx, endpoint);
3253
0
  if (tmp == NULL) {
3254
0
    goto nomem;
3255
0
  }
3256
0
  *pendpoint = tmp;
3257
3258
0
  status = NT_STATUS_OK;
3259
0
  goto done;
3260
3261
0
nomem:
3262
0
  status = NT_STATUS_NO_MEMORY;
3263
0
done:
3264
0
  TALLOC_FREE(frame);
3265
0
  return status;
3266
0
}
3267
3268
static NTSTATUS rpccli_epm_map_interface(
3269
  struct dcerpc_binding_handle *epm_connection,
3270
  enum dcerpc_transport_t transport,
3271
  const struct ndr_syntax_id *iface,
3272
  TALLOC_CTX *mem_ctx,
3273
  char **pendpoint)
3274
0
{
3275
0
  struct dcerpc_binding *binding = NULL;
3276
0
  char *endpoint = NULL;
3277
0
  NTSTATUS status;
3278
3279
0
  status = dcerpc_parse_binding(mem_ctx, "", &binding);
3280
0
  if (!NT_STATUS_IS_OK(status)) {
3281
0
    DBG_DEBUG("dcerpc_parse_binding failed: %s\n",
3282
0
        nt_errstr(status));
3283
0
    goto done;
3284
0
  }
3285
3286
0
  status = dcerpc_binding_set_transport(binding, transport);
3287
0
  if (!NT_STATUS_IS_OK(status)) {
3288
0
    DBG_DEBUG("dcerpc_binding_set_transport failed: %s\n",
3289
0
        nt_errstr(status));
3290
0
    goto done;
3291
0
  }
3292
3293
0
  status = dcerpc_binding_set_abstract_syntax(binding, iface);
3294
0
  if (!NT_STATUS_IS_OK(status)) {
3295
0
    DBG_DEBUG("dcerpc_binding_set_abstract_syntax failed: %s\n",
3296
0
        nt_errstr(status));
3297
0
    goto done;
3298
0
  }
3299
3300
0
  status = rpccli_epm_map_binding(
3301
0
    epm_connection, binding, mem_ctx, &endpoint);
3302
0
  if (!NT_STATUS_IS_OK(status)) {
3303
0
    DBG_DEBUG("rpccli_epm_map_binding failed: %s\n",
3304
0
        nt_errstr(status));
3305
0
    goto done;
3306
0
  }
3307
0
  *pendpoint = endpoint;
3308
3309
0
done:
3310
0
  TALLOC_FREE(binding);
3311
0
  return status;
3312
0
}
3313
3314
/**
3315
 * Determine the tcp port on which a dcerpc interface is listening
3316
 * for the ncacn_ip_tcp transport via the endpoint mapper of the
3317
 * target host.
3318
 */
3319
static NTSTATUS rpc_pipe_get_tcp_port(const char *host,
3320
              const struct samba_sockaddr *saddr,
3321
              const struct ndr_interface_table *table,
3322
              uint16_t *pport)
3323
0
{
3324
0
  TALLOC_CTX *frame = talloc_stackframe();
3325
0
  const char *epm_ep = NULL;
3326
0
  struct rpc_client_association *epm_assoc = NULL;
3327
0
  struct rpc_client_connection *epm_conn = NULL;
3328
0
  struct rpc_pipe_client *epm_pipe = NULL;
3329
0
  struct pipe_auth_data *epm_auth = NULL;
3330
0
  char *endpoint = NULL;
3331
0
  uint16_t port = 0;
3332
0
  NTSTATUS status;
3333
3334
0
  endpoint = dcerpc_default_transport_endpoint(frame,
3335
0
                 NCACN_IP_TCP,
3336
0
                 table);
3337
0
  if (endpoint != NULL) {
3338
0
    port = (uint16_t)atoi(endpoint);
3339
0
  }
3340
3341
0
  if (port != 0) {
3342
0
    *pport = port;
3343
0
    TALLOC_FREE(frame);
3344
0
    return NT_STATUS_OK;
3345
0
  }
3346
3347
0
  epm_ep = dcerpc_default_transport_endpoint(frame,
3348
0
               NCACN_IP_TCP,
3349
0
               &ndr_table_epmapper);
3350
0
  if (epm_ep == NULL) {
3351
0
    TALLOC_FREE(frame);
3352
0
    return NT_STATUS_RPC_INTERNAL_ERROR;
3353
0
  }
3354
3355
0
  status = rpc_client_association_create(frame,
3356
0
                 default_bt_features,
3357
0
                 DCERPC_PROPOSE_HEADER_SIGNING,
3358
0
                 host,
3359
0
                 NCACN_IP_TCP,
3360
0
                 saddr,
3361
0
                 epm_ep,
3362
0
                 &epm_assoc);
3363
0
  if (!NT_STATUS_IS_OK(status)) {
3364
0
    TALLOC_FREE(frame);
3365
0
    return status;
3366
0
  }
3367
3368
  /* open the connection to the endpoint mapper */
3369
0
  status = rpc_pipe_open_tcp_port(frame, epm_assoc, &epm_conn);
3370
0
  if (!NT_STATUS_IS_OK(status)) {
3371
0
    TALLOC_FREE(frame);
3372
0
    return status;
3373
0
  }
3374
3375
0
  status = rpccli_anon_bind_data(frame, &epm_auth);
3376
0
  if (!NT_STATUS_IS_OK(status)) {
3377
0
    TALLOC_FREE(frame);
3378
0
    return status;
3379
0
  }
3380
3381
0
  status = rpc_pipe_wrap_create(&ndr_table_epmapper,
3382
0
              NULL,
3383
0
              &epm_assoc,
3384
0
              &epm_conn,
3385
0
              frame,
3386
0
              &epm_pipe);
3387
0
  if (!NT_STATUS_IS_OK(status)) {
3388
0
    TALLOC_FREE(frame);
3389
0
    return status;
3390
0
  }
3391
3392
0
  status = rpc_pipe_bind(epm_pipe, epm_auth);
3393
0
  if (!NT_STATUS_IS_OK(status)) {
3394
0
    TALLOC_FREE(frame);
3395
0
    return status;
3396
0
  }
3397
3398
0
  status = rpccli_epm_map_interface(
3399
0
    epm_pipe->binding_handle,
3400
0
    NCACN_IP_TCP,
3401
0
    &table->syntax_id,
3402
0
    frame,
3403
0
    &endpoint);
3404
0
  if (!NT_STATUS_IS_OK(status)) {
3405
0
    DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
3406
0
        nt_errstr(status));
3407
0
    TALLOC_FREE(frame);
3408
0
    return status;
3409
0
  }
3410
3411
0
  *pport = (uint16_t)atoi(endpoint);
3412
0
  TALLOC_FREE(frame);
3413
0
  return NT_STATUS_OK;
3414
0
}
3415
3416
static NTSTATUS rpc_pipe_get_ncalrpc_name(
3417
  const struct ndr_syntax_id *iface,
3418
  TALLOC_CTX *mem_ctx,
3419
  char **psocket_name)
3420
0
{
3421
0
  TALLOC_CTX *frame = talloc_stackframe();
3422
0
  struct rpc_pipe_client *epm_pipe = NULL;
3423
0
  struct pipe_auth_data *auth = NULL;
3424
0
  NTSTATUS status = NT_STATUS_OK;
3425
0
  bool is_epm;
3426
3427
0
  is_epm = ndr_syntax_id_equal(iface, &ndr_table_epmapper.syntax_id);
3428
0
  if (is_epm) {
3429
0
    char *endpoint = talloc_strdup(mem_ctx, "EPMAPPER");
3430
0
    if (endpoint == NULL) {
3431
0
      status = NT_STATUS_NO_MEMORY;
3432
0
      goto done;
3433
0
    }
3434
0
    *psocket_name = endpoint;
3435
0
    goto done;
3436
0
  }
3437
3438
0
  status = rpc_pipe_open_ncalrpc(
3439
0
    frame, &ndr_table_epmapper, &epm_pipe);
3440
0
  if (!NT_STATUS_IS_OK(status)) {
3441
0
    DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n",
3442
0
        nt_errstr(status));
3443
0
    goto done;
3444
0
  }
3445
3446
0
  status = rpccli_anon_bind_data(epm_pipe, &auth);
3447
0
  if (!NT_STATUS_IS_OK(status)) {
3448
0
    DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3449
0
        nt_errstr(status));
3450
0
    goto done;
3451
0
  }
3452
3453
0
  status = rpc_pipe_bind(epm_pipe, auth);
3454
0
  if (!NT_STATUS_IS_OK(status)) {
3455
0
    DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
3456
0
    goto done;
3457
0
  }
3458
3459
0
  status = rpccli_epm_map_interface(
3460
0
    epm_pipe->binding_handle,
3461
0
    NCALRPC,
3462
0
    iface,
3463
0
    mem_ctx,
3464
0
    psocket_name);
3465
0
  if (!NT_STATUS_IS_OK(status)) {
3466
0
    DBG_DEBUG("rpccli_epm_map_interface failed: %s\n",
3467
0
        nt_errstr(status));
3468
0
  }
3469
3470
0
done:
3471
0
  TALLOC_FREE(frame);
3472
0
  return status;
3473
0
}
3474
3475
/********************************************************************
3476
 Create a rpc pipe client struct, connecting to a unix domain socket
3477
 ********************************************************************/
3478
NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx,
3479
             const struct ndr_interface_table *table,
3480
             struct rpc_pipe_client **presult)
3481
0
{
3482
0
  TALLOC_CTX *frame = talloc_stackframe();
3483
0
  char *myname = NULL;
3484
0
  char *socket_name = NULL;
3485
0
  struct samba_sockaddr saddr = {
3486
0
    .sa_socklen = sizeof(struct sockaddr_un),
3487
0
    .u = {
3488
0
      .un = {
3489
0
        .sun_family = AF_UNIX,
3490
0
      },
3491
0
    },
3492
0
  };
3493
0
  struct rpc_client_association *assoc = NULL;
3494
0
  struct rpc_client_connection *conn = NULL;
3495
0
  struct rpc_pipe_client *result = NULL;
3496
0
  int pathlen;
3497
0
  NTSTATUS status;
3498
0
  int fd = -1;
3499
3500
0
  myname = get_myname(frame);
3501
0
  if (myname == NULL) {
3502
0
    TALLOC_FREE(frame);
3503
0
    return NT_STATUS_NO_MEMORY;
3504
0
  }
3505
3506
0
  status = rpc_pipe_get_ncalrpc_name(&table->syntax_id,
3507
0
             frame,
3508
0
             &socket_name);
3509
0
  if (!NT_STATUS_IS_OK(status)) {
3510
0
    DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n",
3511
0
        nt_errstr(status));
3512
0
    TALLOC_FREE(frame);
3513
0
    return status;
3514
0
  }
3515
3516
0
  pathlen = snprintf(
3517
0
    saddr.u.un.sun_path,
3518
0
    sizeof(saddr.u.un.sun_path),
3519
0
    "%s/%s",
3520
0
    lp_ncalrpc_dir(),
3521
0
    socket_name);
3522
0
  if ((pathlen < 0) || ((size_t)pathlen >= sizeof(saddr.u.un.sun_path))) {
3523
0
    DBG_DEBUG("socket_path for %s too long\n", socket_name);
3524
0
    TALLOC_FREE(frame);
3525
0
    return NT_STATUS_NAME_TOO_LONG;
3526
0
  }
3527
0
  TALLOC_FREE(socket_name);
3528
3529
0
  status = rpc_client_association_create(mem_ctx,
3530
0
                 0, /* no client_features */
3531
0
                 0, /* flags */
3532
0
                 myname,
3533
0
                 NCALRPC,
3534
0
                 &saddr,
3535
0
                 socket_name,
3536
0
                 &assoc);
3537
0
  if (!NT_STATUS_IS_OK(status)) {
3538
0
    TALLOC_FREE(frame);
3539
0
    return status;
3540
0
  }
3541
0
  talloc_steal(frame, assoc);
3542
3543
0
  status = rpc_client_connection_create(mem_ctx,
3544
0
                assoc,
3545
0
                DCERPC_FRAG_MAX_SIZE,
3546
0
                &conn);
3547
0
  if (!NT_STATUS_IS_OK(status)) {
3548
0
    TALLOC_FREE(frame);
3549
0
    return status;
3550
0
  }
3551
0
  talloc_steal(frame, conn);
3552
3553
0
  fd = socket(AF_UNIX, SOCK_STREAM, 0);
3554
0
  if (fd == -1) {
3555
0
    status = map_nt_error_from_unix(errno);
3556
0
    TALLOC_FREE(frame);
3557
0
    return status;
3558
0
  }
3559
3560
0
  if (connect(fd, &saddr.u.sa, saddr.sa_socklen) == -1) {
3561
0
    status = map_nt_error_from_unix(errno);
3562
0
    close(fd);
3563
0
    DBG_WARNING("connect(%s) failed: %s - %s\n",
3564
0
          saddr.u.un.sun_path,
3565
0
          strerror(errno), nt_errstr(status));
3566
0
    TALLOC_FREE(frame);
3567
0
    return status;
3568
0
  }
3569
3570
0
  status = rpc_transport_sock_init(conn, fd, &conn->transport);
3571
0
  if (!NT_STATUS_IS_OK(status)) {
3572
0
    close(fd);
3573
0
    TALLOC_FREE(frame);
3574
0
    return status;
3575
0
  }
3576
0
  fd = -1;
3577
3578
0
  conn->transport->transport = NCALRPC;
3579
3580
0
  status = rpc_pipe_wrap_create(table,
3581
0
              NULL,
3582
0
              &assoc,
3583
0
              &conn,
3584
0
              mem_ctx,
3585
0
              &result);
3586
0
  if (!NT_STATUS_IS_OK(status)) {
3587
0
    TALLOC_FREE(frame);
3588
0
    return status;
3589
0
  }
3590
3591
0
  *presult = result;
3592
0
  TALLOC_FREE(frame);
3593
0
  return NT_STATUS_OK;
3594
0
}
3595
3596
NTSTATUS rpc_pipe_open_local_np(
3597
  TALLOC_CTX *mem_ctx,
3598
  const struct ndr_interface_table *table,
3599
  const char *remote_client_name,
3600
  const struct tsocket_address *remote_client_addr,
3601
  const char *local_server_name,
3602
  const struct tsocket_address *local_server_addr,
3603
  const struct auth_session_info *session_info,
3604
  struct rpc_pipe_client **presult)
3605
0
{
3606
0
  TALLOC_CTX *frame = talloc_stackframe();
3607
0
  struct rpc_client_association *assoc = NULL;
3608
0
  struct rpc_client_connection *conn = NULL;
3609
0
  struct rpc_pipe_client *result = NULL;
3610
0
  struct pipe_auth_data *auth = NULL;
3611
0
  struct samba_sockaddr saddr = { .sa_socklen = 0, };
3612
0
  const char *pipe_name = NULL;
3613
0
  struct tstream_context *npa_stream = NULL;
3614
0
  NTSTATUS status = NT_STATUS_NO_MEMORY;
3615
0
  int ret;
3616
3617
0
  pipe_name = dcerpc_default_transport_endpoint(frame,
3618
0
                  NCACN_NP,
3619
0
                  table);
3620
0
  if (pipe_name == NULL) {
3621
0
    DBG_DEBUG("dcerpc_default_transport_endpoint failed\n");
3622
0
    TALLOC_FREE(frame);
3623
0
    return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3624
0
  }
3625
3626
0
  if (local_server_name == NULL) {
3627
0
    local_server_name = get_myname(result);
3628
0
  }
3629
3630
0
  if (local_server_addr != NULL) {
3631
0
    saddr.sa_socklen = tsocket_address_bsd_sockaddr(local_server_addr,
3632
0
                &saddr.u.sa,
3633
0
                sizeof(saddr.u.ss));
3634
0
    if (saddr.sa_socklen == -1) {
3635
0
      status = map_nt_error_from_unix(errno);
3636
0
      TALLOC_FREE(frame);
3637
0
      return status;
3638
0
    }
3639
0
  }
3640
3641
0
  status = rpc_client_association_create(mem_ctx,
3642
0
                 0, /* no client_features */
3643
0
                 0, /* flags */
3644
0
                 local_server_name,
3645
0
                 NCACN_NP,
3646
0
                 &saddr,
3647
0
                 pipe_name,
3648
0
                 &assoc);
3649
0
  if (!NT_STATUS_IS_OK(status)) {
3650
0
    TALLOC_FREE(frame);
3651
0
    return status;
3652
0
  }
3653
0
  talloc_steal(frame, assoc);
3654
3655
0
  status = rpc_client_connection_create(mem_ctx,
3656
0
                assoc,
3657
0
                DCERPC_FRAG_MAX_SIZE,
3658
0
                &conn);
3659
0
  if (!NT_STATUS_IS_OK(status)) {
3660
0
    TALLOC_FREE(frame);
3661
0
    return status;
3662
0
  }
3663
0
  talloc_steal(frame, conn);
3664
3665
0
  ret = local_np_connect(
3666
0
    pipe_name,
3667
0
    NCALRPC,
3668
0
    remote_client_name,
3669
0
    remote_client_addr,
3670
0
    local_server_name,
3671
0
    local_server_addr,
3672
0
    session_info,
3673
0
    true,
3674
0
    conn,
3675
0
    &npa_stream);
3676
0
  if (ret != 0) {
3677
0
    DBG_DEBUG("local_np_connect for %s and "
3678
0
        "user %s\\%s failed: %s\n",
3679
0
        pipe_name,
3680
0
        session_info->info->domain_name,
3681
0
        session_info->info->account_name,
3682
0
        strerror(ret));
3683
0
    status = map_nt_error_from_unix(ret);
3684
0
    TALLOC_FREE(frame);
3685
0
    return status;
3686
0
  }
3687
3688
0
  status = rpc_transport_tstream_init(conn,
3689
0
              &npa_stream,
3690
0
              &conn->transport);
3691
0
  if (!NT_STATUS_IS_OK(status)) {
3692
0
    DBG_DEBUG("rpc_transport_tstream_init failed: %s\n",
3693
0
        nt_errstr(status));
3694
0
    TALLOC_FREE(frame);
3695
0
    return status;
3696
0
  }
3697
0
  conn->transport->transport = NCACN_NP;
3698
3699
0
  status = rpc_pipe_wrap_create(table,
3700
0
              NULL,
3701
0
              &assoc,
3702
0
              &conn,
3703
0
              mem_ctx,
3704
0
              &result);
3705
0
  if (!NT_STATUS_IS_OK(status)) {
3706
0
    TALLOC_FREE(frame);
3707
0
    return status;
3708
0
  }
3709
0
  talloc_steal(frame, result);
3710
3711
0
  status = rpccli_anon_bind_data(result, &auth);
3712
0
  if (!NT_STATUS_IS_OK(status)) {
3713
0
    DBG_DEBUG("rpccli_anon_bind_data failed: %s\n",
3714
0
        nt_errstr(status));
3715
0
    TALLOC_FREE(frame);
3716
0
    return status;
3717
0
  }
3718
3719
0
  status = rpc_pipe_bind(result, auth);
3720
0
  if (!NT_STATUS_IS_OK(status)) {
3721
0
    DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status));
3722
0
    TALLOC_FREE(frame);
3723
0
    return status;
3724
0
  }
3725
3726
0
  *presult = talloc_move(mem_ctx, &result);
3727
0
  TALLOC_FREE(frame);
3728
0
  return NT_STATUS_OK;
3729
0
}
3730
3731
struct rpc_client_connection_np_state {
3732
  struct cli_state *cli;
3733
  const char *pipe_name;
3734
  struct rpc_client_connection *conn;
3735
};
3736
3737
static void rpc_client_connection_np_done(struct tevent_req *subreq);
3738
3739
static struct tevent_req *rpc_client_connection_np_send(
3740
  TALLOC_CTX *mem_ctx,
3741
  struct tevent_context *ev,
3742
  struct cli_state *cli,
3743
  const struct rpc_client_association *assoc)
3744
0
{
3745
0
  struct tevent_req *req = NULL, *subreq = NULL;
3746
0
  struct rpc_client_connection_np_state *state = NULL;
3747
0
  enum dcerpc_transport_t transport;
3748
0
  const char *endpoint = NULL;
3749
0
  const struct sockaddr_storage *local_sockaddr = NULL;
3750
0
  struct smbXcli_session *session = NULL;
3751
0
  NTSTATUS status;
3752
3753
0
  req = tevent_req_create(mem_ctx, &state,
3754
0
        struct rpc_client_connection_np_state);
3755
0
  if (req == NULL) {
3756
0
    return NULL;
3757
0
  }
3758
3759
0
  transport = dcerpc_binding_get_transport(assoc->binding);
3760
0
  if (transport != NCACN_NP) {
3761
0
    tevent_req_nterror(req, NT_STATUS_RPC_WRONG_KIND_OF_BINDING);
3762
0
    return tevent_req_post(req, ev);
3763
0
  }
3764
3765
0
  endpoint = dcerpc_binding_get_string_option(assoc->binding,
3766
0
                "endpoint");
3767
0
  if (endpoint == NULL) {
3768
0
    tevent_req_nterror(req, NT_STATUS_RPC_INVALID_ENDPOINT_FORMAT);
3769
0
    return tevent_req_post(req, ev);
3770
0
  }
3771
3772
0
  status = rpc_client_connection_create(state,
3773
0
                assoc,
3774
0
                TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE,
3775
0
                &state->conn);
3776
0
  if (tevent_req_nterror(req, status)) {
3777
0
    return tevent_req_post(req, ev);
3778
0
  }
3779
3780
0
  local_sockaddr = smbXcli_conn_local_sockaddr(cli->conn);
3781
0
  state->conn->localaddr.u.ss = *local_sockaddr;
3782
3783
0
  if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
3784
0
    session = cli->smb2.session;
3785
0
  } else {
3786
0
    session = cli->smb1.session;
3787
0
  }
3788
3789
0
  status = smbXcli_session_application_key(session, state->conn,
3790
0
          &state->conn->transport_session_key);
3791
0
  if (!NT_STATUS_IS_OK(status)) {
3792
0
    state->conn->transport_session_key = data_blob_null;
3793
0
  }
3794
3795
0
  subreq = rpc_transport_np_init_send(state, ev, cli, endpoint);
3796
0
  if (tevent_req_nomem(subreq, req)) {
3797
0
    return tevent_req_post(req, ev);
3798
0
  }
3799
0
  tevent_req_set_callback(subreq, rpc_client_connection_np_done, req);
3800
0
  return req;
3801
0
}
3802
3803
static void rpc_client_connection_np_done(struct tevent_req *subreq)
3804
0
{
3805
0
  struct tevent_req *req = tevent_req_callback_data(
3806
0
    subreq, struct tevent_req);
3807
0
  struct rpc_client_connection_np_state *state = tevent_req_data(
3808
0
    req, struct rpc_client_connection_np_state);
3809
0
  NTSTATUS status;
3810
3811
0
  status = rpc_transport_np_init_recv(subreq,
3812
0
              state->conn,
3813
0
              &state->conn->transport);
3814
0
  TALLOC_FREE(subreq);
3815
0
  if (tevent_req_nterror(req, status)) {
3816
0
    return;
3817
0
  }
3818
3819
0
  state->conn->transport->transport = NCACN_NP;
3820
3821
0
  tevent_req_done(req);
3822
0
}
3823
3824
static NTSTATUS rpc_client_connection_np_recv(
3825
  struct tevent_req *req,
3826
  TALLOC_CTX *mem_ctx,
3827
  struct rpc_client_connection **pconn)
3828
0
{
3829
0
  struct rpc_client_connection_np_state *state = tevent_req_data(
3830
0
    req, struct rpc_client_connection_np_state);
3831
0
  NTSTATUS status;
3832
3833
0
  if (tevent_req_is_nterror(req, &status)) {
3834
0
    tevent_req_received(req);
3835
0
    return status;
3836
0
  }
3837
0
  *pconn = talloc_move(mem_ctx, &state->conn);
3838
0
  tevent_req_received(req);
3839
0
  return NT_STATUS_OK;
3840
0
}
3841
3842
static NTSTATUS rpc_client_connection_np(struct cli_state *cli,
3843
           const struct rpc_client_association *assoc,
3844
           struct rpc_client_connection **pconn)
3845
0
{
3846
0
  struct tevent_context *ev = NULL;
3847
0
  struct tevent_req *req = NULL;
3848
0
  NTSTATUS status = NT_STATUS_NO_MEMORY;
3849
3850
0
  ev = samba_tevent_context_init(cli);
3851
0
  if (ev == NULL) {
3852
0
    goto fail;
3853
0
  }
3854
0
  req = rpc_client_connection_np_send(ev, ev, cli, assoc);
3855
0
  if (req == NULL) {
3856
0
    goto fail;
3857
0
  }
3858
0
  if (!tevent_req_poll_ntstatus(req, ev, &status)) {
3859
0
    goto fail;
3860
0
  }
3861
0
  status = rpc_client_connection_np_recv(req, NULL, pconn);
3862
0
fail:
3863
0
  TALLOC_FREE(req);
3864
0
  TALLOC_FREE(ev);
3865
0
  return status;
3866
0
}
3867
3868
struct rpc_pipe_open_np_state {
3869
  struct cli_state *cli;
3870
  const struct ndr_interface_table *table;
3871
  struct rpc_client_association *assoc;
3872
  struct rpc_client_connection *conn;
3873
  struct rpc_pipe_client *result;
3874
};
3875
3876
static void rpc_pipe_open_np_done(struct tevent_req *subreq);
3877
3878
struct tevent_req *rpc_pipe_open_np_send(
3879
  TALLOC_CTX *mem_ctx,
3880
  struct tevent_context *ev,
3881
  struct cli_state *cli,
3882
  const struct ndr_interface_table *table)
3883
0
{
3884
0
  struct tevent_req *req = NULL, *subreq = NULL;
3885
0
  struct rpc_pipe_open_np_state *state = NULL;
3886
0
  const char *remote_name = NULL;
3887
0
  const struct sockaddr_storage *remote_sockaddr = NULL;
3888
0
  struct samba_sockaddr saddr = { .sa_socklen = 0, };
3889
0
  const char *pipe_name = NULL;
3890
0
  NTSTATUS status;
3891
3892
0
  req = tevent_req_create(
3893
0
    mem_ctx, &state, struct rpc_pipe_open_np_state);
3894
0
  if (req == NULL) {
3895
0
    return NULL;
3896
0
  }
3897
0
  state->cli = cli;
3898
0
  state->table = table;
3899
3900
0
  remote_name = smbXcli_conn_remote_name(cli->conn);
3901
0
  remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
3902
0
  saddr.u.ss = *remote_sockaddr;
3903
3904
0
  pipe_name = dcerpc_default_transport_endpoint(state,
3905
0
                  NCACN_NP,
3906
0
                  table);
3907
0
  if (tevent_req_nomem(pipe_name, req)) {
3908
0
    return tevent_req_post(req, ev);
3909
0
  }
3910
3911
0
  status = rpc_client_association_create(state,
3912
0
                 default_bt_features,
3913
0
                 DCERPC_PROPOSE_HEADER_SIGNING,
3914
0
                 remote_name,
3915
0
                 NCACN_NP,
3916
0
                 &saddr,
3917
0
                 pipe_name,
3918
0
                 &state->assoc);
3919
0
  if (tevent_req_nterror(req, status)) {
3920
0
    return tevent_req_post(req, ev);
3921
0
  }
3922
3923
0
  subreq = rpc_client_connection_np_send(state, ev, cli, state->assoc);
3924
0
  if (tevent_req_nomem(subreq, req)) {
3925
0
    return tevent_req_post(req, ev);
3926
0
  }
3927
0
  tevent_req_set_callback(subreq, rpc_pipe_open_np_done, req);
3928
0
  return req;
3929
0
}
3930
3931
static void rpc_pipe_open_np_done(struct tevent_req *subreq)
3932
0
{
3933
0
  struct tevent_req *req = tevent_req_callback_data(
3934
0
    subreq, struct tevent_req);
3935
0
  struct rpc_pipe_open_np_state *state = tevent_req_data(
3936
0
    req, struct rpc_pipe_open_np_state);
3937
0
  NTSTATUS status;
3938
3939
0
  status = rpc_client_connection_np_recv(subreq,
3940
0
                 state,
3941
0
                 &state->conn);
3942
0
  TALLOC_FREE(subreq);
3943
0
  if (tevent_req_nterror(req, status)) {
3944
0
    return;
3945
0
  }
3946
3947
0
  status = rpc_pipe_wrap_create(state->table,
3948
0
              state->cli,
3949
0
              &state->assoc,
3950
0
              &state->conn,
3951
0
              state,
3952
0
              &state->result);
3953
0
  if (tevent_req_nterror(req, status)) {
3954
0
    return;
3955
0
  }
3956
3957
0
  tevent_req_done(req);
3958
0
}
3959
3960
NTSTATUS rpc_pipe_open_np_recv(
3961
  struct tevent_req *req,
3962
  TALLOC_CTX *mem_ctx,
3963
  struct rpc_pipe_client **_result)
3964
0
{
3965
0
  struct rpc_pipe_open_np_state *state = tevent_req_data(
3966
0
    req, struct rpc_pipe_open_np_state);
3967
0
  NTSTATUS status;
3968
3969
0
  if (tevent_req_is_nterror(req, &status)) {
3970
0
    tevent_req_received(req);
3971
0
    return status;
3972
0
  }
3973
0
  *_result = talloc_move(mem_ctx, &state->result);
3974
0
  tevent_req_received(req);
3975
0
  return NT_STATUS_OK;
3976
0
}
3977
3978
/****************************************************************************
3979
 Open a pipe to a remote server.
3980
 ****************************************************************************/
3981
3982
static NTSTATUS cli_rpc_pipe_open(struct cli_state *cli,
3983
          enum dcerpc_transport_t transport,
3984
          const struct ndr_interface_table *table,
3985
          const char *remote_name,
3986
          const struct sockaddr_storage *remote_sockaddr,
3987
          struct rpc_pipe_client **presult)
3988
0
{
3989
0
  TALLOC_CTX *frame = talloc_stackframe();
3990
0
  struct samba_sockaddr saddr = { .sa_socklen = 0, };
3991
0
  struct rpc_client_association *assoc = NULL;
3992
0
  struct rpc_client_connection *conn = NULL;
3993
0
  struct rpc_pipe_client *result = NULL;
3994
0
  char _tcp_endpoint[6] = { 0, };
3995
0
  const char *endpoint = NULL;
3996
0
  NTSTATUS status;
3997
3998
0
  if (cli != NULL && remote_name == NULL) {
3999
0
    remote_name = smbXcli_conn_remote_name(cli->conn);
4000
0
  }
4001
0
  if (cli != NULL && remote_sockaddr == NULL) {
4002
0
    remote_sockaddr = smbXcli_conn_remote_sockaddr(cli->conn);
4003
0
  }
4004
4005
0
  if (remote_sockaddr != NULL) {
4006
0
    saddr.u.ss = *remote_sockaddr;
4007
0
  } else {
4008
0
    bool ok;
4009
4010
0
    ok = resolve_name(remote_name,
4011
0
          &saddr.u.ss,
4012
0
          NBT_NAME_SERVER,
4013
0
          false);
4014
0
    if (!ok) {
4015
0
      TALLOC_FREE(frame);
4016
0
      return NT_STATUS_NOT_FOUND;
4017
0
    }
4018
0
  }
4019
4020
0
  endpoint = dcerpc_default_transport_endpoint(frame,
4021
0
                 transport,
4022
0
                 table);
4023
0
  if (endpoint == NULL) {
4024
0
    uint16_t port = 0;
4025
4026
0
    if (transport != NCACN_IP_TCP) {
4027
0
      TALLOC_FREE(frame);
4028
0
      return NT_STATUS_RPC_NO_ENDPOINT_FOUND;
4029
0
    }
4030
4031
0
    status = rpc_pipe_get_tcp_port(remote_name,
4032
0
                 &saddr,
4033
0
                 table,
4034
0
                 &port);
4035
0
    if (!NT_STATUS_IS_OK(status)) {
4036
0
      TALLOC_FREE(frame);
4037
0
      return status;
4038
0
    }
4039
4040
0
    snprintf(_tcp_endpoint, sizeof(_tcp_endpoint), "%u", port);
4041
0
    endpoint = _tcp_endpoint;
4042
0
  }
4043
4044
0
  status = rpc_client_association_create(NULL,
4045
0
                 default_bt_features,
4046
0
                 DCERPC_PROPOSE_HEADER_SIGNING,
4047
0
                 remote_name,
4048
0
                 transport,
4049
0
                 &saddr,
4050
0
                 endpoint,
4051
0
                 &assoc);
4052
0
  if (!NT_STATUS_IS_OK(status)) {
4053
0
    TALLOC_FREE(frame);
4054
0
    return status;
4055
0
  }
4056
0
  talloc_steal(frame, assoc);
4057
4058
0
  switch (transport) {
4059
0
  case NCACN_IP_TCP:
4060
0
    status = rpc_pipe_open_tcp_port(NULL,
4061
0
            assoc,
4062
0
            &conn);
4063
0
    if (!NT_STATUS_IS_OK(status)) {
4064
0
      TALLOC_FREE(frame);
4065
0
      return status;
4066
0
    }
4067
0
    talloc_steal(frame, conn);
4068
0
    break;
4069
0
  case NCACN_NP:
4070
0
    status = rpc_client_connection_np(cli,
4071
0
              assoc,
4072
0
              &conn);
4073
0
    if (!NT_STATUS_IS_OK(status)) {
4074
0
      TALLOC_FREE(frame);
4075
0
      return status;
4076
0
    }
4077
0
    talloc_steal(frame, conn);
4078
0
    break;
4079
0
  default:
4080
0
    TALLOC_FREE(frame);
4081
0
    return NT_STATUS_NOT_IMPLEMENTED;
4082
0
  }
4083
0
  status = rpc_pipe_wrap_create(table,
4084
0
              cli,
4085
0
              &assoc,
4086
0
              &conn,
4087
0
              NULL,
4088
0
              &result);
4089
0
  if (!NT_STATUS_IS_OK(status)) {
4090
0
    TALLOC_FREE(frame);
4091
0
    return status;
4092
0
  }
4093
4094
0
  *presult = result;
4095
0
  TALLOC_FREE(frame);
4096
0
  return NT_STATUS_OK;
4097
0
}
4098
4099
static NTSTATUS cli_rpc_pipe_client_reconnect(struct rpc_pipe_client *p)
4100
0
{
4101
0
  enum dcerpc_transport_t transport =
4102
0
    dcerpc_binding_get_transport(p->assoc->binding);
4103
0
  NTSTATUS status;
4104
4105
0
  switch (transport) {
4106
0
  case NCACN_IP_TCP:
4107
0
    status = rpc_pipe_open_tcp_port(p,
4108
0
            p->assoc,
4109
0
            &p->conn);
4110
0
    if (!NT_STATUS_IS_OK(status)) {
4111
0
      return status;
4112
0
    }
4113
0
    break;
4114
0
  case NCACN_NP:
4115
0
    status = rpc_client_connection_np(p->np_cli,
4116
0
              p->assoc,
4117
0
              &p->conn);
4118
0
    if (!NT_STATUS_IS_OK(status)) {
4119
0
      return status;
4120
0
    }
4121
0
    talloc_steal(p, p->conn);
4122
0
    break;
4123
0
  default:
4124
0
    return NT_STATUS_NOT_IMPLEMENTED;
4125
0
  }
4126
4127
0
  return NT_STATUS_OK;
4128
0
}
4129
4130
NTSTATUS cli_rpc_pipe_client_prepare_alter(struct rpc_pipe_client *p,
4131
             bool new_auth_context,
4132
             const struct ndr_interface_table *table,
4133
             bool new_pres_context)
4134
0
{
4135
0
  uint32_t f = p->assoc->features.negotiated;
4136
0
  NTSTATUS status;
4137
4138
0
  if (!new_auth_context && !new_pres_context) {
4139
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
4140
0
  }
4141
4142
0
  TALLOC_FREE(p->binding_handle);
4143
4144
0
  if (new_auth_context) {
4145
0
    p->auth = NULL;
4146
0
  }
4147
4148
0
  if (new_auth_context &&
4149
0
      !(f & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING))
4150
0
  {
4151
    /*
4152
     * new auth context without
4153
     * security context multiplexing.
4154
     *
4155
     * We need to create a new transport
4156
     * connection is the same association
4157
     * group
4158
     *
4159
     * We need to keep the old connection alive
4160
     * in order to connect to the existing association
4161
     * group..., so no TALLOC_FREE(p->conn)
4162
     */
4163
0
    p->conn = NULL;
4164
0
    status = cli_rpc_pipe_client_reconnect(p);
4165
0
    if (!NT_STATUS_IS_OK(status)) {
4166
0
      return status;
4167
0
    }
4168
0
  }
4169
4170
0
  if (new_pres_context) {
4171
    /* rpc_pipe_bind_send should allocate an id... */
4172
0
    p->pres_context_id = UINT16_MAX;
4173
0
    p->table = table;
4174
0
    p->transfer_syntax = ndr_transfer_syntax_ndr;
4175
0
  }
4176
4177
0
  return NT_STATUS_OK;
4178
0
}
4179
4180
/****************************************************************************
4181
 Open a named pipe to an SMB server and bind anonymously.
4182
 ****************************************************************************/
4183
4184
NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli,
4185
              enum dcerpc_transport_t transport,
4186
              const struct ndr_interface_table *table,
4187
              const char *remote_name,
4188
              const struct sockaddr_storage *remote_sockaddr,
4189
              struct rpc_pipe_client **presult)
4190
0
{
4191
0
  struct rpc_pipe_client *result;
4192
0
  struct pipe_auth_data *auth;
4193
0
  NTSTATUS status;
4194
4195
0
  status = cli_rpc_pipe_open(cli,
4196
0
           transport,
4197
0
           table,
4198
0
           remote_name,
4199
0
           remote_sockaddr,
4200
0
           &result);
4201
0
  if (!NT_STATUS_IS_OK(status)) {
4202
0
    return status;
4203
0
  }
4204
4205
0
  status = rpccli_anon_bind_data(result, &auth);
4206
0
  if (!NT_STATUS_IS_OK(status)) {
4207
0
    DEBUG(0, ("rpccli_anon_bind_data returned %s\n",
4208
0
        nt_errstr(status)));
4209
0
    TALLOC_FREE(result);
4210
0
    return status;
4211
0
  }
4212
4213
0
  status = rpc_pipe_bind(result, auth);
4214
0
  if (!NT_STATUS_IS_OK(status)) {
4215
0
    int lvl = 0;
4216
0
    if (ndr_syntax_id_equal(&table->syntax_id,
4217
0
          &ndr_table_dssetup.syntax_id)) {
4218
      /* non AD domains just don't have this pipe, avoid
4219
       * level 0 statement in that case - gd */
4220
0
      lvl = 3;
4221
0
    }
4222
0
    DEBUG(lvl, ("cli_rpc_pipe_open_noauth: rpc_pipe_bind for pipe "
4223
0
          "%s failed with error %s\n",
4224
0
          table->name,
4225
0
          nt_errstr(status) ));
4226
0
    TALLOC_FREE(result);
4227
0
    return status;
4228
0
  }
4229
4230
0
  DEBUG(10,("cli_rpc_pipe_open_noauth: opened pipe %s to machine "
4231
0
      "%s and bound anonymously.\n",
4232
0
      table->name,
4233
0
      result->desthost));
4234
4235
0
  *presult = result;
4236
0
  return NT_STATUS_OK;
4237
0
}
4238
4239
/****************************************************************************
4240
 ****************************************************************************/
4241
4242
NTSTATUS cli_rpc_pipe_open_noauth(struct cli_state *cli,
4243
          const struct ndr_interface_table *table,
4244
          struct rpc_pipe_client **presult)
4245
0
{
4246
0
  const char *remote_name = smbXcli_conn_remote_name(cli->conn);
4247
0
  const struct sockaddr_storage *remote_sockaddr =
4248
0
    smbXcli_conn_remote_sockaddr(cli->conn);
4249
4250
0
  return cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP,
4251
0
              table,
4252
0
              remote_name,
4253
0
              remote_sockaddr,
4254
0
              presult);
4255
0
}
4256
4257
/****************************************************************************
4258
 * Reopen a connection with the same parameters.
4259
 *
4260
 * This is useful if we try an RPC function the server doesn't know about and
4261
 * disconnects us.
4262
 ****************************************************************************/
4263
NTSTATUS cli_rpc_pipe_reopen_np_noauth(struct rpc_pipe_client *rpccli)
4264
0
{
4265
0
  TALLOC_CTX *frame = talloc_stackframe();
4266
0
  enum dcerpc_transport_t transport;
4267
0
  struct cli_state *cli = NULL;
4268
0
  struct rpc_client_association *assoc = NULL;
4269
0
  struct rpc_client_connection *new_conn = NULL;
4270
0
  struct pipe_auth_data *new_auth = NULL;
4271
0
  NTSTATUS status;
4272
4273
0
  if (rpccli->assoc == NULL) {
4274
0
    TALLOC_FREE(frame);
4275
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
4276
0
  }
4277
4278
0
  transport = dcerpc_binding_get_transport(rpccli->assoc->binding);
4279
0
  if (transport != NCACN_NP) {
4280
0
    TALLOC_FREE(frame);
4281
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
4282
0
  }
4283
4284
0
  if (rpccli->np_cli == NULL) {
4285
0
    TALLOC_FREE(frame);
4286
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
4287
0
  }
4288
0
  cli = rpccli->np_cli;
4289
4290
  /*
4291
   * close the old connection
4292
   */
4293
0
  TALLOC_FREE(rpccli->conn);
4294
4295
  /*
4296
   * Free the auth context
4297
   */
4298
0
  TALLOC_FREE(rpccli->auth);
4299
4300
  /*
4301
   * Reset the association
4302
   */
4303
0
  assoc = talloc_move(frame, &rpccli->assoc);
4304
0
  status = dcerpc_binding_set_assoc_group_id(assoc->binding, 0);
4305
0
  if (!NT_STATUS_IS_OK(status)) {
4306
0
    return status;
4307
0
  }
4308
0
  assoc->features.negotiated = 0;
4309
0
  if (assoc->features.client != 0) {
4310
0
    assoc->features.negotiation_done = false;
4311
0
  }
4312
0
  assoc->next_call_id = 0;
4313
4314
0
  status = rpc_client_connection_np(cli,
4315
0
            assoc,
4316
0
            &new_conn);
4317
0
  if (!NT_STATUS_IS_OK(status)) {
4318
0
    TALLOC_FREE(frame);
4319
0
    return status;
4320
0
  }
4321
4322
0
  rpccli->assoc = talloc_move(rpccli, &assoc);
4323
0
  rpccli->conn = talloc_move(rpccli, &new_conn);
4324
4325
  /* rpc_pipe_bind_send should allocate an id... */
4326
0
  rpccli->pres_context_id = UINT16_MAX;
4327
0
  rpccli->verified_pcontext = false;
4328
4329
0
  status = rpccli_anon_bind_data(rpccli, &new_auth);
4330
0
  if (!NT_STATUS_IS_OK(status)) {
4331
0
    TALLOC_FREE(frame);
4332
0
    return status;
4333
0
  }
4334
4335
0
  status = rpc_pipe_bind(rpccli, new_auth);
4336
0
  if (!NT_STATUS_IS_OK(status)) {
4337
0
    TALLOC_FREE(frame);
4338
0
    return status;
4339
0
  }
4340
4341
0
  TALLOC_FREE(frame);
4342
0
  return NT_STATUS_OK;
4343
0
}
4344
4345
/****************************************************************************
4346
 Open a named pipe to an SMB server and bind using the mech specified
4347
4348
 This routine references the creds pointer that is passed in
4349
 ****************************************************************************/
4350
4351
NTSTATUS cli_rpc_pipe_open_with_creds(struct cli_state *cli,
4352
              const struct ndr_interface_table *table,
4353
              enum dcerpc_transport_t transport,
4354
              enum dcerpc_AuthType auth_type,
4355
              enum dcerpc_AuthLevel auth_level,
4356
              const char *target_service,
4357
              const char *target_hostname,
4358
              const struct sockaddr_storage *remote_sockaddr,
4359
              struct cli_credentials *creds,
4360
              struct rpc_pipe_client **presult)
4361
0
{
4362
0
  struct rpc_pipe_client *result;
4363
0
  struct pipe_auth_data *auth = NULL;
4364
0
  NTSTATUS status;
4365
4366
0
  if (target_service == NULL) {
4367
0
    target_service = table->authservices->names[0];
4368
0
  }
4369
4370
0
  status = cli_rpc_pipe_open(cli,
4371
0
           transport,
4372
0
           table,
4373
0
           target_hostname,
4374
0
           remote_sockaddr,
4375
0
           &result);
4376
0
  if (!NT_STATUS_IS_OK(status)) {
4377
0
    return status;
4378
0
  }
4379
4380
0
  status = rpccli_generic_bind_data_from_creds(result,
4381
0
                 auth_type,
4382
0
                 auth_level,
4383
0
                 target_hostname,
4384
0
                 target_service,
4385
0
                 creds,
4386
0
                 &auth);
4387
0
  if (!NT_STATUS_IS_OK(status)) {
4388
0
    DBG_ERR("rpccli_generic_bind_data_from_creds returned %s\n",
4389
0
      nt_errstr(status));
4390
0
    goto err;
4391
0
  }
4392
4393
0
  status = rpc_pipe_bind(result, auth);
4394
0
  if (!NT_STATUS_IS_OK(status)) {
4395
0
    DBG_ERR("cli_rpc_pipe_bind failed with error %s\n",
4396
0
      nt_errstr(status));
4397
0
    goto err;
4398
0
  }
4399
4400
0
  DBG_DEBUG("opened pipe %s to machine %s and bound as user %s.\n",
4401
0
      table->name,
4402
0
      result->desthost,
4403
0
      cli_credentials_get_unparsed_name(creds, talloc_tos()));
4404
4405
0
  *presult = result;
4406
0
  return NT_STATUS_OK;
4407
4408
0
  err:
4409
4410
0
  TALLOC_FREE(result);
4411
0
  return status;
4412
0
}
4413
4414
NTSTATUS cli_rpc_pipe_client_auth_schannel(
4415
  struct rpc_pipe_client *rpccli,
4416
  const struct ndr_interface_table *table,
4417
  struct netlogon_creds_cli_context *netlogon_creds)
4418
0
{
4419
0
  TALLOC_CTX *frame = talloc_stackframe();
4420
0
  struct pipe_auth_data *rpcauth = NULL;
4421
0
  const char *target_service = table->authservices->names[0];
4422
0
  struct cli_credentials *cli_creds = NULL;
4423
0
  enum dcerpc_AuthLevel auth_level;
4424
0
  NTSTATUS status;
4425
4426
0
  auth_level = netlogon_creds_cli_auth_level(netlogon_creds);
4427
4428
0
  status = netlogon_creds_bind_cli_credentials(netlogon_creds,
4429
0
                 frame,
4430
0
                 &cli_creds);
4431
0
  if (!NT_STATUS_IS_OK(status)) {
4432
0
    DBG_DEBUG("netlogon_creds_bind_cli_credentials failed: %s\n",
4433
0
        nt_errstr(status));
4434
0
    TALLOC_FREE(frame);
4435
0
    return status;
4436
0
  }
4437
4438
0
  status = rpccli_generic_bind_data_from_creds(rpccli,
4439
0
                 DCERPC_AUTH_TYPE_SCHANNEL,
4440
0
                 auth_level,
4441
0
                 rpccli->desthost,
4442
0
                 target_service,
4443
0
                 cli_creds,
4444
0
                 &rpcauth);
4445
0
  if (!NT_STATUS_IS_OK(status)) {
4446
0
    DEBUG(0, ("rpccli_generic_bind_data_from_creds returned %s\n",
4447
0
        nt_errstr(status)));
4448
0
    TALLOC_FREE(frame);
4449
0
    return status;
4450
0
  }
4451
4452
0
  status = rpc_pipe_bind(rpccli, rpcauth);
4453
0
  if (!NT_STATUS_IS_OK(status)) {
4454
0
    DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
4455
0
        nt_errstr(status));
4456
0
    TALLOC_FREE(frame);
4457
0
    return status;
4458
0
  }
4459
4460
0
  TALLOC_FREE(frame);
4461
0
  return NT_STATUS_OK;
4462
0
}
4463
4464
NTSTATUS cli_rpc_pipe_open_bind_schannel(
4465
  struct cli_state *cli,
4466
  const struct ndr_interface_table *table,
4467
  enum dcerpc_transport_t transport,
4468
  struct netlogon_creds_cli_context *netlogon_creds,
4469
  const char *remote_name,
4470
  const struct sockaddr_storage *remote_sockaddr,
4471
  struct rpc_pipe_client **_rpccli)
4472
0
{
4473
0
  struct rpc_pipe_client *rpccli = NULL;
4474
0
  NTSTATUS status;
4475
4476
0
  status = cli_rpc_pipe_open(cli,
4477
0
           transport,
4478
0
           table,
4479
0
           remote_name,
4480
0
           remote_sockaddr,
4481
0
           &rpccli);
4482
0
  if (!NT_STATUS_IS_OK(status)) {
4483
0
    return status;
4484
0
  }
4485
4486
0
  status = cli_rpc_pipe_client_auth_schannel(rpccli,
4487
0
               table,
4488
0
               netlogon_creds);
4489
0
  if (!NT_STATUS_IS_OK(status)) {
4490
0
    DBG_DEBUG("rpc_pipe_bind failed with error %s\n",
4491
0
        nt_errstr(status));
4492
0
    TALLOC_FREE(rpccli);
4493
0
    return status;
4494
0
  }
4495
4496
0
  *_rpccli = rpccli;
4497
4498
0
  return NT_STATUS_OK;
4499
0
}
4500
4501
NTSTATUS cli_rpc_pipe_open_schannel_with_creds(struct cli_state *cli,
4502
                 const struct ndr_interface_table *table,
4503
                 enum dcerpc_transport_t transport,
4504
                 struct netlogon_creds_cli_context *netlogon_creds,
4505
                 const char *remote_name,
4506
                 const struct sockaddr_storage *remote_sockaddr,
4507
                 struct rpc_pipe_client **_rpccli)
4508
0
{
4509
0
  TALLOC_CTX *frame = talloc_stackframe();
4510
0
  struct rpc_pipe_client *rpccli;
4511
0
  struct netlogon_creds_cli_lck *lck;
4512
0
  NTSTATUS status;
4513
4514
0
  status = netlogon_creds_cli_lck(
4515
0
    netlogon_creds, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
4516
0
    frame, &lck);
4517
0
  if (!NT_STATUS_IS_OK(status)) {
4518
0
    DBG_WARNING("netlogon_creds_cli_lck returned %s\n",
4519
0
          nt_errstr(status));
4520
0
    TALLOC_FREE(frame);
4521
0
    return status;
4522
0
  }
4523
4524
0
  status = cli_rpc_pipe_open_bind_schannel(cli,
4525
0
             table,
4526
0
             transport,
4527
0
             netlogon_creds,
4528
0
             remote_name,
4529
0
             remote_sockaddr,
4530
0
             &rpccli);
4531
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
4532
0
    netlogon_creds_cli_delete_lck(netlogon_creds);
4533
0
  }
4534
0
  if (!NT_STATUS_IS_OK(status)) {
4535
0
    DBG_DEBUG("cli_rpc_pipe_open_bind_schannel failed: %s\n",
4536
0
        nt_errstr(status));
4537
0
    TALLOC_FREE(frame);
4538
0
    return status;
4539
0
  }
4540
4541
0
  if (ndr_syntax_id_equal(&table->syntax_id,
4542
0
        &ndr_table_netlogon.syntax_id)) {
4543
0
    status = netlogon_creds_cli_check(netlogon_creds,
4544
0
              rpccli->binding_handle,
4545
0
              NULL);
4546
0
    if (!NT_STATUS_IS_OK(status)) {
4547
0
      DEBUG(0, ("netlogon_creds_cli_check failed with %s\n",
4548
0
          nt_errstr(status)));
4549
0
      TALLOC_FREE(frame);
4550
0
      return status;
4551
0
    }
4552
0
  }
4553
4554
0
  DBG_DEBUG("opened pipe %s to machine %s with key %s "
4555
0
      "and bound using schannel.\n",
4556
0
      table->name, rpccli->desthost,
4557
0
      netlogon_creds_cli_debug_string(netlogon_creds, lck));
4558
4559
0
  TALLOC_FREE(frame);
4560
4561
0
  *_rpccli = rpccli;
4562
0
  return NT_STATUS_OK;
4563
0
}