3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*LINTLIBRARY*/
27
28 #include <grp.h>
29 #include <pwd.h>
30 #include <string.h>
31 #include <limits.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/acl.h>
38 #include <aclutils.h>
39 #include <idmap.h>
40 #include <synch.h>
41
42 #define ID_STR_MAX 20 /* digits in LONG_MAX */
43
155 idmap_get_mappings(get_hdl) == 0) {
156 if (status == IDMAP_SUCCESS) {
157 len = snprintf(NULL, 0,
158 "%s-%d", domain, rid);
159 if (*sidp = malloc(len + 1)) {
160 (void) snprintf(*sidp, len + 1,
161 "%s-%d", domain, rid);
162 }
163 }
164 }
165 }
166 if (get_hdl)
167 idmap_get_destroy(get_hdl);
168 }
169
170 free(domain);
171
172 return (*sidp ? 0 : 1);
173 }
174
175 static void
176 aclent_printacl(acl_t *aclp)
177 {
178 aclent_t *tp;
179 int aclcnt;
180 int mask;
181 int slot = 0;
182 char perm[4];
183 char uidp[ID_STR_MAX];
184 char gidp[ID_STR_MAX];
185
186 /* display ACL: assume it is sorted. */
187 aclcnt = aclp->acl_cnt;
188 for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) {
189 if (tp->a_type == CLASS_OBJ)
190 mask = tp->a_perm;
191 }
192 aclcnt = aclp->acl_cnt;
193 for (tp = aclp->acl_aclp; aclcnt--; tp++) {
194 (void) printf(" %d:", slot++);
399 break;
400 if (error = getsidname(acep->a_who, B_FALSE,
401 &sidp, flags & ACL_NORESOLVE))
402 break;
403 error = str_append(dynstr, sidp);
404 } else {
405 if (error = str_append(dynstr, GROUP_TXT))
406 break;
407 error = str_append(dynstr, prgname(acep->a_who, idp,
408 sizeof (idp), flags & ACL_NORESOLVE));
409 }
410 if (error == 0)
411 error = str_append(dynstr, ":");
412 break;
413
414 case ACE_EVERYONE:
415 error = str_append(dynstr, EVERYONEAT_TXT);
416 break;
417
418 case 0:
419 if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {
420 if (error = str_append(dynstr, USERSID_TXT))
421 break;
422 if (error = getsidname(acep->a_who, B_TRUE,
423 &sidp, flags & ACL_NORESOLVE))
424 break;
425 error = str_append(dynstr, sidp);
426 } else {
427 if (error = str_append(dynstr, USER_TXT))
428 break;
429 error = str_append(dynstr, pruname(acep->a_who, idp,
430 sizeof (idp), flags & ACL_NORESOLVE));
431 }
432 if (error == 0)
433 error = str_append(dynstr, ":");
434 break;
435 default:
436 error = 0;
437 break;
438 }
439
440 if (sidp)
441 free(sidp);
442 return (error);
443 }
444
445 /*
446 * compute string of permissions, such as read_data/write_data or
1011 }
1012 yyacl = NULL;
1013 }
1014 (void) mutex_unlock(&yymutex);
1015
1016 return (error);
1017 }
1018
1019 int
1020 acl_parse(const char *acltextp, acl_t **aclp)
1021 {
1022 int error;
1023
1024 yyinteractive = 1;
1025 error = acl_fromtext(acltextp, aclp);
1026 yyinteractive = 0;
1027 return (error);
1028 }
1029
1030 static void
1031 ace_compact_printacl(acl_t *aclp)
1032 {
1033 int cnt;
1034 ace_t *acep;
1035 dynaclstr_t *dstr;
1036 int len;
1037
1038 if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
1039 return;
1040 dstr->d_bufsize = ACE_ENTRY_SIZE;
1041 if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
1042 free(dstr);
1043 return;
1044 }
1045 *dstr->d_aclexport = '\0';
1046
1047 dstr->d_pos = 0;
1048 for (cnt = 0, acep = aclp->acl_aclp;
1049 cnt != aclp->acl_cnt; cnt++, acep++) {
1050 dstr->d_aclexport[0] = '\0';
1051 dstr->d_pos = 0;
1052
1053 if (ace_type_txt(dstr, acep, 0))
1054 break;
1055 len = strlen(&dstr->d_aclexport[0]);
1056 if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags,
1057 aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT))
1058 break;
1059 if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT))
1060 break;
1061 if (ace_access_txt(dstr, acep->a_type) == -1)
1062 break;
1063 (void) printf(" %20.*s%s\n", len, dstr->d_aclexport,
1064 &dstr->d_aclexport[len]);
1065 }
1066
1067 if (dstr->d_aclexport)
1068 free(dstr->d_aclexport);
1069 free(dstr);
1070 }
1071
1072 static void
1073 ace_printacl(acl_t *aclp, int cols, int compact)
1074 {
1075 int slot = 0;
1076 char *token;
1077 char *acltext;
1078
1079 if (compact) {
1080 ace_compact_printacl(aclp);
1081 return;
1082 }
1083
1084 acltext = acl_totext(aclp, 0);
1085
1086 if (acltext == NULL)
1087 return;
1088
1089 token = strtok(acltext, ",");
1090 if (token == NULL) {
1091 free(acltext);
1092 return;
1093 }
1094
1095 do {
1096 (void) printf(" %d:", slot++);
1097 split_line(token, cols - 5);
1098 } while (token = strtok(NULL, ","));
1099 free(acltext);
1100 }
1101
1102 /*
1103 * pretty print an ACL.
1104 * For aclent_t ACL's the format is
1105 * similar to the old format used by getfacl,
1106 * with the addition of adding a "slot" number
1107 * before each entry.
1108 *
1109 * for ace_t ACL's the cols variable will break up
1110 * the long lines into multiple lines and will also
1111 * print a "slot" number.
1112 */
1113 void
1114 acl_printacl(acl_t *aclp, int cols, int compact)
1115 {
1116
1117 switch (aclp->acl_type) {
1118 case ACLENT_T:
1119 aclent_printacl(aclp);
1120 break;
1121 case ACE_T:
1122 ace_printacl(aclp, cols, compact);
1123 break;
1124 }
1125 }
1126
1127 typedef struct value_table {
1128 char p_letter; /* perm letter such as 'r' */
1129 uint32_t p_value; /* value for perm when pletter found */
1130 } value_table_t;
1131
1132 /*
1133 * The permission tables are laid out in positional order
1134 * a '-' character will indicate a permission at a given
1135 * position is not specified. The '-' is not part of the
1136 * table, but will be checked for in the permission computation
1137 * routine.
1138 */
1139 value_table_t ace_perm_table[] = {
1140 { 'r', ACE_READ_DATA},
1141 { 'w', ACE_WRITE_DATA},
1142 { 'x', ACE_EXECUTE},
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*LINTLIBRARY*/
27
28 #include <grp.h>
29 #include <pwd.h>
30 #include <string.h>
31 #include <limits.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/acl.h>
38 #include <aclutils.h>
39 #include <idmap.h>
40 #include <synch.h>
41
42 #define ID_STR_MAX 20 /* digits in LONG_MAX */
43
155 idmap_get_mappings(get_hdl) == 0) {
156 if (status == IDMAP_SUCCESS) {
157 len = snprintf(NULL, 0,
158 "%s-%d", domain, rid);
159 if (*sidp = malloc(len + 1)) {
160 (void) snprintf(*sidp, len + 1,
161 "%s-%d", domain, rid);
162 }
163 }
164 }
165 }
166 if (get_hdl)
167 idmap_get_destroy(get_hdl);
168 }
169
170 free(domain);
171
172 return (*sidp ? 0 : 1);
173 }
174
175 /*
176 * sid_string_by_id() is an exposed interface via -lsec
177 */
178 int
179 sid_string_by_id(uid_t who, boolean_t user, char **sidp, boolean_t noresolve)
180 {
181 return (getsidname(who, user, sidp, noresolve));
182 }
183
184 static void
185 aclent_printacl(acl_t *aclp)
186 {
187 aclent_t *tp;
188 int aclcnt;
189 int mask;
190 int slot = 0;
191 char perm[4];
192 char uidp[ID_STR_MAX];
193 char gidp[ID_STR_MAX];
194
195 /* display ACL: assume it is sorted. */
196 aclcnt = aclp->acl_cnt;
197 for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) {
198 if (tp->a_type == CLASS_OBJ)
199 mask = tp->a_perm;
200 }
201 aclcnt = aclp->acl_cnt;
202 for (tp = aclp->acl_aclp; aclcnt--; tp++) {
203 (void) printf(" %d:", slot++);
408 break;
409 if (error = getsidname(acep->a_who, B_FALSE,
410 &sidp, flags & ACL_NORESOLVE))
411 break;
412 error = str_append(dynstr, sidp);
413 } else {
414 if (error = str_append(dynstr, GROUP_TXT))
415 break;
416 error = str_append(dynstr, prgname(acep->a_who, idp,
417 sizeof (idp), flags & ACL_NORESOLVE));
418 }
419 if (error == 0)
420 error = str_append(dynstr, ":");
421 break;
422
423 case ACE_EVERYONE:
424 error = str_append(dynstr, EVERYONEAT_TXT);
425 break;
426
427 case 0:
428 if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID &&
429 (flags & ACL_EPHEMERAL) == 0) {
430 if (error = str_append(dynstr, USERSID_TXT))
431 break;
432 if (error = getsidname(acep->a_who, B_TRUE,
433 &sidp, flags & ACL_NORESOLVE))
434 break;
435 error = str_append(dynstr, sidp);
436 } else {
437 flags &= ~ACL_NORESOLVE;
438 if (error = str_append(dynstr, USER_TXT))
439 break;
440 error = str_append(dynstr, pruname(acep->a_who, idp,
441 sizeof (idp), flags & ACL_NORESOLVE));
442 }
443 if (error == 0)
444 error = str_append(dynstr, ":");
445 break;
446 default:
447 error = 0;
448 break;
449 }
450
451 if (sidp)
452 free(sidp);
453 return (error);
454 }
455
456 /*
457 * compute string of permissions, such as read_data/write_data or
1022 }
1023 yyacl = NULL;
1024 }
1025 (void) mutex_unlock(&yymutex);
1026
1027 return (error);
1028 }
1029
1030 int
1031 acl_parse(const char *acltextp, acl_t **aclp)
1032 {
1033 int error;
1034
1035 yyinteractive = 1;
1036 error = acl_fromtext(acltextp, aclp);
1037 yyinteractive = 0;
1038 return (error);
1039 }
1040
1041 static void
1042 ace_compact_printacl(acl_t *aclp, int flgs)
1043 {
1044 int cnt;
1045 ace_t *acep;
1046 dynaclstr_t *dstr;
1047 int len;
1048
1049 if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
1050 return;
1051 dstr->d_bufsize = ACE_ENTRY_SIZE;
1052 if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
1053 free(dstr);
1054 return;
1055 }
1056 *dstr->d_aclexport = '\0';
1057
1058 dstr->d_pos = 0;
1059 for (cnt = 0, acep = aclp->acl_aclp;
1060 cnt != aclp->acl_cnt; cnt++, acep++) {
1061 dstr->d_aclexport[0] = '\0';
1062 dstr->d_pos = 0;
1063
1064 if (ace_type_txt(dstr, acep, flgs))
1065 break;
1066 len = strlen(&dstr->d_aclexport[0]);
1067 if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags,
1068 aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT))
1069 break;
1070 if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT))
1071 break;
1072 if (ace_access_txt(dstr, acep->a_type) == -1)
1073 break;
1074 (void) printf(" %20.*s%s\n", len, dstr->d_aclexport,
1075 &dstr->d_aclexport[len]);
1076 }
1077
1078 if (dstr->d_aclexport)
1079 free(dstr->d_aclexport);
1080 free(dstr);
1081 }
1082
1083 static void
1084 ace_printacl(acl_t *aclp, int cols, int flgs)
1085 {
1086 int slot = 0;
1087 char *token;
1088 char *acltext;
1089
1090 if (flgs & ACL_COMPACT_FMT) {
1091 ace_compact_printacl(aclp, flgs);
1092 return;
1093 }
1094
1095 acltext = acl_totext(aclp, flgs);
1096
1097 if (acltext == NULL)
1098 return;
1099
1100 token = strtok(acltext, ",");
1101 if (token == NULL) {
1102 free(acltext);
1103 return;
1104 }
1105
1106 do {
1107 (void) printf(" %d:", slot++);
1108 split_line(token, cols - 5);
1109 } while (token = strtok(NULL, ","));
1110 free(acltext);
1111 }
1112
1113 /*
1114 * pretty print an ACL.
1115 * For aclent_t ACL's the format is
1116 * similar to the old format used by getfacl,
1117 * with the addition of adding a "slot" number
1118 * before each entry.
1119 *
1120 * for ace_t ACL's the cols variable will break up
1121 * the long lines into multiple lines and will also
1122 * print a "slot" number.
1123 */
1124 void
1125 acl_printacl(acl_t *aclp, int cols, int flgs)
1126 {
1127
1128 switch (aclp->acl_type) {
1129 case ACLENT_T:
1130 aclent_printacl(aclp);
1131 break;
1132 case ACE_T:
1133 ace_printacl(aclp, cols, flgs);
1134 break;
1135 }
1136 }
1137
1138 typedef struct value_table {
1139 char p_letter; /* perm letter such as 'r' */
1140 uint32_t p_value; /* value for perm when pletter found */
1141 } value_table_t;
1142
1143 /*
1144 * The permission tables are laid out in positional order
1145 * a '-' character will indicate a permission at a given
1146 * position is not specified. The '-' is not part of the
1147 * table, but will be checked for in the permission computation
1148 * routine.
1149 */
1150 value_table_t ace_perm_table[] = {
1151 { 'r', ACE_READ_DATA},
1152 { 'w', ACE_WRITE_DATA},
1153 { 'x', ACE_EXECUTE},
|