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 #define DefineSimpleCacheLookupMap(STRUCT, FUNC) \ 80 DefineCacheLookup(struct STRUCT, h, FUNC##_lookup, \ 81 (struct STRUCT *item, int set), /*no setup */, \ 82 & FUNC##_cache, FUNC##_hash(item), FUNC##_match(item, tmp), \ 83 STRUCT##_init(new, item), STRUCT##_update(tmp, item), 0) 84 85 /* Common entry handling */ 86 87 #define ENT_HASHBITS 8 88 #define ENT_HASHMAX (1 << ENT_HASHBITS) 89 #define ENT_HASHMASK (ENT_HASHMAX - 1) 90 91 static inline void 92 ent_init(struct ent *new, struct ent *itm) 93 { 94 new->id = itm->id; 95 new->type = itm->type; 96 97 strlcpy(new->name, itm->name, sizeof(new->name)); 98 strlcpy(new->authname, itm->authname, sizeof(new->name)); 99 } 100 101 static inline void 102 ent_update(struct ent *new, struct ent *itm) 103 { 104 ent_init(new, itm); 105 } 106 107 static void 108 ent_put(struct cache_head *ch, struct cache_detail *cd) 109 { 110 if (cache_put(ch, cd)) { 111 struct ent *map = container_of(ch, struct ent, h); 112 kfree(map); 113 } 114 } 115 116 /* 117 * ID -> Name cache 118 */ 119 120 static struct cache_head *idtoname_table[ENT_HASHMAX]; 121 122 static uint32_t 123 idtoname_hash(struct ent *ent) 124 { 125 uint32_t hash; 126 127 hash = hash_str(ent->authname, ENT_HASHBITS); 128 hash = hash_long(hash ^ ent->id, ENT_HASHBITS); 129 130 /* Flip LSB for user/group */ 131 if (ent->type == IDMAP_TYPE_GROUP) 132 hash ^= 1; 133 134 return hash; 135 } 136 137 static void 138 idtoname_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, 139 int *blen) 140 { 141 struct ent *ent = container_of(ch, struct ent, h); 142 char idstr[11]; 143 144 qword_add(bpp, blen, ent->authname); 145 snprintf(idstr, sizeof(idstr), "%d", ent->id); 146 qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user"); 147 qword_add(bpp, blen, idstr); 148 149 (*bpp)[-1] = '\n'; 150 } 151 152 static inline int 153 idtoname_match(struct ent *a, struct ent *b) 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 *, int); 188 189 static struct cache_detail idtoname_cache = { 190 .owner = THIS_MODULE, 191 .hash_size = ENT_HASHMAX, 192 .hash_table = idtoname_table, 193 .name = "nfs4.idtoname", 194 .cache_put = ent_put, 195 .cache_request = idtoname_request, 196 .cache_parse = idtoname_parse, 197 .cache_show = idtoname_show, 198 .warn_no_listener = warn_no_idmapd, 199 }; 200 201 int 202 idtoname_parse(struct cache_detail *cd, char *buf, int buflen) 203 { 204 struct ent ent, *res; 205 char *buf1, *bp; 206 int error = -EINVAL; 207 208 if (buf[buflen - 1] != '\n') 209 return (-EINVAL); 210 buf[buflen - 1]= '\0'; 211 212 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL); 213 if (buf1 == NULL) 214 return (-ENOMEM); 215 216 memset(&ent, 0, sizeof(ent)); 217 218 /* Authentication name */ 219 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0) 220 goto out; 221 memcpy(ent.authname, buf1, sizeof(ent.authname)); 222 223 /* Type */ 224 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0) 225 goto out; 226 ent.type = strcmp(buf1, "user") == 0 ? 227 IDMAP_TYPE_USER : IDMAP_TYPE_GROUP; 228 229 /* ID */ 230 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0) 231 goto out; 232 ent.id = simple_strtoul(buf1, &bp, 10); 233 if (bp == buf1) 234 goto out; 235 236 /* expiry */ 237 ent.h.expiry_time = get_expiry(&buf); 238 if (ent.h.expiry_time == 0) 239 goto out; 240 241 /* Name */ 242 error = qword_get(&buf, buf1, PAGE_SIZE); 243 if (error == -EINVAL) 244 goto out; 245 if (error == -ENOENT) 246 set_bit(CACHE_NEGATIVE, &ent.h.flags); 247 else { 248 if (error >= IDMAP_NAMESZ) { 249 error = -EINVAL; 250 goto out; 251 } 252 memcpy(ent.name, buf1, sizeof(ent.name)); 253 } 254 error = -ENOMEM; 255 if ((res = idtoname_lookup(&ent, 1)) == NULL) 256 goto out; 257 258 ent_put(&res->h, &idtoname_cache); 259 260 error = 0; 261 out: 262 kfree(buf1); 263 264 return error; 265 } 266 267 static DefineSimpleCacheLookupMap(ent, idtoname); 268 269 /* 270 * Name -> ID cache 271 */ 272 273 static struct cache_head *nametoid_table[ENT_HASHMAX]; 274 275 static inline int 276 nametoid_hash(struct ent *ent) 277 { 278 return hash_str(ent->name, ENT_HASHBITS); 279 } 280 281 static void 282 nametoid_request(struct cache_detail *cd, struct cache_head *ch, char **bpp, 283 int *blen) 284 { 285 struct ent *ent = container_of(ch, struct ent, h); 286 287 qword_add(bpp, blen, ent->authname); 288 qword_add(bpp, blen, ent->type == IDMAP_TYPE_GROUP ? "group" : "user"); 289 qword_add(bpp, blen, ent->name); 290 291 (*bpp)[-1] = '\n'; 292 } 293 294 static inline int 295 nametoid_match(struct ent *a, struct ent *b) 296 { 297 return (a->type == b->type && strcmp(a->name, b->name) == 0 && 298 strcmp(a->authname, b->authname) == 0); 299 } 300 301 static int 302 nametoid_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h) 303 { 304 struct ent *ent; 305 306 if (h == NULL) { 307 seq_puts(m, "#domain type name [id]\n"); 308 return 0; 309 } 310 ent = container_of(h, struct ent, h); 311 seq_printf(m, "%s %s %s", ent->authname, 312 ent->type == IDMAP_TYPE_GROUP ? "group" : "user", 313 ent->name); 314 if (test_bit(CACHE_VALID, &h->flags)) 315 seq_printf(m, " %d", ent->id); 316 seq_printf(m, "\n"); 317 return 0; 318 } 319 320 static struct ent *nametoid_lookup(struct ent *, int); 321 static int nametoid_parse(struct cache_detail *, char *, int); 322 323 static struct cache_detail nametoid_cache = { 324 .owner = THIS_MODULE, 325 .hash_size = ENT_HASHMAX, 326 .hash_table = nametoid_table, 327 .name = "nfs4.nametoid", 328 .cache_put = ent_put, 329 .cache_request = nametoid_request, 330 .cache_parse = nametoid_parse, 331 .cache_show = nametoid_show, 332 .warn_no_listener = warn_no_idmapd, 333 }; 334 335 static int 336 nametoid_parse(struct cache_detail *cd, char *buf, int buflen) 337 { 338 struct ent ent, *res; 339 char *buf1; 340 int error = -EINVAL; 341 342 if (buf[buflen - 1] != '\n') 343 return (-EINVAL); 344 buf[buflen - 1]= '\0'; 345 346 buf1 = kmalloc(PAGE_SIZE, GFP_KERNEL); 347 if (buf1 == NULL) 348 return (-ENOMEM); 349 350 memset(&ent, 0, sizeof(ent)); 351 352 /* Authentication name */ 353 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0) 354 goto out; 355 memcpy(ent.authname, buf1, sizeof(ent.authname)); 356 357 /* Type */ 358 if (qword_get(&buf, buf1, PAGE_SIZE) <= 0) 359 goto out; 360 ent.type = strcmp(buf1, "user") == 0 ? 361 IDMAP_TYPE_USER : IDMAP_TYPE_GROUP; 362 363 /* Name */ 364 error = qword_get(&buf, buf1, PAGE_SIZE); 365 if (error <= 0 || error >= IDMAP_NAMESZ) 366 goto out; 367 memcpy(ent.name, buf1, sizeof(ent.name)); 368 369 /* expiry */ 370 ent.h.expiry_time = get_expiry(&buf); 371 if (ent.h.expiry_time == 0) 372 goto out; 373 374 /* ID */ 375 error = get_int(&buf, &ent.id); 376 if (error == -EINVAL) 377 goto out; 378 if (error == -ENOENT) 379 set_bit(CACHE_NEGATIVE, &ent.h.flags); 380 381 error = -ENOMEM; 382 if ((res = nametoid_lookup(&ent, 1)) == NULL) 383 goto out; 384 385 ent_put(&res->h, &nametoid_cache); 386 error = 0; 387 out: 388 kfree(buf1); 389 390 return (error); 391 } 392 393 static DefineSimpleCacheLookupMap(ent, nametoid); 394 395 /* 396 * Exported API 397 */ 398 399 void 400 nfsd_idmap_init(void) 401 { 402 cache_register(&idtoname_cache); 403 cache_register(&nametoid_cache); 404 } 405 406 void 407 nfsd_idmap_shutdown(void) 408 { 409 if (cache_unregister(&idtoname_cache)) 410 printk(KERN_ERR "nfsd: failed to unregister idtoname cache\n"); 411 if (cache_unregister(&nametoid_cache)) 412 printk(KERN_ERR "nfsd: failed to unregister nametoid cache\n"); 413 } 414 415 /* 416 * Deferred request handling 417 */ 418 419 struct idmap_defer_req { 420 struct cache_req req; 421 struct cache_deferred_req deferred_req; 422 wait_queue_head_t waitq; 423 atomic_t count; 424 }; 425 426 static inline void 427 put_mdr(struct idmap_defer_req *mdr) 428 { 429 if (atomic_dec_and_test(&mdr->count)) 430 kfree(mdr); 431 } 432 433 static inline void 434 get_mdr(struct idmap_defer_req *mdr) 435 { 436 atomic_inc(&mdr->count); 437 } 438 439 static void 440 idmap_revisit(struct cache_deferred_req *dreq, int toomany) 441 { 442 struct idmap_defer_req *mdr = 443 container_of(dreq, struct idmap_defer_req, deferred_req); 444 445 wake_up(&mdr->waitq); 446 put_mdr(mdr); 447 } 448 449 static struct cache_deferred_req * 450 idmap_defer(struct cache_req *req) 451 { 452 struct idmap_defer_req *mdr = 453 container_of(req, struct idmap_defer_req, req); 454 455 mdr->deferred_req.revisit = idmap_revisit; 456 get_mdr(mdr); 457 return (&mdr->deferred_req); 458 } 459 460 static inline int 461 do_idmap_lookup(struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, 462 struct cache_detail *detail, struct ent **item, 463 struct idmap_defer_req *mdr) 464 { 465 *item = lookup_fn(key, 0); 466 if (!*item) 467 return -ENOMEM; 468 return cache_check(detail, &(*item)->h, &mdr->req); 469 } 470 471 static inline int 472 do_idmap_lookup_nowait(struct ent *(*lookup_fn)(struct ent *, int), 473 struct ent *key, struct cache_detail *detail, 474 struct ent **item) 475 { 476 int ret = -ENOMEM; 477 478 *item = lookup_fn(key, 0); 479 if (!*item) 480 goto out_err; 481 ret = -ETIMEDOUT; 482 if (!test_bit(CACHE_VALID, &(*item)->h.flags) 483 || (*item)->h.expiry_time < get_seconds() 484 || detail->flush_time > (*item)->h.last_refresh) 485 goto out_put; 486 ret = -ENOENT; 487 if (test_bit(CACHE_NEGATIVE, &(*item)->h.flags)) 488 goto out_put; 489 return 0; 490 out_put: 491 ent_put(&(*item)->h, detail); 492 out_err: 493 *item = NULL; 494 return ret; 495 } 496 497 static int 498 idmap_lookup(struct svc_rqst *rqstp, 499 struct ent *(*lookup_fn)(struct ent *, int), struct ent *key, 500 struct cache_detail *detail, struct ent **item) 501 { 502 struct idmap_defer_req *mdr; 503 int ret; 504 505 mdr = kmalloc(sizeof(*mdr), GFP_KERNEL); 506 if (!mdr) 507 return -ENOMEM; 508 memset(mdr, 0, sizeof(*mdr)); 509 atomic_set(&mdr->count, 1); 510 init_waitqueue_head(&mdr->waitq); 511 mdr->req.defer = idmap_defer; 512 ret = do_idmap_lookup(lookup_fn, key, detail, item, mdr); 513 if (ret == -EAGAIN) { 514 wait_event_interruptible_timeout(mdr->waitq, 515 test_bit(CACHE_VALID, &(*item)->h.flags), 1 * HZ); 516 ret = do_idmap_lookup_nowait(lookup_fn, key, detail, item); 517 } 518 put_mdr(mdr); 519 return ret; 520 } 521 522 static int 523 idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, 524 uid_t *id) 525 { 526 struct ent *item, key = { 527 .type = type, 528 }; 529 int ret; 530 531 if (namelen + 1 > sizeof(key.name)) 532 return -EINVAL; 533 memcpy(key.name, name, namelen); 534 key.name[namelen] = '\0'; 535 strlcpy(key.authname, rqstp->rq_client->name, sizeof(key.authname)); 536 ret = idmap_lookup(rqstp, nametoid_lookup, &key, &nametoid_cache, &item); 537 if (ret == -ENOENT) 538 ret = -ESRCH; /* nfserr_badname */ 539 if (ret) 540 return ret; 541 *id = item->id; 542 ent_put(&item->h, &nametoid_cache); 543 return 0; 544 } 545 546 static int 547 idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) 548 { 549 struct ent *item, key = { 550 .id = id, 551 .type = type, 552 }; 553 int ret; 554 555 strlcpy(key.authname, rqstp->rq_client->name, sizeof(key.authname)); 556 ret = idmap_lookup(rqstp, idtoname_lookup, &key, &idtoname_cache, &item); 557 if (ret == -ENOENT) 558 return sprintf(name, "%u", id); 559 if (ret) 560 return ret; 561 ret = strlen(item->name); 562 BUG_ON(ret > IDMAP_NAMESZ); 563 memcpy(name, item->name, ret); 564 ent_put(&item->h, &idtoname_cache); 565 return ret; 566 } 567 568 int 569 nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, 570 __u32 *id) 571 { 572 return idmap_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); 573 } 574 575 int 576 nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, 577 __u32 *id) 578 { 579 return idmap_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id); 580 } 581 582 int 583 nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 584 { 585 return idmap_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); 586 } 587 588 int 589 nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 590 { 591 return idmap_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); 592 } 593