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);
165 /****************************************************************************
166 Return the file type from the wire filetype for UNIX extensions.
167 ****************************************************************************/
169 mode_t
unix_filetype_from_wire(uint32_t wire_type
)
177 case UNIX_TYPE_SYMLINK
:
181 case UNIX_TYPE_CHARDEV
:
185 case UNIX_TYPE_BLKDEV
:
193 case UNIX_TYPE_SOCKET
:
201 bool smb_buffer_oob(uint32_t bufsize
, uint32_t offset
, uint32_t length
)
203 if ((offset
+ length
< offset
) || (offset
+ length
< length
)) {
207 if ((offset
> bufsize
) || (offset
+ length
> bufsize
)) {
214 /***********************************************************
215 Common function for pushing stings, used by smb_bytes_push_str()
216 and trans_bytes_push_str(). Only difference is the align_odd
218 ***********************************************************/
220 static uint8_t *internal_bytes_push_str(uint8_t *buf
, bool ucs2
,
221 const char *str
, size_t str_len
,
223 size_t *pconverted_size
)
225 TALLOC_CTX
*frame
= talloc_stackframe();
228 size_t converted_size
;
231 * This check prevents us from
232 * (re)alloc buf on a NULL TALLOC_CTX.
239 buflen
= talloc_get_size(buf
);
242 ((align_odd
&& (buflen
% 2 == 0)) ||
243 (!align_odd
&& (buflen
% 2 == 1)))) {
245 * We're pushing into an SMB buffer, align odd
247 buf
= talloc_realloc(NULL
, buf
, uint8_t, buflen
+ 1);
256 if (!convert_string_talloc(frame
, CH_UNIX
,
257 ucs2
? CH_UTF16LE
: CH_DOS
,
258 str
, str_len
, &converted
,
264 buf
= talloc_realloc(NULL
, buf
, uint8_t,
265 buflen
+ converted_size
);
271 memcpy(buf
+ buflen
, converted
, converted_size
);
273 TALLOC_FREE(converted
);
275 if (pconverted_size
) {
276 *pconverted_size
= converted_size
;
283 /***********************************************************
284 Push a string into an SMB buffer, with odd byte alignment
285 if it's a UCS2 string.
286 ***********************************************************/
288 uint8_t *smb_bytes_push_str(uint8_t *buf
, bool ucs2
,
289 const char *str
, size_t str_len
,
290 size_t *pconverted_size
)
292 return internal_bytes_push_str(buf
, ucs2
, str
, str_len
,
293 true, pconverted_size
);
296 uint8_t *smb_bytes_push_bytes(uint8_t *buf
, uint8_t prefix
,
297 const uint8_t *bytes
, size_t num_bytes
)
302 * This check prevents us from
303 * (re)alloc buf on a NULL TALLOC_CTX.
308 buflen
= talloc_get_size(buf
);
310 buf
= talloc_realloc(NULL
, buf
, uint8_t,
311 buflen
+ 1 + num_bytes
);
315 buf
[buflen
] = prefix
;
316 memcpy(&buf
[buflen
+1], bytes
, num_bytes
);
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 ***********************************************************/
327 uint8_t *trans2_bytes_push_str(uint8_t *buf
, bool ucs2
,
328 const char *str
, size_t str_len
,
329 size_t *pconverted_size
)
331 return internal_bytes_push_str(buf
, ucs2
, str
, str_len
,
332 false, pconverted_size
);
335 uint8_t *trans2_bytes_push_bytes(uint8_t *buf
,
336 const uint8_t *bytes
, size_t num_bytes
)
343 buflen
= talloc_get_size(buf
);
345 buf
= talloc_realloc(NULL
, buf
, uint8_t,
350 memcpy(&buf
[buflen
], bytes
, num_bytes
);
354 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
,
367 if (p_consumed
!= NULL
) {
371 if (position
< buf
) {
372 return NT_STATUS_INTERNAL_ERROR
;
375 offset
= PTR_DIFF(position
, buf
);
376 if (offset
> buf_len
) {
377 return NT_STATUS_BUFFER_TOO_SMALL
;
381 ((align_odd
&& (offset
% 2 == 0)) ||
382 (!align_odd
&& (offset
% 2 == 1)))) {
387 if (offset
> buf_len
) {
388 return NT_STATUS_BUFFER_TOO_SMALL
;
395 buf_len
= utf16_len_n(buf
, buf_len
);
397 size_t tmp
= strnlen((const char *)buf
, buf_len
);
404 ok
= convert_string_talloc(mem_ctx
,
405 ucs2
? CH_UTF16LE
: CH_DOS
,
410 return map_nt_error_from_unix_common(errno
);
413 if (p_consumed
!= NULL
) {
414 *p_consumed
= buf_len
+ pad
;
420 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
,
425 return internal_bytes_pull_str(mem_ctx
, _str
, ucs2
, true,
426 buf
, buf_len
, position
, _consumed
);
430 * @brief Translate SMB signing settings as string to an enum.
432 * @param[in] str The string to translate.
434 * @return A corresponding enum @smb_signing_setting tranlated from the string.
436 enum smb_signing_setting
smb_signing_setting_translate(const char *str
)
438 enum smb_signing_setting signing_state
= SMB_SIGNING_REQUIRED
;
439 int32_t val
= lpcfg_parse_enum_vals("client signing", str
);
441 if (val
!= INT32_MIN
) {
445 return signing_state
;
449 * @brief Translate SMB encryption settings as string to an enum.
451 * @param[in] str The string to translate.
453 * @return A corresponding enum @smb_encryption_setting tranlated from the
456 enum smb_encryption_setting
smb_encryption_setting_translate(const char *str
)
458 enum smb_encryption_setting encryption_state
= SMB_ENCRYPTION_REQUIRED
;
459 int32_t val
= lpcfg_parse_enum_vals("client smb encrypt", str
);
461 if (val
!= INT32_MIN
) {
462 encryption_state
= val
;
465 return encryption_state
;
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"},
475 const char *smb3_signing_algorithm_name(uint16_t algo
)
479 for (i
= 0; i
< ARRAY_SIZE(enum_smb3_signing_algorithms
); i
++) {
480 if (enum_smb3_signing_algorithms
[i
].value
!= algo
) {
484 return enum_smb3_signing_algorithms
[i
].name
;
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"},
498 const char *smb3_encryption_algorithm_name(uint16_t algo
)
502 for (i
= 0; i
< ARRAY_SIZE(enum_smb3_encryption_algorithms
); i
++) {
503 if (enum_smb3_encryption_algorithms
[i
].value
!= algo
) {
507 return enum_smb3_encryption_algorithms
[i
].name
;
513 static int32_t parse_enum_val(const struct enum_list
*e
,
514 const char *param_name
,
515 const char *param_value
)
517 struct parm_struct parm
= {
523 int32_t ret
= INT32_MIN
;
526 ok
= lp_set_enum_parm(&parm
, param_value
, &ret
);
534 struct smb311_capabilities
smb311_capabilities_parse(const char *role
,
535 const char * const *signing_algos
,
536 const char * const *encryption_algos
)
538 struct smb311_capabilities c
= {
546 char sign_param
[64] = { 0, };
547 char enc_param
[64] = { 0, };
550 snprintf(sign_param
, sizeof(sign_param
),
551 "%s smb3 signing algorithms", role
);
552 snprintf(enc_param
, sizeof(enc_param
),
553 "%s smb3 encryption algorithms", role
);
555 for (ai
= 0; signing_algos
!= NULL
&& signing_algos
[ai
] != NULL
; ai
++) {
556 const char *algoname
= signing_algos
[ai
];
562 if (c
.signing
.num_algos
>= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS
) {
563 DBG_ERR("WARNING: Ignoring trailing value '%s' for parameter '%s'\n",
564 algoname
, sign_param
);
568 v32
= parse_enum_val(enum_smb3_signing_algorithms
,
569 sign_param
, algoname
);
570 if (v32
== INT32_MAX
) {
575 for (di
= 0; di
< c
.signing
.num_algos
; di
++) {
576 if (algo
!= c
.signing
.algos
[di
]) {
585 DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
586 algoname
, sign_param
);
590 c
.signing
.algos
[c
.signing
.num_algos
] = algo
;
591 c
.signing
.num_algos
+= 1;
594 for (ai
= 0; encryption_algos
!= NULL
&& encryption_algos
[ai
] != NULL
; ai
++) {
595 const char *algoname
= encryption_algos
[ai
];
601 if (c
.encryption
.num_algos
>= SMB3_ENCRYTION_CAPABILITIES_MAX_ALGOS
) {
602 DBG_ERR("WARNING: Ignoring trailing value '%s' for parameter '%s'\n",
603 algoname
, enc_param
);
607 v32
= parse_enum_val(enum_smb3_encryption_algorithms
,
608 enc_param
, algoname
);
609 if (v32
== INT32_MAX
) {
614 for (di
= 0; di
< c
.encryption
.num_algos
; di
++) {
615 if (algo
!= c
.encryption
.algos
[di
]) {
624 DBG_ERR("WARNING: Ignoring duplicate value '%s' for parameter '%s'\n",
625 algoname
, enc_param
);
629 c
.encryption
.algos
[c
.encryption
.num_algos
] = algo
;
630 c
.encryption
.num_algos
+= 1;
636 NTSTATUS
smb311_capabilities_check(const struct smb311_capabilities
*c
,
637 const char *debug_prefix
,
639 NTSTATUS error_status
,
641 enum protocol_types protocol
,
643 uint16_t cipher_algo
)
645 const struct smb3_signing_capabilities
*sign_algos
=
647 const struct smb3_encryption_capabilities
*ciphers
=
649 bool found_signing
= false;
650 bool found_encryption
= false;
653 for (i
= 0; i
< sign_algos
->num_algos
; i
++) {
654 if (sign_algo
== sign_algos
->algos
[i
]) {
658 found_signing
= true;
663 for (i
= 0; i
< ciphers
->num_algos
; i
++) {
664 if (cipher_algo
== SMB2_ENCRYPTION_NONE
) {
666 * encryption not supported, we'll error out later
668 found_encryption
= true;
672 if (cipher_algo
== ciphers
->algos
[i
]) {
676 found_encryption
= true;
681 if (!found_signing
) {
683 * We negotiated a signing algo we don't allow,
684 * most likely for SMB < 3.1.1
686 DEBUG(debug_lvl
,("%s: "
687 "SMB3 signing algorithm[%u][%s] on dialect[%s] "
688 "not allowed by '%s smb3 signing algorithms' - %s.\n",
691 smb3_signing_algorithm_name(sign_algo
),
692 smb_protocol_types_string(protocol
),
694 nt_errstr(error_status
)));
698 if (!found_encryption
) {
700 * We negotiated a cipher we don't allow,
701 * most likely for SMB 3.0 and 3.0.2
703 DEBUG(debug_lvl
,("%s: "
704 "SMB3 encryption algorithm[%u][%s] on dialect[%s] "
705 "not allowed by '%s smb3 encryption algorithms' - %s.\n",
708 smb3_encryption_algorithm_name(cipher_algo
),
709 smb_protocol_types_string(protocol
),
711 nt_errstr(error_status
)));