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

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

NFSv4: Send unmapped uid/gids to the server when using auth_sys



The new behaviour is enabled using the new module parameter
'nfs4_disable_idmapping'.

Note that if the server rejects an unmapped uid or gid, then
the client will automatically switch back to using the idmapper.

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 3ddeb7c5
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1580,6 +1580,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
			of returning the full 64-bit number.
			The default is to return 64-bit inode numbers.

	nfs.nfs4_disable_idmapping=
			[NFSv4] When set, this option disables the NFSv4
			idmapper on the client, but only if the mount
			is using the 'sec=sys' security flavour. This may
			make migration from legacy NFSv2/v3 systems easier
			provided that the server has the appropriate support.
			The default is to always enable NFSv4 idmapping.

	nmi_debug=	[KNL,AVR32,SH] Specify one or more actions to take
			when a NMI is triggered.
			Format: [state][,regs][,debounce][,die]
+16 −0
Original line number Diff line number Diff line
@@ -81,6 +81,11 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
}
#endif /* CONFIG_NFS_V4 */

/*
 * Turn off NFSv4 uid/gid mapping when using AUTH_SYS
 */
static int nfs4_disable_idmapping = 0;

/*
 * RPC cruft for NFS
 */
@@ -1567,6 +1572,13 @@ static int nfs4_init_server(struct nfs_server *server,
	if (error < 0)
		goto error;

	/*
	 * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower
	 * authentication.
	 */
	if (nfs4_disable_idmapping && data->auth_flavors[0] == RPC_AUTH_UNIX)
		server->caps |= NFS_CAP_UIDGID_NOMAP;

	if (data->rsize)
		server->rsize = nfs_block_size(data->rsize, NULL);
	if (data->wsize)
@@ -1984,3 +1996,7 @@ void nfs_fs_proc_exit(void)
}

#endif /* CONFIG_PROC_FS */

module_param(nfs4_disable_idmapping, bool, 0644);
MODULE_PARM_DESC(nfs4_disable_idmapping,
		"Turn off NFSv4 idmapping when using 'sec=sys'");
+16 −8
Original line number Diff line number Diff line
@@ -61,6 +61,9 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen)

#include <linux/slab.h>
#include <linux/cred.h>
#include <linux/sunrpc/sched.h>
#include <linux/nfs4.h>
#include <linux/nfs_fs_sb.h>
#include <linux/nfs_idmap.h>
#include <linux/keyctl.h>
#include <linux/key-type.h>
@@ -257,7 +260,9 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size

int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen)
{
	int ret;
	int ret = -EINVAL;

	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
		ret = nfs_idmap_lookup_name(uid, "user", buf, buflen);
	if (ret < 0)
		ret = nfs_map_numeric_to_string(uid, buf, buflen);
@@ -265,8 +270,9 @@ int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, s
}
int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen)
{
	int ret;
	int ret = -EINVAL;

	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
		ret = nfs_idmap_lookup_name(gid, "group", buf, buflen);
	if (ret < 0)
		ret = nfs_map_numeric_to_string(gid, buf, buflen);
@@ -750,8 +756,9 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size
int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen)
{
	struct idmap *idmap = server->nfs_client->cl_idmap;
	int ret;
	int ret = -EINVAL;

	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
		ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf);
	if (ret < 0)
		ret = nfs_map_numeric_to_string(uid, buf, buflen);
@@ -760,8 +767,9 @@ int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, s
int nfs_map_gid_to_group(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen)
{
	struct idmap *idmap = server->nfs_client->cl_idmap;
	int ret;
	int ret = -EINVAL;

	if (!(server->caps & NFS_CAP_UIDGID_NOMAP))
		ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf);
	if (ret < 0)
		ret = nfs_map_numeric_to_string(uid, buf, buflen);
+14 −1
Original line number Diff line number Diff line
@@ -244,7 +244,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
/* This is the error handling routine for processes that are allowed
 * to sleep.
 */
static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception)
{
	struct nfs_client *clp = server->nfs_client;
	struct nfs4_state *state = exception->state;
@@ -296,6 +296,19 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
				break;
		case -NFS4ERR_OLD_STATEID:
			exception->retry = 1;
			break;
		case -NFS4ERR_BADOWNER:
			/* The following works around a Linux server bug! */
		case -NFS4ERR_BADNAME:
			if (server->caps & NFS_CAP_UIDGID_NOMAP) {
				server->caps &= ~NFS_CAP_UIDGID_NOMAP;
				exception->retry = 1;
				printk(KERN_WARNING "NFS: v4 server %s "
						"does not accept raw "
						"uid/gids. "
						"Reenabling the idmapper.\n",
						server->nfs_client->cl_hostname);
			}
	}
	/* We failed to handle the error */
	return nfs4_map_errors(ret);
+1 −0
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ struct nfs_server {
#define NFS_CAP_CTIME		(1U << 12)
#define NFS_CAP_MTIME		(1U << 13)
#define NFS_CAP_POSIX_LOCK	(1U << 14)
#define NFS_CAP_UIDGID_NOMAP	(1U << 15)


/* maximum number of slots to use */