• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
cifs_parse_smb_version(char * value,struct smb_vol * vol,bool is_smb3)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 
cifs_parse_security_flavors(char * value,struct smb_vol * vol)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
cifs_parse_cache_flavor(char * value,struct smb_vol * vol)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 }
222