* [PATCH v3 0/5] Allow the admin to turn off NFSv4 uid/gid mapping @ 2010-11-30 14:43 Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 1/5] NFSv4: If the server sends us a numeric uid/gid then accept it Trond Myklebust 0 siblings, 1 reply; 8+ messages in thread From: Trond Myklebust @ 2010-11-30 14:43 UTC (permalink / raw) To: linux-nfs The following patches allow the admin to turn off NFSv4 uid/gid mapping if mounting using AUTH_SYS security. Changes w.r.t. first revision: - Added documentation in kernel-parameters.txt - Print a warning if an NFSERR_BADOWNER causes us to turn idmapping on again Changes w.r.t. second revision: - Ensure we propagate the NFS4ERR_BADOWNER up to the NFSv4 middle layers - Fix a typo in nfs4_handle_exception Trond Myklebust (5): NFSv4: If the server sends us a numeric uid/gid then accept it NFSv4: Send unmapped uid/gids to the server if the idmapper fails NFSv4: cleanup idmapper functions to take an nfs_server argument NFSv4: Propagate the error NFS4ERR_BADOWNER to nfs4_do_setattr NFSv4: Send unmapped uid/gids to the server when using auth_sys Documentation/kernel-parameters.txt | 8 +++ fs/nfs/client.c | 16 ++++++ fs/nfs/idmap.c | 87 +++++++++++++++++++++++++++------- fs/nfs/nfs4proc.c | 15 ++++++- fs/nfs/nfs4xdr.c | 19 +++---- include/linux/nfs_fs_sb.h | 1 + include/linux/nfs_idmap.h | 8 ++-- 7 files changed, 120 insertions(+), 34 deletions(-) -- 1.7.3.2 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3 1/5] NFSv4: If the server sends us a numeric uid/gid then accept it 2010-11-30 14:43 [PATCH v3 0/5] Allow the admin to turn off NFSv4 uid/gid mapping Trond Myklebust @ 2010-11-30 14:43 ` Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 2/5] NFSv4: Send unmapped uid/gids to the server if the idmapper fails Trond Myklebust 0 siblings, 1 reply; 8+ messages in thread From: Trond Myklebust @ 2010-11-30 14:43 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/idmap.c | 28 ++++++++++++++++++++++++++-- 1 files changed, 26 insertions(+), 2 deletions(-) diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 4e2d9b6..4281da6 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -33,6 +33,24 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <linux/types.h> +#include <linux/string.h> +#include <linux/kernel.h> + +static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *res) +{ + unsigned long val; + char buf[16]; + + if (memchr(name, '@', namelen) != NULL || namelen >= sizeof(buf)) + return 0; + memcpy(buf, name, namelen); + buf[namelen] = '\0'; + if (strict_strtoul(buf, 0, &val) != 0) + return 0; + *res = val; + return 1; +} #ifdef CONFIG_NFS_USE_NEW_IDMAPPER @@ -42,7 +60,6 @@ #include <linux/keyctl.h> #include <linux/key-type.h> #include <linux/rcupdate.h> -#include <linux/kernel.h> #include <linux/err.h> #include <keys/user-type.h> @@ -221,11 +238,15 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) { + if (nfs_map_string_to_numeric(name, namelen, uid)) + return 0; return nfs_idmap_lookup_id(name, namelen, "uid", uid); } int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *gid) { + if (nfs_map_string_to_numeric(name, namelen, gid)) + return 0; return nfs_idmap_lookup_id(name, namelen, "gid", gid); } @@ -243,7 +264,6 @@ int nfs_map_gid_to_group(struct nfs_client *clp, __u32 gid, char *buf, size_t bu #include <linux/module.h> #include <linux/mutex.h> #include <linux/init.h> -#include <linux/types.h> #include <linux/slab.h> #include <linux/socket.h> #include <linux/in.h> @@ -699,6 +719,8 @@ int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen { struct idmap *idmap = clp->cl_idmap; + if (nfs_map_string_to_numeric(name, namelen, uid)) + return 0; return nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid); } @@ -706,6 +728,8 @@ int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namele { struct idmap *idmap = clp->cl_idmap; + if (nfs_map_string_to_numeric(name, namelen, uid)) + return 0; return nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, uid); } -- 1.7.3.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 2/5] NFSv4: Send unmapped uid/gids to the server if the idmapper fails 2010-11-30 14:43 ` [PATCH v3 1/5] NFSv4: If the server sends us a numeric uid/gid then accept it Trond Myklebust @ 2010-11-30 14:43 ` Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 3/5] NFSv4: cleanup idmapper functions to take an nfs_server argument Trond Myklebust 0 siblings, 1 reply; 8+ messages in thread From: Trond Myklebust @ 2010-11-30 14:43 UTC (permalink / raw) To: linux-nfs Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/idmap.c | 30 ++++++++++++++++++++++++++---- 1 files changed, 26 insertions(+), 4 deletions(-) diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 4281da6..9bf5921 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -52,6 +52,11 @@ static int nfs_map_string_to_numeric(const char *name, size_t namelen, __u32 *re return 1; } +static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen) +{ + return snprintf(buf, buflen, "%u", id); +} + #ifdef CONFIG_NFS_USE_NEW_IDMAPPER #include <linux/slab.h> @@ -252,11 +257,20 @@ int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namele int nfs_map_uid_to_name(struct nfs_client *clp, __u32 uid, char *buf, size_t buflen) { - return nfs_idmap_lookup_name(uid, "user", buf, buflen); + int ret; + ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); + if (ret < 0) + ret = nfs_map_numeric_to_string(uid, buf, buflen); + return ret; } int nfs_map_gid_to_group(struct nfs_client *clp, __u32 gid, char *buf, size_t buflen) { - return nfs_idmap_lookup_name(gid, "group", buf, buflen); + int ret; + + ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); + if (ret < 0) + ret = nfs_map_numeric_to_string(gid, buf, buflen); + return ret; } #else /* CONFIG_NFS_USE_IDMAPPER not defined */ @@ -736,14 +750,22 @@ int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namele int nfs_map_uid_to_name(struct nfs_client *clp, __u32 uid, char *buf, size_t buflen) { struct idmap *idmap = clp->cl_idmap; + int ret; - return nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); + ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); + if (ret < 0) + ret = nfs_map_numeric_to_string(uid, buf, buflen); + return ret; } int nfs_map_gid_to_group(struct nfs_client *clp, __u32 uid, char *buf, size_t buflen) { struct idmap *idmap = clp->cl_idmap; + int ret; - return nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); + ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); + if (ret < 0) + ret = nfs_map_numeric_to_string(uid, buf, buflen); + return ret; } #endif /* CONFIG_NFS_USE_NEW_IDMAPPER */ -- 1.7.3.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 3/5] NFSv4: cleanup idmapper functions to take an nfs_server argument 2010-11-30 14:43 ` [PATCH v3 2/5] NFSv4: Send unmapped uid/gids to the server if the idmapper fails Trond Myklebust @ 2010-11-30 14:43 ` Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 4/5] NFSv4: Propagate the error NFS4ERR_BADOWNER to nfs4_do_setattr Trond Myklebust 0 siblings, 1 reply; 8+ messages in thread From: Trond Myklebust @ 2010-11-30 14:43 UTC (permalink / raw) To: linux-nfs ...instead of the nfs_client. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/idmap.c | 24 ++++++++++++------------ fs/nfs/nfs4xdr.c | 18 ++++++++---------- include/linux/nfs_idmap.h | 8 ++++---- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 9bf5921..114de76 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -241,21 +241,21 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, return ret; } -int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) +int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) { if (nfs_map_string_to_numeric(name, namelen, uid)) return 0; return nfs_idmap_lookup_id(name, namelen, "uid", uid); } -int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *gid) +int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *gid) { if (nfs_map_string_to_numeric(name, namelen, gid)) return 0; return nfs_idmap_lookup_id(name, namelen, "gid", gid); } -int nfs_map_uid_to_name(struct nfs_client *clp, __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; ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); @@ -263,7 +263,7 @@ int nfs_map_uid_to_name(struct nfs_client *clp, __u32 uid, char *buf, size_t buf ret = nfs_map_numeric_to_string(uid, buf, buflen); return ret; } -int nfs_map_gid_to_group(struct nfs_client *clp, __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; @@ -729,27 +729,27 @@ static unsigned int fnvhash32(const void *buf, size_t buflen) return hash; } -int nfs_map_name_to_uid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) +int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) { - struct idmap *idmap = clp->cl_idmap; + struct idmap *idmap = server->nfs_client->cl_idmap; if (nfs_map_string_to_numeric(name, namelen, uid)) return 0; return nfs_idmap_id(idmap, &idmap->idmap_user_hash, name, namelen, uid); } -int nfs_map_group_to_gid(struct nfs_client *clp, const char *name, size_t namelen, __u32 *uid) +int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid) { - struct idmap *idmap = clp->cl_idmap; + struct idmap *idmap = server->nfs_client->cl_idmap; if (nfs_map_string_to_numeric(name, namelen, uid)) return 0; return nfs_idmap_id(idmap, &idmap->idmap_group_hash, name, namelen, uid); } -int nfs_map_uid_to_name(struct nfs_client *clp, __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 = clp->cl_idmap; + struct idmap *idmap = server->nfs_client->cl_idmap; int ret; ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); @@ -757,9 +757,9 @@ int nfs_map_uid_to_name(struct nfs_client *clp, __u32 uid, char *buf, size_t buf ret = nfs_map_numeric_to_string(uid, buf, buflen); return ret; } -int nfs_map_gid_to_group(struct nfs_client *clp, __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 = clp->cl_idmap; + struct idmap *idmap = server->nfs_client->cl_idmap; int ret; ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 9f1826b..0be0277 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -844,7 +844,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const if (iap->ia_valid & ATTR_MODE) len += 4; if (iap->ia_valid & ATTR_UID) { - owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name, IDMAP_NAMESZ); + owner_namelen = nfs_map_uid_to_name(server, iap->ia_uid, owner_name, IDMAP_NAMESZ); if (owner_namelen < 0) { dprintk("nfs: couldn't resolve uid %d to string\n", iap->ia_uid); @@ -856,7 +856,7 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const len += 4 + (XDR_QUADLEN(owner_namelen) << 2); } if (iap->ia_valid & ATTR_GID) { - owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group, IDMAP_NAMESZ); + owner_grouplen = nfs_map_gid_to_group(server, iap->ia_gid, owner_group, IDMAP_NAMESZ); if (owner_grouplen < 0) { dprintk("nfs: couldn't resolve gid %d to string\n", iap->ia_gid); @@ -3460,7 +3460,7 @@ out_overflow: } static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, - struct nfs_client *clp, uint32_t *uid, int may_sleep) + const struct nfs_server *server, uint32_t *uid, int may_sleep) { uint32_t len; __be32 *p; @@ -3480,7 +3480,7 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, if (!may_sleep) { /* do nothing */ } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_name_to_uid(clp, (char *)p, len, uid) == 0) + if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0) ret = NFS_ATTR_FATTR_OWNER; else dprintk("%s: nfs_map_name_to_uid failed!\n", @@ -3498,7 +3498,7 @@ out_overflow: } static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, - struct nfs_client *clp, uint32_t *gid, int may_sleep) + const struct nfs_server *server, uint32_t *gid, int may_sleep) { uint32_t len; __be32 *p; @@ -3518,7 +3518,7 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, if (!may_sleep) { /* do nothing */ } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_group_to_gid(clp, (char *)p, len, gid) == 0) + if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0) ret = NFS_ATTR_FATTR_GROUP; else dprintk("%s: nfs_map_group_to_gid failed!\n", @@ -4017,14 +4017,12 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; - status = decode_attr_owner(xdr, bitmap, server->nfs_client, - &fattr->uid, may_sleep); + status = decode_attr_owner(xdr, bitmap, server, &fattr->uid, may_sleep); if (status < 0) goto xdr_error; fattr->valid |= status; - status = decode_attr_group(xdr, bitmap, server->nfs_client, - &fattr->gid, may_sleep); + status = decode_attr_group(xdr, bitmap, server, &fattr->gid, may_sleep); if (status < 0) goto xdr_error; fattr->valid |= status; diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h index e8352dc..ee97767 100644 --- a/include/linux/nfs_idmap.h +++ b/include/linux/nfs_idmap.h @@ -96,10 +96,10 @@ void nfs_idmap_delete(struct nfs_client *); #endif /* CONFIG_NFS_USE_NEW_IDMAPPER */ -int nfs_map_name_to_uid(struct nfs_client *, const char *, size_t, __u32 *); -int nfs_map_group_to_gid(struct nfs_client *, const char *, size_t, __u32 *); -int nfs_map_uid_to_name(struct nfs_client *, __u32, char *, size_t); -int nfs_map_gid_to_group(struct nfs_client *, __u32, char *, size_t); +int nfs_map_name_to_uid(const struct nfs_server *, const char *, size_t, __u32 *); +int nfs_map_group_to_gid(const struct nfs_server *, const char *, size_t, __u32 *); +int nfs_map_uid_to_name(const struct nfs_server *, __u32, char *, size_t); +int nfs_map_gid_to_group(const struct nfs_server *, __u32, char *, size_t); extern unsigned int nfs_idmap_cache_timeout; #endif /* __KERNEL__ */ -- 1.7.3.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 4/5] NFSv4: Propagate the error NFS4ERR_BADOWNER to nfs4_do_setattr 2010-11-30 14:43 ` [PATCH v3 3/5] NFSv4: cleanup idmapper functions to take an nfs_server argument Trond Myklebust @ 2010-11-30 14:43 ` Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 5/5] NFSv4: Send unmapped uid/gids to the server when using auth_sys Trond Myklebust 0 siblings, 1 reply; 8+ messages in thread From: Trond Myklebust @ 2010-11-30 14:43 UTC (permalink / raw) To: linux-nfs This will be required in order to switch uid/gid mapping back on if the admin has tried to disable it. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs4proc.c | 2 ++ fs/nfs/nfs4xdr.c | 1 - 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 89b0430..e40ab0b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -83,6 +83,8 @@ static int nfs4_map_errors(int err) switch (err) { case -NFS4ERR_RESOURCE: return -EREMOTEIO; + case -NFS4ERR_BADOWNER: + return -EINVAL; default: dprintk("%s could not handle NFSv4 error %d\n", __func__, -err); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 0be0277..c52e991 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -6254,7 +6254,6 @@ static struct { { NFS4ERR_DQUOT, -EDQUOT }, { NFS4ERR_STALE, -ESTALE }, { NFS4ERR_BADHANDLE, -EBADHANDLE }, - { NFS4ERR_BADOWNER, -EINVAL }, { NFS4ERR_BADNAME, -EINVAL }, { NFS4ERR_BAD_COOKIE, -EBADCOOKIE }, { NFS4ERR_NOTSUPP, -ENOTSUPP }, -- 1.7.3.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v3 5/5] NFSv4: Send unmapped uid/gids to the server when using auth_sys 2010-11-30 14:43 ` [PATCH v3 4/5] NFSv4: Propagate the error NFS4ERR_BADOWNER to nfs4_do_setattr Trond Myklebust @ 2010-11-30 14:43 ` Trond Myklebust 2010-11-30 19:48 ` J. Bruce Fields 0 siblings, 1 reply; 8+ messages in thread From: Trond Myklebust @ 2010-11-30 14:43 UTC (permalink / raw) To: linux-nfs 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: Trond Myklebust <Trond.Myklebust@netapp.com> --- Documentation/kernel-parameters.txt | 8 ++++++++ fs/nfs/client.c | 16 ++++++++++++++++ fs/nfs/idmap.c | 21 +++++++++++++-------- fs/nfs/nfs4proc.c | 13 ++++++++++++- include/linux/nfs_fs_sb.h | 1 + 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cdd2a6e..51a74a3 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1573,6 +1573,14 @@ and is between 256 and 4096 characters. It is defined in the file 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] diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 0870d0d..fb84771 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -58,6 +58,11 @@ static LIST_HEAD(nfs_volume_list); static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); /* + * Turn off NFSv4 uid/gid mapping when using AUTH_SYS + */ +static int nfs4_disable_idmapping = 0; + +/* * RPC cruft for NFS */ static struct rpc_version *nfs_version[5] = { @@ -1387,6 +1392,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) @@ -1808,3 +1820,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'"); diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index 114de76..d816bba 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c @@ -257,17 +257,20 @@ 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; - ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); + 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); return ret; } int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) { - int ret; + int ret = -EINVAL; - ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); + 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); return ret; @@ -750,9 +753,10 @@ 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; - ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); + 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); return ret; @@ -760,9 +764,10 @@ 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; - ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); + 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); return ret; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e40ab0b..02f028d 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -241,7 +241,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; @@ -292,6 +292,17 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, break; case -NFS4ERR_OLD_STATEID: exception->retry = 1; + break; + case -NFS4ERR_BADOWNER: + 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); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 452d964..6309262 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -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 */ -- 1.7.3.2 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v3 5/5] NFSv4: Send unmapped uid/gids to the server when using auth_sys 2010-11-30 14:43 ` [PATCH v3 5/5] NFSv4: Send unmapped uid/gids to the server when using auth_sys Trond Myklebust @ 2010-11-30 19:48 ` J. Bruce Fields 2010-11-30 21:48 ` Trond Myklebust 0 siblings, 1 reply; 8+ messages in thread From: J. Bruce Fields @ 2010-11-30 19:48 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs On Tue, Nov 30, 2010 at 09:43:31AM -0500, Trond Myklebust wrote: > 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: Trond Myklebust <Trond.Myklebust@netapp.com> > --- > Documentation/kernel-parameters.txt | 8 ++++++++ > fs/nfs/client.c | 16 ++++++++++++++++ > fs/nfs/idmap.c | 21 +++++++++++++-------- > fs/nfs/nfs4proc.c | 13 ++++++++++++- > include/linux/nfs_fs_sb.h | 1 + > 5 files changed, 50 insertions(+), 9 deletions(-) > > diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt > index cdd2a6e..51a74a3 100644 > --- a/Documentation/kernel-parameters.txt > +++ b/Documentation/kernel-parameters.txt > @@ -1573,6 +1573,14 @@ and is between 256 and 4096 characters. It is defined in the file > 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] > diff --git a/fs/nfs/client.c b/fs/nfs/client.c > index 0870d0d..fb84771 100644 > --- a/fs/nfs/client.c > +++ b/fs/nfs/client.c > @@ -58,6 +58,11 @@ static LIST_HEAD(nfs_volume_list); > static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); > > /* > + * Turn off NFSv4 uid/gid mapping when using AUTH_SYS > + */ > +static int nfs4_disable_idmapping = 0; > + > +/* > * RPC cruft for NFS > */ > static struct rpc_version *nfs_version[5] = { > @@ -1387,6 +1392,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) > @@ -1808,3 +1820,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'"); > diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c > index 114de76..d816bba 100644 > --- a/fs/nfs/idmap.c > +++ b/fs/nfs/idmap.c > @@ -257,17 +257,20 @@ 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; > - ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); > + 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); > return ret; > } > int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) > { > - int ret; > + int ret = -EINVAL; > > - ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); > + 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); > return ret; > @@ -750,9 +753,10 @@ 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; > > - ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); > + 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); > return ret; > @@ -760,9 +764,10 @@ 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; > > - ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); > + 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); > return ret; OK, so on both send and receive sides: if the new option is on, then we use *purely* numeric id's; if off, then we may still use numeric id's/gid's, but only as a fallback. Looks OK to me. --b. > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index e40ab0b..02f028d 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -241,7 +241,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; > @@ -292,6 +292,17 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, > break; > case -NFS4ERR_OLD_STATEID: > exception->retry = 1; > + break; > + case -NFS4ERR_BADOWNER: > + 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); > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h > index 452d964..6309262 100644 > --- a/include/linux/nfs_fs_sb.h > +++ b/include/linux/nfs_fs_sb.h > @@ -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 */ > -- > 1.7.3.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-nfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 5/5] NFSv4: Send unmapped uid/gids to the server when using auth_sys 2010-11-30 19:48 ` J. Bruce Fields @ 2010-11-30 21:48 ` Trond Myklebust 0 siblings, 0 replies; 8+ messages in thread From: Trond Myklebust @ 2010-11-30 21:48 UTC (permalink / raw) To: J. Bruce Fields; +Cc: linux-nfs On Tue, 2010-11-30 at 14:48 -0500, J. Bruce Fields wrote: > On Tue, Nov 30, 2010 at 09:43:31AM -0500, Trond Myklebust wrote: > > 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: Trond Myklebust <Trond.Myklebust@netapp.com> > > --- > > Documentation/kernel-parameters.txt | 8 ++++++++ > > fs/nfs/client.c | 16 ++++++++++++++++ > > fs/nfs/idmap.c | 21 +++++++++++++-------- > > fs/nfs/nfs4proc.c | 13 ++++++++++++- > > include/linux/nfs_fs_sb.h | 1 + > > 5 files changed, 50 insertions(+), 9 deletions(-) > > > > diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt > > index cdd2a6e..51a74a3 100644 > > --- a/Documentation/kernel-parameters.txt > > +++ b/Documentation/kernel-parameters.txt > > @@ -1573,6 +1573,14 @@ and is between 256 and 4096 characters. It is defined in the file > > 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] > > diff --git a/fs/nfs/client.c b/fs/nfs/client.c > > index 0870d0d..fb84771 100644 > > --- a/fs/nfs/client.c > > +++ b/fs/nfs/client.c > > @@ -58,6 +58,11 @@ static LIST_HEAD(nfs_volume_list); > > static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); > > > > /* > > + * Turn off NFSv4 uid/gid mapping when using AUTH_SYS > > + */ > > +static int nfs4_disable_idmapping = 0; > > + > > +/* > > * RPC cruft for NFS > > */ > > static struct rpc_version *nfs_version[5] = { > > @@ -1387,6 +1392,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) > > @@ -1808,3 +1820,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'"); > > diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c > > index 114de76..d816bba 100644 > > --- a/fs/nfs/idmap.c > > +++ b/fs/nfs/idmap.c > > @@ -257,17 +257,20 @@ 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; > > - ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); > > + 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); > > return ret; > > } > > int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) > > { > > - int ret; > > + int ret = -EINVAL; > > > > - ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); > > + 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); > > return ret; > > @@ -750,9 +753,10 @@ 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; > > > > - ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); > > + 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); > > return ret; > > @@ -760,9 +764,10 @@ 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; > > > > - ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); > > + 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); > > return ret; > > OK, so on both send and receive sides: if the new option is on, then we > use *purely* numeric id's; if off, then we may still use numeric > id's/gid's, but only as a fallback. > > Looks OK to me. Yup, but this really wants a corresponding server side option if it is to solve the nfsroot problem. Otherwise we can still deadlock when the server sends us a name@domain owner/group string that we need to translate by means of an upcall to the idmapper. :-) -- Trond Myklebust Linux NFS client maintainer NetApp Trond.Myklebust@netapp.com www.netapp.com ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-11-30 21:48 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-11-30 14:43 [PATCH v3 0/5] Allow the admin to turn off NFSv4 uid/gid mapping Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 1/5] NFSv4: If the server sends us a numeric uid/gid then accept it Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 2/5] NFSv4: Send unmapped uid/gids to the server if the idmapper fails Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 3/5] NFSv4: cleanup idmapper functions to take an nfs_server argument Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 4/5] NFSv4: Propagate the error NFS4ERR_BADOWNER to nfs4_do_setattr Trond Myklebust 2010-11-30 14:43 ` [PATCH v3 5/5] NFSv4: Send unmapped uid/gids to the server when using auth_sys Trond Myklebust 2010-11-30 19:48 ` J. Bruce Fields 2010-11-30 21:48 ` Trond Myklebust
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).