diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2013-02-01 17:50:52 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2013-02-13 09:15:14 -0500 |
commit | ddca4e1730cf1b72044ae76ddf17b29d790b4dbc (patch) | |
tree | f5659143f3b480dd7fd93ea8e0a324884fe3cf87 /fs/nfs_common/nfsacl.c | |
parent | 1ac7fd8190b79c822631ed537186fb8b2d9e9b74 (diff) |
nfs_common: Update the translation between nfsv3 acls linux posix acls
- Use kuid_t and kgit in struct nfsacl_encode_desc.
- Convert from kuids and kgids when generating on the wire values.
- Convert on the wire values to kuids and kgids when read.
- Modify cmp_acl_entry to be type safe comparison on posix acls.
Only acls with type ACL_USER and ACL_GROUP can appear more
than once and as such need to compare more than their tag.
- The e_id field is being removed from posix acls so don't initialize it.
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'fs/nfs_common/nfsacl.c')
-rw-r--r-- | fs/nfs_common/nfsacl.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/fs/nfs_common/nfsacl.c b/fs/nfs_common/nfsacl.c index 6940439bd609..ed628f71274c 100644 --- a/fs/nfs_common/nfsacl.c +++ b/fs/nfs_common/nfsacl.c | |||
@@ -38,8 +38,8 @@ struct nfsacl_encode_desc { | |||
38 | unsigned int count; | 38 | unsigned int count; |
39 | struct posix_acl *acl; | 39 | struct posix_acl *acl; |
40 | int typeflag; | 40 | int typeflag; |
41 | uid_t uid; | 41 | kuid_t uid; |
42 | gid_t gid; | 42 | kgid_t gid; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | struct nfsacl_simple_acl { | 45 | struct nfsacl_simple_acl { |
@@ -60,14 +60,16 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) | |||
60 | *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag); | 60 | *p++ = htonl(entry->e_tag | nfsacl_desc->typeflag); |
61 | switch(entry->e_tag) { | 61 | switch(entry->e_tag) { |
62 | case ACL_USER_OBJ: | 62 | case ACL_USER_OBJ: |
63 | *p++ = htonl(nfsacl_desc->uid); | 63 | *p++ = htonl(from_kuid(&init_user_ns, nfsacl_desc->uid)); |
64 | break; | 64 | break; |
65 | case ACL_GROUP_OBJ: | 65 | case ACL_GROUP_OBJ: |
66 | *p++ = htonl(nfsacl_desc->gid); | 66 | *p++ = htonl(from_kgid(&init_user_ns, nfsacl_desc->gid)); |
67 | break; | 67 | break; |
68 | case ACL_USER: | 68 | case ACL_USER: |
69 | *p++ = htonl(from_kuid(&init_user_ns, entry->e_uid)); | ||
70 | break; | ||
69 | case ACL_GROUP: | 71 | case ACL_GROUP: |
70 | *p++ = htonl(entry->e_id); | 72 | *p++ = htonl(from_kgid(&init_user_ns, entry->e_gid)); |
71 | break; | 73 | break; |
72 | default: /* Solaris depends on that! */ | 74 | default: /* Solaris depends on that! */ |
73 | *p++ = 0; | 75 | *p++ = 0; |
@@ -148,6 +150,7 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem) | |||
148 | (struct nfsacl_decode_desc *) desc; | 150 | (struct nfsacl_decode_desc *) desc; |
149 | __be32 *p = elem; | 151 | __be32 *p = elem; |
150 | struct posix_acl_entry *entry; | 152 | struct posix_acl_entry *entry; |
153 | unsigned int id; | ||
151 | 154 | ||
152 | if (!nfsacl_desc->acl) { | 155 | if (!nfsacl_desc->acl) { |
153 | if (desc->array_len > NFS_ACL_MAX_ENTRIES) | 156 | if (desc->array_len > NFS_ACL_MAX_ENTRIES) |
@@ -160,14 +163,22 @@ xdr_nfsace_decode(struct xdr_array2_desc *desc, void *elem) | |||
160 | 163 | ||
161 | entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++]; | 164 | entry = &nfsacl_desc->acl->a_entries[nfsacl_desc->count++]; |
162 | entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT; | 165 | entry->e_tag = ntohl(*p++) & ~NFS_ACL_DEFAULT; |
163 | entry->e_id = ntohl(*p++); | 166 | id = ntohl(*p++); |
164 | entry->e_perm = ntohl(*p++); | 167 | entry->e_perm = ntohl(*p++); |
165 | 168 | ||
166 | switch(entry->e_tag) { | 169 | switch(entry->e_tag) { |
167 | case ACL_USER_OBJ: | ||
168 | case ACL_USER: | 170 | case ACL_USER: |
169 | case ACL_GROUP_OBJ: | 171 | entry->e_uid = make_kuid(&init_user_ns, id); |
172 | if (!uid_valid(entry->e_uid)) | ||
173 | return -EINVAL; | ||
174 | break; | ||
170 | case ACL_GROUP: | 175 | case ACL_GROUP: |
176 | entry->e_gid = make_kgid(&init_user_ns, id); | ||
177 | if (!gid_valid(entry->e_gid)) | ||
178 | return -EINVAL; | ||
179 | break; | ||
180 | case ACL_USER_OBJ: | ||
181 | case ACL_GROUP_OBJ: | ||
171 | case ACL_OTHER: | 182 | case ACL_OTHER: |
172 | if (entry->e_perm & ~S_IRWXO) | 183 | if (entry->e_perm & ~S_IRWXO) |
173 | return -EINVAL; | 184 | return -EINVAL; |
@@ -190,9 +201,13 @@ cmp_acl_entry(const void *x, const void *y) | |||
190 | 201 | ||
191 | if (a->e_tag != b->e_tag) | 202 | if (a->e_tag != b->e_tag) |
192 | return a->e_tag - b->e_tag; | 203 | return a->e_tag - b->e_tag; |
193 | else if (a->e_id > b->e_id) | 204 | else if ((a->e_tag == ACL_USER) && uid_gt(a->e_uid, b->e_uid)) |
205 | return 1; | ||
206 | else if ((a->e_tag == ACL_USER) && uid_lt(a->e_uid, b->e_uid)) | ||
207 | return -1; | ||
208 | else if ((a->e_tag == ACL_GROUP) && gid_gt(a->e_gid, b->e_gid)) | ||
194 | return 1; | 209 | return 1; |
195 | else if (a->e_id < b->e_id) | 210 | else if ((a->e_tag == ACL_GROUP) && gid_lt(a->e_gid, b->e_gid)) |
196 | return -1; | 211 | return -1; |
197 | else | 212 | else |
198 | return 0; | 213 | return 0; |
@@ -213,22 +228,18 @@ posix_acl_from_nfsacl(struct posix_acl *acl) | |||
213 | sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry), | 228 | sort(acl->a_entries, acl->a_count, sizeof(struct posix_acl_entry), |
214 | cmp_acl_entry, NULL); | 229 | cmp_acl_entry, NULL); |
215 | 230 | ||
216 | /* Clear undefined identifier fields and find the ACL_GROUP_OBJ | 231 | /* Find the ACL_GROUP_OBJ and ACL_MASK entries. */ |
217 | and ACL_MASK entries. */ | ||
218 | FOREACH_ACL_ENTRY(pa, acl, pe) { | 232 | FOREACH_ACL_ENTRY(pa, acl, pe) { |
219 | switch(pa->e_tag) { | 233 | switch(pa->e_tag) { |
220 | case ACL_USER_OBJ: | 234 | case ACL_USER_OBJ: |
221 | pa->e_id = ACL_UNDEFINED_ID; | ||
222 | break; | 235 | break; |
223 | case ACL_GROUP_OBJ: | 236 | case ACL_GROUP_OBJ: |
224 | pa->e_id = ACL_UNDEFINED_ID; | ||
225 | group_obj = pa; | 237 | group_obj = pa; |
226 | break; | 238 | break; |
227 | case ACL_MASK: | 239 | case ACL_MASK: |
228 | mask = pa; | 240 | mask = pa; |
229 | /* fall through */ | 241 | /* fall through */ |
230 | case ACL_OTHER: | 242 | case ACL_OTHER: |
231 | pa->e_id = ACL_UNDEFINED_ID; | ||
232 | break; | 243 | break; |
233 | } | 244 | } |
234 | } | 245 | } |