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_negprot.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
   Core SMB2 server
4
5
   Copyright (C) Stefan Metzmacher 2009
6
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
*/
20
21
#include "includes.h"
22
#include "smbd/smbd.h"
23
#include "smbd/globals.h"
24
#include "../libcli/smb/smb_common.h"
25
#include "../libcli/smb/smb2_negotiate_context.h"
26
#include "../lib/tsocket/tsocket.h"
27
#include "../librpc/ndr/libndr.h"
28
#include "../libcli/smb/smb_signing.h"
29
#include "auth.h"
30
#include "auth/gensec/gensec.h"
31
#include "lib/util/string_wrappers.h"
32
#include "source3/lib/substitute.h"
33
#ifdef HAVE_VALGRIND_CALLGRIND_H
34
#include <valgrind/callgrind.h>
35
#endif /* HAVE_VALGRIND_CALLGRIND_H */
36
37
#undef DBGC_CLASS
38
0
#define DBGC_CLASS DBGC_SMB2
39
40
/*
41
 * this is the entry point if SMB2 is selected via
42
 * the SMB negprot and the given dialect.
43
 */
44
static NTSTATUS reply_smb20xx(struct smb_request *req, uint16_t dialect)
45
0
{
46
0
  uint8_t *smb2_inpdu;
47
0
  uint8_t *smb2_hdr;
48
0
  uint8_t *smb2_body;
49
0
  uint8_t *smb2_dyn;
50
0
  size_t len = SMB2_HDR_BODY + 0x24 + 2;
51
52
0
  smb2_inpdu = talloc_zero_array(talloc_tos(), uint8_t, len);
53
0
  if (smb2_inpdu == NULL) {
54
0
    DEBUG(0, ("Could not push spnego blob\n"));
55
0
    reply_nterror(req, NT_STATUS_NO_MEMORY);
56
0
    return NT_STATUS_NO_MEMORY;
57
0
  }
58
0
  smb2_hdr = smb2_inpdu;
59
0
  smb2_body = smb2_hdr + SMB2_HDR_BODY;
60
0
  smb2_dyn = smb2_body + 0x24;
61
62
0
  SIVAL(smb2_hdr, SMB2_HDR_PROTOCOL_ID,  SMB2_MAGIC);
63
0
  SIVAL(smb2_hdr, SMB2_HDR_LENGTH, SMB2_HDR_BODY);
64
65
0
  SSVAL(smb2_body, 0x00, 0x0024);  /* struct size */
66
0
  SSVAL(smb2_body, 0x02, 0x0001);  /* dialect count */
67
68
0
  SSVAL(smb2_dyn,  0x00, dialect);
69
70
0
  req->outbuf = NULL;
71
72
0
  return smbd_smb2_process_negprot(req->xconn, 0, smb2_inpdu, len);
73
0
}
74
75
/*
76
 * this is the entry point if SMB2 is selected via
77
 * the SMB negprot and the "SMB 2.002" dialect.
78
 */
79
NTSTATUS reply_smb2002(struct smb_request *req, uint16_t choice)
80
0
{
81
0
  return reply_smb20xx(req, SMB2_DIALECT_REVISION_202);
82
0
}
83
84
/*
85
 * this is the entry point if SMB2 is selected via
86
 * the SMB negprot and the "SMB 2.???" dialect.
87
 */
88
NTSTATUS reply_smb20ff(struct smb_request *req, uint16_t choice)
89
0
{
90
0
  struct smbXsrv_connection *xconn = req->xconn;
91
0
  xconn->smb2.allow_2ff = true;
92
0
  return reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
93
0
}
94
95
enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
96
        const int dialect_count,
97
        uint16_t *dialect)
98
0
{
99
0
  static const struct {
100
0
    enum protocol_types proto;
101
0
    uint16_t dialect;
102
0
  } pd[] = {
103
0
    { PROTOCOL_SMB3_11, SMB3_DIALECT_REVISION_311 },
104
0
    { PROTOCOL_SMB3_02, SMB3_DIALECT_REVISION_302 },
105
0
    { PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300 },
106
0
    { PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210 },
107
0
    { PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202 },
108
0
  };
109
0
  size_t i;
110
111
0
  for (i = 0; i < ARRAY_SIZE(pd); i ++) {
112
0
    int c = 0;
113
114
0
    if (lp_server_max_protocol() < pd[i].proto) {
115
0
      continue;
116
0
    }
117
0
    if (lp_server_min_protocol() > pd[i].proto) {
118
0
      continue;
119
0
    }
120
121
0
    for (c = 0; c < dialect_count; c++) {
122
0
      *dialect = SVAL(indyn, c*2);
123
0
      if (*dialect == pd[i].dialect) {
124
0
        return pd[i].proto;
125
0
      }
126
0
    }
127
0
  }
128
129
0
  return PROTOCOL_NONE;
130
0
}
131
132
static NTSTATUS smb2_negotiate_context_process_posix(
133
  const struct smb2_negotiate_contexts *in_c,
134
  bool *posix)
135
0
{
136
0
  struct smb2_negotiate_context *in_posix = NULL;
137
0
  const uint8_t *inbuf = NULL;
138
0
  size_t inbuflen;
139
0
  bool posix_found = false;
140
0
  size_t ofs;
141
0
  int cmp;
142
143
0
  *posix = false;
144
145
0
  if (!lp_smb3_unix_extensions(GLOBAL_SECTION_SNUM)) {
146
0
    return NT_STATUS_OK;
147
0
  }
148
149
0
  in_posix = smb2_negotiate_context_find(in_c,
150
0
                 SMB2_POSIX_EXTENSIONS_AVAILABLE);
151
0
  if (in_posix == NULL) {
152
0
    return NT_STATUS_OK;
153
0
  }
154
155
0
  inbuf = in_posix->data.data;
156
0
  inbuflen = in_posix->data.length;
157
158
  /*
159
   * For now the server only supports one variant.
160
   * Check it's the right one.
161
   */
162
0
  if ((inbuflen % 16) != 0) {
163
0
    return NT_STATUS_INVALID_PARAMETER;
164
0
  }
165
166
0
  SMB_ASSERT(strlen(SMB2_CREATE_TAG_POSIX) == 16);
167
168
0
  for (ofs = 0; ofs < inbuflen; ofs += 16) {
169
0
    cmp = memcmp(inbuf+ofs, SMB2_CREATE_TAG_POSIX, 16);
170
0
    if (cmp == 0) {
171
0
      posix_found = true;
172
0
      break;
173
0
    }
174
0
  }
175
176
0
  if (!posix_found) {
177
0
    DBG_DEBUG("Client requested unknown SMB3 Unix extensions:\n");
178
0
    dump_data(10, inbuf, inbuflen);
179
0
    return NT_STATUS_OK;
180
0
  }
181
182
0
  DBG_DEBUG("Client requested SMB3 Unix extensions\n");
183
0
  *posix = true;
184
0
  return NT_STATUS_OK;
185
0
}
186
187
struct smbd_smb2_request_process_negprot_state {
188
  struct smbd_smb2_request *req;
189
  DATA_BLOB outbody;
190
  DATA_BLOB outdyn;
191
};
192
193
static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq);
194
195
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
196
0
{
197
0
  struct smbd_smb2_request_process_negprot_state *state = NULL;
198
0
  struct smbXsrv_connection *xconn = req->xconn;
199
0
  struct tevent_req *subreq = NULL;
200
0
  NTSTATUS status;
201
0
  const uint8_t *inbody;
202
0
  const uint8_t *indyn = NULL;
203
0
  DATA_BLOB outbody;
204
0
  DATA_BLOB outdyn;
205
0
  DATA_BLOB negprot_spnego_blob;
206
0
  uint16_t security_offset;
207
0
  DATA_BLOB security_buffer;
208
0
  size_t expected_dyn_size = 0;
209
0
  size_t c;
210
0
  uint16_t security_mode;
211
0
  uint16_t dialect_count;
212
0
  uint16_t in_security_mode;
213
0
  uint32_t in_capabilities;
214
0
  DATA_BLOB in_guid_blob;
215
0
  struct GUID in_guid;
216
0
  struct smb2_negotiate_contexts in_c = { .num_contexts = 0, };
217
0
  struct smb2_negotiate_context *in_preauth = NULL;
218
0
  struct smb2_negotiate_context *in_cipher = NULL;
219
0
  struct smb2_negotiate_context *in_sign_algo = NULL;
220
0
  struct smb2_negotiate_context *in_transport_caps = NULL;
221
0
  struct smb2_negotiate_contexts out_c = { .num_contexts = 0, };
222
0
  const struct smb311_capabilities default_smb3_capabilities =
223
0
    smb311_capabilities_parse(
224
0
      "server",
225
0
      lp_server_smb3_signing_algorithms(),
226
0
      lp_server_smb3_encryption_algorithms(),
227
0
      true);
228
0
  DATA_BLOB out_negotiate_context_blob = data_blob_null;
229
0
  uint32_t out_negotiate_context_offset = 0;
230
0
  uint16_t out_negotiate_context_count = 0;
231
0
  uint16_t dialect = 0;
232
0
  uint32_t capabilities;
233
0
  DATA_BLOB out_guid_blob;
234
0
  struct GUID out_guid;
235
0
  enum protocol_types protocol = PROTOCOL_NONE;
236
0
  uint32_t max_limit;
237
0
  uint32_t max_trans = lp_smb2_max_trans();
238
0
  uint32_t max_read = lp_smb2_max_read();
239
0
  uint32_t max_write = lp_smb2_max_write();
240
0
  NTTIME now = timeval_to_nttime(&req->request_time);
241
0
  bool posix = false;
242
0
  bool ok;
243
244
0
  status = smbd_smb2_request_verify_sizes(req, 0x24);
245
0
  if (!NT_STATUS_IS_OK(status)) {
246
0
    return smbd_smb2_request_error(req, status);
247
0
  }
248
0
  inbody = SMBD_SMB2_IN_BODY_PTR(req);
249
250
0
  dialect_count = SVAL(inbody, 0x02);
251
252
0
  in_security_mode = SVAL(inbody, 0x04);
253
0
  in_capabilities = IVAL(inbody, 0x08);
254
0
  in_guid_blob = data_blob_const(inbody + 0x0C, 16);
255
256
0
  if (dialect_count == 0) {
257
0
    return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
258
0
  }
259
260
0
  status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
261
0
  if (!NT_STATUS_IS_OK(status)) {
262
0
    return smbd_smb2_request_error(req, status);
263
0
  }
264
265
0
  expected_dyn_size = dialect_count * 2;
266
0
  if (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
267
0
    return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
268
0
  }
269
0
  indyn = SMBD_SMB2_IN_DYN_PTR(req);
270
271
0
  protocol = smbd_smb2_protocol_dialect_match(indyn,
272
0
          dialect_count,
273
0
          &dialect);
274
275
0
  for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
276
0
    if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
277
0
      break;
278
0
    }
279
280
0
    dialect = SVAL(indyn, c*2);
281
0
    if (dialect == SMB2_DIALECT_REVISION_2FF) {
282
0
      if (xconn->smb2.allow_2ff) {
283
0
        xconn->smb2.allow_2ff = false;
284
0
        protocol = PROTOCOL_SMB2_10;
285
0
        break;
286
0
      }
287
0
    }
288
0
  }
289
290
0
  if (protocol == PROTOCOL_NONE) {
291
0
    return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
292
0
  }
293
294
0
  if (protocol >= PROTOCOL_SMB3_11) {
295
0
    uint32_t in_negotiate_context_offset = 0;
296
0
    uint16_t in_negotiate_context_count = 0;
297
0
    DATA_BLOB in_negotiate_context_blob = data_blob_null;
298
0
    size_t ofs;
299
300
0
    in_negotiate_context_offset = IVAL(inbody, 0x1C);
301
0
    in_negotiate_context_count = SVAL(inbody, 0x20);
302
303
0
    ofs = SMB2_HDR_BODY;
304
0
    ofs += SMBD_SMB2_IN_BODY_LEN(req);
305
0
    ofs += expected_dyn_size;
306
0
    if ((ofs % 8) != 0) {
307
0
      ofs += 8 - (ofs % 8);
308
0
    }
309
310
0
    if (in_negotiate_context_offset != ofs) {
311
0
      return smbd_smb2_request_error(req,
312
0
          NT_STATUS_INVALID_PARAMETER);
313
0
    }
314
315
0
    ofs -= SMB2_HDR_BODY;
316
0
    ofs -= SMBD_SMB2_IN_BODY_LEN(req);
317
318
0
    if (SMBD_SMB2_IN_DYN_LEN(req) < ofs) {
319
0
      return smbd_smb2_request_error(req,
320
0
          NT_STATUS_INVALID_PARAMETER);
321
0
    }
322
323
0
    in_negotiate_context_blob = data_blob_const(indyn,
324
0
            SMBD_SMB2_IN_DYN_LEN(req));
325
326
0
    in_negotiate_context_blob.data += ofs;
327
0
    in_negotiate_context_blob.length -= ofs;
328
329
0
    status = smb2_negotiate_context_parse(req,
330
0
                  in_negotiate_context_blob,
331
0
                  in_negotiate_context_count,
332
0
                  &in_c);
333
0
    if (!NT_STATUS_IS_OK(status)) {
334
0
      return smbd_smb2_request_error(req, status);
335
0
    }
336
337
0
    status = smb2_negotiate_context_process_posix(&in_c, &posix);
338
0
    if (!NT_STATUS_IS_OK(status)) {
339
0
      return smbd_smb2_request_error(req, status);
340
0
    }
341
0
  }
342
343
0
  if ((dialect != SMB2_DIALECT_REVISION_2FF) &&
344
0
      (protocol >= PROTOCOL_SMB2_10) &&
345
0
      !GUID_all_zero(&in_guid))
346
0
  {
347
0
    ok = remote_arch_cache_update(&in_guid);
348
0
    if (!ok) {
349
0
      return smbd_smb2_request_error(
350
0
        req, NT_STATUS_UNSUCCESSFUL);
351
0
    }
352
0
  }
353
354
0
  switch (get_remote_arch()) {
355
0
  case RA_VISTA:
356
0
  case RA_SAMBA:
357
0
  case RA_CIFSFS:
358
0
  case RA_OSX:
359
0
    break;
360
0
  default:
361
0
    set_remote_arch(RA_VISTA);
362
0
    break;
363
0
  }
364
365
0
  {
366
0
    fstring proto;
367
0
    fstr_sprintf(proto,
368
0
           "SMB%X_%02X",
369
0
           (dialect >> 8) & 0xFF, dialect & 0xFF);
370
0
    set_remote_proto(proto);
371
0
    DEBUG(3,("Selected protocol %s\n", proto));
372
0
  }
373
374
0
  reload_services(req->sconn, conn_snum_used, true);
375
376
0
  in_preauth = smb2_negotiate_context_find(&in_c,
377
0
          SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
378
0
  if (protocol >= PROTOCOL_SMB3_11 && in_preauth == NULL) {
379
0
    return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
380
0
  }
381
0
  in_cipher = smb2_negotiate_context_find(&in_c,
382
0
          SMB2_ENCRYPTION_CAPABILITIES);
383
0
  in_sign_algo = smb2_negotiate_context_find(&in_c,
384
0
          SMB2_SIGNING_CAPABILITIES);
385
0
  in_transport_caps =  smb2_negotiate_context_find(&in_c,
386
0
          SMB2_TRANSPORT_CAPABILITIES);
387
388
  /* negprot_spnego() returns the server guid in the first 16 bytes */
389
0
  negprot_spnego_blob = negprot_spnego(req, xconn);
390
0
  if (negprot_spnego_blob.data == NULL) {
391
0
    return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
392
0
  }
393
394
0
  if (negprot_spnego_blob.length < 16) {
395
0
    return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
396
0
  }
397
398
0
  security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
399
0
  if (xconn->smb2.signing_mandatory) {
400
0
    security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
401
0
  }
402
403
0
  capabilities = 0;
404
0
  if (lp_host_msdfs()) {
405
0
    capabilities |= SMB2_CAP_DFS;
406
0
  }
407
408
0
  if (protocol >= PROTOCOL_SMB2_10 &&
409
0
      lp_smb2_leases() &&
410
0
      lp_oplocks(GLOBAL_SECTION_SNUM) &&
411
0
      !lp_kernel_oplocks(GLOBAL_SECTION_SNUM))
412
0
  {
413
0
    capabilities |= SMB2_CAP_LEASING;
414
0
  }
415
416
0
  if ((protocol >= PROTOCOL_SMB3_00) &&
417
0
      (lp_server_smb_encrypt(xconn, -1) != SMB_ENCRYPTION_OFF) &&
418
0
      (in_capabilities & SMB2_CAP_ENCRYPTION)) {
419
0
    capabilities |= SMB2_CAP_ENCRYPTION;
420
0
  }
421
422
0
  if (protocol >= PROTOCOL_SMB3_00 &&
423
0
      in_capabilities & SMB2_CAP_DIRECTORY_LEASING &&
424
0
      lp_smb3_directory_leases())
425
0
  {
426
0
    capabilities |= SMB2_CAP_DIRECTORY_LEASING;
427
0
  }
428
429
  /*
430
   * 0x10000 (65536) is the maximum allowed message size
431
   * for SMB 2.0
432
   */
433
0
  max_limit = 0x10000;
434
435
0
  if (protocol >= PROTOCOL_SMB2_10) {
436
    /* largeMTU is not supported over NBT (tcp port 139) */
437
0
    if (xconn->transport.type != SMB_TRANSPORT_TYPE_NBT) {
438
0
      capabilities |= SMB2_CAP_LARGE_MTU;
439
0
      xconn->smb2.credits.multicredit = true;
440
441
      /*
442
       * We allow up to almost 16MB.
443
       *
444
       * The maximum PDU size is 0xFFFFFF (16776960)
445
       * and we need some space for the header.
446
       */
447
0
      max_limit = 0xFFFF00;
448
0
    }
449
0
  }
450
451
  /*
452
   * the defaults are 8MB, but we'll limit this to max_limit based on
453
   * the dialect (64kb for SMB 2.0, 8MB for SMB >= 2.1 with LargeMTU)
454
   *
455
   * user configured values exceeding the limits will be overwritten,
456
   * only smaller values will be accepted
457
   */
458
459
0
  max_trans = MIN(max_limit, lp_smb2_max_trans());
460
0
  max_read = MIN(max_limit, lp_smb2_max_read());
461
0
  max_write = MIN(max_limit, lp_smb2_max_write());
462
463
0
  if (in_preauth != NULL) {
464
0
    size_t needed = 4;
465
0
    uint16_t hash_count;
466
0
    uint16_t salt_length;
467
0
    uint16_t selected_preauth = 0;
468
0
    const uint8_t *p;
469
0
    uint8_t buf[38];
470
0
    size_t i;
471
472
0
    if (in_preauth->data.length < needed) {
473
0
      return smbd_smb2_request_error(req,
474
0
          NT_STATUS_INVALID_PARAMETER);
475
0
    }
476
477
0
    hash_count = SVAL(in_preauth->data.data, 0);
478
0
    salt_length = SVAL(in_preauth->data.data, 2);
479
480
0
    if (hash_count == 0) {
481
0
      return smbd_smb2_request_error(req,
482
0
          NT_STATUS_INVALID_PARAMETER);
483
0
    }
484
485
0
    p = in_preauth->data.data + needed;
486
0
    needed += hash_count * 2;
487
0
    needed += salt_length;
488
489
0
    if (in_preauth->data.length < needed) {
490
0
      return smbd_smb2_request_error(req,
491
0
          NT_STATUS_INVALID_PARAMETER);
492
0
    }
493
494
0
    for (i=0; i < hash_count; i++) {
495
0
      uint16_t v;
496
497
0
      v = SVAL(p, 0);
498
0
      p += 2;
499
500
0
      if (v == SMB2_PREAUTH_INTEGRITY_SHA512) {
501
0
        selected_preauth = v;
502
0
        break;
503
0
      }
504
0
    }
505
506
0
    if (selected_preauth == 0) {
507
0
      return smbd_smb2_request_error(req,
508
0
        NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP);
509
0
    }
510
511
0
    SSVAL(buf, 0,  1); /* HashAlgorithmCount */
512
0
    SSVAL(buf, 2, 32); /* SaltLength */
513
0
    SSVAL(buf, 4, selected_preauth);
514
0
    generate_random_buffer(buf + 6, 32);
515
516
0
    status = smb2_negotiate_context_add(
517
0
      req,
518
0
      &out_c,
519
0
      SMB2_PREAUTH_INTEGRITY_CAPABILITIES,
520
0
      buf,
521
0
      sizeof(buf));
522
0
    if (!NT_STATUS_IS_OK(status)) {
523
0
      return smbd_smb2_request_error(req, status);
524
0
    }
525
526
0
    req->preauth = &req->xconn->smb2.preauth;
527
0
  }
528
529
0
  if (protocol >= PROTOCOL_SMB3_00) {
530
0
    xconn->smb2.server.sign_algo = SMB2_SIGNING_AES128_CMAC;
531
0
  } else {
532
0
    xconn->smb2.server.sign_algo = SMB2_SIGNING_HMAC_SHA256;
533
0
  }
534
535
0
  if ((capabilities & SMB2_CAP_ENCRYPTION) && (in_cipher != NULL)) {
536
0
    const struct smb3_encryption_capabilities *srv_ciphers =
537
0
      &default_smb3_capabilities.encryption;
538
0
    uint16_t srv_preferred_idx = UINT16_MAX;
539
0
    size_t needed = 2;
540
0
    uint16_t cipher_count;
541
0
    const uint8_t *p;
542
0
    uint8_t buf[4];
543
0
    size_t i;
544
545
0
    capabilities &= ~SMB2_CAP_ENCRYPTION;
546
547
0
    if (in_cipher->data.length < needed) {
548
0
      return smbd_smb2_request_error(req,
549
0
          NT_STATUS_INVALID_PARAMETER);
550
0
    }
551
552
0
    cipher_count = SVAL(in_cipher->data.data, 0);
553
0
    if (cipher_count == 0) {
554
0
      return smbd_smb2_request_error(req,
555
0
          NT_STATUS_INVALID_PARAMETER);
556
0
    }
557
558
0
    p = in_cipher->data.data + needed;
559
0
    needed += cipher_count * 2;
560
561
0
    if (in_cipher->data.length < needed) {
562
0
      return smbd_smb2_request_error(req,
563
0
          NT_STATUS_INVALID_PARAMETER);
564
0
    }
565
566
0
    for (i=0; i < cipher_count; i++) {
567
0
      uint16_t si;
568
0
      uint16_t v;
569
570
0
      v = SVAL(p, 0);
571
0
      p += 2;
572
573
0
      for (si = 0; si < srv_ciphers->num_algos; si++) {
574
0
        if (srv_ciphers->algos[si] != v) {
575
0
          continue;
576
0
        }
577
578
        /*
579
         * The server ciphers are listed
580
         * with the lowest idx being preferred.
581
         */
582
0
        if (si < srv_preferred_idx) {
583
0
          srv_preferred_idx = si;
584
0
        }
585
0
        break;
586
0
      }
587
0
    }
588
589
0
    if (srv_preferred_idx != UINT16_MAX) {
590
0
      xconn->smb2.server.cipher =
591
0
        srv_ciphers->algos[srv_preferred_idx];
592
0
    }
593
594
0
    SSVAL(buf, 0, 1); /* ChiperCount */
595
0
    SSVAL(buf, 2, xconn->smb2.server.cipher);
596
597
0
    status = smb2_negotiate_context_add(
598
0
      req,
599
0
      &out_c,
600
0
      SMB2_ENCRYPTION_CAPABILITIES,
601
0
      buf,
602
0
      sizeof(buf));
603
0
    if (!NT_STATUS_IS_OK(status)) {
604
0
      return smbd_smb2_request_error(req, status);
605
0
    }
606
0
  }
607
608
0
  if (capabilities & SMB2_CAP_ENCRYPTION) {
609
0
    xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
610
0
  }
611
612
0
  if (in_sign_algo != NULL) {
613
0
    const struct smb3_signing_capabilities *srv_sign_algos =
614
0
      &default_smb3_capabilities.signing;
615
0
    uint16_t srv_preferred_idx = UINT16_MAX;
616
0
    size_t needed = 2;
617
0
    uint16_t sign_algo_count;
618
0
    const uint8_t *p;
619
0
    size_t i;
620
621
0
    if (in_sign_algo->data.length < needed) {
622
0
      return smbd_smb2_request_error(req,
623
0
          NT_STATUS_INVALID_PARAMETER);
624
0
    }
625
626
0
    sign_algo_count = SVAL(in_sign_algo->data.data, 0);
627
0
    if (sign_algo_count == 0) {
628
0
      return smbd_smb2_request_error(req,
629
0
          NT_STATUS_INVALID_PARAMETER);
630
0
    }
631
632
0
    p = in_sign_algo->data.data + needed;
633
0
    needed += sign_algo_count * 2;
634
635
0
    if (in_sign_algo->data.length < needed) {
636
0
      return smbd_smb2_request_error(req,
637
0
          NT_STATUS_INVALID_PARAMETER);
638
0
    }
639
640
0
    for (i=0; i < sign_algo_count; i++) {
641
0
      uint16_t si;
642
0
      uint16_t v;
643
644
0
      v = SVAL(p, 0);
645
0
      p += 2;
646
647
0
      for (si = 0; si < srv_sign_algos->num_algos; si++) {
648
0
        if (srv_sign_algos->algos[si] != v) {
649
0
          continue;
650
0
        }
651
652
        /*
653
         * The server sign_algos are listed
654
         * with the lowest idx being preferred.
655
         */
656
0
        if (si < srv_preferred_idx) {
657
0
          srv_preferred_idx = si;
658
0
        }
659
0
        break;
660
0
      }
661
0
    }
662
663
    /*
664
     * If we found a match announce it
665
     * otherwise we'll keep the default
666
     * of SMB2_SIGNING_AES128_CMAC
667
     */
668
0
    if (srv_preferred_idx != UINT16_MAX) {
669
0
      uint8_t buf[4];
670
671
0
      xconn->smb2.server.sign_algo =
672
0
        srv_sign_algos->algos[srv_preferred_idx];
673
674
0
      SSVAL(buf, 0, 1); /* SigningAlgorithmCount */
675
0
      SSVAL(buf, 2, xconn->smb2.server.sign_algo);
676
677
0
      status = smb2_negotiate_context_add(
678
0
        req,
679
0
        &out_c,
680
0
        SMB2_SIGNING_CAPABILITIES,
681
0
        buf,
682
0
        sizeof(buf));
683
0
      if (!NT_STATUS_IS_OK(status)) {
684
0
        return smbd_smb2_request_error(req, status);
685
0
      }
686
0
    }
687
0
  }
688
689
0
  if (in_transport_caps != NULL) {
690
0
    uint32_t caps_flags;
691
692
0
    if (in_transport_caps->data.length != 4) {
693
0
      return smbd_smb2_request_error(
694
0
        req, NT_STATUS_INVALID_PARAMETER);
695
0
    }
696
697
0
    caps_flags = PULL_LE_U32(in_transport_caps->data.data, 0);
698
699
0
    if ((xconn->transport.type == SMB_TRANSPORT_TYPE_QUIC) &&
700
0
        (caps_flags & SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY) &&
701
0
        !lp_server_smb_encryption_over_quic())
702
0
    {
703
0
      uint8_t buf[4];
704
705
0
      PUSH_LE_U32(buf,
706
0
            0,
707
0
            SMB2_ACCEPT_TRANSPORT_LEVEL_SECURITY);
708
709
0
      status = smb2_negotiate_context_add(
710
0
        req,
711
0
        &out_c,
712
0
        SMB2_TRANSPORT_CAPABILITIES,
713
0
        buf,
714
0
        sizeof(buf));
715
0
      if (!NT_STATUS_IS_OK(status)) {
716
0
        return smbd_smb2_request_error(req, status);
717
0
      }
718
719
0
      xconn->transport.trusted_quic = true;
720
0
    }
721
0
  }
722
723
0
  status = smb311_capabilities_check(&default_smb3_capabilities,
724
0
             "smb2srv_negprot",
725
0
             DBGLVL_NOTICE,
726
0
             NT_STATUS_INVALID_PARAMETER,
727
0
             "server",
728
0
             protocol,
729
0
             xconn->smb2.server.sign_algo,
730
0
             xconn->smb2.server.cipher);
731
0
  if (!NT_STATUS_IS_OK(status)) {
732
0
    return smbd_smb2_request_error(req, status);
733
0
  }
734
735
0
  if (protocol >= PROTOCOL_SMB3_00 &&
736
0
      xconn->client->server_multi_channel_enabled)
737
0
  {
738
0
    if (in_capabilities & SMB2_CAP_MULTI_CHANNEL) {
739
0
      capabilities |= SMB2_CAP_MULTI_CHANNEL;
740
0
    }
741
0
  }
742
743
0
  security_offset = SMB2_HDR_BODY + 0x40;
744
745
0
#if 1
746
  /* Try SPNEGO auth... */
747
0
  security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
748
0
            negprot_spnego_blob.length - 16);
749
#else
750
  /* for now we want raw NTLMSSP */
751
  security_buffer = data_blob_const(NULL, 0);
752
#endif
753
754
0
  if (posix) {
755
    /* Client correctly negotiated SMB2 unix extensions. */
756
0
    const uint8_t *buf = (const uint8_t *)SMB2_CREATE_TAG_POSIX;
757
0
    status = smb2_negotiate_context_add(
758
0
        req,
759
0
        &out_c,
760
0
        SMB2_POSIX_EXTENSIONS_AVAILABLE,
761
0
        buf,
762
0
        16);
763
0
    if (!NT_STATUS_IS_OK(status)) {
764
0
      return smbd_smb2_request_error(req, status);
765
0
    }
766
0
    xconn->smb2.server.posix_extensions_negotiated = true;
767
0
  }
768
769
0
  if (out_c.num_contexts != 0) {
770
0
    status = smb2_negotiate_context_push(req,
771
0
            &out_negotiate_context_blob,
772
0
            out_c);
773
0
    if (!NT_STATUS_IS_OK(status)) {
774
0
      return smbd_smb2_request_error(req, status);
775
0
    }
776
0
  }
777
778
0
  if (out_negotiate_context_blob.length != 0) {
779
0
    static const uint8_t zeros[8];
780
0
    size_t pad = 0;
781
0
    size_t ofs;
782
783
0
    outdyn = data_blob_dup_talloc(req, security_buffer);
784
0
    if (outdyn.length != security_buffer.length) {
785
0
      return smbd_smb2_request_error(req,
786
0
            NT_STATUS_NO_MEMORY);
787
0
    }
788
789
0
    ofs = security_offset + security_buffer.length;
790
0
    if ((ofs % 8) != 0) {
791
0
      pad = 8 - (ofs % 8);
792
0
    }
793
0
    ofs += pad;
794
795
0
    ok = data_blob_append(req, &outdyn, zeros, pad);
796
0
    if (!ok) {
797
0
      return smbd_smb2_request_error(req,
798
0
            NT_STATUS_NO_MEMORY);
799
0
    }
800
801
0
    ok = data_blob_append(req, &outdyn,
802
0
              out_negotiate_context_blob.data,
803
0
              out_negotiate_context_blob.length);
804
0
    if (!ok) {
805
0
      return smbd_smb2_request_error(req,
806
0
            NT_STATUS_NO_MEMORY);
807
0
    }
808
809
0
    out_negotiate_context_offset = ofs;
810
0
    out_negotiate_context_count = out_c.num_contexts;
811
0
  } else {
812
0
    outdyn = security_buffer;
813
0
  }
814
815
0
  out_guid_blob = data_blob_const(negprot_spnego_blob.data, 16);
816
0
  status = GUID_from_ndr_blob(&out_guid_blob, &out_guid);
817
0
  if (!NT_STATUS_IS_OK(status)) {
818
0
    return smbd_smb2_request_error(req, status);
819
0
  }
820
821
0
  outbody = smbd_smb2_generate_outbody(req, 0x40);
822
0
  if (outbody.data == NULL) {
823
0
    return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
824
0
  }
825
826
0
  SSVAL(outbody.data, 0x00, 0x40 + 1); /* struct size */
827
0
  SSVAL(outbody.data, 0x02,
828
0
        security_mode);     /* security mode */
829
0
  SSVAL(outbody.data, 0x04, dialect);  /* dialect revision */
830
0
  SSVAL(outbody.data, 0x06,
831
0
        out_negotiate_context_count); /* reserved/NegotiateContextCount */
832
0
  memcpy(outbody.data + 0x08,
833
0
         out_guid_blob.data, 16); /* server guid */
834
0
  SIVAL(outbody.data, 0x18,
835
0
        capabilities);      /* capabilities */
836
0
  SIVAL(outbody.data, 0x1C, max_trans);  /* max transact size */
837
0
  SIVAL(outbody.data, 0x20, max_read); /* max read size */
838
0
  SIVAL(outbody.data, 0x24, max_write);  /* max write size */
839
0
  SBVAL(outbody.data, 0x28, now);    /* system time */
840
0
  SBVAL(outbody.data, 0x30, 0);    /* server start time */
841
0
  SSVAL(outbody.data, 0x38,
842
0
        security_offset);     /* security buffer offset */
843
0
  SSVAL(outbody.data, 0x3A,
844
0
        security_buffer.length);    /* security buffer length */
845
0
  SIVAL(outbody.data, 0x3C,
846
0
        out_negotiate_context_offset);  /* reserved/NegotiateContextOffset */
847
848
0
  if (dialect == SMB2_DIALECT_REVISION_2FF) {
849
0
    return smbd_smb2_request_done(req, outbody, &outdyn);
850
0
  }
851
852
0
  status = smbXsrv_connection_init_tables(xconn, protocol);
853
0
  if (!NT_STATUS_IS_OK(status)) {
854
0
    return smbd_smb2_request_error(req, status);
855
0
  }
856
857
0
  xconn->smb2.client.capabilities = in_capabilities;
858
0
  xconn->smb2.client.security_mode = in_security_mode;
859
0
  xconn->smb2.client.guid = in_guid;
860
0
  xconn->smb2.client.num_dialects = dialect_count;
861
0
  xconn->smb2.client.dialects = talloc_array(xconn,
862
0
               uint16_t,
863
0
               dialect_count);
864
0
  if (xconn->smb2.client.dialects == NULL) {
865
0
    return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
866
0
  }
867
0
  for (c=0; c < dialect_count; c++) {
868
0
    xconn->smb2.client.dialects[c] = SVAL(indyn, c*2);
869
0
  }
870
871
0
  xconn->smb2.server.capabilities = capabilities;
872
0
  xconn->smb2.server.security_mode = security_mode;
873
0
  xconn->smb2.server.guid = out_guid;
874
0
  xconn->smb2.server.dialect = dialect;
875
0
  xconn->smb2.server.max_trans = max_trans;
876
0
  xconn->smb2.server.max_read  = max_read;
877
0
  xconn->smb2.server.max_write = max_write;
878
879
0
  if (xconn->protocol < PROTOCOL_SMB2_10) {
880
    /*
881
     * SMB2_02 doesn't support client guids
882
     */
883
0
    return smbd_smb2_request_done(req, outbody, &outdyn);
884
0
  }
885
886
0
  if (!xconn->client->server_multi_channel_enabled) {
887
    /*
888
     * Only deal with the client guid database
889
     * if multi-channel is enabled.
890
     *
891
     * But we still need to setup
892
     * xconn->client->global->client_guid to
893
     * the correct value.
894
     */
895
0
    xconn->client->global->client_guid =
896
0
      xconn->smb2.client.guid;
897
0
    return smbd_smb2_request_done(req, outbody, &outdyn);
898
0
  }
899
900
0
  if (xconn->smb2.client.guid_verified) {
901
    /*
902
     * The connection was passed from another
903
     * smbd process.
904
     */
905
0
    return smbd_smb2_request_done(req, outbody, &outdyn);
906
0
  }
907
908
0
  state = talloc_zero(req, struct smbd_smb2_request_process_negprot_state);
909
0
  if (state == NULL) {
910
0
    return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
911
0
  }
912
0
  *state = (struct smbd_smb2_request_process_negprot_state) {
913
0
    .req = req,
914
0
    .outbody = outbody,
915
0
    .outdyn = outdyn,
916
0
  };
917
918
0
  subreq = smb2srv_client_mc_negprot_send(state,
919
0
            req->xconn->client->raw_ev_ctx,
920
0
            req);
921
0
  if (subreq == NULL) {
922
0
    return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
923
0
  }
924
0
  tevent_req_set_callback(subreq,
925
0
        smbd_smb2_request_process_negprot_mc_done,
926
0
        state);
927
0
  return NT_STATUS_OK;
928
0
}
929
930
static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq)
931
0
{
932
0
  struct smbd_smb2_request_process_negprot_state *state =
933
0
    tevent_req_callback_data(subreq,
934
0
    struct smbd_smb2_request_process_negprot_state);
935
0
  struct smbd_smb2_request *req = state->req;
936
0
  struct smbXsrv_connection *xconn = req->xconn;
937
0
  NTSTATUS status;
938
939
0
  status = smb2srv_client_mc_negprot_recv(subreq);
940
0
  TALLOC_FREE(subreq);
941
0
  if (NT_STATUS_EQUAL(status, NT_STATUS_MESSAGE_RETRIEVED)) {
942
    /*
943
     * The connection was passed to another process
944
     *
945
     * We mark the error as NT_STATUS_CONNECTION_IN_USE,
946
     * in order to indicate to low level code if
947
     * ctdbd_unregister_ips() or ctdbd_passed_ips()
948
     * is more useful.
949
     */
950
0
    smbXsrv_connection_disconnect_transport(xconn,
951
0
            NT_STATUS_CONNECTION_IN_USE);
952
0
    smbd_server_connection_terminate(xconn,
953
0
             "passed connection");
954
0
    exit_server_cleanly("connection passed");
955
0
    return;
956
0
  }
957
0
  if (!NT_STATUS_IS_OK(status)) {
958
0
    status = smbd_smb2_request_error(req, status);
959
0
    if (NT_STATUS_IS_OK(status)) {
960
0
      return;
961
0
    }
962
963
    /*
964
     * The connection was passed to another process
965
     */
966
0
    smbd_server_connection_terminate(xconn, nt_errstr(status));
967
0
    exit_server_cleanly("connection passed");
968
0
    return;
969
0
  }
970
971
  /*
972
   * We're the first connection...
973
   */
974
0
  status = smbd_smb2_request_done(req, state->outbody, &state->outdyn);
975
0
  if (NT_STATUS_IS_OK(status)) {
976
    /*
977
     * This allows us to support starting smbd under
978
     * callgrind and only start the overhead and
979
     * instrumentation after the SMB2 negprot,
980
     * this allows us to profile only useful
981
     * stuff and not all the smbd startup, forking
982
     * and multichannel handling.
983
     *
984
     * valgrind --tool=callgrind --instr-atstart=no smbd
985
     */
986
#ifdef CALLGRIND_START_INSTRUMENTATION
987
    CALLGRIND_START_INSTRUMENTATION;
988
#endif
989
0
    return;
990
0
  }
991
992
  /*
993
   * The connection was passed to another process
994
   */
995
0
  smbd_server_connection_terminate(xconn, nt_errstr(status));
996
0
  exit_server_cleanly("connection passed");
997
0
  return;
998
0
}
999
1000
/****************************************************************************
1001
 Generate the spnego negprot reply blob. Return the number of bytes used.
1002
****************************************************************************/
1003
1004
DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn)
1005
0
{
1006
0
  DATA_BLOB blob = data_blob_null;
1007
0
  DATA_BLOB blob_out = data_blob_null;
1008
0
  nstring dos_name;
1009
0
  fstring unix_name;
1010
0
  NTSTATUS status;
1011
0
#ifdef DEVELOPER
1012
0
  size_t slen;
1013
0
#endif
1014
0
  struct gensec_security *gensec_security;
1015
1016
  /* See if we can get an SPNEGO blob */
1017
0
  status = auth_generic_prepare(talloc_tos(),
1018
0
              xconn->remote_address,
1019
0
              xconn->local_address,
1020
0
              "SMB",
1021
0
              &gensec_security);
1022
1023
  /*
1024
   * Despite including it above, there is no need to set a
1025
   * remote address or similar as we are just interested in the
1026
   * SPNEGO blob, we never keep this context.
1027
   */
1028
1029
0
  if (NT_STATUS_IS_OK(status)) {
1030
0
    status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_SPNEGO);
1031
0
    if (NT_STATUS_IS_OK(status)) {
1032
0
      status = gensec_update(gensec_security, ctx,
1033
0
                 data_blob_null, &blob);
1034
      /* If we get the list of OIDs, the 'OK' answer
1035
       * is NT_STATUS_MORE_PROCESSING_REQUIRED */
1036
0
      if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1037
0
        DEBUG(0, ("Failed to start SPNEGO handler for negprot OID list!\n"));
1038
0
        blob = data_blob_null;
1039
0
      }
1040
0
    }
1041
0
    TALLOC_FREE(gensec_security);
1042
0
  }
1043
1044
0
#if defined(WITH_SMB1SERVER)
1045
0
  xconn->smb1.negprot.spnego = true;
1046
0
#endif
1047
1048
  /* strangely enough, NT does not sent the single OID NTLMSSP when
1049
     not a ADS member, it sends no OIDs at all
1050
1051
     OLD COMMENT : "we can't do this until we teach our session setup parser to know
1052
       about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
1053
1054
     Our sessionsetup code now handles raw NTLMSSP connects, so we can go
1055
     back to doing what W2K3 does here. This is needed to make PocketPC 2003
1056
     CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
1057
     for details. JRA.
1058
1059
  */
1060
1061
0
  if (blob.length == 0 || blob.data == NULL) {
1062
0
    return data_blob_null;
1063
0
  }
1064
1065
0
  blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length);
1066
0
  if (blob_out.data == NULL) {
1067
0
    data_blob_free(&blob);
1068
0
    return data_blob_null;
1069
0
  }
1070
1071
0
  memset(blob_out.data, '\0', 16);
1072
1073
0
  checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
1074
0
  (void)strlower_m(unix_name);
1075
0
  push_ascii_nstring(dos_name, unix_name);
1076
0
  strlcpy((char *)blob_out.data, dos_name, 17);
1077
1078
0
#ifdef DEVELOPER
1079
  /* Fix valgrind 'uninitialized bytes' issue. */
1080
0
  slen = strlen(dos_name);
1081
0
  if (slen < 16) {
1082
0
    memset(blob_out.data+slen, '\0', 16 - slen);
1083
0
  }
1084
0
#endif
1085
1086
0
  memcpy(&blob_out.data[16], blob.data, blob.length);
1087
1088
0
  data_blob_free(&blob);
1089
1090
0
  return blob_out;
1091
0
}
1092
1093
/*
1094
 * MS-CIFS, 2.2.4.52.2 SMB_COM_NEGOTIATE Response:
1095
 * If the server does not support any of the listed dialects, it MUST return a
1096
 * DialectIndex of 0XFFFF
1097
 */
1098
#define NO_PROTOCOL_CHOSEN  0xffff
1099
1100
#define PROT_SMB_2_002        0x1000
1101
#define PROT_SMB_2_FF       0x2000
1102
1103
/* List of supported SMB1 protocols, most desired first.
1104
 * This is for enabling multi-protocol negotiation in SMB2 when SMB1
1105
 * is disabled.
1106
 */
1107
static const struct {
1108
  const char *proto_name;
1109
  const char *short_name;
1110
  NTSTATUS (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
1111
  int protocol_level;
1112
} supported_protocols[] = {
1113
  {"SMB 2.???",               "SMB2_FF",  reply_smb20ff,  PROTOCOL_SMB2_10},
1114
  {"SMB 2.002",               "SMB2_02",  reply_smb2002,  PROTOCOL_SMB2_02},
1115
  {NULL,NULL,NULL,0},
1116
};
1117
1118
/****************************************************************************
1119
 Reply to a negprot.
1120
 conn POINTER CAN BE NULL HERE !
1121
****************************************************************************/
1122
1123
NTSTATUS smb2_multi_protocol_reply_negprot(struct smb_request *req)
1124
0
{
1125
0
  size_t choice = 0;
1126
0
  bool choice_set = false;
1127
0
  int protocol;
1128
0
  const char *p;
1129
0
  size_t num_cliprotos;
1130
0
  char **cliprotos;
1131
0
  size_t i;
1132
0
  size_t converted_size;
1133
0
  struct smbXsrv_connection *xconn = req->xconn;
1134
0
  struct smbd_server_connection *sconn = req->sconn;
1135
0
  int max_proto;
1136
0
  int min_proto;
1137
0
  NTSTATUS status;
1138
1139
0
  START_PROFILE(SMBnegprot);
1140
1141
0
  if (req->buflen == 0) {
1142
0
    DEBUG(0, ("negprot got no protocols\n"));
1143
0
    reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1144
0
    END_PROFILE(SMBnegprot);
1145
0
    return NT_STATUS_INVALID_PARAMETER;
1146
0
  }
1147
1148
0
  if (req->buf[req->buflen-1] != '\0') {
1149
0
    DEBUG(0, ("negprot protocols not 0-terminated\n"));
1150
0
    reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
1151
0
    END_PROFILE(SMBnegprot);
1152
0
    return NT_STATUS_INVALID_PARAMETER;
1153
0
  }
1154
1155
0
  p = (const char *)req->buf + 1;
1156
1157
0
  num_cliprotos = 0;
1158
0
  cliprotos = NULL;
1159
1160
0
  while (smbreq_bufrem(req, p) > 0) {
1161
1162
0
    char **tmp;
1163
1164
0
    tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
1165
0
             num_cliprotos+1);
1166
0
    if (tmp == NULL) {
1167
0
      DEBUG(0, ("talloc failed\n"));
1168
0
      TALLOC_FREE(cliprotos);
1169
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
1170
0
      END_PROFILE(SMBnegprot);
1171
0
      return NT_STATUS_NO_MEMORY;
1172
0
    }
1173
1174
0
    cliprotos = tmp;
1175
1176
0
    if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
1177
0
               &converted_size)) {
1178
0
      DEBUG(0, ("pull_ascii_talloc failed\n"));
1179
0
      TALLOC_FREE(cliprotos);
1180
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
1181
0
      END_PROFILE(SMBnegprot);
1182
0
      return NT_STATUS_NO_MEMORY;
1183
0
    }
1184
1185
0
    DEBUG(3, ("Requested protocol [%s]\n",
1186
0
        cliprotos[num_cliprotos]));
1187
1188
0
    num_cliprotos += 1;
1189
0
    p += strlen(p) + 2;
1190
0
  }
1191
1192
  /* possibly reload - change of architecture */
1193
0
  reload_services(sconn, conn_snum_used, true);
1194
1195
  /*
1196
   * Anything higher than PROTOCOL_SMB2_10 still
1197
   * needs to go via "SMB 2.???", which is marked
1198
   * as PROTOCOL_SMB2_10.
1199
   *
1200
   * The real negotiation happens via reply_smb20ff()
1201
   * using SMB2 Negotiation.
1202
   */
1203
0
  max_proto = lp_server_max_protocol();
1204
0
  if (max_proto > PROTOCOL_SMB2_10) {
1205
0
    max_proto = PROTOCOL_SMB2_10;
1206
0
  }
1207
0
  min_proto = lp_server_min_protocol();
1208
0
  if (min_proto > PROTOCOL_SMB2_10) {
1209
0
    min_proto = PROTOCOL_SMB2_10;
1210
0
  }
1211
1212
  /* Check for protocols, most desirable first */
1213
0
  for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
1214
0
    i = 0;
1215
0
    if ((supported_protocols[protocol].protocol_level <= max_proto) &&
1216
0
        (supported_protocols[protocol].protocol_level >= min_proto))
1217
0
      while (i < num_cliprotos) {
1218
0
        if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
1219
0
          choice = i;
1220
0
          choice_set = true;
1221
0
        }
1222
0
        i++;
1223
0
      }
1224
0
    if (choice_set) {
1225
0
      break;
1226
0
    }
1227
0
  }
1228
1229
0
  if (!choice_set) {
1230
0
    bool ok;
1231
1232
0
    DBG_NOTICE("No protocol supported !\n");
1233
0
    reply_smb1_outbuf(req, 1, 0);
1234
0
    SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
1235
1236
0
    ok = smb1_srv_send(xconn, (char *)req->outbuf, false, 0, false);
1237
0
    if (!ok) {
1238
0
      DBG_NOTICE("smb1_srv_send failed\n");
1239
0
    }
1240
0
    exit_server_cleanly("no protocol supported\n");
1241
0
  }
1242
1243
0
  set_remote_proto(supported_protocols[protocol].short_name);
1244
0
  reload_services(sconn, conn_snum_used, true);
1245
0
  status = supported_protocols[protocol].proto_reply_fn(req, choice);
1246
0
  if (!NT_STATUS_IS_OK(status)) {
1247
0
    exit_server_cleanly("negprot function failed\n");
1248
0
  }
1249
1250
0
  DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
1251
1252
0
  DBG_INFO("negprot index=%zu\n", choice);
1253
1254
0
  TALLOC_FREE(cliprotos);
1255
1256
0
  END_PROFILE(SMBnegprot);
1257
0
  return NT_STATUS_OK;
1258
0
}