mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-25 16:13:17 +00:00
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
This commit is contained in:
parent
959174ee6c
commit
60bdc14e90
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=118407
@ -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.
|
||||
@ -472,6 +472,64 @@ acl_posix1e_perms_to_mode(struct acl_entry *acl_user_obj_entry,
|
||||
return (mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -559,6 +617,31 @@ acl_posix1e_check(struct acl *acl)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -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.
|
||||
@ -472,6 +472,64 @@ acl_posix1e_perms_to_mode(struct acl_entry *acl_user_obj_entry,
|
||||
return (mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -559,6 +617,31 @@ acl_posix1e_check(struct acl *acl)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -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.
|
||||
@ -472,6 +472,64 @@ acl_posix1e_perms_to_mode(struct acl_entry *acl_user_obj_entry,
|
||||
return (mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -559,6 +617,31 @@ acl_posix1e_check(struct acl *acl)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -116,6 +116,15 @@ typedef struct acl_t_struct *acl_t;
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
/*
|
||||
* POSIX.1e ACLs are capable of expressing the read, write, and execute
|
||||
* bits of the POSIX mode field. We provide two masks: one that defines
|
||||
* the bits the ACL will replace in the mode, and the other that defines
|
||||
* the bits that must be preseved when an ACL is updating a mode.
|
||||
*/
|
||||
#define ACL_OVERRIDE_MASK (S_IRWXU | S_IRWXG | S_IRWXO)
|
||||
#define ACL_PRESERVE_MASK (~ACL_OVERRIDE_MASK)
|
||||
|
||||
/*
|
||||
* Storage for ACLs and support structures.
|
||||
*/
|
||||
@ -123,12 +132,25 @@ typedef struct acl_t_struct *acl_t;
|
||||
MALLOC_DECLARE(M_ACL);
|
||||
#endif
|
||||
|
||||
acl_perm_t acl_posix1e_mode_to_perm(acl_tag_t tag, mode_t mode);
|
||||
/*
|
||||
* File system independent code to move back and forth between POSIX mode
|
||||
* and POSIX.1e ACL representations.
|
||||
*/
|
||||
acl_perm_t acl_posix1e_mode_to_perm(acl_tag_t tag, mode_t mode);
|
||||
struct acl_entry acl_posix1e_mode_to_entry(acl_tag_t tag, uid_t uid,
|
||||
gid_t gid, mode_t mode);
|
||||
mode_t acl_posix1e_perms_to_mode(struct acl_entry *acl_user_obj_entry,
|
||||
struct acl_entry *acl_group_obj_entry, struct acl_entry *acl_other_entry);
|
||||
int acl_posix1e_check(struct acl *acl);
|
||||
gid_t gid, mode_t mode);
|
||||
mode_t acl_posix1e_perms_to_mode(
|
||||
struct acl_entry *acl_user_obj_entry,
|
||||
struct acl_entry *acl_group_obj_entry,
|
||||
struct acl_entry *acl_other_entry);
|
||||
mode_t acl_posix1e_acl_to_mode(struct acl *acl);
|
||||
mode_t acl_posix1e_newfilemode(mode_t cmode,
|
||||
struct acl *dacl);
|
||||
|
||||
/*
|
||||
* File system independent syntax check for a POSIX.1e ACL.
|
||||
*/
|
||||
int acl_posix1e_check(struct acl *acl);
|
||||
|
||||
#else /* !_KERNEL */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user