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 sn = net_generic(xprt->xpt_net, sunrpc_net_id); 351 if (cache_is_expired(sn->ip_map_cache, &ipm->h)) { 352 /* 353 * The entry has been invalidated since it was 354 * remembered, e.g. by a second mount from the 355 * same IP address. 356 */ 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 ug.uid = uid; 497 498 expiry = get_expiry(&mesg); 499 if (expiry == 0) 500 return -EINVAL; 501 502 rv = get_int(&mesg, &gids); 503 if (rv || gids < 0 || gids > 8192) 504 return -EINVAL; 505 506 ug.gi = groups_alloc(gids); 507 if (!ug.gi) 508 return -ENOMEM; 509 510 for (i = 0 ; i < gids ; i++) { 511 int gid; 512 kgid_t kgid; 513 rv = get_int(&mesg, &gid); 514 err = -EINVAL; 515 if (rv) 516 goto out; 517 kgid = make_kgid(&init_user_ns, gid); 518 if (!gid_valid(kgid)) 519 goto out; 520 GROUP_AT(ug.gi, i) = kgid; 521 } 522 523 ugp = unix_gid_lookup(cd, uid); 524 if (ugp) { 525 struct cache_head *ch; 526 ug.h.flags = 0; 527 ug.h.expiry_time = expiry; 528 ch = sunrpc_cache_update(cd, 529 &ug.h, &ugp->h, 530 unix_gid_hash(uid)); 531 if (!ch) 532 err = -ENOMEM; 533 else { 534 err = 0; 535 cache_put(ch, cd); 536 } 537 } else 538 err = -ENOMEM; 539 out: 540 if (ug.gi) 541 put_group_info(ug.gi); 542 return err; 543 } 544 545 static int unix_gid_show(struct seq_file *m, 546 struct cache_detail *cd, 547 struct cache_head *h) 548 { 549 struct user_namespace *user_ns = &init_user_ns; 550 struct unix_gid *ug; 551 int i; 552 int glen; 553 554 if (h == NULL) { 555 seq_puts(m, "#uid cnt: gids...\n"); 556 return 0; 557 } 558 ug = container_of(h, struct unix_gid, h); 559 if (test_bit(CACHE_VALID, &h->flags) && 560 !test_bit(CACHE_NEGATIVE, &h->flags)) 561 glen = ug->gi->ngroups; 562 else 563 glen = 0; 564 565 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen); 566 for (i = 0; i < glen; i++) 567 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i))); 568 seq_printf(m, "\n"); 569 return 0; 570 } 571 572 static struct cache_detail unix_gid_cache_template = { 573 .owner = THIS_MODULE, 574 .hash_size = GID_HASHMAX, 575 .name = "auth.unix.gid", 576 .cache_put = unix_gid_put, 577 .cache_request = unix_gid_request, 578 .cache_parse = unix_gid_parse, 579 .cache_show = unix_gid_show, 580 .match = unix_gid_match, 581 .init = unix_gid_init, 582 .update = unix_gid_update, 583 .alloc = unix_gid_alloc, 584 }; 585 586 int unix_gid_cache_create(struct net *net) 587 { 588 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 589 struct cache_detail *cd; 590 int err; 591 592 cd = cache_create_net(&unix_gid_cache_template, net); 593 if (IS_ERR(cd)) 594 return PTR_ERR(cd); 595 err = cache_register_net(cd, net); 596 if (err) { 597 cache_destroy_net(cd, net); 598 return err; 599 } 600 sn->unix_gid_cache = cd; 601 return 0; 602 } 603 604 void unix_gid_cache_destroy(struct net *net) 605 { 606 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 607 struct cache_detail *cd = sn->unix_gid_cache; 608 609 sn->unix_gid_cache = NULL; 610 cache_purge(cd); 611 cache_unregister_net(cd, net); 612 cache_destroy_net(cd, net); 613 } 614 615 static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid) 616 { 617 struct unix_gid ug; 618 struct cache_head *ch; 619 620 ug.uid = uid; 621 ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid)); 622 if (ch) 623 return container_of(ch, struct unix_gid, h); 624 else 625 return NULL; 626 } 627 628 static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp) 629 { 630 struct unix_gid *ug; 631 struct group_info *gi; 632 int ret; 633 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, 634 sunrpc_net_id); 635 636 ug = unix_gid_lookup(sn->unix_gid_cache, uid); 637 if (!ug) 638 return ERR_PTR(-EAGAIN); 639 ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle); 640 switch (ret) { 641 case -ENOENT: 642 return ERR_PTR(-ENOENT); 643 case -ETIMEDOUT: 644 return ERR_PTR(-ESHUTDOWN); 645 case 0: 646 gi = get_group_info(ug->gi); 647 cache_put(&ug->h, sn->unix_gid_cache); 648 return gi; 649 default: 650 return ERR_PTR(-EAGAIN); 651 } 652 } 653 654 int 655 svcauth_unix_set_client(struct svc_rqst *rqstp) 656 { 657 struct sockaddr_in *sin; 658 struct sockaddr_in6 *sin6, sin6_storage; 659 struct ip_map *ipm; 660 struct group_info *gi; 661 struct svc_cred *cred = &rqstp->rq_cred; 662 struct svc_xprt *xprt = rqstp->rq_xprt; 663 struct net *net = xprt->xpt_net; 664 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 665 666 switch (rqstp->rq_addr.ss_family) { 667 case AF_INET: 668 sin = svc_addr_in(rqstp); 669 sin6 = &sin6_storage; 670 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr); 671 break; 672 case AF_INET6: 673 sin6 = svc_addr_in6(rqstp); 674 break; 675 default: 676 BUG(); 677 } 678 679 rqstp->rq_client = NULL; 680 if (rqstp->rq_proc == 0) 681 return SVC_OK; 682 683 ipm = ip_map_cached_get(xprt); 684 if (ipm == NULL) 685 ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class, 686 &sin6->sin6_addr); 687 688 if (ipm == NULL) 689 return SVC_DENIED; 690 691 switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) { 692 default: 693 BUG(); 694 case -ETIMEDOUT: 695 return SVC_CLOSE; 696 case -EAGAIN: 697 return SVC_DROP; 698 case -ENOENT: 699 return SVC_DENIED; 700 case 0: 701 rqstp->rq_client = &ipm->m_client->h; 702 kref_get(&rqstp->rq_client->ref); 703 ip_map_cached_put(xprt, ipm); 704 break; 705 } 706 707 gi = unix_gid_find(cred->cr_uid, rqstp); 708 switch (PTR_ERR(gi)) { 709 case -EAGAIN: 710 return SVC_DROP; 711 case -ESHUTDOWN: 712 return SVC_CLOSE; 713 case -ENOENT: 714 break; 715 default: 716 put_group_info(cred->cr_group_info); 717 cred->cr_group_info = gi; 718 } 719 return SVC_OK; 720 } 721 722 EXPORT_SYMBOL_GPL(svcauth_unix_set_client); 723 724 static int 725 svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) 726 { 727 struct kvec *argv = &rqstp->rq_arg.head[0]; 728 struct kvec *resv = &rqstp->rq_res.head[0]; 729 struct svc_cred *cred = &rqstp->rq_cred; 730 731 if (argv->iov_len < 3*4) 732 return SVC_GARBAGE; 733 734 if (svc_getu32(argv) != 0) { 735 dprintk("svc: bad null cred\n"); 736 *authp = rpc_autherr_badcred; 737 return SVC_DENIED; 738 } 739 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 740 dprintk("svc: bad null verf\n"); 741 *authp = rpc_autherr_badverf; 742 return SVC_DENIED; 743 } 744 745 /* Signal that mapping to nobody uid/gid is required */ 746 cred->cr_uid = INVALID_UID; 747 cred->cr_gid = INVALID_GID; 748 cred->cr_group_info = groups_alloc(0); 749 if (cred->cr_group_info == NULL) 750 return SVC_CLOSE; /* kmalloc failure - client must retry */ 751 752 /* Put NULL verifier */ 753 svc_putnl(resv, RPC_AUTH_NULL); 754 svc_putnl(resv, 0); 755 756 rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL; 757 return SVC_OK; 758 } 759 760 static int 761 svcauth_null_release(struct svc_rqst *rqstp) 762 { 763 if (rqstp->rq_client) 764 auth_domain_put(rqstp->rq_client); 765 rqstp->rq_client = NULL; 766 if (rqstp->rq_cred.cr_group_info) 767 put_group_info(rqstp->rq_cred.cr_group_info); 768 rqstp->rq_cred.cr_group_info = NULL; 769 770 return 0; /* don't drop */ 771 } 772 773 774 struct auth_ops svcauth_null = { 775 .name = "null", 776 .owner = THIS_MODULE, 777 .flavour = RPC_AUTH_NULL, 778 .accept = svcauth_null_accept, 779 .release = svcauth_null_release, 780 .set_client = svcauth_unix_set_client, 781 }; 782 783 784 static int 785 svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) 786 { 787 struct kvec *argv = &rqstp->rq_arg.head[0]; 788 struct kvec *resv = &rqstp->rq_res.head[0]; 789 struct svc_cred *cred = &rqstp->rq_cred; 790 u32 slen, i; 791 int len = argv->iov_len; 792 793 if ((len -= 3*4) < 0) 794 return SVC_GARBAGE; 795 796 svc_getu32(argv); /* length */ 797 svc_getu32(argv); /* time stamp */ 798 slen = XDR_QUADLEN(svc_getnl(argv)); /* machname length */ 799 if (slen > 64 || (len -= (slen + 3)*4) < 0) 800 goto badcred; 801 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 802 argv->iov_len -= slen*4; 803 /* 804 * Note: we skip uid_valid()/gid_valid() checks here for 805 * backwards compatibility with clients that use -1 id's. 806 * Instead, -1 uid or gid is later mapped to the 807 * (export-specific) anonymous id by nfsd_setuser. 808 * Supplementary gid's will be left alone. 809 */ 810 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ 811 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ 812 slen = svc_getnl(argv); /* gids length */ 813 if (slen > 16 || (len -= (slen + 2)*4) < 0) 814 goto badcred; 815 cred->cr_group_info = groups_alloc(slen); 816 if (cred->cr_group_info == NULL) 817 return SVC_CLOSE; 818 for (i = 0; i < slen; i++) { 819 kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); 820 GROUP_AT(cred->cr_group_info, i) = kgid; 821 } 822 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 823 *authp = rpc_autherr_badverf; 824 return SVC_DENIED; 825 } 826 827 /* Put NULL verifier */ 828 svc_putnl(resv, RPC_AUTH_NULL); 829 svc_putnl(resv, 0); 830 831 rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX; 832 return SVC_OK; 833 834 badcred: 835 *authp = rpc_autherr_badcred; 836 return SVC_DENIED; 837 } 838 839 static int 840 svcauth_unix_release(struct svc_rqst *rqstp) 841 { 842 /* Verifier (such as it is) is already in place. 843 */ 844 if (rqstp->rq_client) 845 auth_domain_put(rqstp->rq_client); 846 rqstp->rq_client = NULL; 847 if (rqstp->rq_cred.cr_group_info) 848 put_group_info(rqstp->rq_cred.cr_group_info); 849 rqstp->rq_cred.cr_group_info = NULL; 850 851 return 0; 852 } 853 854 855 struct auth_ops svcauth_unix = { 856 .name = "unix", 857 .owner = THIS_MODULE, 858 .flavour = RPC_AUTH_UNIX, 859 .accept = svcauth_unix_accept, 860 .release = svcauth_unix_release, 861 .domain_release = svcauth_unix_domain_release, 862 .set_client = svcauth_unix_set_client, 863 }; 864 865 static struct cache_detail ip_map_cache_template = { 866 .owner = THIS_MODULE, 867 .hash_size = IP_HASHMAX, 868 .name = "auth.unix.ip", 869 .cache_put = ip_map_put, 870 .cache_request = ip_map_request, 871 .cache_parse = ip_map_parse, 872 .cache_show = ip_map_show, 873 .match = ip_map_match, 874 .init = ip_map_init, 875 .update = update, 876 .alloc = ip_map_alloc, 877 }; 878 879 int ip_map_cache_create(struct net *net) 880 { 881 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 882 struct cache_detail *cd; 883 int err; 884 885 cd = cache_create_net(&ip_map_cache_template, net); 886 if (IS_ERR(cd)) 887 return PTR_ERR(cd); 888 err = cache_register_net(cd, net); 889 if (err) { 890 cache_destroy_net(cd, net); 891 return err; 892 } 893 sn->ip_map_cache = cd; 894 return 0; 895 } 896 897 void ip_map_cache_destroy(struct net *net) 898 { 899 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 900 struct cache_detail *cd = sn->ip_map_cache; 901 902 sn->ip_map_cache = NULL; 903 cache_purge(cd); 904 cache_unregister_net(cd, net); 905 cache_destroy_net(cd, net); 906 } 907