NFS: add support for multiple sec= mount options
This patch adds support for multiple security options which can be specified using a colon-delimited list of security flavors (the same syntax as nfsd's exports file). This is useful, for instance, when NFSv4.x mounts cross SECINFO boundaries. With this patch a user can use "sec=krb5i,krb5p" to mount a remote filesystem using krb5i, but can still cross into krb5p-only exports. New mounts will try all security options before failing. NFSv4.x SECINFO results will be compared against the sec= flavors to find the first flavor in both lists or if no match is found will return -EPERM. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:

committed by
Trond Myklebust

parent
5837f6dfcb
commit
4d4b69dd84
@@ -2873,11 +2873,24 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
int status = -EPERM;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(flav_array); i++) {
|
||||
status = nfs4_lookup_root_sec(server, fhandle, info, flav_array[i]);
|
||||
if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
|
||||
continue;
|
||||
break;
|
||||
if (server->auth_info.flavor_len > 0) {
|
||||
/* try each flavor specified by user */
|
||||
for (i = 0; i < server->auth_info.flavor_len; i++) {
|
||||
status = nfs4_lookup_root_sec(server, fhandle, info,
|
||||
server->auth_info.flavors[i]);
|
||||
if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* no flavors specified by user, try default list */
|
||||
for (i = 0; i < ARRAY_SIZE(flav_array); i++) {
|
||||
status = nfs4_lookup_root_sec(server, fhandle, info,
|
||||
flav_array[i]);
|
||||
if (status == -NFS4ERR_WRONGSEC || status == -EACCES)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2919,9 +2932,6 @@ int nfs4_proc_get_rootfh(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
status = nfs4_lookup_root(server, fhandle, info);
|
||||
if (status != -NFS4ERR_WRONGSEC)
|
||||
break;
|
||||
/* Did user force a 'sec=' mount option? */
|
||||
if (server->auth_info.flavor_len > 0)
|
||||
break;
|
||||
default:
|
||||
status = nfs4_do_find_root_sec(server, fhandle, info);
|
||||
}
|
||||
@@ -3179,9 +3189,6 @@ static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
|
||||
err = -EPERM;
|
||||
if (client != *clnt)
|
||||
goto out;
|
||||
/* No security negotiation if the user specified 'sec=' */
|
||||
if (NFS_SERVER(dir)->auth_info.flavor_len > 0)
|
||||
goto out;
|
||||
client = nfs4_create_sec_client(client, dir, name);
|
||||
if (IS_ERR(client))
|
||||
return PTR_ERR(client);
|
||||
@@ -7942,6 +7949,9 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nfs_auth_info_match(&server->auth_info, flavor))
|
||||
flavor = RPC_AUTH_MAXFLAVOR;
|
||||
|
||||
if (flavor != RPC_AUTH_MAXFLAVOR) {
|
||||
err = nfs4_lookup_root_sec(server, fhandle,
|
||||
info, flavor);
|
||||
|
Reference in New Issue
Block a user