Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/libcli/smb/smbXcli_base.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   Infrastructure for async SMB client requests
4
   Copyright (C) Volker Lendecke 2008
5
   Copyright (C) Stefan Metzmacher 2011
6
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
*/
20
21
#include "includes.h"
22
#include "system/network.h"
23
#include "../lib/async_req/async_sock.h"
24
#include "../lib/util/tevent_ntstatus.h"
25
#include "../lib/util/tevent_unix.h"
26
#include "lib/tsocket/tsocket.h"
27
#include "source3/lib/util_tsock.h"
28
#include "lib/util/util_net.h"
29
#include "lib/util/dlinklist.h"
30
#include "lib/util/iov_buf.h"
31
#include "../libcli/smb/smb_common.h"
32
#include "../libcli/smb/smb_seal.h"
33
#include "../libcli/smb/smb_signing.h"
34
#include "../libcli/smb/read_smb.h"
35
#include "smbXcli_base.h"
36
#include "librpc/ndr/libndr.h"
37
#include "libcli/smb/smb2_negotiate_context.h"
38
#include "libcli/smb/smb2_signing.h"
39
40
#include "lib/crypto/gnutls_helpers.h"
41
#include <gnutls/gnutls.h>
42
#include <gnutls/crypto.h>
43
44
struct smbXcli_transport;
45
struct smbXcli_conn;
46
struct smbXcli_req;
47
struct smbXcli_session;
48
struct smbXcli_tcon;
49
50
struct smbXcli_transport {
51
  struct smb_transport transport;
52
  int sock_fd;
53
  struct tstream_context *tstream;
54
  enum tls_verify_peer_state verify_peer;
55
  struct samba_sockaddr laddr;
56
  struct samba_sockaddr raddr;
57
58
  struct tevent_req *(*writev_send_fn)(TALLOC_CTX *mem_ctx,
59
               struct tevent_context *ev,
60
               struct smbXcli_transport *xtp,
61
               struct tevent_queue *queue,
62
               struct iovec *iov,
63
               int count);
64
  ssize_t (*writev_recv_fn)(struct tevent_req *req, int *perrno);
65
66
  struct tevent_req *(*read_smb_send_fn)(TALLOC_CTX *mem_ctx,
67
                 struct tevent_context *ev,
68
                 struct smbXcli_transport *xtp);
69
  ssize_t (*read_smb_recv_fn)(struct tevent_req *req,
70
            TALLOC_CTX *mem_ctx,
71
            uint8_t **pbuf,
72
            int *perrno);
73
74
  struct tevent_req *(*monitor_send_fn)(TALLOC_CTX *mem_ctx,
75
                struct tevent_context *ev,
76
                struct smbXcli_transport *xtp);
77
  int (*monitor_recv_fn)(struct tevent_req *req);
78
};
79
80
struct smbXcli_conn {
81
  struct smbXcli_transport *transport;
82
83
  const char *remote_name;
84
85
  struct tevent_queue *outgoing;
86
  struct tevent_req **pending;
87
  struct tevent_req *read_smb_req;
88
  struct tevent_req *monitor_req;
89
  struct tevent_req *suicide_req;
90
91
  enum protocol_types min_protocol;
92
  enum protocol_types max_protocol;
93
  enum protocol_types protocol;
94
  bool allow_signing;
95
  bool desire_signing;
96
  bool mandatory_signing;
97
98
  /*
99
   * The incoming dispatch function should return:
100
   * - NT_STATUS_RETRY, if more incoming PDUs are expected.
101
   * - NT_STATUS_OK, if no more processing is desired, e.g.
102
   *                 the dispatch function called
103
   *                 tevent_req_done().
104
   * - All other return values disconnect the connection.
105
   */
106
  NTSTATUS (*dispatch_incoming)(struct smbXcli_conn *conn,
107
              TALLOC_CTX *tmp_mem,
108
              uint8_t *inbuf);
109
110
  struct {
111
    struct {
112
      uint32_t capabilities;
113
      uint32_t max_xmit;
114
    } client;
115
116
    struct {
117
      uint32_t capabilities;
118
      uint32_t max_xmit;
119
      uint16_t max_mux;
120
      uint16_t security_mode;
121
      bool readbraw;
122
      bool writebraw;
123
      bool lockread;
124
      bool writeunlock;
125
      uint32_t session_key;
126
      struct GUID guid;
127
      DATA_BLOB gss_blob;
128
      uint8_t challenge[8];
129
      const char *workgroup;
130
      const char *name;
131
      int time_zone;
132
      NTTIME system_time;
133
    } server;
134
135
    uint32_t capabilities;
136
    uint32_t max_xmit;
137
138
    uint16_t mid;
139
140
    struct smb1_signing_state *signing;
141
    struct smb_trans_enc_state *trans_enc;
142
143
    struct tevent_req *read_braw_req;
144
  } smb1;
145
146
  struct {
147
    struct {
148
      uint32_t capabilities;
149
      uint16_t security_mode;
150
      struct GUID guid;
151
      struct smb311_capabilities smb3_capabilities;
152
      bool requested_transport_level_security;
153
    } client;
154
155
    struct {
156
      uint32_t capabilities;
157
      uint16_t security_mode;
158
      struct GUID guid;
159
      uint32_t max_trans_size;
160
      uint32_t max_read_size;
161
      uint32_t max_write_size;
162
      NTTIME system_time;
163
      NTTIME start_time;
164
      DATA_BLOB gss_blob;
165
      uint16_t sign_algo;
166
      uint16_t cipher;
167
      bool smb311_posix;
168
      bool transport_trusted;
169
    } server;
170
171
    uint64_t mid;
172
    uint16_t cur_credits;
173
    uint16_t max_credits;
174
175
    uint32_t cc_chunk_len;
176
    uint32_t cc_max_chunks;
177
178
    uint8_t io_priority;
179
180
    bool force_channel_sequence;
181
182
    uint8_t preauth_sha512[64];
183
  } smb2;
184
185
  struct smbXcli_session *sessions;
186
};
187
188
struct smb2cli_session {
189
  uint64_t session_id;
190
  uint16_t session_flags;
191
  struct smb2_signing_key *application_key;
192
  struct smb2_signing_key *signing_key;
193
  bool should_sign;
194
  bool should_encrypt;
195
  struct smb2_signing_key *encryption_key;
196
  struct smb2_signing_key *decryption_key;
197
  uint64_t nonce_high_random;
198
  uint64_t nonce_high_max;
199
  uint64_t nonce_high;
200
  uint64_t nonce_low;
201
  uint16_t channel_sequence;
202
  bool replay_active;
203
  bool require_signed_response;
204
205
  /*
206
   * The following are just for torture tests
207
   */
208
  bool anonymous_signing;
209
  bool anonymous_encryption;
210
  bool no_signing_disconnect;
211
};
212
213
struct smbXcli_session {
214
  struct smbXcli_session *prev, *next;
215
  struct smbXcli_conn *conn;
216
217
  struct {
218
    uint16_t session_id;
219
    uint16_t action;
220
    DATA_BLOB application_key;
221
    bool protected_key;
222
  } smb1;
223
224
  struct smb2cli_session *smb2;
225
226
  struct {
227
    struct smb2_signing_key *signing_key;
228
    uint8_t preauth_sha512[64];
229
  } smb2_channel;
230
231
  /*
232
   * this should be a short term hack
233
   * until the upper layers have implemented
234
   * re-authentication.
235
   */
236
  bool disconnect_expired;
237
};
238
239
struct smbXcli_tcon {
240
  bool is_smb1;
241
  uint32_t fs_attributes;
242
243
  struct {
244
    uint16_t tcon_id;
245
    uint16_t optional_support;
246
    uint32_t maximal_access;
247
    uint32_t guest_maximal_access;
248
    char *service;
249
    char *fs_type;
250
  } smb1;
251
252
  struct {
253
    uint32_t tcon_id;
254
    uint8_t type;
255
    uint32_t flags;
256
    uint32_t capabilities;
257
    uint32_t maximal_access;
258
    bool should_sign;
259
    bool should_encrypt;
260
  } smb2;
261
};
262
263
struct smbXcli_req_state {
264
  struct tevent_context *ev;
265
  struct smbXcli_conn *conn;
266
  struct smbXcli_session *session; /* maybe NULL */
267
  struct smbXcli_tcon *tcon; /* maybe NULL */
268
269
  uint8_t length_hdr[4];
270
271
  bool one_way;
272
273
  uint8_t *inbuf;
274
275
  struct tevent_req *write_req;
276
  ssize_t (*writev_recv_fn)(struct tevent_req *req, int *perrno);
277
278
  struct timeval endtime;
279
280
  struct {
281
    /* Space for the header including the wct */
282
    uint8_t hdr[HDR_VWV];
283
284
    /*
285
     * For normal requests, smb1cli_req_send chooses a mid.
286
     * SecondaryV trans requests need to use the mid of the primary
287
     * request, so we need a place to store it.
288
     * Assume it is set if != 0.
289
     */
290
    uint16_t mid;
291
292
    uint16_t *vwv;
293
    uint8_t bytecount_buf[2];
294
295
0
#define MAX_SMB_IOV 10
296
    /* length_hdr, hdr, words, byte_count, buffers */
297
    struct iovec iov[1 + 3 + MAX_SMB_IOV];
298
    int iov_count;
299
300
    bool one_way_seqnum;
301
    uint32_t seqnum;
302
    struct tevent_req **chained_requests;
303
304
    uint8_t recv_cmd;
305
    NTSTATUS recv_status;
306
    /* always an array of 3 talloc elements */
307
    struct iovec *recv_iov;
308
  } smb1;
309
310
  struct {
311
    const uint8_t *fixed;
312
    uint16_t fixed_len;
313
    const uint8_t *dyn;
314
    uint32_t dyn_len;
315
316
    uint8_t transform[SMB2_TF_HDR_SIZE];
317
    uint8_t hdr[SMB2_HDR_BODY];
318
    uint8_t pad[7]; /* padding space for compounding */
319
320
    /*
321
     * always an array of 3 talloc elements
322
     * (without a SMB2_TRANSFORM header!)
323
     *
324
     * HDR, BODY, DYN
325
     */
326
    struct iovec *recv_iov;
327
328
    /*
329
     * the expected max for the response dyn_len
330
     */
331
    uint32_t max_dyn_len;
332
333
    uint16_t credit_charge;
334
335
    bool should_sign;
336
    bool should_encrypt;
337
    uint64_t encryption_session_id;
338
339
    bool signing_skipped;
340
    bool require_signed_response;
341
    bool notify_async;
342
    bool got_async;
343
    uint16_t cancel_flags;
344
    uint64_t cancel_mid;
345
    uint64_t cancel_aid;
346
  } smb2;
347
};
348
349
static int smbXcli_transport_destructor(struct smbXcli_transport *xtp)
350
0
{
351
0
  if (xtp->sock_fd != -1) {
352
0
    close(xtp->sock_fd);
353
0
    xtp->sock_fd = -1;
354
0
  }
355
0
  TALLOC_FREE(xtp->tstream);
356
0
  return 0;
357
0
}
358
359
static struct tevent_req *smbXcli_transport_tstream_writev_send(
360
        TALLOC_CTX *mem_ctx,
361
        struct tevent_context *ev,
362
        struct smbXcli_transport *xtp,
363
        struct tevent_queue *queue,
364
        struct iovec *iov,
365
        int count)
366
0
{
367
0
  return tstream_writev_queue_send(mem_ctx,
368
0
           ev,
369
0
           xtp->tstream,
370
0
           queue,
371
0
           iov,
372
0
           count);
373
0
}
374
375
static ssize_t smbXcli_transport_tstream_writev_recv(struct tevent_req *req,
376
             int *perrno)
377
0
{
378
0
  return tstream_writev_queue_recv(req, perrno);
379
0
}
380
381
static struct tevent_req *smbXcli_transport_tstream_read_smb_send(
382
        TALLOC_CTX *mem_ctx,
383
        struct tevent_context *ev,
384
        struct smbXcli_transport *xtp)
385
0
{
386
0
  return tstream_read_packet_send(mem_ctx,
387
0
          ev,
388
0
          xtp->tstream,
389
0
          4,
390
0
          read_smb_more,
391
0
          NULL);
392
0
}
393
394
static ssize_t smbXcli_transport_tstream_read_smb_recv(
395
        struct tevent_req *req,
396
        TALLOC_CTX *mem_ctx,
397
        uint8_t **pbuf,
398
        int *perrno)
399
0
{
400
0
  return tstream_read_packet_recv(req, mem_ctx, pbuf, perrno);
401
0
}
402
403
static struct tevent_req *smbXcli_transport_tstream_monitor_send(
404
        TALLOC_CTX *mem_ctx,
405
        struct tevent_context *ev,
406
        struct smbXcli_transport *xtp)
407
0
{
408
0
  return tstream_monitor_send(mem_ctx,
409
0
            ev,
410
0
            xtp->tstream);
411
0
}
412
413
static int smbXcli_transport_tstream_monitor_recv(struct tevent_req *req)
414
0
{
415
0
  int sys_errno = 0;
416
0
  int ret;
417
418
0
  ret = tstream_monitor_recv(req, &sys_errno);
419
0
  if (ret == 0) {
420
0
    sys_errno = EPIPE;
421
0
  }
422
0
  if (sys_errno == 0) {
423
0
    sys_errno = EPIPE;
424
0
  }
425
426
0
  return sys_errno;
427
0
}
428
429
struct smbXcli_transport *smbXcli_transport_tstream(
430
  TALLOC_CTX *mem_ctx,
431
  struct tstream_context **pstream,
432
  enum tls_verify_peer_state verify_peer,
433
  const struct samba_sockaddr *laddr,
434
  const struct samba_sockaddr *raddr,
435
  const struct smb_transport *tp)
436
0
{
437
0
  struct smbXcli_transport *xtp = NULL;
438
439
0
  xtp = talloc_zero(mem_ctx, struct smbXcli_transport);
440
0
  if (xtp == NULL) {
441
0
    return NULL;
442
0
  }
443
444
0
  xtp->transport = *tp;
445
0
  xtp->sock_fd = -1;
446
0
  xtp->verify_peer = verify_peer;
447
448
0
  xtp->laddr = *laddr;
449
0
  xtp->raddr = *raddr;
450
451
0
  xtp->tstream = talloc_move(xtp, pstream);
452
453
0
  xtp->writev_send_fn = smbXcli_transport_tstream_writev_send;
454
0
  xtp->writev_recv_fn = smbXcli_transport_tstream_writev_recv;
455
0
  xtp->read_smb_send_fn = smbXcli_transport_tstream_read_smb_send;
456
0
  xtp->read_smb_recv_fn = smbXcli_transport_tstream_read_smb_recv;
457
0
  xtp->monitor_send_fn = smbXcli_transport_tstream_monitor_send;
458
0
  xtp->monitor_recv_fn = smbXcli_transport_tstream_monitor_recv;
459
460
0
  talloc_set_destructor(xtp, smbXcli_transport_destructor);
461
0
  return xtp;
462
0
}
463
464
static struct tevent_req *smbXcli_transport_bsd_writev_send(
465
        TALLOC_CTX *mem_ctx,
466
        struct tevent_context *ev,
467
        struct smbXcli_transport *xtp,
468
        struct tevent_queue *queue,
469
        struct iovec *iov,
470
        int count)
471
0
{
472
0
  return writev_send(mem_ctx,
473
0
         ev,
474
0
         queue,
475
0
         xtp->sock_fd,
476
0
         false,
477
0
         iov,
478
0
         count);
479
0
}
480
481
static ssize_t smbXcli_transport_bsd_writev_recv(struct tevent_req *req,
482
             int *perrno)
483
0
{
484
0
  return writev_recv(req, perrno);
485
0
}
486
487
static struct tevent_req *smbXcli_transport_bsd_read_smb_send(
488
        TALLOC_CTX *mem_ctx,
489
        struct tevent_context *ev,
490
        struct smbXcli_transport *xtp)
491
0
{
492
0
  return read_smb_send(mem_ctx, ev, xtp->sock_fd);
493
0
}
494
495
static ssize_t smbXcli_transport_bsd_read_smb_recv(
496
        struct tevent_req *req,
497
        TALLOC_CTX *mem_ctx,
498
        uint8_t **pbuf,
499
        int *perrno)
500
0
{
501
0
  return read_smb_recv(req, mem_ctx, pbuf, perrno);
502
0
}
503
504
static struct tevent_req *smbXcli_transport_bsd_monitor_send(
505
        TALLOC_CTX *mem_ctx,
506
        struct tevent_context *ev,
507
        struct smbXcli_transport *xtp)
508
0
{
509
0
  return wait_for_error_send(mem_ctx, ev, xtp->sock_fd);
510
0
}
511
512
static int smbXcli_transport_bsd_monitor_recv(struct tevent_req *req)
513
0
{
514
0
  return wait_for_error_recv(req);
515
0
}
516
517
struct smbXcli_transport *smbXcli_transport_bsd(
518
  TALLOC_CTX *mem_ctx,
519
  int *_fd,
520
  enum tls_verify_peer_state verify_peer,
521
  const struct smb_transport *tp)
522
0
{
523
0
  struct smbXcli_transport *xtp = NULL;
524
0
  int fd = *_fd;
525
0
  int ret;
526
527
0
  xtp = talloc_zero(mem_ctx, struct smbXcli_transport);
528
0
  if (xtp == NULL) {
529
0
    return NULL;
530
0
  }
531
532
0
  xtp->transport = *tp;
533
0
  xtp->sock_fd = fd;
534
0
  xtp->verify_peer = verify_peer;
535
536
0
  xtp->laddr.sa_socklen = sizeof(xtp->laddr.u);
537
0
  ret = getsockname(fd, &xtp->laddr.u.sa, &xtp->laddr.sa_socklen);
538
0
  if (ret == -1) {
539
0
    TALLOC_FREE(xtp);
540
0
    return NULL;
541
0
  }
542
543
0
  xtp->raddr.sa_socklen = sizeof(xtp->raddr.u);
544
0
  ret = getpeername(fd, &xtp->raddr.u.sa, &xtp->raddr.sa_socklen);
545
0
  if (ret == -1) {
546
0
    TALLOC_FREE(xtp);
547
0
    return NULL;
548
0
  }
549
550
0
  ret = set_blocking(fd, false);
551
0
  if (ret < 0) {
552
0
    TALLOC_FREE(xtp);
553
0
    return NULL;
554
0
  }
555
556
0
  xtp->writev_send_fn = smbXcli_transport_bsd_writev_send;
557
0
  xtp->writev_recv_fn = smbXcli_transport_bsd_writev_recv;
558
0
  xtp->read_smb_send_fn = smbXcli_transport_bsd_read_smb_send;
559
0
  xtp->read_smb_recv_fn = smbXcli_transport_bsd_read_smb_recv;
560
0
  xtp->monitor_send_fn = smbXcli_transport_bsd_monitor_send;
561
0
  xtp->monitor_recv_fn = smbXcli_transport_bsd_monitor_recv;
562
563
0
  *_fd = -1;
564
0
  talloc_set_destructor(xtp, smbXcli_transport_destructor);
565
0
  return xtp;
566
0
}
567
568
struct smbXcli_transport *smbXcli_transport_bsd_tstream(
569
  TALLOC_CTX *mem_ctx,
570
  int *fd,
571
  enum tls_verify_peer_state verify_peer,
572
  const struct smb_transport *tp)
573
0
{
574
0
  struct samba_sockaddr laddr = {
575
0
    .sa_socklen = sizeof(struct sockaddr_storage),
576
0
  };
577
0
  struct samba_sockaddr raddr = {
578
0
    .sa_socklen = sizeof(struct sockaddr_storage),
579
0
  };
580
0
  struct tstream_context *tstream = NULL;
581
0
  struct smbXcli_transport *xtp = NULL;
582
0
  int ret;
583
584
0
  ret = getsockname(*fd, &laddr.u.sa, &laddr.sa_socklen);
585
0
  if (ret == -1) {
586
0
    return NULL;
587
0
  }
588
589
0
  ret = getpeername(*fd, &raddr.u.sa, &raddr.sa_socklen);
590
0
  if (ret == -1) {
591
0
    return NULL;
592
0
  }
593
594
0
  ret = set_blocking(*fd, false);
595
0
  if (ret < 0) {
596
0
    return NULL;
597
0
  }
598
599
0
  ret = tstream_bsd_existing_socket(mem_ctx, *fd, &tstream);
600
0
  if (ret == -1) {
601
0
    return NULL;
602
0
  }
603
0
  *fd = -1;
604
0
  tstream_bsd_optimize_readv(tstream, true);
605
606
0
  xtp = smbXcli_transport_tstream(
607
0
    mem_ctx, &tstream, verify_peer, &laddr, &raddr, tp);
608
0
  TALLOC_FREE(tstream);
609
0
  return xtp;
610
0
}
611
612
static int smbXcli_conn_destructor(struct smbXcli_conn *conn)
613
0
{
614
  /*
615
   * NT_STATUS_OK, means we do not notify the callers
616
   */
617
0
  smbXcli_conn_disconnect(conn, NT_STATUS_OK);
618
619
0
  while (conn->sessions) {
620
0
    conn->sessions->conn = NULL;
621
0
    DLIST_REMOVE(conn->sessions, conn->sessions);
622
0
  }
623
624
0
  if (conn->smb1.trans_enc) {
625
0
    TALLOC_FREE(conn->smb1.trans_enc);
626
0
  }
627
628
0
  return 0;
629
0
}
630
631
struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
632
           struct smbXcli_transport **ptransport,
633
           const char *remote_name,
634
           enum smb_signing_setting signing_state,
635
           uint32_t smb1_capabilities,
636
           struct GUID *client_guid,
637
           uint32_t smb2_capabilities,
638
           const struct smb311_capabilities *smb3_capabilities)
639
0
{
640
0
  struct smbXcli_conn *conn = NULL;
641
642
0
  if (smb3_capabilities != NULL) {
643
0
    const struct smb3_signing_capabilities *sign_algos =
644
0
      &smb3_capabilities->signing;
645
0
    const struct smb3_encryption_capabilities *ciphers =
646
0
      &smb3_capabilities->encryption;
647
648
0
    SMB_ASSERT(sign_algos->num_algos <= SMB3_SIGNING_CAPABILITIES_MAX_ALGOS);
649
0
    SMB_ASSERT(ciphers->num_algos <= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS);
650
0
  }
651
652
0
  conn = talloc_zero(mem_ctx, struct smbXcli_conn);
653
0
  if (!conn) {
654
0
    return NULL;
655
0
  }
656
657
0
  conn->transport = talloc_move(conn, ptransport);
658
659
0
  conn->remote_name = talloc_strdup(conn, remote_name);
660
0
  if (conn->remote_name == NULL) {
661
0
    goto error;
662
0
  }
663
664
0
  conn->outgoing = tevent_queue_create(conn, "smbXcli_outgoing");
665
0
  if (conn->outgoing == NULL) {
666
0
    goto error;
667
0
  }
668
0
  conn->pending = NULL;
669
670
0
  conn->min_protocol = PROTOCOL_NONE;
671
0
  conn->max_protocol = PROTOCOL_NONE;
672
0
  conn->protocol = PROTOCOL_NONE;
673
674
0
  switch (signing_state) {
675
0
  case SMB_SIGNING_OFF:
676
    /* never */
677
0
    conn->allow_signing = false;
678
0
    conn->desire_signing = false;
679
0
    conn->mandatory_signing = false;
680
0
    break;
681
0
  case SMB_SIGNING_DEFAULT:
682
0
  case SMB_SIGNING_IF_REQUIRED:
683
    /* if the server requires it */
684
0
    conn->allow_signing = true;
685
0
    conn->desire_signing = false;
686
0
    conn->mandatory_signing = false;
687
0
    break;
688
0
  case SMB_SIGNING_DESIRED:
689
    /* if the server desires it */
690
0
    conn->allow_signing = true;
691
0
    conn->desire_signing = true;
692
0
    conn->mandatory_signing = false;
693
0
    break;
694
0
  case SMB_SIGNING_IPC_DEFAULT:
695
0
  case SMB_SIGNING_REQUIRED:
696
    /* always */
697
0
    conn->allow_signing = true;
698
0
    conn->desire_signing = true;
699
0
    conn->mandatory_signing = true;
700
0
    break;
701
0
  }
702
703
0
  conn->smb1.client.capabilities = smb1_capabilities;
704
0
  conn->smb1.client.max_xmit = UINT16_MAX;
705
706
0
  conn->smb1.capabilities = conn->smb1.client.capabilities;
707
0
  conn->smb1.max_xmit = 1024;
708
709
0
  conn->smb1.mid = 1;
710
711
  /* initialise signing */
712
0
  conn->smb1.signing = smb1_signing_init(conn,
713
0
                conn->allow_signing,
714
0
                conn->desire_signing,
715
0
                conn->mandatory_signing);
716
0
  if (!conn->smb1.signing) {
717
0
    goto error;
718
0
  }
719
720
0
  conn->smb2.client.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
721
0
  if (conn->mandatory_signing) {
722
0
    conn->smb2.client.security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
723
0
  }
724
0
  if (client_guid) {
725
0
    conn->smb2.client.guid = *client_guid;
726
0
  }
727
0
  conn->smb2.client.capabilities = smb2_capabilities;
728
0
  if (smb3_capabilities != NULL) {
729
0
    conn->smb2.client.smb3_capabilities = *smb3_capabilities;
730
0
  }
731
732
0
  conn->smb2.cur_credits = 1;
733
0
  conn->smb2.max_credits = 0;
734
0
  conn->smb2.io_priority = 1;
735
736
  /*
737
   * Samba and Windows servers accept a maximum of 16 MiB with a maximum
738
   * chunk length of 1 MiB.
739
   */
740
0
  conn->smb2.cc_chunk_len = 1024 * 1024;
741
0
  conn->smb2.cc_max_chunks = 16;
742
743
0
  talloc_set_destructor(conn, smbXcli_conn_destructor);
744
0
  return conn;
745
746
0
 error:
747
0
  TALLOC_FREE(conn);
748
0
  return NULL;
749
0
}
750
751
bool smbXcli_conn_is_connected(struct smbXcli_conn *conn)
752
0
{
753
0
  int ret;
754
755
0
  if (conn == NULL) {
756
0
    return false;
757
0
  }
758
759
0
  if (conn->transport == NULL) {
760
0
    return false;
761
0
  }
762
763
0
  if (conn->transport->tstream != NULL) {
764
0
    ret = tstream_pending_bytes(conn->transport->tstream);
765
0
    if (ret < 0) {
766
0
      return false;
767
0
    }
768
769
0
    return true;
770
0
  }
771
772
0
  if (conn->transport->sock_fd == -1) {
773
0
    return false;
774
0
  }
775
776
0
  ret = samba_socket_poll_or_sock_error(conn->transport->sock_fd);
777
0
  if (ret < 0) {
778
0
    return false;
779
0
  }
780
781
0
  return true;
782
0
}
783
784
enum protocol_types smbXcli_conn_protocol(struct smbXcli_conn *conn)
785
0
{
786
0
  return conn->protocol;
787
0
}
788
789
bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn)
790
0
{
791
0
  if (conn->protocol >= PROTOCOL_SMB2_02) {
792
0
    return true;
793
0
  }
794
795
0
  if (conn->smb1.capabilities & CAP_UNICODE) {
796
0
    return true;
797
0
  }
798
799
0
  return false;
800
0
}
801
802
bool smbXcli_conn_signing_mandatory(struct smbXcli_conn *conn)
803
0
{
804
0
  return conn->mandatory_signing;
805
0
}
806
807
bool smbXcli_conn_have_posix(struct smbXcli_conn *conn)
808
0
{
809
0
  if (conn->protocol >= PROTOCOL_SMB3_11) {
810
0
    return conn->smb2.server.smb311_posix;
811
0
  }
812
0
  if (conn->protocol <= PROTOCOL_NT1) {
813
0
    return (conn->smb1.capabilities & CAP_UNIX);
814
0
  }
815
0
  return false;
816
0
}
817
818
/*
819
 * [MS-SMB] 2.2.2.3.5 - SMB1 support for passing through
820
 * query/set commands to the file system
821
 */
822
bool smbXcli_conn_support_passthrough(struct smbXcli_conn *conn)
823
0
{
824
0
  if (conn->protocol >= PROTOCOL_SMB2_02) {
825
0
    return true;
826
0
  }
827
828
0
  if (conn->smb1.capabilities & CAP_W2K_SMBS) {
829
0
    return true;
830
0
  }
831
832
0
  return false;
833
0
}
834
835
void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options)
836
0
{
837
0
  if (conn->transport->sock_fd == -1) {
838
0
    return;
839
0
  }
840
841
0
  set_socket_options(conn->transport->sock_fd, options);
842
0
}
843
844
const struct sockaddr_storage *smbXcli_conn_local_sockaddr(struct smbXcli_conn *conn)
845
0
{
846
0
  return &conn->transport->laddr.u.ss;
847
0
}
848
849
const struct sockaddr_storage *smbXcli_conn_remote_sockaddr(struct smbXcli_conn *conn)
850
0
{
851
0
  return &conn->transport->raddr.u.ss;
852
0
}
853
854
const char *smbXcli_conn_remote_name(struct smbXcli_conn *conn)
855
0
{
856
0
  return conn->remote_name;
857
0
}
858
859
uint16_t smbXcli_conn_max_requests(struct smbXcli_conn *conn)
860
0
{
861
0
  if (conn->protocol >= PROTOCOL_SMB2_02) {
862
    /*
863
     * TODO...
864
     */
865
0
    return 1;
866
0
  }
867
868
0
  return conn->smb1.server.max_mux;
869
0
}
870
871
NTTIME smbXcli_conn_server_system_time(struct smbXcli_conn *conn)
872
0
{
873
0
  if (conn->protocol >= PROTOCOL_SMB2_02) {
874
0
    return conn->smb2.server.system_time;
875
0
  }
876
877
0
  return conn->smb1.server.system_time;
878
0
}
879
880
const DATA_BLOB *smbXcli_conn_server_gss_blob(struct smbXcli_conn *conn)
881
0
{
882
0
  if (conn->protocol >= PROTOCOL_SMB2_02) {
883
0
    return &conn->smb2.server.gss_blob;
884
0
  }
885
886
0
  return &conn->smb1.server.gss_blob;
887
0
}
888
889
const struct GUID *smbXcli_conn_server_guid(struct smbXcli_conn *conn)
890
0
{
891
0
  if (conn->protocol >= PROTOCOL_SMB2_02) {
892
0
    return &conn->smb2.server.guid;
893
0
  }
894
895
0
  return &conn->smb1.server.guid;
896
0
}
897
898
bool smbXcli_conn_get_force_channel_sequence(struct smbXcli_conn *conn)
899
0
{
900
0
  return conn->smb2.force_channel_sequence;
901
0
}
902
903
void smbXcli_conn_set_force_channel_sequence(struct smbXcli_conn *conn,
904
               bool v)
905
0
{
906
0
  conn->smb2.force_channel_sequence = v;
907
0
}
908
909
struct smbXcli_conn_samba_suicide_state {
910
  struct smbXcli_conn *conn;
911
  struct iovec iov;
912
  uint8_t buf[9];
913
  struct tevent_req *write_req;
914
  ssize_t (*writev_recv_fn)(struct tevent_req *req, int *perrno);
915
};
916
917
static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
918
                 enum tevent_req_state req_state);
919
static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq);
920
921
struct tevent_req *smbXcli_conn_samba_suicide_send(TALLOC_CTX *mem_ctx,
922
               struct tevent_context *ev,
923
               struct smbXcli_conn *conn,
924
               uint8_t exitcode)
925
0
{
926
0
  struct tevent_req *req, *subreq;
927
0
  struct smbXcli_conn_samba_suicide_state *state;
928
0
  struct smbXcli_transport *xtp = NULL;
929
930
0
  req = tevent_req_create(mem_ctx, &state,
931
0
        struct smbXcli_conn_samba_suicide_state);
932
0
  if (req == NULL) {
933
0
    return NULL;
934
0
  }
935
0
  state->conn = conn;
936
0
  SIVAL(state->buf, 4, SMB_SUICIDE_PACKET);
937
0
  SCVAL(state->buf, 8, exitcode);
938
0
  _smb_setlen_nbt(state->buf, sizeof(state->buf)-4);
939
940
0
  if (conn->suicide_req != NULL) {
941
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
942
0
    return tevent_req_post(req, ev);
943
0
  }
944
945
0
  state->iov.iov_base = state->buf;
946
0
  state->iov.iov_len = sizeof(state->buf);
947
948
0
  xtp = conn->transport;
949
0
  subreq = xtp->writev_send_fn(state,
950
0
             ev,
951
0
             xtp,
952
0
             conn->outgoing,
953
0
             &state->iov,
954
0
             1);
955
0
  if (tevent_req_nomem(subreq, req)) {
956
0
    return tevent_req_post(req, ev);
957
0
  }
958
0
  state->writev_recv_fn = xtp->writev_recv_fn;
959
0
  tevent_req_set_callback(subreq, smbXcli_conn_samba_suicide_done, req);
960
0
  state->write_req = subreq;
961
962
0
  tevent_req_set_cleanup_fn(req, smbXcli_conn_samba_suicide_cleanup);
963
964
  /*
965
   * We need to use tevent_req_defer_callback()
966
   * in order to allow smbXcli_conn_disconnect()
967
   * to do a safe cleanup.
968
   */
969
0
  tevent_req_defer_callback(req, ev);
970
0
  conn->suicide_req = req;
971
972
0
  return req;
973
0
}
974
975
static void smbXcli_conn_samba_suicide_cleanup(struct tevent_req *req,
976
                 enum tevent_req_state req_state)
977
0
{
978
0
  struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
979
0
    req, struct smbXcli_conn_samba_suicide_state);
980
981
0
  TALLOC_FREE(state->write_req);
982
983
0
  if (state->conn == NULL) {
984
0
    return;
985
0
  }
986
987
0
  if (state->conn->suicide_req == req) {
988
0
    state->conn->suicide_req = NULL;
989
0
  }
990
0
  state->conn = NULL;
991
0
}
992
993
static void smbXcli_conn_samba_suicide_done(struct tevent_req *subreq)
994
0
{
995
0
  struct tevent_req *req = tevent_req_callback_data(
996
0
    subreq, struct tevent_req);
997
0
  struct smbXcli_conn_samba_suicide_state *state = tevent_req_data(
998
0
    req, struct smbXcli_conn_samba_suicide_state);
999
0
  ssize_t nwritten;
1000
0
  int err;
1001
1002
0
  state->write_req = NULL;
1003
1004
0
  nwritten = state->writev_recv_fn(subreq, &err);
1005
0
  TALLOC_FREE(subreq);
1006
0
  if (nwritten == -1) {
1007
    /* here, we need to notify all pending requests */
1008
0
    NTSTATUS status = map_nt_error_from_unix_common(err);
1009
0
    smbXcli_conn_disconnect(state->conn, status);
1010
0
    return;
1011
0
  }
1012
0
  tevent_req_done(req);
1013
0
}
1014
1015
NTSTATUS smbXcli_conn_samba_suicide_recv(struct tevent_req *req)
1016
0
{
1017
0
  return tevent_req_simple_recv_ntstatus(req);
1018
0
}
1019
1020
NTSTATUS smbXcli_conn_samba_suicide(struct smbXcli_conn *conn,
1021
            uint8_t exitcode)
1022
0
{
1023
0
  TALLOC_CTX *frame = talloc_stackframe();
1024
0
  struct tevent_context *ev;
1025
0
  struct tevent_req *req;
1026
0
  NTSTATUS status = NT_STATUS_NO_MEMORY;
1027
0
  bool ok;
1028
1029
0
  if (smbXcli_conn_has_async_calls(conn)) {
1030
    /*
1031
     * Can't use sync call while an async call is in flight
1032
     */
1033
0
    status = NT_STATUS_INVALID_PARAMETER_MIX;
1034
0
    goto fail;
1035
0
  }
1036
0
  ev = samba_tevent_context_init(frame);
1037
0
  if (ev == NULL) {
1038
0
    goto fail;
1039
0
  }
1040
0
  req = smbXcli_conn_samba_suicide_send(frame, ev, conn, exitcode);
1041
0
  if (req == NULL) {
1042
0
    goto fail;
1043
0
  }
1044
0
  ok = tevent_req_poll_ntstatus(req, ev, &status);
1045
0
  if (!ok) {
1046
0
    goto fail;
1047
0
  }
1048
0
  status = smbXcli_conn_samba_suicide_recv(req);
1049
0
 fail:
1050
0
  TALLOC_FREE(frame);
1051
0
  return status;
1052
0
}
1053
1054
uint32_t smb1cli_conn_capabilities(struct smbXcli_conn *conn)
1055
0
{
1056
0
  return conn->smb1.capabilities;
1057
0
}
1058
1059
uint32_t smb1cli_conn_max_xmit(struct smbXcli_conn *conn)
1060
0
{
1061
0
  return conn->smb1.max_xmit;
1062
0
}
1063
1064
bool smb1cli_conn_req_possible(struct smbXcli_conn *conn)
1065
0
{
1066
0
  size_t pending = talloc_array_length(conn->pending);
1067
0
  uint16_t possible = conn->smb1.server.max_mux;
1068
1069
0
  if (pending >= possible) {
1070
0
    return false;
1071
0
  }
1072
1073
0
  return true;
1074
0
}
1075
1076
uint32_t smb1cli_conn_server_session_key(struct smbXcli_conn *conn)
1077
0
{
1078
0
  return conn->smb1.server.session_key;
1079
0
}
1080
1081
const uint8_t *smb1cli_conn_server_challenge(struct smbXcli_conn *conn)
1082
0
{
1083
0
  return conn->smb1.server.challenge;
1084
0
}
1085
1086
uint16_t smb1cli_conn_server_security_mode(struct smbXcli_conn *conn)
1087
0
{
1088
0
  return conn->smb1.server.security_mode;
1089
0
}
1090
1091
bool smb1cli_conn_server_readbraw(struct smbXcli_conn *conn)
1092
0
{
1093
0
  return conn->smb1.server.readbraw;
1094
0
}
1095
1096
bool smb1cli_conn_server_writebraw(struct smbXcli_conn *conn)
1097
0
{
1098
0
  return conn->smb1.server.writebraw;
1099
0
}
1100
1101
bool smb1cli_conn_server_lockread(struct smbXcli_conn *conn)
1102
0
{
1103
0
  return conn->smb1.server.lockread;
1104
0
}
1105
1106
bool smb1cli_conn_server_writeunlock(struct smbXcli_conn *conn)
1107
0
{
1108
0
  return conn->smb1.server.writeunlock;
1109
0
}
1110
1111
int smb1cli_conn_server_time_zone(struct smbXcli_conn *conn)
1112
0
{
1113
0
  return conn->smb1.server.time_zone;
1114
0
}
1115
1116
bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
1117
           const DATA_BLOB user_session_key,
1118
           const DATA_BLOB response)
1119
0
{
1120
0
  return smb1_signing_activate(conn->smb1.signing,
1121
0
            user_session_key,
1122
0
            response);
1123
0
}
1124
1125
bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
1126
        const uint8_t *buf, uint32_t seqnum)
1127
0
{
1128
0
  const uint8_t *hdr = buf + NBT_HDR_SIZE;
1129
0
  size_t len = smb_len_nbt(buf);
1130
1131
0
  return smb1_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
1132
0
}
1133
1134
bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
1135
0
{
1136
0
  return smb1_signing_is_active(conn->smb1.signing);
1137
0
}
1138
1139
void smb1cli_conn_set_encryption(struct smbXcli_conn *conn,
1140
         struct smb_trans_enc_state *es)
1141
0
{
1142
  /* Replace the old state, if any. */
1143
0
  if (conn->smb1.trans_enc) {
1144
0
    TALLOC_FREE(conn->smb1.trans_enc);
1145
0
  }
1146
0
  conn->smb1.trans_enc = es;
1147
0
}
1148
1149
bool smb1cli_conn_encryption_on(struct smbXcli_conn *conn)
1150
0
{
1151
0
  return common_encryption_on(conn->smb1.trans_enc);
1152
0
}
1153
1154
1155
static NTSTATUS smb1cli_pull_raw_error(const uint8_t *hdr)
1156
0
{
1157
0
  uint32_t flags2 = SVAL(hdr, HDR_FLG2);
1158
0
  NTSTATUS status = NT_STATUS(IVAL(hdr, HDR_RCLS));
1159
1160
0
  if (NT_STATUS_IS_OK(status)) {
1161
0
    return NT_STATUS_OK;
1162
0
  }
1163
1164
0
  if (flags2 & FLAGS2_32_BIT_ERROR_CODES) {
1165
0
    return status;
1166
0
  }
1167
1168
0
  return NT_STATUS_DOS(CVAL(hdr, HDR_RCLS), SVAL(hdr, HDR_ERR));
1169
0
}
1170
1171
/**
1172
 * Is the SMB command able to hold an AND_X successor
1173
 * @param[in] cmd The SMB command in question
1174
 * @retval Can we add a chained request after "cmd"?
1175
 */
1176
bool smb1cli_is_andx_req(uint8_t cmd)
1177
0
{
1178
0
  switch (cmd) {
1179
0
  case SMBtconX:
1180
0
  case SMBlockingX:
1181
0
  case SMBopenX:
1182
0
  case SMBreadX:
1183
0
  case SMBwriteX:
1184
0
  case SMBsesssetupX:
1185
0
  case SMBulogoffX:
1186
0
  case SMBntcreateX:
1187
0
    return true;
1188
0
    break;
1189
0
  default:
1190
0
    break;
1191
0
  }
1192
1193
0
  return false;
1194
0
}
1195
1196
static uint16_t smb1cli_alloc_mid(struct smbXcli_conn *conn)
1197
0
{
1198
0
  size_t num_pending = talloc_array_length(conn->pending);
1199
0
  uint16_t result;
1200
1201
0
  if (conn->protocol == PROTOCOL_NONE) {
1202
    /*
1203
     * This is what windows sends on the SMB1 Negprot request
1204
     * and some vendors reuse the SMB1 MID as SMB2 sequence number.
1205
     */
1206
0
    return 0;
1207
0
  }
1208
1209
0
  while (true) {
1210
0
    size_t i;
1211
1212
0
    result = conn->smb1.mid++;
1213
0
    if ((result == 0) || (result == 0xffff)) {
1214
0
      continue;
1215
0
    }
1216
1217
0
    for (i=0; i<num_pending; i++) {
1218
0
      if (result == smb1cli_req_mid(conn->pending[i])) {
1219
0
        break;
1220
0
      }
1221
0
    }
1222
1223
0
    if (i == num_pending) {
1224
0
      return result;
1225
0
    }
1226
0
  }
1227
0
}
1228
1229
static NTSTATUS smbXcli_req_cancel_write_req(struct tevent_req *req)
1230
0
{
1231
0
  struct smbXcli_req_state *state =
1232
0
    tevent_req_data(req,
1233
0
    struct smbXcli_req_state);
1234
0
  struct smbXcli_conn *conn = state->conn;
1235
0
  size_t num_pending = talloc_array_length(conn->pending);
1236
0
  ssize_t ret;
1237
0
  int err;
1238
0
  bool ok;
1239
1240
0
  if (state->write_req == NULL) {
1241
0
    return NT_STATUS_OK;
1242
0
  }
1243
1244
  /*
1245
   * Check if it's possible to cancel the request.
1246
   * If the result is true it's not too late.
1247
   * See writev_cancel().
1248
   */
1249
0
  ok = tevent_req_cancel(state->write_req);
1250
0
  if (ok) {
1251
0
    TALLOC_FREE(state->write_req);
1252
1253
0
    if (conn->protocol >= PROTOCOL_SMB2_02) {
1254
      /*
1255
       * SMB2 has a sane signing state.
1256
       */
1257
0
      return NT_STATUS_OK;
1258
0
    }
1259
1260
0
    if (num_pending > 1) {
1261
      /*
1262
       * We have more pending requests following us.  This
1263
       * means the signing state will be broken for them.
1264
       *
1265
       * As a solution we could add the requests directly to
1266
       * our outgoing queue and do the signing in the trigger
1267
       * function and then use writev_send() without passing a
1268
       * queue.  That way we'll only sign packets we're most
1269
       * likely send to the wire.
1270
       */
1271
0
      return NT_STATUS_REQUEST_OUT_OF_SEQUENCE;
1272
0
    }
1273
1274
    /*
1275
     * If we're the only request that's
1276
     * pending, we're able to recover the signing
1277
     * state.
1278
     */
1279
0
    smb1_signing_cancel_reply(conn->smb1.signing,
1280
0
           state->smb1.one_way_seqnum);
1281
0
    return NT_STATUS_OK;
1282
0
  }
1283
1284
0
  ret = state->writev_recv_fn(state->write_req, &err);
1285
0
  TALLOC_FREE(state->write_req);
1286
0
  if (ret == -1) {
1287
0
    return map_nt_error_from_unix_common(err);
1288
0
  }
1289
1290
0
  return NT_STATUS_OK;
1291
0
}
1292
1293
void smbXcli_req_unset_pending(struct tevent_req *req)
1294
0
{
1295
0
  struct smbXcli_req_state *state =
1296
0
    tevent_req_data(req,
1297
0
    struct smbXcli_req_state);
1298
0
  struct smbXcli_conn *conn = state->conn;
1299
0
  size_t num_pending = talloc_array_length(conn->pending);
1300
0
  size_t i;
1301
0
  NTSTATUS cancel_status;
1302
1303
0
  cancel_status = smbXcli_req_cancel_write_req(req);
1304
1305
0
  if (state->smb1.mid != 0) {
1306
    /*
1307
     * This is a [nt]trans[2] request which waits
1308
     * for more than one reply.
1309
     */
1310
0
    if (!NT_STATUS_IS_OK(cancel_status)) {
1311
      /*
1312
       * If the write_req cancel didn't work
1313
       * we can't use the connection anymore.
1314
       */
1315
0
      smbXcli_conn_disconnect(conn, cancel_status);
1316
0
      return;
1317
0
    }
1318
0
    return;
1319
0
  }
1320
1321
0
  tevent_req_set_cleanup_fn(req, NULL);
1322
1323
0
  if (num_pending == 1) {
1324
    /*
1325
     * The pending read_smb tevent_req is a child of
1326
     * conn->pending. So if nothing is pending anymore, we need to
1327
     * delete the socket read fde.
1328
     */
1329
    /* TODO: smbXcli_conn_cancel_read_req */
1330
0
    TALLOC_FREE(conn->pending);
1331
0
    conn->read_smb_req = NULL;
1332
1333
0
    if (!NT_STATUS_IS_OK(cancel_status)) {
1334
      /*
1335
       * If the write_req cancel didn't work
1336
       * we can't use the connection anymore.
1337
       */
1338
0
      smbXcli_conn_disconnect(conn, cancel_status);
1339
0
      return;
1340
0
    }
1341
0
    return;
1342
0
  }
1343
1344
0
  for (i=0; i<num_pending; i++) {
1345
0
    if (req == conn->pending[i]) {
1346
0
      break;
1347
0
    }
1348
0
  }
1349
0
  if (i == num_pending) {
1350
    /*
1351
     * Something's seriously broken. Just returning here is the
1352
     * right thing nevertheless, the point of this routine is to
1353
     * remove ourselves from conn->pending.
1354
     */
1355
1356
0
    if (!NT_STATUS_IS_OK(cancel_status)) {
1357
      /*
1358
       * If the write_req cancel didn't work
1359
       * we can't use the connection anymore.
1360
       */
1361
0
      smbXcli_conn_disconnect(conn, cancel_status);
1362
0
      return;
1363
0
    }
1364
0
    return;
1365
0
  }
1366
1367
0
  ARRAY_DEL_ELEMENT(conn->pending, i, num_pending);
1368
1369
  /*
1370
   * No NULL check here, we're shrinking by sizeof(void *), and
1371
   * talloc_realloc just adjusts the size for this.
1372
   */
1373
0
  conn->pending = talloc_realloc(NULL, conn->pending, struct tevent_req *,
1374
0
               num_pending - 1);
1375
1376
0
  if (!NT_STATUS_IS_OK(cancel_status)) {
1377
    /*
1378
     * If the write_req cancel didn't work
1379
     * we can't use the connection anymore.
1380
     */
1381
0
    smbXcli_conn_disconnect(conn, cancel_status);
1382
0
    return;
1383
0
  }
1384
0
  return;
1385
0
}
1386
1387
static void smbXcli_req_cleanup(struct tevent_req *req,
1388
        enum tevent_req_state req_state)
1389
0
{
1390
0
  struct smbXcli_req_state *state =
1391
0
    tevent_req_data(req,
1392
0
    struct smbXcli_req_state);
1393
0
  struct smbXcli_conn *conn = state->conn;
1394
0
  NTSTATUS cancel_status;
1395
1396
0
  switch (req_state) {
1397
0
  case TEVENT_REQ_RECEIVED:
1398
    /*
1399
     * Make sure we really remove it from
1400
     * the pending array on destruction.
1401
     *
1402
     * smbXcli_req_unset_pending() calls
1403
     * smbXcli_req_cancel_write_req() internal
1404
     */
1405
0
    state->smb1.mid = 0;
1406
0
    smbXcli_req_unset_pending(req);
1407
0
    return;
1408
0
  default:
1409
0
    cancel_status = smbXcli_req_cancel_write_req(req);
1410
0
    if (!NT_STATUS_IS_OK(cancel_status)) {
1411
      /*
1412
       * If the write_req cancel didn't work
1413
       * we can't use the connection anymore.
1414
       */
1415
0
      smbXcli_conn_disconnect(conn, cancel_status);
1416
0
      return;
1417
0
    }
1418
0
    return;
1419
0
  }
1420
0
}
1421
1422
static bool smb1cli_req_cancel(struct tevent_req *req);
1423
static bool smb2cli_req_cancel(struct tevent_req *req);
1424
1425
static bool smbXcli_req_cancel(struct tevent_req *req)
1426
0
{
1427
0
  struct smbXcli_req_state *state =
1428
0
    tevent_req_data(req,
1429
0
    struct smbXcli_req_state);
1430
1431
0
  if (!smbXcli_conn_is_connected(state->conn)) {
1432
0
    return false;
1433
0
  }
1434
1435
0
  if (state->conn->protocol == PROTOCOL_NONE) {
1436
0
    return false;
1437
0
  }
1438
1439
0
  if (state->conn->protocol >= PROTOCOL_SMB2_02) {
1440
0
    return smb2cli_req_cancel(req);
1441
0
  }
1442
1443
0
  return smb1cli_req_cancel(req);
1444
0
}
1445
1446
static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn);
1447
1448
bool smbXcli_req_set_pending(struct tevent_req *req)
1449
0
{
1450
0
  struct smbXcli_req_state *state =
1451
0
    tevent_req_data(req,
1452
0
    struct smbXcli_req_state);
1453
0
  struct smbXcli_conn *conn = state->conn;
1454
0
  struct tevent_req **pending = NULL;
1455
0
  size_t num_pending = talloc_array_length(conn->pending);
1456
1457
0
  if (!smbXcli_conn_is_connected(conn)) {
1458
0
    return false;
1459
0
  }
1460
1461
0
  pending = talloc_realloc(conn, conn->pending, struct tevent_req *,
1462
0
         num_pending+1);
1463
0
  if (pending == NULL) {
1464
0
    return false;
1465
0
  }
1466
0
  pending[num_pending] = req;
1467
0
  conn->pending = pending;
1468
0
  tevent_req_set_cleanup_fn(req, smbXcli_req_cleanup);
1469
0
  tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
1470
1471
0
  if (!smbXcli_conn_receive_next(conn)) {
1472
    /*
1473
     * the caller should notify the current request
1474
     *
1475
     * And all other pending requests get notified
1476
     * by smbXcli_conn_disconnect().
1477
     */
1478
0
    smbXcli_req_unset_pending(req);
1479
0
    smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
1480
0
    return false;
1481
0
  }
1482
1483
0
  return true;
1484
0
}
1485
1486
static void smbXcli_conn_received(struct tevent_req *subreq);
1487
1488
static bool smbXcli_conn_receive_next(struct smbXcli_conn *conn)
1489
0
{
1490
0
  size_t num_pending = talloc_array_length(conn->pending);
1491
0
  struct tevent_req *req;
1492
0
  struct smbXcli_req_state *state;
1493
0
  struct smbXcli_transport *xtp = conn->transport;
1494
1495
0
  if (conn->read_smb_req != NULL) {
1496
0
    return true;
1497
0
  }
1498
1499
0
  if (num_pending == 0) {
1500
0
    if (conn->smb2.mid < UINT64_MAX) {
1501
      /* no more pending requests, so we are done for now */
1502
0
      return true;
1503
0
    }
1504
1505
    /*
1506
     * If there are no more SMB2 requests possible,
1507
     * because we are out of message ids,
1508
     * we need to disconnect.
1509
     */
1510
0
    smbXcli_conn_disconnect(conn, NT_STATUS_CONNECTION_ABORTED);
1511
0
    return true;
1512
0
  }
1513
1514
0
  req = conn->pending[0];
1515
0
  state = tevent_req_data(req, struct smbXcli_req_state);
1516
1517
  /*
1518
   * We're the first ones, add the read_smb request that waits for the
1519
   * answer from the server
1520
   */
1521
0
  xtp = conn->transport;
1522
0
  conn->read_smb_req = xtp->read_smb_send_fn(conn->pending,
1523
0
               state->ev,
1524
0
               xtp);
1525
0
  if (conn->read_smb_req == NULL) {
1526
0
    return false;
1527
0
  }
1528
0
  tevent_req_set_callback(conn->read_smb_req, smbXcli_conn_received, conn);
1529
0
  return true;
1530
0
}
1531
1532
void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status)
1533
0
{
1534
0
  struct smbXcli_session *session;
1535
0
  int sock_fd = conn->transport->sock_fd;
1536
0
  struct tstream_context *tstream = conn->transport->tstream;
1537
1538
0
  tevent_queue_stop(conn->outgoing);
1539
1540
0
  conn->transport->sock_fd = -1;
1541
0
  conn->transport->tstream = NULL;
1542
1543
0
  session = conn->sessions;
1544
0
  if (talloc_array_length(conn->pending) == 0) {
1545
    /*
1546
     * if we do not have pending requests
1547
     * there is no need to update the channel_sequence
1548
     */
1549
0
    session = NULL;
1550
0
  }
1551
0
  for (; session; session = session->next) {
1552
0
    smb2cli_session_increment_channel_sequence(session);
1553
0
  }
1554
1555
0
  if (conn->monitor_req != NULL) {
1556
    /*
1557
     * smbXcli_conn_monitor_send()
1558
     * used tevent_req_defer_callback() already.
1559
     */
1560
0
    if (!NT_STATUS_IS_OK(status)) {
1561
0
      tevent_req_nterror(conn->monitor_req, status);
1562
0
    }
1563
0
    conn->monitor_req = NULL;
1564
0
  }
1565
1566
0
  if (conn->suicide_req != NULL) {
1567
    /*
1568
     * smbXcli_conn_samba_suicide_send()
1569
     * used tevent_req_defer_callback() already.
1570
     */
1571
0
    if (!NT_STATUS_IS_OK(status)) {
1572
0
      tevent_req_nterror(conn->suicide_req, status);
1573
0
    }
1574
0
    conn->suicide_req = NULL;
1575
0
  }
1576
1577
  /*
1578
   * Cancel all pending requests. We do not do a for-loop walking
1579
   * conn->pending because that array changes in
1580
   * smbXcli_req_unset_pending.
1581
   */
1582
0
  while (conn->pending != NULL &&
1583
0
         talloc_array_length(conn->pending) > 0) {
1584
0
    struct tevent_req *req;
1585
0
    struct smbXcli_req_state *state;
1586
0
    struct tevent_req **chain;
1587
0
    size_t num_chained;
1588
0
    size_t i;
1589
1590
0
    req = conn->pending[0];
1591
0
    state = tevent_req_data(req, struct smbXcli_req_state);
1592
1593
0
    if (state->smb1.chained_requests == NULL) {
1594
0
      bool in_progress;
1595
1596
      /*
1597
       * We're dead. No point waiting for trans2
1598
       * replies.
1599
       */
1600
0
      state->smb1.mid = 0;
1601
1602
0
      smbXcli_req_unset_pending(req);
1603
1604
0
      if (NT_STATUS_IS_OK(status)) {
1605
        /* do not notify the callers */
1606
0
        continue;
1607
0
      }
1608
1609
0
      in_progress = tevent_req_is_in_progress(req);
1610
0
      if (!in_progress) {
1611
        /*
1612
         * already finished
1613
         */
1614
0
        continue;
1615
0
      }
1616
1617
      /*
1618
       * we need to defer the callback, because we may notify
1619
       * more then one caller.
1620
       */
1621
0
      tevent_req_defer_callback(req, state->ev);
1622
0
      tevent_req_nterror(req, status);
1623
0
      continue;
1624
0
    }
1625
1626
0
    chain = talloc_move(conn, &state->smb1.chained_requests);
1627
0
    num_chained = talloc_array_length(chain);
1628
1629
0
    for (i=0; i<num_chained; i++) {
1630
0
      bool in_progress;
1631
1632
0
      req = chain[i];
1633
0
      state = tevent_req_data(req, struct smbXcli_req_state);
1634
1635
      /*
1636
       * We're dead. No point waiting for trans2
1637
       * replies.
1638
       */
1639
0
      state->smb1.mid = 0;
1640
1641
0
      smbXcli_req_unset_pending(req);
1642
1643
0
      if (NT_STATUS_IS_OK(status)) {
1644
        /* do not notify the callers */
1645
0
        continue;
1646
0
      }
1647
1648
0
      in_progress = tevent_req_is_in_progress(req);
1649
0
      if (!in_progress) {
1650
        /*
1651
         * already finished
1652
         */
1653
0
        continue;
1654
0
      }
1655
1656
      /*
1657
       * we need to defer the callback, because we may notify
1658
       * more than one caller.
1659
       */
1660
0
      tevent_req_defer_callback(req, state->ev);
1661
0
      tevent_req_nterror(req, status);
1662
0
    }
1663
0
    TALLOC_FREE(chain);
1664
0
  }
1665
1666
0
  if (sock_fd != -1) {
1667
0
    close(sock_fd);
1668
0
  }
1669
0
  TALLOC_FREE(tstream);
1670
0
}
1671
1672
struct smbXcli_conn_monitor_state {
1673
  struct smbXcli_conn *conn;
1674
  struct tevent_req *monitor_req;
1675
  int (*monitor_recv_fn)(struct tevent_req *req);
1676
};
1677
1678
static void smbXcli_conn_monitor_cleanup(struct tevent_req *req,
1679
           enum tevent_req_state req_state);
1680
static void smbXcli_conn_monitor_done(struct tevent_req *subreq);
1681
1682
struct tevent_req *smbXcli_conn_monitor_send(TALLOC_CTX *mem_ctx,
1683
               struct tevent_context *ev,
1684
               struct smbXcli_conn *conn)
1685
0
{
1686
0
  struct tevent_req *req = NULL;
1687
0
  struct smbXcli_conn_monitor_state *state = NULL;
1688
0
  struct tevent_req *subreq = NULL;
1689
0
  struct smbXcli_transport *xtp = NULL;
1690
0
  bool ok;
1691
1692
0
  req = tevent_req_create(mem_ctx, &state,
1693
0
        struct smbXcli_conn_monitor_state);
1694
0
  if (req == NULL) {
1695
0
    return NULL;
1696
0
  }
1697
0
  state->conn = conn;
1698
1699
0
  if (conn->monitor_req != NULL) {
1700
0
    tevent_req_nterror(req, NT_STATUS_ALREADY_REGISTERED);
1701
0
    return tevent_req_post(req, ev);
1702
0
  }
1703
1704
0
  tevent_req_set_cleanup_fn(req, smbXcli_conn_monitor_cleanup);
1705
1706
  /*
1707
   * We need to use tevent_req_defer_callback()
1708
   * in order to allow smbXcli_conn_disconnect()
1709
   * to do a safe cleanup.
1710
   */
1711
0
  tevent_req_defer_callback(req, ev);
1712
0
  conn->monitor_req = req;
1713
1714
0
  ok = smbXcli_conn_is_connected(conn);
1715
0
  if (!ok) {
1716
0
    smbXcli_conn_disconnect(conn,
1717
0
        NT_STATUS_CONNECTION_DISCONNECTED);
1718
0
    return tevent_req_post(req, ev);
1719
0
  }
1720
1721
0
  xtp = conn->transport;
1722
0
  subreq = xtp->monitor_send_fn(state, ev, xtp);
1723
0
  if (tevent_req_nomem(subreq, req)) {
1724
0
    return tevent_req_post(req, ev);
1725
0
  }
1726
0
  state->monitor_recv_fn = xtp->monitor_recv_fn;
1727
0
  tevent_req_set_callback(subreq, smbXcli_conn_monitor_done, req);
1728
0
  state->monitor_req = subreq;
1729
1730
0
  return req;
1731
0
}
1732
1733
static void smbXcli_conn_monitor_cleanup(struct tevent_req *req,
1734
           enum tevent_req_state req_state)
1735
0
{
1736
0
  struct smbXcli_conn_monitor_state *state = tevent_req_data(
1737
0
    req, struct smbXcli_conn_monitor_state);
1738
1739
0
  TALLOC_FREE(state->monitor_req);
1740
1741
0
  if (state->conn == NULL) {
1742
0
    return;
1743
0
  }
1744
1745
0
  if (state->conn->monitor_req == req) {
1746
0
    state->conn->monitor_req = NULL;
1747
0
  }
1748
0
  state->conn = NULL;
1749
0
}
1750
1751
static void smbXcli_conn_monitor_done(struct tevent_req *subreq)
1752
0
{
1753
0
  struct tevent_req *req = tevent_req_callback_data(subreq,
1754
0
                struct tevent_req);
1755
0
  struct smbXcli_conn_monitor_state *state = tevent_req_data(
1756
0
    req, struct smbXcli_conn_monitor_state);
1757
0
  NTSTATUS status;
1758
0
  int err;
1759
1760
0
  state->monitor_req = NULL;
1761
1762
0
  err = state->monitor_recv_fn(subreq);
1763
0
  TALLOC_FREE(subreq);
1764
  /* here, we need to notify all pending requests */
1765
0
  status = map_nt_error_from_unix_common(err);
1766
0
  smbXcli_conn_disconnect(state->conn, status);
1767
0
}
1768
1769
NTSTATUS smbXcli_conn_monitor_recv(struct tevent_req *req)
1770
0
{
1771
0
  return tevent_req_simple_recv_ntstatus(req);
1772
0
}
1773
1774
NTSTATUS smbXcli_conn_monitor_once(struct smbXcli_conn *conn)
1775
0
{
1776
0
  TALLOC_CTX *frame = talloc_stackframe();
1777
0
  struct tevent_context *ev;
1778
0
  struct tevent_req *req;
1779
0
  NTSTATUS status = NT_STATUS_NO_MEMORY;
1780
0
  bool ok;
1781
1782
0
  if (smbXcli_conn_has_async_calls(conn)) {
1783
    /*
1784
     * Can't use sync call while an async call is in flight
1785
     */
1786
0
    status = NT_STATUS_INVALID_PARAMETER_MIX;
1787
0
    goto fail;
1788
0
  }
1789
0
  ev = samba_tevent_context_init(frame);
1790
0
  if (ev == NULL) {
1791
0
    goto fail;
1792
0
  }
1793
  /*
1794
   * We want tevent_req_poll()
1795
   * to return -1 and errno=EAGAIN
1796
   * instead of blocking in [e]poll waiting
1797
   * for external events to happen.
1798
   *
1799
   * So we use tevent_context_set_wait_timeout(0)
1800
   * that will cause tevent_loop_once() in
1801
   * tevent_req_poll() to break with EAGAIN.
1802
   * It also means that tevent_req_is_in_progress()
1803
   * would still return true.
1804
   */
1805
0
  tevent_context_set_wait_timeout(ev, 0);
1806
0
  req = smbXcli_conn_monitor_send(frame, ev, conn);
1807
0
  if (req == NULL) {
1808
0
    goto fail;
1809
0
  }
1810
0
  ok = tevent_req_poll(req, ev);
1811
0
  if (!ok) {
1812
0
    if (errno == EAGAIN) {
1813
      /*
1814
       * This is exactly what we want:
1815
       * no existing events happened
1816
       * and we avoid blocking in
1817
       * [e]poll waiting.
1818
       *
1819
       * See also the comment above before
1820
       * tevent_context_set_wait_timeout!
1821
       *
1822
       * We don't call smbXcli_conn_monitor_recv()
1823
       * and let TALLOC_FREE(frame) destroy req
1824
       * as well.
1825
       */
1826
0
      status = NT_STATUS_OK;
1827
0
      goto fail;
1828
0
    }
1829
0
    status = map_nt_error_from_unix_common(errno);
1830
0
    goto fail;
1831
0
  }
1832
0
  status = smbXcli_conn_monitor_recv(req);
1833
0
fail:
1834
0
  TALLOC_FREE(frame);
1835
0
  return status;
1836
0
}
1837
1838
/*
1839
 * Fetch a smb request's mid. Only valid after the request has been sent by
1840
 * smb1cli_req_send().
1841
 */
1842
uint16_t smb1cli_req_mid(struct tevent_req *req)
1843
0
{
1844
0
  struct smbXcli_req_state *state =
1845
0
    tevent_req_data(req,
1846
0
    struct smbXcli_req_state);
1847
1848
0
  if (state->smb1.mid != 0) {
1849
0
    return state->smb1.mid;
1850
0
  }
1851
1852
0
  return SVAL(state->smb1.hdr, HDR_MID);
1853
0
}
1854
1855
void smb1cli_req_set_mid(struct tevent_req *req, uint16_t mid)
1856
0
{
1857
0
  struct smbXcli_req_state *state =
1858
0
    tevent_req_data(req,
1859
0
    struct smbXcli_req_state);
1860
1861
0
  state->smb1.mid = mid;
1862
0
}
1863
1864
uint32_t smb1cli_req_seqnum(struct tevent_req *req)
1865
0
{
1866
0
  struct smbXcli_req_state *state =
1867
0
    tevent_req_data(req,
1868
0
    struct smbXcli_req_state);
1869
1870
0
  return state->smb1.seqnum;
1871
0
}
1872
1873
void smb1cli_req_set_seqnum(struct tevent_req *req, uint32_t seqnum)
1874
0
{
1875
0
  struct smbXcli_req_state *state =
1876
0
    tevent_req_data(req,
1877
0
    struct smbXcli_req_state);
1878
1879
0
  state->smb1.seqnum = seqnum;
1880
0
}
1881
1882
static size_t smbXcli_iov_len(const struct iovec *iov, int count)
1883
0
{
1884
0
  ssize_t ret = iov_buflen(iov, count);
1885
1886
  /* Ignore the overflow case for now ... */
1887
0
  return ret;
1888
0
}
1889
1890
static void smb1cli_req_flags(enum protocol_types protocol,
1891
            uint32_t smb1_capabilities,
1892
            uint8_t smb_command,
1893
            uint8_t additional_flags,
1894
            uint8_t clear_flags,
1895
            uint8_t *_flags,
1896
            uint16_t additional_flags2,
1897
            uint16_t clear_flags2,
1898
            uint16_t *_flags2)
1899
0
{
1900
0
  uint8_t flags = 0;
1901
0
  uint16_t flags2 = 0;
1902
1903
0
  if (protocol >= PROTOCOL_LANMAN1) {
1904
0
    flags |= FLAG_CASELESS_PATHNAMES;
1905
0
    flags |= FLAG_CANONICAL_PATHNAMES;
1906
0
  }
1907
1908
0
  if (protocol >= PROTOCOL_LANMAN2) {
1909
0
    flags2 |= FLAGS2_LONG_PATH_COMPONENTS;
1910
0
    flags2 |= FLAGS2_EXTENDED_ATTRIBUTES;
1911
0
  }
1912
1913
0
  if (protocol >= PROTOCOL_NT1) {
1914
0
    flags2 |= FLAGS2_IS_LONG_NAME;
1915
1916
0
    if (smb1_capabilities & CAP_UNICODE) {
1917
0
      flags2 |= FLAGS2_UNICODE_STRINGS;
1918
0
    }
1919
0
    if (smb1_capabilities & CAP_STATUS32) {
1920
0
      flags2 |= FLAGS2_32_BIT_ERROR_CODES;
1921
0
    }
1922
0
    if (smb1_capabilities & CAP_EXTENDED_SECURITY) {
1923
0
      flags2 |= FLAGS2_EXTENDED_SECURITY;
1924
0
    }
1925
0
  }
1926
1927
0
  flags |= additional_flags;
1928
0
  flags &= ~clear_flags;
1929
0
  flags2 |= additional_flags2;
1930
0
  flags2 &= ~clear_flags2;
1931
1932
0
  *_flags = flags;
1933
0
  *_flags2 = flags2;
1934
0
}
1935
1936
static void smb1cli_req_cancel_done(struct tevent_req *subreq);
1937
1938
static bool smb1cli_req_cancel(struct tevent_req *req)
1939
0
{
1940
0
  struct smbXcli_req_state *state =
1941
0
    tevent_req_data(req,
1942
0
    struct smbXcli_req_state);
1943
0
  uint8_t flags;
1944
0
  uint16_t flags2;
1945
0
  uint32_t pid;
1946
0
  uint16_t mid;
1947
0
  struct tevent_req *subreq;
1948
0
  NTSTATUS status;
1949
1950
0
  flags = CVAL(state->smb1.hdr, HDR_FLG);
1951
0
  flags2 = SVAL(state->smb1.hdr, HDR_FLG2);
1952
0
  pid  = SVAL(state->smb1.hdr, HDR_PID);
1953
0
  pid |= SVAL(state->smb1.hdr, HDR_PIDHIGH)<<16;
1954
0
  mid = SVAL(state->smb1.hdr, HDR_MID);
1955
1956
0
  subreq = smb1cli_req_create(state, state->ev,
1957
0
            state->conn,
1958
0
            SMBntcancel,
1959
0
            flags, 0,
1960
0
            flags2, 0,
1961
0
            0, /* timeout */
1962
0
            pid,
1963
0
            state->tcon,
1964
0
            state->session,
1965
0
            0, NULL, /* vwv */
1966
0
            0, NULL); /* bytes */
1967
0
  if (subreq == NULL) {
1968
0
    return false;
1969
0
  }
1970
0
  smb1cli_req_set_mid(subreq, mid);
1971
1972
0
  status = smb1cli_req_chain_submit(&subreq, 1);
1973
0
  if (!NT_STATUS_IS_OK(status)) {
1974
0
    TALLOC_FREE(subreq);
1975
0
    return false;
1976
0
  }
1977
0
  smb1cli_req_set_mid(subreq, 0);
1978
1979
0
  tevent_req_set_callback(subreq, smb1cli_req_cancel_done, NULL);
1980
1981
0
  return true;
1982
0
}
1983
1984
static void smb1cli_req_cancel_done(struct tevent_req *subreq)
1985
0
{
1986
  /* we do not care about the result */
1987
0
  TALLOC_FREE(subreq);
1988
0
}
1989
1990
struct tevent_req *smb1cli_req_create(TALLOC_CTX *mem_ctx,
1991
              struct tevent_context *ev,
1992
              struct smbXcli_conn *conn,
1993
              uint8_t smb_command,
1994
              uint8_t additional_flags,
1995
              uint8_t clear_flags,
1996
              uint16_t additional_flags2,
1997
              uint16_t clear_flags2,
1998
              uint32_t timeout_msec,
1999
              uint32_t pid,
2000
              struct smbXcli_tcon *tcon,
2001
              struct smbXcli_session *session,
2002
              uint8_t wct, uint16_t *vwv,
2003
              int iov_count,
2004
              struct iovec *bytes_iov)
2005
0
{
2006
0
  struct tevent_req *req;
2007
0
  struct smbXcli_req_state *state;
2008
0
  uint8_t flags = 0;
2009
0
  uint16_t flags2 = 0;
2010
0
  uint16_t uid = 0;
2011
0
  uint16_t tid = 0;
2012
0
  ssize_t num_bytes;
2013
2014
0
  if (iov_count > MAX_SMB_IOV) {
2015
    /*
2016
     * Should not happen :-)
2017
     */
2018
0
    return NULL;
2019
0
  }
2020
2021
0
  req = tevent_req_create(mem_ctx, &state,
2022
0
        struct smbXcli_req_state);
2023
0
  if (req == NULL) {
2024
0
    return NULL;
2025
0
  }
2026
0
  state->ev = ev;
2027
0
  state->conn = conn;
2028
0
  state->session = session;
2029
0
  state->tcon = tcon;
2030
2031
0
  if (session) {
2032
0
    uid = session->smb1.session_id;
2033
0
  }
2034
2035
0
  if (tcon) {
2036
0
    tid = tcon->smb1.tcon_id;
2037
2038
0
    if (tcon->fs_attributes & FILE_CASE_SENSITIVE_SEARCH) {
2039
0
      clear_flags |= FLAG_CASELESS_PATHNAMES;
2040
0
    } else {
2041
      /* Default setting, case insensitive. */
2042
0
      additional_flags |= FLAG_CASELESS_PATHNAMES;
2043
0
    }
2044
2045
0
    if (smbXcli_conn_dfs_supported(conn) &&
2046
0
        smbXcli_tcon_is_dfs_share(tcon))
2047
0
    {
2048
0
      additional_flags2 |= FLAGS2_DFS_PATHNAMES;
2049
0
    }
2050
0
  }
2051
2052
0
  state->smb1.recv_cmd = 0xFF;
2053
0
  state->smb1.recv_status = NT_STATUS_INTERNAL_ERROR;
2054
0
  state->smb1.recv_iov = talloc_zero_array(state, struct iovec, 3);
2055
0
  if (state->smb1.recv_iov == NULL) {
2056
0
    TALLOC_FREE(req);
2057
0
    return NULL;
2058
0
  }
2059
2060
0
  smb1cli_req_flags(conn->protocol,
2061
0
        conn->smb1.capabilities,
2062
0
        smb_command,
2063
0
        additional_flags,
2064
0
        clear_flags,
2065
0
        &flags,
2066
0
        additional_flags2,
2067
0
        clear_flags2,
2068
0
        &flags2);
2069
2070
0
  SIVAL(state->smb1.hdr, 0,           SMB_MAGIC);
2071
0
  SCVAL(state->smb1.hdr, HDR_COM,     smb_command);
2072
0
  SIVAL(state->smb1.hdr, HDR_RCLS,    NT_STATUS_V(NT_STATUS_OK));
2073
0
  SCVAL(state->smb1.hdr, HDR_FLG,     flags);
2074
0
  SSVAL(state->smb1.hdr, HDR_FLG2,    flags2);
2075
0
  SSVAL(state->smb1.hdr, HDR_PIDHIGH, pid >> 16);
2076
0
  SSVAL(state->smb1.hdr, HDR_TID,     tid);
2077
0
  SSVAL(state->smb1.hdr, HDR_PID,     pid);
2078
0
  SSVAL(state->smb1.hdr, HDR_UID,     uid);
2079
0
  SSVAL(state->smb1.hdr, HDR_MID,     0); /* this comes later */
2080
0
  SCVAL(state->smb1.hdr, HDR_WCT,     wct);
2081
2082
0
  state->smb1.vwv = vwv;
2083
2084
0
  num_bytes = iov_buflen(bytes_iov, iov_count);
2085
0
  if (num_bytes == -1) {
2086
    /*
2087
     * I'd love to add a check for num_bytes<=UINT16_MAX here, but
2088
     * the smbclient->samba connections can lie and transfer more.
2089
     */
2090
0
    TALLOC_FREE(req);
2091
0
    return NULL;
2092
0
  }
2093
2094
0
  SSVAL(state->smb1.bytecount_buf, 0, num_bytes);
2095
2096
0
  state->smb1.iov[0].iov_base = (void *)state->length_hdr;
2097
0
  state->smb1.iov[0].iov_len  = sizeof(state->length_hdr);
2098
0
  state->smb1.iov[1].iov_base = (void *)state->smb1.hdr;
2099
0
  state->smb1.iov[1].iov_len  = sizeof(state->smb1.hdr);
2100
0
  state->smb1.iov[2].iov_base = (void *)state->smb1.vwv;
2101
0
  state->smb1.iov[2].iov_len  = wct * sizeof(uint16_t);
2102
0
  state->smb1.iov[3].iov_base = (void *)state->smb1.bytecount_buf;
2103
0
  state->smb1.iov[3].iov_len  = sizeof(uint16_t);
2104
2105
0
  if (iov_count != 0) {
2106
0
    memcpy(&state->smb1.iov[4], bytes_iov,
2107
0
           iov_count * sizeof(*bytes_iov));
2108
0
  }
2109
0
  state->smb1.iov_count = iov_count + 4;
2110
2111
0
  if (timeout_msec > 0) {
2112
0
    state->endtime = timeval_current_ofs_msec(timeout_msec);
2113
0
    if (!tevent_req_set_endtime(req, ev, state->endtime)) {
2114
0
      return req;
2115
0
    }
2116
0
  }
2117
2118
0
  switch (smb_command) {
2119
0
  case SMBtranss:
2120
0
  case SMBtranss2:
2121
0
  case SMBnttranss:
2122
0
    state->one_way = true;
2123
0
    break;
2124
0
  case SMBntcancel:
2125
0
    state->one_way = true;
2126
0
    state->smb1.one_way_seqnum = true;
2127
0
    break;
2128
0
  case SMBlockingX:
2129
0
    if ((wct == 8) &&
2130
0
        (CVAL(vwv+3, 0) == LOCKING_ANDX_OPLOCK_RELEASE)) {
2131
0
      state->one_way = true;
2132
0
    }
2133
0
    break;
2134
0
  }
2135
2136
0
  return req;
2137
0
}
2138
2139
static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
2140
           struct iovec *iov, int iov_count,
2141
           uint32_t *seqnum,
2142
           bool one_way_seqnum)
2143
0
{
2144
0
  TALLOC_CTX *frame = NULL;
2145
0
  NTSTATUS status;
2146
0
  uint8_t *buf;
2147
2148
  /*
2149
   * Obvious optimization: Make cli_calculate_sign_mac work with struct
2150
   * iovec directly. MD5Update would do that just fine.
2151
   */
2152
2153
0
  if (iov_count < 4) {
2154
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2155
0
  }
2156
0
  if (iov[0].iov_len != NBT_HDR_SIZE) {
2157
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2158
0
  }
2159
0
  if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
2160
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2161
0
  }
2162
0
  if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
2163
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2164
0
  }
2165
0
  if (iov[3].iov_len != sizeof(uint16_t)) {
2166
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2167
0
  }
2168
2169
0
  frame = talloc_stackframe();
2170
2171
0
  buf = iov_concat(frame, &iov[1], iov_count - 1);
2172
0
  if (buf == NULL) {
2173
0
    return NT_STATUS_NO_MEMORY;
2174
0
  }
2175
2176
0
  *seqnum = smb1_signing_next_seqnum(conn->smb1.signing,
2177
0
            one_way_seqnum);
2178
0
  status = smb1_signing_sign_pdu(conn->smb1.signing,
2179
0
              buf,
2180
0
              talloc_get_size(buf),
2181
0
              *seqnum);
2182
0
  if (!NT_STATUS_IS_OK(status)) {
2183
0
    return status;
2184
0
  }
2185
0
  memcpy(iov[1].iov_base, buf, iov[1].iov_len);
2186
2187
0
  TALLOC_FREE(frame);
2188
0
  return NT_STATUS_OK;
2189
0
}
2190
2191
static void smb1cli_req_writev_done(struct tevent_req *subreq);
2192
static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2193
                 TALLOC_CTX *tmp_mem,
2194
                 uint8_t *inbuf);
2195
2196
static NTSTATUS smb1cli_req_writev_submit(struct tevent_req *req,
2197
            struct smbXcli_req_state *state,
2198
            struct iovec *iov, int iov_count)
2199
0
{
2200
0
  struct smbXcli_transport *xtp = NULL;
2201
0
  struct tevent_req *subreq;
2202
0
  NTSTATUS status;
2203
0
  uint8_t cmd;
2204
0
  uint16_t mid;
2205
0
  ssize_t nbtlen;
2206
2207
0
  if (!smbXcli_conn_is_connected(state->conn)) {
2208
0
    return NT_STATUS_CONNECTION_DISCONNECTED;
2209
0
  }
2210
2211
0
  if (state->conn->protocol > PROTOCOL_NT1) {
2212
0
    DBG_ERR("called for dialect[%s] server[%s]\n",
2213
0
      smb_protocol_types_string(state->conn->protocol),
2214
0
      smbXcli_conn_remote_name(state->conn));
2215
0
    return NT_STATUS_REVISION_MISMATCH;
2216
0
  }
2217
2218
0
  if (iov_count < 4) {
2219
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2220
0
  }
2221
0
  if (iov[0].iov_len != NBT_HDR_SIZE) {
2222
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2223
0
  }
2224
0
  if (iov[1].iov_len != (MIN_SMB_SIZE-sizeof(uint16_t))) {
2225
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2226
0
  }
2227
0
  if (iov[2].iov_len > (0xFF * sizeof(uint16_t))) {
2228
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2229
0
  }
2230
0
  if (iov[3].iov_len != sizeof(uint16_t)) {
2231
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2232
0
  }
2233
2234
0
  cmd = CVAL(iov[1].iov_base, HDR_COM);
2235
0
  if (cmd == SMBreadBraw) {
2236
0
    if (smbXcli_conn_has_async_calls(state->conn)) {
2237
0
      return NT_STATUS_INVALID_PARAMETER_MIX;
2238
0
    }
2239
0
    state->conn->smb1.read_braw_req = req;
2240
0
  }
2241
2242
0
  if (state->smb1.mid != 0) {
2243
0
    mid = state->smb1.mid;
2244
0
  } else {
2245
0
    mid = smb1cli_alloc_mid(state->conn);
2246
0
  }
2247
0
  SSVAL(iov[1].iov_base, HDR_MID, mid);
2248
2249
0
  nbtlen = iov_buflen(&iov[1], iov_count-1);
2250
0
  if ((nbtlen == -1) || (nbtlen > 0x1FFFF)) {
2251
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2252
0
  }
2253
2254
0
  _smb_setlen_nbt(iov[0].iov_base, nbtlen);
2255
2256
0
  status = smb1cli_conn_signv(state->conn, iov, iov_count,
2257
0
            &state->smb1.seqnum,
2258
0
            state->smb1.one_way_seqnum);
2259
2260
0
  if (!NT_STATUS_IS_OK(status)) {
2261
0
    return status;
2262
0
  }
2263
2264
  /*
2265
   * If we supported multiple encryption contexts
2266
   * here we'd look up based on tid.
2267
   */
2268
0
  if (common_encryption_on(state->conn->smb1.trans_enc)) {
2269
0
    char *buf, *enc_buf;
2270
2271
0
    buf = (char *)iov_concat(talloc_tos(), iov, iov_count);
2272
0
    if (buf == NULL) {
2273
0
      return NT_STATUS_NO_MEMORY;
2274
0
    }
2275
0
    status = common_encrypt_buffer(state->conn->smb1.trans_enc,
2276
0
                 (char *)buf, &enc_buf);
2277
0
    TALLOC_FREE(buf);
2278
0
    if (!NT_STATUS_IS_OK(status)) {
2279
0
      DEBUG(0, ("Error in encrypting client message: %s\n",
2280
0
          nt_errstr(status)));
2281
0
      return status;
2282
0
    }
2283
0
    buf = (char *)talloc_memdup(state, enc_buf,
2284
0
              smb_len_nbt(enc_buf)+4);
2285
0
    SAFE_FREE(enc_buf);
2286
0
    if (buf == NULL) {
2287
0
      return NT_STATUS_NO_MEMORY;
2288
0
    }
2289
0
    iov[0].iov_base = (void *)buf;
2290
0
    iov[0].iov_len = talloc_get_size(buf);
2291
0
    iov_count = 1;
2292
0
  }
2293
2294
0
  if (state->conn->dispatch_incoming == NULL) {
2295
0
    state->conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
2296
0
  }
2297
2298
0
  if (!smbXcli_req_set_pending(req)) {
2299
0
    return NT_STATUS_NO_MEMORY;
2300
0
  }
2301
2302
0
  tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
2303
2304
0
  xtp = state->conn->transport;
2305
0
  subreq = xtp->writev_send_fn(state,
2306
0
             state->ev,
2307
0
             xtp,
2308
0
             state->conn->outgoing,
2309
0
             iov,
2310
0
             iov_count);
2311
0
  if (subreq == NULL) {
2312
0
    return NT_STATUS_NO_MEMORY;
2313
0
  }
2314
0
  state->writev_recv_fn = xtp->writev_recv_fn;
2315
0
  tevent_req_set_callback(subreq, smb1cli_req_writev_done, req);
2316
0
  state->write_req = subreq;
2317
2318
0
  return NT_STATUS_OK;
2319
0
}
2320
2321
struct tevent_req *smb1cli_req_send(TALLOC_CTX *mem_ctx,
2322
            struct tevent_context *ev,
2323
            struct smbXcli_conn *conn,
2324
            uint8_t smb_command,
2325
            uint8_t additional_flags,
2326
            uint8_t clear_flags,
2327
            uint16_t additional_flags2,
2328
            uint16_t clear_flags2,
2329
            uint32_t timeout_msec,
2330
            uint32_t pid,
2331
            struct smbXcli_tcon *tcon,
2332
            struct smbXcli_session *session,
2333
            uint8_t wct, uint16_t *vwv,
2334
            uint32_t num_bytes,
2335
            const uint8_t *bytes)
2336
0
{
2337
0
  struct tevent_req *req;
2338
0
  struct iovec iov;
2339
0
  NTSTATUS status;
2340
2341
0
  iov.iov_base = discard_const_p(void, bytes);
2342
0
  iov.iov_len = num_bytes;
2343
2344
0
  req = smb1cli_req_create(mem_ctx, ev, conn, smb_command,
2345
0
         additional_flags, clear_flags,
2346
0
         additional_flags2, clear_flags2,
2347
0
         timeout_msec,
2348
0
         pid, tcon, session,
2349
0
         wct, vwv, 1, &iov);
2350
0
  if (req == NULL) {
2351
0
    return NULL;
2352
0
  }
2353
0
  if (!tevent_req_is_in_progress(req)) {
2354
0
    return tevent_req_post(req, ev);
2355
0
  }
2356
0
  status = smb1cli_req_chain_submit(&req, 1);
2357
0
  if (tevent_req_nterror(req, status)) {
2358
0
    return tevent_req_post(req, ev);
2359
0
  }
2360
0
  return req;
2361
0
}
2362
2363
static void smb1cli_req_writev_done(struct tevent_req *subreq)
2364
0
{
2365
0
  struct tevent_req *req =
2366
0
    tevent_req_callback_data(subreq,
2367
0
    struct tevent_req);
2368
0
  struct smbXcli_req_state *state =
2369
0
    tevent_req_data(req,
2370
0
    struct smbXcli_req_state);
2371
0
  ssize_t nwritten;
2372
0
  int err;
2373
2374
0
  state->write_req = NULL;
2375
2376
0
  nwritten = state->writev_recv_fn(subreq, &err);
2377
0
  TALLOC_FREE(subreq);
2378
0
  if (nwritten == -1) {
2379
    /* here, we need to notify all pending requests */
2380
0
    NTSTATUS status = map_nt_error_from_unix_common(err);
2381
0
    smbXcli_conn_disconnect(state->conn, status);
2382
0
    return;
2383
0
  }
2384
2385
0
  if (state->one_way) {
2386
0
    state->inbuf = NULL;
2387
0
    tevent_req_done(req);
2388
0
    return;
2389
0
  }
2390
0
}
2391
2392
static void smbXcli_conn_received(struct tevent_req *subreq)
2393
0
{
2394
0
  struct smbXcli_conn *conn =
2395
0
    tevent_req_callback_data(subreq,
2396
0
    struct smbXcli_conn);
2397
0
  struct smbXcli_transport *xtp = conn->transport;
2398
0
  TALLOC_CTX *frame = talloc_stackframe();
2399
0
  NTSTATUS status;
2400
0
  uint8_t *inbuf;
2401
0
  ssize_t received;
2402
0
  int err;
2403
2404
0
  if (subreq != conn->read_smb_req) {
2405
0
    DEBUG(1, ("Internal error: cli_smb_received called with "
2406
0
        "unexpected subreq\n"));
2407
0
    smbXcli_conn_disconnect(conn, NT_STATUS_INTERNAL_ERROR);
2408
0
    TALLOC_FREE(frame);
2409
0
    return;
2410
0
  }
2411
0
  conn->read_smb_req = NULL;
2412
2413
0
  received = xtp->read_smb_recv_fn(subreq, frame, &inbuf, &err);
2414
0
  TALLOC_FREE(subreq);
2415
0
  if (received == -1) {
2416
0
    status = map_nt_error_from_unix_common(err);
2417
0
    smbXcli_conn_disconnect(conn, status);
2418
0
    TALLOC_FREE(frame);
2419
0
    return;
2420
0
  }
2421
2422
0
  status = conn->dispatch_incoming(conn, frame, inbuf);
2423
0
  TALLOC_FREE(frame);
2424
0
  if (NT_STATUS_IS_OK(status)) {
2425
    /*
2426
     * We should not do any more processing
2427
     * as the dispatch function called
2428
     * tevent_req_done().
2429
     */
2430
0
    return;
2431
0
  }
2432
2433
0
  if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2434
    /*
2435
     * We got an error, so notify all pending requests
2436
     */
2437
0
    smbXcli_conn_disconnect(conn, status);
2438
0
    return;
2439
0
  }
2440
2441
  /*
2442
   * We got NT_STATUS_RETRY, so we may ask for a
2443
   * next incoming pdu.
2444
   */
2445
0
  if (!smbXcli_conn_receive_next(conn)) {
2446
0
    smbXcli_conn_disconnect(conn, NT_STATUS_NO_MEMORY);
2447
0
  }
2448
0
}
2449
2450
static NTSTATUS smb1cli_inbuf_parse_chain(uint8_t *buf, TALLOC_CTX *mem_ctx,
2451
            struct iovec **piov, int *pnum_iov)
2452
0
{
2453
0
  struct iovec *iov;
2454
0
  size_t num_iov;
2455
0
  size_t buflen;
2456
0
  size_t taken;
2457
0
  size_t remaining;
2458
0
  uint8_t *hdr;
2459
0
  uint8_t cmd;
2460
0
  uint32_t wct_ofs;
2461
0
  NTSTATUS status;
2462
0
  size_t min_size = MIN_SMB_SIZE;
2463
2464
0
  buflen = smb_len_tcp(buf);
2465
0
  taken = 0;
2466
2467
0
  hdr = buf + NBT_HDR_SIZE;
2468
2469
0
  status = smb1cli_pull_raw_error(hdr);
2470
0
  if (NT_STATUS_IS_ERR(status)) {
2471
    /*
2472
     * This is an ugly hack to support OS/2
2473
     * which skips the byte_count in the DATA block
2474
     * on some error responses.
2475
     *
2476
     * See bug #9096
2477
     */
2478
0
    min_size -= sizeof(uint16_t);
2479
0
  }
2480
2481
0
  if (buflen < min_size) {
2482
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
2483
0
  }
2484
2485
  /*
2486
   * This returns iovec elements in the following order:
2487
   *
2488
   * - SMB header
2489
   *
2490
   * - Parameter Block
2491
   * - Data Block
2492
   *
2493
   * - Parameter Block
2494
   * - Data Block
2495
   *
2496
   * - Parameter Block
2497
   * - Data Block
2498
   */
2499
0
  num_iov = 1;
2500
2501
0
  iov = talloc_array(mem_ctx, struct iovec, num_iov);
2502
0
  if (iov == NULL) {
2503
0
    return NT_STATUS_NO_MEMORY;
2504
0
  }
2505
0
  iov[0].iov_base = hdr;
2506
0
  iov[0].iov_len = HDR_WCT;
2507
0
  taken += HDR_WCT;
2508
2509
0
  cmd = CVAL(hdr, HDR_COM);
2510
0
  wct_ofs = HDR_WCT;
2511
2512
0
  while (true) {
2513
0
    size_t len = buflen - taken;
2514
0
    struct iovec *cur;
2515
0
    struct iovec *iov_tmp;
2516
0
    uint8_t wct;
2517
0
    uint32_t bcc_ofs;
2518
0
    uint16_t bcc;
2519
0
    size_t needed;
2520
2521
    /*
2522
     * we need at least WCT
2523
     */
2524
0
    needed = sizeof(uint8_t);
2525
0
    if (len < needed) {
2526
0
      DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2527
0
           __location__, (int)len, (int)needed));
2528
0
      goto inval;
2529
0
    }
2530
2531
    /*
2532
     * Now we check if the specified words are there
2533
     */
2534
0
    wct = CVAL(hdr, wct_ofs);
2535
0
    needed += wct * sizeof(uint16_t);
2536
0
    if (len < needed) {
2537
0
      DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2538
0
           __location__, (int)len, (int)needed));
2539
0
      goto inval;
2540
0
    }
2541
2542
0
    if ((num_iov == 1) &&
2543
0
        (len == needed) &&
2544
0
        NT_STATUS_IS_ERR(status))
2545
0
    {
2546
      /*
2547
       * This is an ugly hack to support OS/2
2548
       * which skips the byte_count in the DATA block
2549
       * on some error responses.
2550
       *
2551
       * See bug #9096
2552
       */
2553
0
      iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2554
0
             num_iov + 2);
2555
0
      if (iov_tmp == NULL) {
2556
0
        TALLOC_FREE(iov);
2557
0
        return NT_STATUS_NO_MEMORY;
2558
0
      }
2559
0
      iov = iov_tmp;
2560
0
      cur = &iov[num_iov];
2561
0
      num_iov += 2;
2562
2563
0
      cur[0].iov_len = 0;
2564
0
      cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2565
0
      cur[1].iov_len = 0;
2566
0
      cur[1].iov_base = cur[0].iov_base;
2567
2568
0
      taken += needed;
2569
0
      break;
2570
0
    }
2571
2572
    /*
2573
     * we need at least BCC
2574
     */
2575
0
    needed += sizeof(uint16_t);
2576
0
    if (len < needed) {
2577
0
      DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2578
0
           __location__, (int)len, (int)needed));
2579
0
      goto inval;
2580
0
    }
2581
2582
    /*
2583
     * Now we check if the specified bytes are there
2584
     */
2585
0
    bcc_ofs = wct_ofs + sizeof(uint8_t) + wct * sizeof(uint16_t);
2586
0
    bcc = SVAL(hdr, bcc_ofs);
2587
0
    needed += bcc * sizeof(uint8_t);
2588
0
    if (len < needed) {
2589
0
      DEBUG(10, ("%s: %d bytes left, expected at least %d\n",
2590
0
           __location__, (int)len, (int)needed));
2591
0
      goto inval;
2592
0
    }
2593
2594
    /*
2595
     * we allocate 2 iovec structures for words and bytes
2596
     */
2597
0
    iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
2598
0
           num_iov + 2);
2599
0
    if (iov_tmp == NULL) {
2600
0
      TALLOC_FREE(iov);
2601
0
      return NT_STATUS_NO_MEMORY;
2602
0
    }
2603
0
    iov = iov_tmp;
2604
0
    cur = &iov[num_iov];
2605
0
    num_iov += 2;
2606
2607
0
    cur[0].iov_len = wct * sizeof(uint16_t);
2608
0
    cur[0].iov_base = hdr + (wct_ofs + sizeof(uint8_t));
2609
0
    cur[1].iov_len = bcc * sizeof(uint8_t);
2610
0
    cur[1].iov_base = hdr + (bcc_ofs + sizeof(uint16_t));
2611
2612
0
    taken += needed;
2613
2614
0
    if (!smb1cli_is_andx_req(cmd)) {
2615
      /*
2616
       * If the current command does not have AndX chanining
2617
       * we are done.
2618
       */
2619
0
      break;
2620
0
    }
2621
2622
0
    if (wct == 0 && bcc == 0) {
2623
      /*
2624
       * An empty response also ends the chain,
2625
       * most likely with an error.
2626
       */
2627
0
      break;
2628
0
    }
2629
2630
0
    if (wct < 2) {
2631
0
      DEBUG(10, ("%s: wct[%d] < 2 for cmd[0x%02X]\n",
2632
0
           __location__, (int)wct, (int)cmd));
2633
0
      goto inval;
2634
0
    }
2635
0
    cmd = CVAL(cur[0].iov_base, 0);
2636
0
    if (cmd == 0xFF) {
2637
      /*
2638
       * If it is the end of the chain we are also done.
2639
       */
2640
0
      break;
2641
0
    }
2642
0
    wct_ofs = SVAL(cur[0].iov_base, 2);
2643
2644
0
    if (wct_ofs < taken) {
2645
0
      goto inval;
2646
0
    }
2647
0
    if (wct_ofs > buflen) {
2648
0
      goto inval;
2649
0
    }
2650
2651
    /*
2652
     * we consumed everything up to the start of the next
2653
     * parameter block.
2654
     */
2655
0
    taken = wct_ofs;
2656
0
  }
2657
2658
0
  remaining = buflen - taken;
2659
2660
0
  if (remaining > 0 && num_iov >= 3) {
2661
    /*
2662
     * The last DATA block gets the remaining
2663
     * bytes, this is needed to support
2664
     * CAP_LARGE_WRITEX and CAP_LARGE_READX.
2665
     */
2666
0
    iov[num_iov-1].iov_len += remaining;
2667
0
  }
2668
2669
0
  *piov = iov;
2670
0
  *pnum_iov = num_iov;
2671
0
  return NT_STATUS_OK;
2672
2673
0
inval:
2674
0
  TALLOC_FREE(iov);
2675
0
  return NT_STATUS_INVALID_NETWORK_RESPONSE;
2676
0
}
2677
2678
static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
2679
                 TALLOC_CTX *tmp_mem,
2680
                 uint8_t *inbuf)
2681
0
{
2682
0
  struct tevent_req *req;
2683
0
  struct smbXcli_req_state *state;
2684
0
  NTSTATUS status;
2685
0
  size_t num_pending;
2686
0
  size_t i;
2687
0
  uint8_t cmd;
2688
0
  uint16_t mid;
2689
0
  bool oplock_break;
2690
0
  uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
2691
0
  size_t len = smb_len_tcp(inbuf);
2692
0
  struct iovec *iov = NULL;
2693
0
  int num_iov = 0;
2694
0
  struct tevent_req **chain = NULL;
2695
0
  size_t num_chained = 0;
2696
0
  size_t num_responses = 0;
2697
2698
0
  if (conn->smb1.read_braw_req != NULL) {
2699
0
    req = conn->smb1.read_braw_req;
2700
0
    conn->smb1.read_braw_req = NULL;
2701
0
    state = tevent_req_data(req, struct smbXcli_req_state);
2702
2703
0
    smbXcli_req_unset_pending(req);
2704
2705
0
    if (state->smb1.recv_iov == NULL) {
2706
      /*
2707
       * For requests with more than
2708
       * one response, we have to readd the
2709
       * recv_iov array.
2710
       */
2711
0
      state->smb1.recv_iov = talloc_zero_array(state,
2712
0
                 struct iovec,
2713
0
                 3);
2714
0
      if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2715
0
        return NT_STATUS_OK;
2716
0
      }
2717
0
    }
2718
2719
0
    state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
2720
0
    state->smb1.recv_iov[0].iov_len = len;
2721
0
    ZERO_STRUCT(state->smb1.recv_iov[1]);
2722
0
    ZERO_STRUCT(state->smb1.recv_iov[2]);
2723
2724
0
    state->smb1.recv_cmd = SMBreadBraw;
2725
0
    state->smb1.recv_status = NT_STATUS_OK;
2726
0
    state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2727
2728
0
    tevent_req_done(req);
2729
0
    return NT_STATUS_OK;
2730
0
  }
2731
2732
0
  if ((IVAL(inhdr, 0) != SMB_MAGIC) /* 0xFF"SMB" */
2733
0
      && (SVAL(inhdr, 0) != 0x45ff)) /* 0xFF"E" */ {
2734
0
    DEBUG(10, ("Got non-SMB PDU\n"));
2735
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
2736
0
  }
2737
2738
  /*
2739
   * If we supported multiple encryption contexts
2740
   * here we'd look up based on tid.
2741
   */
2742
0
  if (common_encryption_on(conn->smb1.trans_enc)
2743
0
      && (CVAL(inbuf, 0) == 0)) {
2744
0
    uint16_t enc_ctx_num;
2745
2746
0
    status = get_enc_ctx_num(inbuf, &enc_ctx_num);
2747
0
    if (!NT_STATUS_IS_OK(status)) {
2748
0
      DEBUG(10, ("get_enc_ctx_num returned %s\n",
2749
0
           nt_errstr(status)));
2750
0
      return status;
2751
0
    }
2752
2753
0
    if (enc_ctx_num != conn->smb1.trans_enc->enc_ctx_num) {
2754
0
      DEBUG(10, ("wrong enc_ctx %d, expected %d\n",
2755
0
           enc_ctx_num,
2756
0
           conn->smb1.trans_enc->enc_ctx_num));
2757
0
      return NT_STATUS_INVALID_HANDLE;
2758
0
    }
2759
2760
0
    status = common_decrypt_buffer(conn->smb1.trans_enc,
2761
0
                 (char *)inbuf);
2762
0
    if (!NT_STATUS_IS_OK(status)) {
2763
0
      DEBUG(10, ("common_decrypt_buffer returned %s\n",
2764
0
           nt_errstr(status)));
2765
0
      return status;
2766
0
    }
2767
0
    inhdr = inbuf + NBT_HDR_SIZE;
2768
0
    len = smb_len_nbt(inbuf);
2769
0
  }
2770
2771
0
  mid = SVAL(inhdr, HDR_MID);
2772
0
  num_pending = talloc_array_length(conn->pending);
2773
2774
0
  for (i=0; i<num_pending; i++) {
2775
0
    if (mid == smb1cli_req_mid(conn->pending[i])) {
2776
0
      break;
2777
0
    }
2778
0
  }
2779
0
  if (i == num_pending) {
2780
    /* Dump unexpected reply */
2781
0
    return NT_STATUS_RETRY;
2782
0
  }
2783
2784
0
  oplock_break = false;
2785
2786
0
  if (mid == 0xffff) {
2787
    /*
2788
     * Paranoia checks that this is really an oplock break request.
2789
     */
2790
0
    oplock_break = (len == 51); /* hdr + 8 words */
2791
0
    oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
2792
0
    oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
2793
0
    oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
2794
0
    oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(7)) == 0);
2795
2796
0
    if (!oplock_break) {
2797
      /* Dump unexpected reply */
2798
0
      return NT_STATUS_RETRY;
2799
0
    }
2800
0
  }
2801
2802
0
  req = conn->pending[i];
2803
0
  state = tevent_req_data(req, struct smbXcli_req_state);
2804
2805
0
  if (!oplock_break /* oplock breaks are not signed */
2806
0
      && !smb1_signing_check_pdu(conn->smb1.signing,
2807
0
              inhdr, len, state->smb1.seqnum+1)) {
2808
0
    DEBUG(10, ("cli_check_sign_mac failed\n"));
2809
0
    return NT_STATUS_ACCESS_DENIED;
2810
0
  }
2811
2812
0
  status = smb1cli_inbuf_parse_chain(inbuf, tmp_mem,
2813
0
             &iov, &num_iov);
2814
0
  if (!NT_STATUS_IS_OK(status)) {
2815
0
    DEBUG(10,("smb1cli_inbuf_parse_chain - %s\n",
2816
0
        nt_errstr(status)));
2817
0
    return status;
2818
0
  }
2819
2820
0
  cmd = CVAL(inhdr, HDR_COM);
2821
0
  status = smb1cli_pull_raw_error(inhdr);
2822
2823
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
2824
0
      (state->session != NULL) && state->session->disconnect_expired)
2825
0
  {
2826
    /*
2827
     * this should be a short term hack
2828
     * until the upper layers have implemented
2829
     * re-authentication.
2830
     */
2831
0
    return status;
2832
0
  }
2833
2834
0
  if (state->smb1.chained_requests == NULL) {
2835
0
    if (num_iov != 3) {
2836
0
      return NT_STATUS_INVALID_NETWORK_RESPONSE;
2837
0
    }
2838
2839
0
    smbXcli_req_unset_pending(req);
2840
2841
0
    if (state->smb1.recv_iov == NULL) {
2842
      /*
2843
       * For requests with more than
2844
       * one response, we have to readd the
2845
       * recv_iov array.
2846
       */
2847
0
      state->smb1.recv_iov = talloc_zero_array(state,
2848
0
                 struct iovec,
2849
0
                 3);
2850
0
      if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2851
0
        return NT_STATUS_OK;
2852
0
      }
2853
0
    }
2854
2855
0
    state->smb1.recv_cmd = cmd;
2856
0
    state->smb1.recv_status = status;
2857
0
    state->inbuf = talloc_move(state->smb1.recv_iov, &inbuf);
2858
2859
0
    state->smb1.recv_iov[0] = iov[0];
2860
0
    state->smb1.recv_iov[1] = iov[1];
2861
0
    state->smb1.recv_iov[2] = iov[2];
2862
2863
0
    if (talloc_array_length(conn->pending) == 0) {
2864
0
      tevent_req_done(req);
2865
0
      return NT_STATUS_OK;
2866
0
    }
2867
2868
0
    tevent_req_defer_callback(req, state->ev);
2869
0
    tevent_req_done(req);
2870
0
    return NT_STATUS_RETRY;
2871
0
  }
2872
2873
0
  chain = talloc_move(tmp_mem, &state->smb1.chained_requests);
2874
0
  num_chained = talloc_array_length(chain);
2875
0
  num_responses = (num_iov - 1)/2;
2876
2877
0
  if (num_responses > num_chained) {
2878
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
2879
0
  }
2880
2881
0
  for (i=0; i<num_chained; i++) {
2882
0
    size_t iov_idx = 1 + (i*2);
2883
0
    struct iovec *cur = &iov[iov_idx];
2884
0
    uint8_t *inbuf_ref;
2885
2886
0
    req = chain[i];
2887
0
    state = tevent_req_data(req, struct smbXcli_req_state);
2888
2889
0
    smbXcli_req_unset_pending(req);
2890
2891
    /*
2892
     * as we finish multiple requests here
2893
     * we need to defer the callbacks as
2894
     * they could destroy our current stack state.
2895
     */
2896
0
    tevent_req_defer_callback(req, state->ev);
2897
2898
0
    if (i >= num_responses) {
2899
0
      tevent_req_nterror(req, NT_STATUS_REQUEST_ABORTED);
2900
0
      continue;
2901
0
    }
2902
2903
0
    if (state->smb1.recv_iov == NULL) {
2904
      /*
2905
       * For requests with more than
2906
       * one response, we have to readd the
2907
       * recv_iov array.
2908
       */
2909
0
      state->smb1.recv_iov = talloc_zero_array(state,
2910
0
                 struct iovec,
2911
0
                 3);
2912
0
      if (tevent_req_nomem(state->smb1.recv_iov, req)) {
2913
0
        continue;
2914
0
      }
2915
0
    }
2916
2917
0
    state->smb1.recv_cmd = cmd;
2918
2919
0
    if (i == (num_responses - 1)) {
2920
      /*
2921
       * The last request in the chain gets the status
2922
       */
2923
0
      state->smb1.recv_status = status;
2924
0
    } else {
2925
0
      cmd = CVAL(cur[0].iov_base, 0);
2926
0
      state->smb1.recv_status = NT_STATUS_OK;
2927
0
    }
2928
2929
0
    state->inbuf = inbuf;
2930
2931
    /*
2932
     * Note: here we use talloc_reference() in a way
2933
     *       that does not expose it to the caller.
2934
     */
2935
0
    inbuf_ref = talloc_reference(state->smb1.recv_iov, inbuf);
2936
0
    if (tevent_req_nomem(inbuf_ref, req)) {
2937
0
      continue;
2938
0
    }
2939
2940
    /* copy the related buffers */
2941
0
    state->smb1.recv_iov[0] = iov[0];
2942
0
    state->smb1.recv_iov[1] = cur[0];
2943
0
    state->smb1.recv_iov[2] = cur[1];
2944
2945
0
    tevent_req_done(req);
2946
0
  }
2947
2948
0
  return NT_STATUS_RETRY;
2949
0
}
2950
2951
NTSTATUS smb1cli_req_recv(struct tevent_req *req,
2952
        TALLOC_CTX *mem_ctx,
2953
        struct iovec **piov,
2954
        uint8_t **phdr,
2955
        uint8_t *pwct,
2956
        uint16_t **pvwv,
2957
        uint32_t *pvwv_offset,
2958
        uint32_t *pnum_bytes,
2959
        uint8_t **pbytes,
2960
        uint32_t *pbytes_offset,
2961
        uint8_t **pinbuf,
2962
        const struct smb1cli_req_expected_response *expected,
2963
        size_t num_expected)
2964
0
{
2965
0
  struct smbXcli_req_state *state =
2966
0
    tevent_req_data(req,
2967
0
    struct smbXcli_req_state);
2968
0
  NTSTATUS status = NT_STATUS_OK;
2969
0
  struct iovec *recv_iov = NULL;
2970
0
  uint8_t *hdr = NULL;
2971
0
  uint8_t wct = 0;
2972
0
  uint32_t vwv_offset = 0;
2973
0
  uint16_t *vwv = NULL;
2974
0
  uint32_t num_bytes = 0;
2975
0
  uint32_t bytes_offset = 0;
2976
0
  uint8_t *bytes = NULL;
2977
0
  size_t i;
2978
0
  bool found_status = false;
2979
0
  bool found_size = false;
2980
2981
0
  if (piov != NULL) {
2982
0
    *piov = NULL;
2983
0
  }
2984
0
  if (phdr != NULL) {
2985
0
    *phdr = 0;
2986
0
  }
2987
0
  if (pwct != NULL) {
2988
0
    *pwct = 0;
2989
0
  }
2990
0
  if (pvwv != NULL) {
2991
0
    *pvwv = NULL;
2992
0
  }
2993
0
  if (pvwv_offset != NULL) {
2994
0
    *pvwv_offset = 0;
2995
0
  }
2996
0
  if (pnum_bytes != NULL) {
2997
0
    *pnum_bytes = 0;
2998
0
  }
2999
0
  if (pbytes != NULL) {
3000
0
    *pbytes = NULL;
3001
0
  }
3002
0
  if (pbytes_offset != NULL) {
3003
0
    *pbytes_offset = 0;
3004
0
  }
3005
0
  if (pinbuf != NULL) {
3006
0
    *pinbuf = NULL;
3007
0
  }
3008
3009
0
  if (state->inbuf != NULL) {
3010
0
    recv_iov = state->smb1.recv_iov;
3011
0
    state->smb1.recv_iov = NULL;
3012
0
    if (state->smb1.recv_cmd != SMBreadBraw) {
3013
0
      hdr = (uint8_t *)recv_iov[0].iov_base;
3014
0
      wct = recv_iov[1].iov_len/2;
3015
0
      vwv = (uint16_t *)recv_iov[1].iov_base;
3016
0
      vwv_offset = PTR_DIFF(vwv, hdr);
3017
0
      num_bytes = recv_iov[2].iov_len;
3018
0
      bytes = (uint8_t *)recv_iov[2].iov_base;
3019
0
      bytes_offset = PTR_DIFF(bytes, hdr);
3020
0
    }
3021
0
  }
3022
3023
0
  if (tevent_req_is_nterror(req, &status)) {
3024
0
    for (i=0; i < num_expected; i++) {
3025
0
      if (NT_STATUS_EQUAL(status, expected[i].status)) {
3026
0
        found_status = true;
3027
0
        break;
3028
0
      }
3029
0
    }
3030
3031
0
    if (found_status) {
3032
0
      return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
3033
0
    }
3034
3035
0
    return status;
3036
0
  }
3037
3038
0
  if (num_expected == 0) {
3039
0
    found_status = true;
3040
0
    found_size = true;
3041
0
  }
3042
3043
0
  status = state->smb1.recv_status;
3044
3045
0
  for (i=0; i < num_expected; i++) {
3046
0
    if (!NT_STATUS_EQUAL(status, expected[i].status)) {
3047
0
      continue;
3048
0
    }
3049
3050
0
    found_status = true;
3051
0
    if (expected[i].wct == 0) {
3052
0
      found_size = true;
3053
0
      break;
3054
0
    }
3055
3056
0
    if (expected[i].wct == wct) {
3057
0
      found_size = true;
3058
0
      break;
3059
0
    }
3060
0
  }
3061
3062
0
  if (!found_status) {
3063
0
    return status;
3064
0
  }
3065
3066
0
  if (!found_size) {
3067
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
3068
0
  }
3069
3070
0
  if (piov != NULL) {
3071
0
    *piov = talloc_move(mem_ctx, &recv_iov);
3072
0
  }
3073
3074
0
  if (phdr != NULL) {
3075
0
    *phdr = hdr;
3076
0
  }
3077
0
  if (pwct != NULL) {
3078
0
    *pwct = wct;
3079
0
  }
3080
0
  if (pvwv != NULL) {
3081
0
    *pvwv = vwv;
3082
0
  }
3083
0
  if (pvwv_offset != NULL) {
3084
0
    *pvwv_offset = vwv_offset;
3085
0
  }
3086
0
  if (pnum_bytes != NULL) {
3087
0
    *pnum_bytes = num_bytes;
3088
0
  }
3089
0
  if (pbytes != NULL) {
3090
0
    *pbytes = bytes;
3091
0
  }
3092
0
  if (pbytes_offset != NULL) {
3093
0
    *pbytes_offset = bytes_offset;
3094
0
  }
3095
0
  if (pinbuf != NULL) {
3096
0
    *pinbuf = state->inbuf;
3097
0
  }
3098
3099
0
  return status;
3100
0
}
3101
3102
size_t smb1cli_req_wct_ofs(struct tevent_req **reqs, int num_reqs)
3103
0
{
3104
0
  size_t wct_ofs;
3105
0
  int i;
3106
3107
0
  wct_ofs = HDR_WCT;
3108
3109
0
  for (i=0; i<num_reqs; i++) {
3110
0
    struct smbXcli_req_state *state;
3111
0
    state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3112
0
    wct_ofs += smbXcli_iov_len(state->smb1.iov+2,
3113
0
             state->smb1.iov_count-2);
3114
0
    wct_ofs = (wct_ofs + 3) & ~3;
3115
0
  }
3116
0
  return wct_ofs;
3117
0
}
3118
3119
NTSTATUS smb1cli_req_chain_submit(struct tevent_req **reqs, int num_reqs)
3120
0
{
3121
0
  struct smbXcli_req_state *first_state =
3122
0
    tevent_req_data(reqs[0],
3123
0
    struct smbXcli_req_state);
3124
0
  struct smbXcli_req_state *state;
3125
0
  size_t wct_offset;
3126
0
  size_t chain_padding = 0;
3127
0
  int i, iovlen;
3128
0
  struct iovec *iov = NULL;
3129
0
  struct iovec *this_iov;
3130
0
  NTSTATUS status;
3131
0
  ssize_t nbt_len;
3132
3133
0
  if (num_reqs == 1) {
3134
0
    return smb1cli_req_writev_submit(reqs[0], first_state,
3135
0
             first_state->smb1.iov,
3136
0
             first_state->smb1.iov_count);
3137
0
  }
3138
3139
0
  iovlen = 0;
3140
0
  for (i=0; i<num_reqs; i++) {
3141
0
    if (!tevent_req_is_in_progress(reqs[i])) {
3142
0
      return NT_STATUS_INTERNAL_ERROR;
3143
0
    }
3144
3145
0
    state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3146
3147
0
    if (state->smb1.iov_count < 4) {
3148
0
      return NT_STATUS_INVALID_PARAMETER_MIX;
3149
0
    }
3150
3151
0
    if (i == 0) {
3152
      /*
3153
       * The NBT and SMB header
3154
       */
3155
0
      iovlen += 2;
3156
0
    } else {
3157
      /*
3158
       * Chain padding
3159
       */
3160
0
      iovlen += 1;
3161
0
    }
3162
3163
    /*
3164
     * words and bytes
3165
     */
3166
0
    iovlen += state->smb1.iov_count - 2;
3167
0
  }
3168
3169
0
  iov = talloc_zero_array(first_state, struct iovec, iovlen);
3170
0
  if (iov == NULL) {
3171
0
    return NT_STATUS_NO_MEMORY;
3172
0
  }
3173
3174
0
  first_state->smb1.chained_requests = (struct tevent_req **)talloc_memdup(
3175
0
    first_state, reqs, sizeof(*reqs) * num_reqs);
3176
0
  if (first_state->smb1.chained_requests == NULL) {
3177
0
    TALLOC_FREE(iov);
3178
0
    return NT_STATUS_NO_MEMORY;
3179
0
  }
3180
3181
0
  wct_offset = HDR_WCT;
3182
0
  this_iov = iov;
3183
3184
0
  for (i=0; i<num_reqs; i++) {
3185
0
    size_t next_padding = 0;
3186
0
    uint16_t *vwv;
3187
3188
0
    state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3189
3190
0
    if (i < num_reqs-1) {
3191
0
      if (!smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))
3192
0
          || CVAL(state->smb1.hdr, HDR_WCT) < 2) {
3193
0
        TALLOC_FREE(iov);
3194
0
        TALLOC_FREE(first_state->smb1.chained_requests);
3195
0
        return NT_STATUS_INVALID_PARAMETER_MIX;
3196
0
      }
3197
0
    }
3198
3199
0
    wct_offset += smbXcli_iov_len(state->smb1.iov+2,
3200
0
                state->smb1.iov_count-2) + 1;
3201
0
    if ((wct_offset % 4) != 0) {
3202
0
      next_padding = 4 - (wct_offset % 4);
3203
0
    }
3204
0
    wct_offset += next_padding;
3205
0
    vwv = state->smb1.vwv;
3206
3207
0
    if (i < num_reqs-1) {
3208
0
      struct smbXcli_req_state *next_state =
3209
0
        tevent_req_data(reqs[i+1],
3210
0
        struct smbXcli_req_state);
3211
0
      SCVAL(vwv+0, 0, CVAL(next_state->smb1.hdr, HDR_COM));
3212
0
      SCVAL(vwv+0, 1, 0);
3213
0
      SSVAL(vwv+1, 0, wct_offset);
3214
0
    } else if (smb1cli_is_andx_req(CVAL(state->smb1.hdr, HDR_COM))) {
3215
      /* properly end the chain */
3216
0
      SCVAL(vwv+0, 0, 0xff);
3217
0
      SCVAL(vwv+0, 1, 0xff);
3218
0
      SSVAL(vwv+1, 0, 0);
3219
0
    }
3220
3221
0
    if (i == 0) {
3222
      /*
3223
       * The NBT and SMB header
3224
       */
3225
0
      this_iov[0] = state->smb1.iov[0];
3226
0
      this_iov[1] = state->smb1.iov[1];
3227
0
      this_iov += 2;
3228
0
    } else {
3229
      /*
3230
       * This one is a bit subtle. We have to add
3231
       * chain_padding bytes between the requests, and we
3232
       * have to also include the wct field of the
3233
       * subsequent requests. We use the subsequent header
3234
       * for the padding, it contains the wct field in its
3235
       * last byte.
3236
       */
3237
0
      this_iov[0].iov_len = chain_padding+1;
3238
0
      this_iov[0].iov_base = (void *)&state->smb1.hdr[
3239
0
        sizeof(state->smb1.hdr) - this_iov[0].iov_len];
3240
0
      memset(this_iov[0].iov_base, 0, this_iov[0].iov_len-1);
3241
0
      this_iov += 1;
3242
0
    }
3243
3244
    /*
3245
     * copy the words and bytes
3246
     */
3247
0
    memcpy(this_iov, state->smb1.iov+2,
3248
0
           sizeof(struct iovec) * (state->smb1.iov_count-2));
3249
0
    this_iov += state->smb1.iov_count - 2;
3250
0
    chain_padding = next_padding;
3251
0
  }
3252
3253
0
  nbt_len = iov_buflen(&iov[1], iovlen-1);
3254
0
  if ((nbt_len == -1) || (nbt_len > first_state->conn->smb1.max_xmit)) {
3255
0
    TALLOC_FREE(iov);
3256
0
    TALLOC_FREE(first_state->smb1.chained_requests);
3257
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
3258
0
  }
3259
3260
0
  status = smb1cli_req_writev_submit(reqs[0], first_state, iov, iovlen);
3261
0
  if (!NT_STATUS_IS_OK(status)) {
3262
0
    TALLOC_FREE(iov);
3263
0
    TALLOC_FREE(first_state->smb1.chained_requests);
3264
0
    return status;
3265
0
  }
3266
3267
0
  return NT_STATUS_OK;
3268
0
}
3269
3270
struct tevent_queue *smbXcli_conn_send_queue(struct smbXcli_conn *conn)
3271
0
{
3272
0
  return conn->outgoing;
3273
0
}
3274
3275
bool smbXcli_conn_has_async_calls(struct smbXcli_conn *conn)
3276
0
{
3277
0
  return ((tevent_queue_length(conn->outgoing) != 0)
3278
0
    || (talloc_array_length(conn->pending) != 0));
3279
0
}
3280
3281
bool smbXcli_conn_dfs_supported(struct smbXcli_conn *conn)
3282
0
{
3283
0
  if (conn->protocol >= PROTOCOL_SMB2_02) {
3284
0
    return (smb2cli_conn_server_capabilities(conn) & SMB2_CAP_DFS);
3285
0
  }
3286
3287
0
  return (smb1cli_conn_capabilities(conn) & CAP_DFS);
3288
0
}
3289
3290
bool smb2cli_conn_req_possible(struct smbXcli_conn *conn, uint32_t *max_dyn_len)
3291
0
{
3292
0
  uint16_t credits = 1;
3293
3294
0
  if (conn->smb2.cur_credits == 0) {
3295
0
    if (max_dyn_len != NULL) {
3296
0
      *max_dyn_len = 0;
3297
0
    }
3298
0
    return false;
3299
0
  }
3300
3301
0
  if (conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3302
0
    credits = conn->smb2.cur_credits;
3303
0
  }
3304
3305
0
  if (max_dyn_len != NULL) {
3306
0
    *max_dyn_len = credits * 65536;
3307
0
  }
3308
3309
0
  return true;
3310
0
}
3311
3312
uint32_t smb2cli_conn_server_capabilities(struct smbXcli_conn *conn)
3313
0
{
3314
0
  return conn->smb2.server.capabilities;
3315
0
}
3316
3317
uint16_t smb2cli_conn_server_security_mode(struct smbXcli_conn *conn)
3318
0
{
3319
0
  return conn->smb2.server.security_mode;
3320
0
}
3321
3322
uint16_t smb2cli_conn_server_signing_algo(struct smbXcli_conn *conn)
3323
0
{
3324
0
  return conn->smb2.server.sign_algo;
3325
0
}
3326
3327
uint16_t smb2cli_conn_server_encryption_algo(struct smbXcli_conn *conn)
3328
0
{
3329
0
  return conn->smb2.server.cipher;
3330
0
}
3331
3332
uint32_t smb2cli_conn_max_trans_size(struct smbXcli_conn *conn)
3333
0
{
3334
0
  return conn->smb2.server.max_trans_size;
3335
0
}
3336
3337
uint32_t smb2cli_conn_max_read_size(struct smbXcli_conn *conn)
3338
0
{
3339
0
  return conn->smb2.server.max_read_size;
3340
0
}
3341
3342
uint32_t smb2cli_conn_max_write_size(struct smbXcli_conn *conn)
3343
0
{
3344
0
  return conn->smb2.server.max_write_size;
3345
0
}
3346
3347
void smb2cli_conn_set_max_credits(struct smbXcli_conn *conn,
3348
          uint16_t max_credits)
3349
0
{
3350
0
  conn->smb2.max_credits = max_credits;
3351
0
}
3352
3353
uint16_t smb2cli_conn_get_cur_credits(struct smbXcli_conn *conn)
3354
0
{
3355
0
  return conn->smb2.cur_credits;
3356
0
}
3357
3358
uint8_t smb2cli_conn_get_io_priority(struct smbXcli_conn *conn)
3359
0
{
3360
0
  if (conn->protocol < PROTOCOL_SMB3_11) {
3361
0
    return 0;
3362
0
  }
3363
3364
0
  return conn->smb2.io_priority;
3365
0
}
3366
3367
void smb2cli_conn_set_io_priority(struct smbXcli_conn *conn,
3368
          uint8_t io_priority)
3369
0
{
3370
0
  conn->smb2.io_priority = io_priority;
3371
0
}
3372
3373
uint32_t smb2cli_conn_cc_chunk_len(struct smbXcli_conn *conn)
3374
0
{
3375
0
  return conn->smb2.cc_chunk_len;
3376
0
}
3377
3378
void smb2cli_conn_set_cc_chunk_len(struct smbXcli_conn *conn,
3379
            uint32_t chunk_len)
3380
0
{
3381
0
  conn->smb2.cc_chunk_len = chunk_len;
3382
0
}
3383
3384
uint32_t smb2cli_conn_cc_max_chunks(struct smbXcli_conn *conn)
3385
0
{
3386
0
  return conn->smb2.cc_max_chunks;
3387
0
}
3388
3389
void smb2cli_conn_set_cc_max_chunks(struct smbXcli_conn *conn,
3390
            uint32_t max_chunks)
3391
0
{
3392
0
  conn->smb2.cc_max_chunks = max_chunks;
3393
0
}
3394
3395
static void smb2cli_req_cancel_done(struct tevent_req *subreq);
3396
3397
static bool smb2cli_req_cancel(struct tevent_req *req)
3398
0
{
3399
0
  struct smbXcli_req_state *state =
3400
0
    tevent_req_data(req,
3401
0
    struct smbXcli_req_state);
3402
0
  struct smbXcli_tcon *tcon = state->tcon;
3403
0
  struct smbXcli_session *session = state->session;
3404
0
  uint8_t *fixed = state->smb2.pad;
3405
0
  uint16_t fixed_len = 4;
3406
0
  struct tevent_req *subreq;
3407
0
  struct smbXcli_req_state *substate;
3408
0
  NTSTATUS status;
3409
3410
0
  if (state->smb2.cancel_mid == UINT64_MAX) {
3411
    /*
3412
     * We already send a cancel,
3413
     * make sure we don't do it
3414
     * twice, otherwise we may
3415
     * expose the same NONCE for
3416
     * AES-128-GMAC signing
3417
     */
3418
0
    return true;
3419
0
  }
3420
3421
0
  SSVAL(fixed, 0, 0x04);
3422
0
  SSVAL(fixed, 2, 0);
3423
3424
0
  subreq = smb2cli_req_create(state, state->ev,
3425
0
            state->conn,
3426
0
            SMB2_OP_CANCEL,
3427
0
            0, 0, /* flags */
3428
0
            0, /* timeout */
3429
0
            tcon, session,
3430
0
            fixed, fixed_len,
3431
0
            NULL, 0, 0);
3432
0
  if (subreq == NULL) {
3433
0
    return false;
3434
0
  }
3435
0
  substate = tevent_req_data(subreq, struct smbXcli_req_state);
3436
3437
0
  substate->smb2.cancel_mid = BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID);
3438
3439
0
  SIVAL(substate->smb2.hdr, SMB2_HDR_FLAGS, state->smb2.cancel_flags);
3440
0
  SBVAL(substate->smb2.hdr, SMB2_HDR_MESSAGE_ID, state->smb2.cancel_mid);
3441
0
  SBVAL(substate->smb2.hdr, SMB2_HDR_ASYNC_ID, state->smb2.cancel_aid);
3442
3443
  /*
3444
   * remember that we don't send a cancel again
3445
   */
3446
0
  state->smb2.cancel_mid = UINT64_MAX;
3447
3448
0
  status = smb2cli_req_compound_submit(&subreq, 1);
3449
0
  if (!NT_STATUS_IS_OK(status)) {
3450
0
    TALLOC_FREE(subreq);
3451
0
    return false;
3452
0
  }
3453
3454
0
  tevent_req_set_callback(subreq, smb2cli_req_cancel_done, NULL);
3455
3456
0
  return true;
3457
0
}
3458
3459
static void smb2cli_req_cancel_done(struct tevent_req *subreq)
3460
0
{
3461
  /* we do not care about the result */
3462
0
  TALLOC_FREE(subreq);
3463
0
}
3464
3465
struct timeval smbXcli_req_endtime(struct tevent_req *req)
3466
0
{
3467
0
  struct smbXcli_req_state *state = tevent_req_data(
3468
0
    req, struct smbXcli_req_state);
3469
3470
0
  return state->endtime;
3471
0
}
3472
3473
struct tevent_req *smb2cli_req_create(TALLOC_CTX *mem_ctx,
3474
              struct tevent_context *ev,
3475
              struct smbXcli_conn *conn,
3476
              uint16_t cmd,
3477
              uint32_t additional_flags,
3478
              uint32_t clear_flags,
3479
              uint32_t timeout_msec,
3480
              struct smbXcli_tcon *tcon,
3481
              struct smbXcli_session *session,
3482
              const uint8_t *fixed,
3483
              uint16_t fixed_len,
3484
              const uint8_t *dyn,
3485
              uint32_t dyn_len,
3486
              uint32_t max_dyn_len)
3487
0
{
3488
0
  struct tevent_req *req;
3489
0
  struct smbXcli_req_state *state;
3490
0
  uint32_t flags = 0;
3491
0
  uint32_t tid = 0;
3492
0
  uint64_t uid = 0;
3493
0
  bool use_channel_sequence = conn->smb2.force_channel_sequence;
3494
0
  uint16_t channel_sequence = 0;
3495
0
  bool use_replay_flag = false;
3496
0
  enum protocol_types proto = smbXcli_conn_protocol(conn);
3497
3498
0
  req = tevent_req_create(mem_ctx, &state,
3499
0
        struct smbXcli_req_state);
3500
0
  if (req == NULL) {
3501
0
    return NULL;
3502
0
  }
3503
3504
0
  if ((proto > PROTOCOL_NONE) && (proto < PROTOCOL_SMB2_02)) {
3505
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
3506
0
    return req;
3507
0
  }
3508
3509
0
  state->ev = ev;
3510
0
  state->conn = conn;
3511
0
  state->session = session;
3512
0
  state->tcon = tcon;
3513
3514
0
  if (conn->smb2.server.capabilities & SMB2_CAP_PERSISTENT_HANDLES) {
3515
0
    use_channel_sequence = true;
3516
0
  } else if (conn->smb2.server.capabilities & SMB2_CAP_MULTI_CHANNEL) {
3517
0
    use_channel_sequence = true;
3518
0
  }
3519
3520
0
  if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_00) {
3521
0
    use_replay_flag = true;
3522
0
  }
3523
3524
0
  if (smbXcli_conn_protocol(conn) >= PROTOCOL_SMB3_11) {
3525
0
    flags |= SMB2_PRIORITY_VALUE_TO_MASK(conn->smb2.io_priority);
3526
0
  }
3527
3528
0
  if (session) {
3529
0
    uid = session->smb2->session_id;
3530
3531
0
    if (use_channel_sequence) {
3532
0
      channel_sequence = session->smb2->channel_sequence;
3533
0
    }
3534
3535
0
    if (use_replay_flag && session->smb2->replay_active) {
3536
0
      additional_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3537
0
    }
3538
3539
0
    state->smb2.should_sign = session->smb2->should_sign;
3540
0
    state->smb2.should_encrypt = session->smb2->should_encrypt;
3541
0
    state->smb2.require_signed_response =
3542
0
      session->smb2->require_signed_response;
3543
3544
0
    if (cmd == SMB2_OP_SESSSETUP &&
3545
0
        !smb2_signing_key_valid(session->smb2_channel.signing_key) &&
3546
0
        smb2_signing_key_valid(session->smb2->signing_key))
3547
0
    {
3548
      /*
3549
       * a session bind needs to be signed
3550
       */
3551
0
      state->smb2.should_sign = true;
3552
0
    }
3553
3554
0
    if (cmd == SMB2_OP_SESSSETUP &&
3555
0
        !smb2_signing_key_valid(session->smb2_channel.signing_key)) {
3556
0
      state->smb2.should_encrypt = false;
3557
0
    }
3558
3559
0
    if (additional_flags & SMB2_HDR_FLAG_SIGNED) {
3560
0
      if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
3561
0
        tevent_req_nterror(req, NT_STATUS_NO_USER_SESSION_KEY);
3562
0
        return req;
3563
0
      }
3564
3565
0
      additional_flags &= ~SMB2_HDR_FLAG_SIGNED;
3566
0
      state->smb2.should_sign = true;
3567
0
    }
3568
0
  }
3569
3570
0
  if (tcon) {
3571
0
    tid = tcon->smb2.tcon_id;
3572
3573
0
    if (tcon->smb2.should_sign) {
3574
0
      state->smb2.should_sign = true;
3575
0
    }
3576
0
    if (tcon->smb2.should_encrypt) {
3577
0
      state->smb2.should_encrypt = true;
3578
0
    }
3579
0
  }
3580
3581
0
  if (conn->smb2.server.transport_trusted) {
3582
    /*
3583
     * We as a client agreed with the server that quic
3584
     * encryption is enough
3585
     */
3586
0
    state->smb2.should_encrypt = false;
3587
0
  }
3588
3589
0
  if (state->smb2.should_encrypt) {
3590
0
    state->smb2.should_sign = false;
3591
0
  }
3592
3593
0
  state->smb2.recv_iov = talloc_zero_array(state, struct iovec, 3);
3594
0
  if (tevent_req_nomem(state->smb2.recv_iov, req)) {
3595
0
    return req;
3596
0
  }
3597
3598
0
  flags |= additional_flags;
3599
0
  flags &= ~clear_flags;
3600
3601
0
  state->smb2.fixed = fixed;
3602
0
  state->smb2.fixed_len = fixed_len;
3603
0
  state->smb2.dyn = dyn;
3604
0
  state->smb2.dyn_len = dyn_len;
3605
0
  state->smb2.max_dyn_len = max_dyn_len;
3606
3607
0
  if (state->smb2.should_encrypt) {
3608
0
    SIVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3609
0
    SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID, uid);
3610
0
  }
3611
3612
0
  SIVAL(state->smb2.hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
3613
0
  SSVAL(state->smb2.hdr, SMB2_HDR_LENGTH,    SMB2_HDR_BODY);
3614
0
  SSVAL(state->smb2.hdr, SMB2_HDR_OPCODE,    cmd);
3615
0
  SSVAL(state->smb2.hdr, SMB2_HDR_CHANNEL_SEQUENCE, channel_sequence);
3616
0
  SIVAL(state->smb2.hdr, SMB2_HDR_FLAGS,   flags);
3617
0
  SIVAL(state->smb2.hdr, SMB2_HDR_PID,   0); /* reserved */
3618
0
  SIVAL(state->smb2.hdr, SMB2_HDR_TID,   tid);
3619
0
  SBVAL(state->smb2.hdr, SMB2_HDR_SESSION_ID,  uid);
3620
3621
0
  switch (cmd) {
3622
0
  case SMB2_OP_CANCEL:
3623
0
    state->one_way = true;
3624
0
    break;
3625
0
  case SMB2_OP_BREAK:
3626
    /*
3627
     * If this is a dummy request, it will have
3628
     * UINT64_MAX as message id.
3629
     * If we send on break acknowledgement,
3630
     * this gets overwritten later.
3631
     */
3632
0
    SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, UINT64_MAX);
3633
0
    break;
3634
0
  }
3635
3636
0
  if (timeout_msec > 0) {
3637
0
    state->endtime = timeval_current_ofs_msec(timeout_msec);
3638
0
    if (!tevent_req_set_endtime(req, ev, state->endtime)) {
3639
0
      return req;
3640
0
    }
3641
0
  }
3642
3643
0
  return req;
3644
0
}
3645
3646
void smb2cli_req_set_notify_async(struct tevent_req *req)
3647
0
{
3648
0
  struct smbXcli_req_state *state =
3649
0
    tevent_req_data(req,
3650
0
    struct smbXcli_req_state);
3651
3652
0
  state->smb2.notify_async = true;
3653
0
}
3654
3655
static void smb2cli_req_writev_done(struct tevent_req *subreq);
3656
static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
3657
                 TALLOC_CTX *tmp_mem,
3658
                 uint8_t *inbuf);
3659
3660
NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
3661
             int num_reqs)
3662
0
{
3663
0
  struct smbXcli_transport *xtp = NULL;
3664
0
  struct smbXcli_req_state *state;
3665
0
  struct tevent_req *subreq;
3666
0
  struct iovec *iov;
3667
0
  int i, num_iov, nbt_len;
3668
0
  int tf_iov = -1;
3669
0
  struct smb2_signing_key *encryption_key = NULL;
3670
0
  uint64_t encryption_session_id = 0;
3671
0
  uint64_t nonce_high = UINT64_MAX;
3672
0
  uint64_t nonce_low = UINT64_MAX;
3673
3674
  /*
3675
   * 1 for the nbt length, optional TRANSFORM
3676
   * per request: HDR, fixed, dyn, padding
3677
   * -1 because the last one does not need padding
3678
   */
3679
3680
0
  iov = talloc_array(reqs[0], struct iovec, 1 + 1 + 4*num_reqs - 1);
3681
0
  if (iov == NULL) {
3682
0
    return NT_STATUS_NO_MEMORY;
3683
0
  }
3684
3685
0
  num_iov = 1;
3686
0
  nbt_len = 0;
3687
3688
  /*
3689
   * the session of the first request that requires encryption
3690
   * specifies the encryption key.
3691
   */
3692
0
  for (i=0; i<num_reqs; i++) {
3693
0
    if (!tevent_req_is_in_progress(reqs[i])) {
3694
0
      return NT_STATUS_INTERNAL_ERROR;
3695
0
    }
3696
3697
0
    state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3698
3699
0
    if (!smbXcli_conn_is_connected(state->conn)) {
3700
0
      return NT_STATUS_CONNECTION_DISCONNECTED;
3701
0
    }
3702
3703
0
    if ((state->conn->protocol != PROTOCOL_NONE) &&
3704
0
        (state->conn->protocol < PROTOCOL_SMB2_02)) {
3705
0
      return NT_STATUS_REVISION_MISMATCH;
3706
0
    }
3707
3708
0
    if (state->session == NULL) {
3709
0
      continue;
3710
0
    }
3711
3712
0
    if (!state->smb2.should_encrypt) {
3713
0
      continue;
3714
0
    }
3715
3716
0
    encryption_key = state->session->smb2->encryption_key;
3717
0
    if (!smb2_signing_key_valid(encryption_key)) {
3718
0
      return NT_STATUS_INVALID_PARAMETER_MIX;
3719
0
    }
3720
3721
0
    encryption_session_id = state->session->smb2->session_id;
3722
3723
0
    state->session->smb2->nonce_low += 1;
3724
0
    if (state->session->smb2->nonce_low == 0) {
3725
0
      state->session->smb2->nonce_high += 1;
3726
0
      state->session->smb2->nonce_low += 1;
3727
0
    }
3728
3729
    /*
3730
     * CCM and GCM algorithms must never have their
3731
     * nonce wrap, or the security of the whole
3732
     * communication and the keys is destroyed.
3733
     * We must drop the connection once we have
3734
     * transferred too much data.
3735
     *
3736
     * NOTE: We assume nonces greater than 8 bytes.
3737
     */
3738
0
    if (state->session->smb2->nonce_high >=
3739
0
        state->session->smb2->nonce_high_max)
3740
0
    {
3741
0
      return NT_STATUS_ENCRYPTION_FAILED;
3742
0
    }
3743
3744
0
    nonce_high = state->session->smb2->nonce_high_random;
3745
0
    nonce_high += state->session->smb2->nonce_high;
3746
0
    nonce_low = state->session->smb2->nonce_low;
3747
3748
0
    tf_iov = num_iov;
3749
0
    iov[num_iov].iov_base = state->smb2.transform;
3750
0
    iov[num_iov].iov_len  = sizeof(state->smb2.transform);
3751
0
    num_iov += 1;
3752
3753
0
    SBVAL(state->smb2.transform, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3754
0
    SBVAL(state->smb2.transform, SMB2_TF_NONCE,
3755
0
          nonce_low);
3756
0
    SBVAL(state->smb2.transform, SMB2_TF_NONCE+8,
3757
0
          nonce_high);
3758
0
    SBVAL(state->smb2.transform, SMB2_TF_SESSION_ID,
3759
0
          encryption_session_id);
3760
3761
0
    nbt_len += SMB2_TF_HDR_SIZE;
3762
0
    break;
3763
0
  }
3764
3765
0
  for (i=0; i<num_reqs; i++) {
3766
0
    int hdr_iov;
3767
0
    size_t reqlen;
3768
0
    bool ret;
3769
0
    uint16_t opcode;
3770
0
    uint64_t avail;
3771
0
    uint16_t charge;
3772
0
    uint16_t credits;
3773
0
    uint64_t mid;
3774
0
    struct smb2_signing_key *signing_key = NULL;
3775
3776
0
    if (!tevent_req_is_in_progress(reqs[i])) {
3777
0
      return NT_STATUS_INTERNAL_ERROR;
3778
0
    }
3779
3780
0
    state = tevent_req_data(reqs[i], struct smbXcli_req_state);
3781
3782
0
    if (!smbXcli_conn_is_connected(state->conn)) {
3783
0
      return NT_STATUS_CONNECTION_DISCONNECTED;
3784
0
    }
3785
3786
0
    if ((state->conn->protocol != PROTOCOL_NONE) &&
3787
0
        (state->conn->protocol < PROTOCOL_SMB2_02)) {
3788
0
      return NT_STATUS_REVISION_MISMATCH;
3789
0
    }
3790
3791
0
    opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
3792
0
    if (opcode == SMB2_OP_CANCEL) {
3793
0
      goto skip_credits;
3794
0
    }
3795
3796
0
    avail = UINT64_MAX - state->conn->smb2.mid;
3797
0
    if (avail < 1) {
3798
0
      return NT_STATUS_CONNECTION_ABORTED;
3799
0
    }
3800
3801
0
    if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3802
0
      uint32_t max_dyn_len = 1;
3803
3804
0
      max_dyn_len = MAX(max_dyn_len, state->smb2.dyn_len);
3805
0
      max_dyn_len = MAX(max_dyn_len, state->smb2.max_dyn_len);
3806
3807
0
      charge = (max_dyn_len - 1)/ 65536 + 1;
3808
0
    } else {
3809
0
      charge = 1;
3810
0
    }
3811
3812
0
    charge = MAX(state->smb2.credit_charge, charge);
3813
3814
0
    avail = MIN(avail, state->conn->smb2.cur_credits);
3815
0
    if (avail < charge) {
3816
0
      DBG_ERR("Insufficient credits. "
3817
0
        "%"PRIu64" available, %"PRIu16" needed\n",
3818
0
        avail, charge);
3819
0
      return NT_STATUS_INTERNAL_ERROR;
3820
0
    }
3821
3822
0
    credits = 0;
3823
0
    if (state->conn->smb2.max_credits > state->conn->smb2.cur_credits) {
3824
0
      credits = state->conn->smb2.max_credits -
3825
0
          state->conn->smb2.cur_credits;
3826
0
    }
3827
0
    if (state->conn->smb2.max_credits >= state->conn->smb2.cur_credits) {
3828
0
      credits += 1;
3829
0
    }
3830
3831
0
    mid = state->conn->smb2.mid;
3832
0
    state->conn->smb2.mid += charge;
3833
0
    state->conn->smb2.cur_credits -= charge;
3834
3835
0
    if (state->conn->smb2.server.capabilities & SMB2_CAP_LARGE_MTU) {
3836
0
      SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT_CHARGE, charge);
3837
0
    }
3838
0
    SSVAL(state->smb2.hdr, SMB2_HDR_CREDIT, credits);
3839
0
    SBVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID, mid);
3840
3841
0
    state->smb2.cancel_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
3842
0
    state->smb2.cancel_flags &= ~SMB2_HDR_FLAG_CHAINED;
3843
0
    if (state->conn->smb2.server.sign_algo >= SMB2_SIGNING_AES128_GMAC) {
3844
0
      state->smb2.cancel_mid = mid;
3845
0
    } else {
3846
0
      state->smb2.cancel_mid = 0;
3847
0
    }
3848
0
    state->smb2.cancel_aid = 0;
3849
3850
0
skip_credits:
3851
0
    if (state->session && encryption_key == NULL) {
3852
      /*
3853
       * We prefer the channel signing key if it is
3854
       * already there.
3855
       */
3856
0
      if (state->smb2.should_sign) {
3857
0
        signing_key = state->session->smb2_channel.signing_key;
3858
0
      }
3859
3860
      /*
3861
       * If it is a channel binding, we already have the main
3862
       * signing key and try that one.
3863
       */
3864
0
      if (signing_key != NULL &&
3865
0
          !smb2_signing_key_valid(signing_key)) {
3866
0
        signing_key = state->session->smb2->signing_key;
3867
0
      }
3868
3869
      /*
3870
       * If we do not have any session key yet, we skip the
3871
       * signing of SMB2_OP_SESSSETUP requests.
3872
       */
3873
0
      if (signing_key != NULL &&
3874
0
          !smb2_signing_key_valid(signing_key)) {
3875
0
        signing_key = NULL;
3876
0
      }
3877
0
    }
3878
3879
0
    hdr_iov = num_iov;
3880
0
    iov[num_iov].iov_base = state->smb2.hdr;
3881
0
    iov[num_iov].iov_len  = sizeof(state->smb2.hdr);
3882
0
    num_iov += 1;
3883
3884
0
    iov[num_iov].iov_base = discard_const(state->smb2.fixed);
3885
0
    iov[num_iov].iov_len  = state->smb2.fixed_len;
3886
0
    num_iov += 1;
3887
3888
0
    if (state->smb2.dyn != NULL) {
3889
0
      iov[num_iov].iov_base = discard_const(state->smb2.dyn);
3890
0
      iov[num_iov].iov_len  = state->smb2.dyn_len;
3891
0
      num_iov += 1;
3892
0
    }
3893
3894
0
    reqlen  = sizeof(state->smb2.hdr);
3895
0
    reqlen += state->smb2.fixed_len;
3896
0
    reqlen += state->smb2.dyn_len;
3897
3898
0
    if (i < num_reqs-1) {
3899
0
      if ((reqlen % 8) > 0) {
3900
0
        uint8_t pad = 8 - (reqlen % 8);
3901
0
        iov[num_iov].iov_base = state->smb2.pad;
3902
0
        iov[num_iov].iov_len = pad;
3903
0
        num_iov += 1;
3904
0
        reqlen += pad;
3905
0
      }
3906
0
      SIVAL(state->smb2.hdr, SMB2_HDR_NEXT_COMMAND, reqlen);
3907
0
    }
3908
3909
0
    state->smb2.encryption_session_id = encryption_session_id;
3910
3911
0
    if (signing_key != NULL) {
3912
0
      NTSTATUS status;
3913
3914
0
      status = smb2_signing_sign_pdu(signing_key,
3915
0
                   &iov[hdr_iov], num_iov - hdr_iov);
3916
0
      if (!NT_STATUS_IS_OK(status)) {
3917
0
        return status;
3918
0
      }
3919
0
    }
3920
3921
0
    nbt_len += reqlen;
3922
3923
0
    ret = smbXcli_req_set_pending(reqs[i]);
3924
0
    if (!ret) {
3925
0
      return NT_STATUS_NO_MEMORY;
3926
0
    }
3927
0
  }
3928
3929
0
  state = tevent_req_data(reqs[0], struct smbXcli_req_state);
3930
0
  _smb_setlen_tcp(state->length_hdr, nbt_len);
3931
0
  iov[0].iov_base = state->length_hdr;
3932
0
  iov[0].iov_len  = sizeof(state->length_hdr);
3933
3934
0
  if (encryption_key != NULL) {
3935
0
    NTSTATUS status;
3936
0
    size_t buflen = nbt_len - SMB2_TF_HDR_SIZE;
3937
0
    uint8_t *buf;
3938
0
    int vi;
3939
3940
0
    buf = talloc_array(iov, uint8_t, buflen);
3941
0
    if (buf == NULL) {
3942
0
      return NT_STATUS_NO_MEMORY;
3943
0
    }
3944
3945
    /*
3946
     * We copy the buffers before encrypting them,
3947
     * this is at least currently needed for the
3948
     * to keep state->smb2.hdr.
3949
     *
3950
     * Also the callers may expect there buffers
3951
     * to be const.
3952
     */
3953
0
    for (vi = tf_iov + 1; vi < num_iov; vi++) {
3954
0
      struct iovec *v = &iov[vi];
3955
0
      const uint8_t *o = (const uint8_t *)v->iov_base;
3956
3957
0
      memcpy(buf, o, v->iov_len);
3958
0
      v->iov_base = (void *)buf;
3959
0
      buf += v->iov_len;
3960
0
    }
3961
3962
0
    status = smb2_signing_encrypt_pdu(encryption_key,
3963
0
          &iov[tf_iov], num_iov - tf_iov);
3964
0
    if (!NT_STATUS_IS_OK(status)) {
3965
0
      return status;
3966
0
    }
3967
0
  }
3968
3969
0
  if (state->conn->dispatch_incoming == NULL) {
3970
0
    state->conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
3971
0
  }
3972
3973
0
  xtp = state->conn->transport;
3974
0
  subreq = xtp->writev_send_fn(state,
3975
0
             state->ev,
3976
0
             xtp,
3977
0
             state->conn->outgoing,
3978
0
             iov,
3979
0
             num_iov);
3980
0
  if (subreq == NULL) {
3981
0
    return NT_STATUS_NO_MEMORY;
3982
0
  }
3983
0
  state->writev_recv_fn = xtp->writev_recv_fn;
3984
0
  tevent_req_set_callback(subreq, smb2cli_req_writev_done, reqs[0]);
3985
0
  state->write_req = subreq;
3986
3987
0
  return NT_STATUS_OK;
3988
0
}
3989
3990
void smb2cli_req_set_credit_charge(struct tevent_req *req, uint16_t charge)
3991
0
{
3992
0
  struct smbXcli_req_state *state =
3993
0
    tevent_req_data(req,
3994
0
    struct smbXcli_req_state);
3995
3996
0
  state->smb2.credit_charge = charge;
3997
0
}
3998
3999
struct tevent_req *smb2cli_req_send(TALLOC_CTX *mem_ctx,
4000
            struct tevent_context *ev,
4001
            struct smbXcli_conn *conn,
4002
            uint16_t cmd,
4003
            uint32_t additional_flags,
4004
            uint32_t clear_flags,
4005
            uint32_t timeout_msec,
4006
            struct smbXcli_tcon *tcon,
4007
            struct smbXcli_session *session,
4008
            const uint8_t *fixed,
4009
            uint16_t fixed_len,
4010
            const uint8_t *dyn,
4011
            uint32_t dyn_len,
4012
            uint32_t max_dyn_len)
4013
0
{
4014
0
  struct tevent_req *req;
4015
0
  NTSTATUS status;
4016
4017
0
  req = smb2cli_req_create(mem_ctx, ev, conn, cmd,
4018
0
         additional_flags, clear_flags,
4019
0
         timeout_msec,
4020
0
         tcon, session,
4021
0
         fixed, fixed_len,
4022
0
         dyn, dyn_len,
4023
0
         max_dyn_len);
4024
0
  if (req == NULL) {
4025
0
    return NULL;
4026
0
  }
4027
0
  if (!tevent_req_is_in_progress(req)) {
4028
0
    return tevent_req_post(req, ev);
4029
0
  }
4030
0
  status = smb2cli_req_compound_submit(&req, 1);
4031
0
  if (tevent_req_nterror(req, status)) {
4032
0
    return tevent_req_post(req, ev);
4033
0
  }
4034
0
  return req;
4035
0
}
4036
4037
static void smb2cli_req_writev_done(struct tevent_req *subreq)
4038
0
{
4039
0
  struct tevent_req *req =
4040
0
    tevent_req_callback_data(subreq,
4041
0
    struct tevent_req);
4042
0
  struct smbXcli_req_state *state =
4043
0
    tevent_req_data(req,
4044
0
    struct smbXcli_req_state);
4045
0
  ssize_t nwritten;
4046
0
  int err;
4047
4048
0
  state->write_req = NULL;
4049
4050
0
  nwritten = state->writev_recv_fn(subreq, &err);
4051
0
  TALLOC_FREE(subreq);
4052
0
  if (nwritten == -1) {
4053
    /* here, we need to notify all pending requests */
4054
0
    NTSTATUS status = map_nt_error_from_unix_common(err);
4055
0
    smbXcli_conn_disconnect(state->conn, status);
4056
0
    return;
4057
0
  }
4058
0
}
4059
4060
static struct smbXcli_session* smbXcli_session_by_uid(struct smbXcli_conn *conn,
4061
                 uint64_t uid)
4062
0
{
4063
0
  struct smbXcli_session *s = conn->sessions;
4064
4065
0
  for (; s; s = s->next) {
4066
0
    if (s->smb2->session_id != uid) {
4067
0
      continue;
4068
0
    }
4069
0
    break;
4070
0
  }
4071
4072
0
  return s;
4073
0
}
4074
4075
static NTSTATUS smb2cli_inbuf_parse_compound(struct smbXcli_conn *conn,
4076
               uint8_t *buf,
4077
               size_t buflen,
4078
               TALLOC_CTX *mem_ctx,
4079
               struct iovec **piov,
4080
               size_t *pnum_iov)
4081
0
{
4082
0
  struct iovec *iov;
4083
0
  int num_iov = 0;
4084
0
  size_t taken = 0;
4085
0
  uint8_t *first_hdr = buf;
4086
0
  size_t verified_buflen = 0;
4087
0
  uint8_t *tf = NULL;
4088
0
  size_t tf_len = 0;
4089
4090
0
  iov = talloc_array(mem_ctx, struct iovec, num_iov);
4091
0
  if (iov == NULL) {
4092
0
    return NT_STATUS_NO_MEMORY;
4093
0
  }
4094
4095
0
  while (taken < buflen) {
4096
0
    size_t len = buflen - taken;
4097
0
    uint8_t *hdr = first_hdr + taken;
4098
0
    struct iovec *cur;
4099
0
    size_t full_size;
4100
0
    size_t next_command_ofs;
4101
0
    uint16_t body_size;
4102
0
    struct iovec *iov_tmp;
4103
4104
0
    if (verified_buflen > taken) {
4105
0
      len = verified_buflen - taken;
4106
0
    } else {
4107
0
      tf = NULL;
4108
0
      tf_len = 0;
4109
0
    }
4110
4111
0
    if (len < 4) {
4112
0
      DEBUG(10, ("%d bytes left, expected at least %d\n",
4113
0
           (int)len, 4));
4114
0
      goto inval;
4115
0
    }
4116
0
    if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
4117
0
      struct smbXcli_session *s;
4118
0
      uint64_t uid;
4119
0
      struct iovec tf_iov[2];
4120
0
      size_t enc_len;
4121
0
      NTSTATUS status;
4122
4123
0
      if (len < SMB2_TF_HDR_SIZE) {
4124
0
        DEBUG(10, ("%d bytes left, expected at least %d\n",
4125
0
             (int)len, SMB2_TF_HDR_SIZE));
4126
0
        goto inval;
4127
0
      }
4128
0
      tf = hdr;
4129
0
      tf_len = SMB2_TF_HDR_SIZE;
4130
0
      taken += tf_len;
4131
4132
0
      hdr = first_hdr + taken;
4133
0
      enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
4134
0
      uid = BVAL(tf, SMB2_TF_SESSION_ID);
4135
4136
0
      if (len < SMB2_TF_HDR_SIZE + enc_len) {
4137
0
        DEBUG(10, ("%d bytes left, expected at least %d\n",
4138
0
             (int)len,
4139
0
             (int)(SMB2_TF_HDR_SIZE + enc_len)));
4140
0
        goto inval;
4141
0
      }
4142
4143
0
      s = smbXcli_session_by_uid(conn, uid);
4144
0
      if (s == NULL) {
4145
0
        DEBUG(10, ("unknown session_id %llu\n",
4146
0
             (unsigned long long)uid));
4147
0
        goto inval;
4148
0
      }
4149
4150
0
      tf_iov[0].iov_base = (void *)tf;
4151
0
      tf_iov[0].iov_len = tf_len;
4152
0
      tf_iov[1].iov_base = (void *)hdr;
4153
0
      tf_iov[1].iov_len = enc_len;
4154
4155
0
      status = smb2_signing_decrypt_pdu(s->smb2->decryption_key,
4156
0
                tf_iov, 2);
4157
0
      if (!NT_STATUS_IS_OK(status)) {
4158
0
        TALLOC_FREE(iov);
4159
0
        return status;
4160
0
      }
4161
4162
0
      verified_buflen = taken + enc_len;
4163
0
      len = enc_len;
4164
0
    }
4165
4166
    /*
4167
     * We need the header plus the body length field
4168
     */
4169
4170
0
    if (len < SMB2_HDR_BODY + 2) {
4171
0
      DEBUG(10, ("%d bytes left, expected at least %d\n",
4172
0
           (int)len, SMB2_HDR_BODY));
4173
0
      goto inval;
4174
0
    }
4175
0
    if (IVAL(hdr, 0) != SMB2_MAGIC) {
4176
0
      DEBUG(10, ("Got non-SMB2 PDU: %x\n",
4177
0
           IVAL(hdr, 0)));
4178
0
      goto inval;
4179
0
    }
4180
0
    if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
4181
0
      DEBUG(10, ("Got HDR len %d, expected %d\n",
4182
0
           SVAL(hdr, 4), SMB2_HDR_BODY));
4183
0
      goto inval;
4184
0
    }
4185
4186
0
    full_size = len;
4187
0
    next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
4188
0
    body_size = SVAL(hdr, SMB2_HDR_BODY);
4189
4190
0
    if (next_command_ofs != 0) {
4191
0
      if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
4192
0
        goto inval;
4193
0
      }
4194
0
      if (next_command_ofs > full_size) {
4195
0
        goto inval;
4196
0
      }
4197
0
      full_size = next_command_ofs;
4198
0
    }
4199
0
    if (body_size < 2) {
4200
0
      goto inval;
4201
0
    }
4202
0
    body_size &= 0xfffe;
4203
4204
0
    if (body_size > (full_size - SMB2_HDR_BODY)) {
4205
0
      goto inval;
4206
0
    }
4207
4208
0
    iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec,
4209
0
           num_iov + 4);
4210
0
    if (iov_tmp == NULL) {
4211
0
      TALLOC_FREE(iov);
4212
0
      return NT_STATUS_NO_MEMORY;
4213
0
    }
4214
0
    iov = iov_tmp;
4215
0
    cur = &iov[num_iov];
4216
0
    num_iov += 4;
4217
4218
0
    cur[0].iov_base = tf;
4219
0
    cur[0].iov_len  = tf_len;
4220
0
    cur[1].iov_base = hdr;
4221
0
    cur[1].iov_len  = SMB2_HDR_BODY;
4222
0
    cur[2].iov_base = hdr + SMB2_HDR_BODY;
4223
0
    cur[2].iov_len  = body_size;
4224
0
    cur[3].iov_base = hdr + SMB2_HDR_BODY + body_size;
4225
0
    cur[3].iov_len  = full_size - (SMB2_HDR_BODY + body_size);
4226
4227
0
    taken += full_size;
4228
0
  }
4229
4230
0
  *piov = iov;
4231
0
  *pnum_iov = num_iov;
4232
0
  return NT_STATUS_OK;
4233
4234
0
inval:
4235
0
  TALLOC_FREE(iov);
4236
0
  return NT_STATUS_INVALID_NETWORK_RESPONSE;
4237
0
}
4238
4239
static struct tevent_req *smb2cli_conn_find_pending(struct smbXcli_conn *conn,
4240
                uint64_t mid)
4241
0
{
4242
0
  size_t num_pending = talloc_array_length(conn->pending);
4243
0
  size_t i;
4244
4245
0
  for (i=0; i<num_pending; i++) {
4246
0
    struct tevent_req *req = conn->pending[i];
4247
0
    struct smbXcli_req_state *state =
4248
0
      tevent_req_data(req,
4249
0
      struct smbXcli_req_state);
4250
4251
0
    if (mid == BVAL(state->smb2.hdr, SMB2_HDR_MESSAGE_ID)) {
4252
0
      return req;
4253
0
    }
4254
0
  }
4255
0
  return NULL;
4256
0
}
4257
4258
static NTSTATUS smb2cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
4259
                 TALLOC_CTX *tmp_mem,
4260
                 uint8_t *inbuf)
4261
0
{
4262
0
  struct tevent_req *req;
4263
0
  struct smbXcli_req_state *state = NULL;
4264
0
  struct iovec *iov = NULL;
4265
0
  size_t i, num_iov = 0;
4266
0
  NTSTATUS status;
4267
0
  bool defer = true;
4268
0
  struct smbXcli_session *last_session = NULL;
4269
0
  size_t inbuf_len = smb_len_tcp(inbuf);
4270
4271
0
  status = smb2cli_inbuf_parse_compound(conn,
4272
0
                inbuf + NBT_HDR_SIZE,
4273
0
                inbuf_len,
4274
0
                tmp_mem,
4275
0
                &iov, &num_iov);
4276
0
  if (!NT_STATUS_IS_OK(status)) {
4277
0
    return status;
4278
0
  }
4279
4280
0
  for (i=0; i<num_iov; i+=4) {
4281
0
    uint8_t *inbuf_ref = NULL;
4282
0
    struct iovec *cur = &iov[i];
4283
0
    uint8_t *inhdr = (uint8_t *)cur[1].iov_base;
4284
0
    uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
4285
0
    uint32_t flags = IVAL(inhdr, SMB2_HDR_FLAGS);
4286
0
    uint64_t mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
4287
0
    uint16_t req_opcode;
4288
0
    uint32_t req_flags;
4289
0
    uint16_t credits = SVAL(inhdr, SMB2_HDR_CREDIT);
4290
0
    uint32_t new_credits;
4291
0
    struct smbXcli_session *session = NULL;
4292
0
    struct smb2_signing_key *signing_key = NULL;
4293
0
    bool was_encrypted = false;
4294
4295
0
    new_credits = conn->smb2.cur_credits;
4296
0
    new_credits += credits;
4297
0
    if (new_credits > UINT16_MAX) {
4298
0
      return NT_STATUS_INVALID_NETWORK_RESPONSE;
4299
0
    }
4300
0
    conn->smb2.cur_credits += credits;
4301
4302
0
    req = smb2cli_conn_find_pending(conn, mid);
4303
0
    if (req == NULL) {
4304
0
      return NT_STATUS_INVALID_NETWORK_RESPONSE;
4305
0
    }
4306
0
    state = tevent_req_data(req, struct smbXcli_req_state);
4307
4308
0
    req_opcode = SVAL(state->smb2.hdr, SMB2_HDR_OPCODE);
4309
0
    if (opcode != req_opcode) {
4310
0
      return NT_STATUS_INVALID_NETWORK_RESPONSE;
4311
0
    }
4312
0
    req_flags = SVAL(state->smb2.hdr, SMB2_HDR_FLAGS);
4313
4314
0
    if (!(flags & SMB2_HDR_FLAG_REDIRECT)) {
4315
0
      return NT_STATUS_INVALID_NETWORK_RESPONSE;
4316
0
    }
4317
4318
0
    status = NT_STATUS(IVAL(inhdr, SMB2_HDR_STATUS));
4319
0
    if ((flags & SMB2_HDR_FLAG_ASYNC) &&
4320
0
        NT_STATUS_EQUAL(status, NT_STATUS_PENDING)) {
4321
0
      uint64_t async_id = BVAL(inhdr, SMB2_HDR_ASYNC_ID);
4322
4323
0
      if (state->smb2.got_async) {
4324
        /* We only expect one STATUS_PENDING response */
4325
0
        return NT_STATUS_INVALID_NETWORK_RESPONSE;
4326
0
      }
4327
0
      state->smb2.got_async = true;
4328
4329
      /*
4330
       * async interim responses are not signed,
4331
       * even if the SMB2_HDR_FLAG_SIGNED flag
4332
       * is set.
4333
       */
4334
0
      state->smb2.cancel_flags |= SMB2_HDR_FLAG_ASYNC;
4335
0
      state->smb2.cancel_aid = async_id;
4336
4337
0
      if (state->smb2.notify_async) {
4338
0
        tevent_req_defer_callback(req, state->ev);
4339
0
        tevent_req_notify_callback(req);
4340
0
      }
4341
0
      continue;
4342
0
    }
4343
4344
0
    session = state->session;
4345
0
    if (req_flags & SMB2_HDR_FLAG_CHAINED) {
4346
0
      session = last_session;
4347
0
    }
4348
0
    last_session = session;
4349
4350
0
    if (flags & SMB2_HDR_FLAG_SIGNED) {
4351
0
      uint64_t uid = BVAL(inhdr, SMB2_HDR_SESSION_ID);
4352
4353
0
      if (session == NULL) {
4354
0
        session = smbXcli_session_by_uid(state->conn,
4355
0
                 uid);
4356
0
      }
4357
4358
0
      if (session == NULL) {
4359
0
        return NT_STATUS_INVALID_NETWORK_RESPONSE;
4360
0
      }
4361
4362
0
      last_session = session;
4363
0
      signing_key = session->smb2_channel.signing_key;
4364
0
    }
4365
4366
0
    if (opcode == SMB2_OP_SESSSETUP) {
4367
      /*
4368
       * We prefer the channel signing key, if it is
4369
       * already there.
4370
       *
4371
       * If we do not have a channel signing key yet,
4372
       * we try the main signing key, if it is not
4373
       * the final response.
4374
       */
4375
0
      if (signing_key != NULL &&
4376
0
          !smb2_signing_key_valid(signing_key) &&
4377
0
          !NT_STATUS_IS_OK(status)) {
4378
0
        signing_key = session->smb2->signing_key;
4379
0
      }
4380
4381
0
      if (signing_key != NULL &&
4382
0
          !smb2_signing_key_valid(signing_key)) {
4383
        /*
4384
         * If we do not have a session key to
4385
         * verify the signature, we defer the
4386
         * signing check to the caller.
4387
         *
4388
         * The caller gets NT_STATUS_OK, it
4389
         * has to call
4390
         * smb2cli_session_set_session_key()
4391
         * or
4392
         * smb2cli_session_set_channel_key()
4393
         * which will check the signature
4394
         * with the channel signing key.
4395
         */
4396
0
        signing_key = NULL;
4397
0
      }
4398
4399
0
      if (!NT_STATUS_IS_OK(status)) {
4400
        /*
4401
         * Only check the signature of the last response
4402
         * of a successful session auth. This matches
4403
         * Windows behaviour for NTLM auth and reauth.
4404
         */
4405
0
        state->smb2.require_signed_response = false;
4406
0
      }
4407
0
    }
4408
4409
0
    if (state->smb2.should_sign ||
4410
0
        state->smb2.require_signed_response)
4411
0
    {
4412
0
      if (!(flags & SMB2_HDR_FLAG_SIGNED)) {
4413
0
        return NT_STATUS_ACCESS_DENIED;
4414
0
      }
4415
0
    }
4416
4417
0
    if (!smb2_signing_key_valid(signing_key) &&
4418
0
        state->smb2.require_signed_response) {
4419
0
      signing_key = session->smb2_channel.signing_key;
4420
0
    }
4421
4422
0
    if (cur[0].iov_len == SMB2_TF_HDR_SIZE) {
4423
0
      const uint8_t *tf = (const uint8_t *)cur[0].iov_base;
4424
0
      uint64_t uid = BVAL(tf, SMB2_TF_SESSION_ID);
4425
4426
      /*
4427
       * If the response was encrypted in a SMB2_TRANSFORM
4428
       * pdu, which belongs to the correct session,
4429
       * we do not need to do signing checks
4430
       *
4431
       * It could be the session the response belongs to
4432
       * or the session that was used to encrypt the
4433
       * SMB2_TRANSFORM request.
4434
       */
4435
0
      if ((session && session->smb2->session_id == uid) ||
4436
0
          (state->smb2.encryption_session_id == uid)) {
4437
0
        signing_key = NULL;
4438
0
        was_encrypted = true;
4439
0
      }
4440
0
    }
4441
4442
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
4443
      /*
4444
       * if the server returns NT_STATUS_USER_SESSION_DELETED
4445
       * the response is not signed and we should
4446
       * propagate the NT_STATUS_USER_SESSION_DELETED
4447
       * status to the caller.
4448
       */
4449
0
      state->smb2.signing_skipped = true;
4450
0
      signing_key = NULL;
4451
0
    }
4452
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_OUT_OF_SEQUENCE)) {
4453
      /*
4454
       * if the server returns
4455
       * NT_STATUS_REQUEST_OUT_OF_SEQUENCE for a session setup
4456
       * request, the response is not signed and we should
4457
       * propagate the NT_STATUS_REQUEST_OUT_OF_SEQUENCE
4458
       * status to the caller
4459
       */
4460
0
      if (opcode == SMB2_OP_SESSSETUP) {
4461
0
        state->smb2.signing_skipped = true;
4462
0
        signing_key = NULL;
4463
0
      }
4464
0
    }
4465
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
4466
      /*
4467
       * if the server returns NT_STATUS_NOT_SUPPORTED
4468
       * for a session setup request, the response is not
4469
       * signed and we should propagate the NT_STATUS_NOT_SUPPORTED
4470
       * status to the caller.
4471
       */
4472
0
      if (opcode == SMB2_OP_SESSSETUP) {
4473
0
        state->smb2.signing_skipped = true;
4474
0
        signing_key = NULL;
4475
0
      }
4476
0
    }
4477
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4478
      /*
4479
       * if the server returns
4480
       * NT_STATUS_ACCESS_DENIED for a session setup
4481
       * request, the response is not signed and we should
4482
       * propagate the NT_STATUS_ACCESS_DENIED
4483
       * status to the caller without disconnecting
4484
       * the connection because we where not able to
4485
       * verify the response signature.
4486
       */
4487
0
      if (opcode == SMB2_OP_SESSSETUP) {
4488
0
        state->smb2.signing_skipped = true;
4489
0
        signing_key = NULL;
4490
0
      }
4491
0
    }
4492
4493
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4494
      /*
4495
       * if the server returns
4496
       * NT_STATUS_INVALID_PARAMETER
4497
       * the response might not be encrypted.
4498
       */
4499
0
      if (state->smb2.should_encrypt && !was_encrypted) {
4500
0
        state->smb2.signing_skipped = true;
4501
0
        signing_key = NULL;
4502
0
      }
4503
0
    }
4504
4505
0
    if (state->smb2.should_encrypt && !was_encrypted) {
4506
0
      if (!state->smb2.signing_skipped) {
4507
0
        return NT_STATUS_ACCESS_DENIED;
4508
0
      }
4509
0
    }
4510
4511
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED) ||
4512
0
        NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED) ||
4513
0
        (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
4514
0
         session != NULL &&
4515
0
         session->smb2->no_signing_disconnect) ||
4516
0
        NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
4517
      /*
4518
       * if the server returns
4519
       * NT_STATUS_NETWORK_NAME_DELETED
4520
       * NT_STATUS_FILE_CLOSED
4521
       * NT_STATUS_INVALID_PARAMETER
4522
       * the response might not be signed
4523
       * as this happens before the signing checks.
4524
       *
4525
       * If server echos the signature (or all zeros)
4526
       * we should report the status from the server
4527
       * to the caller.
4528
       */
4529
0
      if (signing_key) {
4530
0
        bool cmp;
4531
4532
0
        cmp = mem_equal_const_time(inhdr+SMB2_HDR_SIGNATURE,
4533
0
                 state->smb2.hdr+SMB2_HDR_SIGNATURE,
4534
0
                 16);
4535
0
        if (cmp) {
4536
0
          state->smb2.signing_skipped = true;
4537
0
          signing_key = NULL;
4538
0
        }
4539
0
      }
4540
0
      if (signing_key) {
4541
0
        bool zero;
4542
0
        zero = all_zero(inhdr+SMB2_HDR_SIGNATURE, 16);
4543
0
        if (zero) {
4544
0
          state->smb2.signing_skipped = true;
4545
0
          signing_key = NULL;
4546
0
        }
4547
0
      }
4548
0
    }
4549
4550
0
    if (signing_key) {
4551
0
      NTSTATUS signing_status;
4552
4553
0
      signing_status = smb2_signing_check_pdu(signing_key,
4554
0
                &cur[1], 3);
4555
0
      if (!NT_STATUS_IS_OK(signing_status)) {
4556
        /*
4557
         * If the signing check fails, we disconnect
4558
         * the connection.
4559
         *
4560
         * Unless
4561
         * smb2cli_session_torture_no_signing_disconnect
4562
         * was called in torture tests
4563
         */
4564
4565
0
        if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4566
0
          return signing_status;
4567
0
        }
4568
4569
0
        if (!NT_STATUS_EQUAL(status, signing_status)) {
4570
0
          return signing_status;
4571
0
        }
4572
4573
0
        if (session == NULL) {
4574
0
          return signing_status;
4575
0
        }
4576
4577
0
        if (!session->smb2->no_signing_disconnect) {
4578
0
          return signing_status;
4579
0
        }
4580
4581
0
        state->smb2.signing_skipped = true;
4582
0
      }
4583
0
    }
4584
4585
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) &&
4586
0
        (session != NULL) && session->disconnect_expired)
4587
0
    {
4588
      /*
4589
       * this should be a short term hack
4590
       * until the upper layers have implemented
4591
       * re-authentication.
4592
       */
4593
0
      return status;
4594
0
    }
4595
4596
0
    smbXcli_req_unset_pending(req);
4597
4598
    /*
4599
     * There might be more than one response
4600
     * we need to defer the notifications
4601
     */
4602
0
    if ((num_iov == 5) && (talloc_array_length(conn->pending) == 0)) {
4603
0
      defer = false;
4604
0
    }
4605
4606
0
    if (defer) {
4607
0
      tevent_req_defer_callback(req, state->ev);
4608
0
    }
4609
4610
    /*
4611
     * Note: here we use talloc_reference() in a way
4612
     *       that does not expose it to the caller.
4613
     */
4614
0
    inbuf_ref = talloc_reference(state->smb2.recv_iov, inbuf);
4615
0
    if (tevent_req_nomem(inbuf_ref, req)) {
4616
0
      continue;
4617
0
    }
4618
4619
    /* copy the related buffers */
4620
0
    state->smb2.recv_iov[0] = cur[1];
4621
0
    state->smb2.recv_iov[1] = cur[2];
4622
0
    state->smb2.recv_iov[2] = cur[3];
4623
4624
0
    tevent_req_done(req);
4625
0
  }
4626
4627
0
  if (defer) {
4628
0
    return NT_STATUS_RETRY;
4629
0
  }
4630
4631
0
  return NT_STATUS_OK;
4632
0
}
4633
4634
NTSTATUS smb2cli_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
4635
        struct iovec **piov,
4636
        const struct smb2cli_req_expected_response *expected,
4637
        size_t num_expected)
4638
0
{
4639
0
  struct smbXcli_req_state *state =
4640
0
    tevent_req_data(req,
4641
0
    struct smbXcli_req_state);
4642
0
  NTSTATUS status;
4643
0
  size_t body_size;
4644
0
  bool found_status = false;
4645
0
  bool found_size = false;
4646
0
  size_t i;
4647
4648
0
  if (piov != NULL) {
4649
0
    *piov = NULL;
4650
0
  }
4651
4652
0
  if (tevent_req_is_in_progress(req) && state->smb2.got_async) {
4653
0
    return NT_STATUS_PENDING;
4654
0
  }
4655
4656
0
  if (tevent_req_is_nterror(req, &status)) {
4657
0
    for (i=0; i < num_expected; i++) {
4658
0
      if (NT_STATUS_EQUAL(status, expected[i].status)) {
4659
0
        return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
4660
0
      }
4661
0
    }
4662
4663
0
    return status;
4664
0
  }
4665
4666
0
  if (num_expected == 0) {
4667
0
    found_status = true;
4668
0
    found_size = true;
4669
0
  }
4670
4671
0
  status = NT_STATUS(IVAL(state->smb2.recv_iov[0].iov_base, SMB2_HDR_STATUS));
4672
0
  body_size = SVAL(state->smb2.recv_iov[1].iov_base, 0);
4673
4674
0
  for (i=0; i < num_expected; i++) {
4675
0
    if (!NT_STATUS_EQUAL(status, expected[i].status)) {
4676
0
      continue;
4677
0
    }
4678
4679
0
    found_status = true;
4680
0
    if (expected[i].body_size == 0) {
4681
0
      found_size = true;
4682
0
      break;
4683
0
    }
4684
4685
0
    if (expected[i].body_size == body_size) {
4686
0
      found_size = true;
4687
0
      break;
4688
0
    }
4689
0
  }
4690
4691
0
  if (!found_status) {
4692
0
    return status;
4693
0
  }
4694
4695
0
  if (state->smb2.signing_skipped) {
4696
0
    if (num_expected > 0) {
4697
0
      return NT_STATUS_ACCESS_DENIED;
4698
0
    }
4699
0
    if (!NT_STATUS_IS_ERR(status)) {
4700
0
      return NT_STATUS_ACCESS_DENIED;
4701
0
    }
4702
0
  }
4703
4704
0
  if (!found_size) {
4705
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
4706
0
  }
4707
4708
0
  if (piov != NULL) {
4709
0
    *piov = talloc_move(mem_ctx, &state->smb2.recv_iov);
4710
0
  }
4711
4712
0
  return status;
4713
0
}
4714
4715
NTSTATUS smb2cli_req_get_sent_iov(struct tevent_req *req,
4716
          struct iovec *sent_iov)
4717
0
{
4718
0
  struct smbXcli_req_state *state =
4719
0
    tevent_req_data(req,
4720
0
    struct smbXcli_req_state);
4721
4722
0
  if (tevent_req_is_in_progress(req)) {
4723
0
    return NT_STATUS_PENDING;
4724
0
  }
4725
4726
0
  sent_iov[0].iov_base = state->smb2.hdr;
4727
0
  sent_iov[0].iov_len  = sizeof(state->smb2.hdr);
4728
4729
0
  sent_iov[1].iov_base = discard_const(state->smb2.fixed);
4730
0
  sent_iov[1].iov_len  = state->smb2.fixed_len;
4731
4732
0
  if (state->smb2.dyn != NULL) {
4733
0
    sent_iov[2].iov_base = discard_const(state->smb2.dyn);
4734
0
    sent_iov[2].iov_len  = state->smb2.dyn_len;
4735
0
  } else {
4736
0
    sent_iov[2].iov_base = NULL;
4737
0
    sent_iov[2].iov_len  = 0;
4738
0
  }
4739
4740
0
  return NT_STATUS_OK;
4741
0
}
4742
4743
static const struct {
4744
  enum protocol_types proto;
4745
  const char smb1_name[24]; /* strlen("MICROSOFT NETWORKS 1.03") == 23 */
4746
} smb1cli_prots[] = {
4747
  {PROTOCOL_CORE,   "PC NETWORK PROGRAM 1.0"},
4748
  {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
4749
  {PROTOCOL_LANMAN1,  "MICROSOFT NETWORKS 3.0"},
4750
  {PROTOCOL_LANMAN1,  "LANMAN1.0"},
4751
  {PROTOCOL_LANMAN2,  "LM1.2X002"},
4752
  {PROTOCOL_LANMAN2,  "DOS LANMAN2.1"},
4753
  {PROTOCOL_LANMAN2,  "LANMAN2.1"},
4754
  {PROTOCOL_LANMAN2,  "Samba"},
4755
  {PROTOCOL_NT1,    "NT LANMAN 1.0"},
4756
  {PROTOCOL_NT1,    "NT LM 0.12"},
4757
  {PROTOCOL_SMB2_02,  "SMB 2.002"},
4758
  {PROTOCOL_SMB2_10,  "SMB 2.???"},
4759
};
4760
4761
static const struct {
4762
  enum protocol_types proto;
4763
  uint16_t smb2_dialect;
4764
} smb2cli_prots[] = {
4765
  {PROTOCOL_SMB2_02,  SMB2_DIALECT_REVISION_202},
4766
  {PROTOCOL_SMB2_10,  SMB2_DIALECT_REVISION_210},
4767
  {PROTOCOL_SMB3_00,  SMB3_DIALECT_REVISION_300},
4768
  {PROTOCOL_SMB3_02,  SMB3_DIALECT_REVISION_302},
4769
  {PROTOCOL_SMB3_11,  SMB3_DIALECT_REVISION_311},
4770
};
4771
4772
struct smbXcli_negprot_state {
4773
  struct smbXcli_conn *conn;
4774
  struct tevent_context *ev;
4775
  struct smb2_negotiate_contexts *in_ctx;
4776
  struct smb2_negotiate_contexts *out_ctx;
4777
  uint32_t timeout_msec;
4778
4779
  struct {
4780
    uint8_t fixed[36];
4781
  } smb2;
4782
};
4783
4784
static void smbXcli_negprot_invalid_done(struct tevent_req *subreq);
4785
static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state);
4786
static void smbXcli_negprot_smb1_done(struct tevent_req *subreq);
4787
static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state);
4788
static void smbXcli_negprot_smb2_done(struct tevent_req *subreq);
4789
static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
4790
              TALLOC_CTX *frame,
4791
              uint8_t *inbuf);
4792
4793
struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx,
4794
          struct tevent_context *ev,
4795
          struct smbXcli_conn *conn,
4796
          uint32_t timeout_msec,
4797
          enum protocol_types min_protocol,
4798
          enum protocol_types max_protocol,
4799
          uint16_t max_credits,
4800
          struct smb2_negotiate_contexts *in_ctx)
4801
0
{
4802
0
  struct tevent_req *req, *subreq;
4803
0
  struct smbXcli_negprot_state *state;
4804
4805
0
  req = tevent_req_create(mem_ctx, &state,
4806
0
        struct smbXcli_negprot_state);
4807
0
  if (req == NULL) {
4808
0
    return NULL;
4809
0
  }
4810
0
  state->conn = conn;
4811
0
  state->ev = ev;
4812
0
  state->in_ctx = in_ctx;
4813
0
  state->timeout_msec = timeout_msec;
4814
4815
0
  if (min_protocol == PROTOCOL_NONE) {
4816
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4817
0
    return tevent_req_post(req, ev);
4818
0
  }
4819
4820
0
  if (max_protocol == PROTOCOL_NONE) {
4821
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4822
0
    return tevent_req_post(req, ev);
4823
0
  }
4824
4825
0
  if (min_protocol > max_protocol) {
4826
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4827
0
    return tevent_req_post(req, ev);
4828
0
  }
4829
4830
0
  conn->min_protocol = min_protocol;
4831
0
  conn->max_protocol = max_protocol;
4832
0
  conn->protocol = PROTOCOL_NONE;
4833
4834
0
  if (max_protocol >= PROTOCOL_SMB2_02) {
4835
0
    conn->smb2.max_credits = max_credits;
4836
0
  }
4837
4838
0
  if ((min_protocol < PROTOCOL_SMB2_02) &&
4839
0
      (max_protocol < PROTOCOL_SMB2_02)) {
4840
    /*
4841
     * SMB1 only...
4842
     */
4843
0
    conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
4844
4845
0
    subreq = smbXcli_negprot_smb1_subreq(state);
4846
0
    if (tevent_req_nomem(subreq, req)) {
4847
0
      return tevent_req_post(req, ev);
4848
0
    }
4849
0
    tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
4850
0
    return req;
4851
0
  }
4852
4853
0
  if ((min_protocol >= PROTOCOL_SMB2_02) &&
4854
0
      (max_protocol >= PROTOCOL_SMB2_02)) {
4855
    /*
4856
     * SMB2 only...
4857
     */
4858
0
    conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
4859
4860
0
    subreq = smbXcli_negprot_smb2_subreq(state);
4861
0
    if (tevent_req_nomem(subreq, req)) {
4862
0
      return tevent_req_post(req, ev);
4863
0
    }
4864
0
    tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
4865
0
    return req;
4866
0
  }
4867
4868
  /*
4869
   * We send an SMB1 negprot with the SMB2 dialects
4870
   * and expect a SMB1 or a SMB2 response.
4871
   *
4872
   * smbXcli_negprot_dispatch_incoming() will fix the
4873
   * callback to match protocol of the response.
4874
   */
4875
0
  conn->dispatch_incoming = smbXcli_negprot_dispatch_incoming;
4876
4877
0
  subreq = smbXcli_negprot_smb1_subreq(state);
4878
0
  if (tevent_req_nomem(subreq, req)) {
4879
0
    return tevent_req_post(req, ev);
4880
0
  }
4881
0
  tevent_req_set_callback(subreq, smbXcli_negprot_invalid_done, req);
4882
0
  return req;
4883
0
}
4884
4885
static void smbXcli_negprot_invalid_done(struct tevent_req *subreq)
4886
0
{
4887
0
  struct tevent_req *req =
4888
0
    tevent_req_callback_data(subreq,
4889
0
    struct tevent_req);
4890
0
  NTSTATUS status;
4891
4892
  /*
4893
   * we just want the low level error
4894
   */
4895
0
  status = tevent_req_simple_recv_ntstatus(subreq);
4896
0
  TALLOC_FREE(subreq);
4897
0
  if (tevent_req_nterror(req, status)) {
4898
0
    return;
4899
0
  }
4900
4901
  /* this should never happen */
4902
0
  tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
4903
0
}
4904
4905
static struct tevent_req *smbXcli_negprot_smb1_subreq(struct smbXcli_negprot_state *state)
4906
0
{
4907
0
  size_t i;
4908
0
  DATA_BLOB bytes = data_blob_null;
4909
0
  uint8_t flags;
4910
0
  uint16_t flags2;
4911
4912
  /* setup the protocol strings */
4913
0
  for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
4914
0
    uint8_t c = 2;
4915
0
    bool ok;
4916
4917
0
    if (smb1cli_prots[i].proto < state->conn->min_protocol) {
4918
0
      continue;
4919
0
    }
4920
4921
0
    if (smb1cli_prots[i].proto > state->conn->max_protocol) {
4922
0
      continue;
4923
0
    }
4924
4925
0
    ok = data_blob_append(state, &bytes, &c, sizeof(c));
4926
0
    if (!ok) {
4927
0
      return NULL;
4928
0
    }
4929
4930
    /*
4931
     * We know it is already ascii and
4932
     * we want NULL termination.
4933
     */
4934
0
    ok = data_blob_append(state, &bytes,
4935
0
              smb1cli_prots[i].smb1_name,
4936
0
              strlen(smb1cli_prots[i].smb1_name)+1);
4937
0
    if (!ok) {
4938
0
      return NULL;
4939
0
    }
4940
0
  }
4941
4942
0
  smb1cli_req_flags(state->conn->max_protocol,
4943
0
        state->conn->smb1.client.capabilities,
4944
0
        SMBnegprot,
4945
0
        0, 0, &flags,
4946
0
        0, 0, &flags2);
4947
4948
0
  return smb1cli_req_send(state, state->ev, state->conn,
4949
0
        SMBnegprot,
4950
0
        flags, ~flags,
4951
0
        flags2, ~flags2,
4952
0
        state->timeout_msec,
4953
0
        0xFFFE, 0, NULL, /* pid, tid, session */
4954
0
        0, NULL, /* wct, vwv */
4955
0
        bytes.length, bytes.data);
4956
0
}
4957
4958
static void smbXcli_negprot_smb1_done(struct tevent_req *subreq)
4959
0
{
4960
0
  struct tevent_req *req =
4961
0
    tevent_req_callback_data(subreq,
4962
0
    struct tevent_req);
4963
0
  struct smbXcli_negprot_state *state =
4964
0
    tevent_req_data(req,
4965
0
    struct smbXcli_negprot_state);
4966
0
  struct smbXcli_conn *conn = state->conn;
4967
0
  struct iovec *recv_iov = NULL;
4968
0
  uint8_t *inhdr = NULL;
4969
0
  uint8_t wct;
4970
0
  uint16_t *vwv;
4971
0
  uint32_t num_bytes;
4972
0
  uint8_t *bytes;
4973
0
  NTSTATUS status;
4974
0
  uint16_t protnum;
4975
0
  size_t i;
4976
0
  size_t num_prots = 0;
4977
0
  uint8_t flags;
4978
0
  uint32_t client_capabilities = conn->smb1.client.capabilities;
4979
0
  uint32_t both_capabilities;
4980
0
  uint32_t server_capabilities = 0;
4981
0
  uint32_t capabilities;
4982
0
  uint32_t client_max_xmit = conn->smb1.client.max_xmit;
4983
0
  uint32_t server_max_xmit = 0;
4984
0
  uint32_t max_xmit;
4985
0
  uint32_t server_max_mux = 0;
4986
0
  uint16_t server_security_mode = 0;
4987
0
  uint32_t server_session_key = 0;
4988
0
  bool server_readbraw = false;
4989
0
  bool server_writebraw = false;
4990
0
  bool server_lockread = false;
4991
0
  bool server_writeunlock = false;
4992
0
  struct GUID server_guid = GUID_zero();
4993
0
  DATA_BLOB server_gss_blob = data_blob_null;
4994
0
  uint8_t server_challenge[8] = {};
4995
0
  char *server_workgroup = NULL;
4996
0
  char *server_name = NULL;
4997
0
  int server_time_zone = 0;
4998
0
  NTTIME server_system_time = 0;
4999
0
  static const struct smb1cli_req_expected_response expected[] = {
5000
0
  {
5001
0
    .status = NT_STATUS_OK,
5002
0
    .wct = 0x11, /* NT1 */
5003
0
  },
5004
0
  {
5005
0
    .status = NT_STATUS_OK,
5006
0
    .wct = 0x0D, /* LM */
5007
0
  },
5008
0
  {
5009
0
    .status = NT_STATUS_OK,
5010
0
    .wct = 0x01, /* CORE */
5011
0
  }
5012
0
  };
5013
5014
0
  status = smb1cli_req_recv(subreq, state,
5015
0
          &recv_iov,
5016
0
          &inhdr,
5017
0
          &wct,
5018
0
          &vwv,
5019
0
          NULL, /* pvwv_offset */
5020
0
          &num_bytes,
5021
0
          &bytes,
5022
0
          NULL, /* pbytes_offset */
5023
0
          NULL, /* pinbuf */
5024
0
          expected, ARRAY_SIZE(expected));
5025
0
  TALLOC_FREE(subreq);
5026
0
  if (tevent_req_nterror(req, status)) {
5027
0
    return;
5028
0
  }
5029
0
  if (inhdr == NULL) {
5030
0
    tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5031
0
    return;
5032
0
  }
5033
5034
0
  flags = CVAL(inhdr, HDR_FLG);
5035
5036
0
  protnum = SVAL(vwv, 0);
5037
5038
0
  for (i=0; i < ARRAY_SIZE(smb1cli_prots); i++) {
5039
0
    if (smb1cli_prots[i].proto < state->conn->min_protocol) {
5040
0
      continue;
5041
0
    }
5042
5043
0
    if (smb1cli_prots[i].proto > state->conn->max_protocol) {
5044
0
      continue;
5045
0
    }
5046
5047
0
    if (protnum != num_prots) {
5048
0
      num_prots++;
5049
0
      continue;
5050
0
    }
5051
5052
0
    conn->protocol = smb1cli_prots[i].proto;
5053
0
    break;
5054
0
  }
5055
5056
0
  if (conn->protocol == PROTOCOL_NONE) {
5057
0
    DBG_ERR("No compatible protocol selected by server.\n");
5058
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5059
0
    return;
5060
0
  }
5061
5062
0
  if ((conn->protocol < PROTOCOL_NT1) && conn->mandatory_signing) {
5063
0
    DEBUG(0,("smbXcli_negprot: SMB signing is mandatory "
5064
0
       "and the selected protocol level doesn't support it.\n"));
5065
0
    tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5066
0
    return;
5067
0
  }
5068
5069
0
  if (flags & FLAG_SUPPORT_LOCKREAD) {
5070
0
    server_lockread = true;
5071
0
    server_writeunlock = true;
5072
0
  }
5073
5074
0
  if (conn->protocol >= PROTOCOL_NT1) {
5075
0
    const char *client_signing = NULL;
5076
0
    bool server_mandatory = false;
5077
0
    bool server_allowed = false;
5078
0
    const char *server_signing = NULL;
5079
0
    bool ok;
5080
0
    uint8_t key_len;
5081
5082
0
    if (wct != 0x11) {
5083
0
      tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5084
0
      return;
5085
0
    }
5086
5087
    /* NT protocol */
5088
0
    server_security_mode = CVAL(vwv + 1, 0);
5089
0
    server_max_mux = SVAL(vwv + 1, 1);
5090
0
    server_max_xmit = IVAL(vwv + 3, 1);
5091
0
    server_session_key = IVAL(vwv + 7, 1);
5092
0
    server_time_zone = SVALS(vwv + 15, 1);
5093
0
    server_time_zone *= 60;
5094
    /* this time arrives in real GMT */
5095
0
    server_system_time = BVAL(vwv + 11, 1);
5096
0
    server_capabilities = IVAL(vwv + 9, 1);
5097
5098
0
    key_len = CVAL(vwv + 16, 1);
5099
5100
0
    if (server_capabilities & CAP_RAW_MODE) {
5101
0
      server_readbraw = true;
5102
0
      server_writebraw = true;
5103
0
    }
5104
0
    if (server_capabilities & CAP_LOCK_AND_READ) {
5105
0
      server_lockread = true;
5106
0
    }
5107
5108
0
    if (server_capabilities & CAP_EXTENDED_SECURITY) {
5109
0
      DATA_BLOB blob1, blob2;
5110
5111
0
      if (num_bytes < 16) {
5112
0
        tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5113
0
        return;
5114
0
      }
5115
5116
0
      blob1 = data_blob_const(bytes, 16);
5117
0
      status = GUID_from_data_blob(&blob1, &server_guid);
5118
0
      if (tevent_req_nterror(req, status)) {
5119
0
        return;
5120
0
      }
5121
5122
0
      blob1 = data_blob_const(bytes+16, num_bytes-16);
5123
0
      blob2 = data_blob_dup_talloc_s(state, blob1);
5124
0
      if (blob1.length > 0 &&
5125
0
          tevent_req_nomem(blob2.data, req)) {
5126
0
        return;
5127
0
      }
5128
0
      server_gss_blob = blob2;
5129
0
    } else {
5130
0
      DATA_BLOB blob1, blob2;
5131
5132
0
      if (num_bytes < key_len) {
5133
0
        tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5134
0
        return;
5135
0
      }
5136
5137
0
      if (key_len != 0 && key_len != 8) {
5138
0
        tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5139
0
        return;
5140
0
      }
5141
5142
0
      if (key_len == 8) {
5143
0
        memcpy(server_challenge, bytes, 8);
5144
0
      }
5145
5146
0
      blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
5147
0
      blob2 = data_blob_const(bytes+key_len, num_bytes-key_len);
5148
0
      if (blob1.length > 0) {
5149
0
        size_t len;
5150
5151
0
        len = utf16_null_terminated_len_n(blob1.data,
5152
0
                  blob1.length);
5153
0
        blob1.length = len;
5154
5155
0
        ok = convert_string_talloc(state,
5156
0
                 CH_UTF16LE,
5157
0
                 CH_UNIX,
5158
0
                 blob1.data,
5159
0
                 blob1.length,
5160
0
                 &server_workgroup,
5161
0
                 &len);
5162
0
        if (!ok) {
5163
0
          status = map_nt_error_from_unix_common(errno);
5164
0
          tevent_req_nterror(req, status);
5165
0
          return;
5166
0
        }
5167
0
      }
5168
5169
0
      blob2.data += blob1.length;
5170
0
      blob2.length -= blob1.length;
5171
0
      if (blob2.length > 0) {
5172
0
        size_t len;
5173
5174
0
        ok = convert_string_talloc(state,
5175
0
                 CH_UTF16LE,
5176
0
                 CH_UNIX,
5177
0
                 blob2.data,
5178
0
                 blob2.length,
5179
0
                 &server_name,
5180
0
                 &len);
5181
0
        if (!ok) {
5182
0
          status = map_nt_error_from_unix_common(errno);
5183
0
          tevent_req_nterror(req, status);
5184
0
          return;
5185
0
        }
5186
0
      }
5187
0
    }
5188
5189
0
    client_signing = "disabled";
5190
0
    if (conn->allow_signing) {
5191
0
      client_signing = "allowed";
5192
0
    }
5193
0
    if (conn->mandatory_signing) {
5194
0
      client_signing = "required";
5195
0
    }
5196
5197
0
    server_signing = "not supported";
5198
0
    if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
5199
0
      server_signing = "supported";
5200
0
      server_allowed = true;
5201
0
    } else if (conn->mandatory_signing) {
5202
      /*
5203
       * We have mandatory signing as client
5204
       * lets assume the server will look at our
5205
       * FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED
5206
       * flag in the session setup
5207
       */
5208
0
      server_signing = "not announced";
5209
0
      server_allowed = true;
5210
0
    }
5211
0
    if (server_security_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
5212
0
      server_signing = "required";
5213
0
      server_mandatory = true;
5214
0
    }
5215
5216
0
    ok = smb1_signing_set_negotiated(conn->smb1.signing,
5217
0
            server_allowed,
5218
0
            server_mandatory);
5219
0
    if (!ok) {
5220
0
      DEBUG(1,("cli_negprot: SMB signing is required, "
5221
0
         "but client[%s] and server[%s] mismatch\n",
5222
0
         client_signing, server_signing));
5223
0
      tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
5224
0
      return;
5225
0
    }
5226
5227
0
  } else if (conn->protocol >= PROTOCOL_LANMAN1) {
5228
0
    DATA_BLOB blob1;
5229
0
    uint8_t key_len;
5230
0
    time_t t;
5231
5232
0
    if (wct != 0x0D) {
5233
0
      tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5234
0
      return;
5235
0
    }
5236
5237
0
    server_security_mode = SVAL(vwv + 1, 0);
5238
0
    server_max_xmit = SVAL(vwv + 2, 0);
5239
0
    server_max_mux = SVAL(vwv + 3, 0);
5240
0
    server_readbraw = ((SVAL(vwv + 5, 0) & 0x1) != 0);
5241
0
    server_writebraw = ((SVAL(vwv + 5, 0) & 0x2) != 0);
5242
0
    server_session_key = IVAL(vwv + 6, 0);
5243
0
    server_time_zone = SVALS(vwv + 10, 0);
5244
0
    server_time_zone *= 60;
5245
    /* this time is converted to GMT by make_unix_date */
5246
0
    t = pull_dos_date((const uint8_t *)(vwv + 8), server_time_zone);
5247
0
    unix_to_nt_time(&server_system_time, t);
5248
0
    key_len = SVAL(vwv + 11, 0);
5249
5250
0
    if (num_bytes < key_len) {
5251
0
      tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5252
0
      return;
5253
0
    }
5254
5255
0
    if (key_len != 0 && key_len != 8) {
5256
0
      tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5257
0
      return;
5258
0
    }
5259
5260
0
    if (key_len == 8) {
5261
0
      memcpy(server_challenge, bytes, 8);
5262
0
    }
5263
5264
0
    blob1 = data_blob_const(bytes+key_len, num_bytes-key_len);
5265
0
    if (blob1.length > 0) {
5266
0
      size_t len;
5267
0
      bool ok;
5268
5269
0
      len = utf16_null_terminated_len_n(blob1.data,
5270
0
                blob1.length);
5271
0
      blob1.length = len;
5272
5273
0
      ok = convert_string_talloc(state,
5274
0
               CH_DOS,
5275
0
               CH_UNIX,
5276
0
               blob1.data,
5277
0
               blob1.length,
5278
0
               &server_workgroup,
5279
0
               &len);
5280
0
      if (!ok) {
5281
0
        status = map_nt_error_from_unix_common(errno);
5282
0
        tevent_req_nterror(req, status);
5283
0
        return;
5284
0
      }
5285
0
    }
5286
5287
0
  } else {
5288
    /* the old core protocol */
5289
0
    server_time_zone = get_time_zone(time(NULL));
5290
0
    server_max_xmit = 1024;
5291
0
    server_max_mux = 1;
5292
0
  }
5293
5294
0
  if (server_max_xmit < 1024) {
5295
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5296
0
    return;
5297
0
  }
5298
5299
0
  if (server_max_mux < 1) {
5300
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5301
0
    return;
5302
0
  }
5303
5304
  /*
5305
   * Now calculate the negotiated capabilities
5306
   * based on the mask for:
5307
   * - client only flags
5308
   * - flags used in both directions
5309
   * - server only flags
5310
   */
5311
0
  both_capabilities = client_capabilities & server_capabilities;
5312
0
  capabilities = client_capabilities & SMB_CAP_CLIENT_MASK;
5313
0
  capabilities |= both_capabilities & SMB_CAP_BOTH_MASK;
5314
0
  capabilities |= server_capabilities & SMB_CAP_SERVER_MASK;
5315
5316
0
  max_xmit = MIN(client_max_xmit, server_max_xmit);
5317
5318
0
  conn->smb1.server.capabilities = server_capabilities;
5319
0
  conn->smb1.capabilities = capabilities;
5320
5321
0
  conn->smb1.server.max_xmit = server_max_xmit;
5322
0
  conn->smb1.max_xmit = max_xmit;
5323
5324
0
  conn->smb1.server.max_mux = server_max_mux;
5325
5326
0
  conn->smb1.server.security_mode = server_security_mode;
5327
5328
0
  conn->smb1.server.readbraw = server_readbraw;
5329
0
  conn->smb1.server.writebraw = server_writebraw;
5330
0
  conn->smb1.server.lockread = server_lockread;
5331
0
  conn->smb1.server.writeunlock = server_writeunlock;
5332
5333
0
  conn->smb1.server.session_key = server_session_key;
5334
5335
0
  talloc_steal(conn, server_gss_blob.data);
5336
0
  conn->smb1.server.gss_blob = server_gss_blob;
5337
0
  conn->smb1.server.guid = server_guid;
5338
0
  memcpy(conn->smb1.server.challenge, server_challenge, 8);
5339
0
  conn->smb1.server.workgroup = talloc_move(conn, &server_workgroup);
5340
0
  conn->smb1.server.name = talloc_move(conn, &server_name);
5341
5342
0
  conn->smb1.server.time_zone = server_time_zone;
5343
0
  conn->smb1.server.system_time = server_system_time;
5344
5345
0
  tevent_req_done(req);
5346
0
}
5347
5348
static size_t smbXcli_padding_helper(uint32_t offset, size_t n)
5349
0
{
5350
0
  if ((offset & (n-1)) == 0) return 0;
5351
0
  return n - (offset & (n-1));
5352
0
}
5353
5354
static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_state *state)
5355
0
{
5356
0
  struct smbXcli_conn *conn = state->conn;
5357
0
  size_t i;
5358
0
  uint8_t *buf;
5359
0
  uint16_t dialect_count = 0;
5360
0
  DATA_BLOB dyn = data_blob_null;
5361
5362
0
  for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5363
0
    bool ok;
5364
0
    uint8_t val[2];
5365
5366
0
    if (smb2cli_prots[i].proto < conn->min_protocol) {
5367
0
      continue;
5368
0
    }
5369
5370
0
    if (smb2cli_prots[i].proto > conn->max_protocol) {
5371
0
      continue;
5372
0
    }
5373
5374
0
    SSVAL(val, 0, smb2cli_prots[i].smb2_dialect);
5375
5376
0
    ok = data_blob_append(state, &dyn, val, sizeof(val));
5377
0
    if (!ok) {
5378
0
      return NULL;
5379
0
    }
5380
5381
0
    dialect_count++;
5382
0
  }
5383
5384
0
  buf = state->smb2.fixed;
5385
0
  SSVAL(buf, 0, 36);
5386
0
  SSVAL(buf, 2, dialect_count);
5387
0
  SSVAL(buf, 4, conn->smb2.client.security_mode);
5388
0
  SSVAL(buf, 6, 0);  /* Reserved */
5389
0
  if (conn->max_protocol >= PROTOCOL_SMB3_00) {
5390
0
    SIVAL(buf, 8, conn->smb2.client.capabilities);
5391
0
  } else {
5392
0
    SIVAL(buf, 8, 0);  /* Capabilities */
5393
0
  }
5394
0
  if (conn->max_protocol >= PROTOCOL_SMB2_10) {
5395
0
    struct GUID_ndr_buf guid_buf = { .buf = {0}, };
5396
5397
0
    GUID_to_ndr_buf(&conn->smb2.client.guid, &guid_buf);
5398
0
    memcpy(buf+12, guid_buf.buf, 16); /* ClientGuid */
5399
0
  } else {
5400
0
    memset(buf+12, 0, 16);  /* ClientGuid */
5401
0
  }
5402
5403
0
  if (conn->max_protocol >= PROTOCOL_SMB3_11) {
5404
0
    const struct smb3_signing_capabilities *client_sign_algos =
5405
0
      &conn->smb2.client.smb3_capabilities.signing;
5406
0
    const struct smb3_encryption_capabilities *client_ciphers =
5407
0
      &conn->smb2.client.smb3_capabilities.encryption;
5408
0
    enum tls_verify_peer_state verify_peer;
5409
0
    NTSTATUS status;
5410
0
    struct smb2_negotiate_contexts c = { .num_contexts = 0, };
5411
0
    uint8_t *netname_utf16 = NULL;
5412
0
    size_t netname_utf16_len = 0;
5413
0
    uint32_t offset;
5414
0
    DATA_BLOB b;
5415
0
    uint8_t p[38];
5416
0
    static const uint8_t zeros[8] = {0, };
5417
0
    size_t pad;
5418
0
    bool ok;
5419
5420
0
    SSVAL(p, 0,  1); /* HashAlgorithmCount */
5421
0
    SSVAL(p, 2, 32); /* SaltLength */
5422
0
    SSVAL(p, 4, SMB2_PREAUTH_INTEGRITY_SHA512);
5423
0
    generate_random_buffer(p + 6, 32);
5424
5425
0
    status = smb2_negotiate_context_add(
5426
0
      state, &c, SMB2_PREAUTH_INTEGRITY_CAPABILITIES, p, 38);
5427
0
    if (!NT_STATUS_IS_OK(status)) {
5428
0
      return NULL;
5429
0
    }
5430
5431
0
    if (client_ciphers->num_algos > 0) {
5432
0
      size_t ofs = 0;
5433
0
      SSVAL(p, ofs, client_ciphers->num_algos);
5434
0
      ofs += 2;
5435
5436
0
      for (i = 0; i < client_ciphers->num_algos; i++) {
5437
0
        size_t next_ofs = ofs + 2;
5438
0
        SMB_ASSERT(next_ofs < ARRAY_SIZE(p));
5439
0
        SSVAL(p, ofs, client_ciphers->algos[i]);
5440
0
        ofs = next_ofs;
5441
0
      }
5442
5443
0
      status = smb2_negotiate_context_add(
5444
0
        state, &c, SMB2_ENCRYPTION_CAPABILITIES, p, ofs);
5445
0
      if (!NT_STATUS_IS_OK(status)) {
5446
0
        return NULL;
5447
0
      }
5448
0
    }
5449
5450
0
    if (client_sign_algos->num_algos > 0) {
5451
0
      size_t ofs = 0;
5452
0
      SSVAL(p, ofs, client_sign_algos->num_algos);
5453
0
      ofs += 2;
5454
5455
0
      for (i = 0; i < client_sign_algos->num_algos; i++) {
5456
0
        size_t next_ofs = ofs + 2;
5457
0
        SMB_ASSERT(next_ofs < ARRAY_SIZE(p));
5458
0
        SSVAL(p, ofs, client_sign_algos->algos[i]);
5459
0
        ofs = next_ofs;
5460
0
      }
5461
5462
0
      status = smb2_negotiate_context_add(
5463
0
        state, &c, SMB2_SIGNING_CAPABILITIES, p, ofs);
5464
0
      if (!NT_STATUS_IS_OK(status)) {
5465
0
        return NULL;
5466
0
      }
5467
0
    }
5468
5469
0
    verify_peer = conn->transport->verify_peer;
5470
5471
0
    if (tstream_tls_verify_peer_trusted(verify_peer) &&
5472
0
        !conn->smb2.client.smb3_capabilities
5473
0
           .smb_encryption_over_quic)
5474
0
    {
5475
0
      uint8_t cap_buf[sizeof(uint32_t)];
5476
5477
0
      PUSH_LE_U32(cap_buf,
5478
0
            0,
5479
0
            SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY);
5480
5481
0
      status = smb2_negotiate_context_add(
5482
0
        state,
5483
0
        &c,
5484
0
        SMB2_TRANSPORT_CAPABILITIES,
5485
0
        cap_buf,
5486
0
        sizeof(cap_buf));
5487
0
      if (!NT_STATUS_IS_OK(status)) {
5488
0
        return NULL;
5489
0
      }
5490
0
      conn->smb2.client
5491
0
        .requested_transport_level_security = true;
5492
0
    }
5493
5494
0
    ok = convert_string_talloc(state,
5495
0
             CH_UNIX,
5496
0
             CH_UTF16,
5497
0
             conn->remote_name,
5498
0
             strlen(conn->remote_name),
5499
0
             &netname_utf16,
5500
0
             &netname_utf16_len);
5501
0
    if (!ok) {
5502
0
      return NULL;
5503
0
    }
5504
5505
0
    status = smb2_negotiate_context_add(state, &c,
5506
0
          SMB2_NETNAME_NEGOTIATE_CONTEXT_ID,
5507
0
          netname_utf16, netname_utf16_len);
5508
0
    if (!NT_STATUS_IS_OK(status)) {
5509
0
      return NULL;
5510
0
    }
5511
5512
0
    if (state->in_ctx != NULL) {
5513
0
      struct smb2_negotiate_contexts *ctxs = state->in_ctx;
5514
5515
0
      for (i=0; i<ctxs->num_contexts; i++) {
5516
0
        struct smb2_negotiate_context *ctx =
5517
0
          &ctxs->contexts[i];
5518
5519
0
        status = smb2_negotiate_context_add(
5520
0
          state,
5521
0
          &c,
5522
0
          ctx->type,
5523
0
          ctx->data.data,
5524
0
          ctx->data.length);
5525
0
        if (!NT_STATUS_IS_OK(status)) {
5526
0
          return NULL;
5527
0
        }
5528
0
      }
5529
0
    }
5530
5531
0
    status = smb2_negotiate_context_push(state, &b, c);
5532
0
    if (!NT_STATUS_IS_OK(status)) {
5533
0
      return NULL;
5534
0
    }
5535
5536
0
    offset = SMB2_HDR_BODY + sizeof(state->smb2.fixed) + dyn.length;
5537
0
    pad = smbXcli_padding_helper(offset, 8);
5538
5539
0
    ok = data_blob_append(state, &dyn, zeros, pad);
5540
0
    if (!ok) {
5541
0
      return NULL;
5542
0
    }
5543
0
    offset += pad;
5544
5545
0
    ok = data_blob_append(state, &dyn, b.data, b.length);
5546
0
    if (!ok) {
5547
0
      return NULL;
5548
0
    }
5549
5550
0
    SIVAL(buf, 28, offset);   /* NegotiateContextOffset */
5551
0
    SSVAL(buf, 32, c.num_contexts); /* NegotiateContextCount */
5552
0
    SSVAL(buf, 34, 0);        /* Reserved */
5553
0
  } else {
5554
0
    SBVAL(buf, 28, 0); /* Reserved/ClientStartTime */
5555
0
  }
5556
5557
0
  return smb2cli_req_send(state,
5558
0
        state->ev,
5559
0
        conn,
5560
0
        SMB2_OP_NEGPROT,
5561
0
        0, /* additional_flags */
5562
0
        0, /* clear_flags */
5563
0
        state->timeout_msec,
5564
0
        NULL, /* tcon */
5565
0
        NULL, /* session */
5566
0
        state->smb2.fixed,
5567
0
        sizeof(state->smb2.fixed),
5568
0
        dyn.data,
5569
0
        dyn.length,
5570
0
        UINT16_MAX); /* max_dyn_len */
5571
0
}
5572
5573
static NTSTATUS smbXcli_negprot_smb3_check_capabilities(struct tevent_req *req);
5574
5575
static void smbXcli_negprot_smb2_done(struct tevent_req *subreq)
5576
0
{
5577
0
  struct tevent_req *req =
5578
0
    tevent_req_callback_data(subreq,
5579
0
    struct tevent_req);
5580
0
  struct smbXcli_negprot_state *state =
5581
0
    tevent_req_data(req,
5582
0
    struct smbXcli_negprot_state);
5583
0
  struct smbXcli_conn *conn = state->conn;
5584
0
  size_t security_offset, security_length;
5585
0
  DATA_BLOB blob;
5586
0
  NTSTATUS status;
5587
0
  struct iovec *iov = NULL;
5588
0
  uint8_t *body;
5589
0
  size_t i;
5590
0
  uint16_t dialect_revision;
5591
0
  uint32_t negotiate_context_offset = 0;
5592
0
  uint16_t negotiate_context_count = 0;
5593
0
  DATA_BLOB negotiate_context_blob = data_blob_null;
5594
0
  size_t avail;
5595
0
  size_t ctx_ofs;
5596
0
  size_t needed;
5597
0
  struct smb2_negotiate_context *preauth = NULL;
5598
0
  uint16_t hash_count;
5599
0
  uint16_t salt_length;
5600
0
  uint16_t hash_selected;
5601
0
  gnutls_hash_hd_t hash_hnd = NULL;
5602
0
  struct smb2_negotiate_context *sign_algo = NULL;
5603
0
  struct smb2_negotiate_context *cipher = NULL;
5604
0
  struct smb2_negotiate_context *posix = NULL;
5605
0
  struct smb2_negotiate_context *transport_caps = NULL;
5606
0
  struct iovec sent_iov[3] = {{0}, {0}, {0}};
5607
0
  static const struct smb2cli_req_expected_response expected[] = {
5608
0
  {
5609
0
    .status = NT_STATUS_OK,
5610
0
    .body_size = 0x41
5611
0
  }
5612
0
  };
5613
0
  int rc;
5614
5615
0
  status = smb2cli_req_recv(subreq, state, &iov,
5616
0
          expected, ARRAY_SIZE(expected));
5617
0
  if (tevent_req_nterror(req, status)) {
5618
0
    return;
5619
0
  }
5620
0
  if (iov == NULL) {
5621
0
    tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5622
0
    return;
5623
0
  }
5624
5625
0
  body = (uint8_t *)iov[1].iov_base;
5626
5627
0
  dialect_revision = SVAL(body, 4);
5628
5629
0
  for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
5630
0
    if (smb2cli_prots[i].proto < state->conn->min_protocol) {
5631
0
      continue;
5632
0
    }
5633
5634
0
    if (smb2cli_prots[i].proto > state->conn->max_protocol) {
5635
0
      continue;
5636
0
    }
5637
5638
0
    if (smb2cli_prots[i].smb2_dialect != dialect_revision) {
5639
0
      continue;
5640
0
    }
5641
5642
0
    conn->protocol = smb2cli_prots[i].proto;
5643
0
    break;
5644
0
  }
5645
5646
0
  if (conn->protocol == PROTOCOL_NONE) {
5647
0
    TALLOC_FREE(subreq);
5648
5649
0
    if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
5650
0
      tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5651
0
      return;
5652
0
    }
5653
5654
0
    if (dialect_revision != SMB2_DIALECT_REVISION_2FF) {
5655
0
      tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5656
0
      return;
5657
0
    }
5658
5659
    /* make sure we do not loop forever */
5660
0
    state->conn->min_protocol = PROTOCOL_SMB2_02;
5661
5662
    /*
5663
     * send a SMB2 negprot, in order to negotiate
5664
     * the SMB2 dialect.
5665
     */
5666
0
    subreq = smbXcli_negprot_smb2_subreq(state);
5667
0
    if (tevent_req_nomem(subreq, req)) {
5668
0
      return;
5669
0
    }
5670
0
    tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
5671
0
    return;
5672
0
  }
5673
5674
0
  conn->smb2.server.security_mode = SVAL(body, 2);
5675
0
  if (conn->protocol >= PROTOCOL_SMB3_11) {
5676
0
    negotiate_context_count = SVAL(body, 6);
5677
0
  }
5678
5679
0
  blob = data_blob_const(body + 8, 16);
5680
0
  status = GUID_from_data_blob(&blob, &conn->smb2.server.guid);
5681
0
  if (tevent_req_nterror(req, status)) {
5682
0
    return;
5683
0
  }
5684
5685
0
  conn->smb2.server.capabilities  = IVAL(body, 24);
5686
0
  conn->smb2.server.max_trans_size= IVAL(body, 28);
5687
0
  conn->smb2.server.max_read_size = IVAL(body, 32);
5688
0
  conn->smb2.server.max_write_size= IVAL(body, 36);
5689
0
  conn->smb2.server.system_time = BVAL(body, 40);
5690
0
  conn->smb2.server.start_time  = BVAL(body, 48);
5691
5692
0
  if (conn->smb2.server.max_trans_size == 0 ||
5693
0
      conn->smb2.server.max_read_size == 0 ||
5694
0
      conn->smb2.server.max_write_size == 0) {
5695
    /*
5696
     * We can't connect to servers we can't
5697
     * do any operations on.
5698
     */
5699
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5700
0
    return;
5701
0
  }
5702
5703
0
  security_offset = SVAL(body, 56);
5704
0
  security_length = SVAL(body, 58);
5705
5706
0
  if (security_offset == 0) {
5707
    /*
5708
     * Azure sends security_offset = 0 and security_length = 0
5709
     *
5710
     * We just set security_offset to the expected value
5711
     * in order to allow the further logic to work
5712
     * as before.
5713
     */
5714
0
    if (security_length != 0) {
5715
0
      tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5716
0
      return;
5717
0
    }
5718
0
    security_offset = SMB2_HDR_BODY + iov[1].iov_len;
5719
0
  }
5720
5721
0
  if (security_offset != SMB2_HDR_BODY + iov[1].iov_len) {
5722
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5723
0
    return;
5724
0
  }
5725
5726
0
  if (security_length > iov[2].iov_len) {
5727
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5728
0
    return;
5729
0
  }
5730
5731
0
  conn->smb2.server.gss_blob = data_blob_talloc_s(conn,
5732
0
              iov[2].iov_base,
5733
0
              security_length);
5734
0
  if (tevent_req_nomem(conn->smb2.server.gss_blob.data, req)) {
5735
0
    return;
5736
0
  }
5737
5738
0
  if (conn->protocol >= PROTOCOL_SMB3_00) {
5739
0
    conn->smb2.server.sign_algo = SMB2_SIGNING_AES128_CMAC;
5740
0
  } else {
5741
0
    conn->smb2.server.sign_algo = SMB2_SIGNING_HMAC_SHA256;
5742
0
  }
5743
5744
0
  if (conn->protocol < PROTOCOL_SMB3_11) {
5745
0
    TALLOC_FREE(subreq);
5746
5747
0
    if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
5748
0
      conn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
5749
0
    }
5750
5751
0
    status = smbXcli_negprot_smb3_check_capabilities(req);
5752
0
    if (tevent_req_nterror(req, status)) {
5753
0
      return;
5754
0
    }
5755
5756
0
    tevent_req_done(req);
5757
0
    return;
5758
0
  }
5759
5760
  /*
5761
   * Here we are now at SMB3_11, so encryption should be
5762
   * negotiated via context, not capabilities.
5763
   */
5764
5765
0
  if (conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION) {
5766
    /*
5767
     * Server set SMB2_CAP_ENCRYPTION capability,
5768
     * but *SHOULD* not, not *MUST* not. Just mask it off.
5769
     * NetApp seems to do this:
5770
     * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13009
5771
     */
5772
0
    conn->smb2.server.capabilities &= ~SMB2_CAP_ENCRYPTION;
5773
0
  }
5774
5775
0
  negotiate_context_offset = IVAL(body, 60);
5776
0
  if (negotiate_context_offset < security_offset) {
5777
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5778
0
    return;
5779
0
  }
5780
5781
0
  ctx_ofs = negotiate_context_offset - security_offset;
5782
0
  if (ctx_ofs > iov[2].iov_len) {
5783
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5784
0
    return;
5785
0
  }
5786
0
  avail = iov[2].iov_len - security_length;
5787
0
  needed = iov[2].iov_len - ctx_ofs;
5788
0
  if (needed > avail) {
5789
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5790
0
    return;
5791
0
  }
5792
5793
0
  negotiate_context_blob.data = (uint8_t *)iov[2].iov_base;
5794
0
  negotiate_context_blob.length = iov[2].iov_len;
5795
5796
0
  negotiate_context_blob.data += ctx_ofs;
5797
0
  negotiate_context_blob.length -= ctx_ofs;
5798
5799
0
  state->out_ctx = talloc_zero(state, struct smb2_negotiate_contexts);
5800
0
  if (tevent_req_nomem(state->out_ctx, req)) {
5801
0
    return;
5802
0
  }
5803
5804
0
  status = smb2_negotiate_context_parse(state->out_ctx,
5805
0
                negotiate_context_blob,
5806
0
                negotiate_context_count,
5807
0
                state->out_ctx);
5808
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
5809
0
    status = NT_STATUS_INVALID_NETWORK_RESPONSE;
5810
0
  }
5811
0
  if (tevent_req_nterror(req, status)) {
5812
0
    return;
5813
0
  }
5814
5815
0
  preauth = smb2_negotiate_context_find(
5816
0
    state->out_ctx, SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
5817
0
  if (preauth == NULL) {
5818
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5819
0
    return;
5820
0
  }
5821
5822
0
  if (preauth->data.length < 6) {
5823
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5824
0
    return;
5825
0
  }
5826
5827
0
  hash_count = SVAL(preauth->data.data, 0);
5828
0
  salt_length = SVAL(preauth->data.data, 2);
5829
0
  hash_selected = SVAL(preauth->data.data, 4);
5830
5831
0
  if (hash_count != 1) {
5832
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5833
0
    return;
5834
0
  }
5835
5836
0
  if (preauth->data.length != (6 + salt_length)) {
5837
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5838
0
    return;
5839
0
  }
5840
5841
0
  if (hash_selected != SMB2_PREAUTH_INTEGRITY_SHA512) {
5842
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
5843
0
    return;
5844
0
  }
5845
5846
0
  sign_algo = smb2_negotiate_context_find(
5847
0
    state->out_ctx, SMB2_SIGNING_CAPABILITIES);
5848
0
  if (sign_algo != NULL) {
5849
0
    const struct smb3_signing_capabilities *client_sign_algos =
5850
0
      &state->conn->smb2.client.smb3_capabilities.signing;
5851
0
    bool found_selected = false;
5852
0
    uint16_t sign_algo_count;
5853
0
    uint16_t sign_algo_selected;
5854
5855
0
    if (client_sign_algos->num_algos == 0) {
5856
      /*
5857
       * We didn't ask for SMB2_ENCRYPTION_CAPABILITIES
5858
       */
5859
0
      tevent_req_nterror(req,
5860
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5861
0
      return;
5862
0
    }
5863
5864
0
    if (sign_algo->data.length < 2) {
5865
0
      tevent_req_nterror(req,
5866
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5867
0
      return;
5868
0
    }
5869
5870
0
    sign_algo_count = SVAL(sign_algo->data.data, 0);
5871
0
    if (sign_algo_count != 1) {
5872
0
      tevent_req_nterror(req,
5873
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5874
0
      return;
5875
0
    }
5876
5877
0
    if (sign_algo->data.length < (2 + 2 * sign_algo_count)) {
5878
0
      tevent_req_nterror(req,
5879
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5880
0
      return;
5881
0
    }
5882
0
    sign_algo_selected = SVAL(sign_algo->data.data, 2);
5883
5884
0
    for (i = 0; i < client_sign_algos->num_algos; i++) {
5885
0
      if (client_sign_algos->algos[i] == sign_algo_selected) {
5886
        /*
5887
         * We found a match
5888
         */
5889
0
        found_selected = true;
5890
0
        break;
5891
0
      }
5892
0
    }
5893
5894
0
    if (!found_selected) {
5895
      /*
5896
       * The server send a sign_algo we didn't offer.
5897
       */
5898
0
      tevent_req_nterror(req,
5899
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5900
0
      return;
5901
0
    }
5902
5903
0
    conn->smb2.server.sign_algo = sign_algo_selected;
5904
0
  }
5905
5906
0
  cipher = smb2_negotiate_context_find(
5907
0
    state->out_ctx, SMB2_ENCRYPTION_CAPABILITIES);
5908
0
  if (cipher != NULL) {
5909
0
    const struct smb3_encryption_capabilities *client_ciphers =
5910
0
      &state->conn->smb2.client.smb3_capabilities.encryption;
5911
0
    bool found_selected = false;
5912
0
    uint16_t cipher_count;
5913
0
    uint16_t cipher_selected;
5914
5915
0
    if (client_ciphers->num_algos == 0) {
5916
      /*
5917
       * We didn't ask for SMB2_ENCRYPTION_CAPABILITIES
5918
       */
5919
0
      tevent_req_nterror(req,
5920
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5921
0
      return;
5922
0
    }
5923
5924
0
    if (cipher->data.length < 2) {
5925
0
      tevent_req_nterror(req,
5926
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5927
0
      return;
5928
0
    }
5929
5930
0
    cipher_count = SVAL(cipher->data.data, 0);
5931
0
    if (cipher_count != 1) {
5932
0
      tevent_req_nterror(req,
5933
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5934
0
      return;
5935
0
    }
5936
5937
0
    if (cipher->data.length < (2 + 2 * cipher_count)) {
5938
0
      tevent_req_nterror(req,
5939
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5940
0
      return;
5941
0
    }
5942
0
    cipher_selected = SVAL(cipher->data.data, 2);
5943
5944
0
    for (i = 0; i < client_ciphers->num_algos; i++) {
5945
0
      if (cipher_selected == SMB2_ENCRYPTION_NONE) {
5946
        /*
5947
         * encryption not supported
5948
         */
5949
0
        found_selected = true;
5950
0
        break;
5951
0
      }
5952
0
      if (client_ciphers->algos[i] == cipher_selected) {
5953
        /*
5954
         * We found a match
5955
         */
5956
0
        found_selected = true;
5957
0
        break;
5958
0
      }
5959
0
    }
5960
5961
0
    if (!found_selected) {
5962
      /*
5963
       * The server send a cipher we didn't offer.
5964
       */
5965
0
      tevent_req_nterror(req,
5966
0
          NT_STATUS_INVALID_NETWORK_RESPONSE);
5967
0
      return;
5968
0
    }
5969
5970
0
    conn->smb2.server.cipher = cipher_selected;
5971
0
  }
5972
5973
0
  if (conn->smb2.client.requested_transport_level_security) {
5974
0
    transport_caps = smb2_negotiate_context_find(
5975
0
      state->out_ctx, SMB2_TRANSPORT_CAPABILITIES);
5976
0
  }
5977
0
  if (transport_caps != NULL) {
5978
0
    uint32_t caps;
5979
5980
0
    if (transport_caps->data.length != sizeof(uint32_t)) {
5981
0
      tevent_req_nterror(req,
5982
0
             NT_STATUS_INVALID_NETWORK_RESPONSE);
5983
0
      return;
5984
0
    }
5985
5986
0
    caps = PULL_LE_U32(transport_caps->data.data, 0);
5987
5988
0
    conn->smb2.server.transport_trusted =
5989
0
      (caps & SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY) != 0;
5990
0
  }
5991
5992
0
  posix = smb2_negotiate_context_find(
5993
0
    state->out_ctx, SMB2_POSIX_EXTENSIONS_AVAILABLE);
5994
0
  if (posix != NULL) {
5995
0
    DATA_BLOB posix_blob = data_blob_const(
5996
0
      SMB2_CREATE_TAG_POSIX, strlen(SMB2_CREATE_TAG_POSIX));
5997
0
    int cmp = data_blob_cmp(&posix->data, &posix_blob);
5998
5999
0
    conn->smb2.server.smb311_posix = (cmp == 0);
6000
0
  }
6001
6002
6003
  /* First we hash the request */
6004
0
  smb2cli_req_get_sent_iov(subreq, sent_iov);
6005
6006
0
  rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
6007
0
  if (rc < 0) {
6008
0
    tevent_req_nterror(req,
6009
0
           gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
6010
0
    return;
6011
0
  }
6012
6013
0
  rc = gnutls_hash(hash_hnd,
6014
0
       conn->smb2.preauth_sha512,
6015
0
       sizeof(conn->smb2.preauth_sha512));
6016
0
  if (rc < 0) {
6017
0
    gnutls_hash_deinit(hash_hnd, NULL);
6018
0
    tevent_req_nterror(req,
6019
0
           gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
6020
0
    return;
6021
0
  }
6022
0
  for (i = 0; i < 3; i++) {
6023
0
    rc = gnutls_hash(hash_hnd,
6024
0
         sent_iov[i].iov_base,
6025
0
         sent_iov[i].iov_len);
6026
0
    if (rc < 0) {
6027
0
      gnutls_hash_deinit(hash_hnd, NULL);
6028
0
      tevent_req_nterror(req,
6029
0
             gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
6030
0
      return;
6031
0
    }
6032
0
  }
6033
6034
  /* This resets the hash state */
6035
0
  gnutls_hash_output(hash_hnd, conn->smb2.preauth_sha512);
6036
0
  TALLOC_FREE(subreq);
6037
6038
  /* And now we hash the response */
6039
0
  rc = gnutls_hash(hash_hnd,
6040
0
       conn->smb2.preauth_sha512,
6041
0
       sizeof(conn->smb2.preauth_sha512));
6042
0
  if (rc < 0) {
6043
0
    gnutls_hash_deinit(hash_hnd, NULL);
6044
0
    tevent_req_nterror(req,
6045
0
           gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
6046
0
    return;
6047
0
  }
6048
0
  for (i = 0; i < 3; i++) {
6049
0
    rc = gnutls_hash(hash_hnd,
6050
0
         iov[i].iov_base,
6051
0
         iov[i].iov_len);
6052
0
    if (rc < 0) {
6053
0
      gnutls_hash_deinit(hash_hnd, NULL);
6054
0
      tevent_req_nterror(req,
6055
0
             gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED));
6056
0
      return;
6057
0
    }
6058
0
  }
6059
0
  gnutls_hash_deinit(hash_hnd, conn->smb2.preauth_sha512);
6060
0
  if (rc < 0) {
6061
0
    tevent_req_nterror(req,
6062
0
           NT_STATUS_UNSUCCESSFUL);
6063
0
    return;
6064
0
  }
6065
6066
0
  status = smbXcli_negprot_smb3_check_capabilities(req);
6067
0
  if (tevent_req_nterror(req, status)) {
6068
0
    return;
6069
0
  }
6070
6071
0
  tevent_req_done(req);
6072
0
}
6073
6074
static NTSTATUS smbXcli_negprot_smb3_check_capabilities(struct tevent_req *req)
6075
0
{
6076
0
  struct smbXcli_negprot_state *state =
6077
0
    tevent_req_data(req,
6078
0
    struct smbXcli_negprot_state);
6079
0
  struct smbXcli_conn *conn = state->conn;
6080
6081
0
  return smb311_capabilities_check(&conn->smb2.client.smb3_capabilities,
6082
0
           "smbXcli_negprot",
6083
0
           DBGLVL_ERR,
6084
0
           NT_STATUS_ACCESS_DENIED,
6085
0
           "client",
6086
0
           conn->protocol,
6087
0
           conn->smb2.server.sign_algo,
6088
0
           conn->smb2.server.cipher);
6089
0
}
6090
6091
static NTSTATUS smbXcli_negprot_dispatch_incoming(struct smbXcli_conn *conn,
6092
              TALLOC_CTX *tmp_mem,
6093
              uint8_t *inbuf)
6094
0
{
6095
0
  size_t num_pending = talloc_array_length(conn->pending);
6096
0
  struct tevent_req *subreq;
6097
0
  struct smbXcli_req_state *substate;
6098
0
  struct tevent_req *req;
6099
0
  uint32_t protocol_magic;
6100
0
  size_t inbuf_len = smb_len_nbt(inbuf);
6101
6102
0
  if (num_pending != 1) {
6103
0
    return NT_STATUS_INTERNAL_ERROR;
6104
0
  }
6105
6106
0
  if (inbuf_len < 4) {
6107
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
6108
0
  }
6109
6110
0
  subreq = conn->pending[0];
6111
0
  substate = tevent_req_data(subreq, struct smbXcli_req_state);
6112
0
  req = tevent_req_callback_data(subreq, struct tevent_req);
6113
6114
0
  protocol_magic = IVAL(inbuf, 4);
6115
6116
0
  switch (protocol_magic) {
6117
0
  case SMB_MAGIC:
6118
0
    tevent_req_set_callback(subreq, smbXcli_negprot_smb1_done, req);
6119
0
    conn->dispatch_incoming = smb1cli_conn_dispatch_incoming;
6120
0
    return smb1cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
6121
6122
0
  case SMB2_MAGIC:
6123
0
    if (substate->smb2.recv_iov == NULL) {
6124
      /*
6125
       * For the SMB1 negprot we have move it.
6126
       */
6127
0
      substate->smb2.recv_iov = substate->smb1.recv_iov;
6128
0
      substate->smb1.recv_iov = NULL;
6129
0
    }
6130
6131
    /*
6132
     * we got an SMB2 answer, which consumed sequence number 0
6133
     * so we need to use 1 as the next one.
6134
     *
6135
     * we also need to set the current credits to 0
6136
     * as we consumed the initial one. The SMB2 answer
6137
     * hopefully grant us a new credit.
6138
     */
6139
0
    conn->smb2.mid = 1;
6140
0
    conn->smb2.cur_credits = 0;
6141
0
    tevent_req_set_callback(subreq, smbXcli_negprot_smb2_done, req);
6142
0
    conn->dispatch_incoming = smb2cli_conn_dispatch_incoming;
6143
0
    return smb2cli_conn_dispatch_incoming(conn, tmp_mem, inbuf);
6144
0
  }
6145
6146
0
  DEBUG(10, ("Got non-SMB PDU\n"));
6147
0
  return NT_STATUS_INVALID_NETWORK_RESPONSE;
6148
0
}
6149
6150
NTSTATUS smbXcli_negprot_recv(
6151
  struct tevent_req *req,
6152
  TALLOC_CTX *mem_ctx,
6153
  struct smb2_negotiate_contexts **out_ctx)
6154
0
{
6155
0
  struct smbXcli_negprot_state *state = tevent_req_data(
6156
0
    req, struct smbXcli_negprot_state);
6157
0
  NTSTATUS status;
6158
6159
0
  if (tevent_req_is_nterror(req, &status)) {
6160
0
    tevent_req_received(req);
6161
0
    return status;
6162
0
  }
6163
6164
0
  if (out_ctx != NULL) {
6165
0
    *out_ctx = talloc_move(mem_ctx, &state->out_ctx);
6166
0
  }
6167
6168
0
  tevent_req_received(req);
6169
0
  return NT_STATUS_OK;
6170
0
}
6171
6172
NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn,
6173
       uint32_t timeout_msec,
6174
       enum protocol_types min_protocol,
6175
       enum protocol_types max_protocol,
6176
       struct smb2_negotiate_contexts *in_ctx,
6177
       TALLOC_CTX *mem_ctx,
6178
       struct smb2_negotiate_contexts **out_ctx)
6179
0
{
6180
0
  TALLOC_CTX *frame = talloc_stackframe();
6181
0
  struct tevent_context *ev;
6182
0
  struct tevent_req *req;
6183
0
  NTSTATUS status = NT_STATUS_NO_MEMORY;
6184
0
  bool ok;
6185
6186
0
  if (smbXcli_conn_has_async_calls(conn)) {
6187
    /*
6188
     * Can't use sync call while an async call is in flight
6189
     */
6190
0
    status = NT_STATUS_INVALID_PARAMETER_MIX;
6191
0
    goto fail;
6192
0
  }
6193
0
  ev = samba_tevent_context_init(frame);
6194
0
  if (ev == NULL) {
6195
0
    goto fail;
6196
0
  }
6197
0
  req = smbXcli_negprot_send(
6198
0
    frame,
6199
0
    ev,
6200
0
    conn,
6201
0
    timeout_msec,
6202
0
    min_protocol,
6203
0
    max_protocol,
6204
0
    WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK,
6205
0
    in_ctx);
6206
0
  if (req == NULL) {
6207
0
    goto fail;
6208
0
  }
6209
0
  ok = tevent_req_poll_ntstatus(req, ev, &status);
6210
0
  if (!ok) {
6211
0
    goto fail;
6212
0
  }
6213
0
  status = smbXcli_negprot_recv(req, mem_ctx, out_ctx);
6214
0
 fail:
6215
0
  TALLOC_FREE(frame);
6216
0
  return status;
6217
0
}
6218
6219
struct smb2cli_validate_negotiate_info_state {
6220
  struct smbXcli_conn *conn;
6221
  DATA_BLOB in_input_buffer;
6222
  DATA_BLOB in_output_buffer;
6223
  DATA_BLOB out_input_buffer;
6224
  DATA_BLOB out_output_buffer;
6225
  uint16_t dialect;
6226
};
6227
6228
static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq);
6229
6230
struct tevent_req *smb2cli_validate_negotiate_info_send(TALLOC_CTX *mem_ctx,
6231
            struct tevent_context *ev,
6232
            struct smbXcli_conn *conn,
6233
            uint32_t timeout_msec,
6234
            struct smbXcli_session *session,
6235
            struct smbXcli_tcon *tcon)
6236
0
{
6237
0
  struct tevent_req *req;
6238
0
  struct smb2cli_validate_negotiate_info_state *state;
6239
0
  uint8_t *buf;
6240
0
  uint16_t dialect_count = 0;
6241
0
  struct tevent_req *subreq;
6242
0
  bool _save_should_sign;
6243
0
  size_t i;
6244
6245
0
  req = tevent_req_create(mem_ctx, &state,
6246
0
        struct smb2cli_validate_negotiate_info_state);
6247
0
  if (req == NULL) {
6248
0
    return NULL;
6249
0
  }
6250
0
  state->conn = conn;
6251
6252
0
  state->in_input_buffer = data_blob_talloc_zero(state,
6253
0
          4 + 16 + 1 + 1 + 2);
6254
0
  if (tevent_req_nomem(state->in_input_buffer.data, req)) {
6255
0
    return tevent_req_post(req, ev);
6256
0
  }
6257
0
  buf = state->in_input_buffer.data;
6258
6259
0
  if (state->conn->max_protocol >= PROTOCOL_SMB3_00) {
6260
0
    SIVAL(buf, 0, conn->smb2.client.capabilities);
6261
0
  } else {
6262
0
    SIVAL(buf, 0, 0); /* Capabilities */
6263
0
  }
6264
0
  if (state->conn->max_protocol >= PROTOCOL_SMB2_10) {
6265
0
    struct GUID_ndr_buf guid_buf = { .buf = {0}, };
6266
6267
0
    GUID_to_ndr_buf(&conn->smb2.client.guid, &guid_buf);
6268
0
    memcpy(buf+4, guid_buf.buf, 16); /* ClientGuid */
6269
0
  } else {
6270
0
    memset(buf+4, 0, 16); /* ClientGuid */
6271
0
  }
6272
0
  if (state->conn->min_protocol >= PROTOCOL_SMB2_02) {
6273
0
    SCVAL(buf, 20, conn->smb2.client.security_mode);
6274
0
  } else {
6275
0
    SCVAL(buf, 20, 0);
6276
0
  }
6277
0
  SCVAL(buf, 21, 0); /* reserved */
6278
6279
0
  for (i=0; i < ARRAY_SIZE(smb2cli_prots); i++) {
6280
0
    bool ok;
6281
0
    size_t ofs;
6282
6283
0
    if (smb2cli_prots[i].proto < state->conn->min_protocol) {
6284
0
      continue;
6285
0
    }
6286
6287
0
    if (smb2cli_prots[i].proto > state->conn->max_protocol) {
6288
0
      continue;
6289
0
    }
6290
6291
0
    if (smb2cli_prots[i].proto == state->conn->protocol) {
6292
0
      state->dialect = smb2cli_prots[i].smb2_dialect;
6293
0
    }
6294
6295
0
    ofs = state->in_input_buffer.length;
6296
0
    ok = data_blob_realloc(state, &state->in_input_buffer,
6297
0
               ofs + 2);
6298
0
    if (!ok) {
6299
0
      tevent_req_oom(req);
6300
0
      return tevent_req_post(req, ev);
6301
0
    }
6302
6303
0
    buf = state->in_input_buffer.data;
6304
0
    SSVAL(buf, ofs, smb2cli_prots[i].smb2_dialect);
6305
6306
0
    dialect_count++;
6307
0
  }
6308
0
  buf = state->in_input_buffer.data;
6309
0
  SSVAL(buf, 22, dialect_count);
6310
6311
0
  _save_should_sign = smb2cli_tcon_is_signing_on(tcon);
6312
0
  smb2cli_tcon_should_sign(tcon, true);
6313
0
  subreq = smb2cli_ioctl_send(state, ev, conn,
6314
0
            timeout_msec, session, tcon,
6315
0
            UINT64_MAX, /* in_fid_persistent */
6316
0
            UINT64_MAX, /* in_fid_volatile */
6317
0
            FSCTL_VALIDATE_NEGOTIATE_INFO,
6318
0
            0, /* in_max_input_length */
6319
0
            &state->in_input_buffer,
6320
0
            24, /* in_max_output_length */
6321
0
            &state->in_output_buffer,
6322
0
            SMB2_IOCTL_FLAG_IS_FSCTL);
6323
0
  smb2cli_tcon_should_sign(tcon, _save_should_sign);
6324
0
  if (tevent_req_nomem(subreq, req)) {
6325
0
    return tevent_req_post(req, ev);
6326
0
  }
6327
0
  tevent_req_set_callback(subreq,
6328
0
        smb2cli_validate_negotiate_info_done,
6329
0
        req);
6330
6331
0
  return req;
6332
0
}
6333
6334
static void smb2cli_validate_negotiate_info_done(struct tevent_req *subreq)
6335
0
{
6336
0
  struct tevent_req *req =
6337
0
    tevent_req_callback_data(subreq,
6338
0
    struct tevent_req);
6339
0
  struct smb2cli_validate_negotiate_info_state *state =
6340
0
    tevent_req_data(req,
6341
0
    struct smb2cli_validate_negotiate_info_state);
6342
0
  NTSTATUS status;
6343
0
  const uint8_t *buf;
6344
0
  uint32_t capabilities;
6345
0
  DATA_BLOB guid_blob;
6346
0
  struct GUID server_guid;
6347
0
  uint16_t security_mode;
6348
0
  uint16_t dialect;
6349
6350
0
  status = smb2cli_ioctl_recv(subreq, state,
6351
0
            &state->out_input_buffer,
6352
0
            &state->out_output_buffer);
6353
0
  TALLOC_FREE(subreq);
6354
6355
  /*
6356
   * This response must be signed correctly for
6357
   * these "normal" error codes to be processed.
6358
   * If the packet wasn't signed correctly we will get
6359
   * NT_STATUS_ACCESS_DENIED or NT_STATUS_HMAC_NOT_SUPPORTED,
6360
   * or NT_STATUS_INVALID_NETWORK_RESPONSE
6361
   * from smb2_signing_check_pdu().
6362
   *
6363
   * We must never ignore the above errors here.
6364
   */
6365
6366
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
6367
    /*
6368
     * The response was signed, but not supported
6369
     *
6370
     * Older Windows and Samba releases return
6371
     * NT_STATUS_FILE_CLOSED.
6372
     */
6373
0
    tevent_req_done(req);
6374
0
    return;
6375
0
  }
6376
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_DEVICE_REQUEST)) {
6377
    /*
6378
     * The response was signed, but not supported
6379
     *
6380
     * This is returned by the NTVFS based Samba 4.x file server
6381
     * for file shares.
6382
     */
6383
0
    tevent_req_done(req);
6384
0
    return;
6385
0
  }
6386
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_FS_DRIVER_REQUIRED)) {
6387
    /*
6388
     * The response was signed, but not supported
6389
     *
6390
     * This is returned by the NTVFS based Samba 4.x file server
6391
     * for ipc shares.
6392
     */
6393
0
    tevent_req_done(req);
6394
0
    return;
6395
0
  }
6396
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
6397
    /*
6398
     * The response was signed, but not supported
6399
     *
6400
     * This might be returned by older Windows versions or by
6401
     * NetApp SMB server implementations.
6402
     *
6403
     * See
6404
     *
6405
     * https://blogs.msdn.microsoft.com/openspecification/2012/06/28/smb3-secure-dialect-negotiation/
6406
     *
6407
     */
6408
0
    tevent_req_done(req);
6409
0
    return;
6410
0
  }
6411
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
6412
    /*
6413
     * The response was signed, but not supported
6414
     *
6415
     * This might be returned by NetApp Ontap 7.3.7 SMB server
6416
     * implementations.
6417
     *
6418
     * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14607
6419
     *
6420
     */
6421
0
    tevent_req_done(req);
6422
0
    return;
6423
0
  }
6424
0
  if (tevent_req_nterror(req, status)) {
6425
0
    return;
6426
0
  }
6427
6428
0
  if (state->out_output_buffer.length != 24) {
6429
0
    tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
6430
0
    return;
6431
0
  }
6432
6433
0
  buf = state->out_output_buffer.data;
6434
6435
0
  capabilities = IVAL(buf, 0);
6436
0
  guid_blob = data_blob_const(buf + 4, 16);
6437
0
  status = GUID_from_data_blob(&guid_blob, &server_guid);
6438
0
  if (tevent_req_nterror(req, status)) {
6439
0
    return;
6440
0
  }
6441
0
  security_mode = CVAL(buf, 20);
6442
0
  dialect = SVAL(buf, 22);
6443
6444
0
  if (capabilities != state->conn->smb2.server.capabilities) {
6445
0
    tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
6446
0
    return;
6447
0
  }
6448
6449
0
  if (!GUID_equal(&server_guid, &state->conn->smb2.server.guid)) {
6450
0
    tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
6451
0
    return;
6452
0
  }
6453
6454
0
  if (security_mode != state->conn->smb2.server.security_mode) {
6455
0
    tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
6456
0
    return;
6457
0
  }
6458
6459
0
  if (dialect != state->dialect) {
6460
0
    tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
6461
0
    return;
6462
0
  }
6463
6464
0
  tevent_req_done(req);
6465
0
}
6466
6467
NTSTATUS smb2cli_validate_negotiate_info_recv(struct tevent_req *req)
6468
0
{
6469
0
  return tevent_req_simple_recv_ntstatus(req);
6470
0
}
6471
6472
static int smbXcli_session_destructor(struct smbXcli_session *session)
6473
0
{
6474
0
  if (session->conn == NULL) {
6475
0
    return 0;
6476
0
  }
6477
6478
0
  DLIST_REMOVE(session->conn->sessions, session);
6479
0
  return 0;
6480
0
}
6481
6482
struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx,
6483
                 struct smbXcli_conn *conn)
6484
0
{
6485
0
  struct smbXcli_session *session;
6486
0
  NTSTATUS status;
6487
6488
0
  session = talloc_zero(mem_ctx, struct smbXcli_session);
6489
0
  if (session == NULL) {
6490
0
    return NULL;
6491
0
  }
6492
0
  session->smb2 = talloc_zero(session, struct smb2cli_session);
6493
0
  if (session->smb2 == NULL) {
6494
0
    talloc_free(session);
6495
0
    return NULL;
6496
0
  }
6497
0
  talloc_set_destructor(session, smbXcli_session_destructor);
6498
6499
0
  status = smb2_signing_key_sign_create(session->smb2,
6500
0
                conn->smb2.server.sign_algo,
6501
0
                NULL, /* no master key */
6502
0
                NULL, /* derivations */
6503
0
                &session->smb2->signing_key);
6504
0
  if (!NT_STATUS_IS_OK(status)) {
6505
0
    talloc_free(session);
6506
0
    return NULL;
6507
0
  }
6508
6509
0
  DLIST_ADD_END(conn->sessions, session);
6510
0
  session->conn = conn;
6511
6512
0
  status = smb2_signing_key_sign_create(session,
6513
0
                conn->smb2.server.sign_algo,
6514
0
                NULL, /* no master key */
6515
0
                NULL, /* derivations */
6516
0
                &session->smb2_channel.signing_key);
6517
0
  if (!NT_STATUS_IS_OK(status)) {
6518
0
    talloc_free(session);
6519
0
    return NULL;
6520
0
  }
6521
6522
0
  memcpy(session->smb2_channel.preauth_sha512,
6523
0
         conn->smb2.preauth_sha512,
6524
0
         sizeof(session->smb2_channel.preauth_sha512));
6525
6526
0
  return session;
6527
0
}
6528
6529
struct smbXcli_session *smbXcli_session_shallow_copy(TALLOC_CTX *mem_ctx,
6530
            struct smbXcli_session *src)
6531
0
{
6532
0
  struct smbXcli_session *session;
6533
0
  struct timespec ts;
6534
0
  NTTIME nt;
6535
6536
0
  session = talloc_zero(mem_ctx, struct smbXcli_session);
6537
0
  if (session == NULL) {
6538
0
    return NULL;
6539
0
  }
6540
0
  session->smb2 = talloc_zero(session, struct smb2cli_session);
6541
0
  if (session->smb2 == NULL) {
6542
0
    talloc_free(session);
6543
0
    return NULL;
6544
0
  }
6545
6546
  /*
6547
   * Note we keep a pointer to the session keys of the
6548
   * main session and rely on the caller to free the
6549
   * shallow copy first!
6550
   */
6551
0
  session->conn = src->conn;
6552
0
  *session->smb2 = *src->smb2;
6553
0
  session->smb2_channel = src->smb2_channel;
6554
0
  session->disconnect_expired = src->disconnect_expired;
6555
6556
  /*
6557
   * This is only supposed to be called in test code
6558
   * but we should not reuse nonces!
6559
   *
6560
   * Add the current timestamp as NTTIME to nonce_high
6561
   * and set nonce_low to a value we can recognize in captures.
6562
   */
6563
0
  clock_gettime_mono(&ts);
6564
0
  nt = unix_timespec_to_nt_time(ts);
6565
0
  nt &= session->smb2->nonce_high_max;
6566
0
  if (nt == session->smb2->nonce_high_max || nt < UINT8_MAX) {
6567
0
    talloc_free(session);
6568
0
    return NULL;
6569
0
  }
6570
0
  session->smb2->nonce_high += nt;
6571
0
  session->smb2->nonce_low = UINT32_MAX;
6572
6573
0
  DLIST_ADD_END(src->conn->sessions, session);
6574
0
  talloc_set_destructor(session, smbXcli_session_destructor);
6575
6576
0
  return session;
6577
0
}
6578
6579
bool smbXcli_session_is_guest(struct smbXcli_session *session)
6580
0
{
6581
0
  if (session == NULL) {
6582
0
    return false;
6583
0
  }
6584
6585
0
  if (session->conn == NULL) {
6586
0
    return false;
6587
0
  }
6588
6589
0
  if (session->conn->mandatory_signing) {
6590
0
    return false;
6591
0
  }
6592
6593
0
  if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6594
0
    if (session->smb2->session_flags & SMB2_SESSION_FLAG_IS_GUEST) {
6595
0
      return true;
6596
0
    }
6597
0
    return false;
6598
0
  }
6599
6600
0
  if (session->smb1.action & SMB_SETUP_GUEST) {
6601
0
    return true;
6602
0
  }
6603
6604
0
  return false;
6605
0
}
6606
6607
bool smbXcli_session_is_authenticated(struct smbXcli_session *session)
6608
0
{
6609
0
  const DATA_BLOB *application_key;
6610
6611
0
  if (session == NULL) {
6612
0
    return false;
6613
0
  }
6614
6615
0
  if (session->conn == NULL) {
6616
0
    return false;
6617
0
  }
6618
6619
  /*
6620
   * If we have an application key we had a session key negotiated
6621
   * at auth time.
6622
   */
6623
0
  if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6624
0
    if (!smb2_signing_key_valid(session->smb2->application_key)) {
6625
0
      return false;
6626
0
    }
6627
0
    application_key = &session->smb2->application_key->blob;
6628
0
  } else {
6629
0
    application_key = &session->smb1.application_key;
6630
0
  }
6631
6632
0
  if (application_key->length == 0) {
6633
0
    return false;
6634
0
  }
6635
6636
0
  return true;
6637
0
}
6638
6639
NTSTATUS smb2cli_session_signing_key(struct smbXcli_session *session,
6640
             TALLOC_CTX *mem_ctx,
6641
             DATA_BLOB *key)
6642
0
{
6643
0
  const struct smb2_signing_key *sig = NULL;
6644
6645
0
  if (session->conn == NULL) {
6646
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6647
0
  }
6648
6649
  /*
6650
   * Use channel signing key if there is one, otherwise fallback
6651
   * to session.
6652
   */
6653
6654
0
  if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6655
0
    sig = session->smb2_channel.signing_key;
6656
0
  } else if (smb2_signing_key_valid(session->smb2->signing_key)) {
6657
0
    sig = session->smb2->signing_key;
6658
0
  } else {
6659
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6660
0
  }
6661
6662
0
  *key = data_blob_dup_talloc_s(mem_ctx, sig->blob);
6663
0
  if (key->data == NULL) {
6664
0
    return NT_STATUS_NO_MEMORY;
6665
0
  }
6666
6667
0
  return NT_STATUS_OK;
6668
0
}
6669
6670
NTSTATUS smb2cli_session_encryption_key(struct smbXcli_session *session,
6671
          TALLOC_CTX *mem_ctx,
6672
          DATA_BLOB *key)
6673
0
{
6674
0
  if (session->conn == NULL) {
6675
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6676
0
  }
6677
6678
0
  if (session->conn->protocol < PROTOCOL_SMB3_00) {
6679
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6680
0
  }
6681
6682
0
  if (!smb2_signing_key_valid(session->smb2->encryption_key)) {
6683
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6684
0
  }
6685
6686
0
  *key = data_blob_dup_talloc_s(mem_ctx,
6687
0
              session->smb2->encryption_key->blob);
6688
0
  if (key->data == NULL) {
6689
0
    return NT_STATUS_NO_MEMORY;
6690
0
  }
6691
6692
0
  return NT_STATUS_OK;
6693
0
}
6694
6695
NTSTATUS smb2cli_session_decryption_key(struct smbXcli_session *session,
6696
          TALLOC_CTX *mem_ctx,
6697
          DATA_BLOB *key)
6698
0
{
6699
0
  if (session->conn == NULL) {
6700
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6701
0
  }
6702
6703
0
  if (session->conn->protocol < PROTOCOL_SMB3_00) {
6704
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6705
0
  }
6706
6707
0
  if (!smb2_signing_key_valid(session->smb2->decryption_key)) {
6708
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6709
0
  }
6710
6711
0
  *key = data_blob_dup_talloc_s(mem_ctx,
6712
0
              session->smb2->decryption_key->blob);
6713
0
  if (key->data == NULL) {
6714
0
    return NT_STATUS_NO_MEMORY;
6715
0
  }
6716
6717
0
  return NT_STATUS_OK;
6718
0
}
6719
6720
NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session,
6721
           TALLOC_CTX *mem_ctx,
6722
           DATA_BLOB *key)
6723
0
{
6724
0
  const DATA_BLOB *application_key;
6725
6726
0
  *key = data_blob_null;
6727
6728
0
  if (session->conn == NULL) {
6729
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6730
0
  }
6731
6732
0
  if (session->conn->protocol >= PROTOCOL_SMB2_02) {
6733
0
    if (!smb2_signing_key_valid(session->smb2->application_key)) {
6734
0
      return NT_STATUS_NO_USER_SESSION_KEY;
6735
0
    }
6736
0
    application_key = &session->smb2->application_key->blob;
6737
0
  } else {
6738
0
    application_key = &session->smb1.application_key;
6739
0
  }
6740
6741
0
  if (application_key->length == 0) {
6742
0
    return NT_STATUS_NO_USER_SESSION_KEY;
6743
0
  }
6744
6745
0
  *key = data_blob_dup_talloc_s(mem_ctx, *application_key);
6746
0
  if (key->data == NULL) {
6747
0
    return NT_STATUS_NO_MEMORY;
6748
0
  }
6749
6750
0
  return NT_STATUS_OK;
6751
0
}
6752
6753
void smbXcli_session_set_disconnect_expired(struct smbXcli_session *session)
6754
0
{
6755
0
  session->disconnect_expired = true;
6756
0
}
6757
6758
uint16_t smb1cli_session_current_id(struct smbXcli_session *session)
6759
0
{
6760
0
  return session->smb1.session_id;
6761
0
}
6762
6763
void smb1cli_session_set_id(struct smbXcli_session *session,
6764
          uint16_t session_id)
6765
0
{
6766
0
  session->smb1.session_id = session_id;
6767
0
}
6768
6769
void smb1cli_session_set_action(struct smbXcli_session *session,
6770
        uint16_t action)
6771
0
{
6772
0
  session->smb1.action = action;
6773
0
}
6774
6775
NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
6776
           const DATA_BLOB _session_key)
6777
0
{
6778
0
  struct smbXcli_conn *conn = session->conn;
6779
0
  uint8_t session_key[16];
6780
6781
0
  if (conn == NULL) {
6782
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
6783
0
  }
6784
6785
0
  if (session->smb1.application_key.length != 0) {
6786
    /*
6787
     * TODO: do not allow this...
6788
     *
6789
     * return NT_STATUS_INVALID_PARAMETER_MIX;
6790
     */
6791
0
    data_blob_clear_free(&session->smb1.application_key);
6792
0
    session->smb1.protected_key = false;
6793
0
  }
6794
6795
0
  if (_session_key.length == 0) {
6796
0
    return NT_STATUS_OK;
6797
0
  }
6798
6799
0
  ZERO_STRUCT(session_key);
6800
0
  memcpy(session_key, _session_key.data,
6801
0
         MIN(_session_key.length, sizeof(session_key)));
6802
6803
0
  session->smb1.application_key = data_blob_talloc_s(
6804
0
    session, session_key, sizeof(session_key));
6805
0
  ZERO_STRUCT(session_key);
6806
0
  if (session->smb1.application_key.data == NULL) {
6807
0
    return NT_STATUS_NO_MEMORY;
6808
0
  }
6809
6810
0
  session->smb1.protected_key = false;
6811
6812
0
  return NT_STATUS_OK;
6813
0
}
6814
6815
NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session)
6816
0
{
6817
0
  NTSTATUS status;
6818
6819
0
  if (session->smb1.protected_key) {
6820
    /* already protected */
6821
0
    return NT_STATUS_OK;
6822
0
  }
6823
6824
0
  if (session->smb1.application_key.length != 16) {
6825
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
6826
0
  }
6827
6828
0
  status = smb1_key_derivation(session->smb1.application_key.data,
6829
0
            session->smb1.application_key.length,
6830
0
            session->smb1.application_key.data);
6831
0
  if (!NT_STATUS_IS_OK(status)) {
6832
0
    return status;
6833
0
  }
6834
6835
0
  session->smb1.protected_key = true;
6836
6837
0
  return NT_STATUS_OK;
6838
0
}
6839
6840
uint8_t smb2cli_session_security_mode(struct smbXcli_session *session)
6841
0
{
6842
0
  struct smbXcli_conn *conn = session->conn;
6843
0
  uint8_t security_mode = 0;
6844
6845
0
  if (conn == NULL) {
6846
0
    return security_mode;
6847
0
  }
6848
6849
0
  security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
6850
0
  if (conn->mandatory_signing) {
6851
0
    security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
6852
0
  }
6853
0
  if (session->smb2->should_sign) {
6854
0
    security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
6855
0
  }
6856
6857
0
  return security_mode;
6858
0
}
6859
6860
uint64_t smb2cli_session_current_id(struct smbXcli_session *session)
6861
0
{
6862
0
  return session->smb2->session_id;
6863
0
}
6864
6865
uint16_t smb2cli_session_get_flags(struct smbXcli_session *session)
6866
0
{
6867
0
  return session->smb2->session_flags;
6868
0
}
6869
6870
void smb2cli_session_set_id_and_flags(struct smbXcli_session *session,
6871
              uint64_t session_id,
6872
              uint16_t session_flags)
6873
0
{
6874
0
  session->smb2->session_id = session_id;
6875
0
  session->smb2->session_flags = session_flags;
6876
0
}
6877
6878
void smb2cli_session_increment_channel_sequence(struct smbXcli_session *session)
6879
0
{
6880
0
  session->smb2->channel_sequence += 1;
6881
0
}
6882
6883
uint16_t smb2cli_session_reset_channel_sequence(struct smbXcli_session *session,
6884
            uint16_t channel_sequence)
6885
0
{
6886
0
  uint16_t prev_cs;
6887
6888
0
  prev_cs = session->smb2->channel_sequence;
6889
0
  session->smb2->channel_sequence = channel_sequence;
6890
6891
0
  return prev_cs;
6892
0
}
6893
6894
uint16_t smb2cli_session_current_channel_sequence(struct smbXcli_session *session)
6895
0
{
6896
0
  return session->smb2->channel_sequence;
6897
0
}
6898
6899
void smb2cli_session_start_replay(struct smbXcli_session *session)
6900
0
{
6901
0
  session->smb2->replay_active = true;
6902
0
}
6903
6904
void smb2cli_session_stop_replay(struct smbXcli_session *session)
6905
0
{
6906
0
  session->smb2->replay_active = false;
6907
0
}
6908
6909
void smb2cli_session_require_signed_response(struct smbXcli_session *session,
6910
               bool require_signed_response)
6911
0
{
6912
0
  session->smb2->require_signed_response = require_signed_response;
6913
0
}
6914
6915
void smb2cli_session_torture_anonymous_signing(struct smbXcli_session *session,
6916
                 bool anonymous_signing)
6917
0
{
6918
0
  session->smb2->anonymous_signing = anonymous_signing;
6919
0
}
6920
6921
void smb2cli_session_torture_anonymous_encryption(struct smbXcli_session *session,
6922
              bool anonymous_encryption)
6923
0
{
6924
0
  session->smb2->anonymous_encryption = anonymous_encryption;
6925
0
}
6926
6927
void smb2cli_session_torture_no_signing_disconnect(struct smbXcli_session *session)
6928
0
{
6929
0
  session->smb2->no_signing_disconnect = true;
6930
0
}
6931
6932
NTSTATUS smb2cli_session_update_preauth(struct smbXcli_session *session,
6933
          const struct iovec *iov)
6934
0
{
6935
0
  gnutls_hash_hd_t hash_hnd = NULL;
6936
0
  size_t i;
6937
0
  int rc;
6938
6939
0
  if (session->conn == NULL) {
6940
0
    return NT_STATUS_INTERNAL_ERROR;
6941
0
  }
6942
6943
0
  if (session->conn->protocol < PROTOCOL_SMB3_11) {
6944
0
    return NT_STATUS_OK;
6945
0
  }
6946
6947
0
  if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
6948
0
    return NT_STATUS_OK;
6949
0
  }
6950
6951
0
  rc = gnutls_hash_init(&hash_hnd,
6952
0
            GNUTLS_DIG_SHA512);
6953
0
  if (rc < 0) {
6954
0
    return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6955
0
  }
6956
6957
0
  rc = gnutls_hash(hash_hnd,
6958
0
       session->smb2_channel.preauth_sha512,
6959
0
       sizeof(session->smb2_channel.preauth_sha512));
6960
0
  if (rc < 0) {
6961
0
    gnutls_hash_deinit(hash_hnd, NULL);
6962
0
    return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6963
0
  }
6964
0
  for (i = 0; i < 3; i++) {
6965
0
    rc = gnutls_hash(hash_hnd,
6966
0
         iov[i].iov_base,
6967
0
         iov[i].iov_len);
6968
0
    if (rc < 0) {
6969
0
      gnutls_hash_deinit(hash_hnd, NULL);
6970
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
6971
0
    }
6972
0
  }
6973
0
  gnutls_hash_deinit(hash_hnd, session->smb2_channel.preauth_sha512);
6974
6975
0
  return NT_STATUS_OK;
6976
0
}
6977
6978
NTSTATUS smb2cli_session_set_session_key(struct smbXcli_session *session,
6979
           const DATA_BLOB _session_key,
6980
           const struct iovec *recv_iov)
6981
0
{
6982
0
  struct smbXcli_conn *conn = session->conn;
6983
0
  uint16_t no_sign_flags = 0;
6984
0
  bool check_signature = true;
6985
0
  uint32_t hdr_flags;
6986
0
  NTSTATUS status;
6987
0
  struct smb2_signing_derivations derivations = {
6988
0
    .signing = NULL,
6989
0
  };
6990
0
  DATA_BLOB preauth_hash = data_blob_null;
6991
0
  size_t nonce_size = 0;
6992
6993
0
  if (conn == NULL) {
6994
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
6995
0
  }
6996
6997
0
  if (recv_iov[0].iov_len != SMB2_HDR_BODY) {
6998
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
6999
0
  }
7000
7001
0
  if (!conn->mandatory_signing) {
7002
    /*
7003
     * only allow guest sessions without
7004
     * mandatory signing.
7005
     *
7006
     * If we try an authentication with username != ""
7007
     * and the server let us in without verifying the
7008
     * password we don't have a negotiated session key
7009
     * for signing.
7010
     */
7011
0
    no_sign_flags = SMB2_SESSION_FLAG_IS_GUEST;
7012
0
  }
7013
7014
0
  if (session->smb2->session_flags & no_sign_flags) {
7015
0
    session->smb2->should_sign = false;
7016
0
    return NT_STATUS_OK;
7017
0
  }
7018
7019
0
  if (smb2_signing_key_valid(session->smb2->signing_key)) {
7020
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
7021
0
  }
7022
7023
0
  if (conn->protocol >= PROTOCOL_SMB3_11) {
7024
0
    preauth_hash = data_blob_const(session->smb2_channel.preauth_sha512,
7025
0
        sizeof(session->smb2_channel.preauth_sha512));
7026
0
  }
7027
7028
0
  smb2_signing_derivations_fill_const_stack(&derivations,
7029
0
              conn->protocol,
7030
0
              preauth_hash);
7031
7032
0
  if (session->smb2->anonymous_encryption) {
7033
0
    goto skip_signing_key;
7034
0
  }
7035
7036
0
  status = smb2_signing_key_sign_create(session->smb2,
7037
0
                conn->smb2.server.sign_algo,
7038
0
                &_session_key,
7039
0
                derivations.signing,
7040
0
                &session->smb2->signing_key);
7041
0
  if (!NT_STATUS_IS_OK(status)) {
7042
0
    return status;
7043
0
  }
7044
7045
0
  if (session->smb2->anonymous_signing) {
7046
    /*
7047
     * skip encryption and application keys
7048
     */
7049
0
    goto skip_application_key;
7050
0
  }
7051
7052
0
skip_signing_key:
7053
7054
0
  status = smb2_signing_key_cipher_create(session->smb2,
7055
0
            conn->smb2.server.cipher,
7056
0
            &_session_key,
7057
0
            derivations.cipher_c2s,
7058
0
            &session->smb2->encryption_key);
7059
0
  if (!NT_STATUS_IS_OK(status)) {
7060
0
    return status;
7061
0
  }
7062
7063
0
  status = smb2_signing_key_cipher_create(session->smb2,
7064
0
            conn->smb2.server.cipher,
7065
0
            &_session_key,
7066
0
            derivations.cipher_s2c,
7067
0
            &session->smb2->decryption_key);
7068
0
  if (!NT_STATUS_IS_OK(status)) {
7069
0
    return status;
7070
0
  }
7071
7072
0
  if (session->smb2->anonymous_encryption) {
7073
0
    goto skip_application_key;
7074
0
  }
7075
7076
0
  status = smb2_signing_key_sign_create(session->smb2,
7077
0
                conn->smb2.server.sign_algo,
7078
0
                &_session_key,
7079
0
                derivations.application,
7080
0
                &session->smb2->application_key);
7081
0
  if (!NT_STATUS_IS_OK(status)) {
7082
0
    return status;
7083
0
  }
7084
7085
0
skip_application_key:
7086
7087
0
  status = smb2_signing_key_copy(session,
7088
0
               session->smb2->signing_key,
7089
0
               &session->smb2_channel.signing_key);
7090
0
  if (!NT_STATUS_IS_OK(status)) {
7091
0
    return status;
7092
0
  }
7093
7094
0
  check_signature = conn->mandatory_signing;
7095
7096
0
  if (conn->protocol >= PROTOCOL_SMB3_11) {
7097
0
    check_signature = true;
7098
0
  }
7099
7100
0
  if (session->smb2->anonymous_signing) {
7101
0
    check_signature = false;
7102
0
  }
7103
7104
0
  if (session->smb2->anonymous_encryption) {
7105
0
    check_signature = false;
7106
0
  }
7107
7108
0
  hdr_flags = IVAL(recv_iov[0].iov_base, SMB2_HDR_FLAGS);
7109
0
  if (hdr_flags & SMB2_HDR_FLAG_SIGNED) {
7110
    /*
7111
     * Sadly some vendors don't sign the
7112
     * final SMB2 session setup response
7113
     *
7114
     * At least Windows and Samba are always doing this
7115
     * if there's a session key available.
7116
     *
7117
     * We only check the signature if it's mandatory
7118
     * or SMB2_HDR_FLAG_SIGNED is provided.
7119
     */
7120
0
    check_signature = true;
7121
0
  }
7122
7123
0
  if (check_signature) {
7124
0
    status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
7125
0
            recv_iov, 3);
7126
0
    if (!NT_STATUS_IS_OK(status)) {
7127
0
      return status;
7128
0
    }
7129
0
  }
7130
7131
0
  session->smb2->should_sign = false;
7132
0
  session->smb2->should_encrypt = false;
7133
7134
0
  if (conn->desire_signing) {
7135
0
    session->smb2->should_sign = true;
7136
0
  }
7137
7138
0
  if (conn->smb2.server.security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) {
7139
0
    session->smb2->should_sign = true;
7140
0
  }
7141
7142
0
  if (session->smb2->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) {
7143
0
    session->smb2->should_encrypt = true;
7144
0
  }
7145
7146
0
  if (conn->protocol < PROTOCOL_SMB3_00) {
7147
0
    session->smb2->should_encrypt = false;
7148
0
  }
7149
7150
0
  if (conn->smb2.server.cipher == 0) {
7151
0
    session->smb2->should_encrypt = false;
7152
0
  }
7153
7154
0
  if (session->smb2->anonymous_signing) {
7155
0
    session->smb2->should_sign = true;
7156
0
  }
7157
7158
0
  if (session->smb2->anonymous_encryption) {
7159
0
    session->smb2->should_encrypt = true;
7160
0
    session->smb2->should_sign = false;
7161
0
  }
7162
7163
  /*
7164
   * CCM and GCM algorithms must never have their
7165
   * nonce wrap, or the security of the whole
7166
   * communication and the keys is destroyed.
7167
   * We must drop the connection once we have
7168
   * transferred too much data.
7169
   *
7170
   * NOTE: We assume nonces greater than 8 bytes.
7171
   */
7172
0
  generate_nonce_buffer((uint8_t *)&session->smb2->nonce_high_random,
7173
0
            sizeof(session->smb2->nonce_high_random));
7174
0
  switch (conn->smb2.server.cipher) {
7175
0
  case SMB2_ENCRYPTION_AES128_CCM:
7176
0
    nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
7177
0
    break;
7178
0
  case SMB2_ENCRYPTION_AES128_GCM:
7179
0
    nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_128_GCM);
7180
0
    break;
7181
0
  case SMB2_ENCRYPTION_AES256_CCM:
7182
0
    nonce_size = SMB2_AES_128_CCM_NONCE_SIZE;
7183
0
    break;
7184
0
  case SMB2_ENCRYPTION_AES256_GCM:
7185
0
    nonce_size = gnutls_cipher_get_iv_size(GNUTLS_CIPHER_AES_256_GCM);
7186
0
    break;
7187
0
  default:
7188
0
    nonce_size = 0;
7189
0
    break;
7190
0
  }
7191
0
  session->smb2->nonce_high_max = SMB2_NONCE_HIGH_MAX(nonce_size);
7192
0
  session->smb2->nonce_high = 0;
7193
0
  session->smb2->nonce_low = 0;
7194
7195
0
  return NT_STATUS_OK;
7196
0
}
7197
7198
NTSTATUS smb2cli_session_create_channel(TALLOC_CTX *mem_ctx,
7199
          struct smbXcli_session *session1,
7200
          struct smbXcli_conn *conn,
7201
          struct smbXcli_session **_session2)
7202
0
{
7203
0
  struct smbXcli_session *session2;
7204
0
  NTSTATUS status;
7205
7206
0
  if (!smb2_signing_key_valid(session1->smb2->signing_key)) {
7207
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
7208
0
  }
7209
7210
0
  if (conn == NULL) {
7211
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
7212
0
  }
7213
7214
0
  session2 = talloc_zero(mem_ctx, struct smbXcli_session);
7215
0
  if (session2 == NULL) {
7216
0
    return NT_STATUS_NO_MEMORY;
7217
0
  }
7218
0
  session2->smb2 = talloc_reference(session2, session1->smb2);
7219
0
  if (session2->smb2 == NULL) {
7220
0
    talloc_free(session2);
7221
0
    return NT_STATUS_NO_MEMORY;
7222
0
  }
7223
7224
0
  talloc_set_destructor(session2, smbXcli_session_destructor);
7225
0
  DLIST_ADD_END(conn->sessions, session2);
7226
0
  session2->conn = conn;
7227
7228
0
  status = smb2_signing_key_sign_create(session2,
7229
0
                conn->smb2.server.sign_algo,
7230
0
                NULL, /* no master key */
7231
0
                NULL, /* derivations */
7232
0
                &session2->smb2_channel.signing_key);
7233
0
  if (!NT_STATUS_IS_OK(status)) {
7234
0
    talloc_free(session2);
7235
0
    return NT_STATUS_NO_MEMORY;
7236
0
  }
7237
7238
0
  memcpy(session2->smb2_channel.preauth_sha512,
7239
0
         conn->smb2.preauth_sha512,
7240
0
         sizeof(session2->smb2_channel.preauth_sha512));
7241
7242
0
  *_session2 = session2;
7243
0
  return NT_STATUS_OK;
7244
0
}
7245
7246
NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
7247
           const DATA_BLOB _channel_key,
7248
           const struct iovec *recv_iov)
7249
0
{
7250
0
  struct smbXcli_conn *conn = session->conn;
7251
0
  uint8_t channel_key[16];
7252
0
  NTSTATUS status;
7253
0
  struct _derivation {
7254
0
    DATA_BLOB label;
7255
0
    DATA_BLOB context;
7256
0
  };
7257
0
  struct {
7258
0
    struct _derivation signing;
7259
0
  } derivation = {
7260
0
    .signing.label.length = 0,
7261
0
  };
7262
7263
0
  if (conn == NULL) {
7264
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
7265
0
  }
7266
7267
0
  if (smb2_signing_key_valid(session->smb2_channel.signing_key)) {
7268
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
7269
0
  }
7270
7271
0
  if (conn->protocol >= PROTOCOL_SMB3_11) {
7272
0
    struct _derivation *d;
7273
0
    DATA_BLOB p;
7274
7275
0
    p = data_blob_const(session->smb2_channel.preauth_sha512,
7276
0
        sizeof(session->smb2_channel.preauth_sha512));
7277
7278
0
    d = &derivation.signing;
7279
0
    d->label = data_blob_string_const_null("SMBSigningKey");
7280
0
    d->context = p;
7281
0
  } else if (conn->protocol >= PROTOCOL_SMB3_00) {
7282
0
    struct _derivation *d;
7283
7284
0
    d = &derivation.signing;
7285
0
    d->label = data_blob_string_const_null("SMB2AESCMAC");
7286
0
    d->context = data_blob_string_const_null("SmbSign");
7287
0
  }
7288
7289
0
  ZERO_STRUCT(channel_key);
7290
0
  memcpy(channel_key, _channel_key.data,
7291
0
         MIN(_channel_key.length, sizeof(channel_key)));
7292
7293
0
  session->smb2_channel.signing_key->blob = data_blob_talloc_s(
7294
0
    session->smb2_channel.signing_key,
7295
0
    channel_key,
7296
0
    sizeof(channel_key));
7297
0
  if (!smb2_signing_key_valid(session->smb2_channel.signing_key)) {
7298
0
    ZERO_STRUCT(channel_key);
7299
0
    return NT_STATUS_NO_MEMORY;
7300
0
  }
7301
7302
0
  if (conn->protocol >= PROTOCOL_SMB3_00) {
7303
0
    struct _derivation *d = &derivation.signing;
7304
7305
0
    status = samba_gnutls_sp800_108_derive_key(
7306
0
      channel_key,
7307
0
      sizeof(channel_key),
7308
0
      NULL,
7309
0
      0,
7310
0
      d->label.data,
7311
0
      d->label.length,
7312
0
      d->context.data,
7313
0
      d->context.length,
7314
0
      GNUTLS_MAC_SHA256,
7315
0
      session->smb2_channel.signing_key->blob.data,
7316
0
      session->smb2_channel.signing_key->blob.length);
7317
0
    if (!NT_STATUS_IS_OK(status)) {
7318
0
      return status;
7319
0
    }
7320
0
  }
7321
0
  ZERO_STRUCT(channel_key);
7322
7323
0
  status = smb2_signing_check_pdu(session->smb2_channel.signing_key,
7324
0
          recv_iov, 3);
7325
0
  if (!NT_STATUS_IS_OK(status)) {
7326
0
    return status;
7327
0
  }
7328
7329
0
  return NT_STATUS_OK;
7330
0
}
7331
7332
NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
7333
0
{
7334
0
  if (session->smb2->anonymous_signing) {
7335
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
7336
0
  }
7337
7338
0
  if (session->smb2->anonymous_encryption) {
7339
0
    SMB_ASSERT(session->smb2->should_encrypt);
7340
0
    SMB_ASSERT(!session->smb2->should_sign);
7341
0
    return NT_STATUS_OK;
7342
0
  }
7343
7344
0
  if (!session->smb2->should_sign) {
7345
    /*
7346
     * We need required signing on the session
7347
     * in order to prevent man in the middle attacks.
7348
     */
7349
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
7350
0
  }
7351
7352
0
  if (session->smb2->should_encrypt) {
7353
0
    return NT_STATUS_OK;
7354
0
  }
7355
7356
0
  if (session->conn->protocol < PROTOCOL_SMB3_00) {
7357
0
    return NT_STATUS_NOT_SUPPORTED;
7358
0
  }
7359
7360
0
  if (session->conn->smb2.server.cipher == 0) {
7361
0
    return NT_STATUS_NOT_SUPPORTED;
7362
0
  }
7363
7364
0
  if (!smb2_signing_key_valid(session->smb2->signing_key)) {
7365
0
    return NT_STATUS_NOT_SUPPORTED;
7366
0
  }
7367
0
  session->smb2->should_encrypt = true;
7368
0
  return NT_STATUS_OK;
7369
0
}
7370
7371
uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session)
7372
0
{
7373
0
  if (session->conn->protocol < PROTOCOL_SMB3_00) {
7374
0
    return 0;
7375
0
  }
7376
7377
0
  if (!session->smb2->should_encrypt) {
7378
0
    return 0;
7379
0
  }
7380
7381
0
  return session->conn->smb2.server.cipher;
7382
0
}
7383
7384
struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
7385
0
{
7386
0
  struct smbXcli_tcon *tcon;
7387
7388
0
  tcon = talloc_zero(mem_ctx, struct smbXcli_tcon);
7389
0
  if (tcon == NULL) {
7390
0
    return NULL;
7391
0
  }
7392
7393
0
  return tcon;
7394
0
}
7395
7396
/*
7397
 * Return a deep structure copy of a struct smbXcli_tcon *
7398
 */
7399
7400
struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
7401
        const struct smbXcli_tcon *tcon_in)
7402
0
{
7403
0
  struct smbXcli_tcon *tcon;
7404
7405
0
  tcon = talloc_memdup(mem_ctx, tcon_in, sizeof(struct smbXcli_tcon));
7406
0
  if (tcon == NULL) {
7407
0
    return NULL;
7408
0
  }
7409
7410
  /* Deal with the SMB1 strings. */
7411
0
  if (tcon_in->smb1.service != NULL) {
7412
0
    tcon->smb1.service = talloc_strdup(tcon, tcon_in->smb1.service);
7413
0
    if (tcon->smb1.service == NULL) {
7414
0
      TALLOC_FREE(tcon);
7415
0
      return NULL;
7416
0
    }
7417
0
  }
7418
0
  if (tcon->smb1.fs_type != NULL) {
7419
0
    tcon->smb1.fs_type = talloc_strdup(tcon, tcon_in->smb1.fs_type);
7420
0
    if (tcon->smb1.fs_type == NULL) {
7421
0
      TALLOC_FREE(tcon);
7422
0
      return NULL;
7423
0
    }
7424
0
  }
7425
0
  return tcon;
7426
0
}
7427
7428
void smbXcli_tcon_set_fs_attributes(struct smbXcli_tcon *tcon,
7429
            uint32_t fs_attributes)
7430
0
{
7431
0
  tcon->fs_attributes = fs_attributes;
7432
0
}
7433
7434
uint32_t smbXcli_tcon_get_fs_attributes(struct smbXcli_tcon *tcon)
7435
0
{
7436
0
  return tcon->fs_attributes;
7437
0
}
7438
7439
bool smbXcli_tcon_is_dfs_share(struct smbXcli_tcon *tcon)
7440
0
{
7441
0
  if (tcon == NULL) {
7442
0
    return false;
7443
0
  }
7444
7445
0
  if (tcon->is_smb1) {
7446
0
    if (tcon->smb1.optional_support & SMB_SHARE_IN_DFS) {
7447
0
      return true;
7448
0
    }
7449
7450
0
    return false;
7451
0
  }
7452
7453
0
  if (tcon->smb2.capabilities & SMB2_SHARE_CAP_DFS) {
7454
0
    return true;
7455
0
  }
7456
7457
0
  return false;
7458
0
}
7459
7460
uint16_t smb1cli_tcon_current_id(struct smbXcli_tcon *tcon)
7461
0
{
7462
0
  return tcon->smb1.tcon_id;
7463
0
}
7464
7465
void smb1cli_tcon_set_id(struct smbXcli_tcon *tcon, uint16_t tcon_id)
7466
0
{
7467
0
  tcon->is_smb1 = true;
7468
0
  tcon->smb1.tcon_id = tcon_id;
7469
0
}
7470
7471
bool smb1cli_tcon_set_values(struct smbXcli_tcon *tcon,
7472
           uint16_t tcon_id,
7473
           uint16_t optional_support,
7474
           uint32_t maximal_access,
7475
           uint32_t guest_maximal_access,
7476
           const char *service,
7477
           const char *fs_type)
7478
0
{
7479
0
  tcon->is_smb1 = true;
7480
0
  tcon->fs_attributes = 0;
7481
0
  tcon->smb1.tcon_id = tcon_id;
7482
0
  tcon->smb1.optional_support = optional_support;
7483
0
  tcon->smb1.maximal_access = maximal_access;
7484
0
  tcon->smb1.guest_maximal_access = guest_maximal_access;
7485
7486
0
  TALLOC_FREE(tcon->smb1.service);
7487
0
  tcon->smb1.service = talloc_strdup(tcon, service);
7488
0
  if (service != NULL && tcon->smb1.service == NULL) {
7489
0
    return false;
7490
0
  }
7491
7492
0
  TALLOC_FREE(tcon->smb1.fs_type);
7493
0
  tcon->smb1.fs_type = talloc_strdup(tcon, fs_type);
7494
0
  if (fs_type != NULL && tcon->smb1.fs_type == NULL) {
7495
0
    return false;
7496
0
  }
7497
7498
0
  return true;
7499
0
}
7500
7501
uint32_t smb2cli_tcon_current_id(struct smbXcli_tcon *tcon)
7502
0
{
7503
0
  return tcon->smb2.tcon_id;
7504
0
}
7505
7506
void smb2cli_tcon_set_id(struct smbXcli_tcon *tcon, uint32_t tcon_id)
7507
0
{
7508
0
  tcon->smb2.tcon_id = tcon_id;
7509
0
}
7510
7511
uint32_t smb2cli_tcon_capabilities(struct smbXcli_tcon *tcon)
7512
0
{
7513
0
  return tcon->smb2.capabilities;
7514
0
}
7515
7516
uint32_t smb2cli_tcon_flags(struct smbXcli_tcon *tcon)
7517
0
{
7518
0
  return tcon->smb2.flags;
7519
0
}
7520
7521
void smb2cli_tcon_set_values(struct smbXcli_tcon *tcon,
7522
           struct smbXcli_session *session,
7523
           uint32_t tcon_id,
7524
           uint8_t type,
7525
           uint32_t flags,
7526
           uint32_t capabilities,
7527
           uint32_t maximal_access)
7528
0
{
7529
0
  tcon->is_smb1 = false;
7530
0
  tcon->fs_attributes = 0;
7531
0
  tcon->smb2.tcon_id = tcon_id;
7532
0
  tcon->smb2.type = type;
7533
0
  tcon->smb2.flags = flags;
7534
0
  tcon->smb2.capabilities = capabilities;
7535
0
  tcon->smb2.maximal_access = maximal_access;
7536
7537
0
  tcon->smb2.should_sign = false;
7538
0
  tcon->smb2.should_encrypt = false;
7539
7540
0
  if (session == NULL) {
7541
0
    return;
7542
0
  }
7543
7544
0
  tcon->smb2.should_sign = session->smb2->should_sign;
7545
0
  tcon->smb2.should_encrypt = session->smb2->should_encrypt;
7546
7547
0
  if (flags & SMB2_SHAREFLAG_ENCRYPT_DATA) {
7548
0
    tcon->smb2.should_encrypt = true;
7549
0
  }
7550
0
}
7551
7552
void smb2cli_tcon_should_sign(struct smbXcli_tcon *tcon,
7553
            bool should_sign)
7554
0
{
7555
0
  tcon->smb2.should_sign = should_sign;
7556
0
}
7557
7558
bool smb2cli_tcon_is_signing_on(struct smbXcli_tcon *tcon)
7559
0
{
7560
0
  if (tcon->smb2.should_encrypt) {
7561
0
    return true;
7562
0
  }
7563
7564
0
  return tcon->smb2.should_sign;
7565
0
}
7566
7567
void smb2cli_tcon_should_encrypt(struct smbXcli_tcon *tcon,
7568
         bool should_encrypt)
7569
0
{
7570
0
  tcon->smb2.should_encrypt = should_encrypt;
7571
0
}
7572
7573
bool smb2cli_tcon_is_encryption_on(struct smbXcli_tcon *tcon)
7574
0
{
7575
0
  return tcon->smb2.should_encrypt;
7576
0
}
7577
7578
void smb2cli_conn_set_mid(struct smbXcli_conn *conn, uint64_t mid)
7579
0
{
7580
0
  conn->smb2.mid = mid;
7581
0
}
7582
7583
uint64_t smb2cli_conn_get_mid(struct smbXcli_conn *conn)
7584
0
{
7585
0
  return conn->smb2.mid;
7586
0
}
7587
7588
NTSTATUS smb2cli_parse_dyn_buffer(uint32_t dyn_offset,
7589
          const DATA_BLOB dyn_buffer,
7590
          uint32_t min_offset,
7591
          uint32_t buffer_offset,
7592
          uint32_t buffer_length,
7593
          uint32_t max_length,
7594
          uint32_t *next_offset,
7595
          DATA_BLOB *buffer)
7596
0
{
7597
0
  uint32_t offset;
7598
0
  bool oob;
7599
7600
0
  *buffer = data_blob_null;
7601
0
  *next_offset = dyn_offset;
7602
7603
0
  if (buffer_offset == 0) {
7604
    /*
7605
     * If the offset is 0, we better ignore
7606
     * the buffer_length field.
7607
     */
7608
0
    return NT_STATUS_OK;
7609
0
  }
7610
7611
0
  if (buffer_length == 0) {
7612
    /*
7613
     * If the length is 0, we better ignore
7614
     * the buffer_offset field.
7615
     */
7616
0
    return NT_STATUS_OK;
7617
0
  }
7618
7619
0
  if ((buffer_offset % 8) != 0) {
7620
    /*
7621
     * The offset needs to be 8 byte aligned.
7622
     */
7623
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
7624
0
  }
7625
7626
  /*
7627
   * We used to enforce buffer_offset to be
7628
   * an exact match of the expected minimum,
7629
   * but the NetApp Ontap 7.3.7 SMB server
7630
   * gets the padding wrong and aligns the
7631
   * input_buffer_offset by a value of 8.
7632
   *
7633
   * So we just enforce that the offset is
7634
   * not lower than the expected value.
7635
   */
7636
0
  SMB_ASSERT(min_offset >= dyn_offset);
7637
0
  if (buffer_offset < min_offset) {
7638
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
7639
0
  }
7640
7641
  /*
7642
   * Make [input|output]_buffer_offset relative to "dyn_buffer"
7643
   */
7644
0
  offset = buffer_offset - dyn_offset;
7645
0
  oob = smb_buffer_oob(dyn_buffer.length, offset, buffer_length);
7646
0
  if (oob) {
7647
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
7648
0
  }
7649
7650
  /*
7651
   * Give the caller a hint what we consumed,
7652
   * the caller may need to add possible padding.
7653
   */
7654
0
  *next_offset = buffer_offset + buffer_length;
7655
7656
0
  if (max_length == 0) {
7657
    /*
7658
     * If max_input_length is 0 we ignore the
7659
     * input_buffer_length, because Windows 2008 echos the
7660
     * DCERPC request from the requested input_buffer to
7661
     * the response input_buffer.
7662
     *
7663
     * We just use the same logic also for max_output_length...
7664
     */
7665
0
    buffer_length = 0;
7666
0
  }
7667
7668
0
  if (buffer_length > max_length) {
7669
0
    return NT_STATUS_INVALID_NETWORK_RESPONSE;
7670
0
  }
7671
7672
0
  *buffer = (DATA_BLOB) {
7673
0
    .data = dyn_buffer.data + offset,
7674
0
    .length = buffer_length,
7675
0
  };
7676
0
  return NT_STATUS_OK;
7677
0
}
7678
7679
struct smbXcli_session_dump_cp_state {
7680
  char *s;
7681
};
7682
7683
static void smbXcli_session_dump_keys_cb(const char *buf, void *private_data)
7684
0
{
7685
0
  struct smbXcli_session_dump_cp_state *state = private_data;
7686
7687
0
  talloc_asprintf_addbuf(&state->s, "%s", buf);
7688
0
}
7689
7690
void smbXcli_session_dump_keys(uint64_t session_id,
7691
             DATA_BLOB *session_key,
7692
             uint16_t signing_algo,
7693
             DATA_BLOB *signing_key,
7694
             DATA_BLOB *application_key,
7695
             DATA_BLOB *encryption_key,
7696
             DATA_BLOB *decryption_key,
7697
             const char *wireshark_keyfile)
7698
0
{
7699
0
  struct smbXcli_session_dump_cp_state state = {
7700
0
    .s = talloc_strdup(talloc_tos(), ""),
7701
0
  };
7702
0
  DATA_BLOB sidb = {
7703
0
    .data = (uint8_t *)&session_id, .length = sizeof(session_id)
7704
0
  };
7705
0
  char *line = NULL;
7706
0
  int fd = -1;
7707
0
  ssize_t written;
7708
7709
0
  talloc_asprintf_addbuf(&state.s, "debug encryption: dumping generated session keys\n");
7710
0
  talloc_asprintf_addbuf(&state.s, "Session Id    ");
7711
0
  dump_data_cb((uint8_t*)&session_id,
7712
0
         sizeof(session_id),
7713
0
         false,
7714
0
         smbXcli_session_dump_keys_cb,
7715
0
         &state);
7716
0
  talloc_asprintf_addbuf(&state.s, "Session Key   ");
7717
0
  dump_data_cb(session_key->data,
7718
0
         session_key->length,
7719
0
         false,
7720
0
         smbXcli_session_dump_keys_cb,
7721
0
         &state);
7722
0
  talloc_asprintf_addbuf(&state.s, "Signing Algo: %u\n", signing_algo);
7723
0
  talloc_asprintf_addbuf(&state.s, "Signing Key   ");
7724
0
  dump_data_cb(signing_key->data,
7725
0
         signing_key->length,
7726
0
         false,
7727
0
         smbXcli_session_dump_keys_cb,
7728
0
         &state);
7729
0
  talloc_asprintf_addbuf(&state.s, "App Key       ");
7730
0
  dump_data_cb(application_key->data,
7731
0
         application_key->length,
7732
0
         false,
7733
0
         smbXcli_session_dump_keys_cb,
7734
0
         &state);
7735
7736
  /* In client code, ServerIn is the encryption key */
7737
7738
0
  talloc_asprintf_addbuf(&state.s, "ServerIn Key  ");
7739
0
  dump_data_cb(encryption_key->data,
7740
0
         encryption_key->length,
7741
0
         false,
7742
0
         smbXcli_session_dump_keys_cb,
7743
0
         &state);
7744
0
  talloc_asprintf_addbuf(&state.s, "ServerOut Key ");
7745
0
  dump_data_cb(decryption_key->data,
7746
0
         decryption_key->length,
7747
0
         false,
7748
0
         smbXcli_session_dump_keys_cb,
7749
0
         &state);
7750
7751
0
  talloc_asprintf_addbuf(&state.s, "Wireshark configuration line:\n");
7752
0
  line = talloc_asprintf(
7753
0
    talloc_tos(),
7754
0
    "%s,%s,%s,%s\n",
7755
0
    data_blob_hex_string_lower(state.s, &sidb),
7756
0
    data_blob_hex_string_lower(state.s, session_key),
7757
0
    data_blob_hex_string_lower(state.s, decryption_key),
7758
0
    data_blob_hex_string_lower(state.s, encryption_key));
7759
0
  if (line == NULL) {
7760
0
    goto done;
7761
0
  }
7762
0
  talloc_asprintf_addbuf(&state.s, "%s", line);
7763
7764
0
  DEBUG(0, ("%s", state.s));
7765
7766
0
  if (wireshark_keyfile == NULL) {
7767
0
    goto done;
7768
0
  }
7769
0
  fd = open(wireshark_keyfile, O_WRONLY | O_APPEND);
7770
0
  if (fd == -1) {
7771
0
    DBG_ERR("Failed to open '%s': %s\n",
7772
0
      wireshark_keyfile, strerror(errno));
7773
0
    goto done;
7774
0
  }
7775
7776
0
  written = write(fd, line, strlen(line));
7777
0
  if (written != strlen(line)) {
7778
0
    DBG_ERR("Failed to write '%s' to '%s', only wrote: %zd\n",
7779
0
      line, wireshark_keyfile, written);
7780
0
    goto done;
7781
0
  }
7782
7783
0
done:
7784
0
  TALLOC_FREE(line);
7785
0
  TALLOC_FREE(state.s);
7786
0
  if (fd != -1) {
7787
0
    close(fd);
7788
0
  }
7789
0
}