17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5ee519a1fSgjelinek * Common Development and Distribution License (the "License"). 6ee519a1fSgjelinek * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22bf8b6031Smarks * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <grp.h> 307c478bd9Sstevel@tonic-gate #include <pwd.h> 317c478bd9Sstevel@tonic-gate #include <string.h> 327c478bd9Sstevel@tonic-gate #include <limits.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 34fa9e4066Sahrens #include <errno.h> 357c478bd9Sstevel@tonic-gate #include <sys/param.h> 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 375a5eeccaSmarks #include <sys/stat.h> 387c478bd9Sstevel@tonic-gate #include <sys/acl.h> 39fa9e4066Sahrens #include <aclutils.h> 40*b249c65cSmarks #include <idmap.h> 41fa9e4066Sahrens 425a5eeccaSmarks #define ID_STR_MAX 20 /* digits in LONG_MAX */ 435a5eeccaSmarks 445a5eeccaSmarks #define APPENDED_ID_MAX ID_STR_MAX + 1 /* id + colon */ 455a5eeccaSmarks /* 465a5eeccaSmarks * yyinteractive controls whether yyparse should print out 475a5eeccaSmarks * error messages to stderr, and whether or not id's should be 485a5eeccaSmarks * allowed from acl_fromtext(). 495a5eeccaSmarks */ 505a5eeccaSmarks int yyinteractive; 515a5eeccaSmarks acl_t *yyacl; 525a5eeccaSmarks char *yybuf; 53fa9e4066Sahrens 54fa9e4066Sahrens extern acl_t *acl_alloc(enum acl_type); 557c478bd9Sstevel@tonic-gate 56*b249c65cSmarks /* 57*b249c65cSmarks * dynamic string that will increase in size on an 58*b249c65cSmarks * as needed basis. 59*b249c65cSmarks */ 60*b249c65cSmarks typedef struct dynaclstr { 61*b249c65cSmarks size_t d_bufsize; /* current size of aclexport */ 62*b249c65cSmarks char *d_aclexport; 63*b249c65cSmarks int d_pos; 64*b249c65cSmarks } dynaclstr_t; 6511e32170Shm123892 66*b249c65cSmarks static int str_append(dynaclstr_t *, char *); 67*b249c65cSmarks static int aclent_perm_txt(dynaclstr_t *, o_mode_t); 687c478bd9Sstevel@tonic-gate 695a5eeccaSmarks static void 705a5eeccaSmarks aclent_perms(int perm, char *txt_perms) 71fa9e4066Sahrens { 725a5eeccaSmarks if (perm & S_IROTH) 735a5eeccaSmarks txt_perms[0] = 'r'; 745a5eeccaSmarks else 755a5eeccaSmarks txt_perms[0] = '-'; 765a5eeccaSmarks if (perm & S_IWOTH) 775a5eeccaSmarks txt_perms[1] = 'w'; 785a5eeccaSmarks else 795a5eeccaSmarks txt_perms[1] = '-'; 805a5eeccaSmarks if (perm & S_IXOTH) 815a5eeccaSmarks txt_perms[2] = 'x'; 825a5eeccaSmarks else 835a5eeccaSmarks txt_perms[2] = '-'; 845a5eeccaSmarks txt_perms[3] = '\0'; 855a5eeccaSmarks } 86fa9e4066Sahrens 875a5eeccaSmarks static char * 88afe1f701Smarks pruname(uid_t uid, char *uidp, size_t buflen, int noresolve) 895a5eeccaSmarks { 9045a17f45Sgjelinek struct passwd *passwdp = NULL; 91fa9e4066Sahrens 9245a17f45Sgjelinek if (noresolve == 0) 935a5eeccaSmarks passwdp = getpwuid(uid); 945a5eeccaSmarks if (passwdp == (struct passwd *)NULL) { 955a5eeccaSmarks /* could not get passwd information: display uid instead */ 96f48205beScasper (void) snprintf(uidp, buflen, "%u", uid); 97afe1f701Smarks } else { 98afe1f701Smarks (void) strlcpy(uidp, passwdp->pw_name, buflen); 99afe1f701Smarks } 1005a5eeccaSmarks return (uidp); 1015a5eeccaSmarks } 102fa9e4066Sahrens 1035a5eeccaSmarks static char * 104afe1f701Smarks prgname(gid_t gid, char *gidp, size_t buflen, int noresolve) 1055a5eeccaSmarks { 10645a17f45Sgjelinek struct group *groupp = NULL; 107fa9e4066Sahrens 10845a17f45Sgjelinek if (noresolve == 0) 1095a5eeccaSmarks groupp = getgrgid(gid); 1105a5eeccaSmarks if (groupp == (struct group *)NULL) { 1115a5eeccaSmarks /* could not get group information: display gid instead */ 112f48205beScasper (void) snprintf(gidp, buflen, "%u", gid); 113afe1f701Smarks } else { 114afe1f701Smarks (void) strlcpy(gidp, groupp->gr_name, buflen); 115afe1f701Smarks } 1165a5eeccaSmarks return (gidp); 1175a5eeccaSmarks } 118*b249c65cSmarks 119*b249c65cSmarks static char * 120*b249c65cSmarks prsidname(uid_t who, boolean_t user, char **sidp, int noresolve) 121*b249c65cSmarks { 122*b249c65cSmarks idmap_handle_t *idmap_hdl = NULL; 123*b249c65cSmarks idmap_get_handle_t *get_hdl = NULL; 124*b249c65cSmarks idmap_stat status; 125*b249c65cSmarks idmap_rid_t rid; 126*b249c65cSmarks int error = 1; 127*b249c65cSmarks int len; 128*b249c65cSmarks char *domain; 129*b249c65cSmarks char *name; 130*b249c65cSmarks 131*b249c65cSmarks if (noresolve) { 132*b249c65cSmarks len = snprintf(NULL, 0, "%u", who); 133*b249c65cSmarks *sidp = malloc(len + 1); 134*b249c65cSmarks (void) snprintf(*sidp, len + 1, "%u", who); 135*b249c65cSmarks return (*sidp); 136*b249c65cSmarks } 137*b249c65cSmarks 138*b249c65cSmarks /* 139*b249c65cSmarks * First try and get windows name 140*b249c65cSmarks */ 141*b249c65cSmarks 142*b249c65cSmarks if (user) 143*b249c65cSmarks error = idmap_getwinnamebyuid(who, &name, &domain); 144*b249c65cSmarks else 145*b249c65cSmarks error = idmap_getwinnamebygid(who, &name, &domain); 146*b249c65cSmarks 147*b249c65cSmarks if (error) { 148*b249c65cSmarks if (idmap_init(&idmap_hdl) == 0 && 149*b249c65cSmarks idmap_get_create(idmap_hdl, &get_hdl) == 0) { 150*b249c65cSmarks if (user) 151*b249c65cSmarks error = idmap_get_sidbyuid(get_hdl, who, 152*b249c65cSmarks 0, &domain, &rid, &status); 153*b249c65cSmarks else 154*b249c65cSmarks error = idmap_get_sidbygid(get_hdl, who, 155*b249c65cSmarks 0, &domain, &rid, &status); 156*b249c65cSmarks if (error == 0) 157*b249c65cSmarks error = idmap_get_mappings(get_hdl); 158*b249c65cSmarks } 159*b249c65cSmarks if (error == 0) { 160*b249c65cSmarks len = snprintf(NULL, 0, "%s-%d", domain, rid); 161*b249c65cSmarks *sidp = malloc(len + 1); 162*b249c65cSmarks (void) snprintf(*sidp, len + 1, "%s-%d", domain, rid); 163*b249c65cSmarks } else { 164*b249c65cSmarks *sidp = NULL; 165*b249c65cSmarks } 166*b249c65cSmarks if (get_hdl) 167*b249c65cSmarks idmap_get_destroy(get_hdl); 168*b249c65cSmarks if (idmap_hdl) 169*b249c65cSmarks (void) idmap_fini(idmap_hdl); 170*b249c65cSmarks } else { 171*b249c65cSmarks int len; 172*b249c65cSmarks len = snprintf(NULL, 0, "%s@%d", name, domain); 173*b249c65cSmarks *sidp = malloc(len + 1); 174*b249c65cSmarks (void) snprintf(*sidp, len + 1, "%s@%s", name, domain); 175*b249c65cSmarks } 176*b249c65cSmarks return (*sidp); 177*b249c65cSmarks } 178*b249c65cSmarks 1795a5eeccaSmarks static void 1805a5eeccaSmarks aclent_printacl(acl_t *aclp) 1815a5eeccaSmarks { 1825a5eeccaSmarks aclent_t *tp; 1835a5eeccaSmarks int aclcnt; 1845a5eeccaSmarks int mask; 1855a5eeccaSmarks int slot = 0; 1865a5eeccaSmarks char perm[4]; 187afe1f701Smarks char uidp[ID_STR_MAX]; 188afe1f701Smarks char gidp[ID_STR_MAX]; 1895a5eeccaSmarks 1905a5eeccaSmarks /* display ACL: assume it is sorted. */ 1915a5eeccaSmarks aclcnt = aclp->acl_cnt; 1925a5eeccaSmarks for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) { 1935a5eeccaSmarks if (tp->a_type == CLASS_OBJ) 1945a5eeccaSmarks mask = tp->a_perm; 1955a5eeccaSmarks } 1965a5eeccaSmarks aclcnt = aclp->acl_cnt; 1975a5eeccaSmarks for (tp = aclp->acl_aclp; aclcnt--; tp++) { 1985a5eeccaSmarks (void) printf(" %d:", slot++); 1995a5eeccaSmarks switch (tp->a_type) { 2005a5eeccaSmarks case USER: 2015a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2025a5eeccaSmarks (void) printf("user:%s:%s\t\t", 203afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm); 2045a5eeccaSmarks aclent_perms((tp->a_perm & mask), perm); 2055a5eeccaSmarks (void) printf("#effective:%s\n", perm); 2065a5eeccaSmarks break; 2075a5eeccaSmarks case USER_OBJ: 2085a5eeccaSmarks /* no need to display uid */ 2095a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2105a5eeccaSmarks (void) printf("user::%s\n", perm); 2115a5eeccaSmarks break; 2125a5eeccaSmarks case GROUP: 2135a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2145a5eeccaSmarks (void) printf("group:%s:%s\t\t", 215afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm); 2165a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm); 2175a5eeccaSmarks (void) printf("#effective:%s\n", perm); 2185a5eeccaSmarks break; 2195a5eeccaSmarks case GROUP_OBJ: 2205a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2215a5eeccaSmarks (void) printf("group::%s\t\t", perm); 2225a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm); 2235a5eeccaSmarks (void) printf("#effective:%s\n", perm); 2245a5eeccaSmarks break; 2255a5eeccaSmarks case CLASS_OBJ: 2265a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2275a5eeccaSmarks (void) printf("mask:%s\n", perm); 2285a5eeccaSmarks break; 2295a5eeccaSmarks case OTHER_OBJ: 2305a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2315a5eeccaSmarks (void) printf("other:%s\n", perm); 2325a5eeccaSmarks break; 2335a5eeccaSmarks case DEF_USER: 2345a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2355a5eeccaSmarks (void) printf("default:user:%s:%s\n", 236afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm); 2375a5eeccaSmarks break; 2385a5eeccaSmarks case DEF_USER_OBJ: 2395a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2405a5eeccaSmarks (void) printf("default:user::%s\n", perm); 2415a5eeccaSmarks break; 2425a5eeccaSmarks case DEF_GROUP: 2435a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2445a5eeccaSmarks (void) printf("default:group:%s:%s\n", 245afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm); 2465a5eeccaSmarks break; 2475a5eeccaSmarks case DEF_GROUP_OBJ: 2485a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2495a5eeccaSmarks (void) printf("default:group::%s\n", perm); 2505a5eeccaSmarks break; 2515a5eeccaSmarks case DEF_CLASS_OBJ: 2525a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2535a5eeccaSmarks (void) printf("default:mask:%s\n", perm); 2545a5eeccaSmarks break; 2555a5eeccaSmarks case DEF_OTHER_OBJ: 2565a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2575a5eeccaSmarks (void) printf("default:other:%s\n", perm); 2585a5eeccaSmarks break; 2595a5eeccaSmarks default: 2605a5eeccaSmarks (void) fprintf(stderr, 2615b233e2dSmarks dgettext(TEXT_DOMAIN, "unrecognized entry\n")); 2625a5eeccaSmarks break; 2635a5eeccaSmarks } 2645a5eeccaSmarks } 2655a5eeccaSmarks } 2665a5eeccaSmarks 2675a5eeccaSmarks static void 2685a5eeccaSmarks split_line(char *str, int cols) 2695a5eeccaSmarks { 2705a5eeccaSmarks char *ptr; 2715a5eeccaSmarks int len; 2725a5eeccaSmarks int i; 2735a5eeccaSmarks int last_split; 2745a5eeccaSmarks char *pad = ""; 2755a5eeccaSmarks int pad_len; 2765a5eeccaSmarks 2775a5eeccaSmarks len = strlen(str); 2785a5eeccaSmarks ptr = str; 2795a5eeccaSmarks pad_len = 0; 2805a5eeccaSmarks 2815a5eeccaSmarks ptr = str; 2825a5eeccaSmarks last_split = 0; 2835a5eeccaSmarks for (i = 0; i != len; i++) { 2845a5eeccaSmarks if ((i + pad_len + 4) >= cols) { 2855a5eeccaSmarks (void) printf("%s%.*s\n", pad, last_split, ptr); 2865a5eeccaSmarks ptr = &ptr[last_split]; 2875a5eeccaSmarks len = strlen(ptr); 2885a5eeccaSmarks i = 0; 2895a5eeccaSmarks pad_len = 4; 2905a5eeccaSmarks pad = " "; 2915a5eeccaSmarks } else { 2925a5eeccaSmarks if (ptr[i] == '/' || ptr[i] == ':') { 2935a5eeccaSmarks last_split = i; 2945a5eeccaSmarks } 2955a5eeccaSmarks } 2965a5eeccaSmarks } 2975a5eeccaSmarks if (i == len) { 2985a5eeccaSmarks (void) printf("%s%s\n", pad, ptr); 2995a5eeccaSmarks } 3005a5eeccaSmarks } 3015a5eeccaSmarks 302*b249c65cSmarks /* 303*b249c65cSmarks * compute entry type string, such as user:joe, group:staff,... 304*b249c65cSmarks */ 305*b249c65cSmarks static int 306*b249c65cSmarks aclent_type_txt(dynaclstr_t *dstr, aclent_t *aclp, int flags) 3075a5eeccaSmarks { 308afe1f701Smarks char idp[ID_STR_MAX]; 309*b249c65cSmarks int error; 3105a5eeccaSmarks 311*b249c65cSmarks switch (aclp->a_type) { 312*b249c65cSmarks case DEF_USER_OBJ: 313*b249c65cSmarks case USER_OBJ: 314*b249c65cSmarks if (aclp->a_type == USER_OBJ) 315*b249c65cSmarks error = str_append(dstr, "user::"); 316*b249c65cSmarks else 317*b249c65cSmarks error = str_append(dstr, "defaultuser::"); 318*b249c65cSmarks break; 319*b249c65cSmarks 320*b249c65cSmarks case DEF_USER: 321*b249c65cSmarks case USER: 322*b249c65cSmarks if (aclp->a_type == USER) 323*b249c65cSmarks error = str_append(dstr, "user:"); 324*b249c65cSmarks else 325*b249c65cSmarks error = str_append(dstr, "defaultuser:"); 326*b249c65cSmarks if (error) 327*b249c65cSmarks break; 328*b249c65cSmarks error = str_append(dstr, pruname(aclp->a_id, idp, 329*b249c65cSmarks sizeof (idp), flags & ACL_NORESOLVE)); 330*b249c65cSmarks if (error == 0) 331*b249c65cSmarks error = str_append(dstr, ":"); 332*b249c65cSmarks break; 333*b249c65cSmarks 334*b249c65cSmarks case DEF_GROUP_OBJ: 335*b249c65cSmarks case GROUP_OBJ: 336*b249c65cSmarks if (aclp->a_type == GROUP_OBJ) 337*b249c65cSmarks error = str_append(dstr, "group::"); 338*b249c65cSmarks else 339*b249c65cSmarks error = str_append(dstr, "defaultgroup::"); 340*b249c65cSmarks break; 341*b249c65cSmarks 342*b249c65cSmarks case DEF_GROUP: 343*b249c65cSmarks case GROUP: 344*b249c65cSmarks if (aclp->a_type == GROUP) 345*b249c65cSmarks error = str_append(dstr, "group:"); 346*b249c65cSmarks else 347*b249c65cSmarks error = str_append(dstr, "defaultgroup:"); 348*b249c65cSmarks if (error) 349*b249c65cSmarks break; 350*b249c65cSmarks error = str_append(dstr, prgname(aclp->a_id, idp, 351*b249c65cSmarks sizeof (idp), flags & ACL_NORESOLVE)); 352*b249c65cSmarks if (error == 0) 353*b249c65cSmarks error = str_append(dstr, ":"); 354*b249c65cSmarks break; 355*b249c65cSmarks 356*b249c65cSmarks case DEF_CLASS_OBJ: 357*b249c65cSmarks case CLASS_OBJ: 358*b249c65cSmarks if (aclp->a_type == CLASS_OBJ) 359*b249c65cSmarks error = str_append(dstr, "mask:"); 360*b249c65cSmarks else 361*b249c65cSmarks error = str_append(dstr, "defaultmask:"); 362*b249c65cSmarks break; 363*b249c65cSmarks 364*b249c65cSmarks case DEF_OTHER_OBJ: 365*b249c65cSmarks case OTHER_OBJ: 366*b249c65cSmarks if (aclp->a_type == OTHER_OBJ) 367*b249c65cSmarks error = str_append(dstr, "other:"); 368*b249c65cSmarks else 369*b249c65cSmarks error = str_append(dstr, "defaultother:"); 370*b249c65cSmarks break; 371*b249c65cSmarks 372*b249c65cSmarks default: 373*b249c65cSmarks error = 1; 374*b249c65cSmarks break; 375*b249c65cSmarks } 376*b249c65cSmarks 377*b249c65cSmarks return (error); 378*b249c65cSmarks } 379*b249c65cSmarks 380*b249c65cSmarks /* 381*b249c65cSmarks * compute entry type string such as, owner@:, user:joe, group:staff,... 382*b249c65cSmarks */ 383*b249c65cSmarks static int 384*b249c65cSmarks ace_type_txt(dynaclstr_t *dynstr, ace_t *acep, int flags) 385*b249c65cSmarks { 386*b249c65cSmarks char idp[ID_STR_MAX]; 387*b249c65cSmarks int error; 388*b249c65cSmarks char *sidp = NULL; 3895a5eeccaSmarks 3905a5eeccaSmarks switch (acep->a_flags & ACE_TYPE_FLAGS) { 3915a5eeccaSmarks case ACE_OWNER: 392*b249c65cSmarks error = str_append(dynstr, OWNERAT_TXT); 3935a5eeccaSmarks break; 3945a5eeccaSmarks 3955a5eeccaSmarks case ACE_GROUP|ACE_IDENTIFIER_GROUP: 396*b249c65cSmarks error = str_append(dynstr, GROUPAT_TXT); 3975a5eeccaSmarks break; 3985a5eeccaSmarks 3995a5eeccaSmarks case ACE_IDENTIFIER_GROUP: 400*b249c65cSmarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) { 401*b249c65cSmarks if (error = str_append(dynstr, 402*b249c65cSmarks GROUPSID_TXT)) 403*b249c65cSmarks break; 404*b249c65cSmarks error = str_append(dynstr, prsidname(acep->a_who, 405*b249c65cSmarks B_FALSE, &sidp, flags & ACL_NORESOLVE)); 406*b249c65cSmarks } else { 407*b249c65cSmarks if (error = str_append(dynstr, GROUP_TXT)) 408*b249c65cSmarks break; 409*b249c65cSmarks error = str_append(dynstr, prgname(acep->a_who, idp, 410afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE)); 411*b249c65cSmarks } 412*b249c65cSmarks if (error == 0) 413*b249c65cSmarks error = str_append(dynstr, ":"); 4145a5eeccaSmarks break; 4155a5eeccaSmarks 4165a5eeccaSmarks case ACE_EVERYONE: 417*b249c65cSmarks error = str_append(dynstr, EVERYONEAT_TXT); 4185a5eeccaSmarks break; 4195a5eeccaSmarks 4205a5eeccaSmarks case 0: 421*b249c65cSmarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) { 422*b249c65cSmarks if (error = str_append(dynstr, USERSID_TXT)) 423*b249c65cSmarks break; 424*b249c65cSmarks error = str_append(dynstr, prsidname(acep->a_who, 425*b249c65cSmarks B_TRUE, &sidp, flags & ACL_NORESOLVE)); 426*b249c65cSmarks } else { 427*b249c65cSmarks if (error = str_append(dynstr, USER_TXT)) 428*b249c65cSmarks break; 429*b249c65cSmarks error = str_append(dynstr, pruname(acep->a_who, idp, 430afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE)); 431*b249c65cSmarks } 432*b249c65cSmarks if (error == 0) 433*b249c65cSmarks error = str_append(dynstr, ":"); 434*b249c65cSmarks break; 435*b249c65cSmarks default: 436*b249c65cSmarks error = 0; 4375a5eeccaSmarks break; 4385a5eeccaSmarks } 4395a5eeccaSmarks 440*b249c65cSmarks if (sidp) 441*b249c65cSmarks free(sidp); 442*b249c65cSmarks return (error); 4435a5eeccaSmarks } 4445a5eeccaSmarks 445*b249c65cSmarks /* 446*b249c65cSmarks * compute string of permissions, such as read_data/write_data or 447*b249c65cSmarks * rwxp,... 448*b249c65cSmarks * The format depends on the flags field which indicates whether the compact 449*b249c65cSmarks * or verbose format should be used. 450*b249c65cSmarks */ 451*b249c65cSmarks static int 452*b249c65cSmarks ace_perm_txt(dynaclstr_t *dstr, uint32_t mask, 4535a5eeccaSmarks uint32_t iflags, int isdir, int flags) 4545a5eeccaSmarks { 455*b249c65cSmarks int error = 0; 4565a5eeccaSmarks 4575a5eeccaSmarks if (flags & ACL_COMPACT_FMT) { 458*b249c65cSmarks char buf[16]; 4595a5eeccaSmarks 4605a5eeccaSmarks if (mask & ACE_READ_DATA) 4615a5eeccaSmarks buf[0] = 'r'; 4625a5eeccaSmarks else 4635a5eeccaSmarks buf[0] = '-'; 4645a5eeccaSmarks if (mask & ACE_WRITE_DATA) 4655a5eeccaSmarks buf[1] = 'w'; 4665a5eeccaSmarks else 4675a5eeccaSmarks buf[1] = '-'; 4685a5eeccaSmarks if (mask & ACE_EXECUTE) 4695a5eeccaSmarks buf[2] = 'x'; 4705a5eeccaSmarks else 4715a5eeccaSmarks buf[2] = '-'; 4725a5eeccaSmarks if (mask & ACE_APPEND_DATA) 4735a5eeccaSmarks buf[3] = 'p'; 4745a5eeccaSmarks else 4755a5eeccaSmarks buf[3] = '-'; 4765a5eeccaSmarks if (mask & ACE_DELETE) 4775a5eeccaSmarks buf[4] = 'd'; 4785a5eeccaSmarks else 4795a5eeccaSmarks buf[4] = '-'; 4805a5eeccaSmarks if (mask & ACE_DELETE_CHILD) 4815a5eeccaSmarks buf[5] = 'D'; 4825a5eeccaSmarks else 4835a5eeccaSmarks buf[5] = '-'; 4845a5eeccaSmarks if (mask & ACE_READ_ATTRIBUTES) 4855a5eeccaSmarks buf[6] = 'a'; 4865a5eeccaSmarks else 4875a5eeccaSmarks buf[6] = '-'; 4885a5eeccaSmarks if (mask & ACE_WRITE_ATTRIBUTES) 4895a5eeccaSmarks buf[7] = 'A'; 4905a5eeccaSmarks else 4915a5eeccaSmarks buf[7] = '-'; 4925a5eeccaSmarks if (mask & ACE_READ_NAMED_ATTRS) 4935a5eeccaSmarks buf[8] = 'R'; 4945a5eeccaSmarks else 4955a5eeccaSmarks buf[8] = '-'; 4965a5eeccaSmarks if (mask & ACE_WRITE_NAMED_ATTRS) 4975a5eeccaSmarks buf[9] = 'W'; 4985a5eeccaSmarks else 4995a5eeccaSmarks buf[9] = '-'; 5005a5eeccaSmarks if (mask & ACE_READ_ACL) 5015a5eeccaSmarks buf[10] = 'c'; 5025a5eeccaSmarks else 5035a5eeccaSmarks buf[10] = '-'; 5045a5eeccaSmarks if (mask & ACE_WRITE_ACL) 5055a5eeccaSmarks buf[11] = 'C'; 5065a5eeccaSmarks else 5075a5eeccaSmarks buf[11] = '-'; 5085a5eeccaSmarks if (mask & ACE_WRITE_OWNER) 5095a5eeccaSmarks buf[12] = 'o'; 5105a5eeccaSmarks else 5115a5eeccaSmarks buf[12] = '-'; 5125a5eeccaSmarks if (mask & ACE_SYNCHRONIZE) 5135a5eeccaSmarks buf[13] = 's'; 5145a5eeccaSmarks else 5155a5eeccaSmarks buf[13] = '-'; 516*b249c65cSmarks buf[14] = ':'; 517*b249c65cSmarks buf[15] = '\0'; 518*b249c65cSmarks error = str_append(dstr, buf); 5195a5eeccaSmarks } else { 5205a5eeccaSmarks /* 5215a5eeccaSmarks * If ACE is a directory, but inheritance indicates its 5225a5eeccaSmarks * for a file then print permissions for file rather than 5235a5eeccaSmarks * dir. 5245a5eeccaSmarks */ 5255a5eeccaSmarks if (isdir) { 5265a5eeccaSmarks if (mask & ACE_LIST_DIRECTORY) { 5275a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 528*b249c65cSmarks error = str_append(dstr, 529*b249c65cSmarks READ_DATA_TXT); 5305a5eeccaSmarks } else { 531*b249c65cSmarks error = 532*b249c65cSmarks str_append(dstr, READ_DIR_TXT); 5335a5eeccaSmarks } 5345a5eeccaSmarks } 535*b249c65cSmarks if (error == 0 && (mask & ACE_ADD_FILE)) { 5365a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 537*b249c65cSmarks error = 538*b249c65cSmarks str_append(dstr, WRITE_DATA_TXT); 5395a5eeccaSmarks } else { 540*b249c65cSmarks error = 541*b249c65cSmarks str_append(dstr, ADD_FILE_TXT); 5425a5eeccaSmarks } 5435a5eeccaSmarks } 544*b249c65cSmarks if (error == 0 && (mask & ACE_ADD_SUBDIRECTORY)) { 5455a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 546*b249c65cSmarks error = str_append(dstr, 547*b249c65cSmarks APPEND_DATA_TXT); 5485a5eeccaSmarks } else { 549*b249c65cSmarks error = str_append(dstr, 550*b249c65cSmarks ADD_DIR_TXT); 5515a5eeccaSmarks } 5525a5eeccaSmarks } 5535a5eeccaSmarks } else { 5545a5eeccaSmarks if (mask & ACE_READ_DATA) { 555*b249c65cSmarks error = str_append(dstr, READ_DATA_TXT); 5565a5eeccaSmarks } 557*b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_DATA)) { 558*b249c65cSmarks error = str_append(dstr, WRITE_DATA_TXT); 5595a5eeccaSmarks } 560*b249c65cSmarks if (error == 0 && (mask & ACE_APPEND_DATA)) { 561*b249c65cSmarks error = str_append(dstr, APPEND_DATA_TXT); 5625a5eeccaSmarks } 5635a5eeccaSmarks } 564*b249c65cSmarks if (error == 0 && (mask & ACE_READ_NAMED_ATTRS)) { 565*b249c65cSmarks error = str_append(dstr, READ_XATTR_TXT); 5665a5eeccaSmarks } 567*b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_NAMED_ATTRS)) { 568*b249c65cSmarks error = str_append(dstr, WRITE_XATTR_TXT); 5695a5eeccaSmarks } 570*b249c65cSmarks if (error == 0 && (mask & ACE_EXECUTE)) { 571*b249c65cSmarks error = str_append(dstr, EXECUTE_TXT); 5725a5eeccaSmarks } 573*b249c65cSmarks if (error == 0 && (mask & ACE_DELETE_CHILD)) { 574*b249c65cSmarks error = str_append(dstr, DELETE_CHILD_TXT); 5755a5eeccaSmarks } 576*b249c65cSmarks if (error == 0 && (mask & ACE_READ_ATTRIBUTES)) { 577*b249c65cSmarks error = str_append(dstr, READ_ATTRIBUTES_TXT); 5785a5eeccaSmarks } 579*b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_ATTRIBUTES)) { 580*b249c65cSmarks error = str_append(dstr, WRITE_ATTRIBUTES_TXT); 5815a5eeccaSmarks } 582*b249c65cSmarks if (error == 0 && (mask & ACE_DELETE)) { 583*b249c65cSmarks error = str_append(dstr, DELETE_TXT); 5845a5eeccaSmarks } 585*b249c65cSmarks if (error == 0 && (mask & ACE_READ_ACL)) { 586*b249c65cSmarks error = str_append(dstr, READ_ACL_TXT); 5875a5eeccaSmarks } 588*b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_ACL)) { 589*b249c65cSmarks error = str_append(dstr, WRITE_ACL_TXT); 5905a5eeccaSmarks } 591*b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_OWNER)) { 592*b249c65cSmarks error = str_append(dstr, WRITE_OWNER_TXT); 5935a5eeccaSmarks } 594*b249c65cSmarks if (error == 0 && (mask & ACE_SYNCHRONIZE)) { 595*b249c65cSmarks error = str_append(dstr, SYNCHRONIZE_TXT); 596*b249c65cSmarks } 597*b249c65cSmarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') { 598*b249c65cSmarks dstr->d_aclexport[--dstr->d_pos] = '\0'; 599*b249c65cSmarks } 600*b249c65cSmarks if (error == 0) 601*b249c65cSmarks error = str_append(dstr, ":"); 602*b249c65cSmarks } 603*b249c65cSmarks return (error); 6045a5eeccaSmarks } 6055a5eeccaSmarks 606*b249c65cSmarks /* 607*b249c65cSmarks * compute string of access type, such as allow, deny, ... 608*b249c65cSmarks */ 609*b249c65cSmarks static int 610*b249c65cSmarks ace_access_txt(dynaclstr_t *dstr, int type) 6115a5eeccaSmarks { 612*b249c65cSmarks int error; 6135a5eeccaSmarks 614*b249c65cSmarks if (type == ACE_ACCESS_ALLOWED_ACE_TYPE) 615*b249c65cSmarks error = str_append(dstr, ALLOW_TXT); 616*b249c65cSmarks else if (type == ACE_ACCESS_DENIED_ACE_TYPE) 617*b249c65cSmarks error = str_append(dstr, DENY_TXT); 618*b249c65cSmarks else if (type == ACE_SYSTEM_AUDIT_ACE_TYPE) 619*b249c65cSmarks error = str_append(dstr, AUDIT_TXT); 620*b249c65cSmarks else if (type == ACE_SYSTEM_ALARM_ACE_TYPE) 621*b249c65cSmarks error = str_append(dstr, ALARM_TXT); 622*b249c65cSmarks else 623*b249c65cSmarks error = str_append(dstr, UNKNOWN_TXT); 6245a5eeccaSmarks 625*b249c65cSmarks return (error); 6265a5eeccaSmarks } 6275a5eeccaSmarks 628*b249c65cSmarks static int 629*b249c65cSmarks ace_inherit_txt(dynaclstr_t *dstr, uint32_t iflags, int flags) 6305a5eeccaSmarks { 631*b249c65cSmarks int error = 0; 6325a5eeccaSmarks 6335a5eeccaSmarks if (flags & ACL_COMPACT_FMT) { 634*b249c65cSmarks char buf[9]; 635*b249c65cSmarks 6365a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE) 6375a5eeccaSmarks buf[0] = 'f'; 6385a5eeccaSmarks else 6395a5eeccaSmarks buf[0] = '-'; 6405a5eeccaSmarks if (iflags & ACE_DIRECTORY_INHERIT_ACE) 6415a5eeccaSmarks buf[1] = 'd'; 6425a5eeccaSmarks else 6435a5eeccaSmarks buf[1] = '-'; 6445a5eeccaSmarks if (iflags & ACE_INHERIT_ONLY_ACE) 6455a5eeccaSmarks buf[2] = 'i'; 6465a5eeccaSmarks else 6475a5eeccaSmarks buf[2] = '-'; 6485a5eeccaSmarks if (iflags & ACE_NO_PROPAGATE_INHERIT_ACE) 6495a5eeccaSmarks buf[3] = 'n'; 6505a5eeccaSmarks else 6515a5eeccaSmarks buf[3] = '-'; 6525a5eeccaSmarks if (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG) 6535a5eeccaSmarks buf[4] = 'S'; 6545a5eeccaSmarks else 6555a5eeccaSmarks buf[4] = '-'; 6565a5eeccaSmarks if (iflags & ACE_FAILED_ACCESS_ACE_FLAG) 6575a5eeccaSmarks buf[5] = 'F'; 6585a5eeccaSmarks else 6595a5eeccaSmarks buf[5] = '-'; 660da6c28aaSamw if (iflags & ACE_INHERITED_ACE) 661da6c28aaSamw buf[6] = 'I'; 662da6c28aaSamw else 663da6c28aaSamw buf[6] = '-'; 664*b249c65cSmarks buf[7] = ':'; 665*b249c65cSmarks buf[8] = '\0'; 666*b249c65cSmarks error = str_append(dstr, buf); 6675a5eeccaSmarks } else { 6685a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE) { 669*b249c65cSmarks error = str_append(dstr, FILE_INHERIT_TXT); 6705a5eeccaSmarks } 671*b249c65cSmarks if (error == 0 && (iflags & ACE_DIRECTORY_INHERIT_ACE)) { 672*b249c65cSmarks error = str_append(dstr, DIR_INHERIT_TXT); 6735a5eeccaSmarks } 674*b249c65cSmarks if (error == 0 && (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)) { 675*b249c65cSmarks error = str_append(dstr, NO_PROPAGATE_TXT); 6765a5eeccaSmarks } 677*b249c65cSmarks if (error == 0 && (iflags & ACE_INHERIT_ONLY_ACE)) { 678*b249c65cSmarks error = str_append(dstr, INHERIT_ONLY_TXT); 6795a5eeccaSmarks } 680*b249c65cSmarks if (error == 0 && (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)) { 681*b249c65cSmarks error = str_append(dstr, SUCCESSFUL_ACCESS_TXT); 682da6c28aaSamw } 683*b249c65cSmarks if (error == 0 && (iflags & ACE_FAILED_ACCESS_ACE_FLAG)) { 684*b249c65cSmarks error = str_append(dstr, FAILED_ACCESS_TXT); 685da6c28aaSamw } 686*b249c65cSmarks if (error == 0 && (iflags & ACE_INHERITED_ACE)) { 687*b249c65cSmarks error = str_append(dstr, INHERITED_ACE_TXT); 688*b249c65cSmarks } 689*b249c65cSmarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') { 690*b249c65cSmarks dstr->d_aclexport[--dstr->d_pos] = '\0'; 691*b249c65cSmarks error = str_append(dstr, ":"); 692*b249c65cSmarks } 693da6c28aaSamw } 6945a5eeccaSmarks 695*b249c65cSmarks return (error); 696fa9e4066Sahrens } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate /* 6997c478bd9Sstevel@tonic-gate * Convert internal acl representation to external representation. 7007c478bd9Sstevel@tonic-gate * 7017c478bd9Sstevel@tonic-gate * The length of a non-owning user name or non-owning group name ie entries 7027c478bd9Sstevel@tonic-gate * of type DEF_USER, USER, DEF_GROUP or GROUP, can exceed LOGNAME_MAX. We 7037c478bd9Sstevel@tonic-gate * thus check the length of these entries, and if greater than LOGNAME_MAX, 7047c478bd9Sstevel@tonic-gate * we realloc() via increase_length(). 7057c478bd9Sstevel@tonic-gate * 7067c478bd9Sstevel@tonic-gate * The LOGNAME_MAX, ENTRYTYPELEN and PERMS limits are otherwise always 7077c478bd9Sstevel@tonic-gate * adhered to. 7087c478bd9Sstevel@tonic-gate */ 7095a5eeccaSmarks 7105a5eeccaSmarks /* 7115a5eeccaSmarks * acltotext() converts each ACL entry to look like this: 7125a5eeccaSmarks * 7135a5eeccaSmarks * entry_type:uid^gid^name:perms[:id] 7145a5eeccaSmarks * 7155a5eeccaSmarks * The maximum length of entry_type is 14 ("defaultgroup::" and 7165a5eeccaSmarks * "defaultother::") hence ENTRYTYPELEN is set to 14. 7175a5eeccaSmarks * 7185a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8, hence we use, 7195a5eeccaSmarks * however the ID could be a number so we therefore use ID_STR_MAX 7205a5eeccaSmarks * 7215a5eeccaSmarks * The length of a perms entry is 4 to allow for the comma appended to each 7225a5eeccaSmarks * to each acl entry. Hence PERMS is set to 4. 7235a5eeccaSmarks */ 7245a5eeccaSmarks 7255a5eeccaSmarks #define ENTRYTYPELEN 14 7265a5eeccaSmarks #define PERMS 4 7275a5eeccaSmarks #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX) 7285a5eeccaSmarks 7297c478bd9Sstevel@tonic-gate char * 7305a5eeccaSmarks aclent_acltotext(aclent_t *aclp, int aclcnt, int flags) 7317c478bd9Sstevel@tonic-gate { 732*b249c65cSmarks dynaclstr_t *dstr; 7337c478bd9Sstevel@tonic-gate char *aclexport; 734*b249c65cSmarks int i; 735*b249c65cSmarks int error = 0; 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate if (aclp == NULL) 7387c478bd9Sstevel@tonic-gate return (NULL); 739*b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL) 7407c478bd9Sstevel@tonic-gate return (NULL); 741*b249c65cSmarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE; 742*b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) { 7437c478bd9Sstevel@tonic-gate free(dstr); 7447c478bd9Sstevel@tonic-gate return (NULL); 7457c478bd9Sstevel@tonic-gate } 746*b249c65cSmarks *dstr->d_aclexport = '\0'; 747*b249c65cSmarks dstr->d_pos = 0; 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate for (i = 0; i < aclcnt; i++, aclp++) { 750*b249c65cSmarks if (error = aclent_type_txt(dstr, aclp, flags)) 7517c478bd9Sstevel@tonic-gate break; 752*b249c65cSmarks if (error = aclent_perm_txt(dstr, aclp->a_perm)) 7537c478bd9Sstevel@tonic-gate break; 7545a5eeccaSmarks 7555a5eeccaSmarks if ((flags & ACL_APPEND_ID) && ((aclp->a_type == USER) || 7565a5eeccaSmarks (aclp->a_type == DEF_USER) || (aclp->a_type == GROUP) || 7575a5eeccaSmarks (aclp->a_type == DEF_GROUP))) { 758*b249c65cSmarks char id[ID_STR_MAX], *idstr; 759*b249c65cSmarks 760*b249c65cSmarks if (error = str_append(dstr, ":")) 761*b249c65cSmarks break; 7625a5eeccaSmarks id[ID_STR_MAX - 1] = '\0'; /* null terminate buffer */ 7635a5eeccaSmarks idstr = lltostr(aclp->a_id, &id[ID_STR_MAX - 1]); 764*b249c65cSmarks if (error = str_append(dstr, idstr)) 765*b249c65cSmarks break; 7665a5eeccaSmarks } 7677c478bd9Sstevel@tonic-gate if (i < aclcnt - 1) 768*b249c65cSmarks if (error = str_append(dstr, ",")) 769*b249c65cSmarks break; 7707c478bd9Sstevel@tonic-gate } 771*b249c65cSmarks if (error) { 772*b249c65cSmarks if (dstr->d_aclexport) 773*b249c65cSmarks free(dstr->d_aclexport); 774*b249c65cSmarks } else { 775*b249c65cSmarks aclexport = dstr->d_aclexport; 776*b249c65cSmarks } 7777c478bd9Sstevel@tonic-gate free(dstr); 7787c478bd9Sstevel@tonic-gate return (aclexport); 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate 7815a5eeccaSmarks char * 7825a5eeccaSmarks acltotext(aclent_t *aclp, int aclcnt) 7837c478bd9Sstevel@tonic-gate { 7845a5eeccaSmarks return (aclent_acltotext(aclp, aclcnt, 0)); 785fa9e4066Sahrens } 786fa9e4066Sahrens 7877c478bd9Sstevel@tonic-gate 788fa9e4066Sahrens aclent_t * 789fa9e4066Sahrens aclfromtext(char *aclstr, int *aclcnt) 790fa9e4066Sahrens { 791fa9e4066Sahrens acl_t *aclp; 792fa9e4066Sahrens aclent_t *aclentp; 793fa9e4066Sahrens int error; 794fa9e4066Sahrens 7955a5eeccaSmarks error = acl_fromtext(aclstr, &aclp); 796fa9e4066Sahrens if (error) 797fa9e4066Sahrens return (NULL); 798fa9e4066Sahrens 799fa9e4066Sahrens aclentp = aclp->acl_aclp; 800fa9e4066Sahrens aclp->acl_aclp = NULL; 801fa9e4066Sahrens *aclcnt = aclp->acl_cnt; 8025a5eeccaSmarks 8035a5eeccaSmarks acl_free(aclp); 804fa9e4066Sahrens return (aclentp); 805fa9e4066Sahrens } 806fa9e4066Sahrens 807fa9e4066Sahrens 8087c478bd9Sstevel@tonic-gate /* 809*b249c65cSmarks * returns a character position index of the start of the newly 810*b249c65cSmarks * appended string. Returns -1 if operation couldn't be completed. 8117c478bd9Sstevel@tonic-gate */ 8127c478bd9Sstevel@tonic-gate static int 813*b249c65cSmarks str_append(dynaclstr_t *dstr, char *newstr) 8147c478bd9Sstevel@tonic-gate { 815*b249c65cSmarks size_t len = strlen(newstr); 8167c478bd9Sstevel@tonic-gate 817*b249c65cSmarks if ((len + dstr->d_pos) >= dstr->d_bufsize) { 818*b249c65cSmarks dstr->d_aclexport = realloc(dstr->d_aclexport, 819*b249c65cSmarks dstr->d_bufsize + len + 1); 820*b249c65cSmarks if (dstr->d_aclexport == NULL) 8217c478bd9Sstevel@tonic-gate return (1); 822*b249c65cSmarks dstr->d_bufsize += len; 823*b249c65cSmarks } 824*b249c65cSmarks (void) strcat(&dstr->d_aclexport[dstr->d_pos], newstr); 825*b249c65cSmarks dstr->d_pos += len; 8267c478bd9Sstevel@tonic-gate return (0); 8277c478bd9Sstevel@tonic-gate } 828fa9e4066Sahrens 829*b249c65cSmarks static int 830*b249c65cSmarks aclent_perm_txt(dynaclstr_t *dstr, o_mode_t perm) 831*b249c65cSmarks { 832*b249c65cSmarks char buf[4]; 833*b249c65cSmarks 834*b249c65cSmarks if (perm & S_IROTH) 835*b249c65cSmarks buf[0] = 'r'; 836*b249c65cSmarks else 837*b249c65cSmarks buf[0] = '-'; 838*b249c65cSmarks if (perm & S_IWOTH) 839*b249c65cSmarks buf[1] = 'w'; 840*b249c65cSmarks else 841*b249c65cSmarks buf[1] = '-'; 842*b249c65cSmarks if (perm & S_IXOTH) 843*b249c65cSmarks buf[2] = 'x'; 844*b249c65cSmarks else 845*b249c65cSmarks buf[2] = '-'; 846*b249c65cSmarks buf[3] = '\0'; 847*b249c65cSmarks return (str_append(dstr, buf)); 848*b249c65cSmarks } 849*b249c65cSmarks 850fa9e4066Sahrens /* 8515a5eeccaSmarks * ace_acltotext() convert each ace formatted acl to look like this: 852fa9e4066Sahrens * 8535a5eeccaSmarks * entry_type:uid^gid^name:perms[:flags]:<allow|deny>[:id][,] 854fa9e4066Sahrens * 855fa9e4066Sahrens * The maximum length of entry_type is 5 ("group") 856fa9e4066Sahrens * 8575a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8, 8585a5eeccaSmarks * however id could be a number so we therefore use ID_STR_MAX 859fa9e4066Sahrens * 860fa9e4066Sahrens * The length of a perms entry is 144 i.e read_data/write_data... 861fa9e4066Sahrens * to each acl entry. 862fa9e4066Sahrens * 863da6c28aaSamw * iflags: file_inherit/dir_inherit/inherit_only/no_propagate/successful_access 864da6c28aaSamw * /failed_access 865fa9e4066Sahrens * 866fa9e4066Sahrens */ 867fa9e4066Sahrens 868fa9e4066Sahrens #define ACE_ENTRYTYPLEN 6 869da6c28aaSamw #define IFLAGS_STR "file_inherit/dir_inherit/inherit_only/no_propagate/" \ 870da6c28aaSamw "successful_access/failed_access/inherited" 871da6c28aaSamw #define IFLAGS_SIZE (sizeof (IFLAGS_STR) - 1) 8725a5eeccaSmarks #define ACCESS_TYPE_SIZE 7 /* if unknown */ 873fa9e4066Sahrens #define COLON_CNT 3 874fa9e4066Sahrens #define PERMS_LEN 216 8755a5eeccaSmarks #define ACE_ENTRY_SIZE (ACE_ENTRYTYPLEN + ID_STR_MAX + PERMS_LEN + \ 8765a5eeccaSmarks ACCESS_TYPE_SIZE + IFLAGS_SIZE + COLON_CNT + APPENDED_ID_MAX) 877fa9e4066Sahrens 878fa9e4066Sahrens static char * 8795a5eeccaSmarks ace_acltotext(acl_t *aceaclp, int flags) 880fa9e4066Sahrens { 881fa9e4066Sahrens ace_t *aclp = aceaclp->acl_aclp; 882fa9e4066Sahrens int aclcnt = aceaclp->acl_cnt; 8835a5eeccaSmarks int i; 884*b249c65cSmarks int error = 0; 885fa9e4066Sahrens int isdir = (aceaclp->acl_flags & ACL_IS_DIR); 886*b249c65cSmarks dynaclstr_t *dstr; 887*b249c65cSmarks char *aclexport; 888fa9e4066Sahrens 889fa9e4066Sahrens if (aclp == NULL) 890fa9e4066Sahrens return (NULL); 891fa9e4066Sahrens 892*b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL) 893*b249c65cSmarks return (NULL); 894*b249c65cSmarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE; 895*b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) { 896*b249c65cSmarks free(dstr); 897*b249c65cSmarks return (NULL); 898*b249c65cSmarks } 899*b249c65cSmarks *dstr->d_aclexport = '\0'; 900*b249c65cSmarks dstr->d_pos = 0; 901*b249c65cSmarks 902fa9e4066Sahrens for (i = 0; i < aclcnt; i++, aclp++) { 903fa9e4066Sahrens 904*b249c65cSmarks if (error = ace_type_txt(dstr, aclp, flags)) 905*b249c65cSmarks break; 906*b249c65cSmarks if (error = ace_perm_txt(dstr, aclp->a_access_mask, 907*b249c65cSmarks aclp->a_flags, isdir, flags)) 908*b249c65cSmarks break; 909*b249c65cSmarks if (error = ace_inherit_txt(dstr, aclp->a_flags, flags)) 910*b249c65cSmarks break; 911*b249c65cSmarks if (error = ace_access_txt(dstr, aclp->a_type)) 912*b249c65cSmarks break; 913fa9e4066Sahrens 9145a5eeccaSmarks if ((flags & ACL_APPEND_ID) && 9155a5eeccaSmarks (((aclp->a_flags & ACE_TYPE_FLAGS) == 0) || 9165a5eeccaSmarks ((aclp->a_flags & ACE_TYPE_FLAGS) == 9175a5eeccaSmarks ACE_IDENTIFIER_GROUP))) { 918*b249c65cSmarks char id[ID_STR_MAX], *idstr; 919*b249c65cSmarks 920*b249c65cSmarks if (error = str_append(dstr, ":")) 921*b249c65cSmarks break; 9225a5eeccaSmarks id[ID_STR_MAX -1] = '\0'; /* null terminate buffer */ 923*b249c65cSmarks idstr = lltostr((aclp->a_who > MAXUID && 924*b249c65cSmarks !(flags & ACL_NORESOLVE)) ? UID_NOBODY : 925*b249c65cSmarks aclp->a_who, &id[ID_STR_MAX - 1]); 926*b249c65cSmarks if (error = str_append(dstr, idstr)) 927*b249c65cSmarks break; 9285a5eeccaSmarks } 9295a5eeccaSmarks if (i < aclcnt - 1) { 930*b249c65cSmarks if (error = str_append(dstr, ",")) 931*b249c65cSmarks break; 932fa9e4066Sahrens } 933fa9e4066Sahrens } 934*b249c65cSmarks if (error) { 935*b249c65cSmarks if (dstr->d_aclexport) 936*b249c65cSmarks free(dstr->d_aclexport); 937*b249c65cSmarks } else { 938*b249c65cSmarks aclexport = dstr->d_aclexport; 939*b249c65cSmarks } 940*b249c65cSmarks free(dstr); 941fa9e4066Sahrens return (aclexport); 942fa9e4066Sahrens } 943fa9e4066Sahrens 9445a5eeccaSmarks char * 9455a5eeccaSmarks acl_totext(acl_t *aclp, int flags) 946fa9e4066Sahrens { 9475a5eeccaSmarks char *txtp; 948fa9e4066Sahrens 949fa9e4066Sahrens if (aclp == NULL) 950fa9e4066Sahrens return (NULL); 951fa9e4066Sahrens 952fa9e4066Sahrens switch (aclp->acl_type) { 953fa9e4066Sahrens case ACE_T: 9545a5eeccaSmarks txtp = ace_acltotext(aclp, flags); 9555a5eeccaSmarks break; 956fa9e4066Sahrens case ACLENT_T: 9575a5eeccaSmarks txtp = aclent_acltotext(aclp->acl_aclp, aclp->acl_cnt, flags); 9585a5eeccaSmarks break; 959fa9e4066Sahrens } 9605a5eeccaSmarks 9615a5eeccaSmarks return (txtp); 962fa9e4066Sahrens } 963fa9e4066Sahrens 964fa9e4066Sahrens int 965fa9e4066Sahrens acl_fromtext(const char *acltextp, acl_t **ret_aclp) 966fa9e4066Sahrens { 9675a5eeccaSmarks int error; 9685a5eeccaSmarks char *buf; 9695a5eeccaSmarks 9705a5eeccaSmarks buf = malloc(strlen(acltextp) + 2); 9715a5eeccaSmarks if (buf == NULL) 9725a5eeccaSmarks return (EACL_MEM_ERROR); 9735a5eeccaSmarks strcpy(buf, acltextp); 9745a5eeccaSmarks strcat(buf, "\n"); 9755a5eeccaSmarks yybuf = buf; 9765a5eeccaSmarks yyreset(); 9775a5eeccaSmarks error = yyparse(); 9785a5eeccaSmarks free(buf); 9795a5eeccaSmarks 9805a5eeccaSmarks if (yyacl) { 9815a5eeccaSmarks if (error == 0) 9825a5eeccaSmarks *ret_aclp = yyacl; 9835a5eeccaSmarks else { 9845a5eeccaSmarks acl_free(yyacl); 9855a5eeccaSmarks } 9865a5eeccaSmarks yyacl = NULL; 9875a5eeccaSmarks } 9885a5eeccaSmarks return (error); 9895a5eeccaSmarks } 9905a5eeccaSmarks 9915a5eeccaSmarks int 9925a5eeccaSmarks acl_parse(const char *acltextp, acl_t **aclp) 9935a5eeccaSmarks { 994fa9e4066Sahrens int error; 995fa9e4066Sahrens 9965a5eeccaSmarks yyinteractive = 1; 9975a5eeccaSmarks error = acl_fromtext(acltextp, aclp); 9985a5eeccaSmarks yyinteractive = 0; 999fa9e4066Sahrens return (error); 1000fa9e4066Sahrens } 10015a5eeccaSmarks 10025a5eeccaSmarks static void 10035a5eeccaSmarks ace_compact_printacl(acl_t *aclp) 10045a5eeccaSmarks { 10055a5eeccaSmarks int cnt; 10065a5eeccaSmarks ace_t *acep; 1007*b249c65cSmarks dynaclstr_t *dstr; 1008*b249c65cSmarks int len; 10095a5eeccaSmarks 1010*b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL) 1011*b249c65cSmarks return; 1012*b249c65cSmarks dstr->d_bufsize = ACE_ENTRY_SIZE; 1013*b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) { 1014*b249c65cSmarks free(dstr); 1015*b249c65cSmarks return; 1016*b249c65cSmarks } 1017*b249c65cSmarks *dstr->d_aclexport = '\0'; 1018*b249c65cSmarks 1019*b249c65cSmarks dstr->d_pos = 0; 10205a5eeccaSmarks for (cnt = 0, acep = aclp->acl_aclp; 10215a5eeccaSmarks cnt != aclp->acl_cnt; cnt++, acep++) { 1022*b249c65cSmarks dstr->d_aclexport[0] = '\0'; 1023*b249c65cSmarks dstr->d_pos = 0; 1024*b249c65cSmarks 1025*b249c65cSmarks if (ace_type_txt(dstr, acep, 0)) 1026*b249c65cSmarks break; 1027*b249c65cSmarks len = strlen(&dstr->d_aclexport[0]); 1028*b249c65cSmarks if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags, 1029*b249c65cSmarks aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT)) 1030*b249c65cSmarks break; 1031*b249c65cSmarks if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT)) 1032*b249c65cSmarks break; 1033*b249c65cSmarks if (ace_access_txt(dstr, acep->a_type) == -1) 1034*b249c65cSmarks break; 1035*b249c65cSmarks (void) printf(" %20.*s%s\n", len, dstr->d_aclexport, 1036*b249c65cSmarks &dstr->d_aclexport[len]); 10375a5eeccaSmarks } 1038*b249c65cSmarks 1039*b249c65cSmarks if (dstr->d_aclexport) 1040*b249c65cSmarks free(dstr->d_aclexport); 1041*b249c65cSmarks free(dstr); 10425a5eeccaSmarks } 10435a5eeccaSmarks 10445a5eeccaSmarks static void 10455a5eeccaSmarks ace_printacl(acl_t *aclp, int cols, int compact) 10465a5eeccaSmarks { 10475a5eeccaSmarks int slot = 0; 10485a5eeccaSmarks char *token; 10495a5eeccaSmarks char *acltext; 10505a5eeccaSmarks 10515a5eeccaSmarks if (compact) { 10525a5eeccaSmarks ace_compact_printacl(aclp); 10535a5eeccaSmarks return; 10545a5eeccaSmarks } 10555a5eeccaSmarks 10565a5eeccaSmarks acltext = acl_totext(aclp, 0); 10575a5eeccaSmarks 10585a5eeccaSmarks if (acltext == NULL) 10595a5eeccaSmarks return; 10605a5eeccaSmarks 10615a5eeccaSmarks token = strtok(acltext, ","); 10625a5eeccaSmarks if (token == NULL) { 10635a5eeccaSmarks free(acltext); 10645a5eeccaSmarks return; 10655a5eeccaSmarks } 10665a5eeccaSmarks 10675a5eeccaSmarks do { 10685a5eeccaSmarks (void) printf(" %d:", slot++); 10695a5eeccaSmarks split_line(token, cols - 5); 10705a5eeccaSmarks } while (token = strtok(NULL, ",")); 10715a5eeccaSmarks free(acltext); 10725a5eeccaSmarks } 10735a5eeccaSmarks 10745a5eeccaSmarks /* 10755a5eeccaSmarks * pretty print an ACL. 10765a5eeccaSmarks * For aclent_t ACL's the format is 10775a5eeccaSmarks * similar to the old format used by getfacl, 10785a5eeccaSmarks * with the addition of adding a "slot" number 10795a5eeccaSmarks * before each entry. 10805a5eeccaSmarks * 10815a5eeccaSmarks * for ace_t ACL's the cols variable will break up 10825a5eeccaSmarks * the long lines into multiple lines and will also 10835a5eeccaSmarks * print a "slot" number. 10845a5eeccaSmarks */ 10855a5eeccaSmarks void 10865a5eeccaSmarks acl_printacl(acl_t *aclp, int cols, int compact) 10875a5eeccaSmarks { 10885a5eeccaSmarks 10895a5eeccaSmarks switch (aclp->acl_type) { 10905a5eeccaSmarks case ACLENT_T: 10915a5eeccaSmarks aclent_printacl(aclp); 10925a5eeccaSmarks break; 10935a5eeccaSmarks case ACE_T: 10945a5eeccaSmarks ace_printacl(aclp, cols, compact); 10955a5eeccaSmarks break; 10965a5eeccaSmarks } 10975a5eeccaSmarks } 10985a5eeccaSmarks 10995a5eeccaSmarks typedef struct value_table { 11005a5eeccaSmarks char p_letter; /* perm letter such as 'r' */ 11015a5eeccaSmarks uint32_t p_value; /* value for perm when pletter found */ 11025a5eeccaSmarks } value_table_t; 11035a5eeccaSmarks 11045a5eeccaSmarks /* 1105da6c28aaSamw * The permission tables are laid out in positional order 11065a5eeccaSmarks * a '-' character will indicate a permission at a given 11075a5eeccaSmarks * position is not specified. The '-' is not part of the 11085a5eeccaSmarks * table, but will be checked for in the permission computation 11095a5eeccaSmarks * routine. 11105a5eeccaSmarks */ 1111da6c28aaSamw value_table_t ace_perm_table[] = { 11125a5eeccaSmarks { 'r', ACE_READ_DATA}, 11135a5eeccaSmarks { 'w', ACE_WRITE_DATA}, 11145a5eeccaSmarks { 'x', ACE_EXECUTE}, 11155a5eeccaSmarks { 'p', ACE_APPEND_DATA}, 11165a5eeccaSmarks { 'd', ACE_DELETE}, 11175a5eeccaSmarks { 'D', ACE_DELETE_CHILD}, 11185a5eeccaSmarks { 'a', ACE_READ_ATTRIBUTES}, 11195a5eeccaSmarks { 'A', ACE_WRITE_ATTRIBUTES}, 11205a5eeccaSmarks { 'R', ACE_READ_NAMED_ATTRS}, 11215a5eeccaSmarks { 'W', ACE_WRITE_NAMED_ATTRS}, 11225a5eeccaSmarks { 'c', ACE_READ_ACL}, 11235a5eeccaSmarks { 'C', ACE_WRITE_ACL}, 11245a5eeccaSmarks { 'o', ACE_WRITE_OWNER}, 11255a5eeccaSmarks { 's', ACE_SYNCHRONIZE} 11265a5eeccaSmarks }; 11275a5eeccaSmarks 1128da6c28aaSamw #define ACE_PERM_COUNT (sizeof (ace_perm_table) / sizeof (value_table_t)) 11295a5eeccaSmarks 1130da6c28aaSamw value_table_t aclent_perm_table[] = { 11315a5eeccaSmarks { 'r', S_IROTH}, 11325a5eeccaSmarks { 'w', S_IWOTH}, 11335a5eeccaSmarks { 'x', S_IXOTH} 11345a5eeccaSmarks }; 11355a5eeccaSmarks 1136da6c28aaSamw #define ACLENT_PERM_COUNT (sizeof (aclent_perm_table) / sizeof (value_table_t)) 1137da6c28aaSamw 1138da6c28aaSamw value_table_t inherit_table[] = { 11395a5eeccaSmarks {'f', ACE_FILE_INHERIT_ACE}, 11405a5eeccaSmarks {'d', ACE_DIRECTORY_INHERIT_ACE}, 11415a5eeccaSmarks {'i', ACE_INHERIT_ONLY_ACE}, 11425a5eeccaSmarks {'n', ACE_NO_PROPAGATE_INHERIT_ACE}, 11435a5eeccaSmarks {'S', ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, 1144da6c28aaSamw {'F', ACE_FAILED_ACCESS_ACE_FLAG}, 1145da6c28aaSamw {'I', ACE_INHERITED_ACE} 11465a5eeccaSmarks }; 11475a5eeccaSmarks 1148da6c28aaSamw #define IFLAG_COUNT (sizeof (inherit_table) / sizeof (value_table_t)) 1149bf8b6031Smarks #define IFLAG_COUNT_V1 6 /* Older version compatibility */ 1150da6c28aaSamw 11515a5eeccaSmarks /* 11525a5eeccaSmarks * compute value from a permission table or inheritance table 11535a5eeccaSmarks * based on string passed in. If positional is set then 11545a5eeccaSmarks * string must match order in permtab, otherwise any order 11555a5eeccaSmarks * is allowed. 11565a5eeccaSmarks */ 11575a5eeccaSmarks int 11585a5eeccaSmarks compute_values(value_table_t *permtab, int count, 11595a5eeccaSmarks char *permstr, int positional, uint32_t *mask) 11605a5eeccaSmarks { 11615a5eeccaSmarks uint32_t perm_val = 0; 11625a5eeccaSmarks char *pstr; 11635a5eeccaSmarks int i, found; 11645a5eeccaSmarks 11655a5eeccaSmarks if (count < 0) 11665a5eeccaSmarks return (1); 11675a5eeccaSmarks 11685a5eeccaSmarks if (positional) { 11695a5eeccaSmarks for (i = 0, pstr = permstr; i != count && pstr && 11705a5eeccaSmarks *pstr; i++, pstr++) { 11715a5eeccaSmarks if (*pstr == permtab[i].p_letter) { 11725a5eeccaSmarks perm_val |= permtab[i].p_value; 11735a5eeccaSmarks } else if (*pstr != '-') { 11745a5eeccaSmarks return (1); 11755a5eeccaSmarks } 11765a5eeccaSmarks } 11775a5eeccaSmarks } else { /* random order single letters with no '-' */ 11785a5eeccaSmarks for (pstr = permstr; pstr && *pstr; pstr++) { 11795a5eeccaSmarks for (found = 0, i = 0; i != count; i++) { 11805a5eeccaSmarks if (*pstr == permtab[i].p_letter) { 11815a5eeccaSmarks perm_val |= permtab[i].p_value; 11825a5eeccaSmarks found = 1; 11835a5eeccaSmarks break; 11845a5eeccaSmarks } 11855a5eeccaSmarks } 11865a5eeccaSmarks if (found == 0) 11875a5eeccaSmarks return (1); 11885a5eeccaSmarks } 11895a5eeccaSmarks } 11905a5eeccaSmarks 11915a5eeccaSmarks *mask = perm_val; 11925a5eeccaSmarks return (0); 11935a5eeccaSmarks } 11945a5eeccaSmarks 1195bf8b6031Smarks 1196bf8b6031Smarks int 1197bf8b6031Smarks ace_inherit_helper(char *str, uint32_t *imask, int table_length) 1198bf8b6031Smarks { 1199bf8b6031Smarks int rc = 0; 1200bf8b6031Smarks 1201bf8b6031Smarks if (strlen(str) == table_length) { 1202bf8b6031Smarks /* 1203bf8b6031Smarks * If the string == table_length then first check to see it's 1204bf8b6031Smarks * in positional format. If that fails then see if it's in 1205bf8b6031Smarks * non-positional format. 1206bf8b6031Smarks */ 1207bf8b6031Smarks if (compute_values(inherit_table, table_length, str, 1208bf8b6031Smarks 1, imask) && compute_values(inherit_table, 1209bf8b6031Smarks table_length, str, 0, imask)) { 1210bf8b6031Smarks rc = 1; 1211bf8b6031Smarks } 1212bf8b6031Smarks } else { 1213bf8b6031Smarks rc = compute_values(inherit_table, table_length, str, 0, imask); 1214bf8b6031Smarks } 1215bf8b6031Smarks 1216bf8b6031Smarks return (rc ? EACL_INHERIT_ERROR : 0); 1217bf8b6031Smarks } 1218bf8b6031Smarks 12195a5eeccaSmarks /* 12205a5eeccaSmarks * compute value for inheritance flags. 12215a5eeccaSmarks */ 12225a5eeccaSmarks int 12235a5eeccaSmarks compute_ace_inherit(char *str, uint32_t *imask) 12245a5eeccaSmarks { 1225bf8b6031Smarks int rc = 0; 12265a5eeccaSmarks 1227bf8b6031Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT); 12285a5eeccaSmarks 1229bf8b6031Smarks if (rc && strlen(str) != IFLAG_COUNT) { 12305a5eeccaSmarks 1231bf8b6031Smarks /* is it an old formatted inherit string? */ 1232bf8b6031Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT_V1); 1233bf8b6031Smarks } 12345a5eeccaSmarks 1235bf8b6031Smarks return (rc); 12365a5eeccaSmarks } 12375a5eeccaSmarks 12385a5eeccaSmarks 12395a5eeccaSmarks /* 12405a5eeccaSmarks * compute value for ACE permissions. 12415a5eeccaSmarks */ 12425a5eeccaSmarks int 12435a5eeccaSmarks compute_ace_perms(char *str, uint32_t *mask) 12445a5eeccaSmarks { 12455a5eeccaSmarks int positional = 0; 12465a5eeccaSmarks int error; 12475a5eeccaSmarks 12485a5eeccaSmarks if (strlen(str) == ACE_PERM_COUNT) 12495a5eeccaSmarks positional = 1; 12505a5eeccaSmarks 12515a5eeccaSmarks error = compute_values(ace_perm_table, ACE_PERM_COUNT, 12525a5eeccaSmarks str, positional, mask); 12535a5eeccaSmarks 12545a5eeccaSmarks if (error && positional) { 12555a5eeccaSmarks /* 12565a5eeccaSmarks * If positional was set, then make sure permissions 12575a5eeccaSmarks * aren't actually valid in non positional case where 12585a5eeccaSmarks * all permissions are specified, just in random order. 12595a5eeccaSmarks */ 12605a5eeccaSmarks error = compute_values(ace_perm_table, 12615a5eeccaSmarks ACE_PERM_COUNT, str, 0, mask); 12625a5eeccaSmarks } 12635a5eeccaSmarks if (error) 12645a5eeccaSmarks error = EACL_PERM_MASK_ERROR; 12655a5eeccaSmarks 12665a5eeccaSmarks return (error); 12675a5eeccaSmarks } 12685a5eeccaSmarks 12695a5eeccaSmarks 12705a5eeccaSmarks 12715a5eeccaSmarks /* 12725a5eeccaSmarks * compute values for aclent permissions. 12735a5eeccaSmarks */ 12745a5eeccaSmarks int 12755a5eeccaSmarks compute_aclent_perms(char *str, o_mode_t *mask) 12765a5eeccaSmarks { 12775a5eeccaSmarks int error; 12785a5eeccaSmarks uint32_t pmask; 12795a5eeccaSmarks 12805a5eeccaSmarks if (strlen(str) != ACLENT_PERM_COUNT) 12815a5eeccaSmarks return (EACL_PERM_MASK_ERROR); 12825a5eeccaSmarks 12835a5eeccaSmarks *mask = 0; 12845a5eeccaSmarks error = compute_values(aclent_perm_table, ACLENT_PERM_COUNT, 12855a5eeccaSmarks str, 1, &pmask); 12865a5eeccaSmarks if (error == 0) { 12875a5eeccaSmarks *mask = (o_mode_t)pmask; 12885a5eeccaSmarks } else 12895a5eeccaSmarks error = EACL_PERM_MASK_ERROR; 12905a5eeccaSmarks return (error); 12915a5eeccaSmarks } 12925a5eeccaSmarks 12935a5eeccaSmarks /* 12945a5eeccaSmarks * determine ACE permissions. 12955a5eeccaSmarks */ 12965a5eeccaSmarks int 12975a5eeccaSmarks ace_perm_mask(struct acl_perm_type *aclperm, uint32_t *mask) 12985a5eeccaSmarks { 12995a5eeccaSmarks int error; 13005a5eeccaSmarks 13015a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_EMPTY) { 13025a5eeccaSmarks *mask = 0; 13035a5eeccaSmarks return (0); 13045a5eeccaSmarks } 13055a5eeccaSmarks 13065a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_ACE) { 13075a5eeccaSmarks *mask = aclperm->perm_val; 13085a5eeccaSmarks return (0); 13095a5eeccaSmarks } 13105a5eeccaSmarks 13115a5eeccaSmarks error = compute_ace_perms(aclperm->perm_str, mask); 13125a5eeccaSmarks if (error) { 13135b233e2dSmarks acl_error(dgettext(TEXT_DOMAIN, 13145b233e2dSmarks "Invalid permission(s) '%s' specified\n"), 13155a5eeccaSmarks aclperm->perm_str); 13165a5eeccaSmarks return (EACL_PERM_MASK_ERROR); 13175a5eeccaSmarks } 13185a5eeccaSmarks 13195a5eeccaSmarks return (0); 13205a5eeccaSmarks } 1321