0001
0002 #include <linux/types.h>
0003 #include <linux/sched.h>
0004 #include <linux/module.h>
0005 #include <linux/sunrpc/types.h>
0006 #include <linux/sunrpc/xdr.h>
0007 #include <linux/sunrpc/svcsock.h>
0008 #include <linux/sunrpc/svcauth.h>
0009 #include <linux/sunrpc/gss_api.h>
0010 #include <linux/sunrpc/addr.h>
0011 #include <linux/err.h>
0012 #include <linux/seq_file.h>
0013 #include <linux/hash.h>
0014 #include <linux/string.h>
0015 #include <linux/slab.h>
0016 #include <net/sock.h>
0017 #include <net/ipv6.h>
0018 #include <linux/kernel.h>
0019 #include <linux/user_namespace.h>
0020 #define RPCDBG_FACILITY RPCDBG_AUTH
0021
0022
0023 #include "netns.h"
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 struct unix_domain {
0034 struct auth_domain h;
0035
0036 };
0037
0038 extern struct auth_ops svcauth_null;
0039 extern struct auth_ops svcauth_unix;
0040 extern struct auth_ops svcauth_tls;
0041
0042 static void svcauth_unix_domain_release_rcu(struct rcu_head *head)
0043 {
0044 struct auth_domain *dom = container_of(head, struct auth_domain, rcu_head);
0045 struct unix_domain *ud = container_of(dom, struct unix_domain, h);
0046
0047 kfree(dom->name);
0048 kfree(ud);
0049 }
0050
0051 static void svcauth_unix_domain_release(struct auth_domain *dom)
0052 {
0053 call_rcu(&dom->rcu_head, svcauth_unix_domain_release_rcu);
0054 }
0055
0056 struct auth_domain *unix_domain_find(char *name)
0057 {
0058 struct auth_domain *rv;
0059 struct unix_domain *new = NULL;
0060
0061 rv = auth_domain_find(name);
0062 while(1) {
0063 if (rv) {
0064 if (new && rv != &new->h)
0065 svcauth_unix_domain_release(&new->h);
0066
0067 if (rv->flavour != &svcauth_unix) {
0068 auth_domain_put(rv);
0069 return NULL;
0070 }
0071 return rv;
0072 }
0073
0074 new = kmalloc(sizeof(*new), GFP_KERNEL);
0075 if (new == NULL)
0076 return NULL;
0077 kref_init(&new->h.ref);
0078 new->h.name = kstrdup(name, GFP_KERNEL);
0079 if (new->h.name == NULL) {
0080 kfree(new);
0081 return NULL;
0082 }
0083 new->h.flavour = &svcauth_unix;
0084 rv = auth_domain_lookup(name, &new->h);
0085 }
0086 }
0087 EXPORT_SYMBOL_GPL(unix_domain_find);
0088
0089
0090
0091
0092
0093
0094 #define IP_HASHBITS 8
0095 #define IP_HASHMAX (1<<IP_HASHBITS)
0096
0097 struct ip_map {
0098 struct cache_head h;
0099 char m_class[8];
0100 struct in6_addr m_addr;
0101 struct unix_domain *m_client;
0102 struct rcu_head m_rcu;
0103 };
0104
0105 static void ip_map_put(struct kref *kref)
0106 {
0107 struct cache_head *item = container_of(kref, struct cache_head, ref);
0108 struct ip_map *im = container_of(item, struct ip_map,h);
0109
0110 if (test_bit(CACHE_VALID, &item->flags) &&
0111 !test_bit(CACHE_NEGATIVE, &item->flags))
0112 auth_domain_put(&im->m_client->h);
0113 kfree_rcu(im, m_rcu);
0114 }
0115
0116 static inline int hash_ip6(const struct in6_addr *ip)
0117 {
0118 return hash_32(ipv6_addr_hash(ip), IP_HASHBITS);
0119 }
0120 static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
0121 {
0122 struct ip_map *orig = container_of(corig, struct ip_map, h);
0123 struct ip_map *new = container_of(cnew, struct ip_map, h);
0124 return strcmp(orig->m_class, new->m_class) == 0 &&
0125 ipv6_addr_equal(&orig->m_addr, &new->m_addr);
0126 }
0127 static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
0128 {
0129 struct ip_map *new = container_of(cnew, struct ip_map, h);
0130 struct ip_map *item = container_of(citem, struct ip_map, h);
0131
0132 strcpy(new->m_class, item->m_class);
0133 new->m_addr = item->m_addr;
0134 }
0135 static void update(struct cache_head *cnew, struct cache_head *citem)
0136 {
0137 struct ip_map *new = container_of(cnew, struct ip_map, h);
0138 struct ip_map *item = container_of(citem, struct ip_map, h);
0139
0140 kref_get(&item->m_client->h.ref);
0141 new->m_client = item->m_client;
0142 }
0143 static struct cache_head *ip_map_alloc(void)
0144 {
0145 struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL);
0146 if (i)
0147 return &i->h;
0148 else
0149 return NULL;
0150 }
0151
0152 static int ip_map_upcall(struct cache_detail *cd, struct cache_head *h)
0153 {
0154 return sunrpc_cache_pipe_upcall(cd, h);
0155 }
0156
0157 static void ip_map_request(struct cache_detail *cd,
0158 struct cache_head *h,
0159 char **bpp, int *blen)
0160 {
0161 char text_addr[40];
0162 struct ip_map *im = container_of(h, struct ip_map, h);
0163
0164 if (ipv6_addr_v4mapped(&(im->m_addr))) {
0165 snprintf(text_addr, 20, "%pI4", &im->m_addr.s6_addr32[3]);
0166 } else {
0167 snprintf(text_addr, 40, "%pI6", &im->m_addr);
0168 }
0169 qword_add(bpp, blen, im->m_class);
0170 qword_add(bpp, blen, text_addr);
0171 (*bpp)[-1] = '\n';
0172 }
0173
0174 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
0175 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time64_t expiry);
0176
0177 static int ip_map_parse(struct cache_detail *cd,
0178 char *mesg, int mlen)
0179 {
0180
0181
0182
0183 char *buf = mesg;
0184 int len;
0185 char class[8];
0186 union {
0187 struct sockaddr sa;
0188 struct sockaddr_in s4;
0189 struct sockaddr_in6 s6;
0190 } address;
0191 struct sockaddr_in6 sin6;
0192 int err;
0193
0194 struct ip_map *ipmp;
0195 struct auth_domain *dom;
0196 time64_t expiry;
0197
0198 if (mesg[mlen-1] != '\n')
0199 return -EINVAL;
0200 mesg[mlen-1] = 0;
0201
0202
0203 len = qword_get(&mesg, class, sizeof(class));
0204 if (len <= 0) return -EINVAL;
0205
0206
0207 len = qword_get(&mesg, buf, mlen);
0208 if (len <= 0) return -EINVAL;
0209
0210 if (rpc_pton(cd->net, buf, len, &address.sa, sizeof(address)) == 0)
0211 return -EINVAL;
0212 switch (address.sa.sa_family) {
0213 case AF_INET:
0214
0215 sin6.sin6_family = AF_INET6;
0216 ipv6_addr_set_v4mapped(address.s4.sin_addr.s_addr,
0217 &sin6.sin6_addr);
0218 break;
0219 #if IS_ENABLED(CONFIG_IPV6)
0220 case AF_INET6:
0221 memcpy(&sin6, &address.s6, sizeof(sin6));
0222 break;
0223 #endif
0224 default:
0225 return -EINVAL;
0226 }
0227
0228 expiry = get_expiry(&mesg);
0229 if (expiry ==0)
0230 return -EINVAL;
0231
0232
0233 len = qword_get(&mesg, buf, mlen);
0234 if (len < 0) return -EINVAL;
0235
0236 if (len) {
0237 dom = unix_domain_find(buf);
0238 if (dom == NULL)
0239 return -ENOENT;
0240 } else
0241 dom = NULL;
0242
0243
0244 ipmp = __ip_map_lookup(cd, class, &sin6.sin6_addr);
0245 if (ipmp) {
0246 err = __ip_map_update(cd, ipmp,
0247 container_of(dom, struct unix_domain, h),
0248 expiry);
0249 } else
0250 err = -ENOMEM;
0251
0252 if (dom)
0253 auth_domain_put(dom);
0254
0255 cache_flush();
0256 return err;
0257 }
0258
0259 static int ip_map_show(struct seq_file *m,
0260 struct cache_detail *cd,
0261 struct cache_head *h)
0262 {
0263 struct ip_map *im;
0264 struct in6_addr addr;
0265 char *dom = "-no-domain-";
0266
0267 if (h == NULL) {
0268 seq_puts(m, "#class IP domain\n");
0269 return 0;
0270 }
0271 im = container_of(h, struct ip_map, h);
0272
0273 addr = im->m_addr;
0274
0275 if (test_bit(CACHE_VALID, &h->flags) &&
0276 !test_bit(CACHE_NEGATIVE, &h->flags))
0277 dom = im->m_client->h.name;
0278
0279 if (ipv6_addr_v4mapped(&addr)) {
0280 seq_printf(m, "%s %pI4 %s\n",
0281 im->m_class, &addr.s6_addr32[3], dom);
0282 } else {
0283 seq_printf(m, "%s %pI6 %s\n", im->m_class, &addr, dom);
0284 }
0285 return 0;
0286 }
0287
0288
0289 static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class,
0290 struct in6_addr *addr)
0291 {
0292 struct ip_map ip;
0293 struct cache_head *ch;
0294
0295 strcpy(ip.m_class, class);
0296 ip.m_addr = *addr;
0297 ch = sunrpc_cache_lookup_rcu(cd, &ip.h,
0298 hash_str(class, IP_HASHBITS) ^
0299 hash_ip6(addr));
0300
0301 if (ch)
0302 return container_of(ch, struct ip_map, h);
0303 else
0304 return NULL;
0305 }
0306
0307 static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm,
0308 struct unix_domain *udom, time64_t expiry)
0309 {
0310 struct ip_map ip;
0311 struct cache_head *ch;
0312
0313 ip.m_client = udom;
0314 ip.h.flags = 0;
0315 if (!udom)
0316 set_bit(CACHE_NEGATIVE, &ip.h.flags);
0317 ip.h.expiry_time = expiry;
0318 ch = sunrpc_cache_update(cd, &ip.h, &ipm->h,
0319 hash_str(ipm->m_class, IP_HASHBITS) ^
0320 hash_ip6(&ipm->m_addr));
0321 if (!ch)
0322 return -ENOMEM;
0323 cache_put(ch, cd);
0324 return 0;
0325 }
0326
0327 void svcauth_unix_purge(struct net *net)
0328 {
0329 struct sunrpc_net *sn;
0330
0331 sn = net_generic(net, sunrpc_net_id);
0332 cache_purge(sn->ip_map_cache);
0333 }
0334 EXPORT_SYMBOL_GPL(svcauth_unix_purge);
0335
0336 static inline struct ip_map *
0337 ip_map_cached_get(struct svc_xprt *xprt)
0338 {
0339 struct ip_map *ipm = NULL;
0340 struct sunrpc_net *sn;
0341
0342 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) {
0343 spin_lock(&xprt->xpt_lock);
0344 ipm = xprt->xpt_auth_cache;
0345 if (ipm != NULL) {
0346 sn = net_generic(xprt->xpt_net, sunrpc_net_id);
0347 if (cache_is_expired(sn->ip_map_cache, &ipm->h)) {
0348
0349
0350
0351
0352
0353 xprt->xpt_auth_cache = NULL;
0354 spin_unlock(&xprt->xpt_lock);
0355 cache_put(&ipm->h, sn->ip_map_cache);
0356 return NULL;
0357 }
0358 cache_get(&ipm->h);
0359 }
0360 spin_unlock(&xprt->xpt_lock);
0361 }
0362 return ipm;
0363 }
0364
0365 static inline void
0366 ip_map_cached_put(struct svc_xprt *xprt, struct ip_map *ipm)
0367 {
0368 if (test_bit(XPT_CACHE_AUTH, &xprt->xpt_flags)) {
0369 spin_lock(&xprt->xpt_lock);
0370 if (xprt->xpt_auth_cache == NULL) {
0371
0372 xprt->xpt_auth_cache = ipm;
0373 ipm = NULL;
0374 }
0375 spin_unlock(&xprt->xpt_lock);
0376 }
0377 if (ipm) {
0378 struct sunrpc_net *sn;
0379
0380 sn = net_generic(xprt->xpt_net, sunrpc_net_id);
0381 cache_put(&ipm->h, sn->ip_map_cache);
0382 }
0383 }
0384
0385 void
0386 svcauth_unix_info_release(struct svc_xprt *xpt)
0387 {
0388 struct ip_map *ipm;
0389
0390 ipm = xpt->xpt_auth_cache;
0391 if (ipm != NULL) {
0392 struct sunrpc_net *sn;
0393
0394 sn = net_generic(xpt->xpt_net, sunrpc_net_id);
0395 cache_put(&ipm->h, sn->ip_map_cache);
0396 }
0397 }
0398
0399
0400
0401
0402
0403
0404 #define GID_HASHBITS 8
0405 #define GID_HASHMAX (1<<GID_HASHBITS)
0406
0407 struct unix_gid {
0408 struct cache_head h;
0409 kuid_t uid;
0410 struct group_info *gi;
0411 struct rcu_head rcu;
0412 };
0413
0414 static int unix_gid_hash(kuid_t uid)
0415 {
0416 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
0417 }
0418
0419 static void unix_gid_put(struct kref *kref)
0420 {
0421 struct cache_head *item = container_of(kref, struct cache_head, ref);
0422 struct unix_gid *ug = container_of(item, struct unix_gid, h);
0423 if (test_bit(CACHE_VALID, &item->flags) &&
0424 !test_bit(CACHE_NEGATIVE, &item->flags))
0425 put_group_info(ug->gi);
0426 kfree_rcu(ug, rcu);
0427 }
0428
0429 static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
0430 {
0431 struct unix_gid *orig = container_of(corig, struct unix_gid, h);
0432 struct unix_gid *new = container_of(cnew, struct unix_gid, h);
0433 return uid_eq(orig->uid, new->uid);
0434 }
0435 static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem)
0436 {
0437 struct unix_gid *new = container_of(cnew, struct unix_gid, h);
0438 struct unix_gid *item = container_of(citem, struct unix_gid, h);
0439 new->uid = item->uid;
0440 }
0441 static void unix_gid_update(struct cache_head *cnew, struct cache_head *citem)
0442 {
0443 struct unix_gid *new = container_of(cnew, struct unix_gid, h);
0444 struct unix_gid *item = container_of(citem, struct unix_gid, h);
0445
0446 get_group_info(item->gi);
0447 new->gi = item->gi;
0448 }
0449 static struct cache_head *unix_gid_alloc(void)
0450 {
0451 struct unix_gid *g = kmalloc(sizeof(*g), GFP_KERNEL);
0452 if (g)
0453 return &g->h;
0454 else
0455 return NULL;
0456 }
0457
0458 static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h)
0459 {
0460 return sunrpc_cache_pipe_upcall_timeout(cd, h);
0461 }
0462
0463 static void unix_gid_request(struct cache_detail *cd,
0464 struct cache_head *h,
0465 char **bpp, int *blen)
0466 {
0467 char tuid[20];
0468 struct unix_gid *ug = container_of(h, struct unix_gid, h);
0469
0470 snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
0471 qword_add(bpp, blen, tuid);
0472 (*bpp)[-1] = '\n';
0473 }
0474
0475 static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid);
0476
0477 static int unix_gid_parse(struct cache_detail *cd,
0478 char *mesg, int mlen)
0479 {
0480
0481 int id;
0482 kuid_t uid;
0483 int gids;
0484 int rv;
0485 int i;
0486 int err;
0487 time64_t expiry;
0488 struct unix_gid ug, *ugp;
0489
0490 if (mesg[mlen - 1] != '\n')
0491 return -EINVAL;
0492 mesg[mlen-1] = 0;
0493
0494 rv = get_int(&mesg, &id);
0495 if (rv)
0496 return -EINVAL;
0497 uid = make_kuid(current_user_ns(), id);
0498 ug.uid = uid;
0499
0500 expiry = get_expiry(&mesg);
0501 if (expiry == 0)
0502 return -EINVAL;
0503
0504 rv = get_int(&mesg, &gids);
0505 if (rv || gids < 0 || gids > 8192)
0506 return -EINVAL;
0507
0508 ug.gi = groups_alloc(gids);
0509 if (!ug.gi)
0510 return -ENOMEM;
0511
0512 for (i = 0 ; i < gids ; i++) {
0513 int gid;
0514 kgid_t kgid;
0515 rv = get_int(&mesg, &gid);
0516 err = -EINVAL;
0517 if (rv)
0518 goto out;
0519 kgid = make_kgid(current_user_ns(), gid);
0520 if (!gid_valid(kgid))
0521 goto out;
0522 ug.gi->gid[i] = kgid;
0523 }
0524
0525 groups_sort(ug.gi);
0526 ugp = unix_gid_lookup(cd, uid);
0527 if (ugp) {
0528 struct cache_head *ch;
0529 ug.h.flags = 0;
0530 ug.h.expiry_time = expiry;
0531 ch = sunrpc_cache_update(cd,
0532 &ug.h, &ugp->h,
0533 unix_gid_hash(uid));
0534 if (!ch)
0535 err = -ENOMEM;
0536 else {
0537 err = 0;
0538 cache_put(ch, cd);
0539 }
0540 } else
0541 err = -ENOMEM;
0542 out:
0543 if (ug.gi)
0544 put_group_info(ug.gi);
0545 return err;
0546 }
0547
0548 static int unix_gid_show(struct seq_file *m,
0549 struct cache_detail *cd,
0550 struct cache_head *h)
0551 {
0552 struct user_namespace *user_ns = m->file->f_cred->user_ns;
0553 struct unix_gid *ug;
0554 int i;
0555 int glen;
0556
0557 if (h == NULL) {
0558 seq_puts(m, "#uid cnt: gids...\n");
0559 return 0;
0560 }
0561 ug = container_of(h, struct unix_gid, h);
0562 if (test_bit(CACHE_VALID, &h->flags) &&
0563 !test_bit(CACHE_NEGATIVE, &h->flags))
0564 glen = ug->gi->ngroups;
0565 else
0566 glen = 0;
0567
0568 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
0569 for (i = 0; i < glen; i++)
0570 seq_printf(m, " %d", from_kgid_munged(user_ns, ug->gi->gid[i]));
0571 seq_printf(m, "\n");
0572 return 0;
0573 }
0574
0575 static const struct cache_detail unix_gid_cache_template = {
0576 .owner = THIS_MODULE,
0577 .hash_size = GID_HASHMAX,
0578 .name = "auth.unix.gid",
0579 .cache_put = unix_gid_put,
0580 .cache_upcall = unix_gid_upcall,
0581 .cache_request = unix_gid_request,
0582 .cache_parse = unix_gid_parse,
0583 .cache_show = unix_gid_show,
0584 .match = unix_gid_match,
0585 .init = unix_gid_init,
0586 .update = unix_gid_update,
0587 .alloc = unix_gid_alloc,
0588 };
0589
0590 int unix_gid_cache_create(struct net *net)
0591 {
0592 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0593 struct cache_detail *cd;
0594 int err;
0595
0596 cd = cache_create_net(&unix_gid_cache_template, net);
0597 if (IS_ERR(cd))
0598 return PTR_ERR(cd);
0599 err = cache_register_net(cd, net);
0600 if (err) {
0601 cache_destroy_net(cd, net);
0602 return err;
0603 }
0604 sn->unix_gid_cache = cd;
0605 return 0;
0606 }
0607
0608 void unix_gid_cache_destroy(struct net *net)
0609 {
0610 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0611 struct cache_detail *cd = sn->unix_gid_cache;
0612
0613 sn->unix_gid_cache = NULL;
0614 cache_purge(cd);
0615 cache_unregister_net(cd, net);
0616 cache_destroy_net(cd, net);
0617 }
0618
0619 static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
0620 {
0621 struct unix_gid ug;
0622 struct cache_head *ch;
0623
0624 ug.uid = uid;
0625 ch = sunrpc_cache_lookup_rcu(cd, &ug.h, unix_gid_hash(uid));
0626 if (ch)
0627 return container_of(ch, struct unix_gid, h);
0628 else
0629 return NULL;
0630 }
0631
0632 static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
0633 {
0634 struct unix_gid *ug;
0635 struct group_info *gi;
0636 int ret;
0637 struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net,
0638 sunrpc_net_id);
0639
0640 ug = unix_gid_lookup(sn->unix_gid_cache, uid);
0641 if (!ug)
0642 return ERR_PTR(-EAGAIN);
0643 ret = cache_check(sn->unix_gid_cache, &ug->h, &rqstp->rq_chandle);
0644 switch (ret) {
0645 case -ENOENT:
0646 return ERR_PTR(-ENOENT);
0647 case -ETIMEDOUT:
0648 return ERR_PTR(-ESHUTDOWN);
0649 case 0:
0650 gi = get_group_info(ug->gi);
0651 cache_put(&ug->h, sn->unix_gid_cache);
0652 return gi;
0653 default:
0654 return ERR_PTR(-EAGAIN);
0655 }
0656 }
0657
0658 int
0659 svcauth_unix_set_client(struct svc_rqst *rqstp)
0660 {
0661 struct sockaddr_in *sin;
0662 struct sockaddr_in6 *sin6, sin6_storage;
0663 struct ip_map *ipm;
0664 struct group_info *gi;
0665 struct svc_cred *cred = &rqstp->rq_cred;
0666 struct svc_xprt *xprt = rqstp->rq_xprt;
0667 struct net *net = xprt->xpt_net;
0668 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0669
0670 switch (rqstp->rq_addr.ss_family) {
0671 case AF_INET:
0672 sin = svc_addr_in(rqstp);
0673 sin6 = &sin6_storage;
0674 ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, &sin6->sin6_addr);
0675 break;
0676 case AF_INET6:
0677 sin6 = svc_addr_in6(rqstp);
0678 break;
0679 default:
0680 BUG();
0681 }
0682
0683 rqstp->rq_client = NULL;
0684 if (rqstp->rq_proc == 0)
0685 goto out;
0686
0687 rqstp->rq_auth_stat = rpc_autherr_badcred;
0688 ipm = ip_map_cached_get(xprt);
0689 if (ipm == NULL)
0690 ipm = __ip_map_lookup(sn->ip_map_cache, rqstp->rq_server->sv_program->pg_class,
0691 &sin6->sin6_addr);
0692
0693 if (ipm == NULL)
0694 return SVC_DENIED;
0695
0696 switch (cache_check(sn->ip_map_cache, &ipm->h, &rqstp->rq_chandle)) {
0697 default:
0698 BUG();
0699 case -ETIMEDOUT:
0700 return SVC_CLOSE;
0701 case -EAGAIN:
0702 return SVC_DROP;
0703 case -ENOENT:
0704 return SVC_DENIED;
0705 case 0:
0706 rqstp->rq_client = &ipm->m_client->h;
0707 kref_get(&rqstp->rq_client->ref);
0708 ip_map_cached_put(xprt, ipm);
0709 break;
0710 }
0711
0712 gi = unix_gid_find(cred->cr_uid, rqstp);
0713 switch (PTR_ERR(gi)) {
0714 case -EAGAIN:
0715 return SVC_DROP;
0716 case -ESHUTDOWN:
0717 return SVC_CLOSE;
0718 case -ENOENT:
0719 break;
0720 default:
0721 put_group_info(cred->cr_group_info);
0722 cred->cr_group_info = gi;
0723 }
0724
0725 out:
0726 rqstp->rq_auth_stat = rpc_auth_ok;
0727 return SVC_OK;
0728 }
0729
0730 EXPORT_SYMBOL_GPL(svcauth_unix_set_client);
0731
0732 static int
0733 svcauth_null_accept(struct svc_rqst *rqstp)
0734 {
0735 struct kvec *argv = &rqstp->rq_arg.head[0];
0736 struct kvec *resv = &rqstp->rq_res.head[0];
0737 struct svc_cred *cred = &rqstp->rq_cred;
0738
0739 if (argv->iov_len < 3*4)
0740 return SVC_GARBAGE;
0741
0742 if (svc_getu32(argv) != 0) {
0743 dprintk("svc: bad null cred\n");
0744 rqstp->rq_auth_stat = rpc_autherr_badcred;
0745 return SVC_DENIED;
0746 }
0747 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
0748 dprintk("svc: bad null verf\n");
0749 rqstp->rq_auth_stat = rpc_autherr_badverf;
0750 return SVC_DENIED;
0751 }
0752
0753
0754 cred->cr_uid = INVALID_UID;
0755 cred->cr_gid = INVALID_GID;
0756 cred->cr_group_info = groups_alloc(0);
0757 if (cred->cr_group_info == NULL)
0758 return SVC_CLOSE;
0759
0760
0761 svc_putnl(resv, RPC_AUTH_NULL);
0762 svc_putnl(resv, 0);
0763
0764 rqstp->rq_cred.cr_flavor = RPC_AUTH_NULL;
0765 return SVC_OK;
0766 }
0767
0768 static int
0769 svcauth_null_release(struct svc_rqst *rqstp)
0770 {
0771 if (rqstp->rq_client)
0772 auth_domain_put(rqstp->rq_client);
0773 rqstp->rq_client = NULL;
0774 if (rqstp->rq_cred.cr_group_info)
0775 put_group_info(rqstp->rq_cred.cr_group_info);
0776 rqstp->rq_cred.cr_group_info = NULL;
0777
0778 return 0;
0779 }
0780
0781
0782 struct auth_ops svcauth_null = {
0783 .name = "null",
0784 .owner = THIS_MODULE,
0785 .flavour = RPC_AUTH_NULL,
0786 .accept = svcauth_null_accept,
0787 .release = svcauth_null_release,
0788 .set_client = svcauth_unix_set_client,
0789 };
0790
0791
0792 static int
0793 svcauth_tls_accept(struct svc_rqst *rqstp)
0794 {
0795 struct svc_cred *cred = &rqstp->rq_cred;
0796 struct kvec *argv = rqstp->rq_arg.head;
0797 struct kvec *resv = rqstp->rq_res.head;
0798
0799 if (argv->iov_len < XDR_UNIT * 3)
0800 return SVC_GARBAGE;
0801
0802
0803 if (svc_getu32(argv) != xdr_zero) {
0804 rqstp->rq_auth_stat = rpc_autherr_badcred;
0805 return SVC_DENIED;
0806 }
0807
0808
0809 if (svc_getu32(argv) != rpc_auth_null ||
0810 svc_getu32(argv) != xdr_zero) {
0811 rqstp->rq_auth_stat = rpc_autherr_badverf;
0812 return SVC_DENIED;
0813 }
0814
0815
0816 if (rqstp->rq_proc != 0) {
0817 rqstp->rq_auth_stat = rpc_autherr_badcred;
0818 return SVC_DENIED;
0819 }
0820
0821
0822 cred->cr_uid = INVALID_UID;
0823 cred->cr_gid = INVALID_GID;
0824 cred->cr_group_info = groups_alloc(0);
0825 if (cred->cr_group_info == NULL)
0826 return SVC_CLOSE;
0827
0828
0829 svc_putnl(resv, RPC_AUTH_NULL);
0830 if (rqstp->rq_xprt->xpt_ops->xpo_start_tls) {
0831 svc_putnl(resv, 8);
0832 memcpy(resv->iov_base + resv->iov_len, "STARTTLS", 8);
0833 resv->iov_len += 8;
0834 } else
0835 svc_putnl(resv, 0);
0836
0837 rqstp->rq_cred.cr_flavor = RPC_AUTH_TLS;
0838 return SVC_OK;
0839 }
0840
0841 struct auth_ops svcauth_tls = {
0842 .name = "tls",
0843 .owner = THIS_MODULE,
0844 .flavour = RPC_AUTH_TLS,
0845 .accept = svcauth_tls_accept,
0846 .release = svcauth_null_release,
0847 .set_client = svcauth_unix_set_client,
0848 };
0849
0850
0851 static int
0852 svcauth_unix_accept(struct svc_rqst *rqstp)
0853 {
0854 struct kvec *argv = &rqstp->rq_arg.head[0];
0855 struct kvec *resv = &rqstp->rq_res.head[0];
0856 struct svc_cred *cred = &rqstp->rq_cred;
0857 struct user_namespace *userns;
0858 u32 slen, i;
0859 int len = argv->iov_len;
0860
0861 if ((len -= 3*4) < 0)
0862 return SVC_GARBAGE;
0863
0864 svc_getu32(argv);
0865 svc_getu32(argv);
0866 slen = XDR_QUADLEN(svc_getnl(argv));
0867 if (slen > 64 || (len -= (slen + 3)*4) < 0)
0868 goto badcred;
0869 argv->iov_base = (void*)((__be32*)argv->iov_base + slen);
0870 argv->iov_len -= slen*4;
0871
0872
0873
0874
0875
0876
0877
0878 userns = (rqstp->rq_xprt && rqstp->rq_xprt->xpt_cred) ?
0879 rqstp->rq_xprt->xpt_cred->user_ns : &init_user_ns;
0880 cred->cr_uid = make_kuid(userns, svc_getnl(argv));
0881 cred->cr_gid = make_kgid(userns, svc_getnl(argv));
0882 slen = svc_getnl(argv);
0883 if (slen > UNX_NGROUPS || (len -= (slen + 2)*4) < 0)
0884 goto badcred;
0885 cred->cr_group_info = groups_alloc(slen);
0886 if (cred->cr_group_info == NULL)
0887 return SVC_CLOSE;
0888 for (i = 0; i < slen; i++) {
0889 kgid_t kgid = make_kgid(userns, svc_getnl(argv));
0890 cred->cr_group_info->gid[i] = kgid;
0891 }
0892 groups_sort(cred->cr_group_info);
0893 if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
0894 rqstp->rq_auth_stat = rpc_autherr_badverf;
0895 return SVC_DENIED;
0896 }
0897
0898
0899 svc_putnl(resv, RPC_AUTH_NULL);
0900 svc_putnl(resv, 0);
0901
0902 rqstp->rq_cred.cr_flavor = RPC_AUTH_UNIX;
0903 return SVC_OK;
0904
0905 badcred:
0906 rqstp->rq_auth_stat = rpc_autherr_badcred;
0907 return SVC_DENIED;
0908 }
0909
0910 static int
0911 svcauth_unix_release(struct svc_rqst *rqstp)
0912 {
0913
0914
0915 if (rqstp->rq_client)
0916 auth_domain_put(rqstp->rq_client);
0917 rqstp->rq_client = NULL;
0918 if (rqstp->rq_cred.cr_group_info)
0919 put_group_info(rqstp->rq_cred.cr_group_info);
0920 rqstp->rq_cred.cr_group_info = NULL;
0921
0922 return 0;
0923 }
0924
0925
0926 struct auth_ops svcauth_unix = {
0927 .name = "unix",
0928 .owner = THIS_MODULE,
0929 .flavour = RPC_AUTH_UNIX,
0930 .accept = svcauth_unix_accept,
0931 .release = svcauth_unix_release,
0932 .domain_release = svcauth_unix_domain_release,
0933 .set_client = svcauth_unix_set_client,
0934 };
0935
0936 static const struct cache_detail ip_map_cache_template = {
0937 .owner = THIS_MODULE,
0938 .hash_size = IP_HASHMAX,
0939 .name = "auth.unix.ip",
0940 .cache_put = ip_map_put,
0941 .cache_upcall = ip_map_upcall,
0942 .cache_request = ip_map_request,
0943 .cache_parse = ip_map_parse,
0944 .cache_show = ip_map_show,
0945 .match = ip_map_match,
0946 .init = ip_map_init,
0947 .update = update,
0948 .alloc = ip_map_alloc,
0949 };
0950
0951 int ip_map_cache_create(struct net *net)
0952 {
0953 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0954 struct cache_detail *cd;
0955 int err;
0956
0957 cd = cache_create_net(&ip_map_cache_template, net);
0958 if (IS_ERR(cd))
0959 return PTR_ERR(cd);
0960 err = cache_register_net(cd, net);
0961 if (err) {
0962 cache_destroy_net(cd, net);
0963 return err;
0964 }
0965 sn->ip_map_cache = cd;
0966 return 0;
0967 }
0968
0969 void ip_map_cache_destroy(struct net *net)
0970 {
0971 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0972 struct cache_detail *cd = sn->ip_map_cache;
0973
0974 sn->ip_map_cache = NULL;
0975 cache_purge(cd);
0976 cache_unregister_net(cd, net);
0977 cache_destroy_net(cd, net);
0978 }