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 33struct unix_domain { 34 struct auth_domain h; 35 /* other stuff later */ 36}; 37 38extern struct auth_ops svcauth_null; 39extern struct auth_ops svcauth_unix; 40 41static 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 50static void svcauth_unix_domain_release(struct auth_domain *dom) 51{ 52 call_rcu(&dom->rcu_head, svcauth_unix_domain_release_rcu); 53} 54 55struct 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} 86EXPORT_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 96struct 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 104static 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 115static inline int hash_ip6(const struct in6_addr *ip) 116{ 117 return hash_32(ipv6_addr_hash(ip), IP_HASHBITS); 118} 119static 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} 126static 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} 134static 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} 142static 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 151static int ip_map_upcall(struct cache_detail *cd, struct cache_head *h) 152{ 153 return sunrpc_cache_pipe_upcall(cd, h); 154} 155 156static 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 173static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr); 174static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time64_t expiry); 175 176static 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 258static 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 288static 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 306static 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 315static 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 335void 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} 342EXPORT_SYMBOL_GPL(svcauth_unix_purge); 343 344static inline struct ip_map * 345ip_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 373static inline void 374ip_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 393void 394svcauth_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 415struct unix_gid { 416 struct cache_head h; 417 kuid_t uid; 418 struct group_info *gi; 419 struct rcu_head rcu; 420}; 421 422static int unix_gid_hash(kuid_t uid) 423{ 424 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS); 425} 426 427static void unix_gid_free(struct rcu_head *rcu) 428{ 429 struct unix_gid *ug = container_of(rcu, struct unix_gid, rcu); 430 struct cache_head *item = &ug->h; 431 432 if (test_bit(CACHE_VALID, &item->flags) && 433 !test_bit(CACHE_NEGATIVE, &item->flags)) 434 put_group_info(ug->gi); 435 kfree(ug); 436} 437 438static void unix_gid_put(struct kref *kref) 439{ 440 struct cache_head *item = container_of(kref, struct cache_head, ref); 441 struct unix_gid *ug = container_of(item, struct unix_gid, h); 442 443 call_rcu(&ug->rcu, unix_gid_free); 444} 445 446static 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} 452static 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} 458static 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} 466static 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 475static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h) 476{ 477 return sunrpc_cache_pipe_upcall_timeout(cd, h); 478} 479 480static 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 492static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid); 493 494static 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 565static 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 592static 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 607int 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 625void 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 636static 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 649static 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 675int 676svcauth_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 743EXPORT_SYMBOL_GPL(svcauth_unix_set_client); 744 745static int 746svcauth_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 781static int 782svcauth_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 795struct 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 805static int 806svcauth_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 859badcred: 860 *authp = rpc_autherr_badcred; 861 return SVC_DENIED; 862} 863 864static int 865svcauth_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 880struct 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 890static 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 905int 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 923void 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