From: Chuck Lever <chuck.lever@oracle.com>
To: linux-nfs@vger.kernel.org
Subject: [PATCH 3/3] NFS: Use root's credential for lease management when keytab is missing
Date: Fri, 07 Jun 2013 15:45:10 -0400 [thread overview]
Message-ID: <20130607194510.1296.69923.stgit@seurat.1015granger.net> (raw)
In-Reply-To: <20130607194140.1296.54746.stgit@seurat.1015granger.net>
Commit 05f4c350 "NFS: Discover NFSv4 server trunking when mounting"
Fri Sep 14 17:24:32 2012 introduced Uniform Client String support,
which forces our NFS client to establish a client ID immediately
during a mount operation rather than waiting until a user wants to
open a file.
Normally machine credentials (eg. from a keytab) are used to perform
a mount operation that is protected by Kerberos. Before 05fc350,
SETCLIENTID used a machine credential, or fell back to a regular
user's credential if no keytab is available.
On clients that don't have a keytab, performing SETCLIENTID early
means there's no user credential to fall back on, since no regular
user has kinit'd yet. 05f4c350 seems to have broken the ability
to mount with sec=krb5 on clients that don't have a keytab in
kernels 3.7 - 3.9.
To address this regression, commit 4edaa308 (NFS: Use "krb5i" to
establish NFSv4 state whenever possible), Sat Mar 16 15:56:20 2013,
was merged in 3.10. This commit forces the NFS client to fall back
to AUTH_SYS for lease management operations if no keytab is
available.
Neil Brown noticed that, since root is required to kinit to do a
sec=krb5 mount when a client doesn't have a keytab, we can try to
use root's Kerberos credential before AUTH_SYS.
Now, when determining a principal and flavor to use for lease
management, the NFS client tries in this order:
1. Flavor: AUTH_GSS, krb5i
Principal: service principal (via keytab)
2. Flavor: AUTH_GSS, krb5i
Principal: user principal established for UID 0 (via kinit)
3. Flavor: AUTH_SYS
Principal: UID 0 / GID 0
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfs/nfs4proc.c | 21 ++++++++++++++-------
fs/nfs/nfs4state.c | 16 ++++++++--------
2 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 5ba38b3..4d76fae 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4356,7 +4356,8 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
dprintk("NFS call setclientid auth=%s, '%.*s'\n",
clp->cl_rpcclient->cl_auth->au_ops->au_name,
setclientid.sc_name_len, setclientid.sc_name);
- status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+ status = rpc_call_sync(clp->cl_rpcclient, &msg,
+ RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
dprintk("NFS reply setclientid: %d\n", status);
return status;
}
@@ -4383,7 +4384,8 @@ int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
dprintk("NFS call setclientid_confirm auth=%s, (client ID %llx)\n",
clp->cl_rpcclient->cl_auth->au_ops->au_name,
clp->cl_clientid);
- status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+ status = rpc_call_sync(clp->cl_rpcclient, &msg,
+ RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
dprintk("NFS reply setclientid_confirm: %d\n", status);
return status;
}
@@ -5461,7 +5463,8 @@ int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred
goto out;
}
- status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+ status = rpc_call_sync(clp->cl_rpcclient, &msg,
+ RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
if (status == 0) {
if (memcmp(res.session->sess_id.data,
clp->cl_session->sess_id.data, NFS4_MAX_SESSIONID_LEN)) {
@@ -5545,7 +5548,8 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
goto out_server_scope;
}
- status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+ status = rpc_call_sync(clp->cl_rpcclient, &msg,
+ RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
if (status == 0)
status = nfs4_check_cl_exchange_flags(res.flags);
@@ -5605,7 +5609,8 @@ static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
};
int status;
- status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+ status = rpc_call_sync(clp->cl_rpcclient, &msg,
+ RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
if (status)
dprintk("NFS: Got error %d from the server %s on "
"DESTROY_CLIENTID.", status, clp->cl_hostname);
@@ -5871,7 +5876,8 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
nfs4_init_channel_attrs(&args);
args.flags = (SESSION4_PERSIST | SESSION4_BACK_CHAN);
- status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+ status = rpc_call_sync(session->clp->cl_rpcclient, &msg,
+ RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
if (!status) {
/* Verify the session's negotiated channel_attrs values */
@@ -5934,7 +5940,8 @@ int nfs4_proc_destroy_session(struct nfs4_session *session,
if (session->clp->cl_cons_state != NFS_CS_READY)
return status;
- status = rpc_call_sync(session->clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
+ status = rpc_call_sync(session->clp->cl_rpcclient, &msg,
+ RPC_TASK_TIMEOUT|RPC_TASK_ROOTCREDS);
if (status)
dprintk("NFS: Got error %d from the server on DESTROY_SESSION. "
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 4949ce5..d8068ab 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1811,10 +1811,9 @@ static int nfs4_establish_lease(struct nfs_client *clp)
int status;
cred = ops->get_clid_cred(clp);
- if (cred == NULL)
- return -ENOENT;
status = ops->establish_clid(clp, cred);
- put_rpccred(cred);
+ if (cred)
+ put_rpccred(cred);
if (status != 0)
return status;
pnfs_destroy_all_layouts(clp);
@@ -1885,11 +1884,9 @@ int nfs4_discover_server_trunking(struct nfs_client *clp,
again:
status = -ENOENT;
cred = ops->get_clid_cred(clp);
- if (cred == NULL)
- goto out_unlock;
-
status = ops->detect_trunking(clp, result, cred);
- put_rpccred(cred);
+ if (cred)
+ put_rpccred(cred);
switch (status) {
case 0:
break;
@@ -1902,6 +1899,10 @@ again:
__func__, status);
goto again;
case -EACCES:
+ if (clp->cl_machine_cred != NULL) {
+ nfs4_clear_machine_cred(clp);
+ goto again;
+ }
if (i++)
break;
case -NFS4ERR_CLID_INUSE:
@@ -1935,7 +1936,6 @@ again:
status = -EIO;
}
-out_unlock:
mutex_unlock(&nfs_clid_init_mutex);
dprintk("NFS: %s: status = %d\n", __func__, status);
return status;
next prev parent reply other threads:[~2013-06-07 19:45 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-07 19:44 [PATCH 0/3] Use root user credential for lease management Chuck Lever
2013-06-07 19:44 ` [PATCH 1/3] NFS: Never use user credentials for lease renewal Chuck Lever
2013-06-07 19:45 ` [PATCH 2/3] NFS: Partially revert commit 845cbceb Chuck Lever
2013-06-07 19:45 ` Chuck Lever [this message]
2013-06-07 19:52 ` [PATCH 3/3] NFS: Use root's credential for lease management when keytab is missing Myklebust, Trond
2013-06-07 20:04 ` Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130607194510.1296.69923.stgit@seurat.1015granger.net \
--to=chuck.lever@oracle.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).