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 "auth.h"
42 #include "idmap.h"
43 #include "nfsd.h"
44 #include "netns.h"
45 #include "vfs.h"
46
47 /*
48 * Turn off idmapping when using AUTH_SYS.
49 */
50 static bool nfs4_disable_idmapping = true;
51 module_param(nfs4_disable_idmapping, bool, 0644);
52 MODULE_PARM_DESC(nfs4_disable_idmapping,
53 "Turn off server's NFSv4 idmapping when using 'sec=sys'");
54
55 /*
56 * Cache entry
57 */
58
59 /*
60 * XXX we know that IDMAP_NAMESZ < PAGE_SIZE, but it's ugly to rely on
61 * that.
62 */
63
64 struct ent {
65 struct cache_head h;
66 int type; /* User / Group */
67 u32 id;
68 char name[IDMAP_NAMESZ];
69 char authname[IDMAP_NAMESZ];
70 struct rcu_head rcu_head;
71 };
72
73 /* Common entry handling */
74
75 #define ENT_HASHBITS 8
76 #define ENT_HASHMAX (1 << ENT_HASHBITS)
77
78 static void
ent_init(struct cache_head * cnew,struct cache_head * citm)79 ent_init(struct cache_head *cnew, struct cache_head *citm)
80 {
81 struct ent *new = container_of(cnew, struct ent, h);
82 struct ent *itm = container_of(citm, struct ent, h);
83
84 new->id = itm->id;
85 new->type = itm->type;
86
87 strscpy(new->name, itm->name, sizeof(new->name));
88 strscpy(new->authname, itm->authname, sizeof(new->authname));
89 }
90
91 static void
ent_put(struct kref * ref)92 ent_put(struct kref *ref)
93 {
94 struct ent *map = container_of(ref, struct ent, h.ref);
95 kfree_rcu(map, rcu_head);
96 }
97
98 static struct cache_head *
ent_alloc(void)99 ent_alloc(void)
100 {
101 struct ent *e = kmalloc_obj(*e);
102 if (e)
103 return &e->h;
104 else
105 return NULL;
106 }
107
108 /*
109 * ID -> Name cache
110 */
111
112 static uint32_t
idtoname_hash(struct ent * ent)113 idtoname_hash(struct ent *ent)
114 {
115 uint32_t hash;
116
117 hash = hash_str(ent->authname, ENT_HASHBITS);
118 hash = hash_long(hash ^ ent->id, ENT_HASHBITS);
119
120 /* Flip LSB for user/group */
121 if (ent->type == IDMAP_TYPE_GROUP)
122 hash ^= 1;
123
124 return hash;
125 }
126
127 static int
idtoname_upcall(struct cache_detail * cd,struct cache_head * h)128 idtoname_upcall(struct cache_detail *cd, struct cache_head *h)
129 {
130 return sunrpc_cache_upcall_warn(cd, h);
131 }
132
133 static void
idtoname_request(struct cache_detail * cd,struct cache_head * ch,char ** bpp,int * blen)134 idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
135 int *blen)
136 {
137 struct ent *ent = container_of(ch, struct ent, h);
138 char idstr[11];
139
140 qword_add(bpp, blen, ent->authname);
141 snprintf(idstr, sizeof(idstr), "%u", ent->id);
142 qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");
143 qword_add(bpp, blen, idstr);
144
145 (*bpp)[-1] = '\n';
146 }
147
148 static int
idtoname_match(struct cache_head * ca,struct cache_head * cb)149 idtoname_match(struct cache_head *ca, struct cache_head *cb)
150 {
151 struct ent *a = container_of(ca, struct ent, h);
152 struct ent *b = container_of(cb, struct ent, h);
153
154 return (a->id == b->id && a->type == b->type &&
155 strcmp(a->authname, b->authname) == 0);
156 }
157
158 static int
idtoname_show(struct seq_file * m,struct cache_detail * cd,struct cache_head * h)159 idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
160 {
161 struct ent *ent;
162
163 if (h == NULL) {
164 seq_puts(m, "#domain type id [name]\n");
165 return 0;
166 }
167 ent = container_of(h, struct ent, h);
168 seq_printf(m, "%s %s %u", ent->authname,
169 ent->type == IDMAP_TYPE_GROUP ? "group" : "user",
170 ent->id);
171 if (test_bit(CACHE_VALID, &h->flags))
172 seq_printf(m, " %s", ent->name);
173 seq_putc(m, '\n');
174 return 0;
175 }
176
177 static void
warn_no_idmapd(struct cache_detail * detail,int has_died)178 warn_no_idmapd(struct cache_detail *detail, int has_died)
179 {
180 printk("nfsd: nfsv4 idmapping failing: has idmapd %s?\n",
181 has_died ? "died" : "not been started");
182 }
183
184
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 *,
188 struct ent *);
189
190 static const struct cache_detail idtoname_cache_template = {
191 .owner = THIS_MODULE,
192 .hash_size = ENT_HASHMAX,
193 .name = "nfs4.idtoname",
194 .cache_put = ent_put,
195 .cache_upcall = idtoname_upcall,
196 .cache_request = idtoname_request,
197 .cache_parse = idtoname_parse,
198 .cache_show = idtoname_show,
199 .warn_no_listener = warn_no_idmapd,
200 .match = idtoname_match,
201 .init = ent_init,
202 .update = ent_init,
203 .alloc = ent_alloc,
204 };
205
206 static int
idtoname_parse(struct cache_detail * cd,char * buf,int buflen)207 idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
208 {
209 struct ent ent, *res;
210 char *buf1, *bp;
211 int len;
212 int error = -EINVAL;
213
214 if (buf[buflen - 1] != '\n')
215 return (-EINVAL);
216 buf[buflen - 1]= '\0';
217
218 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
219 if (buf1 == NULL)
220 return (-ENOMEM);
221
222 memset(&ent, 0, sizeof(ent));
223
224 /* Authentication name */
225 len = qword_get(&buf, buf1, PAGE_SIZE);
226 if (len <= 0 || len >= IDMAP_NAMESZ)
227 goto out;
228 memcpy(ent.authname, buf1, sizeof(ent.authname));
229
230 /* Type */
231 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
232 goto out;
233 ent.type = strcmp(buf1, "user") == 0 ?
234 IDMAP_TYPE_USER : IDMAP_TYPE_GROUP;
235
236 /* ID */
237 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
238 goto out;
239 ent.id = simple_strtoul(buf1, &bp, 10);
240 if (bp == buf1)
241 goto out;
242
243 /* expiry */
244 error = get_expiry(&buf, &ent.h.expiry_time);
245 if (error)
246 goto out;
247
248 error = -ENOMEM;
249 res = idtoname_lookup(cd, &ent);
250 if (!res)
251 goto out;
252
253 /* Name */
254 error = -EINVAL;
255 len = qword_get(&buf, buf1, PAGE_SIZE);
256 if (len < 0 || len >= IDMAP_NAMESZ)
257 goto out;
258 if (len == 0)
259 set_bit(CACHE_NEGATIVE, &ent.h.flags);
260 else
261 memcpy(ent.name, buf1, sizeof(ent.name));
262 error = -ENOMEM;
263 res = idtoname_update(cd, &ent, res);
264 if (res == NULL)
265 goto out;
266
267 cache_put(&res->h, cd);
268 error = 0;
269 out:
270 kfree(buf1);
271 return error;
272 }
273
274 static struct ent *
idtoname_lookup(struct cache_detail * cd,struct ent * item)275 idtoname_lookup(struct cache_detail *cd, struct ent *item)
276 {
277 struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
278 idtoname_hash(item));
279 if (ch)
280 return container_of(ch, struct ent, h);
281 else
282 return NULL;
283 }
284
285 static struct ent *
idtoname_update(struct cache_detail * cd,struct ent * new,struct ent * old)286 idtoname_update(struct cache_detail *cd, struct ent *new, struct ent *old)
287 {
288 struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
289 idtoname_hash(new));
290 if (ch)
291 return container_of(ch, struct ent, h);
292 else
293 return NULL;
294 }
295
296
297 /*
298 * Name -> ID cache
299 */
300
301 static inline int
nametoid_hash(struct ent * ent)302 nametoid_hash(struct ent *ent)
303 {
304 return hash_str(ent->name, ENT_HASHBITS);
305 }
306
307 static int
nametoid_upcall(struct cache_detail * cd,struct cache_head * h)308 nametoid_upcall(struct cache_detail *cd, struct cache_head *h)
309 {
310 return sunrpc_cache_upcall_warn(cd, h);
311 }
312
313 static void
nametoid_request(struct cache_detail * cd,struct cache_head * ch,char ** bpp,int * blen)314 nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
315 int *blen)
316 {
317 struct ent *ent = container_of(ch, struct ent, h);
318
319 qword_add(bpp, blen, ent->authname);
320 qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");
321 qword_add(bpp, blen, ent->name);
322
323 (*bpp)[-1] = '\n';
324 }
325
326 static int
nametoid_match(struct cache_head * ca,struct cache_head * cb)327 nametoid_match(struct cache_head *ca, struct cache_head *cb)
328 {
329 struct ent *a = container_of(ca, struct ent, h);
330 struct ent *b = container_of(cb, struct ent, h);
331
332 return (a->type == b->type && strcmp(a->name, b->name) == 0 &&
333 strcmp(a->authname, b->authname) == 0);
334 }
335
336 static int
nametoid_show(struct seq_file * m,struct cache_detail * cd,struct cache_head * h)337 nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
338 {
339 struct ent *ent;
340
341 if (h == NULL) {
342 seq_puts(m, "#domain type name [id]\n");
343 return 0;
344 }
345 ent = container_of(h, struct ent, h);
346 seq_printf(m, "%s %s %s", ent->authname,
347 ent->type == IDMAP_TYPE_GROUP ? "group" : "user",
348 ent->name);
349 if (test_bit(CACHE_VALID, &h->flags))
350 seq_printf(m, " %u", ent->id);
351 seq_putc(m, '\n');
352 return 0;
353 }
354
355 static struct ent *nametoid_lookup(struct cache_detail *, struct ent *);
356 static struct ent *nametoid_update(struct cache_detail *, struct ent *,
357 struct ent *);
358 static int nametoid_parse(struct cache_detail *, char *, int);
359
360 static const struct cache_detail nametoid_cache_template = {
361 .owner = THIS_MODULE,
362 .hash_size = ENT_HASHMAX,
363 .name = "nfs4.nametoid",
364 .cache_put = ent_put,
365 .cache_upcall = nametoid_upcall,
366 .cache_request = nametoid_request,
367 .cache_parse = nametoid_parse,
368 .cache_show = nametoid_show,
369 .warn_no_listener = warn_no_idmapd,
370 .match = nametoid_match,
371 .init = ent_init,
372 .update = ent_init,
373 .alloc = ent_alloc,
374 };
375
376 static int
nametoid_parse(struct cache_detail * cd,char * buf,int buflen)377 nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
378 {
379 struct ent ent, *res;
380 char *buf1;
381 int len, error = -EINVAL;
382
383 if (buf[buflen - 1] != '\n')
384 return (-EINVAL);
385 buf[buflen - 1]= '\0';
386
387 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
388 if (buf1 == NULL)
389 return (-ENOMEM);
390
391 memset(&ent, 0, sizeof(ent));
392
393 /* Authentication name */
394 len = qword_get(&buf, buf1, PAGE_SIZE);
395 if (len <= 0 || len >= IDMAP_NAMESZ)
396 goto out;
397 memcpy(ent.authname, buf1, sizeof(ent.authname));
398
399 /* Type */
400 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
401 goto out;
402 ent.type = strcmp(buf1, "user") == 0 ?
403 IDMAP_TYPE_USER : IDMAP_TYPE_GROUP;
404
405 /* Name */
406 len = qword_get(&buf, buf1, PAGE_SIZE);
407 if (len <= 0 || len >= IDMAP_NAMESZ)
408 goto out;
409 memcpy(ent.name, buf1, sizeof(ent.name));
410
411 /* expiry */
412 error = get_expiry(&buf, &ent.h.expiry_time);
413 if (error)
414 goto out;
415
416 /* ID */
417 error = get_int(&buf, &ent.id);
418 if (error == -EINVAL)
419 goto out;
420 if (error == -ENOENT)
421 set_bit(CACHE_NEGATIVE, &ent.h.flags);
422
423 error = -ENOMEM;
424 res = nametoid_lookup(cd, &ent);
425 if (res == NULL)
426 goto out;
427 res = nametoid_update(cd, &ent, res);
428 if (res == NULL)
429 goto out;
430
431 cache_put(&res->h, cd);
432 error = 0;
433 out:
434 kfree(buf1);
435 return (error);
436 }
437
438
439 static struct ent *
nametoid_lookup(struct cache_detail * cd,struct ent * item)440 nametoid_lookup(struct cache_detail *cd, struct ent *item)
441 {
442 struct cache_head *ch = sunrpc_cache_lookup_rcu(cd, &item->h,
443 nametoid_hash(item));
444 if (ch)
445 return container_of(ch, struct ent, h);
446 else
447 return NULL;
448 }
449
450 static struct ent *
nametoid_update(struct cache_detail * cd,struct ent * new,struct ent * old)451 nametoid_update(struct cache_detail *cd, struct ent *new, struct ent *old)
452 {
453 struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
454 nametoid_hash(new));
455 if (ch)
456 return container_of(ch, struct ent, h);
457 else
458 return NULL;
459 }
460
461 /*
462 * Exported API
463 */
464
465 int
nfsd_idmap_init(struct net * net)466 nfsd_idmap_init(struct net *net)
467 {
468 int rv;
469 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
470
471 nn->idtoname_cache = cache_create_net(&idtoname_cache_template, net);
472 if (IS_ERR(nn->idtoname_cache))
473 return PTR_ERR(nn->idtoname_cache);
474 rv = cache_register_net(nn->idtoname_cache, net);
475 if (rv)
476 goto destroy_idtoname_cache;
477 nn->nametoid_cache = cache_create_net(&nametoid_cache_template, net);
478 if (IS_ERR(nn->nametoid_cache)) {
479 rv = PTR_ERR(nn->nametoid_cache);
480 goto unregister_idtoname_cache;
481 }
482 rv = cache_register_net(nn->nametoid_cache, net);
483 if (rv)
484 goto destroy_nametoid_cache;
485 return 0;
486
487 destroy_nametoid_cache:
488 cache_destroy_net(nn->nametoid_cache, net);
489 unregister_idtoname_cache:
490 cache_unregister_net(nn->idtoname_cache, net);
491 destroy_idtoname_cache:
492 cache_destroy_net(nn->idtoname_cache, net);
493 return rv;
494 }
495
496 void
nfsd_idmap_shutdown(struct net * net)497 nfsd_idmap_shutdown(struct net *net)
498 {
499 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
500
501 cache_unregister_net(nn->idtoname_cache, net);
502 cache_unregister_net(nn->nametoid_cache, net);
503 cache_destroy_net(nn->idtoname_cache, net);
504 cache_destroy_net(nn->nametoid_cache, net);
505 }
506
507 static int
idmap_lookup(struct svc_rqst * rqstp,struct ent * (* lookup_fn)(struct cache_detail *,struct ent *),struct ent * key,struct cache_detail * detail,struct ent ** item)508 idmap_lookup(struct svc_rqst *rqstp,
509 struct ent *(*lookup_fn)(struct cache_detail *, struct ent *),
510 struct ent *key, struct cache_detail *detail, struct ent **item)
511 {
512 int ret;
513
514 *item = lookup_fn(detail, key);
515 if (!*item)
516 return -ENOMEM;
517 retry:
518 ret = cache_check(detail, &(*item)->h, &rqstp->rq_chandle);
519
520 if (ret == -ETIMEDOUT) {
521 struct ent *prev_item = *item;
522 *item = lookup_fn(detail, key);
523 if (*item != prev_item)
524 goto retry;
525 cache_put(&(*item)->h, detail);
526 }
527 return ret;
528 }
529
530 static char *
rqst_authname(struct svc_rqst * rqstp)531 rqst_authname(struct svc_rqst *rqstp)
532 {
533 struct auth_domain *clp;
534
535 clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
536 return clp->name;
537 }
538
539 static __be32
idmap_name_to_id(struct svc_rqst * rqstp,int type,const char * name,u32 namelen,u32 * id)540 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
541 u32 *id)
542 {
543 struct ent *item, key = {
544 .type = type,
545 };
546 int ret;
547 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
548
549 if (namelen + 1 > sizeof(key.name))
550 return nfserr_badowner;
551 memcpy(key.name, name, namelen);
552 key.name[namelen] = '\0';
553 strscpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
554 ret = idmap_lookup(rqstp, nametoid_lookup, &key, nn->nametoid_cache, &item);
555 if (ret == -ENOENT)
556 return nfserr_badowner;
557 if (ret)
558 return nfserrno(ret);
559 *id = item->id;
560 cache_put(&item->h, nn->nametoid_cache);
561 return 0;
562 }
563
encode_ascii_id(struct xdr_stream * xdr,u32 id)564 static __be32 encode_ascii_id(struct xdr_stream *xdr, u32 id)
565 {
566 char buf[11];
567 int len;
568 __be32 *p;
569
570 len = sprintf(buf, "%u", id);
571 p = xdr_reserve_space(xdr, len + 4);
572 if (!p)
573 return nfserr_resource;
574 p = xdr_encode_opaque(p, buf, len);
575 return 0;
576 }
577
idmap_id_to_name(struct xdr_stream * xdr,struct svc_rqst * rqstp,int type,u32 id)578 static __be32 idmap_id_to_name(struct xdr_stream *xdr,
579 struct svc_rqst *rqstp, int type, u32 id)
580 {
581 struct ent *item, key = {
582 .id = id,
583 .type = type,
584 };
585 __be32 status = nfs_ok;
586 __be32 *p;
587 int ret;
588 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
589
590 strscpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
591 ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
592 if (ret == -ENOENT)
593 return encode_ascii_id(xdr, id);
594 if (ret)
595 return nfserrno(ret);
596 ret = strlen(item->name);
597 WARN_ON_ONCE(ret > IDMAP_NAMESZ);
598
599 p = xdr_reserve_space(xdr, ret + 4);
600 if (unlikely(!p)) {
601 status = nfserr_resource;
602 goto out_put;
603 }
604 xdr_encode_opaque(p, item->name, ret);
605 out_put:
606 cache_put(&item->h, nn->idtoname_cache);
607 return status;
608 }
609
610 static bool
numeric_name_to_id(struct svc_rqst * rqstp,int type,const char * name,u32 namelen,u32 * id)611 numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
612 {
613 int ret;
614 char buf[11];
615
616 if (namelen + 1 > sizeof(buf))
617 /* too long to represent a 32-bit id: */
618 return false;
619 /* Just to make sure it's null-terminated: */
620 memcpy(buf, name, namelen);
621 buf[namelen] = '\0';
622 ret = kstrtouint(buf, 10, id);
623 return ret == 0;
624 }
625
626 static __be32
do_name_to_id(struct svc_rqst * rqstp,int type,const char * name,u32 namelen,u32 * id)627 do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
628 {
629 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
630 if (numeric_name_to_id(rqstp, type, name, namelen, id))
631 return 0;
632 /*
633 * otherwise, fall through and try idmapping, for
634 * backwards compatibility with clients sending names:
635 */
636 return idmap_name_to_id(rqstp, type, name, namelen, id);
637 }
638
encode_name_from_id(struct xdr_stream * xdr,struct svc_rqst * rqstp,int type,u32 id)639 static __be32 encode_name_from_id(struct xdr_stream *xdr,
640 struct svc_rqst *rqstp, int type, u32 id)
641 {
642 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
643 return encode_ascii_id(xdr, id);
644 return idmap_id_to_name(xdr, rqstp, type, id);
645 }
646
647 /**
648 * nfsd_map_name_to_uid - Map user@domain to local UID
649 * @rqstp: RPC execution context
650 * @name: user@domain name to be mapped
651 * @namelen: length of name, in bytes
652 * @uid: OUT: mapped local UID value
653 *
654 * Returns nfs_ok on success or an NFSv4 status code on failure.
655 */
nfsd_map_name_to_uid(struct svc_rqst * rqstp,const char * name,size_t namelen,kuid_t * uid)656 __be32 nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name,
657 size_t namelen, kuid_t *uid)
658 {
659 __be32 status;
660 u32 id = -1;
661
662 /*
663 * The idmap lookup below triggers an upcall that invokes
664 * cache_check(). RQ_USEDEFERRAL must be clear to prevent
665 * cache_check() from setting RQ_DROPME via svc_defer().
666 * NFSv4 servers are not permitted to drop requests. Also
667 * RQ_DROPME will force NFSv4.1 session slot processing to
668 * be skipped.
669 */
670 WARN_ON_ONCE(test_bit(RQ_USEDEFERRAL, &rqstp->rq_flags));
671
672 if (name == NULL || namelen == 0)
673 return nfserr_inval;
674
675 status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id);
676 if (status)
677 return status;
678 *uid = make_kuid(nfsd_user_namespace(rqstp), id);
679 if (!uid_valid(*uid))
680 status = nfserr_badowner;
681 return status;
682 }
683
684 /**
685 * nfsd_map_name_to_gid - Map user@domain to local GID
686 * @rqstp: RPC execution context
687 * @name: user@domain name to be mapped
688 * @namelen: length of name, in bytes
689 * @gid: OUT: mapped local GID value
690 *
691 * Returns nfs_ok on success or an NFSv4 status code on failure.
692 */
nfsd_map_name_to_gid(struct svc_rqst * rqstp,const char * name,size_t namelen,kgid_t * gid)693 __be32 nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name,
694 size_t namelen, kgid_t *gid)
695 {
696 __be32 status;
697 u32 id = -1;
698
699 /*
700 * The idmap lookup below triggers an upcall that invokes
701 * cache_check(). RQ_USEDEFERRAL must be clear to prevent
702 * cache_check() from setting RQ_DROPME via svc_defer().
703 * NFSv4 servers are not permitted to drop requests. Also
704 * RQ_DROPME will force NFSv4.1 session slot processing to
705 * be skipped.
706 */
707 WARN_ON_ONCE(test_bit(RQ_USEDEFERRAL, &rqstp->rq_flags));
708
709 if (name == NULL || namelen == 0)
710 return nfserr_inval;
711
712 status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id);
713 if (status)
714 return status;
715 *gid = make_kgid(nfsd_user_namespace(rqstp), id);
716 if (!gid_valid(*gid))
717 status = nfserr_badowner;
718 return status;
719 }
720
nfsd4_encode_user(struct xdr_stream * xdr,struct svc_rqst * rqstp,kuid_t uid)721 __be32 nfsd4_encode_user(struct xdr_stream *xdr, struct svc_rqst *rqstp,
722 kuid_t uid)
723 {
724 u32 id = from_kuid_munged(nfsd_user_namespace(rqstp), uid);
725 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_USER, id);
726 }
727
nfsd4_encode_group(struct xdr_stream * xdr,struct svc_rqst * rqstp,kgid_t gid)728 __be32 nfsd4_encode_group(struct xdr_stream *xdr, struct svc_rqst *rqstp,
729 kgid_t gid)
730 {
731 u32 id = from_kgid_munged(nfsd_user_namespace(rqstp), gid);
732 return encode_name_from_id(xdr, rqstp, IDMAP_TYPE_GROUP, id);
733 }
734