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