xref: /linux/fs/nfsd/nfs4idmap.c (revision d141ec2825b4d3ec52f27c43bdd864090159273a)
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