1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1995 Sun Microsystems, Inc. All Rights Reserved 24*7c478bd9Sstevel@tonic-gate * 25*7c478bd9Sstevel@tonic-gate * module: 26*7c478bd9Sstevel@tonic-gate * acls.c 27*7c478bd9Sstevel@tonic-gate * 28*7c478bd9Sstevel@tonic-gate * purpose: 29*7c478bd9Sstevel@tonic-gate * routines to manipulate access control lists, mapping between 30*7c478bd9Sstevel@tonic-gate * the data structures required by the filesystem ACL system calls 31*7c478bd9Sstevel@tonic-gate * and the representation used in our fileinfo structure. 32*7c478bd9Sstevel@tonic-gate * 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate #ident "%W% %E% SMI" 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include <stdio.h> 37*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #include "filesync.h" 40*7c478bd9Sstevel@tonic-gate #include "database.h" 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #ifdef NO_ACLS 43*7c478bd9Sstevel@tonic-gate /* 44*7c478bd9Sstevel@tonic-gate * Solaris 2.4 libc.so does not contain this entry point, so if we 45*7c478bd9Sstevel@tonic-gate * want to build a 2.4 version of filesync, we need to provide a 46*7c478bd9Sstevel@tonic-gate * dummy entry point that will fail when-ever it is called. 47*7c478bd9Sstevel@tonic-gate */ 48*7c478bd9Sstevel@tonic-gate #define acl bogus_acl 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate static int acl(const char *name, int opcode, int count, aclent_t *acls) 51*7c478bd9Sstevel@tonic-gate { 52*7c478bd9Sstevel@tonic-gate return (-1); 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate #endif 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate /* 57*7c478bd9Sstevel@tonic-gate * routine: 58*7c478bd9Sstevel@tonic-gate * get_acls 59*7c478bd9Sstevel@tonic-gate * 60*7c478bd9Sstevel@tonic-gate * purpose: 61*7c478bd9Sstevel@tonic-gate * to read the ACL (if any) from a file into a fileinfo structure 62*7c478bd9Sstevel@tonic-gate * 63*7c478bd9Sstevel@tonic-gate * parameters: 64*7c478bd9Sstevel@tonic-gate * name of file 65*7c478bd9Sstevel@tonic-gate * pointer to fileinfo structure 66*7c478bd9Sstevel@tonic-gate * 67*7c478bd9Sstevel@tonic-gate * returns: 68*7c478bd9Sstevel@tonic-gate * number of ACL entries 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate int 71*7c478bd9Sstevel@tonic-gate get_acls(const char *name, struct fileinfo *ip) 72*7c478bd9Sstevel@tonic-gate { int count; 73*7c478bd9Sstevel@tonic-gate int i; 74*7c478bd9Sstevel@tonic-gate static aclent_t acls[MAX_ACL_ENTRIES]; 75*7c478bd9Sstevel@tonic-gate aclent_t *list; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate count = acl(name, GETACL, MAX_ACL_ENTRIES, acls); 78*7c478bd9Sstevel@tonic-gate if (count <= 0) 79*7c478bd9Sstevel@tonic-gate return (0); 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* with a count of 3 or 4 there may not be any real ones */ 82*7c478bd9Sstevel@tonic-gate if (count > 4) 83*7c478bd9Sstevel@tonic-gate goto gotsome; 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate /* look for anything beyond the normal unix protection */ 86*7c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) 87*7c478bd9Sstevel@tonic-gate switch (acls[i].a_type) { 88*7c478bd9Sstevel@tonic-gate default: /* weird types are real */ 89*7c478bd9Sstevel@tonic-gate goto gotsome; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate case USER_OBJ: 92*7c478bd9Sstevel@tonic-gate case GROUP_OBJ: 93*7c478bd9Sstevel@tonic-gate case OTHER_OBJ: 94*7c478bd9Sstevel@tonic-gate case CLASS_OBJ: 95*7c478bd9Sstevel@tonic-gate continue; /* all file have these */ 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate return (0); /* nothing interesting */ 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate gotsome: 101*7c478bd9Sstevel@tonic-gate /* allocate an array to hold the acls */ 102*7c478bd9Sstevel@tonic-gate list = (aclent_t *) malloc(count * sizeof (*list)); 103*7c478bd9Sstevel@tonic-gate if (list == 0) 104*7c478bd9Sstevel@tonic-gate nomem("Access Control List"); 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate /* copy the acls into the new list */ 107*7c478bd9Sstevel@tonic-gate for (i = 0; i < count; i++) { 108*7c478bd9Sstevel@tonic-gate list[i].a_type = acls[i].a_type; 109*7c478bd9Sstevel@tonic-gate list[i].a_id = acls[i].a_id; 110*7c478bd9Sstevel@tonic-gate list[i].a_perm = acls[i].a_perm; 111*7c478bd9Sstevel@tonic-gate } 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate ip->f_acls = list; 114*7c478bd9Sstevel@tonic-gate ip->f_numacls = count; 115*7c478bd9Sstevel@tonic-gate return (ip->f_numacls); 116*7c478bd9Sstevel@tonic-gate } 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate /* 119*7c478bd9Sstevel@tonic-gate * routine: 120*7c478bd9Sstevel@tonic-gate * cmp_acls 121*7c478bd9Sstevel@tonic-gate * 122*7c478bd9Sstevel@tonic-gate * purpose: 123*7c478bd9Sstevel@tonic-gate * determine whether or not two ACLs are the same 124*7c478bd9Sstevel@tonic-gate * 125*7c478bd9Sstevel@tonic-gate * parameters: 126*7c478bd9Sstevel@tonic-gate * pointer to first fileinfo 127*7c478bd9Sstevel@tonic-gate * pointer to second fileinfo 128*7c478bd9Sstevel@tonic-gate * 129*7c478bd9Sstevel@tonic-gate * returns: 130*7c478bd9Sstevel@tonic-gate * true equal 131*7c478bd9Sstevel@tonic-gate * false different 132*7c478bd9Sstevel@tonic-gate */ 133*7c478bd9Sstevel@tonic-gate int 134*7c478bd9Sstevel@tonic-gate cmp_acls(struct fileinfo *f1, struct fileinfo *f2) 135*7c478bd9Sstevel@tonic-gate { int i; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate if (f1->f_numacls != f2->f_numacls) 138*7c478bd9Sstevel@tonic-gate return (0); 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate if (f1->f_numacls == 0) 141*7c478bd9Sstevel@tonic-gate return (1); 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate for (i = 0; i < f1->f_numacls; i++) { 144*7c478bd9Sstevel@tonic-gate if (f1->f_acls[i].a_type != f2->f_acls[i].a_type) 145*7c478bd9Sstevel@tonic-gate return (0); 146*7c478bd9Sstevel@tonic-gate if (f1->f_acls[i].a_id != f2->f_acls[i].a_id) 147*7c478bd9Sstevel@tonic-gate return (0); 148*7c478bd9Sstevel@tonic-gate if (f1->f_acls[i].a_perm != f2->f_acls[i].a_perm) 149*7c478bd9Sstevel@tonic-gate return (0); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate return (1); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate /* 156*7c478bd9Sstevel@tonic-gate * routine: 157*7c478bd9Sstevel@tonic-gate * set_acls 158*7c478bd9Sstevel@tonic-gate * 159*7c478bd9Sstevel@tonic-gate * purpose: 160*7c478bd9Sstevel@tonic-gate * to write the ACL of a file 161*7c478bd9Sstevel@tonic-gate * 162*7c478bd9Sstevel@tonic-gate * parameters: 163*7c478bd9Sstevel@tonic-gate * name of file 164*7c478bd9Sstevel@tonic-gate * fileinfo pointer (which contains an acl pointer) 165*7c478bd9Sstevel@tonic-gate * 166*7c478bd9Sstevel@tonic-gate * returns: 167*7c478bd9Sstevel@tonic-gate * retcode and errno 168*7c478bd9Sstevel@tonic-gate */ 169*7c478bd9Sstevel@tonic-gate int 170*7c478bd9Sstevel@tonic-gate set_acls(const char *name, struct fileinfo *fp) 171*7c478bd9Sstevel@tonic-gate { int rc; 172*7c478bd9Sstevel@tonic-gate int nacl; 173*7c478bd9Sstevel@tonic-gate aclent_t acls[4], *list; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate if (fp->f_numacls == 0) { 176*7c478bd9Sstevel@tonic-gate /* fabricate a standard set of bogus ACLs */ 177*7c478bd9Sstevel@tonic-gate acls[0].a_type = USER_OBJ; 178*7c478bd9Sstevel@tonic-gate acls[0].a_id = fp->f_uid; 179*7c478bd9Sstevel@tonic-gate acls[0].a_perm = (fp->f_mode >> 6) & 7; 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate acls[1].a_type = GROUP_OBJ; 182*7c478bd9Sstevel@tonic-gate acls[1].a_id = fp->f_gid; 183*7c478bd9Sstevel@tonic-gate acls[1].a_perm = (fp->f_mode >> 3) & 7; 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate acls[2].a_type = CLASS_OBJ; 186*7c478bd9Sstevel@tonic-gate acls[2].a_id = 0; 187*7c478bd9Sstevel@tonic-gate acls[2].a_perm = (fp->f_mode >> 6) & 7; 188*7c478bd9Sstevel@tonic-gate 189*7c478bd9Sstevel@tonic-gate acls[3].a_type = OTHER_OBJ; 190*7c478bd9Sstevel@tonic-gate acls[3].a_id = 0; 191*7c478bd9Sstevel@tonic-gate acls[3].a_perm = fp->f_mode & 7; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate nacl = 4; 194*7c478bd9Sstevel@tonic-gate list = acls; 195*7c478bd9Sstevel@tonic-gate } else { 196*7c478bd9Sstevel@tonic-gate nacl = fp->f_numacls; 197*7c478bd9Sstevel@tonic-gate list = fp->f_acls; 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate rc = acl(name, SETACL, nacl, list); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate /* non-negative number mean success */ 203*7c478bd9Sstevel@tonic-gate if (rc < 0) 204*7c478bd9Sstevel@tonic-gate return (rc); 205*7c478bd9Sstevel@tonic-gate else 206*7c478bd9Sstevel@tonic-gate return (0); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate /* 210*7c478bd9Sstevel@tonic-gate * routine: 211*7c478bd9Sstevel@tonic-gate * show_acls 212*7c478bd9Sstevel@tonic-gate * 213*7c478bd9Sstevel@tonic-gate * purpose: 214*7c478bd9Sstevel@tonic-gate * to map an acl into arguments for a setfacl command 215*7c478bd9Sstevel@tonic-gate * 216*7c478bd9Sstevel@tonic-gate * paramters: 217*7c478bd9Sstevel@tonic-gate * number of elements in list 218*7c478bd9Sstevel@tonic-gate * pointer to list 219*7c478bd9Sstevel@tonic-gate * 220*7c478bd9Sstevel@tonic-gate * returns: 221*7c478bd9Sstevel@tonic-gate * pointer to character buffer containing arguments 222*7c478bd9Sstevel@tonic-gate */ 223*7c478bd9Sstevel@tonic-gate char 224*7c478bd9Sstevel@tonic-gate *show_acls(int numacl, aclent_t *list) 225*7c478bd9Sstevel@tonic-gate { int i, j; 226*7c478bd9Sstevel@tonic-gate int type, perm, id; 227*7c478bd9Sstevel@tonic-gate char *s; 228*7c478bd9Sstevel@tonic-gate static char buf[ MAX_LINE ]; 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate s = buf; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (numacl > 0) { 233*7c478bd9Sstevel@tonic-gate *s++ = '-'; 234*7c478bd9Sstevel@tonic-gate *s++ = 's'; 235*7c478bd9Sstevel@tonic-gate *s++ = ' '; 236*7c478bd9Sstevel@tonic-gate } else { 237*7c478bd9Sstevel@tonic-gate *s++ = '-'; 238*7c478bd9Sstevel@tonic-gate *s++ = 'd'; 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate for (i = 0; i < numacl; i++) { 242*7c478bd9Sstevel@tonic-gate type = list[i].a_type; 243*7c478bd9Sstevel@tonic-gate id = list[i].a_id; 244*7c478bd9Sstevel@tonic-gate perm = list[i].a_perm; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate if (i > 0) 247*7c478bd9Sstevel@tonic-gate *s++ = ','; 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate /* note whether this is per-file or default */ 250*7c478bd9Sstevel@tonic-gate if (type & ACL_DEFAULT) { 251*7c478bd9Sstevel@tonic-gate *s++ = 'd'; 252*7c478bd9Sstevel@tonic-gate *s++ = ':'; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate /* print out the entry type */ 256*7c478bd9Sstevel@tonic-gate if (type & (USER_OBJ|USER)) { 257*7c478bd9Sstevel@tonic-gate *s++ = 'u'; 258*7c478bd9Sstevel@tonic-gate *s++ = ':'; 259*7c478bd9Sstevel@tonic-gate } else if (type & (GROUP_OBJ|GROUP)) { 260*7c478bd9Sstevel@tonic-gate *s++ = 'g'; 261*7c478bd9Sstevel@tonic-gate *s++ = ':'; 262*7c478bd9Sstevel@tonic-gate } else if (type & OTHER_OBJ) { 263*7c478bd9Sstevel@tonic-gate *s++ = 'o'; 264*7c478bd9Sstevel@tonic-gate *s++ = ':'; 265*7c478bd9Sstevel@tonic-gate } else if (type & CLASS_OBJ) { 266*7c478bd9Sstevel@tonic-gate *s++ = 'm'; 267*7c478bd9Sstevel@tonic-gate *s++ = ':'; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate /* print out the ID for this ACL */ 271*7c478bd9Sstevel@tonic-gate if (type & (USER_OBJ|GROUP_OBJ)) 272*7c478bd9Sstevel@tonic-gate *s++ = ':'; 273*7c478bd9Sstevel@tonic-gate else if (type & (USER|GROUP)) { 274*7c478bd9Sstevel@tonic-gate for (j = 1; id/j > 10; j *= 10); 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate while (j > 0) { 277*7c478bd9Sstevel@tonic-gate *s++ = '0' + (id/j); 278*7c478bd9Sstevel@tonic-gate id %= j*10; 279*7c478bd9Sstevel@tonic-gate j /= 10; 280*7c478bd9Sstevel@tonic-gate } 281*7c478bd9Sstevel@tonic-gate 282*7c478bd9Sstevel@tonic-gate *s++ = ':'; 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate 285*7c478bd9Sstevel@tonic-gate /* print out the permissions for this ACL */ 286*7c478bd9Sstevel@tonic-gate *s++ = (perm & 04) ? 'r' : '-'; 287*7c478bd9Sstevel@tonic-gate *s++ = (perm & 02) ? 'w' : '-'; 288*7c478bd9Sstevel@tonic-gate *s++ = (perm & 01) ? 'x' : '-'; 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate *s = 0; 292*7c478bd9Sstevel@tonic-gate return (buf); 293*7c478bd9Sstevel@tonic-gate } 294