~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/smb/client/fs_context.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 /*
 10 #include <linux/module.h>
 11 #include <linux/nsproxy.h>
 12 #include <linux/slab.h>
 13 #include <linux/magic.h>
 14 #include <linux/security.h>
 15 #include <net/net_namespace.h>
 16 #ifdef CONFIG_CIFS_DFS_UPCALL
 17 #include "dfs_cache.h"
 18 #endif
 19 */
 20 
 21 #include <linux/ctype.h>
 22 #include <linux/fs_context.h>
 23 #include <linux/fs_parser.h>
 24 #include <linux/fs.h>
 25 #include <linux/mount.h>
 26 #include <linux/parser.h>
 27 #include <linux/utsname.h>
 28 #include "cifsfs.h"
 29 #include "cifspdu.h"
 30 #include "cifsglob.h"
 31 #include "cifsproto.h"
 32 #include "cifs_unicode.h"
 33 #include "cifs_debug.h"
 34 #include "cifs_fs_sb.h"
 35 #include "ntlmssp.h"
 36 #include "nterr.h"
 37 #include "rfc1002pdu.h"
 38 #include "fs_context.h"
 39 
 40 DEFINE_MUTEX(cifs_mount_mutex);
 41 
 42 static const match_table_t cifs_smb_version_tokens = {
 43         { Smb_1, SMB1_VERSION_STRING },
 44         { Smb_20, SMB20_VERSION_STRING},
 45         { Smb_21, SMB21_VERSION_STRING },
 46         { Smb_30, SMB30_VERSION_STRING },
 47         { Smb_302, SMB302_VERSION_STRING },
 48         { Smb_302, ALT_SMB302_VERSION_STRING },
 49         { Smb_311, SMB311_VERSION_STRING },
 50         { Smb_311, ALT_SMB311_VERSION_STRING },
 51         { Smb_3any, SMB3ANY_VERSION_STRING },
 52         { Smb_default, SMBDEFAULT_VERSION_STRING },
 53         { Smb_version_err, NULL }
 54 };
 55 
 56 static const match_table_t cifs_secflavor_tokens = {
 57         { Opt_sec_krb5, "krb5" },
 58         { Opt_sec_krb5i, "krb5i" },
 59         { Opt_sec_krb5p, "krb5p" },
 60         { Opt_sec_ntlmsspi, "ntlmsspi" },
 61         { Opt_sec_ntlmssp, "ntlmssp" },
 62         { Opt_sec_ntlmv2, "nontlm" },
 63         { Opt_sec_ntlmv2, "ntlmv2" },
 64         { Opt_sec_ntlmv2i, "ntlmv2i" },
 65         { Opt_sec_none, "none" },
 66 
 67         { Opt_sec_err, NULL }
 68 };
 69 
 70 const struct fs_parameter_spec smb3_fs_parameters[] = {
 71         /* Mount options that take no arguments */
 72         fsparam_flag_no("user_xattr", Opt_user_xattr),
 73         fsparam_flag_no("forceuid", Opt_forceuid),
 74         fsparam_flag_no("multichannel", Opt_multichannel),
 75         fsparam_flag_no("forcegid", Opt_forcegid),
 76         fsparam_flag("noblocksend", Opt_noblocksend),
 77         fsparam_flag("noautotune", Opt_noautotune),
 78         fsparam_flag("nolease", Opt_nolease),
 79         fsparam_flag_no("hard", Opt_hard),
 80         fsparam_flag_no("soft", Opt_soft),
 81         fsparam_flag_no("perm", Opt_perm),
 82         fsparam_flag("nodelete", Opt_nodelete),
 83         fsparam_flag_no("mapposix", Opt_mapposix),
 84         fsparam_flag("mapchars", Opt_mapchars),
 85         fsparam_flag("nomapchars", Opt_nomapchars),
 86         fsparam_flag_no("sfu", Opt_sfu),
 87         fsparam_flag("nodfs", Opt_nodfs),
 88         fsparam_flag_no("posixpaths", Opt_posixpaths),
 89         fsparam_flag_no("unix", Opt_unix),
 90         fsparam_flag_no("linux", Opt_unix),
 91         fsparam_flag_no("posix", Opt_unix),
 92         fsparam_flag("nocase", Opt_nocase),
 93         fsparam_flag("ignorecase", Opt_nocase),
 94         fsparam_flag_no("brl", Opt_brl),
 95         fsparam_flag_no("handlecache", Opt_handlecache),
 96         fsparam_flag("forcemandatorylock", Opt_forcemandatorylock),
 97         fsparam_flag("forcemand", Opt_forcemandatorylock),
 98         fsparam_flag("setuidfromacl", Opt_setuidfromacl),
 99         fsparam_flag("idsfromsid", Opt_setuidfromacl),
100         fsparam_flag_no("setuids", Opt_setuids),
101         fsparam_flag_no("dynperm", Opt_dynperm),
102         fsparam_flag_no("intr", Opt_intr),
103         fsparam_flag_no("strictsync", Opt_strictsync),
104         fsparam_flag_no("serverino", Opt_serverino),
105         fsparam_flag("rwpidforward", Opt_rwpidforward),
106         fsparam_flag("cifsacl", Opt_cifsacl),
107         fsparam_flag_no("acl", Opt_acl),
108         fsparam_flag("locallease", Opt_locallease),
109         fsparam_flag("sign", Opt_sign),
110         fsparam_flag("ignore_signature", Opt_ignore_signature),
111         fsparam_flag("signloosely", Opt_ignore_signature),
112         fsparam_flag("seal", Opt_seal),
113         fsparam_flag("noac", Opt_noac),
114         fsparam_flag("fsc", Opt_fsc),
115         fsparam_flag("mfsymlinks", Opt_mfsymlinks),
116         fsparam_flag("multiuser", Opt_multiuser),
117         fsparam_flag("sloppy", Opt_sloppy),
118         fsparam_flag("nosharesock", Opt_nosharesock),
119         fsparam_flag_no("persistenthandles", Opt_persistent),
120         fsparam_flag_no("resilienthandles", Opt_resilient),
121         fsparam_flag_no("tcpnodelay", Opt_tcp_nodelay),
122         fsparam_flag("nosparse", Opt_nosparse),
123         fsparam_flag("domainauto", Opt_domainauto),
124         fsparam_flag("rdma", Opt_rdma),
125         fsparam_flag("modesid", Opt_modesid),
126         fsparam_flag("modefromsid", Opt_modesid),
127         fsparam_flag("rootfs", Opt_rootfs),
128         fsparam_flag("compress", Opt_compress),
129         fsparam_flag("witness", Opt_witness),
130 
131         /* Mount options which take uid or gid */
132         fsparam_uid("backupuid", Opt_backupuid),
133         fsparam_gid("backupgid", Opt_backupgid),
134         fsparam_uid("uid", Opt_uid),
135         fsparam_uid("cruid", Opt_cruid),
136         fsparam_gid("gid", Opt_gid),
137 
138         /* Mount options which take numeric value */
139         fsparam_u32("file_mode", Opt_file_mode),
140         fsparam_u32("dirmode", Opt_dirmode),
141         fsparam_u32("dir_mode", Opt_dirmode),
142         fsparam_u32("port", Opt_port),
143         fsparam_u32("min_enc_offload", Opt_min_enc_offload),
144         fsparam_u32("retrans", Opt_retrans),
145         fsparam_u32("esize", Opt_min_enc_offload),
146         fsparam_u32("bsize", Opt_blocksize),
147         fsparam_u32("rasize", Opt_rasize),
148         fsparam_u32("rsize", Opt_rsize),
149         fsparam_u32("wsize", Opt_wsize),
150         fsparam_u32("actimeo", Opt_actimeo),
151         fsparam_u32("acdirmax", Opt_acdirmax),
152         fsparam_u32("acregmax", Opt_acregmax),
153         fsparam_u32("closetimeo", Opt_closetimeo),
154         fsparam_u32("echo_interval", Opt_echo_interval),
155         fsparam_u32("max_credits", Opt_max_credits),
156         fsparam_u32("max_cached_dirs", Opt_max_cached_dirs),
157         fsparam_u32("handletimeout", Opt_handletimeout),
158         fsparam_u64("snapshot", Opt_snapshot),
159         fsparam_u32("max_channels", Opt_max_channels),
160 
161         /* Mount options which take string value */
162         fsparam_string("source", Opt_source),
163         fsparam_string("user", Opt_user),
164         fsparam_string("username", Opt_user),
165         fsparam_string("pass", Opt_pass),
166         fsparam_string("password", Opt_pass),
167         fsparam_string("password2", Opt_pass2),
168         fsparam_string("ip", Opt_ip),
169         fsparam_string("addr", Opt_ip),
170         fsparam_string("domain", Opt_domain),
171         fsparam_string("dom", Opt_domain),
172         fsparam_string("srcaddr", Opt_srcaddr),
173         fsparam_string("iocharset", Opt_iocharset),
174         fsparam_string("netbiosname", Opt_netbiosname),
175         fsparam_string("servern", Opt_servern),
176         fsparam_string("ver", Opt_ver),
177         fsparam_string("vers", Opt_vers),
178         fsparam_string("sec", Opt_sec),
179         fsparam_string("cache", Opt_cache),
180         fsparam_string("reparse", Opt_reparse),
181 
182         /* Arguments that should be ignored */
183         fsparam_flag("guest", Opt_ignore),
184         fsparam_flag("noatime", Opt_ignore),
185         fsparam_flag("relatime", Opt_ignore),
186         fsparam_flag("_netdev", Opt_ignore),
187         fsparam_flag_no("suid", Opt_ignore),
188         fsparam_flag_no("exec", Opt_ignore),
189         fsparam_flag_no("dev", Opt_ignore),
190         fsparam_flag_no("mand", Opt_ignore),
191         fsparam_flag_no("auto", Opt_ignore),
192         fsparam_string("cred", Opt_ignore),
193         fsparam_string("credentials", Opt_ignore),
194         /*
195          * UNC and prefixpath is now extracted from Opt_source
196          * in the new mount API so we can just ignore them going forward.
197          */
198         fsparam_string("unc", Opt_ignore),
199         fsparam_string("prefixpath", Opt_ignore),
200         {}
201 };
202 
203 static int
204 cifs_parse_security_flavors(struct fs_context *fc, char *value, struct smb3_fs_context *ctx)
205 {
206 
207         substring_t args[MAX_OPT_ARGS];
208 
209         /*
210          * With mount options, the last one should win. Reset any existing
211          * settings back to default.
212          */
213         ctx->sectype = Unspecified;
214         ctx->sign = false;
215 
216         switch (match_token(value, cifs_secflavor_tokens, args)) {
217         case Opt_sec_krb5p:
218                 cifs_errorf(fc, "sec=krb5p is not supported. Use sec=krb5,seal instead\n");
219                 return 1;
220         case Opt_sec_krb5i:
221                 ctx->sign = true;
222                 fallthrough;
223         case Opt_sec_krb5:
224                 ctx->sectype = Kerberos;
225                 break;
226         case Opt_sec_ntlmsspi:
227                 ctx->sign = true;
228                 fallthrough;
229         case Opt_sec_ntlmssp:
230                 ctx->sectype = RawNTLMSSP;
231                 break;
232         case Opt_sec_ntlmv2i:
233                 ctx->sign = true;
234                 fallthrough;
235         case Opt_sec_ntlmv2:
236                 ctx->sectype = NTLMv2;
237                 break;
238         case Opt_sec_none:
239                 ctx->nullauth = 1;
240                 kfree(ctx->username);
241                 ctx->username = NULL;
242                 break;
243         default:
244                 cifs_errorf(fc, "bad security option: %s\n", value);
245                 return 1;
246         }
247 
248         return 0;
249 }
250 
251 static const match_table_t cifs_cacheflavor_tokens = {
252         { Opt_cache_loose, "loose" },
253         { Opt_cache_strict, "strict" },
254         { Opt_cache_none, "none" },
255         { Opt_cache_ro, "ro" },
256         { Opt_cache_rw, "singleclient" },
257         { Opt_cache_err, NULL }
258 };
259 
260 static int
261 cifs_parse_cache_flavor(struct fs_context *fc, char *value, struct smb3_fs_context *ctx)
262 {
263         substring_t args[MAX_OPT_ARGS];
264 
265         switch (match_token(value, cifs_cacheflavor_tokens, args)) {
266         case Opt_cache_loose:
267                 ctx->direct_io = false;
268                 ctx->strict_io = false;
269                 ctx->cache_ro = false;
270                 ctx->cache_rw = false;
271                 break;
272         case Opt_cache_strict:
273                 ctx->direct_io = false;
274                 ctx->strict_io = true;
275                 ctx->cache_ro = false;
276                 ctx->cache_rw = false;
277                 break;
278         case Opt_cache_none:
279                 ctx->direct_io = true;
280                 ctx->strict_io = false;
281                 ctx->cache_ro = false;
282                 ctx->cache_rw = false;
283                 break;
284         case Opt_cache_ro:
285                 ctx->direct_io = false;
286                 ctx->strict_io = false;
287                 ctx->cache_ro = true;
288                 ctx->cache_rw = false;
289                 break;
290         case Opt_cache_rw:
291                 ctx->direct_io = false;
292                 ctx->strict_io = false;
293                 ctx->cache_ro = false;
294                 ctx->cache_rw = true;
295                 break;
296         default:
297                 cifs_errorf(fc, "bad cache= option: %s\n", value);
298                 return 1;
299         }
300         return 0;
301 }
302 
303 static const match_table_t reparse_flavor_tokens = {
304         { Opt_reparse_default,  "default" },
305         { Opt_reparse_nfs,      "nfs" },
306         { Opt_reparse_wsl,      "wsl" },
307         { Opt_reparse_err,      NULL },
308 };
309 
310 static int parse_reparse_flavor(struct fs_context *fc, char *value,
311                                 struct smb3_fs_context *ctx)
312 {
313         substring_t args[MAX_OPT_ARGS];
314 
315         switch (match_token(value, reparse_flavor_tokens, args)) {
316         case Opt_reparse_default:
317                 ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT;
318                 break;
319         case Opt_reparse_nfs:
320                 ctx->reparse_type = CIFS_REPARSE_TYPE_NFS;
321                 break;
322         case Opt_reparse_wsl:
323                 ctx->reparse_type = CIFS_REPARSE_TYPE_WSL;
324                 break;
325         default:
326                 cifs_errorf(fc, "bad reparse= option: %s\n", value);
327                 return 1;
328         }
329         return 0;
330 }
331 
332 #define DUP_CTX_STR(field)                                              \
333 do {                                                                    \
334         if (ctx->field) {                                               \
335                 new_ctx->field = kstrdup(ctx->field, GFP_ATOMIC);       \
336                 if (new_ctx->field == NULL) {                           \
337                         smb3_cleanup_fs_context_contents(new_ctx);      \
338                         return -ENOMEM;                                 \
339                 }                                                       \
340         }                                                               \
341 } while (0)
342 
343 int
344 smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx)
345 {
346         memcpy(new_ctx, ctx, sizeof(*ctx));
347         new_ctx->prepath = NULL;
348         new_ctx->nodename = NULL;
349         new_ctx->username = NULL;
350         new_ctx->password = NULL;
351         new_ctx->password2 = NULL;
352         new_ctx->server_hostname = NULL;
353         new_ctx->domainname = NULL;
354         new_ctx->UNC = NULL;
355         new_ctx->source = NULL;
356         new_ctx->iocharset = NULL;
357         new_ctx->leaf_fullpath = NULL;
358         /*
359          * Make sure to stay in sync with smb3_cleanup_fs_context_contents()
360          */
361         DUP_CTX_STR(prepath);
362         DUP_CTX_STR(username);
363         DUP_CTX_STR(password);
364         DUP_CTX_STR(password2);
365         DUP_CTX_STR(server_hostname);
366         DUP_CTX_STR(UNC);
367         DUP_CTX_STR(source);
368         DUP_CTX_STR(domainname);
369         DUP_CTX_STR(nodename);
370         DUP_CTX_STR(iocharset);
371         DUP_CTX_STR(leaf_fullpath);
372 
373         return 0;
374 }
375 
376 static int
377 cifs_parse_smb_version(struct fs_context *fc, char *value, struct smb3_fs_context *ctx, bool is_smb3)
378 {
379         substring_t args[MAX_OPT_ARGS];
380 
381         switch (match_token(value, cifs_smb_version_tokens, args)) {
382 #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
383         case Smb_1:
384                 if (disable_legacy_dialects) {
385                         cifs_errorf(fc, "mount with legacy dialect disabled\n");
386                         return 1;
387                 }
388                 if (is_smb3) {
389                         cifs_errorf(fc, "vers=1.0 (cifs) not permitted when mounting with smb3\n");
390                         return 1;
391                 }
392                 cifs_errorf(fc, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n");
393                 ctx->ops = &smb1_operations;
394                 ctx->vals = &smb1_values;
395                 break;
396         case Smb_20:
397                 if (disable_legacy_dialects) {
398                         cifs_errorf(fc, "mount with legacy dialect disabled\n");
399                         return 1;
400                 }
401                 if (is_smb3) {
402                         cifs_errorf(fc, "vers=2.0 not permitted when mounting with smb3\n");
403                         return 1;
404                 }
405                 ctx->ops = &smb20_operations;
406                 ctx->vals = &smb20_values;
407                 break;
408 #else
409         case Smb_1:
410                 cifs_errorf(fc, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n");
411                 return 1;
412         case Smb_20:
413                 cifs_errorf(fc, "vers=2.0 mount not permitted when legacy dialects disabled\n");
414                 return 1;
415 #endif /* CIFS_ALLOW_INSECURE_LEGACY */
416         case Smb_21:
417                 ctx->ops = &smb21_operations;
418                 ctx->vals = &smb21_values;
419                 break;
420         case Smb_30:
421                 ctx->ops = &smb30_operations;
422                 ctx->vals = &smb30_values;
423                 break;
424         case Smb_302:
425                 ctx->ops = &smb30_operations; /* currently identical with 3.0 */
426                 ctx->vals = &smb302_values;
427                 break;
428         case Smb_311:
429                 ctx->ops = &smb311_operations;
430                 ctx->vals = &smb311_values;
431                 break;
432         case Smb_3any:
433                 ctx->ops = &smb30_operations; /* currently identical with 3.0 */
434                 ctx->vals = &smb3any_values;
435                 break;
436         case Smb_default:
437                 ctx->ops = &smb30_operations;
438                 ctx->vals = &smbdefault_values;
439                 break;
440         default:
441                 cifs_errorf(fc, "Unknown vers= option specified: %s\n", value);
442                 return 1;
443         }
444         return 0;
445 }
446 
447 int smb3_parse_opt(const char *options, const char *key, char **val)
448 {
449         int rc = -ENOENT;
450         char *opts, *orig, *p;
451 
452         orig = opts = kstrdup(options, GFP_KERNEL);
453         if (!opts)
454                 return -ENOMEM;
455 
456         while ((p = strsep(&opts, ","))) {
457                 char *nval;
458 
459                 if (!*p)
460                         continue;
461                 if (strncasecmp(p, key, strlen(key)))
462                         continue;
463                 nval = strchr(p, '=');
464                 if (nval) {
465                         if (nval == p)
466                                 continue;
467                         *nval++ = 0;
468                         *val = kstrdup(nval, GFP_KERNEL);
469                         rc = !*val ? -ENOMEM : 0;
470                         goto out;
471                 }
472         }
473 out:
474         kfree(orig);
475         return rc;
476 }
477 
478 /*
479  * Remove duplicate path delimiters. Windows is supposed to do that
480  * but there are some bugs that prevent rename from working if there are
481  * multiple delimiters.
482  *
483  * Return a sanitized duplicate of @path or NULL for empty prefix paths.
484  * Otherwise, return ERR_PTR.
485  *
486  * @gfp indicates the GFP_* flags for kstrdup.
487  * The caller is responsible for freeing the original.
488  */
489 #define IS_DELIM(c) ((c) == '/' || (c) == '\\')
490 char *cifs_sanitize_prepath(char *prepath, gfp_t gfp)
491 {
492         char *cursor1 = prepath, *cursor2 = prepath;
493         char *s;
494 
495         /* skip all prepended delimiters */
496         while (IS_DELIM(*cursor1))
497                 cursor1++;
498 
499         /* copy the first letter */
500         *cursor2 = *cursor1;
501 
502         /* copy the remainder... */
503         while (*(cursor1++)) {
504                 /* ... skipping all duplicated delimiters */
505                 if (IS_DELIM(*cursor1) && IS_DELIM(*cursor2))
506                         continue;
507                 *(++cursor2) = *cursor1;
508         }
509 
510         /* if the last character is a delimiter, skip it */
511         if (IS_DELIM(*(cursor2 - 1)))
512                 cursor2--;
513 
514         *cursor2 = '\0';
515         if (!*prepath)
516                 return NULL;
517         s = kstrdup(prepath, gfp);
518         if (!s)
519                 return ERR_PTR(-ENOMEM);
520         return s;
521 }
522 
523 /*
524  * Return full path based on the values of @ctx->{UNC,prepath}.
525  *
526  * It is assumed that both values were already parsed by smb3_parse_devname().
527  */
528 char *smb3_fs_context_fullpath(const struct smb3_fs_context *ctx, char dirsep)
529 {
530         size_t ulen, plen;
531         char *s;
532 
533         ulen = strlen(ctx->UNC);
534         plen = ctx->prepath ? strlen(ctx->prepath) + 1 : 0;
535 
536         s = kmalloc(ulen + plen + 1, GFP_KERNEL);
537         if (!s)
538                 return ERR_PTR(-ENOMEM);
539         memcpy(s, ctx->UNC, ulen);
540         if (plen) {
541                 s[ulen] = dirsep;
542                 memcpy(s + ulen + 1, ctx->prepath, plen);
543         }
544         s[ulen + plen] = '\0';
545         convert_delimiter(s, dirsep);
546         return s;
547 }
548 
549 /*
550  * Parse a devname into substrings and populate the ctx->UNC and ctx->prepath
551  * fields with the result. Returns 0 on success and an error otherwise
552  * (e.g. ENOMEM or EINVAL)
553  */
554 int
555 smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
556 {
557         char *pos;
558         const char *delims = "/\\";
559         size_t len;
560         int rc;
561 
562         if (unlikely(!devname || !*devname)) {
563                 cifs_dbg(VFS, "Device name not specified\n");
564                 return -EINVAL;
565         }
566 
567         /* make sure we have a valid UNC double delimiter prefix */
568         len = strspn(devname, delims);
569         if (len != 2)
570                 return -EINVAL;
571 
572         /* find delimiter between host and sharename */
573         pos = strpbrk(devname + 2, delims);
574         if (!pos)
575                 return -EINVAL;
576 
577         /* record the server hostname */
578         kfree(ctx->server_hostname);
579         ctx->server_hostname = kstrndup(devname + 2, pos - devname - 2, GFP_KERNEL);
580         if (!ctx->server_hostname)
581                 return -ENOMEM;
582 
583         /* skip past delimiter */
584         ++pos;
585 
586         /* now go until next delimiter or end of string */
587         len = strcspn(pos, delims);
588         if (!len)
589                 return -EINVAL;
590 
591         /* move "pos" up to delimiter or NULL */
592         pos += len;
593         kfree(ctx->UNC);
594         ctx->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
595         if (!ctx->UNC)
596                 return -ENOMEM;
597 
598         convert_delimiter(ctx->UNC, '\\');
599 
600         /* skip any delimiter */
601         if (*pos == '/' || *pos == '\\')
602                 pos++;
603 
604         kfree(ctx->prepath);
605         ctx->prepath = NULL;
606 
607         /* If pos is NULL then no prepath */
608         if (!*pos)
609                 return 0;
610 
611         ctx->prepath = cifs_sanitize_prepath(pos, GFP_KERNEL);
612         if (IS_ERR(ctx->prepath)) {
613                 rc = PTR_ERR(ctx->prepath);
614                 ctx->prepath = NULL;
615                 return rc;
616         }
617 
618         return 0;
619 }
620 
621 static void smb3_fs_context_free(struct fs_context *fc);
622 static int smb3_fs_context_parse_param(struct fs_context *fc,
623                                        struct fs_parameter *param);
624 static int smb3_fs_context_parse_monolithic(struct fs_context *fc,
625                                             void *data);
626 static int smb3_get_tree(struct fs_context *fc);
627 static int smb3_reconfigure(struct fs_context *fc);
628 
629 static const struct fs_context_operations smb3_fs_context_ops = {
630         .free                   = smb3_fs_context_free,
631         .parse_param            = smb3_fs_context_parse_param,
632         .parse_monolithic       = smb3_fs_context_parse_monolithic,
633         .get_tree               = smb3_get_tree,
634         .reconfigure            = smb3_reconfigure,
635 };
636 
637 /*
638  * Parse a monolithic block of data from sys_mount().
639  * smb3_fs_context_parse_monolithic - Parse key[=val][,key[=val]]* mount data
640  * @ctx: The superblock configuration to fill in.
641  * @data: The data to parse
642  *
643  * Parse a blob of data that's in key[=val][,key[=val]]* form.  This can be
644  * called from the ->monolithic_mount_data() fs_context operation.
645  *
646  * Returns 0 on success or the error returned by the ->parse_option() fs_context
647  * operation on failure.
648  */
649 static int smb3_fs_context_parse_monolithic(struct fs_context *fc,
650                                            void *data)
651 {
652         char *options = data, *key;
653         int ret = 0;
654 
655         if (!options)
656                 return 0;
657 
658         ret = security_sb_eat_lsm_opts(options, &fc->security);
659         if (ret)
660                 return ret;
661 
662         /* BB Need to add support for sep= here TBD */
663         while ((key = strsep(&options, ",")) != NULL) {
664                 size_t len;
665                 char *value;
666 
667                 if (*key == 0)
668                         break;
669 
670                 /* Check if following character is the deliminator If yes,
671                  * we have encountered a double deliminator reset the NULL
672                  * character to the deliminator
673                  */
674                 while (options && options[0] == ',') {
675                         len = strlen(key);
676                         strcpy(key + len, options);
677                         options = strchr(options, ',');
678                         if (options)
679                                 *options++ = 0;
680                 }
681 
682 
683                 len = 0;
684                 value = strchr(key, '=');
685                 if (value) {
686                         if (value == key)
687                                 continue;
688                         *value++ = 0;
689                         len = strlen(value);
690                 }
691 
692                 ret = vfs_parse_fs_string(fc, key, value, len);
693                 if (ret < 0)
694                         break;
695         }
696 
697         return ret;
698 }
699 
700 /*
701  * Validate the preparsed information in the config.
702  */
703 static int smb3_fs_context_validate(struct fs_context *fc)
704 {
705         struct smb3_fs_context *ctx = smb3_fc2context(fc);
706 
707         if (ctx->rdma && ctx->vals->protocol_id < SMB30_PROT_ID) {
708                 cifs_errorf(fc, "SMB Direct requires Version >=3.0\n");
709                 return -EOPNOTSUPP;
710         }
711 
712 #ifndef CONFIG_KEYS
713         /* Muliuser mounts require CONFIG_KEYS support */
714         if (ctx->multiuser) {
715                 cifs_errorf(fc, "Multiuser mounts require kernels with CONFIG_KEYS enabled\n");
716                 return -1;
717         }
718 #endif
719 
720         if (ctx->got_version == false)
721                 pr_warn_once("No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3.1.1), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3.1.1 (or even SMB3 or SMB2.1) specify vers=1.0 on mount.\n");
722 
723 
724         if (!ctx->UNC) {
725                 cifs_errorf(fc, "CIFS mount error: No usable UNC path provided in device string!\n");
726                 return -1;
727         }
728 
729         /* make sure UNC has a share name */
730         if (strlen(ctx->UNC) < 3 || !strchr(ctx->UNC + 3, '\\')) {
731                 cifs_errorf(fc, "Malformed UNC. Unable to find share name.\n");
732                 return -ENOENT;
733         }
734 
735         if (!ctx->got_ip) {
736                 int len;
737                 const char *slash;
738 
739                 /* No ip= option specified? Try to get it from UNC */
740                 /* Use the address part of the UNC. */
741                 slash = strchr(&ctx->UNC[2], '\\');
742                 len = slash - &ctx->UNC[2];
743                 if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr,
744                                           &ctx->UNC[2], len)) {
745                         pr_err("Unable to determine destination address\n");
746                         return -EHOSTUNREACH;
747                 }
748         }
749 
750         /* set the port that we got earlier */
751         cifs_set_port((struct sockaddr *)&ctx->dstaddr, ctx->port);
752 
753         if (ctx->uid_specified && !ctx->forceuid_specified) {
754                 ctx->override_uid = 1;
755                 pr_notice("enabling forceuid mount option implicitly because uid= option is specified\n");
756         }
757 
758         if (ctx->gid_specified && !ctx->forcegid_specified) {
759                 ctx->override_gid = 1;
760                 pr_notice("enabling forcegid mount option implicitly because gid= option is specified\n");
761         }
762 
763         if (ctx->override_uid && !ctx->uid_specified) {
764                 ctx->override_uid = 0;
765                 pr_notice("ignoring forceuid mount option specified with no uid= option\n");
766         }
767 
768         if (ctx->override_gid && !ctx->gid_specified) {
769                 ctx->override_gid = 0;
770                 pr_notice("ignoring forcegid mount option specified with no gid= option\n");
771         }
772 
773         return 0;
774 }
775 
776 static int smb3_get_tree_common(struct fs_context *fc)
777 {
778         struct smb3_fs_context *ctx = smb3_fc2context(fc);
779         struct dentry *root;
780         int rc = 0;
781 
782         root = cifs_smb3_do_mount(fc->fs_type, 0, ctx);
783         if (IS_ERR(root))
784                 return PTR_ERR(root);
785 
786         fc->root = root;
787 
788         return rc;
789 }
790 
791 /*
792  * Create an SMB3 superblock from the parameters passed.
793  */
794 static int smb3_get_tree(struct fs_context *fc)
795 {
796         int err = smb3_fs_context_validate(fc);
797         int ret;
798 
799         if (err)
800                 return err;
801         cifs_mount_lock();
802         ret = smb3_get_tree_common(fc);
803         cifs_mount_unlock();
804         return ret;
805 }
806 
807 static void smb3_fs_context_free(struct fs_context *fc)
808 {
809         struct smb3_fs_context *ctx = smb3_fc2context(fc);
810 
811         smb3_cleanup_fs_context(ctx);
812 }
813 
814 /*
815  * Compare the old and new proposed context during reconfigure
816  * and check if the changes are compatible.
817  */
818 static int smb3_verify_reconfigure_ctx(struct fs_context *fc,
819                                        struct smb3_fs_context *new_ctx,
820                                        struct smb3_fs_context *old_ctx, bool need_recon)
821 {
822         if (new_ctx->posix_paths != old_ctx->posix_paths) {
823                 cifs_errorf(fc, "can not change posixpaths during remount\n");
824                 return -EINVAL;
825         }
826         if (new_ctx->sectype != old_ctx->sectype) {
827                 cifs_errorf(fc, "can not change sec during remount\n");
828                 return -EINVAL;
829         }
830         if (new_ctx->multiuser != old_ctx->multiuser) {
831                 cifs_errorf(fc, "can not change multiuser during remount\n");
832                 return -EINVAL;
833         }
834         if (new_ctx->UNC &&
835             (!old_ctx->UNC || strcmp(new_ctx->UNC, old_ctx->UNC))) {
836                 cifs_errorf(fc, "can not change UNC during remount\n");
837                 return -EINVAL;
838         }
839         if (new_ctx->username &&
840             (!old_ctx->username || strcmp(new_ctx->username, old_ctx->username))) {
841                 cifs_errorf(fc, "can not change username during remount\n");
842                 return -EINVAL;
843         }
844         if (new_ctx->password &&
845             (!old_ctx->password || strcmp(new_ctx->password, old_ctx->password))) {
846                 if (need_recon == false) {
847                         cifs_errorf(fc,
848                                     "can not change password of active session during remount\n");
849                         return -EINVAL;
850                 } else if (old_ctx->sectype == Kerberos) {
851                         cifs_errorf(fc,
852                                     "can not change password for Kerberos via remount\n");
853                         return -EINVAL;
854                 }
855         }
856         if (new_ctx->domainname &&
857             (!old_ctx->domainname || strcmp(new_ctx->domainname, old_ctx->domainname))) {
858                 cifs_errorf(fc, "can not change domainname during remount\n");
859                 return -EINVAL;
860         }
861         if (strcmp(new_ctx->workstation_name, old_ctx->workstation_name)) {
862                 cifs_errorf(fc, "can not change workstation_name during remount\n");
863                 return -EINVAL;
864         }
865         if (new_ctx->nodename &&
866             (!old_ctx->nodename || strcmp(new_ctx->nodename, old_ctx->nodename))) {
867                 cifs_errorf(fc, "can not change nodename during remount\n");
868                 return -EINVAL;
869         }
870         if (new_ctx->iocharset &&
871             (!old_ctx->iocharset || strcmp(new_ctx->iocharset, old_ctx->iocharset))) {
872                 cifs_errorf(fc, "can not change iocharset during remount\n");
873                 return -EINVAL;
874         }
875 
876         return 0;
877 }
878 
879 #define STEAL_STRING(cifs_sb, ctx, field)                               \
880 do {                                                                    \
881         kfree(ctx->field);                                              \
882         ctx->field = cifs_sb->ctx->field;                               \
883         cifs_sb->ctx->field = NULL;                                     \
884 } while (0)
885 
886 #define STEAL_STRING_SENSITIVE(cifs_sb, ctx, field)                     \
887 do {                                                                    \
888         kfree_sensitive(ctx->field);                                    \
889         ctx->field = cifs_sb->ctx->field;                               \
890         cifs_sb->ctx->field = NULL;                                     \
891 } while (0)
892 
893 static int smb3_reconfigure(struct fs_context *fc)
894 {
895         struct smb3_fs_context *ctx = smb3_fc2context(fc);
896         struct dentry *root = fc->root;
897         struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
898         struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses;
899         bool need_recon = false;
900         int rc;
901 
902         if (ses->expired_pwd)
903                 need_recon = true;
904 
905         rc = smb3_verify_reconfigure_ctx(fc, ctx, cifs_sb->ctx, need_recon);
906         if (rc)
907                 return rc;
908 
909         /*
910          * We can not change UNC/username/password/domainname/
911          * workstation_name/nodename/iocharset
912          * during reconnect so ignore what we have in the new context and
913          * just use what we already have in cifs_sb->ctx.
914          */
915         STEAL_STRING(cifs_sb, ctx, UNC);
916         STEAL_STRING(cifs_sb, ctx, source);
917         STEAL_STRING(cifs_sb, ctx, username);
918         if (need_recon == false)
919                 STEAL_STRING_SENSITIVE(cifs_sb, ctx, password);
920         else  {
921                 kfree_sensitive(ses->password);
922                 ses->password = kstrdup(ctx->password, GFP_KERNEL);
923                 kfree_sensitive(ses->password2);
924                 ses->password2 = kstrdup(ctx->password2, GFP_KERNEL);
925         }
926         STEAL_STRING(cifs_sb, ctx, domainname);
927         STEAL_STRING(cifs_sb, ctx, nodename);
928         STEAL_STRING(cifs_sb, ctx, iocharset);
929 
930         /* if rsize or wsize not passed in on remount, use previous values */
931         if (ctx->rsize == 0)
932                 ctx->rsize = cifs_sb->ctx->rsize;
933         if (ctx->wsize == 0)
934                 ctx->wsize = cifs_sb->ctx->wsize;
935 
936 
937         smb3_cleanup_fs_context_contents(cifs_sb->ctx);
938         rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
939         smb3_update_mnt_flags(cifs_sb);
940 #ifdef CONFIG_CIFS_DFS_UPCALL
941         if (!rc)
942                 rc = dfs_cache_remount_fs(cifs_sb);
943 #endif
944 
945         return rc;
946 }
947 
948 static int smb3_fs_context_parse_param(struct fs_context *fc,
949                                       struct fs_parameter *param)
950 {
951         struct fs_parse_result result;
952         struct smb3_fs_context *ctx = smb3_fc2context(fc);
953         int i, opt;
954         bool is_smb3 = !strcmp(fc->fs_type->name, "smb3");
955         bool skip_parsing = false;
956 
957         cifs_dbg(FYI, "CIFS: parsing cifs mount option '%s'\n", param->key);
958 
959         /*
960          * fs_parse can not handle string options with an empty value so
961          * we will need special handling of them.
962          */
963         if (param->type == fs_value_is_string && param->string[0] == 0) {
964                 if (!strcmp("pass", param->key) || !strcmp("password", param->key)) {
965                         skip_parsing = true;
966                         opt = Opt_pass;
967                 } else if (!strcmp("user", param->key) || !strcmp("username", param->key)) {
968                         skip_parsing = true;
969                         opt = Opt_user;
970                 }
971         }
972 
973         if (!skip_parsing) {
974                 opt = fs_parse(fc, smb3_fs_parameters, param, &result);
975                 if (opt < 0)
976                         return ctx->sloppy ? 1 : opt;
977         }
978 
979         switch (opt) {
980         case Opt_compress:
981                 ctx->compress = true;
982                 cifs_dbg(VFS,
983                         "SMB3 compression support is experimental\n");
984                 break;
985         case Opt_nodfs:
986                 ctx->nodfs = 1;
987                 break;
988         case Opt_hard:
989                 if (result.negated) {
990                         if (ctx->retry == 1)
991                                 cifs_dbg(VFS, "conflicting hard vs. soft mount options\n");
992                         ctx->retry = 0;
993                 } else
994                         ctx->retry = 1;
995                 break;
996         case Opt_soft:
997                 if (result.negated)
998                         ctx->retry = 1;
999                 else {
1000                         if (ctx->retry == 1)
1001                                 cifs_dbg(VFS, "conflicting hard vs soft mount options\n");
1002                         ctx->retry = 0;
1003                 }
1004                 break;
1005         case Opt_mapposix:
1006                 if (result.negated)
1007                         ctx->remap = false;
1008                 else {
1009                         ctx->remap = true;
1010                         ctx->sfu_remap = false; /* disable SFU mapping */
1011                 }
1012                 break;
1013         case Opt_mapchars:
1014                 if (result.negated)
1015                         ctx->sfu_remap = false;
1016                 else {
1017                         ctx->sfu_remap = true;
1018                         ctx->remap = false; /* disable SFM (mapposix) mapping */
1019                 }
1020                 break;
1021         case Opt_user_xattr:
1022                 if (result.negated)
1023                         ctx->no_xattr = 1;
1024                 else
1025                         ctx->no_xattr = 0;
1026                 break;
1027         case Opt_forceuid:
1028                 if (result.negated)
1029                         ctx->override_uid = 0;
1030                 else
1031                         ctx->override_uid = 1;
1032                 ctx->forceuid_specified = true;
1033                 break;
1034         case Opt_forcegid:
1035                 if (result.negated)
1036                         ctx->override_gid = 0;
1037                 else
1038                         ctx->override_gid = 1;
1039                 ctx->forcegid_specified = true;
1040                 break;
1041         case Opt_perm:
1042                 if (result.negated)
1043                         ctx->noperm = 1;
1044                 else
1045                         ctx->noperm = 0;
1046                 break;
1047         case Opt_dynperm:
1048                 if (result.negated)
1049                         ctx->dynperm = 0;
1050                 else
1051                         ctx->dynperm = 1;
1052                 break;
1053         case Opt_sfu:
1054                 if (result.negated)
1055                         ctx->sfu_emul = 0;
1056                 else
1057                         ctx->sfu_emul = 1;
1058                 break;
1059         case Opt_noblocksend:
1060                 ctx->noblocksnd = 1;
1061                 break;
1062         case Opt_noautotune:
1063                 ctx->noautotune = 1;
1064                 break;
1065         case Opt_nolease:
1066                 ctx->no_lease = 1;
1067                 break;
1068         case Opt_nosparse:
1069                 ctx->no_sparse = 1;
1070                 break;
1071         case Opt_nodelete:
1072                 ctx->nodelete = 1;
1073                 break;
1074         case Opt_multichannel:
1075                 if (result.negated) {
1076                         ctx->multichannel = false;
1077                         ctx->max_channels = 1;
1078                 } else {
1079                         ctx->multichannel = true;
1080                         /* if number of channels not specified, default to 2 */
1081                         if (ctx->max_channels < 2)
1082                                 ctx->max_channels = 2;
1083                 }
1084                 break;
1085         case Opt_uid:
1086                 ctx->linux_uid = result.uid;
1087                 ctx->uid_specified = true;
1088                 break;
1089         case Opt_cruid:
1090                 ctx->cred_uid = result.uid;
1091                 ctx->cruid_specified = true;
1092                 break;
1093         case Opt_backupuid:
1094                 ctx->backupuid = result.uid;
1095                 ctx->backupuid_specified = true;
1096                 break;
1097         case Opt_backupgid:
1098                 ctx->backupgid = result.gid;
1099                 ctx->backupgid_specified = true;
1100                 break;
1101         case Opt_gid:
1102                 ctx->linux_gid = result.gid;
1103                 ctx->gid_specified = true;
1104                 break;
1105         case Opt_port:
1106                 ctx->port = result.uint_32;
1107                 break;
1108         case Opt_file_mode:
1109                 ctx->file_mode = result.uint_32;
1110                 break;
1111         case Opt_dirmode:
1112                 ctx->dir_mode = result.uint_32;
1113                 break;
1114         case Opt_min_enc_offload:
1115                 ctx->min_offload = result.uint_32;
1116                 break;
1117         case Opt_retrans:
1118                 ctx->retrans = result.uint_32;
1119                 break;
1120         case Opt_blocksize:
1121                 /*
1122                  * inode blocksize realistically should never need to be
1123                  * less than 16K or greater than 16M and default is 1MB.
1124                  * Note that small inode block sizes (e.g. 64K) can lead
1125                  * to very poor performance of common tools like cp and scp
1126                  */
1127                 if ((result.uint_32 < CIFS_MAX_MSGSIZE) ||
1128                    (result.uint_32 > (4 * SMB3_DEFAULT_IOSIZE))) {
1129                         cifs_errorf(fc, "%s: Invalid blocksize\n",
1130                                 __func__);
1131                         goto cifs_parse_mount_err;
1132                 }
1133                 ctx->bsize = result.uint_32;
1134                 ctx->got_bsize = true;
1135                 break;
1136         case Opt_rasize:
1137                 /*
1138                  * readahead size realistically should never need to be
1139                  * less than 1M (CIFS_DEFAULT_IOSIZE) or greater than 32M
1140                  * (perhaps an exception should be considered in the
1141                  * for the case of a large number of channels
1142                  * when multichannel is negotiated) since that would lead
1143                  * to plenty of parallel I/O in flight to the server.
1144                  * Note that smaller read ahead sizes would
1145                  * hurt performance of common tools like cp and scp
1146                  * which often trigger sequential i/o with read ahead
1147                  */
1148                 if ((result.uint_32 > (8 * SMB3_DEFAULT_IOSIZE)) ||
1149                     (result.uint_32 < CIFS_DEFAULT_IOSIZE)) {
1150                         cifs_errorf(fc, "%s: Invalid rasize %d vs. %d\n",
1151                                 __func__, result.uint_32, SMB3_DEFAULT_IOSIZE);
1152                         goto cifs_parse_mount_err;
1153                 }
1154                 ctx->rasize = result.uint_32;
1155                 break;
1156         case Opt_rsize:
1157                 ctx->rsize = result.uint_32;
1158                 ctx->got_rsize = true;
1159                 break;
1160         case Opt_wsize:
1161                 ctx->wsize = result.uint_32;
1162                 ctx->got_wsize = true;
1163                 if (ctx->wsize % PAGE_SIZE != 0) {
1164                         ctx->wsize = round_down(ctx->wsize, PAGE_SIZE);
1165                         if (ctx->wsize == 0) {
1166                                 ctx->wsize = PAGE_SIZE;
1167                                 cifs_dbg(VFS, "wsize too small, reset to minimum %ld\n", PAGE_SIZE);
1168                         } else {
1169                                 cifs_dbg(VFS,
1170                                          "wsize rounded down to %d to multiple of PAGE_SIZE %ld\n",
1171                                          ctx->wsize, PAGE_SIZE);
1172                         }
1173                 }
1174                 break;
1175         case Opt_acregmax:
1176                 ctx->acregmax = HZ * result.uint_32;
1177                 if (ctx->acregmax > CIFS_MAX_ACTIMEO) {
1178                         cifs_errorf(fc, "acregmax too large\n");
1179                         goto cifs_parse_mount_err;
1180                 }
1181                 break;
1182         case Opt_acdirmax:
1183                 ctx->acdirmax = HZ * result.uint_32;
1184                 if (ctx->acdirmax > CIFS_MAX_ACTIMEO) {
1185                         cifs_errorf(fc, "acdirmax too large\n");
1186                         goto cifs_parse_mount_err;
1187                 }
1188                 break;
1189         case Opt_actimeo:
1190                 if (HZ * result.uint_32 > CIFS_MAX_ACTIMEO) {
1191                         cifs_errorf(fc, "timeout too large\n");
1192                         goto cifs_parse_mount_err;
1193                 }
1194                 if ((ctx->acdirmax != CIFS_DEF_ACTIMEO) ||
1195                     (ctx->acregmax != CIFS_DEF_ACTIMEO)) {
1196                         cifs_errorf(fc, "actimeo ignored since acregmax or acdirmax specified\n");
1197                         break;
1198                 }
1199                 ctx->acdirmax = ctx->acregmax = HZ * result.uint_32;
1200                 break;
1201         case Opt_closetimeo:
1202                 ctx->closetimeo = HZ * result.uint_32;
1203                 if (ctx->closetimeo > SMB3_MAX_DCLOSETIMEO) {
1204                         cifs_errorf(fc, "closetimeo too large\n");
1205                         goto cifs_parse_mount_err;
1206                 }
1207                 break;
1208         case Opt_echo_interval:
1209                 ctx->echo_interval = result.uint_32;
1210                 break;
1211         case Opt_snapshot:
1212                 ctx->snapshot_time = result.uint_64;
1213                 break;
1214         case Opt_max_credits:
1215                 if (result.uint_32 < 20 || result.uint_32 > 60000) {
1216                         cifs_errorf(fc, "%s: Invalid max_credits value\n",
1217                                  __func__);
1218                         goto cifs_parse_mount_err;
1219                 }
1220                 ctx->max_credits = result.uint_32;
1221                 break;
1222         case Opt_max_channels:
1223                 if (result.uint_32 < 1 || result.uint_32 > CIFS_MAX_CHANNELS) {
1224                         cifs_errorf(fc, "%s: Invalid max_channels value, needs to be 1-%d\n",
1225                                  __func__, CIFS_MAX_CHANNELS);
1226                         goto cifs_parse_mount_err;
1227                 }
1228                 ctx->max_channels = result.uint_32;
1229                 /* If more than one channel requested ... they want multichan */
1230                 if (result.uint_32 > 1)
1231                         ctx->multichannel = true;
1232                 break;
1233         case Opt_max_cached_dirs:
1234                 if (result.uint_32 < 1) {
1235                         cifs_errorf(fc, "%s: Invalid max_cached_dirs, needs to be 1 or more\n",
1236                                     __func__);
1237                         goto cifs_parse_mount_err;
1238                 }
1239                 ctx->max_cached_dirs = result.uint_32;
1240                 break;
1241         case Opt_handletimeout:
1242                 ctx->handle_timeout = result.uint_32;
1243                 if (ctx->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) {
1244                         cifs_errorf(fc, "Invalid handle cache timeout, longer than 16 minutes\n");
1245                         goto cifs_parse_mount_err;
1246                 }
1247                 break;
1248         case Opt_source:
1249                 kfree(ctx->UNC);
1250                 ctx->UNC = NULL;
1251                 switch (smb3_parse_devname(param->string, ctx)) {
1252                 case 0:
1253                         break;
1254                 case -ENOMEM:
1255                         cifs_errorf(fc, "Unable to allocate memory for devname\n");
1256                         goto cifs_parse_mount_err;
1257                 case -EINVAL:
1258                         cifs_errorf(fc, "Malformed UNC in devname\n");
1259                         goto cifs_parse_mount_err;
1260                 default:
1261                         cifs_errorf(fc, "Unknown error parsing devname\n");
1262                         goto cifs_parse_mount_err;
1263                 }
1264                 ctx->source = smb3_fs_context_fullpath(ctx, '/');
1265                 if (IS_ERR(ctx->source)) {
1266                         ctx->source = NULL;
1267                         cifs_errorf(fc, "OOM when copying UNC string\n");
1268                         goto cifs_parse_mount_err;
1269                 }
1270                 fc->source = kstrdup(ctx->source, GFP_KERNEL);
1271                 if (fc->source == NULL) {
1272                         cifs_errorf(fc, "OOM when copying UNC string\n");
1273                         goto cifs_parse_mount_err;
1274                 }
1275                 break;
1276         case Opt_user:
1277                 kfree(ctx->username);
1278                 ctx->username = NULL;
1279                 if (ctx->nullauth)
1280                         break;
1281                 if (strlen(param->string) == 0) {
1282                         /* null user, ie. anonymous authentication */
1283                         ctx->nullauth = 1;
1284                         break;
1285                 }
1286 
1287                 if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) >
1288                     CIFS_MAX_USERNAME_LEN) {
1289                         pr_warn("username too long\n");
1290                         goto cifs_parse_mount_err;
1291                 }
1292                 ctx->username = kstrdup(param->string, GFP_KERNEL);
1293                 if (ctx->username == NULL) {
1294                         cifs_errorf(fc, "OOM when copying username string\n");
1295                         goto cifs_parse_mount_err;
1296                 }
1297                 break;
1298         case Opt_pass:
1299                 kfree_sensitive(ctx->password);
1300                 ctx->password = NULL;
1301                 if (strlen(param->string) == 0)
1302                         break;
1303 
1304                 ctx->password = kstrdup(param->string, GFP_KERNEL);
1305                 if (ctx->password == NULL) {
1306                         cifs_errorf(fc, "OOM when copying password string\n");
1307                         goto cifs_parse_mount_err;
1308                 }
1309                 break;
1310         case Opt_pass2:
1311                 kfree_sensitive(ctx->password2);
1312                 ctx->password2 = NULL;
1313                 if (strlen(param->string) == 0)
1314                         break;
1315 
1316                 ctx->password2 = kstrdup(param->string, GFP_KERNEL);
1317                 if (ctx->password2 == NULL) {
1318                         cifs_errorf(fc, "OOM when copying password2 string\n");
1319                         goto cifs_parse_mount_err;
1320                 }
1321                 break;
1322         case Opt_ip:
1323                 if (strlen(param->string) == 0) {
1324                         ctx->got_ip = false;
1325                         break;
1326                 }
1327                 if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr,
1328                                           param->string,
1329                                           strlen(param->string))) {
1330                         pr_err("bad ip= option (%s)\n", param->string);
1331                         goto cifs_parse_mount_err;
1332                 }
1333                 ctx->got_ip = true;
1334                 break;
1335         case Opt_domain:
1336                 if (strnlen(param->string, CIFS_MAX_DOMAINNAME_LEN)
1337                                 == CIFS_MAX_DOMAINNAME_LEN) {
1338                         pr_warn("domain name too long\n");
1339                         goto cifs_parse_mount_err;
1340                 }
1341 
1342                 kfree(ctx->domainname);
1343                 ctx->domainname = kstrdup(param->string, GFP_KERNEL);
1344                 if (ctx->domainname == NULL) {
1345                         cifs_errorf(fc, "OOM when copying domainname string\n");
1346                         goto cifs_parse_mount_err;
1347                 }
1348                 cifs_dbg(FYI, "Domain name set\n");
1349                 break;
1350         case Opt_srcaddr:
1351                 if (!cifs_convert_address(
1352                                 (struct sockaddr *)&ctx->srcaddr,
1353                                 param->string, strlen(param->string))) {
1354                         pr_warn("Could not parse srcaddr: %s\n",
1355                                 param->string);
1356                         goto cifs_parse_mount_err;
1357                 }
1358                 break;
1359         case Opt_iocharset:
1360                 if (strnlen(param->string, 1024) >= 65) {
1361                         pr_warn("iocharset name too long\n");
1362                         goto cifs_parse_mount_err;
1363                 }
1364 
1365                 if (strncasecmp(param->string, "default", 7) != 0) {
1366                         kfree(ctx->iocharset);
1367                         ctx->iocharset = kstrdup(param->string, GFP_KERNEL);
1368                         if (ctx->iocharset == NULL) {
1369                                 cifs_errorf(fc, "OOM when copying iocharset string\n");
1370                                 goto cifs_parse_mount_err;
1371                         }
1372                 }
1373                 /* if iocharset not set then load_nls_default
1374                  * is used by caller
1375                  */
1376                 cifs_dbg(FYI, "iocharset set to %s\n", ctx->iocharset);
1377                 break;
1378         case Opt_netbiosname:
1379                 memset(ctx->source_rfc1001_name, 0x20,
1380                         RFC1001_NAME_LEN);
1381                 /*
1382                  * FIXME: are there cases in which a comma can
1383                  * be valid in workstation netbios name (and
1384                  * need special handling)?
1385                  */
1386                 for (i = 0; i < RFC1001_NAME_LEN; i++) {
1387                         /* don't ucase netbiosname for user */
1388                         if (param->string[i] == 0)
1389                                 break;
1390                         ctx->source_rfc1001_name[i] = param->string[i];
1391                 }
1392                 /* The string has 16th byte zero still from
1393                  * set at top of the function
1394                  */
1395                 if (i == RFC1001_NAME_LEN && param->string[i] != 0)
1396                         pr_warn("netbiosname longer than 15 truncated\n");
1397                 break;
1398         case Opt_servern:
1399                 /* last byte, type, is 0x20 for servr type */
1400                 memset(ctx->target_rfc1001_name, 0x20,
1401                         RFC1001_NAME_LEN_WITH_NULL);
1402                 /*
1403                  * BB are there cases in which a comma can be valid in this
1404                  * workstation netbios name (and need special handling)?
1405                  */
1406 
1407                 /* user or mount helper must uppercase the netbios name */
1408                 for (i = 0; i < 15; i++) {
1409                         if (param->string[i] == 0)
1410                                 break;
1411                         ctx->target_rfc1001_name[i] = param->string[i];
1412                 }
1413 
1414                 /* The string has 16th byte zero still from set at top of function */
1415                 if (i == RFC1001_NAME_LEN && param->string[i] != 0)
1416                         pr_warn("server netbiosname longer than 15 truncated\n");
1417                 break;
1418         case Opt_ver:
1419                 /* version of mount userspace tools, not dialect */
1420                 /* If interface changes in mount.cifs bump to new ver */
1421                 if (strncasecmp(param->string, "1", 1) == 0) {
1422                         if (strlen(param->string) > 1) {
1423                                 pr_warn("Bad mount helper ver=%s. Did you want SMB1 (CIFS) dialect and mean to type vers=1.0 instead?\n",
1424                                         param->string);
1425                                 goto cifs_parse_mount_err;
1426                         }
1427                         /* This is the default */
1428                         break;
1429                 }
1430                 /* For all other value, error */
1431                 pr_warn("Invalid mount helper version specified\n");
1432                 goto cifs_parse_mount_err;
1433         case Opt_vers:
1434                 /* protocol version (dialect) */
1435                 if (cifs_parse_smb_version(fc, param->string, ctx, is_smb3) != 0)
1436                         goto cifs_parse_mount_err;
1437                 ctx->got_version = true;
1438                 break;
1439         case Opt_sec:
1440                 if (cifs_parse_security_flavors(fc, param->string, ctx) != 0)
1441                         goto cifs_parse_mount_err;
1442                 break;
1443         case Opt_cache:
1444                 if (cifs_parse_cache_flavor(fc, param->string, ctx) != 0)
1445                         goto cifs_parse_mount_err;
1446                 break;
1447         case Opt_witness:
1448 #ifndef CONFIG_CIFS_SWN_UPCALL
1449                 cifs_errorf(fc, "Witness support needs CONFIG_CIFS_SWN_UPCALL config option\n");
1450                         goto cifs_parse_mount_err;
1451 #endif
1452                 ctx->witness = true;
1453                 pr_warn_once("Witness protocol support is experimental\n");
1454                 break;
1455         case Opt_rootfs:
1456 #ifndef CONFIG_CIFS_ROOT
1457                 cifs_dbg(VFS, "rootfs support requires CONFIG_CIFS_ROOT config option\n");
1458                 goto cifs_parse_mount_err;
1459 #endif
1460                 ctx->rootfs = true;
1461                 break;
1462         case Opt_posixpaths:
1463                 if (result.negated)
1464                         ctx->posix_paths = 0;
1465                 else
1466                         ctx->posix_paths = 1;
1467                 break;
1468         case Opt_unix:
1469                 if (result.negated) {
1470                         if (ctx->linux_ext == 1)
1471                                 pr_warn_once("conflicting posix mount options specified\n");
1472                         ctx->linux_ext = 0;
1473                         ctx->no_linux_ext = 1;
1474                 } else {
1475                         if (ctx->no_linux_ext == 1)
1476                                 pr_warn_once("conflicting posix mount options specified\n");
1477                         ctx->linux_ext = 1;
1478                         ctx->no_linux_ext = 0;
1479                 }
1480                 break;
1481         case Opt_nocase:
1482                 ctx->nocase = 1;
1483                 break;
1484         case Opt_brl:
1485                 if (result.negated) {
1486                         /*
1487                          * turn off mandatory locking in mode
1488                          * if remote locking is turned off since the
1489                          * local vfs will do advisory
1490                          */
1491                         if (ctx->file_mode ==
1492                                 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1493                                 ctx->file_mode = S_IALLUGO;
1494                         ctx->nobrl =  1;
1495                 } else
1496                         ctx->nobrl =  0;
1497                 break;
1498         case Opt_handlecache:
1499                 if (result.negated)
1500                         ctx->nohandlecache = 1;
1501                 else
1502                         ctx->nohandlecache = 0;
1503                 break;
1504         case Opt_forcemandatorylock:
1505                 ctx->mand_lock = 1;
1506                 break;
1507         case Opt_setuids:
1508                 ctx->setuids = result.negated;
1509                 break;
1510         case Opt_intr:
1511                 ctx->intr = !result.negated;
1512                 break;
1513         case Opt_setuidfromacl:
1514                 ctx->setuidfromacl = 1;
1515                 break;
1516         case Opt_strictsync:
1517                 ctx->nostrictsync = result.negated;
1518                 break;
1519         case Opt_serverino:
1520                 ctx->server_ino = !result.negated;
1521                 break;
1522         case Opt_rwpidforward:
1523                 ctx->rwpidforward = 1;
1524                 break;
1525         case Opt_modesid:
1526                 ctx->mode_ace = 1;
1527                 break;
1528         case Opt_cifsacl:
1529                 ctx->cifs_acl = !result.negated;
1530                 break;
1531         case Opt_acl:
1532                 ctx->no_psx_acl = result.negated;
1533                 break;
1534         case Opt_locallease:
1535                 ctx->local_lease = 1;
1536                 break;
1537         case Opt_sign:
1538                 ctx->sign = true;
1539                 break;
1540         case Opt_ignore_signature:
1541                 ctx->sign = true;
1542                 ctx->ignore_signature = true;
1543                 break;
1544         case Opt_seal:
1545                 /* we do not do the following in secFlags because seal
1546                  * is a per tree connection (mount) not a per socket
1547                  * or per-smb connection option in the protocol
1548                  * vol->secFlg |= CIFSSEC_MUST_SEAL;
1549                  */
1550                 ctx->seal = 1;
1551                 break;
1552         case Opt_noac:
1553                 pr_warn("Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
1554                 break;
1555         case Opt_fsc:
1556 #ifndef CONFIG_CIFS_FSCACHE
1557                 cifs_errorf(fc, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n");
1558                 goto cifs_parse_mount_err;
1559 #endif
1560                 ctx->fsc = true;
1561                 break;
1562         case Opt_mfsymlinks:
1563                 ctx->mfsymlinks = true;
1564                 break;
1565         case Opt_multiuser:
1566                 ctx->multiuser = true;
1567                 break;
1568         case Opt_sloppy:
1569                 ctx->sloppy = true;
1570                 break;
1571         case Opt_nosharesock:
1572                 ctx->nosharesock = true;
1573                 break;
1574         case Opt_persistent:
1575                 if (result.negated) {
1576                         ctx->nopersistent = true;
1577                         if (ctx->persistent) {
1578                                 cifs_errorf(fc, "persistenthandles mount options conflict\n");
1579                                 goto cifs_parse_mount_err;
1580                         }
1581                 } else {
1582                         ctx->persistent = true;
1583                         if ((ctx->nopersistent) || (ctx->resilient)) {
1584                                 cifs_errorf(fc, "persistenthandles mount options conflict\n");
1585                                 goto cifs_parse_mount_err;
1586                         }
1587                 }
1588                 break;
1589         case Opt_resilient:
1590                 if (result.negated) {
1591                         ctx->resilient = false; /* already the default */
1592                 } else {
1593                         ctx->resilient = true;
1594                         if (ctx->persistent) {
1595                                 cifs_errorf(fc, "persistenthandles mount options conflict\n");
1596                                 goto cifs_parse_mount_err;
1597                         }
1598                 }
1599                 break;
1600         case Opt_tcp_nodelay:
1601                 /* tcp nodelay should not usually be needed since we CORK/UNCORK the socket */
1602                 if (result.negated)
1603                         ctx->sockopt_tcp_nodelay = false;
1604                 else
1605                         ctx->sockopt_tcp_nodelay = true;
1606                 break;
1607         case Opt_domainauto:
1608                 ctx->domainauto = true;
1609                 break;
1610         case Opt_rdma:
1611                 ctx->rdma = true;
1612                 break;
1613         case Opt_reparse:
1614                 if (parse_reparse_flavor(fc, param->string, ctx))
1615                         goto cifs_parse_mount_err;
1616                 break;
1617         }
1618         /* case Opt_ignore: - is ignored as expected ... */
1619 
1620         return 0;
1621 
1622  cifs_parse_mount_err:
1623         kfree_sensitive(ctx->password);
1624         ctx->password = NULL;
1625         kfree_sensitive(ctx->password2);
1626         ctx->password2 = NULL;
1627         return -EINVAL;
1628 }
1629 
1630 int smb3_init_fs_context(struct fs_context *fc)
1631 {
1632         struct smb3_fs_context *ctx;
1633         char *nodename = utsname()->nodename;
1634         int i;
1635 
1636         ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL);
1637         if (unlikely(!ctx))
1638                 return -ENOMEM;
1639 
1640         strscpy(ctx->workstation_name, nodename, sizeof(ctx->workstation_name));
1641 
1642         /*
1643          * does not have to be perfect mapping since field is
1644          * informational, only used for servers that do not support
1645          * port 445 and it can be overridden at mount time
1646          */
1647         memset(ctx->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
1648         for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
1649                 ctx->source_rfc1001_name[i] = toupper(nodename[i]);
1650 
1651         ctx->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
1652         /*
1653          * null target name indicates to use *SMBSERVR default called name
1654          *  if we end up sending RFC1001 session initialize
1655          */
1656         ctx->target_rfc1001_name[0] = 0;
1657         ctx->cred_uid = current_uid();
1658         ctx->linux_uid = current_uid();
1659         ctx->linux_gid = current_gid();
1660         /* By default 4MB read ahead size, 1MB block size */
1661         ctx->bsize = CIFS_DEFAULT_IOSIZE; /* can improve cp performance significantly */
1662         ctx->rasize = 0; /* 0 = use default (ie negotiated rsize) for read ahead pages */
1663 
1664         /*
1665          * default to SFM style remapping of seven reserved characters
1666          * unless user overrides it or we negotiate CIFS POSIX where
1667          * it is unnecessary.  Can not simultaneously use more than one mapping
1668          * since then readdir could list files that open could not open
1669          */
1670         ctx->remap = true;
1671 
1672         /* default to only allowing write access to owner of the mount */
1673         ctx->dir_mode = ctx->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
1674 
1675         /* ctx->retry default is 0 (i.e. "soft" limited retry not hard retry) */
1676         /* default is always to request posix paths. */
1677         ctx->posix_paths = 1;
1678         /* default to using server inode numbers where available */
1679         ctx->server_ino = 1;
1680 
1681         /* default is to use strict cifs caching semantics */
1682         ctx->strict_io = true;
1683 
1684         ctx->acregmax = CIFS_DEF_ACTIMEO;
1685         ctx->acdirmax = CIFS_DEF_ACTIMEO;
1686         ctx->closetimeo = SMB3_DEF_DCLOSETIMEO;
1687         ctx->max_cached_dirs = MAX_CACHED_FIDS;
1688         /* Most clients set timeout to 0, allows server to use its default */
1689         ctx->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */
1690 
1691         /* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */
1692         ctx->ops = &smb30_operations;
1693         ctx->vals = &smbdefault_values;
1694 
1695         ctx->echo_interval = SMB_ECHO_INTERVAL_DEFAULT;
1696 
1697         /* default to no multichannel (single server connection) */
1698         ctx->multichannel = false;
1699         ctx->max_channels = 1;
1700 
1701         ctx->backupuid_specified = false; /* no backup intent for a user */
1702         ctx->backupgid_specified = false; /* no backup intent for a group */
1703 
1704         ctx->retrans = 1;
1705         ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT;
1706 
1707 /*
1708  *      short int override_uid = -1;
1709  *      short int override_gid = -1;
1710  *      char *nodename = strdup(utsname()->nodename);
1711  *      struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
1712  */
1713 
1714         fc->fs_private = ctx;
1715         fc->ops = &smb3_fs_context_ops;
1716         return 0;
1717 }
1718 
1719 void
1720 smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx)
1721 {
1722         if (ctx == NULL)
1723                 return;
1724 
1725         /*
1726          * Make sure this stays in sync with smb3_fs_context_dup()
1727          */
1728         kfree(ctx->username);
1729         ctx->username = NULL;
1730         kfree_sensitive(ctx->password);
1731         ctx->password = NULL;
1732         kfree_sensitive(ctx->password2);
1733         ctx->password2 = NULL;
1734         kfree(ctx->server_hostname);
1735         ctx->server_hostname = NULL;
1736         kfree(ctx->UNC);
1737         ctx->UNC = NULL;
1738         kfree(ctx->source);
1739         ctx->source = NULL;
1740         kfree(ctx->domainname);
1741         ctx->domainname = NULL;
1742         kfree(ctx->nodename);
1743         ctx->nodename = NULL;
1744         kfree(ctx->iocharset);
1745         ctx->iocharset = NULL;
1746         kfree(ctx->prepath);
1747         ctx->prepath = NULL;
1748         kfree(ctx->leaf_fullpath);
1749         ctx->leaf_fullpath = NULL;
1750 }
1751 
1752 void
1753 smb3_cleanup_fs_context(struct smb3_fs_context *ctx)
1754 {
1755         if (!ctx)
1756                 return;
1757         smb3_cleanup_fs_context_contents(ctx);
1758         kfree(ctx);
1759 }
1760 
1761 void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb)
1762 {
1763         struct smb3_fs_context *ctx = cifs_sb->ctx;
1764 
1765         if (ctx->nodfs)
1766                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
1767         else
1768                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_DFS;
1769 
1770         if (ctx->noperm)
1771                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1772         else
1773                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_PERM;
1774 
1775         if (ctx->setuids)
1776                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1777         else
1778                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SET_UID;
1779 
1780         if (ctx->setuidfromacl)
1781                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL;
1782         else
1783                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UID_FROM_ACL;
1784 
1785         if (ctx->server_ino)
1786                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1787         else
1788                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
1789 
1790         if (ctx->remap)
1791                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
1792         else
1793                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SFM_CHR;
1794 
1795         if (ctx->sfu_remap)
1796                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1797         else
1798                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SPECIAL_CHR;
1799 
1800         if (ctx->no_xattr)
1801                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1802         else
1803                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_XATTR;
1804 
1805         if (ctx->sfu_emul)
1806                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1807         else
1808                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UNX_EMUL;
1809 
1810         if (ctx->nobrl)
1811                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1812         else
1813                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_BRL;
1814 
1815         if (ctx->nohandlecache)
1816                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE;
1817         else
1818                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_HANDLE_CACHE;
1819 
1820         if (ctx->nostrictsync)
1821                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
1822         else
1823                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOSSYNC;
1824 
1825         if (ctx->mand_lock)
1826                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
1827         else
1828                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOPOSIXBRL;
1829 
1830         if (ctx->rwpidforward)
1831                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
1832         else
1833                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_RWPIDFORWARD;
1834 
1835         if (ctx->mode_ace)
1836                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID;
1837         else
1838                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MODE_FROM_SID;
1839 
1840         if (ctx->cifs_acl)
1841                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1842         else
1843                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_ACL;
1844 
1845         if (ctx->backupuid_specified)
1846                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
1847         else
1848                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPUID;
1849 
1850         if (ctx->backupgid_specified)
1851                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
1852         else
1853                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPGID;
1854 
1855         if (ctx->override_uid)
1856                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
1857         else
1858                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_UID;
1859 
1860         if (ctx->override_gid)
1861                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
1862         else
1863                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_GID;
1864 
1865         if (ctx->dynperm)
1866                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
1867         else
1868                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DYNPERM;
1869 
1870         if (ctx->fsc)
1871                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
1872         else
1873                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_FSCACHE;
1874 
1875         if (ctx->multiuser)
1876                 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
1877                                             CIFS_MOUNT_NO_PERM);
1878         else
1879                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MULTIUSER;
1880 
1881 
1882         if (ctx->strict_io)
1883                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
1884         else
1885                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_STRICT_IO;
1886 
1887         if (ctx->direct_io)
1888                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1889         else
1890                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DIRECT_IO;
1891 
1892         if (ctx->mfsymlinks)
1893                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
1894         else
1895                 cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MF_SYMLINKS;
1896         if (ctx->mfsymlinks) {
1897                 if (ctx->sfu_emul) {
1898                         /*
1899                          * Our SFU ("Services for Unix" emulation does not allow
1900                          * creating symlinks but does allow reading existing SFU
1901                          * symlinks (it does allow both creating and reading SFU
1902                          * style mknod and FIFOs though). When "mfsymlinks" and
1903                          * "sfu" are both enabled at the same time, it allows
1904                          * reading both types of symlinks, but will only create
1905                          * them with mfsymlinks format. This allows better
1906                          * Apple compatibility (probably better for Samba too)
1907                          * while still recognizing old Windows style symlinks.
1908                          */
1909                         cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
1910                 }
1911         }
1912         cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SHUTDOWN;
1913 
1914         return;
1915 }
1916 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php