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