Coverage Report

Created: 2026-02-14 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/smbd/smb2_server.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   Core SMB2 server
4
5
   Copyright (C) Stefan Metzmacher 2009
6
   Copyright (C) Jeremy Allison 2010
7
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
*/
21
22
#include "includes.h"
23
#include "system/network.h"
24
#include "smbd/smbd.h"
25
#include "smbd/globals.h"
26
#include "source3/smbd/smbXsrv_session.h"
27
#include "smbd/smbXsrv_open.h"
28
#include "lib/param/param.h"
29
#include "../libcli/smb/smb_common.h"
30
#include "../lib/tsocket/tsocket.h"
31
#include "../lib/util/tevent_ntstatus.h"
32
#include "smbprofile.h"
33
#include "../lib/util/bitmap.h"
34
#include "../librpc/gen_ndr/krb5pac.h"
35
#include "lib/util/iov_buf.h"
36
#include "lib/async_req/async_sock.h"
37
#include "auth.h"
38
#include "libcli/smb/smbXcli_base.h"
39
#include "source3/lib/substitute.h"
40
41
#if defined(LINUX)
42
/* SIOCOUTQ TIOCOUTQ are the same */
43
0
#define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
44
#define __HAVE_TCP_INFO_RTO 1
45
#define __ALLOW_MULTI_CHANNEL_SUPPORT 1
46
#elif defined(FREEBSD)
47
#define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
48
#define __HAVE_TCP_INFO_RTO 1
49
#define __ALLOW_MULTI_CHANNEL_SUPPORT 1
50
#endif
51
52
#include "lib/crypto/gnutls_helpers.h"
53
#include <gnutls/gnutls.h>
54
#include <gnutls/crypto.h>
55
56
#undef DBGC_CLASS
57
0
#define DBGC_CLASS DBGC_SMB2
58
59
static void smbd_smb2_connection_handler(struct tevent_context *ev,
60
           struct tevent_fd *fde,
61
           uint16_t flags,
62
           void *private_data);
63
static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn);
64
65
static const struct smbd_smb2_dispatch_table {
66
  uint16_t opcode;
67
  uint16_t fileid_ofs;
68
  bool need_session : 1;
69
  bool need_tcon : 1;
70
  bool as_root : 1;
71
  bool modify : 1;
72
} smbd_smb2_table[] = {
73
  {
74
    .opcode = SMB2_OP_NEGPROT,
75
    .as_root = true,
76
  },{
77
    .opcode = SMB2_OP_SESSSETUP,
78
    .as_root = true,
79
  },{
80
    .opcode = SMB2_OP_LOGOFF,
81
    .need_session = true,
82
    .as_root = true,
83
  },{
84
    .opcode = SMB2_OP_TCON,
85
    .need_session = true,
86
    /*
87
     * This call needs to be run as root.
88
     *
89
     * smbd_smb2_request_process_tcon()
90
     * calls make_connection_snum(), which will call
91
     * change_to_user(), when needed.
92
     */
93
    .as_root = true,
94
  },{
95
    .opcode = SMB2_OP_TDIS,
96
    .need_session = true,
97
    .need_tcon = true,
98
    .as_root = true,
99
  },{
100
    .opcode = SMB2_OP_CREATE,
101
    .need_session = true,
102
    .need_tcon = true,
103
  },{
104
    .opcode = SMB2_OP_CLOSE,
105
    .need_session = true,
106
    .need_tcon = true,
107
    .fileid_ofs = 0x08,
108
  },{
109
    .opcode = SMB2_OP_FLUSH,
110
    .need_session = true,
111
    .need_tcon = true,
112
    .fileid_ofs = 0x08,
113
  },{
114
    .opcode = SMB2_OP_READ,
115
    .need_session = true,
116
    .need_tcon = true,
117
    .fileid_ofs = 0x10,
118
  },{
119
    .opcode = SMB2_OP_WRITE,
120
    .need_session = true,
121
    .need_tcon = true,
122
    .fileid_ofs = 0x10,
123
    .modify = true,
124
  },{
125
    .opcode = SMB2_OP_LOCK,
126
    .need_session = true,
127
    .need_tcon = true,
128
    .fileid_ofs = 0x08,
129
  },{
130
    .opcode = SMB2_OP_IOCTL,
131
    .need_session = true,
132
    .need_tcon = true,
133
    .fileid_ofs = 0x08,
134
    .modify = true,
135
  },{
136
    .opcode = SMB2_OP_CANCEL,
137
    .as_root = true,
138
  },{
139
    .opcode = SMB2_OP_KEEPALIVE,
140
  },{
141
    .opcode = SMB2_OP_QUERY_DIRECTORY,
142
    .need_session = true,
143
    .need_tcon = true,
144
    .fileid_ofs = 0x08,
145
  },{
146
    .opcode = SMB2_OP_NOTIFY,
147
    .need_session = true,
148
    .need_tcon = true,
149
    .fileid_ofs = 0x08,
150
  },{
151
    .opcode = SMB2_OP_GETINFO,
152
    .need_session = true,
153
    .need_tcon = true,
154
    .fileid_ofs = 0x18,
155
  },{
156
    .opcode = SMB2_OP_SETINFO,
157
    .need_session = true,
158
    .need_tcon = true,
159
    .fileid_ofs = 0x10,
160
    .modify = true,
161
  },{
162
    .opcode = SMB2_OP_BREAK,
163
    .need_session = true,
164
    .need_tcon = true,
165
    /*
166
     * we do not set
167
     * .fileid_ofs here
168
     * as LEASE breaks does not
169
     * have a file id
170
     */
171
  }
172
};
173
174
const char *smb2_opcode_name(uint16_t opcode)
175
0
{
176
0
  const char *result = "Bad SMB2 opcode";
177
178
0
  switch (opcode) {
179
0
  case SMB2_OP_NEGPROT:
180
0
    result = "SMB2_OP_NEGPROT";
181
0
    break;
182
0
  case SMB2_OP_SESSSETUP:
183
0
    result = "SMB2_OP_SESSSETUP";
184
0
    break;
185
0
  case SMB2_OP_LOGOFF:
186
0
    result = "SMB2_OP_LOGOFF";
187
0
    break;
188
0
  case SMB2_OP_TCON:
189
0
    result = "SMB2_OP_TCON";
190
0
    break;
191
0
  case SMB2_OP_TDIS:
192
0
    result = "SMB2_OP_TDIS";
193
0
    break;
194
0
  case SMB2_OP_CREATE:
195
0
    result = "SMB2_OP_CREATE";
196
0
    break;
197
0
  case SMB2_OP_CLOSE:
198
0
    result = "SMB2_OP_CLOSE";
199
0
    break;
200
0
  case SMB2_OP_FLUSH:
201
0
    result = "SMB2_OP_FLUSH";
202
0
    break;
203
0
  case SMB2_OP_READ:
204
0
    result = "SMB2_OP_READ";
205
0
    break;
206
0
  case SMB2_OP_WRITE:
207
0
    result = "SMB2_OP_WRITE";
208
0
    break;
209
0
  case SMB2_OP_LOCK:
210
0
    result = "SMB2_OP_LOCK";
211
0
    break;
212
0
  case SMB2_OP_IOCTL:
213
0
    result = "SMB2_OP_IOCTL";
214
0
    break;
215
0
  case SMB2_OP_CANCEL:
216
0
    result = "SMB2_OP_CANCEL";
217
0
    break;
218
0
  case SMB2_OP_KEEPALIVE:
219
0
    result = "SMB2_OP_KEEPALIVE";
220
0
    break;
221
0
  case SMB2_OP_QUERY_DIRECTORY:
222
0
    result = "SMB2_OP_QUERY_DIRECTORY";
223
0
    break;
224
0
  case SMB2_OP_NOTIFY:
225
0
    result = "SMB2_OP_NOTIFY";
226
0
    break;
227
0
  case SMB2_OP_GETINFO:
228
0
    result = "SMB2_OP_GETINFO";
229
0
    break;
230
0
  case SMB2_OP_SETINFO:
231
0
    result = "SMB2_OP_SETINFO";
232
0
    break;
233
0
  case SMB2_OP_BREAK:
234
0
    result = "SMB2_OP_BREAK";
235
0
    break;
236
0
  default:
237
0
    break;
238
0
  }
239
0
  return result;
240
0
}
241
242
static const struct smbd_smb2_dispatch_table *smbd_smb2_call(uint16_t opcode)
243
0
{
244
0
  const struct smbd_smb2_dispatch_table *ret = NULL;
245
246
0
  if (opcode >= ARRAY_SIZE(smbd_smb2_table)) {
247
0
    return NULL;
248
0
  }
249
250
0
  ret = &smbd_smb2_table[opcode];
251
252
0
  SMB_ASSERT(ret->opcode == opcode);
253
254
0
  return ret;
255
0
}
256
257
static void print_req_vectors(const struct smbd_smb2_request *req)
258
0
{
259
0
  int i;
260
261
0
  for (i = 0; i < req->in.vector_count; i++) {
262
0
    dbgtext("\treq->in.vector[%u].iov_len = %u\n",
263
0
      (unsigned int)i,
264
0
      (unsigned int)req->in.vector[i].iov_len);
265
0
  }
266
0
  for (i = 0; i < req->out.vector_count; i++) {
267
0
    dbgtext("\treq->out.vector[%u].iov_len = %u\n",
268
0
      (unsigned int)i,
269
0
      (unsigned int)req->out.vector[i].iov_len);
270
0
  }
271
0
}
272
273
bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size)
274
0
{
275
0
  if (size < (4 + SMB2_HDR_BODY)) {
276
0
    return false;
277
0
  }
278
279
0
  if (IVAL(inbuf, 4) != SMB2_MAGIC) {
280
0
    return false;
281
0
  }
282
283
0
  return true;
284
0
}
285
286
bool smbd_smb2_is_compound(const struct smbd_smb2_request *req)
287
0
{
288
0
  return req->in.vector_count >= (2*SMBD_SMB2_NUM_IOV_PER_REQ);
289
0
}
290
291
bool smbd_smb2_is_last_in_compound(const struct smbd_smb2_request *req)
292
0
{
293
0
  return (req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ ==
294
0
    req->in.vector_count);
295
0
}
296
297
static NTSTATUS smbd_initialize_smb2(struct smbXsrv_connection *xconn,
298
             uint64_t expected_seq_low)
299
0
{
300
0
  int rc;
301
302
0
  xconn->smb2.credits.seq_low = expected_seq_low;
303
0
  xconn->smb2.credits.seq_range = 1;
304
0
  xconn->smb2.credits.granted = 1;
305
0
  xconn->smb2.credits.max = lp_smb2_max_credits();
306
0
  xconn->smb2.credits.bitmap = bitmap_talloc(xconn,
307
0
               xconn->smb2.credits.max);
308
0
  if (xconn->smb2.credits.bitmap == NULL) {
309
0
    return NT_STATUS_NO_MEMORY;
310
0
  }
311
312
0
  tevent_fd_set_close_fn(xconn->transport.fde, NULL);
313
0
  TALLOC_FREE(xconn->transport.fde);
314
315
0
  xconn->transport.fde = tevent_add_fd(
316
0
          xconn->client->raw_ev_ctx,
317
0
          xconn,
318
0
          xconn->transport.sock,
319
0
          TEVENT_FD_ERROR | TEVENT_FD_READ,
320
0
          smbd_smb2_connection_handler,
321
0
          xconn);
322
0
  if (xconn->transport.fde == NULL) {
323
0
    close(xconn->transport.sock);
324
0
    xconn->transport.sock = -1;
325
0
    return NT_STATUS_NO_MEMORY;
326
0
  }
327
0
  tevent_fd_set_auto_close(xconn->transport.fde);
328
329
  /*
330
   * Ensure child is set to non-blocking mode,
331
   * unless the system supports MSG_DONTWAIT,
332
   * if MSG_DONTWAIT is available we should force
333
   * blocking mode.
334
   */
335
0
#ifdef MSG_DONTWAIT
336
0
  rc = set_blocking(xconn->transport.sock, true);
337
0
  if (rc < 0) {
338
0
    return NT_STATUS_INTERNAL_ERROR;
339
0
  }
340
#else
341
  rc = set_blocking(xconn->transport.sock, false);
342
  if (rc < 0) {
343
    return NT_STATUS_INTERNAL_ERROR;
344
  }
345
#endif
346
347
0
  return NT_STATUS_OK;
348
0
}
349
350
0
#define smb2_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
351
0
#define _smb2_setlen(_buf,len) do { \
352
0
  uint8_t *buf = (uint8_t *)_buf; \
353
0
  buf[0] = 0; \
354
0
  buf[1] = ((len)&0xFF0000)>>16; \
355
0
  buf[2] = ((len)&0xFF00)>>8; \
356
0
  buf[3] = (len)&0xFF; \
357
0
} while (0)
358
359
static bool smb2_setup_nbt_length(struct iovec *vector, int count)
360
0
{
361
0
  ssize_t len;
362
363
0
  if (count == 0) {
364
0
    return false;
365
0
  }
366
367
0
  len = iov_buflen(vector+1, count-1);
368
369
0
  if ((len == -1) || (len > 0xFFFFFF)) {
370
0
    return false;
371
0
  }
372
373
0
  _smb2_setlen(vector[0].iov_base, len);
374
0
  return true;
375
0
}
376
377
static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
378
0
{
379
0
  TALLOC_FREE(req->first_enc_key);
380
0
  TALLOC_FREE(req->last_sign_key);
381
0
  return 0;
382
0
}
383
384
void smb2_request_set_async_internal(struct smbd_smb2_request *req,
385
             bool async_internal)
386
0
{
387
0
  req->async_internal = async_internal;
388
0
}
389
390
static struct smbd_smb2_request *smbd_smb2_request_allocate(struct smbXsrv_connection *xconn)
391
0
{
392
0
  TALLOC_CTX *mem_pool;
393
0
  struct smbd_smb2_request *req;
394
395
#if 0
396
  /* Enable this to find subtle valgrind errors. */
397
  mem_pool = talloc_init("smbd_smb2_request_allocate");
398
#else
399
0
  mem_pool = talloc_tos();
400
0
#endif
401
0
  if (mem_pool == NULL) {
402
0
    return NULL;
403
0
  }
404
405
0
  req = talloc(mem_pool, struct smbd_smb2_request);
406
0
  if (req == NULL) {
407
0
    talloc_free(mem_pool);
408
0
    return NULL;
409
0
  }
410
0
  talloc_reparent(mem_pool, xconn, req);
411
#if 0
412
  TALLOC_FREE(mem_pool);
413
#endif
414
0
  *req = (struct smbd_smb2_request) {
415
0
    .sconn = xconn->client->sconn,
416
0
    .xconn = xconn,
417
0
    .last_session_id = UINT64_MAX,
418
0
    .last_tid = UINT32_MAX,
419
0
  };
420
421
0
  talloc_set_destructor(req, smbd_smb2_request_destructor);
422
423
0
  return req;
424
0
}
425
426
static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *xconn,
427
                 NTTIME now,
428
                 uint8_t *buf,
429
                 size_t buflen,
430
                 struct smbd_smb2_request *req,
431
                 struct iovec **piov,
432
                 int *pnum_iov)
433
0
{
434
0
  TALLOC_CTX *mem_ctx = req;
435
0
  struct iovec *iov;
436
0
  int num_iov = 1;
437
0
  size_t taken = 0;
438
0
  uint8_t *first_hdr = buf;
439
0
  size_t verified_buflen = 0;
440
0
  uint8_t *tf = NULL;
441
0
  size_t tf_len = 0;
442
443
  /*
444
   * Note: index '0' is reserved for the transport protocol
445
   */
446
0
  iov = req->in._vector;
447
448
0
  while (taken < buflen) {
449
0
    size_t len = buflen - taken;
450
0
    uint8_t *hdr = first_hdr + taken;
451
0
    struct iovec *cur;
452
0
    size_t full_size;
453
0
    size_t next_command_ofs;
454
0
    uint16_t body_size;
455
0
    uint8_t *body = NULL;
456
0
    uint32_t dyn_size;
457
0
    uint8_t *dyn = NULL;
458
0
    struct iovec *iov_alloc = NULL;
459
460
0
    if (iov != req->in._vector) {
461
0
      iov_alloc = iov;
462
0
    }
463
464
0
    if (verified_buflen > taken) {
465
0
      len = verified_buflen - taken;
466
0
    } else {
467
0
      tf = NULL;
468
0
      tf_len = 0;
469
0
    }
470
471
0
    if (len < 4) {
472
0
      DEBUG(10, ("%d bytes left, expected at least %d\n",
473
0
           (int)len, 4));
474
0
      goto inval;
475
0
    }
476
0
    if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
477
0
      struct smbXsrv_session *s = NULL;
478
0
      uint64_t uid;
479
0
      struct iovec tf_iov[2];
480
0
      NTSTATUS status;
481
0
      size_t enc_len;
482
483
0
      if (xconn->protocol < PROTOCOL_SMB3_00) {
484
0
        DEBUG(10, ("Got SMB2_TRANSFORM header, "
485
0
             "but dialect[0x%04X] is used\n",
486
0
             xconn->smb2.server.dialect));
487
0
        goto inval;
488
0
      }
489
490
0
      if (xconn->smb2.server.cipher == 0) {
491
0
        DEBUG(10, ("Got SMB2_TRANSFORM header, "
492
0
             "but not negotiated "
493
0
             "client[0x%08X] server[0x%08X]\n",
494
0
             xconn->smb2.client.capabilities,
495
0
             xconn->smb2.server.capabilities));
496
0
        goto inval;
497
0
      }
498
499
0
      if (!xconn->smb2.got_authenticated_session) {
500
0
        D_INFO("Got SMB2_TRANSFORM header, "
501
0
               "but not no authenticated session yet "
502
0
               "client[%s] server[%s]\n",
503
0
               tsocket_address_string(
504
0
          xconn->remote_address, talloc_tos()),
505
0
               tsocket_address_string(
506
0
          xconn->local_address, talloc_tos()));
507
0
        goto inval;
508
0
      }
509
510
0
      if (len < SMB2_TF_HDR_SIZE) {
511
0
        DEBUG(1, ("%d bytes left, expected at least %d\n",
512
0
             (int)len, SMB2_TF_HDR_SIZE));
513
0
        goto inval;
514
0
      }
515
0
      tf = hdr;
516
0
      tf_len = SMB2_TF_HDR_SIZE;
517
0
      taken += tf_len;
518
519
0
      hdr = first_hdr + taken;
520
0
      enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
521
0
      uid = BVAL(tf, SMB2_TF_SESSION_ID);
522
523
0
      if (len < SMB2_TF_HDR_SIZE + enc_len) {
524
0
        DEBUG(1, ("%d bytes left, expected at least %d\n",
525
0
             (int)len,
526
0
             (int)(SMB2_TF_HDR_SIZE + enc_len)));
527
0
        goto inval;
528
0
      }
529
530
0
      status = smb2srv_session_lookup_conn(xconn, uid, now,
531
0
                   &s);
532
0
      if (!NT_STATUS_IS_OK(status)) {
533
0
        status = smb2srv_session_lookup_global(xconn->client,
534
0
                       uid, req, &s);
535
0
      }
536
0
      if (!NT_STATUS_IS_OK(status)) {
537
0
        DBG_WARNING("invalid session[%" PRIu64 "] in "
538
0
              "SMB2_TRANSFORM header\n",
539
0
              uid);
540
0
        TALLOC_FREE(iov_alloc);
541
0
        return NT_STATUS_USER_SESSION_DELETED;
542
0
      }
543
544
0
      tf_iov[0].iov_base = (void *)tf;
545
0
      tf_iov[0].iov_len = tf_len;
546
0
      tf_iov[1].iov_base = (void *)hdr;
547
0
      tf_iov[1].iov_len = enc_len;
548
549
0
      status = smb2_signing_decrypt_pdu(s->global->decryption_key,
550
0
                tf_iov, 2);
551
0
      if (!NT_STATUS_IS_OK(status)) {
552
0
        TALLOC_FREE(iov_alloc);
553
0
        return status;
554
0
      }
555
556
0
      verified_buflen = taken + enc_len;
557
0
      len = enc_len;
558
0
    }
559
560
    /*
561
     * We need the header plus the body length field
562
     */
563
564
0
    if (len < SMB2_HDR_BODY + 2) {
565
566
0
      if ((len == 5) &&
567
0
          (IVAL(hdr, 0) == SMB_SUICIDE_PACKET) &&
568
0
          lp_parm_bool(-1, "smbd", "suicide mode", false)) {
569
0
        uint8_t exitcode = CVAL(hdr, 4);
570
0
        DBG_WARNING("SUICIDE: Exiting immediately "
571
0
              "with code %"PRIu8"\n",
572
0
              exitcode);
573
0
        exit(exitcode);
574
0
      }
575
576
0
      DEBUG(10, ("%d bytes left, expected at least %d\n",
577
0
           (int)len, SMB2_HDR_BODY));
578
0
      goto inval;
579
0
    }
580
0
    if (IVAL(hdr, 0) != SMB2_MAGIC) {
581
0
      DEBUG(10, ("Got non-SMB2 PDU: %x\n",
582
0
           IVAL(hdr, 0)));
583
0
      goto inval;
584
0
    }
585
0
    if (SVAL(hdr, 4) != SMB2_HDR_BODY) {
586
0
      DEBUG(10, ("Got HDR len %d, expected %d\n",
587
0
           SVAL(hdr, 4), SMB2_HDR_BODY));
588
0
      goto inval;
589
0
    }
590
591
0
    full_size = len;
592
0
    next_command_ofs = IVAL(hdr, SMB2_HDR_NEXT_COMMAND);
593
0
    body_size = SVAL(hdr, SMB2_HDR_BODY);
594
595
0
    if (next_command_ofs != 0) {
596
0
      if (next_command_ofs < (SMB2_HDR_BODY + 2)) {
597
0
        goto inval;
598
0
      }
599
0
      if (next_command_ofs > full_size) {
600
0
        goto inval;
601
0
      }
602
0
      full_size = next_command_ofs;
603
0
    }
604
0
    if (body_size < 2) {
605
0
      goto inval;
606
0
    }
607
0
    body_size &= 0xfffe;
608
609
0
    if (body_size > (full_size - SMB2_HDR_BODY)) {
610
      /*
611
       * let the caller handle the error
612
       */
613
0
      body_size = full_size - SMB2_HDR_BODY;
614
0
    }
615
0
    body = hdr + SMB2_HDR_BODY;
616
0
    dyn = body + body_size;
617
0
    dyn_size = full_size - (SMB2_HDR_BODY + body_size);
618
619
0
    if (num_iov >= ARRAY_SIZE(req->in._vector)) {
620
0
      struct iovec *iov_tmp = NULL;
621
622
0
      iov_tmp = talloc_realloc(mem_ctx, iov_alloc,
623
0
             struct iovec,
624
0
             num_iov +
625
0
             SMBD_SMB2_NUM_IOV_PER_REQ);
626
0
      if (iov_tmp == NULL) {
627
0
        TALLOC_FREE(iov_alloc);
628
0
        return NT_STATUS_NO_MEMORY;
629
0
      }
630
631
0
      if (iov_alloc == NULL) {
632
0
        memcpy(iov_tmp,
633
0
               req->in._vector,
634
0
               sizeof(req->in._vector));
635
0
      }
636
637
0
      iov = iov_tmp;
638
0
    }
639
0
    cur = &iov[num_iov];
640
0
    num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
641
642
0
    cur[SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
643
0
    cur[SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
644
0
    cur[SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
645
0
    cur[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
646
0
    cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
647
0
    cur[SMBD_SMB2_BODY_IOV_OFS].iov_len  = body_size;
648
0
    cur[SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
649
0
    cur[SMBD_SMB2_DYN_IOV_OFS].iov_len   = dyn_size;
650
651
0
    taken += full_size;
652
0
  }
653
654
0
  *piov = iov;
655
0
  *pnum_iov = num_iov;
656
0
  return NT_STATUS_OK;
657
658
0
inval:
659
0
  if (iov != req->in._vector) {
660
0
    TALLOC_FREE(iov);
661
0
  }
662
0
  return NT_STATUS_INVALID_PARAMETER;
663
0
}
664
665
static NTSTATUS smbd_smb2_request_create(struct smbXsrv_connection *xconn,
666
           const uint8_t *_inpdu, size_t size,
667
           struct smbd_smb2_request **_req)
668
0
{
669
0
  struct smbd_smb2_request *req;
670
0
  uint32_t protocol_version;
671
0
  uint8_t *inpdu = NULL;
672
0
  const uint8_t *inhdr = NULL;
673
0
  uint16_t cmd;
674
0
  uint32_t next_command_ofs;
675
0
  NTSTATUS status;
676
0
  NTTIME now;
677
678
0
  if (size < (SMB2_HDR_BODY + 2)) {
679
0
    DEBUG(0,("Invalid SMB2 packet length count %ld\n", (long)size));
680
0
    return NT_STATUS_INVALID_PARAMETER;
681
0
  }
682
683
0
  inhdr = _inpdu;
684
685
0
  protocol_version = IVAL(inhdr, SMB2_HDR_PROTOCOL_ID);
686
0
  if (protocol_version != SMB2_MAGIC) {
687
0
    DEBUG(0,("Invalid SMB packet: protocol prefix: 0x%08X\n",
688
0
       protocol_version));
689
0
    return NT_STATUS_INVALID_PARAMETER;
690
0
  }
691
692
0
  cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
693
0
  if (cmd != SMB2_OP_NEGPROT) {
694
0
    DEBUG(0,("Invalid SMB packet: first request: 0x%04X\n",
695
0
       cmd));
696
0
    return NT_STATUS_INVALID_PARAMETER;
697
0
  }
698
699
0
  next_command_ofs = IVAL(inhdr, SMB2_HDR_NEXT_COMMAND);
700
0
  if (next_command_ofs != 0) {
701
0
    DEBUG(0,("Invalid SMB packet: next_command: 0x%08X\n",
702
0
       next_command_ofs));
703
0
    return NT_STATUS_INVALID_PARAMETER;
704
0
  }
705
706
0
  req = smbd_smb2_request_allocate(xconn);
707
0
  if (req == NULL) {
708
0
    return NT_STATUS_NO_MEMORY;
709
0
  }
710
711
0
  inpdu = talloc_memdup(req, _inpdu, size);
712
0
  if (inpdu == NULL) {
713
0
    return NT_STATUS_NO_MEMORY;
714
0
  }
715
716
0
  req->request_time = timeval_current();
717
0
  now = timeval_to_nttime(&req->request_time);
718
719
0
  status = smbd_smb2_inbuf_parse_compound(xconn,
720
0
            now,
721
0
            inpdu,
722
0
            size,
723
0
            req, &req->in.vector,
724
0
            &req->in.vector_count);
725
0
  if (!NT_STATUS_IS_OK(status)) {
726
0
    TALLOC_FREE(req);
727
0
    return status;
728
0
  }
729
730
0
  req->current_idx = 1;
731
732
0
  *_req = req;
733
0
  return NT_STATUS_OK;
734
0
}
735
736
static bool smb2_validate_sequence_number(struct smbXsrv_connection *xconn,
737
            uint64_t message_id, uint64_t seq_id)
738
0
{
739
0
  struct bitmap *credits_bm = xconn->smb2.credits.bitmap;
740
0
  unsigned int offset;
741
0
  uint64_t seq_tmp;
742
743
0
  seq_tmp = xconn->smb2.credits.seq_low;
744
0
  if (seq_id < seq_tmp) {
745
0
    DBGC_ERR(DBGC_SMB2_CREDITS,
746
0
      "smb2_validate_sequence_number: bad message_id "
747
0
      "%llu (sequence id %llu) "
748
0
      "(granted = %u, low = %llu, range = %u)\n",
749
0
      (unsigned long long)message_id,
750
0
      (unsigned long long)seq_id,
751
0
      (unsigned int)xconn->smb2.credits.granted,
752
0
      (unsigned long long)xconn->smb2.credits.seq_low,
753
0
      (unsigned int)xconn->smb2.credits.seq_range);
754
0
    return false;
755
0
  }
756
757
0
  seq_tmp += xconn->smb2.credits.seq_range;
758
0
  if (seq_id >= seq_tmp) {
759
0
    DBGC_ERR(DBGC_SMB2_CREDITS,
760
0
      "smb2_validate_sequence_number: bad message_id "
761
0
      "%llu (sequence id %llu) "
762
0
      "(granted = %u, low = %llu, range = %u)\n",
763
0
      (unsigned long long)message_id,
764
0
      (unsigned long long)seq_id,
765
0
      (unsigned int)xconn->smb2.credits.granted,
766
0
      (unsigned long long)xconn->smb2.credits.seq_low,
767
0
      (unsigned int)xconn->smb2.credits.seq_range);
768
0
    return false;
769
0
  }
770
771
0
  offset = seq_id % xconn->smb2.credits.max;
772
773
0
  if (bitmap_query(credits_bm, offset)) {
774
0
    DBGC_ERR(DBGC_SMB2_CREDITS,
775
0
      "smb2_validate_sequence_number: duplicate message_id "
776
0
      "%llu (sequence id %llu) "
777
0
      "(granted = %u, low = %llu, range = %u) "
778
0
      "(bm offset %u)\n",
779
0
      (unsigned long long)message_id,
780
0
      (unsigned long long)seq_id,
781
0
      (unsigned int)xconn->smb2.credits.granted,
782
0
      (unsigned long long)xconn->smb2.credits.seq_low,
783
0
      (unsigned int)xconn->smb2.credits.seq_range,
784
0
      offset);
785
0
    return false;
786
0
  }
787
788
  /* Mark the message_ids as seen in the bitmap. */
789
0
  bitmap_set(credits_bm, offset);
790
791
0
  if (seq_id != xconn->smb2.credits.seq_low) {
792
0
    return true;
793
0
  }
794
795
  /*
796
   * Move the window forward by all the message_id's
797
   * already seen.
798
   */
799
0
  while (bitmap_query(credits_bm, offset)) {
800
0
    DBGC_DEBUG(DBGC_SMB2_CREDITS,
801
0
        "smb2_validate_sequence_number: clearing "
802
0
        "id %llu (position %u) from bitmap\n",
803
0
        (unsigned long long)(xconn->smb2.credits.seq_low),
804
0
        offset);
805
0
    bitmap_clear(credits_bm, offset);
806
807
0
    xconn->smb2.credits.seq_low += 1;
808
0
    xconn->smb2.credits.seq_range -= 1;
809
0
    offset = xconn->smb2.credits.seq_low % xconn->smb2.credits.max;
810
0
  }
811
812
0
  return true;
813
0
}
814
815
static bool smb2_validate_message_id(struct smbXsrv_connection *xconn,
816
             const uint8_t *inhdr)
817
0
{
818
0
  uint64_t message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
819
0
  uint16_t opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
820
0
  uint16_t credit_charge = 1;
821
0
  uint64_t i;
822
823
0
  if (opcode == SMB2_OP_CANCEL) {
824
    /* SMB2_CANCEL requests by definition resend messageids. */
825
0
    return true;
826
0
  }
827
828
0
  if (xconn->smb2.credits.multicredit) {
829
0
    credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
830
0
    credit_charge = MAX(credit_charge, 1);
831
0
  }
832
833
0
  DEBUGC(11,
834
0
       DBGC_SMB2_CREDITS,
835
0
       ("smb2_validate_message_id: mid %llu (charge %llu), "
836
0
       "credits_granted %llu, "
837
0
       "seqnum low/range: %llu/%llu\n",
838
0
       (unsigned long long) message_id,
839
0
       (unsigned long long) credit_charge,
840
0
       (unsigned long long) xconn->smb2.credits.granted,
841
0
       (unsigned long long) xconn->smb2.credits.seq_low,
842
0
       (unsigned long long) xconn->smb2.credits.seq_range));
843
844
0
  if (xconn->smb2.credits.granted < credit_charge) {
845
0
    DBGC_ERR(DBGC_SMB2_CREDITS,
846
0
        "smb2_validate_message_id: client used more "
847
0
        "credits than granted, mid %llu, charge %llu, "
848
0
        "credits_granted %llu, "
849
0
        "seqnum low/range: %llu/%llu\n",
850
0
        (unsigned long long) message_id,
851
0
        (unsigned long long) credit_charge,
852
0
        (unsigned long long) xconn->smb2.credits.granted,
853
0
        (unsigned long long) xconn->smb2.credits.seq_low,
854
0
        (unsigned long long) xconn->smb2.credits.seq_range);
855
0
    return false;
856
0
  }
857
858
  /*
859
   * now check the message ids
860
   *
861
   * for multi-credit requests we need to check all current mid plus
862
   * the implicit mids caused by the credit charge
863
   * e.g. current mid = 15, charge 5 => mark 15-19 as used
864
   */
865
866
0
  for (i = 0; i <= (credit_charge-1); i++) {
867
0
    uint64_t id = message_id + i;
868
0
    bool ok;
869
870
0
    DEBUGC(11,
871
0
         DBGC_SMB2_CREDITS,
872
0
         ("Iterating mid %llu charge %u (sequence %llu)\n",
873
0
         (unsigned long long)message_id,
874
0
         credit_charge,
875
0
         (unsigned long long)id));
876
877
0
    ok = smb2_validate_sequence_number(xconn, message_id, id);
878
0
    if (!ok) {
879
0
      return false;
880
0
    }
881
0
  }
882
883
  /* subtract used credits */
884
0
  xconn->smb2.credits.granted -= credit_charge;
885
886
0
  return true;
887
0
}
888
889
static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req)
890
0
{
891
0
  int count;
892
0
  int idx;
893
894
0
  count = req->in.vector_count;
895
896
0
  if (count < 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
897
    /* It's not a SMB2 request */
898
0
    return NT_STATUS_INVALID_PARAMETER;
899
0
  }
900
901
0
  for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
902
0
    struct iovec *hdr = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
903
0
    struct iovec *body = SMBD_SMB2_IDX_BODY_IOV(req,in,idx);
904
0
    const uint8_t *inhdr = NULL;
905
906
0
    if (hdr->iov_len != SMB2_HDR_BODY) {
907
0
      return NT_STATUS_INVALID_PARAMETER;
908
0
    }
909
910
0
    if (body->iov_len < 2) {
911
0
      return NT_STATUS_INVALID_PARAMETER;
912
0
    }
913
914
0
    inhdr = (const uint8_t *)hdr->iov_base;
915
916
    /* Check the SMB2 header */
917
0
    if (IVAL(inhdr, SMB2_HDR_PROTOCOL_ID) != SMB2_MAGIC) {
918
0
      return NT_STATUS_INVALID_PARAMETER;
919
0
    }
920
921
0
    if (!smb2_validate_message_id(req->xconn, inhdr)) {
922
0
      return NT_STATUS_INVALID_PARAMETER;
923
0
    }
924
0
  }
925
926
0
  return NT_STATUS_OK;
927
0
}
928
929
static void smb2_set_operation_credit(struct smbXsrv_connection *xconn,
930
              const struct iovec *in_vector,
931
              struct iovec *out_vector)
932
0
{
933
0
  const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base;
934
0
  uint8_t *outhdr = (uint8_t *)out_vector->iov_base;
935
0
  uint16_t credit_charge = 1;
936
0
  uint16_t credits_requested;
937
0
  uint32_t out_flags;
938
0
  uint16_t cmd;
939
0
  NTSTATUS out_status;
940
0
  uint16_t credits_granted = 0;
941
0
  uint64_t credits_possible;
942
0
  uint16_t current_max_credits;
943
944
  /*
945
   * first we grant only 1/16th of the max range.
946
   *
947
   * Windows also starts with the 1/16th and then grants
948
   * more later. I was only able to trigger higher
949
   * values, when using a very high credit charge.
950
   *
951
   * TODO: scale up depending on load, free memory
952
   *       or other stuff.
953
   *       Maybe also on the relationship between number
954
   *       of requests and the used sequence number.
955
   *       Which means we would grant more credits
956
   *       for client which use multi credit requests.
957
   *
958
   * The above is what Windows Server < 2016 is doing,
959
   * but new servers use all credits (8192 by default).
960
   */
961
0
  current_max_credits = xconn->smb2.credits.max;
962
0
  current_max_credits = MAX(current_max_credits, 1);
963
964
0
  if (xconn->smb2.credits.multicredit) {
965
0
    credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
966
0
    credit_charge = MAX(credit_charge, 1);
967
0
  }
968
969
0
  cmd = SVAL(inhdr, SMB2_HDR_OPCODE);
970
0
  credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT);
971
0
  credits_requested = MAX(credits_requested, 1);
972
0
  out_flags = IVAL(outhdr, SMB2_HDR_FLAGS);
973
0
  out_status = NT_STATUS(IVAL(outhdr, SMB2_HDR_STATUS));
974
975
0
  SMB_ASSERT(xconn->smb2.credits.max >= xconn->smb2.credits.granted);
976
977
0
  if (xconn->smb2.credits.max < credit_charge) {
978
0
    smbd_server_connection_terminate(xconn,
979
0
      "client error: credit charge > max credits\n");
980
0
    return;
981
0
  }
982
983
0
  if (out_flags & SMB2_HDR_FLAG_ASYNC) {
984
    /*
985
     * In case we already send an async interim
986
     * response, we should not grant
987
     * credits on the final response.
988
     */
989
0
    credits_granted = 0;
990
0
  } else {
991
0
    uint16_t additional_possible =
992
0
      xconn->smb2.credits.max - credit_charge;
993
0
    uint16_t additional_max = 0;
994
0
    uint16_t additional_credits = credits_requested - 1;
995
996
0
    switch (cmd) {
997
0
    case SMB2_OP_NEGPROT:
998
0
      break;
999
0
    case SMB2_OP_SESSSETUP:
1000
      /*
1001
       * Windows 2012 RC1 starts to grant
1002
       * additional credits
1003
       * with a successful session setup
1004
       */
1005
0
      if (NT_STATUS_IS_OK(out_status)) {
1006
0
        additional_max = xconn->smb2.credits.max;
1007
0
      }
1008
0
      break;
1009
0
    default:
1010
      /*
1011
       * Windows Server < 2016 and older Samba versions
1012
       * used to only grant additional credits in
1013
       * chunks of 32 credits.
1014
       *
1015
       * But we match Windows Server 2016 and grant
1016
       * all credits as requested.
1017
       */
1018
0
      additional_max = xconn->smb2.credits.max;
1019
0
      break;
1020
0
    }
1021
1022
0
    additional_max = MIN(additional_max, additional_possible);
1023
0
    additional_credits = MIN(additional_credits, additional_max);
1024
1025
0
    credits_granted = credit_charge + additional_credits;
1026
0
  }
1027
1028
  /*
1029
   * sequence numbers should not wrap
1030
   *
1031
   * 1. calculate the possible credits until
1032
   *    the sequence numbers start to wrap on 64-bit.
1033
   *
1034
   * 2. UINT64_MAX is used for Break Notifications.
1035
   *
1036
   * 2. truncate the possible credits to the maximum
1037
   *    credits we want to grant to the client in total.
1038
   *
1039
   * 3. remove the range we'll already granted to the client
1040
   *    this makes sure the client consumes the lowest sequence
1041
   *    number, before we can grant additional credits.
1042
   */
1043
0
  credits_possible = UINT64_MAX - xconn->smb2.credits.seq_low;
1044
0
  if (credits_possible > 0) {
1045
    /* remove UINT64_MAX */
1046
0
    credits_possible -= 1;
1047
0
  }
1048
0
  credits_possible = MIN(credits_possible, current_max_credits);
1049
0
  credits_possible -= xconn->smb2.credits.seq_range;
1050
1051
0
  credits_granted = MIN(credits_granted, credits_possible);
1052
1053
0
  SSVAL(outhdr, SMB2_HDR_CREDIT, credits_granted);
1054
0
  xconn->smb2.credits.granted += credits_granted;
1055
0
  xconn->smb2.credits.seq_range += credits_granted;
1056
1057
0
  DBGC_DEBUG(DBGC_SMB2_CREDITS,
1058
0
    "smb2_set_operation_credit: requested %u, charge %u, "
1059
0
    "granted %u, current possible/max %u/%u, "
1060
0
    "total granted/max/low/range %u/%u/%llu/%u\n",
1061
0
    (unsigned int)credits_requested,
1062
0
    (unsigned int)credit_charge,
1063
0
    (unsigned int)credits_granted,
1064
0
    (unsigned int)credits_possible,
1065
0
    (unsigned int)current_max_credits,
1066
0
    (unsigned int)xconn->smb2.credits.granted,
1067
0
    (unsigned int)xconn->smb2.credits.max,
1068
0
    (unsigned long long)xconn->smb2.credits.seq_low,
1069
0
    (unsigned int)xconn->smb2.credits.seq_range);
1070
0
}
1071
1072
static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
1073
        struct smbd_smb2_request *outreq)
1074
0
{
1075
0
  int count, idx;
1076
0
  uint16_t total_credits = 0;
1077
1078
0
  count = outreq->out.vector_count;
1079
1080
0
  for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
1081
0
    struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(inreq,in,idx);
1082
0
    struct iovec *outhdr_v = SMBD_SMB2_IDX_HDR_IOV(outreq,out,idx);
1083
0
    uint8_t *outhdr = (uint8_t *)outhdr_v->iov_base;
1084
1085
0
    smb2_set_operation_credit(outreq->xconn, inhdr_v, outhdr_v);
1086
1087
    /* To match Windows, count up what we
1088
       just granted. */
1089
0
    total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
1090
    /* Set to zero in all but the last reply. */
1091
0
    if (idx + SMBD_SMB2_NUM_IOV_PER_REQ < count) {
1092
0
      SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
1093
0
    } else {
1094
0
      SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
1095
0
    }
1096
0
  }
1097
0
}
1098
1099
DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size)
1100
0
{
1101
0
  if (req->current_idx <= 1) {
1102
0
    if (size <= sizeof(req->out._body)) {
1103
0
      return data_blob_const(req->out._body, size);
1104
0
    }
1105
0
  }
1106
1107
0
  return data_blob_talloc(req, NULL, size);
1108
0
}
1109
1110
static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
1111
0
{
1112
0
  struct smbXsrv_connection *xconn = req->xconn;
1113
0
  TALLOC_CTX *mem_ctx;
1114
0
  struct iovec *vector;
1115
0
  int count;
1116
0
  int idx;
1117
0
  bool ok;
1118
1119
0
  count = req->in.vector_count;
1120
0
  if (count <= ARRAY_SIZE(req->out._vector)) {
1121
0
    mem_ctx = req;
1122
0
    vector = req->out._vector;
1123
0
  } else {
1124
0
    vector = talloc_zero_array(req, struct iovec, count);
1125
0
    if (vector == NULL) {
1126
0
      return NT_STATUS_NO_MEMORY;
1127
0
    }
1128
0
    mem_ctx = vector;
1129
0
  }
1130
1131
0
  vector[0].iov_base  = req->out.nbt_hdr;
1132
0
  vector[0].iov_len = 4;
1133
0
  SIVAL(req->out.nbt_hdr, 0, 0);
1134
1135
0
  for (idx=1; idx < count; idx += SMBD_SMB2_NUM_IOV_PER_REQ) {
1136
0
    struct iovec *inhdr_v = SMBD_SMB2_IDX_HDR_IOV(req,in,idx);
1137
0
    const uint8_t *inhdr = (const uint8_t *)inhdr_v->iov_base;
1138
0
    uint8_t *outhdr = NULL;
1139
0
    uint8_t *outbody = NULL;
1140
0
    uint32_t next_command_ofs = 0;
1141
0
    struct iovec *current = &vector[idx];
1142
1143
0
    if ((idx + SMBD_SMB2_NUM_IOV_PER_REQ) < count) {
1144
      /* we have a next command -
1145
       * setup for the error case. */
1146
0
      next_command_ofs = SMB2_HDR_BODY + 9;
1147
0
    }
1148
1149
0
    if (idx == 1) {
1150
0
      outhdr = req->out._hdr;
1151
0
    } else {
1152
0
      outhdr = talloc_zero_array(mem_ctx, uint8_t,
1153
0
               OUTVEC_ALLOC_SIZE);
1154
0
      if (outhdr == NULL) {
1155
0
        return NT_STATUS_NO_MEMORY;
1156
0
      }
1157
0
    }
1158
1159
0
    outbody = outhdr + SMB2_HDR_BODY;
1160
1161
    /*
1162
     * SMBD_SMB2_TF_IOV_OFS might be used later
1163
     */
1164
0
    current[SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
1165
0
    current[SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
1166
1167
0
    current[SMBD_SMB2_HDR_IOV_OFS].iov_base  = (void *)outhdr;
1168
0
    current[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
1169
1170
0
    current[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)outbody;
1171
0
    current[SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
1172
1173
0
    current[SMBD_SMB2_DYN_IOV_OFS].iov_base  = NULL;
1174
0
    current[SMBD_SMB2_DYN_IOV_OFS].iov_len   = 0;
1175
1176
    /* setup the SMB2 header */
1177
0
    SIVAL(outhdr, SMB2_HDR_PROTOCOL_ID,  SMB2_MAGIC);
1178
0
    SSVAL(outhdr, SMB2_HDR_LENGTH,   SMB2_HDR_BODY);
1179
0
    SSVAL(outhdr, SMB2_HDR_CREDIT_CHARGE,
1180
0
          SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE));
1181
0
    SIVAL(outhdr, SMB2_HDR_STATUS,
1182
0
          NT_STATUS_V(NT_STATUS_INTERNAL_ERROR));
1183
0
    SSVAL(outhdr, SMB2_HDR_OPCODE,
1184
0
          SVAL(inhdr, SMB2_HDR_OPCODE));
1185
0
    SIVAL(outhdr, SMB2_HDR_FLAGS,
1186
0
          IVAL(inhdr, SMB2_HDR_FLAGS) | SMB2_HDR_FLAG_REDIRECT);
1187
0
    SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
1188
0
    SBVAL(outhdr, SMB2_HDR_MESSAGE_ID,
1189
0
          BVAL(inhdr, SMB2_HDR_MESSAGE_ID));
1190
0
    SIVAL(outhdr, SMB2_HDR_PID,
1191
0
          IVAL(inhdr, SMB2_HDR_PID));
1192
0
    SIVAL(outhdr, SMB2_HDR_TID,
1193
0
          IVAL(inhdr, SMB2_HDR_TID));
1194
0
    SBVAL(outhdr, SMB2_HDR_SESSION_ID,
1195
0
          BVAL(inhdr, SMB2_HDR_SESSION_ID));
1196
0
    memcpy(outhdr + SMB2_HDR_SIGNATURE,
1197
0
           inhdr + SMB2_HDR_SIGNATURE, 16);
1198
1199
    /* setup error body header */
1200
0
    SSVAL(outbody, 0x00, 0x08 + 1);
1201
0
    SSVAL(outbody, 0x02, 0);
1202
0
    SIVAL(outbody, 0x04, 0);
1203
0
  }
1204
1205
0
  req->out.vector = vector;
1206
0
  req->out.vector_count = count;
1207
1208
  /* setup the length of the NBT packet */
1209
0
  ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
1210
0
  if (!ok) {
1211
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
1212
0
  }
1213
1214
0
  DLIST_ADD_END(xconn->smb2.requests, req);
1215
1216
0
  return NT_STATUS_OK;
1217
0
}
1218
1219
bool smbXsrv_server_multi_channel_enabled(void)
1220
0
{
1221
0
  bool enabled = lp_server_multi_channel_support();
1222
#ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
1223
  bool forced = false;
1224
  struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
1225
  bool unspecified = lpcfg_parm_is_unspecified(lp_ctx, "server multi channel support");
1226
  if (unspecified) {
1227
    enabled = false;
1228
  }
1229
  /*
1230
   * If we don't have support from the kernel
1231
   * to ask for the un-acked number of bytes
1232
   * in the socket send queue, we better
1233
   * don't support multi-channel.
1234
   */
1235
  forced = lp_parm_bool(-1, "force", "server multi channel support", false);
1236
  if (enabled && !forced) {
1237
    D_NOTICE("'server multi channel support' enabled "
1238
       "but not supported on %s (%s)\n",
1239
       SYSTEM_UNAME_SYSNAME, SYSTEM_UNAME_RELEASE);
1240
    DEBUGADD(DBGLVL_NOTICE, ("Please report this on "
1241
      "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
1242
    enabled = false;
1243
  }
1244
  TALLOC_FREE(lp_ctx);
1245
#endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
1246
0
  return enabled;
1247
0
}
1248
1249
static NTSTATUS smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection *xconn,
1250
             uint32_t *_rto_usecs)
1251
0
{
1252
  /*
1253
   * Define an Retransmission Timeout
1254
   * of 1 second, if there's no way for the
1255
   * kernel to tell us the current value.
1256
   */
1257
0
  uint32_t rto_usecs = 1000000;
1258
1259
0
#ifdef __HAVE_TCP_INFO_RTO
1260
0
  {
1261
0
    struct tcp_info info;
1262
0
    socklen_t ilen = sizeof(info);
1263
0
    int ret;
1264
1265
0
    ZERO_STRUCT(info);
1266
0
    ret = getsockopt(xconn->transport.sock,
1267
0
         IPPROTO_TCP, TCP_INFO,
1268
0
         (void *)&info, &ilen);
1269
0
    if (ret != 0) {
1270
0
      int saved_errno = errno;
1271
0
      NTSTATUS status = map_nt_error_from_unix(errno);
1272
0
      DBG_ERR("getsockopt(TCP_INFO) errno[%d/%s] -s %s\n",
1273
0
        saved_errno, strerror(saved_errno),
1274
0
        nt_errstr(status));
1275
0
      return status;
1276
0
    }
1277
1278
0
    DBG_DEBUG("tcpi_rto[%u] tcpi_rtt[%u] tcpi_rttvar[%u]\n",
1279
0
        (unsigned)info.tcpi_rto,
1280
0
        (unsigned)info.tcpi_rtt,
1281
0
        (unsigned)info.tcpi_rttvar);
1282
0
    rto_usecs = info.tcpi_rto;
1283
0
  }
1284
0
#endif /* __HAVE_TCP_INFO_RTO */
1285
1286
0
  rto_usecs = MAX(rto_usecs,  200000); /* at least 0.2s */
1287
0
  rto_usecs = MIN(rto_usecs, 1000000); /* at max   1.0s */
1288
0
  *_rto_usecs = rto_usecs;
1289
0
  return NT_STATUS_OK;
1290
0
}
1291
1292
static NTSTATUS smbXsrv_connection_get_acked_bytes(struct smbXsrv_connection *xconn,
1293
               uint64_t *_acked_bytes)
1294
0
{
1295
  /*
1296
   * Unless the kernel has an interface
1297
   * to reveal the number of un-acked bytes
1298
   * in the socket send queue, we'll assume
1299
   * everything is already acked.
1300
   *
1301
   * But that would mean that we better don't
1302
   * pretent to support multi-channel.
1303
   */
1304
0
  uint64_t unacked_bytes = 0;
1305
1306
0
  *_acked_bytes = 0;
1307
1308
0
  if (xconn->ack.force_unacked_timeout) {
1309
    /*
1310
     * Smbtorture tries to test channel failures...
1311
     * Just pretend nothing was acked...
1312
     */
1313
0
    DBG_INFO("Simulating channel failure: "
1314
0
       "xconn->ack.unacked_bytes[%llu]\n",
1315
0
       (unsigned long long)xconn->ack.unacked_bytes);
1316
0
    return NT_STATUS_OK;
1317
0
  }
1318
1319
0
#ifdef __IOCTL_SEND_QUEUE_SIZE_OPCODE
1320
0
  {
1321
0
    int value = 0;
1322
0
    int ret;
1323
1324
    /*
1325
     * If we have kernel support to get
1326
     * the number of bytes waiting in
1327
     * the socket's send queue, we
1328
     * use that in order to find out
1329
     * the number of unacked bytes.
1330
     */
1331
0
    ret = ioctl(xconn->transport.sock,
1332
0
          __IOCTL_SEND_QUEUE_SIZE_OPCODE,
1333
0
          &value);
1334
0
    if (ret != 0) {
1335
0
      int saved_errno = errno;
1336
0
      NTSTATUS status = map_nt_error_from_unix(saved_errno);
1337
0
      DBG_ERR("Failed to get the SEND_QUEUE_SIZE - "
1338
0
        "errno %d (%s) - %s\n",
1339
0
        saved_errno, strerror(saved_errno),
1340
0
        nt_errstr(status));
1341
0
      return status;
1342
0
    }
1343
1344
0
    if (value < 0) {
1345
0
      DBG_ERR("xconn->ack.unacked_bytes[%llu] value[%d]\n",
1346
0
        (unsigned long long)xconn->ack.unacked_bytes,
1347
0
        value);
1348
0
      return NT_STATUS_INTERNAL_ERROR;
1349
0
    }
1350
0
    unacked_bytes = value;
1351
0
  }
1352
0
#endif
1353
0
  if (xconn->ack.unacked_bytes == 0) {
1354
0
    xconn->ack.unacked_bytes = unacked_bytes;
1355
0
    return NT_STATUS_OK;
1356
0
  }
1357
1358
0
  if (xconn->ack.unacked_bytes < unacked_bytes) {
1359
0
    DBG_ERR("xconn->ack.unacked_bytes[%llu] unacked_bytes[%llu]\n",
1360
0
      (unsigned long long)xconn->ack.unacked_bytes,
1361
0
      (unsigned long long)unacked_bytes);
1362
0
    return NT_STATUS_INTERNAL_ERROR;
1363
0
  }
1364
1365
0
  *_acked_bytes = xconn->ack.unacked_bytes - unacked_bytes;
1366
0
  xconn->ack.unacked_bytes = unacked_bytes;
1367
0
  return NT_STATUS_OK;
1368
0
}
1369
1370
static void smbd_smb2_send_queue_ack_fail(struct smbd_smb2_send_queue **queue,
1371
            NTSTATUS status)
1372
0
{
1373
0
  struct smbd_smb2_send_queue *e = NULL;
1374
0
  struct smbd_smb2_send_queue *n = NULL;
1375
1376
0
  for (e = *queue; e != NULL; e = n) {
1377
0
    n = e->next;
1378
1379
0
    DLIST_REMOVE(*queue, e);
1380
0
    if (e->ack.req != NULL) {
1381
0
      tevent_req_nterror(e->ack.req, status);
1382
0
    }
1383
0
  }
1384
0
}
1385
1386
static NTSTATUS smbd_smb2_send_queue_ack_bytes(struct smbd_smb2_send_queue **queue,
1387
                 uint64_t acked_bytes)
1388
0
{
1389
0
  struct smbd_smb2_send_queue *e = NULL;
1390
0
  struct smbd_smb2_send_queue *n = NULL;
1391
1392
0
  for (e = *queue; e != NULL; e = n) {
1393
0
    bool expired;
1394
1395
0
    n = e->next;
1396
1397
0
    if (e->ack.req == NULL) {
1398
0
      continue;
1399
0
    }
1400
1401
0
    if (e->ack.required_acked_bytes <= acked_bytes) {
1402
0
      e->ack.required_acked_bytes = 0;
1403
0
      DLIST_REMOVE(*queue, e);
1404
0
      tevent_req_done(e->ack.req);
1405
0
      continue;
1406
0
    }
1407
0
    e->ack.required_acked_bytes -= acked_bytes;
1408
1409
0
    expired = timeval_expired(&e->ack.timeout);
1410
0
    if (expired) {
1411
0
      return NT_STATUS_IO_TIMEOUT;
1412
0
    }
1413
0
  }
1414
1415
0
  return NT_STATUS_OK;
1416
0
}
1417
1418
static NTSTATUS smbd_smb2_check_ack_queue(struct smbXsrv_connection *xconn)
1419
0
{
1420
0
  uint64_t acked_bytes = 0;
1421
0
  NTSTATUS status;
1422
1423
0
  status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1424
0
  if (!NT_STATUS_IS_OK(status)) {
1425
0
    return status;
1426
0
  }
1427
1428
0
  status = smbd_smb2_send_queue_ack_bytes(&xconn->ack.queue, acked_bytes);
1429
0
  if (!NT_STATUS_IS_OK(status)) {
1430
0
    return status;
1431
0
  }
1432
1433
0
  status = smbd_smb2_send_queue_ack_bytes(&xconn->smb2.send_queue, 0);
1434
0
  if (!NT_STATUS_IS_OK(status)) {
1435
0
    return status;
1436
0
  }
1437
1438
0
  return NT_STATUS_OK;
1439
0
}
1440
1441
static void smbXsrv_connection_ack_checker(struct tevent_req *subreq)
1442
0
{
1443
0
  struct smbXsrv_connection *xconn =
1444
0
    tevent_req_callback_data(subreq,
1445
0
    struct smbXsrv_connection);
1446
0
  struct smbXsrv_client *client = xconn->client;
1447
0
  struct timeval next_check;
1448
0
  NTSTATUS status;
1449
0
  bool ok;
1450
1451
0
  xconn->ack.checker_subreq = NULL;
1452
1453
0
  ok = tevent_wakeup_recv(subreq);
1454
0
  TALLOC_FREE(subreq);
1455
0
  if (!ok) {
1456
0
    smbd_server_connection_terminate(xconn,
1457
0
             "tevent_wakeup_recv() failed");
1458
0
    return;
1459
0
  }
1460
1461
0
  status = smbd_smb2_check_ack_queue(xconn);
1462
0
  if (!NT_STATUS_IS_OK(status)) {
1463
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
1464
0
    return;
1465
0
  }
1466
1467
0
  next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1468
0
  xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1469
0
                   client->raw_ev_ctx,
1470
0
                   next_check);
1471
0
  if (xconn->ack.checker_subreq == NULL) {
1472
0
    smbd_server_connection_terminate(xconn,
1473
0
             "tevent_wakeup_send() failed");
1474
0
    return;
1475
0
  }
1476
0
  tevent_req_set_callback(xconn->ack.checker_subreq,
1477
0
        smbXsrv_connection_ack_checker,
1478
0
        xconn);
1479
0
}
1480
1481
static NTSTATUS smbXsrv_client_pending_breaks_updated(struct smbXsrv_client *client)
1482
0
{
1483
0
  struct smbXsrv_connection *xconn = NULL;
1484
1485
0
  for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1486
0
    struct timeval next_check;
1487
0
    uint64_t acked_bytes = 0;
1488
0
    NTSTATUS status;
1489
1490
    /*
1491
     * A new 'pending break cycle' starts
1492
     * with a first pending break and lasts until
1493
     * all pending breaks are finished.
1494
     *
1495
     * This is typically a very short time,
1496
     * the value of one retransmission timeout.
1497
     */
1498
1499
0
    if (client->pending_breaks == NULL) {
1500
      /*
1501
       * No more pending breaks, remove a pending
1502
       * checker timer
1503
       */
1504
0
      TALLOC_FREE(xconn->ack.checker_subreq);
1505
0
      continue;
1506
0
    }
1507
1508
0
    if (xconn->ack.checker_subreq != NULL) {
1509
      /*
1510
       * The cycle already started =>
1511
       * nothing todo
1512
       */
1513
0
      continue;
1514
0
    }
1515
1516
    /*
1517
     * Get the current retransmission timeout value.
1518
     *
1519
     * It may change over time, but fetching it once
1520
     * per 'pending break' cycled should be enough.
1521
     */
1522
0
    status = smbXsrv_connection_get_rto_usecs(xconn,
1523
0
                &xconn->ack.rto_usecs);
1524
0
    if (!NT_STATUS_IS_OK(status)) {
1525
0
      return status;
1526
0
    }
1527
1528
    /*
1529
     * At the start of the cycle we reset the
1530
     * unacked_bytes counter (first to 0 and
1531
     * within smbXsrv_connection_get_acked_bytes()
1532
     * to the current value in the kernel
1533
     * send queue.
1534
     */
1535
0
    xconn->ack.unacked_bytes = 0;
1536
0
    status = smbXsrv_connection_get_acked_bytes(xconn, &acked_bytes);
1537
0
    if (!NT_STATUS_IS_OK(status)) {
1538
0
      return status;
1539
0
    }
1540
1541
    /*
1542
     * We setup a timer in order to check for
1543
     * acked bytes after one retransmission timeout.
1544
     *
1545
     * The code that sets up the send_queue.ack.timeout
1546
     * uses a multiple of the retransmission timeout.
1547
     */
1548
0
    next_check = timeval_current_ofs_usec(xconn->ack.rto_usecs);
1549
0
    xconn->ack.checker_subreq = tevent_wakeup_send(xconn,
1550
0
              client->raw_ev_ctx,
1551
0
              next_check);
1552
0
    if (xconn->ack.checker_subreq == NULL) {
1553
0
      return NT_STATUS_NO_MEMORY;
1554
0
    }
1555
0
    tevent_req_set_callback(xconn->ack.checker_subreq,
1556
0
          smbXsrv_connection_ack_checker,
1557
0
          xconn);
1558
0
  }
1559
1560
0
  return NT_STATUS_OK;
1561
0
}
1562
1563
void smbXsrv_connection_disconnect_transport(struct smbXsrv_connection *xconn,
1564
               NTSTATUS status)
1565
0
{
1566
0
  if (!NT_STATUS_IS_OK(xconn->transport.status)) {
1567
0
    return;
1568
0
  }
1569
1570
0
  xconn->transport.status = status;
1571
0
  TALLOC_FREE(xconn->transport.fde);
1572
0
  if (xconn->transport.sock != -1) {
1573
0
    xconn->transport.sock = -1;
1574
0
  }
1575
0
  smbd_smb2_send_queue_ack_fail(&xconn->ack.queue, status);
1576
0
  smbd_smb2_send_queue_ack_fail(&xconn->smb2.send_queue, status);
1577
0
  xconn->smb2.send_queue_len = 0;
1578
0
  DO_PROFILE_INC(disconnect);
1579
0
}
1580
1581
size_t smbXsrv_client_valid_connections(struct smbXsrv_client *client)
1582
0
{
1583
0
  struct smbXsrv_connection *xconn = NULL;
1584
0
  size_t num_ok = 0;
1585
1586
0
  for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
1587
0
    if (NT_STATUS_IS_OK(xconn->transport.status)) {
1588
0
      num_ok++;
1589
0
    }
1590
0
  }
1591
1592
0
  return num_ok;
1593
0
}
1594
1595
struct smbXsrv_connection_shutdown_state {
1596
  struct smbXsrv_connection *xconn;
1597
};
1598
1599
static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq);
1600
1601
static struct tevent_req *smbXsrv_connection_shutdown_send(TALLOC_CTX *mem_ctx,
1602
          struct tevent_context *ev,
1603
          struct smbXsrv_connection *xconn)
1604
0
{
1605
0
  struct tevent_req *req = NULL;
1606
0
  struct smbXsrv_connection_shutdown_state *state = NULL;
1607
0
  struct tevent_req *subreq = NULL;
1608
0
  size_t len = 0;
1609
0
  struct smbd_smb2_request *preq = NULL;
1610
0
  NTSTATUS status;
1611
1612
  /*
1613
   * The caller should have called
1614
   * smbXsrv_connection_disconnect_transport() before.
1615
   */
1616
0
  SMB_ASSERT(!NT_STATUS_IS_OK(xconn->transport.status));
1617
0
  SMB_ASSERT(xconn->transport.terminating);
1618
0
  SMB_ASSERT(xconn->transport.shutdown_wait_queue == NULL);
1619
1620
0
  req = tevent_req_create(mem_ctx, &state,
1621
0
        struct smbXsrv_connection_shutdown_state);
1622
0
  if (req == NULL) {
1623
0
    return NULL;
1624
0
  }
1625
1626
0
  state->xconn = xconn;
1627
0
  tevent_req_defer_callback(req, ev);
1628
1629
0
  xconn->transport.shutdown_wait_queue =
1630
0
    tevent_queue_create(state, "smbXsrv_connection_shutdown_queue");
1631
0
  if (tevent_req_nomem(xconn->transport.shutdown_wait_queue, req)) {
1632
0
    return tevent_req_post(req, ev);
1633
0
  }
1634
1635
0
  for (preq = xconn->smb2.requests; preq != NULL; preq = preq->next) {
1636
    /*
1637
     * Now wait until the request is finished.
1638
     *
1639
     * We don't set a callback, as we just want to block the
1640
     * wait queue and the talloc_free() of the request will
1641
     * remove the item from the wait queue.
1642
     *
1643
     * Note that we don't cancel the requests here
1644
     * in order to keep the replay detection logic correct.
1645
     *
1646
     * However if we teardown the last channel of
1647
     * a connection, we'll call some logic via
1648
     * smbXsrv_session_disconnect_xconn()
1649
     * -> smbXsrv_session_disconnect_xconn_callback()
1650
     *   -> smbXsrv_session_remove_channel()
1651
     *     -> smb2srv_session_shutdown_send()
1652
     * will indeed cancel the request.
1653
     */
1654
0
    subreq = tevent_queue_wait_send(preq, ev,
1655
0
          xconn->transport.shutdown_wait_queue);
1656
0
    if (tevent_req_nomem(subreq, req)) {
1657
0
      return tevent_req_post(req, ev);
1658
0
    }
1659
0
  }
1660
1661
  /*
1662
   * This may attach sessions with num_channels == 0
1663
   * to xconn->transport.shutdown_wait_queue.
1664
   */
1665
0
  status = smbXsrv_session_disconnect_xconn(xconn);
1666
0
  if (tevent_req_nterror(req, status)) {
1667
0
    return tevent_req_post(req, ev);
1668
0
  }
1669
1670
0
  len = tevent_queue_length(xconn->transport.shutdown_wait_queue);
1671
0
  if (len == 0) {
1672
0
    tevent_req_done(req);
1673
0
    return tevent_req_post(req, ev);
1674
0
  }
1675
1676
  /*
1677
   * Now we add our own waiter to the end of the queue,
1678
   * this way we get notified when all pending requests are finished
1679
   * and send to the socket.
1680
   */
1681
0
  subreq = tevent_queue_wait_send(state, ev, xconn->transport.shutdown_wait_queue);
1682
0
  if (tevent_req_nomem(subreq, req)) {
1683
0
    return tevent_req_post(req, ev);
1684
0
  }
1685
0
  tevent_req_set_callback(subreq, smbXsrv_connection_shutdown_wait_done, req);
1686
1687
0
  return req;
1688
0
}
1689
1690
static void smbXsrv_connection_shutdown_wait_done(struct tevent_req *subreq)
1691
0
{
1692
0
  struct tevent_req *req =
1693
0
    tevent_req_callback_data(subreq,
1694
0
    struct tevent_req);
1695
0
  struct smbXsrv_connection_shutdown_state *state =
1696
0
    tevent_req_data(req,
1697
0
    struct smbXsrv_connection_shutdown_state);
1698
0
  struct smbXsrv_connection *xconn = state->xconn;
1699
1700
0
  tevent_queue_wait_recv(subreq);
1701
0
  TALLOC_FREE(subreq);
1702
1703
0
  tevent_req_done(req);
1704
  /*
1705
   * make sure the xconn pointer is still valid,
1706
   * it should as we used tevent_req_defer_callback()
1707
   */
1708
0
  SMB_ASSERT(xconn->transport.terminating);
1709
0
}
1710
1711
static NTSTATUS smbXsrv_connection_shutdown_recv(struct tevent_req *req)
1712
0
{
1713
0
  struct smbXsrv_connection_shutdown_state *state =
1714
0
    tevent_req_data(req,
1715
0
    struct smbXsrv_connection_shutdown_state);
1716
0
  struct smbXsrv_connection *xconn = state->xconn;
1717
  /*
1718
   * make sure the xconn pointer is still valid,
1719
   * it should as we used tevent_req_defer_callback()
1720
   */
1721
0
  SMB_ASSERT(xconn->transport.terminating);
1722
0
  return tevent_req_simple_recv_ntstatus(req);
1723
0
}
1724
1725
struct smbd_server_connection_terminate_state {
1726
  struct smbXsrv_connection *xconn;
1727
  char *reason;
1728
};
1729
1730
static void smbd_server_connection_terminate_done(struct tevent_req *subreq)
1731
0
{
1732
0
  struct smbd_server_connection_terminate_state *state =
1733
0
    tevent_req_callback_data(
1734
0
      subreq,
1735
0
      struct smbd_server_connection_terminate_state);
1736
0
  struct smbXsrv_connection *xconn = state->xconn;
1737
0
  struct smbXsrv_client *client = xconn->client;
1738
0
  const char *reason = state->reason;
1739
0
  size_t num_ok;
1740
0
  NTSTATUS status;
1741
1742
0
  status = smbXsrv_connection_shutdown_recv(subreq);
1743
0
  TALLOC_FREE(subreq);
1744
0
  if (!NT_STATUS_IS_OK(status)) {
1745
0
    exit_server("smbXsrv_connection_shutdown_recv failed");
1746
0
  }
1747
1748
0
  DLIST_REMOVE(client->connections, xconn);
1749
0
  TALLOC_FREE(xconn);
1750
1751
0
  num_ok = smbXsrv_client_valid_connections(client);
1752
0
  if (num_ok > 0) {
1753
0
    return;
1754
0
  }
1755
1756
  /*
1757
   * The last connection was disconnected
1758
   */
1759
0
  exit_server_cleanly(reason);
1760
0
}
1761
1762
void smbd_server_connection_terminate_ex(struct smbXsrv_connection *xconn,
1763
           const char *reason,
1764
           const char *location)
1765
0
{
1766
0
  struct smbd_server_connection_terminate_state *state = NULL;
1767
0
  struct smbXsrv_client *client = xconn->client;
1768
0
  struct tevent_req *subreq = NULL;
1769
0
  size_t num_ok = 0;
1770
1771
0
  state = talloc_zero(xconn, struct smbd_server_connection_terminate_state);
1772
0
  if (state == NULL) {
1773
0
    exit_server("smbXsrv_connection_shutdown_send failed");
1774
0
  }
1775
0
  state->xconn = xconn;
1776
0
  state->reason = talloc_strdup(NULL, reason);
1777
0
  if (state->reason == NULL) {
1778
0
    exit_server("talloc_strdup failed");
1779
0
  }
1780
1781
  /*
1782
   * Make sure that no new request will be able to use this session.
1783
   *
1784
   * smbXsrv_connection_disconnect_transport() might be called already,
1785
   * but calling it again is a no-op.
1786
   */
1787
0
  smbXsrv_connection_disconnect_transport(xconn,
1788
0
          NT_STATUS_CONNECTION_DISCONNECTED);
1789
1790
0
  num_ok = smbXsrv_client_valid_connections(client);
1791
1792
0
  if (xconn->transport.terminating) {
1793
0
    DBG_DEBUG("skip recursion conn[%s] num_ok[%zu] reason[%s] at %s\n",
1794
0
        smbXsrv_connection_dbg(xconn), num_ok,
1795
0
        reason, location);
1796
0
    return;
1797
0
  }
1798
0
  xconn->transport.terminating = true;
1799
1800
0
  DBG_DEBUG("conn[%s] num_ok[%zu] reason[%s] at %s\n",
1801
0
      smbXsrv_connection_dbg(xconn), num_ok,
1802
0
      reason, location);
1803
1804
0
  if (xconn->has_cluster_movable_ip) {
1805
    /*
1806
     * If the connection has a movable cluster public address
1807
     * we disconnect all client connections,
1808
     * as the public address might be moved to
1809
     * a different node.
1810
     *
1811
     * In future we may recheck which node currently
1812
     * holds this address, but for now we keep it simple.
1813
     */
1814
0
    smbd_server_disconnect_client_ex(xconn->client,
1815
0
             reason,
1816
0
             location);
1817
0
    return;
1818
0
  }
1819
1820
0
  subreq = smbXsrv_connection_shutdown_send(client,
1821
0
              client->raw_ev_ctx,
1822
0
              xconn);
1823
0
  if (subreq == NULL) {
1824
0
    exit_server("smbXsrv_connection_shutdown_send failed");
1825
0
  }
1826
0
  tevent_req_set_callback(subreq,
1827
0
        smbd_server_connection_terminate_done,
1828
0
        state);
1829
0
  return;
1830
0
}
1831
1832
void smbd_server_disconnect_client_ex(struct smbXsrv_client *client,
1833
              const char *reason,
1834
              const char *location)
1835
0
{
1836
0
  size_t num_ok = 0;
1837
1838
0
  num_ok = smbXsrv_client_valid_connections(client);
1839
1840
0
  DBG_WARNING("client[%s] num_ok[%zu] reason[%s] at %s\n",
1841
0
        client->global->remote_address, num_ok,
1842
0
        reason, location);
1843
1844
  /*
1845
   * Something bad happened we need to disconnect all connections.
1846
   */
1847
0
  exit_server_cleanly(reason);
1848
0
}
1849
1850
static bool dup_smb2_vec4(TALLOC_CTX *ctx,
1851
      struct iovec *outvec,
1852
      const struct iovec *srcvec)
1853
0
{
1854
0
  const uint8_t *srctf;
1855
0
  size_t srctf_len;
1856
0
  const uint8_t *srchdr;
1857
0
  size_t srchdr_len;
1858
0
  const uint8_t *srcbody;
1859
0
  size_t srcbody_len;
1860
0
  const uint8_t *expected_srcbody;
1861
0
  const uint8_t *srcdyn;
1862
0
  size_t srcdyn_len;
1863
0
  const uint8_t *expected_srcdyn;
1864
0
  uint8_t *dsttf;
1865
0
  uint8_t *dsthdr;
1866
0
  uint8_t *dstbody;
1867
0
  uint8_t *dstdyn;
1868
1869
0
  srctf  = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
1870
0
  srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
1871
0
  srchdr  = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
1872
0
  srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
1873
0
  srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
1874
0
  srcbody_len = srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_len;
1875
0
  expected_srcbody = srchdr + SMB2_HDR_BODY;
1876
0
  srcdyn  = (const uint8_t *)srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_base;
1877
0
  srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
1878
0
  expected_srcdyn = srcbody + 8;
1879
1880
0
  if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
1881
0
    return false;
1882
0
  }
1883
1884
0
  if (srchdr_len != SMB2_HDR_BODY) {
1885
0
    return false;
1886
0
  }
1887
1888
0
  if (srctf_len == SMB2_TF_HDR_SIZE) {
1889
0
    dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
1890
0
    if (dsttf == NULL) {
1891
0
      return false;
1892
0
    }
1893
0
  } else {
1894
0
    dsttf = NULL;
1895
0
  }
1896
0
  outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
1897
0
  outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
1898
1899
  /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
1900
   * be allocated with size OUTVEC_ALLOC_SIZE. */
1901
1902
0
  dsthdr = talloc_memdup(ctx, srchdr, OUTVEC_ALLOC_SIZE);
1903
0
  if (dsthdr == NULL) {
1904
0
    return false;
1905
0
  }
1906
0
  outvec[SMBD_SMB2_HDR_IOV_OFS].iov_base = (void *)dsthdr;
1907
0
  outvec[SMBD_SMB2_HDR_IOV_OFS].iov_len = SMB2_HDR_BODY;
1908
1909
  /*
1910
   * If this is a "standard" vec[SMBD_SMB2_BOFY_IOV_OFS] of length 8,
1911
   * pointing to srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + SMB2_HDR_BODY,
1912
   * then duplicate this. Else use talloc_memdup().
1913
   */
1914
1915
0
  if ((srcbody == expected_srcbody) && (srcbody_len == 8)) {
1916
0
    dstbody = dsthdr + SMB2_HDR_BODY;
1917
0
  } else {
1918
0
    dstbody = talloc_memdup(ctx, srcbody, srcbody_len);
1919
0
    if (dstbody == NULL) {
1920
0
      return false;
1921
0
    }
1922
0
  }
1923
0
  outvec[SMBD_SMB2_BODY_IOV_OFS].iov_base = (void *)dstbody;
1924
0
  outvec[SMBD_SMB2_BODY_IOV_OFS].iov_len = srcbody_len;
1925
1926
  /*
1927
   * If this is a "standard" vec[SMBD_SMB2_DYN_IOV_OFS] of length 1,
1928
   * pointing to
1929
   * srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base + 8
1930
   * then duplicate this. Else use talloc_memdup().
1931
   */
1932
1933
0
  if ((srcdyn == expected_srcdyn) && (srcdyn_len == 1)) {
1934
0
    dstdyn = dsthdr + SMB2_HDR_BODY + 8;
1935
0
  } else if (srcdyn == NULL) {
1936
0
    dstdyn = NULL;
1937
0
  } else {
1938
0
    dstdyn = talloc_memdup(ctx, srcdyn, srcdyn_len);
1939
0
    if (dstdyn == NULL) {
1940
0
      return false;
1941
0
    }
1942
0
  }
1943
0
  outvec[SMBD_SMB2_DYN_IOV_OFS].iov_base = (void *)dstdyn;
1944
0
  outvec[SMBD_SMB2_DYN_IOV_OFS].iov_len = srcdyn_len;
1945
1946
0
  return true;
1947
0
}
1948
1949
static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *req)
1950
0
{
1951
0
  struct smbd_smb2_request *newreq = NULL;
1952
0
  struct iovec *outvec = NULL;
1953
0
  int count = req->out.vector_count;
1954
0
  int i;
1955
0
  bool ok;
1956
1957
0
  newreq = smbd_smb2_request_allocate(req->xconn);
1958
0
  if (!newreq) {
1959
0
    return NULL;
1960
0
  }
1961
1962
0
  newreq->session = req->session;
1963
0
  newreq->do_encryption = req->do_encryption;
1964
0
  newreq->do_signing = req->do_signing;
1965
0
  newreq->current_idx = req->current_idx;
1966
1967
0
  outvec = talloc_zero_array(newreq, struct iovec, count);
1968
0
  if (!outvec) {
1969
0
    TALLOC_FREE(newreq);
1970
0
    return NULL;
1971
0
  }
1972
0
  newreq->out.vector = outvec;
1973
0
  newreq->out.vector_count = count;
1974
1975
  /* Setup the outvec's identically to req. */
1976
0
  outvec[0].iov_base = newreq->out.nbt_hdr;
1977
0
  outvec[0].iov_len = 4;
1978
0
  memcpy(newreq->out.nbt_hdr, req->out.nbt_hdr, 4);
1979
1980
  /* Setup the vectors identically to the ones in req. */
1981
0
  for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
1982
0
    if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
1983
0
      break;
1984
0
    }
1985
0
  }
1986
1987
0
  if (i < count) {
1988
    /* Alloc failed. */
1989
0
    TALLOC_FREE(newreq);
1990
0
    return NULL;
1991
0
  }
1992
1993
0
  ok = smb2_setup_nbt_length(newreq->out.vector,
1994
0
           newreq->out.vector_count);
1995
0
  if (!ok) {
1996
0
    TALLOC_FREE(newreq);
1997
0
    return NULL;
1998
0
  }
1999
2000
0
  return newreq;
2001
0
}
2002
2003
static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request *req)
2004
0
{
2005
0
  struct smbXsrv_connection *xconn = req->xconn;
2006
0
  int first_idx = 1;
2007
0
  struct iovec *firsttf = NULL;
2008
0
  struct iovec *outhdr_v = NULL;
2009
0
  uint8_t *outhdr = NULL;
2010
0
  struct smbd_smb2_request *nreq = NULL;
2011
0
  NTSTATUS status;
2012
0
  bool ok;
2013
2014
  /* Create a new smb2 request we'll use
2015
     for the interim return. */
2016
0
  nreq = dup_smb2_req(req);
2017
0
  if (!nreq) {
2018
0
    return NT_STATUS_NO_MEMORY;
2019
0
  }
2020
2021
  /* Lose the last X out vectors. They're the
2022
     ones we'll be using for the async reply. */
2023
0
  nreq->out.vector_count -= SMBD_SMB2_NUM_IOV_PER_REQ;
2024
2025
0
  ok = smb2_setup_nbt_length(nreq->out.vector,
2026
0
           nreq->out.vector_count);
2027
0
  if (!ok) {
2028
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
2029
0
  }
2030
2031
  /* Step back to the previous reply. */
2032
0
  nreq->current_idx -= SMBD_SMB2_NUM_IOV_PER_REQ;
2033
0
  firsttf = SMBD_SMB2_IDX_TF_IOV(nreq,out,first_idx);
2034
0
  outhdr_v = SMBD_SMB2_OUT_HDR_IOV(nreq);
2035
0
  outhdr = SMBD_SMB2_OUT_HDR_PTR(nreq);
2036
  /* And end the chain. */
2037
0
  SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
2038
2039
  /* Calculate outgoing credits */
2040
0
  smb2_calculate_credits(req, nreq);
2041
2042
0
  if (DEBUGLEVEL >= 10) {
2043
0
    dbgtext("smb2_send_async_interim_response: nreq->current_idx = %u\n",
2044
0
      (unsigned int)nreq->current_idx );
2045
0
    dbgtext("smb2_send_async_interim_response: returning %u vectors\n",
2046
0
      (unsigned int)nreq->out.vector_count );
2047
0
    print_req_vectors(nreq);
2048
0
  }
2049
2050
  /*
2051
   * As we have changed the header (SMB2_HDR_NEXT_COMMAND),
2052
   * we need to sign/encrypt here with the last/first key we remembered
2053
   */
2054
0
  if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
2055
0
    status = smb2_signing_encrypt_pdu(req->first_enc_key,
2056
0
          firsttf,
2057
0
          nreq->out.vector_count - first_idx);
2058
0
    if (!NT_STATUS_IS_OK(status)) {
2059
0
      return status;
2060
0
    }
2061
0
  } else if (smb2_signing_key_valid(req->last_sign_key)) {
2062
0
    status = smb2_signing_sign_pdu(req->last_sign_key,
2063
0
                 outhdr_v,
2064
0
                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
2065
0
    if (!NT_STATUS_IS_OK(status)) {
2066
0
      return status;
2067
0
    }
2068
0
  }
2069
2070
0
  nreq->queue_entry.mem_ctx = nreq;
2071
0
  nreq->queue_entry.vector = nreq->out.vector;
2072
0
  nreq->queue_entry.count = nreq->out.vector_count;
2073
0
  DLIST_ADD_END(xconn->smb2.send_queue, &nreq->queue_entry);
2074
0
  xconn->smb2.send_queue_len++;
2075
2076
0
  status = smbd_smb2_flush_send_queue(xconn);
2077
0
  if (!NT_STATUS_IS_OK(status)) {
2078
0
    return status;
2079
0
  }
2080
2081
0
  return NT_STATUS_OK;
2082
0
}
2083
2084
struct smbd_smb2_request_pending_state {
2085
  struct smbd_smb2_send_queue queue_entry;
2086
        uint8_t buf[NBT_HDR_SIZE + SMB2_TF_HDR_SIZE + SMB2_HDR_BODY + 0x08 + 1];
2087
        struct iovec vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
2088
};
2089
2090
static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
2091
              struct tevent_timer *te,
2092
              struct timeval current_time,
2093
              void *private_data);
2094
2095
NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
2096
           struct tevent_req *subreq,
2097
           uint32_t defer_time)
2098
0
{
2099
0
  NTSTATUS status;
2100
0
  struct timeval defer_endtime;
2101
0
  uint8_t *outhdr = NULL;
2102
0
  uint32_t flags;
2103
2104
0
  if (!tevent_req_is_in_progress(subreq)) {
2105
    /*
2106
     * This is a performance optimization,
2107
     * it avoids one tevent_loop iteration,
2108
     * which means we avoid one
2109
     * talloc_stackframe_pool/talloc_free pair.
2110
     */
2111
0
    tevent_req_notify_callback(subreq);
2112
0
    return NT_STATUS_OK;
2113
0
  }
2114
2115
0
  req->subreq = subreq;
2116
0
  subreq = NULL;
2117
2118
0
  if (req->async_te) {
2119
    /* We're already async. */
2120
0
    return NT_STATUS_OK;
2121
0
  }
2122
2123
0
  outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2124
0
  flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2125
0
  if (flags & SMB2_HDR_FLAG_ASYNC) {
2126
    /* We're already async. */
2127
0
    return NT_STATUS_OK;
2128
0
  }
2129
2130
0
  if (req->async_internal || defer_time == 0) {
2131
    /*
2132
     * An SMB2 request implementation wants to handle the request
2133
     * asynchronously "internally" while keeping synchronous
2134
     * behaviour for the SMB2 request. This means we don't send an
2135
     * interim response and we can allow processing of compound SMB2
2136
     * requests (cf the subsequent check) for all cases.
2137
     */
2138
0
    return NT_STATUS_OK;
2139
0
  }
2140
2141
0
  if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
2142
    /*
2143
     * We're trying to go async in a compound request
2144
     * chain. This is only allowed for opens that cause an
2145
     * oplock break or for the last operation in the
2146
     * chain, otherwise it is not allowed. See
2147
     * [MS-SMB2].pdf note <206> on Section 3.3.5.2.7.
2148
     */
2149
0
    const uint8_t *inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2150
2151
0
    if (SVAL(inhdr, SMB2_HDR_OPCODE) != SMB2_OP_CREATE) {
2152
      /*
2153
       * Cancel the outstanding request.
2154
       */
2155
0
      bool ok = tevent_req_cancel(req->subreq);
2156
0
      if (ok) {
2157
0
        return NT_STATUS_OK;
2158
0
      }
2159
0
      TALLOC_FREE(req->subreq);
2160
0
      return smbd_smb2_request_error(req,
2161
0
        NT_STATUS_INTERNAL_ERROR);
2162
0
    }
2163
0
  }
2164
2165
0
  if (DEBUGLEVEL >= 10) {
2166
0
    dbgtext("smbd_smb2_request_pending_queue: req->current_idx = %u\n",
2167
0
      (unsigned int)req->current_idx );
2168
0
    print_req_vectors(req);
2169
0
  }
2170
2171
0
  if (req->current_idx > 1) {
2172
    /*
2173
     * We're going async in a compound
2174
     * chain after the first request has
2175
     * already been processed. Send an
2176
     * interim response containing the
2177
     * set of replies already generated.
2178
     */
2179
0
    int idx = req->current_idx;
2180
2181
0
    status = smb2_send_async_interim_response(req);
2182
0
    if (!NT_STATUS_IS_OK(status)) {
2183
0
      return status;
2184
0
    }
2185
0
    TALLOC_FREE(req->first_enc_key);
2186
2187
0
    req->current_idx = 1;
2188
2189
    /*
2190
     * Re-arrange the in.vectors to remove what
2191
     * we just sent.
2192
     */
2193
0
    memmove(&req->in.vector[1],
2194
0
      &req->in.vector[idx],
2195
0
      sizeof(req->in.vector[0])*(req->in.vector_count - idx));
2196
0
    req->in.vector_count = 1 + (req->in.vector_count - idx);
2197
2198
    /* Re-arrange the out.vectors to match. */
2199
0
    memmove(&req->out.vector[1],
2200
0
      &req->out.vector[idx],
2201
0
      sizeof(req->out.vector[0])*(req->out.vector_count - idx));
2202
0
    req->out.vector_count = 1 + (req->out.vector_count - idx);
2203
2204
0
    if (req->in.vector_count == 1 + SMBD_SMB2_NUM_IOV_PER_REQ) {
2205
      /*
2206
       * We only have one remaining request as
2207
       * we've processed everything else.
2208
       * This is no longer a compound request.
2209
       */
2210
0
      req->compound_related = false;
2211
0
      outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2212
0
      flags = (IVAL(outhdr, SMB2_HDR_FLAGS) & ~SMB2_HDR_FLAG_CHAINED);
2213
0
      SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
2214
0
    }
2215
0
  }
2216
0
  TALLOC_FREE(req->last_sign_key);
2217
2218
  /*
2219
   * smbd_smb2_request_pending_timer() just send a packet
2220
   * to the client and doesn't need any impersonation.
2221
   * So we use req->xconn->client->raw_ev_ctx instead
2222
   * of req->ev_ctx here.
2223
   */
2224
0
  defer_endtime = timeval_current_ofs_usec(defer_time);
2225
0
  req->async_te = tevent_add_timer(req->xconn->client->raw_ev_ctx,
2226
0
           req, defer_endtime,
2227
0
           smbd_smb2_request_pending_timer,
2228
0
           req);
2229
0
  if (req->async_te == NULL) {
2230
0
    return NT_STATUS_NO_MEMORY;
2231
0
  }
2232
2233
0
  return NT_STATUS_OK;
2234
0
}
2235
2236
static
2237
struct smb2_signing_key *smbd_smb2_signing_key(struct smbXsrv_session *session,
2238
                 struct smbXsrv_connection *xconn,
2239
                 bool *_has_channel)
2240
0
{
2241
0
  struct smbXsrv_channel_global0 *c = NULL;
2242
0
  NTSTATUS status;
2243
0
  struct smb2_signing_key *key = NULL;
2244
0
  bool has_channel = false;
2245
2246
0
  status = smbXsrv_session_find_channel(session, xconn, &c);
2247
0
  if (NT_STATUS_IS_OK(status)) {
2248
0
    key = c->signing_key;
2249
0
    has_channel = true;
2250
0
  }
2251
2252
0
  if (!smb2_signing_key_valid(key)) {
2253
0
    key = session->global->signing_key;
2254
0
    has_channel = false;
2255
0
  }
2256
2257
0
  if (_has_channel != NULL) {
2258
0
    *_has_channel = has_channel;
2259
0
  }
2260
2261
0
  return key;
2262
0
}
2263
2264
static NTSTATUS smb2_get_new_nonce(struct smbXsrv_session *session,
2265
           uint64_t *new_nonce_high,
2266
           uint64_t *new_nonce_low)
2267
0
{
2268
0
  uint64_t nonce_high;
2269
0
  uint64_t nonce_low;
2270
2271
0
  session->nonce_low += 1;
2272
0
  if (session->nonce_low == 0) {
2273
0
    session->nonce_low += 1;
2274
0
    session->nonce_high += 1;
2275
0
  }
2276
2277
  /*
2278
   * CCM and GCM algorithms must never have their
2279
   * nonce wrap, or the security of the whole
2280
   * communication and the keys is destroyed.
2281
   * We must drop the connection once we have
2282
   * transferred too much data.
2283
   *
2284
   * NOTE: We assume nonces greater than 8 bytes.
2285
   */
2286
0
  if (session->nonce_high >= session->nonce_high_max) {
2287
0
    return NT_STATUS_ENCRYPTION_FAILED;
2288
0
  }
2289
2290
0
  nonce_high = session->nonce_high_random;
2291
0
  nonce_high += session->nonce_high;
2292
0
  nonce_low = session->nonce_low;
2293
2294
0
  *new_nonce_high = nonce_high;
2295
0
  *new_nonce_low = nonce_low;
2296
0
  return NT_STATUS_OK;
2297
0
}
2298
2299
static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
2300
              struct tevent_timer *te,
2301
              struct timeval current_time,
2302
              void *private_data)
2303
0
{
2304
0
  struct smbd_smb2_request *req =
2305
0
    talloc_get_type_abort(private_data,
2306
0
    struct smbd_smb2_request);
2307
0
  struct smbXsrv_connection *xconn = req->xconn;
2308
0
  struct smbd_smb2_request_pending_state *state = NULL;
2309
0
  uint8_t *outhdr = NULL;
2310
0
  const uint8_t *inhdr = NULL;
2311
0
  uint8_t *tf = NULL;
2312
0
  uint8_t *hdr = NULL;
2313
0
  uint8_t *body = NULL;
2314
0
  uint8_t *dyn = NULL;
2315
0
  uint32_t flags = 0;
2316
0
  uint64_t message_id = 0;
2317
0
  uint64_t async_id = 0;
2318
0
  NTSTATUS status;
2319
0
  bool ok;
2320
2321
0
  TALLOC_FREE(req->async_te);
2322
2323
  /* Ensure our final reply matches the interim one. */
2324
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2325
0
  outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
2326
0
  flags = IVAL(outhdr, SMB2_HDR_FLAGS);
2327
0
  message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2328
2329
0
  async_id = message_id; /* keep it simple for now... */
2330
2331
0
  SIVAL(outhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2332
0
  SBVAL(outhdr, SMB2_HDR_ASYNC_ID, async_id);
2333
2334
0
  DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
2335
0
    "going async\n",
2336
0
    smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2337
0
    (unsigned long long)async_id ));
2338
2339
  /*
2340
   * What we send is identical to a smbd_smb2_request_error
2341
   * packet with an error status of STATUS_PENDING. Make use
2342
   * of this fact sometime when refactoring. JRA.
2343
   */
2344
2345
0
  state = talloc_zero(req->xconn, struct smbd_smb2_request_pending_state);
2346
0
  if (state == NULL) {
2347
0
    smbd_server_connection_terminate(xconn,
2348
0
             nt_errstr(NT_STATUS_NO_MEMORY));
2349
0
    return;
2350
0
  }
2351
2352
0
  tf = state->buf + NBT_HDR_SIZE;
2353
2354
0
  hdr = tf + SMB2_TF_HDR_SIZE;
2355
0
  body = hdr + SMB2_HDR_BODY;
2356
0
  dyn = body + 8;
2357
2358
0
  if (req->do_encryption) {
2359
0
    uint64_t nonce_high = 0;
2360
0
    uint64_t nonce_low = 0;
2361
0
    uint64_t session_id = req->session->global->session_wire_id;
2362
2363
0
    status = smb2_get_new_nonce(req->session,
2364
0
              &nonce_high,
2365
0
              &nonce_low);
2366
0
    if (!NT_STATUS_IS_OK(status)) {
2367
0
      smbd_server_connection_terminate(xconn,
2368
0
               nt_errstr(status));
2369
0
      return;
2370
0
    }
2371
2372
0
    SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
2373
0
    SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
2374
0
    SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
2375
0
    SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
2376
0
  }
2377
2378
0
  SIVAL(hdr, SMB2_HDR_PROTOCOL_ID, SMB2_MAGIC);
2379
0
  SSVAL(hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
2380
0
  SSVAL(hdr, SMB2_HDR_EPOCH, 0);
2381
0
  SIVAL(hdr, SMB2_HDR_STATUS, NT_STATUS_V(NT_STATUS_PENDING));
2382
0
  SSVAL(hdr, SMB2_HDR_OPCODE, SVAL(outhdr, SMB2_HDR_OPCODE));
2383
2384
  /*
2385
   * The STATUS_PENDING response has SMB2_HDR_FLAG_SIGNED
2386
   * clearedm, but echoes the signature field.
2387
   */
2388
0
  flags &= ~SMB2_HDR_FLAG_SIGNED;
2389
0
  SIVAL(hdr, SMB2_HDR_FLAGS, flags);
2390
0
  SIVAL(hdr, SMB2_HDR_NEXT_COMMAND, 0);
2391
0
  SBVAL(hdr, SMB2_HDR_MESSAGE_ID, message_id);
2392
0
  SBVAL(hdr, SMB2_HDR_PID, async_id);
2393
0
  SBVAL(hdr, SMB2_HDR_SESSION_ID,
2394
0
    BVAL(outhdr, SMB2_HDR_SESSION_ID));
2395
0
  memcpy(hdr+SMB2_HDR_SIGNATURE,
2396
0
         outhdr+SMB2_HDR_SIGNATURE, 16);
2397
2398
0
  SSVAL(body, 0x00, 0x08 + 1);
2399
2400
0
  SCVAL(body, 0x02, 0);
2401
0
  SCVAL(body, 0x03, 0);
2402
0
  SIVAL(body, 0x04, 0);
2403
  /* Match W2K8R2... */
2404
0
  SCVAL(dyn,  0x00, 0x21);
2405
2406
0
  state->vector[0].iov_base = (void *)state->buf;
2407
0
  state->vector[0].iov_len = NBT_HDR_SIZE;
2408
2409
0
  if (req->do_encryption) {
2410
0
    state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
2411
0
    state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    =
2412
0
              SMB2_TF_HDR_SIZE;
2413
0
  } else {
2414
0
    state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
2415
0
    state->vector[1+SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
2416
0
  }
2417
2418
0
  state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
2419
0
  state->vector[1+SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
2420
2421
0
  state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
2422
0
  state->vector[1+SMBD_SMB2_BODY_IOV_OFS].iov_len  = 8;
2423
2424
0
  state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_base  = dyn;
2425
0
  state->vector[1+SMBD_SMB2_DYN_IOV_OFS].iov_len   = 1;
2426
2427
0
  ok = smb2_setup_nbt_length(state->vector,
2428
0
           1 + SMBD_SMB2_NUM_IOV_PER_REQ);
2429
0
  if (!ok) {
2430
0
    smbd_server_connection_terminate(
2431
0
      xconn, nt_errstr(NT_STATUS_INTERNAL_ERROR));
2432
0
    return;
2433
0
  }
2434
2435
  /* Ensure we correctly go through crediting. Grant
2436
     the credits now, and zero credits on the final
2437
     response. */
2438
0
  smb2_set_operation_credit(req->xconn,
2439
0
      SMBD_SMB2_IN_HDR_IOV(req),
2440
0
      &state->vector[1+SMBD_SMB2_HDR_IOV_OFS]);
2441
2442
  /*
2443
   * We add SMB2_HDR_FLAG_ASYNC after smb2_set_operation_credit()
2444
   * as it reacts on it
2445
   */
2446
0
  SIVAL(hdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
2447
2448
0
  if (DEBUGLVL(10)) {
2449
0
    int i;
2450
2451
0
    for (i = 0; i < ARRAY_SIZE(state->vector); i++) {
2452
0
      dbgtext("\tstate->vector[%u/%u].iov_len = %u\n",
2453
0
        (unsigned int)i,
2454
0
        (unsigned int)ARRAY_SIZE(state->vector),
2455
0
        (unsigned int)state->vector[i].iov_len);
2456
0
    }
2457
0
  }
2458
2459
0
  if (req->do_encryption) {
2460
0
    struct smbXsrv_session *x = req->session;
2461
0
    struct smb2_signing_key *encryption_key = x->global->encryption_key;
2462
2463
0
    status = smb2_signing_encrypt_pdu(encryption_key,
2464
0
          &state->vector[1+SMBD_SMB2_TF_IOV_OFS],
2465
0
          SMBD_SMB2_NUM_IOV_PER_REQ);
2466
0
    if (!NT_STATUS_IS_OK(status)) {
2467
0
      smbd_server_connection_terminate(xconn,
2468
0
            nt_errstr(status));
2469
0
      return;
2470
0
    }
2471
0
  }
2472
2473
0
  state->queue_entry.mem_ctx = state;
2474
0
  state->queue_entry.vector = state->vector;
2475
0
  state->queue_entry.count = ARRAY_SIZE(state->vector);
2476
0
  DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
2477
0
  xconn->smb2.send_queue_len++;
2478
2479
0
  status = smbd_smb2_flush_send_queue(xconn);
2480
0
  if (!NT_STATUS_IS_OK(status)) {
2481
0
    smbd_server_connection_terminate(xconn,
2482
0
             nt_errstr(status));
2483
0
    return;
2484
0
  }
2485
0
}
2486
2487
static NTSTATUS smbd_smb2_request_process_cancel(struct smbd_smb2_request *req)
2488
0
{
2489
0
  struct smbXsrv_connection *xconn = req->xconn;
2490
0
  struct smbd_smb2_request *cur;
2491
0
  const uint8_t *inhdr;
2492
0
  uint32_t flags;
2493
0
  uint64_t search_message_id;
2494
0
  uint64_t search_async_id;
2495
0
  uint64_t found_id = 0;
2496
2497
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2498
2499
0
  flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2500
0
  search_message_id = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
2501
0
  search_async_id = BVAL(inhdr, SMB2_HDR_PID);
2502
2503
  /*
2504
   * We don't need the request anymore cancel requests never
2505
   * have a response.
2506
   *
2507
   * We defer the TALLOC_FREE(req) to the caller.
2508
   */
2509
0
  DLIST_REMOVE(xconn->smb2.requests, req);
2510
2511
0
  for (cur = xconn->smb2.requests; cur; cur = cur->next) {
2512
0
    const uint8_t *outhdr;
2513
0
    uint64_t message_id;
2514
0
    uint64_t async_id;
2515
2516
0
    if (cur->session != req->session) {
2517
0
      continue;
2518
0
    }
2519
2520
0
    if (cur->compound_related) {
2521
      /*
2522
       * Never cancel anything in a compound request.
2523
       * Way too hard to deal with the result.
2524
       */
2525
0
      continue;
2526
0
    }
2527
2528
0
    outhdr = SMBD_SMB2_OUT_HDR_PTR(cur);
2529
2530
0
    message_id = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
2531
0
    async_id = BVAL(outhdr, SMB2_HDR_PID);
2532
2533
0
    if (flags & SMB2_HDR_FLAG_ASYNC) {
2534
0
      if (search_async_id == async_id) {
2535
0
        found_id = async_id;
2536
0
        break;
2537
0
      }
2538
0
    } else {
2539
0
      if (search_message_id == message_id) {
2540
0
        found_id = message_id;
2541
0
        break;
2542
0
      }
2543
0
    }
2544
0
  }
2545
2546
0
  if (cur && cur->subreq) {
2547
0
    inhdr = SMBD_SMB2_IN_HDR_PTR(cur);
2548
0
    DEBUG(10,("smbd_smb2_request_process_cancel: attempting to "
2549
0
      "cancel opcode[%s] mid %llu\n",
2550
0
      smb2_opcode_name(SVAL(inhdr, SMB2_HDR_OPCODE)),
2551
0
                        (unsigned long long)found_id ));
2552
0
    tevent_req_cancel(cur->subreq);
2553
0
  }
2554
2555
0
  return NT_STATUS_OK;
2556
0
}
2557
2558
/*************************************************************
2559
 Ensure an incoming tid is a valid one for us to access.
2560
 Change to the associated uid credentials and chdir to the
2561
 valid tid directory.
2562
*************************************************************/
2563
2564
static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
2565
0
{
2566
0
  const uint8_t *inhdr;
2567
0
  uint32_t in_flags;
2568
0
  uint32_t in_tid;
2569
0
  struct smbXsrv_tcon *tcon;
2570
0
  NTSTATUS status;
2571
0
  NTTIME now = timeval_to_nttime(&req->request_time);
2572
2573
0
  req->tcon = NULL;
2574
2575
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2576
2577
0
  in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2578
0
  in_tid = IVAL(inhdr, SMB2_HDR_TID);
2579
2580
0
  if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2581
0
    in_tid = req->last_tid;
2582
0
  }
2583
2584
0
  req->last_tid = 0;
2585
2586
0
  status = smb2srv_tcon_lookup(req->session,
2587
0
             in_tid, now, &tcon);
2588
0
  if (!NT_STATUS_IS_OK(status)) {
2589
0
    return status;
2590
0
  }
2591
2592
0
  if (!change_to_user_and_service(
2593
0
        tcon->compat,
2594
0
        req->session->global->session_wire_id))
2595
0
  {
2596
0
    return NT_STATUS_ACCESS_DENIED;
2597
0
  }
2598
2599
0
  req->tcon = tcon;
2600
0
  req->last_tid = in_tid;
2601
2602
0
  return NT_STATUS_OK;
2603
0
}
2604
2605
/*************************************************************
2606
 Ensure an incoming session_id is a valid one for us to access.
2607
*************************************************************/
2608
2609
static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
2610
0
{
2611
0
  const uint8_t *inhdr;
2612
0
  uint32_t in_flags;
2613
0
  uint16_t in_opcode;
2614
0
  uint64_t in_session_id;
2615
0
  struct smbXsrv_session *session = NULL;
2616
0
  struct auth_session_info *session_info;
2617
0
  NTSTATUS status;
2618
0
  NTTIME now = timeval_to_nttime(&req->request_time);
2619
2620
0
  req->session = NULL;
2621
0
  req->tcon = NULL;
2622
2623
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2624
2625
0
  in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2626
0
  in_opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2627
0
  in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
2628
2629
0
  if (in_flags & SMB2_HDR_FLAG_CHAINED) {
2630
0
    in_session_id = req->last_session_id;
2631
0
  }
2632
2633
0
  req->last_session_id = 0;
2634
2635
  /* look an existing session up */
2636
0
  switch (in_opcode) {
2637
0
  case SMB2_OP_SESSSETUP:
2638
    /*
2639
     * For a session bind request, we don't have the
2640
     * channel set up at this point yet, so we defer
2641
     * the verification that the connection belongs
2642
     * to the session to the session setup code, which
2643
     * can look at the session binding flags.
2644
     */
2645
0
    status = smb2srv_session_lookup_client(req->xconn->client,
2646
0
                   in_session_id, now,
2647
0
                   &session);
2648
0
    break;
2649
0
  default:
2650
0
    status = smb2srv_session_lookup_conn(req->xconn,
2651
0
                 in_session_id, now,
2652
0
                 &session);
2653
0
    break;
2654
0
  }
2655
0
  if (session) {
2656
0
    req->session = session;
2657
0
    req->last_session_id = in_session_id;
2658
0
  }
2659
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
2660
0
    switch (in_opcode) {
2661
0
    case SMB2_OP_SESSSETUP:
2662
0
      status = smb2srv_session_lookup_global(req->xconn->client,
2663
0
                     in_session_id,
2664
0
                     req,
2665
0
                     &session);
2666
0
      if (NT_STATUS_IS_OK(status)) {
2667
        /*
2668
         * We fallback to a session of
2669
         * another process in order to
2670
         * get the signing correct.
2671
         *
2672
         * We don't set req->last_session_id here.
2673
         */
2674
0
        req->session = session;
2675
0
      }
2676
0
      break;
2677
0
    default:
2678
0
      break;
2679
0
    }
2680
0
  }
2681
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
2682
0
    switch (in_opcode) {
2683
0
    case SMB2_OP_SESSSETUP:
2684
0
      status = NT_STATUS_OK;
2685
0
      break;
2686
0
    case SMB2_OP_LOGOFF:
2687
0
    case SMB2_OP_CLOSE:
2688
0
    case SMB2_OP_LOCK:
2689
0
    case SMB2_OP_CANCEL:
2690
0
    case SMB2_OP_KEEPALIVE:
2691
      /*
2692
       * [MS-SMB2] 3.3.5.2.9 Verifying the Session
2693
       * specifies that LOGOFF, CLOSE and (UN)LOCK
2694
       * should always be processed even on expired sessions.
2695
       *
2696
       * Also see the logic in
2697
       * smbd_smb2_request_process_lock().
2698
       *
2699
       * The smb2.session.expire2 test shows that
2700
       * CANCEL and KEEPALIVE/ECHO should also
2701
       * be processed.
2702
       */
2703
0
      status = NT_STATUS_OK;
2704
0
      break;
2705
0
    default:
2706
0
      break;
2707
0
    }
2708
0
  }
2709
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
2710
0
    switch (in_opcode) {
2711
0
    case SMB2_OP_TCON:
2712
0
    case SMB2_OP_CREATE:
2713
0
    case SMB2_OP_GETINFO:
2714
0
    case SMB2_OP_SETINFO:
2715
0
      return NT_STATUS_INVALID_HANDLE;
2716
0
    default:
2717
      /*
2718
       * Notice the check for
2719
       * (session_info == NULL)
2720
       * below.
2721
       */
2722
0
      status = NT_STATUS_OK;
2723
0
      break;
2724
0
    }
2725
0
  }
2726
0
  if (!NT_STATUS_IS_OK(status)) {
2727
0
    return status;
2728
0
  }
2729
2730
0
  session_info = session->global->auth_session_info;
2731
0
  if (session_info == NULL) {
2732
0
    return NT_STATUS_INVALID_HANDLE;
2733
0
  }
2734
2735
0
  return NT_STATUS_OK;
2736
0
}
2737
2738
NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
2739
            uint32_t data_length)
2740
0
{
2741
0
  struct smbXsrv_connection *xconn = req->xconn;
2742
0
  uint16_t needed_charge;
2743
0
  uint16_t credit_charge = 1;
2744
0
  const uint8_t *inhdr;
2745
2746
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2747
2748
0
  if (xconn->smb2.credits.multicredit) {
2749
0
    credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
2750
0
    credit_charge = MAX(credit_charge, 1);
2751
0
  }
2752
2753
0
  needed_charge = (data_length - 1)/ 65536 + 1;
2754
2755
0
  DBGC_DEBUG(DBGC_SMB2_CREDITS,
2756
0
       "mid %llu, CreditCharge: %d, NeededCharge: %d\n",
2757
0
       (unsigned long long) BVAL(inhdr, SMB2_HDR_MESSAGE_ID),
2758
0
       credit_charge, needed_charge);
2759
2760
0
  if (needed_charge > credit_charge) {
2761
0
    DBGC_WARNING(DBGC_SMB2_CREDITS,
2762
0
        "CreditCharge too low, given %d, needed %d\n",
2763
0
        credit_charge, needed_charge);
2764
0
    return NT_STATUS_INVALID_PARAMETER;
2765
0
  }
2766
2767
0
  return NT_STATUS_OK;
2768
0
}
2769
2770
NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
2771
          size_t expected_body_size)
2772
0
{
2773
0
  struct iovec *inhdr_v;
2774
0
  const uint8_t *inhdr;
2775
0
  uint16_t opcode;
2776
0
  const uint8_t *inbody;
2777
0
  size_t body_size;
2778
0
  size_t min_dyn_size = expected_body_size & 0x00000001;
2779
0
  int max_idx = req->in.vector_count - SMBD_SMB2_NUM_IOV_PER_REQ;
2780
2781
  /*
2782
   * The following should be checked already.
2783
   */
2784
0
  if (req->in.vector_count < SMBD_SMB2_NUM_IOV_PER_REQ) {
2785
0
    return NT_STATUS_INTERNAL_ERROR;
2786
0
  }
2787
0
  if (req->current_idx > max_idx) {
2788
0
    return NT_STATUS_INTERNAL_ERROR;
2789
0
  }
2790
2791
0
  inhdr_v = SMBD_SMB2_IN_HDR_IOV(req);
2792
0
  if (inhdr_v->iov_len != SMB2_HDR_BODY) {
2793
0
    return NT_STATUS_INTERNAL_ERROR;
2794
0
  }
2795
0
  if (SMBD_SMB2_IN_BODY_LEN(req) < 2) {
2796
0
    return NT_STATUS_INTERNAL_ERROR;
2797
0
  }
2798
2799
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2800
0
  opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
2801
2802
0
  switch (opcode) {
2803
0
  case SMB2_OP_IOCTL:
2804
0
  case SMB2_OP_GETINFO:
2805
0
  case SMB2_OP_WRITE:
2806
0
    min_dyn_size = 0;
2807
0
    break;
2808
0
  }
2809
2810
  /*
2811
   * Now check the expected body size,
2812
   * where the last byte might be in the
2813
   * dynamic section..
2814
   */
2815
0
  if (SMBD_SMB2_IN_BODY_LEN(req) != (expected_body_size & 0xFFFFFFFE)) {
2816
0
    return NT_STATUS_INVALID_PARAMETER;
2817
0
  }
2818
0
  if (SMBD_SMB2_IN_DYN_LEN(req) < min_dyn_size) {
2819
0
    return NT_STATUS_INVALID_PARAMETER;
2820
0
  }
2821
2822
0
  inbody = SMBD_SMB2_IN_BODY_PTR(req);
2823
2824
0
  body_size = SVAL(inbody, 0x00);
2825
0
  if (body_size != expected_body_size) {
2826
0
    return NT_STATUS_INVALID_PARAMETER;
2827
0
  }
2828
2829
0
  return NT_STATUS_OK;
2830
0
}
2831
2832
/* Set a flag if not already set, return true if set */
2833
bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
2834
0
{
2835
0
  if ((flag == 0) || (*flags & flag)) {
2836
0
    return false;
2837
0
  }
2838
2839
0
  *flags |= flag;
2840
0
  return true;
2841
0
}
2842
2843
/*
2844
 * Update encryption state tracking flags, this can be used to
2845
 * determine whether whether the session or tcon is "encrypted".
2846
 */
2847
static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
2848
          uint16_t opcode,
2849
          bool *update_session_globalp,
2850
          bool *update_tcon_globalp)
2851
0
{
2852
  /* Default: assume unecrypted and unsigned */
2853
0
  struct smbXsrv_session *session = req->session;
2854
0
  struct smbXsrv_tcon *tcon = req->tcon;
2855
0
  uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
2856
0
  uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
2857
0
  bool update_session = false;
2858
0
  bool update_tcon = false;
2859
2860
0
  if (session->table == NULL) {
2861
    /*
2862
     * sessions from smb2srv_session_lookup_global()
2863
     * have NT_STATUS_BAD_LOGON_SESSION_STATE
2864
     * and session->table == NULL.
2865
     *
2866
     * They only used to give the correct error
2867
     * status, we should not update any state.
2868
     */
2869
0
    goto out;
2870
0
  }
2871
2872
0
  if (req->was_encrypted && req->do_encryption) {
2873
0
    encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
2874
0
    sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2875
0
  } else {
2876
    /* Unencrypted packet, can be signed */
2877
0
    if (req->do_signing) {
2878
0
      sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
2879
0
    }
2880
0
  }
2881
2882
0
  update_session |= smbXsrv_set_crypto_flag(
2883
0
    &session->global->encryption_flags, encrypt_flag);
2884
0
  update_session |= smbXsrv_set_crypto_flag(
2885
0
    &session->global->signing_flags, sign_flag);
2886
2887
0
  if (tcon) {
2888
0
    update_tcon |= smbXsrv_set_crypto_flag(
2889
0
      &tcon->global->encryption_flags, encrypt_flag);
2890
0
    update_tcon |= smbXsrv_set_crypto_flag(
2891
0
      &tcon->global->signing_flags, sign_flag);
2892
0
  }
2893
2894
0
out:
2895
0
  *update_session_globalp = update_session;
2896
0
  *update_tcon_globalp = update_tcon;
2897
0
  return;
2898
0
}
2899
2900
static NTSTATUS smbd_smb2_request_dispatch_update_counts(
2901
        struct smbd_smb2_request *req,
2902
        bool modify_call)
2903
0
{
2904
0
  struct smbXsrv_connection *xconn = req->xconn;
2905
0
  const uint8_t *inhdr;
2906
0
  uint16_t channel_sequence;
2907
0
  uint8_t generation_wrap = 0;
2908
0
  uint32_t flags;
2909
0
  int cmp;
2910
0
  struct smbXsrv_open *op;
2911
0
  bool update_open = false;
2912
0
  NTSTATUS status = NT_STATUS_OK;
2913
2914
0
  SMB_ASSERT(!req->request_counters_updated);
2915
2916
0
  if (xconn->protocol < PROTOCOL_SMB3_00) {
2917
0
    return NT_STATUS_OK;
2918
0
  }
2919
2920
0
  if (req->compat_chain_fsp == NULL) {
2921
0
    return NT_STATUS_OK;
2922
0
  }
2923
2924
0
  op = req->compat_chain_fsp->op;
2925
0
  if (op == NULL) {
2926
0
    return NT_STATUS_OK;
2927
0
  }
2928
2929
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
2930
0
  flags = IVAL(inhdr, SMB2_HDR_FLAGS);
2931
0
  channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
2932
2933
0
  cmp = channel_sequence - op->global->channel_sequence;
2934
0
  if (cmp < 0) {
2935
    /*
2936
     * csn wrap. We need to watch out for long-running
2937
     * requests that are still sitting on a previously
2938
     * used csn. SMB2_OP_NOTIFY can take VERY long.
2939
     */
2940
0
    generation_wrap += 1;
2941
0
  }
2942
2943
0
  if (abs(cmp) > INT16_MAX) {
2944
    /*
2945
     * [MS-SMB2] 3.3.5.2.10 - Verifying the Channel Sequence Number:
2946
     *
2947
     * If the channel sequence number of the request and the one
2948
     * known to the server are not equal, the channel sequence
2949
     * number and outstanding request counts are only updated
2950
     * "... if the unsigned difference using 16-bit arithmetic
2951
     * between ChannelSequence and Open.ChannelSequence is less than
2952
     * or equal to 0x7FFF ...".
2953
     * Otherwise, an error is returned for the modifying
2954
     * calls write, set_info, and ioctl.
2955
     *
2956
     * There are currently two issues with the description:
2957
     *
2958
     * * For the other calls, the document seems to imply
2959
     *   that processing continues without adapting the
2960
     *   counters (if the sequence numbers are not equal).
2961
     *
2962
     *   TODO: This needs clarification!
2963
     *
2964
     * * Also, the behaviour if the difference is larger
2965
     *   than 0x7FFF is not clear. The document seems to
2966
     *   imply that if such a difference is reached,
2967
     *   the server starts to ignore the counters or
2968
     *   in the case of the modifying calls, return errors.
2969
     *
2970
     *   TODO: This needs clarification!
2971
     *
2972
     * At this point Samba tries to be a little more
2973
     * clever than the description in the MS-SMB2 document
2974
     * by heuristically detecting and properly treating
2975
     * a 16 bit overflow of the client-submitted sequence
2976
     * number:
2977
     *
2978
     * If the stored channel sequence number is more than
2979
     * 0x7FFF larger than the one from the request, then
2980
     * the client-provided sequence number has likely
2981
     * overflown. We treat this case as valid instead
2982
     * of as failure.
2983
     *
2984
     * The MS-SMB2 behaviour would be setting cmp = -1.
2985
     */
2986
0
    cmp *= -1;
2987
0
  }
2988
2989
0
  if (flags & SMB2_HDR_FLAG_REPLAY_OPERATION) {
2990
0
    if (cmp == 0 && op->pre_request_count == 0) {
2991
0
      op->request_count += 1;
2992
0
      req->request_counters_updated = true;
2993
0
    } else if (cmp > 0 && op->pre_request_count == 0) {
2994
0
      op->pre_request_count += op->request_count;
2995
0
      op->request_count = 1;
2996
0
      op->global->channel_sequence = channel_sequence;
2997
0
      op->global->channel_generation += generation_wrap;
2998
0
      update_open = true;
2999
0
      req->request_counters_updated = true;
3000
0
    } else if (modify_call) {
3001
0
      return NT_STATUS_FILE_NOT_AVAILABLE;
3002
0
    }
3003
0
  } else {
3004
0
    if (cmp == 0) {
3005
0
      op->request_count += 1;
3006
0
      req->request_counters_updated = true;
3007
0
    } else if (cmp > 0) {
3008
0
      op->pre_request_count += op->request_count;
3009
0
      op->request_count = 1;
3010
0
      op->global->channel_sequence = channel_sequence;
3011
0
      op->global->channel_generation += generation_wrap;
3012
0
      update_open = true;
3013
0
      req->request_counters_updated = true;
3014
0
    } else if (modify_call) {
3015
0
      return NT_STATUS_FILE_NOT_AVAILABLE;
3016
0
    }
3017
0
  }
3018
0
  req->channel_generation = op->global->channel_generation;
3019
3020
0
  if (update_open) {
3021
0
    status = smbXsrv_open_update(op);
3022
0
  }
3023
3024
0
  return status;
3025
0
}
3026
3027
#ifdef WITH_PROFILE
3028
static int smb2_request_to_snum(const struct smbd_smb2_request *req)
3029
{
3030
  return (req->tcon != NULL) && (req->tcon->compat != NULL)
3031
           ? SNUM(req->tcon->compat)
3032
           : GLOBAL_SECTION_SNUM;
3033
}
3034
#endif
3035
3036
NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
3037
0
{
3038
0
  struct smbXsrv_connection *xconn = req->xconn;
3039
0
  const struct smbd_smb2_dispatch_table *call = NULL;
3040
0
  const struct iovec *intf_v = SMBD_SMB2_IN_TF_IOV(req);
3041
0
  const uint8_t *inhdr;
3042
0
  uint16_t opcode;
3043
0
  uint32_t flags;
3044
0
  uint64_t mid;
3045
0
  NTSTATUS status;
3046
0
  NTSTATUS session_status;
3047
0
  uint32_t allowed_flags;
3048
0
  NTSTATUS return_value;
3049
0
  struct smbXsrv_session *x = NULL;
3050
0
  bool signing_required = false;
3051
0
  bool encryption_desired = false;
3052
0
  bool encryption_required = false;
3053
0
  bool session_expired = false;
3054
3055
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
3056
3057
0
  DO_PROFILE_INC(request);
3058
3059
0
  SMB_ASSERT(!req->request_counters_updated);
3060
3061
  /* TODO: verify more things */
3062
3063
0
  flags = IVAL(inhdr, SMB2_HDR_FLAGS);
3064
0
  opcode = SVAL(inhdr, SMB2_HDR_OPCODE);
3065
0
  mid = BVAL(inhdr, SMB2_HDR_MESSAGE_ID);
3066
0
  DBG_DEBUG("opcode[%s] mid = %"PRIu64"\n",
3067
0
      smb2_opcode_name(opcode),
3068
0
      mid);
3069
3070
0
  if (xconn->protocol >= PROTOCOL_SMB2_02) {
3071
    /*
3072
     * once the protocol is negotiated
3073
     * SMB2_OP_NEGPROT is not allowed anymore
3074
     */
3075
0
    if (opcode == SMB2_OP_NEGPROT) {
3076
      /* drop the connection */
3077
0
      return NT_STATUS_INVALID_PARAMETER;
3078
0
    }
3079
0
  } else {
3080
    /*
3081
     * if the protocol is not negotiated yet
3082
     * only SMB2_OP_NEGPROT is allowed.
3083
     */
3084
0
    if (opcode != SMB2_OP_NEGPROT) {
3085
      /* drop the connection */
3086
0
      return NT_STATUS_INVALID_PARAMETER;
3087
0
    }
3088
0
  }
3089
3090
  /*
3091
   * Check if the client provided a valid session id.
3092
   *
3093
   * As some command don't require a valid session id
3094
   * we defer the check of the session_status
3095
   */
3096
0
  session_status = smbd_smb2_request_check_session(req);
3097
0
  x = req->session;
3098
0
  if (x != NULL) {
3099
0
    signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
3100
0
    encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
3101
0
    encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
3102
0
    session_expired =
3103
0
      NT_STATUS_EQUAL(session_status,
3104
0
          NT_STATUS_NETWORK_SESSION_EXPIRED);
3105
0
  }
3106
3107
0
  req->async_internal = false;
3108
0
  req->do_signing = false;
3109
3110
0
  if (opcode == SMB2_OP_SESSSETUP) {
3111
0
    req->do_encryption = false;
3112
0
  } else {
3113
0
    req->do_encryption = encryption_desired;
3114
0
  }
3115
3116
0
  req->was_encrypted = false;
3117
0
  if (intf_v->iov_len == SMB2_TF_HDR_SIZE) {
3118
0
    const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req);
3119
0
    uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID);
3120
3121
0
    if (x != NULL && x->global->session_wire_id != tf_session_id) {
3122
0
      DBG_ERR("invalid session_id "
3123
0
        "in SMB2_HDR[%" PRIu64 "], SMB2_TF[%" PRIu64
3124
0
        "]\n",
3125
0
        x->global->session_wire_id,
3126
0
        tf_session_id);
3127
      /*
3128
       * TODO: windows allows this...
3129
       * should we drop the connection?
3130
       *
3131
       * For now we just return ACCESS_DENIED
3132
       * (Windows clients never trigger this)
3133
       * and wait for an update of [MS-SMB2].
3134
       */
3135
0
      return smbd_smb2_request_error(req,
3136
0
          NT_STATUS_ACCESS_DENIED);
3137
0
    }
3138
3139
0
    req->was_encrypted = true;
3140
0
    req->do_encryption = true;
3141
0
  }
3142
3143
0
  if (encryption_required && !req->was_encrypted) {
3144
0
    req->do_encryption = true;
3145
0
    return smbd_smb2_request_error(req,
3146
0
        NT_STATUS_ACCESS_DENIED);
3147
0
  }
3148
3149
0
  call = smbd_smb2_call(opcode);
3150
0
  if (call == NULL) {
3151
0
    return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3152
0
  }
3153
3154
0
  allowed_flags = SMB2_HDR_FLAG_CHAINED |
3155
0
      SMB2_HDR_FLAG_SIGNED |
3156
0
      SMB2_HDR_FLAG_DFS;
3157
0
  if (xconn->protocol >= PROTOCOL_SMB3_11) {
3158
0
    allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3159
0
  }
3160
0
  if (opcode == SMB2_OP_NEGPROT) {
3161
0
    if (lp_server_max_protocol() >= PROTOCOL_SMB3_11) {
3162
0
      allowed_flags |= SMB2_HDR_FLAG_PRIORITY_MASK;
3163
0
    }
3164
0
  }
3165
0
  if (opcode == SMB2_OP_CANCEL) {
3166
0
    allowed_flags |= SMB2_HDR_FLAG_ASYNC;
3167
0
  }
3168
0
  if (xconn->protocol >= PROTOCOL_SMB3_00) {
3169
0
    allowed_flags |= SMB2_HDR_FLAG_REPLAY_OPERATION;
3170
0
  }
3171
0
  if ((flags & ~allowed_flags) != 0) {
3172
0
    return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3173
0
  }
3174
3175
0
  if (flags & SMB2_HDR_FLAG_CHAINED) {
3176
    /*
3177
     * This check is mostly for giving the correct error code
3178
     * for compounded requests.
3179
     */
3180
0
    if (!session_expired && !NT_STATUS_IS_OK(session_status)) {
3181
0
      return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3182
0
    }
3183
0
  } else {
3184
0
    req->compat_chain_fsp = NULL;
3185
0
  }
3186
3187
0
  if (req->was_encrypted) {
3188
0
    signing_required = false;
3189
0
  } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) {
3190
0
    struct smb2_signing_key *signing_key = NULL;
3191
0
    bool has_channel = false;
3192
3193
0
    if (x == NULL) {
3194
      /*
3195
       * MS-SMB2: 3.3.5.2.4 Verifying the Signature.
3196
       * If the SMB2 header of the SMB2 NEGOTIATE
3197
       * request has the SMB2_FLAGS_SIGNED bit set in the
3198
       * Flags field, the server MUST fail the request
3199
       * with STATUS_INVALID_PARAMETER.
3200
       *
3201
       * Microsoft test tool checks this.
3202
       */
3203
3204
0
      if ((opcode == SMB2_OP_NEGPROT) &&
3205
0
          (flags & SMB2_HDR_FLAG_SIGNED)) {
3206
0
        status = NT_STATUS_INVALID_PARAMETER;
3207
0
      } else {
3208
0
        status = NT_STATUS_USER_SESSION_DELETED;
3209
0
      }
3210
0
      return smbd_smb2_request_error(req, status);
3211
0
    }
3212
3213
0
    signing_key = smbd_smb2_signing_key(x, xconn, &has_channel);
3214
3215
    /*
3216
     * If we have a signing key, we should
3217
     * sign the response
3218
     */
3219
0
    if (smb2_signing_key_valid(signing_key) && opcode != SMB2_OP_CANCEL) {
3220
0
      req->do_signing = true;
3221
0
    }
3222
3223
0
    status = smb2_signing_check_pdu(signing_key,
3224
0
            SMBD_SMB2_IN_HDR_IOV(req),
3225
0
            SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3226
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
3227
0
        opcode == SMB2_OP_SESSSETUP && !has_channel &&
3228
0
        NT_STATUS_IS_OK(session_status))
3229
0
    {
3230
0
      if (!NT_STATUS_EQUAL(x->status, NT_STATUS_BAD_LOGON_SESSION_STATE)) {
3231
0
        struct smbXsrv_session *session = NULL;
3232
0
        NTSTATUS error;
3233
3234
0
        error = smb2srv_session_lookup_global(req->xconn->client,
3235
0
                      x->global->session_wire_id,
3236
0
                      req,
3237
0
                      &session);
3238
0
        if (!NT_STATUS_IS_OK(error)) {
3239
0
          return smbd_smb2_request_error(req, error);
3240
0
        }
3241
3242
        /*
3243
         * We fallback to a session of
3244
         * another process in order to
3245
         * get the signing correct.
3246
         *
3247
         * We don't set req->last_session_id here.
3248
         */
3249
0
        req->session = x = session;
3250
0
      }
3251
0
      goto skipped_signing;
3252
0
    }
3253
0
    if (!NT_STATUS_IS_OK(status)) {
3254
0
      return smbd_smb2_request_error(req, status);
3255
0
    }
3256
3257
    /*
3258
     * Now that we know the request was correctly signed
3259
     * we have to sign the response too.
3260
     */
3261
0
    if (opcode != SMB2_OP_CANCEL) {
3262
0
      req->do_signing = true;
3263
0
    }
3264
3265
0
    if (!NT_STATUS_IS_OK(session_status)) {
3266
0
      if (session_expired && opcode == SMB2_OP_CREATE) {
3267
0
        req->compound_create_err = session_status;
3268
0
      }
3269
0
      return smbd_smb2_request_error(req, session_status);
3270
0
    }
3271
0
  }
3272
3273
0
  if (opcode == SMB2_OP_IOCTL) {
3274
    /*
3275
     * Some special IOCTL calls don't require
3276
     * file, tcon nor session.
3277
     *
3278
     * They typically don't do any real action
3279
     * on behalf of the client.
3280
     *
3281
     * They are mainly used to alter the behavior
3282
     * of the connection for testing. So we can
3283
     * run as root and skip all file, tcon and session
3284
     * checks below.
3285
     */
3286
0
    static const struct smbd_smb2_dispatch_table _root_ioctl_call = {
3287
0
      .opcode = SMB2_OP_IOCTL,
3288
0
      .as_root = true,
3289
0
    };
3290
0
    const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3291
0
    size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3292
0
    uint32_t in_ctl_code;
3293
0
    size_t needed = 8;
3294
3295
0
    if (needed > body_size) {
3296
0
      return smbd_smb2_request_error(req,
3297
0
          NT_STATUS_INVALID_PARAMETER);
3298
0
    }
3299
3300
0
    in_ctl_code = IVAL(body, 0x04);
3301
    /*
3302
     * Only add trusted IOCTL codes here!
3303
     */
3304
0
    switch (in_ctl_code) {
3305
0
    case FSCTL_SMBTORTURE_FORCE_UNACKED_TIMEOUT:
3306
0
      call = &_root_ioctl_call;
3307
0
      break;
3308
0
    case FSCTL_VALIDATE_NEGOTIATE_INFO:
3309
0
      call = &_root_ioctl_call;
3310
0
      break;
3311
0
    case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
3312
0
      call = &_root_ioctl_call;
3313
0
      break;
3314
0
    }
3315
0
  }
3316
3317
0
skipped_signing:
3318
3319
0
  if (flags & SMB2_HDR_FLAG_CHAINED) {
3320
0
    if (!NT_STATUS_IS_OK(req->compound_create_err)) {
3321
0
      return smbd_smb2_request_error(req,
3322
0
          req->compound_create_err);
3323
0
    }
3324
0
    req->compound_related = true;
3325
0
  }
3326
3327
0
  if (call->need_session) {
3328
0
    if (!NT_STATUS_IS_OK(session_status)) {
3329
0
      if (session_expired && opcode == SMB2_OP_CREATE) {
3330
0
        req->compound_create_err = session_status;
3331
0
      }
3332
0
      return smbd_smb2_request_error(req, session_status);
3333
0
    }
3334
0
  }
3335
3336
0
  if (call->need_tcon) {
3337
0
    SMB_ASSERT(call->need_session);
3338
3339
    /*
3340
     * This call needs to be run as user.
3341
     *
3342
     * smbd_smb2_request_check_tcon()
3343
     * calls change_to_user() on success.
3344
     * Which implies set_current_user_info()
3345
     * and chdir_current_service().
3346
     */
3347
0
    status = smbd_smb2_request_check_tcon(req);
3348
0
    if (!NT_STATUS_IS_OK(status)) {
3349
0
      return smbd_smb2_request_error(req, status);
3350
0
    }
3351
0
    if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
3352
0
      encryption_desired = true;
3353
0
    }
3354
0
    if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
3355
0
      encryption_required = true;
3356
0
    }
3357
0
    if (encryption_required && !req->was_encrypted) {
3358
0
      req->do_encryption = true;
3359
0
      return smbd_smb2_request_error(req,
3360
0
        NT_STATUS_ACCESS_DENIED);
3361
0
    } else if (encryption_desired) {
3362
0
      req->do_encryption = true;
3363
0
    }
3364
0
  } else if (call->need_session) {
3365
0
    struct auth_session_info *session_info = NULL;
3366
3367
    /*
3368
     * Unless we also have need_tcon (see above),
3369
     * we still need to call set_current_user_info().
3370
     */
3371
3372
0
    session_info = req->session->global->auth_session_info;
3373
0
    if (session_info == NULL) {
3374
0
      return NT_STATUS_INVALID_HANDLE;
3375
0
    }
3376
3377
0
    set_current_user_info(session_info->unix_info->sanitized_username,
3378
0
              session_info->unix_info->unix_name,
3379
0
              session_info->info->domain_name);
3380
0
  }
3381
3382
0
  if (req->session) {
3383
0
    bool update_session_global = false;
3384
0
    bool update_tcon_global = false;
3385
3386
0
    smb2srv_update_crypto_flags(req, opcode,
3387
0
              &update_session_global,
3388
0
              &update_tcon_global);
3389
3390
0
    if (update_session_global) {
3391
0
      status = smbXsrv_session_update(x);
3392
0
      if (!NT_STATUS_IS_OK(status)) {
3393
0
        return smbd_smb2_request_error(req, status);
3394
0
      }
3395
0
    }
3396
0
    if (update_tcon_global) {
3397
0
      status = smbXsrv_tcon_update(req->tcon);
3398
0
      if (!NT_STATUS_IS_OK(status)) {
3399
0
        return smbd_smb2_request_error(req, status);
3400
0
      }
3401
0
    }
3402
0
  }
3403
3404
0
  if (call->fileid_ofs != 0) {
3405
0
    size_t needed = call->fileid_ofs + 16;
3406
0
    const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
3407
0
    size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
3408
0
    uint64_t file_id_persistent;
3409
0
    uint64_t file_id_volatile;
3410
0
    struct files_struct *fsp;
3411
3412
0
    SMB_ASSERT(call->need_tcon);
3413
3414
0
    if (needed > body_size) {
3415
0
      return smbd_smb2_request_error(req,
3416
0
          NT_STATUS_INVALID_PARAMETER);
3417
0
    }
3418
3419
0
    file_id_persistent  = BVAL(body, call->fileid_ofs + 0);
3420
0
    file_id_volatile  = BVAL(body, call->fileid_ofs + 8);
3421
3422
0
    fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
3423
0
    if (fsp == NULL) {
3424
0
      if (req->compound_related &&
3425
0
          !NT_STATUS_IS_OK(req->compound_create_err))
3426
0
      {
3427
0
        return smbd_smb2_request_error(req,
3428
0
            req->compound_create_err);
3429
0
      }
3430
      /*
3431
       * smbd_smb2_request_process_ioctl()
3432
       * has more checks in order to return more
3433
       * detailed error codes...
3434
       */
3435
0
      if (opcode != SMB2_OP_IOCTL) {
3436
0
        return smbd_smb2_request_error(req,
3437
0
            NT_STATUS_FILE_CLOSED);
3438
0
      }
3439
0
    } else {
3440
0
      if (fsp->fsp_flags.encryption_required && !req->was_encrypted) {
3441
0
        return smbd_smb2_request_error(req,
3442
0
            NT_STATUS_ACCESS_DENIED);
3443
0
      }
3444
0
    }
3445
0
  }
3446
3447
0
  status = smbd_smb2_request_dispatch_update_counts(req, call->modify);
3448
0
  if (!NT_STATUS_IS_OK(status)) {
3449
0
    return smbd_smb2_request_error(req, status);
3450
0
  }
3451
3452
0
  if (call->as_root) {
3453
0
    SMB_ASSERT(call->fileid_ofs == 0);
3454
    /* This call needs to be run as root */
3455
0
    change_to_root_user();
3456
0
  } else if (opcode != SMB2_OP_KEEPALIVE) {
3457
0
    SMB_ASSERT(call->need_tcon);
3458
0
  }
3459
3460
0
#define _INBYTES(_r) \
3461
0
  iov_buflen(SMBD_SMB2_IN_HDR_IOV(_r), SMBD_SMB2_NUM_IOV_PER_REQ-1)
3462
3463
0
  switch (opcode) {
3464
0
  case SMB2_OP_NEGPROT:
3465
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3466
0
             smb2_negprot,
3467
0
             req->profile,
3468
0
             req->profile_x,
3469
0
             _INBYTES(req));
3470
0
    return_value = smbd_smb2_request_process_negprot(req);
3471
0
    break;
3472
3473
0
  case SMB2_OP_SESSSETUP:
3474
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3475
0
             smb2_sesssetup,
3476
0
             req->profile,
3477
0
             req->profile_x,
3478
0
             _INBYTES(req));
3479
0
    return_value = smbd_smb2_request_process_sesssetup(req);
3480
0
    break;
3481
3482
0
  case SMB2_OP_LOGOFF:
3483
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3484
0
             smb2_logoff,
3485
0
             req->profile,
3486
0
             req->profile_x,
3487
0
             _INBYTES(req));
3488
0
    return_value = smbd_smb2_request_process_logoff(req);
3489
0
    break;
3490
3491
0
  case SMB2_OP_TCON:
3492
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3493
0
             smb2_tcon,
3494
0
             req->profile,
3495
0
             req->profile_x,
3496
0
             _INBYTES(req));
3497
0
    return_value = smbd_smb2_request_process_tcon(req);
3498
0
    break;
3499
3500
0
  case SMB2_OP_TDIS:
3501
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3502
0
             smb2_tdis,
3503
0
             req->profile,
3504
0
             req->profile_x,
3505
0
             _INBYTES(req));
3506
0
    return_value = smbd_smb2_request_process_tdis(req);
3507
0
    break;
3508
3509
0
  case SMB2_OP_CREATE:
3510
0
    if (req->subreq == NULL) {
3511
0
      SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(
3512
0
                 req),
3513
0
               smb2_create,
3514
0
               req->profile,
3515
0
               req->profile_x,
3516
0
               _INBYTES(req));
3517
0
    } else {
3518
0
      SMBPROFILE_IOBYTES_ASYNC_SET_BUSY_X(req->profile,
3519
0
                  req->profile_x);
3520
0
    }
3521
0
    return_value = smbd_smb2_request_process_create(req);
3522
0
    break;
3523
3524
0
  case SMB2_OP_CLOSE:
3525
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3526
0
             smb2_close,
3527
0
             req->profile,
3528
0
             req->profile_x,
3529
0
             _INBYTES(req));
3530
0
    return_value = smbd_smb2_request_process_close(req);
3531
0
    break;
3532
3533
0
  case SMB2_OP_FLUSH:
3534
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3535
0
             smb2_flush,
3536
0
             req->profile,
3537
0
             req->profile_x,
3538
0
             _INBYTES(req));
3539
0
    return_value = smbd_smb2_request_process_flush(req);
3540
0
    break;
3541
3542
0
  case SMB2_OP_READ:
3543
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3544
0
             smb2_read,
3545
0
             req->profile,
3546
0
             req->profile_x,
3547
0
             _INBYTES(req));
3548
0
    return_value = smbd_smb2_request_process_read(req);
3549
0
    break;
3550
3551
0
  case SMB2_OP_WRITE:
3552
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3553
0
             smb2_write,
3554
0
             req->profile,
3555
0
             req->profile_x,
3556
0
             _INBYTES(req));
3557
0
    return_value = smbd_smb2_request_process_write(req);
3558
0
    break;
3559
3560
0
  case SMB2_OP_LOCK:
3561
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3562
0
             smb2_lock,
3563
0
             req->profile,
3564
0
             req->profile_x,
3565
0
             _INBYTES(req));
3566
0
    return_value = smbd_smb2_request_process_lock(req);
3567
0
    break;
3568
3569
0
  case SMB2_OP_IOCTL:
3570
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3571
0
             smb2_ioctl,
3572
0
             req->profile,
3573
0
             req->profile_x,
3574
0
             _INBYTES(req));
3575
0
    return_value = smbd_smb2_request_process_ioctl(req);
3576
0
    break;
3577
3578
0
  case SMB2_OP_CANCEL:
3579
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3580
0
             smb2_cancel,
3581
0
             req->profile,
3582
0
             req->profile_x,
3583
0
             _INBYTES(req));
3584
0
    return_value = smbd_smb2_request_process_cancel(req);
3585
0
    SMBPROFILE_IOBYTES_ASYNC_END_X(req->profile,
3586
0
                 req->profile_x,
3587
0
                 0,
3588
0
                 SMB2_OP_CANCEL,
3589
0
                 NT_STATUS_OK);
3590
3591
    /*
3592
     * We don't need the request anymore cancel requests never
3593
     * have a response.
3594
     *
3595
     * smbd_smb2_request_process_cancel() already called
3596
     * DLIST_REMOVE(xconn->smb2.requests, req);
3597
     */
3598
0
    TALLOC_FREE(req);
3599
3600
0
    break;
3601
3602
0
  case SMB2_OP_KEEPALIVE:
3603
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3604
0
             smb2_keepalive,
3605
0
             req->profile,
3606
0
             req->profile_x,
3607
0
             _INBYTES(req));
3608
0
    return_value = smbd_smb2_request_process_keepalive(req);
3609
0
    break;
3610
3611
0
  case SMB2_OP_QUERY_DIRECTORY:
3612
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3613
0
             smb2_find,
3614
0
             req->profile,
3615
0
             req->profile_x,
3616
0
             _INBYTES(req));
3617
0
    return_value = smbd_smb2_request_process_query_directory(req);
3618
0
    break;
3619
3620
0
  case SMB2_OP_NOTIFY:
3621
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3622
0
             smb2_notify,
3623
0
             req->profile,
3624
0
             req->profile_x,
3625
0
             _INBYTES(req));
3626
0
    return_value = smbd_smb2_request_process_notify(req);
3627
0
    break;
3628
3629
0
  case SMB2_OP_GETINFO:
3630
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3631
0
             smb2_getinfo,
3632
0
             req->profile,
3633
0
             req->profile_x,
3634
0
             _INBYTES(req));
3635
0
    return_value = smbd_smb2_request_process_getinfo(req);
3636
0
    break;
3637
3638
0
  case SMB2_OP_SETINFO:
3639
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3640
0
             smb2_setinfo,
3641
0
             req->profile,
3642
0
             req->profile_x,
3643
0
             _INBYTES(req));
3644
0
    return_value = smbd_smb2_request_process_setinfo(req);
3645
0
    break;
3646
3647
0
  case SMB2_OP_BREAK:
3648
0
    SMBPROFILE_IOBYTES_ASYNC_START_X(smb2_request_to_snum(req),
3649
0
             smb2_break,
3650
0
             req->profile,
3651
0
             req->profile_x,
3652
0
             _INBYTES(req));
3653
0
    return_value = smbd_smb2_request_process_break(req);
3654
0
    break;
3655
3656
0
  default:
3657
0
    return_value = smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
3658
0
    break;
3659
0
  }
3660
0
  return return_value;
3661
0
}
3662
3663
static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
3664
0
{
3665
0
  struct smbXsrv_connection *xconn = req->xconn;
3666
0
  const uint8_t *inhdr;
3667
0
  uint16_t channel_sequence;
3668
0
  struct smbXsrv_open *op;
3669
3670
0
  if (!req->request_counters_updated) {
3671
0
    return;
3672
0
  }
3673
3674
0
  req->request_counters_updated = false;
3675
3676
0
  if (xconn->protocol < PROTOCOL_SMB3_00) {
3677
0
    return;
3678
0
  }
3679
3680
0
  if (req->compat_chain_fsp == NULL) {
3681
0
    return;
3682
0
  }
3683
3684
0
  op = req->compat_chain_fsp->op;
3685
0
  if (op == NULL) {
3686
0
    return;
3687
0
  }
3688
3689
0
  inhdr = SMBD_SMB2_IN_HDR_PTR(req);
3690
0
  channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
3691
3692
0
  if ((op->global->channel_sequence == channel_sequence) &&
3693
0
      (op->global->channel_generation == req->channel_generation)) {
3694
0
    SMB_ASSERT(op->request_count > 0);
3695
0
    op->request_count -= 1;
3696
0
  } else {
3697
0
    SMB_ASSERT(op->pre_request_count > 0);
3698
0
    op->pre_request_count -= 1;
3699
0
  }
3700
0
}
3701
3702
static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
3703
0
{
3704
0
  struct smbXsrv_connection *xconn = req->xconn;
3705
0
  int first_idx = 1;
3706
0
  struct iovec *firsttf = SMBD_SMB2_IDX_TF_IOV(req,out,first_idx);
3707
0
  struct iovec *outhdr = SMBD_SMB2_OUT_HDR_IOV(req);
3708
0
  struct iovec *outdyn = SMBD_SMB2_OUT_DYN_IOV(req);
3709
0
  NTSTATUS status;
3710
0
  bool ok;
3711
3712
0
  req->subreq = NULL;
3713
0
  TALLOC_FREE(req->async_te);
3714
3715
  /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
3716
0
  smbd_smb2_request_reply_update_counts(req);
3717
3718
0
  if (req->do_encryption &&
3719
0
      (firsttf->iov_len == 0) &&
3720
0
      (!smb2_signing_key_valid(req->first_enc_key)) &&
3721
0
      (req->session != NULL) &&
3722
0
      smb2_signing_key_valid(req->session->global->encryption_key))
3723
0
  {
3724
0
    struct smb2_signing_key *encryption_key =
3725
0
      req->session->global->encryption_key;
3726
0
    uint8_t *tf;
3727
0
    uint64_t session_id = req->session->global->session_wire_id;
3728
0
    uint64_t nonce_high;
3729
0
    uint64_t nonce_low;
3730
3731
0
    status = smb2_get_new_nonce(req->session,
3732
0
              &nonce_high,
3733
0
              &nonce_low);
3734
0
    if (!NT_STATUS_IS_OK(status)) {
3735
0
      return status;
3736
0
    }
3737
3738
    /*
3739
     * We need to place the SMB2_TRANSFORM header before the
3740
     * first SMB2 header
3741
     */
3742
3743
    /*
3744
     * we need to remember the encryption key
3745
     * and defer the signing/encryption until
3746
     * we are sure that we do not change
3747
     * the header again.
3748
     */
3749
0
    status = smb2_signing_key_copy(req,
3750
0
                 encryption_key,
3751
0
                 &req->first_enc_key);
3752
0
    if (!NT_STATUS_IS_OK(status)) {
3753
0
      return status;
3754
0
    }
3755
3756
0
    tf = talloc_zero_array(req, uint8_t,
3757
0
               SMB2_TF_HDR_SIZE);
3758
0
    if (tf == NULL) {
3759
0
      return NT_STATUS_NO_MEMORY;
3760
0
    }
3761
3762
0
    SIVAL(tf, SMB2_TF_PROTOCOL_ID, SMB2_TF_MAGIC);
3763
0
    SBVAL(tf, SMB2_TF_NONCE+0, nonce_low);
3764
0
    SBVAL(tf, SMB2_TF_NONCE+8, nonce_high);
3765
0
    SBVAL(tf, SMB2_TF_SESSION_ID, session_id);
3766
3767
0
    firsttf->iov_base = (void *)tf;
3768
0
    firsttf->iov_len = SMB2_TF_HDR_SIZE;
3769
0
  }
3770
3771
0
  if ((req->current_idx > SMBD_SMB2_NUM_IOV_PER_REQ) &&
3772
0
      (smb2_signing_key_valid(req->last_sign_key)) &&
3773
0
      (firsttf->iov_len == 0))
3774
0
  {
3775
0
    int last_idx = req->current_idx - SMBD_SMB2_NUM_IOV_PER_REQ;
3776
0
    struct iovec *lasthdr = SMBD_SMB2_IDX_HDR_IOV(req,out,last_idx);
3777
3778
    /*
3779
     * As we are sure the header of the last request in the
3780
     * compound chain will not change, we can to sign here
3781
     * with the last signing key we remembered.
3782
     */
3783
0
    status = smb2_signing_sign_pdu(req->last_sign_key,
3784
0
                 lasthdr,
3785
0
                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3786
0
    if (!NT_STATUS_IS_OK(status)) {
3787
0
      return status;
3788
0
    }
3789
0
  }
3790
0
  TALLOC_FREE(req->last_sign_key);
3791
3792
0
  SMBPROFILE_IOBYTES_ASYNC_END_X(
3793
0
    req->profile,
3794
0
    req->profile_x,
3795
0
    iov_buflen(outhdr, SMBD_SMB2_NUM_IOV_PER_REQ - 1),
3796
0
    PULL_LE_U16(outhdr->iov_base, SMB2_HDR_OPCODE),
3797
0
    NT_STATUS(IVAL(outhdr->iov_base, SMB2_HDR_STATUS)));
3798
3799
0
  req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
3800
3801
0
  if (req->current_idx < req->out.vector_count) {
3802
    /*
3803
     * We must process the remaining compound
3804
     * SMB2 requests before any new incoming SMB2
3805
     * requests. This is because incoming SMB2
3806
     * requests may include a cancel for a
3807
     * compound request we haven't processed
3808
     * yet.
3809
     */
3810
0
    struct tevent_immediate *im = tevent_create_immediate(req);
3811
0
    if (!im) {
3812
0
      return NT_STATUS_NO_MEMORY;
3813
0
    }
3814
3815
0
    if (req->do_signing && firsttf->iov_len == 0) {
3816
0
      struct smbXsrv_session *x = req->session;
3817
0
      struct smb2_signing_key *signing_key =
3818
0
        smbd_smb2_signing_key(x, xconn, NULL);
3819
3820
      /*
3821
       * we need to remember the signing key
3822
       * and defer the signing until
3823
       * we are sure that we do not change
3824
       * the header again.
3825
       */
3826
0
      status = smb2_signing_key_copy(req,
3827
0
                   signing_key,
3828
0
                   &req->last_sign_key);
3829
0
      if (!NT_STATUS_IS_OK(status)) {
3830
0
        return status;
3831
0
      }
3832
0
    }
3833
3834
    /*
3835
     * smbd_smb2_request_dispatch() will redo the impersonation.
3836
     * So we use req->xconn->client->raw_ev_ctx instead
3837
     * of req->ev_ctx here.
3838
     */
3839
0
    tevent_schedule_immediate(im,
3840
0
          req->xconn->client->raw_ev_ctx,
3841
0
          smbd_smb2_request_dispatch_immediate,
3842
0
          req);
3843
0
    return NT_STATUS_OK;
3844
0
  }
3845
3846
0
  if (req->compound_related) {
3847
0
    req->compound_related = false;
3848
0
  }
3849
3850
0
  ok = smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
3851
0
  if (!ok) {
3852
0
    return NT_STATUS_INVALID_PARAMETER_MIX;
3853
0
  }
3854
3855
  /* Set credit for these operations (zero credits if this
3856
     is a final reply for an async operation). */
3857
0
  smb2_calculate_credits(req, req);
3858
3859
  /*
3860
   * now check if we need to sign the current response
3861
   */
3862
0
  if (firsttf->iov_len == SMB2_TF_HDR_SIZE) {
3863
0
    status = smb2_signing_encrypt_pdu(req->first_enc_key,
3864
0
          firsttf,
3865
0
          req->out.vector_count - first_idx);
3866
0
    if (!NT_STATUS_IS_OK(status)) {
3867
0
      return status;
3868
0
    }
3869
0
  } else if (req->do_signing) {
3870
0
    struct smbXsrv_session *x = req->session;
3871
0
    struct smb2_signing_key *signing_key =
3872
0
      smbd_smb2_signing_key(x, xconn, NULL);
3873
3874
0
    status = smb2_signing_sign_pdu(signing_key,
3875
0
                 outhdr,
3876
0
                 SMBD_SMB2_NUM_IOV_PER_REQ - 1);
3877
0
    if (!NT_STATUS_IS_OK(status)) {
3878
0
      return status;
3879
0
    }
3880
0
  }
3881
0
  TALLOC_FREE(req->first_enc_key);
3882
3883
0
  if (req->preauth != NULL) {
3884
0
    gnutls_hash_hd_t hash_hnd = NULL;
3885
0
    size_t i;
3886
0
    int rc;
3887
3888
0
    rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA512);
3889
0
    if (rc < 0) {
3890
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3891
0
    }
3892
0
    rc = gnutls_hash(hash_hnd,
3893
0
          req->preauth->sha512_value,
3894
0
          sizeof(req->preauth->sha512_value));
3895
0
    if (rc < 0) {
3896
0
      gnutls_hash_deinit(hash_hnd, NULL);
3897
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3898
0
    }
3899
0
    for (i = 1; i < req->in.vector_count; i++) {
3900
0
      rc = gnutls_hash(hash_hnd,
3901
0
           req->in.vector[i].iov_base,
3902
0
           req->in.vector[i].iov_len);
3903
0
      if (rc < 0) {
3904
0
        gnutls_hash_deinit(hash_hnd, NULL);
3905
0
        return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3906
0
      }
3907
0
    }
3908
0
    gnutls_hash_output(hash_hnd, req->preauth->sha512_value);
3909
3910
0
    rc = gnutls_hash(hash_hnd,
3911
0
         req->preauth->sha512_value,
3912
0
         sizeof(req->preauth->sha512_value));
3913
0
    if (rc < 0) {
3914
0
      gnutls_hash_deinit(hash_hnd, NULL);
3915
0
      return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3916
0
    }
3917
0
    for (i = 1; i < req->out.vector_count; i++) {
3918
0
      rc = gnutls_hash(hash_hnd,
3919
0
           req->out.vector[i].iov_base,
3920
0
           req->out.vector[i].iov_len);
3921
0
      if (rc < 0) {
3922
0
        gnutls_hash_deinit(hash_hnd, NULL);
3923
0
        return gnutls_error_to_ntstatus(rc, NT_STATUS_HASH_NOT_SUPPORTED);
3924
0
      }
3925
0
    }
3926
3927
0
    gnutls_hash_deinit(hash_hnd, req->preauth->sha512_value);
3928
3929
0
    req->preauth = NULL;
3930
0
  }
3931
3932
  /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
3933
0
  if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
3934
0
      outdyn->iov_base == NULL && outdyn->iov_len != 0) {
3935
    /* Dynamic part is NULL. Chop it off,
3936
       We're going to send it via sendfile. */
3937
0
    req->out.vector_count -= 1;
3938
0
  }
3939
3940
  /*
3941
   * We're done with this request -
3942
   * move it off the "being processed" queue.
3943
   */
3944
0
  DLIST_REMOVE(xconn->smb2.requests, req);
3945
3946
0
  req->queue_entry.mem_ctx = req;
3947
0
  req->queue_entry.vector = req->out.vector;
3948
0
  req->queue_entry.count = req->out.vector_count;
3949
0
  DLIST_ADD_END(xconn->smb2.send_queue, &req->queue_entry);
3950
0
  xconn->smb2.send_queue_len++;
3951
3952
0
  status = smbd_smb2_flush_send_queue(xconn);
3953
0
  if (!NT_STATUS_IS_OK(status)) {
3954
0
    return status;
3955
0
  }
3956
3957
0
  return NT_STATUS_OK;
3958
0
}
3959
3960
static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn);
3961
3962
void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
3963
          struct tevent_immediate *im,
3964
          void *private_data)
3965
0
{
3966
0
  struct smbd_smb2_request *req = talloc_get_type_abort(private_data,
3967
0
          struct smbd_smb2_request);
3968
0
  struct smbXsrv_connection *xconn = req->xconn;
3969
0
  NTSTATUS status;
3970
3971
0
  TALLOC_FREE(im);
3972
3973
0
  if (DEBUGLEVEL >= 10) {
3974
0
    DBG_DEBUG("idx[%d] of %d vectors\n",
3975
0
        req->current_idx, req->in.vector_count);
3976
0
    print_req_vectors(req);
3977
0
  }
3978
3979
0
  status = smbd_smb2_request_dispatch(req);
3980
0
  if (!NT_STATUS_IS_OK(status)) {
3981
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
3982
0
    return;
3983
0
  }
3984
3985
0
  status = smbd_smb2_request_next_incoming(xconn);
3986
0
  if (!NT_STATUS_IS_OK(status)) {
3987
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
3988
0
    return;
3989
0
  }
3990
0
}
3991
3992
NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req,
3993
           NTSTATUS status,
3994
           DATA_BLOB body, DATA_BLOB *dyn,
3995
           const char *location)
3996
0
{
3997
0
  uint8_t *outhdr;
3998
0
  struct iovec *outbody_v;
3999
0
  struct iovec *outdyn_v;
4000
0
  uint32_t next_command_ofs;
4001
0
  uint64_t mid;
4002
4003
0
  outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
4004
0
  mid = BVAL(outhdr, SMB2_HDR_MESSAGE_ID);
4005
4006
0
  DBG_DEBUG("mid [%"PRIu64"] idx[%d] status[%s] "
4007
0
      "body[%u] dyn[%s:%u] at %s\n",
4008
0
      mid,
4009
0
      req->current_idx,
4010
0
      nt_errstr(status),
4011
0
      (unsigned int)body.length,
4012
0
      dyn ? "yes" : "no",
4013
0
      (unsigned int)(dyn ? dyn->length : 0),
4014
0
      location);
4015
4016
0
  if (body.length < 2) {
4017
0
    return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
4018
0
  }
4019
4020
0
  if ((body.length % 2) != 0) {
4021
0
    return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
4022
0
  }
4023
4024
0
  outbody_v = SMBD_SMB2_OUT_BODY_IOV(req);
4025
0
  outdyn_v = SMBD_SMB2_OUT_DYN_IOV(req);
4026
4027
0
  next_command_ofs = IVAL(outhdr, SMB2_HDR_NEXT_COMMAND);
4028
0
  SIVAL(outhdr, SMB2_HDR_STATUS, NT_STATUS_V(status));
4029
4030
0
  outbody_v->iov_base = (void *)body.data;
4031
0
  outbody_v->iov_len = body.length;
4032
4033
0
  if (dyn) {
4034
0
    outdyn_v->iov_base = (void *)dyn->data;
4035
0
    outdyn_v->iov_len = dyn->length;
4036
0
  } else {
4037
0
    outdyn_v->iov_base = NULL;
4038
0
    outdyn_v->iov_len = 0;
4039
0
  }
4040
4041
  /*
4042
   * See if we need to recalculate the offset to the next response
4043
   *
4044
   * Note that all responses may require padding (including the very last
4045
   * one).
4046
   */
4047
0
  if (req->out.vector_count >= (2 * SMBD_SMB2_NUM_IOV_PER_REQ)) {
4048
0
    next_command_ofs  = SMB2_HDR_BODY;
4049
0
    next_command_ofs += SMBD_SMB2_OUT_BODY_LEN(req);
4050
0
    next_command_ofs += SMBD_SMB2_OUT_DYN_LEN(req);
4051
0
  }
4052
4053
0
  if ((next_command_ofs % 8) != 0) {
4054
0
    size_t pad_size = 8 - (next_command_ofs % 8);
4055
0
    if (SMBD_SMB2_OUT_DYN_LEN(req) == 0) {
4056
      /*
4057
       * if the dyn buffer is empty
4058
       * we can use it to add padding
4059
       */
4060
0
      uint8_t *pad;
4061
4062
0
      pad = talloc_zero_array(req,
4063
0
            uint8_t, pad_size);
4064
0
      if (pad == NULL) {
4065
0
        return smbd_smb2_request_error(req,
4066
0
            NT_STATUS_NO_MEMORY);
4067
0
      }
4068
4069
0
      outdyn_v->iov_base = (void *)pad;
4070
0
      outdyn_v->iov_len = pad_size;
4071
0
    } else {
4072
      /*
4073
       * For now we copy the dynamic buffer
4074
       * and add the padding to the new buffer
4075
       */
4076
0
      size_t old_size;
4077
0
      uint8_t *old_dyn;
4078
0
      size_t new_size;
4079
0
      uint8_t *new_dyn;
4080
4081
0
      old_size = SMBD_SMB2_OUT_DYN_LEN(req);
4082
0
      old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
4083
4084
0
      new_size = old_size + pad_size;
4085
0
      new_dyn = talloc_zero_array(req,
4086
0
                 uint8_t, new_size);
4087
0
      if (new_dyn == NULL) {
4088
0
        return smbd_smb2_request_error(req,
4089
0
            NT_STATUS_NO_MEMORY);
4090
0
      }
4091
4092
0
      memcpy(new_dyn, old_dyn, old_size);
4093
0
      memset(new_dyn + old_size, 0, pad_size);
4094
4095
0
      outdyn_v->iov_base = (void *)new_dyn;
4096
0
      outdyn_v->iov_len = new_size;
4097
0
    }
4098
0
    next_command_ofs += pad_size;
4099
0
  }
4100
4101
0
  if ((req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) >= req->out.vector_count) {
4102
0
    SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, 0);
4103
0
  } else {
4104
0
    SIVAL(outhdr, SMB2_HDR_NEXT_COMMAND, next_command_ofs);
4105
0
  }
4106
0
  return smbd_smb2_request_reply(req);
4107
0
}
4108
4109
NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
4110
            NTSTATUS status,
4111
            uint8_t error_context_count,
4112
            DATA_BLOB *info,
4113
            const char *location)
4114
0
{
4115
0
  struct smbXsrv_connection *xconn = req->xconn;
4116
0
  DATA_BLOB body;
4117
0
  DATA_BLOB _dyn;
4118
0
  uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
4119
0
  size_t unread_bytes = smbd_smb2_unread_bytes(req);
4120
4121
0
  DBG_NOTICE("idx[%d] status[%s] |%s| "
4122
0
       "at %s\n", req->current_idx, nt_errstr(status),
4123
0
       info ? " +info" : "", location);
4124
4125
0
  if (unread_bytes) {
4126
    /* Recvfile error. Drain incoming socket. */
4127
0
    size_t ret;
4128
4129
0
    errno = 0;
4130
0
    ret = drain_socket(xconn->transport.sock, unread_bytes);
4131
0
    if (ret != unread_bytes) {
4132
0
      NTSTATUS error;
4133
4134
0
      if (errno == 0) {
4135
0
        error = NT_STATUS_IO_DEVICE_ERROR;
4136
0
      } else {
4137
0
        error = map_nt_error_from_unix_common(errno);
4138
0
      }
4139
4140
0
      DEBUG(2, ("Failed to drain %u bytes from SMB2 socket: "
4141
0
          "ret[%u] errno[%d] => %s\n",
4142
0
          (unsigned)unread_bytes,
4143
0
          (unsigned)ret, errno, nt_errstr(error)));
4144
0
      return error;
4145
0
    }
4146
0
  }
4147
4148
0
  if (req->compound_related &&
4149
0
      NT_STATUS_EQUAL(status, NT_STATUS_CANCELLED))
4150
0
  {
4151
    /*
4152
     * A compound request went async but was cancelled as it was not
4153
     * one of the allowed async compound requests.
4154
     */
4155
0
    status = NT_STATUS_INTERNAL_ERROR;
4156
0
  }
4157
4158
0
  body.data = outhdr + SMB2_HDR_BODY;
4159
0
  body.length = 8;
4160
0
  SSVAL(body.data, 0, 9);
4161
0
  SCVAL(body.data, 2, error_context_count);
4162
4163
0
  if (info) {
4164
0
    SIVAL(body.data, 0x04, info->length);
4165
0
  } else {
4166
    /* Allocated size of req->out.vector[i].iov_base
4167
     * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
4168
     * 1 byte without having to do an alloc.
4169
     */
4170
0
    info = &_dyn;
4171
0
    info->data = ((uint8_t *)outhdr) +
4172
0
      OUTVEC_ALLOC_SIZE - 1;
4173
0
    info->length = 1;
4174
0
    SCVAL(info->data, 0, 0);
4175
0
  }
4176
4177
  /*
4178
   * Note: Even if there is an error, continue to process the request.
4179
   * per MS-SMB2.
4180
   */
4181
4182
0
  return smbd_smb2_request_done_ex(req, status, body, info, __location__);
4183
0
}
4184
4185
struct smbd_smb2_break_state {
4186
  struct tevent_req *req;
4187
  struct smbd_smb2_send_queue queue_entry;
4188
  uint8_t nbt_hdr[NBT_HDR_SIZE];
4189
  uint8_t hdr[SMB2_HDR_BODY];
4190
  struct iovec vector[1+SMBD_SMB2_NUM_IOV_PER_REQ];
4191
};
4192
4193
static struct tevent_req *smbd_smb2_break_send(TALLOC_CTX *mem_ctx,
4194
                 struct tevent_context *ev,
4195
                 struct smbXsrv_connection *xconn,
4196
                 uint64_t session_id,
4197
                 const uint8_t *body,
4198
                 size_t body_len)
4199
0
{
4200
0
  struct tevent_req *req = NULL;
4201
0
  struct smbd_smb2_break_state *state = NULL;
4202
0
  NTSTATUS status;
4203
0
  bool ok;
4204
4205
0
  req = tevent_req_create(mem_ctx, &state,
4206
0
        struct smbd_smb2_break_state);
4207
0
  if (req == NULL) {
4208
0
    return NULL;
4209
0
  }
4210
4211
0
  state->req = req;
4212
0
  tevent_req_defer_callback(req, ev);
4213
4214
0
  SIVAL(state->hdr, 0,       SMB2_MAGIC);
4215
0
  SSVAL(state->hdr, SMB2_HDR_LENGTH,   SMB2_HDR_BODY);
4216
0
  SSVAL(state->hdr, SMB2_HDR_EPOCH,    0);
4217
0
  SIVAL(state->hdr, SMB2_HDR_STATUS,   0);
4218
0
  SSVAL(state->hdr, SMB2_HDR_OPCODE,   SMB2_OP_BREAK);
4219
0
  SSVAL(state->hdr, SMB2_HDR_CREDIT,   0);
4220
0
  SIVAL(state->hdr, SMB2_HDR_FLAGS,    SMB2_HDR_FLAG_REDIRECT);
4221
0
  SIVAL(state->hdr, SMB2_HDR_NEXT_COMMAND, 0);
4222
0
  SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID,   UINT64_MAX);
4223
0
  SIVAL(state->hdr, SMB2_HDR_PID,      0);
4224
0
  SIVAL(state->hdr, SMB2_HDR_TID,      0);
4225
0
  SBVAL(state->hdr, SMB2_HDR_SESSION_ID,   session_id);
4226
0
  memset(state->hdr+SMB2_HDR_SIGNATURE, 0, 16);
4227
4228
0
  state->vector[0] = (struct iovec) {
4229
0
    .iov_base = state->nbt_hdr,
4230
0
    .iov_len  = sizeof(state->nbt_hdr)
4231
0
  };
4232
4233
0
  state->vector[1+SMBD_SMB2_TF_IOV_OFS] = (struct iovec) {
4234
0
    .iov_base = NULL,
4235
0
    .iov_len  = 0
4236
0
  };
4237
4238
0
  state->vector[1+SMBD_SMB2_HDR_IOV_OFS] = (struct iovec) {
4239
0
    .iov_base = state->hdr,
4240
0
    .iov_len  = sizeof(state->hdr)
4241
0
  };
4242
4243
0
  state->vector[1+SMBD_SMB2_BODY_IOV_OFS] = (struct iovec) {
4244
0
    .iov_base = discard_const_p(uint8_t, body),
4245
0
    .iov_len  = body_len,
4246
0
  };
4247
4248
  /*
4249
   * state->vector[1+SMBD_SMB2_DYN_IOV_OFS] is NULL by talloc_zero above
4250
   */
4251
4252
0
  ok = smb2_setup_nbt_length(state->vector,
4253
0
           1 + SMBD_SMB2_NUM_IOV_PER_REQ);
4254
0
  if (!ok) {
4255
0
    tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
4256
0
    return tevent_req_post(req, ev);
4257
0
  }
4258
4259
  /*
4260
   * We require TCP acks for this PDU to the client!
4261
   * We want 5 retransmissions and timeout when the
4262
   * retransmission timeout (rto) passed 6 times.
4263
   *
4264
   * required_acked_bytes gets a dummy value of
4265
   * UINT64_MAX, as long it's in xconn->smb2.send_queue,
4266
   * it'll get the real value when it's moved to
4267
   * xconn->ack.queue.
4268
   *
4269
   * state->queue_entry.ack.req gets completed with
4270
   * 1.  tevent_req_done(), when all bytes are acked.
4271
   * 2a. tevent_req_nterror(NT_STATUS_IO_TIMEOUT), when
4272
   *     the timeout expired before all bytes were acked.
4273
   * 2b. tevent_req_nterror(transport_error), when the
4274
   *     connection got a disconnect from the kernel.
4275
   */
4276
0
  state->queue_entry.ack.timeout =
4277
0
    timeval_current_ofs_usec(xconn->ack.rto_usecs * 6);
4278
0
  state->queue_entry.ack.required_acked_bytes = UINT64_MAX;
4279
0
  state->queue_entry.ack.req = req;
4280
0
  state->queue_entry.mem_ctx = state;
4281
0
  state->queue_entry.vector = state->vector;
4282
0
  state->queue_entry.count = ARRAY_SIZE(state->vector);
4283
0
  DLIST_ADD_END(xconn->smb2.send_queue, &state->queue_entry);
4284
0
  xconn->smb2.send_queue_len++;
4285
4286
0
  status = smbd_smb2_flush_send_queue(xconn);
4287
0
  if (tevent_req_nterror(req, status)) {
4288
0
    return tevent_req_post(req, ev);
4289
0
  }
4290
4291
0
  return req;
4292
0
}
4293
4294
static NTSTATUS smbd_smb2_break_recv(struct tevent_req *req)
4295
0
{
4296
0
  return tevent_req_simple_recv_ntstatus(req);
4297
0
}
4298
4299
struct smbXsrv_pending_break {
4300
  struct smbXsrv_pending_break *prev, *next;
4301
  struct smbXsrv_client *client;
4302
  bool disable_oplock_break_retries;
4303
  uint64_t session_id;
4304
  uint64_t last_channel_id;
4305
  union {
4306
    uint8_t generic[1];
4307
    uint8_t oplock[0x18];
4308
    uint8_t lease[0x2c];
4309
  } body;
4310
  size_t body_len;
4311
};
4312
4313
static void smbXsrv_pending_break_done(struct tevent_req *subreq);
4314
4315
static struct smbXsrv_pending_break *smbXsrv_pending_break_create(
4316
    struct smbXsrv_client *client,
4317
    uint64_t session_id)
4318
0
{
4319
0
  struct smbXsrv_pending_break *pb = NULL;
4320
4321
0
  pb = talloc_zero(client, struct smbXsrv_pending_break);
4322
0
  if (pb == NULL) {
4323
0
    return NULL;
4324
0
  }
4325
0
  pb->client = client;
4326
0
  pb->session_id = session_id;
4327
0
  pb->disable_oplock_break_retries = lp_smb2_disable_oplock_break_retry();
4328
4329
0
  return pb;
4330
0
}
4331
4332
static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb);
4333
4334
static NTSTATUS smbXsrv_pending_break_schedule(struct smbXsrv_pending_break *pb)
4335
0
{
4336
0
  struct smbXsrv_client *client = pb->client;
4337
0
  NTSTATUS status;
4338
4339
0
  DLIST_ADD_END(client->pending_breaks, pb);
4340
0
  status = smbXsrv_client_pending_breaks_updated(client);
4341
0
  if (!NT_STATUS_IS_OK(status)) {
4342
0
    return status;
4343
0
  }
4344
4345
0
  status = smbXsrv_pending_break_submit(pb);
4346
0
  if (!NT_STATUS_IS_OK(status)) {
4347
0
    return status;
4348
0
  }
4349
4350
0
  return NT_STATUS_OK;
4351
0
}
4352
4353
static NTSTATUS smbXsrv_pending_break_submit(struct smbXsrv_pending_break *pb)
4354
0
{
4355
0
  struct smbXsrv_client *client = pb->client;
4356
0
  struct smbXsrv_session *session = NULL;
4357
0
  struct smbXsrv_connection *xconn = NULL;
4358
0
  struct smbXsrv_connection *oplock_xconn = NULL;
4359
0
  struct tevent_req *subreq = NULL;
4360
0
  NTSTATUS status;
4361
4362
0
  if (pb->session_id != 0) {
4363
0
    status = get_valid_smbXsrv_session(client,
4364
0
               pb->session_id,
4365
0
               &session);
4366
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
4367
0
      return NT_STATUS_ABANDONED;
4368
0
    }
4369
0
    if (!NT_STATUS_IS_OK(status)) {
4370
0
      return status;
4371
0
    }
4372
4373
0
    if (pb->last_channel_id != 0) {
4374
      /*
4375
       * This is what current Windows servers
4376
       * do, they don't retry on all available
4377
       * channels. They only use the last channel.
4378
       *
4379
       * But it doesn't match the specification in
4380
       * [MS-SMB2] "3.3.4.6 Object Store Indicates an
4381
       * Oplock Break"
4382
       *
4383
       * Per default disable_oplock_break_retries is false
4384
       * and we behave like the specification.
4385
       */
4386
0
      if (pb->disable_oplock_break_retries) {
4387
0
        return NT_STATUS_ABANDONED;
4388
0
      }
4389
0
    }
4390
0
  }
4391
4392
0
  for (xconn = client->connections; xconn != NULL; xconn = xconn->next) {
4393
0
    if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4394
0
      continue;
4395
0
    }
4396
4397
0
    if (xconn->channel_id == 0) {
4398
      /*
4399
       * non-multichannel case
4400
       */
4401
0
      break;
4402
0
    }
4403
4404
0
    if (session != NULL) {
4405
0
      struct smbXsrv_channel_global0 *c = NULL;
4406
4407
      /*
4408
       * Having a session means we're handling
4409
       * an oplock break and we only need to
4410
       * use channels available on the
4411
       * session.
4412
       */
4413
0
      status = smbXsrv_session_find_channel(session, xconn, &c);
4414
0
      if (!NT_STATUS_IS_OK(status)) {
4415
0
        continue;
4416
0
      }
4417
4418
      /*
4419
       * This is what current Windows servers
4420
       * do, they don't retry on all available
4421
       * channels. They only use the last channel.
4422
       *
4423
       * But it doesn't match the specification
4424
       * in [MS-SMB2] "3.3.4.6 Object Store Indicates an
4425
       * Oplock Break"
4426
       *
4427
       * Per default disable_oplock_break_retries is false
4428
       * and we behave like the specification.
4429
       */
4430
0
      if (pb->disable_oplock_break_retries) {
4431
0
        oplock_xconn = xconn;
4432
0
        continue;
4433
0
      }
4434
0
    }
4435
4436
0
    if (xconn->channel_id > pb->last_channel_id) {
4437
      /*
4438
       * multichannel case
4439
       */
4440
0
      break;
4441
0
    }
4442
0
  }
4443
4444
0
  if (xconn == NULL) {
4445
0
    xconn = oplock_xconn;
4446
0
  }
4447
4448
0
  if (xconn == NULL) {
4449
    /*
4450
     * If there's no remaining connection available
4451
     * tell the caller to stop...
4452
     */
4453
0
    return NT_STATUS_ABANDONED;
4454
0
  }
4455
4456
0
  pb->last_channel_id = xconn->channel_id;
4457
4458
0
  subreq = smbd_smb2_break_send(pb,
4459
0
              client->raw_ev_ctx,
4460
0
              xconn,
4461
0
              pb->session_id,
4462
0
              pb->body.generic,
4463
0
              pb->body_len);
4464
0
  if (subreq == NULL) {
4465
0
    return NT_STATUS_NO_MEMORY;
4466
0
  }
4467
0
  tevent_req_set_callback(subreq,
4468
0
        smbXsrv_pending_break_done,
4469
0
        pb);
4470
4471
0
  return NT_STATUS_OK;
4472
0
}
4473
4474
static void smbXsrv_pending_break_done(struct tevent_req *subreq)
4475
0
{
4476
0
  struct smbXsrv_pending_break *pb =
4477
0
    tevent_req_callback_data(subreq,
4478
0
    struct smbXsrv_pending_break);
4479
0
  struct smbXsrv_client *client = pb->client;
4480
0
  NTSTATUS status;
4481
4482
0
  status = smbd_smb2_break_recv(subreq);
4483
0
  TALLOC_FREE(subreq);
4484
0
  if (!NT_STATUS_IS_OK(status)) {
4485
0
    status = smbXsrv_pending_break_submit(pb);
4486
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_ABANDONED)) {
4487
      /*
4488
       * If there's no remaining connection
4489
       * there's no need to send a break again.
4490
       */
4491
0
      goto remove;
4492
0
    }
4493
0
    if (!NT_STATUS_IS_OK(status)) {
4494
0
      smbd_server_disconnect_client(client, nt_errstr(status));
4495
0
      return;
4496
0
    }
4497
0
    return;
4498
0
  }
4499
4500
0
remove:
4501
0
  DLIST_REMOVE(client->pending_breaks, pb);
4502
0
  TALLOC_FREE(pb);
4503
4504
0
  status = smbXsrv_client_pending_breaks_updated(client);
4505
0
  if (!NT_STATUS_IS_OK(status)) {
4506
0
    smbd_server_disconnect_client(client, nt_errstr(status));
4507
0
    return;
4508
0
  }
4509
0
}
4510
4511
NTSTATUS smbd_smb2_send_oplock_break(struct smbXsrv_client *client,
4512
             struct smbXsrv_open *op,
4513
             uint8_t oplock_level)
4514
0
{
4515
0
  struct smbXsrv_pending_break *pb = NULL;
4516
0
  uint8_t *body = NULL;
4517
4518
0
  pb = smbXsrv_pending_break_create(client,
4519
0
            op->compat->vuid);
4520
0
  if (pb == NULL) {
4521
0
    return NT_STATUS_NO_MEMORY;
4522
0
  }
4523
0
  pb->body_len = sizeof(pb->body.oplock);
4524
0
  body = pb->body.oplock;
4525
4526
0
  SSVAL(body, 0x00, pb->body_len);
4527
0
  SCVAL(body, 0x02, oplock_level);
4528
0
  SCVAL(body, 0x03, 0);    /* reserved */
4529
0
  SIVAL(body, 0x04, 0);    /* reserved */
4530
0
  SBVAL(body, 0x08, op->global->open_persistent_id);
4531
0
  SBVAL(body, 0x10, op->global->open_volatile_id);
4532
4533
0
  return smbXsrv_pending_break_schedule(pb);
4534
0
}
4535
4536
NTSTATUS smbd_smb2_send_lease_break(struct smbXsrv_client *client,
4537
            uint16_t new_epoch,
4538
            uint32_t lease_flags,
4539
            struct smb2_lease_key *lease_key,
4540
            uint32_t current_lease_state,
4541
            uint32_t new_lease_state)
4542
0
{
4543
0
  struct smbXsrv_pending_break *pb = NULL;
4544
0
  uint8_t *body = NULL;
4545
4546
0
  pb = smbXsrv_pending_break_create(client,
4547
0
            0); /* no session_id */
4548
0
  if (pb == NULL) {
4549
0
    return NT_STATUS_NO_MEMORY;
4550
0
  }
4551
0
  pb->body_len = sizeof(pb->body.lease);
4552
0
  body = pb->body.lease;
4553
4554
0
  SSVAL(body, 0x00, pb->body_len);
4555
0
  SSVAL(body, 0x02, new_epoch);
4556
0
  SIVAL(body, 0x04, lease_flags);
4557
0
  SBVAL(body, 0x08, lease_key->data[0]);
4558
0
  SBVAL(body, 0x10, lease_key->data[1]);
4559
0
  SIVAL(body, 0x18, current_lease_state);
4560
0
  SIVAL(body, 0x1c, new_lease_state);
4561
0
  SIVAL(body, 0x20, 0);    /* BreakReason, MUST be 0 */
4562
0
  SIVAL(body, 0x24, 0);    /* AccessMaskHint, MUST be 0 */
4563
0
  SIVAL(body, 0x28, 0);    /* ShareMaskHint, MUST be 0 */
4564
4565
0
  return smbXsrv_pending_break_schedule(pb);
4566
0
}
4567
4568
static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
4569
0
{
4570
0
  NTSTATUS status;
4571
0
  uint32_t flags;
4572
0
  uint64_t file_id_persistent;
4573
0
  uint64_t file_id_volatile;
4574
0
  struct smbXsrv_open *op = NULL;
4575
0
  struct files_struct *fsp = NULL;
4576
0
  const uint8_t *body = NULL;
4577
4578
  /*
4579
   * This is only called with a pktbuf
4580
   * of at least SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN
4581
   * bytes
4582
   */
4583
4584
0
  if (IVAL(state->pktbuf, 0) == SMB2_TF_MAGIC) {
4585
    /* Transform header. Cannot recvfile. */
4586
0
    return false;
4587
0
  }
4588
0
  if (IVAL(state->pktbuf, 0) != SMB2_MAGIC) {
4589
    /* Not SMB2. Normal error path will cope. */
4590
0
    return false;
4591
0
  }
4592
0
  if (SVAL(state->pktbuf, 4) != SMB2_HDR_BODY) {
4593
    /* Not SMB2. Normal error path will cope. */
4594
0
    return false;
4595
0
  }
4596
0
  if (SVAL(state->pktbuf, SMB2_HDR_OPCODE) != SMB2_OP_WRITE) {
4597
    /* Needs to be a WRITE. */
4598
0
    return false;
4599
0
  }
4600
0
  if (IVAL(state->pktbuf, SMB2_HDR_NEXT_COMMAND) != 0) {
4601
    /* Chained. Cannot recvfile. */
4602
0
    return false;
4603
0
  }
4604
0
  flags = IVAL(state->pktbuf, SMB2_HDR_FLAGS);
4605
0
  if (flags & SMB2_HDR_FLAG_CHAINED) {
4606
    /* Chained. Cannot recvfile. */
4607
0
    return false;
4608
0
  }
4609
0
  if (flags & SMB2_HDR_FLAG_SIGNED) {
4610
    /* Signed. Cannot recvfile. */
4611
0
    return false;
4612
0
  }
4613
4614
0
  body = &state->pktbuf[SMB2_HDR_BODY];
4615
4616
0
  file_id_persistent  = BVAL(body, 0x10);
4617
0
  file_id_volatile  = BVAL(body, 0x18);
4618
4619
0
  status = smb2srv_open_lookup(state->req->xconn,
4620
0
             file_id_persistent,
4621
0
             file_id_volatile,
4622
0
             0, /* now */
4623
0
             &op);
4624
0
  if (!NT_STATUS_IS_OK(status)) {
4625
0
    return false;
4626
0
  }
4627
4628
0
  fsp = op->compat;
4629
0
  if (fsp == NULL) {
4630
0
    return false;
4631
0
  }
4632
0
  if (fsp->conn == NULL) {
4633
0
    return false;
4634
0
  }
4635
4636
0
  if (IS_IPC(fsp->conn)) {
4637
0
    return false;
4638
0
  }
4639
0
  if (IS_PRINT(fsp->conn)) {
4640
0
    return false;
4641
0
  }
4642
0
  if (fsp_is_alternate_stream(fsp)) {
4643
0
    return false;
4644
0
  }
4645
4646
0
  DEBUG(10,("Doing recvfile write len = %u\n",
4647
0
    (unsigned int)(state->pktfull - state->pktlen)));
4648
4649
0
  return true;
4650
0
}
4651
4652
static NTSTATUS smbd_smb2_request_next_incoming(struct smbXsrv_connection *xconn)
4653
0
{
4654
0
  struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
4655
0
  struct smbd_smb2_request *req = NULL;
4656
0
  size_t max_send_queue_len;
4657
0
  size_t cur_send_queue_len;
4658
4659
0
  if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4660
    /*
4661
     * we're not supposed to do any io
4662
     */
4663
0
    return NT_STATUS_OK;
4664
0
  }
4665
4666
0
  if (state->req != NULL) {
4667
    /*
4668
     * if there is already a tstream_readv_pdu
4669
     * pending, we are done.
4670
     */
4671
0
    return NT_STATUS_OK;
4672
0
  }
4673
4674
0
  max_send_queue_len = MAX(1, xconn->smb2.credits.max/16);
4675
0
  cur_send_queue_len = xconn->smb2.send_queue_len;
4676
4677
0
  if (cur_send_queue_len > max_send_queue_len) {
4678
    /*
4679
     * if we have a lot of requests to send,
4680
     * we wait until they are on the wire until we
4681
     * ask for the next request.
4682
     */
4683
0
    return NT_STATUS_OK;
4684
0
  }
4685
4686
  /* ask for the next request */
4687
0
  req = smbd_smb2_request_allocate(xconn);
4688
0
  if (req == NULL) {
4689
0
    return NT_STATUS_NO_MEMORY;
4690
0
  }
4691
0
  *state = (struct smbd_smb2_request_read_state) {
4692
0
    .req = req,
4693
0
    .min_recv_size = lp_min_receive_file_size(),
4694
0
    ._vector = {
4695
0
      [0] = (struct iovec) {
4696
0
        .iov_base = (void *)state->hdr.nbt,
4697
0
        .iov_len = NBT_HDR_SIZE,
4698
0
      },
4699
0
    },
4700
0
    .vector = state->_vector,
4701
0
    .count = 1,
4702
0
  };
4703
4704
0
  TEVENT_FD_READABLE(xconn->transport.fde);
4705
4706
0
  return NT_STATUS_OK;
4707
0
}
4708
4709
NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
4710
             uint64_t expected_seq_low,
4711
             const uint8_t *inpdu, size_t size)
4712
0
{
4713
0
  struct smbd_server_connection *sconn = xconn->client->sconn;
4714
0
  NTSTATUS status;
4715
0
  struct smbd_smb2_request *req = NULL;
4716
4717
0
  DBG_DEBUG("packet length %zu\n", size);
4718
4719
0
  status = smbd_initialize_smb2(xconn, expected_seq_low);
4720
0
  if (!NT_STATUS_IS_OK(status)) {
4721
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
4722
0
    return status;
4723
0
  }
4724
4725
  /*
4726
   * If a new connection joins the process, when we're
4727
   * already in a "pending break cycle", we need to
4728
   * turn on the ack checker on the new connection.
4729
   */
4730
0
  status = smbXsrv_client_pending_breaks_updated(xconn->client);
4731
0
  if (!NT_STATUS_IS_OK(status)) {
4732
    /*
4733
     * If there's a problem, we disconnect the whole
4734
     * client with all connections here!
4735
     *
4736
     * Instead of just the new connection.
4737
     */
4738
0
    smbd_server_disconnect_client(xconn->client, nt_errstr(status));
4739
0
    return status;
4740
0
  }
4741
4742
0
  status = smbd_smb2_request_create(xconn, inpdu, size, &req);
4743
0
  if (!NT_STATUS_IS_OK(status)) {
4744
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
4745
0
    return status;
4746
0
  }
4747
4748
0
  status = smbd_smb2_request_validate(req);
4749
0
  if (!NT_STATUS_IS_OK(status)) {
4750
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
4751
0
    return status;
4752
0
  }
4753
4754
0
  status = smbd_smb2_request_setup_out(req);
4755
0
  if (!NT_STATUS_IS_OK(status)) {
4756
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
4757
0
    return status;
4758
0
  }
4759
4760
#ifdef WITH_PROFILE
4761
  /*
4762
   * this was already counted at the SMB1 layer =>
4763
   * smbd_smb2_request_dispatch() should not count it twice.
4764
   */
4765
  if (profile_p->values.request_stats.count > 0) {
4766
    profile_p->values.request_stats.count--;
4767
  }
4768
#endif
4769
0
  status = smbd_smb2_request_dispatch(req);
4770
0
  if (!NT_STATUS_IS_OK(status)) {
4771
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
4772
0
    return status;
4773
0
  }
4774
4775
0
  status = smbd_smb2_request_next_incoming(xconn);
4776
0
  if (!NT_STATUS_IS_OK(status)) {
4777
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
4778
0
    return status;
4779
0
  }
4780
4781
0
  sconn->num_requests++;
4782
0
  return NT_STATUS_OK;
4783
0
}
4784
4785
static int socket_error_from_errno(int ret,
4786
           int sys_errno,
4787
           bool *retry)
4788
0
{
4789
0
  *retry = false;
4790
4791
0
  if (ret >= 0) {
4792
0
    return 0;
4793
0
  }
4794
4795
0
  if (ret != -1) {
4796
0
    return EIO;
4797
0
  }
4798
4799
0
  if (sys_errno == 0) {
4800
0
    return EIO;
4801
0
  }
4802
4803
0
  if (sys_errno == EINTR) {
4804
0
    *retry = true;
4805
0
    return sys_errno;
4806
0
  }
4807
4808
0
  if (sys_errno == EINPROGRESS) {
4809
0
    *retry = true;
4810
0
    return sys_errno;
4811
0
  }
4812
4813
0
  if (sys_errno == EAGAIN) {
4814
0
    *retry = true;
4815
0
    return sys_errno;
4816
0
  }
4817
4818
  /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */
4819
0
  if (sys_errno == ENOMEM) {
4820
0
    *retry = true;
4821
0
    return sys_errno;
4822
0
  }
4823
4824
0
#ifdef EWOULDBLOCK
4825
#if EWOULDBLOCK != EAGAIN
4826
  if (sys_errno == EWOULDBLOCK) {
4827
    *retry = true;
4828
    return sys_errno;
4829
  }
4830
#endif
4831
0
#endif
4832
4833
0
  return sys_errno;
4834
0
}
4835
4836
static NTSTATUS smbd_smb2_advance_send_queue(struct smbXsrv_connection *xconn,
4837
               struct smbd_smb2_send_queue **_e,
4838
               size_t n)
4839
0
{
4840
0
  struct smbd_smb2_send_queue *e = *_e;
4841
0
  bool ok;
4842
4843
0
  xconn->ack.unacked_bytes += n;
4844
4845
0
  ok = iov_advance(&e->vector, &e->count, n);
4846
0
  if (!ok) {
4847
0
    return NT_STATUS_INTERNAL_ERROR;
4848
0
  }
4849
4850
0
  if (e->count > 0) {
4851
0
    return NT_STATUS_RETRY;
4852
0
  }
4853
4854
0
  xconn->smb2.send_queue_len--;
4855
0
  DLIST_REMOVE(xconn->smb2.send_queue, e);
4856
4857
0
  if (e->ack.req == NULL) {
4858
0
    *_e = NULL;
4859
0
    talloc_free(e->mem_ctx);
4860
0
    return NT_STATUS_OK;
4861
0
  }
4862
4863
0
  e->ack.required_acked_bytes = xconn->ack.unacked_bytes;
4864
0
  DLIST_ADD_END(xconn->ack.queue, e);
4865
4866
0
  return NT_STATUS_OK;
4867
0
}
4868
4869
static NTSTATUS smbd_smb2_flush_with_sendmsg(struct smbXsrv_connection *xconn)
4870
0
{
4871
0
  int ret;
4872
0
  int err;
4873
0
  bool retry;
4874
0
  NTSTATUS status;
4875
4876
0
  if (xconn->smb2.send_queue == NULL) {
4877
0
    TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
4878
0
    return NT_STATUS_OK;
4879
0
  }
4880
4881
0
  while (xconn->smb2.send_queue != NULL) {
4882
0
    struct smbd_smb2_send_queue *e = xconn->smb2.send_queue;
4883
0
    unsigned sendmsg_flags = 0;
4884
4885
0
    if (!NT_STATUS_IS_OK(xconn->transport.status)) {
4886
      /*
4887
       * we're not supposed to do any io
4888
       * just flush all pending stuff.
4889
       */
4890
0
      xconn->smb2.send_queue_len--;
4891
0
      DLIST_REMOVE(xconn->smb2.send_queue, e);
4892
4893
0
      talloc_free(e->mem_ctx);
4894
0
      continue;
4895
0
    }
4896
4897
0
    if (e->sendfile_header != NULL) {
4898
0
      size_t size = 0;
4899
0
      size_t i = 0;
4900
0
      uint8_t *buf;
4901
4902
0
      status = NT_STATUS_INTERNAL_ERROR;
4903
4904
0
      for (i=0; i < e->count; i++) {
4905
0
        size += e->vector[i].iov_len;
4906
0
      }
4907
4908
0
      if (size <= e->sendfile_header->length) {
4909
0
        buf = e->sendfile_header->data;
4910
0
      } else {
4911
0
        buf = talloc_array(e->mem_ctx, uint8_t, size);
4912
0
        if (buf == NULL) {
4913
0
          return NT_STATUS_NO_MEMORY;
4914
0
        }
4915
0
      }
4916
4917
0
      size = 0;
4918
0
      for (i=0; i < e->count; i++) {
4919
0
        memcpy(buf+size,
4920
0
               e->vector[i].iov_base,
4921
0
               e->vector[i].iov_len);
4922
0
        size += e->vector[i].iov_len;
4923
0
      }
4924
4925
0
      e->sendfile_header->data = buf;
4926
0
      e->sendfile_header->length = size;
4927
0
      e->sendfile_status = &status;
4928
0
      e->count = 0;
4929
4930
0
      xconn->smb2.send_queue_len--;
4931
0
      DLIST_REMOVE(xconn->smb2.send_queue, e);
4932
4933
0
      size += e->sendfile_body_size;
4934
4935
      /*
4936
       * This triggers the sendfile path via
4937
       * the destructor.
4938
       */
4939
0
      talloc_free(e->mem_ctx);
4940
4941
0
      if (!NT_STATUS_IS_OK(status)) {
4942
0
        smbXsrv_connection_disconnect_transport(xconn,
4943
0
                  status);
4944
0
        return status;
4945
0
      }
4946
0
      xconn->ack.unacked_bytes += size;
4947
0
      continue;
4948
0
    }
4949
4950
0
    e->msg = (struct msghdr) {
4951
0
      .msg_iov = e->vector,
4952
0
      .msg_iovlen = e->count,
4953
0
    };
4954
4955
0
#ifdef MSG_NOSIGNAL
4956
0
    sendmsg_flags |= MSG_NOSIGNAL;
4957
0
#endif
4958
0
#ifdef MSG_DONTWAIT
4959
0
    sendmsg_flags |= MSG_DONTWAIT;
4960
0
#endif
4961
4962
0
    ret = sendmsg(xconn->transport.sock, &e->msg, sendmsg_flags);
4963
0
    if (ret == 0) {
4964
      /* propagate end of file */
4965
0
      return NT_STATUS_INTERNAL_ERROR;
4966
0
    }
4967
0
    err = socket_error_from_errno(ret, errno, &retry);
4968
0
    if (retry) {
4969
      /* retry later */
4970
0
      TEVENT_FD_WRITEABLE(xconn->transport.fde);
4971
0
      return NT_STATUS_OK;
4972
0
    }
4973
0
    if (err != 0) {
4974
0
      status = map_nt_error_from_unix_common(err);
4975
0
      smbXsrv_connection_disconnect_transport(xconn,
4976
0
                status);
4977
0
      return status;
4978
0
    }
4979
4980
0
    status = smbd_smb2_advance_send_queue(xconn, &e, ret);
4981
0
    if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
4982
      /* retry later */
4983
0
      TEVENT_FD_WRITEABLE(xconn->transport.fde);
4984
0
      return NT_STATUS_OK;
4985
0
    }
4986
0
    if (!NT_STATUS_IS_OK(status)) {
4987
0
      smbXsrv_connection_disconnect_transport(xconn,
4988
0
                status);
4989
0
      return status;
4990
0
    }
4991
0
  }
4992
4993
0
  return NT_STATUS_MORE_PROCESSING_REQUIRED;
4994
0
}
4995
4996
static NTSTATUS smbd_smb2_flush_send_queue(struct smbXsrv_connection *xconn)
4997
0
{
4998
0
  NTSTATUS status;
4999
5000
0
  status = smbd_smb2_flush_with_sendmsg(xconn);
5001
0
  if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
5002
0
    return status;
5003
0
  }
5004
5005
  /*
5006
   * Restart reads if we were blocked on
5007
   * draining the send queue.
5008
   */
5009
5010
0
  status = smbd_smb2_request_next_incoming(xconn);
5011
0
  if (!NT_STATUS_IS_OK(status)) {
5012
0
    return status;
5013
0
  }
5014
5015
0
  return NT_STATUS_OK;
5016
0
}
5017
5018
static NTSTATUS smbd_smb2_advance_incoming(struct smbXsrv_connection *xconn, size_t n)
5019
0
{
5020
0
  struct smbd_server_connection *sconn = xconn->client->sconn;
5021
0
  struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
5022
0
  struct smbd_smb2_request *req = NULL;
5023
0
  size_t min_recvfile_size = UINT32_MAX;
5024
0
  NTSTATUS status;
5025
0
  NTTIME now;
5026
0
  bool ok;
5027
5028
0
  ok = iov_advance(&state->vector, &state->count, n);
5029
0
  if (!ok) {
5030
0
    return NT_STATUS_INTERNAL_ERROR;
5031
0
  }
5032
5033
0
  if (state->count > 0) {
5034
0
    return NT_STATUS_PENDING;
5035
0
  }
5036
5037
0
  if (state->pktlen > 0) {
5038
0
    if (!state->doing_receivefile) {
5039
      /*
5040
       * we have all the data.
5041
       */
5042
0
      goto got_full;
5043
0
    }
5044
5045
0
    if (!is_smb2_recvfile_write(state)) {
5046
0
      size_t ofs = state->pktlen;
5047
5048
      /*
5049
       * Not a possible receivefile write.
5050
       * Read the rest of the data.
5051
       */
5052
0
      state->doing_receivefile = false;
5053
5054
0
      state->pktbuf = talloc_realloc(state->req,
5055
0
                   state->pktbuf,
5056
0
                   uint8_t,
5057
0
                   state->pktfull);
5058
0
      if (state->pktbuf == NULL) {
5059
0
        return NT_STATUS_NO_MEMORY;
5060
0
      }
5061
5062
0
      state->_vector[0]  = (struct iovec) {
5063
0
        .iov_base = (void *)(state->pktbuf + ofs),
5064
0
        .iov_len = (state->pktfull - ofs),
5065
0
      };
5066
0
      state->vector = state->_vector;
5067
0
      state->count = 1;
5068
5069
0
      state->pktlen = state->pktfull;
5070
0
      return NT_STATUS_RETRY;
5071
0
    }
5072
5073
    /*
5074
     * This is a receivefile write so we've
5075
     * done a short read.
5076
     */
5077
0
    goto got_full;
5078
0
  }
5079
5080
  /*
5081
   * Now we analyze the NBT header
5082
   */
5083
0
  if (state->hdr.nbt[0] != 0x00) {
5084
0
    state->min_recv_size = 0;
5085
0
  }
5086
0
  state->pktfull = smb2_len(state->hdr.nbt);
5087
0
  if (state->pktfull == 0) {
5088
0
    goto got_full;
5089
0
  }
5090
5091
0
  if (state->min_recv_size != 0) {
5092
0
    min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
5093
0
    min_recvfile_size += state->min_recv_size;
5094
0
  }
5095
5096
0
  if (state->pktfull > min_recvfile_size) {
5097
    /*
5098
     * Might be a receivefile write. Read the SMB2 HEADER +
5099
     * SMB2_WRITE header first. Set 'doing_receivefile'
5100
     * as we're *attempting* receivefile write. If this
5101
     * turns out not to be a SMB2_WRITE request or otherwise
5102
     * not suitable then we'll just read the rest of the data
5103
     * the next time this function is called.
5104
     */
5105
0
    state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
5106
0
    state->doing_receivefile = true;
5107
0
  } else {
5108
0
    state->pktlen = state->pktfull;
5109
0
  }
5110
5111
0
  state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
5112
0
  if (state->pktbuf == NULL) {
5113
0
    return NT_STATUS_NO_MEMORY;
5114
0
  }
5115
5116
0
  state->_vector[0] = (struct iovec) {
5117
0
    .iov_base = (void *)state->pktbuf,
5118
0
    .iov_len = state->pktlen,
5119
0
  };
5120
0
  state->vector = state->_vector;
5121
0
  state->count = 1;
5122
5123
0
  return NT_STATUS_RETRY;
5124
5125
0
got_full:
5126
5127
0
  if (state->hdr.nbt[0] != 0x00) {
5128
0
    DEBUG(1,("ignore NBT[0x%02X] msg\n",
5129
0
       state->hdr.nbt[0]));
5130
5131
0
    req = state->req;
5132
0
    *state = (struct smbd_smb2_request_read_state) {
5133
0
      .req = req,
5134
0
      .min_recv_size = lp_min_receive_file_size(),
5135
0
      ._vector = {
5136
0
        [0] = (struct iovec) {
5137
0
          .iov_base = (void *)state->hdr.nbt,
5138
0
          .iov_len = NBT_HDR_SIZE,
5139
0
        },
5140
0
      },
5141
0
      .vector = state->_vector,
5142
0
      .count = 1,
5143
0
    };
5144
0
    return NT_STATUS_RETRY;
5145
0
  }
5146
5147
0
  req = state->req;
5148
5149
0
  req->request_time = timeval_current();
5150
0
  now = timeval_to_nttime(&req->request_time);
5151
5152
0
  status = smbd_smb2_inbuf_parse_compound(xconn,
5153
0
            now,
5154
0
            state->pktbuf,
5155
0
            state->pktlen,
5156
0
            req,
5157
0
            &req->in.vector,
5158
0
            &req->in.vector_count);
5159
0
  if (!NT_STATUS_IS_OK(status)) {
5160
0
    return status;
5161
0
  }
5162
5163
0
  if (state->doing_receivefile) {
5164
0
    req->smb1req = talloc_zero(req, struct smb_request);
5165
0
    if (req->smb1req == NULL) {
5166
0
      return NT_STATUS_NO_MEMORY;
5167
0
    }
5168
0
    req->smb1req->unread_bytes = state->pktfull - state->pktlen;
5169
0
  }
5170
5171
0
  *state = (struct smbd_smb2_request_read_state) {
5172
0
    .req = NULL,
5173
0
  };
5174
5175
0
  req->current_idx = 1;
5176
5177
0
  DEBUG(10,("smbd_smb2_request idx[%d] of %d vectors\n",
5178
0
     req->current_idx, req->in.vector_count));
5179
5180
0
  status = smbd_smb2_request_validate(req);
5181
0
  if (!NT_STATUS_IS_OK(status)) {
5182
0
    return status;
5183
0
  }
5184
5185
0
  status = smbd_smb2_request_setup_out(req);
5186
0
  if (!NT_STATUS_IS_OK(status)) {
5187
0
    return status;
5188
0
  }
5189
5190
0
  status = smbd_smb2_request_dispatch(req);
5191
0
  if (!NT_STATUS_IS_OK(status)) {
5192
0
    return status;
5193
0
  }
5194
5195
0
  sconn->num_requests++;
5196
5197
  /* The timeout_processing function isn't run nearly
5198
     often enough to implement 'max log size' without
5199
     overrunning the size of the file by many megabytes.
5200
     This is especially true if we are running at debug
5201
     level 10.  Checking every 50 SMB2s is a nice
5202
     tradeoff of performance vs log file size overrun. */
5203
5204
0
  if ((sconn->num_requests % 50) == 0 &&
5205
0
      need_to_check_log_size()) {
5206
0
    change_to_root_user();
5207
0
    check_log_size();
5208
0
  }
5209
5210
0
  status = smbd_smb2_request_next_incoming(xconn);
5211
0
  if (!NT_STATUS_IS_OK(status)) {
5212
0
    return status;
5213
0
  }
5214
5215
0
  return NT_STATUS_OK;
5216
0
}
5217
5218
static NTSTATUS smbd_smb2_io_handler(struct smbXsrv_connection *xconn,
5219
             uint16_t fde_flags)
5220
0
{
5221
0
  struct smbd_smb2_request_read_state *state = &xconn->smb2.request_read_state;
5222
0
  unsigned recvmsg_flags = 0;
5223
0
  int ret;
5224
0
  int err;
5225
0
  bool retry;
5226
0
  NTSTATUS status;
5227
5228
0
  if (!NT_STATUS_IS_OK(xconn->transport.status)) {
5229
    /*
5230
     * we're not supposed to do any io
5231
     */
5232
0
    TEVENT_FD_NOT_READABLE(xconn->transport.fde);
5233
0
    TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
5234
0
    TEVENT_FD_NOT_WANTERROR(xconn->transport.fde);
5235
0
    return NT_STATUS_OK;
5236
0
  }
5237
5238
0
  if (fde_flags & TEVENT_FD_ERROR) {
5239
0
    ret = samba_socket_poll_or_sock_error(xconn->transport.sock);
5240
0
    if (ret == -1) {
5241
0
      err = errno;
5242
0
      status = map_nt_error_from_unix_common(err);
5243
0
      smbXsrv_connection_disconnect_transport(xconn,
5244
0
                status);
5245
0
      return status;
5246
0
    }
5247
    /* This should not happen */
5248
0
    status = NT_STATUS_REMOTE_DISCONNECT;
5249
0
    smbXsrv_connection_disconnect_transport(xconn,
5250
0
              status);
5251
0
    return status;
5252
0
  }
5253
5254
0
  if (fde_flags & TEVENT_FD_WRITE) {
5255
0
    status = smbd_smb2_flush_send_queue(xconn);
5256
0
    if (!NT_STATUS_IS_OK(status)) {
5257
0
      return status;
5258
0
    }
5259
0
  }
5260
5261
0
  if (!(fde_flags & TEVENT_FD_READ)) {
5262
0
    return NT_STATUS_OK;
5263
0
  }
5264
5265
0
  if (state->req == NULL) {
5266
0
    TEVENT_FD_NOT_READABLE(xconn->transport.fde);
5267
0
    return NT_STATUS_OK;
5268
0
  }
5269
5270
0
again:
5271
5272
0
  state->msg = (struct msghdr) {
5273
0
    .msg_iov = state->vector,
5274
0
    .msg_iovlen = state->count,
5275
0
  };
5276
5277
0
#ifdef MSG_NOSIGNAL
5278
0
  recvmsg_flags |= MSG_NOSIGNAL;
5279
0
#endif
5280
0
#ifdef MSG_DONTWAIT
5281
0
  recvmsg_flags |= MSG_DONTWAIT;
5282
0
#endif
5283
5284
0
  ret = recvmsg(xconn->transport.sock, &state->msg, recvmsg_flags);
5285
0
  if (ret == 0) {
5286
    /* propagate end of file */
5287
0
    status = NT_STATUS_END_OF_FILE;
5288
0
    smbXsrv_connection_disconnect_transport(xconn,
5289
0
              status);
5290
0
    return status;
5291
0
  }
5292
0
  err = socket_error_from_errno(ret, errno, &retry);
5293
0
  if (retry) {
5294
    /* retry later */
5295
0
    TEVENT_FD_READABLE(xconn->transport.fde);
5296
0
    return NT_STATUS_OK;
5297
0
  }
5298
0
  if (err != 0) {
5299
0
    status = map_nt_error_from_unix_common(err);
5300
0
    smbXsrv_connection_disconnect_transport(xconn,
5301
0
              status);
5302
0
    return status;
5303
0
  }
5304
5305
0
  status = smbd_smb2_advance_incoming(xconn, ret);
5306
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_PENDING)) {
5307
    /* we have more to read */
5308
0
    TEVENT_FD_READABLE(xconn->transport.fde);
5309
0
    return NT_STATUS_OK;
5310
0
  }
5311
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
5312
    /*
5313
     * smbd_smb2_advance_incoming setup a new vector
5314
     * that we should try to read immediately.
5315
     */
5316
0
    goto again;
5317
0
  }
5318
0
  if (!NT_STATUS_IS_OK(status)) {
5319
0
    return status;
5320
0
  }
5321
5322
0
  return NT_STATUS_OK;
5323
0
}
5324
5325
static void smbd_smb2_connection_handler(struct tevent_context *ev,
5326
           struct tevent_fd *fde,
5327
           uint16_t flags,
5328
           void *private_data)
5329
0
{
5330
0
  struct smbXsrv_connection *xconn =
5331
0
    talloc_get_type_abort(private_data,
5332
0
    struct smbXsrv_connection);
5333
0
  NTSTATUS status;
5334
5335
0
  status = smbd_smb2_io_handler(xconn, flags);
5336
0
  if (!NT_STATUS_IS_OK(status)) {
5337
    smbd_server_connection_terminate(xconn, nt_errstr(status));
5338
0
    return;
5339
0
  }
5340
0
}