Coverage Report

Created: 2025-11-16 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/smbd/smb1_negprot.c
Line
Count
Source
1
/* 
2
   Unix SMB/CIFS implementation.
3
   negprot reply code
4
   Copyright (C) Andrew Tridgell 1992-1998
5
   Copyright (C) Volker Lendecke 2007
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 "serverid.h"
25
#include "auth.h"
26
#include "messages.h"
27
#include "smbprofile.h"
28
#include "auth/gensec/gensec.h"
29
#include "../libcli/smb/smb_signing.h"
30
#include "lib/util/string_wrappers.h"
31
#include "source3/lib/substitute.h"
32
33
/*
34
 * MS-CIFS, 2.2.4.52.2 SMB_COM_NEGOTIATE Response:
35
 * If the server does not support any of the listed dialects, it MUST return a
36
 * DialectIndex of 0XFFFF
37
 */
38
#define NO_PROTOCOL_CHOSEN  0xffff
39
40
static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
41
0
{
42
0
  NTSTATUS nt_status;
43
44
  /* We might be called more than once, multiple negprots are
45
   * permitted */
46
0
  if (xconn->smb1.negprot.auth_context) {
47
0
    DEBUG(3, ("get challenge: is this a secondary negprot? "
48
0
        "sconn->negprot.auth_context is non-NULL!\n"));
49
0
    TALLOC_FREE(xconn->smb1.negprot.auth_context);
50
0
  }
51
52
0
  DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
53
0
  nt_status = make_auth4_context(
54
0
    xconn, &xconn->smb1.negprot.auth_context);
55
0
  if (!NT_STATUS_IS_OK(nt_status)) {
56
0
    DEBUG(0, ("make_auth_context_subsystem returned %s\n",
57
0
        nt_errstr(nt_status)));
58
0
    smb_panic("cannot make_negprot_global_auth_context!");
59
0
  }
60
0
  DEBUG(10, ("get challenge: getting challenge\n"));
61
0
  xconn->smb1.negprot.auth_context->get_ntlm_challenge(
62
0
    xconn->smb1.negprot.auth_context, buff);
63
0
}
64
65
/****************************************************************************
66
 Reply for the lanman 1.0 protocol.
67
****************************************************************************/
68
69
static NTSTATUS reply_lanman1(struct smb_request *req, uint16_t choice)
70
0
{
71
0
  int secword=0;
72
0
  time_t t = time(NULL);
73
0
  struct smbXsrv_connection *xconn = req->xconn;
74
0
  uint16_t raw;
75
0
  NTSTATUS status;
76
77
0
  if (lp_async_smb_echo_handler()) {
78
0
    raw = 0;
79
0
  } else {
80
0
    raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
81
0
  }
82
83
0
  xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
84
85
0
  secword |= NEGOTIATE_SECURITY_USER_LEVEL;
86
0
  if (xconn->smb1.negprot.encrypted_passwords) {
87
0
    secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
88
0
  }
89
90
0
  reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
91
92
0
  SSVAL(req->outbuf,smb_vwv0,choice);
93
0
  SSVAL(req->outbuf,smb_vwv1,secword);
94
  /* Create a token value and add it to the outgoing packet. */
95
0
  if (xconn->smb1.negprot.encrypted_passwords) {
96
0
    get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
97
0
    SSVAL(req->outbuf,smb_vwv11, 8);
98
0
  }
99
100
0
  status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
101
0
  if (!NT_STATUS_IS_OK(status)) {
102
0
    reply_nterror(req, status);
103
0
    return status;
104
0
  }
105
106
  /* Reply, SMBlockread, SMBwritelock supported. */
107
0
  SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
108
0
  SSVAL(req->outbuf,smb_vwv2, xconn->smb1.negprot.max_recv);
109
0
  SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */
110
0
  SSVAL(req->outbuf,smb_vwv4, 1);
111
0
  SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support
112
    readbraw writebraw (possibly) */
113
0
  SIVAL(req->outbuf,smb_vwv6, getpid());
114
0
  SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
115
116
0
  srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
117
118
0
  return NT_STATUS_OK;
119
0
}
120
121
/****************************************************************************
122
 Reply for the lanman 2.0 protocol.
123
****************************************************************************/
124
125
static NTSTATUS reply_lanman2(struct smb_request *req, uint16_t choice)
126
0
{
127
0
  int secword=0;
128
0
  time_t t = time(NULL);
129
0
  struct smbXsrv_connection *xconn = req->xconn;
130
0
  uint16_t raw;
131
0
  NTSTATUS status;
132
133
0
  if (lp_async_smb_echo_handler()) {
134
0
    raw = 0;
135
0
  } else {
136
0
    raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
137
0
  }
138
139
0
  xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
140
141
0
  secword |= NEGOTIATE_SECURITY_USER_LEVEL;
142
0
  if (xconn->smb1.negprot.encrypted_passwords) {
143
0
    secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
144
0
  }
145
146
0
  reply_smb1_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
147
148
0
  SSVAL(req->outbuf,smb_vwv0, choice);
149
0
  SSVAL(req->outbuf,smb_vwv1, secword);
150
0
  SIVAL(req->outbuf,smb_vwv6, getpid());
151
152
  /* Create a token value and add it to the outgoing packet. */
153
0
  if (xconn->smb1.negprot.encrypted_passwords) {
154
0
    get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
155
0
    SSVAL(req->outbuf,smb_vwv11, 8);
156
0
  }
157
158
0
  status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
159
0
  if (!NT_STATUS_IS_OK(status)) {
160
0
    reply_nterror(req, status);
161
0
    return status;
162
0
  }
163
164
  /* Reply, SMBlockread, SMBwritelock supported. */
165
0
  SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
166
0
  SSVAL(req->outbuf,smb_vwv2,xconn->smb1.negprot.max_recv);
167
0
  SSVAL(req->outbuf,smb_vwv3,lp_max_mux());
168
0
  SSVAL(req->outbuf,smb_vwv4,1);
169
0
  SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
170
0
  SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
171
0
  srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
172
0
  return NT_STATUS_OK;
173
0
}
174
175
/****************************************************************************
176
 Reply for the nt protocol.
177
****************************************************************************/
178
179
static NTSTATUS reply_nt1(struct smb_request *req, uint16_t choice)
180
0
{
181
  /* dual names + lock_and_read + nt SMBs + remote API calls */
182
0
  int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
183
0
    CAP_LEVEL_II_OPLOCKS;
184
185
0
  int secword=0;
186
0
  bool negotiate_spnego = False;
187
0
  struct timespec ts;
188
0
  ssize_t ret;
189
0
  struct smbXsrv_connection *xconn = req->xconn;
190
0
  bool signing_desired = false;
191
0
  bool signing_required = false;
192
0
  NTSTATUS status;
193
194
0
  xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
195
196
  /* Check the flags field to see if this is Vista.
197
     WinXP sets it and Vista does not. But we have to 
198
     distinguish from NT which doesn't set it either. */
199
200
0
  if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
201
0
    ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
202
0
  {
203
0
    if ((get_remote_arch() != RA_SAMBA) &&
204
0
        (get_remote_arch() != RA_CIFSFS)) {
205
0
      set_remote_arch( RA_VISTA );
206
0
    }
207
0
  }
208
209
0
  reply_smb1_outbuf(req,17,0);
210
211
  /* do spnego in user level security if the client
212
     supports it and we can do encrypted passwords */
213
214
0
  if (xconn->smb1.negprot.encrypted_passwords &&
215
0
      (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
216
0
    negotiate_spnego = True;
217
0
    capabilities |= CAP_EXTENDED_SECURITY;
218
0
    add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
219
    /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
220
       (already partially constructed. */
221
0
    SSVAL(req->outbuf, smb_flg2,
222
0
          req->flags2 | FLAGS2_EXTENDED_SECURITY);
223
0
  }
224
225
0
  capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
226
227
0
  if (lp_unicode()) {
228
0
    capabilities |= CAP_UNICODE;
229
0
  }
230
231
0
  if (lp_smb1_unix_extensions()) {
232
0
    capabilities |= CAP_UNIX;
233
0
  }
234
235
0
  if (lp_large_readwrite())
236
0
    capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
237
238
0
  capabilities |= CAP_LARGE_FILES;
239
240
0
  if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
241
0
    capabilities |= CAP_RAW_MODE;
242
243
0
  if (lp_nt_status_support())
244
0
    capabilities |= CAP_STATUS32;
245
246
0
  if (lp_host_msdfs())
247
0
    capabilities |= CAP_DFS;
248
249
0
  secword |= NEGOTIATE_SECURITY_USER_LEVEL;
250
0
  if (xconn->smb1.negprot.encrypted_passwords) {
251
0
    secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
252
0
  }
253
254
0
  signing_desired = smb1_signing_is_desired(xconn->smb1.signing_state);
255
0
  signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
256
257
0
  if (signing_desired) {
258
0
    secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
259
    /* No raw mode with smb signing. */
260
0
    capabilities &= ~CAP_RAW_MODE;
261
0
    if (signing_required) {
262
0
      secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
263
0
    }
264
0
  }
265
266
0
  SSVAL(req->outbuf,smb_vwv0,choice);
267
0
  SCVAL(req->outbuf,smb_vwv1,secword);
268
269
0
  status = smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
270
0
  if (!NT_STATUS_IS_OK(status)) {
271
0
    reply_nterror(req, status);
272
0
    return status;
273
0
  }
274
275
0
  SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
276
0
  SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
277
0
  SIVAL(req->outbuf,smb_vwv3+1,
278
0
        xconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
279
0
  SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
280
0
  SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
281
0
  SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
282
0
  clock_gettime(CLOCK_REALTIME,&ts);
283
0
  put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,&ts);
284
0
  SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
285
286
0
  if (!negotiate_spnego) {
287
    /* Create a token value and add it to the outgoing packet. */
288
0
    if (xconn->smb1.negprot.encrypted_passwords) {
289
0
      uint8_t chal[8];
290
      /* note that we do not send a challenge at all if
291
         we are using plaintext */
292
0
      get_challenge(xconn, chal);
293
0
      ret = message_push_blob(
294
0
        &req->outbuf, data_blob_const(chal, sizeof(chal)));
295
0
      if (ret == -1) {
296
0
        DEBUG(0, ("Could not push challenge\n"));
297
0
        reply_nterror(req, NT_STATUS_NO_MEMORY);
298
0
        return NT_STATUS_NO_MEMORY;
299
0
      }
300
0
      SCVAL(req->outbuf, smb_vwv16+1, ret);
301
0
    }
302
0
    ret = message_push_string(&req->outbuf, lp_workgroup(),
303
0
            STR_UNICODE|STR_TERMINATE
304
0
            |STR_NOALIGN);
305
0
    if (ret == -1) {
306
0
      DEBUG(0, ("Could not push workgroup string\n"));
307
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
308
0
      return NT_STATUS_NO_MEMORY;
309
0
    }
310
0
    ret = message_push_string(&req->outbuf, lp_netbios_name(),
311
0
            STR_UNICODE|STR_TERMINATE
312
0
            |STR_NOALIGN);
313
0
    if (ret == -1) {
314
0
      DEBUG(0, ("Could not push netbios name string\n"));
315
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
316
0
      return NT_STATUS_NO_MEMORY;
317
0
    }
318
0
    DEBUG(3,("not using SPNEGO\n"));
319
0
  } else {
320
0
    DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
321
322
0
    if (spnego_blob.data == NULL) {
323
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
324
0
      return NT_STATUS_NO_MEMORY;
325
0
    }
326
327
0
    ret = message_push_blob(&req->outbuf, spnego_blob);
328
0
    if (ret == -1) {
329
0
      DEBUG(0, ("Could not push spnego blob\n"));
330
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
331
0
      return NT_STATUS_NO_MEMORY;
332
0
    }
333
0
    data_blob_free(&spnego_blob);
334
335
0
    SCVAL(req->outbuf,smb_vwv16+1, 0);
336
0
    DEBUG(3,("using SPNEGO\n"));
337
0
  }
338
339
0
  return NT_STATUS_OK;
340
0
}
341
342
/* these are the protocol lists used for auto architecture detection:
343
344
WinNT 3.51:
345
protocol [PC NETWORK PROGRAM 1.0]
346
protocol [XENIX CORE]
347
protocol [MICROSOFT NETWORKS 1.03]
348
protocol [LANMAN1.0]
349
protocol [Windows for Workgroups 3.1a]
350
protocol [LM1.2X002]
351
protocol [LANMAN2.1]
352
protocol [NT LM 0.12]
353
354
Win95:
355
protocol [PC NETWORK PROGRAM 1.0]
356
protocol [XENIX CORE]
357
protocol [MICROSOFT NETWORKS 1.03]
358
protocol [LANMAN1.0]
359
protocol [Windows for Workgroups 3.1a]
360
protocol [LM1.2X002]
361
protocol [LANMAN2.1]
362
protocol [NT LM 0.12]
363
364
Win2K:
365
protocol [PC NETWORK PROGRAM 1.0]
366
protocol [LANMAN1.0]
367
protocol [Windows for Workgroups 3.1a]
368
protocol [LM1.2X002]
369
protocol [LANMAN2.1]
370
protocol [NT LM 0.12]
371
372
Vista:
373
protocol [PC NETWORK PROGRAM 1.0]
374
protocol [LANMAN1.0]
375
protocol [Windows for Workgroups 3.1a]
376
protocol [LM1.2X002]
377
protocol [LANMAN2.1]
378
protocol [NT LM 0.12]
379
protocol [SMB 2.001]
380
381
OS/2:
382
protocol [PC NETWORK PROGRAM 1.0]
383
protocol [XENIX CORE]
384
protocol [LANMAN1.0]
385
protocol [LM1.2X002]
386
protocol [LANMAN2.1]
387
388
OSX:
389
protocol [NT LM 0.12]
390
protocol [SMB 2.002]
391
protocol [SMB 2.???]
392
*/
393
394
/*
395
  * Modified to recognize the architecture of the remote machine better.
396
  *
397
  * This appears to be the matrix of which protocol is used by which
398
  * product.
399
       Protocol                       WfWg Win95 WinNT Win2K OS/2 Vista OSX
400
       PC NETWORK PROGRAM 1.0          1     1     1     1     1    1
401
       XENIX CORE                                  2           2
402
       MICROSOFT NETWORKS 3.0          2     2
403
       DOS LM1.2X002                   3     3
404
       MICROSOFT NETWORKS 1.03                     3
405
       DOS LANMAN2.1                   4     4
406
       LANMAN1.0                                   4     2     3    2
407
       Windows for Workgroups 3.1a     5     5     5     3          3
408
       LM1.2X002                                   6     4     4    4
409
       LANMAN2.1                                   7     5     5    5
410
       NT LM 0.12                            6     8     6     6    6    1
411
       SMB 2.001                                                    7
412
       SMB 2.002                                                         2
413
       SMB 2.???                                                         3
414
  *
415
  *  tim@fsg.com 09/29/95
416
  *  Win2K added by matty 17/7/99
417
  */
418
419
0
#define PROT_PC_NETWORK_PROGRAM_1_0   0x0001
420
0
#define PROT_XENIX_CORE       0x0002
421
0
#define PROT_MICROSOFT_NETWORKS_3_0   0x0004
422
0
#define PROT_DOS_LM1_2X002      0x0008
423
0
#define PROT_MICROSOFT_NETWORKS_1_03    0x0010
424
0
#define PROT_DOS_LANMAN2_1      0x0020
425
0
#define PROT_LANMAN1_0        0x0040
426
0
#define PROT_WFWG       0x0080
427
0
#define PROT_LM1_2X002        0x0100
428
0
#define PROT_LANMAN2_1        0x0200
429
0
#define PROT_NT_LM_0_12       0x0400
430
0
#define PROT_SMB_2_001        0x0800
431
0
#define PROT_SMB_2_002        0x1000
432
0
#define PROT_SMB_2_FF       0x2000
433
0
#define PROT_SAMBA        0x4000
434
0
#define PROT_POSIX_2        0x8000
435
436
0
#define ARCH_WFWG     ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_MICROSOFT_NETWORKS_3_0 | \
437
0
      PROT_DOS_LM1_2X002 | PROT_DOS_LANMAN2_1 | PROT_WFWG )
438
0
#define ARCH_WIN95    ( ARCH_WFWG | PROT_NT_LM_0_12 )
439
0
#define ARCH_WINNT    ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_XENIX_CORE | \
440
0
      PROT_MICROSOFT_NETWORKS_1_03 | PROT_LANMAN1_0 | PROT_WFWG | \
441
0
      PROT_LM1_2X002 | PROT_LANMAN2_1 | PROT_NT_LM_0_12 )
442
0
#define ARCH_WIN2K    ( ARCH_WINNT & ~(PROT_XENIX_CORE | PROT_MICROSOFT_NETWORKS_1_03) )
443
0
#define ARCH_OS2      ( ARCH_WINNT & ~(PROT_MICROSOFT_NETWORKS_1_03 | PROT_WFWG) )
444
0
#define ARCH_VISTA    ( ARCH_WIN2K | PROT_SMB_2_001 )
445
0
#define ARCH_SAMBA    ( PROT_SAMBA )
446
0
#define ARCH_CIFSFS   ( PROT_POSIX_2 )
447
0
#define ARCH_OSX      ( PROT_NT_LM_0_12 | PROT_SMB_2_002 | PROT_SMB_2_FF )
448
449
/* List of supported protocols, most desired first */
450
static const struct {
451
  const char *proto_name;
452
  const char *short_name;
453
  NTSTATUS (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
454
  int protocol_level;
455
} supported_protocols[] = {
456
  {"SMB 2.???",               "SMB2_FF",  reply_smb20ff,  PROTOCOL_SMB2_10},
457
  {"SMB 2.002",               "SMB2_02",  reply_smb2002,  PROTOCOL_SMB2_02},
458
  {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
459
  {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
460
  {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
461
  {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
462
  {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
463
  {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
464
  {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
465
  {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
466
  {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
467
  {NULL,NULL,NULL,0},
468
};
469
470
/****************************************************************************
471
 Reply to a negprot.
472
 conn POINTER CAN BE NULL HERE !
473
****************************************************************************/
474
475
void reply_negprot(struct smb_request *req)
476
0
{
477
0
  size_t choice = 0;
478
0
  int chosen_level = -1;
479
0
  bool choice_set = false;
480
0
  int protocol;
481
0
  const char *p;
482
0
  int protocols = 0;
483
0
  size_t num_cliprotos;
484
0
  char **cliprotos;
485
0
  size_t i;
486
0
  size_t converted_size;
487
0
  struct smbXsrv_connection *xconn = req->xconn;
488
0
  struct smbd_server_connection *sconn = req->sconn;
489
0
  bool signing_required = true;
490
0
  int max_proto;
491
0
  int min_proto;
492
0
  NTSTATUS status;
493
494
0
  START_PROFILE(SMBnegprot);
495
496
0
  if (xconn->smb1.negprot.done) {
497
0
    END_PROFILE(SMBnegprot);
498
0
    exit_server_cleanly("multiple negprot's are not permitted");
499
0
  }
500
501
0
  if (req->buflen == 0) {
502
0
    DEBUG(0, ("negprot got no protocols\n"));
503
0
    reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
504
0
    END_PROFILE(SMBnegprot);
505
0
    return;
506
0
  }
507
508
0
  if (req->buf[req->buflen-1] != '\0') {
509
0
    DEBUG(0, ("negprot protocols not 0-terminated\n"));
510
0
    reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
511
0
    END_PROFILE(SMBnegprot);
512
0
    return;
513
0
  }
514
515
0
  p = (const char *)req->buf + 1;
516
517
0
  num_cliprotos = 0;
518
0
  cliprotos = NULL;
519
520
0
  while (smbreq_bufrem(req, p) > 0) {
521
522
0
    char **tmp = talloc_realloc(talloc_tos(),
523
0
              cliprotos,
524
0
              char *,
525
0
              num_cliprotos + 1);
526
0
    if (tmp == NULL) {
527
0
      DEBUG(0, ("talloc failed\n"));
528
0
      TALLOC_FREE(cliprotos);
529
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
530
0
      END_PROFILE(SMBnegprot);
531
0
      return;
532
0
    }
533
534
0
    cliprotos = tmp;
535
536
0
    if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
537
0
               &converted_size)) {
538
0
      DEBUG(0, ("pull_ascii_talloc failed\n"));
539
0
      TALLOC_FREE(cliprotos);
540
0
      reply_nterror(req, NT_STATUS_NO_MEMORY);
541
0
      END_PROFILE(SMBnegprot);
542
0
      return;
543
0
    }
544
545
0
    DEBUG(3, ("Requested protocol [%s]\n",
546
0
        cliprotos[num_cliprotos]));
547
548
0
    num_cliprotos += 1;
549
0
    p += strlen(p) + 2;
550
0
  }
551
552
0
  for (i=0; i<num_cliprotos; i++) {
553
0
    if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
554
0
      protocols |= PROT_WFWG;
555
0
    } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
556
0
      protocols |= PROT_DOS_LM1_2X002;
557
0
    } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
558
0
      protocols |= PROT_DOS_LANMAN2_1;
559
0
    } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
560
0
      protocols |= PROT_LANMAN1_0;
561
0
    } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
562
0
      protocols |= PROT_NT_LM_0_12;
563
0
    } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
564
0
      protocols |= PROT_SMB_2_001;
565
0
    } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
566
0
      protocols |= PROT_SMB_2_002;
567
0
    } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
568
0
      protocols |= PROT_SMB_2_FF;
569
0
    } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
570
0
      protocols |= PROT_LANMAN2_1;
571
0
    } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
572
0
      protocols |= PROT_LM1_2X002;
573
0
    } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
574
0
      protocols |= PROT_MICROSOFT_NETWORKS_1_03;
575
0
    } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
576
0
      protocols |= PROT_MICROSOFT_NETWORKS_3_0;
577
0
    } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
578
0
      protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
579
0
    } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
580
0
      protocols |= PROT_XENIX_CORE;
581
0
    } else if (strcsequal(cliprotos[i], "Samba")) {
582
0
      protocols = PROT_SAMBA;
583
0
      break;
584
0
    } else if (strcsequal(cliprotos[i], "POSIX 2")) {
585
0
      protocols = PROT_POSIX_2;
586
0
      break;
587
0
    }
588
0
  }
589
590
0
  switch ( protocols ) {
591
    /* Old CIFSFS can send one arch only, NT LM 0.12. */
592
0
    case PROT_NT_LM_0_12:
593
0
    case ARCH_CIFSFS:
594
0
      set_remote_arch(RA_CIFSFS);
595
0
      break;
596
0
    case ARCH_SAMBA:
597
0
      set_remote_arch(RA_SAMBA);
598
0
      break;
599
0
    case ARCH_WFWG:
600
0
      set_remote_arch(RA_WFWG);
601
0
      break;
602
0
    case ARCH_WIN95:
603
0
      set_remote_arch(RA_WIN95);
604
0
      break;
605
0
    case ARCH_WINNT:
606
0
      set_remote_arch(RA_WINNT);
607
0
      break;
608
0
    case ARCH_WIN2K:
609
0
      set_remote_arch(RA_WIN2K);
610
0
      break;
611
0
    case ARCH_VISTA:
612
0
      set_remote_arch(RA_VISTA);
613
0
      break;
614
0
    case ARCH_OS2:
615
0
      set_remote_arch(RA_OS2);
616
0
      break;
617
0
    case ARCH_OSX:
618
0
      set_remote_arch(RA_OSX);
619
0
      break;
620
0
    default:
621
0
      set_remote_arch(RA_UNKNOWN);
622
0
    break;
623
0
  }
624
625
  /* possibly reload - change of architecture */
626
0
  reload_services(sconn, conn_snum_used, true);
627
628
  /*
629
   * Anything higher than PROTOCOL_SMB2_10 still
630
   * needs to go via "SMB 2.???", which is marked
631
   * as PROTOCOL_SMB2_10.
632
   *
633
   * The real negotiation happens via reply_smb20ff()
634
   * using SMB2 Negotiation.
635
   */
636
0
  max_proto = lp_server_max_protocol();
637
0
  if (max_proto > PROTOCOL_SMB2_10) {
638
0
    max_proto = PROTOCOL_SMB2_10;
639
0
  }
640
0
  min_proto = lp_server_min_protocol();
641
0
  if (min_proto > PROTOCOL_SMB2_10) {
642
0
    min_proto = PROTOCOL_SMB2_10;
643
0
  }
644
645
  /* Check for protocols, most desirable first */
646
0
  for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
647
0
    i = 0;
648
0
    if ((supported_protocols[protocol].protocol_level <= max_proto) &&
649
0
        (supported_protocols[protocol].protocol_level >= min_proto))
650
0
      while (i < num_cliprotos) {
651
0
        if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
652
0
          choice = i;
653
0
          chosen_level = supported_protocols[protocol].protocol_level;
654
0
          choice_set = true;
655
0
        }
656
0
        i++;
657
0
      }
658
0
    if (choice_set) {
659
0
      break;
660
0
    }
661
0
  }
662
663
0
  if (!choice_set) {
664
0
    bool ok;
665
666
0
    DBG_NOTICE("No protocol supported !\n");
667
0
    reply_smb1_outbuf(req, 1, 0);
668
0
    SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
669
670
0
    ok = smb1_srv_send(xconn, (char *)req->outbuf, false, 0, false);
671
0
    if (!ok) {
672
0
      DBG_NOTICE("smb1_srv_send failed\n");
673
0
    }
674
0
    exit_server_cleanly("no protocol supported\n");
675
0
  }
676
677
0
  set_remote_proto(supported_protocols[protocol].short_name);
678
0
  reload_services(sconn, conn_snum_used, true);
679
0
  status = supported_protocols[protocol].proto_reply_fn(req, choice);
680
0
  if (!NT_STATUS_IS_OK(status)) {
681
0
    exit_server_cleanly("negprot function failed\n");
682
0
  }
683
684
0
  DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
685
686
0
  DBG_INFO("negprot index=%zu\n", choice);
687
688
0
  xconn->smb1.negprot.done = true;
689
690
  /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
691
0
  signing_required = smb1_signing_is_mandatory(xconn->smb1.signing_state);
692
0
  if (signing_required && (chosen_level < PROTOCOL_NT1)) {
693
0
    exit_server_cleanly("SMB signing is required and "
694
0
      "client negotiated a downlevel protocol");
695
0
  }
696
697
0
  TALLOC_FREE(cliprotos);
698
699
0
  if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
700
0
      !fork_echo_handler(xconn)) {
701
0
    exit_server("Failed to fork echo handler");
702
0
  }
703
704
0
  END_PROFILE(SMBnegprot);
705
0
  return;
706
0
}