Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nfs4idmap.c
Go to the documentation of this file.
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 <[email protected]>
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  */
48 static bool nfs4_disable_idmapping = true;
49 module_param(nfs4_disable_idmapping, bool, 0644);
50 MODULE_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 
65 struct ent {
66  struct cache_head h;
67  int type; /* User / Group */
71 };
72 
73 /* Common entry handling */
74 
75 #define ENT_HASHBITS 8
76 #define ENT_HASHMAX (1 << ENT_HASHBITS)
77 
78 static void
79 ent_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 
91 static void
92 ent_put(struct kref *ref)
93 {
94  struct ent *map = container_of(ref, struct ent, h.ref);
95  kfree(map);
96 }
97 
98 static struct cache_head *
99 ent_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 
112 static uint32_t
113 idtoname_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 
127 static void
128 idtoname_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 
142 static int
143 idtoname_upcall(struct cache_detail *cd, struct cache_head *ch)
144 {
145  return sunrpc_cache_pipe_upcall(cd, ch, idtoname_request);
146 }
147 
148 static int
149 idtoname_match(struct cache_head *ca, struct cache_head *cb)
150 {
151  struct ent *a = container_of(ca, struct ent, h);
152  struct ent *b = container_of(cb, struct ent, h);
153 
154  return (a->id == b->id && a->type == b->type &&
155  strcmp(a->authname, b->authname) == 0);
156 }
157 
158 static int
159 idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)
160 {
161  struct ent *ent;
162 
163  if (h == NULL) {
164  seq_puts(m, "#domain type id [name]\n");
165  return 0;
166  }
167  ent = container_of(h, struct ent, h);
168  seq_printf(m, "%s %s %u", ent->authname,
169  ent->type == IDMAP_TYPE_GROUP ? "group" : "user",
170  ent->id);
171  if (test_bit(CACHE_VALID, &h->flags))
172  seq_printf(m, " %s", ent->name);
173  seq_printf(m, "\n");
174  return 0;
175 }
176 
177 static void
178 warn_no_idmapd(struct cache_detail *detail, int has_died)
179 {
180  printk("nfsd: nfsv4 idmapping failing: has idmapd %s?\n",
181  has_died ? "died" : "not been started");
182 }
183 
184 
185 static int idtoname_parse(struct cache_detail *, char *, int);
186 static struct ent *idtoname_lookup(struct cache_detail *, struct ent *);
187 static struct ent *idtoname_update(struct cache_detail *, struct ent *,
188  struct ent *);
189 
190 static struct cache_detail idtoname_cache_template = {
191  .owner = THIS_MODULE,
192  .hash_size = ENT_HASHMAX,
193  .name = "nfs4.idtoname",
194  .cache_put = ent_put,
195  .cache_upcall = idtoname_upcall,
196  .cache_parse = idtoname_parse,
197  .cache_show = idtoname_show,
198  .warn_no_listener = warn_no_idmapd,
199  .match = idtoname_match,
200  .init = ent_init,
201  .update = ent_init,
202  .alloc = ent_alloc,
203 };
204 
205 static int
206 idtoname_parse(struct cache_detail *cd, char *buf, int buflen)
207 {
208  struct ent ent, *res;
209  char *buf1, *bp;
210  int len;
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 ?
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(cd, &ent);
248  if (!res)
249  goto out;
250 
251  /* Name */
252  error = -EINVAL;
253  len = qword_get(&buf, buf1, PAGE_SIZE);
254  if (len < 0)
255  goto out;
256  if (len == 0)
257  set_bit(CACHE_NEGATIVE, &ent.h.flags);
258  else if (len >= IDMAP_NAMESZ)
259  goto out;
260  else
261  memcpy(ent.name, buf1, sizeof(ent.name));
262  error = -ENOMEM;
263  res = idtoname_update(cd, &ent, res);
264  if (res == NULL)
265  goto out;
266 
267  cache_put(&res->h, cd);
268 
269  error = 0;
270 out:
271  kfree(buf1);
272 
273  return error;
274 }
275 
276 
277 static struct ent *
278 idtoname_lookup(struct cache_detail *cd, struct ent *item)
279 {
280  struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h,
281  idtoname_hash(item));
282  if (ch)
283  return container_of(ch, struct ent, h);
284  else
285  return NULL;
286 }
287 
288 static struct ent *
289 idtoname_update(struct cache_detail *cd, struct ent *new, struct ent *old)
290 {
291  struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
292  idtoname_hash(new));
293  if (ch)
294  return container_of(ch, struct ent, h);
295  else
296  return NULL;
297 }
298 
299 
300 /*
301  * Name -> ID cache
302  */
303 
304 static inline int
305 nametoid_hash(struct ent *ent)
306 {
307  return hash_str(ent->name, ENT_HASHBITS);
308 }
309 
310 static void
311 nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp,
312  int *blen)
313 {
314  struct ent *ent = container_of(ch, struct ent, h);
315 
316  qword_add(bpp, blen, ent->authname);
317  qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user");
318  qword_add(bpp, blen, ent->name);
319 
320  (*bpp)[-1] = '\n';
321 }
322 
323 static int
324 nametoid_upcall(struct cache_detail *cd, struct cache_head *ch)
325 {
326  return sunrpc_cache_pipe_upcall(cd, ch, nametoid_request);
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, " %u", ent->id);
354  seq_printf(m, "\n");
355  return 0;
356 }
357 
358 static struct ent *nametoid_lookup(struct cache_detail *, struct ent *);
359 static struct ent *nametoid_update(struct cache_detail *, struct ent *,
360  struct ent *);
361 static int nametoid_parse(struct cache_detail *, char *, int);
362 
363 static struct cache_detail nametoid_cache_template = {
364  .owner = THIS_MODULE,
365  .hash_size = ENT_HASHMAX,
366  .name = "nfs4.nametoid",
367  .cache_put = ent_put,
368  .cache_upcall = nametoid_upcall,
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 ?
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(cd, &ent);
426  if (res == NULL)
427  goto out;
428  res = nametoid_update(cd, &ent, res);
429  if (res == NULL)
430  goto out;
431 
432  cache_put(&res->h, cd);
433  error = 0;
434 out:
435  kfree(buf1);
436 
437  return (error);
438 }
439 
440 
441 static struct ent *
442 nametoid_lookup(struct cache_detail *cd, struct ent *item)
443 {
444  struct cache_head *ch = sunrpc_cache_lookup(cd, &item->h,
445  nametoid_hash(item));
446  if (ch)
447  return container_of(ch, struct ent, h);
448  else
449  return NULL;
450 }
451 
452 static struct ent *
453 nametoid_update(struct cache_detail *cd, struct ent *new, struct ent *old)
454 {
455  struct cache_head *ch = sunrpc_cache_update(cd, &new->h, &old->h,
456  nametoid_hash(new));
457  if (ch)
458  return container_of(ch, struct ent, h);
459  else
460  return NULL;
461 }
462 
463 /*
464  * Exported API
465  */
466 
467 int
469 {
470  int rv;
471  struct nfsd_net *nn = net_generic(net, nfsd_net_id);
472 
473  nn->idtoname_cache = cache_create_net(&idtoname_cache_template, net);
474  if (IS_ERR(nn->idtoname_cache))
475  return PTR_ERR(nn->idtoname_cache);
476  rv = cache_register_net(nn->idtoname_cache, net);
477  if (rv)
478  goto destroy_idtoname_cache;
479  nn->nametoid_cache = cache_create_net(&nametoid_cache_template, net);
480  if (IS_ERR(nn->nametoid_cache)) {
481  rv = PTR_ERR(nn->nametoid_cache);
482  goto unregister_idtoname_cache;
483  }
484  rv = cache_register_net(nn->nametoid_cache, net);
485  if (rv)
486  goto destroy_nametoid_cache;
487  return 0;
488 
489 destroy_nametoid_cache:
491 unregister_idtoname_cache:
493 destroy_idtoname_cache:
495  return rv;
496 }
497 
498 void
500 {
501  struct nfsd_net *nn = net_generic(net, nfsd_net_id);
502 
507 }
508 
509 static int
510 idmap_lookup(struct svc_rqst *rqstp,
511  struct ent *(*lookup_fn)(struct cache_detail *, struct ent *),
512  struct ent *key, struct cache_detail *detail, struct ent **item)
513 {
514  int ret;
515 
516  *item = lookup_fn(detail, key);
517  if (!*item)
518  return -ENOMEM;
519  retry:
520  ret = cache_check(detail, &(*item)->h, &rqstp->rq_chandle);
521 
522  if (ret == -ETIMEDOUT) {
523  struct ent *prev_item = *item;
524  *item = lookup_fn(detail, key);
525  if (*item != prev_item)
526  goto retry;
527  cache_put(&(*item)->h, detail);
528  }
529  return ret;
530 }
531 
532 static char *
533 rqst_authname(struct svc_rqst *rqstp)
534 {
535  struct auth_domain *clp;
536 
537  clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client;
538  return clp->name;
539 }
540 
541 static __be32
542 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
543  uid_t *id)
544 {
545  struct ent *item, key = {
546  .type = type,
547  };
548  int ret;
549  struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
550 
551  if (namelen + 1 > sizeof(key.name))
552  return nfserr_badowner;
553  memcpy(key.name, name, namelen);
554  key.name[namelen] = '\0';
555  strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
556  ret = idmap_lookup(rqstp, nametoid_lookup, &key, nn->nametoid_cache, &item);
557  if (ret == -ENOENT)
558  return nfserr_badowner;
559  if (ret)
560  return nfserrno(ret);
561  *id = item->id;
562  cache_put(&item->h, nn->nametoid_cache);
563  return 0;
564 }
565 
566 static int
567 idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
568 {
569  struct ent *item, key = {
570  .id = id,
571  .type = type,
572  };
573  int ret;
574  struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
575 
576  strlcpy(key.authname, rqst_authname(rqstp), sizeof(key.authname));
577  ret = idmap_lookup(rqstp, idtoname_lookup, &key, nn->idtoname_cache, &item);
578  if (ret == -ENOENT)
579  return sprintf(name, "%u", id);
580  if (ret)
581  return ret;
582  ret = strlen(item->name);
583  BUG_ON(ret > IDMAP_NAMESZ);
584  memcpy(name, item->name, ret);
585  cache_put(&item->h, nn->idtoname_cache);
586  return ret;
587 }
588 
589 static bool
590 numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id)
591 {
592  int ret;
593  char buf[11];
594 
595  if (namelen + 1 > sizeof(buf))
596  /* too long to represent a 32-bit id: */
597  return false;
598  /* Just to make sure it's null-terminated: */
599  memcpy(buf, name, namelen);
600  buf[namelen] = '\0';
601  ret = kstrtouint(buf, 10, id);
602  return ret == 0;
603 }
604 
605 static __be32
606 do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id)
607 {
608  if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
609  if (numeric_name_to_id(rqstp, type, name, namelen, id))
610  return 0;
611  /*
612  * otherwise, fall through and try idmapping, for
613  * backwards compatibility with clients sending names:
614  */
615  return idmap_name_to_id(rqstp, type, name, namelen, id);
616 }
617 
618 static int
619 do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
620 {
621  if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
622  return sprintf(name, "%u", id);
623  return idmap_id_to_name(rqstp, type, id, name);
624 }
625 
626 __be32
627 nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
628  __u32 *id)
629 {
630  return do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id);
631 }
632 
633 __be32
634 nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
635  __u32 *id)
636 {
637  return do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id);
638 }
639 
640 int
641 nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
642 {
643  return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name);
644 }
645 
646 int
647 nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name)
648 {
649  return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name);
650 }