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 /*
221fdeec65Sjoyce mcintosh * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
23*8ce3a038SMarcel Telka * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
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>
409fb67ea3Safshin 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;
539fb67ea3Safshin 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
aclent_perms(int perm,char * txt_perms)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 *
pruname(uid_t uid,char * uidp,size_t buflen,int noresolve)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 *
prgname(gid_t gid,char * gidp,size_t buflen,int noresolve)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
getsidname(uid_t who,boolean_t user,char ** sidp,boolean_t noresolve)121909c9a9fSMark Shellenbaum getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve)
122b249c65cSmarks {
123b249c65cSmarks idmap_get_handle_t *get_hdl = NULL;
124b249c65cSmarks idmap_stat status;
125b249c65cSmarks idmap_rid_t rid;
126909c9a9fSMark Shellenbaum int error = IDMAP_ERR_NORESULT;
127b249c65cSmarks int len;
1289a2c8b2bSGowtham Thommandra char *domain = NULL;
129b249c65cSmarks
130909c9a9fSMark Shellenbaum *sidp = NULL;
131b249c65cSmarks
132b249c65cSmarks /*
133b249c65cSmarks * First try and get windows name
134b249c65cSmarks */
135b249c65cSmarks
136909c9a9fSMark Shellenbaum if (!noresolve) {
137b249c65cSmarks if (user)
138909c9a9fSMark Shellenbaum error = idmap_getwinnamebyuid(who,
139*8ce3a038SMarcel Telka IDMAP_REQ_FLG_USE_CACHE, sidp, NULL);
140b249c65cSmarks else
141909c9a9fSMark Shellenbaum error = idmap_getwinnamebygid(who,
142*8ce3a038SMarcel Telka IDMAP_REQ_FLG_USE_CACHE, sidp, NULL);
143909c9a9fSMark Shellenbaum }
144909c9a9fSMark Shellenbaum if (error != IDMAP_SUCCESS) {
1451fdeec65Sjoyce mcintosh if (idmap_get_create(&get_hdl) == IDMAP_SUCCESS) {
146b249c65cSmarks if (user)
147b249c65cSmarks error = idmap_get_sidbyuid(get_hdl, who,
1483ee87bcaSJulian Pullen IDMAP_REQ_FLG_USE_CACHE, &domain, &rid,
1493ee87bcaSJulian Pullen &status);
150b249c65cSmarks else
151b249c65cSmarks error = idmap_get_sidbygid(get_hdl, who,
1523ee87bcaSJulian Pullen IDMAP_REQ_FLG_USE_CACHE, &domain, &rid,
1533ee87bcaSJulian Pullen &status);
154909c9a9fSMark Shellenbaum if (error == IDMAP_SUCCESS &&
155909c9a9fSMark Shellenbaum idmap_get_mappings(get_hdl) == 0) {
156909c9a9fSMark Shellenbaum if (status == IDMAP_SUCCESS) {
157909c9a9fSMark Shellenbaum len = snprintf(NULL, 0,
158909c9a9fSMark Shellenbaum "%s-%d", domain, rid);
159909c9a9fSMark Shellenbaum if (*sidp = malloc(len + 1)) {
160909c9a9fSMark Shellenbaum (void) snprintf(*sidp, len + 1,
161909c9a9fSMark Shellenbaum "%s-%d", domain, rid);
162b249c65cSmarks }
163909c9a9fSMark Shellenbaum }
164909c9a9fSMark Shellenbaum }
165b249c65cSmarks }
166b249c65cSmarks if (get_hdl)
167b249c65cSmarks idmap_get_destroy(get_hdl);
168b249c65cSmarks }
1699a2c8b2bSGowtham Thommandra
1709a2c8b2bSGowtham Thommandra free(domain);
171*8ce3a038SMarcel Telka
172909c9a9fSMark Shellenbaum return (*sidp ? 0 : 1);
173b249c65cSmarks }
174b249c65cSmarks
1755a5eeccaSmarks static void
aclent_printacl(acl_t * aclp)1765a5eeccaSmarks aclent_printacl(acl_t *aclp)
1775a5eeccaSmarks {
1785a5eeccaSmarks aclent_t *tp;
1795a5eeccaSmarks int aclcnt;
1805a5eeccaSmarks int mask;
1815a5eeccaSmarks int slot = 0;
1825a5eeccaSmarks char perm[4];
183afe1f701Smarks char uidp[ID_STR_MAX];
184afe1f701Smarks char gidp[ID_STR_MAX];
1855a5eeccaSmarks
1865a5eeccaSmarks /* display ACL: assume it is sorted. */
1875a5eeccaSmarks aclcnt = aclp->acl_cnt;
1885a5eeccaSmarks for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) {
1895a5eeccaSmarks if (tp->a_type == CLASS_OBJ)
1905a5eeccaSmarks mask = tp->a_perm;
1915a5eeccaSmarks }
1925a5eeccaSmarks aclcnt = aclp->acl_cnt;
1935a5eeccaSmarks for (tp = aclp->acl_aclp; aclcnt--; tp++) {
1945a5eeccaSmarks (void) printf(" %d:", slot++);
1955a5eeccaSmarks switch (tp->a_type) {
1965a5eeccaSmarks case USER:
1975a5eeccaSmarks aclent_perms(tp->a_perm, perm);
1985a5eeccaSmarks (void) printf("user:%s:%s\t\t",
199afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm);
2005a5eeccaSmarks aclent_perms((tp->a_perm & mask), perm);
2015a5eeccaSmarks (void) printf("#effective:%s\n", perm);
2025a5eeccaSmarks break;
2035a5eeccaSmarks case USER_OBJ:
2045a5eeccaSmarks /* no need to display uid */
2055a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2065a5eeccaSmarks (void) printf("user::%s\n", perm);
2075a5eeccaSmarks break;
2085a5eeccaSmarks case GROUP:
2095a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2105a5eeccaSmarks (void) printf("group:%s:%s\t\t",
211afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm);
2125a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm);
2135a5eeccaSmarks (void) printf("#effective:%s\n", perm);
2145a5eeccaSmarks break;
2155a5eeccaSmarks case GROUP_OBJ:
2165a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2175a5eeccaSmarks (void) printf("group::%s\t\t", perm);
2185a5eeccaSmarks aclent_perms(tp->a_perm & mask, perm);
2195a5eeccaSmarks (void) printf("#effective:%s\n", perm);
2205a5eeccaSmarks break;
2215a5eeccaSmarks case CLASS_OBJ:
2225a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2235a5eeccaSmarks (void) printf("mask:%s\n", perm);
2245a5eeccaSmarks break;
2255a5eeccaSmarks case OTHER_OBJ:
2265a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2275a5eeccaSmarks (void) printf("other:%s\n", perm);
2285a5eeccaSmarks break;
2295a5eeccaSmarks case DEF_USER:
2305a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2315a5eeccaSmarks (void) printf("default:user:%s:%s\n",
232afe1f701Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm);
2335a5eeccaSmarks break;
2345a5eeccaSmarks case DEF_USER_OBJ:
2355a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2365a5eeccaSmarks (void) printf("default:user::%s\n", perm);
2375a5eeccaSmarks break;
2385a5eeccaSmarks case DEF_GROUP:
2395a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2405a5eeccaSmarks (void) printf("default:group:%s:%s\n",
241afe1f701Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm);
2425a5eeccaSmarks break;
2435a5eeccaSmarks case DEF_GROUP_OBJ:
2445a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2455a5eeccaSmarks (void) printf("default:group::%s\n", perm);
2465a5eeccaSmarks break;
2475a5eeccaSmarks case DEF_CLASS_OBJ:
2485a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2495a5eeccaSmarks (void) printf("default:mask:%s\n", perm);
2505a5eeccaSmarks break;
2515a5eeccaSmarks case DEF_OTHER_OBJ:
2525a5eeccaSmarks aclent_perms(tp->a_perm, perm);
2535a5eeccaSmarks (void) printf("default:other:%s\n", perm);
2545a5eeccaSmarks break;
2555a5eeccaSmarks default:
2565a5eeccaSmarks (void) fprintf(stderr,
2575b233e2dSmarks dgettext(TEXT_DOMAIN, "unrecognized entry\n"));
2585a5eeccaSmarks break;
2595a5eeccaSmarks }
2605a5eeccaSmarks }
2615a5eeccaSmarks }
2625a5eeccaSmarks
2635a5eeccaSmarks static void
split_line(char * str,int cols)2645a5eeccaSmarks split_line(char *str, int cols)
2655a5eeccaSmarks {
2665a5eeccaSmarks char *ptr;
2675a5eeccaSmarks int len;
2685a5eeccaSmarks int i;
2695a5eeccaSmarks int last_split;
2705a5eeccaSmarks char *pad = "";
2715a5eeccaSmarks int pad_len;
2725a5eeccaSmarks
2735a5eeccaSmarks len = strlen(str);
2745a5eeccaSmarks ptr = str;
2755a5eeccaSmarks pad_len = 0;
2765a5eeccaSmarks
2775a5eeccaSmarks ptr = str;
2785a5eeccaSmarks last_split = 0;
2795a5eeccaSmarks for (i = 0; i != len; i++) {
2805a5eeccaSmarks if ((i + pad_len + 4) >= cols) {
2815a5eeccaSmarks (void) printf("%s%.*s\n", pad, last_split, ptr);
2825a5eeccaSmarks ptr = &ptr[last_split];
2835a5eeccaSmarks len = strlen(ptr);
2845a5eeccaSmarks i = 0;
2855a5eeccaSmarks pad_len = 4;
2865a5eeccaSmarks pad = " ";
2875a5eeccaSmarks } else {
2885a5eeccaSmarks if (ptr[i] == '/' || ptr[i] == ':') {
2895a5eeccaSmarks last_split = i;
2905a5eeccaSmarks }
2915a5eeccaSmarks }
2925a5eeccaSmarks }
2935a5eeccaSmarks if (i == len) {
2945a5eeccaSmarks (void) printf("%s%s\n", pad, ptr);
2955a5eeccaSmarks }
2965a5eeccaSmarks }
2975a5eeccaSmarks
298b249c65cSmarks /*
299b249c65cSmarks * compute entry type string, such as user:joe, group:staff,...
300b249c65cSmarks */
301b249c65cSmarks static int
aclent_type_txt(dynaclstr_t * dstr,aclent_t * aclp,int flags)302b249c65cSmarks aclent_type_txt(dynaclstr_t *dstr, aclent_t *aclp, int flags)
3035a5eeccaSmarks {
304afe1f701Smarks char idp[ID_STR_MAX];
305b249c65cSmarks int error;
3065a5eeccaSmarks
307b249c65cSmarks switch (aclp->a_type) {
308b249c65cSmarks case DEF_USER_OBJ:
309b249c65cSmarks case USER_OBJ:
310b249c65cSmarks if (aclp->a_type == USER_OBJ)
311b249c65cSmarks error = str_append(dstr, "user::");
312b249c65cSmarks else
313b249c65cSmarks error = str_append(dstr, "defaultuser::");
314b249c65cSmarks break;
315b249c65cSmarks
316b249c65cSmarks case DEF_USER:
317b249c65cSmarks case USER:
318b249c65cSmarks if (aclp->a_type == USER)
319b249c65cSmarks error = str_append(dstr, "user:");
320b249c65cSmarks else
321b249c65cSmarks error = str_append(dstr, "defaultuser:");
322b249c65cSmarks if (error)
323b249c65cSmarks break;
324b249c65cSmarks error = str_append(dstr, pruname(aclp->a_id, idp,
325b249c65cSmarks sizeof (idp), flags & ACL_NORESOLVE));
326b249c65cSmarks if (error == 0)
327b249c65cSmarks error = str_append(dstr, ":");
328b249c65cSmarks break;
329b249c65cSmarks
330b249c65cSmarks case DEF_GROUP_OBJ:
331b249c65cSmarks case GROUP_OBJ:
332b249c65cSmarks if (aclp->a_type == GROUP_OBJ)
333b249c65cSmarks error = str_append(dstr, "group::");
334b249c65cSmarks else
335b249c65cSmarks error = str_append(dstr, "defaultgroup::");
336b249c65cSmarks break;
337b249c65cSmarks
338b249c65cSmarks case DEF_GROUP:
339b249c65cSmarks case GROUP:
340b249c65cSmarks if (aclp->a_type == GROUP)
341b249c65cSmarks error = str_append(dstr, "group:");
342b249c65cSmarks else
343b249c65cSmarks error = str_append(dstr, "defaultgroup:");
344b249c65cSmarks if (error)
345b249c65cSmarks break;
346b249c65cSmarks error = str_append(dstr, prgname(aclp->a_id, idp,
347b249c65cSmarks sizeof (idp), flags & ACL_NORESOLVE));
348b249c65cSmarks if (error == 0)
349b249c65cSmarks error = str_append(dstr, ":");
350b249c65cSmarks break;
351b249c65cSmarks
352b249c65cSmarks case DEF_CLASS_OBJ:
353b249c65cSmarks case CLASS_OBJ:
354b249c65cSmarks if (aclp->a_type == CLASS_OBJ)
355b249c65cSmarks error = str_append(dstr, "mask:");
356b249c65cSmarks else
357b249c65cSmarks error = str_append(dstr, "defaultmask:");
358b249c65cSmarks break;
359b249c65cSmarks
360b249c65cSmarks case DEF_OTHER_OBJ:
361b249c65cSmarks case OTHER_OBJ:
362b249c65cSmarks if (aclp->a_type == OTHER_OBJ)
363b249c65cSmarks error = str_append(dstr, "other:");
364b249c65cSmarks else
365b249c65cSmarks error = str_append(dstr, "defaultother:");
366b249c65cSmarks break;
367b249c65cSmarks
368b249c65cSmarks default:
369b249c65cSmarks error = 1;
370b249c65cSmarks break;
371b249c65cSmarks }
372b249c65cSmarks
373b249c65cSmarks return (error);
374b249c65cSmarks }
375b249c65cSmarks
376b249c65cSmarks /*
377b249c65cSmarks * compute entry type string such as, owner@:, user:joe, group:staff,...
378b249c65cSmarks */
379b249c65cSmarks static int
ace_type_txt(dynaclstr_t * dynstr,ace_t * acep,int flags)380b249c65cSmarks ace_type_txt(dynaclstr_t *dynstr, ace_t *acep, int flags)
381b249c65cSmarks {
382b249c65cSmarks char idp[ID_STR_MAX];
383b249c65cSmarks int error;
384b249c65cSmarks char *sidp = NULL;
3855a5eeccaSmarks
3865a5eeccaSmarks switch (acep->a_flags & ACE_TYPE_FLAGS) {
3875a5eeccaSmarks case ACE_OWNER:
388b249c65cSmarks error = str_append(dynstr, OWNERAT_TXT);
3895a5eeccaSmarks break;
3905a5eeccaSmarks
3915a5eeccaSmarks case ACE_GROUP|ACE_IDENTIFIER_GROUP:
392b249c65cSmarks error = str_append(dynstr, GROUPAT_TXT);
3935a5eeccaSmarks break;
3945a5eeccaSmarks
3955a5eeccaSmarks case ACE_IDENTIFIER_GROUP:
396b249c65cSmarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {
397b249c65cSmarks if (error = str_append(dynstr,
398b249c65cSmarks GROUPSID_TXT))
399b249c65cSmarks break;
400909c9a9fSMark Shellenbaum if (error = getsidname(acep->a_who, B_FALSE,
401909c9a9fSMark Shellenbaum &sidp, flags & ACL_NORESOLVE))
402909c9a9fSMark Shellenbaum break;
403909c9a9fSMark Shellenbaum error = str_append(dynstr, sidp);
404b249c65cSmarks } else {
405b249c65cSmarks if (error = str_append(dynstr, GROUP_TXT))
406b249c65cSmarks break;
407b249c65cSmarks error = str_append(dynstr, prgname(acep->a_who, idp,
408afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE));
409b249c65cSmarks }
410b249c65cSmarks if (error == 0)
411b249c65cSmarks error = str_append(dynstr, ":");
4125a5eeccaSmarks break;
4135a5eeccaSmarks
4145a5eeccaSmarks case ACE_EVERYONE:
415b249c65cSmarks error = str_append(dynstr, EVERYONEAT_TXT);
4165a5eeccaSmarks break;
4175a5eeccaSmarks
4185a5eeccaSmarks case 0:
419b249c65cSmarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {
420b249c65cSmarks if (error = str_append(dynstr, USERSID_TXT))
421b249c65cSmarks break;
422909c9a9fSMark Shellenbaum if (error = getsidname(acep->a_who, B_TRUE,
423909c9a9fSMark Shellenbaum &sidp, flags & ACL_NORESOLVE))
424909c9a9fSMark Shellenbaum break;
425909c9a9fSMark Shellenbaum error = str_append(dynstr, sidp);
426b249c65cSmarks } else {
427b249c65cSmarks if (error = str_append(dynstr, USER_TXT))
428b249c65cSmarks break;
429b249c65cSmarks error = str_append(dynstr, pruname(acep->a_who, idp,
430afe1f701Smarks sizeof (idp), flags & ACL_NORESOLVE));
431b249c65cSmarks }
432b249c65cSmarks if (error == 0)
433b249c65cSmarks error = str_append(dynstr, ":");
434b249c65cSmarks break;
435b249c65cSmarks default:
436b249c65cSmarks error = 0;
4375a5eeccaSmarks break;
4385a5eeccaSmarks }
4395a5eeccaSmarks
440b249c65cSmarks if (sidp)
441b249c65cSmarks free(sidp);
442b249c65cSmarks return (error);
4435a5eeccaSmarks }
4445a5eeccaSmarks
445b249c65cSmarks /*
446b249c65cSmarks * compute string of permissions, such as read_data/write_data or
447b249c65cSmarks * rwxp,...
448b249c65cSmarks * The format depends on the flags field which indicates whether the compact
449b249c65cSmarks * or verbose format should be used.
450b249c65cSmarks */
451b249c65cSmarks static int
ace_perm_txt(dynaclstr_t * dstr,uint32_t mask,uint32_t iflags,int isdir,int flags)452b249c65cSmarks ace_perm_txt(dynaclstr_t *dstr, uint32_t mask,
4535a5eeccaSmarks uint32_t iflags, int isdir, int flags)
4545a5eeccaSmarks {
455b249c65cSmarks int error = 0;
4565a5eeccaSmarks
4575a5eeccaSmarks if (flags & ACL_COMPACT_FMT) {
458b249c65cSmarks char buf[16];
4595a5eeccaSmarks
4605a5eeccaSmarks if (mask & ACE_READ_DATA)
4615a5eeccaSmarks buf[0] = 'r';
4625a5eeccaSmarks else
4635a5eeccaSmarks buf[0] = '-';
4645a5eeccaSmarks if (mask & ACE_WRITE_DATA)
4655a5eeccaSmarks buf[1] = 'w';
4665a5eeccaSmarks else
4675a5eeccaSmarks buf[1] = '-';
4685a5eeccaSmarks if (mask & ACE_EXECUTE)
4695a5eeccaSmarks buf[2] = 'x';
4705a5eeccaSmarks else
4715a5eeccaSmarks buf[2] = '-';
4725a5eeccaSmarks if (mask & ACE_APPEND_DATA)
4735a5eeccaSmarks buf[3] = 'p';
4745a5eeccaSmarks else
4755a5eeccaSmarks buf[3] = '-';
4765a5eeccaSmarks if (mask & ACE_DELETE)
4775a5eeccaSmarks buf[4] = 'd';
4785a5eeccaSmarks else
4795a5eeccaSmarks buf[4] = '-';
4805a5eeccaSmarks if (mask & ACE_DELETE_CHILD)
4815a5eeccaSmarks buf[5] = 'D';
4825a5eeccaSmarks else
4835a5eeccaSmarks buf[5] = '-';
4845a5eeccaSmarks if (mask & ACE_READ_ATTRIBUTES)
4855a5eeccaSmarks buf[6] = 'a';
4865a5eeccaSmarks else
4875a5eeccaSmarks buf[6] = '-';
4885a5eeccaSmarks if (mask & ACE_WRITE_ATTRIBUTES)
4895a5eeccaSmarks buf[7] = 'A';
4905a5eeccaSmarks else
4915a5eeccaSmarks buf[7] = '-';
4925a5eeccaSmarks if (mask & ACE_READ_NAMED_ATTRS)
4935a5eeccaSmarks buf[8] = 'R';
4945a5eeccaSmarks else
4955a5eeccaSmarks buf[8] = '-';
4965a5eeccaSmarks if (mask & ACE_WRITE_NAMED_ATTRS)
4975a5eeccaSmarks buf[9] = 'W';
4985a5eeccaSmarks else
4995a5eeccaSmarks buf[9] = '-';
5005a5eeccaSmarks if (mask & ACE_READ_ACL)
5015a5eeccaSmarks buf[10] = 'c';
5025a5eeccaSmarks else
5035a5eeccaSmarks buf[10] = '-';
5045a5eeccaSmarks if (mask & ACE_WRITE_ACL)
5055a5eeccaSmarks buf[11] = 'C';
5065a5eeccaSmarks else
5075a5eeccaSmarks buf[11] = '-';
5085a5eeccaSmarks if (mask & ACE_WRITE_OWNER)
5095a5eeccaSmarks buf[12] = 'o';
5105a5eeccaSmarks else
5115a5eeccaSmarks buf[12] = '-';
5125a5eeccaSmarks if (mask & ACE_SYNCHRONIZE)
5135a5eeccaSmarks buf[13] = 's';
5145a5eeccaSmarks else
5155a5eeccaSmarks buf[13] = '-';
516b249c65cSmarks buf[14] = ':';
517b249c65cSmarks buf[15] = '\0';
518b249c65cSmarks error = str_append(dstr, buf);
5195a5eeccaSmarks } else {
5205a5eeccaSmarks /*
5215a5eeccaSmarks * If ACE is a directory, but inheritance indicates its
5225a5eeccaSmarks * for a file then print permissions for file rather than
5235a5eeccaSmarks * dir.
5245a5eeccaSmarks */
5255a5eeccaSmarks if (isdir) {
5265a5eeccaSmarks if (mask & ACE_LIST_DIRECTORY) {
5275a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) {
528b249c65cSmarks error = str_append(dstr,
529b249c65cSmarks READ_DATA_TXT);
5305a5eeccaSmarks } else {
531b249c65cSmarks error =
532b249c65cSmarks str_append(dstr, READ_DIR_TXT);
5335a5eeccaSmarks }
5345a5eeccaSmarks }
535b249c65cSmarks if (error == 0 && (mask & ACE_ADD_FILE)) {
5365a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) {
537b249c65cSmarks error =
538b249c65cSmarks str_append(dstr, WRITE_DATA_TXT);
5395a5eeccaSmarks } else {
540b249c65cSmarks error =
541b249c65cSmarks str_append(dstr, ADD_FILE_TXT);
5425a5eeccaSmarks }
5435a5eeccaSmarks }
544b249c65cSmarks if (error == 0 && (mask & ACE_ADD_SUBDIRECTORY)) {
5455a5eeccaSmarks if (iflags == ACE_FILE_INHERIT_ACE) {
546b249c65cSmarks error = str_append(dstr,
547b249c65cSmarks APPEND_DATA_TXT);
5485a5eeccaSmarks } else {
549b249c65cSmarks error = str_append(dstr,
550b249c65cSmarks ADD_DIR_TXT);
5515a5eeccaSmarks }
5525a5eeccaSmarks }
5535a5eeccaSmarks } else {
5545a5eeccaSmarks if (mask & ACE_READ_DATA) {
555b249c65cSmarks error = str_append(dstr, READ_DATA_TXT);
5565a5eeccaSmarks }
557b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_DATA)) {
558b249c65cSmarks error = str_append(dstr, WRITE_DATA_TXT);
5595a5eeccaSmarks }
560b249c65cSmarks if (error == 0 && (mask & ACE_APPEND_DATA)) {
561b249c65cSmarks error = str_append(dstr, APPEND_DATA_TXT);
5625a5eeccaSmarks }
5635a5eeccaSmarks }
564b249c65cSmarks if (error == 0 && (mask & ACE_READ_NAMED_ATTRS)) {
565b249c65cSmarks error = str_append(dstr, READ_XATTR_TXT);
5665a5eeccaSmarks }
567b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_NAMED_ATTRS)) {
568b249c65cSmarks error = str_append(dstr, WRITE_XATTR_TXT);
5695a5eeccaSmarks }
570b249c65cSmarks if (error == 0 && (mask & ACE_EXECUTE)) {
571b249c65cSmarks error = str_append(dstr, EXECUTE_TXT);
5725a5eeccaSmarks }
573b249c65cSmarks if (error == 0 && (mask & ACE_DELETE_CHILD)) {
574b249c65cSmarks error = str_append(dstr, DELETE_CHILD_TXT);
5755a5eeccaSmarks }
576b249c65cSmarks if (error == 0 && (mask & ACE_READ_ATTRIBUTES)) {
577b249c65cSmarks error = str_append(dstr, READ_ATTRIBUTES_TXT);
5785a5eeccaSmarks }
579b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_ATTRIBUTES)) {
580b249c65cSmarks error = str_append(dstr, WRITE_ATTRIBUTES_TXT);
5815a5eeccaSmarks }
582b249c65cSmarks if (error == 0 && (mask & ACE_DELETE)) {
583b249c65cSmarks error = str_append(dstr, DELETE_TXT);
5845a5eeccaSmarks }
585b249c65cSmarks if (error == 0 && (mask & ACE_READ_ACL)) {
586b249c65cSmarks error = str_append(dstr, READ_ACL_TXT);
5875a5eeccaSmarks }
588b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_ACL)) {
589b249c65cSmarks error = str_append(dstr, WRITE_ACL_TXT);
5905a5eeccaSmarks }
591b249c65cSmarks if (error == 0 && (mask & ACE_WRITE_OWNER)) {
592b249c65cSmarks error = str_append(dstr, WRITE_OWNER_TXT);
5935a5eeccaSmarks }
594b249c65cSmarks if (error == 0 && (mask & ACE_SYNCHRONIZE)) {
595b249c65cSmarks error = str_append(dstr, SYNCHRONIZE_TXT);
596b249c65cSmarks }
597b249c65cSmarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') {
598b249c65cSmarks dstr->d_aclexport[--dstr->d_pos] = '\0';
599b249c65cSmarks }
600b249c65cSmarks if (error == 0)
601b249c65cSmarks error = str_append(dstr, ":");
602b249c65cSmarks }
603b249c65cSmarks return (error);
6045a5eeccaSmarks }
6055a5eeccaSmarks
606b249c65cSmarks /*
607b249c65cSmarks * compute string of access type, such as allow, deny, ...
608b249c65cSmarks */
609b249c65cSmarks static int
ace_access_txt(dynaclstr_t * dstr,int type)610b249c65cSmarks ace_access_txt(dynaclstr_t *dstr, int type)
6115a5eeccaSmarks {
612b249c65cSmarks int error;
6135a5eeccaSmarks
614b249c65cSmarks if (type == ACE_ACCESS_ALLOWED_ACE_TYPE)
615b249c65cSmarks error = str_append(dstr, ALLOW_TXT);
616b249c65cSmarks else if (type == ACE_ACCESS_DENIED_ACE_TYPE)
617b249c65cSmarks error = str_append(dstr, DENY_TXT);
618b249c65cSmarks else if (type == ACE_SYSTEM_AUDIT_ACE_TYPE)
619b249c65cSmarks error = str_append(dstr, AUDIT_TXT);
620b249c65cSmarks else if (type == ACE_SYSTEM_ALARM_ACE_TYPE)
621b249c65cSmarks error = str_append(dstr, ALARM_TXT);
622b249c65cSmarks else
623b249c65cSmarks error = str_append(dstr, UNKNOWN_TXT);
6245a5eeccaSmarks
625b249c65cSmarks return (error);
6265a5eeccaSmarks }
6275a5eeccaSmarks
628b249c65cSmarks static int
ace_inherit_txt(dynaclstr_t * dstr,uint32_t iflags,int flags)629b249c65cSmarks ace_inherit_txt(dynaclstr_t *dstr, uint32_t iflags, int flags)
6305a5eeccaSmarks {
631b249c65cSmarks int error = 0;
6325a5eeccaSmarks
6335a5eeccaSmarks if (flags & ACL_COMPACT_FMT) {
634b249c65cSmarks char buf[9];
635b249c65cSmarks
6365a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE)
6375a5eeccaSmarks buf[0] = 'f';
6385a5eeccaSmarks else
6395a5eeccaSmarks buf[0] = '-';
6405a5eeccaSmarks if (iflags & ACE_DIRECTORY_INHERIT_ACE)
6415a5eeccaSmarks buf[1] = 'd';
6425a5eeccaSmarks else
6435a5eeccaSmarks buf[1] = '-';
6445a5eeccaSmarks if (iflags & ACE_INHERIT_ONLY_ACE)
6455a5eeccaSmarks buf[2] = 'i';
6465a5eeccaSmarks else
6475a5eeccaSmarks buf[2] = '-';
6485a5eeccaSmarks if (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)
6495a5eeccaSmarks buf[3] = 'n';
6505a5eeccaSmarks else
6515a5eeccaSmarks buf[3] = '-';
6525a5eeccaSmarks if (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)
6535a5eeccaSmarks buf[4] = 'S';
6545a5eeccaSmarks else
6555a5eeccaSmarks buf[4] = '-';
6565a5eeccaSmarks if (iflags & ACE_FAILED_ACCESS_ACE_FLAG)
6575a5eeccaSmarks buf[5] = 'F';
6585a5eeccaSmarks else
6595a5eeccaSmarks buf[5] = '-';
660da6c28aaSamw if (iflags & ACE_INHERITED_ACE)
661da6c28aaSamw buf[6] = 'I';
662da6c28aaSamw else
663da6c28aaSamw buf[6] = '-';
664b249c65cSmarks buf[7] = ':';
665b249c65cSmarks buf[8] = '\0';
666b249c65cSmarks error = str_append(dstr, buf);
6675a5eeccaSmarks } else {
6685a5eeccaSmarks if (iflags & ACE_FILE_INHERIT_ACE) {
669b249c65cSmarks error = str_append(dstr, FILE_INHERIT_TXT);
6705a5eeccaSmarks }
671b249c65cSmarks if (error == 0 && (iflags & ACE_DIRECTORY_INHERIT_ACE)) {
672b249c65cSmarks error = str_append(dstr, DIR_INHERIT_TXT);
6735a5eeccaSmarks }
674b249c65cSmarks if (error == 0 && (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)) {
675b249c65cSmarks error = str_append(dstr, NO_PROPAGATE_TXT);
6765a5eeccaSmarks }
677b249c65cSmarks if (error == 0 && (iflags & ACE_INHERIT_ONLY_ACE)) {
678b249c65cSmarks error = str_append(dstr, INHERIT_ONLY_TXT);
6795a5eeccaSmarks }
680b249c65cSmarks if (error == 0 && (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)) {
681b249c65cSmarks error = str_append(dstr, SUCCESSFUL_ACCESS_TXT);
682da6c28aaSamw }
683b249c65cSmarks if (error == 0 && (iflags & ACE_FAILED_ACCESS_ACE_FLAG)) {
684b249c65cSmarks error = str_append(dstr, FAILED_ACCESS_TXT);
685da6c28aaSamw }
686b249c65cSmarks if (error == 0 && (iflags & ACE_INHERITED_ACE)) {
687b249c65cSmarks error = str_append(dstr, INHERITED_ACE_TXT);
688b249c65cSmarks }
689b249c65cSmarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') {
690b249c65cSmarks dstr->d_aclexport[--dstr->d_pos] = '\0';
691b249c65cSmarks error = str_append(dstr, ":");
692b249c65cSmarks }
693da6c28aaSamw }
6945a5eeccaSmarks
695b249c65cSmarks return (error);
696fa9e4066Sahrens }
6977c478bd9Sstevel@tonic-gate
6987c478bd9Sstevel@tonic-gate /*
6997c478bd9Sstevel@tonic-gate * Convert internal acl representation to external representation.
7007c478bd9Sstevel@tonic-gate *
7017c478bd9Sstevel@tonic-gate * The length of a non-owning user name or non-owning group name ie entries
7027c478bd9Sstevel@tonic-gate * of type DEF_USER, USER, DEF_GROUP or GROUP, can exceed LOGNAME_MAX. We
7037c478bd9Sstevel@tonic-gate * thus check the length of these entries, and if greater than LOGNAME_MAX,
7047c478bd9Sstevel@tonic-gate * we realloc() via increase_length().
7057c478bd9Sstevel@tonic-gate *
7067c478bd9Sstevel@tonic-gate * The LOGNAME_MAX, ENTRYTYPELEN and PERMS limits are otherwise always
7077c478bd9Sstevel@tonic-gate * adhered to.
7087c478bd9Sstevel@tonic-gate */
7095a5eeccaSmarks
7105a5eeccaSmarks /*
7115a5eeccaSmarks * acltotext() converts each ACL entry to look like this:
7125a5eeccaSmarks *
7135a5eeccaSmarks * entry_type:uid^gid^name:perms[:id]
7145a5eeccaSmarks *
7155a5eeccaSmarks * The maximum length of entry_type is 14 ("defaultgroup::" and
7165a5eeccaSmarks * "defaultother::") hence ENTRYTYPELEN is set to 14.
7175a5eeccaSmarks *
7185a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8, hence we use,
7195a5eeccaSmarks * however the ID could be a number so we therefore use ID_STR_MAX
7205a5eeccaSmarks *
7215a5eeccaSmarks * The length of a perms entry is 4 to allow for the comma appended to each
7225a5eeccaSmarks * to each acl entry. Hence PERMS is set to 4.
7235a5eeccaSmarks */
7245a5eeccaSmarks
7255a5eeccaSmarks #define ENTRYTYPELEN 14
7265a5eeccaSmarks #define PERMS 4
7275a5eeccaSmarks #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX)
7285a5eeccaSmarks
7297c478bd9Sstevel@tonic-gate char *
aclent_acltotext(aclent_t * aclp,int aclcnt,int flags)7305a5eeccaSmarks aclent_acltotext(aclent_t *aclp, int aclcnt, int flags)
7317c478bd9Sstevel@tonic-gate {
732b249c65cSmarks dynaclstr_t *dstr;
733909c9a9fSMark Shellenbaum char *aclexport = NULL;
734b249c65cSmarks int i;
735b249c65cSmarks int error = 0;
7367c478bd9Sstevel@tonic-gate
7377c478bd9Sstevel@tonic-gate if (aclp == NULL)
7387c478bd9Sstevel@tonic-gate return (NULL);
739b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
7407c478bd9Sstevel@tonic-gate return (NULL);
741b249c65cSmarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE;
742b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
7437c478bd9Sstevel@tonic-gate free(dstr);
7447c478bd9Sstevel@tonic-gate return (NULL);
7457c478bd9Sstevel@tonic-gate }
746b249c65cSmarks *dstr->d_aclexport = '\0';
747b249c65cSmarks dstr->d_pos = 0;
7487c478bd9Sstevel@tonic-gate
7497c478bd9Sstevel@tonic-gate for (i = 0; i < aclcnt; i++, aclp++) {
750b249c65cSmarks if (error = aclent_type_txt(dstr, aclp, flags))
7517c478bd9Sstevel@tonic-gate break;
752b249c65cSmarks if (error = aclent_perm_txt(dstr, aclp->a_perm))
7537c478bd9Sstevel@tonic-gate break;
7545a5eeccaSmarks
7555a5eeccaSmarks if ((flags & ACL_APPEND_ID) && ((aclp->a_type == USER) ||
7565a5eeccaSmarks (aclp->a_type == DEF_USER) || (aclp->a_type == GROUP) ||
7575a5eeccaSmarks (aclp->a_type == DEF_GROUP))) {
758b249c65cSmarks char id[ID_STR_MAX], *idstr;
759b249c65cSmarks
760b249c65cSmarks if (error = str_append(dstr, ":"))
761b249c65cSmarks break;
7625a5eeccaSmarks id[ID_STR_MAX - 1] = '\0'; /* null terminate buffer */
7635a5eeccaSmarks idstr = lltostr(aclp->a_id, &id[ID_STR_MAX - 1]);
764b249c65cSmarks if (error = str_append(dstr, idstr))
765b249c65cSmarks break;
7665a5eeccaSmarks }
7677c478bd9Sstevel@tonic-gate if (i < aclcnt - 1)
768b249c65cSmarks if (error = str_append(dstr, ","))
769b249c65cSmarks break;
7707c478bd9Sstevel@tonic-gate }
771b249c65cSmarks if (error) {
772b249c65cSmarks if (dstr->d_aclexport)
773b249c65cSmarks free(dstr->d_aclexport);
774b249c65cSmarks } else {
775b249c65cSmarks aclexport = dstr->d_aclexport;
776b249c65cSmarks }
7777c478bd9Sstevel@tonic-gate free(dstr);
7787c478bd9Sstevel@tonic-gate return (aclexport);
7797c478bd9Sstevel@tonic-gate }
7807c478bd9Sstevel@tonic-gate
7815a5eeccaSmarks char *
acltotext(aclent_t * aclp,int aclcnt)7825a5eeccaSmarks acltotext(aclent_t *aclp, int aclcnt)
7837c478bd9Sstevel@tonic-gate {
7845a5eeccaSmarks return (aclent_acltotext(aclp, aclcnt, 0));
785fa9e4066Sahrens }
786fa9e4066Sahrens
7877c478bd9Sstevel@tonic-gate
788fa9e4066Sahrens aclent_t *
aclfromtext(char * aclstr,int * aclcnt)789fa9e4066Sahrens aclfromtext(char *aclstr, int *aclcnt)
790fa9e4066Sahrens {
791fa9e4066Sahrens acl_t *aclp;
792fa9e4066Sahrens aclent_t *aclentp;
793fa9e4066Sahrens int error;
794fa9e4066Sahrens
7955a5eeccaSmarks error = acl_fromtext(aclstr, &aclp);
796fa9e4066Sahrens if (error)
797fa9e4066Sahrens return (NULL);
798fa9e4066Sahrens
799fa9e4066Sahrens aclentp = aclp->acl_aclp;
800fa9e4066Sahrens aclp->acl_aclp = NULL;
801fa9e4066Sahrens *aclcnt = aclp->acl_cnt;
8025a5eeccaSmarks
8035a5eeccaSmarks acl_free(aclp);
804fa9e4066Sahrens return (aclentp);
805fa9e4066Sahrens }
806fa9e4066Sahrens
807fa9e4066Sahrens
8087c478bd9Sstevel@tonic-gate /*
809909c9a9fSMark Shellenbaum * Append string onto dynaclstr_t.
810909c9a9fSMark Shellenbaum *
811909c9a9fSMark Shellenbaum * Return 0 on success, 1 for failure.
8127c478bd9Sstevel@tonic-gate */
8137c478bd9Sstevel@tonic-gate static int
str_append(dynaclstr_t * dstr,char * newstr)814b249c65cSmarks str_append(dynaclstr_t *dstr, char *newstr)
8157c478bd9Sstevel@tonic-gate {
816b249c65cSmarks size_t len = strlen(newstr);
8177c478bd9Sstevel@tonic-gate
818b249c65cSmarks if ((len + dstr->d_pos) >= dstr->d_bufsize) {
819b249c65cSmarks dstr->d_aclexport = realloc(dstr->d_aclexport,
820b249c65cSmarks dstr->d_bufsize + len + 1);
821b249c65cSmarks if (dstr->d_aclexport == NULL)
8227c478bd9Sstevel@tonic-gate return (1);
823b249c65cSmarks dstr->d_bufsize += len;
824b249c65cSmarks }
825b249c65cSmarks (void) strcat(&dstr->d_aclexport[dstr->d_pos], newstr);
826b249c65cSmarks dstr->d_pos += len;
8277c478bd9Sstevel@tonic-gate return (0);
8287c478bd9Sstevel@tonic-gate }
829fa9e4066Sahrens
830b249c65cSmarks static int
aclent_perm_txt(dynaclstr_t * dstr,o_mode_t perm)831b249c65cSmarks aclent_perm_txt(dynaclstr_t *dstr, o_mode_t perm)
832b249c65cSmarks {
833b249c65cSmarks char buf[4];
834b249c65cSmarks
835b249c65cSmarks if (perm & S_IROTH)
836b249c65cSmarks buf[0] = 'r';
837b249c65cSmarks else
838b249c65cSmarks buf[0] = '-';
839b249c65cSmarks if (perm & S_IWOTH)
840b249c65cSmarks buf[1] = 'w';
841b249c65cSmarks else
842b249c65cSmarks buf[1] = '-';
843b249c65cSmarks if (perm & S_IXOTH)
844b249c65cSmarks buf[2] = 'x';
845b249c65cSmarks else
846b249c65cSmarks buf[2] = '-';
847b249c65cSmarks buf[3] = '\0';
848b249c65cSmarks return (str_append(dstr, buf));
849b249c65cSmarks }
850b249c65cSmarks
851fa9e4066Sahrens /*
8525a5eeccaSmarks * ace_acltotext() convert each ace formatted acl to look like this:
853fa9e4066Sahrens *
8545a5eeccaSmarks * entry_type:uid^gid^name:perms[:flags]:<allow|deny>[:id][,]
855fa9e4066Sahrens *
856fa9e4066Sahrens * The maximum length of entry_type is 5 ("group")
857fa9e4066Sahrens *
8585a5eeccaSmarks * The max length of a uid^gid^name entry (in theory) is 8,
8595a5eeccaSmarks * however id could be a number so we therefore use ID_STR_MAX
860fa9e4066Sahrens *
861fa9e4066Sahrens * The length of a perms entry is 144 i.e read_data/write_data...
862fa9e4066Sahrens * to each acl entry.
863fa9e4066Sahrens *
864da6c28aaSamw * iflags: file_inherit/dir_inherit/inherit_only/no_propagate/successful_access
865da6c28aaSamw * /failed_access
866fa9e4066Sahrens *
867fa9e4066Sahrens */
868fa9e4066Sahrens
869fa9e4066Sahrens #define ACE_ENTRYTYPLEN 6
870da6c28aaSamw #define IFLAGS_STR "file_inherit/dir_inherit/inherit_only/no_propagate/" \
871da6c28aaSamw "successful_access/failed_access/inherited"
872da6c28aaSamw #define IFLAGS_SIZE (sizeof (IFLAGS_STR) - 1)
8735a5eeccaSmarks #define ACCESS_TYPE_SIZE 7 /* if unknown */
874fa9e4066Sahrens #define COLON_CNT 3
875fa9e4066Sahrens #define PERMS_LEN 216
8765a5eeccaSmarks #define ACE_ENTRY_SIZE (ACE_ENTRYTYPLEN + ID_STR_MAX + PERMS_LEN + \
8775a5eeccaSmarks ACCESS_TYPE_SIZE + IFLAGS_SIZE + COLON_CNT + APPENDED_ID_MAX)
878fa9e4066Sahrens
879fa9e4066Sahrens static char *
ace_acltotext(acl_t * aceaclp,int flags)8805a5eeccaSmarks ace_acltotext(acl_t *aceaclp, int flags)
881fa9e4066Sahrens {
882fa9e4066Sahrens ace_t *aclp = aceaclp->acl_aclp;
883fa9e4066Sahrens int aclcnt = aceaclp->acl_cnt;
8845a5eeccaSmarks int i;
885b249c65cSmarks int error = 0;
886fa9e4066Sahrens int isdir = (aceaclp->acl_flags & ACL_IS_DIR);
887b249c65cSmarks dynaclstr_t *dstr;
888909c9a9fSMark Shellenbaum char *aclexport = NULL;
8899a2c8b2bSGowtham Thommandra char *rawsidp = NULL;
890fa9e4066Sahrens
891fa9e4066Sahrens if (aclp == NULL)
892fa9e4066Sahrens return (NULL);
893fa9e4066Sahrens
894b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
895b249c65cSmarks return (NULL);
896b249c65cSmarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE;
897b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
898b249c65cSmarks free(dstr);
899b249c65cSmarks return (NULL);
900b249c65cSmarks }
901b249c65cSmarks *dstr->d_aclexport = '\0';
902b249c65cSmarks dstr->d_pos = 0;
903b249c65cSmarks
904fa9e4066Sahrens for (i = 0; i < aclcnt; i++, aclp++) {
905fa9e4066Sahrens
906b249c65cSmarks if (error = ace_type_txt(dstr, aclp, flags))
907b249c65cSmarks break;
908b249c65cSmarks if (error = ace_perm_txt(dstr, aclp->a_access_mask,
909b249c65cSmarks aclp->a_flags, isdir, flags))
910b249c65cSmarks break;
911b249c65cSmarks if (error = ace_inherit_txt(dstr, aclp->a_flags, flags))
912b249c65cSmarks break;
913b249c65cSmarks if (error = ace_access_txt(dstr, aclp->a_type))
914b249c65cSmarks break;
915fa9e4066Sahrens
9165a5eeccaSmarks if ((flags & ACL_APPEND_ID) &&
9175a5eeccaSmarks (((aclp->a_flags & ACE_TYPE_FLAGS) == 0) ||
9185a5eeccaSmarks ((aclp->a_flags & ACE_TYPE_FLAGS) ==
9195a5eeccaSmarks ACE_IDENTIFIER_GROUP))) {
920b249c65cSmarks char id[ID_STR_MAX], *idstr;
921b249c65cSmarks
922b249c65cSmarks if (error = str_append(dstr, ":"))
923b249c65cSmarks break;
9245f41bf46SMark Shellenbaum
9255f41bf46SMark Shellenbaum rawsidp = NULL;
9265f41bf46SMark Shellenbaum id[ID_STR_MAX -1] = '\0'; /* null terminate */
9275f41bf46SMark Shellenbaum if (aclp->a_who > MAXUID && (flags & ACL_SID_FMT)) {
9285f41bf46SMark Shellenbaum
9295f41bf46SMark Shellenbaum error = getsidname(aclp->a_who,
9305f41bf46SMark Shellenbaum ((aclp->a_flags & ACE_TYPE_FLAGS) == 0) ?
9315f41bf46SMark Shellenbaum B_TRUE : B_FALSE, &idstr, 1);
9329a2c8b2bSGowtham Thommandra rawsidp = idstr;
9335f41bf46SMark Shellenbaum if (error)
9345f41bf46SMark Shellenbaum break;
9355f41bf46SMark Shellenbaum } else if (aclp->a_who > MAXUID &&
9365f41bf46SMark Shellenbaum !(flags & ACL_NORESOLVE)) {
9375f41bf46SMark Shellenbaum idstr = lltostr(UID_NOBODY,
9385f41bf46SMark Shellenbaum &id[ID_STR_MAX - 1]);
9395f41bf46SMark Shellenbaum } else {
9405f41bf46SMark Shellenbaum idstr = lltostr(aclp->a_who,
9415f41bf46SMark Shellenbaum &id[ID_STR_MAX - 1]);
9425f41bf46SMark Shellenbaum }
943b249c65cSmarks if (error = str_append(dstr, idstr))
944b249c65cSmarks break;
9459a2c8b2bSGowtham Thommandra if (rawsidp) {
9465f41bf46SMark Shellenbaum free(rawsidp);
9479a2c8b2bSGowtham Thommandra rawsidp = NULL;
9489a2c8b2bSGowtham Thommandra }
9495a5eeccaSmarks }
9505a5eeccaSmarks if (i < aclcnt - 1) {
951b249c65cSmarks if (error = str_append(dstr, ","))
952b249c65cSmarks break;
953fa9e4066Sahrens }
954fa9e4066Sahrens }
9559a2c8b2bSGowtham Thommandra
9569a2c8b2bSGowtham Thommandra if (rawsidp)
9579a2c8b2bSGowtham Thommandra free(rawsidp);
958b249c65cSmarks if (error) {
959b249c65cSmarks if (dstr->d_aclexport)
960b249c65cSmarks free(dstr->d_aclexport);
961b249c65cSmarks } else {
962b249c65cSmarks aclexport = dstr->d_aclexport;
963b249c65cSmarks }
964b249c65cSmarks free(dstr);
965fa9e4066Sahrens return (aclexport);
966fa9e4066Sahrens }
967fa9e4066Sahrens
9685a5eeccaSmarks char *
acl_totext(acl_t * aclp,int flags)9695a5eeccaSmarks acl_totext(acl_t *aclp, int flags)
970fa9e4066Sahrens {
9715a5eeccaSmarks char *txtp;
972fa9e4066Sahrens
973fa9e4066Sahrens if (aclp == NULL)
974fa9e4066Sahrens return (NULL);
975fa9e4066Sahrens
976fa9e4066Sahrens switch (aclp->acl_type) {
977fa9e4066Sahrens case ACE_T:
9785a5eeccaSmarks txtp = ace_acltotext(aclp, flags);
9795a5eeccaSmarks break;
980fa9e4066Sahrens case ACLENT_T:
9815a5eeccaSmarks txtp = aclent_acltotext(aclp->acl_aclp, aclp->acl_cnt, flags);
9825a5eeccaSmarks break;
983fa9e4066Sahrens }
9845a5eeccaSmarks
9855a5eeccaSmarks return (txtp);
986fa9e4066Sahrens }
987fa9e4066Sahrens
988fa9e4066Sahrens int
acl_fromtext(const char * acltextp,acl_t ** ret_aclp)989fa9e4066Sahrens acl_fromtext(const char *acltextp, acl_t **ret_aclp)
990fa9e4066Sahrens {
9915a5eeccaSmarks int error;
9925a5eeccaSmarks char *buf;
9935a5eeccaSmarks
9945a5eeccaSmarks buf = malloc(strlen(acltextp) + 2);
9955a5eeccaSmarks if (buf == NULL)
9965a5eeccaSmarks return (EACL_MEM_ERROR);
9975a5eeccaSmarks strcpy(buf, acltextp);
9985a5eeccaSmarks strcat(buf, "\n");
9999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
10009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_lock(&yymutex);
10015a5eeccaSmarks yybuf = buf;
10025a5eeccaSmarks yyreset();
10035a5eeccaSmarks error = yyparse();
10045a5eeccaSmarks free(buf);
10055a5eeccaSmarks
10065a5eeccaSmarks if (yyacl) {
10075a5eeccaSmarks if (error == 0)
10085a5eeccaSmarks *ret_aclp = yyacl;
10095a5eeccaSmarks else {
10105a5eeccaSmarks acl_free(yyacl);
10115a5eeccaSmarks }
10125a5eeccaSmarks yyacl = NULL;
10135a5eeccaSmarks }
10149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) mutex_unlock(&yymutex);
10159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
10165a5eeccaSmarks return (error);
10175a5eeccaSmarks }
10185a5eeccaSmarks
10195a5eeccaSmarks int
acl_parse(const char * acltextp,acl_t ** aclp)10205a5eeccaSmarks acl_parse(const char *acltextp, acl_t **aclp)
10215a5eeccaSmarks {
1022fa9e4066Sahrens int error;
1023fa9e4066Sahrens
10245a5eeccaSmarks yyinteractive = 1;
10255a5eeccaSmarks error = acl_fromtext(acltextp, aclp);
10265a5eeccaSmarks yyinteractive = 0;
1027fa9e4066Sahrens return (error);
1028fa9e4066Sahrens }
10295a5eeccaSmarks
10305a5eeccaSmarks static void
ace_compact_printacl(acl_t * aclp)10315a5eeccaSmarks ace_compact_printacl(acl_t *aclp)
10325a5eeccaSmarks {
10335a5eeccaSmarks int cnt;
10345a5eeccaSmarks ace_t *acep;
1035b249c65cSmarks dynaclstr_t *dstr;
1036b249c65cSmarks int len;
10375a5eeccaSmarks
1038b249c65cSmarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
1039b249c65cSmarks return;
1040b249c65cSmarks dstr->d_bufsize = ACE_ENTRY_SIZE;
1041b249c65cSmarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
1042b249c65cSmarks free(dstr);
1043b249c65cSmarks return;
1044b249c65cSmarks }
1045b249c65cSmarks *dstr->d_aclexport = '\0';
1046b249c65cSmarks
1047b249c65cSmarks dstr->d_pos = 0;
10485a5eeccaSmarks for (cnt = 0, acep = aclp->acl_aclp;
10495a5eeccaSmarks cnt != aclp->acl_cnt; cnt++, acep++) {
1050b249c65cSmarks dstr->d_aclexport[0] = '\0';
1051b249c65cSmarks dstr->d_pos = 0;
1052b249c65cSmarks
1053b249c65cSmarks if (ace_type_txt(dstr, acep, 0))
1054b249c65cSmarks break;
1055b249c65cSmarks len = strlen(&dstr->d_aclexport[0]);
1056b249c65cSmarks if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags,
1057b249c65cSmarks aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT))
1058b249c65cSmarks break;
1059b249c65cSmarks if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT))
1060b249c65cSmarks break;
1061b249c65cSmarks if (ace_access_txt(dstr, acep->a_type) == -1)
1062b249c65cSmarks break;
1063b249c65cSmarks (void) printf(" %20.*s%s\n", len, dstr->d_aclexport,
1064b249c65cSmarks &dstr->d_aclexport[len]);
10655a5eeccaSmarks }
1066b249c65cSmarks
1067b249c65cSmarks if (dstr->d_aclexport)
1068b249c65cSmarks free(dstr->d_aclexport);
1069b249c65cSmarks free(dstr);
10705a5eeccaSmarks }
10715a5eeccaSmarks
10725a5eeccaSmarks static void
ace_printacl(acl_t * aclp,int cols,int compact)10735a5eeccaSmarks ace_printacl(acl_t *aclp, int cols, int compact)
10745a5eeccaSmarks {
10755a5eeccaSmarks int slot = 0;
10765a5eeccaSmarks char *token;
10775a5eeccaSmarks char *acltext;
10785a5eeccaSmarks
10795a5eeccaSmarks if (compact) {
10805a5eeccaSmarks ace_compact_printacl(aclp);
10815a5eeccaSmarks return;
10825a5eeccaSmarks }
10835a5eeccaSmarks
10845a5eeccaSmarks acltext = acl_totext(aclp, 0);
10855a5eeccaSmarks
10865a5eeccaSmarks if (acltext == NULL)
10875a5eeccaSmarks return;
10885a5eeccaSmarks
10895a5eeccaSmarks token = strtok(acltext, ",");
10905a5eeccaSmarks if (token == NULL) {
10915a5eeccaSmarks free(acltext);
10925a5eeccaSmarks return;
10935a5eeccaSmarks }
10945a5eeccaSmarks
10955a5eeccaSmarks do {
10965a5eeccaSmarks (void) printf(" %d:", slot++);
10975a5eeccaSmarks split_line(token, cols - 5);
10985a5eeccaSmarks } while (token = strtok(NULL, ","));
10995a5eeccaSmarks free(acltext);
11005a5eeccaSmarks }
11015a5eeccaSmarks
11025a5eeccaSmarks /*
11035a5eeccaSmarks * pretty print an ACL.
11045a5eeccaSmarks * For aclent_t ACL's the format is
11055a5eeccaSmarks * similar to the old format used by getfacl,
11065a5eeccaSmarks * with the addition of adding a "slot" number
11075a5eeccaSmarks * before each entry.
11085a5eeccaSmarks *
11095a5eeccaSmarks * for ace_t ACL's the cols variable will break up
11105a5eeccaSmarks * the long lines into multiple lines and will also
11115a5eeccaSmarks * print a "slot" number.
11125a5eeccaSmarks */
11135a5eeccaSmarks void
acl_printacl(acl_t * aclp,int cols,int compact)11145a5eeccaSmarks acl_printacl(acl_t *aclp, int cols, int compact)
11155a5eeccaSmarks {
11165a5eeccaSmarks
11175a5eeccaSmarks switch (aclp->acl_type) {
11185a5eeccaSmarks case ACLENT_T:
11195a5eeccaSmarks aclent_printacl(aclp);
11205a5eeccaSmarks break;
11215a5eeccaSmarks case ACE_T:
11225a5eeccaSmarks ace_printacl(aclp, cols, compact);
11235a5eeccaSmarks break;
11245a5eeccaSmarks }
11255a5eeccaSmarks }
11265a5eeccaSmarks
11275a5eeccaSmarks typedef struct value_table {
11285a5eeccaSmarks char p_letter; /* perm letter such as 'r' */
11295a5eeccaSmarks uint32_t p_value; /* value for perm when pletter found */
11305a5eeccaSmarks } value_table_t;
11315a5eeccaSmarks
11325a5eeccaSmarks /*
1133da6c28aaSamw * The permission tables are laid out in positional order
11345a5eeccaSmarks * a '-' character will indicate a permission at a given
11355a5eeccaSmarks * position is not specified. The '-' is not part of the
11365a5eeccaSmarks * table, but will be checked for in the permission computation
11375a5eeccaSmarks * routine.
11385a5eeccaSmarks */
1139da6c28aaSamw value_table_t ace_perm_table[] = {
11405a5eeccaSmarks { 'r', ACE_READ_DATA},
11415a5eeccaSmarks { 'w', ACE_WRITE_DATA},
11425a5eeccaSmarks { 'x', ACE_EXECUTE},
11435a5eeccaSmarks { 'p', ACE_APPEND_DATA},
11445a5eeccaSmarks { 'd', ACE_DELETE},
11455a5eeccaSmarks { 'D', ACE_DELETE_CHILD},
11465a5eeccaSmarks { 'a', ACE_READ_ATTRIBUTES},
11475a5eeccaSmarks { 'A', ACE_WRITE_ATTRIBUTES},
11485a5eeccaSmarks { 'R', ACE_READ_NAMED_ATTRS},
11495a5eeccaSmarks { 'W', ACE_WRITE_NAMED_ATTRS},
11505a5eeccaSmarks { 'c', ACE_READ_ACL},
11515a5eeccaSmarks { 'C', ACE_WRITE_ACL},
11525a5eeccaSmarks { 'o', ACE_WRITE_OWNER},
11535a5eeccaSmarks { 's', ACE_SYNCHRONIZE}
11545a5eeccaSmarks };
11555a5eeccaSmarks
1156da6c28aaSamw #define ACE_PERM_COUNT (sizeof (ace_perm_table) / sizeof (value_table_t))
11575a5eeccaSmarks
1158da6c28aaSamw value_table_t aclent_perm_table[] = {
11595a5eeccaSmarks { 'r', S_IROTH},
11605a5eeccaSmarks { 'w', S_IWOTH},
11615a5eeccaSmarks { 'x', S_IXOTH}
11625a5eeccaSmarks };
11635a5eeccaSmarks
1164da6c28aaSamw #define ACLENT_PERM_COUNT (sizeof (aclent_perm_table) / sizeof (value_table_t))
1165da6c28aaSamw
1166da6c28aaSamw value_table_t inherit_table[] = {
11675a5eeccaSmarks {'f', ACE_FILE_INHERIT_ACE},
11685a5eeccaSmarks {'d', ACE_DIRECTORY_INHERIT_ACE},
11695a5eeccaSmarks {'i', ACE_INHERIT_ONLY_ACE},
11705a5eeccaSmarks {'n', ACE_NO_PROPAGATE_INHERIT_ACE},
11715a5eeccaSmarks {'S', ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
1172da6c28aaSamw {'F', ACE_FAILED_ACCESS_ACE_FLAG},
1173da6c28aaSamw {'I', ACE_INHERITED_ACE}
11745a5eeccaSmarks };
11755a5eeccaSmarks
1176da6c28aaSamw #define IFLAG_COUNT (sizeof (inherit_table) / sizeof (value_table_t))
1177bf8b6031Smarks #define IFLAG_COUNT_V1 6 /* Older version compatibility */
1178da6c28aaSamw
11795a5eeccaSmarks /*
11805a5eeccaSmarks * compute value from a permission table or inheritance table
11815a5eeccaSmarks * based on string passed in. If positional is set then
11825a5eeccaSmarks * string must match order in permtab, otherwise any order
11835a5eeccaSmarks * is allowed.
11845a5eeccaSmarks */
11855a5eeccaSmarks int
compute_values(value_table_t * permtab,int count,char * permstr,int positional,uint32_t * mask)11865a5eeccaSmarks compute_values(value_table_t *permtab, int count,
11875a5eeccaSmarks char *permstr, int positional, uint32_t *mask)
11885a5eeccaSmarks {
11895a5eeccaSmarks uint32_t perm_val = 0;
11905a5eeccaSmarks char *pstr;
11915a5eeccaSmarks int i, found;
11925a5eeccaSmarks
11935a5eeccaSmarks if (count < 0)
11945a5eeccaSmarks return (1);
11955a5eeccaSmarks
11965a5eeccaSmarks if (positional) {
11975a5eeccaSmarks for (i = 0, pstr = permstr; i != count && pstr &&
11985a5eeccaSmarks *pstr; i++, pstr++) {
11995a5eeccaSmarks if (*pstr == permtab[i].p_letter) {
12005a5eeccaSmarks perm_val |= permtab[i].p_value;
12015a5eeccaSmarks } else if (*pstr != '-') {
12025a5eeccaSmarks return (1);
12035a5eeccaSmarks }
12045a5eeccaSmarks }
12055a5eeccaSmarks } else { /* random order single letters with no '-' */
12065a5eeccaSmarks for (pstr = permstr; pstr && *pstr; pstr++) {
12075a5eeccaSmarks for (found = 0, i = 0; i != count; i++) {
12085a5eeccaSmarks if (*pstr == permtab[i].p_letter) {
12095a5eeccaSmarks perm_val |= permtab[i].p_value;
12105a5eeccaSmarks found = 1;
12115a5eeccaSmarks break;
12125a5eeccaSmarks }
12135a5eeccaSmarks }
12145a5eeccaSmarks if (found == 0)
12155a5eeccaSmarks return (1);
12165a5eeccaSmarks }
12175a5eeccaSmarks }
12185a5eeccaSmarks
12195a5eeccaSmarks *mask = perm_val;
12205a5eeccaSmarks return (0);
12215a5eeccaSmarks }
12225a5eeccaSmarks
1223bf8b6031Smarks
1224bf8b6031Smarks int
ace_inherit_helper(char * str,uint32_t * imask,int table_length)1225bf8b6031Smarks ace_inherit_helper(char *str, uint32_t *imask, int table_length)
1226bf8b6031Smarks {
1227bf8b6031Smarks int rc = 0;
1228bf8b6031Smarks
1229bf8b6031Smarks if (strlen(str) == table_length) {
1230bf8b6031Smarks /*
1231bf8b6031Smarks * If the string == table_length then first check to see it's
1232bf8b6031Smarks * in positional format. If that fails then see if it's in
1233bf8b6031Smarks * non-positional format.
1234bf8b6031Smarks */
1235bf8b6031Smarks if (compute_values(inherit_table, table_length, str,
1236bf8b6031Smarks 1, imask) && compute_values(inherit_table,
1237bf8b6031Smarks table_length, str, 0, imask)) {
1238bf8b6031Smarks rc = 1;
1239bf8b6031Smarks }
1240bf8b6031Smarks } else {
1241bf8b6031Smarks rc = compute_values(inherit_table, table_length, str, 0, imask);
1242bf8b6031Smarks }
1243bf8b6031Smarks
1244bf8b6031Smarks return (rc ? EACL_INHERIT_ERROR : 0);
1245bf8b6031Smarks }
1246bf8b6031Smarks
12475a5eeccaSmarks /*
12485a5eeccaSmarks * compute value for inheritance flags.
12495a5eeccaSmarks */
12505a5eeccaSmarks int
compute_ace_inherit(char * str,uint32_t * imask)12515a5eeccaSmarks compute_ace_inherit(char *str, uint32_t *imask)
12525a5eeccaSmarks {
1253bf8b6031Smarks int rc = 0;
12545a5eeccaSmarks
1255bf8b6031Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT);
12565a5eeccaSmarks
1257bf8b6031Smarks if (rc && strlen(str) != IFLAG_COUNT) {
12585a5eeccaSmarks
1259bf8b6031Smarks /* is it an old formatted inherit string? */
1260bf8b6031Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT_V1);
1261bf8b6031Smarks }
12625a5eeccaSmarks
1263bf8b6031Smarks return (rc);
12645a5eeccaSmarks }
12655a5eeccaSmarks
12665a5eeccaSmarks
12675a5eeccaSmarks /*
12685a5eeccaSmarks * compute value for ACE permissions.
12695a5eeccaSmarks */
12705a5eeccaSmarks int
compute_ace_perms(char * str,uint32_t * mask)12715a5eeccaSmarks compute_ace_perms(char *str, uint32_t *mask)
12725a5eeccaSmarks {
12735a5eeccaSmarks int positional = 0;
12745a5eeccaSmarks int error;
12755a5eeccaSmarks
12765a5eeccaSmarks if (strlen(str) == ACE_PERM_COUNT)
12775a5eeccaSmarks positional = 1;
12785a5eeccaSmarks
12795a5eeccaSmarks error = compute_values(ace_perm_table, ACE_PERM_COUNT,
12805a5eeccaSmarks str, positional, mask);
12815a5eeccaSmarks
12825a5eeccaSmarks if (error && positional) {
12835a5eeccaSmarks /*
12845a5eeccaSmarks * If positional was set, then make sure permissions
12855a5eeccaSmarks * aren't actually valid in non positional case where
12865a5eeccaSmarks * all permissions are specified, just in random order.
12875a5eeccaSmarks */
12885a5eeccaSmarks error = compute_values(ace_perm_table,
12895a5eeccaSmarks ACE_PERM_COUNT, str, 0, mask);
12905a5eeccaSmarks }
12915a5eeccaSmarks if (error)
12925a5eeccaSmarks error = EACL_PERM_MASK_ERROR;
12935a5eeccaSmarks
12945a5eeccaSmarks return (error);
12955a5eeccaSmarks }
12965a5eeccaSmarks
12975a5eeccaSmarks
12985a5eeccaSmarks
12995a5eeccaSmarks /*
13005a5eeccaSmarks * compute values for aclent permissions.
13015a5eeccaSmarks */
13025a5eeccaSmarks int
compute_aclent_perms(char * str,o_mode_t * mask)13035a5eeccaSmarks compute_aclent_perms(char *str, o_mode_t *mask)
13045a5eeccaSmarks {
13055a5eeccaSmarks int error;
13065a5eeccaSmarks uint32_t pmask;
13075a5eeccaSmarks
13085a5eeccaSmarks if (strlen(str) != ACLENT_PERM_COUNT)
13095a5eeccaSmarks return (EACL_PERM_MASK_ERROR);
13105a5eeccaSmarks
13115a5eeccaSmarks *mask = 0;
13125a5eeccaSmarks error = compute_values(aclent_perm_table, ACLENT_PERM_COUNT,
13135a5eeccaSmarks str, 1, &pmask);
13145a5eeccaSmarks if (error == 0) {
13155a5eeccaSmarks *mask = (o_mode_t)pmask;
13165a5eeccaSmarks } else
13175a5eeccaSmarks error = EACL_PERM_MASK_ERROR;
13185a5eeccaSmarks return (error);
13195a5eeccaSmarks }
13205a5eeccaSmarks
13215a5eeccaSmarks /*
13225a5eeccaSmarks * determine ACE permissions.
13235a5eeccaSmarks */
13245a5eeccaSmarks int
ace_perm_mask(struct acl_perm_type * aclperm,uint32_t * mask)13255a5eeccaSmarks ace_perm_mask(struct acl_perm_type *aclperm, uint32_t *mask)
13265a5eeccaSmarks {
13275a5eeccaSmarks int error;
13285a5eeccaSmarks
13295a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_EMPTY) {
13305a5eeccaSmarks *mask = 0;
13315a5eeccaSmarks return (0);
13325a5eeccaSmarks }
13335a5eeccaSmarks
13345a5eeccaSmarks if (aclperm->perm_style == PERM_TYPE_ACE) {
13355a5eeccaSmarks *mask = aclperm->perm_val;
13365a5eeccaSmarks return (0);
13375a5eeccaSmarks }
13385a5eeccaSmarks
13395a5eeccaSmarks error = compute_ace_perms(aclperm->perm_str, mask);
13405a5eeccaSmarks if (error) {
13415b233e2dSmarks acl_error(dgettext(TEXT_DOMAIN,
13425b233e2dSmarks "Invalid permission(s) '%s' specified\n"),
13435a5eeccaSmarks aclperm->perm_str);
13445a5eeccaSmarks return (EACL_PERM_MASK_ERROR);
13455a5eeccaSmarks }
13465a5eeccaSmarks
13475a5eeccaSmarks return (0);
13485a5eeccaSmarks }
1349