2 Unix SMB/CIFS implementation.
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/>.
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
)
32 case PROTOCOL_DEFAULT
:
38 case PROTOCOL_COREPLUS
:
40 case PROTOCOL_LANMAN1
:
42 case PROTOCOL_LANMAN2
:
46 case PROTOCOL_SMB2_02
:
48 case PROTOCOL_SMB2_10
:
50 case PROTOCOL_SMB3_00
:
52 case PROTOCOL_SMB3_02
:
54 case PROTOCOL_SMB3_11
:
58 return "Invalid protocol_types value";
62 Return a string representing a CIFS attribute for a file.
64 char *attrib_string(TALLOC_CTX
*mem_ctx
, uint32_t attrib
)
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
}
89 ret
= talloc_array(mem_ctx
, char, ARRAY_SIZE(attr_strs
)+1);
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
;
102 talloc_set_name_const(ret
, 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);
125 ret
|= ((perms
& S_ISVTX
) ? UNIX_STICKY
: 0);
128 ret
|= ((perms
& S_ISGID
) ? UNIX_SET_GID
: 0);
131 ret
|= ((perms
& S_ISUID
) ? UNIX_SET_UID
: 0);
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);
154 ret
|= ((perms
& UNIX_STICKY
) ? S_ISVTX
: 0);
157 ret
|= ((perms
& UNIX_SET_GID
) ? S_ISGID
: 0);
160 ret
|= ((perms
& UNIX_SET_UID
) ? S_ISUID
: 0);
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
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
)) {
182 return unix_filetypes
[wire_type
];
185 uint32_t unix_filetype_to_wire(mode_t mode
)
187 mode_t type
= mode
& S_IFMT
;
190 for (i
= 0; i
< ARRAY_SIZE(unix_filetypes
); i
++) {
191 if (type
== unix_filetypes
[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
) >>
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
)) {
217 if ((offset
> bufsize
) || (offset
+ length
> bufsize
)) {
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
228 ***********************************************************/
230 static uint8_t *internal_bytes_push_str(uint8_t *buf
, bool ucs2
,
231 const char *str
, size_t str_len
,
233 size_t *pconverted_size
)
235 TALLOC_CTX
*frame
= talloc_stackframe();
238 size_t converted_size
;
241 * This check prevents us from
242 * (re)alloc buf on a NULL TALLOC_CTX.
249 buflen
= talloc_get_size(buf
);
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);
266 if (!convert_string_talloc(frame
, CH_UNIX
,
267 ucs2
? CH_UTF16LE
: CH_DOS
,
268 str
, str_len
, &converted
,
274 buf
= talloc_realloc(NULL
, buf
, uint8_t,
275 buflen
+ converted_size
);
281 memcpy(buf
+ buflen
, converted
, converted_size
);
283 TALLOC_FREE(converted
);
285 if (pconverted_size
) {
286 *pconverted_size
= converted_size
;
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
)
312 * This check prevents us from
313 * (re)alloc buf on a NULL TALLOC_CTX.
318 buflen
= talloc_get_size(buf
);
320 buf
= talloc_realloc(NULL
, buf
, uint8_t,
321 buflen
+ 1 + num_bytes
);
325 buf
[buflen
] = prefix
;
326 memcpy(&buf
[buflen
+1], bytes
, num_bytes
);
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
)
353 buflen
= talloc_get_size(buf
);
355 buf
= talloc_realloc(NULL
, buf
, uint8_t,
360 memcpy(&buf
[buflen
], bytes
, num_bytes
);
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
,
377 if (p_consumed
!= NULL
) {
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
;
391 ((align_odd
&& (offset
% 2 == 0)) ||
392 (!align_odd
&& (offset
% 2 == 1)))) {
397 if (offset
> buf_len
) {
398 return NT_STATUS_BUFFER_TOO_SMALL
;
405 buf_len
= utf16_null_terminated_len_n(buf
, buf_len
);
407 size_t tmp
= strnlen((const char *)buf
, buf_len
);
414 ok
= convert_string_talloc(mem_ctx
,
415 ucs2
? CH_UTF16LE
: CH_DOS
,
420 return map_nt_error_from_unix_common(errno
);
423 if (p_consumed
!= NULL
) {
424 *p_consumed
= buf_len
+ pad
;
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
,
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
) {
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
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"},
485 const char *smb3_signing_algorithm_name(uint16_t algo
)
489 for (i
= 0; i
< ARRAY_SIZE(enum_smb3_signing_algorithms
); i
++) {
490 if (enum_smb3_signing_algorithms
[i
].value
!= algo
) {
494 return enum_smb3_signing_algorithms
[i
].name
;
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"},
508 const char *smb3_encryption_algorithm_name(uint16_t algo
)
512 for (i
= 0; i
< ARRAY_SIZE(enum_smb3_encryption_algorithms
); i
++) {
513 if (enum_smb3_encryption_algorithms
[i
].value
!= algo
) {
517 return enum_smb3_encryption_algorithms
[i
].name
;
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
= {
533 int32_t ret
= INT32_MIN
;
536 ok
= lp_set_enum_parm(&parm
, param_value
, &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
= {
556 char sign_param
[64] = { 0, };
557 char enc_param
[64] = { 0, };
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
];
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
);
578 v32
= parse_enum_val(enum_smb3_signing_algorithms
,
579 sign_param
, algoname
);
580 if (v32
== INT32_MAX
) {
585 for (di
= 0; di
< c
.signing
.num_algos
; di
++) {
586 if (algo
!= c
.signing
.algos
[di
]) {
595 DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
596 algoname
, sign_param
);
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
];
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
);
617 v32
= parse_enum_val(enum_smb3_encryption_algorithms
,
618 enc_param
, algoname
);
619 if (v32
== INT32_MAX
) {
624 for (di
= 0; di
< c
.encryption
.num_algos
; di
++) {
625 if (algo
!= c
.encryption
.algos
[di
]) {
634 DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
635 algoname
, enc_param
);
639 c
.encryption
.algos
[c
.encryption
.num_algos
] = algo
;
640 c
.encryption
.num_algos
+= 1;
646 NTSTATUS
smb311_capabilities_check(const struct smb311_capabilities
*c
,
647 const char *debug_prefix
,
649 NTSTATUS error_status
,
651 enum protocol_types protocol
,
653 uint16_t cipher_algo
)
655 const struct smb3_signing_capabilities
*sign_algos
=
657 const struct smb3_encryption_capabilities
*ciphers
=
659 bool found_signing
= false;
660 bool found_encryption
= false;
663 for (i
= 0; i
< sign_algos
->num_algos
; i
++) {
664 if (sign_algo
== sign_algos
->algos
[i
]) {
668 found_signing
= true;
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;
682 if (cipher_algo
== ciphers
->algos
[i
]) {
686 found_encryption
= true;
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",
701 smb3_signing_algorithm_name(sign_algo
),
702 smb_protocol_types_string(protocol
),
704 nt_errstr(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",
718 smb3_encryption_algorithm_name(cipher_algo
),
719 smb_protocol_types_string(protocol
),
721 nt_errstr(error_status
)));