Print this page
NEX-1767 ls is unable to display SIDs
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
SUP-795 IDMAP: idmap_getwinnamebyuid() and idmap_getwinnamebygid() fails for empty domains
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libsec/common/acltext.c
+++ new/usr/src/lib/libsec/common/acltext.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 26 /*LINTLIBRARY*/
27 27
28 28 #include <grp.h>
29 29 #include <pwd.h>
30 30 #include <string.h>
31 31 #include <limits.h>
32 32 #include <stdlib.h>
33 33 #include <errno.h>
34 34 #include <sys/param.h>
35 35 #include <sys/types.h>
36 36 #include <sys/stat.h>
37 37 #include <sys/acl.h>
38 38 #include <aclutils.h>
39 39 #include <idmap.h>
40 40 #include <synch.h>
41 41
42 42 #define ID_STR_MAX 20 /* digits in LONG_MAX */
43 43
44 44 #define APPENDED_ID_MAX ID_STR_MAX + 1 /* id + colon */
45 45 /*
46 46 * yyinteractive controls whether yyparse should print out
47 47 * error messages to stderr, and whether or not id's should be
48 48 * allowed from acl_fromtext().
49 49 */
50 50 int yyinteractive;
51 51 acl_t *yyacl;
52 52 char *yybuf;
53 53 mutex_t yymutex;
54 54
55 55 extern acl_t *acl_alloc(enum acl_type);
56 56
57 57 /*
58 58 * dynamic string that will increase in size on an
59 59 * as needed basis.
60 60 */
61 61 typedef struct dynaclstr {
62 62 size_t d_bufsize; /* current size of aclexport */
63 63 char *d_aclexport;
64 64 int d_pos;
65 65 } dynaclstr_t;
66 66
67 67 static int str_append(dynaclstr_t *, char *);
68 68 static int aclent_perm_txt(dynaclstr_t *, o_mode_t);
69 69
70 70 static void
71 71 aclent_perms(int perm, char *txt_perms)
72 72 {
73 73 if (perm & S_IROTH)
74 74 txt_perms[0] = 'r';
75 75 else
76 76 txt_perms[0] = '-';
77 77 if (perm & S_IWOTH)
78 78 txt_perms[1] = 'w';
79 79 else
80 80 txt_perms[1] = '-';
81 81 if (perm & S_IXOTH)
82 82 txt_perms[2] = 'x';
83 83 else
84 84 txt_perms[2] = '-';
85 85 txt_perms[3] = '\0';
86 86 }
87 87
88 88 static char *
89 89 pruname(uid_t uid, char *uidp, size_t buflen, int noresolve)
90 90 {
91 91 struct passwd *passwdp = NULL;
92 92
93 93 if (noresolve == 0)
94 94 passwdp = getpwuid(uid);
95 95 if (passwdp == (struct passwd *)NULL) {
96 96 /* could not get passwd information: display uid instead */
97 97 (void) snprintf(uidp, buflen, "%u", uid);
98 98 } else {
99 99 (void) strlcpy(uidp, passwdp->pw_name, buflen);
100 100 }
101 101 return (uidp);
102 102 }
103 103
104 104 static char *
105 105 prgname(gid_t gid, char *gidp, size_t buflen, int noresolve)
106 106 {
107 107 struct group *groupp = NULL;
108 108
109 109 if (noresolve == 0)
110 110 groupp = getgrgid(gid);
111 111 if (groupp == (struct group *)NULL) {
112 112 /* could not get group information: display gid instead */
113 113 (void) snprintf(gidp, buflen, "%u", gid);
114 114 } else {
115 115 (void) strlcpy(gidp, groupp->gr_name, buflen);
116 116 }
117 117 return (gidp);
118 118 }
119 119
120 120 static int
121 121 getsidname(uid_t who, boolean_t user, char **sidp, boolean_t noresolve)
122 122 {
123 123 idmap_get_handle_t *get_hdl = NULL;
124 124 idmap_stat status;
125 125 idmap_rid_t rid;
126 126 int error = IDMAP_ERR_NORESULT;
127 127 int len;
128 128 char *domain = NULL;
129 129
130 130 *sidp = NULL;
131 131
132 132 /*
133 133 * First try and get windows name
134 134 */
135 135
136 136 if (!noresolve) {
137 137 if (user)
138 138 error = idmap_getwinnamebyuid(who,
139 139 IDMAP_REQ_FLG_USE_CACHE, sidp, NULL);
140 140 else
141 141 error = idmap_getwinnamebygid(who,
142 142 IDMAP_REQ_FLG_USE_CACHE, sidp, NULL);
143 143 }
144 144 if (error != IDMAP_SUCCESS) {
145 145 if (idmap_get_create(&get_hdl) == IDMAP_SUCCESS) {
146 146 if (user)
147 147 error = idmap_get_sidbyuid(get_hdl, who,
148 148 IDMAP_REQ_FLG_USE_CACHE, &domain, &rid,
149 149 &status);
150 150 else
151 151 error = idmap_get_sidbygid(get_hdl, who,
152 152 IDMAP_REQ_FLG_USE_CACHE, &domain, &rid,
153 153 &status);
154 154 if (error == IDMAP_SUCCESS &&
155 155 idmap_get_mappings(get_hdl) == 0) {
156 156 if (status == IDMAP_SUCCESS) {
157 157 len = snprintf(NULL, 0,
158 158 "%s-%d", domain, rid);
159 159 if (*sidp = malloc(len + 1)) {
160 160 (void) snprintf(*sidp, len + 1,
161 161 "%s-%d", domain, rid);
162 162 }
163 163 }
164 164 }
|
↓ open down ↓ |
131 lines elided |
↑ open up ↑ |
165 165 }
166 166 if (get_hdl)
167 167 idmap_get_destroy(get_hdl);
168 168 }
169 169
170 170 free(domain);
171 171
172 172 return (*sidp ? 0 : 1);
173 173 }
174 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 +
175 184 static void
176 185 aclent_printacl(acl_t *aclp)
177 186 {
178 187 aclent_t *tp;
179 188 int aclcnt;
180 189 int mask;
181 190 int slot = 0;
182 191 char perm[4];
183 192 char uidp[ID_STR_MAX];
184 193 char gidp[ID_STR_MAX];
185 194
186 195 /* display ACL: assume it is sorted. */
187 196 aclcnt = aclp->acl_cnt;
188 197 for (tp = aclp->acl_aclp; tp && aclcnt--; tp++) {
189 198 if (tp->a_type == CLASS_OBJ)
190 199 mask = tp->a_perm;
191 200 }
192 201 aclcnt = aclp->acl_cnt;
193 202 for (tp = aclp->acl_aclp; aclcnt--; tp++) {
194 203 (void) printf(" %d:", slot++);
195 204 switch (tp->a_type) {
196 205 case USER:
197 206 aclent_perms(tp->a_perm, perm);
198 207 (void) printf("user:%s:%s\t\t",
199 208 pruname(tp->a_id, uidp, sizeof (uidp), 0), perm);
200 209 aclent_perms((tp->a_perm & mask), perm);
201 210 (void) printf("#effective:%s\n", perm);
202 211 break;
203 212 case USER_OBJ:
204 213 /* no need to display uid */
205 214 aclent_perms(tp->a_perm, perm);
206 215 (void) printf("user::%s\n", perm);
207 216 break;
208 217 case GROUP:
209 218 aclent_perms(tp->a_perm, perm);
210 219 (void) printf("group:%s:%s\t\t",
211 220 prgname(tp->a_id, gidp, sizeof (gidp), 0), perm);
212 221 aclent_perms(tp->a_perm & mask, perm);
213 222 (void) printf("#effective:%s\n", perm);
214 223 break;
215 224 case GROUP_OBJ:
216 225 aclent_perms(tp->a_perm, perm);
217 226 (void) printf("group::%s\t\t", perm);
218 227 aclent_perms(tp->a_perm & mask, perm);
219 228 (void) printf("#effective:%s\n", perm);
220 229 break;
221 230 case CLASS_OBJ:
222 231 aclent_perms(tp->a_perm, perm);
223 232 (void) printf("mask:%s\n", perm);
224 233 break;
225 234 case OTHER_OBJ:
226 235 aclent_perms(tp->a_perm, perm);
227 236 (void) printf("other:%s\n", perm);
228 237 break;
229 238 case DEF_USER:
230 239 aclent_perms(tp->a_perm, perm);
231 240 (void) printf("default:user:%s:%s\n",
232 241 pruname(tp->a_id, uidp, sizeof (uidp), 0), perm);
233 242 break;
234 243 case DEF_USER_OBJ:
235 244 aclent_perms(tp->a_perm, perm);
236 245 (void) printf("default:user::%s\n", perm);
237 246 break;
238 247 case DEF_GROUP:
239 248 aclent_perms(tp->a_perm, perm);
240 249 (void) printf("default:group:%s:%s\n",
241 250 prgname(tp->a_id, gidp, sizeof (gidp), 0), perm);
242 251 break;
243 252 case DEF_GROUP_OBJ:
244 253 aclent_perms(tp->a_perm, perm);
245 254 (void) printf("default:group::%s\n", perm);
246 255 break;
247 256 case DEF_CLASS_OBJ:
248 257 aclent_perms(tp->a_perm, perm);
249 258 (void) printf("default:mask:%s\n", perm);
250 259 break;
251 260 case DEF_OTHER_OBJ:
252 261 aclent_perms(tp->a_perm, perm);
253 262 (void) printf("default:other:%s\n", perm);
254 263 break;
255 264 default:
256 265 (void) fprintf(stderr,
257 266 dgettext(TEXT_DOMAIN, "unrecognized entry\n"));
258 267 break;
259 268 }
260 269 }
261 270 }
262 271
263 272 static void
264 273 split_line(char *str, int cols)
265 274 {
266 275 char *ptr;
267 276 int len;
268 277 int i;
269 278 int last_split;
270 279 char *pad = "";
271 280 int pad_len;
272 281
273 282 len = strlen(str);
274 283 ptr = str;
275 284 pad_len = 0;
276 285
277 286 ptr = str;
278 287 last_split = 0;
279 288 for (i = 0; i != len; i++) {
280 289 if ((i + pad_len + 4) >= cols) {
281 290 (void) printf("%s%.*s\n", pad, last_split, ptr);
282 291 ptr = &ptr[last_split];
283 292 len = strlen(ptr);
284 293 i = 0;
285 294 pad_len = 4;
286 295 pad = " ";
287 296 } else {
288 297 if (ptr[i] == '/' || ptr[i] == ':') {
289 298 last_split = i;
290 299 }
291 300 }
292 301 }
293 302 if (i == len) {
294 303 (void) printf("%s%s\n", pad, ptr);
295 304 }
296 305 }
297 306
298 307 /*
299 308 * compute entry type string, such as user:joe, group:staff,...
300 309 */
301 310 static int
302 311 aclent_type_txt(dynaclstr_t *dstr, aclent_t *aclp, int flags)
303 312 {
304 313 char idp[ID_STR_MAX];
305 314 int error;
306 315
307 316 switch (aclp->a_type) {
308 317 case DEF_USER_OBJ:
309 318 case USER_OBJ:
310 319 if (aclp->a_type == USER_OBJ)
311 320 error = str_append(dstr, "user::");
312 321 else
313 322 error = str_append(dstr, "defaultuser::");
314 323 break;
315 324
316 325 case DEF_USER:
317 326 case USER:
318 327 if (aclp->a_type == USER)
319 328 error = str_append(dstr, "user:");
320 329 else
321 330 error = str_append(dstr, "defaultuser:");
322 331 if (error)
323 332 break;
324 333 error = str_append(dstr, pruname(aclp->a_id, idp,
325 334 sizeof (idp), flags & ACL_NORESOLVE));
326 335 if (error == 0)
327 336 error = str_append(dstr, ":");
328 337 break;
329 338
330 339 case DEF_GROUP_OBJ:
331 340 case GROUP_OBJ:
332 341 if (aclp->a_type == GROUP_OBJ)
333 342 error = str_append(dstr, "group::");
334 343 else
335 344 error = str_append(dstr, "defaultgroup::");
336 345 break;
337 346
338 347 case DEF_GROUP:
339 348 case GROUP:
340 349 if (aclp->a_type == GROUP)
341 350 error = str_append(dstr, "group:");
342 351 else
343 352 error = str_append(dstr, "defaultgroup:");
344 353 if (error)
345 354 break;
346 355 error = str_append(dstr, prgname(aclp->a_id, idp,
347 356 sizeof (idp), flags & ACL_NORESOLVE));
348 357 if (error == 0)
349 358 error = str_append(dstr, ":");
350 359 break;
351 360
352 361 case DEF_CLASS_OBJ:
353 362 case CLASS_OBJ:
354 363 if (aclp->a_type == CLASS_OBJ)
355 364 error = str_append(dstr, "mask:");
356 365 else
357 366 error = str_append(dstr, "defaultmask:");
358 367 break;
359 368
360 369 case DEF_OTHER_OBJ:
361 370 case OTHER_OBJ:
362 371 if (aclp->a_type == OTHER_OBJ)
363 372 error = str_append(dstr, "other:");
364 373 else
365 374 error = str_append(dstr, "defaultother:");
366 375 break;
367 376
368 377 default:
369 378 error = 1;
370 379 break;
371 380 }
372 381
373 382 return (error);
374 383 }
375 384
376 385 /*
377 386 * compute entry type string such as, owner@:, user:joe, group:staff,...
378 387 */
379 388 static int
380 389 ace_type_txt(dynaclstr_t *dynstr, ace_t *acep, int flags)
381 390 {
382 391 char idp[ID_STR_MAX];
383 392 int error;
384 393 char *sidp = NULL;
385 394
386 395 switch (acep->a_flags & ACE_TYPE_FLAGS) {
387 396 case ACE_OWNER:
388 397 error = str_append(dynstr, OWNERAT_TXT);
389 398 break;
390 399
391 400 case ACE_GROUP|ACE_IDENTIFIER_GROUP:
392 401 error = str_append(dynstr, GROUPAT_TXT);
393 402 break;
394 403
395 404 case ACE_IDENTIFIER_GROUP:
396 405 if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {
397 406 if (error = str_append(dynstr,
398 407 GROUPSID_TXT))
399 408 break;
400 409 if (error = getsidname(acep->a_who, B_FALSE,
401 410 &sidp, flags & ACL_NORESOLVE))
402 411 break;
403 412 error = str_append(dynstr, sidp);
404 413 } else {
405 414 if (error = str_append(dynstr, GROUP_TXT))
406 415 break;
407 416 error = str_append(dynstr, prgname(acep->a_who, idp,
408 417 sizeof (idp), flags & ACL_NORESOLVE));
|
↓ open down ↓ |
224 lines elided |
↑ open up ↑ |
409 418 }
410 419 if (error == 0)
411 420 error = str_append(dynstr, ":");
412 421 break;
413 422
414 423 case ACE_EVERYONE:
415 424 error = str_append(dynstr, EVERYONEAT_TXT);
416 425 break;
417 426
418 427 case 0:
419 - if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID) {
428 + if ((flags & ACL_SID_FMT) && acep->a_who > MAXUID &&
429 + (flags & ACL_EPHEMERAL) == 0) {
420 430 if (error = str_append(dynstr, USERSID_TXT))
421 431 break;
422 432 if (error = getsidname(acep->a_who, B_TRUE,
423 433 &sidp, flags & ACL_NORESOLVE))
424 434 break;
425 435 error = str_append(dynstr, sidp);
426 436 } else {
437 + flags &= ~ACL_NORESOLVE;
427 438 if (error = str_append(dynstr, USER_TXT))
428 439 break;
429 440 error = str_append(dynstr, pruname(acep->a_who, idp,
430 441 sizeof (idp), flags & ACL_NORESOLVE));
431 442 }
432 443 if (error == 0)
433 444 error = str_append(dynstr, ":");
434 445 break;
435 446 default:
436 447 error = 0;
437 448 break;
438 449 }
439 450
440 451 if (sidp)
441 452 free(sidp);
442 453 return (error);
443 454 }
444 455
445 456 /*
446 457 * compute string of permissions, such as read_data/write_data or
447 458 * rwxp,...
448 459 * The format depends on the flags field which indicates whether the compact
449 460 * or verbose format should be used.
450 461 */
451 462 static int
452 463 ace_perm_txt(dynaclstr_t *dstr, uint32_t mask,
453 464 uint32_t iflags, int isdir, int flags)
454 465 {
455 466 int error = 0;
456 467
457 468 if (flags & ACL_COMPACT_FMT) {
458 469 char buf[16];
459 470
460 471 if (mask & ACE_READ_DATA)
461 472 buf[0] = 'r';
462 473 else
463 474 buf[0] = '-';
464 475 if (mask & ACE_WRITE_DATA)
465 476 buf[1] = 'w';
466 477 else
467 478 buf[1] = '-';
468 479 if (mask & ACE_EXECUTE)
469 480 buf[2] = 'x';
470 481 else
471 482 buf[2] = '-';
472 483 if (mask & ACE_APPEND_DATA)
473 484 buf[3] = 'p';
474 485 else
475 486 buf[3] = '-';
476 487 if (mask & ACE_DELETE)
477 488 buf[4] = 'd';
478 489 else
479 490 buf[4] = '-';
480 491 if (mask & ACE_DELETE_CHILD)
481 492 buf[5] = 'D';
482 493 else
483 494 buf[5] = '-';
484 495 if (mask & ACE_READ_ATTRIBUTES)
485 496 buf[6] = 'a';
486 497 else
487 498 buf[6] = '-';
488 499 if (mask & ACE_WRITE_ATTRIBUTES)
489 500 buf[7] = 'A';
490 501 else
491 502 buf[7] = '-';
492 503 if (mask & ACE_READ_NAMED_ATTRS)
493 504 buf[8] = 'R';
494 505 else
495 506 buf[8] = '-';
496 507 if (mask & ACE_WRITE_NAMED_ATTRS)
497 508 buf[9] = 'W';
498 509 else
499 510 buf[9] = '-';
500 511 if (mask & ACE_READ_ACL)
501 512 buf[10] = 'c';
502 513 else
503 514 buf[10] = '-';
504 515 if (mask & ACE_WRITE_ACL)
505 516 buf[11] = 'C';
506 517 else
507 518 buf[11] = '-';
508 519 if (mask & ACE_WRITE_OWNER)
509 520 buf[12] = 'o';
510 521 else
511 522 buf[12] = '-';
512 523 if (mask & ACE_SYNCHRONIZE)
513 524 buf[13] = 's';
514 525 else
515 526 buf[13] = '-';
516 527 buf[14] = ':';
517 528 buf[15] = '\0';
518 529 error = str_append(dstr, buf);
519 530 } else {
520 531 /*
521 532 * If ACE is a directory, but inheritance indicates its
522 533 * for a file then print permissions for file rather than
523 534 * dir.
524 535 */
525 536 if (isdir) {
526 537 if (mask & ACE_LIST_DIRECTORY) {
527 538 if (iflags == ACE_FILE_INHERIT_ACE) {
528 539 error = str_append(dstr,
529 540 READ_DATA_TXT);
530 541 } else {
531 542 error =
532 543 str_append(dstr, READ_DIR_TXT);
533 544 }
534 545 }
535 546 if (error == 0 && (mask & ACE_ADD_FILE)) {
536 547 if (iflags == ACE_FILE_INHERIT_ACE) {
537 548 error =
538 549 str_append(dstr, WRITE_DATA_TXT);
539 550 } else {
540 551 error =
541 552 str_append(dstr, ADD_FILE_TXT);
542 553 }
543 554 }
544 555 if (error == 0 && (mask & ACE_ADD_SUBDIRECTORY)) {
545 556 if (iflags == ACE_FILE_INHERIT_ACE) {
546 557 error = str_append(dstr,
547 558 APPEND_DATA_TXT);
548 559 } else {
549 560 error = str_append(dstr,
550 561 ADD_DIR_TXT);
551 562 }
552 563 }
553 564 } else {
554 565 if (mask & ACE_READ_DATA) {
555 566 error = str_append(dstr, READ_DATA_TXT);
556 567 }
557 568 if (error == 0 && (mask & ACE_WRITE_DATA)) {
558 569 error = str_append(dstr, WRITE_DATA_TXT);
559 570 }
560 571 if (error == 0 && (mask & ACE_APPEND_DATA)) {
561 572 error = str_append(dstr, APPEND_DATA_TXT);
562 573 }
563 574 }
564 575 if (error == 0 && (mask & ACE_READ_NAMED_ATTRS)) {
565 576 error = str_append(dstr, READ_XATTR_TXT);
566 577 }
567 578 if (error == 0 && (mask & ACE_WRITE_NAMED_ATTRS)) {
568 579 error = str_append(dstr, WRITE_XATTR_TXT);
569 580 }
570 581 if (error == 0 && (mask & ACE_EXECUTE)) {
571 582 error = str_append(dstr, EXECUTE_TXT);
572 583 }
573 584 if (error == 0 && (mask & ACE_DELETE_CHILD)) {
574 585 error = str_append(dstr, DELETE_CHILD_TXT);
575 586 }
576 587 if (error == 0 && (mask & ACE_READ_ATTRIBUTES)) {
577 588 error = str_append(dstr, READ_ATTRIBUTES_TXT);
578 589 }
579 590 if (error == 0 && (mask & ACE_WRITE_ATTRIBUTES)) {
580 591 error = str_append(dstr, WRITE_ATTRIBUTES_TXT);
581 592 }
582 593 if (error == 0 && (mask & ACE_DELETE)) {
583 594 error = str_append(dstr, DELETE_TXT);
584 595 }
585 596 if (error == 0 && (mask & ACE_READ_ACL)) {
586 597 error = str_append(dstr, READ_ACL_TXT);
587 598 }
588 599 if (error == 0 && (mask & ACE_WRITE_ACL)) {
589 600 error = str_append(dstr, WRITE_ACL_TXT);
590 601 }
591 602 if (error == 0 && (mask & ACE_WRITE_OWNER)) {
592 603 error = str_append(dstr, WRITE_OWNER_TXT);
593 604 }
594 605 if (error == 0 && (mask & ACE_SYNCHRONIZE)) {
595 606 error = str_append(dstr, SYNCHRONIZE_TXT);
596 607 }
597 608 if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') {
598 609 dstr->d_aclexport[--dstr->d_pos] = '\0';
599 610 }
600 611 if (error == 0)
601 612 error = str_append(dstr, ":");
602 613 }
603 614 return (error);
604 615 }
605 616
606 617 /*
607 618 * compute string of access type, such as allow, deny, ...
608 619 */
609 620 static int
610 621 ace_access_txt(dynaclstr_t *dstr, int type)
611 622 {
612 623 int error;
613 624
614 625 if (type == ACE_ACCESS_ALLOWED_ACE_TYPE)
615 626 error = str_append(dstr, ALLOW_TXT);
616 627 else if (type == ACE_ACCESS_DENIED_ACE_TYPE)
617 628 error = str_append(dstr, DENY_TXT);
618 629 else if (type == ACE_SYSTEM_AUDIT_ACE_TYPE)
619 630 error = str_append(dstr, AUDIT_TXT);
620 631 else if (type == ACE_SYSTEM_ALARM_ACE_TYPE)
621 632 error = str_append(dstr, ALARM_TXT);
622 633 else
623 634 error = str_append(dstr, UNKNOWN_TXT);
624 635
625 636 return (error);
626 637 }
627 638
628 639 static int
629 640 ace_inherit_txt(dynaclstr_t *dstr, uint32_t iflags, int flags)
630 641 {
631 642 int error = 0;
632 643
633 644 if (flags & ACL_COMPACT_FMT) {
634 645 char buf[9];
635 646
636 647 if (iflags & ACE_FILE_INHERIT_ACE)
637 648 buf[0] = 'f';
638 649 else
639 650 buf[0] = '-';
640 651 if (iflags & ACE_DIRECTORY_INHERIT_ACE)
641 652 buf[1] = 'd';
642 653 else
643 654 buf[1] = '-';
644 655 if (iflags & ACE_INHERIT_ONLY_ACE)
645 656 buf[2] = 'i';
646 657 else
647 658 buf[2] = '-';
648 659 if (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)
649 660 buf[3] = 'n';
650 661 else
651 662 buf[3] = '-';
652 663 if (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)
653 664 buf[4] = 'S';
654 665 else
655 666 buf[4] = '-';
656 667 if (iflags & ACE_FAILED_ACCESS_ACE_FLAG)
657 668 buf[5] = 'F';
658 669 else
659 670 buf[5] = '-';
660 671 if (iflags & ACE_INHERITED_ACE)
661 672 buf[6] = 'I';
662 673 else
663 674 buf[6] = '-';
664 675 buf[7] = ':';
665 676 buf[8] = '\0';
666 677 error = str_append(dstr, buf);
667 678 } else {
668 679 if (iflags & ACE_FILE_INHERIT_ACE) {
669 680 error = str_append(dstr, FILE_INHERIT_TXT);
670 681 }
671 682 if (error == 0 && (iflags & ACE_DIRECTORY_INHERIT_ACE)) {
672 683 error = str_append(dstr, DIR_INHERIT_TXT);
673 684 }
674 685 if (error == 0 && (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)) {
675 686 error = str_append(dstr, NO_PROPAGATE_TXT);
676 687 }
677 688 if (error == 0 && (iflags & ACE_INHERIT_ONLY_ACE)) {
678 689 error = str_append(dstr, INHERIT_ONLY_TXT);
679 690 }
680 691 if (error == 0 && (iflags & ACE_SUCCESSFUL_ACCESS_ACE_FLAG)) {
681 692 error = str_append(dstr, SUCCESSFUL_ACCESS_TXT);
682 693 }
683 694 if (error == 0 && (iflags & ACE_FAILED_ACCESS_ACE_FLAG)) {
684 695 error = str_append(dstr, FAILED_ACCESS_TXT);
685 696 }
686 697 if (error == 0 && (iflags & ACE_INHERITED_ACE)) {
687 698 error = str_append(dstr, INHERITED_ACE_TXT);
688 699 }
689 700 if (error == 0 && dstr->d_aclexport[dstr->d_pos-1] == '/') {
690 701 dstr->d_aclexport[--dstr->d_pos] = '\0';
691 702 error = str_append(dstr, ":");
692 703 }
693 704 }
694 705
695 706 return (error);
696 707 }
697 708
698 709 /*
699 710 * Convert internal acl representation to external representation.
700 711 *
701 712 * The length of a non-owning user name or non-owning group name ie entries
702 713 * of type DEF_USER, USER, DEF_GROUP or GROUP, can exceed LOGNAME_MAX. We
703 714 * thus check the length of these entries, and if greater than LOGNAME_MAX,
704 715 * we realloc() via increase_length().
705 716 *
706 717 * The LOGNAME_MAX, ENTRYTYPELEN and PERMS limits are otherwise always
707 718 * adhered to.
708 719 */
709 720
710 721 /*
711 722 * acltotext() converts each ACL entry to look like this:
712 723 *
713 724 * entry_type:uid^gid^name:perms[:id]
714 725 *
715 726 * The maximum length of entry_type is 14 ("defaultgroup::" and
716 727 * "defaultother::") hence ENTRYTYPELEN is set to 14.
717 728 *
718 729 * The max length of a uid^gid^name entry (in theory) is 8, hence we use,
719 730 * however the ID could be a number so we therefore use ID_STR_MAX
720 731 *
721 732 * The length of a perms entry is 4 to allow for the comma appended to each
722 733 * to each acl entry. Hence PERMS is set to 4.
723 734 */
724 735
725 736 #define ENTRYTYPELEN 14
726 737 #define PERMS 4
727 738 #define ACL_ENTRY_SIZE (ENTRYTYPELEN + ID_STR_MAX + PERMS + APPENDED_ID_MAX)
728 739
729 740 char *
730 741 aclent_acltotext(aclent_t *aclp, int aclcnt, int flags)
731 742 {
732 743 dynaclstr_t *dstr;
733 744 char *aclexport = NULL;
734 745 int i;
735 746 int error = 0;
736 747
737 748 if (aclp == NULL)
738 749 return (NULL);
739 750 if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
740 751 return (NULL);
741 752 dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE;
742 753 if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
743 754 free(dstr);
744 755 return (NULL);
745 756 }
746 757 *dstr->d_aclexport = '\0';
747 758 dstr->d_pos = 0;
748 759
749 760 for (i = 0; i < aclcnt; i++, aclp++) {
750 761 if (error = aclent_type_txt(dstr, aclp, flags))
751 762 break;
752 763 if (error = aclent_perm_txt(dstr, aclp->a_perm))
753 764 break;
754 765
755 766 if ((flags & ACL_APPEND_ID) && ((aclp->a_type == USER) ||
756 767 (aclp->a_type == DEF_USER) || (aclp->a_type == GROUP) ||
757 768 (aclp->a_type == DEF_GROUP))) {
758 769 char id[ID_STR_MAX], *idstr;
759 770
760 771 if (error = str_append(dstr, ":"))
761 772 break;
762 773 id[ID_STR_MAX - 1] = '\0'; /* null terminate buffer */
763 774 idstr = lltostr(aclp->a_id, &id[ID_STR_MAX - 1]);
764 775 if (error = str_append(dstr, idstr))
765 776 break;
766 777 }
767 778 if (i < aclcnt - 1)
768 779 if (error = str_append(dstr, ","))
769 780 break;
770 781 }
771 782 if (error) {
772 783 if (dstr->d_aclexport)
773 784 free(dstr->d_aclexport);
774 785 } else {
775 786 aclexport = dstr->d_aclexport;
776 787 }
777 788 free(dstr);
778 789 return (aclexport);
779 790 }
780 791
781 792 char *
782 793 acltotext(aclent_t *aclp, int aclcnt)
783 794 {
784 795 return (aclent_acltotext(aclp, aclcnt, 0));
785 796 }
786 797
787 798
788 799 aclent_t *
789 800 aclfromtext(char *aclstr, int *aclcnt)
790 801 {
791 802 acl_t *aclp;
792 803 aclent_t *aclentp;
793 804 int error;
794 805
795 806 error = acl_fromtext(aclstr, &aclp);
796 807 if (error)
797 808 return (NULL);
798 809
799 810 aclentp = aclp->acl_aclp;
800 811 aclp->acl_aclp = NULL;
801 812 *aclcnt = aclp->acl_cnt;
802 813
803 814 acl_free(aclp);
804 815 return (aclentp);
805 816 }
806 817
807 818
808 819 /*
809 820 * Append string onto dynaclstr_t.
810 821 *
811 822 * Return 0 on success, 1 for failure.
812 823 */
813 824 static int
814 825 str_append(dynaclstr_t *dstr, char *newstr)
815 826 {
816 827 size_t len = strlen(newstr);
817 828
818 829 if ((len + dstr->d_pos) >= dstr->d_bufsize) {
819 830 dstr->d_aclexport = realloc(dstr->d_aclexport,
820 831 dstr->d_bufsize + len + 1);
821 832 if (dstr->d_aclexport == NULL)
822 833 return (1);
823 834 dstr->d_bufsize += len;
824 835 }
825 836 (void) strcat(&dstr->d_aclexport[dstr->d_pos], newstr);
826 837 dstr->d_pos += len;
827 838 return (0);
828 839 }
829 840
830 841 static int
831 842 aclent_perm_txt(dynaclstr_t *dstr, o_mode_t perm)
832 843 {
833 844 char buf[4];
834 845
835 846 if (perm & S_IROTH)
836 847 buf[0] = 'r';
837 848 else
838 849 buf[0] = '-';
839 850 if (perm & S_IWOTH)
840 851 buf[1] = 'w';
841 852 else
842 853 buf[1] = '-';
843 854 if (perm & S_IXOTH)
844 855 buf[2] = 'x';
845 856 else
846 857 buf[2] = '-';
847 858 buf[3] = '\0';
848 859 return (str_append(dstr, buf));
849 860 }
850 861
851 862 /*
852 863 * ace_acltotext() convert each ace formatted acl to look like this:
853 864 *
854 865 * entry_type:uid^gid^name:perms[:flags]:<allow|deny>[:id][,]
855 866 *
856 867 * The maximum length of entry_type is 5 ("group")
857 868 *
858 869 * The max length of a uid^gid^name entry (in theory) is 8,
859 870 * however id could be a number so we therefore use ID_STR_MAX
860 871 *
861 872 * The length of a perms entry is 144 i.e read_data/write_data...
862 873 * to each acl entry.
863 874 *
864 875 * iflags: file_inherit/dir_inherit/inherit_only/no_propagate/successful_access
865 876 * /failed_access
866 877 *
867 878 */
868 879
869 880 #define ACE_ENTRYTYPLEN 6
870 881 #define IFLAGS_STR "file_inherit/dir_inherit/inherit_only/no_propagate/" \
871 882 "successful_access/failed_access/inherited"
872 883 #define IFLAGS_SIZE (sizeof (IFLAGS_STR) - 1)
873 884 #define ACCESS_TYPE_SIZE 7 /* if unknown */
874 885 #define COLON_CNT 3
875 886 #define PERMS_LEN 216
876 887 #define ACE_ENTRY_SIZE (ACE_ENTRYTYPLEN + ID_STR_MAX + PERMS_LEN + \
877 888 ACCESS_TYPE_SIZE + IFLAGS_SIZE + COLON_CNT + APPENDED_ID_MAX)
878 889
879 890 static char *
880 891 ace_acltotext(acl_t *aceaclp, int flags)
881 892 {
882 893 ace_t *aclp = aceaclp->acl_aclp;
883 894 int aclcnt = aceaclp->acl_cnt;
884 895 int i;
885 896 int error = 0;
886 897 int isdir = (aceaclp->acl_flags & ACL_IS_DIR);
887 898 dynaclstr_t *dstr;
888 899 char *aclexport = NULL;
889 900 char *rawsidp = NULL;
890 901
891 902 if (aclp == NULL)
892 903 return (NULL);
893 904
894 905 if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
895 906 return (NULL);
896 907 dstr->d_bufsize = aclcnt * ACL_ENTRY_SIZE;
897 908 if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
898 909 free(dstr);
899 910 return (NULL);
900 911 }
901 912 *dstr->d_aclexport = '\0';
902 913 dstr->d_pos = 0;
903 914
904 915 for (i = 0; i < aclcnt; i++, aclp++) {
905 916
906 917 if (error = ace_type_txt(dstr, aclp, flags))
907 918 break;
908 919 if (error = ace_perm_txt(dstr, aclp->a_access_mask,
909 920 aclp->a_flags, isdir, flags))
910 921 break;
911 922 if (error = ace_inherit_txt(dstr, aclp->a_flags, flags))
912 923 break;
913 924 if (error = ace_access_txt(dstr, aclp->a_type))
914 925 break;
915 926
916 927 if ((flags & ACL_APPEND_ID) &&
917 928 (((aclp->a_flags & ACE_TYPE_FLAGS) == 0) ||
918 929 ((aclp->a_flags & ACE_TYPE_FLAGS) ==
919 930 ACE_IDENTIFIER_GROUP))) {
920 931 char id[ID_STR_MAX], *idstr;
921 932
922 933 if (error = str_append(dstr, ":"))
923 934 break;
924 935
925 936 rawsidp = NULL;
926 937 id[ID_STR_MAX -1] = '\0'; /* null terminate */
927 938 if (aclp->a_who > MAXUID && (flags & ACL_SID_FMT)) {
928 939
929 940 error = getsidname(aclp->a_who,
930 941 ((aclp->a_flags & ACE_TYPE_FLAGS) == 0) ?
931 942 B_TRUE : B_FALSE, &idstr, 1);
932 943 rawsidp = idstr;
933 944 if (error)
934 945 break;
935 946 } else if (aclp->a_who > MAXUID &&
936 947 !(flags & ACL_NORESOLVE)) {
937 948 idstr = lltostr(UID_NOBODY,
938 949 &id[ID_STR_MAX - 1]);
939 950 } else {
940 951 idstr = lltostr(aclp->a_who,
941 952 &id[ID_STR_MAX - 1]);
942 953 }
943 954 if (error = str_append(dstr, idstr))
944 955 break;
945 956 if (rawsidp) {
946 957 free(rawsidp);
947 958 rawsidp = NULL;
948 959 }
949 960 }
950 961 if (i < aclcnt - 1) {
951 962 if (error = str_append(dstr, ","))
952 963 break;
953 964 }
954 965 }
955 966
956 967 if (rawsidp)
957 968 free(rawsidp);
958 969 if (error) {
959 970 if (dstr->d_aclexport)
960 971 free(dstr->d_aclexport);
961 972 } else {
962 973 aclexport = dstr->d_aclexport;
963 974 }
964 975 free(dstr);
965 976 return (aclexport);
966 977 }
967 978
968 979 char *
969 980 acl_totext(acl_t *aclp, int flags)
970 981 {
971 982 char *txtp;
972 983
973 984 if (aclp == NULL)
974 985 return (NULL);
975 986
976 987 switch (aclp->acl_type) {
977 988 case ACE_T:
978 989 txtp = ace_acltotext(aclp, flags);
979 990 break;
980 991 case ACLENT_T:
981 992 txtp = aclent_acltotext(aclp->acl_aclp, aclp->acl_cnt, flags);
982 993 break;
983 994 }
984 995
985 996 return (txtp);
986 997 }
987 998
988 999 int
989 1000 acl_fromtext(const char *acltextp, acl_t **ret_aclp)
990 1001 {
991 1002 int error;
992 1003 char *buf;
993 1004
994 1005 buf = malloc(strlen(acltextp) + 2);
995 1006 if (buf == NULL)
996 1007 return (EACL_MEM_ERROR);
997 1008 strcpy(buf, acltextp);
998 1009 strcat(buf, "\n");
999 1010
1000 1011 (void) mutex_lock(&yymutex);
1001 1012 yybuf = buf;
1002 1013 yyreset();
1003 1014 error = yyparse();
1004 1015 free(buf);
1005 1016
1006 1017 if (yyacl) {
1007 1018 if (error == 0)
1008 1019 *ret_aclp = yyacl;
1009 1020 else {
1010 1021 acl_free(yyacl);
1011 1022 }
1012 1023 yyacl = NULL;
1013 1024 }
1014 1025 (void) mutex_unlock(&yymutex);
1015 1026
1016 1027 return (error);
1017 1028 }
1018 1029
1019 1030 int
1020 1031 acl_parse(const char *acltextp, acl_t **aclp)
|
↓ open down ↓ |
584 lines elided |
↑ open up ↑ |
1021 1032 {
1022 1033 int error;
1023 1034
1024 1035 yyinteractive = 1;
1025 1036 error = acl_fromtext(acltextp, aclp);
1026 1037 yyinteractive = 0;
1027 1038 return (error);
1028 1039 }
1029 1040
1030 1041 static void
1031 -ace_compact_printacl(acl_t *aclp)
1042 +ace_compact_printacl(acl_t *aclp, int flgs)
1032 1043 {
1033 1044 int cnt;
1034 1045 ace_t *acep;
1035 1046 dynaclstr_t *dstr;
1036 1047 int len;
1037 1048
1038 1049 if ((dstr = malloc(sizeof (dynaclstr_t))) == NULL)
1039 1050 return;
1040 1051 dstr->d_bufsize = ACE_ENTRY_SIZE;
1041 1052 if ((dstr->d_aclexport = malloc(dstr->d_bufsize)) == NULL) {
1042 1053 free(dstr);
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
1043 1054 return;
1044 1055 }
1045 1056 *dstr->d_aclexport = '\0';
1046 1057
1047 1058 dstr->d_pos = 0;
1048 1059 for (cnt = 0, acep = aclp->acl_aclp;
1049 1060 cnt != aclp->acl_cnt; cnt++, acep++) {
1050 1061 dstr->d_aclexport[0] = '\0';
1051 1062 dstr->d_pos = 0;
1052 1063
1053 - if (ace_type_txt(dstr, acep, 0))
1064 + if (ace_type_txt(dstr, acep, flgs))
1054 1065 break;
1055 1066 len = strlen(&dstr->d_aclexport[0]);
1056 1067 if (ace_perm_txt(dstr, acep->a_access_mask, acep->a_flags,
1057 1068 aclp->acl_flags & ACL_IS_DIR, ACL_COMPACT_FMT))
1058 1069 break;
1059 1070 if (ace_inherit_txt(dstr, acep->a_flags, ACL_COMPACT_FMT))
1060 1071 break;
1061 1072 if (ace_access_txt(dstr, acep->a_type) == -1)
1062 1073 break;
1063 1074 (void) printf(" %20.*s%s\n", len, dstr->d_aclexport,
1064 1075 &dstr->d_aclexport[len]);
1065 1076 }
1066 1077
1067 1078 if (dstr->d_aclexport)
1068 1079 free(dstr->d_aclexport);
1069 1080 free(dstr);
1070 1081 }
1071 1082
1072 1083 static void
1073 -ace_printacl(acl_t *aclp, int cols, int compact)
1084 +ace_printacl(acl_t *aclp, int cols, int flgs)
1074 1085 {
1075 1086 int slot = 0;
1076 1087 char *token;
1077 1088 char *acltext;
1078 1089
1079 - if (compact) {
1080 - ace_compact_printacl(aclp);
1090 + if (flgs & ACL_COMPACT_FMT) {
1091 + ace_compact_printacl(aclp, flgs);
1081 1092 return;
1082 1093 }
1083 1094
1084 - acltext = acl_totext(aclp, 0);
1095 + acltext = acl_totext(aclp, flgs);
1085 1096
1086 1097 if (acltext == NULL)
1087 1098 return;
1088 1099
1089 1100 token = strtok(acltext, ",");
1090 1101 if (token == NULL) {
1091 1102 free(acltext);
1092 1103 return;
1093 1104 }
1094 1105
1095 1106 do {
1096 1107 (void) printf(" %d:", slot++);
1097 1108 split_line(token, cols - 5);
1098 1109 } while (token = strtok(NULL, ","));
1099 1110 free(acltext);
1100 1111 }
1101 1112
1102 1113 /*
1103 1114 * pretty print an ACL.
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
1104 1115 * For aclent_t ACL's the format is
1105 1116 * similar to the old format used by getfacl,
1106 1117 * with the addition of adding a "slot" number
1107 1118 * before each entry.
1108 1119 *
1109 1120 * for ace_t ACL's the cols variable will break up
1110 1121 * the long lines into multiple lines and will also
1111 1122 * print a "slot" number.
1112 1123 */
1113 1124 void
1114 -acl_printacl(acl_t *aclp, int cols, int compact)
1125 +acl_printacl(acl_t *aclp, int cols, int flgs)
1115 1126 {
1116 1127
1117 1128 switch (aclp->acl_type) {
1118 1129 case ACLENT_T:
1119 1130 aclent_printacl(aclp);
1120 1131 break;
1121 1132 case ACE_T:
1122 - ace_printacl(aclp, cols, compact);
1133 + ace_printacl(aclp, cols, flgs);
1123 1134 break;
1124 1135 }
1125 1136 }
1126 1137
1127 1138 typedef struct value_table {
1128 1139 char p_letter; /* perm letter such as 'r' */
1129 1140 uint32_t p_value; /* value for perm when pletter found */
1130 1141 } value_table_t;
1131 1142
1132 1143 /*
1133 1144 * The permission tables are laid out in positional order
1134 1145 * a '-' character will indicate a permission at a given
1135 1146 * position is not specified. The '-' is not part of the
1136 1147 * table, but will be checked for in the permission computation
1137 1148 * routine.
1138 1149 */
1139 1150 value_table_t ace_perm_table[] = {
1140 1151 { 'r', ACE_READ_DATA},
1141 1152 { 'w', ACE_WRITE_DATA},
1142 1153 { 'x', ACE_EXECUTE},
1143 1154 { 'p', ACE_APPEND_DATA},
1144 1155 { 'd', ACE_DELETE},
1145 1156 { 'D', ACE_DELETE_CHILD},
1146 1157 { 'a', ACE_READ_ATTRIBUTES},
1147 1158 { 'A', ACE_WRITE_ATTRIBUTES},
1148 1159 { 'R', ACE_READ_NAMED_ATTRS},
1149 1160 { 'W', ACE_WRITE_NAMED_ATTRS},
1150 1161 { 'c', ACE_READ_ACL},
1151 1162 { 'C', ACE_WRITE_ACL},
1152 1163 { 'o', ACE_WRITE_OWNER},
1153 1164 { 's', ACE_SYNCHRONIZE}
1154 1165 };
1155 1166
1156 1167 #define ACE_PERM_COUNT (sizeof (ace_perm_table) / sizeof (value_table_t))
1157 1168
1158 1169 value_table_t aclent_perm_table[] = {
1159 1170 { 'r', S_IROTH},
1160 1171 { 'w', S_IWOTH},
1161 1172 { 'x', S_IXOTH}
1162 1173 };
1163 1174
1164 1175 #define ACLENT_PERM_COUNT (sizeof (aclent_perm_table) / sizeof (value_table_t))
1165 1176
1166 1177 value_table_t inherit_table[] = {
1167 1178 {'f', ACE_FILE_INHERIT_ACE},
1168 1179 {'d', ACE_DIRECTORY_INHERIT_ACE},
1169 1180 {'i', ACE_INHERIT_ONLY_ACE},
1170 1181 {'n', ACE_NO_PROPAGATE_INHERIT_ACE},
1171 1182 {'S', ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
1172 1183 {'F', ACE_FAILED_ACCESS_ACE_FLAG},
1173 1184 {'I', ACE_INHERITED_ACE}
1174 1185 };
1175 1186
1176 1187 #define IFLAG_COUNT (sizeof (inherit_table) / sizeof (value_table_t))
1177 1188 #define IFLAG_COUNT_V1 6 /* Older version compatibility */
1178 1189
1179 1190 /*
1180 1191 * compute value from a permission table or inheritance table
1181 1192 * based on string passed in. If positional is set then
1182 1193 * string must match order in permtab, otherwise any order
1183 1194 * is allowed.
1184 1195 */
1185 1196 int
1186 1197 compute_values(value_table_t *permtab, int count,
1187 1198 char *permstr, int positional, uint32_t *mask)
1188 1199 {
1189 1200 uint32_t perm_val = 0;
1190 1201 char *pstr;
1191 1202 int i, found;
1192 1203
1193 1204 if (count < 0)
1194 1205 return (1);
1195 1206
1196 1207 if (positional) {
1197 1208 for (i = 0, pstr = permstr; i != count && pstr &&
1198 1209 *pstr; i++, pstr++) {
1199 1210 if (*pstr == permtab[i].p_letter) {
1200 1211 perm_val |= permtab[i].p_value;
1201 1212 } else if (*pstr != '-') {
1202 1213 return (1);
1203 1214 }
1204 1215 }
1205 1216 } else { /* random order single letters with no '-' */
1206 1217 for (pstr = permstr; pstr && *pstr; pstr++) {
1207 1218 for (found = 0, i = 0; i != count; i++) {
1208 1219 if (*pstr == permtab[i].p_letter) {
1209 1220 perm_val |= permtab[i].p_value;
1210 1221 found = 1;
1211 1222 break;
1212 1223 }
1213 1224 }
1214 1225 if (found == 0)
1215 1226 return (1);
1216 1227 }
1217 1228 }
1218 1229
1219 1230 *mask = perm_val;
1220 1231 return (0);
1221 1232 }
1222 1233
1223 1234
1224 1235 int
1225 1236 ace_inherit_helper(char *str, uint32_t *imask, int table_length)
1226 1237 {
1227 1238 int rc = 0;
1228 1239
1229 1240 if (strlen(str) == table_length) {
1230 1241 /*
1231 1242 * If the string == table_length then first check to see it's
1232 1243 * in positional format. If that fails then see if it's in
1233 1244 * non-positional format.
1234 1245 */
1235 1246 if (compute_values(inherit_table, table_length, str,
1236 1247 1, imask) && compute_values(inherit_table,
1237 1248 table_length, str, 0, imask)) {
1238 1249 rc = 1;
1239 1250 }
1240 1251 } else {
1241 1252 rc = compute_values(inherit_table, table_length, str, 0, imask);
1242 1253 }
1243 1254
1244 1255 return (rc ? EACL_INHERIT_ERROR : 0);
1245 1256 }
1246 1257
1247 1258 /*
1248 1259 * compute value for inheritance flags.
1249 1260 */
1250 1261 int
1251 1262 compute_ace_inherit(char *str, uint32_t *imask)
1252 1263 {
1253 1264 int rc = 0;
1254 1265
1255 1266 rc = ace_inherit_helper(str, imask, IFLAG_COUNT);
1256 1267
1257 1268 if (rc && strlen(str) != IFLAG_COUNT) {
1258 1269
1259 1270 /* is it an old formatted inherit string? */
1260 1271 rc = ace_inherit_helper(str, imask, IFLAG_COUNT_V1);
1261 1272 }
1262 1273
1263 1274 return (rc);
1264 1275 }
1265 1276
1266 1277
1267 1278 /*
1268 1279 * compute value for ACE permissions.
1269 1280 */
1270 1281 int
1271 1282 compute_ace_perms(char *str, uint32_t *mask)
1272 1283 {
1273 1284 int positional = 0;
1274 1285 int error;
1275 1286
1276 1287 if (strlen(str) == ACE_PERM_COUNT)
1277 1288 positional = 1;
1278 1289
1279 1290 error = compute_values(ace_perm_table, ACE_PERM_COUNT,
1280 1291 str, positional, mask);
1281 1292
1282 1293 if (error && positional) {
1283 1294 /*
1284 1295 * If positional was set, then make sure permissions
1285 1296 * aren't actually valid in non positional case where
1286 1297 * all permissions are specified, just in random order.
1287 1298 */
1288 1299 error = compute_values(ace_perm_table,
1289 1300 ACE_PERM_COUNT, str, 0, mask);
1290 1301 }
1291 1302 if (error)
1292 1303 error = EACL_PERM_MASK_ERROR;
1293 1304
1294 1305 return (error);
1295 1306 }
1296 1307
1297 1308
1298 1309
1299 1310 /*
1300 1311 * compute values for aclent permissions.
1301 1312 */
1302 1313 int
1303 1314 compute_aclent_perms(char *str, o_mode_t *mask)
1304 1315 {
1305 1316 int error;
1306 1317 uint32_t pmask;
1307 1318
1308 1319 if (strlen(str) != ACLENT_PERM_COUNT)
1309 1320 return (EACL_PERM_MASK_ERROR);
1310 1321
1311 1322 *mask = 0;
1312 1323 error = compute_values(aclent_perm_table, ACLENT_PERM_COUNT,
1313 1324 str, 1, &pmask);
1314 1325 if (error == 0) {
1315 1326 *mask = (o_mode_t)pmask;
1316 1327 } else
1317 1328 error = EACL_PERM_MASK_ERROR;
1318 1329 return (error);
1319 1330 }
1320 1331
1321 1332 /*
1322 1333 * determine ACE permissions.
1323 1334 */
1324 1335 int
1325 1336 ace_perm_mask(struct acl_perm_type *aclperm, uint32_t *mask)
1326 1337 {
1327 1338 int error;
1328 1339
1329 1340 if (aclperm->perm_style == PERM_TYPE_EMPTY) {
1330 1341 *mask = 0;
1331 1342 return (0);
1332 1343 }
1333 1344
1334 1345 if (aclperm->perm_style == PERM_TYPE_ACE) {
1335 1346 *mask = aclperm->perm_val;
1336 1347 return (0);
1337 1348 }
1338 1349
1339 1350 error = compute_ace_perms(aclperm->perm_str, mask);
1340 1351 if (error) {
1341 1352 acl_error(dgettext(TEXT_DOMAIN,
1342 1353 "Invalid permission(s) '%s' specified\n"),
1343 1354 aclperm->perm_str);
1344 1355 return (EACL_PERM_MASK_ERROR);
1345 1356 }
1346 1357
1347 1358 return (0);
1348 1359 }
|
↓ open down ↓ |
216 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX