Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97f68c6b authored by NeilBrown's avatar NeilBrown Committed by Anna Schumaker
Browse files

SUNRPC: add 'struct cred *' to auth_cred and rpc_cred



The SUNRPC credential framework was put together before
Linux has 'struct cred'.  Now that we have it, it makes sense to
use it.
This first step just includes a suitable 'struct cred *' pointer
in every 'struct auth_cred' and almost every 'struct rpc_cred'.

The rpc_cred used for auth_null has a NULL 'struct cred *' as nothing
else really makes sense.

For rpc_cred, the pointer is reference counted.
For auth_cred it isn't.  struct auth_cred are either allocated on
the stack, in which case the thread owns a reference to the auth,
or are part of 'struct generic_cred' in which case gc_base owns the
reference, and "acred" shares it.

Signed-off-by: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent f06bc033
Loading
Loading
Loading
Loading
+17 −0
Original line number Original line Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
#include <linux/nfs_page.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/sched/mm.h>


#include <linux/sunrpc/metrics.h>
#include <linux/sunrpc/metrics.h>


@@ -415,6 +416,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
		struct nfs4_ff_layout_mirror *mirror;
		struct nfs4_ff_layout_mirror *mirror;
		struct auth_cred acred = { .group_info = ff_zero_group };
		struct auth_cred acred = { .group_info = ff_zero_group };
		struct rpc_cred	__rcu *cred;
		struct rpc_cred	__rcu *cred;
		struct cred *kcred;
		u32 ds_count, fh_count, id;
		u32 ds_count, fh_count, id;
		int j;
		int j;


@@ -491,8 +493,23 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,


		acred.gid = make_kgid(&init_user_ns, id);
		acred.gid = make_kgid(&init_user_ns, id);


		if (gfp_flags & __GFP_FS)
			kcred = prepare_kernel_cred(NULL);
		else {
			unsigned int nofs_flags = memalloc_nofs_save();
			kcred = prepare_kernel_cred(NULL);
			memalloc_nofs_restore(nofs_flags);
		}
		rc = -ENOMEM;
		if (!kcred)
			goto out_err_free;
		kcred->fsuid = acred.uid;
		kcred->fsgid = acred.gid;
		acred.cred = kcred;

		/* find the cred for it */
		/* find the cred for it */
		rcu_assign_pointer(cred, rpc_lookup_generic_cred(&acred, 0, gfp_flags));
		rcu_assign_pointer(cred, rpc_lookup_generic_cred(&acred, 0, gfp_flags));
		put_cred(kcred);
		if (IS_ERR(cred)) {
		if (IS_ERR(cred)) {
			rc = PTR_ERR(cred);
			rc = PTR_ERR(cred);
			goto out_err_free;
			goto out_err_free;
+12 −1
Original line number Original line Diff line number Diff line
@@ -858,10 +858,21 @@ static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc
	} else {
	} else {
		struct rpc_auth *auth = client->cl_auth;
		struct rpc_auth *auth = client->cl_auth;
		struct auth_cred acred = {};
		struct auth_cred acred = {};
		struct cred *kcred;
		struct rpc_cred *ret;

		kcred = prepare_kernel_cred(NULL);
		if (!kcred)
			return NULL;


		acred.uid = ses->se_cb_sec.uid;
		acred.uid = ses->se_cb_sec.uid;
		acred.gid = ses->se_cb_sec.gid;
		acred.gid = ses->se_cb_sec.gid;
		return auth->au_ops->lookup_cred(client->cl_auth, &acred, 0);
		kcred->uid = acred.uid;
		kcred->gid = acred.gid;
		acred.cred = kcred;
		ret = auth->au_ops->lookup_cred(client->cl_auth, &acred, 0);
		put_cred(kcred);
		return ret;
	}
	}
}
}


+2 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ enum {


/* Work around the lack of a VFS credential */
/* Work around the lack of a VFS credential */
struct auth_cred {
struct auth_cred {
	const struct cred *cred;
	kuid_t	uid;
	kuid_t	uid;
	kgid_t	gid;
	kgid_t	gid;
	struct group_info *group_info;
	struct group_info *group_info;
@@ -68,6 +69,7 @@ struct rpc_cred {
	unsigned long		cr_expire;	/* when to gc */
	unsigned long		cr_expire;	/* when to gc */
	unsigned long		cr_flags;	/* various flags */
	unsigned long		cr_flags;	/* various flags */
	refcount_t		cr_count;	/* ref count */
	refcount_t		cr_count;	/* ref count */
	const struct cred	*cr_cred;


	kuid_t			cr_uid;
	kuid_t			cr_uid;


+7 −1
Original line number Original line Diff line number Diff line
@@ -659,6 +659,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int flags)
	acred.uid = cred->fsuid;
	acred.uid = cred->fsuid;
	acred.gid = cred->fsgid;
	acred.gid = cred->fsgid;
	acred.group_info = cred->group_info;
	acred.group_info = cred->group_info;
	acred.cred = cred;
	ret = auth->au_ops->lookup_cred(auth, &acred, flags);
	ret = auth->au_ops->lookup_cred(auth, &acred, flags);
	return ret;
	return ret;
}
}
@@ -674,6 +675,7 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
	cred->cr_auth = auth;
	cred->cr_auth = auth;
	cred->cr_ops = ops;
	cred->cr_ops = ops;
	cred->cr_expire = jiffies;
	cred->cr_expire = jiffies;
	cred->cr_cred = get_cred(acred->cred);
	cred->cr_uid = acred->uid;
	cred->cr_uid = acred->uid;
}
}
EXPORT_SYMBOL_GPL(rpcauth_init_cred);
EXPORT_SYMBOL_GPL(rpcauth_init_cred);
@@ -694,11 +696,15 @@ rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
	struct auth_cred acred = {
	struct auth_cred acred = {
		.uid = GLOBAL_ROOT_UID,
		.uid = GLOBAL_ROOT_UID,
		.gid = GLOBAL_ROOT_GID,
		.gid = GLOBAL_ROOT_GID,
		.cred = get_task_cred(&init_task),
	};
	};
	struct rpc_cred *ret;


	dprintk("RPC: %5u looking up %s cred\n",
	dprintk("RPC: %5u looking up %s cred\n",
		task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
		task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
	return auth->au_ops->lookup_cred(auth, &acred, lookupflags);
	ret = auth->au_ops->lookup_cred(auth, &acred, lookupflags);
	put_cred(acred.cred);
	return ret;
}
}


static struct rpc_cred *
static struct rpc_cred *
+7 −1
Original line number Original line Diff line number Diff line
@@ -61,11 +61,15 @@ struct rpc_cred *rpc_lookup_machine_cred(const char *service_name)
		.gid = RPC_MACHINE_CRED_GROUPID,
		.gid = RPC_MACHINE_CRED_GROUPID,
		.principal = service_name,
		.principal = service_name,
		.machine_cred = 1,
		.machine_cred = 1,
		.cred = get_task_cred(&init_task),
	};
	};
	struct rpc_cred *ret;


	dprintk("RPC:       looking up machine cred for service %s\n",
	dprintk("RPC:       looking up machine cred for service %s\n",
			service_name);
			service_name);
	return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0);
	ret = generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0);
	put_cred(acred.cred);
	return ret;
}
}
EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);
EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);


@@ -110,6 +114,7 @@ generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, g
	gcred->acred.uid = acred->uid;
	gcred->acred.uid = acred->uid;
	gcred->acred.gid = acred->gid;
	gcred->acred.gid = acred->gid;
	gcred->acred.group_info = acred->group_info;
	gcred->acred.group_info = acred->group_info;
	gcred->acred.cred = gcred->gc_base.cr_cred;
	gcred->acred.ac_flags = 0;
	gcred->acred.ac_flags = 0;
	if (gcred->acred.group_info != NULL)
	if (gcred->acred.group_info != NULL)
		get_group_info(gcred->acred.group_info);
		get_group_info(gcred->acred.group_info);
@@ -132,6 +137,7 @@ generic_free_cred(struct rpc_cred *cred)
	dprintk("RPC:       generic_free_cred %p\n", gcred);
	dprintk("RPC:       generic_free_cred %p\n", gcred);
	if (gcred->acred.group_info != NULL)
	if (gcred->acred.group_info != NULL)
		put_group_info(gcred->acred.group_info);
		put_group_info(gcred->acred.group_info);
	put_cred(cred->cr_cred);
	kfree(gcred);
	kfree(gcred);
}
}


Loading