10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51507Sgjelinek * Common Development and Distribution License (the "License").
61507Sgjelinek * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12914SJoyce.McIntosh@Sun.COM * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate /*LINTLIBRARY*/
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include <grp.h>
280Sstevel@tonic-gate #include <pwd.h>
290Sstevel@tonic-gate #include <string.h>
300Sstevel@tonic-gate #include <limits.h>
310Sstevel@tonic-gate #include <stdlib.h>
32789Sahrens #include <errno.h>
330Sstevel@tonic-gate #include <sys/param.h>
340Sstevel@tonic-gate #include <sys/types.h>
351420Smarks #include <sys/stat.h>
360Sstevel@tonic-gate #include <sys/acl.h>
37789Sahrens #include <aclutils.h>
387057Smarks #include <idmap.h>
3911963SAfshin.Ardakani@Sun.COM #include <synch.h>
401420Smarks
411420Smarks #define ID_STR_MAX 20 /* digits in LONG_MAX */
42789Sahrens
431420Smarks #define APPENDED_ID_MAX ID_STR_MAX + 1 /* id + colon */
441420Smarks /*
451420Smarks * yyinteractive controls whether yyparse should print out
461420Smarks * error messages to stderr, and whether or not id's should be
471420Smarks * allowed from acl_fromtext().
481420Smarks */
491420Smarks int yyinteractive;
501420Smarks acl_t *yyacl;
511420Smarks char *yybuf;
5211963SAfshin.Ardakani@Sun.COM mutex_t yymutex;
53789Sahrens
54789Sahrens extern acl_t *acl_alloc(enum acl_type);
550Sstevel@tonic-gate
567057Smarks /*
577057Smarks * dynamic string that will increase in size on an
587057Smarks * as needed basis.
597057Smarks */
607057Smarks typedef struct dynaclstr {
617057Smarks size_t d_bufsize; /* current size of aclexport */
627057Smarks char *d_aclexport;
637057Smarks int d_pos;
647057Smarks } dynaclstr_t;
65922Shm123892
667057Smarks static int str_append(dynaclstr_t *, char *);
677057Smarks static int aclent_perm_txt(dynaclstr_t *, o_mode_t);
680Sstevel@tonic-gate
691420Smarks static void
aclent_perms(int perm,char * txt_perms)701420Smarks aclent_perms(int perm, char *txt_perms)
711420Smarks {
721420Smarks if (perm & S_IROTH)
731420Smarks txt_perms[0] = 'r';
741420Smarks else
751420Smarks txt_perms[0] = '-';
761420Smarks if (perm & S_IWOTH)
771420Smarks txt_perms[1] = 'w';
781420Smarks else
791420Smarks txt_perms[1] = '-';
801420Smarks if (perm & S_IXOTH)
811420Smarks txt_perms[2] = 'x';
821420Smarks else
831420Smarks txt_perms[2] = '-';
841420Smarks txt_perms[3] = '\0';
851420Smarks }
861420Smarks
871420Smarks static char *
pruname(uid_t uid,char * uidp,size_t buflen,int noresolve)881535Smarks pruname(uid_t uid, char *uidp, size_t buflen, int noresolve)
891420Smarks {
901515Sgjelinek struct passwd *passwdp = NULL;
911420Smarks
921515Sgjelinek if (noresolve == 0)
931515Sgjelinek passwdp = getpwuid(uid);
941420Smarks if (passwdp == (struct passwd *)NULL) {
951420Smarks /* could not get passwd information: display uid instead */
964321Scasper (void) snprintf(uidp, buflen, "%u", uid);
971535Smarks } else {
981535Smarks (void) strlcpy(uidp, passwdp->pw_name, buflen);
991535Smarks }
1001535Smarks return (uidp);
1011420Smarks }
1021420Smarks
1031420Smarks static char *
prgname(gid_t gid,char * gidp,size_t buflen,int noresolve)1041535Smarks prgname(gid_t gid, char *gidp, size_t buflen, int noresolve)
1051420Smarks {
1061515Sgjelinek struct group *groupp = NULL;
1071420Smarks
1081515Sgjelinek if (noresolve == 0)
1091515Sgjelinek groupp = getgrgid(gid);
1101420Smarks if (groupp == (struct group *)NULL) {
1111420Smarks /* could not get group information: display gid instead */
1124321Scasper (void) snprintf(gidp, buflen, "%u", gid);
1131535Smarks } else {
1141535Smarks (void) strlcpy(gidp, groupp->gr_name, buflen);
1151535Smarks }
1161535Smarks return (gidp);
1171420Smarks }
1187057Smarks
1197680SMark.Shellenbaum@Sun.COM static int
getsidname(uid_t who,boolean_t user,char ** sidp,boolean_t noresolve)1207680SMark.Shellenbaum@Sun.COM getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve)
1217057Smarks {
1227057Smarks idmap_get_handle_t *get_hdl = NULL;
1237057Smarks idmap_stat status;
1247057Smarks idmap_rid_t rid;
1257680SMark.Shellenbaum@Sun.COM int error = IDMAP_ERR_NORESULT;
1267057Smarks int len;
12711605SGowtham.Thommandra@Sun.COM char *domain = NULL;
12811605SGowtham.Thommandra@Sun.COM char *name = NULL;
1297057Smarks
1307680SMark.Shellenbaum@Sun.COM *sidp = NULL;
1317057Smarks
1327057Smarks /*
1337057Smarks * First try and get windows name
1347057Smarks */
1357057Smarks
1367680SMark.Shellenbaum@Sun.COM if (!noresolve) {
1377680SMark.Shellenbaum@Sun.COM if (user)
1387680SMark.Shellenbaum@Sun.COM error = idmap_getwinnamebyuid(who,
1397680SMark.Shellenbaum@Sun.COM IDMAP_REQ_FLG_USE_CACHE, &name, &domain);
1407680SMark.Shellenbaum@Sun.COM else
1417680SMark.Shellenbaum@Sun.COM error = idmap_getwinnamebygid(who,
1427680SMark.Shellenbaum@Sun.COM IDMAP_REQ_FLG_USE_CACHE, &name, &domain);
1437680SMark.Shellenbaum@Sun.COM }
1447680SMark.Shellenbaum@Sun.COM if (error != IDMAP_SUCCESS) {
145*12914SJoyce.McIntosh@Sun.COM if (idmap_get_create(&get_hdl) == IDMAP_SUCCESS) {
1467057Smarks if (user)
1477057Smarks error = idmap_get_sidbyuid(get_hdl, who,
1487369SJulian.Pullen@Sun.COM IDMAP_REQ_FLG_USE_CACHE, &domain, &rid,
1497369SJulian.Pullen@Sun.COM &status);
1507057Smarks else
1517057Smarks error = idmap_get_sidbygid(get_hdl, who,
1527369SJulian.Pullen@Sun.COM IDMAP_REQ_FLG_USE_CACHE, &domain, &rid,
1537369SJulian.Pullen@Sun.COM &status);
1547680SMark.Shellenbaum@Sun.COM if (error == IDMAP_SUCCESS &&
1557680SMark.Shellenbaum@Sun.COM idmap_get_mappings(get_hdl) == 0) {
1567680SMark.Shellenbaum@Sun.COM if (status == IDMAP_SUCCESS) {
1577680SMark.Shellenbaum@Sun.COM len = snprintf(NULL, 0,
1587680SMark.Shellenbaum@Sun.COM "%s-%d", domain, rid);
1597680SMark.Shellenbaum@Sun.COM if (*sidp = malloc(len + 1)) {
1607680SMark.Shellenbaum@Sun.COM (void) snprintf(*sidp, len + 1,
1617680SMark.Shellenbaum@Sun.COM "%s-%d", domain, rid);
1627680SMark.Shellenbaum@Sun.COM }
1637680SMark.Shellenbaum@Sun.COM }
1647680SMark.Shellenbaum@Sun.COM }
1657057Smarks }
1667057Smarks if (get_hdl)
1677057Smarks idmap_get_destroy(get_hdl);
1687057Smarks } else {
1697057Smarks int len;
1707680SMark.Shellenbaum@Sun.COM
1718268SMark.Shellenbaum@Sun.COM len = snprintf(NULL, 0, "%s@%s", name, domain);
1727680SMark.Shellenbaum@Sun.COM if (*sidp = malloc(len + 1))
1737680SMark.Shellenbaum@Sun.COM (void) snprintf(*sidp, len + 1, "%s@%s", name, domain);
17411605SGowtham.Thommandra@Sun.COM }
17511605SGowtham.Thommandra@Sun.COM
17611605SGowtham.Thommandra@Sun.COM if (name)
1778268SMark.Shellenbaum@Sun.COM free(name);
17811605SGowtham.Thommandra@Sun.COM if (domain)
1798268SMark.Shellenbaum@Sun.COM free(domain);
1807680SMark.Shellenbaum@Sun.COM return (*sidp ? 0 : 1);
1817057Smarks }
1827057Smarks
1831420Smarks static void
aclent_printacl(acl_t * aclp)1841420Smarks aclent_printacl(acl_t *aclp)
185789Sahrens {
1861420Smarks aclent_t *tp;
1871420Smarks int aclcnt;
1881420Smarks int mask;
1891420Smarks int slot = 0;
1901420Smarks char perm[4];
1911535Smarks char uidp[ID_STR_MAX];
1921535Smarks char gidp[ID_STR_MAX];
1931420Smarks
1941420Smarks /* display ACL: assume it is sorted. */
1951420Smarks aclcnt = aclp->acl_cnt;
1961420Smarks for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) {
1971420Smarks if (tp->a_type == CLASS_OBJ)
1981420Smarks mask = tp->a_perm;
1991420Smarks }
2001420Smarks aclcnt = aclp->acl_cnt;
2011420Smarks for (tp = aclp->acl_aclp; aclcnt--; tp++) {
2021420Smarks (void) printf(" %d:", slot++);
2031420Smarks switch (tp->a_type) {
2041420Smarks case USER:
2051420Smarks aclent_perms(tp->a_perm, perm);
2061420Smarks (void) printf("user:%s:%s\t\t",
2071535Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm);
2081420Smarks aclent_perms((tp->a_perm & mask), perm);
2091420Smarks (void) printf("#effective:%s\n", perm);
2101420Smarks break;
2111420Smarks case USER_OBJ:
2121420Smarks /* no need to display uid */
2131420Smarks aclent_perms(tp->a_perm, perm);
2141420Smarks (void) printf("user::%s\n", perm);
2151420Smarks break;
2161420Smarks case GROUP:
2171420Smarks aclent_perms(tp->a_perm, perm);
2181420Smarks (void) printf("group:%s:%s\t\t",
2191535Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm);
2201420Smarks aclent_perms(tp->a_perm & mask, perm);
2211420Smarks (void) printf("#effective:%s\n", perm);
2221420Smarks break;
2231420Smarks case GROUP_OBJ:
2241420Smarks aclent_perms(tp->a_perm, perm);
2251420Smarks (void) printf("group::%s\t\t", perm);
2261420Smarks aclent_perms(tp->a_perm & mask, perm);
2271420Smarks (void) printf("#effective:%s\n", perm);
2281420Smarks break;
2291420Smarks case CLASS_OBJ:
2301420Smarks aclent_perms(tp->a_perm, perm);
2311420Smarks (void) printf("mask:%s\n", perm);
2321420Smarks break;
2331420Smarks case OTHER_OBJ:
2341420Smarks aclent_perms(tp->a_perm, perm);
2351420Smarks (void) printf("other:%s\n", perm);
2361420Smarks break;
2371420Smarks case DEF_USER:
2381420Smarks aclent_perms(tp->a_perm, perm);
2391420Smarks (void) printf("default:user:%s:%s\n",
2401535Smarks pruname(tp->a_id, uidp, sizeof (uidp), 0), perm);
2411420Smarks break;
2421420Smarks case DEF_USER_OBJ:
2431420Smarks aclent_perms(tp->a_perm, perm);
2441420Smarks (void) printf("default:user::%s\n", perm);
2451420Smarks break;
2461420Smarks case DEF_GROUP:
2471420Smarks aclent_perms(tp->a_perm, perm);
2481420Smarks (void) printf("default:group:%s:%s\n",
2491535Smarks prgname(tp->a_id, gidp, sizeof (gidp), 0), perm);
2501420Smarks break;
2511420Smarks case DEF_GROUP_OBJ:
2521420Smarks aclent_perms(tp->a_perm, perm);
2531420Smarks (void) printf("default:group::%s\n", perm);
2541420Smarks break;
2551420Smarks case DEF_CLASS_OBJ:
2561420Smarks aclent_perms(tp->a_perm, perm);
2571420Smarks (void) printf("default:mask:%s\n", perm);
2581420Smarks break;
2591420Smarks case DEF_OTHER_OBJ:
2601420Smarks aclent_perms(tp->a_perm, perm);
2611420Smarks (void) printf("default:other:%s\n", perm);
2621420Smarks break;
2631420Smarks default:
2641420Smarks (void) fprintf(stderr,
2651567Smarks dgettext(TEXT_DOMAIN, "unrecognized entry\n"));
2661420Smarks break;
2671420Smarks }
2681420Smarks }
2691420Smarks }
2701420Smarks
2711420Smarks static void
split_line(char * str,int cols)2721420Smarks split_line(char *str, int cols)
2731420Smarks {
2741420Smarks char *ptr;
2751420Smarks int len;
2761420Smarks int i;
2771420Smarks int last_split;
2781420Smarks char *pad = "";
2791420Smarks int pad_len;
2801420Smarks
2811420Smarks len = strlen(str);
2821420Smarks ptr = str;
2831420Smarks pad_len = 0;
2841420Smarks
2851420Smarks ptr = str;
2861420Smarks last_split = 0;
2871420Smarks for (i = 0; i != len; i++) {
2881420Smarks if ((i + pad_len + 4) >= cols) {
2891420Smarks (void) printf("%s%.*s\n", pad, last_split, ptr);
2901420Smarks ptr = &ptr[last_split];
2911420Smarks len = strlen(ptr);
2921420Smarks i = 0;
2931420Smarks pad_len = 4;
2941420Smarks pad = " ";
2951420Smarks } else {
2961420Smarks if (ptr[i] == '/' || ptr[i] == ':') {
2971420Smarks last_split = i;
2981420Smarks }
2991420Smarks }
3001420Smarks }
3011420Smarks if (i == len) {
3021420Smarks (void) printf("%s%s\n", pad, ptr);
3031420Smarks }
3041420Smarks }
3051420Smarks
3067057Smarks /*
3077057Smarks * compute entry type string, such as user:joe, group:staff,...
3087057Smarks */
3097057Smarks static int
aclent_type_txt(dynaclstr_t * dstr,aclent_t * aclp,int flags)3107057Smarks aclent_type_txt(dynaclstr_t *dstr, aclent_t *aclp, int flags)
3111420Smarks {
3127057Smarks char idp[ID_STR_MAX];
3137057Smarks int error;
3147057Smarks
3157057Smarks switch (aclp->a_type) {
3167057Smarks case DEF_USER_OBJ:
3177057Smarks case USER_OBJ:
3187057Smarks if (aclp->a_type == USER_OBJ)
3197057Smarks error = str_append(dstr, "user::");
3207057Smarks else
3217057Smarks error = str_append(dstr, "defaultuser::");
3227057Smarks break;
3237057Smarks
3247057Smarks case DEF_USER:
3257057Smarks case USER:
3267057Smarks if (aclp->a_type == USER)
3277057Smarks error = str_append(dstr, "user:");
3287057Smarks else
3297057Smarks error = str_append(dstr, "defaultuser:");
3307057Smarks if (error)
3317057Smarks break;
3327057Smarks error = str_append(dstr, pruname(aclp->a_id, idp,
3337057Smarks sizeof (idp), flags & ACL_NORESOLVE));
3347057Smarks if (error == 0)
3357057Smarks error = str_append(dstr, ":");
3367057Smarks break;
3377057Smarks
3387057Smarks case DEF_GROUP_OBJ:
3397057Smarks case GROUP_OBJ:
3407057Smarks if (aclp->a_type == GROUP_OBJ)
3417057Smarks error = str_append(dstr, "group::");
3427057Smarks else
3437057Smarks error = str_append(dstr, "defaultgroup::");
3447057Smarks break;
3451420Smarks
3467057Smarks case DEF_GROUP:
3477057Smarks case GROUP:
3487057Smarks if (aclp->a_type == GROUP)
3497057Smarks error = str_append(dstr, "group:");
3507057Smarks else
3517057Smarks error = str_append(dstr, "defaultgroup:");
3527057Smarks if (error)
3537057Smarks break;
3547057Smarks error = str_append(dstr, prgname(aclp->a_id, idp,
3557057Smarks sizeof (idp), flags & ACL_NORESOLVE));
3567057Smarks if (error == 0)
3577057Smarks error = str_append(dstr, ":");
3587057Smarks break;
3597057Smarks
3607057Smarks case DEF_CLASS_OBJ:
3617057Smarks case CLASS_OBJ:
3627057Smarks if (aclp->a_type == CLASS_OBJ)
3637057Smarks error = str_append(dstr, "mask:");
3647057Smarks else
3657057Smarks error = str_append(dstr, "defaultmask:");
3667057Smarks break;
3671420Smarks
3687057Smarks case DEF_OTHER_OBJ:
3697057Smarks case OTHER_OBJ:
3707057Smarks if (aclp->a_type == OTHER_OBJ)
3717057Smarks error = str_append(dstr, "other:");
3727057Smarks else
3737057Smarks error = str_append(dstr, "defaultother:");
3747057Smarks break;
3757057Smarks
3767057Smarks default:
3777057Smarks error = 1;
3787057Smarks break;
3797057Smarks }
3807057Smarks
3817057Smarks return (error);
3827057Smarks }
3837057Smarks
3847057Smarks /*
3857057Smarks * compute entry type string such as, owner@:, user:joe, group:staff,...
3867057Smarks */
3877057Smarks static int
ace_type_txt(dynaclstr_t * dynstr,ace_t * acep,int flags)3887057Smarks ace_type_txt(dynaclstr_t *dynstr, ace_t *acep, int flags)
3897057Smarks {
3907057Smarks char idp[ID_STR_MAX];
3917057Smarks int error;
3927057Smarks char *sidp = NULL;
3931420Smarks
3941420Smarks switch (acep->a_flags & ACE_TYPE_FLAGS) {
3951420Smarks case ACE_OWNER:
3967057Smarks error = str_append(dynstr, OWNERAT_TXT);
3971420Smarks break;
3981420Smarks
3991420Smarks case ACE_GROUP|ACE_IDENTIFIER_GROUP:
4007057Smarks error = str_append(dynstr, GROUPAT_TXT);
4011420Smarks break;
4021420Smarks
4031420Smarks case ACE_IDENTIFIER_GROUP:
4047057Smarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {
4057057Smarks if (error = str_append(dynstr,
4067057Smarks GROUPSID_TXT))
4077057Smarks break;
4087680SMark.Shellenbaum@Sun.COM if (error = getsidname(acep->a_who, B_FALSE,
4097680SMark.Shellenbaum@Sun.COM &sidp, flags & ACL_NORESOLVE))
4107680SMark.Shellenbaum@Sun.COM break;
4117680SMark.Shellenbaum@Sun.COM error = str_append(dynstr, sidp);
4127057Smarks } else {
4137057Smarks if (error = str_append(dynstr, GROUP_TXT))
4147057Smarks break;
4157057Smarks error = str_append(dynstr, prgname(acep->a_who, idp,
4167057Smarks sizeof (idp), flags & ACL_NORESOLVE));
4177057Smarks }
4187057Smarks if (error == 0)
4197057Smarks error = str_append(dynstr, ":");
4201420Smarks break;
4211420Smarks
4221420Smarks case ACE_EVERYONE:
4237057Smarks error = str_append(dynstr, EVERYONEAT_TXT);
4241420Smarks break;
4251420Smarks
4261420Smarks case 0:
4277057Smarks if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {
4287057Smarks if (error = str_append(dynstr, USERSID_TXT))
4297057Smarks break;
4307680SMark.Shellenbaum@Sun.COM if (error = getsidname(acep->a_who, B_TRUE,
4317680SMark.Shellenbaum@Sun.COM &sidp, flags & ACL_NORESOLVE))
4327680SMark.Shellenbaum@Sun.COM break;
4337680SMark.Shellenbaum@Sun.COM error = str_append(dynstr, sidp);
4347057Smarks } else {
4357057Smarks if (error = str_append(dynstr, USER_TXT))
4367057Smarks break;
4377057Smarks error = str_append(dynstr, pruname(acep->a_who, idp,
4387057Smarks sizeof (idp), flags & ACL_NORESOLVE));
4397057Smarks }
4407057Smarks if (error == 0)
4417057Smarks error = str_append(dynstr, ":");
4427057Smarks break;
4437057Smarks default:
4447057Smarks error = 0;
4451420Smarks break;
4461420Smarks }
4471420Smarks
4487057Smarks if (sidp)
4497057Smarks free(sidp);
4507057Smarks return (error);
4511420Smarks }
4521420Smarks
4537057Smarks /*
4547057Smarks * compute string of permissions, such as read_data/write_data or
4557057Smarks * rwxp,...
4567057Smarks * The format depends on the flags field which indicates whether the compact
4577057Smarks * or verbose format should be used.
4587057Smarks */
4597057Smarks static int
ace_perm_txt(dynaclstr_t * dstr,uint32_t mask,uint32_t iflags,int isdir,int flags)4607057Smarks ace_perm_txt(dynaclstr_t *dstr, uint32_t mask,
4611420Smarks uint32_t iflags, int isdir, int flags)
4621420Smarks {
4637057Smarks int error = 0;
4641420Smarks
4651420Smarks if (flags & ACL_COMPACT_FMT) {
4667057Smarks char buf[16];
467789Sahrens
4681420Smarks if (mask & ACE_READ_DATA)
4691420Smarks buf[0] = 'r';
4701420Smarks else
4711420Smarks buf[0] = '-';
4721420Smarks if (mask & ACE_WRITE_DATA)
4731420Smarks buf[1] = 'w';
4741420Smarks else
4751420Smarks buf[1] = '-';
4761420Smarks if (mask & ACE_EXECUTE)
4771420Smarks buf[2] = 'x';
4781420Smarks else
4791420Smarks buf[2] = '-';
4801420Smarks if (mask & ACE_APPEND_DATA)
4811420Smarks buf[3] = 'p';
4821420Smarks else
4831420Smarks buf[3] = '-';
4841420Smarks if (mask & ACE_DELETE)
4851420Smarks buf[4] = 'd';
4861420Smarks else
4871420Smarks buf[4] = '-';
4881420Smarks if (mask & ACE_DELETE_CHILD)
4891420Smarks buf[5] = 'D';
4901420Smarks else
4911420Smarks buf[5] = '-';
4921420Smarks if (mask & ACE_READ_ATTRIBUTES)
4931420Smarks buf[6] = 'a';
4941420Smarks else
4951420Smarks buf[6] = '-';
4961420Smarks if (mask & ACE_WRITE_ATTRIBUTES)
4971420Smarks buf[7] = 'A';
4981420Smarks else
4991420Smarks buf[7] = '-';
5001420Smarks if (mask & ACE_READ_NAMED_ATTRS)
5011420Smarks buf[8] = 'R';
5021420Smarks else
5031420Smarks buf[8] = '-';
5041420Smarks if (mask & ACE_WRITE_NAMED_ATTRS)
5051420Smarks buf[9] = 'W';
5061420Smarks else
5071420Smarks buf[9] = '-';
5081420Smarks if (mask & ACE_READ_ACL)
5091420Smarks buf[10] = 'c';
5101420Smarks else
5111420Smarks buf[10] = '-';
5121420Smarks if (mask & ACE_WRITE_ACL)
5131420Smarks buf[11] = 'C';
5141420Smarks else
5151420Smarks buf[11] = '-';
5161420Smarks if (mask & ACE_WRITE_OWNER)
5171420Smarks buf[12] = 'o';
5181420Smarks else
5191420Smarks buf[12] = '-';
5201420Smarks if (mask & ACE_SYNCHRONIZE)
5211420Smarks buf[13] = 's';
5221420Smarks else
5231420Smarks buf[13] = '-';
5247057Smarks buf[14] = ':';
5257057Smarks buf[15] = '\0';
5267057Smarks error = str_append(dstr, buf);
5271420Smarks } else {
5281420Smarks /*
5291420Smarks * If ACE is a directory, but inheritance indicates its
5301420Smarks * for a file then print permissions for file rather than
5311420Smarks * dir.
5321420Smarks */
5331420Smarks if (isdir) {
5341420Smarks if (mask & ACE_LIST_DIRECTORY) {
5351420Smarks if (iflags == ACE_FILE_INHERIT_ACE) {
5367057Smarks error = str_append(dstr,
5377057Smarks READ_DATA_TXT);
5381420Smarks } else {
5397057Smarks error =
5407057Smarks str_append(dstr, READ_DIR_TXT);
5411420Smarks }
5421420Smarks }
5437057Smarks if (error == 0 && (mask & ACE_ADD_FILE)) {
5441420Smarks if (iflags == ACE_FILE_INHERIT_ACE) {
5457057Smarks error =
5467057Smarks str_append(dstr, WRITE_DATA_TXT);
5471420Smarks } else {
5487057Smarks error =
5497057Smarks str_append(dstr, ADD_FILE_TXT);
5501420Smarks }
5511420Smarks }
5527057Smarks if (error == 0 && (mask & ACE_ADD_SUBDIRECTORY)) {
5531420Smarks if (iflags == ACE_FILE_INHERIT_ACE) {
5547057Smarks error = str_append(dstr,
5557057Smarks APPEND_DATA_TXT);
5561420Smarks } else {
5577057Smarks error = str_append(dstr,
5587057Smarks ADD_DIR_TXT);
5591420Smarks }
5601420Smarks }
5611420Smarks } else {
5621420Smarks if (mask & ACE_READ_DATA) {
5637057Smarks error = str_append(dstr, READ_DATA_TXT);
5641420Smarks }
5657057Smarks if (error == 0 && (mask & ACE_WRITE_DATA)) {
5667057Smarks error = str_append(dstr, WRITE_DATA_TXT);
5671420Smarks }
5687057Smarks if (error == 0 && (mask & ACE_APPEND_DATA)) {
5697057Smarks error = str_append(dstr, APPEND_DATA_TXT);
5701420Smarks }
5711420Smarks }
5727057Smarks if (error == 0 && (mask & ACE_READ_NAMED_ATTRS)) {
5737057Smarks error = str_append(dstr, READ_XATTR_TXT);
5741420Smarks }
5757057Smarks if (error == 0 && (mask & ACE_WRITE_NAMED_ATTRS)) {
5767057Smarks error = str_append(dstr, WRITE_XATTR_TXT);
5771420Smarks }
5787057Smarks if (error == 0 && (mask & ACE_EXECUTE)) {
5797057Smarks error = str_append(dstr, EXECUTE_TXT);
5801420Smarks }
5817057Smarks if (error == 0 && (mask & ACE_DELETE_CHILD)) {
5827057Smarks error = str_append(dstr, DELETE_CHILD_TXT);
5831420Smarks }
5847057Smarks if (error == 0 && (mask & ACE_READ_ATTRIBUTES)) {
5857057Smarks error = str_append(dstr, READ_ATTRIBUTES_TXT);
5861420Smarks }
5877057Smarks if (error == 0 && (mask & ACE_WRITE_ATTRIBUTES)) {
5887057Smarks error = str_append(dstr, WRITE_ATTRIBUTES_TXT);
5891420Smarks }
5907057Smarks if (error == 0 && (mask & ACE_DELETE)) {
5917057Smarks error = str_append(dstr, DELETE_TXT);
5921420Smarks }
5937057Smarks if (error == 0 && (mask & ACE_READ_ACL)) {
5947057Smarks error = str_append(dstr, READ_ACL_TXT);
5951420Smarks }
5967057Smarks if (error == 0 && (mask & ACE_WRITE_ACL)) {
5977057Smarks error = str_append(dstr, WRITE_ACL_TXT);
5981420Smarks }
5997057Smarks if (error == 0 && (mask & ACE_WRITE_OWNER)) {
6007057Smarks error = str_append(dstr, WRITE_OWNER_TXT);
6011420Smarks }
6027057Smarks if (error == 0 && (mask & ACE_SYNCHRONIZE)) {
6037057Smarks error = str_append(dstr, SYNCHRONIZE_TXT);
6041420Smarks }
6057057Smarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') {
6067057Smarks dstr->d_aclexport[--dstr->d_pos] = '\0';
6077057Smarks }
6087057Smarks if (error == 0)
6097057Smarks error = str_append(dstr, ":");
6101420Smarks }
6117057Smarks return (error);
6121420Smarks }
6131420Smarks
6147057Smarks /*
6157057Smarks * compute string of access type, such as allow, deny, ...
6167057Smarks */
6177057Smarks static int
ace_access_txt(dynaclstr_t * dstr,int type)6187057Smarks ace_access_txt(dynaclstr_t *dstr, int type)
6191420Smarks {
6207057Smarks int error;
6211420Smarks
6227057Smarks if (type == ACE_ACCESS_ALLOWED_ACE_TYPE)
6237057Smarks error = str_append(dstr, ALLOW_TXT);
6247057Smarks else if (type == ACE_ACCESS_DENIED_ACE_TYPE)
6257057Smarks error = str_append(dstr, DENY_TXT);
6267057Smarks else if (type == ACE_SYSTEM_AUDIT_ACE_TYPE)
6277057Smarks error = str_append(dstr, AUDIT_TXT);
6287057Smarks else if (type == ACE_SYSTEM_ALARM_ACE_TYPE)
6297057Smarks error = str_append(dstr, ALARM_TXT);
6307057Smarks else
6317057Smarks error = str_append(dstr, UNKNOWN_TXT);
6321420Smarks
6337057Smarks return (error);
6341420Smarks }
6351420Smarks
6367057Smarks static int
ace_inherit_txt(dynaclstr_t * dstr,uint32_t iflags,int flags)6377057Smarks ace_inherit_txt(dynaclstr_t *dstr, uint32_t iflags, int flags)
6381420Smarks {
6397057Smarks int error = 0;
640789Sahrens
6411420Smarks if (flags & ACL_COMPACT_FMT) {
6427057Smarks char buf[9];
6437057Smarks
6441420Smarks if (iflags & ACE_FILE_INHERIT_ACE)
6451420Smarks buf[0] = 'f';
6461420Smarks else
6471420Smarks buf[0] = '-';
6481420Smarks if (iflags & ACE_DIRECTORY_INHERIT_ACE)
6491420Smarks buf[1] = 'd';
6501420Smarks else
6511420Smarks buf[1] = '-';
6521420Smarks if (iflags & ACE_INHERIT_ONLY_ACE)
6531420Smarks buf[2] = 'i';
6541420Smarks else
6551420Smarks buf[2] = '-';
6561420Smarks if (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)
6571420Smarks buf[3] = 'n';
6581420Smarks else
6591420Smarks buf[3] = '-';
6601420Smarks if (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)
6611420Smarks buf[4] = 'S';
6621420Smarks else
6631420Smarks buf[4] = '-';
6641420Smarks if (iflags & ACE_FAILED_ACCESS_ACE_FLAG)
6651420Smarks buf[5] = 'F';
6661420Smarks else
6671420Smarks buf[5] = '-';
6685331Samw if (iflags & ACE_INHERITED_ACE)
6695331Samw buf[6] = 'I';
6705331Samw else
6715331Samw buf[6] = '-';
6727057Smarks buf[7] = ':';
6737057Smarks buf[8] = '\0';
6747057Smarks error = str_append(dstr, buf);
6751420Smarks } else {
6761420Smarks if (iflags & ACE_FILE_INHERIT_ACE) {
6777057Smarks error = str_append(dstr, FILE_INHERIT_TXT);
6781420Smarks }
6797057Smarks if (error == 0 && (iflags & ACE_DIRECTORY_INHERIT_ACE)) {
6807057Smarks error = str_append(dstr, DIR_INHERIT_TXT);
6811420Smarks }
6827057Smarks if (error == 0 && (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)) {
6837057Smarks error = str_append(dstr, NO_PROPAGATE_TXT);
6841420Smarks }
6857057Smarks if (error == 0 && (iflags & ACE_INHERIT_ONLY_ACE)) {
6867057Smarks error = str_append(dstr, INHERIT_ONLY_TXT);
6871420Smarks }
6887057Smarks if (error == 0 && (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)) {
6897057Smarks error = str_append(dstr, SUCCESSFUL_ACCESS_TXT);
6905331Samw }
6917057Smarks if (error == 0 && (iflags & ACE_FAILED_ACCESS_ACE_FLAG)) {
6927057Smarks error = str_append(dstr, FAILED_ACCESS_TXT);
6935331Samw }
6947057Smarks if (error == 0 && (iflags & ACE_INHERITED_ACE)) {
6957057Smarks error = str_append(dstr, INHERITED_ACE_TXT);
6965331Samw }
6977057Smarks if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') {
6987057Smarks dstr->d_aclexport[--dstr->d_pos] = '\0';
6997057Smarks error = str_append(dstr, ":");
7007057Smarks }
7011420Smarks }
7021420Smarks
7037057Smarks return (error);
704789Sahrens }
7050Sstevel@tonic-gate
7060Sstevel@tonic-gate /*
7070Sstevel@tonic-gate * Convert internal acl representation to external representation.
7080Sstevel@tonic-gate *
7090Sstevel@tonic-gate * The length of a non-owning user name or non-owning group name ie entries
7100Sstevel@tonic-gate * of type DEF_USER, USER, DEF_GROUP or GROUP, can exceed LOGNAME_MAX. We
7110Sstevel@tonic-gate * thus check the length of these entries, and if greater than LOGNAME_MAX,
7120Sstevel@tonic-gate * we realloc() via increase_length().
7130Sstevel@tonic-gate *
7140Sstevel@tonic-gate * The LOGNAME_MAX, ENTRYTYPELEN and PERMS limits are otherwise always
7150Sstevel@tonic-gate * adhered to.
7160Sstevel@tonic-gate */
7171420Smarks
7181420Smarks /*
7191420Smarks * acltotext() converts each ACL entry to look like this:
7201420Smarks *
7211420Smarks * entry_type:uid^gid^name:perms[:id]
7221420Smarks *
7231420Smarks * The maximum length of entry_type is 14 ("defaultgroup::" and
7241420Smarks * "defaultother::") hence ENTRYTYPELEN is set to 14.
7251420Smarks *
7261420Smarks * The max length of a uid^gid^name entry (in theory) is 8, hence we use,
7271420Smarks * however the ID could be a number so we therefore use ID_STR_MAX
7281420Smarks *
7291420Smarks * The length of a perms entry is 4 to allow for the comma appended to each
7301420Smarks * to each acl entry. Hence PERMS is set to 4.
7311420Smarks */
7321420Smarks
7331420Smarks #define ENTRYTYPELEN 14
7341420Smarks #define PERMS 4
7351420Smarks #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX)
7361420Smarks
7370Sstevel@tonic-gate char *
aclent_acltotext(aclent_t * aclp,int aclcnt,int flags)7381420Smarks aclent_acltotext(aclent_t *aclp, int aclcnt, int flags)
7390Sstevel@tonic-gate {
7407057Smarks dynaclstr_t *dstr;
7417680SMark.Shellenbaum@Sun.COM char *aclexport = NULL;
7427057Smarks int i;
7437057Smarks int error = 0;
7440Sstevel@tonic-gate
7450Sstevel@tonic-gate if (aclp == NULL)
7460Sstevel@tonic-gate return (NULL);
7477057Smarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
7480Sstevel@tonic-gate return (NULL);
7497057Smarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE;
7507057Smarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
7510Sstevel@tonic-gate free(dstr);
7520Sstevel@tonic-gate return (NULL);
7530Sstevel@tonic-gate }
7547057Smarks *dstr->d_aclexport = '\0';
7557057Smarks dstr->d_pos = 0;
7560Sstevel@tonic-gate
7570Sstevel@tonic-gate for (i = 0; i < aclcnt; i++, aclp++) {
7587057Smarks if (error = aclent_type_txt(dstr, aclp, flags))
7590Sstevel@tonic-gate break;
7607057Smarks if (error = aclent_perm_txt(dstr, aclp->a_perm))
7610Sstevel@tonic-gate break;
7621420Smarks
7631420Smarks if ((flags & ACL_APPEND_ID) && ((aclp->a_type == USER) ||
7641420Smarks (aclp->a_type == DEF_USER) || (aclp->a_type == GROUP) ||
7651420Smarks (aclp->a_type == DEF_GROUP))) {
7667057Smarks char id[ID_STR_MAX], *idstr;
7677057Smarks
7687057Smarks if (error = str_append(dstr, ":"))
7697057Smarks break;
7701420Smarks id[ID_STR_MAX - 1] = '\0'; /* null terminate buffer */
7711420Smarks idstr = lltostr(aclp->a_id, &id[ID_STR_MAX - 1]);
7727057Smarks if (error = str_append(dstr, idstr))
7737057Smarks break;
7741420Smarks }
7750Sstevel@tonic-gate if (i < aclcnt - 1)
7767057Smarks if (error = str_append(dstr, ","))
7777057Smarks break;
7780Sstevel@tonic-gate }
7797057Smarks if (error) {
7807057Smarks if (dstr->d_aclexport)
7817057Smarks free(dstr->d_aclexport);
7827057Smarks } else {
7837057Smarks aclexport = dstr->d_aclexport;
7847057Smarks }
7850Sstevel@tonic-gate free(dstr);
7860Sstevel@tonic-gate return (aclexport);
7870Sstevel@tonic-gate }
7880Sstevel@tonic-gate
7891420Smarks char *
acltotext(aclent_t * aclp,int aclcnt)7901420Smarks acltotext(aclent_t *aclp, int aclcnt)
7910Sstevel@tonic-gate {
7921420Smarks return (aclent_acltotext(aclp, aclcnt, 0));
7931420Smarks }
7940Sstevel@tonic-gate
7950Sstevel@tonic-gate
796789Sahrens aclent_t *
aclfromtext(char * aclstr,int * aclcnt)797789Sahrens aclfromtext(char *aclstr, int *aclcnt)
798789Sahrens {
799789Sahrens acl_t *aclp;
800789Sahrens aclent_t *aclentp;
801789Sahrens int error;
802789Sahrens
8031420Smarks error = acl_fromtext(aclstr, &aclp);
804789Sahrens if (error)
805789Sahrens return (NULL);
806789Sahrens
807789Sahrens aclentp = aclp->acl_aclp;
808789Sahrens aclp->acl_aclp = NULL;
8091420Smarks *aclcnt = aclp->acl_cnt;
810789Sahrens
8111420Smarks acl_free(aclp);
812789Sahrens return (aclentp);
813789Sahrens }
814789Sahrens
815789Sahrens
8167057Smarks /*
8177680SMark.Shellenbaum@Sun.COM * Append string onto dynaclstr_t.
8187680SMark.Shellenbaum@Sun.COM *
8197680SMark.Shellenbaum@Sun.COM * Return 0 on success, 1 for failure.
8207057Smarks */
8217057Smarks static int
str_append(dynaclstr_t * dstr,char * newstr)8227057Smarks str_append(dynaclstr_t *dstr, char *newstr)
8230Sstevel@tonic-gate {
8247057Smarks size_t len = strlen(newstr);
8257057Smarks
8267057Smarks if ((len + dstr->d_pos) >= dstr->d_bufsize) {
8277057Smarks dstr->d_aclexport = realloc(dstr->d_aclexport,
8287057Smarks dstr->d_bufsize + len + 1);
8297057Smarks if (dstr->d_aclexport == NULL)
8307057Smarks return (1);
8317057Smarks dstr->d_bufsize += len;
8327057Smarks }
8337057Smarks (void) strcat(&dstr->d_aclexport[dstr->d_pos], newstr);
8347057Smarks dstr->d_pos += len;
8357057Smarks return (0);
8360Sstevel@tonic-gate }
8370Sstevel@tonic-gate
8387057Smarks static int
aclent_perm_txt(dynaclstr_t * dstr,o_mode_t perm)8397057Smarks aclent_perm_txt(dynaclstr_t *dstr, o_mode_t perm)
8400Sstevel@tonic-gate {
8417057Smarks char buf[4];
8420Sstevel@tonic-gate
8437057Smarks if (perm & S_IROTH)
8447057Smarks buf[0] = 'r';
8457057Smarks else
8467057Smarks buf[0] = '-';
8477057Smarks if (perm & S_IWOTH)
8487057Smarks buf[1] = 'w';
8497057Smarks else
8507057Smarks buf[1] = '-';
8517057Smarks if (perm & S_IXOTH)
8527057Smarks buf[2] = 'x';
8537057Smarks else
8547057Smarks buf[2] = '-';
8557057Smarks buf[3] = '\0';
8567057Smarks return (str_append(dstr, buf));
8570Sstevel@tonic-gate }
858789Sahrens
859789Sahrens /*
8601420Smarks * ace_acltotext() convert each ace formatted acl to look like this:
861789Sahrens *
8621420Smarks * entry_type:uid^gid^name:perms[:flags]:<allow|deny>[:id][,]
863789Sahrens *
864789Sahrens * The maximum length of entry_type is 5 ("group")
865789Sahrens *
8661420Smarks * The max length of a uid^gid^name entry (in theory) is 8,
8671420Smarks * however id could be a number so we therefore use ID_STR_MAX
868789Sahrens *
869789Sahrens * The length of a perms entry is 144 i.e read_data/write_data...
870789Sahrens * to each acl entry.
871789Sahrens *
8725331Samw * iflags: file_inherit/dir_inherit/inherit_only/no_propagate/successful_access
8735331Samw * /failed_access
874789Sahrens *
875789Sahrens */
876789Sahrens
877789Sahrens #define ACE_ENTRYTYPLEN 6
8785331Samw #define IFLAGS_STR "file_inherit/dir_inherit/inherit_only/no_propagate/" \
8795331Samw "successful_access/failed_access/inherited"
8805331Samw #define IFLAGS_SIZE (sizeof (IFLAGS_STR) - 1)
8811420Smarks #define ACCESS_TYPE_SIZE 7 /* if unknown */
882789Sahrens #define COLON_CNT 3
883789Sahrens #define PERMS_LEN 216
8845331Samw #define ACE_ENTRY_SIZE (ACE_ENTRYTYPLEN + ID_STR_MAX + PERMS_LEN + \
8851420Smarks ACCESS_TYPE_SIZE + IFLAGS_SIZE + COLON_CNT + APPENDED_ID_MAX)
886789Sahrens
887789Sahrens static char *
ace_acltotext(acl_t * aceaclp,int flags)8881420Smarks ace_acltotext(acl_t *aceaclp, int flags)
889789Sahrens {
890789Sahrens ace_t *aclp = aceaclp->acl_aclp;
891789Sahrens int aclcnt = aceaclp->acl_cnt;
8927057Smarks int i;
8937057Smarks int error = 0;
8947057Smarks int isdir = (aceaclp->acl_flags & ACL_IS_DIR);
8957057Smarks dynaclstr_t *dstr;
8967680SMark.Shellenbaum@Sun.COM char *aclexport = NULL;
89711605SGowtham.Thommandra@Sun.COM char *rawsidp = NULL;
898789Sahrens
899789Sahrens if (aclp == NULL)
900789Sahrens return (NULL);
901789Sahrens
9027057Smarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
9037057Smarks return (NULL);
9047057Smarks dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE;
9057057Smarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
9067057Smarks free(dstr);
9077057Smarks return (NULL);
9087057Smarks }
9097057Smarks *dstr->d_aclexport = '\0';
9107057Smarks dstr->d_pos = 0;
9117057Smarks
912789Sahrens for (i = 0; i < aclcnt; i++, aclp++) {
9131420Smarks
9147057Smarks if (error = ace_type_txt(dstr, aclp, flags))
9157057Smarks break;
9167057Smarks if (error = ace_perm_txt(dstr, aclp->a_access_mask,
9177057Smarks aclp->a_flags, isdir, flags))
9187057Smarks break;
9197057Smarks if (error = ace_inherit_txt(dstr, aclp->a_flags, flags))
9207057Smarks break;
9217057Smarks if (error = ace_access_txt(dstr, aclp->a_type))
9227057Smarks break;
923789Sahrens
9241420Smarks if ((flags & ACL_APPEND_ID) &&
9251420Smarks (((aclp->a_flags & ACE_TYPE_FLAGS) == 0) ||
9261420Smarks ((aclp->a_flags & ACE_TYPE_FLAGS) ==
9271420Smarks ACE_IDENTIFIER_GROUP))) {
9287057Smarks char id[ID_STR_MAX], *idstr;
9297057Smarks
9307057Smarks if (error = str_append(dstr, ":"))
9317057Smarks break;
9328268SMark.Shellenbaum@Sun.COM
9338268SMark.Shellenbaum@Sun.COM rawsidp = NULL;
9348268SMark.Shellenbaum@Sun.COM id[ID_STR_MAX -1] = '\0'; /* null terminate */
9358268SMark.Shellenbaum@Sun.COM if (aclp->a_who > MAXUID && (flags & ACL_SID_FMT)) {
9368268SMark.Shellenbaum@Sun.COM
9378268SMark.Shellenbaum@Sun.COM error = getsidname(aclp->a_who,
9388268SMark.Shellenbaum@Sun.COM ((aclp->a_flags & ACE_TYPE_FLAGS) == 0) ?
9398268SMark.Shellenbaum@Sun.COM B_TRUE : B_FALSE, &idstr, 1);
94011605SGowtham.Thommandra@Sun.COM rawsidp = idstr;
9418268SMark.Shellenbaum@Sun.COM if (error)
9428268SMark.Shellenbaum@Sun.COM break;
9438268SMark.Shellenbaum@Sun.COM } else if (aclp->a_who > MAXUID &&
9448268SMark.Shellenbaum@Sun.COM !(flags & ACL_NORESOLVE)) {
9458268SMark.Shellenbaum@Sun.COM idstr = lltostr(UID_NOBODY,
9468268SMark.Shellenbaum@Sun.COM &id[ID_STR_MAX - 1]);
9478268SMark.Shellenbaum@Sun.COM } else {
9488268SMark.Shellenbaum@Sun.COM idstr = lltostr(aclp->a_who,
9498268SMark.Shellenbaum@Sun.COM &id[ID_STR_MAX - 1]);
9508268SMark.Shellenbaum@Sun.COM }
9517057Smarks if (error = str_append(dstr, idstr))
9527057Smarks break;
95311605SGowtham.Thommandra@Sun.COM if (rawsidp) {
9548268SMark.Shellenbaum@Sun.COM free(rawsidp);
95511605SGowtham.Thommandra@Sun.COM rawsidp = NULL;
95611605SGowtham.Thommandra@Sun.COM }
957789Sahrens }
9581420Smarks if (i < aclcnt - 1) {
9597057Smarks if (error = str_append(dstr, ","))
9607057Smarks break;
961789Sahrens }
962789Sahrens }
96311605SGowtham.Thommandra@Sun.COM
96411605SGowtham.Thommandra@Sun.COM if (rawsidp)
96511605SGowtham.Thommandra@Sun.COM free(rawsidp);
9667057Smarks if (error) {
9677057Smarks if (dstr->d_aclexport)
9687057Smarks free(dstr->d_aclexport);
9697057Smarks } else {
9707057Smarks aclexport = dstr->d_aclexport;
9717057Smarks }
9727057Smarks free(dstr);
973789Sahrens return (aclexport);
974789Sahrens }
975789Sahrens
9761420Smarks char *
acl_totext(acl_t * aclp,int flags)9771420Smarks acl_totext(acl_t *aclp, int flags)
978789Sahrens {
9791420Smarks char *txtp;
980789Sahrens
981789Sahrens if (aclp == NULL)
982789Sahrens return (NULL);
983789Sahrens
984789Sahrens switch (aclp->acl_type) {
985789Sahrens case ACE_T:
9861420Smarks txtp = ace_acltotext(aclp, flags);
9871420Smarks break;
988789Sahrens case ACLENT_T:
9891420Smarks txtp = aclent_acltotext(aclp->acl_aclp, aclp->acl_cnt, flags);
9901420Smarks break;
991789Sahrens }
9921420Smarks
9931420Smarks return (txtp);
994789Sahrens }
995789Sahrens
996789Sahrens int
acl_fromtext(const char * acltextp,acl_t ** ret_aclp)997789Sahrens acl_fromtext(const char *acltextp, acl_t **ret_aclp)
998789Sahrens {
9991420Smarks int error;
10001420Smarks char *buf;
10011420Smarks
10021420Smarks buf = malloc(strlen(acltextp) + 2);
10031420Smarks if (buf == NULL)
10041420Smarks return (EACL_MEM_ERROR);
10051420Smarks strcpy(buf, acltextp);
10061420Smarks strcat(buf, "\n");
100711963SAfshin.Ardakani@Sun.COM
100811963SAfshin.Ardakani@Sun.COM (void) mutex_lock(&yymutex);
10091420Smarks yybuf = buf;
10101420Smarks yyreset();
10111420Smarks error = yyparse();
10121420Smarks free(buf);
10131420Smarks
10141420Smarks if (yyacl) {
10151420Smarks if (error == 0)
10161420Smarks *ret_aclp = yyacl;
10171420Smarks else {
10181420Smarks acl_free(yyacl);
10191420Smarks }
10201420Smarks yyacl = NULL;
10211420Smarks }
102211963SAfshin.Ardakani@Sun.COM (void) mutex_unlock(&yymutex);
102311963SAfshin.Ardakani@Sun.COM
10241420Smarks return (error);
10251420Smarks }
10261420Smarks
10271420Smarks int
acl_parse(const char * acltextp,acl_t ** aclp)10281420Smarks acl_parse(const char *acltextp, acl_t **aclp)
10291420Smarks {
1030789Sahrens int error;
1031789Sahrens
10321420Smarks yyinteractive = 1;
10331420Smarks error = acl_fromtext(acltextp, aclp);
10341420Smarks yyinteractive = 0;
10351420Smarks return (error);
10361420Smarks }
10371420Smarks
10381420Smarks static void
ace_compact_printacl(acl_t * aclp)10391420Smarks ace_compact_printacl(acl_t *aclp)
10401420Smarks {
10411420Smarks int cnt;
10421420Smarks ace_t *acep;
10437057Smarks dynaclstr_t *dstr;
10447057Smarks int len;
1045789Sahrens
10467057Smarks if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
10477057Smarks return;
10487057Smarks dstr->d_bufsize = ACE_ENTRY_SIZE;
10497057Smarks if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
10507057Smarks free(dstr);
10517057Smarks return;
10527057Smarks }
10537057Smarks *dstr->d_aclexport = '\0';
10547057Smarks
10557057Smarks dstr->d_pos = 0;
10561420Smarks for (cnt = 0, acep = aclp->acl_aclp;
10571420Smarks cnt != aclp->acl_cnt; cnt++, acep++) {
10587057Smarks dstr->d_aclexport[0] = '\0';
10597057Smarks dstr->d_pos = 0;
10607057Smarks
10617057Smarks if (ace_type_txt(dstr, acep, 0))
10627057Smarks break;
10637057Smarks len = strlen(&dstr->d_aclexport[0]);
10647057Smarks if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags,
10657057Smarks aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT))
10667057Smarks break;
10677057Smarks if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT))
10687057Smarks break;
10697057Smarks if (ace_access_txt(dstr, acep->a_type) == -1)
10707057Smarks break;
10717057Smarks (void) printf(" %20.*s%s\n", len, dstr->d_aclexport,
10727057Smarks &dstr->d_aclexport[len]);
10731420Smarks }
10747057Smarks
10757057Smarks if (dstr->d_aclexport)
10767057Smarks free(dstr->d_aclexport);
10777057Smarks free(dstr);
10781420Smarks }
1079789Sahrens
10801420Smarks static void
ace_printacl(acl_t * aclp,int cols,int compact)10811420Smarks ace_printacl(acl_t *aclp, int cols, int compact)
10821420Smarks {
10831420Smarks int slot = 0;
10841420Smarks char *token;
10851420Smarks char *acltext;
10861420Smarks
10871420Smarks if (compact) {
10881420Smarks ace_compact_printacl(aclp);
10891420Smarks return;
1090789Sahrens }
1091789Sahrens
10921420Smarks acltext = acl_totext(aclp, 0);
10931420Smarks
10941420Smarks if (acltext == NULL)
10951420Smarks return;
10961420Smarks
10971420Smarks token = strtok(acltext, ",");
10981420Smarks if (token == NULL) {
10991420Smarks free(acltext);
11001420Smarks return;
1101789Sahrens }
1102789Sahrens
11031420Smarks do {
11041420Smarks (void) printf(" %d:", slot++);
11051420Smarks split_line(token, cols - 5);
11061420Smarks } while (token = strtok(NULL, ","));
11071420Smarks free(acltext);
11081420Smarks }
11091420Smarks
11101420Smarks /*
11111420Smarks * pretty print an ACL.
11121420Smarks * For aclent_t ACL's the format is
11131420Smarks * similar to the old format used by getfacl,
11141420Smarks * with the addition of adding a "slot" number
11151420Smarks * before each entry.
11161420Smarks *
11171420Smarks * for ace_t ACL's the cols variable will break up
11181420Smarks * the long lines into multiple lines and will also
11191420Smarks * print a "slot" number.
11201420Smarks */
11211420Smarks void
acl_printacl(acl_t * aclp,int cols,int compact)11221420Smarks acl_printacl(acl_t *aclp, int cols, int compact)
11231420Smarks {
11241420Smarks
11251420Smarks switch (aclp->acl_type) {
11261420Smarks case ACLENT_T:
11271420Smarks aclent_printacl(aclp);
11281420Smarks break;
11291420Smarks case ACE_T:
11301420Smarks ace_printacl(aclp, cols, compact);
11311420Smarks break;
11321420Smarks }
11331420Smarks }
11341420Smarks
11351420Smarks typedef struct value_table {
11361420Smarks char p_letter; /* perm letter such as 'r' */
11371420Smarks uint32_t p_value; /* value for perm when pletter found */
11381420Smarks } value_table_t;
11391420Smarks
11401420Smarks /*
11415331Samw * The permission tables are laid out in positional order
11421420Smarks * a '-' character will indicate a permission at a given
11431420Smarks * position is not specified. The '-' is not part of the
11441420Smarks * table, but will be checked for in the permission computation
11451420Smarks * routine.
11461420Smarks */
11475331Samw value_table_t ace_perm_table[] = {
11481420Smarks { 'r', ACE_READ_DATA},
11491420Smarks { 'w', ACE_WRITE_DATA},
11501420Smarks { 'x', ACE_EXECUTE},
11511420Smarks { 'p', ACE_APPEND_DATA},
11521420Smarks { 'd', ACE_DELETE},
11531420Smarks { 'D', ACE_DELETE_CHILD},
11541420Smarks { 'a', ACE_READ_ATTRIBUTES},
11551420Smarks { 'A', ACE_WRITE_ATTRIBUTES},
11561420Smarks { 'R', ACE_READ_NAMED_ATTRS},
11571420Smarks { 'W', ACE_WRITE_NAMED_ATTRS},
11581420Smarks { 'c', ACE_READ_ACL},
11591420Smarks { 'C', ACE_WRITE_ACL},
11601420Smarks { 'o', ACE_WRITE_OWNER},
11611420Smarks { 's', ACE_SYNCHRONIZE}
11621420Smarks };
11631420Smarks
11645331Samw #define ACE_PERM_COUNT (sizeof (ace_perm_table) / sizeof (value_table_t))
11651420Smarks
11665331Samw value_table_t aclent_perm_table[] = {
11671420Smarks { 'r', S_IROTH},
11681420Smarks { 'w', S_IWOTH},
11691420Smarks { 'x', S_IXOTH}
11701420Smarks };
11711420Smarks
11725331Samw #define ACLENT_PERM_COUNT (sizeof (aclent_perm_table) / sizeof (value_table_t))
11735331Samw
11745331Samw value_table_t inherit_table[] = {
11751420Smarks {'f', ACE_FILE_INHERIT_ACE},
11761420Smarks {'d', ACE_DIRECTORY_INHERIT_ACE},
11771420Smarks {'i', ACE_INHERIT_ONLY_ACE},
11781420Smarks {'n', ACE_NO_PROPAGATE_INHERIT_ACE},
11791420Smarks {'S', ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
11805331Samw {'F', ACE_FAILED_ACCESS_ACE_FLAG},
11815331Samw {'I', ACE_INHERITED_ACE}
11821420Smarks };
11831420Smarks
11845331Samw #define IFLAG_COUNT (sizeof (inherit_table) / sizeof (value_table_t))
11856269Smarks #define IFLAG_COUNT_V1 6 /* Older version compatibility */
11865331Samw
11871420Smarks /*
11881420Smarks * compute value from a permission table or inheritance table
11891420Smarks * based on string passed in. If positional is set then
11901420Smarks * string must match order in permtab, otherwise any order
11911420Smarks * is allowed.
11921420Smarks */
11931420Smarks int
compute_values(value_table_t * permtab,int count,char * permstr,int positional,uint32_t * mask)11941420Smarks compute_values(value_table_t *permtab, int count,
11951420Smarks char *permstr, int positional, uint32_t *mask)
11961420Smarks {
11971420Smarks uint32_t perm_val = 0;
11981420Smarks char *pstr;
11991420Smarks int i, found;
12001420Smarks
12011420Smarks if (count < 0)
12021420Smarks return (1);
12031420Smarks
12041420Smarks if (positional) {
12051420Smarks for (i = 0, pstr = permstr; i != count && pstr &&
12061420Smarks *pstr; i++, pstr++) {
12071420Smarks if (*pstr == permtab[i].p_letter) {
12081420Smarks perm_val |= permtab[i].p_value;
12091420Smarks } else if (*pstr != '-') {
12101420Smarks return (1);
12111420Smarks }
1212789Sahrens }
12131420Smarks } else { /* random order single letters with no '-' */
12141420Smarks for (pstr = permstr; pstr && *pstr; pstr++) {
12151420Smarks for (found = 0, i = 0; i != count; i++) {
12161420Smarks if (*pstr == permtab[i].p_letter) {
12171420Smarks perm_val |= permtab[i].p_value;
12181420Smarks found = 1;
12191420Smarks break;
12201420Smarks }
12211420Smarks }
12221420Smarks if (found == 0)
12231420Smarks return (1);
12241420Smarks }
1225789Sahrens }
1226789Sahrens
12271420Smarks *mask = perm_val;
12281420Smarks return (0);
12291420Smarks }
1230789Sahrens
12316269Smarks
12326269Smarks int
ace_inherit_helper(char * str,uint32_t * imask,int table_length)12336269Smarks ace_inherit_helper(char *str, uint32_t *imask, int table_length)
12346269Smarks {
12356269Smarks int rc = 0;
12366269Smarks
12376269Smarks if (strlen(str) == table_length) {
12386269Smarks /*
12396269Smarks * If the string == table_length then first check to see it's
12406269Smarks * in positional format. If that fails then see if it's in
12416269Smarks * non-positional format.
12426269Smarks */
12436269Smarks if (compute_values(inherit_table, table_length, str,
12446269Smarks 1, imask) && compute_values(inherit_table,
12456269Smarks table_length, str, 0, imask)) {
12466269Smarks rc = 1;
12476269Smarks }
12486269Smarks } else {
12496269Smarks rc = compute_values(inherit_table, table_length, str, 0, imask);
12506269Smarks }
12516269Smarks
12526269Smarks return (rc ? EACL_INHERIT_ERROR : 0);
12536269Smarks }
12546269Smarks
12551420Smarks /*
12561420Smarks * compute value for inheritance flags.
12571420Smarks */
12581420Smarks int
compute_ace_inherit(char * str,uint32_t * imask)12591420Smarks compute_ace_inherit(char *str, uint32_t *imask)
12601420Smarks {
12616269Smarks int rc = 0;
1262789Sahrens
12636269Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT);
12646269Smarks
12656269Smarks if (rc && strlen(str) != IFLAG_COUNT) {
12661420Smarks
12676269Smarks /* is it an old formatted inherit string? */
12686269Smarks rc = ace_inherit_helper(str, imask, IFLAG_COUNT_V1);
12696269Smarks }
12701420Smarks
12716269Smarks return (rc);
1272789Sahrens }
12731420Smarks
12741420Smarks
12751420Smarks /*
12761420Smarks * compute value for ACE permissions.
12771420Smarks */
12781420Smarks int
compute_ace_perms(char * str,uint32_t * mask)12791420Smarks compute_ace_perms(char *str, uint32_t *mask)
12801420Smarks {
12811420Smarks int positional = 0;
12821420Smarks int error;
12831420Smarks
12841420Smarks if (strlen(str) == ACE_PERM_COUNT)
12851420Smarks positional = 1;
12861420Smarks
12871420Smarks error = compute_values(ace_perm_table, ACE_PERM_COUNT,
12881420Smarks str, positional, mask);
12891420Smarks
12901420Smarks if (error && positional) {
12911420Smarks /*
12921420Smarks * If positional was set, then make sure permissions
12931420Smarks * aren't actually valid in non positional case where
12941420Smarks * all permissions are specified, just in random order.
12951420Smarks */
12961420Smarks error = compute_values(ace_perm_table,
12971420Smarks ACE_PERM_COUNT, str, 0, mask);
12981420Smarks }
12991420Smarks if (error)
13001420Smarks error = EACL_PERM_MASK_ERROR;
13011420Smarks
13021420Smarks return (error);
13031420Smarks }
13041420Smarks
13051420Smarks
13061420Smarks
13071420Smarks /*
13081420Smarks * compute values for aclent permissions.
13091420Smarks */
13101420Smarks int
compute_aclent_perms(char * str,o_mode_t * mask)13111420Smarks compute_aclent_perms(char *str, o_mode_t *mask)
13121420Smarks {
13131420Smarks int error;
13141420Smarks uint32_t pmask;
13151420Smarks
13161420Smarks if (strlen(str) != ACLENT_PERM_COUNT)
13171420Smarks return (EACL_PERM_MASK_ERROR);
13181420Smarks
13191420Smarks *mask = 0;
13201420Smarks error = compute_values(aclent_perm_table, ACLENT_PERM_COUNT,
13211420Smarks str, 1, &pmask);
13221420Smarks if (error == 0) {
13231420Smarks *mask = (o_mode_t)pmask;
13241420Smarks } else
13251420Smarks error = EACL_PERM_MASK_ERROR;
13261420Smarks return (error);
13271420Smarks }
13281420Smarks
13291420Smarks /*
13301420Smarks * determine ACE permissions.
13311420Smarks */
13321420Smarks int
ace_perm_mask(struct acl_perm_type * aclperm,uint32_t * mask)13331420Smarks ace_perm_mask(struct acl_perm_type *aclperm, uint32_t *mask)
13341420Smarks {
13351420Smarks int error;
13361420Smarks
13371420Smarks if (aclperm->perm_style == PERM_TYPE_EMPTY) {
13381420Smarks *mask = 0;
13391420Smarks return (0);
13401420Smarks }
13411420Smarks
13421420Smarks if (aclperm->perm_style == PERM_TYPE_ACE) {
13431420Smarks *mask = aclperm->perm_val;
13441420Smarks return (0);
13451420Smarks }
13461420Smarks
13471420Smarks error = compute_ace_perms(aclperm->perm_str, mask);
13481420Smarks if (error) {
13491567Smarks acl_error(dgettext(TEXT_DOMAIN,
13501567Smarks "Invalid permission(s) '%s' specified\n"),
13511420Smarks aclperm->perm_str);
13521420Smarks return (EACL_PERM_MASK_ERROR);
13531420Smarks }
13541420Smarks
13551420Smarks return (0);
13561420Smarks }
1357