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