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