35 #include <linux/module.h>
37 #include <linux/sched.h>
38 #include <linux/slab.h>
48 static bool nfs4_disable_idmapping =
true;
51 "Turn off server's NFSv4 idmapping when using 'sec=sys'");
62 #define IDMAP_TYPE_USER 0
63 #define IDMAP_TYPE_GROUP 1
75 #define ENT_HASHBITS 8
76 #define ENT_HASHMAX (1 << ENT_HASHBITS)
85 new->type = itm->
type;
92 ent_put(
struct kref *ref)
113 idtoname_hash(
struct ent *
ent)
135 snprintf(idstr,
sizeof(idstr),
"%u", ent->
id);
164 seq_puts(m,
"#domain type id [name]\n");
178 warn_no_idmapd(
struct cache_detail *detail,
int has_died)
180 printk(
"nfsd: nfsv4 idmapping failing: has idmapd %s?\n",
181 has_died ?
"died" :
"not been started");
185 static int idtoname_parse(
struct cache_detail *,
char *,
int);
186 static struct ent *idtoname_lookup(
struct cache_detail *,
struct ent *);
187 static struct ent *idtoname_update(
struct cache_detail *,
struct ent *,
193 .name =
"nfs4.idtoname",
194 .cache_put = ent_put,
195 .cache_upcall = idtoname_upcall,
196 .cache_parse = idtoname_parse,
197 .cache_show = idtoname_show,
198 .warn_no_listener = warn_no_idmapd,
199 .match = idtoname_match,
208 struct ent ent, *
res;
213 if (buf[buflen - 1] !=
'\n')
215 buf[buflen - 1]=
'\0';
221 memset(&ent, 0,
sizeof(ent));
242 ent.
h.expiry_time = get_expiry(&buf);
243 if (ent.
h.expiry_time == 0)
247 res = idtoname_lookup(cd, &ent);
263 res = idtoname_update(cd, &ent, res);
267 cache_put(&res->
h, cd);
281 idtoname_hash(item));
289 idtoname_update(
struct cache_detail *cd,
struct ent *
new,
struct ent *old)
305 nametoid_hash(
struct ent *ent)
345 seq_puts(m,
"#domain type name [id]\n");
358 static struct ent *nametoid_lookup(
struct cache_detail *,
struct ent *);
359 static struct ent *nametoid_update(
struct cache_detail *,
struct ent *,
361 static int nametoid_parse(
struct cache_detail *,
char *,
int);
366 .name =
"nfs4.nametoid",
367 .cache_put = ent_put,
368 .cache_upcall = nametoid_upcall,
369 .cache_parse = nametoid_parse,
370 .cache_show = nametoid_show,
371 .warn_no_listener = warn_no_idmapd,
372 .match = nametoid_match,
379 nametoid_parse(
struct cache_detail *cd,
char *buf,
int buflen)
381 struct ent ent, *
res;
385 if (buf[buflen - 1] !=
'\n')
387 buf[buflen - 1]=
'\0';
393 memset(&ent, 0,
sizeof(ent));
413 ent.
h.expiry_time = get_expiry(&buf);
414 if (ent.
h.expiry_time == 0)
418 error = get_int(&buf, &ent.
id);
425 res = nametoid_lookup(cd, &ent);
428 res = nametoid_update(cd, &ent, res);
432 cache_put(&res->
h, cd);
442 nametoid_lookup(
struct cache_detail *cd,
struct ent *item)
445 nametoid_hash(item));
453 nametoid_update(
struct cache_detail *cd,
struct ent *
new,
struct ent *old)
478 goto destroy_idtoname_cache;
482 goto unregister_idtoname_cache;
486 goto destroy_nametoid_cache;
489 destroy_nametoid_cache:
491 unregister_idtoname_cache:
493 destroy_idtoname_cache:
510 idmap_lookup(
struct svc_rqst *rqstp,
511 struct ent *(*lookup_fn)(
struct cache_detail *,
struct ent *),
516 *item = lookup_fn(detail, key);
523 struct ent *prev_item = *
item;
524 *item = lookup_fn(detail, key);
525 if (*item != prev_item)
527 cache_put(&(*item)->h, detail);
533 rqst_authname(
struct svc_rqst *rqstp)
535 struct auth_domain *clp;
545 struct ent *
item, key = {
551 if (namelen + 1 >
sizeof(key.
name))
556 ret = idmap_lookup(rqstp, nametoid_lookup, &key, nn->
nametoid_cache, &item);
567 idmap_id_to_name(
struct svc_rqst *rqstp,
int type,
uid_t id,
char *name)
569 struct ent *
item, key = {
577 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->
idtoname_cache, &item);
579 return sprintf(name,
"%u",
id);
590 numeric_name_to_id(
struct svc_rqst *rqstp,
int type,
const char *name,
u32 namelen,
uid_t *
id)
595 if (namelen + 1 >
sizeof(buf))
599 memcpy(buf, name, namelen);
606 do_name_to_id(
struct svc_rqst *rqstp,
int type,
const char *name,
u32 namelen,
uid_t *
id)
608 if (nfs4_disable_idmapping && rqstp->
rq_cred.cr_flavor < RPC_AUTH_GSS)
609 if (numeric_name_to_id(rqstp, type, name, namelen,
id))
615 return idmap_name_to_id(rqstp, type, name, namelen,
id);
619 do_id_to_name(
struct svc_rqst *rqstp,
int type,
uid_t id,
char *name)
621 if (nfs4_disable_idmapping && rqstp->
rq_cred.cr_flavor < RPC_AUTH_GSS)
622 return sprintf(name,
"%u",
id);
623 return idmap_id_to_name(rqstp, type,
id, name);