fs/nfs/nfs4namespace.c

Source file repositories/reference/linux-study-clean/fs/nfs/nfs4namespace.c

File Facts

System
Linux kernel
Corpus path
fs/nfs/nfs4namespace.c
Extension
.c
Size
13823 bytes
Lines
565
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret == 0) {
			ret = nfs_dns_resolve_name(net, string, len, ss, salen);
			if (ret < 0)
				ret = 0;
		}
	} else if (port) {
		rpc_set_port(sa, port);
	}
	return ret;
}

/**
 * nfs_find_best_sec - Find a security mechanism supported locally
 * @clnt: pointer to rpc_clnt
 * @server: NFS server struct
 * @flavors: List of security tuples returned by SECINFO procedure
 *
 * Return an rpc client that uses the first security mechanism in
 * "flavors" that is locally supported.  The "flavors" array
 * is searched in the order returned from the server, per RFC 3530
 * recommendation and each flavor is checked for membership in the
 * sec= mount option list if it exists.
 *
 * Return -EPERM if no matching flavor is found in the array.
 *
 * Please call rpc_shutdown_client() when you are done with this rpc client.
 *
 */
static struct rpc_clnt *nfs_find_best_sec(struct rpc_clnt *clnt,
					  struct nfs_server *server,
					  struct nfs4_secinfo_flavors *flavors)
{
	rpc_authflavor_t pflavor;
	struct nfs4_secinfo4 *secinfo;
	unsigned int i;

	for (i = 0; i < flavors->num_flavors; i++) {
		secinfo = &flavors->flavors[i];

		switch (secinfo->flavor) {
		case RPC_AUTH_NULL:
		case RPC_AUTH_UNIX:
		case RPC_AUTH_GSS:
			pflavor = rpcauth_get_pseudoflavor(secinfo->flavor,
							&secinfo->flavor_info);
			/* does the pseudoflavor match a sec= mount opt? */
			if (pflavor != RPC_AUTH_MAXFLAVOR &&
			    nfs_auth_info_match(&server->auth_info, pflavor)) {
				struct rpc_clnt *new;
				struct rpc_cred *cred;

				/* Cloning creates an rpc_auth for the flavor */
				new = rpc_clone_client_set_auth(clnt, pflavor);
				if (IS_ERR(new))
					continue;
				/**
				* Check that the user actually can use the
				* flavor. This is mostly for RPC_AUTH_GSS
				* where cr_init obtains a gss context
				*/
				cred = rpcauth_lookupcred(new->cl_auth, 0);
				if (IS_ERR(cred)) {
					rpc_shutdown_client(new);
					continue;
				}
				put_rpccred(cred);
				return new;
			}
		}
	}
	return ERR_PTR(-EPERM);
}

/**
 * nfs4_negotiate_security - in response to an NFS4ERR_WRONGSEC on lookup,
 * return an rpc_clnt that uses the best available security flavor with
 * respect to the secinfo flavor list and the sec= mount options.
 *
 * @clnt: RPC client to clone
 * @inode: directory inode
 * @name: lookup name
 *
 * Please call rpc_shutdown_client() when you are done with this rpc client.
 */
struct rpc_clnt *
nfs4_negotiate_security(struct rpc_clnt *clnt, struct inode *inode,
					const struct qstr *name)
{
	struct page *page;
	struct nfs4_secinfo_flavors *flavors;

Annotation

Implementation Notes