Skip to content

Commit b1b3e13

Browse files
westonandrosadamsonTrond Myklebust
authored andcommitted
NFSv4: use mach cred for SECINFO_NO_NAME w/ integrity
Commit 9743120 introduced a regression that causes SECINFO_NO_NAME to fail without sending an RPC if: 1) the nfs_client's rpc_client is using krb5i/p (now tried by default) 2) the current user doesn't have valid kerberos credentials This situation is quite common - as of now a sec=sys mount would use krb5i for the nfs_client's rpc_client and a user would hardly be faulted for not having run kinit. The solution is to use the machine cred when trying to use an integrity protected auth flavor for SECINFO_NO_NAME. Older servers may not support using the machine cred or an integrity protected auth flavor for SECINFO_NO_NAME in every circumstance, so we fall back to using the user's cred and the filesystem's auth flavor in this case. We run into another problem when running against linux nfs servers - they return NFS4ERR_WRONGSEC when using integrity auth flavor (unless the mount is also that flavor) even though that is not a valid error for SECINFO*. Even though it's against spec, handle WRONGSEC errors on SECINFO_NO_NAME by falling back to using the user cred and the filesystem's auth flavor. Signed-off-by: Weston Andros Adamson <dros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
1 parent 0aea92b commit b1b3e13

File tree

1 file changed

+37
-4
lines changed

1 file changed

+37
-4
lines changed

fs/nfs/nfs4proc.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7483,7 +7483,8 @@ nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data, bool sync)
74837483
*/
74847484
static int
74857485
_nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
7486-
struct nfs_fsinfo *info, struct nfs4_secinfo_flavors *flavors)
7486+
struct nfs_fsinfo *info,
7487+
struct nfs4_secinfo_flavors *flavors, bool use_integrity)
74877488
{
74887489
struct nfs41_secinfo_no_name_args args = {
74897490
.style = SECINFO_STYLE_CURRENT_FH,
@@ -7496,8 +7497,23 @@ _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
74967497
.rpc_argp = &args,
74977498
.rpc_resp = &res,
74987499
};
7499-
return nfs4_call_sync(server->nfs_client->cl_rpcclient, server, &msg,
7500-
&args.seq_args, &res.seq_res, 0);
7500+
struct rpc_clnt *clnt = server->client;
7501+
int status;
7502+
7503+
if (use_integrity) {
7504+
clnt = server->nfs_client->cl_rpcclient;
7505+
msg.rpc_cred = nfs4_get_clid_cred(server->nfs_client);
7506+
}
7507+
7508+
dprintk("--> %s\n", __func__);
7509+
status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
7510+
&res.seq_res, 0);
7511+
dprintk("<-- %s status=%d\n", __func__, status);
7512+
7513+
if (msg.rpc_cred)
7514+
put_rpccred(msg.rpc_cred);
7515+
7516+
return status;
75017517
}
75027518

75037519
static int
@@ -7507,7 +7523,24 @@ nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
75077523
struct nfs4_exception exception = { };
75087524
int err;
75097525
do {
7510-
err = _nfs41_proc_secinfo_no_name(server, fhandle, info, flavors);
7526+
/* first try using integrity protection */
7527+
err = -NFS4ERR_WRONGSEC;
7528+
7529+
/* try to use integrity protection with machine cred */
7530+
if (_nfs4_is_integrity_protected(server->nfs_client))
7531+
err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
7532+
flavors, true);
7533+
7534+
/*
7535+
* if unable to use integrity protection, or SECINFO with
7536+
* integrity protection returns NFS4ERR_WRONGSEC (which is
7537+
* disallowed by spec, but exists in deployed servers) use
7538+
* the current filesystem's rpc_client and the user cred.
7539+
*/
7540+
if (err == -NFS4ERR_WRONGSEC)
7541+
err = _nfs41_proc_secinfo_no_name(server, fhandle, info,
7542+
flavors, false);
7543+
75117544
switch (err) {
75127545
case 0:
75137546
case -NFS4ERR_WRONGSEC:

0 commit comments

Comments
 (0)