Commit af093835 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

SUNRPC: Fix RPCAUTH_LOOKUP_ROOTCREDS



The current RPCAUTH_LOOKUP_ROOTCREDS flag only works for AUTH_SYS
authentication, and then only as a special case in the code. This patch
removes the auth_sys special casing, and replaces it with generic code.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 25337fdc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -89,7 +89,6 @@ struct rpc_auth {

/* Flags for rpcauth_lookupcred() */
#define RPCAUTH_LOOKUP_NEW		0x01	/* Accept an uninitialised cred */
#define RPCAUTH_LOOKUP_ROOTCREDS	0x02	/* This really ought to go! */

/*
 * Client authentication ops
@@ -136,7 +135,8 @@ void rpcauth_release(struct rpc_auth *);
struct rpc_cred *	rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
void			rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
struct rpc_cred *	rpcauth_lookupcred(struct rpc_auth *, int);
struct rpc_cred *	rpcauth_bindcred(struct rpc_task *);
void			rpcauth_bindcred(struct rpc_task *);
void			rpcauth_bind_root_cred(struct rpc_task *);
void			rpcauth_holdcred(struct rpc_task *);
void			put_rpccred(struct rpc_cred *);
void			rpcauth_unbindcred(struct rpc_task *);
+20 −15
Original line number Diff line number Diff line
@@ -285,9 +285,6 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,

	nr = hash_long(acred->uid, RPC_CREDCACHE_HASHBITS);

	if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS))
		nr = acred->uid & RPC_CREDCACHE_MASK;

	rcu_read_lock();
	hlist_for_each_entry_rcu(entry, pos, &cache->hashtable[nr], cr_hash) {
		if (!entry->cr_ops->crmatch(acred, entry, flags))
@@ -378,30 +375,38 @@ rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
}
EXPORT_SYMBOL_GPL(rpcauth_init_cred);

struct rpc_cred *
rpcauth_bindcred(struct rpc_task *task)
void
rpcauth_bind_root_cred(struct rpc_task *task)
{
	struct rpc_auth *auth = task->tk_client->cl_auth;
	struct auth_cred acred = {
		.uid = current->fsuid,
		.gid = current->fsgid,
		.group_info = current->group_info,
		.uid = 0,
		.gid = 0,
	};
	struct rpc_cred *ret;
	int flags = 0;

	dprintk("RPC: %5u looking up %s cred\n",
		task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
	get_group_info(acred.group_info);
	if (task->tk_flags & RPC_TASK_ROOTCREDS)
		flags |= RPCAUTH_LOOKUP_ROOTCREDS;
	ret = auth->au_ops->lookup_cred(auth, &acred, flags);
	ret = auth->au_ops->lookup_cred(auth, &acred, 0);
	if (!IS_ERR(ret))
		task->tk_msg.rpc_cred = ret;
	else
		task->tk_status = PTR_ERR(ret);
}

void
rpcauth_bindcred(struct rpc_task *task)
{
	struct rpc_auth *auth = task->tk_client->cl_auth;
	struct rpc_cred *ret;

	dprintk("RPC: %5u looking up %s cred\n",
		task->tk_pid, auth->au_ops->au_name);
	ret = rpcauth_lookupcred(auth, 0);
	if (!IS_ERR(ret))
		task->tk_msg.rpc_cred = ret;
	else
		task->tk_status = PTR_ERR(ret);
	put_group_info(acred.group_info);
	return ret;
}

void
+24 −32
Original line number Diff line number Diff line
@@ -60,7 +60,8 @@ static struct rpc_cred *
unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
{
	struct unx_cred	*cred;
	int		i;
	unsigned int groups = 0;
	unsigned int i;

	dprintk("RPC:       allocating UNIX cred for uid %d gid %d\n",
			acred->uid, acred->gid);
@@ -70,12 +71,9 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)

	rpcauth_init_cred(&cred->uc_base, acred, auth, &unix_credops);
	cred->uc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
	if (flags & RPCAUTH_LOOKUP_ROOTCREDS) {
		cred->uc_uid = 0;
		cred->uc_gid = 0;
		cred->uc_gids[0] = NOGROUP;
	} else {
		int groups = acred->group_info->ngroups;

	if (acred->group_info != NULL)
		groups = acred->group_info->ngroups;
	if (groups > NFS_NGROUPS)
		groups = NFS_NGROUPS;

@@ -84,7 +82,6 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
		cred->uc_gids[i] = GROUP_AT(acred->group_info, i);
	if (i < NFS_NGROUPS)
		cred->uc_gids[i] = NOGROUP;
	}

	return &cred->uc_base;
}
@@ -118,15 +115,14 @@ static int
unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
{
	struct unx_cred	*cred = container_of(rcred, struct unx_cred, uc_base);
	int		i;
	unsigned int groups = 0;
	unsigned int i;

	if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) {
		int groups;

		if (cred->uc_uid != acred->uid
		 || cred->uc_gid != acred->gid)
	if (cred->uc_uid != acred->uid || cred->uc_gid != acred->gid)
		return 0;

	if (acred->group_info != NULL)
		groups = acred->group_info->ngroups;
	if (groups > NFS_NGROUPS)
		groups = NFS_NGROUPS;
@@ -135,10 +131,6 @@ unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags)
			return 0;
	return 1;
}
	return (cred->uc_uid == 0
	     && cred->uc_gid == 0
	     && cred->uc_gids[0] == (gid_t) NOGROUP);
}

/*
 * Marshal credentials.
+3 −1
Original line number Diff line number Diff line
@@ -821,8 +821,10 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
		/* Bind the user cred */
		if (task->tk_msg.rpc_cred != NULL)
			rpcauth_holdcred(task);
		else
		else if (!(task_setup_data->flags & RPC_TASK_ROOTCREDS))
			rpcauth_bindcred(task);
		else
			rpcauth_bind_root_cred(task);
		if (task->tk_action == NULL)
			rpc_call_start(task);
	}