summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_acl_posix1e.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2003-08-04 02:13:05 +0000
committerrwatson <rwatson@FreeBSD.org>2003-08-04 02:13:05 +0000
commit543a0376198dff1ddab776667470525600f2e0b7 (patch)
tree0fff626afb370057db475fbd154ed2df8043303f /sys/kern/subr_acl_posix1e.c
parent0a1cb2dc0dfb51be6c7c68742d54c60e6dfed5ac (diff)
downloadFreeBSD-src-543a0376198dff1ddab776667470525600f2e0b7.zip
FreeBSD-src-543a0376198dff1ddab776667470525600f2e0b7.tar.gz
Move more ACL logic from the UFS code (ufs_acl.c) to the central POSIX.1e
support routines in kern_acl.c: - Define ACL_OVERRIDE_MASK and ACL_PRESERVE_MASK centrally in acl.h: the mode bits that are (and aren't) stored in the ACL. - Add acl_posix1e_acl_to_mode(): given a POSIX.1e extended ACL, generate a compatibility mode (only the bits supported by the POSIX.1e ACL). - acl_posix1e_newfilemode(): Given a requested creation mode and default ACL, calculate the mode for the new file system object (only the bits supported by the POSIX.1e ACL). PR: 50148 Reported by: Ritz, Bruno <bruno_ritz@gmx.ch> Obtained from: TrustedBSD Project
Diffstat (limited to 'sys/kern/subr_acl_posix1e.c')
-rw-r--r--sys/kern/subr_acl_posix1e.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/sys/kern/subr_acl_posix1e.c b/sys/kern/subr_acl_posix1e.c
index 5a60f78..c0bd1eb 100644
--- a/sys/kern/subr_acl_posix1e.c
+++ b/sys/kern/subr_acl_posix1e.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
+ * Copyright (c) 1999, 2000, 2001, 2002, 2003 Robert N. M. Watson
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@@ -473,6 +473,64 @@ acl_posix1e_perms_to_mode(struct acl_entry *acl_user_obj_entry,
}
/*
+ * Utility function to generate a file mode given a complete POSIX.1e
+ * access ACL. Note that if the ACL is improperly formed, this may
+ * result in a panic.
+ */
+mode_t
+acl_posix1e_acl_to_mode(struct acl *acl)
+{
+ struct acl_entry *acl_mask, *acl_user_obj, *acl_group_obj, *acl_other;
+ int i;
+
+ /*
+ * Find the ACL entries relevant to a POSIX permission mode.
+ */
+ acl_user_obj = acl_group_obj = acl_other = acl_mask = NULL;
+ for (i = 0; i < acl->acl_cnt; i++) {
+ switch (acl->acl_entry[i].ae_tag) {
+ case ACL_USER_OBJ:
+ acl_user_obj = &acl->acl_entry[i];
+ break;
+
+ case ACL_GROUP_OBJ:
+ acl_group_obj = &acl->acl_entry[i];
+ break;
+
+ case ACL_OTHER:
+ acl_other = &acl->acl_entry[i];
+ break;
+
+ case ACL_MASK:
+ acl_mask = &acl->acl_entry[i];
+ break;
+
+ case ACL_USER:
+ case ACL_GROUP:
+ break;
+
+ default:
+ panic("acl_posix1e_acl_to_mode: bad ae_tag");
+ }
+ }
+
+ if (acl_user_obj == NULL || acl_group_obj == NULL || acl_other == NULL)
+ panic("acl_posix1e_acl_to_mode: missing base ae_tags");
+
+ /*
+ * POSIX.1e specifies that if there is an ACL_MASK entry, we replace
+ * the mode "group" bits with its permissions. If there isn't, we
+ * use the ACL_GROUP_OBJ permissions.
+ */
+ if (acl_mask != NULL)
+ return (acl_posix1e_perms_to_mode(acl_user_obj, acl_mask,
+ acl_other));
+ else
+ return (acl_posix1e_perms_to_mode(acl_user_obj, acl_group_obj,
+ acl_other));
+}
+
+/*
* Perform a syntactic check of the ACL, sufficient to allow an
* implementing filesystem to determine if it should accept this and
* rely on the POSIX.1e ACL properties.
@@ -560,6 +618,31 @@ acl_posix1e_check(struct acl *acl)
}
/*
+ * Given a requested mode for a new object, and a default ACL, combine
+ * the two to produce a new mode. Be careful not to clear any bits that
+ * aren't intended to be affected by the POSIX.1e ACL. Eventually,
+ * this might also take the cmask as an argument, if we push that down
+ * into per-filesystem-code.
+ */
+mode_t
+acl_posix1e_newfilemode(mode_t cmode, struct acl *dacl)
+{
+ mode_t mode;
+
+ mode = cmode;
+ /*
+ * The current composition policy is that a permission bit must
+ * be set in *both* the ACL and the requested creation mode for
+ * it to appear in the resulting mode/ACL. First clear any
+ * possibly effected bits, then reconstruct.
+ */
+ mode &= ACL_PRESERVE_MASK;
+ mode |= (ACL_OVERRIDE_MASK & cmode & acl_posix1e_acl_to_mode(dacl));
+
+ return (mode);
+}
+
+/*
* These calls wrap the real vnode operations, and are called by the
* syscall code once the syscall has converted the path or file
* descriptor to a vnode (unlocked). The aclp pointer is assumed
OpenPOWER on IntegriCloud