1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 5 * All rights reserved. 6 * 7 * This software was developed by Robert Watson for the TrustedBSD Project. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 /* 31 * acl_set_file -- set a file/directory ACL by name 32 */ 33 34 #include <sys/types.h> 35 #include "namespace.h" 36 #include <sys/acl.h> 37 #include "un-namespace.h" 38 39 #include <errno.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <unistd.h> 43 44 #include "acl_support.h" 45 46 /* 47 * For POSIX.1e-semantic ACLs, do a presort so the kernel doesn't have to 48 * (the POSIX.1e semantic code will reject unsorted ACL submission). If it's 49 * not a semantic that the library knows about, just submit it flat and 50 * assume the caller knows what they're up to. 51 */ 52 int 53 acl_set_file(const char *path_p, acl_type_t type, acl_t acl) 54 { 55 56 if (acl == NULL || path_p == NULL) { 57 errno = EINVAL; 58 return (-1); 59 } 60 type = _acl_type_unold(type); 61 if (_acl_type_not_valid_for_acl(acl, type)) { 62 errno = EINVAL; 63 return (-1); 64 } 65 if (_posix1e_acl(acl, type)) 66 _posix1e_acl_sort(acl); 67 68 acl->ats_cur_entry = 0; 69 70 return (__acl_set_file(path_p, type, &acl->ats_acl)); 71 } 72 73 int 74 acl_set_link_np(const char *path_p, acl_type_t type, acl_t acl) 75 { 76 77 if (acl == NULL || path_p == NULL) { 78 errno = EINVAL; 79 return (-1); 80 } 81 type = _acl_type_unold(type); 82 if (_acl_type_not_valid_for_acl(acl, type)) { 83 errno = EINVAL; 84 return (-1); 85 } 86 if (_posix1e_acl(acl, type)) 87 _posix1e_acl_sort(acl); 88 89 acl->ats_cur_entry = 0; 90 91 return (__acl_set_link(path_p, type, &acl->ats_acl)); 92 } 93 94 int 95 acl_set_fd(int fd, acl_t acl) 96 { 97 98 if (fpathconf(fd, _PC_ACL_NFS4) == 1) 99 return (acl_set_fd_np(fd, acl, ACL_TYPE_NFS4)); 100 101 return (acl_set_fd_np(fd, acl, ACL_TYPE_ACCESS)); 102 } 103 104 int 105 acl_set_fd_np(int fd, acl_t acl, acl_type_t type) 106 { 107 108 if (acl == NULL) { 109 errno = EINVAL; 110 return (-1); 111 } 112 type = _acl_type_unold(type); 113 if (_acl_type_not_valid_for_acl(acl, type)) { 114 errno = EINVAL; 115 return (-1); 116 } 117 if (_posix1e_acl(acl, type)) 118 _posix1e_acl_sort(acl); 119 120 acl->ats_cur_entry = 0; 121 122 return (___acl_set_fd(fd, type, &acl->ats_acl)); 123 } 124 125 /* 126 * acl_set_permset() (23.4.23): sets the permissions of ACL entry entry_d 127 * with the permissions in permset_d 128 */ 129 int 130 acl_set_permset(acl_entry_t entry_d, acl_permset_t permset_d) 131 { 132 133 if (!entry_d) { 134 errno = EINVAL; 135 return (-1); 136 } 137 138 if ((*permset_d & ACL_POSIX1E_BITS) != *permset_d) { 139 if ((*permset_d & ACL_NFS4_PERM_BITS) != *permset_d) { 140 errno = EINVAL; 141 return (-1); 142 } 143 if (!_entry_brand_may_be(entry_d, ACL_BRAND_NFS4)) { 144 errno = EINVAL; 145 return (-1); 146 } 147 _entry_brand_as(entry_d, ACL_BRAND_NFS4); 148 } 149 150 entry_d->ae_perm = *permset_d; 151 152 return (0); 153 } 154 155 /* 156 * acl_set_qualifier() sets the qualifier (ae_id) of the tag for 157 * ACL entry entry_d to the value referred to by tag_qualifier_p 158 */ 159 int 160 acl_set_qualifier(acl_entry_t entry_d, const void *tag_qualifier_p) 161 { 162 163 if (!entry_d || !tag_qualifier_p) { 164 errno = EINVAL; 165 return (-1); 166 } 167 switch(entry_d->ae_tag) { 168 case ACL_USER: 169 case ACL_GROUP: 170 entry_d->ae_id = *(uid_t *)tag_qualifier_p; 171 break; 172 default: 173 errno = EINVAL; 174 return (-1); 175 } 176 177 return (0); 178 } 179 180 /* 181 * acl_set_tag_type() sets the tag type for ACL entry entry_d to the 182 * value of tag_type 183 */ 184 int 185 acl_set_tag_type(acl_entry_t entry_d, acl_tag_t tag_type) 186 { 187 188 if (entry_d == NULL) { 189 errno = EINVAL; 190 return (-1); 191 } 192 193 switch(tag_type) { 194 case ACL_OTHER: 195 case ACL_MASK: 196 if (!_entry_brand_may_be(entry_d, ACL_BRAND_POSIX)) { 197 errno = EINVAL; 198 return (-1); 199 } 200 _entry_brand_as(entry_d, ACL_BRAND_POSIX); 201 break; 202 case ACL_EVERYONE: 203 if (!_entry_brand_may_be(entry_d, ACL_BRAND_NFS4)) { 204 errno = EINVAL; 205 return (-1); 206 } 207 _entry_brand_as(entry_d, ACL_BRAND_NFS4); 208 break; 209 } 210 211 switch(tag_type) { 212 case ACL_USER_OBJ: 213 case ACL_USER: 214 case ACL_GROUP_OBJ: 215 case ACL_GROUP: 216 case ACL_MASK: 217 case ACL_OTHER: 218 case ACL_EVERYONE: 219 entry_d->ae_tag = tag_type; 220 return (0); 221 } 222 223 errno = EINVAL; 224 return (-1); 225 } 226 227 int 228 acl_set_entry_type_np(acl_entry_t entry_d, acl_entry_type_t entry_type) 229 { 230 231 if (entry_d == NULL) { 232 errno = EINVAL; 233 return (-1); 234 } 235 if (!_entry_brand_may_be(entry_d, ACL_BRAND_NFS4)) { 236 errno = EINVAL; 237 return (-1); 238 } 239 _entry_brand_as(entry_d, ACL_BRAND_NFS4); 240 241 switch (entry_type) { 242 case ACL_ENTRY_TYPE_ALLOW: 243 case ACL_ENTRY_TYPE_DENY: 244 case ACL_ENTRY_TYPE_AUDIT: 245 case ACL_ENTRY_TYPE_ALARM: 246 entry_d->ae_entry_type = entry_type; 247 return (0); 248 } 249 250 errno = EINVAL; 251 return (-1); 252 } 253