diff options
Diffstat (limited to 'lib/libc/posix1e/acl_strip.c')
-rw-r--r-- | lib/libc/posix1e/acl_strip.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/lib/libc/posix1e/acl_strip.c b/lib/libc/posix1e/acl_strip.c index 1dcdfcd..ae37b38 100644 --- a/lib/libc/posix1e/acl_strip.c +++ b/lib/libc/posix1e/acl_strip.c @@ -14,14 +14,14 @@ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 AUTHOR OR THE VOICES IN HIS HEAD 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. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 <sys/cdefs.h> @@ -31,22 +31,23 @@ __FBSDID("$FreeBSD$"); #include <stdio.h> #include <assert.h> #include <sys/acl.h> +#include <sys/stat.h> #include "acl_support.h" /* - * These two routines from sys/kern/subr_acl_nfs4.c are used by both kernel + * These routines from sys/kern/subr_acl_nfs4.c are used by both kernel * and libc. */ -void acl_nfs4_sync_acl_from_mode(struct acl *aclp, mode_t mode, - int file_owner_id); void acl_nfs4_sync_mode_from_acl(mode_t *_mode, const struct acl *aclp); +void acl_nfs4_trivial_from_mode_libc(struct acl *aclp, int file_owner_id, + int canonical_six); static acl_t -_nfs4_acl_strip_np(const acl_t aclp, int recalculate_mask) +_nfs4_acl_strip_np(const acl_t aclp, int canonical_six) { acl_t newacl; - mode_t mode; + mode_t mode = 0; newacl = acl_init(ACL_MAX_ENTRIES); if (newacl == NULL) { @@ -57,7 +58,7 @@ _nfs4_acl_strip_np(const acl_t aclp, int recalculate_mask) _acl_brand_as(newacl, ACL_BRAND_NFS4); acl_nfs4_sync_mode_from_acl(&mode, &(aclp->ats_acl)); - acl_nfs4_sync_acl_from_mode(&(newacl->ats_acl), mode, -1); + acl_nfs4_trivial_from_mode_libc(&(newacl->ats_acl), mode, canonical_six); return (newacl); } @@ -136,7 +137,7 @@ acl_strip_np(const acl_t aclp, int recalculate_mask) { switch (_acl_brand(aclp)) { case ACL_BRAND_NFS4: - return (_nfs4_acl_strip_np(aclp, recalculate_mask)); + return (_nfs4_acl_strip_np(aclp, 0)); case ACL_BRAND_POSIX: return (_posix1e_acl_strip_np(aclp, recalculate_mask)); @@ -176,10 +177,34 @@ acl_is_trivial_np(const acl_t aclp, int *trivialp) case ACL_BRAND_NFS4: /* - * Calculate trivial ACL - using acl_strip_np - and compare + * If the ACL has more than canonical six entries, + * it's non trivial by definition. + */ + if (aclp->ats_acl.acl_cnt > 6) { + *trivialp = 0; + return (0); + } + + /* + * Calculate trivial ACL - using acl_strip_np(3) - and compare * with the original. */ - tmpacl = acl_strip_np(aclp, 0); + tmpacl = _nfs4_acl_strip_np(aclp, 0); + if (tmpacl == NULL) + return (-1); + + differs = _acl_differs(aclp, tmpacl); + acl_free(tmpacl); + + if (differs == 0) { + *trivialp = 1; + return (0); + } + + /* + * Try again with an old-style, "canonical six" trivial ACL. + */ + tmpacl = _nfs4_acl_strip_np(aclp, 1); if (tmpacl == NULL) return (-1); |