1789Sahrens /* 2789Sahrens * CDDL HEADER START 3789Sahrens * 4789Sahrens * The contents of this file are subject to the terms of the 5*4321Scasper * Common Development and Distribution License (the "License"). 6*4321Scasper * You may not use this file except in compliance with the License. 7789Sahrens * 8789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9789Sahrens * or http://www.opensolaris.org/os/licensing. 10789Sahrens * See the License for the specific language governing permissions 11789Sahrens * and limitations under the License. 12789Sahrens * 13789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 14789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15789Sahrens * If applicable, add the following below this CDDL HEADER, with the 16789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 17789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 18789Sahrens * 19789Sahrens * CDDL HEADER END 20789Sahrens */ 21789Sahrens /* 22*4321Scasper * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23789Sahrens * Use is subject to license terms. 24789Sahrens */ 25789Sahrens 26789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 27789Sahrens 28789Sahrens #include <sys/types.h> 29789Sahrens #include <sys/acl.h> 30789Sahrens #include <sys/stat.h> 31789Sahrens #if defined(_KERNEL) 32789Sahrens #include <sys/systm.h> 33789Sahrens #else 34789Sahrens #include <errno.h> 35789Sahrens #include <stdlib.h> 36789Sahrens #include <strings.h> 37789Sahrens #include <assert.h> 38789Sahrens #define ASSERT assert 39789Sahrens #endif 40789Sahrens 41789Sahrens 42789Sahrens ace_t trivial_acl[] = { 43*4321Scasper {(uid_t)-1, 0, ACE_OWNER, ACE_ACCESS_DENIED_ACE_TYPE}, 44*4321Scasper {(uid_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES| 45789Sahrens ACE_WRITE_NAMED_ATTRS, ACE_OWNER, ACE_ACCESS_ALLOWED_ACE_TYPE}, 46*4321Scasper {(uid_t)-1, 0, ACE_GROUP|ACE_IDENTIFIER_GROUP, 47*4321Scasper ACE_ACCESS_DENIED_ACE_TYPE}, 48*4321Scasper {(uid_t)-1, 0, ACE_GROUP|ACE_IDENTIFIER_GROUP, 49*4321Scasper ACE_ACCESS_ALLOWED_ACE_TYPE}, 50*4321Scasper {(uid_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER| ACE_WRITE_ATTRIBUTES| 51789Sahrens ACE_WRITE_NAMED_ATTRS, ACE_EVERYONE, ACE_ACCESS_DENIED_ACE_TYPE}, 52*4321Scasper {(uid_t)-1, ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_NAMED_ATTRS| 53789Sahrens ACE_SYNCHRONIZE, ACE_EVERYONE, ACE_ACCESS_ALLOWED_ACE_TYPE} 54789Sahrens }; 55789Sahrens 56789Sahrens 57789Sahrens void 58789Sahrens adjust_ace_pair(ace_t *pair, mode_t mode) 59789Sahrens { 60789Sahrens if (mode & S_IROTH) 61789Sahrens pair[1].a_access_mask |= ACE_READ_DATA; 62789Sahrens else 63789Sahrens pair[0].a_access_mask |= ACE_READ_DATA; 64789Sahrens if (mode & S_IWOTH) 65789Sahrens pair[1].a_access_mask |= 66789Sahrens ACE_WRITE_DATA|ACE_APPEND_DATA; 67789Sahrens else 68789Sahrens pair[0].a_access_mask |= 69789Sahrens ACE_WRITE_DATA|ACE_APPEND_DATA; 70789Sahrens if (mode & S_IXOTH) 71789Sahrens pair[1].a_access_mask |= ACE_EXECUTE; 72789Sahrens else 73789Sahrens pair[0].a_access_mask |= ACE_EXECUTE; 74789Sahrens } 75789Sahrens 76789Sahrens /* 77789Sahrens * ace_trivial: 78789Sahrens * determine whether an ace_t acl is trivial 79789Sahrens * 80789Sahrens * Trivialness implys that the acl is composed of only 81789Sahrens * owner, group, everyone entries. ACL can't 82789Sahrens * have read_acl denied, and write_owner/write_acl/write_attributes 83789Sahrens * can only be owner@ entry. 84789Sahrens */ 85789Sahrens int 86789Sahrens ace_trivial(ace_t *acep, int aclcnt) 87789Sahrens { 88789Sahrens int i; 89789Sahrens int owner_seen = 0; 90789Sahrens int group_seen = 0; 91789Sahrens int everyone_seen = 0; 92789Sahrens 93789Sahrens for (i = 0; i != aclcnt; i++) { 94789Sahrens switch (acep[i].a_flags & 0xf040) { 95789Sahrens case ACE_OWNER: 96789Sahrens if (group_seen || everyone_seen) 97789Sahrens return (1); 98789Sahrens owner_seen++; 99789Sahrens break; 100789Sahrens case ACE_GROUP|ACE_IDENTIFIER_GROUP: 101789Sahrens if (everyone_seen || owner_seen == 0) 102789Sahrens return (1); 103789Sahrens group_seen++; 104789Sahrens break; 105789Sahrens 106789Sahrens case ACE_EVERYONE: 107789Sahrens if (owner_seen == 0 || group_seen == 0) 108789Sahrens return (1); 109789Sahrens everyone_seen++; 110789Sahrens break; 111789Sahrens default: 112789Sahrens return (1); 113789Sahrens 114789Sahrens } 115789Sahrens 116789Sahrens if (acep[i].a_flags & (ACE_FILE_INHERIT_ACE| 117789Sahrens ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE| 118789Sahrens ACE_INHERIT_ONLY_ACE)) 119789Sahrens return (1); 120789Sahrens 121789Sahrens /* 122789Sahrens * Special check for some special bits 123789Sahrens * 124905Smarks * Don't allow anybody to deny reading basic 125905Smarks * attributes or a files ACL. 126789Sahrens */ 127905Smarks if ((acep[i].a_access_mask & 128905Smarks (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) && 129789Sahrens (acep[i].a_type == ACE_ACCESS_DENIED_ACE_TYPE)) 130789Sahrens return (1); 131789Sahrens 132789Sahrens /* 133789Sahrens * Allow on owner@ to allow 134789Sahrens * write_acl/write_owner/write_attributes 135789Sahrens */ 136789Sahrens if (acep[i].a_type == ACE_ACCESS_ALLOWED_ACE_TYPE && 137789Sahrens (!(acep[i].a_flags & ACE_OWNER) && (acep[i].a_access_mask & 138789Sahrens (ACE_WRITE_OWNER|ACE_WRITE_ACL|ACE_WRITE_ATTRIBUTES)))) 139789Sahrens return (1); 140789Sahrens } 141789Sahrens 142789Sahrens if ((owner_seen == 0) || (group_seen == 0) || (everyone_seen == 0)) 143789Sahrens return (1); 144789Sahrens 145789Sahrens return (0); 146789Sahrens } 147789Sahrens 148789Sahrens 149789Sahrens /* 150789Sahrens * Generic shellsort, from K&R (1st ed, p 58.), somewhat modified. 151789Sahrens * v = Ptr to array/vector of objs 152789Sahrens * n = # objs in the array 153789Sahrens * s = size of each obj (must be multiples of a word size) 154789Sahrens * f = ptr to function to compare two objs 155789Sahrens * returns (-1 = less than, 0 = equal, 1 = greater than 156789Sahrens */ 157789Sahrens void 158789Sahrens ksort(caddr_t v, int n, int s, int (*f)()) 159789Sahrens { 160789Sahrens int g, i, j, ii; 161789Sahrens unsigned int *p1, *p2; 162789Sahrens unsigned int tmp; 163789Sahrens 164789Sahrens /* No work to do */ 165789Sahrens if (v == NULL || n <= 1) 166789Sahrens return; 167789Sahrens 168789Sahrens /* Sanity check on arguments */ 169789Sahrens ASSERT(((uintptr_t)v & 0x3) == 0 && (s & 0x3) == 0); 170789Sahrens ASSERT(s > 0); 171789Sahrens for (g = n / 2; g > 0; g /= 2) { 172789Sahrens for (i = g; i < n; i++) { 173789Sahrens for (j = i - g; j >= 0 && 174789Sahrens (*f)(v + j * s, v + (j + g) * s) == 1; 175789Sahrens j -= g) { 176789Sahrens p1 = (void *)(v + j * s); 177789Sahrens p2 = (void *)(v + (j + g) * s); 178789Sahrens for (ii = 0; ii < s / 4; ii++) { 179789Sahrens tmp = *p1; 180789Sahrens *p1++ = *p2; 181789Sahrens *p2++ = tmp; 182789Sahrens } 183789Sahrens } 184789Sahrens } 185789Sahrens } 186789Sahrens } 187789Sahrens 188789Sahrens /* 189789Sahrens * Compare two acls, all fields. Returns: 190789Sahrens * -1 (less than) 191789Sahrens * 0 (equal) 192789Sahrens * +1 (greater than) 193789Sahrens */ 194789Sahrens int 195789Sahrens cmp2acls(void *a, void *b) 196789Sahrens { 197789Sahrens aclent_t *x = (aclent_t *)a; 198789Sahrens aclent_t *y = (aclent_t *)b; 199789Sahrens 200789Sahrens /* Compare types */ 201789Sahrens if (x->a_type < y->a_type) 202789Sahrens return (-1); 203789Sahrens if (x->a_type > y->a_type) 204789Sahrens return (1); 205789Sahrens /* Equal types; compare id's */ 206789Sahrens if (x->a_id < y->a_id) 207789Sahrens return (-1); 208789Sahrens if (x->a_id > y->a_id) 209789Sahrens return (1); 210789Sahrens /* Equal ids; compare perms */ 211789Sahrens if (x->a_perm < y->a_perm) 212789Sahrens return (-1); 213789Sahrens if (x->a_perm > y->a_perm) 214789Sahrens return (1); 215789Sahrens /* Totally equal */ 216789Sahrens return (0); 217789Sahrens } 218