Merge tag 'gfs2-v5.10-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / fs / cifs / fs_context.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2020, Microsoft Corporation.
4  *
5  *   Author(s): Steve French <stfrench@microsoft.com>
6  *              David Howells <dhowells@redhat.com>
7  */
8
9 #include "cifsglob.h"
10 #include "cifs_debug.h"
11 #include "fs_context.h"
12
13 static const match_table_t cifs_smb_version_tokens = {
14         { Smb_1, SMB1_VERSION_STRING },
15         { Smb_20, SMB20_VERSION_STRING},
16         { Smb_21, SMB21_VERSION_STRING },
17         { Smb_30, SMB30_VERSION_STRING },
18         { Smb_302, SMB302_VERSION_STRING },
19         { Smb_302, ALT_SMB302_VERSION_STRING },
20         { Smb_311, SMB311_VERSION_STRING },
21         { Smb_311, ALT_SMB311_VERSION_STRING },
22         { Smb_3any, SMB3ANY_VERSION_STRING },
23         { Smb_default, SMBDEFAULT_VERSION_STRING },
24         { Smb_version_err, NULL }
25 };
26
27 int
28 cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3)
29 {
30         substring_t args[MAX_OPT_ARGS];
31
32         switch (match_token(value, cifs_smb_version_tokens, args)) {
33 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
34         case Smb_1:
35                 if (disable_legacy_dialects) {
36                         cifs_dbg(VFS, "mount with legacy dialect disabled\n");
37                         return 1;
38                 }
39                 if (is_smb3) {
40                         cifs_dbg(VFS, "vers=1.0 (cifs) not permitted when mounting with smb3\n");
41                         return 1;
42                 }
43                 cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n");
44                 vol->ops = &smb1_operations;
45                 vol->vals = &smb1_values;
46                 break;
47         case Smb_20:
48                 if (disable_legacy_dialects) {
49                         cifs_dbg(VFS, "mount with legacy dialect disabled\n");
50                         return 1;
51                 }
52                 if (is_smb3) {
53                         cifs_dbg(VFS, "vers=2.0 not permitted when mounting with smb3\n");
54                         return 1;
55                 }
56                 vol->ops = &smb20_operations;
57                 vol->vals = &smb20_values;
58                 break;
59 #else
60         case Smb_1:
61                 cifs_dbg(VFS, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n");
62                 return 1;
63         case Smb_20:
64                 cifs_dbg(VFS, "vers=2.0 mount not permitted when legacy dialects disabled\n");
65                 return 1;
66 #endif /* CIFS_ALLOW_INSECURE_LEGACY */
67         case Smb_21:
68                 vol->ops = &smb21_operations;
69                 vol->vals = &smb21_values;
70                 break;
71         case Smb_30:
72                 vol->ops = &smb30_operations;
73                 vol->vals = &smb30_values;
74                 break;
75         case Smb_302:
76                 vol->ops = &smb30_operations; /* currently identical with 3.0 */
77                 vol->vals = &smb302_values;
78                 break;
79         case Smb_311:
80                 vol->ops = &smb311_operations;
81                 vol->vals = &smb311_values;
82                 break;
83         case Smb_3any:
84                 vol->ops = &smb30_operations; /* currently identical with 3.0 */
85                 vol->vals = &smb3any_values;
86                 break;
87         case Smb_default:
88                 vol->ops = &smb30_operations; /* currently identical with 3.0 */
89                 vol->vals = &smbdefault_values;
90                 break;
91         default:
92                 cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
93                 return 1;
94         }
95         return 0;
96 }
97
98 static const match_table_t cifs_secflavor_tokens = {
99         { Opt_sec_krb5, "krb5" },
100         { Opt_sec_krb5i, "krb5i" },
101         { Opt_sec_krb5p, "krb5p" },
102         { Opt_sec_ntlmsspi, "ntlmsspi" },
103         { Opt_sec_ntlmssp, "ntlmssp" },
104         { Opt_ntlm, "ntlm" },
105         { Opt_sec_ntlmi, "ntlmi" },
106         { Opt_sec_ntlmv2, "nontlm" },
107         { Opt_sec_ntlmv2, "ntlmv2" },
108         { Opt_sec_ntlmv2i, "ntlmv2i" },
109         { Opt_sec_lanman, "lanman" },
110         { Opt_sec_none, "none" },
111
112         { Opt_sec_err, NULL }
113 };
114
115 int cifs_parse_security_flavors(char *value, struct smb_vol *vol)
116 {
117
118         substring_t args[MAX_OPT_ARGS];
119
120         /*
121          * With mount options, the last one should win. Reset any existing
122          * settings back to default.
123          */
124         vol->sectype = Unspecified;
125         vol->sign = false;
126
127         switch (match_token(value, cifs_secflavor_tokens, args)) {
128         case Opt_sec_krb5p:
129                 cifs_dbg(VFS, "sec=krb5p is not supported!\n");
130                 return 1;
131         case Opt_sec_krb5i:
132                 vol->sign = true;
133                 fallthrough;
134         case Opt_sec_krb5:
135                 vol->sectype = Kerberos;
136                 break;
137         case Opt_sec_ntlmsspi:
138                 vol->sign = true;
139                 fallthrough;
140         case Opt_sec_ntlmssp:
141                 vol->sectype = RawNTLMSSP;
142                 break;
143         case Opt_sec_ntlmi:
144                 vol->sign = true;
145                 fallthrough;
146         case Opt_ntlm:
147                 vol->sectype = NTLM;
148                 break;
149         case Opt_sec_ntlmv2i:
150                 vol->sign = true;
151                 fallthrough;
152         case Opt_sec_ntlmv2:
153                 vol->sectype = NTLMv2;
154                 break;
155 #ifdef CONFIG_CIFS_WEAK_PW_HASH
156         case Opt_sec_lanman:
157                 vol->sectype = LANMAN;
158                 break;
159 #endif
160         case Opt_sec_none:
161                 vol->nullauth = 1;
162                 break;
163         default:
164                 cifs_dbg(VFS, "bad security option: %s\n", value);
165                 return 1;
166         }
167
168         return 0;
169 }
170
171 static const match_table_t cifs_cacheflavor_tokens = {
172         { Opt_cache_loose, "loose" },
173         { Opt_cache_strict, "strict" },
174         { Opt_cache_none, "none" },
175         { Opt_cache_ro, "ro" },
176         { Opt_cache_rw, "singleclient" },
177         { Opt_cache_err, NULL }
178 };
179
180 int
181 cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
182 {
183         substring_t args[MAX_OPT_ARGS];
184
185         switch (match_token(value, cifs_cacheflavor_tokens, args)) {
186         case Opt_cache_loose:
187                 vol->direct_io = false;
188                 vol->strict_io = false;
189                 vol->cache_ro = false;
190                 vol->cache_rw = false;
191                 break;
192         case Opt_cache_strict:
193                 vol->direct_io = false;
194                 vol->strict_io = true;
195                 vol->cache_ro = false;
196                 vol->cache_rw = false;
197                 break;
198         case Opt_cache_none:
199                 vol->direct_io = true;
200                 vol->strict_io = false;
201                 vol->cache_ro = false;
202                 vol->cache_rw = false;
203                 break;
204         case Opt_cache_ro:
205                 vol->direct_io = false;
206                 vol->strict_io = false;
207                 vol->cache_ro = true;
208                 vol->cache_rw = false;
209                 break;
210         case Opt_cache_rw:
211                 vol->direct_io = false;
212                 vol->strict_io = false;
213                 vol->cache_ro = false;
214                 vol->cache_rw = true;
215                 break;
216         default:
217                 cifs_dbg(VFS, "bad cache= option: %s\n", value);
218                 return 1;
219         }
220         return 0;
221 }