Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : client file operations
4 : Copyright (C) Andrew Tridgell 1994-1998
5 : Copyright (C) Jeremy Allison 2001-2002
6 : Copyright (C) James Myers 2003
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "libcli/smb/smb_common.h"
24 : #include "system/filesys.h"
25 : #include "lib/param/loadparm.h"
26 : #include "lib/param/param.h"
27 : #include "libcli/smb/smb2_negotiate_context.h"
28 :
29 8 : const char *smb_protocol_types_string(enum protocol_types protocol)
30 : {
31 8 : switch (protocol) {
32 0 : case PROTOCOL_DEFAULT:
33 0 : return "DEFAULT";
34 0 : case PROTOCOL_NONE:
35 0 : return "NONE";
36 0 : case PROTOCOL_CORE:
37 0 : return "CORE";
38 0 : case PROTOCOL_COREPLUS:
39 0 : return "COREPLUS";
40 0 : case PROTOCOL_LANMAN1:
41 0 : return "LANMAN1";
42 0 : case PROTOCOL_LANMAN2:
43 0 : return "LANMAN2";
44 0 : case PROTOCOL_NT1:
45 0 : return "NT1";
46 0 : case PROTOCOL_SMB2_02:
47 0 : return "SMB2_02";
48 4 : case PROTOCOL_SMB2_10:
49 4 : return "SMB2_10";
50 0 : case PROTOCOL_SMB3_00:
51 0 : return "SMB3_00";
52 0 : case PROTOCOL_SMB3_02:
53 0 : return "SMB3_02";
54 4 : case PROTOCOL_SMB3_11:
55 4 : return "SMB3_11";
56 : }
57 :
58 0 : return "Invalid protocol_types value";
59 : }
60 :
61 : /**
62 : Return a string representing a CIFS attribute for a file.
63 : **/
64 37631 : char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)
65 : {
66 0 : size_t i, len;
67 0 : static const struct {
68 : char c;
69 : uint16_t attr;
70 : } attr_strs[] = {
71 : {'V', FILE_ATTRIBUTE_VOLUME},
72 : {'D', FILE_ATTRIBUTE_DIRECTORY},
73 : {'A', FILE_ATTRIBUTE_ARCHIVE},
74 : {'H', FILE_ATTRIBUTE_HIDDEN},
75 : {'S', FILE_ATTRIBUTE_SYSTEM},
76 : {'N', FILE_ATTRIBUTE_NORMAL},
77 : {'R', FILE_ATTRIBUTE_READONLY},
78 : {'d', FILE_ATTRIBUTE_DEVICE},
79 : {'t', FILE_ATTRIBUTE_TEMPORARY},
80 : {'s', FILE_ATTRIBUTE_SPARSE},
81 : {'r', FILE_ATTRIBUTE_REPARSE_POINT},
82 : {'c', FILE_ATTRIBUTE_COMPRESSED},
83 : {'o', FILE_ATTRIBUTE_OFFLINE},
84 : {'n', FILE_ATTRIBUTE_NONINDEXED},
85 : {'e', FILE_ATTRIBUTE_ENCRYPTED}
86 : };
87 0 : char *ret;
88 :
89 37631 : ret = talloc_array(mem_ctx, char, ARRAY_SIZE(attr_strs)+1);
90 37631 : if (!ret) {
91 0 : return NULL;
92 : }
93 :
94 602096 : for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) {
95 564465 : if (attrib & attr_strs[i].attr) {
96 38500 : ret[len++] = attr_strs[i].c;
97 : }
98 : }
99 :
100 37631 : ret[len] = 0;
101 :
102 37631 : talloc_set_name_const(ret, ret);
103 :
104 37631 : return ret;
105 : }
106 :
107 : /****************************************************************************
108 : Map standard UNIX permissions onto wire representations.
109 : ****************************************************************************/
110 :
111 7147 : uint32_t unix_perms_to_wire(mode_t perms)
112 : {
113 7147 : unsigned int ret = 0;
114 :
115 7147 : ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);
116 7147 : ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);
117 7147 : ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0);
118 7147 : ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0);
119 7147 : ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0);
120 7147 : ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0);
121 7147 : ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0);
122 7147 : ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0);
123 7147 : ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0);
124 : #ifdef S_ISVTX
125 7147 : ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0);
126 : #endif
127 : #ifdef S_ISGID
128 7147 : ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0);
129 : #endif
130 : #ifdef S_ISUID
131 7147 : ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0);
132 : #endif
133 7147 : return ret;
134 : }
135 :
136 : /****************************************************************************
137 : Map wire permissions to standard UNIX.
138 : ****************************************************************************/
139 :
140 4461 : mode_t wire_perms_to_unix(uint32_t perms)
141 : {
142 4461 : mode_t ret = (mode_t)0;
143 :
144 4461 : ret |= ((perms & UNIX_X_OTH) ? S_IXOTH : 0);
145 4461 : ret |= ((perms & UNIX_W_OTH) ? S_IWOTH : 0);
146 4461 : ret |= ((perms & UNIX_R_OTH) ? S_IROTH : 0);
147 4461 : ret |= ((perms & UNIX_X_GRP) ? S_IXGRP : 0);
148 4461 : ret |= ((perms & UNIX_W_GRP) ? S_IWGRP : 0);
149 4461 : ret |= ((perms & UNIX_R_GRP) ? S_IRGRP : 0);
150 4461 : ret |= ((perms & UNIX_X_USR) ? S_IXUSR : 0);
151 4461 : ret |= ((perms & UNIX_W_USR) ? S_IWUSR : 0);
152 4461 : ret |= ((perms & UNIX_R_USR) ? S_IRUSR : 0);
153 : #ifdef S_ISVTX
154 4461 : ret |= ((perms & UNIX_STICKY) ? S_ISVTX : 0);
155 : #endif
156 : #ifdef S_ISGID
157 4461 : ret |= ((perms & UNIX_SET_GID) ? S_ISGID : 0);
158 : #endif
159 : #ifdef S_ISUID
160 4461 : ret |= ((perms & UNIX_SET_UID) ? S_ISUID : 0);
161 : #endif
162 4461 : return ret;
163 : }
164 :
165 : /****************************************************************************
166 : Return the file type from the wire filetype for UNIX extensions.
167 : ****************************************************************************/
168 :
169 106 : mode_t unix_filetype_from_wire(uint32_t wire_type)
170 : {
171 106 : switch (wire_type) {
172 48 : case UNIX_TYPE_FILE:
173 48 : return S_IFREG;
174 20 : case UNIX_TYPE_DIR:
175 20 : return S_IFDIR;
176 : #ifdef S_IFLNK
177 36 : case UNIX_TYPE_SYMLINK:
178 36 : return S_IFLNK;
179 : #endif
180 : #ifdef S_IFCHR
181 0 : case UNIX_TYPE_CHARDEV:
182 0 : return S_IFCHR;
183 : #endif
184 : #ifdef S_IFBLK
185 0 : case UNIX_TYPE_BLKDEV:
186 0 : return S_IFBLK;
187 : #endif
188 : #ifdef S_IFIFO
189 1 : case UNIX_TYPE_FIFO:
190 1 : return S_IFIFO;
191 : #endif
192 : #ifdef S_IFSOCK
193 1 : case UNIX_TYPE_SOCKET:
194 1 : return S_IFSOCK;
195 : #endif
196 0 : default:
197 0 : return (mode_t)0;
198 : }
199 : }
200 :
201 755755 : bool smb_buffer_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
202 : {
203 755755 : if ((offset + length < offset) || (offset + length < length)) {
204 : /* wrap */
205 0 : return true;
206 : }
207 755755 : if ((offset > bufsize) || (offset + length > bufsize)) {
208 : /* overflow */
209 0 : return true;
210 : }
211 740032 : return false;
212 : }
213 :
214 : /***********************************************************
215 : Common function for pushing strings, used by smb_bytes_push_str()
216 : and trans_bytes_push_str(). Only difference is the align_odd
217 : parameter setting.
218 : ***********************************************************/
219 :
220 74143 : static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2,
221 : const char *str, size_t str_len,
222 : bool align_odd,
223 : size_t *pconverted_size)
224 : {
225 74143 : TALLOC_CTX *frame = talloc_stackframe();
226 0 : size_t buflen;
227 0 : char *converted;
228 0 : size_t converted_size;
229 :
230 : /*
231 : * This check prevents us from
232 : * (re)alloc buf on a NULL TALLOC_CTX.
233 : */
234 74143 : if (buf == NULL) {
235 0 : TALLOC_FREE(frame);
236 0 : return NULL;
237 : }
238 :
239 74143 : buflen = talloc_get_size(buf);
240 :
241 74143 : if (ucs2 &&
242 39333 : ((align_odd && (buflen % 2 == 0)) ||
243 52286 : (!align_odd && (buflen % 2 == 1)))) {
244 : /*
245 : * We're pushing into an SMB buffer, align odd
246 : */
247 14445 : buf = talloc_realloc(NULL, buf, uint8_t, buflen + 1);
248 14445 : if (buf == NULL) {
249 0 : TALLOC_FREE(frame);
250 0 : return NULL;
251 : }
252 14445 : buf[buflen] = '\0';
253 14445 : buflen += 1;
254 : }
255 :
256 74143 : if (!convert_string_talloc(frame, CH_UNIX,
257 : ucs2 ? CH_UTF16LE : CH_DOS,
258 : str, str_len, &converted,
259 : &converted_size)) {
260 0 : TALLOC_FREE(frame);
261 0 : return NULL;
262 : }
263 :
264 74143 : buf = talloc_realloc(NULL, buf, uint8_t,
265 : buflen + converted_size);
266 74143 : if (buf == NULL) {
267 0 : TALLOC_FREE(frame);
268 0 : return NULL;
269 : }
270 :
271 74143 : memcpy(buf + buflen, converted, converted_size);
272 :
273 74143 : TALLOC_FREE(converted);
274 :
275 74143 : if (pconverted_size) {
276 4334 : *pconverted_size = converted_size;
277 : }
278 :
279 74143 : TALLOC_FREE(frame);
280 74143 : return buf;
281 : }
282 :
283 : /***********************************************************
284 : Push a string into an SMB buffer, with odd byte alignment
285 : if it's a UCS2 string.
286 : ***********************************************************/
287 :
288 46755 : uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2,
289 : const char *str, size_t str_len,
290 : size_t *pconverted_size)
291 : {
292 46755 : return internal_bytes_push_str(buf, ucs2, str, str_len,
293 : true, pconverted_size);
294 : }
295 :
296 12 : uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix,
297 : const uint8_t *bytes, size_t num_bytes)
298 : {
299 0 : size_t buflen;
300 :
301 : /*
302 : * This check prevents us from
303 : * (re)alloc buf on a NULL TALLOC_CTX.
304 : */
305 12 : if (buf == NULL) {
306 0 : return NULL;
307 : }
308 12 : buflen = talloc_get_size(buf);
309 :
310 12 : buf = talloc_realloc(NULL, buf, uint8_t,
311 : buflen + 1 + num_bytes);
312 12 : if (buf == NULL) {
313 0 : return NULL;
314 : }
315 12 : buf[buflen] = prefix;
316 12 : memcpy(&buf[buflen+1], bytes, num_bytes);
317 12 : return buf;
318 : }
319 :
320 : /***********************************************************
321 : Same as smb_bytes_push_str(), but without the odd byte
322 : align for ucs2 (we're pushing into a param or data block).
323 : static for now, although this will probably change when
324 : other modules use async trans calls.
325 : ***********************************************************/
326 :
327 27388 : uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2,
328 : const char *str, size_t str_len,
329 : size_t *pconverted_size)
330 : {
331 27388 : return internal_bytes_push_str(buf, ucs2, str, str_len,
332 : false, pconverted_size);
333 : }
334 :
335 0 : uint8_t *trans2_bytes_push_bytes(uint8_t *buf,
336 : const uint8_t *bytes, size_t num_bytes)
337 : {
338 0 : size_t buflen;
339 :
340 0 : if (buf == NULL) {
341 0 : return NULL;
342 : }
343 0 : buflen = talloc_get_size(buf);
344 :
345 0 : buf = talloc_realloc(NULL, buf, uint8_t,
346 : buflen + num_bytes);
347 0 : if (buf == NULL) {
348 0 : return NULL;
349 : }
350 0 : memcpy(&buf[buflen], bytes, num_bytes);
351 0 : return buf;
352 : }
353 :
354 15401 : static NTSTATUS internal_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str,
355 : bool ucs2, bool align_odd,
356 : const uint8_t *buf, size_t buf_len,
357 : const uint8_t *position,
358 : size_t *p_consumed)
359 : {
360 15401 : size_t pad = 0;
361 10 : size_t offset;
362 15401 : char *str = NULL;
363 15401 : size_t str_len = 0;
364 10 : bool ok;
365 :
366 15401 : *_str = NULL;
367 15401 : if (p_consumed != NULL) {
368 15401 : *p_consumed = 0;
369 : }
370 :
371 15401 : if (position < buf) {
372 1 : return NT_STATUS_INTERNAL_ERROR;
373 : }
374 :
375 15400 : offset = PTR_DIFF(position, buf);
376 15400 : if (offset > buf_len) {
377 1 : return NT_STATUS_BUFFER_TOO_SMALL;
378 : }
379 :
380 15399 : if (ucs2 &&
381 15350 : ((align_odd && (offset % 2 == 0)) ||
382 15208 : (!align_odd && (offset % 2 == 1)))) {
383 137 : pad += 1;
384 137 : offset += 1;
385 : }
386 :
387 15399 : if (offset > buf_len) {
388 0 : return NT_STATUS_BUFFER_TOO_SMALL;
389 : }
390 :
391 15399 : buf_len -= offset;
392 15399 : buf += offset;
393 :
394 15399 : if (ucs2) {
395 15350 : buf_len = utf16_null_terminated_len_n(buf, buf_len);
396 : } else {
397 49 : size_t tmp = strnlen((const char *)buf, buf_len);
398 49 : if (tmp < buf_len) {
399 1 : tmp += 1;
400 : }
401 48 : buf_len = tmp;
402 : }
403 :
404 15400 : ok = convert_string_talloc(mem_ctx,
405 : ucs2 ? CH_UTF16LE : CH_DOS,
406 : CH_UNIX,
407 : buf, buf_len,
408 : &str, &str_len);
409 15399 : if (!ok) {
410 0 : return map_nt_error_from_unix_common(errno);
411 : }
412 :
413 15399 : if (p_consumed != NULL) {
414 15399 : *p_consumed = buf_len + pad;
415 : }
416 15399 : *_str = str;
417 15399 : return NT_STATUS_OK;
418 : }
419 :
420 15401 : NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2,
421 : const uint8_t *buf, size_t buf_len,
422 : const uint8_t *position,
423 : size_t *_consumed)
424 : {
425 15401 : return internal_bytes_pull_str(mem_ctx, _str, ucs2, true,
426 : buf, buf_len, position, _consumed);
427 : }
428 :
429 : /**
430 : * @brief Translate SMB signing settings as string to an enum.
431 : *
432 : * @param[in] str The string to translate.
433 : *
434 : * @return A corresponding enum @smb_signing_setting translated from the string.
435 : */
436 4 : enum smb_signing_setting smb_signing_setting_translate(const char *str)
437 : {
438 4 : enum smb_signing_setting signing_state = SMB_SIGNING_REQUIRED;
439 4 : int32_t val = lpcfg_parse_enum_vals("client signing", str);
440 :
441 4 : if (val != INT32_MIN) {
442 3 : signing_state = val;
443 : }
444 :
445 4 : return signing_state;
446 : }
447 :
448 : /**
449 : * @brief Translate SMB encryption settings as string to an enum.
450 : *
451 : * @param[in] str The string to translate.
452 : *
453 : * @return A corresponding enum @smb_encryption_setting translated from the
454 : * string.
455 : */
456 4 : enum smb_encryption_setting smb_encryption_setting_translate(const char *str)
457 : {
458 4 : enum smb_encryption_setting encryption_state = SMB_ENCRYPTION_REQUIRED;
459 4 : int32_t val = lpcfg_parse_enum_vals("client smb encrypt", str);
460 :
461 4 : if (val != INT32_MIN) {
462 3 : encryption_state = val;
463 : }
464 :
465 4 : return encryption_state;
466 : }
467 :
468 : static const struct enum_list enum_smb3_signing_algorithms[] = {
469 : {SMB2_SIGNING_AES128_GMAC, "AES-128-GMAC"},
470 : {SMB2_SIGNING_AES128_CMAC, "AES-128-CMAC"},
471 : {SMB2_SIGNING_HMAC_SHA256, "HMAC-SHA256"},
472 : {-1, NULL}
473 : };
474 :
475 0 : const char *smb3_signing_algorithm_name(uint16_t algo)
476 : {
477 0 : size_t i;
478 :
479 0 : for (i = 0; i < ARRAY_SIZE(enum_smb3_signing_algorithms); i++) {
480 0 : if (enum_smb3_signing_algorithms[i].value != algo) {
481 0 : continue;
482 : }
483 :
484 0 : return enum_smb3_signing_algorithms[i].name;
485 : }
486 :
487 0 : return NULL;
488 : }
489 :
490 : static const struct enum_list enum_smb3_encryption_algorithms[] = {
491 : {SMB2_ENCRYPTION_AES128_GCM, "AES-128-GCM"},
492 : {SMB2_ENCRYPTION_AES128_CCM, "AES-128-CCM"},
493 : {SMB2_ENCRYPTION_AES256_GCM, "AES-256-GCM"},
494 : {SMB2_ENCRYPTION_AES256_CCM, "AES-256-CCM"},
495 : {-1, NULL}
496 : };
497 :
498 0 : const char *smb3_encryption_algorithm_name(uint16_t algo)
499 : {
500 0 : size_t i;
501 :
502 0 : for (i = 0; i < ARRAY_SIZE(enum_smb3_encryption_algorithms); i++) {
503 0 : if (enum_smb3_encryption_algorithms[i].value != algo) {
504 0 : continue;
505 : }
506 :
507 0 : return enum_smb3_encryption_algorithms[i].name;
508 : }
509 :
510 0 : return NULL;
511 : }
512 :
513 519932 : static int32_t parse_enum_val(const struct enum_list *e,
514 : const char *param_name,
515 : const char *param_value)
516 : {
517 519932 : struct parm_struct parm = {
518 : .label = param_name,
519 : .type = P_LIST,
520 : .p_class = P_GLOBAL,
521 : .enum_list = e,
522 : };
523 519932 : int32_t ret = INT32_MIN;
524 12579 : bool ok;
525 :
526 519932 : ok = lp_set_enum_parm(&parm, param_value, &ret);
527 519932 : if (!ok) {
528 0 : return INT32_MIN;
529 : }
530 :
531 519932 : return ret;
532 : }
533 :
534 74276 : struct smb311_capabilities smb311_capabilities_parse(const char *role,
535 : const char * const *signing_algos,
536 : const char * const *encryption_algos)
537 : {
538 74276 : struct smb311_capabilities c = {
539 : .signing = {
540 : .num_algos = 0,
541 : },
542 : .encryption = {
543 : .num_algos = 0,
544 : },
545 : };
546 74276 : char sign_param[64] = { 0, };
547 74276 : char enc_param[64] = { 0, };
548 1797 : size_t ai;
549 :
550 74276 : snprintf(sign_param, sizeof(sign_param),
551 : "%s smb3 signing algorithms", role);
552 74276 : snprintf(enc_param, sizeof(enc_param),
553 : "%s smb3 encryption algorithms", role);
554 :
555 297104 : for (ai = 0; signing_algos != NULL && signing_algos[ai] != NULL; ai++) {
556 222828 : const char *algoname = signing_algos[ai];
557 5391 : int32_t v32;
558 5391 : uint16_t algo;
559 5391 : size_t di;
560 222828 : bool ignore = false;
561 :
562 222828 : if (c.signing.num_algos >= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS) {
563 0 : DBG_ERR("WARNING: Ignoring trailing value '%s' for parameter '%s'\n",
564 : algoname, sign_param);
565 0 : continue;
566 : }
567 :
568 222828 : v32 = parse_enum_val(enum_smb3_signing_algorithms,
569 : sign_param, algoname);
570 222828 : if (v32 == INT32_MAX) {
571 0 : continue;
572 : }
573 222828 : algo = v32;
574 :
575 445656 : for (di = 0; di < c.signing.num_algos; di++) {
576 222828 : if (algo != c.signing.algos[di]) {
577 222828 : continue;
578 : }
579 :
580 0 : ignore = true;
581 0 : break;
582 : }
583 :
584 222828 : if (ignore) {
585 0 : DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
586 : algoname, sign_param);
587 0 : continue;
588 : }
589 :
590 222828 : c.signing.algos[c.signing.num_algos] = algo;
591 222828 : c.signing.num_algos += 1;
592 : }
593 :
594 371380 : for (ai = 0; encryption_algos != NULL && encryption_algos[ai] != NULL; ai++) {
595 297104 : const char *algoname = encryption_algos[ai];
596 7188 : int32_t v32;
597 7188 : uint16_t algo;
598 7188 : size_t di;
599 297104 : bool ignore = false;
600 :
601 297104 : if (c.encryption.num_algos >= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS) {
602 0 : DBG_ERR("WARNING: Ignoring trailing value '%s' for parameter '%s'\n",
603 : algoname, enc_param);
604 0 : continue;
605 : }
606 :
607 297104 : v32 = parse_enum_val(enum_smb3_encryption_algorithms,
608 : enc_param, algoname);
609 297104 : if (v32 == INT32_MAX) {
610 0 : continue;
611 : }
612 297104 : algo = v32;
613 :
614 742760 : for (di = 0; di < c.encryption.num_algos; di++) {
615 445656 : if (algo != c.encryption.algos[di]) {
616 445656 : continue;
617 : }
618 :
619 0 : ignore = true;
620 0 : break;
621 : }
622 :
623 297104 : if (ignore) {
624 0 : DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
625 : algoname, enc_param);
626 0 : continue;
627 : }
628 :
629 297104 : c.encryption.algos[c.encryption.num_algos] = algo;
630 297104 : c.encryption.num_algos += 1;
631 : }
632 :
633 74276 : return c;
634 : }
635 :
636 69305 : NTSTATUS smb311_capabilities_check(const struct smb311_capabilities *c,
637 : const char *debug_prefix,
638 : int debug_lvl,
639 : NTSTATUS error_status,
640 : const char *role,
641 : enum protocol_types protocol,
642 : uint16_t sign_algo,
643 : uint16_t cipher_algo)
644 : {
645 69305 : const struct smb3_signing_capabilities *sign_algos =
646 : &c->signing;
647 69305 : const struct smb3_encryption_capabilities *ciphers =
648 : &c->encryption;
649 69305 : bool found_signing = false;
650 69305 : bool found_encryption = false;
651 1844 : size_t i;
652 :
653 116637 : for (i = 0; i < sign_algos->num_algos; i++) {
654 116637 : if (sign_algo == sign_algos->algos[i]) {
655 : /*
656 : * We found a match
657 : */
658 67461 : found_signing = true;
659 67461 : break;
660 : }
661 : }
662 :
663 69729 : for (i = 0; i < ciphers->num_algos; i++) {
664 69729 : if (cipher_algo == SMB2_ENCRYPTION_NONE) {
665 : /*
666 : * encryption not supported, we'll error out later
667 : */
668 23266 : found_encryption = true;
669 23266 : break;
670 : }
671 :
672 46011 : if (cipher_algo == ciphers->algos[i]) {
673 : /*
674 : * We found a match
675 : */
676 44195 : found_encryption = true;
677 44195 : break;
678 : }
679 : }
680 :
681 69305 : if (!found_signing) {
682 : /*
683 : * We negotiated a signing algo we don't allow,
684 : * most likely for SMB < 3.1.1
685 : */
686 0 : DEBUG(debug_lvl,("%s: "
687 : "SMB3 signing algorithm[%u][%s] on dialect[%s] "
688 : "not allowed by '%s smb3 signing algorithms' - %s.\n",
689 : debug_prefix,
690 : sign_algo,
691 : smb3_signing_algorithm_name(sign_algo),
692 : smb_protocol_types_string(protocol),
693 : role,
694 : nt_errstr(error_status)));
695 0 : return error_status;
696 : }
697 :
698 69305 : if (!found_encryption) {
699 : /*
700 : * We negotiated a cipher we don't allow,
701 : * most likely for SMB 3.0 and 3.0.2
702 : */
703 0 : DEBUG(debug_lvl,("%s: "
704 : "SMB3 encryption algorithm[%u][%s] on dialect[%s] "
705 : "not allowed by '%s smb3 encryption algorithms' - %s.\n",
706 : debug_prefix,
707 : cipher_algo,
708 : smb3_encryption_algorithm_name(cipher_algo),
709 : smb_protocol_types_string(protocol),
710 : role,
711 : nt_errstr(error_status)));
712 0 : return error_status;
713 : }
714 :
715 69305 : return NT_STATUS_OK;
716 : }
|