1 #include <linux/types.h> 2 #include <linux/sched.h> 3 #include <linux/module.h> 4 #include <linux/sunrpc/types.h> 5 #include <linux/sunrpc/xdr.h> 6 #include <linux/sunrpc/svcsock.h> 7 #include <linux/sunrpc/svcauth.h> 8 #include <linux/sunrpc/gss_api.h> 9 #include <linux/err.h> 10 #include <linux/seq_file.h> 11 #include <linux/hash.h> 12 #include <linux/string.h> 13 #include <linux/slab.h> 14 #include <net/sock.h> 15 #include <net/ipv6.h> 16 #include <linux/kernel.h> 17 #define RPCDBG_FACILITY RPCDBG_AUTH 18 19 #include <linux/sunrpc/clnt.h> 20 21 #include "netns.h" 22 23 /* 24 * AUTHUNIX and AUTHNULL credentials are both handled here. 25 * AUTHNULL is treated just like AUTHUNIX except that the uid/gid 26 * are always nobody (-2). i.e. we do the same IP address checks for 27 * AUTHNULL as for AUTHUNIX, and that is done here. 28 */ 29 30 31 struct unix_domain { 32 struct auth_domain h; 33 int addr_changes; 34 /* other stuff later */ 35 }; 36 37 extern struct auth_ops svcauth_unix; 38 39 struct auth_domain *unix_domain_find(char *name) 40 { 41 struct auth_domain *rv; 42 struct unix_domain *new = NULL; 43 44 rv = auth_domain_lookup(name, NULL); 45 while(1) { 46 if (rv) { 47 if (new && rv != &new->h) 48 auth_domain_put(&new->h); 49 50 if (rv->flavour != &svcauth_unix) { 51 auth_domain_put(rv); 52 return NULL; 53 } 54 return rv; 55 } 56 57 new = kmalloc(sizeof(*new), GFP_KERNEL); 58 if (new == NULL) 59 return NULL; 60 kref_init(&new->h.ref); 61 new->h.name = kstrdup(name, GFP_KERNEL); 62 if (new->h.name == NULL) { 63 kfree(new); 64 return NULL; 65 } 66 new->h.flavour = &svcauth_unix; 67 new->addr_changes = 0; 68 rv = auth_domain_lookup(name, &new->h); 69 } 70 } 71 EXPORT_SYMBOL_GPL(unix_domain_find); 72 73 static void svcauth_unix_domain_release(struct auth_domain *dom) 74 { 75 struct unix_domain *ud = container_of(dom, struct unix_domain, h); 76 77 kfree(dom->name); 78 kfree(ud); 79 } 80 81 82 /************************************************** 83 * cache for IP address to unix_domain 84 * as needed by AUTH_UNIX 85 */ 86 #define IP_HASHBITS 8 87 #define IP_HASHMAX (1<<IP_HASHBITS) 88 #define IP_HASHMASK (IP_HASHMAX-1) 89 90 struct ip_map { 91 struct cache_head h; 92 char m_class[8]; /* e.g. "nfsd" */ 93 struct in6_addr m_addr; 94 struct unix_domain *m_client; 95 int m_add_change; 96 }; 97 98 static void ip_map_put(struct kref *kref) 99 { 100 struct cache_head *item = container_of(kref, struct cache_head, ref); 101 struct ip_map *im = container_of(item, struct ip_map,h); 102 103 if (test_bit(CACHE_VALID, &item->flags) && 104 !test_bit(CACHE_NEGATIVE, &item->flags)) 105 auth_domain_put(&im->m_client->h); 106 kfree(im); 107 } 108 109 #if IP_HASHBITS == 8 110 /* hash_long on a 64 bit machine is currently REALLY BAD for 111 * IP addresses in reverse-endian (i.e. on a little-endian machine). 112 * So use a trivial but reliable hash instead 113 */ 114 static inline int hash_ip(__be32 ip) 115 { 116 int hash = (__force u32)ip ^ ((__force u32)ip>>16); 117 return (hash ^ (hash>>8)) & 0xff; 118 } 119 #endif 120 static inline int hash_ip6(struct in6_addr ip) 121 { 122 return (hash_ip(ip.s6_addr32[0]) ^ 123 hash_ip(ip.s6_addr32[1]) ^ 124 hash_ip(ip.s6_addr32[2]) ^ 125 hash_ip(ip.s6_addr32[3])); 126 } 127 static int ip_map_match(struct cache_head *corig, struct cache_head *cnew) 128 { 129 struct ip_map *orig = container_of(corig, struct ip_map, h); 130 struct ip_map *new = container_of(cnew, struct ip_map, h); 131 return strcmp(orig->m_class, new->m_class) == 0 && 132 ipv6_addr_equal(&orig->m_addr, &new->m_addr); 133 } 134 static void ip_map_init(struct cache_head *cnew, struct cache_head *citem) 135 { 136 struct ip_map *new = container_of(cnew, struct ip_map, h); 137 struct ip_map *item = container_of(citem, struct ip_map, h); 138 139 strcpy(new->m_class, item->m_class); 140 ipv6_addr_copy(&new->m_addr, &item->m_addr); 141 } 142 static void update(struct cache_head *cnew, struct cache_head *citem) 143 { 144 struct ip_map *new = container_of(cnew, struct ip_map, h); 145 struct ip_map *item = container_of(citem, struct ip_map, h); 146 147 kref_get(&item->m_client->h.ref); 148 new->m_client = item->m_client; 149 new->m_add_change = item->m_add_change; 150 } 151 static struct cache_head *ip_map_alloc(void) 152 { 153 struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL); 154 if (i) 155 return &i->h; 156 else 157 return NULL; 158 } 159 160 static void ip_map_request(struct cache_detail *cd, 161 struct cache_head *h, 162 char **bpp, int *blen) 163 { 164 char text_addr[40]; 165 struct ip_map *im = container_of(h, struct ip_map, h); 166 167 if (ipv6_addr_v4mapped(&(im->m_addr))) { 168 snprintf(text_addr, 20, "%pI4", &im->m_addr.s6_addr32[3]); 169 } else { 170 snprintf(text_addr, 40, "%pI6", &im->m_addr); 171 } 172 qword_add(bpp, blen, im->m_class); 173 qword_add(bpp, blen, text_addr); 174 (*bpp)[-1] = '\n'; 175 } 176 177 static int ip_map_upcall(struct cache_detail *cd, struct cache_head *h) 178 { 179 return sunrpc_cache_pipe_upcall(cd, h, ip_map_request); 180 } 181 182 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr); 183 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry); 184 185 static int ip_map_parse(struct cache_detail *cd, 186 char *mesg, int mlen) 187 { 188 /* class ipaddress [domainname] */ 189 /* should be safe just to use the start of the input buffer 190 * for scratch: */ 191 char *buf = mesg; 192 int len; 193 char class[8]; 194 union { 195 struct sockaddr sa; 196 struct sockaddr_in s4; 197 struct sockaddr_in6 s6; 198 } address; 199 struct sockaddr_in6 sin6; 200 int err; 201 202 struct ip_map *ipmp; 203 struct auth_domain *dom; 204 time_t expiry; 205 206 if (mesg[mlen-1] != '\n') 207 return -EINVAL; 208 mesg[mlen-1] = 0; 209 210 /* class */ 211 len = qword_get(&mesg, class, sizeof(class)); 212 if (len <= 0) return -EINVAL; 213 214 /* ip address */ 215 len = qword_get(&mesg, buf, mlen); 216 if (len <= 0) return -EINVAL; 217 218 if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0) 219 return -EINVAL; 220 switch (address.sa.sa_family) { 221 case AF_INET: 222 /* Form a mapped IPv4 address in sin6 */ 223 sin6.sin6_family = AF_INET6; 224 ipv6_addr_set_v4mapped(address.s4.sin_addr.s_addr, 225 &sin6.sin6_addr); 226 break; 227 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 228 case AF_INET6: 229 memcpy(&sin6, &address.s6, sizeof(sin6)); 230 break; 231 #endif 232 default: 233 return -EINVAL; 234 } 235 236 expiry = get_expiry(&mesg); 237 if (expiry ==0) 238 return -EINVAL; 239 240 /* domainname, or empty for NEGATIVE */ 241 len = qword_get(&mesg, buf, mlen); 242 if (len < 0) return -EINVAL; 243 244 if (len) { 245 dom = unix_domain_find(buf); 246 if (dom == NULL) 247 return -ENOENT; 248 } else 249 dom = NULL; 250 251 /* IPv6 scope IDs are ignored for now */ 252 ipmp = __ip_map_lookup(cd, class, &sin6.sin6_addr); 253 if (ipmp) { 254 err = __ip_map_update(cd, ipmp, 255 container_of(dom, struct unix_domain, h), 256 expiry); 257 } else 258 err = -ENOMEM; 259 260 if (dom) 261 auth_domain_put(dom); 262 263 cache_flush(); 264 return err; 265 } 266 267 static int ip_map_show(struct seq_file *m, 268 struct cache_detail *cd, 269 struct cache_head *h) 270 { 271 struct ip_map *im; 272 struct in6_addr addr; 273 char *dom = "-no-domain-"; 274 275 if (h == NULL) { 276 seq_puts(m, "#class IP domain\n"); 277 return 0; 278 } 279 im = container_of(h, struct ip_map, h); 280 /* class addr domain */ 281 ipv6_addr_copy(&addr, &im->m_addr); 282 283 if (test_bit(CACHE_VALID, &h->flags) && 284 !test_bit(CACHE_NEGATIVE, &h->flags)) 285 dom = im->m_client->h.name; 286 287 if (ipv6_addr_v4mapped(&addr)) { 288 seq_printf(m, "%s %pI4 %s\n", 289 im->m_class, &addr.s6_addr32[3], dom); 290 } else { 291 seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom); 292 } 293 return 0; 294 } 295 296 297 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, 298 struct in6_addr *addr) 299 { 300 struct ip_map ip; 301 struct cache_head *ch; 302 303 strcpy(ip.m_class, class); 304 ipv6_addr_copy(&ip.m_addr, addr); 305 ch = sunrpc_cache_lookup(cd, &ip.h, 306 hash_str(class, IP_HASHBITS) ^ 307 hash_ip6(*addr)); 308 309 if (ch) 310 return container_of(ch, struct ip_map, h); 311 else 312 return NULL; 313 } 314 315 static inline struct ip_map *ip_map_lookup(struct net *net, char *class, 316 struct in6_addr *addr) 317 { 318 struct sunrpc_net *sn; 319 320 sn = net_generic(net, sunrpc_net_id); 321 return __ip_map_lookup(sn->ip_map_cache, class, addr); 322 } 323 324 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, 325 struct unix_domain *udom, time_t expiry) 326 { 327 struct ip_map ip; 328 struct cache_head *ch; 329 330 ip.m_client = udom; 331 ip.h.flags = 0; 332 if (!udom) 333 set_bit(CACHE_NEGATIVE, &ip.h.flags); 334 else { 335 ip.m_add_change = udom->addr_changes; 336 /* if this is from the legacy set_client system call, 337 * we need m_add_change to be one higher 338 */ 339 if (expiry == NEVER) 340 ip.m_add_change++; 341 } 342 ip.h.expiry_time = expiry; 343 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, 344 hash_str(ipm->m_class, IP_HASHBITS) ^ 345 hash_ip6(ipm->m_addr)); 346 if (!ch) 347 return -ENOMEM; 348 cache_put(ch, cd); 349 return 0; 350 } 351 352 static inline int ip_map_update(struct net *net, struct ip_map *ipm, 353 struct unix_domain *udom, time_t expiry) 354 { 355 struct sunrpc_net *sn; 356 357 sn = net_generic(net, sunrpc_net_id); 358 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); 359 } 360 361 int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) 362 { 363 struct unix_domain *udom; 364 struct ip_map *ipmp; 365 366 if (dom->flavour != &svcauth_unix) 367 return -EINVAL; 368 udom = container_of(dom, struct unix_domain, h); 369 ipmp = ip_map_lookup(net, "nfsd", addr); 370 371 if (ipmp) 372 return ip_map_update(net, ipmp, udom, NEVER); 373 else 374 return -ENOMEM; 375 } 376 EXPORT_SYMBOL_GPL(auth_unix_add_addr); 377 378 int auth_unix_forget_old(struct auth_domain *dom) 379 { 380 struct unix_domain *udom; 381 382 if (dom->flavour != &svcauth_unix) 383 return -EINVAL; 384 udom = container_of(dom, struct unix_domain, h); 385 udom->addr_changes++; 386 return 0; 387 } 388 EXPORT_SYMBOL_GPL(auth_unix_forget_old); 389 390 struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr) 391 { 392 struct ip_map *ipm; 393 struct auth_domain *rv; 394 struct sunrpc_net *sn; 395 396 sn = net_generic(net, sunrpc_net_id); 397 ipm = ip_map_lookup(net, "nfsd", addr); 398 399 if (!ipm) 400 return NULL; 401 if (cache_check(sn->ip_map_cache, &ipm->h, NULL)) 402 return NULL; 403 404 if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { 405 if (test_and_set_bit(CACHE_NEGATIVE, &ipm->h.flags) == 0) 406 auth_domain_put(&ipm->m_client->h); 407 rv = NULL; 408 } else { 409 rv = &ipm->m_client->h; 410 kref_get(&rv->ref); 411 } 412 cache_put(&ipm->h, sn->ip_map_cache); 413 return rv; 414 } 415 EXPORT_SYMBOL_GPL(auth_unix_lookup); 416 417 void svcauth_unix_purge(void) 418 { 419 struct net *net; 420 421 for_each_net(net) { 422 struct sunrpc_net *sn; 423 424 sn = net_generic(net, sunrpc_net_id); 425 cache_purge(sn->ip_map_cache); 426 } 427 } 428 EXPORT_SYMBOL_GPL(svcauth_unix_purge); 429 430 static inline struct ip_map * 431 ip_map_cached_get(struct svc_xprt *xprt) 432 { 433 struct ip_map *ipm = NULL; 434 struct sunrpc_net *sn; 435 436 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { 437 spin_lock(&xprt->xpt_lock); 438 ipm = xprt->xpt_auth_cache; 439 if (ipm != NULL) { 440 if (!cache_valid(&ipm->h)) { 441 /* 442 * The entry has been invalidated since it was 443 * remembered, e.g. by a second mount from the 444 * same IP address. 445 */ 446 sn = net_generic(xprt->xpt_net, sunrpc_net_id); 447 xprt->xpt_auth_cache = NULL; 448 spin_unlock(&xprt->xpt_lock); 449 cache_put(&ipm->h, sn->ip_map_cache); 450 return NULL; 451 } 452 cache_get(&ipm->h); 453 } 454 spin_unlock(&xprt->xpt_lock); 455 } 456 return ipm; 457 } 458 459 static inline void 460 ip_map_cached_put(struct svc_xprt *xprt, struct ip_map *ipm) 461 { 462 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { 463 spin_lock(&xprt->xpt_lock); 464 if (xprt->xpt_auth_cache == NULL) { 465 /* newly cached, keep the reference */ 466 xprt->xpt_auth_cache = ipm; 467 ipm = NULL; 468 } 469 spin_unlock(&xprt->xpt_lock); 470 } 471 if (ipm) { 472 struct sunrpc_net *sn; 473 474 sn = net_generic(xprt->xpt_net, sunrpc_net_id); 475 cache_put(&ipm->h, sn->ip_map_cache); 476 } 477 } 478 479 void 480 svcauth_unix_info_release(struct svc_xprt *xpt) 481 { 482 struct ip_map *ipm; 483 484 ipm = xpt->xpt_auth_cache; 485 if (ipm != NULL) { 486 struct sunrpc_net *sn; 487 488 sn = net_generic(xpt->xpt_net, sunrpc_net_id); 489 cache_put(&ipm->h, sn->ip_map_cache); 490 } 491 } 492 493 /**************************************************************************** 494 * auth.unix.gid cache 495 * simple cache to map a UID to a list of GIDs 496 * because AUTH_UNIX aka AUTH_SYS has a max of 16 497 */ 498 #define GID_HASHBITS 8 499 #define GID_HASHMAX (1<<GID_HASHBITS) 500 #define GID_HASHMASK (GID_HASHMAX - 1) 501 502 struct unix_gid { 503 struct cache_head h; 504 uid_t uid; 505 struct group_info *gi; 506 }; 507 static struct cache_head *gid_table[GID_HASHMAX]; 508 509 static void unix_gid_put(struct kref *kref) 510 { 511 struct cache_head *item = container_of(kref, struct cache_head, ref); 512 struct unix_gid *ug = container_of(item, struct unix_gid, h); 513 if (test_bit(CACHE_VALID, &item->flags) && 514 !test_bit(CACHE_NEGATIVE, &item->flags)) 515 put_group_info(ug->gi); 516 kfree(ug); 517 } 518 519 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew) 520 { 521 struct unix_gid *orig = container_of(corig, struct unix_gid, h); 522 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 523 return orig->uid == new->uid; 524 } 525 static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) 526 { 527 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 528 struct unix_gid *item = container_of(citem, struct unix_gid, h); 529 new->uid = item->uid; 530 } 531 static void unix_gid_update(struct cache_head *cnew, struct cache_head *citem) 532 { 533 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 534 struct unix_gid *item = container_of(citem, struct unix_gid, h); 535 536 get_group_info(item->gi); 537 new->gi = item->gi; 538 } 539 static struct cache_head *unix_gid_alloc(void) 540 { 541 struct unix_gid *g = kmalloc(sizeof(*g), GFP_KERNEL); 542 if (g) 543 return &g->h; 544 else 545 return NULL; 546 } 547 548 static void unix_gid_request(struct cache_detail *cd, 549 struct cache_head *h, 550 char **bpp, int *blen) 551 { 552 char tuid[20]; 553 struct unix_gid *ug = container_of(h, struct unix_gid, h); 554 555 snprintf(tuid, 20, "%u", ug->uid); 556 qword_add(bpp, blen, tuid); 557 (*bpp)[-1] = '\n'; 558 } 559 560 static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h) 561 { 562 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); 563 } 564 565 static struct unix_gid *unix_gid_lookup(uid_t uid); 566 extern struct cache_detail unix_gid_cache; 567 568 static int unix_gid_parse(struct cache_detail *cd, 569 char *mesg, int mlen) 570 { 571 /* uid expiry Ngid gid0 gid1 ... gidN-1 */ 572 int uid; 573 int gids; 574 int rv; 575 int i; 576 int err; 577 time_t expiry; 578 struct unix_gid ug, *ugp; 579 580 if (mlen <= 0 || mesg[mlen-1] != '\n') 581 return -EINVAL; 582 mesg[mlen-1] = 0; 583 584 rv = get_int(&mesg, &uid); 585 if (rv) 586 return -EINVAL; 587 ug.uid = uid; 588 589 expiry = get_expiry(&mesg); 590 if (expiry == 0) 591 return -EINVAL; 592 593 rv = get_int(&mesg, &gids); 594 if (rv || gids < 0 || gids > 8192) 595 return -EINVAL; 596 597 ug.gi = groups_alloc(gids); 598 if (!ug.gi) 599 return -ENOMEM; 600 601 for (i = 0 ; i < gids ; i++) { 602 int gid; 603 rv = get_int(&mesg, &gid); 604 err = -EINVAL; 605 if (rv) 606 goto out; 607 GROUP_AT(ug.gi, i) = gid; 608 } 609 610 ugp = unix_gid_lookup(uid); 611 if (ugp) { 612 struct cache_head *ch; 613 ug.h.flags = 0; 614 ug.h.expiry_time = expiry; 615 ch = sunrpc_cache_update(&unix_gid_cache, 616 &ug.h, &ugp->h, 617 hash_long(uid, GID_HASHBITS)); 618 if (!ch) 619 err = -ENOMEM; 620 else { 621 err = 0; 622 cache_put(ch, &unix_gid_cache); 623 } 624 } else 625 err = -ENOMEM; 626 out: 627 if (ug.gi) 628 put_group_info(ug.gi); 629 return err; 630 } 631 632 static int unix_gid_show(struct seq_file *m, 633 struct cache_detail *cd, 634 struct cache_head *h) 635 { 636 struct unix_gid *ug; 637 int i; 638 int glen; 639 640 if (h == NULL) { 641 seq_puts(m, "#uid cnt: gids...\n"); 642 return 0; 643 } 644 ug = container_of(h, struct unix_gid, h); 645 if (test_bit(CACHE_VALID, &h->flags) && 646 !test_bit(CACHE_NEGATIVE, &h->flags)) 647 glen = ug->gi->ngroups; 648 else 649 glen = 0; 650 651 seq_printf(m, "%u %d:", ug->uid, glen); 652 for (i = 0; i < glen; i++) 653 seq_printf(m, " %d", GROUP_AT(ug->gi, i)); 654 seq_printf(m, "\n"); 655 return 0; 656 } 657 658 struct cache_detail unix_gid_cache = { 659 .owner = THIS_MODULE, 660 .hash_size = GID_HASHMAX, 661 .hash_table = gid_table, 662 .name = "auth.unix.gid", 663 .cache_put = unix_gid_put, 664 .cache_upcall = unix_gid_upcall, 665 .cache_parse = unix_gid_parse, 666 .cache_show = unix_gid_show, 667 .match = unix_gid_match, 668 .init = unix_gid_init, 669 .update = unix_gid_update, 670 .alloc = unix_gid_alloc, 671 }; 672 673 static struct unix_gid *unix_gid_lookup(uid_t uid) 674 { 675 struct unix_gid ug; 676 struct cache_head *ch; 677 678 ug.uid = uid; 679 ch = sunrpc_cache_lookup(&unix_gid_cache, &ug.h, 680 hash_long(uid, GID_HASHBITS)); 681 if (ch) 682 return container_of(ch, struct unix_gid, h); 683 else 684 return NULL; 685 } 686 687 static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) 688 { 689 struct unix_gid *ug; 690 struct group_info *gi; 691 int ret; 692 693 ug = unix_gid_lookup(uid); 694 if (!ug) 695 return ERR_PTR(-EAGAIN); 696 ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle); 697 switch (ret) { 698 case -ENOENT: 699 return ERR_PTR(-ENOENT); 700 case -ETIMEDOUT: 701 return ERR_PTR(-ESHUTDOWN); 702 case 0: 703 gi = get_group_info(ug->gi); 704 cache_put(&ug->h, &unix_gid_cache); 705 return gi; 706 default: 707 return ERR_PTR(-EAGAIN); 708 } 709 } 710 711 int 712 svcauth_unix_set_client(struct svc_rqst *rqstp) 713 { 714 struct sockaddr_in *sin; 715 struct sockaddr_in6 *sin6, sin6_storage; 716 struct ip_map *ipm; 717 struct group_info *gi; 718 struct svc_cred *cred = &rqstp->rq_cred; 719 struct svc_xprt *xprt = rqstp->rq_xprt; 720 struct net *net = xprt->xpt_net; 721 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 722 723 switch (rqstp->rq_addr.ss_family) { 724 case AF_INET: 725 sin = svc_addr_in(rqstp); 726 sin6 = &sin6_storage; 727 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr); 728 break; 729 case AF_INET6: 730 sin6 = svc_addr_in6(rqstp); 731 break; 732 default: 733 BUG(); 734 } 735 736 rqstp->rq_client = NULL; 737 if (rqstp->rq_proc == 0) 738 return SVC_OK; 739 740 ipm = ip_map_cached_get(xprt); 741 if (ipm == NULL) 742 ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class, 743 &sin6->sin6_addr); 744 745 if (ipm == NULL) 746 return SVC_DENIED; 747 748 switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) { 749 default: 750 BUG(); 751 case -ETIMEDOUT: 752 return SVC_CLOSE; 753 case -EAGAIN: 754 return SVC_DROP; 755 case -ENOENT: 756 return SVC_DENIED; 757 case 0: 758 rqstp->rq_client = &ipm->m_client->h; 759 kref_get(&rqstp->rq_client->ref); 760 ip_map_cached_put(xprt, ipm); 761 break; 762 } 763 764 gi = unix_gid_find(cred->cr_uid, rqstp); 765 switch (PTR_ERR(gi)) { 766 case -EAGAIN: 767 return SVC_DROP; 768 case -ESHUTDOWN: 769 return SVC_CLOSE; 770 case -ENOENT: 771 break; 772 default: 773 put_group_info(cred->cr_group_info); 774 cred->cr_group_info = gi; 775 } 776 return SVC_OK; 777 } 778 779 EXPORT_SYMBOL_GPL(svcauth_unix_set_client); 780 781 static int 782 svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) 783 { 784 struct kvec *argv = &rqstp->rq_arg.head[0]; 785 struct kvec *resv = &rqstp->rq_res.head[0]; 786 struct svc_cred *cred = &rqstp->rq_cred; 787 788 cred->cr_group_info = NULL; 789 rqstp->rq_client = NULL; 790 791 if (argv->iov_len < 3*4) 792 return SVC_GARBAGE; 793 794 if (svc_getu32(argv) != 0) { 795 dprintk("svc: bad null cred\n"); 796 *authp = rpc_autherr_badcred; 797 return SVC_DENIED; 798 } 799 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 800 dprintk("svc: bad null verf\n"); 801 *authp = rpc_autherr_badverf; 802 return SVC_DENIED; 803 } 804 805 /* Signal that mapping to nobody uid/gid is required */ 806 cred->cr_uid = (uid_t) -1; 807 cred->cr_gid = (gid_t) -1; 808 cred->cr_group_info = groups_alloc(0); 809 if (cred->cr_group_info == NULL) 810 return SVC_CLOSE; /* kmalloc failure - client must retry */ 811 812 /* Put NULL verifier */ 813 svc_putnl(resv, RPC_AUTH_NULL); 814 svc_putnl(resv, 0); 815 816 rqstp->rq_flavor = RPC_AUTH_NULL; 817 return SVC_OK; 818 } 819 820 static int 821 svcauth_null_release(struct svc_rqst *rqstp) 822 { 823 if (rqstp->rq_client) 824 auth_domain_put(rqstp->rq_client); 825 rqstp->rq_client = NULL; 826 if (rqstp->rq_cred.cr_group_info) 827 put_group_info(rqstp->rq_cred.cr_group_info); 828 rqstp->rq_cred.cr_group_info = NULL; 829 830 return 0; /* don't drop */ 831 } 832 833 834 struct auth_ops svcauth_null = { 835 .name = "null", 836 .owner = THIS_MODULE, 837 .flavour = RPC_AUTH_NULL, 838 .accept = svcauth_null_accept, 839 .release = svcauth_null_release, 840 .set_client = svcauth_unix_set_client, 841 }; 842 843 844 static int 845 svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) 846 { 847 struct kvec *argv = &rqstp->rq_arg.head[0]; 848 struct kvec *resv = &rqstp->rq_res.head[0]; 849 struct svc_cred *cred = &rqstp->rq_cred; 850 u32 slen, i; 851 int len = argv->iov_len; 852 853 cred->cr_group_info = NULL; 854 rqstp->rq_client = NULL; 855 856 if ((len -= 3*4) < 0) 857 return SVC_GARBAGE; 858 859 svc_getu32(argv); /* length */ 860 svc_getu32(argv); /* time stamp */ 861 slen = XDR_QUADLEN(svc_getnl(argv)); /* machname length */ 862 if (slen > 64 || (len -= (slen + 3)*4) < 0) 863 goto badcred; 864 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 865 argv->iov_len -= slen*4; 866 867 cred->cr_uid = svc_getnl(argv); /* uid */ 868 cred->cr_gid = svc_getnl(argv); /* gid */ 869 slen = svc_getnl(argv); /* gids length */ 870 if (slen > 16 || (len -= (slen + 2)*4) < 0) 871 goto badcred; 872 cred->cr_group_info = groups_alloc(slen); 873 if (cred->cr_group_info == NULL) 874 return SVC_CLOSE; 875 for (i = 0; i < slen; i++) 876 GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); 877 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 878 *authp = rpc_autherr_badverf; 879 return SVC_DENIED; 880 } 881 882 /* Put NULL verifier */ 883 svc_putnl(resv, RPC_AUTH_NULL); 884 svc_putnl(resv, 0); 885 886 rqstp->rq_flavor = RPC_AUTH_UNIX; 887 return SVC_OK; 888 889 badcred: 890 *authp = rpc_autherr_badcred; 891 return SVC_DENIED; 892 } 893 894 static int 895 svcauth_unix_release(struct svc_rqst *rqstp) 896 { 897 /* Verifier (such as it is) is already in place. 898 */ 899 if (rqstp->rq_client) 900 auth_domain_put(rqstp->rq_client); 901 rqstp->rq_client = NULL; 902 if (rqstp->rq_cred.cr_group_info) 903 put_group_info(rqstp->rq_cred.cr_group_info); 904 rqstp->rq_cred.cr_group_info = NULL; 905 906 return 0; 907 } 908 909 910 struct auth_ops svcauth_unix = { 911 .name = "unix", 912 .owner = THIS_MODULE, 913 .flavour = RPC_AUTH_UNIX, 914 .accept = svcauth_unix_accept, 915 .release = svcauth_unix_release, 916 .domain_release = svcauth_unix_domain_release, 917 .set_client = svcauth_unix_set_client, 918 }; 919 920 int ip_map_cache_create(struct net *net) 921 { 922 int err = -ENOMEM; 923 struct cache_detail *cd; 924 struct cache_head **tbl; 925 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 926 927 cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL); 928 if (cd == NULL) 929 goto err_cd; 930 931 tbl = kzalloc(IP_HASHMAX * sizeof(struct cache_head *), GFP_KERNEL); 932 if (tbl == NULL) 933 goto err_tbl; 934 935 cd->owner = THIS_MODULE, 936 cd->hash_size = IP_HASHMAX, 937 cd->hash_table = tbl, 938 cd->name = "auth.unix.ip", 939 cd->cache_put = ip_map_put, 940 cd->cache_upcall = ip_map_upcall, 941 cd->cache_parse = ip_map_parse, 942 cd->cache_show = ip_map_show, 943 cd->match = ip_map_match, 944 cd->init = ip_map_init, 945 cd->update = update, 946 cd->alloc = ip_map_alloc, 947 948 err = cache_register_net(cd, net); 949 if (err) 950 goto err_reg; 951 952 sn->ip_map_cache = cd; 953 return 0; 954 955 err_reg: 956 kfree(tbl); 957 err_tbl: 958 kfree(cd); 959 err_cd: 960 return err; 961 } 962 963 void ip_map_cache_destroy(struct net *net) 964 { 965 struct sunrpc_net *sn; 966 967 sn = net_generic(net, sunrpc_net_id); 968 cache_purge(sn->ip_map_cache); 969 cache_unregister_net(sn->ip_map_cache, net); 970 kfree(sn->ip_map_cache->hash_table); 971 kfree(sn->ip_map_cache); 972 } 973