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 /* 229a2c8b2bSGowtham Thommandra * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <grp.h> 297c478bd9Sstevel@tonic-gate #include <pwd.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <limits.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 33fa9e4066Sahrens #include <errno.h> 347c478bd9Sstevel@tonic-gate #include <sys/param.h> 357c478bd9Sstevel@tonic-gate #include <sys/types.h> 365a5eeccaSmarks #include <sys/stat.h> 377c478bd9Sstevel@tonic-gate #include <sys/acl.h> 38fa9e4066Sahrens #include <aclutils.h> 39b249c65cSmarks #include <idmap.h> 40*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <synch.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; 53*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_t yymutex; 54fa9e4066Sahrens 55fa9e4066Sahrens extern acl_t *acl_alloc(enum acl_type); 567c478bd9Sstevel@tonic-gate 57b249c65cSmarks /* 58b249c65cSmarks * dynamic string that will increase in size on an 59b249c65cSmarks * as needed basis. 60b249c65cSmarks */ 61b249c65cSmarks typedef struct dynaclstr { 62b249c65cSmarks size_t d_bufsize; /* current size of aclexport */ 63b249c65cSmarks char *d_aclexport; 64b249c65cSmarks int d_pos; 65b249c65cSmarks } dynaclstr_t; 6611e32170Shm123892 67b249c65cSmarks static int str_append(dynaclstr_t *, char *); 68b249c65cSmarks static int aclent_perm_txt(dynaclstr_t *, o_mode_t); 697c478bd9Sstevel@tonic-gate 705a5eeccaSmarks static void 715a5eeccaSmarks aclent_perms(int perm, char *txt_perms) 72fa9e4066Sahrens { 735a5eeccaSmarks if (perm & S_IROTH) 745a5eeccaSmarks txt_perms[0] = 'r'; 755a5eeccaSmarks else 765a5eeccaSmarks txt_perms[0] = '-'; 775a5eeccaSmarks if (perm & S_IWOTH) 785a5eeccaSmarks txt_perms[1] = 'w'; 795a5eeccaSmarks else 805a5eeccaSmarks txt_perms[1] = '-'; 815a5eeccaSmarks if (perm & S_IXOTH) 825a5eeccaSmarks txt_perms[2] = 'x'; 835a5eeccaSmarks else 845a5eeccaSmarks txt_perms[2] = '-'; 855a5eeccaSmarks txt_perms[3] = '\0'; 865a5eeccaSmarks } 87fa9e4066Sahrens 885a5eeccaSmarks static char * 89afe1f701Smarks pruname(uid_t uid, char *uidp, size_t buflen, int noresolve) 905a5eeccaSmarks { 9145a17f45Sgjelinek struct passwd *passwdp = NULL; 92fa9e4066Sahrens 9345a17f45Sgjelinek if (noresolve == 0) 945a5eeccaSmarks passwdp = getpwuid(uid); 955a5eeccaSmarks if (passwdp == (struct passwd *)NULL) { 965a5eeccaSmarks /* could not get passwd information: display uid instead */ 97f48205beScasper (void) snprintf(uidp, buflen, "%u", uid); 98afe1f701Smarks } else { 99afe1f701Smarks (void) strlcpy(uidp, passwdp->pw_name, buflen); 100afe1f701Smarks } 1015a5eeccaSmarks return (uidp); 1025a5eeccaSmarks } 103fa9e4066Sahrens 1045a5eeccaSmarks static char * 105afe1f701Smarks prgname(gid_t gid, char *gidp, size_t buflen, int noresolve) 1065a5eeccaSmarks { 10745a17f45Sgjelinek struct group *groupp = NULL; 108fa9e4066Sahrens 10945a17f45Sgjelinek if (noresolve == 0) 1105a5eeccaSmarks groupp = getgrgid(gid); 1115a5eeccaSmarks if (groupp == (struct group *)NULL) { 1125a5eeccaSmarks /* could not get group information: display gid instead */ 113f48205beScasper (void) snprintf(gidp, buflen, "%u", gid); 114afe1f701Smarks } else { 115afe1f701Smarks (void) strlcpy(gidp, groupp->gr_name, buflen); 116afe1f701Smarks } 1175a5eeccaSmarks return (gidp); 1185a5eeccaSmarks } 119b249c65cSmarks 120909c9a9fSMark Shellenbaum static int 121909c9a9fSMark Shellenbaum getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve) 122b249c65cSmarks { 123b249c65cSmarks idmap_handle_t *idmap_hdl = NULL; 124b249c65cSmarks idmap_get_handle_t *get_hdl = NULL; 125b249c65cSmarks idmap_stat status; 126b249c65cSmarks idmap_rid_t rid; 127909c9a9fSMark Shellenbaum int error = IDMAP_ERR_NORESULT; 128b249c65cSmarks int len; 1299a2c8b2bSGowtham Thommandra char *domain = NULL; 1309a2c8b2bSGowtham Thommandra char *name = NULL; 131b249c65cSmarks 132909c9a9fSMark Shellenbaum *sidp = NULL; 133b249c65cSmarks 134b249c65cSmarks /* 135b249c65cSmarks * First try and get windows name 136b249c65cSmarks */ 137b249c65cSmarks 138909c9a9fSMark Shellenbaum if (!noresolve) { 139b249c65cSmarks if (user) 140909c9a9fSMark Shellenbaum error = idmap_getwinnamebyuid(who, 141909c9a9fSMark Shellenbaum IDMAP_REQ_FLG_USE_CACHE, &name, &domain); 142b249c65cSmarks else 143909c9a9fSMark Shellenbaum error = idmap_getwinnamebygid(who, 144909c9a9fSMark Shellenbaum IDMAP_REQ_FLG_USE_CACHE, &name, &domain); 145909c9a9fSMark Shellenbaum } 146909c9a9fSMark Shellenbaum if (error != IDMAP_SUCCESS) { 147909c9a9fSMark Shellenbaum if (idmap_init(&idmap_hdl) == IDMAP_SUCCESS && 148909c9a9fSMark Shellenbaum idmap_get_create(idmap_hdl, &get_hdl) == IDMAP_SUCCESS) { 149b249c65cSmarks if (user) 150b249c65cSmarks error = idmap_get_sidbyuid(get_hdl, who, 1513ee87bcaSJulian Pullen IDMAP_REQ_FLG_USE_CACHE, &domain, &rid, 1523ee87bcaSJulian Pullen &status); 153b249c65cSmarks else 154b249c65cSmarks error = idmap_get_sidbygid(get_hdl, who, 1553ee87bcaSJulian Pullen IDMAP_REQ_FLG_USE_CACHE, &domain, &rid, 1563ee87bcaSJulian Pullen &status); 157909c9a9fSMark Shellenbaum if (error == IDMAP_SUCCESS && 158909c9a9fSMark Shellenbaum idmap_get_mappings(get_hdl) == 0) { 159909c9a9fSMark Shellenbaum if (status == IDMAP_SUCCESS) { 160909c9a9fSMark Shellenbaum len = snprintf(NULL, 0, 161909c9a9fSMark Shellenbaum "%s-%d", domain, rid); 162909c9a9fSMark Shellenbaum if (*sidp = malloc(len + 1)) { 163909c9a9fSMark Shellenbaum (void) snprintf(*sidp, len + 1, 164909c9a9fSMark Shellenbaum "%s-%d", domain, rid); 165b249c65cSmarks } 166909c9a9fSMark Shellenbaum } 167909c9a9fSMark Shellenbaum } 168b249c65cSmarks } 169b249c65cSmarks if (get_hdl) 170b249c65cSmarks idmap_get_destroy(get_hdl); 171b249c65cSmarks if (idmap_hdl) 172b249c65cSmarks (void) idmap_fini(idmap_hdl); 173b249c65cSmarks } else { 174b249c65cSmarks int len; 175909c9a9fSMark Shellenbaum 1765f41bf46SMark Shellenbaum len = snprintf(NULL, 0, "%s@%s", name, domain); 177909c9a9fSMark Shellenbaum if (*sidp = malloc(len + 1)) 178b249c65cSmarks (void) snprintf(*sidp, len + 1, "%s@%s", name, domain); 179b249c65cSmarks } 1809a2c8b2bSGowtham Thommandra 1819a2c8b2bSGowtham Thommandra if (name) 1829a2c8b2bSGowtham Thommandra free(name); 1839a2c8b2bSGowtham Thommandra if (domain) 1849a2c8b2bSGowtham Thommandra free(domain); 185909c9a9fSMark Shellenbaum return (*sidp ? 0 : 1); 186b249c65cSmarks } 187b249c65cSmarks 1885a5eeccaSmarks static void 1895a5eeccaSmarks aclent_printacl(acl_t *aclp) 1905a5eeccaSmarks { 1915a5eeccaSmarks aclent_t *tp; 1925a5eeccaSmarks int aclcnt; 1935a5eeccaSmarks int mask; 1945a5eeccaSmarks int slot = 0; 1955a5eeccaSmarks char perm[4]; 196afe1f701Smarks char uidp[ID_STR_MAX]; 197afe1f701Smarks char gidp[ID_STR_MAX]; 1985a5eeccaSmarks 1995a5eeccaSmarks /* display ACL: assume it is sorted. */ 2005a5eeccaSmarks aclcnt = aclp->acl_cnt; 2015a5eeccaSmarks for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) { 2025a5eeccaSmarks if (tp->a_type == CLASS_OBJ) 2035a5eeccaSmarks mask = tp->a_perm; 2045a5eeccaSmarks } 2055a5eeccaSmarks aclcnt = aclp->acl_cnt; 2065a5eeccaSmarks for (tp = aclp->acl_aclp; aclcnt--; tp++) { 2075a5eeccaSmarks (void) printf(" %d:", slot++); 2085a5eeccaSmarks switch (tp->a_type) { 2095a5eeccaSmarks case USER: 2105a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2115a5eeccaSmarks (void) printf("user:%s:%s\t\t", 212afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm); 2135a5eeccaSmarks aclent_perms((tp->a_perm & mask), perm); 2145a5eeccaSmarks (void) printf("#effective:%s\n", perm); 2155a5eeccaSmarks break; 2165a5eeccaSmarks case USER_OBJ: 2175a5eeccaSmarks /* no need to display uid */ 2185a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2195a5eeccaSmarks (void) printf("user::%s\n", perm); 2205a5eeccaSmarks break; 2215a5eeccaSmarks case GROUP: 2225a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2235a5eeccaSmarks (void) printf("group:%s:%s\t\t", 224afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm); 2255a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm); 2265a5eeccaSmarks (void) printf("#effective:%s\n", perm); 2275a5eeccaSmarks break; 2285a5eeccaSmarks case GROUP_OBJ: 2295a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2305a5eeccaSmarks (void) printf("group::%s\t\t", perm); 2315a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm); 2325a5eeccaSmarks (void) printf("#effective:%s\n", perm); 2335a5eeccaSmarks break; 2345a5eeccaSmarks case CLASS_OBJ: 2355a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2365a5eeccaSmarks (void) printf("mask:%s\n", perm); 2375a5eeccaSmarks break; 2385a5eeccaSmarks case OTHER_OBJ: 2395a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2405a5eeccaSmarks (void) printf("other:%s\n", perm); 2415a5eeccaSmarks break; 2425a5eeccaSmarks case DEF_USER: 2435a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2445a5eeccaSmarks (void) printf("default:user:%s:%s\n", 245afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm); 2465a5eeccaSmarks break; 2475a5eeccaSmarks case DEF_USER_OBJ: 2485a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2495a5eeccaSmarks (void) printf("default:user::%s\n", perm); 2505a5eeccaSmarks break; 2515a5eeccaSmarks case DEF_GROUP: 2525a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2535a5eeccaSmarks (void) printf("default:group:%s:%s\n", 254afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm); 2555a5eeccaSmarks break; 2565a5eeccaSmarks case DEF_GROUP_OBJ: 2575a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2585a5eeccaSmarks (void) printf("default:group::%s\n", perm); 2595a5eeccaSmarks break; 2605a5eeccaSmarks case DEF_CLASS_OBJ: 2615a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2625a5eeccaSmarks (void) printf("default:mask:%s\n", perm); 2635a5eeccaSmarks break; 2645a5eeccaSmarks case DEF_OTHER_OBJ: 2655a5eeccaSmarks aclent_perms(tp->a_perm, perm); 2665a5eeccaSmarks (void) printf("default:other:%s\n", perm); 2675a5eeccaSmarks break; 2685a5eeccaSmarks default: 2695a5eeccaSmarks (void) fprintf(stderr, 2705b233e2dSmarks dgettext(TEXT_DOMAIN, "unrecognized entry\n")); 2715a5eeccaSmarks break; 2725a5eeccaSmarks } 2735a5eeccaSmarks } 2745a5eeccaSmarks } 2755a5eeccaSmarks 2765a5eeccaSmarks static void 2775a5eeccaSmarks split_line(char *str, int cols) 2785a5eeccaSmarks { 2795a5eeccaSmarks char *ptr; 2805a5eeccaSmarks int len; 2815a5eeccaSmarks int i; 2825a5eeccaSmarks int last_split; 2835a5eeccaSmarks char *pad = ""; 2845a5eeccaSmarks int pad_len; 2855a5eeccaSmarks 2865a5eeccaSmarks len = strlen(str); 2875a5eeccaSmarks ptr = str; 2885a5eeccaSmarks pad_len = 0; 2895a5eeccaSmarks 2905a5eeccaSmarks ptr = str; 2915a5eeccaSmarks last_split = 0; 2925a5eeccaSmarks for (i = 0; i != len; i++) { 2935a5eeccaSmarks if ((i + pad_len + 4) >= cols) { 2945a5eeccaSmarks (void) printf("%s%.*s\n", pad, last_split, ptr); 2955a5eeccaSmarks ptr = &ptr[last_split]; 2965a5eeccaSmarks len = strlen(ptr); 2975a5eeccaSmarks i = 0; 2985a5eeccaSmarks pad_len = 4; 2995a5eeccaSmarks pad = " "; 3005a5eeccaSmarks } else { 3015a5eeccaSmarks if (ptr[i] == '/' || ptr[i] == ':') { 3025a5eeccaSmarks last_split = i; 3035a5eeccaSmarks } 3045a5eeccaSmarks } 3055a5eeccaSmarks } 3065a5eeccaSmarks if (i == len) { 3075a5eeccaSmarks (void) printf("%s%s\n", pad, ptr); 3085a5eeccaSmarks } 3095a5eeccaSmarks } 3105a5eeccaSmarks 311b249c65cSmarks /* 312b249c65cSmarks * compute entry type string, such as user:joe, group:staff,... 313b249c65cSmarks */ 314b249c65cSmarks static int 315b249c65cSmarks aclent_type_txt(dynaclstr_t *dstr, aclent_t *aclp, int flags) 3165a5eeccaSmarks { 317afe1f701Smarks char idp[ID_STR_MAX]; 318b249c65cSmarks int error; 3195a5eeccaSmarks 320b249c65cSmarks switch (aclp->a_type) { 321b249c65cSmarks case DEF_USER_OBJ: 322b249c65cSmarks case USER_OBJ: 323b249c65cSmarks if (aclp->a_type == USER_OBJ) 324b249c65cSmarks error = str_append(dstr, "user::"); 325b249c65cSmarks else 326b249c65cSmarks error = str_append(dstr, "defaultuser::"); 327b249c65cSmarks break; 328b249c65cSmarks 329b249c65cSmarks case DEF_USER: 330b249c65cSmarks case USER: 331b249c65cSmarks if (aclp->a_type == USER) 332b249c65cSmarks error = str_append(dstr, "user:"); 333b249c65cSmarks else 334b249c65cSmarks error = str_append(dstr, "defaultuser:"); 335b249c65cSmarks if (error) 336b249c65cSmarks break; 337b249c65cSmarks error = str_append(dstr, pruname(aclp->a_id, idp, 338b249c65cSmarks sizeof (idp), flags & ACL_NORESOLVE)); 339b249c65cSmarks if (error == 0) 340b249c65cSmarks error = str_append(dstr, ":"); 341b249c65cSmarks break; 342b249c65cSmarks 343b249c65cSmarks case DEF_GROUP_OBJ: 344b249c65cSmarks case GROUP_OBJ: 345b249c65cSmarks if (aclp->a_type == GROUP_OBJ) 346b249c65cSmarks error = str_append(dstr, "group::"); 347b249c65cSmarks else 348b249c65cSmarks error = str_append(dstr, "defaultgroup::"); 349b249c65cSmarks break; 350b249c65cSmarks 351b249c65cSmarks case DEF_GROUP: 352b249c65cSmarks case GROUP: 353b249c65cSmarks if (aclp->a_type == GROUP) 354b249c65cSmarks error = str_append(dstr, "group:"); 355b249c65cSmarks else 356b249c65cSmarks error = str_append(dstr, "defaultgroup:"); 357b249c65cSmarks if (error) 358b249c65cSmarks break; 359b249c65cSmarks error = str_append(dstr, prgname(aclp->a_id, idp, 360b249c65cSmarks sizeof (idp), flags & ACL_NORESOLVE)); 361b249c65cSmarks if (error == 0) 362b249c65cSmarks error = str_append(dstr, ":"); 363b249c65cSmarks break; 364b249c65cSmarks 365b249c65cSmarks case DEF_CLASS_OBJ: 366b249c65cSmarks case CLASS_OBJ: 367b249c65cSmarks if (aclp->a_type == CLASS_OBJ) 368b249c65cSmarks error = str_append(dstr, "mask:"); 369b249c65cSmarks else 370b249c65cSmarks error = str_append(dstr, "defaultmask:"); 371b249c65cSmarks break; 372b249c65cSmarks 373b249c65cSmarks case DEF_OTHER_OBJ: 374b249c65cSmarks case OTHER_OBJ: 375b249c65cSmarks if (aclp->a_type == OTHER_OBJ) 376b249c65cSmarks error = str_append(dstr, "other:"); 377b249c65cSmarks else 378b249c65cSmarks error = str_append(dstr, "defaultother:"); 379b249c65cSmarks break; 380b249c65cSmarks 381b249c65cSmarks default: 382b249c65cSmarks error = 1; 383b249c65cSmarks break; 384b249c65cSmarks } 385b249c65cSmarks 386b249c65cSmarks return (error); 387b249c65cSmarks } 388b249c65cSmarks 389b249c65cSmarks /* 390b249c65cSmarks * compute entry type string such as, owner@:, user:joe, group:staff,... 391b249c65cSmarks */ 392b249c65cSmarks static int 393b249c65cSmarks ace_type_txt(dynaclstr_t *dynstr, ace_t *acep, int flags) 394b249c65cSmarks { 395b249c65cSmarks char idp[ID_STR_MAX]; 396b249c65cSmarks int error; 397b249c65cSmarks char *sidp = NULL; 3985a5eeccaSmarks 3995a5eeccaSmarks switch (acep->a_flags & ACE_TYPE_FLAGS) { 4005a5eeccaSmarks case ACE_OWNER: 401b249c65cSmarks error = str_append(dynstr, OWNERAT_TXT); 4025a5eeccaSmarks break; 4035a5eeccaSmarks 4045a5eeccaSmarks case ACE_GROUP|ACE_IDENTIFIER_GROUP: 405b249c65cSmarks error = str_append(dynstr, GROUPAT_TXT); 4065a5eeccaSmarks break; 4075a5eeccaSmarks 4085a5eeccaSmarks case ACE_IDENTIFIER_GROUP: 409b249c65cSmarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) { 410b249c65cSmarks if (error = str_append(dynstr, 411b249c65cSmarks GROUPSID_TXT)) 412b249c65cSmarks break; 413909c9a9fSMark Shellenbaum if (error = getsidname(acep->a_who, B_FALSE, 414909c9a9fSMark Shellenbaum &sidp, flags & ACL_NORESOLVE)) 415909c9a9fSMark Shellenbaum break; 416909c9a9fSMark Shellenbaum error = str_append(dynstr, sidp); 417b249c65cSmarks } else { 418b249c65cSmarks if (error = str_append(dynstr, GROUP_TXT)) 419b249c65cSmarks break; 420b249c65cSmarks error = str_append(dynstr, prgname(acep->a_who, idp, 421afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE)); 422b249c65cSmarks } 423b249c65cSmarks if (error == 0) 424b249c65cSmarks error = str_append(dynstr, ":"); 4255a5eeccaSmarks break; 4265a5eeccaSmarks 4275a5eeccaSmarks case ACE_EVERYONE: 428b249c65cSmarks error = str_append(dynstr, EVERYONEAT_TXT); 4295a5eeccaSmarks break; 4305a5eeccaSmarks 4315a5eeccaSmarks case 0: 432b249c65cSmarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) { 433b249c65cSmarks if (error = str_append(dynstr, USERSID_TXT)) 434b249c65cSmarks break; 435909c9a9fSMark Shellenbaum if (error = getsidname(acep->a_who, B_TRUE, 436909c9a9fSMark Shellenbaum &sidp, flags & ACL_NORESOLVE)) 437909c9a9fSMark Shellenbaum break; 438909c9a9fSMark Shellenbaum error = str_append(dynstr, sidp); 439b249c65cSmarks } else { 440b249c65cSmarks if (error = str_append(dynstr, USER_TXT)) 441b249c65cSmarks break; 442b249c65cSmarks error = str_append(dynstr, pruname(acep->a_who, idp, 443afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE)); 444b249c65cSmarks } 445b249c65cSmarks if (error == 0) 446b249c65cSmarks error = str_append(dynstr, ":"); 447b249c65cSmarks break; 448b249c65cSmarks default: 449b249c65cSmarks error = 0; 4505a5eeccaSmarks break; 4515a5eeccaSmarks } 4525a5eeccaSmarks 453b249c65cSmarks if (sidp) 454b249c65cSmarks free(sidp); 455b249c65cSmarks return (error); 4565a5eeccaSmarks } 4575a5eeccaSmarks 458b249c65cSmarks /* 459b249c65cSmarks * compute string of permissions, such as read_data/write_data or 460b249c65cSmarks * rwxp,... 461b249c65cSmarks * The format depends on the flags field which indicates whether the compact 462b249c65cSmarks * or verbose format should be used. 463b249c65cSmarks */ 464b249c65cSmarks static int 465b249c65cSmarks ace_perm_txt(dynaclstr_t *dstr, uint32_t mask, 4665a5eeccaSmarks uint32_t iflags, int isdir, int flags) 4675a5eeccaSmarks { 468b249c65cSmarks int error = 0; 4695a5eeccaSmarks 4705a5eeccaSmarks if (flags & ACL_COMPACT_FMT) { 471b249c65cSmarks char buf[16]; 4725a5eeccaSmarks 4735a5eeccaSmarks if (mask & ACE_READ_DATA) 4745a5eeccaSmarks buf[0] = 'r'; 4755a5eeccaSmarks else 4765a5eeccaSmarks buf[0] = '-'; 4775a5eeccaSmarks if (mask & ACE_WRITE_DATA) 4785a5eeccaSmarks buf[1] = 'w'; 4795a5eeccaSmarks else 4805a5eeccaSmarks buf[1] = '-'; 4815a5eeccaSmarks if (mask & ACE_EXECUTE) 4825a5eeccaSmarks buf[2] = 'x'; 4835a5eeccaSmarks else 4845a5eeccaSmarks buf[2] = '-'; 4855a5eeccaSmarks if (mask & ACE_APPEND_DATA) 4865a5eeccaSmarks buf[3] = 'p'; 4875a5eeccaSmarks else 4885a5eeccaSmarks buf[3] = '-'; 4895a5eeccaSmarks if (mask & ACE_DELETE) 4905a5eeccaSmarks buf[4] = 'd'; 4915a5eeccaSmarks else 4925a5eeccaSmarks buf[4] = '-'; 4935a5eeccaSmarks if (mask & ACE_DELETE_CHILD) 4945a5eeccaSmarks buf[5] = 'D'; 4955a5eeccaSmarks else 4965a5eeccaSmarks buf[5] = '-'; 4975a5eeccaSmarks if (mask & ACE_READ_ATTRIBUTES) 4985a5eeccaSmarks buf[6] = 'a'; 4995a5eeccaSmarks else 5005a5eeccaSmarks buf[6] = '-'; 5015a5eeccaSmarks if (mask & ACE_WRITE_ATTRIBUTES) 5025a5eeccaSmarks buf[7] = 'A'; 5035a5eeccaSmarks else 5045a5eeccaSmarks buf[7] = '-'; 5055a5eeccaSmarks if (mask & ACE_READ_NAMED_ATTRS) 5065a5eeccaSmarks buf[8] = 'R'; 5075a5eeccaSmarks else 5085a5eeccaSmarks buf[8] = '-'; 5095a5eeccaSmarks if (mask & ACE_WRITE_NAMED_ATTRS) 5105a5eeccaSmarks buf[9] = 'W'; 5115a5eeccaSmarks else 5125a5eeccaSmarks buf[9] = '-'; 5135a5eeccaSmarks if (mask & ACE_READ_ACL) 5145a5eeccaSmarks buf[10] = 'c'; 5155a5eeccaSmarks else 5165a5eeccaSmarks buf[10] = '-'; 5175a5eeccaSmarks if (mask & ACE_WRITE_ACL) 5185a5eeccaSmarks buf[11] = 'C'; 5195a5eeccaSmarks else 5205a5eeccaSmarks buf[11] = '-'; 5215a5eeccaSmarks if (mask & ACE_WRITE_OWNER) 5225a5eeccaSmarks buf[12] = 'o'; 5235a5eeccaSmarks else 5245a5eeccaSmarks buf[12] = '-'; 5255a5eeccaSmarks if (mask & ACE_SYNCHRONIZE) 5265a5eeccaSmarks buf[13] = 's'; 5275a5eeccaSmarks else 5285a5eeccaSmarks buf[13] = '-'; 529b249c65cSmarks buf[14] = ':'; 530b249c65cSmarks buf[15] = '\0'; 531b249c65cSmarks error = str_append(dstr, buf); 5325a5eeccaSmarks } else { 5335a5eeccaSmarks /* 5345a5eeccaSmarks * If ACE is a directory, but inheritance indicates its 5355a5eeccaSmarks * for a file then print permissions for file rather than 5365a5eeccaSmarks * dir. 5375a5eeccaSmarks */ 5385a5eeccaSmarks if (isdir) { 5395a5eeccaSmarks if (mask & ACE_LIST_DIRECTORY) { 5405a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 541b249c65cSmarks error = str_append(dstr, 542b249c65cSmarks READ_DATA_TXT); 5435a5eeccaSmarks } else { 544b249c65cSmarks error = 545b249c65cSmarks str_append(dstr, READ_DIR_TXT); 5465a5eeccaSmarks } 5475a5eeccaSmarks } 548b249c65cSmarks if (error == 0 && (mask & ACE_ADD_FILE)) { 5495a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 550b249c65cSmarks error = 551b249c65cSmarks str_append(dstr, WRITE_DATA_TXT); 5525a5eeccaSmarks } else { 553b249c65cSmarks error = 554b249c65cSmarks str_append(dstr, ADD_FILE_TXT); 5555a5eeccaSmarks } 5565a5eeccaSmarks } 557b249c65cSmarks if (error == 0 && (mask & ACE_ADD_SUBDIRECTORY)) { 5585a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 559b249c65cSmarks error = str_append(dstr, 560b249c65cSmarks APPEND_DATA_TXT); 5615a5eeccaSmarks } else { 562b249c65cSmarks error = str_append(dstr, 563b249c65cSmarks ADD_DIR_TXT); 5645a5eeccaSmarks } 5655a5eeccaSmarks } 5665a5eeccaSmarks } else { 5675a5eeccaSmarks if (mask & ACE_READ_DATA) { 568b249c65cSmarks error = str_append(dstr, READ_DATA_TXT); 5695a5eeccaSmarks } 570b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_DATA)) { 571b249c65cSmarks error = str_append(dstr, WRITE_DATA_TXT); 5725a5eeccaSmarks } 573b249c65cSmarks if (error == 0 && (mask & ACE_APPEND_DATA)) { 574b249c65cSmarks error = str_append(dstr, APPEND_DATA_TXT); 5755a5eeccaSmarks } 5765a5eeccaSmarks } 577b249c65cSmarks if (error == 0 && (mask & ACE_READ_NAMED_ATTRS)) { 578b249c65cSmarks error = str_append(dstr, READ_XATTR_TXT); 5795a5eeccaSmarks } 580b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_NAMED_ATTRS)) { 581b249c65cSmarks error = str_append(dstr, WRITE_XATTR_TXT); 5825a5eeccaSmarks } 583b249c65cSmarks if (error == 0 && (mask & ACE_EXECUTE)) { 584b249c65cSmarks error = str_append(dstr, EXECUTE_TXT); 5855a5eeccaSmarks } 586b249c65cSmarks if (error == 0 && (mask & ACE_DELETE_CHILD)) { 587b249c65cSmarks error = str_append(dstr, DELETE_CHILD_TXT); 5885a5eeccaSmarks } 589b249c65cSmarks if (error == 0 && (mask & ACE_READ_ATTRIBUTES)) { 590b249c65cSmarks error = str_append(dstr, READ_ATTRIBUTES_TXT); 5915a5eeccaSmarks } 592b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_ATTRIBUTES)) { 593b249c65cSmarks error = str_append(dstr, WRITE_ATTRIBUTES_TXT); 5945a5eeccaSmarks } 595b249c65cSmarks if (error == 0 && (mask & ACE_DELETE)) { 596b249c65cSmarks error = str_append(dstr, DELETE_TXT); 5975a5eeccaSmarks } 598b249c65cSmarks if (error == 0 && (mask & ACE_READ_ACL)) { 599b249c65cSmarks error = str_append(dstr, READ_ACL_TXT); 6005a5eeccaSmarks } 601b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_ACL)) { 602b249c65cSmarks error = str_append(dstr, WRITE_ACL_TXT); 6035a5eeccaSmarks } 604b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_OWNER)) { 605b249c65cSmarks error = str_append(dstr, WRITE_OWNER_TXT); 6065a5eeccaSmarks } 607b249c65cSmarks if (error == 0 && (mask & ACE_SYNCHRONIZE)) { 608b249c65cSmarks error = str_append(dstr, SYNCHRONIZE_TXT); 609b249c65cSmarks } 610b249c65cSmarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') { 611b249c65cSmarks dstr->d_aclexport[--dstr->d_pos] = '\0'; 612b249c65cSmarks } 613b249c65cSmarks if (error == 0) 614b249c65cSmarks error = str_append(dstr, ":"); 615b249c65cSmarks } 616b249c65cSmarks return (error); 6175a5eeccaSmarks } 6185a5eeccaSmarks 619b249c65cSmarks /* 620b249c65cSmarks * compute string of access type, such as allow, deny, ... 621b249c65cSmarks */ 622b249c65cSmarks static int 623b249c65cSmarks ace_access_txt(dynaclstr_t *dstr, int type) 6245a5eeccaSmarks { 625b249c65cSmarks int error; 6265a5eeccaSmarks 627b249c65cSmarks if (type == ACE_ACCESS_ALLOWED_ACE_TYPE) 628b249c65cSmarks error = str_append(dstr, ALLOW_TXT); 629b249c65cSmarks else if (type == ACE_ACCESS_DENIED_ACE_TYPE) 630b249c65cSmarks error = str_append(dstr, DENY_TXT); 631b249c65cSmarks else if (type == ACE_SYSTEM_AUDIT_ACE_TYPE) 632b249c65cSmarks error = str_append(dstr, AUDIT_TXT); 633b249c65cSmarks else if (type == ACE_SYSTEM_ALARM_ACE_TYPE) 634b249c65cSmarks error = str_append(dstr, ALARM_TXT); 635b249c65cSmarks else 636b249c65cSmarks error = str_append(dstr, UNKNOWN_TXT); 6375a5eeccaSmarks 638b249c65cSmarks return (error); 6395a5eeccaSmarks } 6405a5eeccaSmarks 641b249c65cSmarks static int 642b249c65cSmarks ace_inherit_txt(dynaclstr_t *dstr, uint32_t iflags, int flags) 6435a5eeccaSmarks { 644b249c65cSmarks int error = 0; 6455a5eeccaSmarks 6465a5eeccaSmarks if (flags & ACL_COMPACT_FMT) { 647b249c65cSmarks char buf[9]; 648b249c65cSmarks 6495a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE) 6505a5eeccaSmarks buf[0] = 'f'; 6515a5eeccaSmarks else 6525a5eeccaSmarks buf[0] = '-'; 6535a5eeccaSmarks if (iflags & ACE_DIRECTORY_INHERIT_ACE) 6545a5eeccaSmarks buf[1] = 'd'; 6555a5eeccaSmarks else 6565a5eeccaSmarks buf[1] = '-'; 6575a5eeccaSmarks if (iflags & ACE_INHERIT_ONLY_ACE) 6585a5eeccaSmarks buf[2] = 'i'; 6595a5eeccaSmarks else 6605a5eeccaSmarks buf[2] = '-'; 6615a5eeccaSmarks if (iflags & ACE_NO_PROPAGATE_INHERIT_ACE) 6625a5eeccaSmarks buf[3] = 'n'; 6635a5eeccaSmarks else 6645a5eeccaSmarks buf[3] = '-'; 6655a5eeccaSmarks if (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG) 6665a5eeccaSmarks buf[4] = 'S'; 6675a5eeccaSmarks else 6685a5eeccaSmarks buf[4] = '-'; 6695a5eeccaSmarks if (iflags & ACE_FAILED_ACCESS_ACE_FLAG) 6705a5eeccaSmarks buf[5] = 'F'; 6715a5eeccaSmarks else 6725a5eeccaSmarks buf[5] = '-'; 673da6c28aaSamw if (iflags & ACE_INHERITED_ACE) 674da6c28aaSamw buf[6] = 'I'; 675da6c28aaSamw else 676da6c28aaSamw buf[6] = '-'; 677b249c65cSmarks buf[7] = ':'; 678b249c65cSmarks buf[8] = '\0'; 679b249c65cSmarks error = str_append(dstr, buf); 6805a5eeccaSmarks } else { 6815a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE) { 682b249c65cSmarks error = str_append(dstr, FILE_INHERIT_TXT); 6835a5eeccaSmarks } 684b249c65cSmarks if (error == 0 && (iflags & ACE_DIRECTORY_INHERIT_ACE)) { 685b249c65cSmarks error = str_append(dstr, DIR_INHERIT_TXT); 6865a5eeccaSmarks } 687b249c65cSmarks if (error == 0 && (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)) { 688b249c65cSmarks error = str_append(dstr, NO_PROPAGATE_TXT); 6895a5eeccaSmarks } 690b249c65cSmarks if (error == 0 && (iflags & ACE_INHERIT_ONLY_ACE)) { 691b249c65cSmarks error = str_append(dstr, INHERIT_ONLY_TXT); 6925a5eeccaSmarks } 693b249c65cSmarks if (error == 0 && (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)) { 694b249c65cSmarks error = str_append(dstr, SUCCESSFUL_ACCESS_TXT); 695da6c28aaSamw } 696b249c65cSmarks if (error == 0 && (iflags & ACE_FAILED_ACCESS_ACE_FLAG)) { 697b249c65cSmarks error = str_append(dstr, FAILED_ACCESS_TXT); 698da6c28aaSamw } 699b249c65cSmarks if (error == 0 && (iflags & ACE_INHERITED_ACE)) { 700b249c65cSmarks error = str_append(dstr, INHERITED_ACE_TXT); 701b249c65cSmarks } 702b249c65cSmarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') { 703b249c65cSmarks dstr->d_aclexport[--dstr->d_pos] = '\0'; 704b249c65cSmarks error = str_append(dstr, ":"); 705b249c65cSmarks } 706da6c28aaSamw } 7075a5eeccaSmarks 708b249c65cSmarks return (error); 709fa9e4066Sahrens } 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate /* 7127c478bd9Sstevel@tonic-gate * Convert internal acl representation to external representation. 7137c478bd9Sstevel@tonic-gate * 7147c478bd9Sstevel@tonic-gate * The length of a non-owning user name or non-owning group name ie entries 7157c478bd9Sstevel@tonic-gate * of type DEF_USER, USER, DEF_GROUP or GROUP, can exceed LOGNAME_MAX. We 7167c478bd9Sstevel@tonic-gate * thus check the length of these entries, and if greater than LOGNAME_MAX, 7177c478bd9Sstevel@tonic-gate * we realloc() via increase_length(). 7187c478bd9Sstevel@tonic-gate * 7197c478bd9Sstevel@tonic-gate * The LOGNAME_MAX, ENTRYTYPELEN and PERMS limits are otherwise always 7207c478bd9Sstevel@tonic-gate * adhered to. 7217c478bd9Sstevel@tonic-gate */ 7225a5eeccaSmarks 7235a5eeccaSmarks /* 7245a5eeccaSmarks * acltotext() converts each ACL entry to look like this: 7255a5eeccaSmarks * 7265a5eeccaSmarks * entry_type:uid^gid^name:perms[:id] 7275a5eeccaSmarks * 7285a5eeccaSmarks * The maximum length of entry_type is 14 ("defaultgroup::" and 7295a5eeccaSmarks * "defaultother::") hence ENTRYTYPELEN is set to 14. 7305a5eeccaSmarks * 7315a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8, hence we use, 7325a5eeccaSmarks * however the ID could be a number so we therefore use ID_STR_MAX 7335a5eeccaSmarks * 7345a5eeccaSmarks * The length of a perms entry is 4 to allow for the comma appended to each 7355a5eeccaSmarks * to each acl entry. Hence PERMS is set to 4. 7365a5eeccaSmarks */ 7375a5eeccaSmarks 7385a5eeccaSmarks #define ENTRYTYPELEN 14 7395a5eeccaSmarks #define PERMS 4 7405a5eeccaSmarks #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX) 7415a5eeccaSmarks 7427c478bd9Sstevel@tonic-gate char * 7435a5eeccaSmarks aclent_acltotext(aclent_t *aclp, int aclcnt, int flags) 7447c478bd9Sstevel@tonic-gate { 745b249c65cSmarks dynaclstr_t *dstr; 746909c9a9fSMark Shellenbaum char *aclexport = NULL; 747b249c65cSmarks int i; 748b249c65cSmarks int error = 0; 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate if (aclp == NULL) 7517c478bd9Sstevel@tonic-gate return (NULL); 752b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL) 7537c478bd9Sstevel@tonic-gate return (NULL); 754b249c65cSmarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE; 755b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) { 7567c478bd9Sstevel@tonic-gate free(dstr); 7577c478bd9Sstevel@tonic-gate return (NULL); 7587c478bd9Sstevel@tonic-gate } 759b249c65cSmarks *dstr->d_aclexport = '\0'; 760b249c65cSmarks dstr->d_pos = 0; 7617c478bd9Sstevel@tonic-gate 7627c478bd9Sstevel@tonic-gate for (i = 0; i < aclcnt; i++, aclp++) { 763b249c65cSmarks if (error = aclent_type_txt(dstr, aclp, flags)) 7647c478bd9Sstevel@tonic-gate break; 765b249c65cSmarks if (error = aclent_perm_txt(dstr, aclp->a_perm)) 7667c478bd9Sstevel@tonic-gate break; 7675a5eeccaSmarks 7685a5eeccaSmarks if ((flags & ACL_APPEND_ID) && ((aclp->a_type == USER) || 7695a5eeccaSmarks (aclp->a_type == DEF_USER) || (aclp->a_type == GROUP) || 7705a5eeccaSmarks (aclp->a_type == DEF_GROUP))) { 771b249c65cSmarks char id[ID_STR_MAX], *idstr; 772b249c65cSmarks 773b249c65cSmarks if (error = str_append(dstr, ":")) 774b249c65cSmarks break; 7755a5eeccaSmarks id[ID_STR_MAX - 1] = '\0'; /* null terminate buffer */ 7765a5eeccaSmarks idstr = lltostr(aclp->a_id, &id[ID_STR_MAX - 1]); 777b249c65cSmarks if (error = str_append(dstr, idstr)) 778b249c65cSmarks break; 7795a5eeccaSmarks } 7807c478bd9Sstevel@tonic-gate if (i < aclcnt - 1) 781b249c65cSmarks if (error = str_append(dstr, ",")) 782b249c65cSmarks break; 7837c478bd9Sstevel@tonic-gate } 784b249c65cSmarks if (error) { 785b249c65cSmarks if (dstr->d_aclexport) 786b249c65cSmarks free(dstr->d_aclexport); 787b249c65cSmarks } else { 788b249c65cSmarks aclexport = dstr->d_aclexport; 789b249c65cSmarks } 7907c478bd9Sstevel@tonic-gate free(dstr); 7917c478bd9Sstevel@tonic-gate return (aclexport); 7927c478bd9Sstevel@tonic-gate } 7937c478bd9Sstevel@tonic-gate 7945a5eeccaSmarks char * 7955a5eeccaSmarks acltotext(aclent_t *aclp, int aclcnt) 7967c478bd9Sstevel@tonic-gate { 7975a5eeccaSmarks return (aclent_acltotext(aclp, aclcnt, 0)); 798fa9e4066Sahrens } 799fa9e4066Sahrens 8007c478bd9Sstevel@tonic-gate 801fa9e4066Sahrens aclent_t * 802fa9e4066Sahrens aclfromtext(char *aclstr, int *aclcnt) 803fa9e4066Sahrens { 804fa9e4066Sahrens acl_t *aclp; 805fa9e4066Sahrens aclent_t *aclentp; 806fa9e4066Sahrens int error; 807fa9e4066Sahrens 8085a5eeccaSmarks error = acl_fromtext(aclstr, &aclp); 809fa9e4066Sahrens if (error) 810fa9e4066Sahrens return (NULL); 811fa9e4066Sahrens 812fa9e4066Sahrens aclentp = aclp->acl_aclp; 813fa9e4066Sahrens aclp->acl_aclp = NULL; 814fa9e4066Sahrens *aclcnt = aclp->acl_cnt; 8155a5eeccaSmarks 8165a5eeccaSmarks acl_free(aclp); 817fa9e4066Sahrens return (aclentp); 818fa9e4066Sahrens } 819fa9e4066Sahrens 820fa9e4066Sahrens 8217c478bd9Sstevel@tonic-gate /* 822909c9a9fSMark Shellenbaum * Append string onto dynaclstr_t. 823909c9a9fSMark Shellenbaum * 824909c9a9fSMark Shellenbaum * Return 0 on success, 1 for failure. 8257c478bd9Sstevel@tonic-gate */ 8267c478bd9Sstevel@tonic-gate static int 827b249c65cSmarks str_append(dynaclstr_t *dstr, char *newstr) 8287c478bd9Sstevel@tonic-gate { 829b249c65cSmarks size_t len = strlen(newstr); 8307c478bd9Sstevel@tonic-gate 831b249c65cSmarks if ((len + dstr->d_pos) >= dstr->d_bufsize) { 832b249c65cSmarks dstr->d_aclexport = realloc(dstr->d_aclexport, 833b249c65cSmarks dstr->d_bufsize + len + 1); 834b249c65cSmarks if (dstr->d_aclexport == NULL) 8357c478bd9Sstevel@tonic-gate return (1); 836b249c65cSmarks dstr->d_bufsize += len; 837b249c65cSmarks } 838b249c65cSmarks (void) strcat(&dstr->d_aclexport[dstr->d_pos], newstr); 839b249c65cSmarks dstr->d_pos += len; 8407c478bd9Sstevel@tonic-gate return (0); 8417c478bd9Sstevel@tonic-gate } 842fa9e4066Sahrens 843b249c65cSmarks static int 844b249c65cSmarks aclent_perm_txt(dynaclstr_t *dstr, o_mode_t perm) 845b249c65cSmarks { 846b249c65cSmarks char buf[4]; 847b249c65cSmarks 848b249c65cSmarks if (perm & S_IROTH) 849b249c65cSmarks buf[0] = 'r'; 850b249c65cSmarks else 851b249c65cSmarks buf[0] = '-'; 852b249c65cSmarks if (perm & S_IWOTH) 853b249c65cSmarks buf[1] = 'w'; 854b249c65cSmarks else 855b249c65cSmarks buf[1] = '-'; 856b249c65cSmarks if (perm & S_IXOTH) 857b249c65cSmarks buf[2] = 'x'; 858b249c65cSmarks else 859b249c65cSmarks buf[2] = '-'; 860b249c65cSmarks buf[3] = '\0'; 861b249c65cSmarks return (str_append(dstr, buf)); 862b249c65cSmarks } 863b249c65cSmarks 864fa9e4066Sahrens /* 8655a5eeccaSmarks * ace_acltotext() convert each ace formatted acl to look like this: 866fa9e4066Sahrens * 8675a5eeccaSmarks * entry_type:uid^gid^name:perms[:flags]:<allow|deny>[:id][,] 868fa9e4066Sahrens * 869fa9e4066Sahrens * The maximum length of entry_type is 5 ("group") 870fa9e4066Sahrens * 8715a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8, 8725a5eeccaSmarks * however id could be a number so we therefore use ID_STR_MAX 873fa9e4066Sahrens * 874fa9e4066Sahrens * The length of a perms entry is 144 i.e read_data/write_data... 875fa9e4066Sahrens * to each acl entry. 876fa9e4066Sahrens * 877da6c28aaSamw * iflags: file_inherit/dir_inherit/inherit_only/no_propagate/successful_access 878da6c28aaSamw * /failed_access 879fa9e4066Sahrens * 880fa9e4066Sahrens */ 881fa9e4066Sahrens 882fa9e4066Sahrens #define ACE_ENTRYTYPLEN 6 883da6c28aaSamw #define IFLAGS_STR "file_inherit/dir_inherit/inherit_only/no_propagate/" \ 884da6c28aaSamw "successful_access/failed_access/inherited" 885da6c28aaSamw #define IFLAGS_SIZE (sizeof (IFLAGS_STR) - 1) 8865a5eeccaSmarks #define ACCESS_TYPE_SIZE 7 /* if unknown */ 887fa9e4066Sahrens #define COLON_CNT 3 888fa9e4066Sahrens #define PERMS_LEN 216 8895a5eeccaSmarks #define ACE_ENTRY_SIZE (ACE_ENTRYTYPLEN + ID_STR_MAX + PERMS_LEN + \ 8905a5eeccaSmarks ACCESS_TYPE_SIZE + IFLAGS_SIZE + COLON_CNT + APPENDED_ID_MAX) 891fa9e4066Sahrens 892fa9e4066Sahrens static char * 8935a5eeccaSmarks ace_acltotext(acl_t *aceaclp, int flags) 894fa9e4066Sahrens { 895fa9e4066Sahrens ace_t *aclp = aceaclp->acl_aclp; 896fa9e4066Sahrens int aclcnt = aceaclp->acl_cnt; 8975a5eeccaSmarks int i; 898b249c65cSmarks int error = 0; 899fa9e4066Sahrens int isdir = (aceaclp->acl_flags & ACL_IS_DIR); 900b249c65cSmarks dynaclstr_t *dstr; 901909c9a9fSMark Shellenbaum char *aclexport = NULL; 9029a2c8b2bSGowtham Thommandra char *rawsidp = NULL; 903fa9e4066Sahrens 904fa9e4066Sahrens if (aclp == NULL) 905fa9e4066Sahrens return (NULL); 906fa9e4066Sahrens 907b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL) 908b249c65cSmarks return (NULL); 909b249c65cSmarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE; 910b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) { 911b249c65cSmarks free(dstr); 912b249c65cSmarks return (NULL); 913b249c65cSmarks } 914b249c65cSmarks *dstr->d_aclexport = '\0'; 915b249c65cSmarks dstr->d_pos = 0; 916b249c65cSmarks 917fa9e4066Sahrens for (i = 0; i < aclcnt; i++, aclp++) { 918fa9e4066Sahrens 919b249c65cSmarks if (error = ace_type_txt(dstr, aclp, flags)) 920b249c65cSmarks break; 921b249c65cSmarks if (error = ace_perm_txt(dstr, aclp->a_access_mask, 922b249c65cSmarks aclp->a_flags, isdir, flags)) 923b249c65cSmarks break; 924b249c65cSmarks if (error = ace_inherit_txt(dstr, aclp->a_flags, flags)) 925b249c65cSmarks break; 926b249c65cSmarks if (error = ace_access_txt(dstr, aclp->a_type)) 927b249c65cSmarks break; 928fa9e4066Sahrens 9295a5eeccaSmarks if ((flags & ACL_APPEND_ID) && 9305a5eeccaSmarks (((aclp->a_flags & ACE_TYPE_FLAGS) == 0) || 9315a5eeccaSmarks ((aclp->a_flags & ACE_TYPE_FLAGS) == 9325a5eeccaSmarks ACE_IDENTIFIER_GROUP))) { 933b249c65cSmarks char id[ID_STR_MAX], *idstr; 934b249c65cSmarks 935b249c65cSmarks if (error = str_append(dstr, ":")) 936b249c65cSmarks break; 9375f41bf46SMark Shellenbaum 9385f41bf46SMark Shellenbaum rawsidp = NULL; 9395f41bf46SMark Shellenbaum id[ID_STR_MAX -1] = '\0'; /* null terminate */ 9405f41bf46SMark Shellenbaum if (aclp->a_who > MAXUID && (flags & ACL_SID_FMT)) { 9415f41bf46SMark Shellenbaum 9425f41bf46SMark Shellenbaum error = getsidname(aclp->a_who, 9435f41bf46SMark Shellenbaum ((aclp->a_flags & ACE_TYPE_FLAGS) == 0) ? 9445f41bf46SMark Shellenbaum B_TRUE : B_FALSE, &idstr, 1); 9459a2c8b2bSGowtham Thommandra rawsidp = idstr; 9465f41bf46SMark Shellenbaum if (error) 9475f41bf46SMark Shellenbaum break; 9485f41bf46SMark Shellenbaum } else if (aclp->a_who > MAXUID && 9495f41bf46SMark Shellenbaum !(flags & ACL_NORESOLVE)) { 9505f41bf46SMark Shellenbaum idstr = lltostr(UID_NOBODY, 9515f41bf46SMark Shellenbaum &id[ID_STR_MAX - 1]); 9525f41bf46SMark Shellenbaum } else { 9535f41bf46SMark Shellenbaum idstr = lltostr(aclp->a_who, 9545f41bf46SMark Shellenbaum &id[ID_STR_MAX - 1]); 9555f41bf46SMark Shellenbaum } 956b249c65cSmarks if (error = str_append(dstr, idstr)) 957b249c65cSmarks break; 9589a2c8b2bSGowtham Thommandra if (rawsidp) { 9595f41bf46SMark Shellenbaum free(rawsidp); 9609a2c8b2bSGowtham Thommandra rawsidp = NULL; 9619a2c8b2bSGowtham Thommandra } 9625a5eeccaSmarks } 9635a5eeccaSmarks if (i < aclcnt - 1) { 964b249c65cSmarks if (error = str_append(dstr, ",")) 965b249c65cSmarks break; 966fa9e4066Sahrens } 967fa9e4066Sahrens } 9689a2c8b2bSGowtham Thommandra 9699a2c8b2bSGowtham Thommandra if (rawsidp) 9709a2c8b2bSGowtham Thommandra free(rawsidp); 971b249c65cSmarks if (error) { 972b249c65cSmarks if (dstr->d_aclexport) 973b249c65cSmarks free(dstr->d_aclexport); 974b249c65cSmarks } else { 975b249c65cSmarks aclexport = dstr->d_aclexport; 976b249c65cSmarks } 977b249c65cSmarks free(dstr); 978fa9e4066Sahrens return (aclexport); 979fa9e4066Sahrens } 980fa9e4066Sahrens 9815a5eeccaSmarks char * 9825a5eeccaSmarks acl_totext(acl_t *aclp, int flags) 983fa9e4066Sahrens { 9845a5eeccaSmarks char *txtp; 985fa9e4066Sahrens 986fa9e4066Sahrens if (aclp == NULL) 987fa9e4066Sahrens return (NULL); 988fa9e4066Sahrens 989fa9e4066Sahrens switch (aclp->acl_type) { 990fa9e4066Sahrens case ACE_T: 9915a5eeccaSmarks txtp = ace_acltotext(aclp, flags); 9925a5eeccaSmarks break; 993fa9e4066Sahrens case ACLENT_T: 9945a5eeccaSmarks txtp = aclent_acltotext(aclp->acl_aclp, aclp->acl_cnt, flags); 9955a5eeccaSmarks break; 996fa9e4066Sahrens } 9975a5eeccaSmarks 9985a5eeccaSmarks return (txtp); 999fa9e4066Sahrens } 1000fa9e4066Sahrens 1001fa9e4066Sahrens int 1002fa9e4066Sahrens acl_fromtext(const char *acltextp, acl_t **ret_aclp) 1003fa9e4066Sahrens { 10045a5eeccaSmarks int error; 10055a5eeccaSmarks char *buf; 10065a5eeccaSmarks 10075a5eeccaSmarks buf = malloc(strlen(acltextp) + 2); 10085a5eeccaSmarks if (buf == NULL) 10095a5eeccaSmarks return (EACL_MEM_ERROR); 10105a5eeccaSmarks strcpy(buf, acltextp); 10115a5eeccaSmarks strcat(buf, "\n"); 1012*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1013*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&yymutex); 10145a5eeccaSmarks yybuf = buf; 10155a5eeccaSmarks yyreset(); 10165a5eeccaSmarks error = yyparse(); 10175a5eeccaSmarks free(buf); 10185a5eeccaSmarks 10195a5eeccaSmarks if (yyacl) { 10205a5eeccaSmarks if (error == 0) 10215a5eeccaSmarks *ret_aclp = yyacl; 10225a5eeccaSmarks else { 10235a5eeccaSmarks acl_free(yyacl); 10245a5eeccaSmarks } 10255a5eeccaSmarks yyacl = NULL; 10265a5eeccaSmarks } 1027*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&yymutex); 1028*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 10295a5eeccaSmarks return (error); 10305a5eeccaSmarks } 10315a5eeccaSmarks 10325a5eeccaSmarks int 10335a5eeccaSmarks acl_parse(const char *acltextp, acl_t **aclp) 10345a5eeccaSmarks { 1035fa9e4066Sahrens int error; 1036fa9e4066Sahrens 10375a5eeccaSmarks yyinteractive = 1; 10385a5eeccaSmarks error = acl_fromtext(acltextp, aclp); 10395a5eeccaSmarks yyinteractive = 0; 1040fa9e4066Sahrens return (error); 1041fa9e4066Sahrens } 10425a5eeccaSmarks 10435a5eeccaSmarks static void 10445a5eeccaSmarks ace_compact_printacl(acl_t *aclp) 10455a5eeccaSmarks { 10465a5eeccaSmarks int cnt; 10475a5eeccaSmarks ace_t *acep; 1048b249c65cSmarks dynaclstr_t *dstr; 1049b249c65cSmarks int len; 10505a5eeccaSmarks 1051b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL) 1052b249c65cSmarks return; 1053b249c65cSmarks dstr->d_bufsize = ACE_ENTRY_SIZE; 1054b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) { 1055b249c65cSmarks free(dstr); 1056b249c65cSmarks return; 1057b249c65cSmarks } 1058b249c65cSmarks *dstr->d_aclexport = '\0'; 1059b249c65cSmarks 1060b249c65cSmarks dstr->d_pos = 0; 10615a5eeccaSmarks for (cnt = 0, acep = aclp->acl_aclp; 10625a5eeccaSmarks cnt != aclp->acl_cnt; cnt++, acep++) { 1063b249c65cSmarks dstr->d_aclexport[0] = '\0'; 1064b249c65cSmarks dstr->d_pos = 0; 1065b249c65cSmarks 1066b249c65cSmarks if (ace_type_txt(dstr, acep, 0)) 1067b249c65cSmarks break; 1068b249c65cSmarks len = strlen(&dstr->d_aclexport[0]); 1069b249c65cSmarks if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags, 1070b249c65cSmarks aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT)) 1071b249c65cSmarks break; 1072b249c65cSmarks if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT)) 1073b249c65cSmarks break; 1074b249c65cSmarks if (ace_access_txt(dstr, acep->a_type) == -1) 1075b249c65cSmarks break; 1076b249c65cSmarks (void) printf(" %20.*s%s\n", len, dstr->d_aclexport, 1077b249c65cSmarks &dstr->d_aclexport[len]); 10785a5eeccaSmarks } 1079b249c65cSmarks 1080b249c65cSmarks if (dstr->d_aclexport) 1081b249c65cSmarks free(dstr->d_aclexport); 1082b249c65cSmarks free(dstr); 10835a5eeccaSmarks } 10845a5eeccaSmarks 10855a5eeccaSmarks static void 10865a5eeccaSmarks ace_printacl(acl_t *aclp, int cols, int compact) 10875a5eeccaSmarks { 10885a5eeccaSmarks int slot = 0; 10895a5eeccaSmarks char *token; 10905a5eeccaSmarks char *acltext; 10915a5eeccaSmarks 10925a5eeccaSmarks if (compact) { 10935a5eeccaSmarks ace_compact_printacl(aclp); 10945a5eeccaSmarks return; 10955a5eeccaSmarks } 10965a5eeccaSmarks 10975a5eeccaSmarks acltext = acl_totext(aclp, 0); 10985a5eeccaSmarks 10995a5eeccaSmarks if (acltext == NULL) 11005a5eeccaSmarks return; 11015a5eeccaSmarks 11025a5eeccaSmarks token = strtok(acltext, ","); 11035a5eeccaSmarks if (token == NULL) { 11045a5eeccaSmarks free(acltext); 11055a5eeccaSmarks return; 11065a5eeccaSmarks } 11075a5eeccaSmarks 11085a5eeccaSmarks do { 11095a5eeccaSmarks (void) printf(" %d:", slot++); 11105a5eeccaSmarks split_line(token, cols - 5); 11115a5eeccaSmarks } while (token = strtok(NULL, ",")); 11125a5eeccaSmarks free(acltext); 11135a5eeccaSmarks } 11145a5eeccaSmarks 11155a5eeccaSmarks /* 11165a5eeccaSmarks * pretty print an ACL. 11175a5eeccaSmarks * For aclent_t ACL's the format is 11185a5eeccaSmarks * similar to the old format used by getfacl, 11195a5eeccaSmarks * with the addition of adding a "slot" number 11205a5eeccaSmarks * before each entry. 11215a5eeccaSmarks * 11225a5eeccaSmarks * for ace_t ACL's the cols variable will break up 11235a5eeccaSmarks * the long lines into multiple lines and will also 11245a5eeccaSmarks * print a "slot" number. 11255a5eeccaSmarks */ 11265a5eeccaSmarks void 11275a5eeccaSmarks acl_printacl(acl_t *aclp, int cols, int compact) 11285a5eeccaSmarks { 11295a5eeccaSmarks 11305a5eeccaSmarks switch (aclp->acl_type) { 11315a5eeccaSmarks case ACLENT_T: 11325a5eeccaSmarks aclent_printacl(aclp); 11335a5eeccaSmarks break; 11345a5eeccaSmarks case ACE_T: 11355a5eeccaSmarks ace_printacl(aclp, cols, compact); 11365a5eeccaSmarks break; 11375a5eeccaSmarks } 11385a5eeccaSmarks } 11395a5eeccaSmarks 11405a5eeccaSmarks typedef struct value_table { 11415a5eeccaSmarks char p_letter; /* perm letter such as 'r' */ 11425a5eeccaSmarks uint32_t p_value; /* value for perm when pletter found */ 11435a5eeccaSmarks } value_table_t; 11445a5eeccaSmarks 11455a5eeccaSmarks /* 1146da6c28aaSamw * The permission tables are laid out in positional order 11475a5eeccaSmarks * a '-' character will indicate a permission at a given 11485a5eeccaSmarks * position is not specified. The '-' is not part of the 11495a5eeccaSmarks * table, but will be checked for in the permission computation 11505a5eeccaSmarks * routine. 11515a5eeccaSmarks */ 1152da6c28aaSamw value_table_t ace_perm_table[] = { 11535a5eeccaSmarks { 'r', ACE_READ_DATA}, 11545a5eeccaSmarks { 'w', ACE_WRITE_DATA}, 11555a5eeccaSmarks { 'x', ACE_EXECUTE}, 11565a5eeccaSmarks { 'p', ACE_APPEND_DATA}, 11575a5eeccaSmarks { 'd', ACE_DELETE}, 11585a5eeccaSmarks { 'D', ACE_DELETE_CHILD}, 11595a5eeccaSmarks { 'a', ACE_READ_ATTRIBUTES}, 11605a5eeccaSmarks { 'A', ACE_WRITE_ATTRIBUTES}, 11615a5eeccaSmarks { 'R', ACE_READ_NAMED_ATTRS}, 11625a5eeccaSmarks { 'W', ACE_WRITE_NAMED_ATTRS}, 11635a5eeccaSmarks { 'c', ACE_READ_ACL}, 11645a5eeccaSmarks { 'C', ACE_WRITE_ACL}, 11655a5eeccaSmarks { 'o', ACE_WRITE_OWNER}, 11665a5eeccaSmarks { 's', ACE_SYNCHRONIZE} 11675a5eeccaSmarks }; 11685a5eeccaSmarks 1169da6c28aaSamw #define ACE_PERM_COUNT (sizeof (ace_perm_table) / sizeof (value_table_t)) 11705a5eeccaSmarks 1171da6c28aaSamw value_table_t aclent_perm_table[] = { 11725a5eeccaSmarks { 'r', S_IROTH}, 11735a5eeccaSmarks { 'w', S_IWOTH}, 11745a5eeccaSmarks { 'x', S_IXOTH} 11755a5eeccaSmarks }; 11765a5eeccaSmarks 1177da6c28aaSamw #define ACLENT_PERM_COUNT (sizeof (aclent_perm_table) / sizeof (value_table_t)) 1178da6c28aaSamw 1179da6c28aaSamw value_table_t inherit_table[] = { 11805a5eeccaSmarks {'f', ACE_FILE_INHERIT_ACE}, 11815a5eeccaSmarks {'d', ACE_DIRECTORY_INHERIT_ACE}, 11825a5eeccaSmarks {'i', ACE_INHERIT_ONLY_ACE}, 11835a5eeccaSmarks {'n', ACE_NO_PROPAGATE_INHERIT_ACE}, 11845a5eeccaSmarks {'S', ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, 1185da6c28aaSamw {'F', ACE_FAILED_ACCESS_ACE_FLAG}, 1186da6c28aaSamw {'I', ACE_INHERITED_ACE} 11875a5eeccaSmarks }; 11885a5eeccaSmarks 1189da6c28aaSamw #define IFLAG_COUNT (sizeof (inherit_table) / sizeof (value_table_t)) 1190bf8b6031Smarks #define IFLAG_COUNT_V1 6 /* Older version compatibility */ 1191da6c28aaSamw 11925a5eeccaSmarks /* 11935a5eeccaSmarks * compute value from a permission table or inheritance table 11945a5eeccaSmarks * based on string passed in. If positional is set then 11955a5eeccaSmarks * string must match order in permtab, otherwise any order 11965a5eeccaSmarks * is allowed. 11975a5eeccaSmarks */ 11985a5eeccaSmarks int 11995a5eeccaSmarks compute_values(value_table_t *permtab, int count, 12005a5eeccaSmarks char *permstr, int positional, uint32_t *mask) 12015a5eeccaSmarks { 12025a5eeccaSmarks uint32_t perm_val = 0; 12035a5eeccaSmarks char *pstr; 12045a5eeccaSmarks int i, found; 12055a5eeccaSmarks 12065a5eeccaSmarks if (count < 0) 12075a5eeccaSmarks return (1); 12085a5eeccaSmarks 12095a5eeccaSmarks if (positional) { 12105a5eeccaSmarks for (i = 0, pstr = permstr; i != count && pstr && 12115a5eeccaSmarks *pstr; i++, pstr++) { 12125a5eeccaSmarks if (*pstr == permtab[i].p_letter) { 12135a5eeccaSmarks perm_val |= permtab[i].p_value; 12145a5eeccaSmarks } else if (*pstr != '-') { 12155a5eeccaSmarks return (1); 12165a5eeccaSmarks } 12175a5eeccaSmarks } 12185a5eeccaSmarks } else { /* random order single letters with no '-' */ 12195a5eeccaSmarks for (pstr = permstr; pstr && *pstr; pstr++) { 12205a5eeccaSmarks for (found = 0, i = 0; i != count; i++) { 12215a5eeccaSmarks if (*pstr == permtab[i].p_letter) { 12225a5eeccaSmarks perm_val |= permtab[i].p_value; 12235a5eeccaSmarks found = 1; 12245a5eeccaSmarks break; 12255a5eeccaSmarks } 12265a5eeccaSmarks } 12275a5eeccaSmarks if (found == 0) 12285a5eeccaSmarks return (1); 12295a5eeccaSmarks } 12305a5eeccaSmarks } 12315a5eeccaSmarks 12325a5eeccaSmarks *mask = perm_val; 12335a5eeccaSmarks return (0); 12345a5eeccaSmarks } 12355a5eeccaSmarks 1236bf8b6031Smarks 1237bf8b6031Smarks int 1238bf8b6031Smarks ace_inherit_helper(char *str, uint32_t *imask, int table_length) 1239bf8b6031Smarks { 1240bf8b6031Smarks int rc = 0; 1241bf8b6031Smarks 1242bf8b6031Smarks if (strlen(str) == table_length) { 1243bf8b6031Smarks /* 1244bf8b6031Smarks * If the string == table_length then first check to see it's 1245bf8b6031Smarks * in positional format. If that fails then see if it's in 1246bf8b6031Smarks * non-positional format. 1247bf8b6031Smarks */ 1248bf8b6031Smarks if (compute_values(inherit_table, table_length, str, 1249bf8b6031Smarks 1, imask) && compute_values(inherit_table, 1250bf8b6031Smarks table_length, str, 0, imask)) { 1251bf8b6031Smarks rc = 1; 1252bf8b6031Smarks } 1253bf8b6031Smarks } else { 1254bf8b6031Smarks rc = compute_values(inherit_table, table_length, str, 0, imask); 1255bf8b6031Smarks } 1256bf8b6031Smarks 1257bf8b6031Smarks return (rc ? EACL_INHERIT_ERROR : 0); 1258bf8b6031Smarks } 1259bf8b6031Smarks 12605a5eeccaSmarks /* 12615a5eeccaSmarks * compute value for inheritance flags. 12625a5eeccaSmarks */ 12635a5eeccaSmarks int 12645a5eeccaSmarks compute_ace_inherit(char *str, uint32_t *imask) 12655a5eeccaSmarks { 1266bf8b6031Smarks int rc = 0; 12675a5eeccaSmarks 1268bf8b6031Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT); 12695a5eeccaSmarks 1270bf8b6031Smarks if (rc && strlen(str) != IFLAG_COUNT) { 12715a5eeccaSmarks 1272bf8b6031Smarks /* is it an old formatted inherit string? */ 1273bf8b6031Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT_V1); 1274bf8b6031Smarks } 12755a5eeccaSmarks 1276bf8b6031Smarks return (rc); 12775a5eeccaSmarks } 12785a5eeccaSmarks 12795a5eeccaSmarks 12805a5eeccaSmarks /* 12815a5eeccaSmarks * compute value for ACE permissions. 12825a5eeccaSmarks */ 12835a5eeccaSmarks int 12845a5eeccaSmarks compute_ace_perms(char *str, uint32_t *mask) 12855a5eeccaSmarks { 12865a5eeccaSmarks int positional = 0; 12875a5eeccaSmarks int error; 12885a5eeccaSmarks 12895a5eeccaSmarks if (strlen(str) == ACE_PERM_COUNT) 12905a5eeccaSmarks positional = 1; 12915a5eeccaSmarks 12925a5eeccaSmarks error = compute_values(ace_perm_table, ACE_PERM_COUNT, 12935a5eeccaSmarks str, positional, mask); 12945a5eeccaSmarks 12955a5eeccaSmarks if (error && positional) { 12965a5eeccaSmarks /* 12975a5eeccaSmarks * If positional was set, then make sure permissions 12985a5eeccaSmarks * aren't actually valid in non positional case where 12995a5eeccaSmarks * all permissions are specified, just in random order. 13005a5eeccaSmarks */ 13015a5eeccaSmarks error = compute_values(ace_perm_table, 13025a5eeccaSmarks ACE_PERM_COUNT, str, 0, mask); 13035a5eeccaSmarks } 13045a5eeccaSmarks if (error) 13055a5eeccaSmarks error = EACL_PERM_MASK_ERROR; 13065a5eeccaSmarks 13075a5eeccaSmarks return (error); 13085a5eeccaSmarks } 13095a5eeccaSmarks 13105a5eeccaSmarks 13115a5eeccaSmarks 13125a5eeccaSmarks /* 13135a5eeccaSmarks * compute values for aclent permissions. 13145a5eeccaSmarks */ 13155a5eeccaSmarks int 13165a5eeccaSmarks compute_aclent_perms(char *str, o_mode_t *mask) 13175a5eeccaSmarks { 13185a5eeccaSmarks int error; 13195a5eeccaSmarks uint32_t pmask; 13205a5eeccaSmarks 13215a5eeccaSmarks if (strlen(str) != ACLENT_PERM_COUNT) 13225a5eeccaSmarks return (EACL_PERM_MASK_ERROR); 13235a5eeccaSmarks 13245a5eeccaSmarks *mask = 0; 13255a5eeccaSmarks error = compute_values(aclent_perm_table, ACLENT_PERM_COUNT, 13265a5eeccaSmarks str, 1, &pmask); 13275a5eeccaSmarks if (error == 0) { 13285a5eeccaSmarks *mask = (o_mode_t)pmask; 13295a5eeccaSmarks } else 13305a5eeccaSmarks error = EACL_PERM_MASK_ERROR; 13315a5eeccaSmarks return (error); 13325a5eeccaSmarks } 13335a5eeccaSmarks 13345a5eeccaSmarks /* 13355a5eeccaSmarks * determine ACE permissions. 13365a5eeccaSmarks */ 13375a5eeccaSmarks int 13385a5eeccaSmarks ace_perm_mask(struct acl_perm_type *aclperm, uint32_t *mask) 13395a5eeccaSmarks { 13405a5eeccaSmarks int error; 13415a5eeccaSmarks 13425a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_EMPTY) { 13435a5eeccaSmarks *mask = 0; 13445a5eeccaSmarks return (0); 13455a5eeccaSmarks } 13465a5eeccaSmarks 13475a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_ACE) { 13485a5eeccaSmarks *mask = aclperm->perm_val; 13495a5eeccaSmarks return (0); 13505a5eeccaSmarks } 13515a5eeccaSmarks 13525a5eeccaSmarks error = compute_ace_perms(aclperm->perm_str, mask); 13535a5eeccaSmarks if (error) { 13545b233e2dSmarks acl_error(dgettext(TEXT_DOMAIN, 13555b233e2dSmarks "Invalid permission(s) '%s' specified\n"), 13565a5eeccaSmarks aclperm->perm_str); 13575a5eeccaSmarks return (EACL_PERM_MASK_ERROR); 13585a5eeccaSmarks } 13595a5eeccaSmarks 13605a5eeccaSmarks return (0); 13615a5eeccaSmarks } 1362