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