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