NFSv3: match sec= flavor against server list
Older linux clients match the 'sec=' mount option flavor against the server's flavor list (if available) and return EPERM if the specified flavor or AUTH_NULL (which "matches" any flavor) is not found. Recent changes skip this step and allow the vfs mount even though no operations will succeed, creating a 'dud' mount. This patch reverts back to the old behavior of matching specified flavors against the server list and also returns EPERM when no sec= is specified and none of the flavors returned by the server are supported by the client. Example of behavior change: the server's /etc/exports: /export/krb5 *(sec=krb5,rw,no_root_squash) old client behavior: $ uname -a Linux one.apikia.fake 3.8.8-202.fc18.x86_64 #1 SMP Wed Apr 17 23:25:17 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux $ sudo mount -v -o sec=sys,vers=3 zero:/export/krb5 /mnt mount.nfs: timeout set for Sun May 5 17:32:04 2013 mount.nfs: trying text-based options 'sec=sys,vers=3,addr=192.168.100.10' mount.nfs: prog 100003, trying vers=3, prot=6 mount.nfs: trying 192.168.100.10 prog 100003 vers 3 prot TCP port 2049 mount.nfs: prog 100005, trying vers=3, prot=17 mount.nfs: trying 192.168.100.10 prog 100005 vers 3 prot UDP port 20048 mount.nfs: mount(2): Permission denied mount.nfs: access denied by server while mounting zero:/export/krb5 recently changed behavior: $ uname -a Linux one.apikia.fake 3.9.0-testing+ #2 SMP Fri May 3 20:29:32 EDT 2013 x86_64 x86_64 x86_64 GNU/Linux $ sudo mount -v -o sec=sys,vers=3 zero:/export/krb5 /mnt mount.nfs: timeout set for Sun May 5 17:37:17 2013 mount.nfs: trying text-based options 'sec=sys,vers=3,addr=192.168.100.10' mount.nfs: prog 100003, trying vers=3, prot=6 mount.nfs: trying 192.168.100.10 prog 100003 vers 3 prot TCP port 2049 mount.nfs: prog 100005, trying vers=3, prot=17 mount.nfs: trying 192.168.100.10 prog 100005 vers 3 prot UDP port 20048 $ ls /mnt ls: cannot open directory /mnt: Permission denied $ sudo ls /mnt ls: cannot open directory /mnt: Permission denied $ sudo df /mnt df: ‘/mnt’: Permission denied df: no file systems processed $ sudo umount /mnt $ Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
c8b2d0bfd3
commit
d497ab9751
|
@ -1607,16 +1607,15 @@ static int nfs_parse_mount_options(char *raw,
|
||||||
/*
|
/*
|
||||||
* Select a security flavor for this mount. The selected flavor
|
* Select a security flavor for this mount. The selected flavor
|
||||||
* is planted in args->auth_flavors[0].
|
* is planted in args->auth_flavors[0].
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -EACCES on failure.
|
||||||
*/
|
*/
|
||||||
static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
|
static int nfs_select_flavor(struct nfs_parsed_mount_data *args,
|
||||||
struct nfs_mount_request *request)
|
struct nfs_mount_request *request)
|
||||||
{
|
{
|
||||||
unsigned int i, count = *(request->auth_flav_len);
|
unsigned int i, count = *(request->auth_flav_len);
|
||||||
rpc_authflavor_t flavor;
|
rpc_authflavor_t flavor;
|
||||||
|
|
||||||
if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The NFSv2 MNT operation does not return a flavor list.
|
* The NFSv2 MNT operation does not return a flavor list.
|
||||||
*/
|
*/
|
||||||
|
@ -1630,6 +1629,25 @@ static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
goto out_default;
|
goto out_default;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the sec= mount option is used, the specified flavor or AUTH_NULL
|
||||||
|
* must be in the list returned by the server.
|
||||||
|
*
|
||||||
|
* AUTH_NULL has a special meaning when it's in the server list - it
|
||||||
|
* means that the server will ignore the rpc creds, so any flavor
|
||||||
|
* can be used.
|
||||||
|
*/
|
||||||
|
if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) {
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (args->auth_flavors[0] == request->auth_flavs[i] ||
|
||||||
|
request->auth_flavs[i] == RPC_AUTH_NULL)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
dfprintk(MOUNT, "NFS: auth flavor %d not supported by server\n",
|
||||||
|
args->auth_flavors[0]);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RFC 2623, section 2.7 suggests we SHOULD prefer the
|
* RFC 2623, section 2.7 suggests we SHOULD prefer the
|
||||||
* flavor listed first. However, some servers list
|
* flavor listed first. However, some servers list
|
||||||
|
@ -1650,12 +1668,29 @@ static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As a last chance, see if the server list contains AUTH_NULL -
|
||||||
|
* if it does, use the default flavor.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (request->auth_flavs[i] == RPC_AUTH_NULL)
|
||||||
|
goto out_default;
|
||||||
|
}
|
||||||
|
|
||||||
|
dfprintk(MOUNT, "NFS: no auth flavors in common with server\n");
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
out_default:
|
out_default:
|
||||||
flavor = RPC_AUTH_UNIX;
|
/* use default if flavor not already set */
|
||||||
|
flavor = (args->auth_flavors[0] == RPC_AUTH_MAXFLAVOR) ?
|
||||||
|
RPC_AUTH_UNIX : args->auth_flavors[0];
|
||||||
out_set:
|
out_set:
|
||||||
args->auth_flavors[0] = flavor;
|
args->auth_flavors[0] = flavor;
|
||||||
out:
|
out:
|
||||||
dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]);
|
dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]);
|
||||||
|
return 0;
|
||||||
|
out_err:
|
||||||
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1718,8 +1753,7 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfs_select_flavor(args, &request);
|
return nfs_select_flavor(args, &request);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dentry *nfs_try_mount(int flags, const char *dev_name,
|
struct dentry *nfs_try_mount(int flags, const char *dev_name,
|
||||||
|
|
Loading…
Reference in New Issue