diff options
author | Robert Watson <rwatson@FreeBSD.org> | 2003-08-04 02:13:05 +0000 |
---|---|---|
committer | Robert Watson <rwatson@FreeBSD.org> | 2003-08-04 02:13:05 +0000 |
commit | 60bdc14e9026d94165d0ffcad4e2347f7d3e7121 (patch) | |
tree | 0fff626afb370057db475fbd154ed2df8043303f /sys/kern/kern_acl.c | |
parent | 959174ee6cea1fb7b1cac3a21cb5202a756666d6 (diff) | |
download | src-60bdc14e9026d94165d0ffcad4e2347f7d3e7121.tar.gz src-60bdc14e9026d94165d0ffcad4e2347f7d3e7121.zip |
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
Notes
Notes:
svn path=/head/; revision=118407
Diffstat (limited to 'sys/kern/kern_acl.c')
-rw-r--r-- | sys/kern/kern_acl.c | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/sys/kern/kern_acl.c b/sys/kern/kern_acl.c index 5a60f78ac258..c0bd1ebd5ce2 100644 --- a/sys/kern/kern_acl.c +++ b/sys/kern/kern_acl.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 |