114721edaSChris D. Faulhaber /* 214721edaSChris D. Faulhaber * Copyright (c) 2001 Chris D. Faulhaber 314721edaSChris D. Faulhaber * All rights reserved. 414721edaSChris D. Faulhaber * 514721edaSChris D. Faulhaber * Redistribution and use in source and binary forms, with or without 614721edaSChris D. Faulhaber * modification, are permitted provided that the following conditions 714721edaSChris D. Faulhaber * are met: 814721edaSChris D. Faulhaber * 1. Redistributions of source code must retain the above copyright 914721edaSChris D. Faulhaber * notice, this list of conditions and the following disclaimer. 1014721edaSChris D. Faulhaber * 2. Redistributions in binary form must reproduce the above copyright 1114721edaSChris D. Faulhaber * notice, this list of conditions and the following disclaimer in the 1214721edaSChris D. Faulhaber * documentation and/or other materials provided with the distribution. 1314721edaSChris D. Faulhaber * 1414721edaSChris D. Faulhaber * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1514721edaSChris D. Faulhaber * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1614721edaSChris D. Faulhaber * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1714721edaSChris D. Faulhaber * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE VOICES IN HIS HEAD BE 1814721edaSChris D. Faulhaber * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1914721edaSChris D. Faulhaber * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2014721edaSChris D. Faulhaber * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2114721edaSChris D. Faulhaber * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2214721edaSChris D. Faulhaber * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2314721edaSChris D. Faulhaber * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2414721edaSChris D. Faulhaber * POSSIBILITY OF SUCH DAMAGE. 2514721edaSChris D. Faulhaber * 2614721edaSChris D. Faulhaber * $FreeBSD$ 2714721edaSChris D. Faulhaber */ 2814721edaSChris D. Faulhaber 2914721edaSChris D. Faulhaber #include <sys/types.h> 3014721edaSChris D. Faulhaber #include <sys/acl.h> 3114721edaSChris D. Faulhaber 3214721edaSChris D. Faulhaber #include <errno.h> 3314721edaSChris D. Faulhaber 3414721edaSChris D. Faulhaber /* 3514721edaSChris D. Faulhaber * acl_calc_mask() calculates and set the permissions associated 3614721edaSChris D. Faulhaber * with the ACL_MASK ACL entry. If the ACL already contains an 3714721edaSChris D. Faulhaber * ACL_MASK entry, its permissions shall be overwritten; if not, 3814721edaSChris D. Faulhaber * one shall be added. 3914721edaSChris D. Faulhaber */ 4014721edaSChris D. Faulhaber int 4114721edaSChris D. Faulhaber acl_calc_mask(acl_t *acl_p) 4214721edaSChris D. Faulhaber { 4314721edaSChris D. Faulhaber acl_t acl_new; 4414721edaSChris D. Faulhaber int group_obj, i, mask_mode, mask_num, other_obj, user_obj; 4514721edaSChris D. Faulhaber 4614721edaSChris D. Faulhaber /* check args */ 4714721edaSChris D. Faulhaber if (!acl_p || !*acl_p || ((*acl_p)->acl_cnt < 3) || 4814721edaSChris D. Faulhaber ((*acl_p)->acl_cnt > ACL_MAX_ENTRIES)) { 4914721edaSChris D. Faulhaber errno = EINVAL; 5014721edaSChris D. Faulhaber return -1; 5114721edaSChris D. Faulhaber } 5214721edaSChris D. Faulhaber 5314721edaSChris D. Faulhaber acl_new = acl_dup(*acl_p); 5414721edaSChris D. Faulhaber if (!acl_new) 5514721edaSChris D. Faulhaber return -1; 5614721edaSChris D. Faulhaber 5714721edaSChris D. Faulhaber user_obj = group_obj = other_obj = mask_mode = 0; 5814721edaSChris D. Faulhaber mask_num = -1; 5914721edaSChris D. Faulhaber 6014721edaSChris D. Faulhaber /* gather permissions and find a mask entry */ 6114721edaSChris D. Faulhaber for (i = 0; i < acl_new->acl_cnt; i++) { 6214721edaSChris D. Faulhaber switch(acl_new->acl_entry[i].ae_tag) { 6314721edaSChris D. Faulhaber case ACL_USER_OBJ: 6414721edaSChris D. Faulhaber user_obj++; 6514721edaSChris D. Faulhaber break; 6614721edaSChris D. Faulhaber case ACL_OTHER: 6714721edaSChris D. Faulhaber other_obj++; 6814721edaSChris D. Faulhaber break; 6914721edaSChris D. Faulhaber case ACL_GROUP_OBJ: 7014721edaSChris D. Faulhaber group_obj++; 7114721edaSChris D. Faulhaber /* FALLTHROUGH */ 7214721edaSChris D. Faulhaber case ACL_GROUP: 7314721edaSChris D. Faulhaber case ACL_USER: 7414721edaSChris D. Faulhaber mask_mode |= 7514721edaSChris D. Faulhaber acl_new->acl_entry[i].ae_perm & ACL_PERM_BITS; 7614721edaSChris D. Faulhaber break; 7714721edaSChris D. Faulhaber case ACL_MASK: 7814721edaSChris D. Faulhaber mask_num = i; 7914721edaSChris D. Faulhaber break; 8014721edaSChris D. Faulhaber default: 8114721edaSChris D. Faulhaber errno = EINVAL; 8214721edaSChris D. Faulhaber acl_free(acl_new); 8314721edaSChris D. Faulhaber return -1; 8414721edaSChris D. Faulhaber /* NOTREACHED */ 8514721edaSChris D. Faulhaber } 8614721edaSChris D. Faulhaber } 8714721edaSChris D. Faulhaber if ((user_obj != 1) || (group_obj != 1) || (other_obj != 1)) { 8814721edaSChris D. Faulhaber errno = EINVAL; 8914721edaSChris D. Faulhaber acl_free(acl_new); 9014721edaSChris D. Faulhaber return -1; 9114721edaSChris D. Faulhaber } 9214721edaSChris D. Faulhaber /* if a mask entry already exists, overwrite the perms */ 9314721edaSChris D. Faulhaber if (mask_num != -1) { 9414721edaSChris D. Faulhaber acl_new->acl_entry[mask_num].ae_perm = mask_mode; 9514721edaSChris D. Faulhaber } else { 9614721edaSChris D. Faulhaber /* if no mask exists, check acl_cnt... */ 9714721edaSChris D. Faulhaber if (acl_new->acl_cnt == ACL_MAX_ENTRIES) { 9814721edaSChris D. Faulhaber errno = EINVAL; 9914721edaSChris D. Faulhaber acl_free(acl_new); 10014721edaSChris D. Faulhaber return -1; 10114721edaSChris D. Faulhaber } 10214721edaSChris D. Faulhaber /* ...and add the mask entry */ 10314721edaSChris D. Faulhaber acl_new->acl_entry[acl_new->acl_cnt].ae_tag = ACL_MASK; 10414721edaSChris D. Faulhaber acl_new->acl_entry[acl_new->acl_cnt].ae_id = 0; 10514721edaSChris D. Faulhaber acl_new->acl_entry[acl_new->acl_cnt].ae_perm = mask_mode; 10614721edaSChris D. Faulhaber acl_new->acl_cnt++; 10714721edaSChris D. Faulhaber } 10814721edaSChris D. Faulhaber 10914721edaSChris D. Faulhaber if (acl_valid(acl_new) == -1) { 11014721edaSChris D. Faulhaber errno = EINVAL; 11114721edaSChris D. Faulhaber acl_free(acl_new); 11214721edaSChris D. Faulhaber return -1; 11314721edaSChris D. Faulhaber } 11414721edaSChris D. Faulhaber 11514721edaSChris D. Faulhaber **acl_p = *acl_new; 11614721edaSChris D. Faulhaber acl_free(acl_new); 11714721edaSChris D. Faulhaber 11814721edaSChris D. Faulhaber return 0; 11914721edaSChris D. Faulhaber } 120