18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2020, Microsoft Corporation. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author(s): Steve French <stfrench@microsoft.com> 68c2ecf20Sopenharmony_ci * David Howells <dhowells@redhat.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "cifsglob.h" 108c2ecf20Sopenharmony_ci#include "cifs_debug.h" 118c2ecf20Sopenharmony_ci#include "fs_context.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic const match_table_t cifs_smb_version_tokens = { 148c2ecf20Sopenharmony_ci { Smb_1, SMB1_VERSION_STRING }, 158c2ecf20Sopenharmony_ci { Smb_20, SMB20_VERSION_STRING}, 168c2ecf20Sopenharmony_ci { Smb_21, SMB21_VERSION_STRING }, 178c2ecf20Sopenharmony_ci { Smb_30, SMB30_VERSION_STRING }, 188c2ecf20Sopenharmony_ci { Smb_302, SMB302_VERSION_STRING }, 198c2ecf20Sopenharmony_ci { Smb_302, ALT_SMB302_VERSION_STRING }, 208c2ecf20Sopenharmony_ci { Smb_311, SMB311_VERSION_STRING }, 218c2ecf20Sopenharmony_ci { Smb_311, ALT_SMB311_VERSION_STRING }, 228c2ecf20Sopenharmony_ci { Smb_3any, SMB3ANY_VERSION_STRING }, 238c2ecf20Sopenharmony_ci { Smb_default, SMBDEFAULT_VERSION_STRING }, 248c2ecf20Sopenharmony_ci { Smb_version_err, NULL } 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciint 288c2ecf20Sopenharmony_cicifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci substring_t args[MAX_OPT_ARGS]; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci switch (match_token(value, cifs_smb_version_tokens, args)) { 338c2ecf20Sopenharmony_ci#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 348c2ecf20Sopenharmony_ci case Smb_1: 358c2ecf20Sopenharmony_ci if (disable_legacy_dialects) { 368c2ecf20Sopenharmony_ci cifs_dbg(VFS, "mount with legacy dialect disabled\n"); 378c2ecf20Sopenharmony_ci return 1; 388c2ecf20Sopenharmony_ci } 398c2ecf20Sopenharmony_ci if (is_smb3) { 408c2ecf20Sopenharmony_ci cifs_dbg(VFS, "vers=1.0 (cifs) not permitted when mounting with smb3\n"); 418c2ecf20Sopenharmony_ci return 1; 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n"); 448c2ecf20Sopenharmony_ci vol->ops = &smb1_operations; 458c2ecf20Sopenharmony_ci vol->vals = &smb1_values; 468c2ecf20Sopenharmony_ci break; 478c2ecf20Sopenharmony_ci case Smb_20: 488c2ecf20Sopenharmony_ci if (disable_legacy_dialects) { 498c2ecf20Sopenharmony_ci cifs_dbg(VFS, "mount with legacy dialect disabled\n"); 508c2ecf20Sopenharmony_ci return 1; 518c2ecf20Sopenharmony_ci } 528c2ecf20Sopenharmony_ci if (is_smb3) { 538c2ecf20Sopenharmony_ci cifs_dbg(VFS, "vers=2.0 not permitted when mounting with smb3\n"); 548c2ecf20Sopenharmony_ci return 1; 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci vol->ops = &smb20_operations; 578c2ecf20Sopenharmony_ci vol->vals = &smb20_values; 588c2ecf20Sopenharmony_ci break; 598c2ecf20Sopenharmony_ci#else 608c2ecf20Sopenharmony_ci case Smb_1: 618c2ecf20Sopenharmony_ci cifs_dbg(VFS, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n"); 628c2ecf20Sopenharmony_ci return 1; 638c2ecf20Sopenharmony_ci case Smb_20: 648c2ecf20Sopenharmony_ci cifs_dbg(VFS, "vers=2.0 mount not permitted when legacy dialects disabled\n"); 658c2ecf20Sopenharmony_ci return 1; 668c2ecf20Sopenharmony_ci#endif /* CIFS_ALLOW_INSECURE_LEGACY */ 678c2ecf20Sopenharmony_ci case Smb_21: 688c2ecf20Sopenharmony_ci vol->ops = &smb21_operations; 698c2ecf20Sopenharmony_ci vol->vals = &smb21_values; 708c2ecf20Sopenharmony_ci break; 718c2ecf20Sopenharmony_ci case Smb_30: 728c2ecf20Sopenharmony_ci vol->ops = &smb30_operations; 738c2ecf20Sopenharmony_ci vol->vals = &smb30_values; 748c2ecf20Sopenharmony_ci break; 758c2ecf20Sopenharmony_ci case Smb_302: 768c2ecf20Sopenharmony_ci vol->ops = &smb30_operations; /* currently identical with 3.0 */ 778c2ecf20Sopenharmony_ci vol->vals = &smb302_values; 788c2ecf20Sopenharmony_ci break; 798c2ecf20Sopenharmony_ci case Smb_311: 808c2ecf20Sopenharmony_ci vol->ops = &smb311_operations; 818c2ecf20Sopenharmony_ci vol->vals = &smb311_values; 828c2ecf20Sopenharmony_ci break; 838c2ecf20Sopenharmony_ci case Smb_3any: 848c2ecf20Sopenharmony_ci vol->ops = &smb30_operations; /* currently identical with 3.0 */ 858c2ecf20Sopenharmony_ci vol->vals = &smb3any_values; 868c2ecf20Sopenharmony_ci break; 878c2ecf20Sopenharmony_ci case Smb_default: 888c2ecf20Sopenharmony_ci vol->ops = &smb30_operations; /* currently identical with 3.0 */ 898c2ecf20Sopenharmony_ci vol->vals = &smbdefault_values; 908c2ecf20Sopenharmony_ci break; 918c2ecf20Sopenharmony_ci default: 928c2ecf20Sopenharmony_ci cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value); 938c2ecf20Sopenharmony_ci return 1; 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci return 0; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic const match_table_t cifs_secflavor_tokens = { 998c2ecf20Sopenharmony_ci { Opt_sec_krb5, "krb5" }, 1008c2ecf20Sopenharmony_ci { Opt_sec_krb5i, "krb5i" }, 1018c2ecf20Sopenharmony_ci { Opt_sec_krb5p, "krb5p" }, 1028c2ecf20Sopenharmony_ci { Opt_sec_ntlmsspi, "ntlmsspi" }, 1038c2ecf20Sopenharmony_ci { Opt_sec_ntlmssp, "ntlmssp" }, 1048c2ecf20Sopenharmony_ci { Opt_ntlm, "ntlm" }, 1058c2ecf20Sopenharmony_ci { Opt_sec_ntlmi, "ntlmi" }, 1068c2ecf20Sopenharmony_ci { Opt_sec_ntlmv2, "nontlm" }, 1078c2ecf20Sopenharmony_ci { Opt_sec_ntlmv2, "ntlmv2" }, 1088c2ecf20Sopenharmony_ci { Opt_sec_ntlmv2i, "ntlmv2i" }, 1098c2ecf20Sopenharmony_ci { Opt_sec_lanman, "lanman" }, 1108c2ecf20Sopenharmony_ci { Opt_sec_none, "none" }, 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci { Opt_sec_err, NULL } 1138c2ecf20Sopenharmony_ci}; 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ciint cifs_parse_security_flavors(char *value, struct smb_vol *vol) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci substring_t args[MAX_OPT_ARGS]; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* 1218c2ecf20Sopenharmony_ci * With mount options, the last one should win. Reset any existing 1228c2ecf20Sopenharmony_ci * settings back to default. 1238c2ecf20Sopenharmony_ci */ 1248c2ecf20Sopenharmony_ci vol->sectype = Unspecified; 1258c2ecf20Sopenharmony_ci vol->sign = false; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci switch (match_token(value, cifs_secflavor_tokens, args)) { 1288c2ecf20Sopenharmony_ci case Opt_sec_krb5p: 1298c2ecf20Sopenharmony_ci cifs_dbg(VFS, "sec=krb5p is not supported!\n"); 1308c2ecf20Sopenharmony_ci return 1; 1318c2ecf20Sopenharmony_ci case Opt_sec_krb5i: 1328c2ecf20Sopenharmony_ci vol->sign = true; 1338c2ecf20Sopenharmony_ci fallthrough; 1348c2ecf20Sopenharmony_ci case Opt_sec_krb5: 1358c2ecf20Sopenharmony_ci vol->sectype = Kerberos; 1368c2ecf20Sopenharmony_ci break; 1378c2ecf20Sopenharmony_ci case Opt_sec_ntlmsspi: 1388c2ecf20Sopenharmony_ci vol->sign = true; 1398c2ecf20Sopenharmony_ci fallthrough; 1408c2ecf20Sopenharmony_ci case Opt_sec_ntlmssp: 1418c2ecf20Sopenharmony_ci vol->sectype = RawNTLMSSP; 1428c2ecf20Sopenharmony_ci break; 1438c2ecf20Sopenharmony_ci case Opt_sec_ntlmi: 1448c2ecf20Sopenharmony_ci vol->sign = true; 1458c2ecf20Sopenharmony_ci fallthrough; 1468c2ecf20Sopenharmony_ci case Opt_ntlm: 1478c2ecf20Sopenharmony_ci vol->sectype = NTLM; 1488c2ecf20Sopenharmony_ci break; 1498c2ecf20Sopenharmony_ci case Opt_sec_ntlmv2i: 1508c2ecf20Sopenharmony_ci vol->sign = true; 1518c2ecf20Sopenharmony_ci fallthrough; 1528c2ecf20Sopenharmony_ci case Opt_sec_ntlmv2: 1538c2ecf20Sopenharmony_ci vol->sectype = NTLMv2; 1548c2ecf20Sopenharmony_ci break; 1558c2ecf20Sopenharmony_ci#ifdef CONFIG_CIFS_WEAK_PW_HASH 1568c2ecf20Sopenharmony_ci case Opt_sec_lanman: 1578c2ecf20Sopenharmony_ci vol->sectype = LANMAN; 1588c2ecf20Sopenharmony_ci break; 1598c2ecf20Sopenharmony_ci#endif 1608c2ecf20Sopenharmony_ci case Opt_sec_none: 1618c2ecf20Sopenharmony_ci vol->nullauth = 1; 1628c2ecf20Sopenharmony_ci break; 1638c2ecf20Sopenharmony_ci default: 1648c2ecf20Sopenharmony_ci cifs_dbg(VFS, "bad security option: %s\n", value); 1658c2ecf20Sopenharmony_ci return 1; 1668c2ecf20Sopenharmony_ci } 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci return 0; 1698c2ecf20Sopenharmony_ci} 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cistatic const match_table_t cifs_cacheflavor_tokens = { 1728c2ecf20Sopenharmony_ci { Opt_cache_loose, "loose" }, 1738c2ecf20Sopenharmony_ci { Opt_cache_strict, "strict" }, 1748c2ecf20Sopenharmony_ci { Opt_cache_none, "none" }, 1758c2ecf20Sopenharmony_ci { Opt_cache_ro, "ro" }, 1768c2ecf20Sopenharmony_ci { Opt_cache_rw, "singleclient" }, 1778c2ecf20Sopenharmony_ci { Opt_cache_err, NULL } 1788c2ecf20Sopenharmony_ci}; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ciint 1818c2ecf20Sopenharmony_cicifs_parse_cache_flavor(char *value, struct smb_vol *vol) 1828c2ecf20Sopenharmony_ci{ 1838c2ecf20Sopenharmony_ci substring_t args[MAX_OPT_ARGS]; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci switch (match_token(value, cifs_cacheflavor_tokens, args)) { 1868c2ecf20Sopenharmony_ci case Opt_cache_loose: 1878c2ecf20Sopenharmony_ci vol->direct_io = false; 1888c2ecf20Sopenharmony_ci vol->strict_io = false; 1898c2ecf20Sopenharmony_ci vol->cache_ro = false; 1908c2ecf20Sopenharmony_ci vol->cache_rw = false; 1918c2ecf20Sopenharmony_ci break; 1928c2ecf20Sopenharmony_ci case Opt_cache_strict: 1938c2ecf20Sopenharmony_ci vol->direct_io = false; 1948c2ecf20Sopenharmony_ci vol->strict_io = true; 1958c2ecf20Sopenharmony_ci vol->cache_ro = false; 1968c2ecf20Sopenharmony_ci vol->cache_rw = false; 1978c2ecf20Sopenharmony_ci break; 1988c2ecf20Sopenharmony_ci case Opt_cache_none: 1998c2ecf20Sopenharmony_ci vol->direct_io = true; 2008c2ecf20Sopenharmony_ci vol->strict_io = false; 2018c2ecf20Sopenharmony_ci vol->cache_ro = false; 2028c2ecf20Sopenharmony_ci vol->cache_rw = false; 2038c2ecf20Sopenharmony_ci break; 2048c2ecf20Sopenharmony_ci case Opt_cache_ro: 2058c2ecf20Sopenharmony_ci vol->direct_io = false; 2068c2ecf20Sopenharmony_ci vol->strict_io = false; 2078c2ecf20Sopenharmony_ci vol->cache_ro = true; 2088c2ecf20Sopenharmony_ci vol->cache_rw = false; 2098c2ecf20Sopenharmony_ci break; 2108c2ecf20Sopenharmony_ci case Opt_cache_rw: 2118c2ecf20Sopenharmony_ci vol->direct_io = false; 2128c2ecf20Sopenharmony_ci vol->strict_io = false; 2138c2ecf20Sopenharmony_ci vol->cache_ro = false; 2148c2ecf20Sopenharmony_ci vol->cache_rw = true; 2158c2ecf20Sopenharmony_ci break; 2168c2ecf20Sopenharmony_ci default: 2178c2ecf20Sopenharmony_ci cifs_dbg(VFS, "bad cache= option: %s\n", value); 2188c2ecf20Sopenharmony_ci return 1; 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci return 0; 2218c2ecf20Sopenharmony_ci} 222