diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/acl.h | 2 | ||||
-rw-r--r-- | fs/nfsd/auth.c | 12 | ||||
-rw-r--r-- | fs/nfsd/auth.h | 6 | ||||
-rw-r--r-- | fs/nfsd/export.c | 22 | ||||
-rw-r--r-- | fs/nfsd/idmap.h | 8 | ||||
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 14 | ||||
-rw-r--r-- | fs/nfsd/nfs4acl.c | 63 | ||||
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 38 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 6 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 54 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 14 | ||||
-rw-r--r-- | fs/nfsd/state.h | 4 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 8 |
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 @@ | |||
44 | struct nfs4_acl *nfs4_acl_new(int); | 44 | struct nfs4_acl *nfs4_acl_new(int); |
45 | int nfs4_acl_get_whotype(char *, u32); | 45 | int nfs4_acl_get_whotype(char *, u32); |
46 | int nfs4_acl_write_who(int who, char *p); | 46 | int nfs4_acl_write_who(int who, char *p); |
47 | int 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 | ||
615 | static void exp_flags(struct seq_file *m, int flag, int fsid, | 619 | static 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); |
617 | static void show_secinfo(struct seq_file *m, struct svc_export *exp); | 621 | static void show_secinfo(struct seq_file *m, struct svc_export *exp); |
618 | 622 | ||
619 | static int svc_export_show(struct seq_file *m, | 623 | static 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 | ||
1181 | static void exp_flags(struct seq_file *m, int flag, int fsid, | 1185 | static 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 *); |
59 | int nfsd_map_uid_to_name(struct svc_rqst *, __u32, char *); | 59 | int nfsd_map_uid_to_name(struct svc_rqst *, kuid_t, char *); |
60 | int nfsd_map_gid_to_name(struct svc_rqst *, __u32, char *); | 60 | int 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 | ||
348 | static bool | ||
349 | pace_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 | |||
348 | static void | 360 | static void |
349 | sort_pacl_range(struct posix_acl *pacl, int start, int end) { | 361 | sort_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 | ||
400 | struct posix_user_ace_state { | 412 | struct 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; |
573 | out_err: | 584 | out_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 | ||
590 | static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid) | 601 | static 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 | ||
618 | static 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 | |||
606 | static void deny_bits_array(struct posix_ace_state_array *a, u32 mask) | 635 | static 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, | |||
65 | struct ent { | 65 | struct 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 | ||
541 | static __be32 | 541 | static __be32 |
542 | idmap_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, | 542 | idmap_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 | ||
566 | static int | 566 | static int |
567 | idmap_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | 567 | idmap_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 | ||
589 | static bool | 589 | static bool |
590 | numeric_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) | 590 | numeric_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 | ||
605 | static __be32 | 605 | static __be32 |
606 | do_name_to_id(struct svc_rqst *rqstp, int type, const char *name, u32 namelen, uid_t *id) | 606 | do_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 | ||
618 | static int | 618 | static int |
619 | do_id_to_name(struct svc_rqst *rqstp, int type, uid_t id, char *name) | 619 | do_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 |
627 | nfsd_map_name_to_uid(struct svc_rqst *rqstp, const char *name, size_t namelen, | 627 | nfsd_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 |
634 | nfsd_map_name_to_gid(struct svc_rqst *rqstp, const char *name, size_t namelen, | 640 | nfsd_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 | ||
640 | int | 652 | int |
641 | nfsd_map_uid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) | 653 | nfsd_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 | ||
646 | int | 659 | int |
647 | nfsd_map_gid_to_name(struct svc_rqst *rqstp, __u32 id, char *name) | 660 | nfsd_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 | |||
1227 | same_creds(struct svc_cred *cr1, struct svc_cred *cr2) | 1227 | same_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 | ||
1928 | static __be32 | 1935 | static __be32 |
1929 | nfsd4_encode_name(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | 1936 | nfsd4_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 | ||
1950 | static inline __be32 | 1957 | static inline __be32 |
1951 | nfsd4_encode_user(struct svc_rqst *rqstp, uid_t uid, __be32 **p, int *buflen) | 1958 | nfsd4_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 | ||
1956 | static inline __be32 | 1964 | static inline __be32 |
1957 | nfsd4_encode_group(struct svc_rqst *rqstp, uid_t gid, __be32 **p, int *buflen) | 1965 | nfsd4_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 | ||
1962 | static inline __be32 | 1971 | static inline __be32 |
1963 | nfsd4_encode_aclname(struct svc_rqst *rqstp, int whotype, uid_t id, int group, | 1972 | nfsd4_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 | ||
153 | struct nfsd4_cb_sec { | 153 | struct 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 | ||
159 | struct nfsd4_create_session { | 159 | struct 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} */ |