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