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