aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/acl.h2
-rw-r--r--fs/nfsd/auth.c12
-rw-r--r--fs/nfsd/auth.h6
-rw-r--r--fs/nfsd/export.c22
-rw-r--r--fs/nfsd/idmap.h8
-rw-r--r--fs/nfsd/nfs3xdr.c14
-rw-r--r--fs/nfsd/nfs4acl.c63
-rw-r--r--fs/nfsd/nfs4idmap.c38
-rw-r--r--fs/nfsd/nfs4recover.c4
-rw-r--r--fs/nfsd/nfs4state.c6
-rw-r--r--fs/nfsd/nfs4xdr.c54
-rw-r--r--fs/nfsd/nfsxdr.c14
-rw-r--r--fs/nfsd/state.h4
-rw-r--r--fs/nfsd/vfs.c8
14 files changed, 158 insertions, 97 deletions
diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h
index 34e5c40af5ef..8b186a4955cc 100644
--- a/fs/nfsd/acl.h
+++ b/fs/nfsd/acl.h
@@ -44,8 +44,6 @@
44struct nfs4_acl *nfs4_acl_new(int); 44struct nfs4_acl *nfs4_acl_new(int);
45int nfs4_acl_get_whotype(char *, u32); 45int nfs4_acl_get_whotype(char *, u32);
46int nfs4_acl_write_who(int who, char *p); 46int nfs4_acl_write_who(int who, char *p);
47int nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group,
48 uid_t who, u32 mask);
49 47
50#define NFS4_ACL_TYPE_DEFAULT 0x01 48#define NFS4_ACL_TYPE_DEFAULT 0x01
51#define NFS4_ACL_DIR 0x02 49#define NFS4_ACL_DIR 0x02
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c
index 34a10d78b839..06cddd572264 100644
--- a/fs/nfsd/auth.c
+++ b/fs/nfsd/auth.c
@@ -47,9 +47,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
47 if (!gi) 47 if (!gi)
48 goto oom; 48 goto oom;
49 } else if (flags & NFSEXP_ROOTSQUASH) { 49 } else if (flags & NFSEXP_ROOTSQUASH) {
50 if (!new->fsuid) 50 if (uid_eq(new->fsuid, GLOBAL_ROOT_UID))
51 new->fsuid = exp->ex_anon_uid; 51 new->fsuid = exp->ex_anon_uid;
52 if (!new->fsgid) 52 if (gid_eq(new->fsgid, GLOBAL_ROOT_GID))
53 new->fsgid = exp->ex_anon_gid; 53 new->fsgid = exp->ex_anon_gid;
54 54
55 gi = groups_alloc(rqgi->ngroups); 55 gi = groups_alloc(rqgi->ngroups);
@@ -58,7 +58,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
58 58
59 for (i = 0; i < rqgi->ngroups; i++) { 59 for (i = 0; i < rqgi->ngroups; i++) {
60 if (gid_eq(GLOBAL_ROOT_GID, GROUP_AT(rqgi, i))) 60 if (gid_eq(GLOBAL_ROOT_GID, GROUP_AT(rqgi, i)))
61 GROUP_AT(gi, i) = make_kgid(&init_user_ns, exp->ex_anon_gid); 61 GROUP_AT(gi, i) = exp->ex_anon_gid;
62 else 62 else
63 GROUP_AT(gi, i) = GROUP_AT(rqgi, i); 63 GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
64 } 64 }
@@ -66,9 +66,9 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
66 gi = get_group_info(rqgi); 66 gi = get_group_info(rqgi);
67 } 67 }
68 68
69 if (new->fsuid == (uid_t) -1) 69 if (uid_eq(new->fsuid, INVALID_UID))
70 new->fsuid = exp->ex_anon_uid; 70 new->fsuid = exp->ex_anon_uid;
71 if (new->fsgid == (gid_t) -1) 71 if (gid_eq(new->fsgid, INVALID_GID))
72 new->fsgid = exp->ex_anon_gid; 72 new->fsgid = exp->ex_anon_gid;
73 73
74 ret = set_groups(new, gi); 74 ret = set_groups(new, gi);
@@ -76,7 +76,7 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
76 if (ret < 0) 76 if (ret < 0)
77 goto error; 77 goto error;
78 78
79 if (new->fsuid) 79 if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID))
80 new->cap_effective = cap_drop_nfsd_set(new->cap_effective); 80 new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
81 else 81 else
82 new->cap_effective = cap_raise_nfsd_set(new->cap_effective, 82 new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
diff --git a/fs/nfsd/auth.h b/fs/nfsd/auth.h
index 78b3c0e93822..53325a12ba62 100644
--- a/fs/nfsd/auth.h
+++ b/fs/nfsd/auth.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * nfsd-specific authentication stuff. 2 * nfsd-specific authentication stuff.
3 * uid/gid mapping not yet implemented.
4 * 3 *
5 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 4 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
6 */ 5 */
@@ -8,11 +7,6 @@
8#ifndef LINUX_NFSD_AUTH_H 7#ifndef LINUX_NFSD_AUTH_H
9#define LINUX_NFSD_AUTH_H 8#define LINUX_NFSD_AUTH_H
10 9
11#define nfsd_luid(rq, uid) ((u32)(uid))
12#define nfsd_lgid(rq, gid) ((u32)(gid))
13#define nfsd_ruid(rq, uid) ((u32)(uid))
14#define nfsd_rgid(rq, gid) ((u32)(gid))
15
16/* 10/*
17 * Set the current process's fsuid/fsgid etc to those of the NFS 11 * Set the current process's fsuid/fsgid etc to those of the NFS
18 * client user 12 * client user
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index a3946cf13fc8..5681c5906f08 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -544,13 +544,17 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
544 err = get_int(&mesg, &an_int); 544 err = get_int(&mesg, &an_int);
545 if (err) 545 if (err)
546 goto out3; 546 goto out3;
547 exp.ex_anon_uid= an_int; 547 exp.ex_anon_uid= make_kuid(&init_user_ns, an_int);
548 if (!uid_valid(exp.ex_anon_uid))
549 goto out3;
548 550
549 /* anon gid */ 551 /* anon gid */
550 err = get_int(&mesg, &an_int); 552 err = get_int(&mesg, &an_int);
551 if (err) 553 if (err)
552 goto out3; 554 goto out3;
553 exp.ex_anon_gid= an_int; 555 exp.ex_anon_gid= make_kgid(&init_user_ns, an_int);
556 if (!gid_valid(exp.ex_anon_gid))
557 goto out3;
554 558
555 /* fsid */ 559 /* fsid */
556 err = get_int(&mesg, &an_int); 560 err = get_int(&mesg, &an_int);
@@ -613,7 +617,7 @@ out:
613} 617}
614 618
615static void exp_flags(struct seq_file *m, int flag, int fsid, 619static void exp_flags(struct seq_file *m, int flag, int fsid,
616 uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fslocs); 620 kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fslocs);
617static void show_secinfo(struct seq_file *m, struct svc_export *exp); 621static void show_secinfo(struct seq_file *m, struct svc_export *exp);
618 622
619static int svc_export_show(struct seq_file *m, 623static int svc_export_show(struct seq_file *m,
@@ -1179,15 +1183,17 @@ static void show_secinfo(struct seq_file *m, struct svc_export *exp)
1179} 1183}
1180 1184
1181static void exp_flags(struct seq_file *m, int flag, int fsid, 1185static void exp_flags(struct seq_file *m, int flag, int fsid,
1182 uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fsloc) 1186 kuid_t anonu, kgid_t anong, struct nfsd4_fs_locations *fsloc)
1183{ 1187{
1184 show_expflags(m, flag, NFSEXP_ALLFLAGS); 1188 show_expflags(m, flag, NFSEXP_ALLFLAGS);
1185 if (flag & NFSEXP_FSID) 1189 if (flag & NFSEXP_FSID)
1186 seq_printf(m, ",fsid=%d", fsid); 1190 seq_printf(m, ",fsid=%d", fsid);
1187 if (anonu != (uid_t)-2 && anonu != (0x10000-2)) 1191 if (!uid_eq(anonu, make_kuid(&init_user_ns, (uid_t)-2)) &&
1188 seq_printf(m, ",anonuid=%u", anonu); 1192 !uid_eq(anonu, make_kuid(&init_user_ns, 0x10000-2)))
1189 if (anong != (gid_t)-2 && anong != (0x10000-2)) 1193 seq_printf(m, ",anonuid=%u", from_kuid(&init_user_ns, anonu));
1190 seq_printf(m, ",anongid=%u", anong); 1194 if (!gid_eq(anong, make_kgid(&init_user_ns, (gid_t)-2)) &&
1195 !gid_eq(anong, make_kgid(&init_user_ns, 0x10000-2)))
1196 seq_printf(m, ",anongid=%u", from_kgid(&init_user_ns, anong));
1191 if (fsloc && fsloc->locations_count > 0) { 1197 if (fsloc && fsloc->locations_count > 0) {
1192 char *loctype = (fsloc->migrated) ? "refer" : "replicas"; 1198 char *loctype = (fsloc->migrated) ? "refer" : "replicas";
1193 int i; 1199 int i;
diff --git a/fs/nfsd/idmap.h b/fs/nfsd/idmap.h
index 9d513efc01ba..bf95f6b817a4 100644
--- a/fs/nfsd/idmap.h
+++ b/fs/nfsd/idmap.h
@@ -54,9 +54,9 @@ static inline void nfsd_idmap_shutdown(struct net *net)
54} 54}
55#endif 55#endif
56 56
57__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, __u32 *); 57__be32 nfsd_map_name_to_uid(struct svc_rqst *, const char *, size_t, kuid_t *);
58__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, __u32 *); 58__be32 nfsd_map_name_to_gid(struct svc_rqst *, const char *, size_t, kgid_t *);
59int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *); 59int nfsd_map_uid_to_name(struct svc_rqst *, kuid_t, char *);
60int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *); 60int nfsd_map_gid_to_name(struct svc_rqst *, kgid_t, char *);
61 61
62#endif /* LINUX_NFSD_IDMAP_H */ 62#endif /* LINUX_NFSD_IDMAP_H */
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 324c0baf7cda..925c944bc0bc 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -105,12 +105,14 @@ decode_sattr3(__be32 *p, struct iattr *iap)
105 iap->ia_mode = ntohl(*p++); 105 iap->ia_mode = ntohl(*p++);
106 } 106 }
107 if (*p++) { 107 if (*p++) {
108 iap->ia_valid |= ATTR_UID; 108 iap->ia_uid = make_kuid(&init_user_ns, ntohl(*p++));
109 iap->ia_uid = ntohl(*p++); 109 if (uid_valid(iap->ia_uid))
110 iap->ia_valid |= ATTR_UID;
110 } 111 }
111 if (*p++) { 112 if (*p++) {
112 iap->ia_valid |= ATTR_GID; 113 iap->ia_gid = make_kgid(&init_user_ns, ntohl(*p++));
113 iap->ia_gid = ntohl(*p++); 114 if (gid_valid(iap->ia_gid))
115 iap->ia_valid |= ATTR_GID;
114 } 116 }
115 if (*p++) { 117 if (*p++) {
116 u64 newsize; 118 u64 newsize;
@@ -167,8 +169,8 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
167 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]); 169 *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
168 *p++ = htonl((u32) stat->mode); 170 *p++ = htonl((u32) stat->mode);
169 *p++ = htonl((u32) stat->nlink); 171 *p++ = htonl((u32) stat->nlink);
170 *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); 172 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
171 *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); 173 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
172 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) { 174 if (S_ISLNK(stat->mode) && stat->size > NFS3_MAXPATHLEN) {
173 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN); 175 p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
174 } else { 176 } else {
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
index 9c51aff02ae2..8a50b3c18093 100644
--- a/fs/nfsd/nfs4acl.c
+++ b/fs/nfsd/nfs4acl.c
@@ -264,7 +264,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
264 ace->flag = eflag; 264 ace->flag = eflag;
265 ace->access_mask = deny_mask_from_posix(deny, flags); 265 ace->access_mask = deny_mask_from_posix(deny, flags);
266 ace->whotype = NFS4_ACL_WHO_NAMED; 266 ace->whotype = NFS4_ACL_WHO_NAMED;
267 ace->who = pa->e_id; 267 ace->who_uid = pa->e_uid;
268 ace++; 268 ace++;
269 acl->naces++; 269 acl->naces++;
270 } 270 }
@@ -273,7 +273,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
273 ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, 273 ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
274 flags); 274 flags);
275 ace->whotype = NFS4_ACL_WHO_NAMED; 275 ace->whotype = NFS4_ACL_WHO_NAMED;
276 ace->who = pa->e_id; 276 ace->who_uid = pa->e_uid;
277 ace++; 277 ace++;
278 acl->naces++; 278 acl->naces++;
279 pa++; 279 pa++;
@@ -300,7 +300,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
300 ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, 300 ace->access_mask = mask_from_posix(pa->e_perm & pas.mask,
301 flags); 301 flags);
302 ace->whotype = NFS4_ACL_WHO_NAMED; 302 ace->whotype = NFS4_ACL_WHO_NAMED;
303 ace->who = pa->e_id; 303 ace->who_gid = pa->e_gid;
304 ace++; 304 ace++;
305 acl->naces++; 305 acl->naces++;
306 pa++; 306 pa++;
@@ -329,7 +329,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
329 ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; 329 ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP;
330 ace->access_mask = deny_mask_from_posix(deny, flags); 330 ace->access_mask = deny_mask_from_posix(deny, flags);
331 ace->whotype = NFS4_ACL_WHO_NAMED; 331 ace->whotype = NFS4_ACL_WHO_NAMED;
332 ace->who = pa->e_id; 332 ace->who_gid = pa->e_gid;
333 ace++; 333 ace++;
334 acl->naces++; 334 acl->naces++;
335 } 335 }
@@ -345,6 +345,18 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl,
345 acl->naces++; 345 acl->naces++;
346} 346}
347 347
348static bool
349pace_gt(struct posix_acl_entry *pace1, struct posix_acl_entry *pace2)
350{
351 if (pace1->e_tag != pace2->e_tag)
352 return pace1->e_tag > pace2->e_tag;
353 if (pace1->e_tag == ACL_USER)
354 return uid_gt(pace1->e_uid, pace2->e_uid);
355 if (pace1->e_tag == ACL_GROUP)
356 return gid_gt(pace1->e_gid, pace2->e_gid);
357 return false;
358}
359
348static void 360static void
349sort_pacl_range(struct posix_acl *pacl, int start, int end) { 361sort_pacl_range(struct posix_acl *pacl, int start, int end) {
350 int sorted = 0, i; 362 int sorted = 0, i;
@@ -355,8 +367,8 @@ sort_pacl_range(struct posix_acl *pacl, int start, int end) {
355 while (!sorted) { 367 while (!sorted) {
356 sorted = 1; 368 sorted = 1;
357 for (i = start; i < end; i++) { 369 for (i = start; i < end; i++) {
358 if (pacl->a_entries[i].e_id 370 if (pace_gt(&pacl->a_entries[i],
359 > pacl->a_entries[i+1].e_id) { 371 &pacl->a_entries[i+1])) {
360 sorted = 0; 372 sorted = 0;
361 tmp = pacl->a_entries[i]; 373 tmp = pacl->a_entries[i];
362 pacl->a_entries[i] = pacl->a_entries[i+1]; 374 pacl->a_entries[i] = pacl->a_entries[i+1];
@@ -398,7 +410,10 @@ struct posix_ace_state {
398}; 410};
399 411
400struct posix_user_ace_state { 412struct posix_user_ace_state {
401 uid_t uid; 413 union {
414 kuid_t uid;
415 kgid_t gid;
416 };
402 struct posix_ace_state perms; 417 struct posix_ace_state perms;
403}; 418};
404 419
@@ -521,7 +536,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
521 if (error) 536 if (error)
522 goto out_err; 537 goto out_err;
523 low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags); 538 low_mode_from_nfs4(state->owner.allow, &pace->e_perm, flags);
524 pace->e_id = ACL_UNDEFINED_ID;
525 539
526 for (i=0; i < state->users->n; i++) { 540 for (i=0; i < state->users->n; i++) {
527 pace++; 541 pace++;
@@ -531,7 +545,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
531 goto out_err; 545 goto out_err;
532 low_mode_from_nfs4(state->users->aces[i].perms.allow, 546 low_mode_from_nfs4(state->users->aces[i].perms.allow,
533 &pace->e_perm, flags); 547 &pace->e_perm, flags);
534 pace->e_id = state->users->aces[i].uid; 548 pace->e_uid = state->users->aces[i].uid;
535 add_to_mask(state, &state->users->aces[i].perms); 549 add_to_mask(state, &state->users->aces[i].perms);
536 } 550 }
537 551
@@ -541,7 +555,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
541 if (error) 555 if (error)
542 goto out_err; 556 goto out_err;
543 low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags); 557 low_mode_from_nfs4(state->group.allow, &pace->e_perm, flags);
544 pace->e_id = ACL_UNDEFINED_ID;
545 add_to_mask(state, &state->group); 558 add_to_mask(state, &state->group);
546 559
547 for (i=0; i < state->groups->n; i++) { 560 for (i=0; i < state->groups->n; i++) {
@@ -552,14 +565,13 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
552 goto out_err; 565 goto out_err;
553 low_mode_from_nfs4(state->groups->aces[i].perms.allow, 566 low_mode_from_nfs4(state->groups->aces[i].perms.allow,
554 &pace->e_perm, flags); 567 &pace->e_perm, flags);
555 pace->e_id = state->groups->aces[i].uid; 568 pace->e_gid = state->groups->aces[i].gid;
556 add_to_mask(state, &state->groups->aces[i].perms); 569 add_to_mask(state, &state->groups->aces[i].perms);
557 } 570 }
558 571
559 pace++; 572 pace++;
560 pace->e_tag = ACL_MASK; 573 pace->e_tag = ACL_MASK;
561 low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags); 574 low_mode_from_nfs4(state->mask.allow, &pace->e_perm, flags);
562 pace->e_id = ACL_UNDEFINED_ID;
563 575
564 pace++; 576 pace++;
565 pace->e_tag = ACL_OTHER; 577 pace->e_tag = ACL_OTHER;
@@ -567,7 +579,6 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags)
567 if (error) 579 if (error)
568 goto out_err; 580 goto out_err;
569 low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags); 581 low_mode_from_nfs4(state->other.allow, &pace->e_perm, flags);
570 pace->e_id = ACL_UNDEFINED_ID;
571 582
572 return pacl; 583 return pacl;
573out_err: 584out_err:
@@ -587,12 +598,13 @@ static inline void deny_bits(struct posix_ace_state *astate, u32 mask)
587 astate->deny |= mask & ~astate->allow; 598 astate->deny |= mask & ~astate->allow;
588} 599}
589 600
590static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid) 601static int find_uid(struct posix_acl_state *state, kuid_t uid)
591{ 602{
603 struct posix_ace_state_array *a = state->users;
592 int i; 604 int i;
593 605
594 for (i = 0; i < a->n; i++) 606 for (i = 0; i < a->n; i++)
595 if (a->aces[i].uid == uid) 607 if (uid_eq(a->aces[i].uid, uid))
596 return i; 608 return i;
597 /* Not found: */ 609 /* Not found: */
598 a->n++; 610 a->n++;
@@ -603,6 +615,23 @@ static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array
603 return i; 615 return i;
604} 616}
605 617
618static int find_gid(struct posix_acl_state *state, kgid_t gid)
619{
620 struct posix_ace_state_array *a = state->groups;
621 int i;
622
623 for (i = 0; i < a->n; i++)
624 if (gid_eq(a->aces[i].gid, gid))
625 return i;
626 /* Not found: */
627 a->n++;
628 a->aces[i].gid = gid;
629 a->aces[i].perms.allow = state->everyone.allow;
630 a->aces[i].perms.deny = state->everyone.deny;
631
632 return i;
633}
634
606static void deny_bits_array(struct posix_ace_state_array *a, u32 mask) 635static void deny_bits_array(struct posix_ace_state_array *a, u32 mask)
607{ 636{
608 int i; 637 int i;
@@ -636,7 +665,7 @@ static void process_one_v4_ace(struct posix_acl_state *state,
636 } 665 }
637 break; 666 break;
638 case ACL_USER: 667 case ACL_USER:
639 i = find_uid(state, state->users, ace->who); 668 i = find_uid(state, ace->who_uid);
640 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 669 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
641 allow_bits(&state->users->aces[i].perms, mask); 670 allow_bits(&state->users->aces[i].perms, mask);
642 } else { 671 } else {
@@ -658,7 +687,7 @@ static void process_one_v4_ace(struct posix_acl_state *state,
658 } 687 }
659 break; 688 break;
660 case ACL_GROUP: 689 case ACL_GROUP:
661 i = find_uid(state, state->groups, ace->who); 690 i = find_gid(state, ace->who_gid);
662 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { 691 if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) {
663 allow_bits(&state->groups->aces[i].perms, mask); 692 allow_bits(&state->groups->aces[i].perms, mask);
664 } else { 693 } else {
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index a1f10c0a6255..0ce12346df9c 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -65,7 +65,7 @@ MODULE_PARM_DESC(nfs4_disable_idmapping,
65struct ent { 65struct ent {
66 struct cache_head h; 66 struct cache_head h;
67 int type; /* User / Group */ 67 int type; /* User / Group */
68 uid_t id; 68 u32 id;
69 char name[IDMAP_NAMESZ]; 69 char name[IDMAP_NAMESZ];
70 char authname[IDMAP_NAMESZ]; 70 char authname[IDMAP_NAMESZ];
71}; 71};
@@ -540,7 +540,7 @@ rqst_authname(struct svc_rqst *rqstp)
540 540
541static __be32 541static __be32
542idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, 542idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen,
543 uid_t *id) 543 u32 *id)
544{ 544{
545 struct ent *item, key = { 545 struct ent *item, key = {
546 .type = type, 546 .type = type,
@@ -564,7 +564,7 @@ idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen
564} 564}
565 565
566static int 566static int
567idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) 567idmap_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name)
568{ 568{
569 struct ent *item, key = { 569 struct ent *item, key = {
570 .id = id, 570 .id = id,
@@ -587,7 +587,7 @@ idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
587} 587}
588 588
589static bool 589static bool
590numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) 590numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
591{ 591{
592 int ret; 592 int ret;
593 char buf[11]; 593 char buf[11];
@@ -603,7 +603,7 @@ numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namel
603} 603}
604 604
605static __be32 605static __be32
606do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) 606do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u32 *id)
607{ 607{
608 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) 608 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
609 if (numeric_name_to_id(rqstp, type, name, namelen, id)) 609 if (numeric_name_to_id(rqstp, type, name, namelen, id))
@@ -616,7 +616,7 @@ do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, u
616} 616}
617 617
618static int 618static int
619do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) 619do_id_to_name(struct svc_rqst *rqstp, int type, u32 id, char *name)
620{ 620{
621 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS) 621 if (nfs4_disable_idmapping && rqstp->rq_cred.cr_flavor < RPC_AUTH_GSS)
622 return sprintf(name, "%u", id); 622 return sprintf(name, "%u", id);
@@ -625,26 +625,40 @@ do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name)
625 625
626__be32 626__be32
627nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, 627nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen,
628 __u32 *id) 628 kuid_t *uid)
629{ 629{
630 return do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, id); 630 __be32 status;
631 u32 id = -1;
632 status = do_name_to_id(rqstp, IDMAP_TYPE_USER, name, namelen, &id);
633 *uid = make_kuid(&init_user_ns, id);
634 if (!uid_valid(*uid))
635 status = nfserr_badowner;
636 return status;
631} 637}
632 638
633__be32 639__be32
634nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, 640nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen,
635 __u32 *id) 641 kgid_t *gid)
636{ 642{
637 return do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, id); 643 __be32 status;
644 u32 id = -1;
645 status = do_name_to_id(rqstp, IDMAP_TYPE_GROUP, name, namelen, &id);
646 *gid = make_kgid(&init_user_ns, id);
647 if (!gid_valid(*gid))
648 status = nfserr_badowner;
649 return status;
638} 650}
639 651
640int 652int
641nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 653nfsd_map_uid_to_name(struct svc_rqst *rqstp, kuid_t uid, char *name)
642{ 654{
655 u32 id = from_kuid(&init_user_ns, uid);
643 return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name); 656 return do_id_to_name(rqstp, IDMAP_TYPE_USER, id, name);
644} 657}
645 658
646int 659int
647nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) 660nfsd_map_gid_to_name(struct svc_rqst *rqstp, kgid_t gid, char *name)
648{ 661{
662 u32 id = from_kgid(&init_user_ns, gid);
649 return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name); 663 return do_id_to_name(rqstp, IDMAP_TYPE_GROUP, id, name);
650} 664}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ba6fdd4a0455..4914af4a817e 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -73,8 +73,8 @@ nfs4_save_creds(const struct cred **original_creds)
73 if (!new) 73 if (!new)
74 return -ENOMEM; 74 return -ENOMEM;
75 75
76 new->fsuid = 0; 76 new->fsuid = GLOBAL_ROOT_UID;
77 new->fsgid = 0; 77 new->fsgid = GLOBAL_ROOT_GID;
78 *original_creds = override_creds(new); 78 *original_creds = override_creds(new);
79 put_cred(new); 79 put_cred(new);
80 return 0; 80 return 0;
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 499e957510e7..9e7103b6e0ad 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1202,7 +1202,7 @@ static bool groups_equal(struct group_info *g1, struct group_info *g2)
1202 if (g1->ngroups != g2->ngroups) 1202 if (g1->ngroups != g2->ngroups)
1203 return false; 1203 return false;
1204 for (i=0; i<g1->ngroups; i++) 1204 for (i=0; i<g1->ngroups; i++)
1205 if (GROUP_AT(g1, i) != GROUP_AT(g2, i)) 1205 if (!gid_eq(GROUP_AT(g1, i), GROUP_AT(g2, i)))
1206 return false; 1206 return false;
1207 return true; 1207 return true;
1208} 1208}
@@ -1227,8 +1227,8 @@ static bool
1227same_creds(struct svc_cred *cr1, struct svc_cred *cr2) 1227same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1228{ 1228{
1229 if ((is_gss_cred(cr1) != is_gss_cred(cr2)) 1229 if ((is_gss_cred(cr1) != is_gss_cred(cr2))
1230 || (cr1->cr_uid != cr2->cr_uid) 1230 || (!uid_eq(cr1->cr_uid, cr2->cr_uid))
1231 || (cr1->cr_gid != cr2->cr_gid) 1231 || (!gid_eq(cr1->cr_gid, cr2->cr_gid))
1232 || !groups_equal(cr1->cr_group_info, cr2->cr_group_info)) 1232 || !groups_equal(cr1->cr_group_info, cr2->cr_group_info))
1233 return false; 1233 return false;
1234 if (cr1->cr_principal == cr2->cr_principal) 1234 if (cr1->cr_principal == cr2->cr_principal)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 0dc11586682f..2d1d06bae3a7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -293,13 +293,13 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
293 ace->whotype = nfs4_acl_get_whotype(buf, dummy32); 293 ace->whotype = nfs4_acl_get_whotype(buf, dummy32);
294 status = nfs_ok; 294 status = nfs_ok;
295 if (ace->whotype != NFS4_ACL_WHO_NAMED) 295 if (ace->whotype != NFS4_ACL_WHO_NAMED)
296 ace->who = 0; 296 ;
297 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) 297 else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
298 status = nfsd_map_name_to_gid(argp->rqstp, 298 status = nfsd_map_name_to_gid(argp->rqstp,
299 buf, dummy32, &ace->who); 299 buf, dummy32, &ace->who_gid);
300 else 300 else
301 status = nfsd_map_name_to_uid(argp->rqstp, 301 status = nfsd_map_name_to_uid(argp->rqstp,
302 buf, dummy32, &ace->who); 302 buf, dummy32, &ace->who_uid);
303 if (status) 303 if (status)
304 return status; 304 return status;
305 } 305 }
@@ -464,9 +464,16 @@ static __be32 nfsd4_decode_cb_sec(struct nfsd4_compoundargs *argp, struct nfsd4_
464 READ32(dummy); 464 READ32(dummy);
465 READ_BUF(dummy * 4); 465 READ_BUF(dummy * 4);
466 if (cbs->flavor == (u32)(-1)) { 466 if (cbs->flavor == (u32)(-1)) {
467 cbs->uid = uid; 467 kuid_t kuid = make_kuid(&init_user_ns, uid);
468 cbs->gid = gid; 468 kgid_t kgid = make_kgid(&init_user_ns, gid);
469 cbs->flavor = RPC_AUTH_UNIX; 469 if (uid_valid(kuid) && gid_valid(kgid)) {
470 cbs->uid = kuid;
471 cbs->gid = kgid;
472 cbs->flavor = RPC_AUTH_UNIX;
473 } else {
474 dprintk("RPC_AUTH_UNIX with invalid"
475 "uid or gid ignoring!\n");
476 }
470 } 477 }
471 break; 478 break;
472 case RPC_AUTH_GSS: 479 case RPC_AUTH_GSS:
@@ -1926,7 +1933,7 @@ static u32 nfs4_file_type(umode_t mode)
1926} 1933}
1927 1934
1928static __be32 1935static __be32
1929nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1936nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, kuid_t uid, kgid_t gid,
1930 __be32 **p, int *buflen) 1937 __be32 **p, int *buflen)
1931{ 1938{
1932 int status; 1939 int status;
@@ -1935,10 +1942,10 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1935 return nfserr_resource; 1942 return nfserr_resource;
1936 if (whotype != NFS4_ACL_WHO_NAMED) 1943 if (whotype != NFS4_ACL_WHO_NAMED)
1937 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1)); 1944 status = nfs4_acl_write_who(whotype, (u8 *)(*p + 1));
1938 else if (group) 1945 else if (gid_valid(gid))
1939 status = nfsd_map_gid_to_name(rqstp, id, (u8 *)(*p + 1)); 1946 status = nfsd_map_gid_to_name(rqstp, gid, (u8 *)(*p + 1));
1940 else 1947 else
1941 status = nfsd_map_uid_to_name(rqstp, id, (u8 *)(*p + 1)); 1948 status = nfsd_map_uid_to_name(rqstp, uid, (u8 *)(*p + 1));
1942 if (status < 0) 1949 if (status < 0)
1943 return nfserrno(status); 1950 return nfserrno(status);
1944 *p = xdr_encode_opaque(*p, NULL, status); 1951 *p = xdr_encode_opaque(*p, NULL, status);
@@ -1948,22 +1955,33 @@ nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group,
1948} 1955}
1949 1956
1950static inline __be32 1957static inline __be32
1951nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen) 1958nfsd4_encode_user(struct svc_rqst *rqstp, kuid_t user, __be32 **p, int *buflen)
1952{ 1959{
1953 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, uid, 0, p, buflen); 1960 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, user, INVALID_GID,
1961 p, buflen);
1954} 1962}
1955 1963
1956static inline __be32 1964static inline __be32
1957nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen) 1965nfsd4_encode_group(struct svc_rqst *rqstp, kgid_t group, __be32 **p, int *buflen)
1958{ 1966{
1959 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, gid, 1, p, buflen); 1967 return nfsd4_encode_name(rqstp, NFS4_ACL_WHO_NAMED, INVALID_UID, group,
1968 p, buflen);
1960} 1969}
1961 1970
1962static inline __be32 1971static inline __be32
1963nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, 1972nfsd4_encode_aclname(struct svc_rqst *rqstp, struct nfs4_ace *ace,
1964 __be32 **p, int *buflen) 1973 __be32 **p, int *buflen)
1965{ 1974{
1966 return nfsd4_encode_name(rqstp, whotype, id, group, p, buflen); 1975 kuid_t uid = INVALID_UID;
1976 kgid_t gid = INVALID_GID;
1977
1978 if (ace->whotype == NFS4_ACL_WHO_NAMED) {
1979 if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP)
1980 gid = ace->who_gid;
1981 else
1982 uid = ace->who_uid;
1983 }
1984 return nfsd4_encode_name(rqstp, ace->whotype, uid, gid, p, buflen);
1967} 1985}
1968 1986
1969#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \ 1987#define WORD0_ABSENT_FS_ATTRS (FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_FSID | \
@@ -2224,9 +2242,7 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
2224 WRITE32(ace->type); 2242 WRITE32(ace->type);
2225 WRITE32(ace->flag); 2243 WRITE32(ace->flag);
2226 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL); 2244 WRITE32(ace->access_mask & NFS4_ACE_MASK_ALL);
2227 status = nfsd4_encode_aclname(rqstp, ace->whotype, 2245 status = nfsd4_encode_aclname(rqstp, ace, &p, &buflen);
2228 ace->who, ace->flag & NFS4_ACE_IDENTIFIER_GROUP,
2229 &p, &buflen);
2230 if (status == nfserr_resource) 2246 if (status == nfserr_resource)
2231 goto out_resource; 2247 goto out_resource;
2232 if (status) 2248 if (status)
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 979b42106979..4201ede0ec91 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -100,12 +100,14 @@ decode_sattr(__be32 *p, struct iattr *iap)
100 iap->ia_mode = tmp; 100 iap->ia_mode = tmp;
101 } 101 }
102 if ((tmp = ntohl(*p++)) != (u32)-1) { 102 if ((tmp = ntohl(*p++)) != (u32)-1) {
103 iap->ia_valid |= ATTR_UID; 103 iap->ia_uid = make_kuid(&init_user_ns, tmp);
104 iap->ia_uid = tmp; 104 if (uid_valid(iap->ia_uid))
105 iap->ia_valid |= ATTR_UID;
105 } 106 }
106 if ((tmp = ntohl(*p++)) != (u32)-1) { 107 if ((tmp = ntohl(*p++)) != (u32)-1) {
107 iap->ia_valid |= ATTR_GID; 108 iap->ia_gid = make_kgid(&init_user_ns, tmp);
108 iap->ia_gid = tmp; 109 if (gid_valid(iap->ia_gid))
110 iap->ia_valid |= ATTR_GID;
109 } 111 }
110 if ((tmp = ntohl(*p++)) != (u32)-1) { 112 if ((tmp = ntohl(*p++)) != (u32)-1) {
111 iap->ia_valid |= ATTR_SIZE; 113 iap->ia_valid |= ATTR_SIZE;
@@ -151,8 +153,8 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
151 *p++ = htonl(nfs_ftypes[type >> 12]); 153 *p++ = htonl(nfs_ftypes[type >> 12]);
152 *p++ = htonl((u32) stat->mode); 154 *p++ = htonl((u32) stat->mode);
153 *p++ = htonl((u32) stat->nlink); 155 *p++ = htonl((u32) stat->nlink);
154 *p++ = htonl((u32) nfsd_ruid(rqstp, stat->uid)); 156 *p++ = htonl((u32) from_kuid(&init_user_ns, stat->uid));
155 *p++ = htonl((u32) nfsd_rgid(rqstp, stat->gid)); 157 *p++ = htonl((u32) from_kgid(&init_user_ns, stat->gid));
156 158
157 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) { 159 if (S_ISLNK(type) && stat->size > NFS_MAXPATHLEN) {
158 *p++ = htonl(NFS_MAXPATHLEN); 160 *p++ = htonl(NFS_MAXPATHLEN);
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index d1c229feed52..1a8c7391f7ae 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -152,8 +152,8 @@ struct nfsd4_channel_attrs {
152 152
153struct nfsd4_cb_sec { 153struct nfsd4_cb_sec {
154 u32 flavor; /* (u32)(-1) used to mean "no valid flavor" */ 154 u32 flavor; /* (u32)(-1) used to mean "no valid flavor" */
155 u32 uid; 155 kuid_t uid;
156 u32 gid; 156 kgid_t gid;
157}; 157};
158 158
159struct nfsd4_create_session { 159struct nfsd4_create_session {
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index d586117fa94a..31ff1d642e31 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -401,8 +401,8 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
401 401
402 /* Revoke setuid/setgid on chown */ 402 /* Revoke setuid/setgid on chown */
403 if (!S_ISDIR(inode->i_mode) && 403 if (!S_ISDIR(inode->i_mode) &&
404 (((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) || 404 (((iap->ia_valid & ATTR_UID) && !uid_eq(iap->ia_uid, inode->i_uid)) ||
405 ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid))) { 405 ((iap->ia_valid & ATTR_GID) && !gid_eq(iap->ia_gid, inode->i_gid)))) {
406 iap->ia_valid |= ATTR_KILL_PRIV; 406 iap->ia_valid |= ATTR_KILL_PRIV;
407 if (iap->ia_valid & ATTR_MODE) { 407 if (iap->ia_valid & ATTR_MODE) {
408 /* we're setting mode too, just clear the s*id bits */ 408 /* we're setting mode too, just clear the s*id bits */
@@ -1205,7 +1205,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
1205 * send along the gid on create when it tries to implement 1205 * send along the gid on create when it tries to implement
1206 * setgid directories via NFS: 1206 * setgid directories via NFS:
1207 */ 1207 */
1208 if (current_fsuid() != 0) 1208 if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
1209 iap->ia_valid &= ~(ATTR_UID|ATTR_GID); 1209 iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
1210 if (iap->ia_valid) 1210 if (iap->ia_valid)
1211 return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1211 return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
@@ -2150,7 +2150,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
2150 * with NFSv3. 2150 * with NFSv3.
2151 */ 2151 */
2152 if ((acc & NFSD_MAY_OWNER_OVERRIDE) && 2152 if ((acc & NFSD_MAY_OWNER_OVERRIDE) &&
2153 inode->i_uid == current_fsuid()) 2153 uid_eq(inode->i_uid, current_fsuid()))
2154 return 0; 2154 return 0;
2155 2155
2156 /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ 2156 /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */