diff --git a/.gitignore b/.gitignore index 08b9615..d39a8c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -/acl-2.[23].*.tar.gz -/acl-2.[23].*.tar.gz.sig +acl-2.2.49.src.tar.gz diff --git a/0001-acl-2.2.53-test-runwrapper.patch b/0001-acl-2.2.53-test-runwrapper.patch deleted file mode 100644 index 7c27c6c..0000000 --- a/0001-acl-2.2.53-test-runwrapper.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 085cc4ff56857d234e80f37d0316c13eb5718696 Mon Sep 17 00:00:00 2001 -From: Kamil Dudka -Date: Tue, 3 Jul 2018 10:46:58 +0200 -Subject: [PATCH] test/runwrapper: copy the preloaded library - -... to a temporary directory because the original location might -not be accessible by other users. ---- - test/runwrapper | 20 ++++++++++++++++++-- - 1 file changed, 18 insertions(+), 2 deletions(-) - -diff --git a/test/runwrapper b/test/runwrapper -index 6e0e899..de4555a 100755 ---- a/test/runwrapper -+++ b/test/runwrapper -@@ -1,7 +1,23 @@ - #!/bin/bash - --if [ -e "$PWD/.libs/libtestlookup.so" ]; then -- export LD_PRELOAD="$PWD/.libs/libtestlookup.so" -+src="$PWD/.libs/libtestlookup.so" -+dst= -+if [ -e "$src" ]; then -+ # copy the preloaded library to a temporary directory because -+ # the original location might not be accessible by other users -+ tmp="$(mktemp -d)" -+ chmod 0755 "$tmp" -+ dst="${tmp}/libtestlookup.so" -+ cp -L "$src" "$dst" -+ export LD_PRELOAD="$dst" - fi - - "${srcdir:-${PWD}}"/test/run "$@" -+ec="$?" -+ -+if [ -n "$dst" ]; then -+ # remove the temporary location -+ rm -rf "$dst" -+fi -+ -+exit "$ec" --- -2.14.4 - diff --git a/acl-2.2.39-build.patch b/acl-2.2.39-build.patch new file mode 100644 index 0000000..fbe608a --- /dev/null +++ b/acl-2.2.39-build.patch @@ -0,0 +1,40 @@ +diff --git a/include/builddefs.in b/include/builddefs.in +index d054a56..10b0cd4 100644 +--- a/include/builddefs.in ++++ b/include/builddefs.in +@@ -28,14 +28,14 @@ PKG_RELEASE = @pkg_release@ + PKG_VERSION = @pkg_version@ + PKG_PLATFORM = @pkg_platform@ + PKG_DISTRIBUTION= @pkg_distribution@ +-PKG_BIN_DIR = @bindir@ +-PKG_SBIN_DIR = @sbindir@ +-PKG_LIB_DIR = @libdir@@libdirsuffix@ +-PKG_DEVLIB_DIR = @libexecdir@@libdirsuffix@ +-PKG_INC_DIR = @includedir@ +-PKG_MAN_DIR = @mandir@ +-PKG_DOC_DIR = @datadir@/doc/@pkg_name@ +-PKG_LOCALE_DIR = @datadir@/locale ++PKG_BIN_DIR = $(DESTDIR)@bindir@ ++PKG_SBIN_DIR = $(DESTDIR)@sbindir@ ++PKG_LIB_DIR = $(DESTDIR)@libdir@@libdirsuffix@ ++PKG_DEVLIB_DIR = $(DESTDIR)@libexecdir@@libdirsuffix@ ++PKG_INC_DIR = $(DESTDIR)@includedir@ ++PKG_MAN_DIR = $(DESTDIR)@mandir@ ++PKG_DOC_DIR = $(DESTDIR)@datadir@/doc/@pkg_name@-@pkg_version@ ++PKG_LOCALE_DIR = $(DESTDIR)@datadir@/locale + + CC = @cc@ + AWK = @awk@ +diff --git a/include/buildmacros b/include/buildmacros +index 17423c0..3118a17 100644 +--- a/include/buildmacros ++++ b/include/buildmacros +@@ -40,7 +40,7 @@ OBJECTS = $(ASFILES:.s=.o) \ + $(LFILES:.l=.o) \ + $(YFILES:%.y=%.tab.o) + +-INSTALL = $(TOPDIR)/include/install-sh -o $(PKG_USER) -g $(PKG_GROUP) ++INSTALL = $(TOPDIR)/include/install-sh + + SHELL = /bin/sh + IMAGES_DIR = $(TOPDIR)/all-images diff --git a/acl-2.2.39-nfsv4.patch b/acl-2.2.39-nfsv4.patch new file mode 100644 index 0000000..ee7ae04 --- /dev/null +++ b/acl-2.2.39-nfsv4.patch @@ -0,0 +1,3280 @@ +NOTE: This patch is not being used any more since 2.2.39-8. + +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_get_who.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,103 @@ ++/* ++ * NFSv4 ACL Code ++ * Read the who value from the ace and return its type and optionally ++ * its value. ++ * ++ * Ace is a reference to the ace to extract the who value from. ++ * Type is a reference where the value of the whotype will be stored. ++ * Who is a double reference that should either be passed as NULL ++ * (and thus no who string will be returned) or as a pointer to a ++ * char* where the who string will be allocated. This string must be ++ * freed by the caller. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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_nfs4_get_who(struct nfs4_ace* ace, int* type, char** who) ++{ ++ int itype; ++ char* iwho = NULL; ++ int wholen; ++ ++ if(ace == NULL || ace->who == NULL) ++ goto inval_failed; ++ ++ itype = acl_nfs4_get_whotype(ace->who); ++ ++ if(type != NULL) { ++ *type = itype; ++ } ++ ++ ++ if(who == NULL) ++ return 0; ++ ++ switch(itype) ++ { ++ case NFS4_ACL_WHO_NAMED: ++ iwho = ace->who; ++ break; ++ case NFS4_ACL_WHO_OWNER: ++ iwho = NFS4_ACL_WHO_OWNER_STRING; ++ break; ++ case NFS4_ACL_WHO_GROUP: ++ iwho = NFS4_ACL_WHO_GROUP_STRING; ++ break; ++ case NFS4_ACL_WHO_EVERYONE: ++ iwho = NFS4_ACL_WHO_EVERYONE_STRING; ++ break; ++ default: ++ goto inval_failed; ++ } ++ ++ wholen = strlen(iwho); ++ if(wholen < 0) ++ goto inval_failed; ++ ++ (*who) = (char *) malloc(sizeof(char) * (wholen + 1)); ++ if((*who) == NULL) { ++ errno = ENOMEM; ++ goto failed; ++ } ++ ++ strcpy((*who), iwho); ++ ++ return 0; ++ ++inval_failed: ++ errno = EINVAL; ++ ++failed: ++ return -1; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_add_ace.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,83 @@ ++/* ++ * NFSv4 ACL Code ++ * Add an ace to the acl ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen ++ * J. Bruce Fields ++ * Nathaniel Gallaher ++ * Jeff Sedlak ++ * ++ * 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_nfs4_add_ace(struct nfs4_acl *acl, u32 type, u32 flag, u32 access_mask, ++ int whotype, char* who) ++{ ++ struct nfs4_ace *ace; ++ int result; ++ ++ if(acl == NULL) ++ { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if ((ace = malloc(sizeof(*ace))) == NULL) ++ { ++ errno = ENOMEM; ++ return -1; ++ } ++ ++ ace->type = type; ++ ace->flag = flag; ++ ++ if( type == NFS4_ACE_ACCESS_DENIED_ACE_TYPE ) ++ access_mask = access_mask & ~(NFS4_ACE_MASK_IGNORE); ++ ++ ++ /* Castrate delete_child if we aren't a directory */ ++ if (!acl->is_directory) ++ access_mask &= ~NFS4_ACE_DELETE_CHILD; ++ ++ ++ ace->access_mask = access_mask & NFS4_ACE_MASK_ALL; ++ ++ result = acl_nfs4_set_who(ace, whotype, who); ++ if(result < 0) ++ return -1; ++ ++ TAILQ_INSERT_TAIL(&acl->ace_head, ace, l_ace); ++ acl->naces++; ++ ++ return 0; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_get_whotype.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,60 @@ ++/* ++ * NFSv4 ACL Code ++ * Get the whotype of the who string passed ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen ++ * J. Bruce Fields ++ * Nathaniel Gallaher ++ * Jeff Sedlak ++ * ++ * 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" ++ ++inline int ++acl_nfs4_get_whotype(char *p) ++{ ++ if(0 == strcmp(p, NFS4_ACL_WHO_OWNER_STRING) && ++ strlen(p) == strlen(NFS4_ACL_WHO_OWNER_STRING)) { ++ return NFS4_ACL_WHO_OWNER; ++ } ++ if(0 == strcmp(p, NFS4_ACL_WHO_GROUP_STRING) && ++ strlen(p) == strlen(NFS4_ACL_WHO_GROUP_STRING)) { ++ return NFS4_ACL_WHO_GROUP; ++ } ++ if(0 == strcmp(p, NFS4_ACL_WHO_EVERYONE_STRING) && ++ strlen(p) == strlen(NFS4_ACL_WHO_EVERYONE_STRING)) { ++ return NFS4_ACL_WHO_EVERYONE; ++ } ++ ++ return NFS4_ACL_WHO_NAMED; ++} ++ ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_free.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,61 @@ ++/* ++ * Copyright (c) 2004 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen ++ * J. Bruce Fields ++ * Nathaniel Gallaher ++ * Jeff Sedlak ++ * ++ * 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, the following disclaimer, and ++ * any and all other licensing or copyright notices included in ++ * any files in this distribution. ++ * 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" ++ ++void ++acl_nfs4_free(struct nfs4_acl *acl) ++{ ++ struct nfs4_ace *ace; ++ ++ if (!acl) ++ return; ++ ++ while (!TAILQ_IS_EMPTY(acl->ace_head)) { ++ ace = (acl)->ace_head.tqh_first; ++ ++ TAILQ_REMOVE( &(acl->ace_head), ace, l_ace); ++ free(ace->who); ++ free(ace); ++ } ++ ++ free(acl); ++ ++ return; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_n4tp_acl_trans.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,439 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert NFSv4 ACL to a POSIX ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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 ++#include ++#include "libacl_nfs4.h" ++ ++ ++/* ++ * 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 know which, so we allocate ++ * enough space for either: ++ */ ++ alloc = sizeof(struct posix_ace_state_array) ++ + cnt*sizeof(struct posix_user_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; ++ ++ if (state->users->n || state->groups->n) ++ nace = 4 + state->users->n + state->groups->n; ++ else ++ nace = 3; ++ 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); ++ } ++ ++ if (nace > 3) { ++ 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; ++} ++ ++#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \ ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE) ++ ++/* Strip or keep inheritance aces depending on type of posix acl requested */ ++static void acl_nfs4_check_inheritance(struct nfs4_acl *acl, u32 iflags) ++{ ++ struct nfs4_ace * cur_ace; ++ struct nfs4_ace * temp_ace; ++ ++ cur_ace = acl->ace_head.tqh_first; ++ ++ while (cur_ace) { ++ /* get the next ace now in case we free the current ace */ ++ temp_ace = cur_ace; ++ cur_ace = cur_ace->l_ace.tqe_next; ++ ++ if (iflags & NFS4_ACL_REQUEST_DEFAULT) { ++ if (!(temp_ace->flag & FILE_OR_DIR_INHERIT)) ++ acl_nfs4_remove_ace(acl, temp_ace); ++ } else { ++ if (temp_ace->flag & NFS4_ACE_INHERIT_ONLY_ACE) ++ acl_nfs4_remove_ace(acl, temp_ace); ++ } ++ } ++} ++ ++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; ++ struct nfs4_ace * cur_ace; ++ int ret; ++ u32 iflags = NFS4_ACL_NOFLAGS; ++ ++ if (ptype == ACL_TYPE_DEFAULT) { ++ if (nacl_p->is_directory) ++ iflags |= NFS4_ACL_REQUEST_DEFAULT; ++ else { ++ errno = EINVAL; ++ return NULL; ++ } ++ } ++ ++ /* Copy so we can delete bits without borking the original */ ++ temp_acl = acl_nfs4_copy_acl(nacl_p); ++ if (temp_acl == NULL) ++ return NULL; ++ ++ acl_nfs4_check_inheritance(temp_acl, iflags); ++ ++ if (ptype == ACL_TYPE_DEFAULT && temp_acl->naces == 0) { ++ acl_nfs4_free(temp_acl); ++ return acl_init(0); ++ } ++ ++ ret = init_state(&state, temp_acl->naces); ++ if (ret) ++ goto 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; ++ } ++ ++ acl_nfs4_free(temp_acl); ++ ++ pacl = posix_state_to_acl(&state, nacl_p->is_directory); ++ ++ free_state(&state); ++ ++ ret = acl_valid(pacl); ++ if (ret < 0) ++ goto free_failed; ++ ++ return pacl; ++ ++free_failed: ++ acl_nfs4_free(temp_acl); ++ return NULL; ++} +--- acl-2.2.39/libacl/acl_set_fd.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_set_fd.c 2007-08-22 12:02:13.000000000 -0400 +@@ -24,6 +24,11 @@ + #include "libacl.h" + #include "__acl_to_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++ #include ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + +@@ -37,10 +42,42 @@ acl_set_fd(int fd, acl_t acl) + const char *name = ACL_EA_ACCESS; + size_t size; + int error; ++#ifdef USE_NFSV4_TRANS ++ int retval; ++ struct nfs4_acl * nacl; ++#endif + + if (!acl_obj_p) + return -1; ++ ++#ifdef USE_NFSV4_TRANS ++ retval = fgetxattr(fd, ACL_NFS4_XATTR, NULL, 0); ++ ++ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) { ++ ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++ } else { ++ char domain[NFS4_MAX_DOMAIN_LEN]; ++ nfs4_init_name_mapping(NULL); ++ error = nfs4_get_default_domain(NULL, domain, sizeof(domain)); ++ if (error) ++ return -1; ++ nacl = acl_nfs4_new(0); ++ if (acl == NULL) { ++ errno = ENOMEM; ++ return -1; ++ } ++ error = acl_ptn4_acl_trans(acl, nacl, ACL_TYPE_ACCESS, 0, domain); ++ if (error) ++ return -1; ++ ++ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p); ++ name = ACL_NFS4_XATTR; ++ acl_nfs4_free(nacl); ++ } ++#else + ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++#endif ++ + if (!ext_acl_p) + return -1; + error = fsetxattr(fd, name, (char *)ext_acl_p, size, 0); +--- acl-2.2.39/libacl/Makefile.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/Makefile 2007-08-22 12:02:13.000000000 -0400 +@@ -8,19 +8,35 @@ LTLDFLAGS += -Wl,--version-script,$(TOPD + include $(TOPDIR)/include/builddefs + + LTLIBRARY = libacl.la +-LTLIBS = -lattr $(LIBMISC) ++LTLIBS = -lattr -lnfsidmap $(LIBMISC) + LTDEPENDENCIES = $(LIBMISC) +-LT_CURRENT = 2 ++LT_CURRENT = 3 + LT_REVISION = 0 +-LT_AGE = 1 ++LT_AGE = 2 ++ ++CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(LIBACL_NFS4_CFILES) \ ++ $(INTERNAL_CFILES) perm_copy_fd.c perm_copy_file.c + +-CFILES = $(POSIX_CFILES) $(LIBACL_CFILES) $(INTERNAL_CFILES) \ +- perm_copy_fd.c perm_copy_file.c + HFILES = libobj.h libacl.h byteorder.h __acl_from_xattr.h __acl_to_xattr.h \ +- perm_copy.h ++ perm_copy.h $(LIBACL_NFS4_HFILES) + + LCFLAGS = -include perm_copy.h + ++LIBACL_NFS4_CFILES = \ ++ acl_nfs4_get_who.c \ ++ acl_n4tp_acl_trans.c acl_nfs4_get_whotype.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_free.c acl_nfs4_xattr_load.c \ ++ acl_nfs4_xattr_pack.c acl_nfs4_xattr_size.c \ ++ acl_ptn4_acl_trans.c \ ++ acl_ptn4_get_mask.c __posix_acl_from_nfs4_xattr.c \ ++ ++ ++LIBACL_NFS4_HFILES = ../include/libacl_nfs4.h ../include/nfs4.h ++ + POSIX_CFILES = \ + acl_add_perm.c acl_calc_mask.c acl_clear_perms.c acl_copy_entry.c \ + acl_copy_ext.c acl_copy_int.c acl_create_entry.c acl_delete_def_file.c \ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_remove_ace.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,48 @@ ++/* ++ * NFSv4 ACL Code ++ * Remove an ace from an NFS4 ACL ++ * ++ * Copyright (c) 2004 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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, the following disclaimer, and ++ * any and all other licensing or copyright notices included in ++ * any files in this distribution. ++ * 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" ++ ++void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace) ++{ ++ TAILQ_REMOVE(&acl->ace_head, ace, l_ace); ++ free(ace->who); ++ free(ace); ++ acl->naces--; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_set_who.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,92 @@ ++/* ++ * NFSv4 ACL Code ++ * Write the who entry in the nfs4 ace. Who is a user supplied buffer ++ * containing a named who entry (null terminated string) if type is ++ * set to NFS4_ACL_WHO_NAMED. Otherwise, the who buffer is not used. ++ * The user supplied who buffer must be freed by the caller. ++ * ++ * This code allocates the who buffer used in the ace. This must be freed ++ * upon ace removal by the ace_remove or acl_free. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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_nfs4_set_who(struct nfs4_ace* ace, int type, char* who) ++{ ++ char* iwho = NULL; ++ int wholen; ++ ++ if(ace == NULL) ++ goto inval_failed; ++ ++ switch(type) ++ { ++ case NFS4_ACL_WHO_NAMED: ++ if(who == NULL) ++ goto inval_failed; ++ iwho = who; ++ break; ++ case NFS4_ACL_WHO_OWNER: ++ iwho = NFS4_ACL_WHO_OWNER_STRING; ++ break; ++ case NFS4_ACL_WHO_GROUP: ++ iwho = NFS4_ACL_WHO_GROUP_STRING; ++ break; ++ case NFS4_ACL_WHO_EVERYONE: ++ iwho = NFS4_ACL_WHO_EVERYONE_STRING; ++ break; ++ default: ++ goto inval_failed; ++ } ++ ++ wholen = strlen(iwho); ++ if(wholen < 1) ++ goto inval_failed; ++ ++ ace->who = (char *) malloc(sizeof(char) * (wholen + 1)); ++ if(ace->who == NULL) { ++ errno = ENOMEM; ++ goto failed; ++ } ++ ++ strcpy(ace->who, iwho); ++ ++ return 0; ++ ++inval_failed: ++ errno = EINVAL; ++ ++failed: ++ return -1; ++} ++ +--- acl-2.2.39/libacl/acl_set_file.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_set_file.c 2007-08-22 12:02:13.000000000 -0400 +@@ -26,9 +26,38 @@ + #include "libacl.h" + #include "__acl_to_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++ #include ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + ++#ifdef USE_NFSV4_TRANS ++static struct nfs4_acl *get_nfs4_acl(const char *path_p, int is_dir) ++{ ++ struct nfs4_acl * acl = NULL; ++ ssize_t ret; ++ char *buf; ++ ++ ret = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0); ++ if (ret < 0) ++ return NULL; ++ buf = malloc(ret); ++ if (buf == NULL) ++ return NULL; ++ ret = getxattr(path_p, ACL_NFS4_XATTR, buf, ret); ++ if (ret < 0) ++ goto out_free; ++ acl = acl_nfs4_xattr_load(buf, ret, is_dir); ++ ++out_free: ++ free(buf); ++ return acl; ++} ++ ++#endif + + /* 23.4.22 */ + int +@@ -39,9 +68,15 @@ acl_set_file(const char *path_p, acl_typ + const char *name; + size_t size; + int error; ++ struct stat st; ++#ifdef USE_NFSV4_TRANS ++ struct nfs4_acl * nacl; ++ int is_dir = NFS4_ACL_ISFILE; ++#endif + + if (!acl_obj_p) + return -1; ++ + switch (type) { + case ACL_TYPE_ACCESS: + name = ACL_EA_ACCESS; +@@ -54,8 +89,41 @@ acl_set_file(const char *path_p, acl_typ + return -1; + } + ++ ++#ifdef USE_NFSV4_TRANS ++ if (stat(path_p, &st) != 0) ++ return -1; ++ if (S_ISDIR(st.st_mode)) ++ is_dir = NFS4_ACL_ISDIR; ++ if (type == ACL_TYPE_DEFAULT && !is_dir) { ++ errno = EACCES; ++ return -1; ++ } ++ nacl = get_nfs4_acl(path_p, is_dir); ++ if (nacl == NULL && (errno == ENOATTR || errno == EOPNOTSUPP)) ++ ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++ else { ++ char domain[NFS4_MAX_DOMAIN_LEN]; ++ ++ nfs4_init_name_mapping(NULL); ++ error = nfs4_get_default_domain(NULL, domain, sizeof(domain)); ++ if (error) { ++ acl_nfs4_free(nacl); ++ return -1; ++ } ++ error = acl_ptn4_acl_trans(acl, nacl, type, is_dir, domain); ++ if (error) { ++ acl_nfs4_free(nacl); ++ return -1; ++ } ++ ++ size = acl_nfs4_xattr_pack(nacl, &ext_acl_p); ++ name = ACL_NFS4_XATTR; ++ acl_nfs4_free(nacl); ++ } ++#else ++ + if (type == ACL_TYPE_DEFAULT) { +- struct stat st; + + if (stat(path_p, &st) != 0) + return -1; +@@ -68,6 +136,8 @@ acl_set_file(const char *path_p, acl_typ + } + + ext_acl_p = __acl_to_xattr(acl_obj_p, &size); ++#endif ++ + if (!ext_acl_p) + return -1; + error = setxattr(path_p, name, (char *)ext_acl_p, size, 0); +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/__posix_acl_from_nfs4_xattr.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,60 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert NFSv4 xattr values to a posix ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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 ++#include "libacl_nfs4.h" ++ ++/* xattr_v is a char buffer filled with the nfsv4 xattr value. ++ * xattr_size should be the byte count of the length of the xattr_v ++ * data size. xattr_v may be larger than bytes, but only ++ * the first bytes will be read. is the posix acl ++ * type requested. Currently either default, or access */ ++ ++acl_t __posix_acl_from_nfs4_xattr(char* xattr_v, ++ int xattr_size, acl_type_t ptype, u32 is_dir) ++{ ++ struct nfs4_acl * nfsacl = NULL; ++ acl_t pacl; ++ ++ nfsacl = acl_nfs4_xattr_load(xattr_v, xattr_size, is_dir); ++ if(nfsacl == NULL) { ++ return NULL; ++ } ++ ++ pacl = acl_n4tp_acl_trans(nfsacl, ptype); ++ ++ return pacl; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_xattr_load.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,191 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert NFSv4 xattr values to a posix ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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 ++#include ++#include "libacl_nfs4.h" ++ ++ ++struct nfs4_acl * acl_nfs4_xattr_load( ++ char * xattr_v, ++ int xattr_size, ++ u32 is_dir) ++{ ++ struct nfs4_acl * nacl_p; ++ char* bufp = xattr_v; ++ int bufs = xattr_size; ++ u32 ace_n; ++ u32 wholen; ++ char* who; ++ int d_ptr; ++ u32 num_aces; ++ ++ u32 type, flag, access_mask; ++ ++ if(xattr_size < sizeof(u32)) { ++ errno = EINVAL; ++ return NULL; ++ } ++ ++ if((nacl_p = acl_nfs4_new(is_dir)) == NULL) { ++ errno = ENOMEM; ++ return NULL; ++ } ++ ++ /* Grab the number of aces in the acl */ ++ num_aces = (u32)ntohl(*((u32*)(bufp))); ++ ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Got number of aces: %d\n", nacl_p->naces); ++#endif ++ ++ ++ d_ptr = sizeof(u32); ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ for(ace_n = 0; num_aces > ace_n ; ace_n++) ++ { ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Getting Ace #%d of %d\n", ace_n, num_aces); ++#endif ++ /* Get the acl type */ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ type = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Type: %x\n", type); ++#endif ++ ++ d_ptr = sizeof(u32); ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the acl flag */ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ flag = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Flag: %x\n", flag); ++#endif ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the access mask */ ++ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ access_mask = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Access Mask: %x\n", access_mask); ++#endif ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the who string length*/ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ wholen = (u32)ntohl(*((u32*)bufp)); ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Wholen: %d\n", wholen); ++#endif ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Get the who string */ ++ if(bufs <= 0) { ++ errno = EINVAL; ++ goto bad_xattr_val; ++ } ++ ++ who = (char *) malloc((wholen+1) * sizeof(char)); ++ if(who == NULL) ++ { ++ errno = ENOMEM; ++ goto bad_xattr_val; ++ } ++ ++ memcpy(who, bufp, wholen); ++ ++ who[wholen] = '\0'; ++ ++#ifdef LIBACL_NFS4_DEBUG ++ printf(" Who: %s\n", who); ++#endif ++ ++ d_ptr = ((wholen / sizeof(u32))*sizeof(u32)); ++ if(wholen % sizeof(u32) != 0) ++ d_ptr += sizeof(u32); ++ ++ bufp += d_ptr; ++ bufs -= d_ptr; ++ ++ /* Make sure we aren't outside our domain */ ++ if(bufs < 0) { ++ free(who); ++ goto bad_xattr_val; ++ } ++ ++ if(acl_nfs4_add_ace(nacl_p, type, flag, access_mask, acl_nfs4_get_whotype(who), who) < 0) { ++ free(who); ++ goto bad_xattr_val; ++ } ++ ++ free(who); ++ } ++ ++ return nacl_p; ++ ++bad_xattr_val: ++ /* We bailed for some reason */ ++ acl_nfs4_free(nacl_p); ++ return NULL; ++} +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_xattr_pack.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,148 @@ ++/* ++ * NFSv4 ACL Code ++ * Pack an NFS4 ACL into an XDR encoded buffer. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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 ++#include ++ ++int acl_nfs4_xattr_pack(struct nfs4_acl * acl, char** bufp) ++{ ++ struct nfs4_ace * ace; ++ int buflen; ++ int rbuflen; ++ int num_aces; ++ int ace_num; ++ int wholen; ++ int result; ++ char* p; ++ char* who; ++ ++ if(acl == NULL || bufp == NULL) ++ { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ buflen = acl_nfs4_xattr_size(acl); ++ if(buflen < 0) ++ { ++ goto failed; ++ } ++ ++ *bufp = (char*) malloc(buflen); ++ if(*bufp == NULL) { ++ errno = ENOMEM; ++ goto failed; ++ } ++ ++ p = *bufp; ++ ++ num_aces = acl->naces; ++ ++ *((u32*)p) = htonl(num_aces); ++ ++ rbuflen = sizeof(u32); ++ p += sizeof(u32); ++ ++ ace = acl->ace_head.tqh_first; ++ ace_num = 1; ++ ++ while(1) ++ { ++ if(ace == NULL) ++ { ++ if(ace_num > num_aces) { ++ break; ++ } else { ++ errno = ENODATA; ++ goto failed; ++ } ++ } ++ ++ *((u32*)p) = htonl(ace->type); ++ p += sizeof(u32); ++ rbuflen += sizeof(u32); ++ ++ *((u32*)p) = htonl(ace->flag); ++ p += sizeof(u32); ++ rbuflen += sizeof(u32); ++ ++ *((u32*)p) = htonl(ace->access_mask); ++ p += sizeof(u32); ++ rbuflen += sizeof(u32); ++ ++ result = acl_nfs4_get_who(ace, NULL, &who); ++ if(result < 0) { ++ goto free_failed; ++ } ++ ++ wholen = strlen(who); ++ *((u32*)p) = htonl(wholen); ++ rbuflen += sizeof(u32); ++ ++ p += sizeof(u32); ++ ++ memcpy(p, who, wholen); ++ free(who); ++ ++ p += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD; ++ if(wholen % NFS4_XDR_MOD) { ++ p += NFS4_XDR_MOD; ++ } ++ ++ rbuflen += (wholen / NFS4_XDR_MOD) * NFS4_XDR_MOD; ++ if(wholen % NFS4_XDR_MOD) { ++ rbuflen += NFS4_XDR_MOD; ++ } ++ ++ ace = ace->l_ace.tqe_next; ++ ace_num++; ++ } ++ ++ if (buflen != rbuflen) ++ { ++ goto free_failed; ++ } ++ return buflen; ++ ++free_failed: ++ free(*bufp); ++ *bufp = NULL; ++ ++failed: ++ return -1; ++} ++ ++ ++ +--- acl-2.2.39/libacl/acl_extended_file.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_extended_file.c 2007-08-22 12:02:13.000000000 -0400 +@@ -22,6 +22,7 @@ + #include + #include + #include "libacl.h" ++#include "libacl_nfs4.h" + + #include "byteorder.h" + #include "acl_ea.h" +@@ -33,6 +34,34 @@ acl_extended_file(const char *path_p) + int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry); + int retval; + ++ /* XXX: Ugh: what's the easiest way to do this, taking ++ * into account default acl's, and that length alone won't do this? ++ * Also I'm a little uncomfortable with the amount of #ifdef ++ * NFS4 stuff that's going on. We need a cleaner separation. */ ++#ifdef USE_NFSV4_TRANS ++ retval = getxattr(path_p, ACL_NFS4_XATTR, NULL, 0); ++ if (retval < 0 && errno != ENOATTR && errno != EOPNOTSUPP) ++ return -1; ++ if (retval >= 0) { ++ struct nfs4_acl *nfsacl; ++ char *ext_acl_p = alloca(retval); ++ if (!ext_acl_p) ++ return -1; ++ ++ retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, retval); ++ if (retval == -1) ++ return -1; ++ ++ nfsacl = acl_nfs4_xattr_load(ext_acl_p, retval, NFS4_ACL_ISFILE); ++ if (nfsacl) { ++ int count = nfsacl->naces; ++ acl_nfs4_free(nfsacl); ++ return count > 6; ++ } ++ return 0; ++ } ++#endif ++ + retval = getxattr(path_p, ACL_EA_ACCESS, NULL, 0); + if (retval < 0 && errno != ENOATTR && errno != ENODATA) + return -1; +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_ptn4_acl_trans.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,509 @@ ++/* ++ * NFSv4 ACL Code ++ * Convert a posix ACL to an NFSv4 ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * J. Bruce Fields ++ * ++ * 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 ++#include ++#include "libacl_nfs4.h" ++ ++ ++#define FILE_OR_DIR_INHERIT (NFS4_ACE_FILE_INHERIT_ACE \ ++ | NFS4_ACE_DIRECTORY_INHERIT_ACE) ++#define NFS4_INHERITANCE_FLAGS (FILE_OR_DIR_INHERIT | NFS4_ACE_INHERIT_ONLY_ACE) ++ ++/* Plan: ++ * 1: if setting default, remove all purely inherited aces, and replace ++ * all dual-use aces by purely effective aces ++ * 2: if setting effective, remove all purely effective aces, and replace ++ * all dual-use aces by purely inherited ones ++ */ ++static void purge_aces(struct nfs4_acl *nacl, acl_type_t type) ++{ ++ struct nfs4_ace *p, *next; ++ ++ for (p = nacl->ace_head.tqh_first; p != NULL; p = next) { ++ next = p->l_ace.tqe_next; ++ ++ if (!(p->flag & FILE_OR_DIR_INHERIT)) { ++ /* purely effective */ ++ if (type == ACL_TYPE_ACCESS) ++ acl_nfs4_remove_ace(nacl, p); ++ } else if (p->flag & NFS4_ACE_INHERIT_ONLY_ACE) { ++ /* purely inherited */ ++ if (type == ACL_TYPE_DEFAULT) ++ acl_nfs4_remove_ace(nacl, p); ++ } else { ++ /* both effective and inherited */ ++ if (type == ACL_TYPE_DEFAULT) { ++ /* Change to purely effective */ ++ p->flag &= ~NFS4_INHERITANCE_FLAGS; ++ } else { /* ACL_TYPE_ACCESS */ ++ /* Change to purely inherited */ ++ p->flag |= NFS4_INHERITANCE_FLAGS; ++ } ++ } ++ ++ } ++} ++ ++int ++acl_ptn4_acl_trans(acl_t pacl, struct nfs4_acl *acl, acl_type_t type, u32 is_dir, char *nfs_domain) ++{ ++ int eflag; ++ u32 mask, mask_mask = 0; ++ int num_aces; ++ int result, result2; ++ u32 iflags = NFS4_ACL_NOFLAGS; ++ int allocated = 0; ++ ++ acl_entry_t pace_p; ++ acl_tag_t ace_type; ++ acl_permset_t perms; ++ ++ char who_buf_static[NFS4_ACL_WHO_BUFFER_LEN_GUESS]; ++ char *who_buf = NULL; ++ int who_buflen; ++ int who_buflen_static = NFS4_ACL_WHO_BUFFER_LEN_GUESS; ++ uid_t * uid_p; ++ gid_t * gid_p; ++ ++ eflag = 0; ++ ++ if (type == ACL_TYPE_DEFAULT) { ++ eflag = NFS4_INHERITANCE_FLAGS; ++ iflags |= NFS4_ACL_REQUEST_DEFAULT; ++ } ++ ++ purge_aces(acl, type); ++ ++ if (is_dir & NFS4_ACL_ISDIR) ++ iflags |= NFS4_ACL_ISDIR; ++ ++ ++ if (pacl == NULL || (acl_valid(pacl) < 0 || acl_entries(pacl) == 0)) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ /* Start Conversion */ ++ ++ /* 3 aces minimum (mode bits) */ ++ num_aces = acl_entries(pacl); ++ if (num_aces < 3) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ /* Get the mask entry */ ++ ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ ++ while (result > 0 && mask_mask == 0) { ++ result = acl_get_tag_type(pace_p, &ace_type); ++ if (result < 0) ++ goto out; ++ ++ if (ace_type == ACL_MASK) { ++ result = acl_get_permset(pace_p, &perms); ++ if(result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask_mask, perms, iflags); ++ if(result < 0) ++ goto out; ++ ++ mask_mask = ~mask_mask; ++ } ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ } ++ ++ /* Get the file owner entry */ ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_tag_type(pace_p, &ace_type); ++ if (result < 0) ++ goto out; ++ ++ if (ace_type != ACL_USER_OBJ) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags | NFS4_ACL_OWNER); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_OWNER, NULL); ++ ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result < 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type == ACL_USER && result > 0) { ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ uid_p = acl_get_qualifier(pace_p); ++ ++ who_buf = who_buf_static; ++ who_buflen = who_buflen_static; ++ ++ result = nfs4_init_name_mapping(NULL); ++ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen); ++ ++ ++ while (result == -ENOBUFS) { ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ /* Increase the size by a full buflen unit */ ++ who_buflen += who_buflen_static; ++ who_buf = malloc(who_buflen); ++ ++ if (who_buf == NULL) { ++ result = -ENOMEM; ++ break; ++ } ++ ++ result = nfs4_init_name_mapping(NULL); ++ result = nfs4_uid_to_name(*uid_p, nfs_domain, who_buf, who_buflen); ++ ++ } ++ acl_free(uid_p); ++ if (result < 0) { ++ errno = -result; ++ goto out; ++ } ++ ++ if (who_buf == NULL) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ eflag, mask_mask, NFS4_ACL_WHO_NAMED, who_buf); ++ if (result < 0) { ++ if(who_buf != who_buf_static) ++ free(who_buf); ++ goto out; ++ } ++ ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_NAMED, ++ who_buf); ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ } ++ ++ /* In the case of groups, we apply allow ACEs first, then deny ACEs, ++ * since a user can be in more than one group. */ ++ ++ /* allow ACEs */ ++ ++ if (num_aces > 3) { ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ if (ace_type != ACL_GROUP_OBJ) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, ++ NFS4_ACL_WHO_GROUP, NULL); ++ ++ if (result < 0) ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, NFS4_ACL_WHO_GROUP, NULL); ++ ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type == ACL_GROUP && result > 0) { ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ gid_p = acl_get_qualifier(pace_p); ++ ++ who_buf = who_buf_static; ++ who_buflen = who_buflen_static; ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ ++ ++ while (result == -ENOBUFS) { ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ /* Increase the size by a full buflen unit */ ++ who_buflen += who_buflen_static; ++ who_buf = malloc(who_buflen); ++ ++ if (who_buf == NULL) { ++ result = -ENOMEM; ++ break; ++ } ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ } ++ ++ acl_free(gid_p); ++ ++ if (result < 0) { ++ errno = -result; ++ goto out; ++ } ++ ++ if (who_buf == NULL) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask_mask, ++ NFS4_ACL_WHO_NAMED, who_buf); ++ if (result < 0) { ++ if(who_buf != who_buf_static) ++ free(who_buf); ++ goto out; ++ } ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, mask, ++ NFS4_ACL_WHO_NAMED, who_buf); ++ ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ if (result < 0) ++ goto out; ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ } ++ ++ /* deny ACEs */ ++ ++ result = acl_get_entry(pacl, ACL_FIRST_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type != ACL_GROUP_OBJ && result > 0) { ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if(result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if(result2 < 0) ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask, NFS4_ACL_WHO_GROUP, ++ NULL); ++ ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ ++ while (ace_type == ACL_GROUP && result > 0) { ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ gid_p = acl_get_qualifier(pace_p); ++ ++ who_buf = who_buf_static; ++ who_buflen = who_buflen_static; ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ ++ ++ while (result == -ENOBUFS) { ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ ++ /* Increase the size by a full buflen unit */ ++ who_buflen += who_buflen_static; ++ who_buf = malloc(who_buflen); ++ ++ if (who_buf == NULL) { ++ result = -ENOMEM; ++ break; ++ } ++ ++ result = nfs4_gid_to_name(*gid_p, nfs_domain, who_buf, who_buflen); ++ } ++ ++ acl_free(gid_p); ++ ++ if (result < 0) { ++ errno = -result; ++ goto out; ++ } ++ ++ if (who_buf == NULL) ++ goto out; ++ ++ result = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ NFS4_ACE_IDENTIFIER_GROUP | eflag, ~mask, ++ NFS4_ACL_WHO_NAMED, who_buf); ++ if (who_buf != who_buf_static) ++ free(who_buf); ++ if (result < 0) ++ goto out; ++ ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ } ++ ++ if (ace_type == ACL_MASK) { ++ result = acl_get_entry(pacl, ACL_NEXT_ENTRY, &pace_p); ++ if (result <= 0) ++ goto out; ++ ++ result2 = acl_get_tag_type(pace_p, &ace_type); ++ if (result2 < 0) ++ goto out; ++ } ++ ++ if (ace_type != ACL_OTHER) { ++ errno = EINVAL; ++ goto out; ++ } ++ ++ result = acl_get_permset(pace_p, &perms); ++ if (result < 0) ++ goto out; ++ ++ result = acl_ptn4_get_mask(&mask, perms, iflags); ++ if (result < 0) ++ goto out; ++ ++ result = acl_nfs4_add_pair(acl, eflag, mask, NFS4_ACL_WHO_EVERYONE, NULL); ++ ++ return result; ++out: ++ if (allocated) ++ acl_nfs4_free(acl); ++ return -1; ++} +--- acl-2.2.39/libacl/acl_get_fd.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_get_fd.c 2007-08-22 12:02:13.000000000 -0400 +@@ -28,6 +28,10 @@ + #include "libacl.h" + #include "__acl_from_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + +@@ -38,31 +42,59 @@ acl_get_fd(int fd) + { + const size_t size_guess = acl_ea_size(16); + char *ext_acl_p = alloca(size_guess); ++ char *name = ACL_EA_ACCESS; + int retval; ++ int nfsv4acls; + + if (!ext_acl_p) + return NULL; +- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p, size_guess); ++ ++#ifdef USE_NFSV4_TRANS ++ retval = fgetxattr(fd, ACL_NFS4_XATTR, ext_acl_p, size_guess); ++ if(retval == -1 && (errno == ENOATTR || errno == EOPNOTSUPP)) { ++ nfsv4acls = ACL_NFS4_NOT_USED; ++ retval = fgetxattr(fd, name, ext_acl_p, size_guess); ++ } else { ++ nfsv4acls = ACL_NFS4_USED; ++ name = ACL_NFS4_XATTR; ++ } ++#else ++ retval = fgetxattr(fd, name, ext_acl_p, size_guess); ++#endif ++ + if (retval == -1 && errno == ERANGE) { +- retval = fgetxattr(fd, ACL_EA_ACCESS, NULL, 0); ++ retval = fgetxattr(fd, name, NULL, 0); + if (retval > 0) { + ext_acl_p = alloca(retval); + if (!ext_acl_p) + return NULL; +- retval = fgetxattr(fd, ACL_EA_ACCESS, ext_acl_p,retval); ++ retval = fgetxattr(fd, name, ext_acl_p, retval); + } + } + if (retval > 0) { +- acl_t acl = __acl_from_xattr(ext_acl_p, retval); +- return acl; ++#ifdef USE_NFSV4_TRANS ++ if(nfsv4acls == ACL_NFS4_USED) { ++ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval, ++ ACL_TYPE_ACCESS, NFS4_ACL_ISFILE); ++ ++ return acl; ++ } ++ else ++#endif ++ { ++ acl_t acl = __acl_from_xattr(ext_acl_p, retval); ++ return acl; ++ } + } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) { + struct stat st; + +- if (fstat(fd, &st) == 0) +- return acl_from_mode(st.st_mode); +- else ++ if (fstat(fd, &st) != 0) { + return NULL; +- } else ++ } ++ ++ return acl_from_mode(st.st_mode); ++ } else { + return NULL; ++ } + } + +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_xattr_size.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,91 @@ ++/* ++ * NFSv4 ACL Code ++ * Return the expected xattr XDR encoded size of the nfs acl. Used for ++ * figuring the size of the xattr buffer. ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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 ++ ++int acl_nfs4_xattr_size(struct nfs4_acl * acl) ++{ ++ int size = 0; ++ struct nfs4_ace * ace; ++ int ace_num; ++ int num_aces; ++ ++ if(acl == NULL) { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ /* Space for number of aces */ ++ size += sizeof(u32); ++ ++ ace = acl->ace_head.tqh_first; ++ ace_num = 1; ++ ++ num_aces = acl->naces; ++ ++ while(1) ++ { ++ if(ace == NULL) { ++ if(ace_num > num_aces) { ++ break; ++ } else { ++ errno = ENODATA; ++ goto failed; ++ } ++ } ++ ++ /* space for type, flag, and mask */ ++ size += (3 * sizeof(u32)); ++ ++ /* space for strlen */ ++ size += sizeof(u32); ++ ++ /* space for the who string... xdr encoded */ ++ size += (strlen(ace->who) / NFS4_XDR_MOD) * NFS4_XDR_MOD * sizeof(char); ++ if(strlen(ace->who) % NFS4_XDR_MOD) { ++ size += NFS4_XDR_MOD; ++ } ++ ++ ace = ace->l_ace.tqe_next; ++ ace_num++; ++ } ++ ++ return size; ++ ++failed: ++ return -1; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_ptn4_get_mask.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,81 @@ ++/* ++ * NFSv4 ACL Code ++ * Translate POSIX permissions to an NFSv4 mask ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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 ++#include ++ ++int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, int iflags) ++{ ++ int result; ++ ++ *mask = NFS4_ANYONE_MODE; ++ ++ if (perms == NULL) { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ if (iflags & NFS4_ACL_OWNER) ++ *mask |= NFS4_OWNER_MODE; ++ ++ result = acl_get_perm(perms, ACL_READ); ++ if (result < 0) ++ goto failed; ++ else if(result == 1) ++ *mask |= NFS4_READ_MODE; ++ ++ result = acl_get_perm(perms, ACL_WRITE); ++ if (result < 0) ++ goto failed; ++ else if (result == 1) { ++ *mask |= NFS4_WRITE_MODE; ++ if (iflags & NFS4_ACL_ISDIR) ++ *mask |= NFS4_ACE_DELETE_CHILD; ++ } ++ ++ result = acl_get_perm(perms, ACL_EXECUTE); ++ if (result < 0) ++ goto failed; ++ else if (result == 1) ++ *mask |= NFS4_EXECUTE_MODE; ++ ++ return 0; ++ ++failed: ++ return -1; ++} ++ ++ ++ +--- acl-2.2.39/libacl/acl_get_file.c.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/libacl/acl_get_file.c 2007-08-22 12:02:13.000000000 -0400 +@@ -28,6 +28,10 @@ + #include "libacl.h" + #include "__acl_from_xattr.h" + ++#ifdef USE_NFSV4_TRANS ++ #include "libacl_nfs4.h" ++#endif ++ + #include "byteorder.h" + #include "acl_ea.h" + +@@ -40,6 +44,8 @@ acl_get_file(const char *path_p, acl_typ + char *ext_acl_p = alloca(size_guess); + const char *name; + int retval; ++ int nfsv4acls; ++ int iflags; + + switch(type) { + case ACL_TYPE_ACCESS: +@@ -55,8 +61,20 @@ acl_get_file(const char *path_p, acl_typ + + if (!ext_acl_p) + return NULL; ++#ifdef USE_NFSV4_TRANS ++ retval = getxattr(path_p, ACL_NFS4_XATTR, ext_acl_p, size_guess); ++ if((retval == -1) && (errno == ENOATTR || errno == EOPNOTSUPP)) { ++ nfsv4acls = ACL_NFS4_NOT_USED; ++ retval = getxattr(path_p, name, ext_acl_p, size_guess); ++ } else { ++ nfsv4acls = ACL_NFS4_USED; ++ name = ACL_NFS4_XATTR; ++ } ++#else + retval = getxattr(path_p, name, ext_acl_p, size_guess); +- if (retval == -1 && errno == ERANGE) { ++#endif ++ ++ if ((retval == -1) && (errno == ERANGE)) { + retval = getxattr(path_p, name, NULL, 0); + if (retval > 0) { + ext_acl_p = alloca(retval); +@@ -66,9 +84,29 @@ acl_get_file(const char *path_p, acl_typ + } + } + if (retval > 0) { +- acl_t acl = __acl_from_xattr(ext_acl_p, retval); +- return acl; +- } else if (retval == 0 || errno == ENOATTR || errno == ENODATA) { ++#ifdef USE_NFSV4_TRANS ++ if(nfsv4acls == ACL_NFS4_USED) { ++ struct stat st; ++ ++ iflags = NFS4_ACL_ISFILE; ++ ++ if (stat(path_p, &st) != 0) ++ return NULL; ++ ++ if (S_ISDIR(st.st_mode)) ++ iflags = NFS4_ACL_ISDIR; ++ ++ acl_t acl = __posix_acl_from_nfs4_xattr(ext_acl_p, retval, type, ++ iflags); ++ return acl; ++ } ++ else ++#endif ++ { ++ acl_t acl = __acl_from_xattr(ext_acl_p, retval); ++ return acl; ++ } ++ } else if ((retval == 0) || (errno == ENOATTR) || (errno == ENODATA)) { + struct stat st; + + if (stat(path_p, &st) != 0) +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/libacl_nfs4.h 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,97 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* mode bit translations: */ ++#define NFS4_READ_MODE NFS4_ACE_READ_DATA ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) ++#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE ++#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \ ++ NFS4_ACE_SYNCHRONIZE) ++#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) ++ ++#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \ ++ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS) ++/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in ++ * general (should only be ignored on files). */ ++#define MASK_EQUAL(mask1, mask2) \ ++ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD) \ ++ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD)) ++ ++/* Maximum length of the ace->who attribute */ ++#define NFS4_ACL_WHO_LENGTH_MAX 2048 ++#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255 ++ ++/* NFS4 acl xattr name */ ++#define ACL_NFS4_XATTR "system.nfs4_acl" ++ ++/* Macro for finding empty tailqs */ ++#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL) ++ ++/* Flags to pass certain properties around */ ++#define NFS4_ACL_NOFLAGS 0x00 ++#define NFS4_ACL_ISFILE 0x00 ++#define NFS4_ACL_ISDIR 0x01 ++#define NFS4_ACL_OWNER 0x02 ++#define NFS4_ACL_REQUEST_DEFAULT 0x04 ++#define NFS4_ACL_RAW 0x01 ++ ++#define NFS4_XDR_MOD 4 ++ ++typedef u_int32_t u32; ++ ++enum { ACL_NFS4_NOT_USED = 0, ++ ACL_NFS4_USED ++}; ++ ++struct ace_container { ++ struct nfs4_ace *ace; ++ TAILQ_ENTRY(ace_container) l_ace; ++}; ++ ++TAILQ_HEAD(ace_container_list_head, ace_container); ++ ++/**** Public functions ****/ ++ ++/** Manipulation functions **/ ++extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*); ++extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*); ++extern void acl_nfs4_free(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_new(u32); ++extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*); ++extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32); ++extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**); ++extern int acl_nfs4_xattr_size(struct nfs4_acl *); ++extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace); ++ ++/** Conversion functions **/ ++ ++/* nfs4 -> posix */ ++extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t); ++ ++/* posix -> nfs4 */ ++extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, ++ int iflags); ++extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*); ++ ++ ++/** Access Functions **/ ++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); ++ ++/* These will change */ ++char * nfs4_get_who_from_uid(uid_t); ++char * nfs4_get_who_from_gid(gid_t); ++/* End change */ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_new.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,58 @@ ++/* ++ * Common NFSv4 ACL handling code. ++ * Create a new NFSv4 ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen ++ * J. Bruce Fields ++ * Nathaniel Gallaher ++ * Jeff Sedlak ++ * ++ * 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" ++ ++struct nfs4_acl * ++acl_nfs4_new(u32 is_dir) ++{ ++ struct nfs4_acl *acl; ++ ++ if ((acl = malloc(sizeof(*acl))) == NULL) ++ return NULL; ++ ++ acl->naces = 0; ++ acl->is_directory = is_dir; ++ ++ TAILQ_INIT(&acl->ace_head); ++ ++ return acl; ++} ++ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_copy_acl.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,85 @@ ++/* ++ * NFSv4 ACL Code ++ * Deep copy an NFS4 ACL ++ * ++ * Copyright (c) 2002, 2003 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Nathaniel Gallaher ++ * ++ * 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" ++ ++struct nfs4_acl * acl_nfs4_copy_acl(struct nfs4_acl * nacl) ++{ ++ struct nfs4_acl * new_acl; ++ struct nfs4_ace * ace; ++ u32 nace; ++ u32 num_aces; ++ int result; ++ ++ if(nacl == NULL) { ++ errno = EINVAL; ++ goto failed; ++ } ++ ++ num_aces = nacl->naces; ++ ++ new_acl = acl_nfs4_new(nacl->is_directory); ++ if(new_acl == NULL) ++ goto failed; ++ ++ ace = nacl->ace_head.tqh_first; ++ nace = 1; ++ ++ while(1) ++ { ++ if(ace == NULL) { ++ if(nace > num_aces) ++ break; ++ else ++ goto free_failed; ++ } ++ ++ result = acl_nfs4_add_ace(new_acl, ace->type, ace->flag, ++ ace->access_mask, acl_nfs4_get_whotype(ace->who), ace->who); ++ if(result < 0) ++ goto free_failed; ++ ++ ace = ace->l_ace.tqe_next; ++ nace++; ++ } ++ ++ return new_acl; ++ ++free_failed: ++ acl_nfs4_free(new_acl); ++ ++failed: ++ return NULL; ++} +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/libacl/acl_nfs4_add_pair.c 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,60 @@ ++/* ++ * Add a pair of aces to the acl. The ace masks are complements of each other ++ * This keeps us from walking off the end of the acl ++ * ++ * Copyright (c) 2004 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Marius Aamodt Eriksen ++ * J. Bruce Fields ++ * Nathaniel Gallaher ++ * Jeff Sedlak ++ * ++ * 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, the following disclaimer, and ++ * any and all other licensing or copyright notices included in ++ * any files in this distribution. ++ * 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_nfs4_add_pair(struct nfs4_acl *acl, int eflag, u32 mask, int ownertype, ++ char* owner) ++{ ++ int error; ++ ++ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE, ++ eflag, mask, ownertype, owner); ++ if (error < 0) ++ return error; ++ error = acl_nfs4_add_ace(acl, NFS4_ACE_ACCESS_DENIED_ACE_TYPE, ++ eflag, ~mask, ownertype, owner); ++ return error; ++} ++ ++ +--- acl-2.2.39/exports.orig 2006-06-20 02:51:25.000000000 -0400 ++++ acl-2.2.39/exports 2007-08-22 12:02:13.000000000 -0400 +@@ -67,3 +67,33 @@ ACL_1.1 { + perm_copy_fd; + perm_copy_file; + } ACL_1.0; ++ ++ACL_1.2 { ++ global: ++ acl_nfs4_add_ace; ++ acl_nfs4_add_pair; ++ acl_nfs4_free; ++ acl_nfs4_new; ++ acl_nfs4_set_dir; ++ acl_nfs4_set_who; ++ acl_nfs4_copy_acl; ++ acl_nfs4_xattr_load; ++ acl_nfs4_xattr_pack; ++ acl_nfs4_xattr_size; ++ acl_nfs4_remove_ace; ++ ++ acl_n4tp_acl_trans; ++ ++ acl_ptn4_get_mask; ++ acl_ptn4_acl_trans; ++ ++ acl_nfs4_get_whotype; ++ acl_nfs4_get_who; ++ acl_nfs4_entries; ++ ++ local: ++ __posix_acl_from_nfs4_xattr; ++ nfs4_get_who_from_uid; ++ nfs4_get_who_from_gid; ++ ++} ACL_1.1; +--- acl-2.2.39/include/builddefs.in.orig 2007-08-22 11:59:37.000000000 -0400 ++++ acl-2.2.39/include/builddefs.in 2007-08-22 12:02:13.000000000 -0400 +@@ -65,7 +65,7 @@ endif + + GCFLAGS = $(OPTIMIZER) $(DEBUG) -funsigned-char -fno-strict-aliasing -Wall \ + -DVERSION=\"$(PKG_VERSION)\" -DLOCALEDIR=\"$(PKG_LOCALE_DIR)\" \ +- -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include ++ -DPACKAGE=\"$(PKG_NAME)\" -I$(TOPDIR)/include -DUSE_NFSV4_TRANS + + # Global, Platform, Local CFLAGS + CFLAGS += $(GCFLAGS) $(PCFLAGS) $(LCFLAGS) +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/include/nfs4.h 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,397 @@ ++/* ++ * NFSv4 protocol definitions. ++ * ++ * Copyright (c) 2002 The Regents of the University of Michigan. ++ * All rights reserved. ++ * ++ * Kendrick Smith ++ * Andy Adamson ++ */ ++ ++#include ++#include ++ ++#ifndef _LINUX_NFS4_H ++#define _LINUX_NFS4_H ++ ++#define NFS4_VERIFIER_SIZE 8 ++#define NFS4_FHSIZE 128 ++#define NFS4_MAXNAMLEN NAME_MAX ++ ++#define NFS4_ACCESS_READ 0x0001 ++#define NFS4_ACCESS_LOOKUP 0x0002 ++#define NFS4_ACCESS_MODIFY 0x0004 ++#define NFS4_ACCESS_EXTEND 0x0008 ++#define NFS4_ACCESS_DELETE 0x0010 ++#define NFS4_ACCESS_EXECUTE 0x0020 ++ ++#define NFS4_FH_PERISTENT 0x0000 ++#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001 ++#define NFS4_FH_VOLATILE_ANY 0x0002 ++#define NFS4_FH_VOL_MIGRATION 0x0004 ++#define NFS4_FH_VOL_RENAME 0x0008 ++ ++#define NFS4_OPEN_RESULT_CONFIRM 0x0002 ++ ++#define NFS4_SHARE_ACCESS_READ 0x0001 ++#define NFS4_SHARE_ACCESS_WRITE 0x0002 ++#define NFS4_SHARE_ACCESS_BOTH 0x0003 ++#define NFS4_SHARE_DENY_READ 0x0001 ++#define NFS4_SHARE_DENY_WRITE 0x0002 ++#define NFS4_SHARE_DENY_BOTH 0x0003 ++ ++#define NFS4_SET_TO_SERVER_TIME 0 ++#define NFS4_SET_TO_CLIENT_TIME 1 ++ ++#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0 ++#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1 ++#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2 ++#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3 ++ ++#define ACL4_SUPPORT_ALLOW_ACL 0x01 ++#define ACL4_SUPPORT_DENY_ACL 0x02 ++#define ACL4_SUPPORT_AUDIT_ACL 0x04 ++#define ACL4_SUPPORT_ALARM_ACL 0x08 ++ ++#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001 ++#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002 ++#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004 ++#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008 ++#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010 ++#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020 ++#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040 ++#define NFS4_ACE_OWNER 0x00000080 ++#define NFS4_ACE_GROUP 0x00000100 ++#define NFS4_ACE_EVERYONE 0x00000200 ++ ++#define NFS4_ACE_READ_DATA 0x00000001 ++#define NFS4_ACE_LIST_DIRECTORY 0x00000001 ++#define NFS4_ACE_WRITE_DATA 0x00000002 ++#define NFS4_ACE_ADD_FILE 0x00000002 ++#define NFS4_ACE_APPEND_DATA 0x00000004 ++#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004 ++#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008 ++#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010 ++#define NFS4_ACE_EXECUTE 0x00000020 ++#define NFS4_ACE_DELETE_CHILD 0x00000040 ++#define NFS4_ACE_READ_ATTRIBUTES 0x00000080 ++#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100 ++#define NFS4_ACE_DELETE 0x00010000 ++#define NFS4_ACE_READ_ACL 0x00020000 ++#define NFS4_ACE_WRITE_ACL 0x00040000 ++#define NFS4_ACE_WRITE_OWNER 0x00080000 ++#define NFS4_ACE_SYNCHRONIZE 0x00100000 ++#define NFS4_ACE_GENERIC_READ 0x00120081 ++#define NFS4_ACE_GENERIC_WRITE 0x00160106 ++#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0 ++#define NFS4_ACE_MASK_ALL 0x001F01FF ++ ++enum nfs4_acl_whotype { ++ NFS4_ACL_WHO_NAMED = 0, ++ NFS4_ACL_WHO_OWNER, ++ NFS4_ACL_WHO_GROUP, ++ NFS4_ACL_WHO_EVERYONE, ++}; ++ ++#define NFS4_ACL_WHO_OWNER_STRING "OWNER@" ++#define NFS4_ACL_WHO_GROUP_STRING "GROUP@" ++#define NFS4_ACL_WHO_EVERYONE_STRING "EVERYONE@" ++ ++struct nfs4_ace { ++ u_int32_t type; ++ u_int32_t flag; ++ u_int32_t access_mask; ++ char* who; ++ TAILQ_ENTRY(nfs4_ace) l_ace; ++}; ++ ++TAILQ_HEAD(ace_list_head, nfs4_ace); ++ ++struct nfs4_acl { ++ u_int32_t naces; ++ u_int32_t is_directory; ++ struct ace_list_head ace_head; ++}; ++ ++typedef struct { char data[NFS4_VERIFIER_SIZE]; } nfs4_verifier; ++typedef struct { char data[16]; } nfs4_stateid; ++ ++enum nfs_opnum4 { ++ OP_ACCESS = 3, ++ OP_CLOSE = 4, ++ OP_COMMIT = 5, ++ OP_CREATE = 6, ++ OP_DELEGPURGE = 7, ++ OP_DELEGRETURN = 8, ++ OP_GETATTR = 9, ++ OP_GETFH = 10, ++ OP_LINK = 11, ++ OP_LOCK = 12, ++ OP_LOCKT = 13, ++ OP_LOCKU = 14, ++ OP_LOOKUP = 15, ++ OP_LOOKUPP = 16, ++ OP_NVERIFY = 17, ++ OP_OPEN = 18, ++ OP_OPENATTR = 19, ++ OP_OPEN_CONFIRM = 20, ++ OP_OPEN_DOWNGRADE = 21, ++ OP_PUTFH = 22, ++ OP_PUTPUBFH = 23, ++ OP_PUTROOTFH = 24, ++ OP_READ = 25, ++ OP_READDIR = 26, ++ OP_READLINK = 27, ++ OP_REMOVE = 28, ++ OP_RENAME = 29, ++ OP_RENEW = 30, ++ OP_RESTOREFH = 31, ++ OP_SAVEFH = 32, ++ OP_SECINFO = 33, ++ OP_SETATTR = 34, ++ OP_SETCLIENTID = 35, ++ OP_SETCLIENTID_CONFIRM = 36, ++ OP_VERIFY = 37, ++ OP_WRITE = 38, ++ OP_RELEASE_LOCKOWNER = 39, ++ OP_ILLEGAL = 10044, ++}; ++ ++enum nfsstat4 { ++ NFS4_OK = 0, ++ NFS4ERR_PERM = 1, ++ NFS4ERR_NOENT = 2, ++ NFS4ERR_IO = 5, ++ NFS4ERR_NXIO = 6, ++ NFS4ERR_ACCESS = 13, ++ NFS4ERR_EXIST = 17, ++ NFS4ERR_XDEV = 18, ++ /* Unused/reserved 19 */ ++ NFS4ERR_NOTDIR = 20, ++ NFS4ERR_ISDIR = 21, ++ NFS4ERR_INVAL = 22, ++ NFS4ERR_FBIG = 27, ++ NFS4ERR_NOSPC = 28, ++ NFS4ERR_ROFS = 30, ++ NFS4ERR_MLINK = 31, ++ NFS4ERR_NAMETOOLONG = 63, ++ NFS4ERR_NOTEMPTY = 66, ++ NFS4ERR_DQUOT = 69, ++ NFS4ERR_STALE = 70, ++ NFS4ERR_BADHANDLE = 10001, ++ NFS4ERR_BAD_COOKIE = 10003, ++ NFS4ERR_NOTSUPP = 10004, ++ NFS4ERR_TOOSMALL = 10005, ++ NFS4ERR_SERVERFAULT = 10006, ++ NFS4ERR_BADTYPE = 10007, ++ NFS4ERR_DELAY = 10008, ++ NFS4ERR_SAME = 10009, ++ NFS4ERR_DENIED = 10010, ++ NFS4ERR_EXPIRED = 10011, ++ NFS4ERR_LOCKED = 10012, ++ NFS4ERR_GRACE = 10013, ++ NFS4ERR_FHEXPIRED = 10014, ++ NFS4ERR_SHARE_DENIED = 10015, ++ NFS4ERR_WRONGSEC = 10016, ++ NFS4ERR_CLID_INUSE = 10017, ++ NFS4ERR_RESOURCE = 10018, ++ NFS4ERR_MOVED = 10019, ++ NFS4ERR_NOFILEHANDLE = 10020, ++ NFS4ERR_MINOR_VERS_MISMATCH = 10021, ++ NFS4ERR_STALE_CLIENTID = 10022, ++ NFS4ERR_STALE_STATEID = 10023, ++ NFS4ERR_OLD_STATEID = 10024, ++ NFS4ERR_BAD_STATEID = 10025, ++ NFS4ERR_BAD_SEQID = 10026, ++ NFS4ERR_NOT_SAME = 10027, ++ NFS4ERR_LOCK_RANGE = 10028, ++ NFS4ERR_SYMLINK = 10029, ++ NFS4ERR_RESTOREFH = 10030, ++ NFS4ERR_LEASE_MOVED = 10031, ++ NFS4ERR_ATTRNOTSUPP = 10032, ++ NFS4ERR_NO_GRACE = 10033, ++ NFS4ERR_RECLAIM_BAD = 10034, ++ NFS4ERR_RECLAIM_CONFLICT = 10035, ++ NFS4ERR_BADXDR = 10036, ++ NFS4ERR_LOCKS_HELD = 10037, ++ NFS4ERR_OPENMODE = 10038, ++ NFS4ERR_BADOWNER = 10039, ++ NFS4ERR_BADCHAR = 10040, ++ NFS4ERR_BADNAME = 10041, ++ NFS4ERR_BAD_RANGE = 10042, ++ NFS4ERR_LOCK_NOTSUPP = 10043, ++ NFS4ERR_OP_ILLEGAL = 10044, ++ NFS4ERR_DEADLOCK = 10045, ++ NFS4ERR_FILE_OPEN = 10046, ++ NFS4ERR_ADMIN_REVOKED = 10047, ++ NFS4ERR_CB_PATH_DOWN = 10048 ++}; ++ ++/* ++ * Note: NF4BAD is not actually part of the protocol; it is just used ++ * internally by nfsd. ++ */ ++enum nfs_ftype4 { ++ NF4BAD = 0, ++ NF4REG = 1, /* Regular File */ ++ NF4DIR = 2, /* Directory */ ++ NF4BLK = 3, /* Special File - block device */ ++ NF4CHR = 4, /* Special File - character device */ ++ NF4LNK = 5, /* Symbolic Link */ ++ NF4SOCK = 6, /* Special File - socket */ ++ NF4FIFO = 7, /* Special File - fifo */ ++ NF4ATTRDIR = 8, /* Attribute Directory */ ++ NF4NAMEDATTR = 9 /* Named Attribute */ ++}; ++ ++enum open_claim_type4 { ++ NFS4_OPEN_CLAIM_NULL = 0, ++ NFS4_OPEN_CLAIM_PREVIOUS = 1, ++ NFS4_OPEN_CLAIM_DELEGATE_CUR = 2, ++ NFS4_OPEN_CLAIM_DELEGATE_PREV = 3 ++}; ++ ++enum opentype4 { ++ NFS4_OPEN_NOCREATE = 0, ++ NFS4_OPEN_CREATE = 1 ++}; ++ ++enum createmode4 { ++ NFS4_CREATE_UNCHECKED = 0, ++ NFS4_CREATE_GUARDED = 1, ++ NFS4_CREATE_EXCLUSIVE = 2 ++}; ++ ++enum limit_by4 { ++ NFS4_LIMIT_SIZE = 1, ++ NFS4_LIMIT_BLOCKS = 2 ++}; ++ ++enum open_delegation_type4 { ++ NFS4_OPEN_DELEGATE_NONE = 0, ++ NFS4_OPEN_DELEGATE_READ = 1, ++ NFS4_OPEN_DELEGATE_WRITE = 2 ++}; ++ ++enum lock_type4 { ++ NFS4_UNLOCK_LT = 0, ++ NFS4_READ_LT = 1, ++ NFS4_WRITE_LT = 2, ++ NFS4_READW_LT = 3, ++ NFS4_WRITEW_LT = 4 ++}; ++ ++ ++/* Mandatory Attributes */ ++#define FATTR4_WORD0_SUPPORTED_ATTRS (1UL << 0) ++#define FATTR4_WORD0_TYPE (1UL << 1) ++#define FATTR4_WORD0_FH_EXPIRE_TYPE (1UL << 2) ++#define FATTR4_WORD0_CHANGE (1UL << 3) ++#define FATTR4_WORD0_SIZE (1UL << 4) ++#define FATTR4_WORD0_LINK_SUPPORT (1UL << 5) ++#define FATTR4_WORD0_SYMLINK_SUPPORT (1UL << 6) ++#define FATTR4_WORD0_NAMED_ATTR (1UL << 7) ++#define FATTR4_WORD0_FSID (1UL << 8) ++#define FATTR4_WORD0_UNIQUE_HANDLES (1UL << 9) ++#define FATTR4_WORD0_LEASE_TIME (1UL << 10) ++#define FATTR4_WORD0_RDATTR_ERROR (1UL << 11) ++ ++/* Recommended Attributes */ ++#define FATTR4_WORD0_ACL (1UL << 12) ++#define FATTR4_WORD0_ACLSUPPORT (1UL << 13) ++#define FATTR4_WORD0_ARCHIVE (1UL << 14) ++#define FATTR4_WORD0_CANSETTIME (1UL << 15) ++#define FATTR4_WORD0_CASE_INSENSITIVE (1UL << 16) ++#define FATTR4_WORD0_CASE_PRESERVING (1UL << 17) ++#define FATTR4_WORD0_CHOWN_RESTRICTED (1UL << 18) ++#define FATTR4_WORD0_FILEHANDLE (1UL << 19) ++#define FATTR4_WORD0_FILEID (1UL << 20) ++#define FATTR4_WORD0_FILES_AVAIL (1UL << 21) ++#define FATTR4_WORD0_FILES_FREE (1UL << 22) ++#define FATTR4_WORD0_FILES_TOTAL (1UL << 23) ++#define FATTR4_WORD0_FS_LOCATIONS (1UL << 24) ++#define FATTR4_WORD0_HIDDEN (1UL << 25) ++#define FATTR4_WORD0_HOMOGENEOUS (1UL << 26) ++#define FATTR4_WORD0_MAXFILESIZE (1UL << 27) ++#define FATTR4_WORD0_MAXLINK (1UL << 28) ++#define FATTR4_WORD0_MAXNAME (1UL << 29) ++#define FATTR4_WORD0_MAXREAD (1UL << 30) ++#define FATTR4_WORD0_MAXWRITE (1UL << 31) ++#define FATTR4_WORD1_MIMETYPE (1UL << 0) ++#define FATTR4_WORD1_MODE (1UL << 1) ++#define FATTR4_WORD1_NO_TRUNC (1UL << 2) ++#define FATTR4_WORD1_NUMLINKS (1UL << 3) ++#define FATTR4_WORD1_OWNER (1UL << 4) ++#define FATTR4_WORD1_OWNER_GROUP (1UL << 5) ++#define FATTR4_WORD1_QUOTA_HARD (1UL << 6) ++#define FATTR4_WORD1_QUOTA_SOFT (1UL << 7) ++#define FATTR4_WORD1_QUOTA_USED (1UL << 8) ++#define FATTR4_WORD1_RAWDEV (1UL << 9) ++#define FATTR4_WORD1_SPACE_AVAIL (1UL << 10) ++#define FATTR4_WORD1_SPACE_FREE (1UL << 11) ++#define FATTR4_WORD1_SPACE_TOTAL (1UL << 12) ++#define FATTR4_WORD1_SPACE_USED (1UL << 13) ++#define FATTR4_WORD1_SYSTEM (1UL << 14) ++#define FATTR4_WORD1_TIME_ACCESS (1UL << 15) ++#define FATTR4_WORD1_TIME_ACCESS_SET (1UL << 16) ++#define FATTR4_WORD1_TIME_BACKUP (1UL << 17) ++#define FATTR4_WORD1_TIME_CREATE (1UL << 18) ++#define FATTR4_WORD1_TIME_DELTA (1UL << 19) ++#define FATTR4_WORD1_TIME_METADATA (1UL << 20) ++#define FATTR4_WORD1_TIME_MODIFY (1UL << 21) ++#define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22) ++#define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) ++ ++#define NFSPROC4_NULL 0 ++#define NFSPROC4_COMPOUND 1 ++#define NFS4_MINOR_VERSION 0 ++#define NFS4_DEBUG 1 ++ ++#ifdef __KERNEL__ ++ ++/* Index of predefined Linux client operations */ ++ ++enum { ++ NFSPROC4_CLNT_NULL = 0, /* Unused */ ++ NFSPROC4_CLNT_READ, ++ NFSPROC4_CLNT_WRITE, ++ NFSPROC4_CLNT_COMMIT, ++ NFSPROC4_CLNT_OPEN, ++ NFSPROC4_CLNT_OPEN_CONFIRM, ++ NFSPROC4_CLNT_OPEN_RECLAIM, ++ NFSPROC4_CLNT_OPEN_DOWNGRADE, ++ NFSPROC4_CLNT_CLOSE, ++ NFSPROC4_CLNT_SETATTR, ++ NFSPROC4_CLNT_FSINFO, ++ NFSPROC4_CLNT_RENEW, ++ NFSPROC4_CLNT_SETCLIENTID, ++ NFSPROC4_CLNT_SETCLIENTID_CONFIRM, ++ NFSPROC4_CLNT_LOCK, ++ NFSPROC4_CLNT_LOCKT, ++ NFSPROC4_CLNT_LOCKU, ++ NFSPROC4_CLNT_ACCESS, ++ NFSPROC4_CLNT_GETATTR, ++ NFSPROC4_CLNT_LOOKUP, ++ NFSPROC4_CLNT_LOOKUP_ROOT, ++ NFSPROC4_CLNT_REMOVE, ++ NFSPROC4_CLNT_RENAME, ++ NFSPROC4_CLNT_LINK, ++ NFSPROC4_CLNT_CREATE, ++ NFSPROC4_CLNT_PATHCONF, ++ NFSPROC4_CLNT_STATFS, ++ NFSPROC4_CLNT_READLINK, ++ NFSPROC4_CLNT_READDIR, ++ NFSPROC4_CLNT_SERVER_CAPS, ++ NFSPROC4_CLNT_DELEGRETURN, ++ NFSPROC4_CLNT_GETACL, ++ NFSPROC4_CLNT_SETACL, ++}; ++ ++#endif ++#endif ++ ++/* ++ * Local variables: ++ * c-basic-offset: 8 ++ * End: ++ */ +--- /dev/null 2007-08-22 11:21:03.626521839 -0400 ++++ acl-2.2.39/include/libacl_nfs4.h 2007-08-22 12:02:13.000000000 -0400 +@@ -0,0 +1,97 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* mode bit translations: */ ++#define NFS4_READ_MODE NFS4_ACE_READ_DATA ++#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) ++#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE ++#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | \ ++ NFS4_ACE_SYNCHRONIZE) ++#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) ++ ++#define NFS4_ACE_MASK_IGNORE (NFS4_ACE_DELETE | NFS4_ACE_WRITE_OWNER \ ++ | NFS4_ACE_READ_NAMED_ATTRS | NFS4_ACE_WRITE_NAMED_ATTRS) ++/* XXX not sure about the following. Note that e.g. DELETE_CHILD is wrong in ++ * general (should only be ignored on files). */ ++#define MASK_EQUAL(mask1, mask2) \ ++ (((mask1) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD) \ ++ == ((mask2) & NFS4_ACE_MASK_ALL & ~NFS4_ACE_MASK_IGNORE & \ ++ ~NFS4_ACE_DELETE_CHILD)) ++ ++/* Maximum length of the ace->who attribute */ ++#define NFS4_ACL_WHO_LENGTH_MAX 2048 ++#define NFS4_ACL_WHO_BUFFER_LEN_GUESS 255 ++ ++/* NFS4 acl xattr name */ ++#define ACL_NFS4_XATTR "system.nfs4_acl" ++ ++/* Macro for finding empty tailqs */ ++#define TAILQ_IS_EMPTY(head) (head.tqh_first == NULL) ++ ++/* Flags to pass certain properties around */ ++#define NFS4_ACL_NOFLAGS 0x00 ++#define NFS4_ACL_ISFILE 0x00 ++#define NFS4_ACL_ISDIR 0x01 ++#define NFS4_ACL_OWNER 0x02 ++#define NFS4_ACL_REQUEST_DEFAULT 0x04 ++#define NFS4_ACL_RAW 0x01 ++ ++#define NFS4_XDR_MOD 4 ++ ++typedef u_int32_t u32; ++ ++enum { ACL_NFS4_NOT_USED = 0, ++ ACL_NFS4_USED ++}; ++ ++struct ace_container { ++ struct nfs4_ace *ace; ++ TAILQ_ENTRY(ace_container) l_ace; ++}; ++ ++TAILQ_HEAD(ace_container_list_head, ace_container); ++ ++/**** Public functions ****/ ++ ++/** Manipulation functions **/ ++extern int acl_nfs4_add_ace(struct nfs4_acl *, u32, u32, u32, int, char*); ++extern int acl_nfs4_add_pair(struct nfs4_acl *, int, u32, int, char*); ++extern void acl_nfs4_free(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_new(u32); ++extern int acl_nfs4_set_who(struct nfs4_ace*, int, char*); ++extern struct nfs4_acl *acl_nfs4_copy_acl(struct nfs4_acl *); ++extern struct nfs4_acl *acl_nfs4_xattr_load(char *, int, u32); ++extern int acl_nfs4_xattr_pack(struct nfs4_acl *, char**); ++extern int acl_nfs4_xattr_size(struct nfs4_acl *); ++extern void acl_nfs4_remove_ace(struct nfs4_acl * acl, struct nfs4_ace * ace); ++ ++/** Conversion functions **/ ++ ++/* nfs4 -> posix */ ++extern acl_t acl_n4tp_acl_trans(struct nfs4_acl *, acl_type_t); ++ ++/* posix -> nfs4 */ ++extern int acl_ptn4_get_mask(u32* mask, acl_permset_t perms, ++ int iflags); ++extern int acl_ptn4_acl_trans(acl_t, struct nfs4_acl *, acl_type_t, u32, char*); ++ ++ ++/** Access Functions **/ ++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); ++ ++/* These will change */ ++char * nfs4_get_who_from_uid(uid_t); ++char * nfs4_get_who_from_gid(gid_t); ++/* End change */ diff --git a/acl-2.2.49-bz467936.patch b/acl-2.2.49-bz467936.patch new file mode 100644 index 0000000..a07b4fd --- /dev/null +++ b/acl-2.2.49-bz467936.patch @@ -0,0 +1,90 @@ +From 16230023e5afcb0b42b8d01207e3449d22772c31 Mon Sep 17 00:00:00 2001 +From: Brandon Philips +Date: Thu, 17 Dec 2009 14:28:04 -0800 +Subject: [PATCH] setfacl: changing owner and when S_ISUID should be set --restore fix + +Fix a problem in setfacl --restore when the owner or group is changed +and the S_ISUID and S_ISGID are to be set. + +The root of the problem is that chown() can clear the S_ISUID and +S_ISGID bits as described in chown(2): + + When the owner or group of an executable file are changed by a + non- superuser, the S_ISUID and S_ISGID mode bits are cleared. POSIX + does not specify whether this also should happen when root does the + chown(); the Linux behavior depends on the kernel version. In case of + a non- group-executable file (i.e., one for which the S_IXGRP bit is + not set) the S_ISGID bit indicates mandatory locking, and is not + cleared by a chown(). + +To fix the issue re-stat() the file after chown() so that the logic +surrounding the chmod() has the updated mode of the file. + +Signed-off-by: Brandon Philips +--- + setfacl/setfacl.c | 8 +++++++- + test/root/restore.test | 23 +++++++++++++++++++++++ + 2 files changed, 30 insertions(+), 1 deletions(-) + create mode 100644 test/root/restore.test + +diff --git a/setfacl/setfacl.c b/setfacl/setfacl.c +index 091b9cc..56b0aa4 100644 +--- a/setfacl/setfacl.c ++++ b/setfacl/setfacl.c +@@ -128,6 +128,7 @@ restore( + struct do_set_args args; + int line = 0, backup_line; + int error, status = 0; ++ int chmod_required = 0; + + memset(&st, 0, sizeof(st)); + +@@ -206,10 +207,15 @@ restore( + strerror(errno)); + status = 1; + } ++ ++ /* chown() clears setuid/setgid so force a chmod if ++ * S_ISUID/S_ISGID was expected */ ++ if ((st.st_mode & flags) & (S_ISUID | S_ISGID)) ++ chmod_required = 1; + } + + mask = S_ISUID | S_ISGID | S_ISVTX; +- if ((st.st_mode & mask) != (flags & mask)) { ++ if (chmod_required || ((st.st_mode & mask) != (flags & mask))) { + if (!args.mode) + args.mode = st.st_mode; + args.mode &= (S_IRWXU | S_IRWXG | S_IRWXO); +diff --git a/test/root/restore.test b/test/root/restore.test +new file mode 100644 +index 0000000..6003cd4 +--- /dev/null ++++ b/test/root/restore.test +@@ -0,0 +1,23 @@ ++Ensure setuid bit is restored when the owner changes ++ https://bugzilla.redhat.com/show_bug.cgi?id=467936#c7 ++ ++ $ touch passwd ++ $ chmod 755 passwd ++ $ chmod u+s passwd ++ $ getfacl passwd > passwd.acl ++ $ cat passwd.acl ++ > # file: passwd ++ > # owner: root ++ > # group: root ++ > # flags: s-- ++ > user::rwx ++ > group::r-x ++ > other::r-x ++ > ++ $ chown bin passwd ++ $ chmod u+s passwd ++ $ setfacl --restore passwd.acl ++ $ ls -dl passwd | awk '{print $1 " " $3 " " $4}' ++ > -rwsr-xr-x root root ++ ++ $ rm passwd passwd.acl +-- +1.6.2.5 + diff --git a/acl-2.2.49-bz675451.patch b/acl-2.2.49-bz675451.patch new file mode 100644 index 0000000..9417ab0 --- /dev/null +++ b/acl-2.2.49-bz675451.patch @@ -0,0 +1,27 @@ + man/man1/setfacl.1 | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/man/man1/setfacl.1 b/man/man1/setfacl.1 +index 25908e2..776f22d 100644 +--- a/man/man1/setfacl.1 ++++ b/man/man1/setfacl.1 +@@ -62,7 +62,7 @@ ACL entries for this operation must include permissions. + + The + .IR "\-x (\-\-remove)" " and " "\-X (\-\-remove-file)" +-options remove ACL enries. Only ++options remove ACL entries. Only + ACL entries without the + .I perms + field are accepted as parameters, unless POSIXLY_CORRECT is defined. +@@ -240,8 +240,8 @@ owner, owning group, or others entry, a copy of the ACL owner, owning group, or + .IP * 4 + If a Default ACL contains named user entries or named group entries, and no mask entry exists, a mask entry containing the same permissions as the default Default ACL's group entry is added. Unless the + .I \-n +-option is given, the permissions of the mask entry are further adjusted to inclu +-de the union of all permissions affected by the mask entry. (See the ++option is given, the permissions of the mask entry are further adjusted to ++include the union of all permissions affected by the mask entry. (See the + .I \-n + option description). + .PP diff --git a/acl-2.2.49-bz692982.patch b/acl-2.2.49-bz692982.patch new file mode 100644 index 0000000..0b5ef44 --- /dev/null +++ b/acl-2.2.49-bz692982.patch @@ -0,0 +1,375 @@ +From 6bf5e24d48077db58b389e90558100fc121b8134 Mon Sep 17 00:00:00 2001 +From: Kamil Dudka +Date: Mon, 4 Apr 2011 12:43:39 +0200 +Subject: [PATCH 1/2] libacl: Add acl_extended_file_nofollow() + +This function calls lgetxattr() instead of getxattr(), which helps ls(1) +to prevent unnecessary automatic mounts, which acl_extended_file() +triggers. See the following bug report for more details: +https://bugzilla.redhat.com/692982 +--- + exports | 1 + + include/libacl.h | 1 + + libacl/Makefile | 3 +- + libacl/__acl_extended_file.c | 49 +++++++++++++++++++++++++++++++++++ + libacl/__acl_extended_file.h | 4 +++ + libacl/acl_extended_file.c | 20 ++------------ + libacl/acl_extended_file_nofollow.c | 34 ++++++++++++++++++++++++ + man/man3/acl_extended_file.3 | 11 +++++++- + man/man5/acl.5 | 1 + + 9 files changed, 105 insertions(+), 19 deletions(-) + create mode 100644 libacl/__acl_extended_file.c + create mode 100644 libacl/__acl_extended_file.h + create mode 100644 libacl/acl_extended_file_nofollow.c + +diff --git a/exports b/exports +index ef02842..b368c22 100644 +--- a/exports ++++ b/exports +@@ -82,4 +82,5 @@ ACL_1.1 { + # Linux specific extensions + perm_copy_fd; + perm_copy_file; ++ acl_extended_file_nofollow; + } ACL_1.0; +diff --git a/include/libacl.h b/include/libacl.h +index 41ec48e..d6a6650 100644 +--- a/include/libacl.h ++++ b/include/libacl.h +@@ -59,6 +59,7 @@ extern int acl_check(acl_t acl, int *last); + extern acl_t acl_from_mode(mode_t mode); + extern int acl_equiv_mode(acl_t acl, mode_t *mode_p); + int acl_extended_file(const char *path_p); ++int acl_extended_file_nofollow(const char *path_p); + int acl_extended_fd(int fd); + extern int acl_entries(acl_t acl); + extern const char *acl_error(int code); +diff --git a/libacl/Makefile b/libacl/Makefile +index 1224b65..cfe3d3a 100644 +--- a/libacl/Makefile ++++ b/libacl/Makefile +@@ -47,7 +47,8 @@ POSIX_CFILES = \ + + LIBACL_CFILES = \ + acl_to_any_text.c acl_entries.c acl_check.c acl_error.c acl_cmp.c \ +- acl_extended_fd.c acl_extended_file.c acl_equiv_mode.c acl_from_mode.c ++ acl_extended_fd.c acl_extended_file.c acl_equiv_mode.c acl_from_mode.c \ ++ acl_extended_file_nofollow.c __acl_extended_file.c + + INTERNAL_CFILES = \ + __acl_to_any_text.c __acl_to_xattr.c __acl_from_xattr.c \ +diff --git a/libacl/__acl_extended_file.c b/libacl/__acl_extended_file.c +new file mode 100644 +index 0000000..629afe9 +--- /dev/null ++++ b/libacl/__acl_extended_file.c +@@ -0,0 +1,49 @@ ++/* ++ File: acl_extended_file.c ++ ++ Copyright (C) 2000, 2011 ++ Andreas Gruenbacher, ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this library; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++*/ ++ ++#include ++#include ++#include "libacl.h" ++ ++#include "byteorder.h" ++#include "acl_ea.h" ++#include "__acl_extended_file.h" ++ ++ ++int ++__acl_extended_file(const char *path_p, getxattr_t fun) ++{ ++ int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry); ++ int retval; ++ ++ retval = fun(path_p, ACL_EA_ACCESS, NULL, 0); ++ if (retval < 0 && errno != ENOATTR && errno != ENODATA) ++ return -1; ++ if (retval > base_size) ++ return 1; ++ retval = fun(path_p, ACL_EA_DEFAULT, NULL, 0); ++ if (retval < 0 && errno != ENOATTR && errno != ENODATA) ++ return -1; ++ if (retval >= base_size) ++ return 1; ++ return 0; ++} ++ +diff --git a/libacl/__acl_extended_file.h b/libacl/__acl_extended_file.h +new file mode 100644 +index 0000000..f8881a1 +--- /dev/null ++++ b/libacl/__acl_extended_file.h +@@ -0,0 +1,4 @@ ++typedef ssize_t (*getxattr_t)(const char *, const char *, void *value, ++ size_t size); ++ ++int __acl_extended_file(const char *path_p, getxattr_t fun); +diff --git a/libacl/acl_extended_file.c b/libacl/acl_extended_file.c +index d1cb85d..f417784 100644 +--- a/libacl/acl_extended_file.c ++++ b/libacl/acl_extended_file.c +@@ -1,7 +1,7 @@ + /* + File: acl_extended_file.c + +- Copyright (C) 2000 ++ Copyright (C) 2011 + Andreas Gruenbacher, + + This program is free software; you can redistribute it and/or +@@ -23,26 +23,12 @@ + #include + #include "libacl.h" + +-#include "byteorder.h" +-#include "acl_ea.h" ++#include "__acl_extended_file.h" + + + int + acl_extended_file(const char *path_p) + { +- int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry); +- int retval; +- +- retval = getxattr(path_p, ACL_EA_ACCESS, NULL, 0); +- if (retval < 0 && errno != ENOATTR && errno != ENODATA) +- return -1; +- if (retval > base_size) +- return 1; +- retval = getxattr(path_p, ACL_EA_DEFAULT, NULL, 0); +- if (retval < 0 && errno != ENOATTR && errno != ENODATA) +- return -1; +- if (retval >= base_size) +- return 1; +- return 0; ++ return __acl_extended_file(path_p, getxattr); + } + +diff --git a/libacl/acl_extended_file_nofollow.c b/libacl/acl_extended_file_nofollow.c +new file mode 100644 +index 0000000..8f4711f +--- /dev/null ++++ b/libacl/acl_extended_file_nofollow.c +@@ -0,0 +1,34 @@ ++/* ++ File: acl_extended_file.c ++ ++ Copyright (C) 2011 ++ Andreas Gruenbacher, ++ ++ This program is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with this library; if not, write to the Free Software ++ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++*/ ++ ++#include ++#include ++#include "libacl.h" ++ ++#include "__acl_extended_file.h" ++ ++ ++int ++acl_extended_file_nofollow(const char *path_p) ++{ ++ return __acl_extended_file(path_p, lgetxattr); ++} ++ +diff --git a/man/man3/acl_extended_file.3 b/man/man3/acl_extended_file.3 +index 0ca7e0f..1f04331 100644 +--- a/man/man3/acl_extended_file.3 ++++ b/man/man3/acl_extended_file.3 +@@ -25,7 +25,7 @@ + .Dt ACL_EXTENDED_FILE 3 + .Os "Linux ACL" + .Sh NAME +-.Nm acl_extended_file ++.Nm acl_extended_file, acl_extended_file_nofollow + .Nd test for information in ACLs by file name + .Sh LIBRARY + Linux Access Control Lists library (libacl, \-lacl). +@@ -34,6 +34,8 @@ Linux Access Control Lists library (libacl, \-lacl). + .In acl/libacl.h + .Ft int + .Fn acl_extended_file "const char *path_p" ++.Ft int ++.Fn acl_extended_file_nofollow "const char *path_p" + .Sh DESCRIPTION + The + .Fn acl_extended_file +@@ -61,6 +63,13 @@ mechanisms, such as Mandatory Access Control schemes. The + .Xr access 2 + system call can be used to check whether a given type of access to a file + object would be granted. ++.Pp ++.Fn acl_extended_file_nofollow ++is identical to ++.Fn acl_extended_file , ++except in the case of a symbolic link, where the link itself is interrogated, ++not the file that it refers to. Since symbolic links have no ACL themselves, ++the operation is supposed to fail on them. + .Sh RETURN VALUE + If successful, the + .Fn acl_extended_file +diff --git a/man/man5/acl.5 b/man/man5/acl.5 +index 6b0f468..aec58aa 100644 +--- a/man/man5/acl.5 ++++ b/man/man5/acl.5 +@@ -497,6 +497,7 @@ These non-portable extensions are available on Linux systems. + .Xr acl_error 3 , + .Xr acl_extended_fd 3 , + .Xr acl_extended_file 3 , ++.Xr acl_extended_file_nofollow 3 , + .Xr acl_from_mode 3 , + .Xr acl_get_perm 3 , + .Xr acl_to_any_text 3 +-- +1.7.4 + + +From ad4ca5aaee96e98b2e8e8a4351fa5e6c58d65216 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 4 Apr 2011 17:18:38 +0200 +Subject: [PATCH 2/2] Minor fixes to the previous commit + +* Assign the new libacl version ACL_1.2 to acl_extended_file_nofollow + so that package managers will end up with the appropriate + dependencies. +* Add a manpage entry for acl_extended_file_nofollow which sources + ("links to") the acl_extended_file manpage. +* Remove the prototype for getxattr/lgetxattr. +* Whitespace cleanups. +--- + exports | 7 ++++++- + libacl/__acl_extended_file.c | 7 ++++--- + libacl/__acl_extended_file.h | 7 +++---- + libacl/acl_extended_file_nofollow.c | 3 +-- + man/man3/acl_extended_file.3 | 2 +- + man/man3/acl_extended_file_nofollow.3 | 1 + + 6 files changed, 16 insertions(+), 11 deletions(-) + create mode 100644 man/man3/acl_extended_file_nofollow.3 + +diff --git a/exports b/exports +index b368c22..7d8e69e 100644 +--- a/exports ++++ b/exports +@@ -82,5 +82,10 @@ ACL_1.1 { + # Linux specific extensions + perm_copy_fd; + perm_copy_file; +- acl_extended_file_nofollow; + } ACL_1.0; ++ ++ACL_1.2 { ++ global: ++ # Linux specific extensions ++ acl_extended_file_nofollow; ++} ACL_1.1; +diff --git a/libacl/__acl_extended_file.c b/libacl/__acl_extended_file.c +index 629afe9..3e45abd 100644 +--- a/libacl/__acl_extended_file.c ++++ b/libacl/__acl_extended_file.c +@@ -1,5 +1,5 @@ + /* +- File: acl_extended_file.c ++ File: __acl_extended_file.c + + Copyright (C) 2000, 2011 + Andreas Gruenbacher, +@@ -29,7 +29,9 @@ + + + int +-__acl_extended_file(const char *path_p, getxattr_t fun) ++__acl_extended_file(const char *path_p, ++ ssize_t (*fun)(const char *, const char *, ++ void *, size_t)) + { + int base_size = sizeof(acl_ea_header) + 3 * sizeof(acl_ea_entry); + int retval; +@@ -46,4 +48,3 @@ __acl_extended_file(const char *path_p, getxattr_t fun) + return 1; + return 0; + } +- +diff --git a/libacl/__acl_extended_file.h b/libacl/__acl_extended_file.h +index f8881a1..0b0da9e 100644 +--- a/libacl/__acl_extended_file.h ++++ b/libacl/__acl_extended_file.h +@@ -1,4 +1,3 @@ +-typedef ssize_t (*getxattr_t)(const char *, const char *, void *value, +- size_t size); +- +-int __acl_extended_file(const char *path_p, getxattr_t fun); ++int __acl_extended_file(const char *path_p, ++ ssize_t (*)(const char *, const char *, ++ void *, size_t)); +diff --git a/libacl/acl_extended_file_nofollow.c b/libacl/acl_extended_file_nofollow.c +index 8f4711f..c253e4d 100644 +--- a/libacl/acl_extended_file_nofollow.c ++++ b/libacl/acl_extended_file_nofollow.c +@@ -1,5 +1,5 @@ + /* +- File: acl_extended_file.c ++ File: acl_extended_file_nofollow.c + + Copyright (C) 2011 + Andreas Gruenbacher, +@@ -31,4 +31,3 @@ acl_extended_file_nofollow(const char *path_p) + { + return __acl_extended_file(path_p, lgetxattr); + } +- +diff --git a/man/man3/acl_extended_file.3 b/man/man3/acl_extended_file.3 +index 1f04331..fdeef86 100644 +--- a/man/man3/acl_extended_file.3 ++++ b/man/man3/acl_extended_file.3 +@@ -65,7 +65,7 @@ system call can be used to check whether a given type of access to a file + object would be granted. + .Pp + .Fn acl_extended_file_nofollow +-is identical to ++is identical to + .Fn acl_extended_file , + except in the case of a symbolic link, where the link itself is interrogated, + not the file that it refers to. Since symbolic links have no ACL themselves, +diff --git a/man/man3/acl_extended_file_nofollow.3 b/man/man3/acl_extended_file_nofollow.3 +new file mode 100644 +index 0000000..44fc24f +--- /dev/null ++++ b/man/man3/acl_extended_file_nofollow.3 +@@ -0,0 +1 @@ ++.so man3/acl_extended_file.3 +-- +1.7.4 + diff --git a/acl-2.2.49-setfacl-restore.patch b/acl-2.2.49-setfacl-restore.patch new file mode 100644 index 0000000..8490091 --- /dev/null +++ b/acl-2.2.49-setfacl-restore.patch @@ -0,0 +1,27 @@ +diff --git a/setfacl/setfacl.c b/setfacl/setfacl.c +index 7142af0..23784a7 100644 +--- a/setfacl/setfacl.c ++++ b/setfacl/setfacl.c +@@ -125,7 +125,7 @@ restore( + uid_t uid; + gid_t gid; + mode_t mask, flags; +- struct do_set_args args; ++ struct do_set_args args = { 0 }; + int line = 0, backup_line; + int error, status = 0; + int chmod_required = 0; +diff --git a/test/misc.test b/test/misc.test +index e6140da..a910bd0 100644 +--- a/test/misc.test ++++ b/test/misc.test +@@ -424,3 +424,9 @@ Now, chmod should change the group_obj entry + > + + $ rmdir d ++ ++Malformed restore file ++ ++ $ echo "# owner: root" > f ++ $ setfacl --restore=f 2>&1 ++ >setfacl: f: No filename found in line 0, aborting diff --git a/acl-2.2.49-setfacl-walk.patch b/acl-2.2.49-setfacl-walk.patch new file mode 100644 index 0000000..d797fb0 --- /dev/null +++ b/acl-2.2.49-setfacl-walk.patch @@ -0,0 +1,30 @@ +diff --git a/setfacl/setfacl.c b/setfacl/setfacl.c +index 091b9cc..be34e69 100644 +--- a/setfacl/setfacl.c ++++ b/setfacl/setfacl.c +@@ -76,7 +76,7 @@ struct option long_options[] = { + const char *progname; + const char *cmd_line_options, *cmd_line_spec; + +-int walk_flags = WALK_TREE_DEREFERENCE; ++int walk_flags = WALK_TREE_DEREFERENCE_TOPLEVEL; + int opt_recalculate; /* recalculate mask entry (0=default, 1=yes, -1=no) */ + int opt_promote; /* promote access ACL to default ACL */ + int opt_test; /* do not write to the file system. +@@ -580,13 +580,14 @@ int main(int argc, char *argv[]) + break; + + case 'L': /* follow symlinks */ +- walk_flags |= WALK_TREE_LOGICAL; ++ walk_flags |= WALK_TREE_LOGICAL | WALK_TREE_DEREFERENCE; + walk_flags &= ~WALK_TREE_PHYSICAL; + break; + + case 'P': /* do not follow symlinks */ + walk_flags |= WALK_TREE_PHYSICAL; +- walk_flags &= ~WALK_TREE_LOGICAL; ++ walk_flags &= ~(WALK_TREE_LOGICAL | WALK_TREE_DEREFERENCE | ++ WALK_TREE_DEREFERENCE_TOPLEVEL); + break; + + case 't': /* test mode */ diff --git a/acl-2.2.49-tests.patch b/acl-2.2.49-tests.patch new file mode 100644 index 0000000..d48b998 --- /dev/null +++ b/acl-2.2.49-tests.patch @@ -0,0 +1,136 @@ +diff --git a/test/cp.test b/test/cp.test +index a888c04..4a75ffd 100644 +--- a/test/cp.test ++++ b/test/cp.test +@@ -9,7 +9,7 @@ The cp utility should only copy ACLs if `-p' is given. + > -rw-rw-r--+ + + $ cp f g +- $ ls -l g | awk -- '{ print $1 }' ++ $ ls -l g | awk -- '{ print $1 }' | sed 's/\\.$//' + > -rw-r--r-- + + $ rm g +diff --git a/test/getfacl-recursive.test b/test/getfacl-recursive.test +index b88c211..a72192e 100644 +--- a/test/getfacl-recursive.test ++++ b/test/getfacl-recursive.test +@@ -1,5 +1,6 @@ + Tests for proper path recursion + ++ $ umask 022 + $ mkdir -p 1/2/3 + $ mkdir 1/link + $ touch 1/link/file +diff --git a/test/misc.test b/test/misc.test +index 7c62c64..e6140da 100644 +--- a/test/misc.test ++++ b/test/misc.test +@@ -253,7 +253,7 @@ Add some users and groups + Symlink in directory with default ACL? + + $ ln -s d d/l +- $ ls -dl d/l | awk '{print $1}' ++ $ ls -dl d/l | awk '{print $1}' | sed 's/\\.$//' + > lrwxrwxrwx + + $ ls -dl -L d/l | awk '{print $1}' +@@ -342,7 +342,7 @@ Remove the default ACL + Reset to base entries + + $ setfacl -b d +- $ ls -dl d | awk '{print $1}' ++ $ ls -dl d | awk '{print $1}' | sed 's/\\.$//' + > drwxr-x--- + + $ getfacl --omit-header d +@@ -354,7 +354,7 @@ Reset to base entries + Now, chmod should change the group_obj entry + + $ chmod 775 d +- $ ls -dl d | awk '{print $1}' ++ $ ls -dl d | awk '{print $1}' | sed 's/\\.$//' + > drwxrwxr-x + + $ getfacl --omit-header d +diff --git a/test/root/permissions.test b/test/root/permissions.test +index afaf5f0..4880bd2 100644 +--- a/test/root/permissions.test ++++ b/test/root/permissions.test +@@ -20,7 +20,7 @@ defined permissions. + $ cd d + $ umask 027 + $ touch f +- $ ls -l f | awk -- '{ print $1, $3, $4 }' ++ $ ls -l f | awk -- '{ print $1, $3, $4 }' | sed 's/---\\./---/' + > -rw-r----- root root + + +@@ -40,7 +40,7 @@ Now, change the ownership of the file to bin:bin and verify that this + gives user bin write access. + + $ chown bin:bin f +- $ ls -l f | awk -- '{ print $1, $3, $4 }' ++ $ ls -l f | awk -- '{ print $1, $3, $4 }' | sed 's/---\\./---/' + > -rw-r----- bin bin + $ su bin + $ echo bin >> f +@@ -257,12 +257,12 @@ directories if the file has an ACL and only CAP_FOWNER would grant them. + $ mkdir -m 600 x + $ chown daemon:daemon x + $ echo j > x/j +- $ ls -l x/j | awk -- '{ print $1, $3, $4 }' ++ $ ls -l x/j | awk -- '{ print $1, $3, $4 }' | sed 's/---\\./---/' + > -rw-r----- root root + + $ setfacl -m u:daemon:r x + +- $ ls -l x/j | awk -- '{ print $1, $3, $4 }' ++ $ ls -l x/j | awk -- '{ print $1, $3, $4 }' | sed 's/---\\./---/' + > -rw-r----- root root + (With the bug this gives: `ls: x/j: Permission denied'.) + +diff --git a/test/root/restore.test b/test/root/restore.test +index 6003cd4..5dbf73c 100644 +--- a/test/root/restore.test ++++ b/test/root/restore.test +@@ -17,7 +17,7 @@ Ensure setuid bit is restored when the owner changes + $ chown bin passwd + $ chmod u+s passwd + $ setfacl --restore passwd.acl +- $ ls -dl passwd | awk '{print $1 " " $3 " " $4}' ++ $ ls -dl passwd | awk '{print $1 " " $3 " " $4}' | sed 's/\\. root/ root/' + > -rwsr-xr-x root root + + $ rm passwd passwd.acl +diff --git a/test/root/setfacl.test b/test/root/setfacl.test +index 630e9fb..dd7fe08 100644 +--- a/test/root/setfacl.test ++++ b/test/root/setfacl.test +@@ -8,7 +8,7 @@ Setfacl utility tests. Run these tests on a filesystem with ACL support. + $ sg bin + $ umask 027 + $ touch g +- $ ls -dl g | awk '{print $1}' ++ $ ls -dl g | awk '{print $1}' | sed 's/\\.$//' + > -rw-r----- + + $ setfacl -m m:- g +diff --git a/test/sbits-restore.test b/test/sbits-restore.test +index e5e4fb2..abdb58a 100644 +--- a/test/sbits-restore.test ++++ b/test/sbits-restore.test +@@ -13,10 +13,10 @@ Ensure setting of SUID/SGID/sticky via --restore works + $ touch d/g + $ touch d/u + $ setfacl --restore d.acl +- $ ls -dl d | awk '{print $1}' ++ $ ls -dl d | awk '{print $1}' | sed 's/\\.$//' + > drwxr-xr-t +- $ ls -dl d/u | awk '{print $1}' ++ $ ls -dl d/u | awk '{print $1}' | sed 's/\\.$//' + > -rwSr--r-- +- $ ls -dl d/g | awk '{print $1}' ++ $ ls -dl d/g | awk '{print $1}' | sed 's/\\.$//' + > -rw-r-Sr-- + $ rm -Rf d diff --git a/acl.spec b/acl.spec index ca33309..102b4a7 100644 --- a/acl.spec +++ b/acl.spec @@ -1,28 +1,37 @@ Summary: Access control list utilities Name: acl -Version: 2.3.2 -Release: 5%{?dist} +Version: 2.2.49 +Release: 9%{?dist} +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: gawk -BuildRequires: gcc BuildRequires: gettext BuildRequires: libattr-devel BuildRequires: libtool -BuildRequires: make -BuildRequires: perl(FileHandle) -BuildRequires: gnupg2 -Requires: libacl%{?_isa} = %{version}-%{release} -Source0: https://download-mirror.savannah.gnu.org/releases/acl/acl-%{version}.tar.gz -Source1: https://download-mirror.savannah.gnu.org/releases/acl/acl-%{version}.tar.gz.sig -# Retreived from https://savannah.nongnu.org/people/viewgpg.php?user_id=15000 -# Source2: agruen-key.gpg -# Retrieved from https://savannah.nongnu.org/people/viewgpg.php?user_id=42032 -Source2: vapier-key.gpg +Requires: libacl = %{version}-%{release} +Source: http://download.savannah.gnu.org/releases-noredirect/acl/acl-%{version}.src.tar.gz +Patch1: acl-2.2.39-build.patch -# avoid permission denied problem with LD_PRELOAD in the test-suite -Patch1: 0001-acl-2.2.53-test-runwrapper.patch +# bz #488674 +Patch2: acl-2.2.49-setfacl-walk.patch -License: GPL-2.0-or-later AND LGPL-2.1-or-later -URL: https://savannah.nongnu.org/projects/acl +# bz #467936 +Patch3: acl-2.2.49-bz467936.patch + +# prepare the test-suite for SELinux and arbitrary umask +Patch4: acl-2.2.49-tests.patch + +# bz #576550 +Patch5: acl-2.2.49-setfacl-restore.patch + +# fix typos in setfacl(1) man page (#675451) +Patch6: acl-2.2.49-bz675451.patch + +# add function acl_extended_file_nofollow() (#692982) +Patch7: acl-2.2.49-bz692982.patch + +License: GPLv2+ +Group: System Environment/Base +URL: http://oss.sgi.com/projects/xfs/ %description This package contains the getfacl and setfacl utilities needed for @@ -30,8 +39,10 @@ manipulating access control lists. %package -n libacl Summary: Dynamic library for access control list support -License: LGPL-2.1-or-later -Conflicts: filesystem < 3 +License: LGPLv2+ +Group: System Environment/Libraries +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig %description -n libacl This package contains the libacl.so dynamic library which contains @@ -39,298 +50,101 @@ the POSIX 1003.1e draft standard 17 functions for manipulating access control lists. %package -n libacl-devel -Summary: Files needed for building programs with libacl -License: LGPL-2.1-or-later -Requires: libacl%{?_isa} = %{version}-%{release}, libattr-devel +Summary: Access control list static libraries and headers +License: LGPLv2+ +Group: Development/Libraries +Requires: libacl = %{version}-%{release}, libattr-devel %description -n libacl-devel -This package contains header files and documentation needed to develop +This package contains static libraries and header files needed to develop programs which make use of the access control list programming interface defined in POSIX 1003.1e draft standard 17. %prep -%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' -%autosetup -p1 +%setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 %build -%configure +touch .census +# acl abuses libexecdir +%configure --libdir=/%{_lib} --libexecdir=%{_libdir} # uncomment to turn on optimizations # sed -i 's/-O2/-O0/' libtool include/builddefs # unset CFLAGS -%make_build +make %{?_smp_mflags} LIBTOOL="libtool --tag=CC" %check -# make the test-suite use the just built library (instead of the system one) -export LD_LIBRARY_PATH="${RPM_BUILD_ROOT}%{_libdir}:${LD_LIBRARY_PATH}" - -if ./setfacl -m "u:$(id -u):rwx" .; then - if test 0 = "$(id -u)"; then - # test/root/permissions.test requires the 'daemon' user to be a member - # of the 'bin' group in order not to fail. Prevent the test from - # running if we detect that its requirements are not met (#1085389). - if id -nG daemon | { ! grep bin >/dev/null; }; then - sed -e 's|test/root/permissions.test||' \ - -i test/Makemodule.am Makefile.in Makefile - fi - - # test/root/setfacl.test fails if 'bin' user cannot access build dir - if ! runuser -u bin -- "${PWD}/setfacl" --version; then - sed -e 's|test/root/setfacl.test||' \ - -i test/Makemodule.am Makefile.in Makefile - fi +if ./setfacl/setfacl -m u:`id -u`:rwx .; then + make tests || exit $? + if test 0 = `id -u`; then + make root-tests || exit $? fi - - # run the upstream test-suite - %make_build check || exit $? else echo '*** ACLs are probably not supported by the file system,' \ 'the test-suite will NOT run ***' fi %install -%make_install +rm -rf $RPM_BUILD_ROOT +make install DESTDIR=$RPM_BUILD_ROOT +make install-dev DESTDIR=$RPM_BUILD_ROOT +make install-lib DESTDIR=$RPM_BUILD_ROOT # get rid of libacl.a and libacl.la +rm -f $RPM_BUILD_ROOT/%{_lib}/libacl.a +rm -f $RPM_BUILD_ROOT/%{_lib}/libacl.la rm -f $RPM_BUILD_ROOT%{_libdir}/libacl.a rm -f $RPM_BUILD_ROOT%{_libdir}/libacl.la -chmod 0755 $RPM_BUILD_ROOT/%{_libdir}/libacl.so.*.*.* - -# drop already installed documentation, we will use an RPM macro to install it -rm -rf $RPM_BUILD_ROOT%{_docdir}/%{name}* +# fix links to shared libs and permissions +rm -f $RPM_BUILD_ROOT%{_libdir}/libacl.so +ln -sf ../../%{_lib}/libacl.so $RPM_BUILD_ROOT/%{_libdir}/libacl.so +chmod 0755 $RPM_BUILD_ROOT/%{_lib}/libacl.so.*.*.* %find_lang %{name} -%ldconfig_scriptlets -n libacl +%clean +rm -rf $RPM_BUILD_ROOT + +%post -n libacl -p /sbin/ldconfig + +%postun -n libacl -p /sbin/ldconfig %files -f %{name}.lang -%license doc/COPYING* +%defattr(-,root,root,-) %{_bindir}/chacl %{_bindir}/getfacl %{_bindir}/setfacl +%{_datadir}/doc/acl-%{version} %{_mandir}/man1/chacl.1* %{_mandir}/man1/getfacl.1* %{_mandir}/man1/setfacl.1* %{_mandir}/man5/acl.5* %files -n libacl-devel +%defattr(-,root,root,-) +/%{_lib}/libacl.so %{_libdir}/libacl.so -%{_libdir}/pkgconfig/*.pc %{_includedir}/acl %{_includedir}/sys/acl.h %{_mandir}/man3/acl_* %files -n libacl -%{_libdir}/libacl.so.* +%defattr(-,root,root,-) +/%{_lib}/libacl.so.* %changelog -* Fri Jan 16 2026 Fedora Release Engineering - 2.3.2-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_44_Mass_Rebuild - -* Wed Jul 23 2025 Fedora Release Engineering - 2.3.2-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Thu Jan 16 2025 Fedora Release Engineering - 2.3.2-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Wed Jul 17 2024 Fedora Release Engineering - 2.3.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Wed Jan 24 2024 Lukáš Zaoral - 2.3.2-1 -- rebase to latest version (rhbz#2260000) - -* Mon Jan 22 2024 Fedora Release Engineering - 2.3.1-13 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Fri Jan 19 2024 Fedora Release Engineering - 2.3.1-12 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Fri Dec 01 2023 Lukáš Zaoral - 2.3.1-11 -- make acl compatible with -D_FORTIFY_SOURCE=3 (rhbz#2249839) - -* Fri Oct 06 2023 Lukáš Zaoral - 2.3.1-10 -- preserve failed setfacl return code (RHEL-3909) -- make the license tag more precise - -* Mon Sep 11 2023 Temuri Doghonadze - 2.3.1-9 -- Backport Georgian locale from git -- Note, it will not be needed after release of new version of acl - -* Wed Jul 19 2023 Fedora Release Engineering - 2.3.1-8 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Tue Mar 14 2023 Lukáš Zaoral - 2.3.1-7 -- migrated to SPDX license - -* Thu Jan 26 2023 Lukáš Zaoral - 2.3.1-6 -- acl is not yet compatible with -D_FORTIFY_SOURCE=3 - -* Wed Jan 18 2023 Fedora Release Engineering - 2.3.1-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Wed Jul 20 2022 Fedora Release Engineering - 2.3.1-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Wed Jan 19 2022 Fedora Release Engineering - 2.3.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Wed Jul 21 2021 Fedora Release Engineering - 2.3.1-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Tue Mar 16 2021 Kamil Dudka - 2.3.1-1 -- new upstream release - -* Fri Mar 12 2021 Kamil Dudka - 2.3.0-1 -- new upstream release - -* Mon Jan 25 2021 Fedora Release Engineering - 2.2.53-10 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Mon Aug 31 2020 Kamil Dudka 2.2.53-9 -- make __acl_create_entry_obj() work with LTO enabled (#1873975) - -* Fri Jul 31 2020 Fedora Release Engineering - 2.2.53-8 -- Second attempt - Rebuilt for - https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Mon Jul 27 2020 Fedora Release Engineering - 2.2.53-7 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Wed Jun 03 2020 Tom Stellard - 2.2.53-6 -- Spec file cleanups and build fix -- Add BuildRequires: perl-FileHandle to fix make check -- Add BuildRequres: gcc [1] -- Use make_build [2] and make_install[3] macros -- [1] https://docs.fedoraproject.org/en-US/packaging-guidelines/C_and_C++/#_buildrequires_and_requires -- [2] https://docs.fedoraproject.org/en-US/packaging-guidelines/#_parallel_make -- [3] https://docs.fedoraproject.org/en-US/packaging-guidelines/#_why_the_makeinstall_macro_should_not_be_used - -* Tue Jan 28 2020 Fedora Release Engineering - 2.2.53-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Wed Jul 24 2019 Fedora Release Engineering - 2.2.53-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Thu Jan 31 2019 Fedora Release Engineering - 2.2.53-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Thu Jul 12 2018 Fedora Release Engineering - 2.2.53-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Mon Jul 02 2018 Kamil Dudka 2.2.53-1 -- new upstream release - -* Tue Mar 13 2018 Kamil Dudka 2.2.52-21 -- update link to POSIX.1e draft in acl(5) man page (#1510527) - -* Wed Feb 07 2018 Fedora Release Engineering - 2.2.52-20 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Sun Feb 04 2018 Igor Gnatenko - 2.2.52-19 -- Switch to %%ldconfig_scriptlets - -* Wed Aug 02 2017 Fedora Release Engineering - 2.2.52-18 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild - -* Wed Jul 26 2017 Fedora Release Engineering - 2.2.52-17 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Mon Jul 24 2017 Kamil Dudka 2.2.52-16 -- fix test-suite failure with perl-5.26.0 (#1473845) -- update URL of the upstream source tarball - -* Thu May 18 2017 Kamil Dudka 2.2.52-15 -- setfacl.1: document the meaning of '-' in perms (#1337039) -- avoid failure of %%check when building as root (#1085389) -- apply patches automatically to ease maintenance - -* Wed May 17 2017 Kamil Dudka 2.2.52-14 -- drop obsolete BuildRoot and Group tags -- fix spurious acl_check() failure on setfacl --restore (#1451826) - -* Fri Feb 10 2017 Fedora Release Engineering - 2.2.52-13 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Fri Feb 03 2017 Kamil Dudka 2.2.52-12 -- update project URL (#1418474) - -* Wed Feb 03 2016 Fedora Release Engineering - 2.2.52-11 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Fri Aug 14 2015 Adam Jackson 2.2.52-10 -- Remove bizarre 12 year old libtool invocation workaround that prevented - hardened cflags working - -* Tue Jun 16 2015 Fedora Release Engineering - 2.2.52-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Sat Feb 21 2015 Till Maas - 2.2.52-8 -- Rebuilt for - https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code - -* Fri Aug 15 2014 Fedora Release Engineering - 2.2.52-7 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild - -* Fri Jul 11 2014 Tom Callaway - 2.2.52-6 -- tag licenses properly - -* Sat Jun 07 2014 Fedora Release Engineering - 2.2.52-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Fri Nov 01 2013 Kamil Dudka 2.2.52-4 -- fix SIGSEGV of getfacl -e on overly long group name - -* Fri Aug 09 2013 Kamil Dudka 2.2.52-3 -- drop a docdir-related patch to fix a packaging failure (#993659) - -* Sat Aug 03 2013 Fedora Release Engineering - 2.2.52-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild - -* Mon May 20 2013 Kamil Dudka 2.2.52-1 -- new upstream release, drop applied patches -- drop workarounds that are no longer necessary - -* Wed Feb 13 2013 Fedora Release Engineering - 2.2.51-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild - -* Tue Aug 28 2012 Kamil Dudka 2.2.51-8 -- fix specfile issues reported by the fedora-review script - -* Wed Jul 18 2012 Fedora Release Engineering - 2.2.51-7 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild - -* Wed May 02 2012 Kamil Dudka 2.2.51-6 -- do not mention static libraries in the summary of libacl{,-devel} (#817952) - -* Wed Jan 25 2012 Harald Hoyer 2.2.51-5 -- add filesystem guard - -* Wed Jan 25 2012 Harald Hoyer 2.2.51-4 -- install everything in /usr - https://fedoraproject.org/wiki/Features/UsrMove - -* Thu Jan 12 2012 Fedora Release Engineering - 2.2.51-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild - -* Fri May 06 2011 Kamil Dudka 2.2.51-2 -- update project URL (#699058) - -* Thu Apr 21 2011 Kamil Dudka 2.2.51-1 -- new upstream release - -* Tue Apr 19 2011 Kamil Dudka 2.2.50-1 -- new upstream release - -* Wed Apr 06 2011 Kamil Dudka 2.2.49-11 -- add function acl_extended_file_nofollow() (#692982) - -* Tue Mar 29 2011 Kamil Dudka 2.2.49-10 +* Fri Jul 08 2011 Kamil Dudka 2.2.49-9 - fix typos in setfacl(1) man page (#675451) - -* Mon Feb 07 2011 Fedora Release Engineering - 2.2.49-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild +- add function acl_extended_file_nofollow() (#692982) * Thu Jul 08 2010 Kamil Dudka 2.2.49-8 - remove dependency of libacl-devel on nfs-utils-lib and openldap diff --git a/agruen-key.gpg b/agruen-key.gpg deleted file mode 100644 index 2e22cc2..0000000 --- a/agruen-key.gpg +++ /dev/null @@ -1,476 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- - -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 -=C+9j ------END PGP PUBLIC KEY BLOCK----- \ No newline at end of file diff --git a/sources b/sources index f92416f..71c84af 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -SHA512 (acl-2.3.2.tar.gz) = 31aeb39958d8af5d08933dd3a89333a41025c3eb49fc461fa3c291caca51dad575ec13faeb7deba9b3c2ebf7615be7d45e2b78e50d4f83d8ec933c95931a7682 -SHA512 (acl-2.3.2.tar.gz.sig) = fcd05951bba9d99bceb6dee409ae9e186808c7106f68f7d8e31959f75e0f5b01e18b87c4c7340cb4c168734b596468c710342a7d8c5e27c9fc55f1fcb57f9625 +181445894cca986da9ae0099d5ce2d08 acl-2.2.49.src.tar.gz diff --git a/vapier-key.gpg b/vapier-key.gpg deleted file mode 100644 index 1beefff..0000000 --- a/vapier-key.gpg +++ /dev/null @@ -1,724 +0,0 @@ ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2.0.22 (GNU/Linux) - -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 -XkRSpu2IWY1HGR7q3i8hJf2o4Offzthpuc2ezw== -=BP++ ------END PGP PUBLIC KEY BLOCK----- \ No newline at end of file