summaryrefslogtreecommitdiffstats
path: root/lib/libc/posix1e/acl_strip.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/posix1e/acl_strip.c')
-rw-r--r--lib/libc/posix1e/acl_strip.c59
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);
OpenPOWER on IntegriCloud