NFSv4.1: try SECINFO_NO_NAME flavs until one works

Call nfs4_lookup_root_sec for each flavor returned by SECINFO_NO_NAME until
one works.

One example of a situation this fixes:

 - server configured for krb5
 - server principal somehow gets deleted from KDC
 - server still thinking krb is good, sends krb5 as first entry in
    SECINFO_NO_NAME response
 - client tries krb5, but this fails without even sending an RPC because
    gssd's requests to the KDC can't find the server's principal

Signed-off-by: Weston Andros Adamson <dros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Weston Andros Adamson 2013-09-24 13:58:02 -04:00 committed by Trond Myklebust
parent acd65e5bc1
commit 58a8cf1212
1 changed files with 27 additions and 3 deletions

View File

@ -7578,6 +7578,8 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
struct page *page; struct page *page;
rpc_authflavor_t flavor; rpc_authflavor_t flavor;
struct nfs4_secinfo_flavors *flavors; struct nfs4_secinfo_flavors *flavors;
struct nfs4_secinfo4 *secinfo;
int i;
page = alloc_page(GFP_KERNEL); page = alloc_page(GFP_KERNEL);
if (!page) { if (!page) {
@ -7599,9 +7601,31 @@ nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
if (err) if (err)
goto out_freepage; goto out_freepage;
flavor = nfs_find_best_sec(flavors); for (i = 0; i < flavors->num_flavors; i++) {
if (err == 0) secinfo = &flavors->flavors[i];
err = nfs4_lookup_root_sec(server, fhandle, info, flavor);
switch (secinfo->flavor) {
case RPC_AUTH_NULL:
case RPC_AUTH_UNIX:
case RPC_AUTH_GSS:
flavor = rpcauth_get_pseudoflavor(secinfo->flavor,
&secinfo->flavor_info);
break;
default:
flavor = RPC_AUTH_MAXFLAVOR;
break;
}
if (flavor != RPC_AUTH_MAXFLAVOR) {
err = nfs4_lookup_root_sec(server, fhandle,
info, flavor);
if (!err)
break;
}
}
if (flavor == RPC_AUTH_MAXFLAVOR)
err = -EPERM;
out_freepage: out_freepage:
put_page(page); put_page(page);