summaryrefslogtreecommitdiffstats
path: root/fs/nfs_common/nfsacl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs_common/nfsacl.c')
-rw-r--r--fs/nfs_common/nfsacl.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c
index 6940439bd60..ed628f71274 100644
--- a/fs/nfs_common/nfsacl.c
+++ b/fs/nfs_common/nfsacl.c
@@ -38,8 +38,8 @@ struct nfsacl_encode_desc {
unsigned int count;
struct posix_acl *acl;
int typeflag;
- uid_t uid;
- gid_t gid;
+ kuid_t uid;
+ kgid_t gid;
};
struct nfsacl_simple_acl {
@@ -60,14 +60,16 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
*p++ = htonl(entry->e_tag | nfsacl_desc->typeflag);
switch(entry->e_tag) {
case ACL_USER_OBJ:
- *p++ = htonl(nfsacl_desc->uid);
+ *p++ = htonl(from_kuid(&init_user_ns, nfsacl_desc->uid));
break;
case ACL_GROUP_OBJ:
- *p++ = htonl(nfsacl_desc->gid);
+ *p++ = htonl(from_kgid(&init_user_ns, nfsacl_desc->gid));
break;
case ACL_USER:
+ *p++ = htonl(from_kuid(&init_user_ns, entry->e_uid));
+ break;
case ACL_GROUP:
- *p++ = htonl(entry->e_id);
+ *p++ = htonl(from_kgid(&init_user_ns, entry->e_gid));
break;
default: /* Solaris depends on that! */
*p++ = 0;
@@ -148,6 +150,7 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem)
(struct nfsacl_decode_desc *) desc;
__be32 *p = elem;
struct posix_acl_entry *entry;
+ unsigned int id;
if (!nfsacl_desc->acl) {
if (desc->array_len > NFS_ACL_MAX_ENTRIES)
@@ -160,14 +163,22 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem)
entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++];
entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT;
- entry->e_id = ntohl(*p++);
+ id = ntohl(*p++);
entry->e_perm = ntohl(*p++);
switch(entry->e_tag) {
- case ACL_USER_OBJ:
case ACL_USER:
- case ACL_GROUP_OBJ:
+ entry->e_uid = make_kuid(&init_user_ns, id);
+ if (!uid_valid(entry->e_uid))
+ return -EINVAL;
+ break;
case ACL_GROUP:
+ entry->e_gid = make_kgid(&init_user_ns, id);
+ if (!gid_valid(entry->e_gid))
+ return -EINVAL;
+ break;
+ case ACL_USER_OBJ:
+ case ACL_GROUP_OBJ:
case ACL_OTHER:
if (entry->e_perm & ~S_IRWXO)
return -EINVAL;
@@ -190,9 +201,13 @@ cmp_acl_entry(const void *x, const void *y)
if (a->e_tag != b->e_tag)
return a->e_tag - b->e_tag;
- else if (a->e_id > b->e_id)
+ else if ((a->e_tag == ACL_USER) && uid_gt(a->e_uid, b->e_uid))
+ return 1;
+ else if ((a->e_tag == ACL_USER) && uid_lt(a->e_uid, b->e_uid))
+ return -1;
+ else if ((a->e_tag == ACL_GROUP) && gid_gt(a->e_gid, b->e_gid))
return 1;
- else if (a->e_id < b->e_id)
+ else if ((a->e_tag == ACL_GROUP) && gid_lt(a->e_gid, b->e_gid))
return -1;
else
return 0;
@@ -213,22 +228,18 @@ posix_acl_from_nfsacl(struct posix_acl *acl)
sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry),
cmp_acl_entry, NULL);
- /* Clear undefined identifier fields and find the ACL_GROUP_OBJ
- and ACL_MASK entries. */
+ /* Find the ACL_GROUP_OBJ and ACL_MASK entries. */
FOREACH_ACL_ENTRY(pa, acl, pe) {
switch(pa->e_tag) {
case ACL_USER_OBJ:
- pa->e_id = ACL_UNDEFINED_ID;
break;
case ACL_GROUP_OBJ:
- pa->e_id = ACL_UNDEFINED_ID;
group_obj = pa;
break;
case ACL_MASK:
mask = pa;
/* fall through */
case ACL_OTHER:
- pa->e_id = ACL_UNDEFINED_ID;
break;
}
}