acl_calc_mask.c revision 90781
174432Sjedgar/* 290781Sjedgar * Copyright (c) 2001-2002 Chris D. Faulhaber 374432Sjedgar * All rights reserved. 474432Sjedgar * 574432Sjedgar * Redistribution and use in source and binary forms, with or without 674432Sjedgar * modification, are permitted provided that the following conditions 774432Sjedgar * are met: 874432Sjedgar * 1. Redistributions of source code must retain the above copyright 974432Sjedgar * notice, this list of conditions and the following disclaimer. 1074432Sjedgar * 2. Redistributions in binary form must reproduce the above copyright 1174432Sjedgar * notice, this list of conditions and the following disclaimer in the 1274432Sjedgar * documentation and/or other materials provided with the distribution. 1374432Sjedgar * 1474432Sjedgar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1574432Sjedgar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1674432Sjedgar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1774432Sjedgar * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE VOICES IN HIS HEAD BE 1874432Sjedgar * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1974432Sjedgar * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2074432Sjedgar * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2174432Sjedgar * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2274432Sjedgar * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2374432Sjedgar * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2474432Sjedgar * POSSIBILITY OF SUCH DAMAGE. 2574432Sjedgar * 2674432Sjedgar * $FreeBSD: head/lib/libc/posix1e/acl_calc_mask.c 90781 2002-02-17 20:05:20Z jedgar $ 2774432Sjedgar */ 2874432Sjedgar 2974432Sjedgar#include <sys/types.h> 3075185Stmm#include "namespace.h" 3174432Sjedgar#include <sys/acl.h> 3275185Stmm#include "un-namespace.h" 3374432Sjedgar 3474432Sjedgar#include <errno.h> 3575928Sjedgar#include <stdio.h> 3674432Sjedgar 3774432Sjedgar/* 3875928Sjedgar * acl_calc_mask() (23.4.2): calculate and set the permissions 3975928Sjedgar * associated with the ACL_MASK ACL entry. If the ACL already 4075928Sjedgar * contains an ACL_MASK entry, its permissions shall be 4175928Sjedgar * overwritten; if not, one shall be added. 4274432Sjedgar */ 4374432Sjedgarint 4474432Sjedgaracl_calc_mask(acl_t *acl_p) 4574432Sjedgar{ 4675928Sjedgar struct acl *acl_int, *acl_int_new; 4775928Sjedgar acl_t acl_new; 4875928Sjedgar int i, mask_mode, mask_num; 4974432Sjedgar 5075928Sjedgar /* 5175928Sjedgar * (23.4.2.4) requires acl_p to point to a pointer to a valid ACL. 5275928Sjedgar * Since one of the primary reasons to use this function would be 5375928Sjedgar * to calculate the appropriate mask to obtain a valid ACL, we only 5475928Sjedgar * perform sanity checks here and validate the ACL prior to 5575928Sjedgar * returning. 5675928Sjedgar */ 5790781Sjedgar if (acl_p == NULL || *acl_p == NULL) { 5874432Sjedgar errno = EINVAL; 5990781Sjedgar return (-1); 6074432Sjedgar } 6175928Sjedgar acl_int = &(*acl_p)->ats_acl; 6275928Sjedgar if ((acl_int->acl_cnt < 3) || (acl_int->acl_cnt > ACL_MAX_ENTRIES)) { 6375928Sjedgar errno = EINVAL; 6490781Sjedgar return (-1); 6575928Sjedgar } 6674432Sjedgar 6774432Sjedgar acl_new = acl_dup(*acl_p); 6890781Sjedgar if (acl_new == NULL) 6990781Sjedgar return (-1); 7075928Sjedgar acl_int_new = &acl_new->ats_acl; 7174432Sjedgar 7275928Sjedgar mask_mode = 0; 7374432Sjedgar mask_num = -1; 7474432Sjedgar 7574432Sjedgar /* gather permissions and find a mask entry */ 7675928Sjedgar for (i = 0; i < acl_int_new->acl_cnt; i++) { 7775928Sjedgar switch(acl_int_new->acl_entry[i].ae_tag) { 7875928Sjedgar case ACL_USER: 7975928Sjedgar case ACL_GROUP: 8074432Sjedgar case ACL_GROUP_OBJ: 8174432Sjedgar mask_mode |= 8275928Sjedgar acl_int_new->acl_entry[i].ae_perm & ACL_PERM_BITS; 8374432Sjedgar break; 8474432Sjedgar case ACL_MASK: 8574432Sjedgar mask_num = i; 8674432Sjedgar break; 8774432Sjedgar } 8874432Sjedgar } 8975928Sjedgar 9074432Sjedgar /* if a mask entry already exists, overwrite the perms */ 9175928Sjedgar if (mask_num != -1) 9275928Sjedgar acl_int_new->acl_entry[mask_num].ae_perm = mask_mode; 9375928Sjedgar else { 9474432Sjedgar /* if no mask exists, check acl_cnt... */ 9575928Sjedgar if (acl_int_new->acl_cnt == ACL_MAX_ENTRIES) { 9675928Sjedgar errno = ENOMEM; 9790781Sjedgar return (-1); 9874432Sjedgar } 9974432Sjedgar /* ...and add the mask entry */ 10075928Sjedgar acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_tag = ACL_MASK; 10175928Sjedgar acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_id = 10275928Sjedgar ACL_UNDEFINED_ID; 10375928Sjedgar acl_int_new->acl_entry[acl_int_new->acl_cnt].ae_perm = 10475928Sjedgar mask_mode; 10575928Sjedgar acl_int_new->acl_cnt++; 10674432Sjedgar } 10774432Sjedgar 10874432Sjedgar if (acl_valid(acl_new) == -1) { 10974432Sjedgar errno = EINVAL; 11074432Sjedgar acl_free(acl_new); 11190781Sjedgar return (-1); 11274432Sjedgar } 11374432Sjedgar 11474432Sjedgar **acl_p = *acl_new; 11574432Sjedgar acl_free(acl_new); 11674432Sjedgar 11790781Sjedgar return (0); 11874432Sjedgar} 119