aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/svcauth_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sunrpc/svcauth_unix.c')
-rw-r--r--net/sunrpc/svcauth_unix.c59
1 files changed, 30 insertions, 29 deletions
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 4d0129203733..c3f9e1ef7f53 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -6,6 +6,7 @@
6#include <linux/sunrpc/svcsock.h> 6#include <linux/sunrpc/svcsock.h>
7#include <linux/sunrpc/svcauth.h> 7#include <linux/sunrpc/svcauth.h>
8#include <linux/sunrpc/gss_api.h> 8#include <linux/sunrpc/gss_api.h>
9#include <linux/sunrpc/addr.h>
9#include <linux/err.h> 10#include <linux/err.h>
10#include <linux/seq_file.h> 11#include <linux/seq_file.h>
11#include <linux/hash.h> 12#include <linux/hash.h>
@@ -17,7 +18,6 @@
17#include <linux/user_namespace.h> 18#include <linux/user_namespace.h>
18#define RPCDBG_FACILITY RPCDBG_AUTH 19#define RPCDBG_FACILITY RPCDBG_AUTH
19 20
20#include <linux/sunrpc/clnt.h>
21 21
22#include "netns.h" 22#include "netns.h"
23 23
@@ -157,11 +157,6 @@ static void ip_map_request(struct cache_detail *cd,
157 (*bpp)[-1] = '\n'; 157 (*bpp)[-1] = '\n';
158} 158}
159 159
160static int ip_map_upcall(struct cache_detail *cd, struct cache_head *h)
161{
162 return sunrpc_cache_pipe_upcall(cd, h, ip_map_request);
163}
164
165static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr); 160static struct ip_map *__ip_map_lookup(struct cache_detail *cd, char *class, struct in6_addr *addr);
166static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry); 161static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
167 162
@@ -415,10 +410,15 @@ svcauth_unix_info_release(struct svc_xprt *xpt)
415 410
416struct unix_gid { 411struct unix_gid {
417 struct cache_head h; 412 struct cache_head h;
418 uid_t uid; 413 kuid_t uid;
419 struct group_info *gi; 414 struct group_info *gi;
420}; 415};
421 416
417static int unix_gid_hash(kuid_t uid)
418{
419 return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
420}
421
422static void unix_gid_put(struct kref *kref) 422static void unix_gid_put(struct kref *kref)
423{ 423{
424 struct cache_head *item = container_of(kref, struct cache_head, ref); 424 struct cache_head *item = container_of(kref, struct cache_head, ref);
@@ -433,7 +433,7 @@ static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
433{ 433{
434 struct unix_gid *orig = container_of(corig, struct unix_gid, h); 434 struct unix_gid *orig = container_of(corig, struct unix_gid, h);
435 struct unix_gid *new = container_of(cnew, struct unix_gid, h); 435 struct unix_gid *new = container_of(cnew, struct unix_gid, h);
436 return orig->uid == new->uid; 436 return uid_eq(orig->uid, new->uid);
437} 437}
438static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem) 438static void unix_gid_init(struct cache_head *cnew, struct cache_head *citem)
439{ 439{
@@ -465,23 +465,19 @@ static void unix_gid_request(struct cache_detail *cd,
465 char tuid[20]; 465 char tuid[20];
466 struct unix_gid *ug = container_of(h, struct unix_gid, h); 466 struct unix_gid *ug = container_of(h, struct unix_gid, h);
467 467
468 snprintf(tuid, 20, "%u", ug->uid); 468 snprintf(tuid, 20, "%u", from_kuid(&init_user_ns, ug->uid));
469 qword_add(bpp, blen, tuid); 469 qword_add(bpp, blen, tuid);
470 (*bpp)[-1] = '\n'; 470 (*bpp)[-1] = '\n';
471} 471}
472 472
473static int unix_gid_upcall(struct cache_detail *cd, struct cache_head *h) 473static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid);
474{
475 return sunrpc_cache_pipe_upcall(cd, h, unix_gid_request);
476}
477
478static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid);
479 474
480static int unix_gid_parse(struct cache_detail *cd, 475static int unix_gid_parse(struct cache_detail *cd,
481 char *mesg, int mlen) 476 char *mesg, int mlen)
482{ 477{
483 /* uid expiry Ngid gid0 gid1 ... gidN-1 */ 478 /* uid expiry Ngid gid0 gid1 ... gidN-1 */
484 int uid; 479 int id;
480 kuid_t uid;
485 int gids; 481 int gids;
486 int rv; 482 int rv;
487 int i; 483 int i;
@@ -493,9 +489,12 @@ static int unix_gid_parse(struct cache_detail *cd,
493 return -EINVAL; 489 return -EINVAL;
494 mesg[mlen-1] = 0; 490 mesg[mlen-1] = 0;
495 491
496 rv = get_int(&mesg, &uid); 492 rv = get_int(&mesg, &id);
497 if (rv) 493 if (rv)
498 return -EINVAL; 494 return -EINVAL;
495 uid = make_kuid(&init_user_ns, id);
496 if (!uid_valid(uid))
497 return -EINVAL;
499 ug.uid = uid; 498 ug.uid = uid;
500 499
501 expiry = get_expiry(&mesg); 500 expiry = get_expiry(&mesg);
@@ -530,7 +529,7 @@ static int unix_gid_parse(struct cache_detail *cd,
530 ug.h.expiry_time = expiry; 529 ug.h.expiry_time = expiry;
531 ch = sunrpc_cache_update(cd, 530 ch = sunrpc_cache_update(cd,
532 &ug.h, &ugp->h, 531 &ug.h, &ugp->h,
533 hash_long(uid, GID_HASHBITS)); 532 unix_gid_hash(uid));
534 if (!ch) 533 if (!ch)
535 err = -ENOMEM; 534 err = -ENOMEM;
536 else { 535 else {
@@ -549,7 +548,7 @@ static int unix_gid_show(struct seq_file *m,
549 struct cache_detail *cd, 548 struct cache_detail *cd,
550 struct cache_head *h) 549 struct cache_head *h)
551{ 550{
552 struct user_namespace *user_ns = current_user_ns(); 551 struct user_namespace *user_ns = &init_user_ns;
553 struct unix_gid *ug; 552 struct unix_gid *ug;
554 int i; 553 int i;
555 int glen; 554 int glen;
@@ -565,7 +564,7 @@ static int unix_gid_show(struct seq_file *m,
565 else 564 else
566 glen = 0; 565 glen = 0;
567 566
568 seq_printf(m, "%u %d:", ug->uid, glen); 567 seq_printf(m, "%u %d:", from_kuid_munged(user_ns, ug->uid), glen);
569 for (i = 0; i < glen; i++) 568 for (i = 0; i < glen; i++)
570 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i))); 569 seq_printf(m, " %d", from_kgid_munged(user_ns, GROUP_AT(ug->gi, i)));
571 seq_printf(m, "\n"); 570 seq_printf(m, "\n");
@@ -577,7 +576,7 @@ static struct cache_detail unix_gid_cache_template = {
577 .hash_size = GID_HASHMAX, 576 .hash_size = GID_HASHMAX,
578 .name = "auth.unix.gid", 577 .name = "auth.unix.gid",
579 .cache_put = unix_gid_put, 578 .cache_put = unix_gid_put,
580 .cache_upcall = unix_gid_upcall, 579 .cache_request = unix_gid_request,
581 .cache_parse = unix_gid_parse, 580 .cache_parse = unix_gid_parse,
582 .cache_show = unix_gid_show, 581 .cache_show = unix_gid_show,
583 .match = unix_gid_match, 582 .match = unix_gid_match,
@@ -615,20 +614,20 @@ void unix_gid_cache_destroy(struct net *net)
615 cache_destroy_net(cd, net); 614 cache_destroy_net(cd, net);
616} 615}
617 616
618static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, uid_t uid) 617static struct unix_gid *unix_gid_lookup(struct cache_detail *cd, kuid_t uid)
619{ 618{
620 struct unix_gid ug; 619 struct unix_gid ug;
621 struct cache_head *ch; 620 struct cache_head *ch;
622 621
623 ug.uid = uid; 622 ug.uid = uid;
624 ch = sunrpc_cache_lookup(cd, &ug.h, hash_long(uid, GID_HASHBITS)); 623 ch = sunrpc_cache_lookup(cd, &ug.h, unix_gid_hash(uid));
625 if (ch) 624 if (ch)
626 return container_of(ch, struct unix_gid, h); 625 return container_of(ch, struct unix_gid, h);
627 else 626 else
628 return NULL; 627 return NULL;
629} 628}
630 629
631static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) 630static struct group_info *unix_gid_find(kuid_t uid, struct svc_rqst *rqstp)
632{ 631{
633 struct unix_gid *ug; 632 struct unix_gid *ug;
634 struct group_info *gi; 633 struct group_info *gi;
@@ -750,8 +749,8 @@ svcauth_null_accept(struct svc_rqst *rqstp, __be32 *authp)
750 } 749 }
751 750
752 /* Signal that mapping to nobody uid/gid is required */ 751 /* Signal that mapping to nobody uid/gid is required */
753 cred->cr_uid = (uid_t) -1; 752 cred->cr_uid = INVALID_UID;
754 cred->cr_gid = (gid_t) -1; 753 cred->cr_gid = INVALID_GID;
755 cred->cr_group_info = groups_alloc(0); 754 cred->cr_group_info = groups_alloc(0);
756 if (cred->cr_group_info == NULL) 755 if (cred->cr_group_info == NULL)
757 return SVC_CLOSE; /* kmalloc failure - client must retry */ 756 return SVC_CLOSE; /* kmalloc failure - client must retry */
@@ -812,8 +811,10 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp)
812 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */ 811 argv->iov_base = (void*)((__be32*)argv->iov_base + slen); /* skip machname */
813 argv->iov_len -= slen*4; 812 argv->iov_len -= slen*4;
814 813
815 cred->cr_uid = svc_getnl(argv); /* uid */ 814 cred->cr_uid = make_kuid(&init_user_ns, svc_getnl(argv)); /* uid */
816 cred->cr_gid = svc_getnl(argv); /* gid */ 815 cred->cr_gid = make_kgid(&init_user_ns, svc_getnl(argv)); /* gid */
816 if (!uid_valid(cred->cr_uid) || !gid_valid(cred->cr_gid))
817 goto badcred;
817 slen = svc_getnl(argv); /* gids length */ 818 slen = svc_getnl(argv); /* gids length */
818 if (slen > 16 || (len -= (slen + 2)*4) < 0) 819 if (slen > 16 || (len -= (slen + 2)*4) < 0)
819 goto badcred; 820 goto badcred;
@@ -874,7 +875,7 @@ static struct cache_detail ip_map_cache_template = {
874 .hash_size = IP_HASHMAX, 875 .hash_size = IP_HASHMAX,
875 .name = "auth.unix.ip", 876 .name = "auth.unix.ip",
876 .cache_put = ip_map_put, 877 .cache_put = ip_map_put,
877 .cache_upcall = ip_map_upcall, 878 .cache_request = ip_map_request,
878 .cache_parse = ip_map_parse, 879 .cache_parse = ip_map_parse,
879 .cache_show = ip_map_show, 880 .cache_show = ip_map_show,
880 .match = ip_map_match, 881 .match = ip_map_match,