1 #include <linux/types.h>
2 #include <linux/sched.h>
3 #include <linux/module.h>
11 #include <linux/hash.h>
12 #include <linux/string.h>
13 #include <linux/slab.h>
16 #include <linux/kernel.h>
18 #define RPCDBG_FACILITY RPCDBG_AUTH
40 static void svcauth_unix_domain_release(
struct auth_domain *dom)
50 struct auth_domain *rv;
56 if (
new && rv != &new->h)
57 svcauth_unix_domain_release(&new->h);
69 kref_init(&new->h.ref);
71 if (new->h.name ==
NULL) {
87 #define IP_HASHMAX (1<<IP_HASHBITS)
96 static void ip_map_put(
struct kref *
kref)
107 static inline int hash_ip6(
const struct in6_addr *
ip)
116 ipv6_addr_equal(&orig->
m_addr, &new->m_addr);
124 new->m_addr = item->
m_addr;
145 char **
bpp,
int *blen)
150 if (ipv6_addr_v4mapped(&(im->
m_addr))) {
169 char *mesg,
int mlen)
186 struct auth_domain *dom;
189 if (mesg[mlen-1] !=
'\n')
194 len =
qword_get(&mesg,
class,
sizeof(
class));
195 if (len <= 0)
return -
EINVAL;
199 if (len <= 0)
return -
EINVAL;
203 switch (
address.sa.sa_family) {
207 ipv6_addr_set_v4mapped(
address.s4.sin_addr.s_addr,
210 #if IS_ENABLED(CONFIG_IPV6)
219 expiry = get_expiry(&mesg);
225 if (len < 0)
return -
EINVAL;
235 ipmp = __ip_map_lookup(cd,
class, &sin6.sin6_addr);
237 err = __ip_map_update(cd, ipmp,
250 static int ip_map_show(
struct seq_file *
m,
256 char *dom =
"-no-domain-";
270 if (ipv6_addr_v4mapped(&
addr)) {
286 strcpy(ip.m_class,
class);
298 static inline struct ip_map *ip_map_lookup(
struct net *
net,
char *
class,
317 ip.h.expiry_time = expiry;
327 static inline int ip_map_update(
struct net *
net,
struct ip_map *ipm,
333 return __ip_map_update(sn->
ip_map_cache, ipm, udom, expiry);
345 static inline struct ip_map *
346 ip_map_cached_get(
struct svc_xprt *xprt)
355 if (!cache_valid(&ipm->
h)) {
413 #define GID_HASHBITS 8
414 #define GID_HASHMAX (1<<GID_HASHBITS)
422 static void unix_gid_put(
struct kref *
kref)
436 return orig->
uid ==
new->uid;
442 new->uid = item->
uid;
449 get_group_info(item->
gi);
452 static struct cache_head *unix_gid_alloc(
void)
463 char **bpp,
int *blen)
481 char *mesg,
int mlen)
492 if (mesg[mlen - 1] !=
'\n')
496 rv = get_int(&mesg, &uid);
501 expiry = get_expiry(&mesg);
505 rv = get_int(&mesg, &gids);
506 if (rv || gids < 0 || gids > 8192)
513 for (i = 0 ; i < gids ; i++) {
516 rv = get_int(&mesg, &gid);
521 if (!gid_valid(kgid))
526 ugp = unix_gid_lookup(cd, uid);
530 ug.h.expiry_time = expiry;
548 static int unix_gid_show(
struct seq_file *m,
564 glen = ug->
gi->ngroups;
569 for (i = 0; i < glen; i++)
578 .name =
"auth.unix.gid",
579 .cache_put = unix_gid_put,
580 .cache_upcall = unix_gid_upcall,
581 .cache_parse = unix_gid_parse,
582 .cache_show = unix_gid_show,
583 .match = unix_gid_match,
584 .init = unix_gid_init,
585 .update = unix_gid_update,
586 .alloc = unix_gid_alloc,
649 gi = get_group_info(ug->
gi);
669 switch (rqstp->
rq_addr.ss_family) {
671 sin = svc_addr_in(rqstp);
672 sin6 = &sin6_storage;
676 sin6 = svc_addr_in6(rqstp);
686 ipm = ip_map_cached_get(xprt);
706 ip_map_cached_put(xprt, ipm);
710 gi = unix_gid_find(cred->cr_uid, rqstp);
711 switch (PTR_ERR(gi)) {
720 cred->cr_group_info = gi;
734 cred->cr_group_info =
NULL;
735 cred->cr_principal =
NULL;
741 if (svc_getu32(argv) != 0) {
742 dprintk(
"svc: bad null cred\n");
743 *authp = rpc_autherr_badcred;
746 if (svc_getu32(argv) !=
htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
747 dprintk(
"svc: bad null verf\n");
748 *authp = rpc_autherr_badverf;
753 cred->cr_uid = (
uid_t) -1;
754 cred->cr_gid = (
gid_t) -1;
756 if (cred->cr_group_info ==
NULL)
760 svc_putnl(resv, RPC_AUTH_NULL);
763 rqstp->
rq_cred.cr_flavor = RPC_AUTH_NULL;
768 svcauth_null_release(
struct svc_rqst *rqstp)
773 if (rqstp->
rq_cred.cr_group_info)
784 .flavour = RPC_AUTH_NULL,
785 .accept = svcauth_null_accept,
786 .release = svcauth_null_release,
796 struct svc_cred *cred = &rqstp->
rq_cred;
800 cred->cr_group_info =
NULL;
801 cred->cr_principal =
NULL;
804 if ((len -= 3*4) < 0)
809 slen = XDR_QUADLEN(svc_getnl(argv));
810 if (slen > 64 || (len -= (slen + 3)*4) < 0)
815 cred->cr_uid = svc_getnl(argv);
816 cred->cr_gid = svc_getnl(argv);
817 slen = svc_getnl(argv);
818 if (slen > 16 || (len -= (slen + 2)*4) < 0)
821 if (cred->cr_group_info ==
NULL)
823 for (i = 0; i < slen; i++) {
825 if (!gid_valid(kgid))
827 GROUP_AT(cred->cr_group_info, i) = kgid;
829 if (svc_getu32(argv) !=
htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) {
830 *authp = rpc_autherr_badverf;
835 svc_putnl(resv, RPC_AUTH_NULL);
838 rqstp->
rq_cred.cr_flavor = RPC_AUTH_UNIX;
842 *authp = rpc_autherr_badcred;
847 svcauth_unix_release(
struct svc_rqst *rqstp)
854 if (rqstp->
rq_cred.cr_group_info)
865 .flavour = RPC_AUTH_UNIX,
866 .accept = svcauth_unix_accept,
867 .release = svcauth_unix_release,
868 .domain_release = svcauth_unix_domain_release,
875 .name =
"auth.unix.ip",
876 .cache_put = ip_map_put,
877 .cache_upcall = ip_map_upcall,
878 .cache_parse = ip_map_parse,
879 .cache_show = ip_map_show,
880 .match = ip_map_match,
883 .alloc = ip_map_alloc,