diff options
Diffstat (limited to 'sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch')
-rw-r--r-- | sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch | 1740 |
1 files changed, 0 insertions, 1740 deletions
diff --git a/sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch b/sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch deleted file mode 100644 index f6c134d..0000000 --- a/sys-apps/acl/files/0002-nfsd4-move-to-new-nfsv4-posix-mapping-clean-up.patch +++ /dev/null @@ -1,1740 +0,0 @@ -From 7b6f7353fe4d05c18fcc5a932282b16c4cfe55b4 Mon Sep 17 00:00:00 2001 -From: "J. Bruce Fields" <bfields@snoopy.citi.umich.edu> -Date: Mon, 11 Dec 2006 18:38:01 -0500 -Subject: [PATCH 02/17] nfsd4: move to new nfsv4->posix mapping; clean up - -Move to the new nfsv4->posix mapping which accepts any nfsv4 acl and converts -it to the closest posix acl, erring on the side of permissiveness. - -Also delete some cruft. - -Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu> ---- - exports | 22 -- - include/libacl_nfs4.h | 21 -- - libacl/Makefile | 7 +- - libacl/acl_n4tp_ace_count.c | 57 ---- - libacl/acl_n4tp_ace_trans.c | 76 ------ - libacl/acl_n4tp_acl_trans.c | 400 +++++++++++++++++++++++++----- - libacl/acl_n4tp_get_whotype.c | 73 ------ - libacl/acl_n4tp_set_mode.c | 98 ------- - libacl/acl_n4tp_set_who.c | 89 ------- - libacl/acl_nfs4_copy_acl.c | 4 +- - libacl/acl_nfs4_utils.c | 566 ----------------------------------------- - libacl/acl_nfs4_xattr_pack.c | 4 +- - libacl/acl_nfs4_xattr_size.c | 4 +- - libacl/libacl_nfs4.h | 32 --- - 14 files changed, 348 insertions(+), 1105 deletions(-) - delete mode 100644 libacl/acl_n4tp_ace_count.c - delete mode 100644 libacl/acl_n4tp_ace_trans.c - delete mode 100644 libacl/acl_n4tp_get_whotype.c - delete mode 100644 libacl/acl_n4tp_set_mode.c - delete mode 100644 libacl/acl_n4tp_set_who.c - delete mode 100644 libacl/acl_nfs4_utils.c - -diff --git a/exports b/exports -index 08bf390..31f3e00 100644 ---- a/exports -+++ b/exports -@@ -103,39 +103,17 @@ ACL_1.2 { - acl_nfs4_remove_ace; - - acl_n4tp_acl_trans; -- acl_n4tp_set_mode; -- acl_n4tp_ace_count; -- acl_n4tp_ace_trans; -- acl_n4tp_set_who; -- acl_n4tp_get_whotype; - - acl_ptn4_get_mask; - acl_ptn4_acl_trans; - -- acl_nfs4_get_next_ace; -- acl_nfs4_get_first_ace; -- acl_nfs4_get_dir; - acl_nfs4_get_whotype; - acl_nfs4_get_who; - acl_nfs4_entries; - - local: - __posix_acl_from_nfs4_xattr; -- complementary_ace_pair; -- same_who; -- nfs4_get_gid_from_who; -- nfs4_get_uid_from_who; - nfs4_get_who_from_uid; - nfs4_get_who_from_gid; -- __nfs4_get_local_uid_from_who; -- __nfs4_get_foreign_uid_from_who; -- __nfs4_get_local_gid_from_who; -- __nfs4_get_foreign_gid_from_who; -- is_who_local; - -- user_obj_from_v4; -- users_from_v4; -- group_obj_and_groups_from_v4; -- mask_from_v4; -- other_from_v4; - } ACL_1.1; -diff --git a/include/libacl_nfs4.h b/include/libacl_nfs4.h -index e6a466c..9103424 100644 ---- a/include/libacl_nfs4.h -+++ b/include/libacl_nfs4.h -@@ -82,14 +82,6 @@ extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace) - - /* nfs4 -> posix */ - extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t); --extern int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask, -- int iflags); --extern int acl_n4tp_ace_count(struct nfs4_acl *n4acl); --extern int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl, -- acl_tag_t tag, int iflags); --extern int acl_n4tp_set_who(acl_entry_t ace, char* who, -- acl_tag_t who_type); --extern acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace); - - /* posix -> nfs4 */ - extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, -@@ -98,28 +90,15 @@ extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*); - - - /** Access Functions **/ --extern inline struct nfs4_ace * -- acl_nfs4_get_next_ace(struct nfs4_ace **); --extern inline struct nfs4_ace * -- acl_nfs4_get_first_ace(struct nfs4_acl *); - extern inline int acl_nfs4_get_whotype(char*); - extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**); - - /**** Private(?) functions ****/ - acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32); --int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny); --int same_who(struct nfs4_ace *a, struct nfs4_ace *b); - - /* These will change */ --int nfs4_get_gid_from_who(gid_t* gid, const char * who); --int nfs4_get_uid_from_who(uid_t* uid, const char * who); - char * nfs4_get_who_from_uid(uid_t); - char * nfs4_get_who_from_gid(gid_t); --int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who); --int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who); --int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who); --int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who); --int is_who_local(const char * who); - /* End change */ - - int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace, -diff --git a/libacl/Makefile b/libacl/Makefile -index 8335170..feee9a5 100644 ---- a/libacl/Makefile -+++ b/libacl/Makefile -@@ -37,15 +37,12 @@ HFILES = libobj.h libacl.h byteorder.h __acl_from_xattr.h __acl_to_xattr.h \ - LCFLAGS = -include perm_copy.h - - LIBACL_NFS4_CFILES = \ -- acl_n4tp_ace_count.c \ -- acl_n4tp_ace_trans.c acl_nfs4_get_who.c \ -+ acl_nfs4_get_who.c \ - acl_n4tp_acl_trans.c acl_nfs4_get_whotype.c \ -- acl_n4tp_get_whotype.c acl_nfs4_new.c \ -- acl_n4tp_set_mode.c acl_n4tp_set_who.c \ -+ acl_nfs4_new.c \ - acl_nfs4_add_ace.c acl_nfs4_remove_ace.c \ - acl_nfs4_add_pair.c \ - acl_nfs4_copy_acl.c acl_nfs4_set_who.c \ -- acl_nfs4_utils.c \ - acl_nfs4_free.c acl_nfs4_xattr_load.c \ - acl_nfs4_xattr_pack.c acl_nfs4_xattr_size.c \ - acl_ptn4_acl_trans.c \ -diff --git a/libacl/acl_n4tp_ace_count.c b/libacl/acl_n4tp_ace_count.c -deleted file mode 100644 -index ecce637..0000000 ---- a/libacl/acl_n4tp_ace_count.c -+++ /dev/null -@@ -1,57 +0,0 @@ --/* -- * NFSv4 ACL Code -- * Calculate the POSIX ACE count based upon the assumption that -- * POSIX<->NFSv4 ACL translation has been the standard on the -- * server/client. This would break against other servers? -- * -- * Copyright (c) 2002, 2003 The Regents of the University of Michigan. -- * All rights reserved. -- * -- * Nathaniel Gallaher <ngallahe@umich.edu> -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. Neither the name of the University nor the names of its -- * contributors may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#include <acl/libacl.h> --#include "libacl_nfs4.h" -- --int acl_n4tp_ace_count(struct nfs4_acl *n4acl) --{ -- if (n4acl->naces == 0) -- return 0; -- if (n4acl->naces == 6) /* owner, owner group, and other only */ -- return 3; -- else { /* Otherwise there must be a mask entry. */ -- /* Also, the remaining entries are for named users and -- * groups, and come in threes (mask, allow, deny): */ -- if (n4acl->naces < 7) -- return -1; -- if ((n4acl->naces - 7) % 3) -- return -1; -- return 4 + (n4acl->naces - 7)/3; -- } --} -- -diff --git a/libacl/acl_n4tp_ace_trans.c b/libacl/acl_n4tp_ace_trans.c -deleted file mode 100644 -index c5cc4da..0000000 ---- a/libacl/acl_n4tp_ace_trans.c -+++ /dev/null -@@ -1,76 +0,0 @@ --/* -- * NFSv4 ACL Code -- * Translate an NFSv4 ace to a POSIX ace. -- * -- * Copyright (c) 2002, 2003 The Regents of the University of Michigan. -- * All rights reserved. -- * -- * Nathaniel Gallaher <ngallahe@umich.edu> -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. Neither the name of the University nor the names of its -- * contributors may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#include "libacl_nfs4.h" -- --int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl, acl_tag_t tag, -- int iflags) --{ -- int result; -- acl_entry_t new_ace; -- -- -- if(ace == NULL || pacl == NULL || *pacl == NULL) { -- errno = EINVAL; -- goto failed; -- } -- -- result = acl_create_entry(pacl, &new_ace); -- if(result < 0) -- goto failed; -- -- result = acl_set_tag_type(new_ace, tag); -- if(result < 0) -- goto ace_failed; -- -- result = acl_n4tp_set_mode(new_ace, ace->access_mask, iflags); -- if(result < 0) -- goto ace_failed; -- -- if(tag == ACL_USER || tag == ACL_GROUP) { -- result = acl_n4tp_set_who(new_ace, ace->who, tag); -- if(result < 0) -- goto ace_failed; -- } -- -- return 0; -- --ace_failed: -- acl_delete_entry(*pacl, new_ace); -- --failed: -- return -1; --} -- -diff --git a/libacl/acl_n4tp_acl_trans.c b/libacl/acl_n4tp_acl_trans.c -index f658242..7fcb992 100644 ---- a/libacl/acl_n4tp_acl_trans.c -+++ b/libacl/acl_n4tp_acl_trans.c -@@ -34,27 +34,335 @@ - */ - - #include <acl/libacl.h> -+#include <nfsidmap.h> - #include "libacl_nfs4.h" - --acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype) -+ -+/* -+ * While processing the NFSv4 ACE, this maintains bitmasks representing -+ * which permission bits have been allowed and which denied to a given -+ * entity: */ -+struct posix_ace_state { -+ u_int32_t allow; -+ u_int32_t deny; -+}; -+ -+struct posix_user_ace_state { -+ uid_t uid; -+ struct posix_ace_state perms; -+}; -+ -+struct posix_ace_state_array { -+ int n; -+ struct posix_user_ace_state aces[]; -+}; -+ -+/* -+ * While processing the NFSv4 ACE, this maintains the partial permissions -+ * calculated so far: */ -+ -+struct posix_acl_state { -+ struct posix_ace_state owner; -+ struct posix_ace_state group; -+ struct posix_ace_state other; -+ struct posix_ace_state everyone; -+ struct posix_ace_state mask; /* Deny unused in this case */ -+ struct posix_ace_state_array *users; -+ struct posix_ace_state_array *groups; -+}; -+ -+static int -+init_state(struct posix_acl_state *state, int cnt) -+{ -+ int alloc; -+ -+ memset(state, 0, sizeof(struct posix_acl_state)); -+ /* -+ * In the worst case, each individual acl could be for a distinct -+ * named user or group, but we don't no which, so we allocate -+ * enough space for either: -+ */ -+ alloc = sizeof(struct posix_ace_state_array) -+ + cnt*sizeof(struct posix_ace_state); -+ state->users = calloc(1, alloc); -+ if (!state->users) -+ return -ENOMEM; -+ state->groups = calloc(1, alloc); -+ if (!state->groups) { -+ free(state->users); -+ return -ENOMEM; -+ } -+ return 0; -+} -+ -+static void -+free_state(struct posix_acl_state *state) { -+ free(state->users); -+ free(state->groups); -+} -+ -+static inline void add_to_mask(struct posix_acl_state *state, struct posix_ace_state *astate) -+{ -+ state->mask.allow |= astate->allow; -+} -+ -+/* -+ * We only map from NFSv4 to POSIX ACLs when getting ACLs, when we err on the -+ * side of permissiveness (so as not to make the file appear more secure than -+ * it really is), so the mode bit mapping below is optimistic. -+ */ -+static void -+set_mode_from_nfs4(acl_entry_t pace, u_int32_t perm, int is_dir) -+{ -+ u32 write_mode = NFS4_WRITE_MODE; -+ acl_permset_t perms; -+ -+ acl_get_permset(pace, &perms); -+ acl_clear_perms(perms); -+ if (is_dir) -+ write_mode |= NFS4_ACE_DELETE_CHILD; -+ if (perm & NFS4_READ_MODE) -+ acl_add_perm(perms, ACL_READ); -+ if (perm & write_mode) -+ acl_add_perm(perms, ACL_WRITE); -+ if (perm & NFS4_EXECUTE_MODE) -+ acl_add_perm(perms, ACL_EXECUTE); -+ acl_set_permset(pace, perms); -+} -+ -+/* XXX: add a "check allow" that can warn on e.g. allows of WRITE_ACL -+ * to non-owner? */ -+ -+/* XXX: replace error returns by errno sets all over. Ugh. */ -+ -+static acl_t -+posix_state_to_acl(struct posix_acl_state *state, int is_dir) -+{ -+ acl_entry_t pace; -+ acl_t pacl; -+ int nace; -+ int i, error = 0; -+ -+ nace = 4 + state->users->n + state->groups->n; -+ pacl = acl_init(nace); -+ if (!pacl) -+ return NULL; -+ -+ error = acl_create_entry(&pacl, &pace); -+ if (error) -+ goto out_err; -+ acl_set_tag_type(pace, ACL_USER_OBJ); -+ set_mode_from_nfs4(pace, state->owner.allow, is_dir); -+ -+ for (i=0; i < state->users->n; i++) { -+ error = acl_create_entry(&pacl, &pace); -+ if (error) -+ goto out_err; -+ acl_set_tag_type(pace, ACL_USER); -+ set_mode_from_nfs4(pace, state->users->aces[i].perms.allow, -+ is_dir); -+ acl_set_qualifier(pace, &state->users->aces[i].uid); -+ add_to_mask(state, &state->users->aces[i].perms); -+ } -+ -+ error = acl_create_entry(&pacl, &pace); -+ if (error) -+ goto out_err; -+ acl_set_tag_type(pace, ACL_GROUP_OBJ); -+ set_mode_from_nfs4(pace, state->group.allow, is_dir); -+ add_to_mask(state, &state->group); -+ -+ for (i=0; i < state->groups->n; i++) { -+ error = acl_create_entry(&pacl, &pace); -+ if (error) -+ goto out_err; -+ acl_set_tag_type(pace, ACL_GROUP); -+ set_mode_from_nfs4(pace, state->groups->aces[i].perms.allow, -+ is_dir); -+ acl_set_qualifier(pace, &state->groups->aces[i].uid); -+ add_to_mask(state, &state->groups->aces[i].perms); -+ } -+ -+ error = acl_create_entry(&pacl, &pace); -+ if (error) -+ goto out_err; -+ acl_set_tag_type(pace, ACL_MASK); -+ set_mode_from_nfs4(pace, state->mask.allow, is_dir); -+ -+ error = acl_create_entry(&pacl, &pace); -+ if (error) -+ goto out_err; -+ acl_set_tag_type(pace, ACL_OTHER); -+ set_mode_from_nfs4(pace, state->other.allow, is_dir); -+ -+ return pacl; -+out_err: -+ acl_free(pacl); -+ return NULL; -+} -+ -+static inline void allow_bits(struct posix_ace_state *astate, u32 mask) -+{ -+ /* Allow all bits in the mask not already denied: */ -+ astate->allow |= mask & ~astate->deny; -+} -+ -+static inline void deny_bits(struct posix_ace_state *astate, u32 mask) -+{ -+ /* Deny all bits in the mask not already allowed: */ -+ astate->deny |= mask & ~astate->allow; -+} -+ -+static int find_uid(struct posix_acl_state *state, struct posix_ace_state_array *a, uid_t uid) -+{ -+ int i; -+ -+ for (i = 0; i < a->n; i++) -+ if (a->aces[i].uid == uid) -+ return i; -+ /* Not found: */ -+ a->n++; -+ a->aces[i].uid = uid; -+ a->aces[i].perms.allow = state->everyone.allow; -+ a->aces[i].perms.deny = state->everyone.deny; -+ -+ return i; -+} -+ -+static void deny_bits_array(struct posix_ace_state_array *a, u32 mask) -+{ -+ int i; -+ -+ for (i=0; i < a->n; i++) -+ deny_bits(&a->aces[i].perms, mask); -+} -+ -+static void allow_bits_array(struct posix_ace_state_array *a, u32 mask) -+{ -+ int i; -+ -+ for (i=0; i < a->n; i++) -+ allow_bits(&a->aces[i].perms, mask); -+} -+ -+static acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace) - { -+ int nfs4type; -+ int result; -+ -+ result = acl_nfs4_get_who(ace, &nfs4type, NULL); -+ if (result < 0) -+ return -1; -+ -+ switch (nfs4type) { -+ case NFS4_ACL_WHO_NAMED: -+ return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? -+ ACL_GROUP : ACL_USER); -+ case NFS4_ACL_WHO_OWNER: -+ return ACL_USER_OBJ; -+ case NFS4_ACL_WHO_GROUP: -+ return ACL_GROUP_OBJ; -+ case NFS4_ACL_WHO_EVERYONE: -+ return ACL_OTHER; -+ } -+ errno = EINVAL; -+ return -1; -+} -+ -+static int process_one_v4_ace(struct posix_acl_state *state, -+ struct nfs4_ace *ace) -+{ -+ u32 mask = ace->access_mask; -+ uid_t id; -+ int i; -+ -+ if (nfs4_init_name_mapping(NULL)) -+ return -1; -+ -+ switch (acl_n4tp_get_whotype(ace)) { -+ case ACL_USER_OBJ: -+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { -+ allow_bits(&state->owner, mask); -+ } else { -+ deny_bits(&state->owner, mask); -+ } -+ break; -+ case ACL_USER: -+ if (nfs4_name_to_uid(ace->who, &id)) -+ return -1; -+ i = find_uid(state, state->users, id); -+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { -+ allow_bits(&state->users->aces[i].perms, mask); -+ mask = state->users->aces[i].perms.allow; -+ allow_bits(&state->owner, mask); -+ } else { -+ deny_bits(&state->users->aces[i].perms, mask); -+ } -+ break; -+ case ACL_GROUP_OBJ: -+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { -+ allow_bits(&state->group, mask); -+ mask = state->group.allow; -+ allow_bits(&state->owner, mask); -+ allow_bits(&state->everyone, mask); -+ allow_bits_array(state->users, mask); -+ allow_bits_array(state->groups, mask); -+ } else { -+ deny_bits(&state->group, mask); -+ } -+ break; -+ case ACL_GROUP: -+ if (nfs4_name_to_gid(ace->who, &id)) -+ return -1; -+ i = find_uid(state, state->groups, id); -+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { -+ allow_bits(&state->groups->aces[i].perms, mask); -+ mask = state->groups->aces[i].perms.allow; -+ allow_bits(&state->owner, mask); -+ allow_bits(&state->group, mask); -+ allow_bits(&state->everyone, mask); -+ allow_bits_array(state->users, mask); -+ allow_bits_array(state->groups, mask); -+ } else { -+ deny_bits(&state->groups->aces[i].perms, mask); -+ } -+ break; -+ case ACL_OTHER: -+ if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { -+ allow_bits(&state->owner, mask); -+ allow_bits(&state->group, mask); -+ allow_bits(&state->other, mask); -+ allow_bits(&state->everyone, mask); -+ allow_bits_array(state->users, mask); -+ allow_bits_array(state->groups, mask); -+ } else { -+ deny_bits(&state->owner, mask); -+ deny_bits(&state->group, mask); -+ deny_bits(&state->other, mask); -+ deny_bits(&state->everyone, mask); -+ deny_bits_array(state->users, mask); -+ deny_bits_array(state->groups, mask); -+ } -+ } -+ return 0; -+} - -- acl_t pacl_p = NULL; -- acl_t * pacl_pp; -+acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype) -+{ -+ struct posix_acl_state state; -+ acl_t pacl; - struct nfs4_acl * temp_acl; -- int naces = -1; - int num_aces; - int ace_num; - struct nfs4_ace * cur_ace = NULL; -- struct nfs4_ace * mask_ace = NULL; - struct nfs4_ace * temp_ace = NULL; -- int result; -+ int ret; - u32 flags; - u32 iflags = NFS4_ACL_NOFLAGS; - - if (nacl_p == NULL) { - errno = EINVAL; -- goto failed; -+ return NULL; - } - - if (ptype == ACL_TYPE_DEFAULT) { -@@ -62,25 +370,25 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype) - iflags |= NFS4_ACL_REQUEST_DEFAULT; - else { - errno = EINVAL; -- goto failed; -+ return NULL; - } - } - - /* Copy so we can delete bits without borking the original */ - temp_acl = acl_nfs4_copy_acl(nacl_p); - if (temp_acl == NULL) -- goto failed; -+ return NULL; - - num_aces = temp_acl->naces; - - /* Strip or keep inheritance aces depending upon the type of posix acl - * requested */ -- cur_ace = acl_nfs4_get_first_ace(temp_acl); -+ cur_ace = temp_acl->ace_head.tqh_first; - ace_num = 1; - -- while(1) { -- if(cur_ace == NULL) { -- if(ace_num > num_aces) -+ while (1) { -+ if (cur_ace == NULL) { -+ if (ace_num > num_aces) - break; - else - goto free_failed; -@@ -88,10 +396,11 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype) - - /* get the next ace now because we may be freeing the current ace */ - temp_ace = cur_ace; -- acl_nfs4_get_next_ace(&cur_ace); -+ cur_ace = cur_ace->l_ace.tqe_next; - - flags = temp_ace->flag; - -+ /* XXX: bring in sync with current kernel: */ - if (iflags & NFS4_ACL_REQUEST_DEFAULT) { - if((flags & NFS4_INHERITANCE_FLAGS) != NFS4_INHERITANCE_FLAGS) - acl_nfs4_remove_ace(temp_acl, temp_ace); -@@ -104,61 +413,32 @@ acl_t acl_n4tp_acl_trans(struct nfs4_acl * nacl_p, acl_type_t ptype) - ace_num++; - } - -- -- naces = acl_n4tp_ace_count(temp_acl); -- if (naces < 0) { -- errno = EINVAL; -+ ret = init_state(&state, temp_acl->naces); -+ if (ret) - goto free_failed; -- } -- -- if (naces == 0) -- return acl_init(0); -- -- pacl_p = acl_init(naces); -- -- if(pacl_p == NULL) -- goto free_failed; -- -- pacl_pp = &pacl_p; - -- cur_ace = acl_nfs4_get_first_ace(temp_acl); -- -- result = user_obj_from_v4(temp_acl, &cur_ace, pacl_pp, iflags); -- if(result < 0) -- goto acl_free_failed; -- -- result = users_from_v4(temp_acl, &cur_ace, &mask_ace, pacl_pp, iflags); -- if(result < 0) -- goto acl_free_failed; -- -- result = group_obj_and_groups_from_v4(temp_acl, &cur_ace, -- &mask_ace, pacl_pp, iflags); -- if(result < 0) -- goto acl_free_failed; -- -- result = mask_from_v4(temp_acl, &cur_ace, &mask_ace, pacl_pp, iflags); -- if(result < 0) -- goto acl_free_failed; -+ cur_ace = temp_acl->ace_head.tqh_first; -+ while (cur_ace) { -+ if (process_one_v4_ace(&state, cur_ace)) { -+ free_state(&state); -+ goto free_failed; -+ } -+ cur_ace = cur_ace->l_ace.tqe_next; -+ } - -- result = other_from_v4(temp_acl, &cur_ace, pacl_pp, iflags); -- if(result < 0) -- goto acl_free_failed; -+ acl_nfs4_free(temp_acl); - -- result = acl_valid(*pacl_pp); -- if(result < 0) -- goto acl_free_failed; -+ pacl = posix_state_to_acl(&state, nacl_p->is_directory); - -- acl_nfs4_free(temp_acl); -+ free_state(&state); - -- return *pacl_pp; -+ ret = acl_valid(pacl); -+ if (ret < 0) -+ goto free_failed; - --acl_free_failed: -- acl_free(*pacl_pp); -+ return pacl; - - free_failed: - acl_nfs4_free(temp_acl); -- --failed: - return NULL; - } -- -diff --git a/libacl/acl_n4tp_get_whotype.c b/libacl/acl_n4tp_get_whotype.c -deleted file mode 100644 -index fd553c6..0000000 ---- a/libacl/acl_n4tp_get_whotype.c -+++ /dev/null -@@ -1,73 +0,0 @@ --/* -- * NFSv4 ACL Code -- * Convert NFSv4 ACE who to a POSIX ACE whotype -- * -- * Copyright (c) 2002, 2003 The Regents of the University of Michigan. -- * All rights reserved. -- * -- * Nathaniel Gallaher <ngallahe@umich.edu> -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. Neither the name of the University nor the names of its -- * contributors may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#include <acl/libacl.h> --#include "libacl_nfs4.h" -- --acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace) --{ -- int nfs4type; -- int result; -- -- if(ace == NULL) -- goto inval_failed; -- -- if(ace->who == NULL || strlen(ace->who) <= 0) -- goto inval_failed; -- -- result = acl_nfs4_get_who(ace, &nfs4type, NULL); -- if ( result < 0 ) -- goto failed; -- -- switch (nfs4type) { -- case NFS4_ACL_WHO_NAMED: -- return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? -- ACL_GROUP : ACL_USER); -- case NFS4_ACL_WHO_OWNER: -- return ACL_USER_OBJ; -- case NFS4_ACL_WHO_GROUP: -- return ACL_GROUP_OBJ; -- case NFS4_ACL_WHO_EVERYONE: -- return ACL_OTHER; -- } -- --inval_failed: -- errno = EINVAL; -- --failed: -- return -1; --} -- -- -diff --git a/libacl/acl_n4tp_set_mode.c b/libacl/acl_n4tp_set_mode.c -deleted file mode 100644 -index bef5e23..0000000 ---- a/libacl/acl_n4tp_set_mode.c -+++ /dev/null -@@ -1,98 +0,0 @@ --/* -- * NFSv4 ACL Code -- * Set posix ACL mode based on NFSv4 mask -- * Copyright (c) 2002, 2003 The Regents of the University of Michigan. -- * All rights reserved. -- * -- * Nathaniel Gallaher <ngallahe@umich.edu> -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. Neither the name of the University nor the names of its -- * contributors may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#include <acl/libacl.h> --#include "libacl_nfs4.h" -- --int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask, int iflags) --{ -- /* XXX we might also want to ignore DELETE_CHILD on non-directories */ -- /* XXX also add special interpretation to EXECUTE on directories */ -- u32 ignore = NFS4_ACE_SYNCHRONIZE; -- u32 new_mask; -- acl_permset_t perms; -- int result; -- -- if((iflags & NFS4_ACL_ISDIR) != NFS4_ACL_ISDIR) -- ignore |= NFS4_ACE_DELETE_CHILD; -- -- nfs4_access_mask |= ignore; -- -- result = acl_get_permset(pace, &perms); -- if(result < 0) -- goto failed; -- -- result = acl_clear_perms(perms); -- if(result < 0) -- goto failed; -- -- if ((nfs4_access_mask & NFS4_READ_MODE) == NFS4_READ_MODE) { -- result = acl_add_perm(perms, ACL_READ); -- if(result < 0) -- goto failed; -- } -- -- if ((nfs4_access_mask & NFS4_WRITE_MODE) == NFS4_WRITE_MODE) { -- result = acl_add_perm(perms, ACL_WRITE); -- if(result < 0) -- goto failed; -- } -- -- if ((nfs4_access_mask & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) { -- result = acl_add_perm(perms, ACL_EXECUTE); -- if(result < 0) -- goto failed; -- } -- -- result = acl_ptn4_get_mask(&new_mask, perms, iflags); -- if(result < 0) -- goto failed; -- -- new_mask |= ignore; -- -- if (!MASK_EQUAL(nfs4_access_mask, new_mask)) { -- errno = EINVAL; -- goto failed; -- } -- -- result = acl_set_permset(pace, perms); -- if(result < 0) -- goto failed; -- -- return 0; -- --failed: -- return -1; --} -- -diff --git a/libacl/acl_n4tp_set_who.c b/libacl/acl_n4tp_set_who.c -deleted file mode 100644 -index 241ef71..0000000 ---- a/libacl/acl_n4tp_set_who.c -+++ /dev/null -@@ -1,89 +0,0 @@ --/* -- * NFSv4 ACL Code -- * Set the POSIX ACE who based on the whotype and NFS who attr. -- * Translation is done using the NFS4 mapping functions. -- * -- * Copyright (c) 2002, 2003 The Regents of the University of Michigan. -- * All rights reserved. -- * -- * Nathaniel Gallaher <ngallahe@umich.edu> -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. Neither the name of the University nor the names of its -- * contributors may be used to endorse or promote products derived -- * from this software without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -- * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- */ -- --#include <acl/libacl.h> --#include <nfsidmap.h> --#include "libacl_nfs4.h" -- --#define PATH_IDMAPDCONF "/etc/idmapd.conf" --char *conf_path = PATH_IDMAPDCONF; -- --int acl_n4tp_set_who(acl_entry_t ace, char* who, acl_tag_t who_type) --{ -- int result; -- uid_t uid; -- gid_t gid; -- -- if(ace == NULL || who == NULL) { -- errno = EINVAL; -- goto failed; -- } -- -- switch(who_type) { -- case ACL_USER: -- result = nfs4_init_name_mapping(NULL); -- if (result < 0) -- goto failed; -- result = nfs4_name_to_uid(who, &uid); -- if(result < 0) -- goto failed; -- result = acl_set_qualifier(ace, (void *) &uid); -- if(result < 0) -- goto failed; -- break; -- case ACL_GROUP: -- result = nfs4_init_name_mapping(NULL); -- if (result < 0) -- goto failed; -- result = nfs4_name_to_gid(who, &gid); -- if(result < 0) -- goto failed; -- result = acl_set_qualifier(ace, (void *) &gid); -- if(result < 0) -- goto failed; -- break; -- default: -- errno = EINVAL; -- goto failed; -- } -- -- return 0; -- --failed: -- return -1; --} -- -- -diff --git a/libacl/acl_nfs4_copy_acl.c b/libacl/acl_nfs4_copy_acl.c -index 94d8a83..4ce63f7 100644 ---- a/libacl/acl_nfs4_copy_acl.c -+++ b/libacl/acl_nfs4_copy_acl.c -@@ -54,7 +54,7 @@ struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl) - if(new_acl == NULL) - goto failed; - -- ace = acl_nfs4_get_first_ace(nacl); -+ ace = nacl->ace_head.tqh_first; - nace = 1; - - while(1) -@@ -71,7 +71,7 @@ struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl) - if(result < 0) - goto free_failed; - -- acl_nfs4_get_next_ace(&ace); -+ ace = ace->l_ace.tqe_next; - nace++; - } - -diff --git a/libacl/acl_nfs4_utils.c b/libacl/acl_nfs4_utils.c -deleted file mode 100644 -index 49238ee..0000000 ---- a/libacl/acl_nfs4_utils.c -+++ /dev/null -@@ -1,566 +0,0 @@ --#include <acl/libacl.h> --#include "libacl_nfs4.h" -- --int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace, -- acl_t *pacl, int iflags) --{ -- struct nfs4_ace *ace = *n4ace; -- struct nfs4_ace *ace2; -- -- if (ace == NULL) -- goto inval_out; -- -- if (pacl == NULL || *pacl == NULL) -- goto inval_out; -- -- if (acl_n4tp_get_whotype(ace) != ACL_USER_OBJ) -- goto inval_out; -- -- if(acl_n4tp_ace_trans(ace, pacl, ACL_USER_OBJ, iflags|NFS4_ACL_OWNER) < 0) -- goto out; -- -- ace2 = acl_nfs4_get_next_ace(n4ace); -- if (ace2 == NULL) -- goto inval_out; -- -- if (!complementary_ace_pair(ace, ace2)) -- goto inval_out; -- -- ace2 = acl_nfs4_get_next_ace(n4ace); -- -- return 0; -- --inval_out: -- errno = EINVAL; --out: -- return -1; --} -- --/* public */ --inline struct nfs4_ace * acl_nfs4_get_next_ace(struct nfs4_ace ** ace) --{ -- if(ace == NULL || (*ace) == NULL) -- return NULL; -- -- (*ace) = (*ace)->l_ace.tqe_next; -- return *ace; --} -- --/* public */ --inline struct nfs4_ace * acl_nfs4_get_first_ace(struct nfs4_acl * acl) --{ -- if(acl == NULL) -- return NULL; -- -- return acl->ace_head.tqh_first; --} -- -- -- -- --int nfs4_get_gid_from_who(gid_t* gid, const char * who) --{ -- int islocal; -- int result; -- -- if(who == NULL || gid == NULL) { -- errno = EINVAL; -- goto failed; -- } -- -- islocal = is_who_local(who); -- if(islocal < 0) -- goto failed; -- else if (islocal == 1) -- result = __nfs4_get_local_gid_from_who(gid, who); -- else -- result = __nfs4_get_foreign_gid_from_who(gid, who); -- -- if(result < 0) -- goto failed; -- -- return 0; -- --failed: -- return -1; --} -- --int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who) --{ -- /* XXX Just trim things at the @. We need to pull the local domain -- * name from the conf file for comparison, and handle foriegn names -- * as well. Tie this in with idmapd and gssvcd */ -- /* Special whos? */ -- -- struct group * grent; -- char * gname_buf = NULL; -- int gname_buflen; -- char * char_pos = NULL; -- int char_posi; -- -- -- if(who == NULL) { -- errno = EINVAL; -- goto failed; -- } -- -- gname_buflen = strlen(who); -- if(gname_buflen <= 0) { -- errno = EINVAL; -- goto failed; -- } -- -- char_pos = strchr(who, '@'); -- char_posi = char_pos - who; -- -- if((gname_buf = (char*) malloc(sizeof(char) * (char_posi + 1))) == NULL) -- { -- errno = ENOMEM; -- goto failed; -- } -- -- strncpy(gname_buf, who, char_posi); -- gname_buf[char_posi] = '\0'; -- -- grent = getgrnam(gname_buf); -- free(gname_buf); -- -- if(grent == NULL) -- goto failed; -- -- *gid = grent->gr_gid; -- -- return 0; -- --failed: -- return -1; --} -- --int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who) --{ -- return -1; --} -- -- --int nfs4_get_uid_from_who(uid_t* uid, const char * who) --{ -- int islocal; -- int result; -- -- if(who == NULL || uid == NULL) { -- errno = EINVAL; -- goto failed; -- } -- -- islocal = is_who_local(who); -- if(islocal < 0) -- goto failed; -- else if (islocal == 1) -- result = __nfs4_get_local_uid_from_who(uid, who); -- else -- result = __nfs4_get_foreign_uid_from_who(uid, who); -- -- if(result < 0) -- goto failed; -- -- return 0; -- --failed: -- return -1; --} -- --int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who) --{ -- /* XXX Just trim things at the @. We need to pull the local domain -- * name from the conf file for comparison, and handle foriegn names -- * as well. Tie this in with idmapd and gssvcd */ -- /* Special whos? */ -- -- char* lname_buf; -- char* char_pos; -- int lname_buflen; -- struct passwd *pwent; -- int char_posi; -- -- if(who == NULL) { -- errno = EINVAL; -- goto failed; -- } -- -- lname_buflen = strlen(who); -- if(lname_buflen <= 0) { -- errno = EINVAL; -- goto failed; -- } -- -- char_pos = strchr(who, '@'); -- char_posi = char_pos - who; -- -- if((lname_buf = (char*) malloc(sizeof(char) * (char_posi + 1))) == NULL) -- { -- errno = ENOMEM; -- goto failed; -- } -- -- strncpy(lname_buf, who, char_posi); -- lname_buf[char_posi] = '\0'; -- -- pwent = getpwnam(lname_buf); -- free(lname_buf); -- -- if(pwent == NULL) -- goto failed; -- -- *uid = pwent->pw_uid; -- -- return 0; -- --failed: -- return -1; --} -- -- -- --int is_who_local(const char * who) --{ -- /* -1 on error, 0 for no, 1 for yes */ -- /* TODO: Compare domain to local domain */ -- if(who == NULL){ -- errno = EINVAL; -- return -1; -- } -- -- if(strchr(who, '@') == NULL) { -- errno = EINVAL; -- return -1; -- } -- -- return 1; --} -- --int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who) --{ -- /* TODO: Make this work */ -- return -1; --} -- -- -- --int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p, -- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags) --{ -- struct nfs4_ace *ace, *ace2; -- int result; -- -- ace = *n4ace_p; -- -- if (ace == NULL) { -- goto inval_failed; -- } -- -- while (ace != NULL && acl_n4tp_get_whotype(ace) == ACL_USER) { -- if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) -- goto inval_failed; -- if (*mask_ace && -- !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask)) -- goto inval_failed; -- *mask_ace = ace; -- -- ace = acl_nfs4_get_next_ace(n4ace_p); -- if (ace == NULL) -- goto inval_failed; -- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) -- goto inval_failed; -- result = acl_n4tp_ace_trans(ace, pacl, ACL_USER, iflags); -- if (result < 0) -- goto failed; -- -- ace2 = acl_nfs4_get_next_ace(n4ace_p); -- if (ace2 == NULL) -- goto failed; -- if (!complementary_ace_pair(ace, ace2)) -- goto failed; -- if ((*mask_ace)->flag != ace2->flag || -- !same_who(*mask_ace, ace2)) -- goto failed; -- ace = acl_nfs4_get_next_ace(n4ace_p); -- } -- -- return 0; -- --inval_failed: -- errno = EINVAL; -- --failed: -- return -1; --} -- --int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny) --{ -- return MASK_EQUAL(allow->access_mask, ~deny->access_mask) && -- allow->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && -- deny->type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE && -- allow->flag == deny->flag && -- same_who(allow, deny); --} -- --int same_who(struct nfs4_ace *a, struct nfs4_ace *b) --{ -- if(!strcmp(a->who, b->who) && strlen(a->who) == strlen(b->who)) -- return 1; -- return 0; --} -- --int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl, -- struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace, -- acl_t *pacl, int iflags) --{ -- struct nfs4_ace *ace, *ace2; -- int num_aces; -- struct ace_container_list_head ace_list; -- struct ace_container *ace_c = NULL; -- int result; -- -- TAILQ_INIT(&ace_list); -- -- ace = *n4ace_p; -- -- num_aces = acl_n4tp_ace_count(n4acl); -- -- if(num_aces < 0) -- goto inval_failed; -- -- /* group owner (mask and allow aces) */ -- -- if (num_aces != 3) { -- /* then the group owner should be preceded by mask */ -- if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) -- goto inval_failed; -- -- /* If we already got a mask, and it doesn't match this one... */ -- if (*mask_ace && -- !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask)) -- goto inval_failed; -- *mask_ace = ace; -- ace = acl_nfs4_get_next_ace(n4ace_p); -- if (ace == NULL) -- goto inval_failed; -- -- if ((*mask_ace)->flag != ace->flag || !same_who(*mask_ace, ace)) -- goto inval_failed; -- } -- -- if (acl_n4tp_get_whotype(ace) != ACL_GROUP_OBJ) -- goto inval_failed; -- -- if((ace_c = malloc(sizeof(struct ace_container))) == NULL) { -- errno = ENOMEM; -- goto failed; -- } -- ace_c->ace = ace; -- -- TAILQ_INSERT_TAIL(&ace_list, ace_c, l_ace); -- -- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) -- goto inval_failed; -- -- result = acl_n4tp_ace_trans(ace, pacl, ACL_GROUP_OBJ, iflags); -- if (result < 0) -- goto inval_failed; -- -- ace = acl_nfs4_get_next_ace(n4ace_p); -- if (ace == NULL) -- goto inval_failed; -- -- /* groups (mask and allow aces) */ -- -- while (acl_n4tp_get_whotype(ace) == ACL_GROUP) { -- if (*mask_ace == NULL) -- goto inval_failed; -- -- if (ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE || -- !MASK_EQUAL(ace->access_mask, (*mask_ace)->access_mask)) -- goto inval_failed; -- *mask_ace = ace; -- -- ace = acl_nfs4_get_next_ace(n4ace_p); -- if (ace == NULL) -- goto inval_failed; -- -- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE || -- !same_who(ace, *mask_ace)) -- goto inval_failed; -- -- if((ace_c = malloc(sizeof(struct ace_container))) == NULL) { -- errno = ENOMEM; -- goto failed; -- } -- ace_c->ace = ace; -- -- TAILQ_INSERT_TAIL(&ace_list, ace_c, l_ace); -- -- result = acl_n4tp_ace_trans(ace, pacl, ACL_GROUP, iflags); -- if (result < 0) -- goto inval_failed; -- -- ace = acl_nfs4_get_next_ace(n4ace_p); -- if (ace == NULL) -- goto inval_failed; -- } -- -- /* group owner (deny ace) */ -- -- if (acl_n4tp_get_whotype(ace) != ACL_GROUP_OBJ) -- goto inval_failed; -- -- ace_c = ace_list.tqh_first; -- ace2 = ace_c->ace; -- if (!complementary_ace_pair(ace2, ace)) -- goto inval_failed; -- TAILQ_REMOVE(&ace_list, ace_c, l_ace); -- free(ace_c); -- -- /* groups (deny aces) */ -- -- while (!TAILQ_IS_EMPTY(ace_list)) { -- ace = acl_nfs4_get_next_ace(n4ace_p); -- if (ace == NULL) -- goto inval_failed; -- if (acl_n4tp_get_whotype(ace) != ACL_GROUP) -- goto inval_failed; -- ace_c = ace_list.tqh_first; -- ace2 = ace_c->ace; -- if (!complementary_ace_pair(ace2, ace)) -- goto inval_failed; -- TAILQ_REMOVE(&ace_list, ace_c, l_ace); -- free(ace_c); -- } -- -- ace = acl_nfs4_get_next_ace(n4ace_p); -- if (ace == NULL) -- goto inval_failed; -- if (acl_n4tp_get_whotype(ace) != ACL_OTHER) -- goto inval_failed; -- -- return 0; -- --inval_failed: -- errno = EINVAL; -- --failed: -- while (!TAILQ_IS_EMPTY(ace_list)) { -- ace_c = ace_list.tqh_first; -- TAILQ_REMOVE(&ace_list, ace_c, l_ace); -- free(ace_c); -- } -- return -1; --} -- --int --other_from_v4(struct nfs4_acl *n4acl, -- struct nfs4_ace ** n4ace_p, acl_t *pacl, int iflags) --{ -- int result; -- struct nfs4_ace *ace, *ace2; -- -- ace = *n4ace_p; -- if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) -- goto inval_failed; -- -- result = acl_n4tp_ace_trans(ace, pacl, ACL_OTHER, iflags); -- if (result < 0) -- goto failed; -- -- ace2 = acl_nfs4_get_next_ace(n4ace_p); -- if (ace2 == NULL) -- goto inval_failed; -- -- if (!complementary_ace_pair(ace, ace2)) -- goto inval_failed; -- -- return 0; -- --inval_failed: -- errno = EINVAL; -- --failed: -- return -1; --} -- --int mask_from_v4(struct nfs4_acl *n4acl, -- struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace, -- acl_t *pacl, int iflags) --{ -- int result; -- struct nfs4_ace *ace; -- -- ace = *n4ace_p; -- if (acl_n4tp_ace_count(n4acl) != 3) { -- if (*mask_ace == NULL) -- goto inval_failed; -- (*mask_ace)->access_mask = ~(*mask_ace)->access_mask; -- -- result = acl_n4tp_ace_trans(*mask_ace, pacl, ACL_MASK, iflags); -- if(result < 0) -- goto failed; -- -- //ace = acl_nfs4_get_next_ace(n4ace_p); -- //if (ace == NULL) -- // goto inval_failed; -- } -- -- return 0; -- --inval_failed: -- errno = EINVAL; -- --failed: -- return -1; --} -- -- --/* --static inline int --match_who(struct nfs4_ace *ace, uid_t owner, gid_t group, uid_t who) --{ -- switch (ace->whotype) { -- case NFS4_ACL_WHO_NAMED: -- return who == ace->who; -- case NFS4_ACL_WHO_OWNER: -- return who == owner; -- case NFS4_ACL_WHO_GROUP: -- return who == group; -- case NFS4_ACL_WHO_EVERYONE: -- return 1; -- default: -- return 0; -- } --} --*/ --/* 0 = granted, -EACCES = denied; mask is an nfsv4 mask, not mode bits */ --/* --int --nfs4_acl_permission(struct nfs4_acl *acl, uid_t owner, gid_t group, -- uid_t who, u32 mask) --{ -- struct nfs4_ace *ace; -- u32 allowed = 0; -- -- list_for_each_entry(ace, &acl->ace_head, l_ace) { -- if (!match_who(ace, group, owner, who)) -- continue; -- switch (ace->type) { -- case NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE: -- allowed |= ace->access_mask; -- if ((allowed & mask) == mask) -- return 0; -- break; -- case NFS4_ACE_ACCESS_DENIED_ACE_TYPE: -- if (ace->access_mask & mask) -- return -EACCES; -- break; -- } -- } -- return -EACCES; --} --*/ -diff --git a/libacl/acl_nfs4_xattr_pack.c b/libacl/acl_nfs4_xattr_pack.c -index be92ba4..6274f48 100644 ---- a/libacl/acl_nfs4_xattr_pack.c -+++ b/libacl/acl_nfs4_xattr_pack.c -@@ -75,7 +75,7 @@ int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp) - rbuflen = sizeof(u32); - p += sizeof(u32); - -- ace = acl_nfs4_get_first_ace(acl); -+ ace = acl->ace_head.tqh_first; - ace_num = 1; - - while(1) -@@ -126,7 +126,7 @@ int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp) - rbuflen += NFS4_XDR_MOD; - } - -- acl_nfs4_get_next_ace(&ace); -+ ace = ace->l_ace.tqe_next; - ace_num++; - } - -diff --git a/libacl/acl_nfs4_xattr_size.c b/libacl/acl_nfs4_xattr_size.c -index 3719535..a20b5d6 100644 ---- a/libacl/acl_nfs4_xattr_size.c -+++ b/libacl/acl_nfs4_xattr_size.c -@@ -51,7 +51,7 @@ int acl_nfs4_xattr_size(struct nfs4_acl * acl) - /* Space for number of aces */ - size += sizeof(u32); - -- ace = acl_nfs4_get_first_ace(acl); -+ ace = acl->ace_head.tqh_first; - ace_num = 1; - - num_aces = acl->naces; -@@ -79,7 +79,7 @@ int acl_nfs4_xattr_size(struct nfs4_acl * acl) - size += NFS4_XDR_MOD; - } - -- acl_nfs4_get_next_ace(&ace); -+ ace = ace->l_ace.tqe_next; - ace_num++; - } - -diff --git a/libacl/libacl_nfs4.h b/libacl/libacl_nfs4.h -index e6a466c..1402f92 100644 ---- a/libacl/libacl_nfs4.h -+++ b/libacl/libacl_nfs4.h -@@ -82,14 +82,6 @@ extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace) - - /* nfs4 -> posix */ - extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t); --extern int acl_n4tp_set_mode(acl_entry_t pace, u32 nfs4_access_mask, -- int iflags); --extern int acl_n4tp_ace_count(struct nfs4_acl *n4acl); --extern int acl_n4tp_ace_trans(struct nfs4_ace *ace, acl_t *pacl, -- acl_tag_t tag, int iflags); --extern int acl_n4tp_set_who(acl_entry_t ace, char* who, -- acl_tag_t who_type); --extern acl_tag_t acl_n4tp_get_whotype(struct nfs4_ace *ace); - - /* posix -> nfs4 */ - extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, -@@ -98,37 +90,13 @@ extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*); - - - /** Access Functions **/ --extern inline struct nfs4_ace * -- acl_nfs4_get_next_ace(struct nfs4_ace **); --extern inline struct nfs4_ace * -- acl_nfs4_get_first_ace(struct nfs4_acl *); - extern inline int acl_nfs4_get_whotype(char*); - extern int acl_nfs4_get_who(struct nfs4_ace*, int*, char**); - - /**** Private(?) functions ****/ - acl_t __posix_acl_from_nfs4_xattr(char*, int, acl_type_t, u32); --int complementary_ace_pair(struct nfs4_ace *allow, struct nfs4_ace *deny); --int same_who(struct nfs4_ace *a, struct nfs4_ace *b); - - /* These will change */ --int nfs4_get_gid_from_who(gid_t* gid, const char * who); --int nfs4_get_uid_from_who(uid_t* uid, const char * who); - char * nfs4_get_who_from_uid(uid_t); - char * nfs4_get_who_from_gid(gid_t); --int __nfs4_get_local_uid_from_who(uid_t* uid, const char * who); --int __nfs4_get_foreign_uid_from_who(uid_t* uid, const char * who); --int __nfs4_get_local_gid_from_who(gid_t* gid, const char * who); --int __nfs4_get_foreign_gid_from_who(gid_t* gid, const char * who); --int is_who_local(const char * who); - /* End change */ -- --int user_obj_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace **n4ace, -- acl_t *pacl, int iflags); --int users_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p, -- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags); --int group_obj_and_groups_from_v4(struct nfs4_acl *n4acl, -- struct nfs4_ace ** n4ace_p, struct nfs4_ace **mask_ace, acl_t *pacl, int iflags); --int mask_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p, -- struct nfs4_ace **mask_ace, acl_t *pacl, int iflags); --int other_from_v4(struct nfs4_acl *n4acl, struct nfs4_ace ** n4ace_p, -- acl_t *pacl, int iflags); --- -1.7.8.1 - |