1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * This file and its contents are supplied under the terms of the 4 * Common Development and Distribution License ("CDDL"), version 1.0. 5 * You may only use this file in accordance with the terms of version 6 * 1.0 of the CDDL. 7 * 8 * A full copy of the text of the CDDL should have accompanied this 9 * source. A copy of the CDDL is also available via the Internet at 10 * https://opensource.org/license/CDDL-1.0. 11 */ 12 /* 13 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 14 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 15 */ 16 17 #include <sys/types.h> 18 #include <sys/stat.h> 19 #include <sys/avl.h> 20 #include <sys/misc.h> 21 #include <sys/kmem.h> 22 #include <sys/systm.h> 23 #include <sys/sysmacros.h> 24 #include <acl/acl_common.h> 25 #include <sys/debug.h> 26 27 #define ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \ 28 ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_EXECUTE | \ 29 ACE_READ_ATTRIBUTES | ACE_READ_ACL | ACE_WRITE_ACL) 30 31 32 #define ACL_SYNCHRONIZE_SET_DENY 0x0000001 33 #define ACL_SYNCHRONIZE_SET_ALLOW 0x0000002 34 #define ACL_SYNCHRONIZE_ERR_DENY 0x0000004 35 #define ACL_SYNCHRONIZE_ERR_ALLOW 0x0000008 36 37 #define ACL_WRITE_OWNER_SET_DENY 0x0000010 38 #define ACL_WRITE_OWNER_SET_ALLOW 0x0000020 39 #define ACL_WRITE_OWNER_ERR_DENY 0x0000040 40 #define ACL_WRITE_OWNER_ERR_ALLOW 0x0000080 41 42 #define ACL_DELETE_SET_DENY 0x0000100 43 #define ACL_DELETE_SET_ALLOW 0x0000200 44 #define ACL_DELETE_ERR_DENY 0x0000400 45 #define ACL_DELETE_ERR_ALLOW 0x0000800 46 47 #define ACL_WRITE_ATTRS_OWNER_SET_DENY 0x0001000 48 #define ACL_WRITE_ATTRS_OWNER_SET_ALLOW 0x0002000 49 #define ACL_WRITE_ATTRS_OWNER_ERR_DENY 0x0004000 50 #define ACL_WRITE_ATTRS_OWNER_ERR_ALLOW 0x0008000 51 52 #define ACL_WRITE_ATTRS_WRITER_SET_DENY 0x0010000 53 #define ACL_WRITE_ATTRS_WRITER_SET_ALLOW 0x0020000 54 #define ACL_WRITE_ATTRS_WRITER_ERR_DENY 0x0040000 55 #define ACL_WRITE_ATTRS_WRITER_ERR_ALLOW 0x0080000 56 57 #define ACL_WRITE_NAMED_WRITER_SET_DENY 0x0100000 58 #define ACL_WRITE_NAMED_WRITER_SET_ALLOW 0x0200000 59 #define ACL_WRITE_NAMED_WRITER_ERR_DENY 0x0400000 60 #define ACL_WRITE_NAMED_WRITER_ERR_ALLOW 0x0800000 61 62 #define ACL_READ_NAMED_READER_SET_DENY 0x1000000 63 #define ACL_READ_NAMED_READER_SET_ALLOW 0x2000000 64 #define ACL_READ_NAMED_READER_ERR_DENY 0x4000000 65 #define ACL_READ_NAMED_READER_ERR_ALLOW 0x8000000 66 67 68 #define ACE_VALID_MASK_BITS (\ 69 ACE_READ_DATA | \ 70 ACE_LIST_DIRECTORY | \ 71 ACE_WRITE_DATA | \ 72 ACE_ADD_FILE | \ 73 ACE_APPEND_DATA | \ 74 ACE_ADD_SUBDIRECTORY | \ 75 ACE_READ_NAMED_ATTRS | \ 76 ACE_WRITE_NAMED_ATTRS | \ 77 ACE_EXECUTE | \ 78 ACE_DELETE_CHILD | \ 79 ACE_READ_ATTRIBUTES | \ 80 ACE_WRITE_ATTRIBUTES | \ 81 ACE_DELETE | \ 82 ACE_READ_ACL | \ 83 ACE_WRITE_ACL | \ 84 ACE_WRITE_OWNER | \ 85 ACE_SYNCHRONIZE) 86 87 #define ACE_MASK_UNDEFINED 0x80000000 88 89 #define ACE_VALID_FLAG_BITS (ACE_FILE_INHERIT_ACE | \ 90 ACE_DIRECTORY_INHERIT_ACE | \ 91 ACE_NO_PROPAGATE_INHERIT_ACE | ACE_INHERIT_ONLY_ACE | \ 92 ACE_SUCCESSFUL_ACCESS_ACE_FLAG | ACE_FAILED_ACCESS_ACE_FLAG | \ 93 ACE_IDENTIFIER_GROUP | ACE_OWNER | ACE_GROUP | ACE_EVERYONE) 94 95 /* 96 * ACL conversion helpers 97 */ 98 99 typedef enum { 100 ace_unused, 101 ace_user_obj, 102 ace_user, 103 ace_group, /* includes GROUP and GROUP_OBJ */ 104 ace_other_obj 105 } ace_to_aent_state_t; 106 107 typedef struct acevals { 108 uid_t key; 109 avl_node_t avl; 110 uint32_t mask; 111 uint32_t allowed; 112 uint32_t denied; 113 int aent_type; 114 } acevals_t; 115 116 typedef struct ace_list { 117 acevals_t user_obj; 118 avl_tree_t user; 119 int numusers; 120 acevals_t group_obj; 121 avl_tree_t group; 122 int numgroups; 123 acevals_t other_obj; 124 uint32_t acl_mask; 125 int hasmask; 126 int dfacl_flag; 127 ace_to_aent_state_t state; 128 int seen; /* bitmask of all aclent_t a_type values seen */ 129 } ace_list_t; 130 131 /* 132 * Generic shellsort, from K&R (1st ed, p 58.), somewhat modified. 133 * v = Ptr to array/vector of objs 134 * n = # objs in the array 135 * s = size of each obj (must be multiples of a word size) 136 * f = ptr to function to compare two objs 137 * returns (-1 = less than, 0 = equal, 1 = greater than 138 */ 139 void 140 ksort(caddr_t v, int n, int s, int (*f)(void *, void *)) 141 { 142 int g, i, j, ii; 143 unsigned int *p1, *p2; 144 unsigned int tmp; 145 146 /* No work to do */ 147 if (v == NULL || n <= 1) 148 return; 149 150 /* Sanity check on arguments */ 151 ASSERT3U(((uintptr_t)v & 0x3), ==, 0); 152 ASSERT3S((s & 0x3), ==, 0); 153 ASSERT3S(s, >, 0); 154 for (g = n / 2; g > 0; g /= 2) { 155 for (i = g; i < n; i++) { 156 for (j = i - g; j >= 0 && 157 (*f)(v + j * s, v + (j + g) * s) == 1; 158 j -= g) { 159 p1 = (void *)(v + j * s); 160 p2 = (void *)(v + (j + g) * s); 161 for (ii = 0; ii < s / 4; ii++) { 162 tmp = *p1; 163 *p1++ = *p2; 164 *p2++ = tmp; 165 } 166 } 167 } 168 } 169 } 170 171 /* 172 * Compare two acls, all fields. Returns: 173 * -1 (less than) 174 * 0 (equal) 175 * +1 (greater than) 176 */ 177 int 178 cmp2acls(void *a, void *b) 179 { 180 aclent_t *x = (aclent_t *)a; 181 aclent_t *y = (aclent_t *)b; 182 183 /* Compare types */ 184 if (x->a_type < y->a_type) 185 return (-1); 186 if (x->a_type > y->a_type) 187 return (1); 188 /* Equal types; compare id's */ 189 if (x->a_id < y->a_id) 190 return (-1); 191 if (x->a_id > y->a_id) 192 return (1); 193 /* Equal ids; compare perms */ 194 if (x->a_perm < y->a_perm) 195 return (-1); 196 if (x->a_perm > y->a_perm) 197 return (1); 198 /* Totally equal */ 199 return (0); 200 } 201 202 static int 203 cacl_malloc(void **ptr, size_t size) 204 { 205 *ptr = kmem_zalloc(size, KM_SLEEP); 206 return (0); 207 } 208 209 210 #define SET_ACE(acl, index, who, mask, type, flags) { \ 211 acl[0][index].a_who = (uint32_t)who; \ 212 acl[0][index].a_type = type; \ 213 acl[0][index].a_flags = flags; \ 214 acl[0][index++].a_access_mask = mask; \ 215 } 216 217 void 218 acl_trivial_access_masks(mode_t mode, boolean_t isdir, trivial_acl_t *masks) 219 { 220 uint32_t read_mask = ACE_READ_DATA; 221 uint32_t write_mask = ACE_WRITE_DATA|ACE_APPEND_DATA; 222 uint32_t execute_mask = ACE_EXECUTE; 223 224 (void) isdir; /* will need this later */ 225 226 masks->deny1 = 0; 227 if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH))) 228 masks->deny1 |= read_mask; 229 if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH))) 230 masks->deny1 |= write_mask; 231 if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH))) 232 masks->deny1 |= execute_mask; 233 234 masks->deny2 = 0; 235 if (!(mode & S_IRGRP) && (mode & S_IROTH)) 236 masks->deny2 |= read_mask; 237 if (!(mode & S_IWGRP) && (mode & S_IWOTH)) 238 masks->deny2 |= write_mask; 239 if (!(mode & S_IXGRP) && (mode & S_IXOTH)) 240 masks->deny2 |= execute_mask; 241 242 masks->allow0 = 0; 243 if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH))) 244 masks->allow0 |= read_mask; 245 if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH))) 246 masks->allow0 |= write_mask; 247 if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH))) 248 masks->allow0 |= execute_mask; 249 250 masks->owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL| 251 ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES| 252 ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE; 253 if (mode & S_IRUSR) 254 masks->owner |= read_mask; 255 if (mode & S_IWUSR) 256 masks->owner |= write_mask; 257 if (mode & S_IXUSR) 258 masks->owner |= execute_mask; 259 260 masks->group = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS| 261 ACE_SYNCHRONIZE; 262 if (mode & S_IRGRP) 263 masks->group |= read_mask; 264 if (mode & S_IWGRP) 265 masks->group |= write_mask; 266 if (mode & S_IXGRP) 267 masks->group |= execute_mask; 268 269 masks->everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS| 270 ACE_SYNCHRONIZE; 271 if (mode & S_IROTH) 272 masks->everyone |= read_mask; 273 if (mode & S_IWOTH) 274 masks->everyone |= write_mask; 275 if (mode & S_IXOTH) 276 masks->everyone |= execute_mask; 277 } 278 279 int 280 acl_trivial_create(mode_t mode, boolean_t isdir, ace_t **acl, int *count) 281 { 282 int index = 0; 283 int error; 284 trivial_acl_t masks; 285 286 *count = 3; 287 acl_trivial_access_masks(mode, isdir, &masks); 288 289 if (masks.allow0) 290 (*count)++; 291 if (masks.deny1) 292 (*count)++; 293 if (masks.deny2) 294 (*count)++; 295 296 if ((error = cacl_malloc((void **)acl, *count * sizeof (ace_t))) != 0) 297 return (error); 298 299 if (masks.allow0) { 300 SET_ACE(acl, index, -1, masks.allow0, 301 ACE_ACCESS_ALLOWED_ACE_TYPE, ACE_OWNER); 302 } 303 if (masks.deny1) { 304 SET_ACE(acl, index, -1, masks.deny1, 305 ACE_ACCESS_DENIED_ACE_TYPE, ACE_OWNER); 306 } 307 if (masks.deny2) { 308 SET_ACE(acl, index, -1, masks.deny2, 309 ACE_ACCESS_DENIED_ACE_TYPE, ACE_GROUP|ACE_IDENTIFIER_GROUP); 310 } 311 312 SET_ACE(acl, index, -1, masks.owner, ACE_ACCESS_ALLOWED_ACE_TYPE, 313 ACE_OWNER); 314 SET_ACE(acl, index, -1, masks.group, ACE_ACCESS_ALLOWED_ACE_TYPE, 315 ACE_IDENTIFIER_GROUP|ACE_GROUP); 316 SET_ACE(acl, index, -1, masks.everyone, ACE_ACCESS_ALLOWED_ACE_TYPE, 317 ACE_EVERYONE); 318 319 return (0); 320 } 321 322 /* 323 * ace_trivial: 324 * determine whether an ace_t acl is trivial 325 * 326 * Trivialness implies that the acl is composed of only 327 * owner, group, everyone entries. ACL can't 328 * have read_acl denied, and write_owner/write_acl/write_attributes 329 * can only be owner@ entry. 330 */ 331 int 332 ace_trivial_common(void *acep, int aclcnt, 333 uintptr_t (*walk)(void *, uintptr_t, int aclcnt, 334 uint16_t *, uint16_t *, uint32_t *)) 335 { 336 uint16_t flags; 337 uint32_t mask; 338 uint16_t type; 339 uintptr_t cookie = 0; 340 341 while ((cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask))) { 342 switch (flags & ACE_TYPE_FLAGS) { 343 case ACE_OWNER: 344 case ACE_GROUP|ACE_IDENTIFIER_GROUP: 345 case ACE_EVERYONE: 346 break; 347 default: 348 return (1); 349 350 } 351 352 if (flags & (ACE_FILE_INHERIT_ACE| 353 ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE| 354 ACE_INHERIT_ONLY_ACE)) 355 return (1); 356 357 /* 358 * Special check for some special bits 359 * 360 * Don't allow anybody to deny reading basic 361 * attributes or a files ACL. 362 */ 363 if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) && 364 (type == ACE_ACCESS_DENIED_ACE_TYPE)) 365 return (1); 366 367 /* 368 * Delete permissions are never set by default 369 */ 370 if (mask & (ACE_DELETE|ACE_DELETE_CHILD)) 371 return (1); 372 /* 373 * only allow owner@ to have 374 * write_acl/write_owner/write_attributes/write_xattr/ 375 */ 376 if (type == ACE_ACCESS_ALLOWED_ACE_TYPE && 377 (!(flags & ACE_OWNER) && (mask & 378 (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES| 379 ACE_WRITE_NAMED_ATTRS)))) 380 return (1); 381 382 } 383 return (0); 384 } 385