diff options
Diffstat (limited to 'net/sunrpc/svcauth_unix.c')
| -rw-r--r-- | net/sunrpc/svcauth_unix.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index d8c041114497..207311610988 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
| @@ -10,11 +10,13 @@ | |||
| 10 | #include <linux/seq_file.h> | 10 | #include <linux/seq_file.h> |
| 11 | #include <linux/hash.h> | 11 | #include <linux/hash.h> |
| 12 | #include <linux/string.h> | 12 | #include <linux/string.h> |
| 13 | #include <linux/slab.h> | ||
| 13 | #include <net/sock.h> | 14 | #include <net/sock.h> |
| 14 | #include <net/ipv6.h> | 15 | #include <net/ipv6.h> |
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 16 | #define RPCDBG_FACILITY RPCDBG_AUTH | 17 | #define RPCDBG_FACILITY RPCDBG_AUTH |
| 17 | 18 | ||
| 19 | #include <linux/sunrpc/clnt.h> | ||
| 18 | 20 | ||
| 19 | /* | 21 | /* |
| 20 | * AUTHUNIX and AUTHNULL credentials are both handled here. | 22 | * AUTHUNIX and AUTHNULL credentials are both handled here. |
| @@ -187,10 +189,13 @@ static int ip_map_parse(struct cache_detail *cd, | |||
| 187 | * for scratch: */ | 189 | * for scratch: */ |
| 188 | char *buf = mesg; | 190 | char *buf = mesg; |
| 189 | int len; | 191 | int len; |
| 190 | int b1, b2, b3, b4, b5, b6, b7, b8; | ||
| 191 | char c; | ||
| 192 | char class[8]; | 192 | char class[8]; |
| 193 | struct in6_addr addr; | 193 | union { |
| 194 | struct sockaddr sa; | ||
| 195 | struct sockaddr_in s4; | ||
| 196 | struct sockaddr_in6 s6; | ||
| 197 | } address; | ||
| 198 | struct sockaddr_in6 sin6; | ||
| 194 | int err; | 199 | int err; |
| 195 | 200 | ||
| 196 | struct ip_map *ipmp; | 201 | struct ip_map *ipmp; |
| @@ -209,24 +214,24 @@ static int ip_map_parse(struct cache_detail *cd, | |||
| 209 | len = qword_get(&mesg, buf, mlen); | 214 | len = qword_get(&mesg, buf, mlen); |
| 210 | if (len <= 0) return -EINVAL; | 215 | if (len <= 0) return -EINVAL; |
| 211 | 216 | ||
| 212 | if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) == 4) { | 217 | if (rpc_pton(buf, len, &address.sa, sizeof(address)) == 0) |
| 213 | addr.s6_addr32[0] = 0; | ||
| 214 | addr.s6_addr32[1] = 0; | ||
| 215 | addr.s6_addr32[2] = htonl(0xffff); | ||
| 216 | addr.s6_addr32[3] = | ||
| 217 | htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); | ||
| 218 | } else if (sscanf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x%c", | ||
| 219 | &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) { | ||
| 220 | addr.s6_addr16[0] = htons(b1); | ||
| 221 | addr.s6_addr16[1] = htons(b2); | ||
| 222 | addr.s6_addr16[2] = htons(b3); | ||
| 223 | addr.s6_addr16[3] = htons(b4); | ||
| 224 | addr.s6_addr16[4] = htons(b5); | ||
| 225 | addr.s6_addr16[5] = htons(b6); | ||
| 226 | addr.s6_addr16[6] = htons(b7); | ||
| 227 | addr.s6_addr16[7] = htons(b8); | ||
| 228 | } else | ||
| 229 | return -EINVAL; | 218 | return -EINVAL; |
| 219 | switch (address.sa.sa_family) { | ||
| 220 | case AF_INET: | ||
| 221 | /* Form a mapped IPv4 address in sin6 */ | ||
| 222 | memset(&sin6, 0, sizeof(sin6)); | ||
| 223 | sin6.sin6_family = AF_INET6; | ||
| 224 | sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); | ||
| 225 | sin6.sin6_addr.s6_addr32[3] = address.s4.sin_addr.s_addr; | ||
| 226 | break; | ||
| 227 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
| 228 | case AF_INET6: | ||
| 229 | memcpy(&sin6, &address.s6, sizeof(sin6)); | ||
| 230 | break; | ||
| 231 | #endif | ||
| 232 | default: | ||
| 233 | return -EINVAL; | ||
| 234 | } | ||
| 230 | 235 | ||
| 231 | expiry = get_expiry(&mesg); | 236 | expiry = get_expiry(&mesg); |
| 232 | if (expiry ==0) | 237 | if (expiry ==0) |
| @@ -243,7 +248,8 @@ static int ip_map_parse(struct cache_detail *cd, | |||
| 243 | } else | 248 | } else |
| 244 | dom = NULL; | 249 | dom = NULL; |
| 245 | 250 | ||
| 246 | ipmp = ip_map_lookup(class, &addr); | 251 | /* IPv6 scope IDs are ignored for now */ |
| 252 | ipmp = ip_map_lookup(class, &sin6.sin6_addr); | ||
| 247 | if (ipmp) { | 253 | if (ipmp) { |
| 248 | err = ip_map_update(ipmp, | 254 | err = ip_map_update(ipmp, |
| 249 | container_of(dom, struct unix_domain, h), | 255 | container_of(dom, struct unix_domain, h), |
| @@ -619,7 +625,7 @@ static int unix_gid_show(struct seq_file *m, | |||
| 619 | else | 625 | else |
| 620 | glen = 0; | 626 | glen = 0; |
| 621 | 627 | ||
| 622 | seq_printf(m, "%d %d:", ug->uid, glen); | 628 | seq_printf(m, "%u %d:", ug->uid, glen); |
| 623 | for (i = 0; i < glen; i++) | 629 | for (i = 0; i < glen; i++) |
| 624 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); | 630 | seq_printf(m, " %d", GROUP_AT(ug->gi, i)); |
| 625 | seq_printf(m, "\n"); | 631 | seq_printf(m, "\n"); |
