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 /* 22f48205beScasper * Copyright 2007 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> 40fa9e4066Sahrens 415a5eeccaSmarks #define ID_STR_MAX 20 /* digits in LONG_MAX */ 425a5eeccaSmarks 435a5eeccaSmarks #define APPENDED_ID_MAX ID_STR_MAX + 1 /* id + colon */ 445a5eeccaSmarks /* 455a5eeccaSmarks * yyinteractive controls whether yyparse should print out 465a5eeccaSmarks * error messages to stderr, and whether or not id's should be 475a5eeccaSmarks * allowed from acl_fromtext(). 485a5eeccaSmarks */ 495a5eeccaSmarks int yyinteractive; 505a5eeccaSmarks acl_t *yyacl; 515a5eeccaSmarks char *yybuf; 52fa9e4066Sahrens 53fa9e4066Sahrens extern acl_t *acl_alloc(enum acl_type); 547c478bd9Sstevel@tonic-gate 5511e32170Shm123892 567c478bd9Sstevel@tonic-gate struct dynaclstr { 577c478bd9Sstevel@tonic-gate size_t bufsize; /* current size of aclexport */ 587c478bd9Sstevel@tonic-gate char *aclexport; 597c478bd9Sstevel@tonic-gate }; 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static char *strappend(char *, char *); 627c478bd9Sstevel@tonic-gate static char *convert_perm(char *, o_mode_t); 637c478bd9Sstevel@tonic-gate static int increase_length(struct dynaclstr *, size_t); 647c478bd9Sstevel@tonic-gate 655a5eeccaSmarks static void 665a5eeccaSmarks aclent_perms(int perm, char *txt_perms) 67fa9e4066Sahrens { 685a5eeccaSmarks if (perm & S_IROTH) 695a5eeccaSmarks txt_perms[0] = 'r'; 705a5eeccaSmarks else 715a5eeccaSmarks txt_perms[0] = '-'; 725a5eeccaSmarks if (perm & S_IWOTH) 735a5eeccaSmarks txt_perms[1] = 'w'; 745a5eeccaSmarks else 755a5eeccaSmarks txt_perms[1] = '-'; 765a5eeccaSmarks if (perm & S_IXOTH) 775a5eeccaSmarks txt_perms[2] = 'x'; 785a5eeccaSmarks else 795a5eeccaSmarks txt_perms[2] = '-'; 805a5eeccaSmarks txt_perms[3] = '\0'; 815a5eeccaSmarks } 82fa9e4066Sahrens 835a5eeccaSmarks static char * 84afe1f701Smarks pruname(uid_t uid, char *uidp, size_t buflen, int noresolve) 855a5eeccaSmarks { 8645a17f45Sgjelinek struct passwd *passwdp = NULL; 87fa9e4066Sahrens 8845a17f45Sgjelinek if (noresolve == 0) 895a5eeccaSmarks passwdp = getpwuid(uid); 905a5eeccaSmarks if (passwdp == (struct passwd *)NULL) { 915a5eeccaSmarks /* could not get passwd information: display uid instead */ 92f48205beScasper (void) snprintf(uidp, buflen, "%u", uid); 93afe1f701Smarks } else { 94afe1f701Smarks (void) strlcpy(uidp, passwdp->pw_name, buflen); 95afe1f701Smarks } 965a5eeccaSmarks return (uidp); 975a5eeccaSmarks } 98fa9e4066Sahrens 995a5eeccaSmarks static char * 100afe1f701Smarks prgname(gid_t gid, char *gidp, size_t buflen, int noresolve) 1015a5eeccaSmarks { 10245a17f45Sgjelinek struct group *groupp = NULL; 103fa9e4066Sahrens 10445a17f45Sgjelinek if (noresolve == 0) 1055a5eeccaSmarks groupp = getgrgid(gid); 1065a5eeccaSmarks if (groupp == (struct group *)NULL) { 1075a5eeccaSmarks /* could not get group information: display gid instead */ 108f48205beScasper (void) snprintf(gidp, buflen, "%u", gid); 109afe1f701Smarks } else { 110afe1f701Smarks (void) strlcpy(gidp, groupp->gr_name, buflen); 111afe1f701Smarks } 1125a5eeccaSmarks return (gidp); 1135a5eeccaSmarks } 1145a5eeccaSmarks static void 1155a5eeccaSmarks aclent_printacl(acl_t *aclp) 1165a5eeccaSmarks { 1175a5eeccaSmarks aclent_t *tp; 1185a5eeccaSmarks int aclcnt; 1195a5eeccaSmarks int mask; 1205a5eeccaSmarks int slot = 0; 1215a5eeccaSmarks char perm[4]; 122afe1f701Smarks char uidp[ID_STR_MAX]; 123afe1f701Smarks char gidp[ID_STR_MAX]; 1245a5eeccaSmarks 1255a5eeccaSmarks /* display ACL: assume it is sorted. */ 1265a5eeccaSmarks aclcnt = aclp->acl_cnt; 1275a5eeccaSmarks for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) { 1285a5eeccaSmarks if (tp->a_type == CLASS_OBJ) 1295a5eeccaSmarks mask = tp->a_perm; 1305a5eeccaSmarks } 1315a5eeccaSmarks aclcnt = aclp->acl_cnt; 1325a5eeccaSmarks for (tp = aclp->acl_aclp; aclcnt--; tp++) { 1335a5eeccaSmarks (void) printf(" %d:", slot++); 1345a5eeccaSmarks switch (tp->a_type) { 1355a5eeccaSmarks case USER: 1365a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1375a5eeccaSmarks (void) printf("user:%s:%s\t\t", 138afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm); 1395a5eeccaSmarks aclent_perms((tp->a_perm & mask), perm); 1405a5eeccaSmarks (void) printf("#effective:%s\n", perm); 1415a5eeccaSmarks break; 1425a5eeccaSmarks case USER_OBJ: 1435a5eeccaSmarks /* no need to display uid */ 1445a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1455a5eeccaSmarks (void) printf("user::%s\n", perm); 1465a5eeccaSmarks break; 1475a5eeccaSmarks case GROUP: 1485a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1495a5eeccaSmarks (void) printf("group:%s:%s\t\t", 150afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm); 1515a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm); 1525a5eeccaSmarks (void) printf("#effective:%s\n", perm); 1535a5eeccaSmarks break; 1545a5eeccaSmarks case GROUP_OBJ: 1555a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1565a5eeccaSmarks (void) printf("group::%s\t\t", perm); 1575a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm); 1585a5eeccaSmarks (void) printf("#effective:%s\n", perm); 1595a5eeccaSmarks break; 1605a5eeccaSmarks case CLASS_OBJ: 1615a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1625a5eeccaSmarks (void) printf("mask:%s\n", perm); 1635a5eeccaSmarks break; 1645a5eeccaSmarks case OTHER_OBJ: 1655a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1665a5eeccaSmarks (void) printf("other:%s\n", perm); 1675a5eeccaSmarks break; 1685a5eeccaSmarks case DEF_USER: 1695a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1705a5eeccaSmarks (void) printf("default:user:%s:%s\n", 171afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm); 1725a5eeccaSmarks break; 1735a5eeccaSmarks case DEF_USER_OBJ: 1745a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1755a5eeccaSmarks (void) printf("default:user::%s\n", perm); 1765a5eeccaSmarks break; 1775a5eeccaSmarks case DEF_GROUP: 1785a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1795a5eeccaSmarks (void) printf("default:group:%s:%s\n", 180afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm); 1815a5eeccaSmarks break; 1825a5eeccaSmarks case DEF_GROUP_OBJ: 1835a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1845a5eeccaSmarks (void) printf("default:group::%s\n", perm); 1855a5eeccaSmarks break; 1865a5eeccaSmarks case DEF_CLASS_OBJ: 1875a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1885a5eeccaSmarks (void) printf("default:mask:%s\n", perm); 1895a5eeccaSmarks break; 1905a5eeccaSmarks case DEF_OTHER_OBJ: 1915a5eeccaSmarks aclent_perms(tp->a_perm, perm); 1925a5eeccaSmarks (void) printf("default:other:%s\n", perm); 1935a5eeccaSmarks break; 1945a5eeccaSmarks default: 1955a5eeccaSmarks (void) fprintf(stderr, 1965b233e2dSmarks dgettext(TEXT_DOMAIN, "unrecognized entry\n")); 1975a5eeccaSmarks break; 1985a5eeccaSmarks } 1995a5eeccaSmarks } 2005a5eeccaSmarks } 2015a5eeccaSmarks 2025a5eeccaSmarks static void 2035a5eeccaSmarks split_line(char *str, int cols) 2045a5eeccaSmarks { 2055a5eeccaSmarks char *ptr; 2065a5eeccaSmarks int len; 2075a5eeccaSmarks int i; 2085a5eeccaSmarks int last_split; 2095a5eeccaSmarks char *pad = ""; 2105a5eeccaSmarks int pad_len; 2115a5eeccaSmarks 2125a5eeccaSmarks len = strlen(str); 2135a5eeccaSmarks ptr = str; 2145a5eeccaSmarks pad_len = 0; 2155a5eeccaSmarks 2165a5eeccaSmarks ptr = str; 2175a5eeccaSmarks last_split = 0; 2185a5eeccaSmarks for (i = 0; i != len; i++) { 2195a5eeccaSmarks if ((i + pad_len + 4) >= cols) { 2205a5eeccaSmarks (void) printf("%s%.*s\n", pad, last_split, ptr); 2215a5eeccaSmarks ptr = &ptr[last_split]; 2225a5eeccaSmarks len = strlen(ptr); 2235a5eeccaSmarks i = 0; 2245a5eeccaSmarks pad_len = 4; 2255a5eeccaSmarks pad = " "; 2265a5eeccaSmarks } else { 2275a5eeccaSmarks if (ptr[i] == '/' || ptr[i] == ':') { 2285a5eeccaSmarks last_split = i; 2295a5eeccaSmarks } 2305a5eeccaSmarks } 2315a5eeccaSmarks } 2325a5eeccaSmarks if (i == len) { 2335a5eeccaSmarks (void) printf("%s%s\n", pad, ptr); 2345a5eeccaSmarks } 2355a5eeccaSmarks } 2365a5eeccaSmarks 2375a5eeccaSmarks #define OWNERAT_TXT "owner@" 2385a5eeccaSmarks #define GROUPAT_TXT "group@" 2395a5eeccaSmarks #define EVERYONEAT_TXT "everyone@" 2405a5eeccaSmarks #define GROUP_TXT "group:" 2415a5eeccaSmarks #define USER_TXT "user:" 2425a5eeccaSmarks 2435a5eeccaSmarks char * 24445a17f45Sgjelinek ace_type_txt(char *buf, char **endp, ace_t *acep, int flags) 2455a5eeccaSmarks { 2465a5eeccaSmarks 247afe1f701Smarks char idp[ID_STR_MAX]; 2485a5eeccaSmarks 2495a5eeccaSmarks if (buf == NULL) 2505a5eeccaSmarks return (NULL); 2515a5eeccaSmarks 2525a5eeccaSmarks switch (acep->a_flags & ACE_TYPE_FLAGS) { 2535a5eeccaSmarks case ACE_OWNER: 2545a5eeccaSmarks strcpy(buf, OWNERAT_TXT); 2555a5eeccaSmarks *endp = buf + sizeof (OWNERAT_TXT) - 1; 2565a5eeccaSmarks break; 2575a5eeccaSmarks 2585a5eeccaSmarks case ACE_GROUP|ACE_IDENTIFIER_GROUP: 2595a5eeccaSmarks strcpy(buf, GROUPAT_TXT); 2605a5eeccaSmarks *endp = buf + sizeof (GROUPAT_TXT) - 1; 2615a5eeccaSmarks break; 2625a5eeccaSmarks 2635a5eeccaSmarks case ACE_IDENTIFIER_GROUP: 2645a5eeccaSmarks strcpy(buf, GROUP_TXT); 265afe1f701Smarks strcat(buf, prgname(acep->a_who, idp, 266afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE)); 2675a5eeccaSmarks *endp = buf + strlen(buf); 2685a5eeccaSmarks break; 2695a5eeccaSmarks 2705a5eeccaSmarks case ACE_EVERYONE: 2715a5eeccaSmarks strcpy(buf, EVERYONEAT_TXT); 2725a5eeccaSmarks *endp = buf + sizeof (EVERYONEAT_TXT) - 1; 2735a5eeccaSmarks break; 2745a5eeccaSmarks 2755a5eeccaSmarks case 0: 2765a5eeccaSmarks strcpy(buf, USER_TXT); 277afe1f701Smarks strcat(buf, pruname(acep->a_who, idp, 278afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE)); 2795a5eeccaSmarks *endp = buf + strlen(buf); 2805a5eeccaSmarks break; 2815a5eeccaSmarks } 2825a5eeccaSmarks 2835a5eeccaSmarks return (buf); 2845a5eeccaSmarks } 2855a5eeccaSmarks 2865a5eeccaSmarks #define READ_DATA_TXT "read_data/" 2875a5eeccaSmarks #define WRITE_DATA_TXT "write_data/" 2885a5eeccaSmarks #define EXECUTE_TXT "execute/" 2895a5eeccaSmarks #define READ_XATTR_TXT "read_xattr/" 2905a5eeccaSmarks #define WRITE_XATTR_TXT "write_xattr/" 2915a5eeccaSmarks #define READ_ATTRIBUTES_TXT "read_attributes/" 2925a5eeccaSmarks #define WRITE_ATTRIBUTES_TXT "write_attributes/" 2935a5eeccaSmarks #define DELETE_TXT "delete/" 2945a5eeccaSmarks #define DELETE_CHILD_TXT "delete_child/" 2955a5eeccaSmarks #define WRITE_OWNER_TXT "write_owner/" 2965a5eeccaSmarks #define READ_ACL_TXT "read_acl/" 2975a5eeccaSmarks #define WRITE_ACL_TXT "write_acl/" 2985a5eeccaSmarks #define APPEND_DATA_TXT "append_data/" 2995a5eeccaSmarks #define READ_DIR_TXT "list_directory/read_data/" 3005a5eeccaSmarks #define ADD_DIR_TXT "add_subdirectory/append_data/" 3015a5eeccaSmarks #define ADD_FILE_TXT "add_file/write_data/" 3025a5eeccaSmarks #define SYNCHRONIZE_TXT "synchronize" /* not slash on this one */ 3035a5eeccaSmarks 3045a5eeccaSmarks char * 3055a5eeccaSmarks ace_perm_txt(char *buf, char **endp, uint32_t mask, 3065a5eeccaSmarks uint32_t iflags, int isdir, int flags) 3075a5eeccaSmarks { 3085a5eeccaSmarks char *lend = buf; /* local end */ 3095a5eeccaSmarks 3105a5eeccaSmarks if (buf == NULL) 3115a5eeccaSmarks return (NULL); 3125a5eeccaSmarks 3135a5eeccaSmarks if (flags & ACL_COMPACT_FMT) { 3145a5eeccaSmarks 3155a5eeccaSmarks if (mask & ACE_READ_DATA) 3165a5eeccaSmarks buf[0] = 'r'; 3175a5eeccaSmarks else 3185a5eeccaSmarks buf[0] = '-'; 3195a5eeccaSmarks if (mask & ACE_WRITE_DATA) 3205a5eeccaSmarks buf[1] = 'w'; 3215a5eeccaSmarks else 3225a5eeccaSmarks buf[1] = '-'; 3235a5eeccaSmarks if (mask & ACE_EXECUTE) 3245a5eeccaSmarks buf[2] = 'x'; 3255a5eeccaSmarks else 3265a5eeccaSmarks buf[2] = '-'; 3275a5eeccaSmarks if (mask & ACE_APPEND_DATA) 3285a5eeccaSmarks buf[3] = 'p'; 3295a5eeccaSmarks else 3305a5eeccaSmarks buf[3] = '-'; 3315a5eeccaSmarks if (mask & ACE_DELETE) 3325a5eeccaSmarks buf[4] = 'd'; 3335a5eeccaSmarks else 3345a5eeccaSmarks buf[4] = '-'; 3355a5eeccaSmarks if (mask & ACE_DELETE_CHILD) 3365a5eeccaSmarks buf[5] = 'D'; 3375a5eeccaSmarks else 3385a5eeccaSmarks buf[5] = '-'; 3395a5eeccaSmarks if (mask & ACE_READ_ATTRIBUTES) 3405a5eeccaSmarks buf[6] = 'a'; 3415a5eeccaSmarks else 3425a5eeccaSmarks buf[6] = '-'; 3435a5eeccaSmarks if (mask & ACE_WRITE_ATTRIBUTES) 3445a5eeccaSmarks buf[7] = 'A'; 3455a5eeccaSmarks else 3465a5eeccaSmarks buf[7] = '-'; 3475a5eeccaSmarks if (mask & ACE_READ_NAMED_ATTRS) 3485a5eeccaSmarks buf[8] = 'R'; 3495a5eeccaSmarks else 3505a5eeccaSmarks buf[8] = '-'; 3515a5eeccaSmarks if (mask & ACE_WRITE_NAMED_ATTRS) 3525a5eeccaSmarks buf[9] = 'W'; 3535a5eeccaSmarks else 3545a5eeccaSmarks buf[9] = '-'; 3555a5eeccaSmarks if (mask & ACE_READ_ACL) 3565a5eeccaSmarks buf[10] = 'c'; 3575a5eeccaSmarks else 3585a5eeccaSmarks buf[10] = '-'; 3595a5eeccaSmarks if (mask & ACE_WRITE_ACL) 3605a5eeccaSmarks buf[11] = 'C'; 3615a5eeccaSmarks else 3625a5eeccaSmarks buf[11] = '-'; 3635a5eeccaSmarks if (mask & ACE_WRITE_OWNER) 3645a5eeccaSmarks buf[12] = 'o'; 3655a5eeccaSmarks else 3665a5eeccaSmarks buf[12] = '-'; 3675a5eeccaSmarks if (mask & ACE_SYNCHRONIZE) 3685a5eeccaSmarks buf[13] = 's'; 3695a5eeccaSmarks else 3705a5eeccaSmarks buf[13] = '-'; 3715a5eeccaSmarks buf[14] = '\0'; 3725a5eeccaSmarks *endp = buf + 14; 3735a5eeccaSmarks return (buf); 3745a5eeccaSmarks } else { 3755a5eeccaSmarks /* 3765a5eeccaSmarks * If ACE is a directory, but inheritance indicates its 3775a5eeccaSmarks * for a file then print permissions for file rather than 3785a5eeccaSmarks * dir. 3795a5eeccaSmarks */ 3805a5eeccaSmarks if (isdir) { 3815a5eeccaSmarks if (mask & ACE_LIST_DIRECTORY) { 3825a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 3835a5eeccaSmarks strcpy(lend, READ_DATA_TXT); 3845a5eeccaSmarks lend += sizeof (READ_DATA_TXT) - 1; 3855a5eeccaSmarks } else { 3865a5eeccaSmarks strcpy(lend, READ_DIR_TXT); 3875a5eeccaSmarks lend += sizeof (READ_DIR_TXT) - 1; 3885a5eeccaSmarks } 3895a5eeccaSmarks } 3905a5eeccaSmarks if (mask & ACE_ADD_FILE) { 3915a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 3925a5eeccaSmarks strcpy(lend, WRITE_DATA_TXT); 3935a5eeccaSmarks lend += sizeof (WRITE_DATA_TXT) - 1; 3945a5eeccaSmarks } else { 3955a5eeccaSmarks strcpy(lend, ADD_FILE_TXT); 3965a5eeccaSmarks lend += 3975a5eeccaSmarks sizeof (ADD_FILE_TXT) -1; 3985a5eeccaSmarks } 3995a5eeccaSmarks } 4005a5eeccaSmarks if (mask & ACE_ADD_SUBDIRECTORY) { 4015a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) { 4025a5eeccaSmarks strcpy(lend, APPEND_DATA_TXT); 4035a5eeccaSmarks lend += sizeof (APPEND_DATA_TXT) - 1; 4045a5eeccaSmarks } else { 4055a5eeccaSmarks strcpy(lend, ADD_DIR_TXT); 4065a5eeccaSmarks lend += sizeof (ADD_DIR_TXT) - 1; 4075a5eeccaSmarks } 4085a5eeccaSmarks } 4095a5eeccaSmarks } else { 4105a5eeccaSmarks if (mask & ACE_READ_DATA) { 4115a5eeccaSmarks strcpy(lend, READ_DATA_TXT); 4125a5eeccaSmarks lend += sizeof (READ_DATA_TXT) - 1; 4135a5eeccaSmarks } 4145a5eeccaSmarks if (mask & ACE_WRITE_DATA) { 4155a5eeccaSmarks strcpy(lend, WRITE_DATA_TXT); 4165a5eeccaSmarks lend += sizeof (WRITE_DATA_TXT) - 1; 4175a5eeccaSmarks } 4185a5eeccaSmarks if (mask & ACE_APPEND_DATA) { 4195a5eeccaSmarks strcpy(lend, APPEND_DATA_TXT); 4205a5eeccaSmarks lend += sizeof (APPEND_DATA_TXT) - 1; 4215a5eeccaSmarks } 4225a5eeccaSmarks } 4235a5eeccaSmarks if (mask & ACE_READ_NAMED_ATTRS) { 4245a5eeccaSmarks strcpy(lend, READ_XATTR_TXT); 4255a5eeccaSmarks lend += sizeof (READ_XATTR_TXT) - 1; 4265a5eeccaSmarks } 4275a5eeccaSmarks if (mask & ACE_WRITE_NAMED_ATTRS) { 4285a5eeccaSmarks strcpy(lend, WRITE_XATTR_TXT); 4295a5eeccaSmarks lend += sizeof (WRITE_XATTR_TXT) - 1; 4305a5eeccaSmarks } 4315a5eeccaSmarks if (mask & ACE_EXECUTE) { 4325a5eeccaSmarks strcpy(lend, EXECUTE_TXT); 4335a5eeccaSmarks lend += sizeof (EXECUTE_TXT) - 1; 4345a5eeccaSmarks } 4355a5eeccaSmarks if (mask & ACE_DELETE_CHILD) { 4365a5eeccaSmarks strcpy(lend, DELETE_CHILD_TXT); 4375a5eeccaSmarks lend += sizeof (DELETE_CHILD_TXT) - 1; 4385a5eeccaSmarks } 4395a5eeccaSmarks if (mask & ACE_READ_ATTRIBUTES) { 4405a5eeccaSmarks strcpy(lend, READ_ATTRIBUTES_TXT); 4415a5eeccaSmarks lend += sizeof (READ_ATTRIBUTES_TXT) - 1; 4425a5eeccaSmarks } 4435a5eeccaSmarks if (mask & ACE_WRITE_ATTRIBUTES) { 4445a5eeccaSmarks strcpy(lend, WRITE_ATTRIBUTES_TXT); 4455a5eeccaSmarks lend += sizeof (WRITE_ATTRIBUTES_TXT) - 1; 4465a5eeccaSmarks } 4475a5eeccaSmarks if (mask & ACE_DELETE) { 4485a5eeccaSmarks strcpy(lend, DELETE_TXT); 4495a5eeccaSmarks lend += sizeof (DELETE_TXT) - 1; 4505a5eeccaSmarks } 4515a5eeccaSmarks if (mask & ACE_READ_ACL) { 4525a5eeccaSmarks strcpy(lend, READ_ACL_TXT); 4535a5eeccaSmarks lend += sizeof (READ_ACL_TXT) - 1; 4545a5eeccaSmarks } 4555a5eeccaSmarks if (mask & ACE_WRITE_ACL) { 4565a5eeccaSmarks strcpy(lend, WRITE_ACL_TXT); 4575a5eeccaSmarks lend += sizeof (WRITE_ACL_TXT) - 1; 4585a5eeccaSmarks } 4595a5eeccaSmarks if (mask & ACE_WRITE_OWNER) { 4605a5eeccaSmarks strcpy(lend, WRITE_OWNER_TXT); 4615a5eeccaSmarks lend += sizeof (WRITE_OWNER_TXT) - 1; 4625a5eeccaSmarks } 4635a5eeccaSmarks if (mask & ACE_SYNCHRONIZE) { 4645a5eeccaSmarks strcpy(lend, SYNCHRONIZE_TXT); 4655a5eeccaSmarks lend += sizeof (SYNCHRONIZE_TXT) - 1; 4665a5eeccaSmarks } 4675a5eeccaSmarks 4685a5eeccaSmarks if (*(lend - 1) == '/') 4695a5eeccaSmarks *--lend = '\0'; 4705a5eeccaSmarks } 4715a5eeccaSmarks 4725a5eeccaSmarks *endp = lend; 4735a5eeccaSmarks return (buf); 4745a5eeccaSmarks } 4755a5eeccaSmarks 4765a5eeccaSmarks #define ALLOW_TXT "allow" 4775a5eeccaSmarks #define DENY_TXT "deny" 4785a5eeccaSmarks #define ALARM_TXT "alarm" 4795a5eeccaSmarks #define AUDIT_TXT "audit" 4805a5eeccaSmarks #define UNKNOWN_TXT "unknown" 4815a5eeccaSmarks char * 4825a5eeccaSmarks ace_access_txt(char *buf, char **endp, int type) 4835a5eeccaSmarks { 4845a5eeccaSmarks 4855a5eeccaSmarks if (buf == NULL) 4865a5eeccaSmarks return (NULL); 4875a5eeccaSmarks 4885a5eeccaSmarks if (type == ACE_ACCESS_ALLOWED_ACE_TYPE) { 4895a5eeccaSmarks strcpy(buf, ALLOW_TXT); 4905a5eeccaSmarks *endp += sizeof (ALLOW_TXT) - 1; 4915a5eeccaSmarks } else if (type == ACE_ACCESS_DENIED_ACE_TYPE) { 4925a5eeccaSmarks strcpy(buf, DENY_TXT); 4935a5eeccaSmarks *endp += sizeof (DENY_TXT) - 1; 4945a5eeccaSmarks } else if (type == ACE_SYSTEM_AUDIT_ACE_TYPE) { 4955a5eeccaSmarks strcpy(buf, AUDIT_TXT); 4965a5eeccaSmarks *endp += sizeof (AUDIT_TXT) - 1; 4975a5eeccaSmarks } else if (type == ACE_SYSTEM_ALARM_ACE_TYPE) { 4985a5eeccaSmarks strcpy(buf, ALARM_TXT); 4995a5eeccaSmarks *endp += sizeof (ALARM_TXT) - 1; 5005a5eeccaSmarks } else { 5015a5eeccaSmarks strcpy(buf, UNKNOWN_TXT); 5025a5eeccaSmarks *endp += sizeof (UNKNOWN_TXT) - 1; 5035a5eeccaSmarks } 5045a5eeccaSmarks 5055a5eeccaSmarks return (buf); 5065a5eeccaSmarks } 5075a5eeccaSmarks 5085a5eeccaSmarks static char * 5095a5eeccaSmarks ace_inherit_txt(char *buf, char **endp, uint32_t iflags, int flags) 5105a5eeccaSmarks { 5115a5eeccaSmarks 5125a5eeccaSmarks char *lend = buf; 5135a5eeccaSmarks 5145a5eeccaSmarks if (buf == NULL) { 5155a5eeccaSmarks return (NULL); 5165a5eeccaSmarks } 5175a5eeccaSmarks 5185a5eeccaSmarks if (flags & ACL_COMPACT_FMT) { 5195a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE) 5205a5eeccaSmarks buf[0] = 'f'; 5215a5eeccaSmarks else 5225a5eeccaSmarks buf[0] = '-'; 5235a5eeccaSmarks if (iflags & ACE_DIRECTORY_INHERIT_ACE) 5245a5eeccaSmarks buf[1] = 'd'; 5255a5eeccaSmarks else 5265a5eeccaSmarks buf[1] = '-'; 5275a5eeccaSmarks if (iflags & ACE_INHERIT_ONLY_ACE) 5285a5eeccaSmarks buf[2] = 'i'; 5295a5eeccaSmarks else 5305a5eeccaSmarks buf[2] = '-'; 5315a5eeccaSmarks if (iflags & ACE_NO_PROPAGATE_INHERIT_ACE) 5325a5eeccaSmarks buf[3] = 'n'; 5335a5eeccaSmarks else 5345a5eeccaSmarks buf[3] = '-'; 5355a5eeccaSmarks if (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG) 5365a5eeccaSmarks buf[4] = 'S'; 5375a5eeccaSmarks else 5385a5eeccaSmarks buf[4] = '-'; 5395a5eeccaSmarks if (iflags & ACE_FAILED_ACCESS_ACE_FLAG) 5405a5eeccaSmarks buf[5] = 'F'; 5415a5eeccaSmarks else 5425a5eeccaSmarks buf[5] = '-'; 543*da6c28aaSamw if (iflags & ACE_INHERITED_ACE) 544*da6c28aaSamw buf[6] = 'I'; 545*da6c28aaSamw else 546*da6c28aaSamw buf[6] = '-'; 547*da6c28aaSamw buf[7] = '\0'; 548*da6c28aaSamw *endp = buf + 7; 5495a5eeccaSmarks } else { 5505a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE) { 5515a5eeccaSmarks strcpy(lend, "file_inherit/"); 5525a5eeccaSmarks lend += sizeof ("file_inherit/") - 1; 5535a5eeccaSmarks } 5545a5eeccaSmarks if (iflags & ACE_DIRECTORY_INHERIT_ACE) { 5555a5eeccaSmarks strcpy(lend, "dir_inherit/"); 5565a5eeccaSmarks lend += sizeof ("dir_inherit/") - 1; 5575a5eeccaSmarks } 5585a5eeccaSmarks if (iflags & ACE_NO_PROPAGATE_INHERIT_ACE) { 5595a5eeccaSmarks strcpy(lend, "no_propagate/"); 5605a5eeccaSmarks lend += sizeof ("no_propagate/") - 1; 5615a5eeccaSmarks } 5625a5eeccaSmarks if (iflags & ACE_INHERIT_ONLY_ACE) { 5635a5eeccaSmarks strcpy(lend, "inherit_only/"); 5645a5eeccaSmarks lend += sizeof ("inherit_only/") - 1; 5655a5eeccaSmarks } 566*da6c28aaSamw if (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG) { 567*da6c28aaSamw strcpy(lend, "successful_access/"); 568*da6c28aaSamw lend += sizeof ("successful_access/") - 1; 569*da6c28aaSamw } 570*da6c28aaSamw if (iflags & ACE_FAILED_ACCESS_ACE_FLAG) { 571*da6c28aaSamw strcpy(lend, "failed_access/"); 572*da6c28aaSamw lend += sizeof ("failed_access/") - 1; 573*da6c28aaSamw } 574*da6c28aaSamw if (iflags & ACE_INHERITED_ACE) { 575*da6c28aaSamw strcpy(lend, "inherited/"); 576*da6c28aaSamw lend += sizeof ("inherited/") - 1; 577*da6c28aaSamw } 5785a5eeccaSmarks 5795a5eeccaSmarks if (*(lend - 1) == '/') 5805a5eeccaSmarks *--lend = '\0'; 5815a5eeccaSmarks *endp = lend; 5825a5eeccaSmarks } 5835a5eeccaSmarks 5845a5eeccaSmarks return (buf); 585fa9e4066Sahrens } 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate /* 5887c478bd9Sstevel@tonic-gate * Convert internal acl representation to external representation. 5897c478bd9Sstevel@tonic-gate * 5907c478bd9Sstevel@tonic-gate * The length of a non-owning user name or non-owning group name ie entries 5917c478bd9Sstevel@tonic-gate * of type DEF_USER, USER, DEF_GROUP or GROUP, can exceed LOGNAME_MAX. We 5927c478bd9Sstevel@tonic-gate * thus check the length of these entries, and if greater than LOGNAME_MAX, 5937c478bd9Sstevel@tonic-gate * we realloc() via increase_length(). 5947c478bd9Sstevel@tonic-gate * 5957c478bd9Sstevel@tonic-gate * The LOGNAME_MAX, ENTRYTYPELEN and PERMS limits are otherwise always 5967c478bd9Sstevel@tonic-gate * adhered to. 5977c478bd9Sstevel@tonic-gate */ 5985a5eeccaSmarks 5995a5eeccaSmarks /* 6005a5eeccaSmarks * acltotext() converts each ACL entry to look like this: 6015a5eeccaSmarks * 6025a5eeccaSmarks * entry_type:uid^gid^name:perms[:id] 6035a5eeccaSmarks * 6045a5eeccaSmarks * The maximum length of entry_type is 14 ("defaultgroup::" and 6055a5eeccaSmarks * "defaultother::") hence ENTRYTYPELEN is set to 14. 6065a5eeccaSmarks * 6075a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8, hence we use, 6085a5eeccaSmarks * however the ID could be a number so we therefore use ID_STR_MAX 6095a5eeccaSmarks * 6105a5eeccaSmarks * The length of a perms entry is 4 to allow for the comma appended to each 6115a5eeccaSmarks * to each acl entry. Hence PERMS is set to 4. 6125a5eeccaSmarks */ 6135a5eeccaSmarks 6145a5eeccaSmarks #define ENTRYTYPELEN 14 6155a5eeccaSmarks #define PERMS 4 6165a5eeccaSmarks #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX) 6175a5eeccaSmarks #define UPDATE_WHERE where = dstr->aclexport + strlen(dstr->aclexport) 6185a5eeccaSmarks 6197c478bd9Sstevel@tonic-gate char * 6205a5eeccaSmarks aclent_acltotext(aclent_t *aclp, int aclcnt, int flags) 6217c478bd9Sstevel@tonic-gate { 6227c478bd9Sstevel@tonic-gate char *aclexport; 6237c478bd9Sstevel@tonic-gate char *where; 624ee519a1fSgjelinek struct group *groupp = NULL; 625ee519a1fSgjelinek struct passwd *passwdp = NULL; 6267c478bd9Sstevel@tonic-gate struct dynaclstr *dstr; 6277c478bd9Sstevel@tonic-gate int i, rtn; 6287c478bd9Sstevel@tonic-gate size_t excess = 0; 629afe1f701Smarks char id[ID_STR_MAX], *idstr; 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate if (aclp == NULL) 6327c478bd9Sstevel@tonic-gate return (NULL); 6337c478bd9Sstevel@tonic-gate if ((dstr = malloc(sizeof (struct dynaclstr))) == NULL) 6347c478bd9Sstevel@tonic-gate return (NULL); 6357c478bd9Sstevel@tonic-gate dstr->bufsize = aclcnt * ACL_ENTRY_SIZE; 6367c478bd9Sstevel@tonic-gate if ((dstr->aclexport = malloc(dstr->bufsize)) == NULL) { 6377c478bd9Sstevel@tonic-gate free(dstr); 6387c478bd9Sstevel@tonic-gate return (NULL); 6397c478bd9Sstevel@tonic-gate } 6407c478bd9Sstevel@tonic-gate *dstr->aclexport = '\0'; 6417c478bd9Sstevel@tonic-gate where = dstr->aclexport; 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate for (i = 0; i < aclcnt; i++, aclp++) { 6447c478bd9Sstevel@tonic-gate switch (aclp->a_type) { 6457c478bd9Sstevel@tonic-gate case DEF_USER_OBJ: 6467c478bd9Sstevel@tonic-gate case USER_OBJ: 6477c478bd9Sstevel@tonic-gate if (aclp->a_type == USER_OBJ) 6487c478bd9Sstevel@tonic-gate where = strappend(where, "user::"); 6497c478bd9Sstevel@tonic-gate else 6507c478bd9Sstevel@tonic-gate where = strappend(where, "defaultuser::"); 6517c478bd9Sstevel@tonic-gate where = convert_perm(where, aclp->a_perm); 6527c478bd9Sstevel@tonic-gate break; 6537c478bd9Sstevel@tonic-gate case DEF_USER: 6547c478bd9Sstevel@tonic-gate case USER: 6557c478bd9Sstevel@tonic-gate if (aclp->a_type == USER) 6567c478bd9Sstevel@tonic-gate where = strappend(where, "user:"); 6577c478bd9Sstevel@tonic-gate else 6587c478bd9Sstevel@tonic-gate where = strappend(where, "defaultuser:"); 659ee519a1fSgjelinek if ((flags & ACL_NORESOLVE) == 0) 6607c478bd9Sstevel@tonic-gate passwdp = getpwuid(aclp->a_id); 6617c478bd9Sstevel@tonic-gate if (passwdp == (struct passwd *)NULL) { 6627c478bd9Sstevel@tonic-gate /* put in uid instead */ 6637c478bd9Sstevel@tonic-gate (void) sprintf(where, "%d", aclp->a_id); 66411e32170Shm123892 UPDATE_WHERE; 6657c478bd9Sstevel@tonic-gate } else { 6667c478bd9Sstevel@tonic-gate excess = strlen(passwdp->pw_name) - LOGNAME_MAX; 6677c478bd9Sstevel@tonic-gate if (excess > 0) { 6687c478bd9Sstevel@tonic-gate rtn = increase_length(dstr, excess); 6697c478bd9Sstevel@tonic-gate if (rtn == 1) { 67011e32170Shm123892 UPDATE_WHERE; 6717c478bd9Sstevel@tonic-gate } else { 6727c478bd9Sstevel@tonic-gate free(dstr->aclexport); 6737c478bd9Sstevel@tonic-gate free(dstr); 6747c478bd9Sstevel@tonic-gate return (NULL); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate where = strappend(where, passwdp->pw_name); 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate where = strappend(where, ":"); 6807c478bd9Sstevel@tonic-gate where = convert_perm(where, aclp->a_perm); 6817c478bd9Sstevel@tonic-gate break; 6827c478bd9Sstevel@tonic-gate case DEF_GROUP_OBJ: 6837c478bd9Sstevel@tonic-gate case GROUP_OBJ: 6847c478bd9Sstevel@tonic-gate if (aclp->a_type == GROUP_OBJ) 6857c478bd9Sstevel@tonic-gate where = strappend(where, "group::"); 6867c478bd9Sstevel@tonic-gate else 6877c478bd9Sstevel@tonic-gate where = strappend(where, "defaultgroup::"); 6887c478bd9Sstevel@tonic-gate where = convert_perm(where, aclp->a_perm); 6897c478bd9Sstevel@tonic-gate break; 6907c478bd9Sstevel@tonic-gate case DEF_GROUP: 6917c478bd9Sstevel@tonic-gate case GROUP: 6927c478bd9Sstevel@tonic-gate if (aclp->a_type == GROUP) 6937c478bd9Sstevel@tonic-gate where = strappend(where, "group:"); 6947c478bd9Sstevel@tonic-gate else 6957c478bd9Sstevel@tonic-gate where = strappend(where, "defaultgroup:"); 696ee519a1fSgjelinek if ((flags & ACL_NORESOLVE) == 0) 6977c478bd9Sstevel@tonic-gate groupp = getgrgid(aclp->a_id); 6987c478bd9Sstevel@tonic-gate if (groupp == (struct group *)NULL) { 6997c478bd9Sstevel@tonic-gate /* put in gid instead */ 7007c478bd9Sstevel@tonic-gate (void) sprintf(where, "%d", aclp->a_id); 70111e32170Shm123892 UPDATE_WHERE; 7027c478bd9Sstevel@tonic-gate } else { 7037c478bd9Sstevel@tonic-gate excess = strlen(groupp->gr_name) - LOGNAME_MAX; 7047c478bd9Sstevel@tonic-gate if (excess > 0) { 7057c478bd9Sstevel@tonic-gate rtn = increase_length(dstr, excess); 7067c478bd9Sstevel@tonic-gate if (rtn == 1) { 70711e32170Shm123892 UPDATE_WHERE; 7087c478bd9Sstevel@tonic-gate } else { 7097c478bd9Sstevel@tonic-gate free(dstr->aclexport); 7107c478bd9Sstevel@tonic-gate free(dstr); 7117c478bd9Sstevel@tonic-gate return (NULL); 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate where = strappend(where, groupp->gr_name); 7157c478bd9Sstevel@tonic-gate } 7167c478bd9Sstevel@tonic-gate where = strappend(where, ":"); 7177c478bd9Sstevel@tonic-gate where = convert_perm(where, aclp->a_perm); 7187c478bd9Sstevel@tonic-gate break; 7197c478bd9Sstevel@tonic-gate case DEF_CLASS_OBJ: 7207c478bd9Sstevel@tonic-gate case CLASS_OBJ: 7217c478bd9Sstevel@tonic-gate if (aclp->a_type == CLASS_OBJ) 7227c478bd9Sstevel@tonic-gate where = strappend(where, "mask:"); 7237c478bd9Sstevel@tonic-gate else 7247c478bd9Sstevel@tonic-gate where = strappend(where, "defaultmask:"); 7257c478bd9Sstevel@tonic-gate where = convert_perm(where, aclp->a_perm); 7267c478bd9Sstevel@tonic-gate break; 7277c478bd9Sstevel@tonic-gate case DEF_OTHER_OBJ: 7287c478bd9Sstevel@tonic-gate case OTHER_OBJ: 7297c478bd9Sstevel@tonic-gate if (aclp->a_type == OTHER_OBJ) 7307c478bd9Sstevel@tonic-gate where = strappend(where, "other:"); 7317c478bd9Sstevel@tonic-gate else 7327c478bd9Sstevel@tonic-gate where = strappend(where, "defaultother:"); 7337c478bd9Sstevel@tonic-gate where = convert_perm(where, aclp->a_perm); 7347c478bd9Sstevel@tonic-gate break; 7357c478bd9Sstevel@tonic-gate default: 7367c478bd9Sstevel@tonic-gate free(dstr->aclexport); 7377c478bd9Sstevel@tonic-gate free(dstr); 7387c478bd9Sstevel@tonic-gate return (NULL); 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate } 7415a5eeccaSmarks 7425a5eeccaSmarks if ((flags & ACL_APPEND_ID) && ((aclp->a_type == USER) || 7435a5eeccaSmarks (aclp->a_type == DEF_USER) || (aclp->a_type == GROUP) || 7445a5eeccaSmarks (aclp->a_type == DEF_GROUP))) { 7455a5eeccaSmarks where = strappend(where, ":"); 7465a5eeccaSmarks id[ID_STR_MAX - 1] = '\0'; /* null terminate buffer */ 7475a5eeccaSmarks idstr = lltostr(aclp->a_id, &id[ID_STR_MAX - 1]); 7485a5eeccaSmarks where = strappend(where, idstr); 7495a5eeccaSmarks } 7507c478bd9Sstevel@tonic-gate if (i < aclcnt - 1) 7517c478bd9Sstevel@tonic-gate where = strappend(where, ","); 7527c478bd9Sstevel@tonic-gate } 7537c478bd9Sstevel@tonic-gate aclexport = dstr->aclexport; 7547c478bd9Sstevel@tonic-gate free(dstr); 7557c478bd9Sstevel@tonic-gate return (aclexport); 7565a5eeccaSmarks 7575a5eeccaSmarks 7585a5eeccaSmarks 7595a5eeccaSmarks 7607c478bd9Sstevel@tonic-gate } 7617c478bd9Sstevel@tonic-gate 7625a5eeccaSmarks char * 7635a5eeccaSmarks acltotext(aclent_t *aclp, int aclcnt) 7647c478bd9Sstevel@tonic-gate { 7655a5eeccaSmarks return (aclent_acltotext(aclp, aclcnt, 0)); 766fa9e4066Sahrens } 767fa9e4066Sahrens 7687c478bd9Sstevel@tonic-gate 769fa9e4066Sahrens aclent_t * 770fa9e4066Sahrens aclfromtext(char *aclstr, int *aclcnt) 771fa9e4066Sahrens { 772fa9e4066Sahrens acl_t *aclp; 773fa9e4066Sahrens aclent_t *aclentp; 774fa9e4066Sahrens int error; 775fa9e4066Sahrens 7765a5eeccaSmarks error = acl_fromtext(aclstr, &aclp); 777fa9e4066Sahrens if (error) 778fa9e4066Sahrens return (NULL); 779fa9e4066Sahrens 780fa9e4066Sahrens aclentp = aclp->acl_aclp; 781fa9e4066Sahrens aclp->acl_aclp = NULL; 782fa9e4066Sahrens *aclcnt = aclp->acl_cnt; 7835a5eeccaSmarks 7845a5eeccaSmarks acl_free(aclp); 785fa9e4066Sahrens return (aclentp); 786fa9e4066Sahrens } 787fa9e4066Sahrens 788fa9e4066Sahrens 7897c478bd9Sstevel@tonic-gate static char * 7907c478bd9Sstevel@tonic-gate strappend(char *where, char *newstr) 7917c478bd9Sstevel@tonic-gate { 7927c478bd9Sstevel@tonic-gate (void) strcat(where, newstr); 7937c478bd9Sstevel@tonic-gate return (where + strlen(newstr)); 7947c478bd9Sstevel@tonic-gate } 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate static char * 7977c478bd9Sstevel@tonic-gate convert_perm(char *where, o_mode_t perm) 7987c478bd9Sstevel@tonic-gate { 7995a5eeccaSmarks if (perm & S_IROTH) 8007c478bd9Sstevel@tonic-gate where = strappend(where, "r"); 8017c478bd9Sstevel@tonic-gate else 8027c478bd9Sstevel@tonic-gate where = strappend(where, "-"); 8035a5eeccaSmarks if (perm & S_IWOTH) 8047c478bd9Sstevel@tonic-gate where = strappend(where, "w"); 8057c478bd9Sstevel@tonic-gate else 8067c478bd9Sstevel@tonic-gate where = strappend(where, "-"); 8075a5eeccaSmarks if (perm & S_IXOTH) 8087c478bd9Sstevel@tonic-gate where = strappend(where, "x"); 8097c478bd9Sstevel@tonic-gate else 8107c478bd9Sstevel@tonic-gate where = strappend(where, "-"); 8117c478bd9Sstevel@tonic-gate /* perm is the last field */ 8127c478bd9Sstevel@tonic-gate return (where); 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate /* 8167c478bd9Sstevel@tonic-gate * Callers should check the return code as this routine may change the string 8177c478bd9Sstevel@tonic-gate * pointer in dynaclstr. 8187c478bd9Sstevel@tonic-gate */ 8197c478bd9Sstevel@tonic-gate static int 8207c478bd9Sstevel@tonic-gate increase_length(struct dynaclstr *dacl, size_t increase) 8217c478bd9Sstevel@tonic-gate { 8227c478bd9Sstevel@tonic-gate char *tptr; 8237c478bd9Sstevel@tonic-gate size_t newsize; 8247c478bd9Sstevel@tonic-gate 8257c478bd9Sstevel@tonic-gate newsize = dacl->bufsize + increase; 8267c478bd9Sstevel@tonic-gate tptr = realloc(dacl->aclexport, newsize); 8277c478bd9Sstevel@tonic-gate if (tptr != NULL) { 8287c478bd9Sstevel@tonic-gate dacl->aclexport = tptr; 8297c478bd9Sstevel@tonic-gate dacl->bufsize = newsize; 8307c478bd9Sstevel@tonic-gate return (1); 8317c478bd9Sstevel@tonic-gate } else 8327c478bd9Sstevel@tonic-gate return (0); 8337c478bd9Sstevel@tonic-gate } 834fa9e4066Sahrens 835fa9e4066Sahrens /* 8365a5eeccaSmarks * ace_acltotext() convert each ace formatted acl to look like this: 837fa9e4066Sahrens * 8385a5eeccaSmarks * entry_type:uid^gid^name:perms[:flags]:<allow|deny>[:id][,] 839fa9e4066Sahrens * 840fa9e4066Sahrens * The maximum length of entry_type is 5 ("group") 841fa9e4066Sahrens * 8425a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8, 8435a5eeccaSmarks * however id could be a number so we therefore use ID_STR_MAX 844fa9e4066Sahrens * 845fa9e4066Sahrens * The length of a perms entry is 144 i.e read_data/write_data... 846fa9e4066Sahrens * to each acl entry. 847fa9e4066Sahrens * 848*da6c28aaSamw * iflags: file_inherit/dir_inherit/inherit_only/no_propagate/successful_access 849*da6c28aaSamw * /failed_access 850fa9e4066Sahrens * 851fa9e4066Sahrens */ 852fa9e4066Sahrens 853fa9e4066Sahrens #define ACE_ENTRYTYPLEN 6 854*da6c28aaSamw #define IFLAGS_STR "file_inherit/dir_inherit/inherit_only/no_propagate/" \ 855*da6c28aaSamw "successful_access/failed_access/inherited" 856*da6c28aaSamw #define IFLAGS_SIZE (sizeof (IFLAGS_STR) - 1) 8575a5eeccaSmarks #define ACCESS_TYPE_SIZE 7 /* if unknown */ 858fa9e4066Sahrens #define COLON_CNT 3 859fa9e4066Sahrens #define PERMS_LEN 216 8605a5eeccaSmarks #define ACE_ENTRY_SIZE (ACE_ENTRYTYPLEN + ID_STR_MAX + PERMS_LEN + \ 8615a5eeccaSmarks ACCESS_TYPE_SIZE + IFLAGS_SIZE + COLON_CNT + APPENDED_ID_MAX) 862fa9e4066Sahrens 863fa9e4066Sahrens static char * 8645a5eeccaSmarks ace_acltotext(acl_t *aceaclp, int flags) 865fa9e4066Sahrens { 866fa9e4066Sahrens ace_t *aclp = aceaclp->acl_aclp; 867fa9e4066Sahrens int aclcnt = aceaclp->acl_cnt; 868fa9e4066Sahrens char *aclexport; 8695a5eeccaSmarks char *endp; 8705a5eeccaSmarks int i; 8715a5eeccaSmarks char id[ID_STR_MAX], *idstr; 872fa9e4066Sahrens int isdir = (aceaclp->acl_flags & ACL_IS_DIR); 873fa9e4066Sahrens 874fa9e4066Sahrens if (aclp == NULL) 875fa9e4066Sahrens return (NULL); 8765a5eeccaSmarks if ((aclexport = malloc(aclcnt * ACE_ENTRY_SIZE)) == NULL) 877fa9e4066Sahrens return (NULL); 878fa9e4066Sahrens 8795a5eeccaSmarks aclexport[0] = '\0'; 8805a5eeccaSmarks endp = aclexport; 881fa9e4066Sahrens for (i = 0; i < aclcnt; i++, aclp++) { 882fa9e4066Sahrens 88345a17f45Sgjelinek (void) ace_type_txt(endp, &endp, aclp, flags); 8845a5eeccaSmarks *endp++ = ':'; 8855a5eeccaSmarks *endp = '\0'; 8865a5eeccaSmarks (void) ace_perm_txt(endp, &endp, aclp->a_access_mask, 8875a5eeccaSmarks aclp->a_flags, isdir, flags); 8885a5eeccaSmarks *endp++ = ':'; 8895a5eeccaSmarks *endp = '\0'; 8905a5eeccaSmarks (void) ace_inherit_txt(endp, &endp, aclp->a_flags, flags); 8915a5eeccaSmarks if (flags & ACL_COMPACT_FMT || aclp->a_flags & 8925a5eeccaSmarks (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE | 893*da6c28aaSamw (ACE_INHERIT_ONLY_ACE | ACE_NO_PROPAGATE_INHERIT_ACE | 894*da6c28aaSamw ACE_INHERITED_ACE | ACE_SUCCESSFUL_ACCESS_ACE_FLAG | 895*da6c28aaSamw ACE_FAILED_ACCESS_ACE_FLAG))) { 8965a5eeccaSmarks *endp++ = ':'; 8975a5eeccaSmarks *endp = '\0'; 898fa9e4066Sahrens } 8995a5eeccaSmarks (void) ace_access_txt(endp, &endp, aclp->a_type); 900fa9e4066Sahrens 9015a5eeccaSmarks if ((flags & ACL_APPEND_ID) && 9025a5eeccaSmarks (((aclp->a_flags & ACE_TYPE_FLAGS) == 0) || 9035a5eeccaSmarks ((aclp->a_flags & ACE_TYPE_FLAGS) == 9045a5eeccaSmarks ACE_IDENTIFIER_GROUP))) { 9055a5eeccaSmarks *endp++ = ':'; 9065a5eeccaSmarks *endp = '\0'; 9075a5eeccaSmarks id[ID_STR_MAX -1] = '\0'; /* null terminate buffer */ 9085a5eeccaSmarks idstr = lltostr(aclp->a_who, &id[ID_STR_MAX - 1]); 9095a5eeccaSmarks strcpy(endp, idstr); 9105a5eeccaSmarks endp += strlen(idstr); 9115a5eeccaSmarks } 9125a5eeccaSmarks if (i < aclcnt - 1) { 9135a5eeccaSmarks *endp++ = ','; 9145a5eeccaSmarks *(endp + 1) = '\0'; 915fa9e4066Sahrens } 916fa9e4066Sahrens } 917fa9e4066Sahrens return (aclexport); 918fa9e4066Sahrens } 919fa9e4066Sahrens 9205a5eeccaSmarks char * 9215a5eeccaSmarks acl_totext(acl_t *aclp, int flags) 922fa9e4066Sahrens { 923fa9e4066Sahrens 9245a5eeccaSmarks char *txtp; 925fa9e4066Sahrens 926fa9e4066Sahrens if (aclp == NULL) 927fa9e4066Sahrens return (NULL); 928fa9e4066Sahrens 929fa9e4066Sahrens switch (aclp->acl_type) { 930fa9e4066Sahrens case ACE_T: 9315a5eeccaSmarks txtp = ace_acltotext(aclp, flags); 9325a5eeccaSmarks break; 933fa9e4066Sahrens case ACLENT_T: 9345a5eeccaSmarks txtp = aclent_acltotext(aclp->acl_aclp, aclp->acl_cnt, flags); 9355a5eeccaSmarks break; 936fa9e4066Sahrens } 9375a5eeccaSmarks 9385a5eeccaSmarks return (txtp); 939fa9e4066Sahrens } 940fa9e4066Sahrens 941fa9e4066Sahrens int 942fa9e4066Sahrens acl_fromtext(const char *acltextp, acl_t **ret_aclp) 943fa9e4066Sahrens { 9445a5eeccaSmarks int error; 9455a5eeccaSmarks char *buf; 9465a5eeccaSmarks 9475a5eeccaSmarks buf = malloc(strlen(acltextp) + 2); 9485a5eeccaSmarks if (buf == NULL) 9495a5eeccaSmarks return (EACL_MEM_ERROR); 9505a5eeccaSmarks strcpy(buf, acltextp); 9515a5eeccaSmarks strcat(buf, "\n"); 9525a5eeccaSmarks yybuf = buf; 9535a5eeccaSmarks yyreset(); 9545a5eeccaSmarks error = yyparse(); 9555a5eeccaSmarks free(buf); 9565a5eeccaSmarks 9575a5eeccaSmarks if (yyacl) { 9585a5eeccaSmarks if (error == 0) 9595a5eeccaSmarks *ret_aclp = yyacl; 9605a5eeccaSmarks else { 9615a5eeccaSmarks acl_free(yyacl); 9625a5eeccaSmarks } 9635a5eeccaSmarks yyacl = NULL; 9645a5eeccaSmarks } 9655a5eeccaSmarks return (error); 9665a5eeccaSmarks } 9675a5eeccaSmarks 9685a5eeccaSmarks int 9695a5eeccaSmarks acl_parse(const char *acltextp, acl_t **aclp) 9705a5eeccaSmarks { 971fa9e4066Sahrens int error; 972fa9e4066Sahrens 9735a5eeccaSmarks yyinteractive = 1; 9745a5eeccaSmarks error = acl_fromtext(acltextp, aclp); 9755a5eeccaSmarks yyinteractive = 0; 976fa9e4066Sahrens return (error); 977fa9e4066Sahrens } 9785a5eeccaSmarks 9795a5eeccaSmarks static void 9805a5eeccaSmarks ace_compact_printacl(acl_t *aclp) 9815a5eeccaSmarks { 9825a5eeccaSmarks int cnt; 9835a5eeccaSmarks ace_t *acep; 9845a5eeccaSmarks char *endp; 9855a5eeccaSmarks char buf[ACE_ENTRY_SIZE]; 9865a5eeccaSmarks 9875a5eeccaSmarks for (cnt = 0, acep = aclp->acl_aclp; 9885a5eeccaSmarks cnt != aclp->acl_cnt; cnt++, acep++) { 9895a5eeccaSmarks buf[0] = '\0'; 99045a17f45Sgjelinek (void) printf(" %14s:", ace_type_txt(buf, &endp, acep, 0)); 9915a5eeccaSmarks (void) printf("%s:", ace_perm_txt(endp, &endp, 9925a5eeccaSmarks acep->a_access_mask, acep->a_flags, 9935a5eeccaSmarks aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT)); 9945a5eeccaSmarks (void) printf("%s:", 9955a5eeccaSmarks ace_inherit_txt(endp, &endp, acep->a_flags, 9965a5eeccaSmarks ACL_COMPACT_FMT)); 9975a5eeccaSmarks (void) printf("%s\n", ace_access_txt(endp, &endp, 9985a5eeccaSmarks acep->a_type)); 9995a5eeccaSmarks } 10005a5eeccaSmarks } 10015a5eeccaSmarks 10025a5eeccaSmarks static void 10035a5eeccaSmarks ace_printacl(acl_t *aclp, int cols, int compact) 10045a5eeccaSmarks { 10055a5eeccaSmarks int slot = 0; 10065a5eeccaSmarks char *token; 10075a5eeccaSmarks char *acltext; 10085a5eeccaSmarks 10095a5eeccaSmarks if (compact) { 10105a5eeccaSmarks ace_compact_printacl(aclp); 10115a5eeccaSmarks return; 10125a5eeccaSmarks } 10135a5eeccaSmarks 10145a5eeccaSmarks acltext = acl_totext(aclp, 0); 10155a5eeccaSmarks 10165a5eeccaSmarks if (acltext == NULL) 10175a5eeccaSmarks return; 10185a5eeccaSmarks 10195a5eeccaSmarks token = strtok(acltext, ","); 10205a5eeccaSmarks if (token == NULL) { 10215a5eeccaSmarks free(acltext); 10225a5eeccaSmarks return; 10235a5eeccaSmarks } 10245a5eeccaSmarks 10255a5eeccaSmarks do { 10265a5eeccaSmarks (void) printf(" %d:", slot++); 10275a5eeccaSmarks split_line(token, cols - 5); 10285a5eeccaSmarks } while (token = strtok(NULL, ",")); 10295a5eeccaSmarks free(acltext); 10305a5eeccaSmarks } 10315a5eeccaSmarks 10325a5eeccaSmarks /* 10335a5eeccaSmarks * pretty print an ACL. 10345a5eeccaSmarks * For aclent_t ACL's the format is 10355a5eeccaSmarks * similar to the old format used by getfacl, 10365a5eeccaSmarks * with the addition of adding a "slot" number 10375a5eeccaSmarks * before each entry. 10385a5eeccaSmarks * 10395a5eeccaSmarks * for ace_t ACL's the cols variable will break up 10405a5eeccaSmarks * the long lines into multiple lines and will also 10415a5eeccaSmarks * print a "slot" number. 10425a5eeccaSmarks */ 10435a5eeccaSmarks void 10445a5eeccaSmarks acl_printacl(acl_t *aclp, int cols, int compact) 10455a5eeccaSmarks { 10465a5eeccaSmarks 10475a5eeccaSmarks switch (aclp->acl_type) { 10485a5eeccaSmarks case ACLENT_T: 10495a5eeccaSmarks aclent_printacl(aclp); 10505a5eeccaSmarks break; 10515a5eeccaSmarks case ACE_T: 10525a5eeccaSmarks ace_printacl(aclp, cols, compact); 10535a5eeccaSmarks break; 10545a5eeccaSmarks } 10555a5eeccaSmarks } 10565a5eeccaSmarks 10575a5eeccaSmarks typedef struct value_table { 10585a5eeccaSmarks char p_letter; /* perm letter such as 'r' */ 10595a5eeccaSmarks uint32_t p_value; /* value for perm when pletter found */ 10605a5eeccaSmarks } value_table_t; 10615a5eeccaSmarks 10625a5eeccaSmarks /* 1063*da6c28aaSamw * The permission tables are laid out in positional order 10645a5eeccaSmarks * a '-' character will indicate a permission at a given 10655a5eeccaSmarks * position is not specified. The '-' is not part of the 10665a5eeccaSmarks * table, but will be checked for in the permission computation 10675a5eeccaSmarks * routine. 10685a5eeccaSmarks */ 1069*da6c28aaSamw value_table_t ace_perm_table[] = { 10705a5eeccaSmarks { 'r', ACE_READ_DATA}, 10715a5eeccaSmarks { 'w', ACE_WRITE_DATA}, 10725a5eeccaSmarks { 'x', ACE_EXECUTE}, 10735a5eeccaSmarks { 'p', ACE_APPEND_DATA}, 10745a5eeccaSmarks { 'd', ACE_DELETE}, 10755a5eeccaSmarks { 'D', ACE_DELETE_CHILD}, 10765a5eeccaSmarks { 'a', ACE_READ_ATTRIBUTES}, 10775a5eeccaSmarks { 'A', ACE_WRITE_ATTRIBUTES}, 10785a5eeccaSmarks { 'R', ACE_READ_NAMED_ATTRS}, 10795a5eeccaSmarks { 'W', ACE_WRITE_NAMED_ATTRS}, 10805a5eeccaSmarks { 'c', ACE_READ_ACL}, 10815a5eeccaSmarks { 'C', ACE_WRITE_ACL}, 10825a5eeccaSmarks { 'o', ACE_WRITE_OWNER}, 10835a5eeccaSmarks { 's', ACE_SYNCHRONIZE} 10845a5eeccaSmarks }; 10855a5eeccaSmarks 1086*da6c28aaSamw #define ACE_PERM_COUNT (sizeof (ace_perm_table) / sizeof (value_table_t)) 10875a5eeccaSmarks 1088*da6c28aaSamw value_table_t aclent_perm_table[] = { 10895a5eeccaSmarks { 'r', S_IROTH}, 10905a5eeccaSmarks { 'w', S_IWOTH}, 10915a5eeccaSmarks { 'x', S_IXOTH} 10925a5eeccaSmarks }; 10935a5eeccaSmarks 1094*da6c28aaSamw #define ACLENT_PERM_COUNT (sizeof (aclent_perm_table) / sizeof (value_table_t)) 1095*da6c28aaSamw 1096*da6c28aaSamw value_table_t inherit_table[] = { 10975a5eeccaSmarks {'f', ACE_FILE_INHERIT_ACE}, 10985a5eeccaSmarks {'d', ACE_DIRECTORY_INHERIT_ACE}, 10995a5eeccaSmarks {'i', ACE_INHERIT_ONLY_ACE}, 11005a5eeccaSmarks {'n', ACE_NO_PROPAGATE_INHERIT_ACE}, 11015a5eeccaSmarks {'S', ACE_SUCCESSFUL_ACCESS_ACE_FLAG}, 1102*da6c28aaSamw {'F', ACE_FAILED_ACCESS_ACE_FLAG}, 1103*da6c28aaSamw {'I', ACE_INHERITED_ACE} 11045a5eeccaSmarks }; 11055a5eeccaSmarks 1106*da6c28aaSamw #define IFLAG_COUNT (sizeof (inherit_table) / sizeof (value_table_t)) 1107*da6c28aaSamw 11085a5eeccaSmarks /* 11095a5eeccaSmarks * compute value from a permission table or inheritance table 11105a5eeccaSmarks * based on string passed in. If positional is set then 11115a5eeccaSmarks * string must match order in permtab, otherwise any order 11125a5eeccaSmarks * is allowed. 11135a5eeccaSmarks */ 11145a5eeccaSmarks int 11155a5eeccaSmarks compute_values(value_table_t *permtab, int count, 11165a5eeccaSmarks char *permstr, int positional, uint32_t *mask) 11175a5eeccaSmarks { 11185a5eeccaSmarks uint32_t perm_val = 0; 11195a5eeccaSmarks char *pstr; 11205a5eeccaSmarks int i, found; 11215a5eeccaSmarks 11225a5eeccaSmarks if (count < 0) 11235a5eeccaSmarks return (1); 11245a5eeccaSmarks 11255a5eeccaSmarks if (positional) { 11265a5eeccaSmarks for (i = 0, pstr = permstr; i != count && pstr && 11275a5eeccaSmarks *pstr; i++, pstr++) { 11285a5eeccaSmarks if (*pstr == permtab[i].p_letter) { 11295a5eeccaSmarks perm_val |= permtab[i].p_value; 11305a5eeccaSmarks } else if (*pstr != '-') { 11315a5eeccaSmarks return (1); 11325a5eeccaSmarks } 11335a5eeccaSmarks } 11345a5eeccaSmarks } else { /* random order single letters with no '-' */ 11355a5eeccaSmarks for (pstr = permstr; pstr && *pstr; pstr++) { 11365a5eeccaSmarks for (found = 0, i = 0; i != count; i++) { 11375a5eeccaSmarks if (*pstr == permtab[i].p_letter) { 11385a5eeccaSmarks perm_val |= permtab[i].p_value; 11395a5eeccaSmarks found = 1; 11405a5eeccaSmarks break; 11415a5eeccaSmarks } 11425a5eeccaSmarks } 11435a5eeccaSmarks if (found == 0) 11445a5eeccaSmarks return (1); 11455a5eeccaSmarks } 11465a5eeccaSmarks } 11475a5eeccaSmarks 11485a5eeccaSmarks *mask = perm_val; 11495a5eeccaSmarks return (0); 11505a5eeccaSmarks } 11515a5eeccaSmarks 11525a5eeccaSmarks /* 11535a5eeccaSmarks * compute value for inheritance flags. 11545a5eeccaSmarks */ 11555a5eeccaSmarks int 11565a5eeccaSmarks compute_ace_inherit(char *str, uint32_t *imask) 11575a5eeccaSmarks { 11585a5eeccaSmarks int error; 11595a5eeccaSmarks int positional = 0; 11605a5eeccaSmarks 11615a5eeccaSmarks if (strlen(str) == IFLAG_COUNT) 11625a5eeccaSmarks positional = 1; 11635a5eeccaSmarks 11645a5eeccaSmarks error = compute_values(inherit_table, IFLAG_COUNT, 11655a5eeccaSmarks str, positional, imask); 11665a5eeccaSmarks 11675a5eeccaSmarks if (error) 11685a5eeccaSmarks return (EACL_INHERIT_ERROR); 11695a5eeccaSmarks 11705a5eeccaSmarks return (error); 11715a5eeccaSmarks } 11725a5eeccaSmarks 11735a5eeccaSmarks 11745a5eeccaSmarks /* 11755a5eeccaSmarks * compute value for ACE permissions. 11765a5eeccaSmarks */ 11775a5eeccaSmarks int 11785a5eeccaSmarks compute_ace_perms(char *str, uint32_t *mask) 11795a5eeccaSmarks { 11805a5eeccaSmarks int positional = 0; 11815a5eeccaSmarks int error; 11825a5eeccaSmarks 11835a5eeccaSmarks if (strlen(str) == ACE_PERM_COUNT) 11845a5eeccaSmarks positional = 1; 11855a5eeccaSmarks 11865a5eeccaSmarks error = compute_values(ace_perm_table, ACE_PERM_COUNT, 11875a5eeccaSmarks str, positional, mask); 11885a5eeccaSmarks 11895a5eeccaSmarks if (error && positional) { 11905a5eeccaSmarks /* 11915a5eeccaSmarks * If positional was set, then make sure permissions 11925a5eeccaSmarks * aren't actually valid in non positional case where 11935a5eeccaSmarks * all permissions are specified, just in random order. 11945a5eeccaSmarks */ 11955a5eeccaSmarks error = compute_values(ace_perm_table, 11965a5eeccaSmarks ACE_PERM_COUNT, str, 0, mask); 11975a5eeccaSmarks } 11985a5eeccaSmarks if (error) 11995a5eeccaSmarks error = EACL_PERM_MASK_ERROR; 12005a5eeccaSmarks 12015a5eeccaSmarks return (error); 12025a5eeccaSmarks } 12035a5eeccaSmarks 12045a5eeccaSmarks 12055a5eeccaSmarks 12065a5eeccaSmarks /* 12075a5eeccaSmarks * compute values for aclent permissions. 12085a5eeccaSmarks */ 12095a5eeccaSmarks int 12105a5eeccaSmarks compute_aclent_perms(char *str, o_mode_t *mask) 12115a5eeccaSmarks { 12125a5eeccaSmarks int error; 12135a5eeccaSmarks uint32_t pmask; 12145a5eeccaSmarks 12155a5eeccaSmarks if (strlen(str) != ACLENT_PERM_COUNT) 12165a5eeccaSmarks return (EACL_PERM_MASK_ERROR); 12175a5eeccaSmarks 12185a5eeccaSmarks *mask = 0; 12195a5eeccaSmarks error = compute_values(aclent_perm_table, ACLENT_PERM_COUNT, 12205a5eeccaSmarks str, 1, &pmask); 12215a5eeccaSmarks if (error == 0) { 12225a5eeccaSmarks *mask = (o_mode_t)pmask; 12235a5eeccaSmarks } else 12245a5eeccaSmarks error = EACL_PERM_MASK_ERROR; 12255a5eeccaSmarks return (error); 12265a5eeccaSmarks } 12275a5eeccaSmarks 12285a5eeccaSmarks /* 12295a5eeccaSmarks * determine ACE permissions. 12305a5eeccaSmarks */ 12315a5eeccaSmarks int 12325a5eeccaSmarks ace_perm_mask(struct acl_perm_type *aclperm, uint32_t *mask) 12335a5eeccaSmarks { 12345a5eeccaSmarks int error; 12355a5eeccaSmarks 12365a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_EMPTY) { 12375a5eeccaSmarks *mask = 0; 12385a5eeccaSmarks return (0); 12395a5eeccaSmarks } 12405a5eeccaSmarks 12415a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_ACE) { 12425a5eeccaSmarks *mask = aclperm->perm_val; 12435a5eeccaSmarks return (0); 12445a5eeccaSmarks } 12455a5eeccaSmarks 12465a5eeccaSmarks error = compute_ace_perms(aclperm->perm_str, mask); 12475a5eeccaSmarks if (error) { 12485b233e2dSmarks acl_error(dgettext(TEXT_DOMAIN, 12495b233e2dSmarks "Invalid permission(s) '%s' specified\n"), 12505a5eeccaSmarks aclperm->perm_str); 12515a5eeccaSmarks return (EACL_PERM_MASK_ERROR); 12525a5eeccaSmarks } 12535a5eeccaSmarks 12545a5eeccaSmarks return (0); 12555a5eeccaSmarks } 1256