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