aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-03-22 16:07:18 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-03-26 11:49:48 -0400
commite9541ce8efc22c233a045f091c2b969923709038 (patch)
treedb3fc2a326dae9ada480bbdaeb08202a4b596098 /fs/nfsd
parentcc27e0d407021a278d08c1952f5af4ab38c49eda (diff)
nfsd4: allow numeric idmapping
Mimic the client side by providing a module parameter that turns off idmapping in the auth_sys case, for backwards compatibility with NFSv2 and NFSv3. Unlike in the client case, we don't have any way to negotiate, since the client can return an error to us if it doesn't like the id that we return to it in (for example) a getattr call. However, it has always been possible for servers to return numeric id's, and as far as we're aware clients have always been able to handle them. Also, in the auth_sys case clients already need to have numeric id's the same between client and server. Therefore we believe it's safe to default this to on; but the module parameter is available to return to previous behavior if this proves to be a problem in some unexpected setup. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4idmap.c53
1 files changed, 49 insertions, 4 deletions
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 94096273cd6c..69ca9c5bb600 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -41,6 +41,14 @@
41#include "nfsd.h" 41#include "nfsd.h"
42 42
43/* 43/*
44 * Turn off idmapping when using AUTH_SYS.
45 */
46static bool nfs4_disable_idmapping = true;
47module_param(nfs4_disable_idmapping, bool, 0644);
48MODULE_PARM_DESC(nfs4_disable_idmapping,
49 "Turn off server's NFSv4 idmapping when using 'sec=sys'");
50
51/*
44 * Cache entry 52 * Cache entry
45 */ 53 */
46 54
@@ -561,28 +569,65 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
561 return ret; 569 return ret;
562} 570}
563 571
572static bool
573numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id)
574{
575 int ret;
576 char buf[11];
577
578 if (namelen + 1 > sizeof(buf))
579 /* too long to represent a 32-bit id: */
580 return false;
581 /* Just to make sure it's null-terminated: */
582 memcpy(buf, name, namelen);
583 buf[namelen] = '\0';
584 ret = strict_strtoul(name, 10, (unsigned long *)id);
585 return ret == 0;
586}
587
588static __be32
589do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id)
590{
591 if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS)
592 if (numeric_name_to_id(rqstp, type, name, namelen, id))
593 return 0;
594 /*
595 * otherwise, fall through and try idmapping, for
596 * backwards compatibility with clients sending names:
597 */
598 return idmap_name_to_id(rqstp, type, name, namelen, id);
599}
600
601static int
602do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
603{
604 if (nfs4_disable_idmapping && rqstp->rq_flavor < RPC_AUTH_GSS)
605 return sprintf(name, "%u", id);
606 return idmap_id_to_name(rqstp, type, id, name);
607}
608
564__be32 609__be32
565nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, 610nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
566 __u32 *id) 611 __u32 *id)
567{ 612{
568 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); 613 return do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id);
569} 614}
570 615
571__be32 616__be32
572nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, 617nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
573 __u32 *id) 618 __u32 *id)
574{ 619{
575 return idmap_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id); 620 return do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id);
576} 621}
577 622
578int 623int
579nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 624nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
580{ 625{
581 return idmap_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); 626 return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name);
582} 627}
583 628
584int 629int
585nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 630nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
586{ 631{
587 return idmap_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); 632 return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name);
588} 633}