smbd: Remove an unnecessary call to SMB_VFS_STAT()
[samba4-gss.git] / libcli / smb / util.c
blob4861c13dd820c3515d304f6f0a9aac7dae7d28f2
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
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.
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.
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/>.
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"
29 const char *smb_protocol_types_string(enum protocol_types protocol)
31 switch (protocol) {
32 case PROTOCOL_DEFAULT:
33 return "DEFAULT";
34 case PROTOCOL_NONE:
35 return "NONE";
36 case PROTOCOL_CORE:
37 return "CORE";
38 case PROTOCOL_COREPLUS:
39 return "COREPLUS";
40 case PROTOCOL_LANMAN1:
41 return "LANMAN1";
42 case PROTOCOL_LANMAN2:
43 return "LANMAN2";
44 case PROTOCOL_NT1:
45 return "NT1";
46 case PROTOCOL_SMB2_02:
47 return "SMB2_02";
48 case PROTOCOL_SMB2_10:
49 return "SMB2_10";
50 case PROTOCOL_SMB3_00:
51 return "SMB3_00";
52 case PROTOCOL_SMB3_02:
53 return "SMB3_02";
54 case PROTOCOL_SMB3_11:
55 return "SMB3_11";
58 return "Invalid protocol_types value";
61 /**
62 Return a string representing a CIFS attribute for a file.
63 **/
64 char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)
66 size_t i, len;
67 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}
87 char *ret;
89 ret = talloc_array(mem_ctx, char, ARRAY_SIZE(attr_strs)+1);
90 if (!ret) {
91 return NULL;
94 for (len=i=0; i<ARRAY_SIZE(attr_strs); i++) {
95 if (attrib & attr_strs[i].attr) {
96 ret[len++] = attr_strs[i].c;
100 ret[len] = 0;
102 talloc_set_name_const(ret, ret);
104 return ret;
107 /****************************************************************************
108 Map standard UNIX permissions onto wire representations.
109 ****************************************************************************/
111 uint32_t unix_perms_to_wire(mode_t perms)
113 unsigned int ret = 0;
115 ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0);
116 ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0);
117 ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0);
118 ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0);
119 ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0);
120 ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0);
121 ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0);
122 ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0);
123 ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0);
124 #ifdef S_ISVTX
125 ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0);
126 #endif
127 #ifdef S_ISGID
128 ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0);
129 #endif
130 #ifdef S_ISUID
131 ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0);
132 #endif
133 return ret;
136 /****************************************************************************
137 Map wire permissions to standard UNIX.
138 ****************************************************************************/
140 mode_t wire_perms_to_unix(uint32_t perms)
142 mode_t ret = (mode_t)0;
144 ret |= ((perms & UNIX_X_OTH) ? S_IXOTH : 0);
145 ret |= ((perms & UNIX_W_OTH) ? S_IWOTH : 0);
146 ret |= ((perms & UNIX_R_OTH) ? S_IROTH : 0);
147 ret |= ((perms & UNIX_X_GRP) ? S_IXGRP : 0);
148 ret |= ((perms & UNIX_W_GRP) ? S_IWGRP : 0);
149 ret |= ((perms & UNIX_R_GRP) ? S_IRGRP : 0);
150 ret |= ((perms & UNIX_X_USR) ? S_IXUSR : 0);
151 ret |= ((perms & UNIX_W_USR) ? S_IWUSR : 0);
152 ret |= ((perms & UNIX_R_USR) ? S_IRUSR : 0);
153 #ifdef S_ISVTX
154 ret |= ((perms & UNIX_STICKY) ? S_ISVTX : 0);
155 #endif
156 #ifdef S_ISGID
157 ret |= ((perms & UNIX_SET_GID) ? S_ISGID : 0);
158 #endif
159 #ifdef S_ISUID
160 ret |= ((perms & UNIX_SET_UID) ? S_ISUID : 0);
161 #endif
162 return ret;
166 /****************************************************************************
167 * Return the file type from the wire filetype for UNIX extensions.
169 * This uses the fact that the unix file types are numbered from
170 * FILE=0 to SOCKET=6. This is an accepted protocol element that will
171 * never change.
172 ****************************************************************************/
174 static const mode_t unix_filetypes[] =
175 {S_IFREG, S_IFDIR, S_IFLNK, S_IFCHR, S_IFBLK, S_IFIFO, S_IFSOCK};
177 mode_t wire_filetype_to_unix(uint32_t wire_type)
179 if (wire_type >= ARRAY_SIZE(unix_filetypes)) {
180 return (mode_t)0;
182 return unix_filetypes[wire_type];
185 uint32_t unix_filetype_to_wire(mode_t mode)
187 mode_t type = mode & S_IFMT;
188 size_t i;
190 for (i = 0; i < ARRAY_SIZE(unix_filetypes); i++) {
191 if (type == unix_filetypes[i]) {
192 return i;
195 return UNIX_TYPE_UNKNOWN;
198 mode_t wire_mode_to_unix(uint32_t wire)
200 uint32_t wire_type = (wire & UNIX_FILETYPE_MASK) >>
201 UNIX_FILETYPE_SHIFT;
202 return wire_perms_to_unix(wire) | wire_filetype_to_unix(wire_type);
205 uint32_t unix_mode_to_wire(mode_t mode)
207 uint32_t wire_type = unix_filetype_to_wire(mode);
208 return unix_perms_to_wire(mode) | (wire_type << UNIX_FILETYPE_SHIFT);
211 bool smb_buffer_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
213 if ((offset + length < offset) || (offset + length < length)) {
214 /* wrap */
215 return true;
217 if ((offset > bufsize) || (offset + length > bufsize)) {
218 /* overflow */
219 return true;
221 return false;
224 /***********************************************************
225 Common function for pushing strings, used by smb_bytes_push_str()
226 and trans_bytes_push_str(). Only difference is the align_odd
227 parameter setting.
228 ***********************************************************/
230 static uint8_t *internal_bytes_push_str(uint8_t *buf, bool ucs2,
231 const char *str, size_t str_len,
232 bool align_odd,
233 size_t *pconverted_size)
235 TALLOC_CTX *frame = talloc_stackframe();
236 size_t buflen;
237 char *converted;
238 size_t converted_size;
241 * This check prevents us from
242 * (re)alloc buf on a NULL TALLOC_CTX.
244 if (buf == NULL) {
245 TALLOC_FREE(frame);
246 return NULL;
249 buflen = talloc_get_size(buf);
251 if (ucs2 &&
252 ((align_odd && (buflen % 2 == 0)) ||
253 (!align_odd && (buflen % 2 == 1)))) {
255 * We're pushing into an SMB buffer, align odd
257 buf = talloc_realloc(NULL, buf, uint8_t, buflen + 1);
258 if (buf == NULL) {
259 TALLOC_FREE(frame);
260 return NULL;
262 buf[buflen] = '\0';
263 buflen += 1;
266 if (!convert_string_talloc(frame, CH_UNIX,
267 ucs2 ? CH_UTF16LE : CH_DOS,
268 str, str_len, &converted,
269 &converted_size)) {
270 TALLOC_FREE(frame);
271 return NULL;
274 buf = talloc_realloc(NULL, buf, uint8_t,
275 buflen + converted_size);
276 if (buf == NULL) {
277 TALLOC_FREE(frame);
278 return NULL;
281 memcpy(buf + buflen, converted, converted_size);
283 TALLOC_FREE(converted);
285 if (pconverted_size) {
286 *pconverted_size = converted_size;
289 TALLOC_FREE(frame);
290 return buf;
293 /***********************************************************
294 Push a string into an SMB buffer, with odd byte alignment
295 if it's a UCS2 string.
296 ***********************************************************/
298 uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2,
299 const char *str, size_t str_len,
300 size_t *pconverted_size)
302 return internal_bytes_push_str(buf, ucs2, str, str_len,
303 true, pconverted_size);
306 uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix,
307 const uint8_t *bytes, size_t num_bytes)
309 size_t buflen;
312 * This check prevents us from
313 * (re)alloc buf on a NULL TALLOC_CTX.
315 if (buf == NULL) {
316 return NULL;
318 buflen = talloc_get_size(buf);
320 buf = talloc_realloc(NULL, buf, uint8_t,
321 buflen + 1 + num_bytes);
322 if (buf == NULL) {
323 return NULL;
325 buf[buflen] = prefix;
326 memcpy(&buf[buflen+1], bytes, num_bytes);
327 return buf;
330 /***********************************************************
331 Same as smb_bytes_push_str(), but without the odd byte
332 align for ucs2 (we're pushing into a param or data block).
333 static for now, although this will probably change when
334 other modules use async trans calls.
335 ***********************************************************/
337 uint8_t *trans2_bytes_push_str(uint8_t *buf, bool ucs2,
338 const char *str, size_t str_len,
339 size_t *pconverted_size)
341 return internal_bytes_push_str(buf, ucs2, str, str_len,
342 false, pconverted_size);
345 uint8_t *trans2_bytes_push_bytes(uint8_t *buf,
346 const uint8_t *bytes, size_t num_bytes)
348 size_t buflen;
350 if (buf == NULL) {
351 return NULL;
353 buflen = talloc_get_size(buf);
355 buf = talloc_realloc(NULL, buf, uint8_t,
356 buflen + num_bytes);
357 if (buf == NULL) {
358 return NULL;
360 memcpy(&buf[buflen], bytes, num_bytes);
361 return buf;
364 static NTSTATUS internal_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str,
365 bool ucs2, bool align_odd,
366 const uint8_t *buf, size_t buf_len,
367 const uint8_t *position,
368 size_t *p_consumed)
370 size_t pad = 0;
371 size_t offset;
372 char *str = NULL;
373 size_t str_len = 0;
374 bool ok;
376 *_str = NULL;
377 if (p_consumed != NULL) {
378 *p_consumed = 0;
381 if (position < buf) {
382 return NT_STATUS_INTERNAL_ERROR;
385 offset = PTR_DIFF(position, buf);
386 if (offset > buf_len) {
387 return NT_STATUS_BUFFER_TOO_SMALL;
390 if (ucs2 &&
391 ((align_odd && (offset % 2 == 0)) ||
392 (!align_odd && (offset % 2 == 1)))) {
393 pad += 1;
394 offset += 1;
397 if (offset > buf_len) {
398 return NT_STATUS_BUFFER_TOO_SMALL;
401 buf_len -= offset;
402 buf += offset;
404 if (ucs2) {
405 buf_len = utf16_null_terminated_len_n(buf, buf_len);
406 } else {
407 size_t tmp = strnlen((const char *)buf, buf_len);
408 if (tmp < buf_len) {
409 tmp += 1;
411 buf_len = tmp;
414 ok = convert_string_talloc(mem_ctx,
415 ucs2 ? CH_UTF16LE : CH_DOS,
416 CH_UNIX,
417 buf, buf_len,
418 &str, &str_len);
419 if (!ok) {
420 return map_nt_error_from_unix_common(errno);
423 if (p_consumed != NULL) {
424 *p_consumed = buf_len + pad;
426 *_str = str;
427 return NT_STATUS_OK;
430 NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2,
431 const uint8_t *buf, size_t buf_len,
432 const uint8_t *position,
433 size_t *_consumed)
435 return internal_bytes_pull_str(mem_ctx, _str, ucs2, true,
436 buf, buf_len, position, _consumed);
440 * @brief Translate SMB signing settings as string to an enum.
442 * @param[in] str The string to translate.
444 * @return A corresponding enum @smb_signing_setting translated from the string.
446 enum smb_signing_setting smb_signing_setting_translate(const char *str)
448 enum smb_signing_setting signing_state = SMB_SIGNING_REQUIRED;
449 int32_t val = lpcfg_parse_enum_vals("client signing", str);
451 if (val != INT32_MIN) {
452 signing_state = val;
455 return signing_state;
459 * @brief Translate SMB encryption settings as string to an enum.
461 * @param[in] str The string to translate.
463 * @return A corresponding enum @smb_encryption_setting translated from the
464 * string.
466 enum smb_encryption_setting smb_encryption_setting_translate(const char *str)
468 enum smb_encryption_setting encryption_state = SMB_ENCRYPTION_REQUIRED;
469 int32_t val = lpcfg_parse_enum_vals("client smb encrypt", str);
471 if (val != INT32_MIN) {
472 encryption_state = val;
475 return encryption_state;
478 static const struct enum_list enum_smb3_signing_algorithms[] = {
479 {SMB2_SIGNING_AES128_GMAC, "AES-128-GMAC"},
480 {SMB2_SIGNING_AES128_CMAC, "AES-128-CMAC"},
481 {SMB2_SIGNING_HMAC_SHA256, "HMAC-SHA256"},
482 {-1, NULL}
485 const char *smb3_signing_algorithm_name(uint16_t algo)
487 size_t i;
489 for (i = 0; i < ARRAY_SIZE(enum_smb3_signing_algorithms); i++) {
490 if (enum_smb3_signing_algorithms[i].value != algo) {
491 continue;
494 return enum_smb3_signing_algorithms[i].name;
497 return NULL;
500 static const struct enum_list enum_smb3_encryption_algorithms[] = {
501 {SMB2_ENCRYPTION_AES128_GCM, "AES-128-GCM"},
502 {SMB2_ENCRYPTION_AES128_CCM, "AES-128-CCM"},
503 {SMB2_ENCRYPTION_AES256_GCM, "AES-256-GCM"},
504 {SMB2_ENCRYPTION_AES256_CCM, "AES-256-CCM"},
505 {-1, NULL}
508 const char *smb3_encryption_algorithm_name(uint16_t algo)
510 size_t i;
512 for (i = 0; i < ARRAY_SIZE(enum_smb3_encryption_algorithms); i++) {
513 if (enum_smb3_encryption_algorithms[i].value != algo) {
514 continue;
517 return enum_smb3_encryption_algorithms[i].name;
520 return NULL;
523 static int32_t parse_enum_val(const struct enum_list *e,
524 const char *param_name,
525 const char *param_value)
527 struct parm_struct parm = {
528 .label = param_name,
529 .type = P_LIST,
530 .p_class = P_GLOBAL,
531 .enum_list = e,
533 int32_t ret = INT32_MIN;
534 bool ok;
536 ok = lp_set_enum_parm(&parm, param_value, &ret);
537 if (!ok) {
538 return INT32_MIN;
541 return ret;
544 struct smb311_capabilities smb311_capabilities_parse(const char *role,
545 const char * const *signing_algos,
546 const char * const *encryption_algos)
548 struct smb311_capabilities c = {
549 .signing = {
550 .num_algos = 0,
552 .encryption = {
553 .num_algos = 0,
556 char sign_param[64] = { 0, };
557 char enc_param[64] = { 0, };
558 size_t ai;
560 snprintf(sign_param, sizeof(sign_param),
561 "%s smb3 signing algorithms", role);
562 snprintf(enc_param, sizeof(enc_param),
563 "%s smb3 encryption algorithms", role);
565 for (ai = 0; signing_algos != NULL && signing_algos[ai] != NULL; ai++) {
566 const char *algoname = signing_algos[ai];
567 int32_t v32;
568 uint16_t algo;
569 size_t di;
570 bool ignore = false;
572 if (c.signing.num_algos >= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS) {
573 DBG_ERR("WARNING: Ignoring trailing value '%s' for parameter '%s'\n",
574 algoname, sign_param);
575 continue;
578 v32 = parse_enum_val(enum_smb3_signing_algorithms,
579 sign_param, algoname);
580 if (v32 == INT32_MAX) {
581 continue;
583 algo = v32;
585 for (di = 0; di < c.signing.num_algos; di++) {
586 if (algo != c.signing.algos[di]) {
587 continue;
590 ignore = true;
591 break;
594 if (ignore) {
595 DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
596 algoname, sign_param);
597 continue;
600 c.signing.algos[c.signing.num_algos] = algo;
601 c.signing.num_algos += 1;
604 for (ai = 0; encryption_algos != NULL && encryption_algos[ai] != NULL; ai++) {
605 const char *algoname = encryption_algos[ai];
606 int32_t v32;
607 uint16_t algo;
608 size_t di;
609 bool ignore = false;
611 if (c.encryption.num_algos >= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS) {
612 DBG_ERR("WARNING: Ignoring trailing value '%s' for parameter '%s'\n",
613 algoname, enc_param);
614 continue;
617 v32 = parse_enum_val(enum_smb3_encryption_algorithms,
618 enc_param, algoname);
619 if (v32 == INT32_MAX) {
620 continue;
622 algo = v32;
624 for (di = 0; di < c.encryption.num_algos; di++) {
625 if (algo != c.encryption.algos[di]) {
626 continue;
629 ignore = true;
630 break;
633 if (ignore) {
634 DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
635 algoname, enc_param);
636 continue;
639 c.encryption.algos[c.encryption.num_algos] = algo;
640 c.encryption.num_algos += 1;
643 return c;
646 NTSTATUS smb311_capabilities_check(const struct smb311_capabilities *c,
647 const char *debug_prefix,
648 int debug_lvl,
649 NTSTATUS error_status,
650 const char *role,
651 enum protocol_types protocol,
652 uint16_t sign_algo,
653 uint16_t cipher_algo)
655 const struct smb3_signing_capabilities *sign_algos =
656 &c->signing;
657 const struct smb3_encryption_capabilities *ciphers =
658 &c->encryption;
659 bool found_signing = false;
660 bool found_encryption = false;
661 size_t i;
663 for (i = 0; i < sign_algos->num_algos; i++) {
664 if (sign_algo == sign_algos->algos[i]) {
666 * We found a match
668 found_signing = true;
669 break;
673 for (i = 0; i < ciphers->num_algos; i++) {
674 if (cipher_algo == SMB2_ENCRYPTION_NONE) {
676 * encryption not supported, we'll error out later
678 found_encryption = true;
679 break;
682 if (cipher_algo == ciphers->algos[i]) {
684 * We found a match
686 found_encryption = true;
687 break;
691 if (!found_signing) {
693 * We negotiated a signing algo we don't allow,
694 * most likely for SMB < 3.1.1
696 DEBUG(debug_lvl,("%s: "
697 "SMB3 signing algorithm[%u][%s] on dialect[%s] "
698 "not allowed by '%s smb3 signing algorithms' - %s.\n",
699 debug_prefix,
700 sign_algo,
701 smb3_signing_algorithm_name(sign_algo),
702 smb_protocol_types_string(protocol),
703 role,
704 nt_errstr(error_status)));
705 return error_status;
708 if (!found_encryption) {
710 * We negotiated a cipher we don't allow,
711 * most likely for SMB 3.0 and 3.0.2
713 DEBUG(debug_lvl,("%s: "
714 "SMB3 encryption algorithm[%u][%s] on dialect[%s] "
715 "not allowed by '%s smb3 encryption algorithms' - %s.\n",
716 debug_prefix,
717 cipher_algo,
718 smb3_encryption_algorithm_name(cipher_algo),
719 smb_protocol_types_string(protocol),
720 role,
721 nt_errstr(error_status)));
722 return error_status;
725 return NT_STATUS_OK;