GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / fs / nfsd / nfs4idmap.c
blobd0a42a1ec2b3af1c816d4cd4d6c5ec27f994ec43
1 /*
2 * Mapping of UID/GIDs to name and vice versa.
4 * Copyright (c) 2002, 2003 The Regents of the University of
5 * Michigan. All rights reserved.
7 * Marius Aamodt Eriksen <marius@umich.edu>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
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.
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.
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>
42 * Cache entry
46 #define IDMAP_TYPE_USER 0
47 #define IDMAP_TYPE_GROUP 1
49 struct 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];
57 /* Common entry handling */
59 #define ENT_HASHBITS 8
60 #define ENT_HASHMAX (1 << ENT_HASHBITS)
61 #define ENT_HASHMASK (ENT_HASHMAX - 1)
63 static void
64 ent_init(struct cache_head *cnew, struct cache_head *citm)
66 struct ent *new = container_of(cnew, struct ent, h);
67 struct ent *itm = container_of(citm, struct ent, h);
69 new->id = itm->id;
70 new->type = itm->type;
72 strlcpy(new->name, itm->name, sizeof(new->name));
73 strlcpy(new->authname, itm->authname, sizeof(new->name));
76 static void
77 ent_put(struct kref *ref)
79 struct ent *map = container_of(ref, struct ent, h.ref);
80 kfree(map);
83 static struct cache_head *
84 ent_alloc(void)
86 struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL);
87 if (e)
88 return &e->h;
89 else
90 return NULL;
94 * ID -> Name cache
97 static struct cache_head *idtoname_table[ENT_HASHMAX];
99 static uint32_t
100 idtoname_hash(struct ent *ent)
102 uint32_t hash;
104 hash = hash_str(ent->authname, ENT_HASHBITS);
105 hash = hash_long(hash ^ ent->id, ENT_HASHBITS);
107 /* Flip LSB for user/group */
108 if (ent->type == IDMAP_TYPE_GROUP)
109 hash ^= 1;
111 return hash;
114 static void
115 idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
116 int *blen)
118 struct ent *ent = container_of(ch, struct ent, h);
119 char idstr[11];
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);
126 (*bpp)[-1] = '\n';
129 static int
130 idtoname_upcall(struct cache_detail *cd, struct cache_head *ch)
132 return sunrpc_cache_pipe_upcall(cd, ch, idtoname_request);
135 static int
136 idtoname_match(struct cache_head *ca, struct cache_head *cb)
138 struct ent *a = container_of(ca, struct ent, h);
139 struct ent *b = container_of(cb, struct ent, h);
141 return (a->id == b->id && a->type == b->type &&
142 strcmp(a->authname, b->authname) == 0);
145 static int
146 idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
148 struct ent *ent;
150 if (h == NULL) {
151 seq_puts(m, "#domain type id [name]\n");
152 return 0;
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;
164 static void
165 warn_no_idmapd(struct cache_detail *detail, int has_died)
167 printk("nfsd: nfsv4 idmapping failing: has idmapd %s?\n",
168 has_died ? "died" : "not been started");
172 static int idtoname_parse(struct cache_detail *, char *, int);
173 static struct ent *idtoname_lookup(struct ent *);
174 static struct ent *idtoname_update(struct ent *, struct ent *);
176 static 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,
192 static int
193 idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
195 struct ent ent, *res;
196 char *buf1, *bp;
197 int len;
198 int error = -EINVAL;
200 if (buf[buflen - 1] != '\n')
201 return (-EINVAL);
202 buf[buflen - 1]= '\0';
204 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
205 if (buf1 == NULL)
206 return (-ENOMEM);
208 memset(&ent, 0, sizeof(ent));
210 /* Authentication name */
211 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
212 goto out;
213 memcpy(ent.authname, buf1, sizeof(ent.authname));
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;
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;
228 /* expiry */
229 ent.h.expiry_time = get_expiry(&buf);
230 if (ent.h.expiry_time == 0)
231 goto out;
233 error = -ENOMEM;
234 res = idtoname_lookup(&ent);
235 if (!res)
236 goto out;
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;
254 cache_put(&res->h, &idtoname_cache);
256 error = 0;
257 out:
258 kfree(buf1);
260 return error;
264 static struct ent *
265 idtoname_lookup(struct ent *item)
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;
276 static struct ent *
277 idtoname_update(struct ent *new, struct ent *old)
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;
290 * Name -> ID cache
293 static struct cache_head *nametoid_table[ENT_HASHMAX];
295 static inline int
296 nametoid_hash(struct ent *ent)
298 return hash_str(ent->name, ENT_HASHBITS);
301 static void
302 nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
303 int *blen)
305 struct ent *ent = container_of(ch, struct ent, h);
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);
311 (*bpp)[-1] = '\n';
314 static int
315 nametoid_upcall(struct cache_detail *cd, struct cache_head *ch)
317 return sunrpc_cache_pipe_upcall(cd, ch, nametoid_request);
320 static int
321 nametoid_match(struct cache_head *ca, struct cache_head *cb)
323 struct ent *a = container_of(ca, struct ent, h);
324 struct ent *b = container_of(cb, struct ent, h);
326 return (a->type == b->type && strcmp(a->name, b->name) == 0 &&
327 strcmp(a->authname, b->authname) == 0);
330 static int
331 nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
333 struct ent *ent;
335 if (h == NULL) {
336 seq_puts(m, "#domain type name [id]\n");
337 return 0;
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;
349 static struct ent *nametoid_lookup(struct ent *);
350 static struct ent *nametoid_update(struct ent *, struct ent *);
351 static int nametoid_parse(struct cache_detail *, char *, int);
353 static 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,
369 static int
370 nametoid_parse(struct cache_detail *cd, char *buf, int buflen)
372 struct ent ent, *res;
373 char *buf1;
374 int error = -EINVAL;
376 if (buf[buflen - 1] != '\n')
377 return (-EINVAL);
378 buf[buflen - 1]= '\0';
380 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL);
381 if (buf1 == NULL)
382 return (-ENOMEM);
384 memset(&ent, 0, sizeof(ent));
386 /* Authentication name */
387 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0)
388 goto out;
389 memcpy(ent.authname, buf1, sizeof(ent.authname));
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;
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));
403 /* expiry */
404 ent.h.expiry_time = get_expiry(&buf);
405 if (ent.h.expiry_time == 0)
406 goto out;
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);
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;
423 cache_put(&res->h, &nametoid_cache);
424 error = 0;
425 out:
426 kfree(buf1);
428 return (error);
432 static struct ent *
433 nametoid_lookup(struct ent *item)
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;
444 static struct ent *
445 nametoid_update(struct ent *new, struct ent *old)
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;
457 * Exported API
461 nfsd_idmap_init(void)
463 int rv;
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;
474 void
475 nfsd_idmap_shutdown(void)
477 cache_unregister(&idtoname_cache);
478 cache_unregister(&nametoid_cache);
482 * Deferred request handling
485 struct 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;
492 static inline void
493 put_mdr(struct idmap_defer_req *mdr)
495 if (atomic_dec_and_test(&mdr->count))
496 kfree(mdr);
499 static inline void
500 get_mdr(struct idmap_defer_req *mdr)
502 atomic_inc(&mdr->count);
505 static void
506 idmap_revisit(struct cache_deferred_req *dreq, int toomany)
508 struct idmap_defer_req *mdr =
509 container_of(dreq, struct idmap_defer_req, deferred_req);
511 wake_up(&mdr->waitq);
512 put_mdr(mdr);
515 static struct cache_deferred_req *
516 idmap_defer(struct cache_req *req)
518 struct idmap_defer_req *mdr =
519 container_of(req, struct idmap_defer_req, req);
521 mdr->deferred_req.revisit = idmap_revisit;
522 get_mdr(mdr);
523 return (&mdr->deferred_req);
526 static inline int
527 do_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)
531 *item = lookup_fn(key);
532 if (!*item)
533 return -ENOMEM;
534 return cache_check(detail, &(*item)->h, &mdr->req);
537 static inline int
538 do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *),
539 struct ent *key, struct cache_detail *detail,
540 struct ent **item)
542 int ret = -ENOMEM;
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;
556 out_put:
557 cache_put(&(*item)->h, detail);
558 out_err:
559 *item = NULL;
560 return ret;
563 static int
564 idmap_lookup(struct svc_rqst *rqstp,
565 struct ent *(*lookup_fn)(struct ent *), struct ent *key,
566 struct cache_detail *detail, struct ent **item)
568 struct idmap_defer_req *mdr;
569 int ret;
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);
583 put_mdr(mdr);
584 return ret;
587 static char *
588 rqst_authname(struct svc_rqst *rqstp)
590 struct auth_domain *clp;
592 clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
593 return clp->name;
596 static int
597 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
598 uid_t *id)
600 struct ent *item, key = {
601 .type = type,
603 int ret;
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;
620 static int
621 idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
623 struct ent *item, key = {
624 .id = id,
625 .type = type,
627 int ret;
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;
643 nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
644 __u32 *id)
646 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id);
650 nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
651 __u32 *id)
653 return idmap_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id);
657 nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
659 return idmap_id_to_name(rqstp, IDMAP_TYPE_USER, id, name);
663 nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
665 return idmap_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name);