1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #ifndef lint 29 static char sccsid[] = "%Z%%M% %I% %E% SMI"; 30 #endif 31 32 /* 33 * getfacl [-ad] file ... 34 * This command displays discretionary information for a file or files. 35 * display format: 36 * # file: filename 37 * # owner: uid 38 * # group: gid 39 * user::perm 40 * user:uid:perm 41 * group::perm 42 * group:gid:perm 43 * mask:perm 44 * other:perm 45 * default:user::perm 46 * default:user:uid:perm 47 * default:group::perm 48 * default:group:gid:perm 49 * default:mask:perm 50 * default:other:perm 51 */ 52 53 #include <stdlib.h> 54 #include <stdio.h> 55 #include <pwd.h> 56 #include <grp.h> 57 #include <locale.h> 58 #include <sys/acl.h> 59 #include <errno.h> 60 61 static char *pruname(uid_t); 62 static char *prgname(gid_t); 63 static char *display(int); 64 static void usage(); 65 66 67 int 68 main(int argc, char *argv[]) 69 { 70 int c; 71 int aflag = 0; 72 int dflag = 0; 73 int errflag = 0; 74 int savecnt; 75 int aclcnt; 76 int mask; 77 aclent_t *aclp; 78 aclent_t *tp; 79 char *permp; 80 81 (void) setlocale(LC_ALL, ""); 82 (void) textdomain(TEXT_DOMAIN); 83 84 if (argc < 2) 85 usage(); 86 87 while ((c = getopt(argc, argv, "ad")) != EOF) { 88 switch (c) { 89 case 'a': 90 aflag++; 91 break; 92 case 'd': 93 dflag++; 94 break; 95 case '?': 96 errflag++; 97 break; 98 } 99 } 100 if (errflag) 101 usage(); 102 103 if (optind >= argc) 104 usage(); 105 106 for (; optind < argc; optind++) { 107 register char *filep; 108 109 filep = argv[optind]; 110 111 /* Get ACL info of the files */ 112 errno = 0; 113 if ((aclcnt = acl(filep, GETACLCNT, 0, NULL)) < 0) { 114 if (errno == ENOSYS) { 115 (void) fprintf(stderr, 116 gettext("File system doesn't support " 117 "aclent_t style ACL's.\n" 118 "See acl(5) for more information on " 119 "Solaris ACL support.\n")); 120 exit(2); 121 } 122 perror(filep); 123 exit(2); 124 } 125 if (aclcnt < MIN_ACL_ENTRIES) { 126 (void) fprintf(stderr, 127 gettext("%d: acl count too small from %s\n"), 128 aclcnt, filep); 129 exit(2); 130 } 131 132 if ((aclp = (aclent_t *)malloc(sizeof (aclent_t) * aclcnt)) 133 == NULL) { 134 (void) fprintf(stderr, 135 gettext("Insufficient memory\n")); 136 exit(1); 137 } 138 139 errno = 0; 140 if (acl(filep, GETACL, aclcnt, aclp) < 0) { 141 perror(filep); 142 exit(2); 143 } 144 145 /* display ACL: assume it is sorted. */ 146 (void) printf("\n# file: %s\n", filep); 147 savecnt = aclcnt; 148 for (tp = aclp; aclcnt--; tp++) { 149 if (tp->a_type == USER_OBJ) 150 (void) printf("# owner: %s\n", 151 pruname(tp->a_id)); 152 if (tp->a_type == GROUP_OBJ) 153 (void) printf("# group: %s\n", 154 prgname(tp->a_id)); 155 if (tp->a_type == CLASS_OBJ) 156 mask = tp->a_perm; 157 } 158 aclcnt = savecnt; 159 for (tp = aclp; aclcnt--; tp++) { 160 switch (tp->a_type) { 161 case USER: 162 if (!dflag) { 163 permp = display(tp->a_perm); 164 (void) printf("user:%s:%s\t\t", 165 pruname(tp->a_id), permp); 166 free(permp); 167 permp = display(tp->a_perm & mask); 168 (void) printf( 169 "#effective:%s\n", permp); 170 free(permp); 171 } 172 break; 173 case USER_OBJ: 174 if (!dflag) { 175 /* no need to display uid */ 176 permp = display(tp->a_perm); 177 (void) printf("user::%s\n", permp); 178 free(permp); 179 } 180 break; 181 case GROUP: 182 if (!dflag) { 183 permp = display(tp->a_perm); 184 (void) printf("group:%s:%s\t\t", 185 prgname(tp->a_id), permp); 186 free(permp); 187 permp = display(tp->a_perm & mask); 188 (void) printf( 189 "#effective:%s\n", permp); 190 free(permp); 191 } 192 break; 193 case GROUP_OBJ: 194 if (!dflag) { 195 permp = display(tp->a_perm); 196 (void) printf("group::%s\t\t", permp); 197 free(permp); 198 permp = display(tp->a_perm & mask); 199 (void) printf( 200 "#effective:%s\n", permp); 201 free(permp); 202 } 203 break; 204 case CLASS_OBJ: 205 if (!dflag) { 206 permp = display(tp->a_perm); 207 (void) printf("mask:%s\n", permp); 208 free(permp); 209 } 210 break; 211 case OTHER_OBJ: 212 if (!dflag) { 213 permp = display(tp->a_perm); 214 (void) printf("other:%s\n", permp); 215 free(permp); 216 } 217 break; 218 case DEF_USER: 219 if (!aflag) { 220 permp = display(tp->a_perm); 221 (void) printf("default:user:%s:%s\n", 222 pruname(tp->a_id), permp); 223 free(permp); 224 } 225 break; 226 case DEF_USER_OBJ: 227 if (!aflag) { 228 permp = display(tp->a_perm); 229 (void) printf("default:user::%s\n", 230 permp); 231 free(permp); 232 } 233 break; 234 case DEF_GROUP: 235 if (!aflag) { 236 permp = display(tp->a_perm); 237 (void) printf("default:group:%s:%s\n", 238 prgname(tp->a_id), permp); 239 free(permp); 240 } 241 break; 242 case DEF_GROUP_OBJ: 243 if (!aflag) { 244 permp = display(tp->a_perm); 245 (void) printf("default:group::%s\n", 246 permp); 247 free(permp); 248 } 249 break; 250 case DEF_CLASS_OBJ: 251 if (!aflag) { 252 permp = display(tp->a_perm); 253 (void) printf("default:mask:%s\n", 254 permp); 255 free(permp); 256 } 257 break; 258 case DEF_OTHER_OBJ: 259 if (!aflag) { 260 permp = display(tp->a_perm); 261 (void) printf("default:other:%s\n", 262 permp); 263 free(permp); 264 } 265 break; 266 default: 267 (void) fprintf(stderr, 268 gettext("unrecognized entry\n")); 269 break; 270 } 271 } 272 free(aclp); 273 } 274 return (0); 275 } 276 277 static char * 278 display(int perm) 279 { 280 char *buf; 281 282 buf = malloc(4); 283 if (buf == NULL) { 284 (void) fprintf(stderr, gettext("Insufficient memory\n")); 285 exit(1); 286 } 287 288 if (perm & 4) 289 buf[0] = 'r'; 290 else 291 buf[0] = '-'; 292 if (perm & 2) 293 buf[1] = 'w'; 294 else 295 buf[1] = '-'; 296 if (perm & 1) 297 buf[2] = 'x'; 298 else 299 buf[2] = '-'; 300 buf[3] = '\0'; 301 return (buf); 302 } 303 304 static char * 305 pruname(uid_t uid) 306 { 307 struct passwd *passwdp; 308 static char uidp[10]; /* big enough */ 309 310 passwdp = getpwuid(uid); 311 if (passwdp == (struct passwd *)NULL) { 312 /* could not get passwd information: display uid instead */ 313 (void) sprintf(uidp, "%u", uid); 314 return (uidp); 315 } else 316 return (passwdp->pw_name); 317 } 318 319 static char * 320 prgname(gid_t gid) 321 { 322 struct group *groupp; 323 static char gidp[10]; /* big enough */ 324 325 groupp = getgrgid(gid); 326 if (groupp == (struct group *)NULL) { 327 /* could not get group information: display gid instead */ 328 (void) sprintf(gidp, "%u", gid); 329 return (gidp); 330 } else 331 return (groupp->gr_name); 332 } 333 334 static void 335 usage() 336 { 337 (void) fprintf(stderr, 338 gettext("usage: getfacl [-ad] file ... \n")); 339 exit(1); 340 }