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