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