Commit b064eca2 authored by Trond Myklebust's avatar Trond Myklebust

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
...@@ -1580,6 +1580,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -1580,6 +1580,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
of returning the full 64-bit number. of returning the full 64-bit number.
The default is to return 64-bit inode numbers. 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 nmi_debug= [KNL,AVR32,SH] Specify one or more actions to take
when a NMI is triggered. when a NMI is triggered.
Format: [state][,regs][,debounce][,die] Format: [state][,regs][,debounce][,die]
......
...@@ -81,6 +81,11 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion) ...@@ -81,6 +81,11 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
} }
#endif /* CONFIG_NFS_V4 */ #endif /* CONFIG_NFS_V4 */
/*
* Turn off NFSv4 uid/gid mapping when using AUTH_SYS
*/
static int nfs4_disable_idmapping = 0;
/* /*
* RPC cruft for NFS * RPC cruft for NFS
*/ */
...@@ -1567,6 +1572,13 @@ static int nfs4_init_server(struct nfs_server *server, ...@@ -1567,6 +1572,13 @@ static int nfs4_init_server(struct nfs_server *server,
if (error < 0) if (error < 0)
goto error; 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) if (data->rsize)
server->rsize = nfs_block_size(data->rsize, NULL); server->rsize = nfs_block_size(data->rsize, NULL);
if (data->wsize) if (data->wsize)
...@@ -1984,3 +1996,7 @@ void nfs_fs_proc_exit(void) ...@@ -1984,3 +1996,7 @@ void nfs_fs_proc_exit(void)
} }
#endif /* CONFIG_PROC_FS */ #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'");
...@@ -61,6 +61,9 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen) ...@@ -61,6 +61,9 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen)
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/cred.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/nfs_idmap.h>
#include <linux/keyctl.h> #include <linux/keyctl.h>
#include <linux/key-type.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 ...@@ -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 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); ret = nfs_idmap_lookup_name(uid, "user", buf, buflen);
if (ret < 0) if (ret < 0)
ret = nfs_map_numeric_to_string(uid, buf, buflen); 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 ...@@ -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 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); ret = nfs_idmap_lookup_name(gid, "group", buf, buflen);
if (ret < 0) if (ret < 0)
ret = nfs_map_numeric_to_string(gid, buf, buflen); 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 ...@@ -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) 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; 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); ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf);
if (ret < 0) if (ret < 0)
ret = nfs_map_numeric_to_string(uid, buf, buflen); 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 ...@@ -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) 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; 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); ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf);
if (ret < 0) if (ret < 0)
ret = nfs_map_numeric_to_string(uid, buf, buflen); ret = nfs_map_numeric_to_string(uid, buf, buflen);
......
...@@ -244,7 +244,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) ...@@ -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 /* This is the error handling routine for processes that are allowed
* to sleep. * 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 nfs_client *clp = server->nfs_client;
struct nfs4_state *state = exception->state; struct nfs4_state *state = exception->state;
...@@ -296,6 +296,19 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, ...@@ -296,6 +296,19 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode,
break; break;
case -NFS4ERR_OLD_STATEID: case -NFS4ERR_OLD_STATEID:
exception->retry = 1; 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 */ /* We failed to handle the error */
return nfs4_map_errors(ret); return nfs4_map_errors(ret);
......
...@@ -177,6 +177,7 @@ struct nfs_server { ...@@ -177,6 +177,7 @@ struct nfs_server {
#define NFS_CAP_CTIME (1U << 12) #define NFS_CAP_CTIME (1U << 12)
#define NFS_CAP_MTIME (1U << 13) #define NFS_CAP_MTIME (1U << 13)
#define NFS_CAP_POSIX_LOCK (1U << 14) #define NFS_CAP_POSIX_LOCK (1U << 14)
#define NFS_CAP_UIDGID_NOMAP (1U << 15)
/* maximum number of slots to use */ /* maximum number of slots to use */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment