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