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