root/fs/nfsd/nfs4idmap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ent_init
  2. ent_put
  3. ent_alloc
  4. idtoname_hash
  5. idtoname_request
  6. idtoname_match
  7. idtoname_show
  8. warn_no_idmapd
  9. idtoname_parse
  10. idtoname_lookup
  11. idtoname_update
  12. nametoid_hash
  13. nametoid_request
  14. nametoid_match
  15. nametoid_show
  16. nametoid_parse
  17. nametoid_lookup
  18. nametoid_update
  19. nfsd_idmap_init
  20. nfsd_idmap_shutdown
  21. idmap_lookup
  22. rqst_authname
  23. idmap_name_to_id
  24. encode_ascii_id
  25. idmap_id_to_name
  26. numeric_name_to_id
  27. do_name_to_id
  28. encode_name_from_id
  29. nfsd_map_name_to_uid
  30. nfsd_map_name_to_gid
  31. nfsd4_encode_user
  32. nfsd4_encode_group

   1 /*
   2  *  Mapping of UID/GIDs to name and vice versa.
   3  *
   4  *  Copyright (c) 2002, 2003 The Regents of the University of
   5  *  Michigan.  All rights reserved.
   6  *
   7  *  Marius Aamodt Eriksen <marius@umich.edu>
   8  *
   9  *  Redistribution and use in source and binary forms, with or without
  10  *  modification, are permitted provided that the following conditions
  11  *  are met:
  12  *
  13  *  1. Redistributions of source code must retain the above copyright
  14  *     notice, this list of conditions and the following disclaimer.
  15  *  2. Redistributions in binary form must reproduce the above copyright
  16  *     notice, this list of conditions and the following disclaimer in the
  17  *     documentation and/or other materials provided with the distribution.
  18  *  3. Neither the name of the University nor the names of its
  19  *     contributors may be used to endorse or promote products derived
  20  *     from this software without specific prior written permission.
  21  *
  22  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  23  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  24  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  29  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  30  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  31  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33  */
  34 
  35 #include <linux/module.h>
  36 #include <linux/seq_file.h>
  37 #include <linux/sched.h>
  38 #include <linux/slab.h>
  39 #include <linux/sunrpc/svc_xprt.h>
  40 #include <net/net_namespace.h>
  41 #include "idmap.h"
  42 #include "nfsd.h"
  43 #include "netns.h"
  44 
  45 /*
  46  * Turn off idmapping when using AUTH_SYS.
  47  */
  48 static bool nfs4_disable_idmapping = true;
  49 module_param(nfs4_disable_idmapping, bool, 0644);
  50 MODULE_PARM_DESC(nfs4_disable_idmapping,
  51                 "Turn off server's NFSv4 idmapping when using 'sec=sys'");
  52 
  53 /*
  54  * Cache entry
  55  */
  56 
  57 /*
  58  * XXX we know that IDMAP_NAMESZ < PAGE_SIZE, but it's ugly to rely on
  59  * that.
  60  */
  61 
  62 struct ent {
  63         struct cache_head h;
  64         int               type;                /* User / Group */
  65         u32               id;
  66         char              name[IDMAP_NAMESZ];
  67         char              authname[IDMAP_NAMESZ];
  68         struct rcu_head   rcu_head;
  69 };
  70 
  71 /* Common entry handling */
  72 
  73 #define ENT_HASHBITS          8
  74 #define ENT_HASHMAX           (1 << ENT_HASHBITS)
  75 
  76 static void
  77 ent_init(struct cache_head *cnew, struct cache_head *citm)
  78 {
  79         struct ent *new = container_of(cnew, struct ent, h);
  80         struct ent *itm = container_of(citm, struct ent, h);
  81 
  82         new->id = itm->id;
  83         new->type = itm->type;
  84 
  85         strlcpy(new->name, itm->name, sizeof(new->name));
  86         strlcpy(new->authname, itm->authname, sizeof(new->authname));
  87 }
  88 
  89 static void
  90 ent_put(struct kref *ref)
  91 {
  92         struct ent *map = container_of(ref, struct ent, h.ref);
  93         kfree_rcu(map, rcu_head);
  94 }
  95 
  96 static struct cache_head *
  97 ent_alloc(void)
  98 {
  99         struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL);
 100         if (e)
 101                 return &e->h;
 102         else
 103                 return NULL;
 104 }
 105 
 106 /*
 107  * ID -> Name cache
 108  */
 109 
 110 static uint32_t
 111 idtoname_hash(struct ent *ent)
 112 {
 113         uint32_t hash;
 114 
 115         hash = hash_str(ent->authname, ENT_HASHBITS);
 116         hash = hash_long(hash ^ ent->id, ENT_HASHBITS);
 117 
 118         /* Flip LSB for user/group */
 119         if (ent->type == IDMAP_TYPE_GROUP)
 120                 hash ^= 1;
 121 
 122         return hash;
 123 }
 124 
 125 static void
 126 idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
 127     int *blen)
 128 {
 129         struct ent *ent = container_of(ch, struct ent, h);
 130         char idstr[11];
 131 
 132         qword_add(bpp, blen, ent->authname);
 133         snprintf(idstr, sizeof(idstr), "%u", ent->id);
 134         qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");
 135         qword_add(bpp, blen, idstr);
 136 
 137         (*bpp)[-1] = '\n';
 138 }
 139 
 140 static int
 141 idtoname_match(struct cache_head *ca, struct cache_head *cb)
 142 {
 143         struct ent *a = container_of(ca, struct ent, h);
 144         struct ent *b = container_of(cb, struct ent, h);
 145 
 146         return (a->id == b->id && a->type == b->type &&
 147             strcmp(a->authname, b->authname) == 0);
 148 }
 149 
 150 static int
 151 idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
 152 {
 153         struct ent *ent;
 154 
 155         if (h == NULL) {
 156                 seq_puts(m, "#domain type id [name]\n");
 157                 return 0;
 158         }
 159         ent = container_of(h, struct ent, h);
 160         seq_printf(m, "%s %s %u", ent->authname,
 161                         ent->type == IDMAP_TYPE_GROUP ? "group" : "user",
 162                         ent->id);
 163         if (test_bit(CACHE_VALID, &h->flags))
 164                 seq_printf(m, " %s", ent->name);
 165         seq_printf(m, "\n");
 166         return 0;
 167 }
 168 
 169 static void
 170 warn_no_idmapd(struct cache_detail *detail, int has_died)
 171 {
 172         printk("nfsd: nfsv4 idmapping failing: has idmapd %s?\n",
 173                         has_died ? "died" : "not been started");
 174 }
 175 
 176 
 177 static int         idtoname_parse(struct cache_detail *, char *, int);
 178 static struct ent *idtoname_lookup(struct cache_detail *, struct ent *);
 179 static struct ent *idtoname_update(struct cache_detail *, struct ent *,
 180                                    struct ent *);
 181 
 182 static const struct cache_detail idtoname_cache_template = {
 183         .owner          = THIS_MODULE,
 184         .hash_size      = ENT_HASHMAX,
 185         .name           = "nfs4.idtoname",
 186         .cache_put      = ent_put,
 187         .cache_request  = idtoname_request,
 188         .cache_parse    = idtoname_parse,
 189         .cache_show     = idtoname_show,
 190         .warn_no_listener = warn_no_idmapd,
 191         .match          = idtoname_match,
 192         .init           = ent_init,
 193         .update         = ent_init,
 194         .alloc          = ent_alloc,
 195 };
 196 
 197 static int
 198 idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
 199 {
 200         struct ent ent, *res;
 201         char *buf1, *bp;
 202         int len;
 203         int error = -EINVAL;
 204 
 205         if (buf[buflen - 1] != '\n')
 206                 return (-EINVAL);
 207         buf[buflen - 1]= '\0';
 208 
 209         buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
 210         if (buf1 == NULL)
 211                 return (-ENOMEM);
 212 
 213         memset(&ent, 0, sizeof(ent));
 214 
 215         /* Authentication name */
 216         len = qword_get(&buf, buf1, PAGE_SIZE);
 217         if (len <= 0 || len >= IDMAP_NAMESZ)
 218                 goto out;
 219         memcpy(ent.authname, buf1, sizeof(ent.authname));
 220 
 221         /* Type */
 222         if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
 223                 goto out;
 224         ent.type = strcmp(buf1, "user") == 0 ?
 225                 IDMAP_TYPE_USER : IDMAP_TYPE_GROUP;
 226 
 227         /* ID */
 228         if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
 229                 goto out;
 230         ent.id = simple_strtoul(buf1, &bp, 10);
 231         if (bp == buf1)
 232                 goto out;
 233 
 234         /* expiry */
 235         ent.h.expiry_time = get_expiry(&buf);
 236         if (ent.h.expiry_time == 0)
 237                 goto out;
 238 
 239         error = -ENOMEM;
 240         res = idtoname_lookup(cd, &ent);
 241         if (!res)
 242                 goto out;
 243 
 244         /* Name */
 245         error = -EINVAL;
 246         len = qword_get(&buf, buf1, PAGE_SIZE);
 247         if (len < 0 || len >= IDMAP_NAMESZ)
 248                 goto out;
 249         if (len == 0)
 250                 set_bit(CACHE_NEGATIVE, &ent.h.flags);
 251         else
 252                 memcpy(ent.name, buf1, sizeof(ent.name));
 253         error = -ENOMEM;
 254         res = idtoname_update(cd, &ent, res);
 255         if (res == NULL)
 256                 goto out;
 257 
 258         cache_put(&res->h, cd);
 259         error = 0;
 260 out:
 261         kfree(buf1);
 262         return error;
 263 }
 264 
 265 static struct ent *
 266 idtoname_lookup(struct cache_detail *cd, struct ent *item)
 267 {
 268         struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
 269                                                         idtoname_hash(item));
 270         if (ch)
 271                 return container_of(ch, struct ent, h);
 272         else
 273                 return NULL;
 274 }
 275 
 276 static struct ent *
 277 idtoname_update(struct cache_detail *cd, struct ent *new, struct ent *old)
 278 {
 279         struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
 280                                                     idtoname_hash(new));
 281         if (ch)
 282                 return container_of(ch, struct ent, h);
 283         else
 284                 return NULL;
 285 }
 286 
 287 
 288 /*
 289  * Name -> ID cache
 290  */
 291 
 292 static inline int
 293 nametoid_hash(struct ent *ent)
 294 {
 295         return hash_str(ent->name, ENT_HASHBITS);
 296 }
 297 
 298 static void
 299 nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
 300     int *blen)
 301 {
 302         struct ent *ent = container_of(ch, struct ent, h);
 303 
 304         qword_add(bpp, blen, ent->authname);
 305         qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");
 306         qword_add(bpp, blen, ent->name);
 307 
 308         (*bpp)[-1] = '\n';
 309 }
 310 
 311 static int
 312 nametoid_match(struct cache_head *ca, struct cache_head *cb)
 313 {
 314         struct ent *a = container_of(ca, struct ent, h);
 315         struct ent *b = container_of(cb, struct ent, h);
 316 
 317         return (a->type == b->type && strcmp(a->name, b->name) == 0 &&
 318             strcmp(a->authname, b->authname) == 0);
 319 }
 320 
 321 static int
 322 nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
 323 {
 324         struct ent *ent;
 325 
 326         if (h == NULL) {
 327                 seq_puts(m, "#domain type name [id]\n");
 328                 return 0;
 329         }
 330         ent = container_of(h, struct ent, h);
 331         seq_printf(m, "%s %s %s", ent->authname,
 332                         ent->type == IDMAP_TYPE_GROUP ? "group" : "user",
 333                         ent->name);
 334         if (test_bit(CACHE_VALID, &h->flags))
 335                 seq_printf(m, " %u", ent->id);
 336         seq_printf(m, "\n");
 337         return 0;
 338 }
 339 
 340 static struct ent *nametoid_lookup(struct cache_detail *, struct ent *);
 341 static struct ent *nametoid_update(struct cache_detail *, struct ent *,
 342                                    struct ent *);
 343 static int         nametoid_parse(struct cache_detail *, char *, int);
 344 
 345 static const struct cache_detail nametoid_cache_template = {
 346         .owner          = THIS_MODULE,
 347         .hash_size      = ENT_HASHMAX,
 348         .name           = "nfs4.nametoid",
 349         .cache_put      = ent_put,
 350         .cache_request  = nametoid_request,
 351         .cache_parse    = nametoid_parse,
 352         .cache_show     = nametoid_show,
 353         .warn_no_listener = warn_no_idmapd,
 354         .match          = nametoid_match,
 355         .init           = ent_init,
 356         .update         = ent_init,
 357         .alloc          = ent_alloc,
 358 };
 359 
 360 static int
 361 nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
 362 {
 363         struct ent ent, *res;
 364         char *buf1;
 365         int len, error = -EINVAL;
 366 
 367         if (buf[buflen - 1] != '\n')
 368                 return (-EINVAL);
 369         buf[buflen - 1]= '\0';
 370 
 371         buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
 372         if (buf1 == NULL)
 373                 return (-ENOMEM);
 374 
 375         memset(&ent, 0, sizeof(ent));
 376 
 377         /* Authentication name */
 378         len = qword_get(&buf, buf1, PAGE_SIZE);
 379         if (len <= 0 || len >= IDMAP_NAMESZ)
 380                 goto out;
 381         memcpy(ent.authname, buf1, sizeof(ent.authname));
 382 
 383         /* Type */
 384         if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
 385                 goto out;
 386         ent.type = strcmp(buf1, "user") == 0 ?
 387                 IDMAP_TYPE_USER : IDMAP_TYPE_GROUP;
 388 
 389         /* Name */
 390         len = qword_get(&buf, buf1, PAGE_SIZE);
 391         if (len <= 0 || len >= IDMAP_NAMESZ)
 392                 goto out;
 393         memcpy(ent.name, buf1, sizeof(ent.name));
 394 
 395         /* expiry */
 396         ent.h.expiry_time = get_expiry(&buf);
 397         if (ent.h.expiry_time == 0)
 398                 goto out;
 399 
 400         /* ID */
 401         error = get_int(&buf, &ent.id);
 402         if (error == -EINVAL)
 403                 goto out;
 404         if (error == -ENOENT)
 405                 set_bit(CACHE_NEGATIVE, &ent.h.flags);
 406 
 407         error = -ENOMEM;
 408         res = nametoid_lookup(cd, &ent);
 409         if (res == NULL)
 410                 goto out;
 411         res = nametoid_update(cd, &ent, res);
 412         if (res == NULL)
 413                 goto out;
 414 
 415         cache_put(&res->h, cd);
 416         error = 0;
 417 out:
 418         kfree(buf1);
 419         return (error);
 420 }
 421 
 422 
 423 static struct ent *
 424 nametoid_lookup(struct cache_detail *cd, struct ent *item)
 425 {
 426         struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
 427                                                         nametoid_hash(item));
 428         if (ch)
 429                 return container_of(ch, struct ent, h);
 430         else
 431                 return NULL;
 432 }
 433 
 434 static struct ent *
 435 nametoid_update(struct cache_detail *cd, struct ent *new, struct ent *old)
 436 {
 437         struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
 438                                                     nametoid_hash(new));
 439         if (ch)
 440                 return container_of(ch, struct ent, h);
 441         else
 442                 return NULL;
 443 }
 444 
 445 /*
 446  * Exported API
 447  */
 448 
 449 int
 450 nfsd_idmap_init(struct net *net)
 451 {
 452         int rv;
 453         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 454 
 455         nn->idtoname_cache = cache_create_net(&idtoname_cache_template, net);
 456         if (IS_ERR(nn->idtoname_cache))
 457                 return PTR_ERR(nn->idtoname_cache);
 458         rv = cache_register_net(nn->idtoname_cache, net);
 459         if (rv)
 460                 goto destroy_idtoname_cache;
 461         nn->nametoid_cache = cache_create_net(&nametoid_cache_template, net);
 462         if (IS_ERR(nn->nametoid_cache)) {
 463                 rv = PTR_ERR(nn->nametoid_cache);
 464                 goto unregister_idtoname_cache;
 465         }
 466         rv = cache_register_net(nn->nametoid_cache, net);
 467         if (rv)
 468                 goto destroy_nametoid_cache;
 469         return 0;
 470 
 471 destroy_nametoid_cache:
 472         cache_destroy_net(nn->nametoid_cache, net);
 473 unregister_idtoname_cache:
 474         cache_unregister_net(nn->idtoname_cache, net);
 475 destroy_idtoname_cache:
 476         cache_destroy_net(nn->idtoname_cache, net);
 477         return rv;
 478 }
 479 
 480 void
 481 nfsd_idmap_shutdown(struct net *net)
 482 {
 483         struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 484 
 485         cache_unregister_net(nn->idtoname_cache, net);
 486         cache_unregister_net(nn->nametoid_cache, net);
 487         cache_destroy_net(nn->idtoname_cache, net);
 488         cache_destroy_net(nn->nametoid_cache, net);
 489 }
 490 
 491 static int
 492 idmap_lookup(struct svc_rqst *rqstp,
 493                 struct ent *(*lookup_fn)(struct cache_detail *, struct ent *),
 494                 struct ent *key, struct cache_detail *detail, struct ent **item)
 495 {
 496         int ret;
 497 
 498         *item = lookup_fn(detail, key);
 499         if (!*item)
 500                 return -ENOMEM;
 501  retry:
 502         ret = cache_check(detail, &(*item)->h, &rqstp->rq_chandle);
 503 
 504         if (ret == -ETIMEDOUT) {
 505                 struct ent *prev_item = *item;
 506                 *item = lookup_fn(detail, key);
 507                 if (*item != prev_item)
 508                         goto retry;
 509                 cache_put(&(*item)->h, detail);
 510         }
 511         return ret;
 512 }
 513 
 514 static char *
 515 rqst_authname(struct svc_rqst *rqstp)
 516 {
 517         struct auth_domain *clp;
 518 
 519         clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
 520         return clp->name;
 521 }
 522 
 523 static __be32
 524 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
 525                 u32 *id)
 526 {
 527         struct ent *item, key = {
 528                 .type = type,
 529         };
 530         int ret;
 531         struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 532 
 533         if (namelen + 1 > sizeof(key.name))
 534                 return nfserr_badowner;
 535         memcpy(key.name, name, namelen);
 536         key.name[namelen] = '\0';
 537         strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
 538         ret = idmap_lookup(rqstp, nametoid_lookup, &key, nn->nametoid_cache, &item);
 539         if (ret == -ENOENT)
 540                 return nfserr_badowner;
 541         if (ret)
 542                 return nfserrno(ret);
 543         *id = item->id;
 544         cache_put(&item->h, nn->nametoid_cache);
 545         return 0;
 546 }
 547 
 548 static __be32 encode_ascii_id(struct xdr_stream *xdr, u32 id)
 549 {
 550         char buf[11];
 551         int len;
 552         __be32 *p;
 553 
 554         len = sprintf(buf, "%u", id);
 555         p = xdr_reserve_space(xdr, len + 4);
 556         if (!p)
 557                 return nfserr_resource;
 558         p = xdr_encode_opaque(p, buf, len);
 559         return 0;
 560 }
 561 
 562 static __be32 idmap_id_to_name(struct xdr_stream *xdr,
 563                                struct svc_rqst *rqstp, int type, u32 id)
 564 {
 565         struct ent *item, key = {
 566                 .id = id,
 567                 .type = type,
 568         };
 569         __be32 *p;
 570         int ret;
 571         struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
 572 
 573         strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
 574         ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
 575         if (ret == -ENOENT)
 576                 return encode_ascii_id(xdr, id);
 577         if (ret)
 578                 return nfserrno(ret);
 579         ret = strlen(item->name);
 580         WARN_ON_ONCE(ret > IDMAP_NAMESZ);
 581         p = xdr_reserve_space(xdr, ret + 4);
 582         if (!p)
 583                 return nfserr_resource;
 584         p = xdr_encode_opaque(p, item->name, ret);
 585         cache_put(&item->h, nn->idtoname_cache);
 586         return 0;
 587 }
 588 
 589 static bool
 590 numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
 591 {
 592         int ret;
 593         char buf[11];
 594 
 595         if (namelen + 1 > sizeof(buf))
 596                 /* too long to represent a 32-bit id: */
 597                 return false;
 598         /* Just to make sure it's null-terminated: */
 599         memcpy(buf, name, namelen);
 600         buf[namelen] = '\0';
 601         ret = kstrtouint(buf, 10, id);
 602         return ret == 0;
 603 }
 604 
 605 static __be32
 606 do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
 607 {
 608         if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
 609                 if (numeric_name_to_id(rqstp, type, name, namelen, id))
 610                         return 0;
 611                 /*
 612                  * otherwise, fall through and try idmapping, for
 613                  * backwards compatibility with clients sending names:
 614                  */
 615         return idmap_name_to_id(rqstp, type, name, namelen, id);
 616 }
 617 
 618 static __be32 encode_name_from_id(struct xdr_stream *xdr,
 619                                   struct svc_rqst *rqstp, int type, u32 id)
 620 {
 621         if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
 622                 return encode_ascii_id(xdr, id);
 623         return idmap_id_to_name(xdr, rqstp, type, id);
 624 }
 625 
 626 __be32
 627 nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
 628                 kuid_t *uid)
 629 {
 630         __be32 status;
 631         u32 id = -1;
 632 
 633         if (name == NULL || namelen == 0)
 634                 return nfserr_inval;
 635 
 636         status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id);
 637         *uid = make_kuid(nfsd_user_namespace(rqstp), id);
 638         if (!uid_valid(*uid))
 639                 status = nfserr_badowner;
 640         return status;
 641 }
 642 
 643 __be32
 644 nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
 645                 kgid_t *gid)
 646 {
 647         __be32 status;
 648         u32 id = -1;
 649 
 650         if (name == NULL || namelen == 0)
 651                 return nfserr_inval;
 652 
 653         status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id);
 654         *gid = make_kgid(nfsd_user_namespace(rqstp), id);
 655         if (!gid_valid(*gid))
 656                 status = nfserr_badowner;
 657         return status;
 658 }
 659 
 660 __be32 nfsd4_encode_user(struct xdr_stream *xdr, struct svc_rqst *rqstp,
 661                          kuid_t uid)
 662 {
 663         u32 id = from_kuid_munged(nfsd_user_namespace(rqstp), uid);
 664         return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_USER, id);
 665 }
 666 
 667 __be32 nfsd4_encode_group(struct xdr_stream *xdr, struct svc_rqst *rqstp,
 668                           kgid_t gid)
 669 {
 670         u32 id = from_kgid_munged(nfsd_user_namespace(rqstp), gid);
 671         return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_GROUP, id);
 672 }

/* [<][>][^][v][top][bottom][index][help] */