net/sunrpc/auth_unix.c

Source file repositories/reference/linux-study-clean/net/sunrpc/auth_unix.c

File Facts

System
Linux kernel
Corpus path
net/sunrpc/auth_unix.c
Extension
.c
Size
5604 bytes
Lines
244
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * linux/net/sunrpc/auth_unix.c
 *
 * UNIX-style authentication; no AUTH_SHORT support
 *
 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
 */

#include <linux/slab.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/mempool.h>
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/auth.h>
#include <linux/user_namespace.h>


#if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
# define RPCDBG_FACILITY	RPCDBG_AUTH
#endif

static struct rpc_auth		unix_auth;
static const struct rpc_credops	unix_credops;
static mempool_t		*unix_pool;

static struct rpc_auth *
unx_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
{
	refcount_inc(&unix_auth.au_count);
	return &unix_auth;
}

static void
unx_destroy(struct rpc_auth *auth)
{
}

/*
 * Lookup AUTH_UNIX creds for current process
 */
static struct rpc_cred *unx_lookup_cred(struct rpc_auth *auth,
					struct auth_cred *acred, int flags)
{
	struct rpc_cred *ret;

	ret = kmalloc_obj(*ret, rpc_task_gfp_mask());
	if (!ret) {
		if (!(flags & RPCAUTH_LOOKUP_ASYNC))
			return ERR_PTR(-ENOMEM);
		ret = mempool_alloc(unix_pool, GFP_NOWAIT);
		if (!ret)
			return ERR_PTR(-ENOMEM);
	}
	rpcauth_init_cred(ret, acred, auth, &unix_credops);
	ret->cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
	return ret;
}

static void
unx_free_cred_callback(struct rcu_head *head)
{
	struct rpc_cred *rpc_cred = container_of(head, struct rpc_cred, cr_rcu);

	put_cred(rpc_cred->cr_cred);
	mempool_free(rpc_cred, unix_pool);
}

static void
unx_destroy_cred(struct rpc_cred *cred)
{
	call_rcu(&cred->cr_rcu, unx_free_cred_callback);
}

/*
 * Match credentials against current the auth_cred.
 */
static int
unx_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
{
	unsigned int groups = 0;
	unsigned int i;

	if (cred->cr_cred == acred->cred)
		return 1;

	if (!uid_eq(cred->cr_cred->fsuid, acred->cred->fsuid) || !gid_eq(cred->cr_cred->fsgid, acred->cred->fsgid))
		return 0;

Annotation

Implementation Notes