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/err.h> 10 #include <linux/seq_file.h> 11 #include <linux/hash.h> 12 #include <linux/string.h> 13 #include <linux/slab.h> 14 #include <net/sock.h> 15 #include <net/ipv6.h> 16 #include <linux/kernel.h> 17 #define RPCDBG_FACILITY RPCDBG_AUTH 18 19 #include <linux/sunrpc/clnt.h> 20 21 #include "netns.h" 22 23 /* 24 * AUTHUNIX and AUTHNULL credentials are both handled here. 25 * AUTHNULL is treated just like AUTHUNIX except that the uid/gid 26 * are always nobody (-2). i.e. we do the same IP address checks for 27 * AUTHNULL as for AUTHUNIX, and that is done here. 28 */ 29 30 31 struct unix_domain { 32 struct auth_domain h; 33 /* other stuff later */ 34 }; 35 36 extern struct auth_ops svcauth_null; 37 extern struct auth_ops svcauth_unix; 38 39 static void svcauth_unix_domain_release(struct auth_domain *dom) 40 { 41 struct unix_domain *ud = container_of(dom, struct unix_domain, h); 42 43 kfree(dom->name); 44 kfree(ud); 45 } 46 47 struct auth_domain *unix_domain_find(char *name) 48 { 49 struct auth_domain *rv; 50 struct unix_domain *new = NULL; 51 52 rv = auth_domain_lookup(name, NULL); 53 while(1) { 54 if (rv) { 55 if (new && rv != &new->h) 56 svcauth_unix_domain_release(&new->h); 57 58 if (rv->flavour != &svcauth_unix) { 59 auth_domain_put(rv); 60 return NULL; 61 } 62 return rv; 63 } 64 65 new = kmalloc(sizeof(*new), GFP_KERNEL); 66 if (new == NULL) 67 return NULL; 68 kref_init(&new->h.ref); 69 new->h.name = kstrdup(name, GFP_KERNEL); 70 if (new->h.name == NULL) { 71 kfree(new); 72 return NULL; 73 } 74 new->h.flavour = &svcauth_unix; 75 rv = auth_domain_lookup(name, &new->h); 76 } 77 } 78 EXPORT_SYMBOL_GPL(unix_domain_find); 79 80 81 /************************************************** 82 * cache for IP address to unix_domain 83 * as needed by AUTH_UNIX 84 */ 85 #define IP_HASHBITS 8 86 #define IP_HASHMAX (1<<IP_HASHBITS) 87 88 struct ip_map { 89 struct cache_head h; 90 char m_class[8]; /* e.g. "nfsd" */ 91 struct in6_addr m_addr; 92 struct unix_domain *m_client; 93 }; 94 95 static void ip_map_put(struct kref *kref) 96 { 97 struct cache_head *item = container_of(kref, struct cache_head, ref); 98 struct ip_map *im = container_of(item, struct ip_map,h); 99 100 if (test_bit(CACHE_VALID, &item->flags) && 101 !test_bit(CACHE_NEGATIVE, &item->flags)) 102 auth_domain_put(&im->m_client->h); 103 kfree(im); 104 } 105 106 #if IP_HASHBITS == 8 107 /* hash_long on a 64 bit machine is currently REALLY BAD for 108 * IP addresses in reverse-endian (i.e. on a little-endian machine). 109 * So use a trivial but reliable hash instead 110 */ 111 static inline int hash_ip(__be32 ip) 112 { 113 int hash = (__force u32)ip ^ ((__force u32)ip>>16); 114 return (hash ^ (hash>>8)) & 0xff; 115 } 116 #endif 117 static inline int hash_ip6(struct in6_addr ip) 118 { 119 return (hash_ip(ip.s6_addr32[0]) ^ 120 hash_ip(ip.s6_addr32[1]) ^ 121 hash_ip(ip.s6_addr32[2]) ^ 122 hash_ip(ip.s6_addr32[3])); 123 } 124 static int ip_map_match(struct cache_head *corig, struct cache_head *cnew) 125 { 126 struct ip_map *orig = container_of(corig, struct ip_map, h); 127 struct ip_map *new = container_of(cnew, struct ip_map, h); 128 return strcmp(orig->m_class, new->m_class) == 0 && 129 ipv6_addr_equal(&orig->m_addr, &new->m_addr); 130 } 131 static void ip_map_init(struct cache_head *cnew, struct cache_head *citem) 132 { 133 struct ip_map *new = container_of(cnew, struct ip_map, h); 134 struct ip_map *item = container_of(citem, struct ip_map, h); 135 136 strcpy(new->m_class, item->m_class); 137 ipv6_addr_copy(&new->m_addr, &item->m_addr); 138 } 139 static void update(struct cache_head *cnew, struct cache_head *citem) 140 { 141 struct ip_map *new = container_of(cnew, struct ip_map, h); 142 struct ip_map *item = container_of(citem, struct ip_map, h); 143 144 kref_get(&item->m_client->h.ref); 145 new->m_client = item->m_client; 146 } 147 static struct cache_head *ip_map_alloc(void) 148 { 149 struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL); 150 if (i) 151 return &i->h; 152 else 153 return NULL; 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 int ip_map_upcall(struct cache_detail *cd, struct cache_head *h) 174 { 175 return sunrpc_cache_pipe_upcall(cd, h, ip_map_request); 176 } 177 178 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr); 179 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry); 180 181 static int ip_map_parse(struct cache_detail *cd, 182 char *mesg, int mlen) 183 { 184 /* class ipaddress [domainname] */ 185 /* should be safe just to use the start of the input buffer 186 * for scratch: */ 187 char *buf = mesg; 188 int len; 189 char class[8]; 190 union { 191 struct sockaddr sa; 192 struct sockaddr_in s4; 193 struct sockaddr_in6 s6; 194 } address; 195 struct sockaddr_in6 sin6; 196 int err; 197 198 struct ip_map *ipmp; 199 struct auth_domain *dom; 200 time_t expiry; 201 202 if (mesg[mlen-1] != '\n') 203 return -EINVAL; 204 mesg[mlen-1] = 0; 205 206 /* class */ 207 len = qword_get(&mesg, class, sizeof(class)); 208 if (len <= 0) return -EINVAL; 209 210 /* ip address */ 211 len = qword_get(&mesg, buf, mlen); 212 if (len <= 0) return -EINVAL; 213 214 if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0) 215 return -EINVAL; 216 switch (address.sa.sa_family) { 217 case AF_INET: 218 /* Form a mapped IPv4 address in sin6 */ 219 sin6.sin6_family = AF_INET6; 220 ipv6_addr_set_v4mapped(address.s4.sin_addr.s_addr, 221 &sin6.sin6_addr); 222 break; 223 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 224 case AF_INET6: 225 memcpy(&sin6, &address.s6, sizeof(sin6)); 226 break; 227 #endif 228 default: 229 return -EINVAL; 230 } 231 232 expiry = get_expiry(&mesg); 233 if (expiry ==0) 234 return -EINVAL; 235 236 /* domainname, or empty for NEGATIVE */ 237 len = qword_get(&mesg, buf, mlen); 238 if (len < 0) return -EINVAL; 239 240 if (len) { 241 dom = unix_domain_find(buf); 242 if (dom == NULL) 243 return -ENOENT; 244 } else 245 dom = NULL; 246 247 /* IPv6 scope IDs are ignored for now */ 248 ipmp = __ip_map_lookup(cd, class, &sin6.sin6_addr); 249 if (ipmp) { 250 err = __ip_map_update(cd, ipmp, 251 container_of(dom, struct unix_domain, h), 252 expiry); 253 } else 254 err = -ENOMEM; 255 256 if (dom) 257 auth_domain_put(dom); 258 259 cache_flush(); 260 return err; 261 } 262 263 static int ip_map_show(struct seq_file *m, 264 struct cache_detail *cd, 265 struct cache_head *h) 266 { 267 struct ip_map *im; 268 struct in6_addr addr; 269 char *dom = "-no-domain-"; 270 271 if (h == NULL) { 272 seq_puts(m, "#class IP domain\n"); 273 return 0; 274 } 275 im = container_of(h, struct ip_map, h); 276 /* class addr domain */ 277 ipv6_addr_copy(&addr, &im->m_addr); 278 279 if (test_bit(CACHE_VALID, &h->flags) && 280 !test_bit(CACHE_NEGATIVE, &h->flags)) 281 dom = im->m_client->h.name; 282 283 if (ipv6_addr_v4mapped(&addr)) { 284 seq_printf(m, "%s %pI4 %s\n", 285 im->m_class, &addr.s6_addr32[3], dom); 286 } else { 287 seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom); 288 } 289 return 0; 290 } 291 292 293 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, 294 struct in6_addr *addr) 295 { 296 struct ip_map ip; 297 struct cache_head *ch; 298 299 strcpy(ip.m_class, class); 300 ipv6_addr_copy(&ip.m_addr, addr); 301 ch = sunrpc_cache_lookup(cd, &ip.h, 302 hash_str(class, IP_HASHBITS) ^ 303 hash_ip6(*addr)); 304 305 if (ch) 306 return container_of(ch, struct ip_map, h); 307 else 308 return NULL; 309 } 310 311 static inline struct ip_map *ip_map_lookup(struct net *net, char *class, 312 struct in6_addr *addr) 313 { 314 struct sunrpc_net *sn; 315 316 sn = net_generic(net, sunrpc_net_id); 317 return __ip_map_lookup(sn->ip_map_cache, class, addr); 318 } 319 320 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, 321 struct unix_domain *udom, time_t expiry) 322 { 323 struct ip_map ip; 324 struct cache_head *ch; 325 326 ip.m_client = udom; 327 ip.h.flags = 0; 328 if (!udom) 329 set_bit(CACHE_NEGATIVE, &ip.h.flags); 330 ip.h.expiry_time = expiry; 331 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, 332 hash_str(ipm->m_class, IP_HASHBITS) ^ 333 hash_ip6(ipm->m_addr)); 334 if (!ch) 335 return -ENOMEM; 336 cache_put(ch, cd); 337 return 0; 338 } 339 340 static inline int ip_map_update(struct net *net, struct ip_map *ipm, 341 struct unix_domain *udom, time_t expiry) 342 { 343 struct sunrpc_net *sn; 344 345 sn = net_generic(net, sunrpc_net_id); 346 return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); 347 } 348 349 350 void svcauth_unix_purge(void) 351 { 352 struct net *net; 353 354 for_each_net(net) { 355 struct sunrpc_net *sn; 356 357 sn = net_generic(net, sunrpc_net_id); 358 cache_purge(sn->ip_map_cache); 359 } 360 } 361 EXPORT_SYMBOL_GPL(svcauth_unix_purge); 362 363 static inline struct ip_map * 364 ip_map_cached_get(struct svc_xprt *xprt) 365 { 366 struct ip_map *ipm = NULL; 367 struct sunrpc_net *sn; 368 369 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { 370 spin_lock(&xprt->xpt_lock); 371 ipm = xprt->xpt_auth_cache; 372 if (ipm != NULL) { 373 if (!cache_valid(&ipm->h)) { 374 /* 375 * The entry has been invalidated since it was 376 * remembered, e.g. by a second mount from the 377 * same IP address. 378 */ 379 sn = net_generic(xprt->xpt_net, sunrpc_net_id); 380 xprt->xpt_auth_cache = NULL; 381 spin_unlock(&xprt->xpt_lock); 382 cache_put(&ipm->h, sn->ip_map_cache); 383 return NULL; 384 } 385 cache_get(&ipm->h); 386 } 387 spin_unlock(&xprt->xpt_lock); 388 } 389 return ipm; 390 } 391 392 static inline void 393 ip_map_cached_put(struct svc_xprt *xprt, struct ip_map *ipm) 394 { 395 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) { 396 spin_lock(&xprt->xpt_lock); 397 if (xprt->xpt_auth_cache == NULL) { 398 /* newly cached, keep the reference */ 399 xprt->xpt_auth_cache = ipm; 400 ipm = NULL; 401 } 402 spin_unlock(&xprt->xpt_lock); 403 } 404 if (ipm) { 405 struct sunrpc_net *sn; 406 407 sn = net_generic(xprt->xpt_net, sunrpc_net_id); 408 cache_put(&ipm->h, sn->ip_map_cache); 409 } 410 } 411 412 void 413 svcauth_unix_info_release(struct svc_xprt *xpt) 414 { 415 struct ip_map *ipm; 416 417 ipm = xpt->xpt_auth_cache; 418 if (ipm != NULL) { 419 struct sunrpc_net *sn; 420 421 sn = net_generic(xpt->xpt_net, sunrpc_net_id); 422 cache_put(&ipm->h, sn->ip_map_cache); 423 } 424 } 425 426 /**************************************************************************** 427 * auth.unix.gid cache 428 * simple cache to map a UID to a list of GIDs 429 * because AUTH_UNIX aka AUTH_SYS has a max of 16 430 */ 431 #define GID_HASHBITS 8 432 #define GID_HASHMAX (1<<GID_HASHBITS) 433 434 struct unix_gid { 435 struct cache_head h; 436 uid_t uid; 437 struct group_info *gi; 438 }; 439 static struct cache_head *gid_table[GID_HASHMAX]; 440 441 static void unix_gid_put(struct kref *kref) 442 { 443 struct cache_head *item = container_of(kref, struct cache_head, ref); 444 struct unix_gid *ug = container_of(item, struct unix_gid, h); 445 if (test_bit(CACHE_VALID, &item->flags) && 446 !test_bit(CACHE_NEGATIVE, &item->flags)) 447 put_group_info(ug->gi); 448 kfree(ug); 449 } 450 451 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew) 452 { 453 struct unix_gid *orig = container_of(corig, struct unix_gid, h); 454 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 455 return orig->uid == new->uid; 456 } 457 static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) 458 { 459 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 460 struct unix_gid *item = container_of(citem, struct unix_gid, h); 461 new->uid = item->uid; 462 } 463 static void unix_gid_update(struct cache_head *cnew, struct cache_head *citem) 464 { 465 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 466 struct unix_gid *item = container_of(citem, struct unix_gid, h); 467 468 get_group_info(item->gi); 469 new->gi = item->gi; 470 } 471 static struct cache_head *unix_gid_alloc(void) 472 { 473 struct unix_gid *g = kmalloc(sizeof(*g), GFP_KERNEL); 474 if (g) 475 return &g->h; 476 else 477 return NULL; 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", ug->uid); 488 qword_add(bpp, blen, tuid); 489 (*bpp)[-1] = '\n'; 490 } 491 492 static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h) 493 { 494 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request); 495 } 496 497 static struct unix_gid *unix_gid_lookup(uid_t uid); 498 extern struct cache_detail unix_gid_cache; 499 500 static int unix_gid_parse(struct cache_detail *cd, 501 char *mesg, int mlen) 502 { 503 /* uid expiry Ngid gid0 gid1 ... gidN-1 */ 504 int uid; 505 int gids; 506 int rv; 507 int i; 508 int err; 509 time_t expiry; 510 struct unix_gid ug, *ugp; 511 512 if (mlen <= 0 || mesg[mlen-1] != '\n') 513 return -EINVAL; 514 mesg[mlen-1] = 0; 515 516 rv = get_int(&mesg, &uid); 517 if (rv) 518 return -EINVAL; 519 ug.uid = uid; 520 521 expiry = get_expiry(&mesg); 522 if (expiry == 0) 523 return -EINVAL; 524 525 rv = get_int(&mesg, &gids); 526 if (rv || gids < 0 || gids > 8192) 527 return -EINVAL; 528 529 ug.gi = groups_alloc(gids); 530 if (!ug.gi) 531 return -ENOMEM; 532 533 for (i = 0 ; i < gids ; i++) { 534 int gid; 535 rv = get_int(&mesg, &gid); 536 err = -EINVAL; 537 if (rv) 538 goto out; 539 GROUP_AT(ug.gi, i) = gid; 540 } 541 542 ugp = unix_gid_lookup(uid); 543 if (ugp) { 544 struct cache_head *ch; 545 ug.h.flags = 0; 546 ug.h.expiry_time = expiry; 547 ch = sunrpc_cache_update(&unix_gid_cache, 548 &ug.h, &ugp->h, 549 hash_long(uid, GID_HASHBITS)); 550 if (!ch) 551 err = -ENOMEM; 552 else { 553 err = 0; 554 cache_put(ch, &unix_gid_cache); 555 } 556 } else 557 err = -ENOMEM; 558 out: 559 if (ug.gi) 560 put_group_info(ug.gi); 561 return err; 562 } 563 564 static int unix_gid_show(struct seq_file *m, 565 struct cache_detail *cd, 566 struct cache_head *h) 567 { 568 struct unix_gid *ug; 569 int i; 570 int glen; 571 572 if (h == NULL) { 573 seq_puts(m, "#uid cnt: gids...\n"); 574 return 0; 575 } 576 ug = container_of(h, struct unix_gid, h); 577 if (test_bit(CACHE_VALID, &h->flags) && 578 !test_bit(CACHE_NEGATIVE, &h->flags)) 579 glen = ug->gi->ngroups; 580 else 581 glen = 0; 582 583 seq_printf(m, "%u %d:", ug->uid, glen); 584 for (i = 0; i < glen; i++) 585 seq_printf(m, " %d", GROUP_AT(ug->gi, i)); 586 seq_printf(m, "\n"); 587 return 0; 588 } 589 590 struct cache_detail unix_gid_cache = { 591 .owner = THIS_MODULE, 592 .hash_size = GID_HASHMAX, 593 .hash_table = gid_table, 594 .name = "auth.unix.gid", 595 .cache_put = unix_gid_put, 596 .cache_upcall = unix_gid_upcall, 597 .cache_parse = unix_gid_parse, 598 .cache_show = unix_gid_show, 599 .match = unix_gid_match, 600 .init = unix_gid_init, 601 .update = unix_gid_update, 602 .alloc = unix_gid_alloc, 603 }; 604 605 static struct unix_gid *unix_gid_lookup(uid_t uid) 606 { 607 struct unix_gid ug; 608 struct cache_head *ch; 609 610 ug.uid = uid; 611 ch = sunrpc_cache_lookup(&unix_gid_cache, &ug.h, 612 hash_long(uid, GID_HASHBITS)); 613 if (ch) 614 return container_of(ch, struct unix_gid, h); 615 else 616 return NULL; 617 } 618 619 static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) 620 { 621 struct unix_gid *ug; 622 struct group_info *gi; 623 int ret; 624 625 ug = unix_gid_lookup(uid); 626 if (!ug) 627 return ERR_PTR(-EAGAIN); 628 ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle); 629 switch (ret) { 630 case -ENOENT: 631 return ERR_PTR(-ENOENT); 632 case -ETIMEDOUT: 633 return ERR_PTR(-ESHUTDOWN); 634 case 0: 635 gi = get_group_info(ug->gi); 636 cache_put(&ug->h, &unix_gid_cache); 637 return gi; 638 default: 639 return ERR_PTR(-EAGAIN); 640 } 641 } 642 643 int 644 svcauth_unix_set_client(struct svc_rqst *rqstp) 645 { 646 struct sockaddr_in *sin; 647 struct sockaddr_in6 *sin6, sin6_storage; 648 struct ip_map *ipm; 649 struct group_info *gi; 650 struct svc_cred *cred = &rqstp->rq_cred; 651 struct svc_xprt *xprt = rqstp->rq_xprt; 652 struct net *net = xprt->xpt_net; 653 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 654 655 switch (rqstp->rq_addr.ss_family) { 656 case AF_INET: 657 sin = svc_addr_in(rqstp); 658 sin6 = &sin6_storage; 659 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr); 660 break; 661 case AF_INET6: 662 sin6 = svc_addr_in6(rqstp); 663 break; 664 default: 665 BUG(); 666 } 667 668 rqstp->rq_client = NULL; 669 if (rqstp->rq_proc == 0) 670 return SVC_OK; 671 672 ipm = ip_map_cached_get(xprt); 673 if (ipm == NULL) 674 ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class, 675 &sin6->sin6_addr); 676 677 if (ipm == NULL) 678 return SVC_DENIED; 679 680 switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) { 681 default: 682 BUG(); 683 case -ETIMEDOUT: 684 return SVC_CLOSE; 685 case -EAGAIN: 686 return SVC_DROP; 687 case -ENOENT: 688 return SVC_DENIED; 689 case 0: 690 rqstp->rq_client = &ipm->m_client->h; 691 kref_get(&rqstp->rq_client->ref); 692 ip_map_cached_put(xprt, ipm); 693 break; 694 } 695 696 gi = unix_gid_find(cred->cr_uid, rqstp); 697 switch (PTR_ERR(gi)) { 698 case -EAGAIN: 699 return SVC_DROP; 700 case -ESHUTDOWN: 701 return SVC_CLOSE; 702 case -ENOENT: 703 break; 704 default: 705 put_group_info(cred->cr_group_info); 706 cred->cr_group_info = gi; 707 } 708 return SVC_OK; 709 } 710 711 EXPORT_SYMBOL_GPL(svcauth_unix_set_client); 712 713 static int 714 svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp) 715 { 716 struct kvec *argv = &rqstp->rq_arg.head[0]; 717 struct kvec *resv = &rqstp->rq_res.head[0]; 718 struct svc_cred *cred = &rqstp->rq_cred; 719 720 cred->cr_group_info = NULL; 721 rqstp->rq_client = NULL; 722 723 if (argv->iov_len < 3*4) 724 return SVC_GARBAGE; 725 726 if (svc_getu32(argv) != 0) { 727 dprintk("svc: bad null cred\n"); 728 *authp = rpc_autherr_badcred; 729 return SVC_DENIED; 730 } 731 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 732 dprintk("svc: bad null verf\n"); 733 *authp = rpc_autherr_badverf; 734 return SVC_DENIED; 735 } 736 737 /* Signal that mapping to nobody uid/gid is required */ 738 cred->cr_uid = (uid_t) -1; 739 cred->cr_gid = (gid_t) -1; 740 cred->cr_group_info = groups_alloc(0); 741 if (cred->cr_group_info == NULL) 742 return SVC_CLOSE; /* kmalloc failure - client must retry */ 743 744 /* Put NULL verifier */ 745 svc_putnl(resv, RPC_AUTH_NULL); 746 svc_putnl(resv, 0); 747 748 rqstp->rq_flavor = RPC_AUTH_NULL; 749 return SVC_OK; 750 } 751 752 static int 753 svcauth_null_release(struct svc_rqst *rqstp) 754 { 755 if (rqstp->rq_client) 756 auth_domain_put(rqstp->rq_client); 757 rqstp->rq_client = NULL; 758 if (rqstp->rq_cred.cr_group_info) 759 put_group_info(rqstp->rq_cred.cr_group_info); 760 rqstp->rq_cred.cr_group_info = NULL; 761 762 return 0; /* don't drop */ 763 } 764 765 766 struct auth_ops svcauth_null = { 767 .name = "null", 768 .owner = THIS_MODULE, 769 .flavour = RPC_AUTH_NULL, 770 .accept = svcauth_null_accept, 771 .release = svcauth_null_release, 772 .set_client = svcauth_unix_set_client, 773 }; 774 775 776 static int 777 svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) 778 { 779 struct kvec *argv = &rqstp->rq_arg.head[0]; 780 struct kvec *resv = &rqstp->rq_res.head[0]; 781 struct svc_cred *cred = &rqstp->rq_cred; 782 u32 slen, i; 783 int len = argv->iov_len; 784 785 cred->cr_group_info = NULL; 786 rqstp->rq_client = NULL; 787 788 if ((len -= 3*4) < 0) 789 return SVC_GARBAGE; 790 791 svc_getu32(argv); /* length */ 792 svc_getu32(argv); /* time stamp */ 793 slen = XDR_QUADLEN(svc_getnl(argv)); /* machname length */ 794 if (slen > 64 || (len -= (slen + 3)*4) < 0) 795 goto badcred; 796 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 797 argv->iov_len -= slen*4; 798 799 cred->cr_uid = svc_getnl(argv); /* uid */ 800 cred->cr_gid = svc_getnl(argv); /* gid */ 801 slen = svc_getnl(argv); /* gids length */ 802 if (slen > 16 || (len -= (slen + 2)*4) < 0) 803 goto badcred; 804 cred->cr_group_info = groups_alloc(slen); 805 if (cred->cr_group_info == NULL) 806 return SVC_CLOSE; 807 for (i = 0; i < slen; i++) 808 GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); 809 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { 810 *authp = rpc_autherr_badverf; 811 return SVC_DENIED; 812 } 813 814 /* Put NULL verifier */ 815 svc_putnl(resv, RPC_AUTH_NULL); 816 svc_putnl(resv, 0); 817 818 rqstp->rq_flavor = RPC_AUTH_UNIX; 819 return SVC_OK; 820 821 badcred: 822 *authp = rpc_autherr_badcred; 823 return SVC_DENIED; 824 } 825 826 static int 827 svcauth_unix_release(struct svc_rqst *rqstp) 828 { 829 /* Verifier (such as it is) is already in place. 830 */ 831 if (rqstp->rq_client) 832 auth_domain_put(rqstp->rq_client); 833 rqstp->rq_client = NULL; 834 if (rqstp->rq_cred.cr_group_info) 835 put_group_info(rqstp->rq_cred.cr_group_info); 836 rqstp->rq_cred.cr_group_info = NULL; 837 838 return 0; 839 } 840 841 842 struct auth_ops svcauth_unix = { 843 .name = "unix", 844 .owner = THIS_MODULE, 845 .flavour = RPC_AUTH_UNIX, 846 .accept = svcauth_unix_accept, 847 .release = svcauth_unix_release, 848 .domain_release = svcauth_unix_domain_release, 849 .set_client = svcauth_unix_set_client, 850 }; 851 852 int ip_map_cache_create(struct net *net) 853 { 854 int err = -ENOMEM; 855 struct cache_detail *cd; 856 struct cache_head **tbl; 857 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 858 859 cd = kzalloc(sizeof(struct cache_detail), GFP_KERNEL); 860 if (cd == NULL) 861 goto err_cd; 862 863 tbl = kzalloc(IP_HASHMAX * sizeof(struct cache_head *), GFP_KERNEL); 864 if (tbl == NULL) 865 goto err_tbl; 866 867 cd->owner = THIS_MODULE, 868 cd->hash_size = IP_HASHMAX, 869 cd->hash_table = tbl, 870 cd->name = "auth.unix.ip", 871 cd->cache_put = ip_map_put, 872 cd->cache_upcall = ip_map_upcall, 873 cd->cache_parse = ip_map_parse, 874 cd->cache_show = ip_map_show, 875 cd->match = ip_map_match, 876 cd->init = ip_map_init, 877 cd->update = update, 878 cd->alloc = ip_map_alloc, 879 880 err = cache_register_net(cd, net); 881 if (err) 882 goto err_reg; 883 884 sn->ip_map_cache = cd; 885 return 0; 886 887 err_reg: 888 kfree(tbl); 889 err_tbl: 890 kfree(cd); 891 err_cd: 892 return err; 893 } 894 895 void ip_map_cache_destroy(struct net *net) 896 { 897 struct sunrpc_net *sn; 898 899 sn = net_generic(net, sunrpc_net_id); 900 cache_purge(sn->ip_map_cache); 901 cache_unregister_net(sn->ip_map_cache, net); 902 kfree(sn->ip_map_cache->hash_table); 903 kfree(sn->ip_map_cache); 904 } 905