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