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 <marius@umich.edu> 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/nfsd_idmap.h> 37#include <linux/seq_file.h> 38#include <linux/sched.h> 39#include <linux/slab.h> 40 41/* 42 * Cache entry 43 */ 44 45 46#define IDMAP_TYPE_USER 0 47#define IDMAP_TYPE_GROUP 1 48 49struct 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]; 55}; 56 57/* Common entry handling */ 58 59#define ENT_HASHBITS 8 60#define ENT_HASHMAX (1 << ENT_HASHBITS) 61#define ENT_HASHMASK (ENT_HASHMAX - 1) 62 63static void 64ent_init(struct cache_head *cnew, struct cache_head *citm) 65{ 66 struct ent *new = container_of(cnew, struct ent, h); 67 struct ent *itm = container_of(citm, struct ent, h); 68 69 new->id = itm->id; 70 new->type = itm->type; 71 72 strlcpy(new->name, itm->name, sizeof(new->name)); 73 strlcpy(new->authname, itm->authname, sizeof(new->name)); 74} 75 76static void 77ent_put(struct kref *ref) 78{ 79 struct ent *map = container_of(ref, struct ent, h.ref); 80 kfree(map); 81} 82 83static struct cache_head * 84ent_alloc(void) 85{ 86 struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL); 87 if (e) 88 return &e->h; 89 else 90 return NULL; 91} 92 93/* 94 * ID -> Name cache 95 */ 96 97static struct cache_head *idtoname_table[ENT_HASHMAX]; 98 99static uint32_t 100idtoname_hash(struct ent *ent) 101{ 102 uint32_t hash; 103 104 hash = hash_str(ent->authname, ENT_HASHBITS); 105 hash = hash_long(hash ^ ent->id, ENT_HASHBITS); 106 107 /* Flip LSB for user/group */ 108 if (ent->type == IDMAP_TYPE_GROUP) 109 hash ^= 1; 110 111 return hash; 112} 113 114static void 115idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, 116 int *blen) 117{ 118 struct ent *ent = container_of(ch, struct ent, h); 119 char idstr[11]; 120 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); 125 126 (*bpp)[-1] = '\n'; 127} 128 129static int 130idtoname_upcall(struct cache_detail *cd, struct cache_head *ch) 131{ 132 return sunrpc_cache_pipe_upcall(cd, ch, idtoname_request); 133} 134 135static int 136idtoname_match(struct cache_head *ca, struct cache_head *cb) 137{ 138 struct ent *a = container_of(ca, struct ent, h); 139 struct ent *b = container_of(cb, struct ent, h); 140 141 return (a->id == b->id && a->type == b->type && 142 strcmp(a->authname, b->authname) == 0); 143} 144 145static int 146idtoname_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) 147{ 148 struct ent *ent; 149 150 if (h == NULL) { 151 seq_puts(m, "#domain type id [name]\n"); 152 return 0; 153 } 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; 162} 163 164static void 165warn_no_idmapd(struct cache_detail *detail, int has_died) 166{ 167 printk("nfsd: nfsv4 idmapping failing: has idmapd %s?\n", 168 has_died ? "died" : "not been started"); 169} 170 171 172static int idtoname_parse(struct cache_detail *, char *, int); 173static struct ent *idtoname_lookup(struct ent *); 174static struct ent *idtoname_update(struct ent *, struct ent *); 175 176static 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, 190}; 191 192static int 193idtoname_parse(struct cache_detail *cd, char *buf, int buflen) 194{ 195 struct ent ent, *res; 196 char *buf1, *bp; 197 int len; 198 int error = -EINVAL; 199 200 if (buf[buflen - 1] != '\n') 201 return (-EINVAL); 202 buf[buflen - 1]= '\0'; 203 204 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL); 205 if (buf1 == NULL) 206 return (-ENOMEM); 207 208 memset(&ent, 0, sizeof(ent)); 209 210 /* Authentication name */ 211 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0) 212 goto out; 213 memcpy(ent.authname, buf1, sizeof(ent.authname)); 214 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; 220 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; 227 228 /* expiry */ 229 ent.h.expiry_time = get_expiry(&buf); 230 if (ent.h.expiry_time == 0) 231 goto out; 232 233 error = -ENOMEM; 234 res = idtoname_lookup(&ent); 235 if (!res) 236 goto out; 237 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; 253 254 cache_put(&res->h, &idtoname_cache); 255 256 error = 0; 257out: 258 kfree(buf1); 259 260 return error; 261} 262 263 264static struct ent * 265idtoname_lookup(struct ent *item) 266{ 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; 274} 275 276static struct ent * 277idtoname_update(struct ent *new, struct ent *old) 278{ 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; 286} 287 288 289/* 290 * Name -> ID cache 291 */ 292 293static struct cache_head *nametoid_table[ENT_HASHMAX]; 294 295static inline int 296nametoid_hash(struct ent *ent) 297{ 298 return hash_str(ent->name, ENT_HASHBITS); 299} 300 301static void 302nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, 303 int *blen) 304{ 305 struct ent *ent = container_of(ch, struct ent, h); 306 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); 310 311 (*bpp)[-1] = '\n'; 312} 313 314static int 315nametoid_upcall(struct cache_detail *cd, struct cache_head *ch) 316{ 317 return sunrpc_cache_pipe_upcall(cd, ch, nametoid_request); 318} 319 320static int 321nametoid_match(struct cache_head *ca, struct cache_head *cb) 322{ 323 struct ent *a = container_of(ca, struct ent, h); 324 struct ent *b = container_of(cb, struct ent, h); 325 326 return (a->type == b->type && strcmp(a->name, b->name) == 0 && 327 strcmp(a->authname, b->authname) == 0); 328} 329 330static int 331nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) 332{ 333 struct ent *ent; 334 335 if (h == NULL) { 336 seq_puts(m, "#domain type name [id]\n"); 337 return 0; 338 } 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; 347} 348 349static struct ent *nametoid_lookup(struct ent *); 350static struct ent *nametoid_update(struct ent *, struct ent *); 351static int nametoid_parse(struct cache_detail *, char *, int); 352 353static 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, 367}; 368 369static int 370nametoid_parse(struct cache_detail *cd, char *buf, int buflen) 371{ 372 struct ent ent, *res; 373 char *buf1; 374 int error = -EINVAL; 375 376 if (buf[buflen - 1] != '\n') 377 return (-EINVAL); 378 buf[buflen - 1]= '\0'; 379 380 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL); 381 if (buf1 == NULL) 382 return (-ENOMEM); 383 384 memset(&ent, 0, sizeof(ent)); 385 386 /* Authentication name */ 387 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0) 388 goto out; 389 memcpy(ent.authname, buf1, sizeof(ent.authname)); 390 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; 396 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)); 402 403 /* expiry */ 404 ent.h.expiry_time = get_expiry(&buf); 405 if (ent.h.expiry_time == 0) 406 goto out; 407 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); 414 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; 422 423 cache_put(&res->h, &nametoid_cache); 424 error = 0; 425out: 426 kfree(buf1); 427 428 return (error); 429} 430 431 432static struct ent * 433nametoid_lookup(struct ent *item) 434{ 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; 442} 443 444static struct ent * 445nametoid_update(struct ent *new, struct ent *old) 446{ 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; 454} 455 456/* 457 * Exported API 458 */ 459 460int 461nfsd_idmap_init(void) 462{ 463 int rv; 464 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; 472} 473 474void 475nfsd_idmap_shutdown(void) 476{ 477 cache_unregister(&idtoname_cache); 478 cache_unregister(&nametoid_cache); 479} 480 481/* 482 * Deferred request handling 483 */ 484 485struct 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; 490}; 491 492static inline void 493put_mdr(struct idmap_defer_req *mdr) 494{ 495 if (atomic_dec_and_test(&mdr->count)) 496 kfree(mdr); 497} 498 499static inline void 500get_mdr(struct idmap_defer_req *mdr) 501{ 502 atomic_inc(&mdr->count); 503} 504 505static void 506idmap_revisit(struct cache_deferred_req *dreq, int toomany) 507{ 508 struct idmap_defer_req *mdr = 509 container_of(dreq, struct idmap_defer_req, deferred_req); 510 511 wake_up(&mdr->waitq); 512 put_mdr(mdr); 513} 514 515static struct cache_deferred_req * 516idmap_defer(struct cache_req *req) 517{ 518 struct idmap_defer_req *mdr = 519 container_of(req, struct idmap_defer_req, req); 520 521 mdr->deferred_req.revisit = idmap_revisit; 522 get_mdr(mdr); 523 return (&mdr->deferred_req); 524} 525 526static inline int 527do_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) 530{ 531 *item = lookup_fn(key); 532 if (!*item) 533 return -ENOMEM; 534 return cache_check(detail, &(*item)->h, &mdr->req); 535} 536 537static inline int 538do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *), 539 struct ent *key, struct cache_detail *detail, 540 struct ent **item) 541{ 542 int ret = -ENOMEM; 543 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; 556out_put: 557 cache_put(&(*item)->h, detail); 558out_err: 559 *item = NULL; 560 return ret; 561} 562 563static int 564idmap_lookup(struct svc_rqst *rqstp, 565 struct ent *(*lookup_fn)(struct ent *), struct ent *key, 566 struct cache_detail *detail, struct ent **item) 567{ 568 struct idmap_defer_req *mdr; 569 int ret; 570 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); 582 } 583 put_mdr(mdr); 584 return ret; 585} 586 587static char * 588rqst_authname(struct svc_rqst *rqstp) 589{ 590 struct auth_domain *clp; 591 592 clp = rqstp->rq_gssclient ? rqstp->rq_gssclient : rqstp->rq_client; 593 return clp->name; 594} 595 596static int 597idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, 598 uid_t *id) 599{ 600 struct ent *item, key = { 601 .type = type, 602 }; 603 int ret; 604 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; 618} 619 620static int 621idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) 622{ 623 struct ent *item, key = { 624 .id = id, 625 .type = type, 626 }; 627 int ret; 628 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; 640} 641 642int 643nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, 644 __u32 *id) 645{ 646 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); 647} 648 649int 650nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, 651 __u32 *id) 652{ 653 return idmap_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id); 654} 655 656int 657nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 658{ 659 return idmap_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); 660} 661 662int 663nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 664{ 665 return idmap_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); 666} 667