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