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 void svcauth_unix_purge(struct net *net) 336 { 337 struct sunrpc_net *sn; 338 339 sn = net_generic(net, sunrpc_net_id); 340 cache_purge(sn->ip_map_cache); 341 } 342 EXPORT_SYMBOL_GPL(svcauth_unix_purge); 343 344 static inline struct ip_map * 345 ip_map_cached_get(struct svc_xprt *xprt) 346 { 347 struct ip_map *ipm = NULL; 348 struct sunrpc_net *sn; 349 350 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { 351 spin_lock(&xprt->xpt_lock); 352 ipm = xprt->xpt_auth_cache; 353 if (ipm != NULL) { 354 sn = net_generic(xprt->xpt_net, sunrpc_net_id); 355 if (cache_is_expired(sn->ip_map_cache, &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 xprt->xpt_auth_cache = NULL; 362 spin_unlock(&xprt->xpt_lock); 363 cache_put(&ipm->h, sn->ip_map_cache); 364 return NULL; 365 } 366 cache_get(&ipm->h); 367 } 368 spin_unlock(&xprt->xpt_lock); 369 } 370 return ipm; 371 } 372 373 static inline void 374 ip_map_cached_put(struct svc_xprt *xprt, struct ip_map *ipm) 375 { 376 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { 377 spin_lock(&xprt->xpt_lock); 378 if (xprt->xpt_auth_cache == NULL) { 379 /* newly cached, keep the reference */ 380 xprt->xpt_auth_cache = ipm; 381 ipm = NULL; 382 } 383 spin_unlock(&xprt->xpt_lock); 384 } 385 if (ipm) { 386 struct sunrpc_net *sn; 387 388 sn = net_generic(xprt->xpt_net, sunrpc_net_id); 389 cache_put(&ipm->h, sn->ip_map_cache); 390 } 391 } 392 393 void 394 svcauth_unix_info_release(struct svc_xprt *xpt) 395 { 396 struct ip_map *ipm; 397 398 ipm = xpt->xpt_auth_cache; 399 if (ipm != NULL) { 400 struct sunrpc_net *sn; 401 402 sn = net_generic(xpt->xpt_net, sunrpc_net_id); 403 cache_put(&ipm->h, sn->ip_map_cache); 404 } 405 } 406 407 /**************************************************************************** 408 * auth.unix.gid cache 409 * simple cache to map a UID to a list of GIDs 410 * because AUTH_UNIX aka AUTH_SYS has a max of UNX_NGROUPS 411 */ 412 #define GID_HASHBITS 8 413 #define GID_HASHMAX (1<<GID_HASHBITS) 414 415 struct unix_gid { 416 struct cache_head h; 417 kuid_t uid; 418 struct group_info *gi; 419 struct rcu_head rcu; 420 }; 421 422 static int unix_gid_hash(kuid_t uid) 423 { 424 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS); 425 } 426 427 static void unix_gid_put(struct kref *kref) 428 { 429 struct cache_head *item = container_of(kref, struct cache_head, ref); 430 struct unix_gid *ug = container_of(item, struct unix_gid, h); 431 if (test_bit(CACHE_VALID, &item->flags) && 432 !test_bit(CACHE_NEGATIVE, &item->flags)) 433 put_group_info(ug->gi); 434 kfree_rcu(ug, rcu); 435 } 436 437 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew) 438 { 439 struct unix_gid *orig = container_of(corig, struct unix_gid, h); 440 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 441 return uid_eq(orig->uid, new->uid); 442 } 443 static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) 444 { 445 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 446 struct unix_gid *item = container_of(citem, struct unix_gid, h); 447 new->uid = item->uid; 448 } 449 static void unix_gid_update(struct cache_head *cnew, struct cache_head *citem) 450 { 451 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 452 struct unix_gid *item = container_of(citem, struct unix_gid, h); 453 454 get_group_info(item->gi); 455 new->gi = item->gi; 456 } 457 static struct cache_head *unix_gid_alloc(void) 458 { 459 struct unix_gid *g = kmalloc(sizeof(*g), GFP_KERNEL); 460 if (g) 461 return &g->h; 462 else 463 return NULL; 464 } 465 466 static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h) 467 { 468 return sunrpc_cache_pipe_upcall_timeout(cd, h); 469 } 470 471 static void unix_gid_request(struct cache_detail *cd, 472 struct cache_head *h, 473 char **bpp, int *blen) 474 { 475 char tuid[20]; 476 struct unix_gid *ug = container_of(h, struct unix_gid, h); 477 478 snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid)); 479 qword_add(bpp, blen, tuid); 480 (*bpp)[-1] = '\n'; 481 } 482 483 static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid); 484 485 static int unix_gid_parse(struct cache_detail *cd, 486 char *mesg, int mlen) 487 { 488 /* uid expiry Ngid gid0 gid1 ... gidN-1 */ 489 int id; 490 kuid_t uid; 491 int gids; 492 int rv; 493 int i; 494 int err; 495 time64_t expiry; 496 struct unix_gid ug, *ugp; 497 498 if (mesg[mlen - 1] != '\n') 499 return -EINVAL; 500 mesg[mlen-1] = 0; 501 502 rv = get_int(&mesg, &id); 503 if (rv) 504 return -EINVAL; 505 uid = make_kuid(current_user_ns(), id); 506 ug.uid = uid; 507 508 expiry = get_expiry(&mesg); 509 if (expiry == 0) 510 return -EINVAL; 511 512 rv = get_int(&mesg, &gids); 513 if (rv || gids < 0 || gids > 8192) 514 return -EINVAL; 515 516 ug.gi = groups_alloc(gids); 517 if (!ug.gi) 518 return -ENOMEM; 519 520 for (i = 0 ; i < gids ; i++) { 521 int gid; 522 kgid_t kgid; 523 rv = get_int(&mesg, &gid); 524 err = -EINVAL; 525 if (rv) 526 goto out; 527 kgid = make_kgid(current_user_ns(), gid); 528 if (!gid_valid(kgid)) 529 goto out; 530 ug.gi->gid[i] = kgid; 531 } 532 533 groups_sort(ug.gi); 534 ugp = unix_gid_lookup(cd, uid); 535 if (ugp) { 536 struct cache_head *ch; 537 ug.h.flags = 0; 538 ug.h.expiry_time = expiry; 539 ch = sunrpc_cache_update(cd, 540 &ug.h, &ugp->h, 541 unix_gid_hash(uid)); 542 if (!ch) 543 err = -ENOMEM; 544 else { 545 err = 0; 546 cache_put(ch, cd); 547 } 548 } else 549 err = -ENOMEM; 550 out: 551 if (ug.gi) 552 put_group_info(ug.gi); 553 return err; 554 } 555 556 static int unix_gid_show(struct seq_file *m, 557 struct cache_detail *cd, 558 struct cache_head *h) 559 { 560 struct user_namespace *user_ns = m->file->f_cred->user_ns; 561 struct unix_gid *ug; 562 int i; 563 int glen; 564 565 if (h == NULL) { 566 seq_puts(m, "#uid cnt: gids...\n"); 567 return 0; 568 } 569 ug = container_of(h, struct unix_gid, h); 570 if (test_bit(CACHE_VALID, &h->flags) && 571 !test_bit(CACHE_NEGATIVE, &h->flags)) 572 glen = ug->gi->ngroups; 573 else 574 glen = 0; 575 576 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen); 577 for (i = 0; i < glen; i++) 578 seq_printf(m, " %d", from_kgid_munged(user_ns, ug->gi->gid[i])); 579 seq_printf(m, "\n"); 580 return 0; 581 } 582 583 static const struct cache_detail unix_gid_cache_template = { 584 .owner = THIS_MODULE, 585 .hash_size = GID_HASHMAX, 586 .name = "auth.unix.gid", 587 .cache_put = unix_gid_put, 588 .cache_upcall = unix_gid_upcall, 589 .cache_request = unix_gid_request, 590 .cache_parse = unix_gid_parse, 591 .cache_show = unix_gid_show, 592 .match = unix_gid_match, 593 .init = unix_gid_init, 594 .update = unix_gid_update, 595 .alloc = unix_gid_alloc, 596 }; 597 598 int unix_gid_cache_create(struct net *net) 599 { 600 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 601 struct cache_detail *cd; 602 int err; 603 604 cd = cache_create_net(&unix_gid_cache_template, net); 605 if (IS_ERR(cd)) 606 return PTR_ERR(cd); 607 err = cache_register_net(cd, net); 608 if (err) { 609 cache_destroy_net(cd, net); 610 return err; 611 } 612 sn->unix_gid_cache = cd; 613 return 0; 614 } 615 616 void unix_gid_cache_destroy(struct net *net) 617 { 618 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 619 struct cache_detail *cd = sn->unix_gid_cache; 620 621 sn->unix_gid_cache = NULL; 622 cache_purge(cd); 623 cache_unregister_net(cd, net); 624 cache_destroy_net(cd, net); 625 } 626 627 static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid) 628 { 629 struct unix_gid ug; 630 struct cache_head *ch; 631 632 ug.uid = uid; 633 ch = sunrpc_cache_lookup_rcu(cd, &ug.h, unix_gid_hash(uid)); 634 if (ch) 635 return container_of(ch, struct unix_gid, h); 636 else 637 return NULL; 638 } 639 640 static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp) 641 { 642 struct unix_gid *ug; 643 struct group_info *gi; 644 int ret; 645 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, 646 sunrpc_net_id); 647 648 ug = unix_gid_lookup(sn->unix_gid_cache, uid); 649 if (!ug) 650 return ERR_PTR(-EAGAIN); 651 ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle); 652 switch (ret) { 653 case -ENOENT: 654 return ERR_PTR(-ENOENT); 655 case -ETIMEDOUT: 656 return ERR_PTR(-ESHUTDOWN); 657 case 0: 658 gi = get_group_info(ug->gi); 659 cache_put(&ug->h, sn->unix_gid_cache); 660 return gi; 661 default: 662 return ERR_PTR(-EAGAIN); 663 } 664 } 665 666 int 667 svcauth_unix_set_client(struct svc_rqst *rqstp) 668 { 669 struct sockaddr_in *sin; 670 struct sockaddr_in6 *sin6, sin6_storage; 671 struct ip_map *ipm; 672 struct group_info *gi; 673 struct svc_cred *cred = &rqstp->rq_cred; 674 struct svc_xprt *xprt = rqstp->rq_xprt; 675 struct net *net = xprt->xpt_net; 676 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 677 678 switch (rqstp->rq_addr.ss_family) { 679 case AF_INET: 680 sin = svc_addr_in(rqstp); 681 sin6 = &sin6_storage; 682 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr); 683 break; 684 case AF_INET6: 685 sin6 = svc_addr_in6(rqstp); 686 break; 687 default: 688 BUG(); 689 } 690 691 rqstp->rq_client = NULL; 692 if (rqstp->rq_proc == 0) 693 return SVC_OK; 694 695 ipm = ip_map_cached_get(xprt); 696 if (ipm == NULL) 697 ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class, 698 &sin6->sin6_addr); 699 700 if (ipm == NULL) 701 return SVC_DENIED; 702 703 switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) { 704 default: 705 BUG(); 706 case -ETIMEDOUT: 707 return SVC_CLOSE; 708 case -EAGAIN: 709 return SVC_DROP; 710 case -ENOENT: 711 return SVC_DENIED; 712 case 0: 713 rqstp->rq_client = &ipm->m_client->h; 714 kref_get(&rqstp->rq_client->ref); 715 ip_map_cached_put(xprt, ipm); 716 break; 717 } 718 719 gi = unix_gid_find(cred->cr_uid, rqstp); 720 switch (PTR_ERR(gi)) { 721 case -EAGAIN: 722 return SVC_DROP; 723 case -ESHUTDOWN: 724 return SVC_CLOSE; 725 case -ENOENT: 726 break; 727 default: 728 put_group_info(cred->cr_group_info); 729 cred->cr_group_info = gi; 730 } 731 return SVC_OK; 732 } 733 734 EXPORT_SYMBOL_GPL(svcauth_unix_set_client); 735 736 static int 737 svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) 738 { 739 struct kvec *argv = &rqstp->rq_arg.head[0]; 740 struct kvec *resv = &rqstp->rq_res.head[0]; 741 struct svc_cred *cred = &rqstp->rq_cred; 742 743 if (argv->iov_len < 3*4) 744 return SVC_GARBAGE; 745 746 if (svc_getu32(argv) != 0) { 747 dprintk("svc: bad null cred\n"); 748 *authp = rpc_autherr_badcred; 749 return SVC_DENIED; 750 } 751 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 752 dprintk("svc: bad null verf\n"); 753 *authp = rpc_autherr_badverf; 754 return SVC_DENIED; 755 } 756 757 /* Signal that mapping to nobody uid/gid is required */ 758 cred->cr_uid = INVALID_UID; 759 cred->cr_gid = INVALID_GID; 760 cred->cr_group_info = groups_alloc(0); 761 if (cred->cr_group_info == NULL) 762 return SVC_CLOSE; /* kmalloc failure - client must retry */ 763 764 /* Put NULL verifier */ 765 svc_putnl(resv, RPC_AUTH_NULL); 766 svc_putnl(resv, 0); 767 768 rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL; 769 return SVC_OK; 770 } 771 772 static int 773 svcauth_null_release(struct svc_rqst *rqstp) 774 { 775 if (rqstp->rq_client) 776 auth_domain_put(rqstp->rq_client); 777 rqstp->rq_client = NULL; 778 if (rqstp->rq_cred.cr_group_info) 779 put_group_info(rqstp->rq_cred.cr_group_info); 780 rqstp->rq_cred.cr_group_info = NULL; 781 782 return 0; /* don't drop */ 783 } 784 785 786 struct auth_ops svcauth_null = { 787 .name = "null", 788 .owner = THIS_MODULE, 789 .flavour = RPC_AUTH_NULL, 790 .accept = svcauth_null_accept, 791 .release = svcauth_null_release, 792 .set_client = svcauth_unix_set_client, 793 }; 794 795 796 static int 797 svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) 798 { 799 struct kvec *argv = &rqstp->rq_arg.head[0]; 800 struct kvec *resv = &rqstp->rq_res.head[0]; 801 struct svc_cred *cred = &rqstp->rq_cred; 802 struct user_namespace *userns; 803 u32 slen, i; 804 int len = argv->iov_len; 805 806 if ((len -= 3*4) < 0) 807 return SVC_GARBAGE; 808 809 svc_getu32(argv); /* length */ 810 svc_getu32(argv); /* time stamp */ 811 slen = XDR_QUADLEN(svc_getnl(argv)); /* machname length */ 812 if (slen > 64 || (len -= (slen + 3)*4) < 0) 813 goto badcred; 814 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 815 argv->iov_len -= slen*4; 816 /* 817 * Note: we skip uid_valid()/gid_valid() checks here for 818 * backwards compatibility with clients that use -1 id's. 819 * Instead, -1 uid or gid is later mapped to the 820 * (export-specific) anonymous id by nfsd_setuser. 821 * Supplementary gid's will be left alone. 822 */ 823 userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ? 824 rqstp->rq_xprt->xpt_cred->user_ns : &init_user_ns; 825 cred->cr_uid = make_kuid(userns, svc_getnl(argv)); /* uid */ 826 cred->cr_gid = make_kgid(userns, svc_getnl(argv)); /* gid */ 827 slen = svc_getnl(argv); /* gids length */ 828 if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0) 829 goto badcred; 830 cred->cr_group_info = groups_alloc(slen); 831 if (cred->cr_group_info == NULL) 832 return SVC_CLOSE; 833 for (i = 0; i < slen; i++) { 834 kgid_t kgid = make_kgid(userns, svc_getnl(argv)); 835 cred->cr_group_info->gid[i] = kgid; 836 } 837 groups_sort(cred->cr_group_info); 838 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 839 *authp = rpc_autherr_badverf; 840 return SVC_DENIED; 841 } 842 843 /* Put NULL verifier */ 844 svc_putnl(resv, RPC_AUTH_NULL); 845 svc_putnl(resv, 0); 846 847 rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX; 848 return SVC_OK; 849 850 badcred: 851 *authp = rpc_autherr_badcred; 852 return SVC_DENIED; 853 } 854 855 static int 856 svcauth_unix_release(struct svc_rqst *rqstp) 857 { 858 /* Verifier (such as it is) is already in place. 859 */ 860 if (rqstp->rq_client) 861 auth_domain_put(rqstp->rq_client); 862 rqstp->rq_client = NULL; 863 if (rqstp->rq_cred.cr_group_info) 864 put_group_info(rqstp->rq_cred.cr_group_info); 865 rqstp->rq_cred.cr_group_info = NULL; 866 867 return 0; 868 } 869 870 871 struct auth_ops svcauth_unix = { 872 .name = "unix", 873 .owner = THIS_MODULE, 874 .flavour = RPC_AUTH_UNIX, 875 .accept = svcauth_unix_accept, 876 .release = svcauth_unix_release, 877 .domain_release = svcauth_unix_domain_release, 878 .set_client = svcauth_unix_set_client, 879 }; 880 881 static const struct cache_detail ip_map_cache_template = { 882 .owner = THIS_MODULE, 883 .hash_size = IP_HASHMAX, 884 .name = "auth.unix.ip", 885 .cache_put = ip_map_put, 886 .cache_upcall = ip_map_upcall, 887 .cache_request = ip_map_request, 888 .cache_parse = ip_map_parse, 889 .cache_show = ip_map_show, 890 .match = ip_map_match, 891 .init = ip_map_init, 892 .update = update, 893 .alloc = ip_map_alloc, 894 }; 895 896 int ip_map_cache_create(struct net *net) 897 { 898 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 899 struct cache_detail *cd; 900 int err; 901 902 cd = cache_create_net(&ip_map_cache_template, net); 903 if (IS_ERR(cd)) 904 return PTR_ERR(cd); 905 err = cache_register_net(cd, net); 906 if (err) { 907 cache_destroy_net(cd, net); 908 return err; 909 } 910 sn->ip_map_cache = cd; 911 return 0; 912 } 913 914 void ip_map_cache_destroy(struct net *net) 915 { 916 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 917 struct cache_detail *cd = sn->ip_map_cache; 918 919 sn->ip_map_cache = NULL; 920 cache_purge(cd); 921 cache_unregister_net(cd, net); 922 cache_destroy_net(cd, net); 923 } 924