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 32struct unix_domain { 33 struct auth_domain h; 34 /* other stuff later */ 35}; 36 37extern struct auth_ops svcauth_null; 38extern struct auth_ops svcauth_unix; 39 40static 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 48struct 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} 79EXPORT_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 89struct 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 96static 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 107static inline int hash_ip6(const struct in6_addr *ip) 108{ 109 return hash_32(ipv6_addr_hash(ip), IP_HASHBITS); 110} 111static 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} 118static 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} 126static 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} 134static 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 143static 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 160static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr); 161static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry); 162 163static 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 245static 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 275static 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 293static 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 302static 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 322static 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 331void 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} 338EXPORT_SYMBOL_GPL(svcauth_unix_purge); 339 340static inline struct ip_map * 341ip_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 369static inline void 370ip_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 389void 390svcauth_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 411struct unix_gid { 412 struct cache_head h; 413 kuid_t uid; 414 struct group_info *gi; 415}; 416 417static int unix_gid_hash(kuid_t uid) 418{ 419 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS); 420} 421 422static 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 432static 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} 438static 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} 444static 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} 452static 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 461static 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 473static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid); 474 475static 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 545static 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 572static 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 586int 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 604void 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 615static 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 628static 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 654int 655svcauth_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 722EXPORT_SYMBOL_GPL(svcauth_unix_set_client); 723 724static int 725svcauth_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 cred->cr_group_info = NULL; 732 cred->cr_principal = NULL; 733 rqstp->rq_client = NULL; 734 735 if (argv->iov_len < 3*4) 736 return SVC_GARBAGE; 737 738 if (svc_getu32(argv) != 0) { 739 dprintk("svc: bad null cred\n"); 740 *authp = rpc_autherr_badcred; 741 return SVC_DENIED; 742 } 743 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 744 dprintk("svc: bad null verf\n"); 745 *authp = rpc_autherr_badverf; 746 return SVC_DENIED; 747 } 748 749 /* Signal that mapping to nobody uid/gid is required */ 750 cred->cr_uid = INVALID_UID; 751 cred->cr_gid = INVALID_GID; 752 cred->cr_group_info = groups_alloc(0); 753 if (cred->cr_group_info == NULL) 754 return SVC_CLOSE; /* kmalloc failure - client must retry */ 755 756 /* Put NULL verifier */ 757 svc_putnl(resv, RPC_AUTH_NULL); 758 svc_putnl(resv, 0); 759 760 rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL; 761 return SVC_OK; 762} 763 764static int 765svcauth_null_release(struct svc_rqst *rqstp) 766{ 767 if (rqstp->rq_client) 768 auth_domain_put(rqstp->rq_client); 769 rqstp->rq_client = NULL; 770 if (rqstp->rq_cred.cr_group_info) 771 put_group_info(rqstp->rq_cred.cr_group_info); 772 rqstp->rq_cred.cr_group_info = NULL; 773 774 return 0; /* don't drop */ 775} 776 777 778struct auth_ops svcauth_null = { 779 .name = "null", 780 .owner = THIS_MODULE, 781 .flavour = RPC_AUTH_NULL, 782 .accept = svcauth_null_accept, 783 .release = svcauth_null_release, 784 .set_client = svcauth_unix_set_client, 785}; 786 787 788static int 789svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) 790{ 791 struct kvec *argv = &rqstp->rq_arg.head[0]; 792 struct kvec *resv = &rqstp->rq_res.head[0]; 793 struct svc_cred *cred = &rqstp->rq_cred; 794 u32 slen, i; 795 int len = argv->iov_len; 796 797 cred->cr_group_info = NULL; 798 cred->cr_principal = NULL; 799 rqstp->rq_client = NULL; 800 801 if ((len -= 3*4) < 0) 802 return SVC_GARBAGE; 803 804 svc_getu32(argv); /* length */ 805 svc_getu32(argv); /* time stamp */ 806 slen = XDR_QUADLEN(svc_getnl(argv)); /* machname length */ 807 if (slen > 64 || (len -= (slen + 3)*4) < 0) 808 goto badcred; 809 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 810 argv->iov_len -= slen*4; 811 /* 812 * Note: we skip uid_valid()/gid_valid() checks here for 813 * backwards compatibility with clients that use -1 id's. 814 * Instead, -1 uid or gid is later mapped to the 815 * (export-specific) anonymous id by nfsd_setuser. 816 * Supplementary gid's will be left alone. 817 */ 818 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */ 819 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */ 820 slen = svc_getnl(argv); /* gids length */ 821 if (slen > 16 || (len -= (slen + 2)*4) < 0) 822 goto badcred; 823 cred->cr_group_info = groups_alloc(slen); 824 if (cred->cr_group_info == NULL) 825 return SVC_CLOSE; 826 for (i = 0; i < slen; i++) { 827 kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); 828 GROUP_AT(cred->cr_group_info, i) = kgid; 829 } 830 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 831 *authp = rpc_autherr_badverf; 832 return SVC_DENIED; 833 } 834 835 /* Put NULL verifier */ 836 svc_putnl(resv, RPC_AUTH_NULL); 837 svc_putnl(resv, 0); 838 839 rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX; 840 return SVC_OK; 841 842badcred: 843 *authp = rpc_autherr_badcred; 844 return SVC_DENIED; 845} 846 847static int 848svcauth_unix_release(struct svc_rqst *rqstp) 849{ 850 /* Verifier (such as it is) is already in place. 851 */ 852 if (rqstp->rq_client) 853 auth_domain_put(rqstp->rq_client); 854 rqstp->rq_client = NULL; 855 if (rqstp->rq_cred.cr_group_info) 856 put_group_info(rqstp->rq_cred.cr_group_info); 857 rqstp->rq_cred.cr_group_info = NULL; 858 859 return 0; 860} 861 862 863struct auth_ops svcauth_unix = { 864 .name = "unix", 865 .owner = THIS_MODULE, 866 .flavour = RPC_AUTH_UNIX, 867 .accept = svcauth_unix_accept, 868 .release = svcauth_unix_release, 869 .domain_release = svcauth_unix_domain_release, 870 .set_client = svcauth_unix_set_client, 871}; 872 873static struct cache_detail ip_map_cache_template = { 874 .owner = THIS_MODULE, 875 .hash_size = IP_HASHMAX, 876 .name = "auth.unix.ip", 877 .cache_put = ip_map_put, 878 .cache_request = ip_map_request, 879 .cache_parse = ip_map_parse, 880 .cache_show = ip_map_show, 881 .match = ip_map_match, 882 .init = ip_map_init, 883 .update = update, 884 .alloc = ip_map_alloc, 885}; 886 887int ip_map_cache_create(struct net *net) 888{ 889 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 890 struct cache_detail *cd; 891 int err; 892 893 cd = cache_create_net(&ip_map_cache_template, net); 894 if (IS_ERR(cd)) 895 return PTR_ERR(cd); 896 err = cache_register_net(cd, net); 897 if (err) { 898 cache_destroy_net(cd, net); 899 return err; 900 } 901 sn->ip_map_cache = cd; 902 return 0; 903} 904 905void ip_map_cache_destroy(struct net *net) 906{ 907 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 908 struct cache_detail *cd = sn->ip_map_cache; 909 910 sn->ip_map_cache = NULL; 911 cache_purge(cd); 912 cache_unregister_net(cd, net); 913 cache_destroy_net(cd, net); 914} 915