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 } 665