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