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