1*d81d5b2fSGleb Popov /*- 2*d81d5b2fSGleb Popov * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*d81d5b2fSGleb Popov * 4*d81d5b2fSGleb Popov * Copyright (c) 2021 Gleb Popov 5*d81d5b2fSGleb Popov * All rights reserved. 6*d81d5b2fSGleb Popov * 7*d81d5b2fSGleb Popov * Redistribution and use in source and binary forms, with or without 8*d81d5b2fSGleb Popov * modification, are permitted provided that the following conditions 9*d81d5b2fSGleb Popov * are met: 10*d81d5b2fSGleb Popov * 1. Redistributions of source code must retain the above copyright 11*d81d5b2fSGleb Popov * notice, this list of conditions and the following disclaimer. 12*d81d5b2fSGleb Popov * 2. Redistributions in binary form must reproduce the above copyright 13*d81d5b2fSGleb Popov * notice, this list of conditions and the following disclaimer in the 14*d81d5b2fSGleb Popov * documentation and/or other materials provided with the distribution. 15*d81d5b2fSGleb Popov * 16*d81d5b2fSGleb Popov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*d81d5b2fSGleb Popov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*d81d5b2fSGleb Popov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*d81d5b2fSGleb Popov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*d81d5b2fSGleb Popov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*d81d5b2fSGleb Popov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*d81d5b2fSGleb Popov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*d81d5b2fSGleb Popov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*d81d5b2fSGleb Popov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*d81d5b2fSGleb Popov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*d81d5b2fSGleb Popov * SUCH DAMAGE. 27*d81d5b2fSGleb Popov */ 28*d81d5b2fSGleb Popov /* 29*d81d5b2fSGleb Popov * acl_equiv_mode_np: Check if an ACL can be represented as a mode_t. 30*d81d5b2fSGleb Popov */ 31*d81d5b2fSGleb Popov 32*d81d5b2fSGleb Popov #include <sys/cdefs.h> 33*d81d5b2fSGleb Popov __FBSDID("$FreeBSD$"); 34*d81d5b2fSGleb Popov 35*d81d5b2fSGleb Popov #include <sys/types.h> 36*d81d5b2fSGleb Popov #include <sys/param.h> 37*d81d5b2fSGleb Popov #include <sys/errno.h> 38*d81d5b2fSGleb Popov #include <sys/stat.h> 39*d81d5b2fSGleb Popov #include <sys/acl.h> 40*d81d5b2fSGleb Popov 41*d81d5b2fSGleb Popov #include "acl_support.h" 42*d81d5b2fSGleb Popov 43*d81d5b2fSGleb Popov int 44*d81d5b2fSGleb Popov acl_equiv_mode_np(acl_t acl, mode_t *mode_p) 45*d81d5b2fSGleb Popov { 46*d81d5b2fSGleb Popov mode_t ret_mode = 0; 47*d81d5b2fSGleb Popov 48*d81d5b2fSGleb Popov if (acl == NULL) { 49*d81d5b2fSGleb Popov errno = EINVAL; 50*d81d5b2fSGleb Popov return (-1); 51*d81d5b2fSGleb Popov } 52*d81d5b2fSGleb Popov 53*d81d5b2fSGleb Popov /* Linux returns 0 for ACL returned by acl_init() */ 54*d81d5b2fSGleb Popov if (_acl_brand(acl) == ACL_BRAND_UNKNOWN && acl->ats_acl.acl_cnt == 0) 55*d81d5b2fSGleb Popov return (0); 56*d81d5b2fSGleb Popov 57*d81d5b2fSGleb Popov // TODO: Do we want to handle ACL_BRAND_NFS4 in this function? */ 58*d81d5b2fSGleb Popov if (_acl_brand(acl) != ACL_BRAND_POSIX) 59*d81d5b2fSGleb Popov return (1); 60*d81d5b2fSGleb Popov 61*d81d5b2fSGleb Popov for (int cur_entry = 0; cur_entry < acl->ats_acl.acl_cnt; cur_entry++) { 62*d81d5b2fSGleb Popov acl_entry_t entry = &acl->ats_acl.acl_entry[cur_entry]; 63*d81d5b2fSGleb Popov 64*d81d5b2fSGleb Popov if ((entry->ae_perm & ACL_PERM_BITS) != entry->ae_perm) 65*d81d5b2fSGleb Popov return (1); 66*d81d5b2fSGleb Popov 67*d81d5b2fSGleb Popov switch (entry->ae_tag) { 68*d81d5b2fSGleb Popov case ACL_USER_OBJ: 69*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_READ) 70*d81d5b2fSGleb Popov ret_mode |= S_IRUSR; 71*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_WRITE) 72*d81d5b2fSGleb Popov ret_mode |= S_IWUSR; 73*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_EXECUTE) 74*d81d5b2fSGleb Popov ret_mode |= S_IXUSR; 75*d81d5b2fSGleb Popov break; 76*d81d5b2fSGleb Popov case ACL_GROUP_OBJ: 77*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_READ) 78*d81d5b2fSGleb Popov ret_mode |= S_IRGRP; 79*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_WRITE) 80*d81d5b2fSGleb Popov ret_mode |= S_IWGRP; 81*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_EXECUTE) 82*d81d5b2fSGleb Popov ret_mode |= S_IXGRP; 83*d81d5b2fSGleb Popov break; 84*d81d5b2fSGleb Popov case ACL_OTHER: 85*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_READ) 86*d81d5b2fSGleb Popov ret_mode |= S_IROTH; 87*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_WRITE) 88*d81d5b2fSGleb Popov ret_mode |= S_IWOTH; 89*d81d5b2fSGleb Popov if (entry->ae_perm & ACL_EXECUTE) 90*d81d5b2fSGleb Popov ret_mode |= S_IXOTH; 91*d81d5b2fSGleb Popov break; 92*d81d5b2fSGleb Popov default: 93*d81d5b2fSGleb Popov return (1); 94*d81d5b2fSGleb Popov } 95*d81d5b2fSGleb Popov } 96*d81d5b2fSGleb Popov 97*d81d5b2fSGleb Popov if (mode_p != NULL) 98*d81d5b2fSGleb Popov *mode_p = ret_mode; 99*d81d5b2fSGleb Popov 100*d81d5b2fSGleb Popov return (0); 101*d81d5b2fSGleb Popov } 102