PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/common/acl/acl_common.c

https://bitbucket.org/osunix/osunix-gate
C | 1755 lines | 1327 code | 203 blank | 225 comment | 389 complexity | 2f38d28d82144286e5495b50249c13b3 MD5 | raw file
Possible License(s): BSD-3-Clause-No-Nuclear-License-2014, MPL-2.0-no-copyleft-exception, BSD-3-Clause, BSD-2-Clause, LGPL-3.0, 0BSD, GPL-2.0, LGPL-2.0, AGPL-1.0, AGPL-3.0, GPL-3.0, LGPL-2.1
  1. /*
  2. * CDDL HEADER START
  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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23. */
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #include <sys/avl.h>
  27. #if defined(_KERNEL)
  28. #include <sys/systm.h>
  29. #include <sys/sysmacros.h>
  30. #include <acl/acl_common.h>
  31. #else
  32. #include <errno.h>
  33. #include <stdlib.h>
  34. #include <stddef.h>
  35. #include <strings.h>
  36. #include <unistd.h>
  37. #include <assert.h>
  38. #include <grp.h>
  39. #include <pwd.h>
  40. #include <acl_common.h>
  41. #define ASSERT assert
  42. #endif
  43. #define ACE_POSIX_SUPPORTED_BITS (ACE_READ_DATA | \
  44. ACE_WRITE_DATA | ACE_APPEND_DATA | ACE_EXECUTE | \
  45. ACE_READ_ATTRIBUTES | ACE_READ_ACL | ACE_WRITE_ACL)
  46. #define ACL_SYNCHRONIZE_SET_DENY 0x0000001
  47. #define ACL_SYNCHRONIZE_SET_ALLOW 0x0000002
  48. #define ACL_SYNCHRONIZE_ERR_DENY 0x0000004
  49. #define ACL_SYNCHRONIZE_ERR_ALLOW 0x0000008
  50. #define ACL_WRITE_OWNER_SET_DENY 0x0000010
  51. #define ACL_WRITE_OWNER_SET_ALLOW 0x0000020
  52. #define ACL_WRITE_OWNER_ERR_DENY 0x0000040
  53. #define ACL_WRITE_OWNER_ERR_ALLOW 0x0000080
  54. #define ACL_DELETE_SET_DENY 0x0000100
  55. #define ACL_DELETE_SET_ALLOW 0x0000200
  56. #define ACL_DELETE_ERR_DENY 0x0000400
  57. #define ACL_DELETE_ERR_ALLOW 0x0000800
  58. #define ACL_WRITE_ATTRS_OWNER_SET_DENY 0x0001000
  59. #define ACL_WRITE_ATTRS_OWNER_SET_ALLOW 0x0002000
  60. #define ACL_WRITE_ATTRS_OWNER_ERR_DENY 0x0004000
  61. #define ACL_WRITE_ATTRS_OWNER_ERR_ALLOW 0x0008000
  62. #define ACL_WRITE_ATTRS_WRITER_SET_DENY 0x0010000
  63. #define ACL_WRITE_ATTRS_WRITER_SET_ALLOW 0x0020000
  64. #define ACL_WRITE_ATTRS_WRITER_ERR_DENY 0x0040000
  65. #define ACL_WRITE_ATTRS_WRITER_ERR_ALLOW 0x0080000
  66. #define ACL_WRITE_NAMED_WRITER_SET_DENY 0x0100000
  67. #define ACL_WRITE_NAMED_WRITER_SET_ALLOW 0x0200000
  68. #define ACL_WRITE_NAMED_WRITER_ERR_DENY 0x0400000
  69. #define ACL_WRITE_NAMED_WRITER_ERR_ALLOW 0x0800000
  70. #define ACL_READ_NAMED_READER_SET_DENY 0x1000000
  71. #define ACL_READ_NAMED_READER_SET_ALLOW 0x2000000
  72. #define ACL_READ_NAMED_READER_ERR_DENY 0x4000000
  73. #define ACL_READ_NAMED_READER_ERR_ALLOW 0x8000000
  74. #define ACE_VALID_MASK_BITS (\
  75. ACE_READ_DATA | \
  76. ACE_LIST_DIRECTORY | \
  77. ACE_WRITE_DATA | \
  78. ACE_ADD_FILE | \
  79. ACE_APPEND_DATA | \
  80. ACE_ADD_SUBDIRECTORY | \
  81. ACE_READ_NAMED_ATTRS | \
  82. ACE_WRITE_NAMED_ATTRS | \
  83. ACE_EXECUTE | \
  84. ACE_DELETE_CHILD | \
  85. ACE_READ_ATTRIBUTES | \
  86. ACE_WRITE_ATTRIBUTES | \
  87. ACE_DELETE | \
  88. ACE_READ_ACL | \
  89. ACE_WRITE_ACL | \
  90. ACE_WRITE_OWNER | \
  91. ACE_SYNCHRONIZE)
  92. #define ACE_MASK_UNDEFINED 0x80000000
  93. #define ACE_VALID_FLAG_BITS (ACE_FILE_INHERIT_ACE | \
  94. ACE_DIRECTORY_INHERIT_ACE | \
  95. ACE_NO_PROPAGATE_INHERIT_ACE | ACE_INHERIT_ONLY_ACE | \
  96. ACE_SUCCESSFUL_ACCESS_ACE_FLAG | ACE_FAILED_ACCESS_ACE_FLAG | \
  97. ACE_IDENTIFIER_GROUP | ACE_OWNER | ACE_GROUP | ACE_EVERYONE)
  98. /*
  99. * ACL conversion helpers
  100. */
  101. typedef enum {
  102. ace_unused,
  103. ace_user_obj,
  104. ace_user,
  105. ace_group, /* includes GROUP and GROUP_OBJ */
  106. ace_other_obj
  107. } ace_to_aent_state_t;
  108. typedef struct acevals {
  109. uid_t key;
  110. avl_node_t avl;
  111. uint32_t mask;
  112. uint32_t allowed;
  113. uint32_t denied;
  114. int aent_type;
  115. } acevals_t;
  116. typedef struct ace_list {
  117. acevals_t user_obj;
  118. avl_tree_t user;
  119. int numusers;
  120. acevals_t group_obj;
  121. avl_tree_t group;
  122. int numgroups;
  123. acevals_t other_obj;
  124. uint32_t acl_mask;
  125. int hasmask;
  126. int dfacl_flag;
  127. ace_to_aent_state_t state;
  128. int seen; /* bitmask of all aclent_t a_type values seen */
  129. } ace_list_t;
  130. /*
  131. * Generic shellsort, from K&R (1st ed, p 58.), somewhat modified.
  132. * v = Ptr to array/vector of objs
  133. * n = # objs in the array
  134. * s = size of each obj (must be multiples of a word size)
  135. * f = ptr to function to compare two objs
  136. * returns (-1 = less than, 0 = equal, 1 = greater than
  137. */
  138. void
  139. ksort(caddr_t v, int n, int s, int (*f)())
  140. {
  141. int g, i, j, ii;
  142. unsigned int *p1, *p2;
  143. unsigned int tmp;
  144. /* No work to do */
  145. if (v == NULL || n <= 1)
  146. return;
  147. /* Sanity check on arguments */
  148. ASSERT(((uintptr_t)v & 0x3) == 0 && (s & 0x3) == 0);
  149. ASSERT(s > 0);
  150. for (g = n / 2; g > 0; g /= 2) {
  151. for (i = g; i < n; i++) {
  152. for (j = i - g; j >= 0 &&
  153. (*f)(v + j * s, v + (j + g) * s) == 1;
  154. j -= g) {
  155. p1 = (void *)(v + j * s);
  156. p2 = (void *)(v + (j + g) * s);
  157. for (ii = 0; ii < s / 4; ii++) {
  158. tmp = *p1;
  159. *p1++ = *p2;
  160. *p2++ = tmp;
  161. }
  162. }
  163. }
  164. }
  165. }
  166. /*
  167. * Compare two acls, all fields. Returns:
  168. * -1 (less than)
  169. * 0 (equal)
  170. * +1 (greater than)
  171. */
  172. int
  173. cmp2acls(void *a, void *b)
  174. {
  175. aclent_t *x = (aclent_t *)a;
  176. aclent_t *y = (aclent_t *)b;
  177. /* Compare types */
  178. if (x->a_type < y->a_type)
  179. return (-1);
  180. if (x->a_type > y->a_type)
  181. return (1);
  182. /* Equal types; compare id's */
  183. if (x->a_id < y->a_id)
  184. return (-1);
  185. if (x->a_id > y->a_id)
  186. return (1);
  187. /* Equal ids; compare perms */
  188. if (x->a_perm < y->a_perm)
  189. return (-1);
  190. if (x->a_perm > y->a_perm)
  191. return (1);
  192. /* Totally equal */
  193. return (0);
  194. }
  195. /*ARGSUSED*/
  196. static void *
  197. cacl_realloc(void *ptr, size_t size, size_t new_size)
  198. {
  199. #if defined(_KERNEL)
  200. void *tmp;
  201. tmp = kmem_alloc(new_size, KM_SLEEP);
  202. (void) memcpy(tmp, ptr, (size < new_size) ? size : new_size);
  203. kmem_free(ptr, size);
  204. return (tmp);
  205. #else
  206. return (realloc(ptr, new_size));
  207. #endif
  208. }
  209. static int
  210. cacl_malloc(void **ptr, size_t size)
  211. {
  212. #if defined(_KERNEL)
  213. *ptr = kmem_zalloc(size, KM_SLEEP);
  214. return (0);
  215. #else
  216. *ptr = calloc(1, size);
  217. if (*ptr == NULL)
  218. return (errno);
  219. return (0);
  220. #endif
  221. }
  222. /*ARGSUSED*/
  223. static void
  224. cacl_free(void *ptr, size_t size)
  225. {
  226. #if defined(_KERNEL)
  227. kmem_free(ptr, size);
  228. #else
  229. free(ptr);
  230. #endif
  231. }
  232. acl_t *
  233. acl_alloc(enum acl_type type)
  234. {
  235. acl_t *aclp;
  236. if (cacl_malloc((void **)&aclp, sizeof (acl_t)) != 0)
  237. return (NULL);
  238. aclp->acl_aclp = NULL;
  239. aclp->acl_cnt = 0;
  240. switch (type) {
  241. case ACE_T:
  242. aclp->acl_type = ACE_T;
  243. aclp->acl_entry_size = sizeof (ace_t);
  244. break;
  245. case ACLENT_T:
  246. aclp->acl_type = ACLENT_T;
  247. aclp->acl_entry_size = sizeof (aclent_t);
  248. break;
  249. default:
  250. acl_free(aclp);
  251. aclp = NULL;
  252. }
  253. return (aclp);
  254. }
  255. /*
  256. * Free acl_t structure
  257. */
  258. void
  259. acl_free(acl_t *aclp)
  260. {
  261. int acl_size;
  262. if (aclp == NULL)
  263. return;
  264. if (aclp->acl_aclp) {
  265. acl_size = aclp->acl_cnt * aclp->acl_entry_size;
  266. cacl_free(aclp->acl_aclp, acl_size);
  267. }
  268. cacl_free(aclp, sizeof (acl_t));
  269. }
  270. static uint32_t
  271. access_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow)
  272. {
  273. uint32_t access_mask = 0;
  274. int acl_produce;
  275. int synchronize_set = 0, write_owner_set = 0;
  276. int delete_set = 0, write_attrs_set = 0;
  277. int read_named_set = 0, write_named_set = 0;
  278. acl_produce = (ACL_SYNCHRONIZE_SET_ALLOW |
  279. ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
  280. ACL_WRITE_ATTRS_WRITER_SET_DENY);
  281. if (isallow) {
  282. synchronize_set = ACL_SYNCHRONIZE_SET_ALLOW;
  283. write_owner_set = ACL_WRITE_OWNER_SET_ALLOW;
  284. delete_set = ACL_DELETE_SET_ALLOW;
  285. if (hasreadperm)
  286. read_named_set = ACL_READ_NAMED_READER_SET_ALLOW;
  287. if (haswriteperm)
  288. write_named_set = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
  289. if (isowner)
  290. write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
  291. else if (haswriteperm)
  292. write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
  293. } else {
  294. synchronize_set = ACL_SYNCHRONIZE_SET_DENY;
  295. write_owner_set = ACL_WRITE_OWNER_SET_DENY;
  296. delete_set = ACL_DELETE_SET_DENY;
  297. if (hasreadperm)
  298. read_named_set = ACL_READ_NAMED_READER_SET_DENY;
  299. if (haswriteperm)
  300. write_named_set = ACL_WRITE_NAMED_WRITER_SET_DENY;
  301. if (isowner)
  302. write_attrs_set = ACL_WRITE_ATTRS_OWNER_SET_DENY;
  303. else if (haswriteperm)
  304. write_attrs_set = ACL_WRITE_ATTRS_WRITER_SET_DENY;
  305. else
  306. /*
  307. * If the entity is not the owner and does not
  308. * have write permissions ACE_WRITE_ATTRIBUTES will
  309. * always go in the DENY ACE.
  310. */
  311. access_mask |= ACE_WRITE_ATTRIBUTES;
  312. }
  313. if (acl_produce & synchronize_set)
  314. access_mask |= ACE_SYNCHRONIZE;
  315. if (acl_produce & write_owner_set)
  316. access_mask |= ACE_WRITE_OWNER;
  317. if (acl_produce & delete_set)
  318. access_mask |= ACE_DELETE;
  319. if (acl_produce & write_attrs_set)
  320. access_mask |= ACE_WRITE_ATTRIBUTES;
  321. if (acl_produce & read_named_set)
  322. access_mask |= ACE_READ_NAMED_ATTRS;
  323. if (acl_produce & write_named_set)
  324. access_mask |= ACE_WRITE_NAMED_ATTRS;
  325. return (access_mask);
  326. }
  327. /*
  328. * Given an mode_t, convert it into an access_mask as used
  329. * by nfsace, assuming aclent_t -> nfsace semantics.
  330. */
  331. static uint32_t
  332. mode_to_ace_access(mode_t mode, int isdir, int isowner, int isallow)
  333. {
  334. uint32_t access = 0;
  335. int haswriteperm = 0;
  336. int hasreadperm = 0;
  337. if (isallow) {
  338. haswriteperm = (mode & S_IWOTH);
  339. hasreadperm = (mode & S_IROTH);
  340. } else {
  341. haswriteperm = !(mode & S_IWOTH);
  342. hasreadperm = !(mode & S_IROTH);
  343. }
  344. /*
  345. * The following call takes care of correctly setting the following
  346. * mask bits in the access_mask:
  347. * ACE_SYNCHRONIZE, ACE_WRITE_OWNER, ACE_DELETE,
  348. * ACE_WRITE_ATTRIBUTES, ACE_WRITE_NAMED_ATTRS, ACE_READ_NAMED_ATTRS
  349. */
  350. access = access_mask_set(haswriteperm, hasreadperm, isowner, isallow);
  351. if (isallow) {
  352. access |= ACE_READ_ACL | ACE_READ_ATTRIBUTES;
  353. if (isowner)
  354. access |= ACE_WRITE_ACL;
  355. } else {
  356. if (! isowner)
  357. access |= ACE_WRITE_ACL;
  358. }
  359. /* read */
  360. if (mode & S_IROTH) {
  361. access |= ACE_READ_DATA;
  362. }
  363. /* write */
  364. if (mode & S_IWOTH) {
  365. access |= ACE_WRITE_DATA |
  366. ACE_APPEND_DATA;
  367. if (isdir)
  368. access |= ACE_DELETE_CHILD;
  369. }
  370. /* exec */
  371. if (mode & 01) {
  372. access |= ACE_EXECUTE;
  373. }
  374. return (access);
  375. }
  376. /*
  377. * Given an nfsace (presumably an ALLOW entry), make a
  378. * corresponding DENY entry at the address given.
  379. */
  380. static void
  381. ace_make_deny(ace_t *allow, ace_t *deny, int isdir, int isowner)
  382. {
  383. (void) memcpy(deny, allow, sizeof (ace_t));
  384. deny->a_who = allow->a_who;
  385. deny->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
  386. deny->a_access_mask ^= ACE_POSIX_SUPPORTED_BITS;
  387. if (isdir)
  388. deny->a_access_mask ^= ACE_DELETE_CHILD;
  389. deny->a_access_mask &= ~(ACE_SYNCHRONIZE | ACE_WRITE_OWNER |
  390. ACE_DELETE | ACE_WRITE_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
  391. ACE_WRITE_NAMED_ATTRS);
  392. deny->a_access_mask |= access_mask_set((allow->a_access_mask &
  393. ACE_WRITE_DATA), (allow->a_access_mask & ACE_READ_DATA), isowner,
  394. B_FALSE);
  395. }
  396. /*
  397. * Make an initial pass over an array of aclent_t's. Gather
  398. * information such as an ACL_MASK (if any), number of users,
  399. * number of groups, and whether the array needs to be sorted.
  400. */
  401. static int
  402. ln_aent_preprocess(aclent_t *aclent, int n,
  403. int *hasmask, mode_t *mask,
  404. int *numuser, int *numgroup, int *needsort)
  405. {
  406. int error = 0;
  407. int i;
  408. int curtype = 0;
  409. *hasmask = 0;
  410. *mask = 07;
  411. *needsort = 0;
  412. *numuser = 0;
  413. *numgroup = 0;
  414. for (i = 0; i < n; i++) {
  415. if (aclent[i].a_type < curtype)
  416. *needsort = 1;
  417. else if (aclent[i].a_type > curtype)
  418. curtype = aclent[i].a_type;
  419. if (aclent[i].a_type & USER)
  420. (*numuser)++;
  421. if (aclent[i].a_type & (GROUP | GROUP_OBJ))
  422. (*numgroup)++;
  423. if (aclent[i].a_type & CLASS_OBJ) {
  424. if (*hasmask) {
  425. error = EINVAL;
  426. goto out;
  427. } else {
  428. *hasmask = 1;
  429. *mask = aclent[i].a_perm;
  430. }
  431. }
  432. }
  433. if ((! *hasmask) && (*numuser + *numgroup > 1)) {
  434. error = EINVAL;
  435. goto out;
  436. }
  437. out:
  438. return (error);
  439. }
  440. /*
  441. * Convert an array of aclent_t into an array of nfsace entries,
  442. * following POSIX draft -> nfsv4 conversion semantics as outlined in
  443. * the IETF draft.
  444. */
  445. static int
  446. ln_aent_to_ace(aclent_t *aclent, int n, ace_t **acepp, int *rescount, int isdir)
  447. {
  448. int error = 0;
  449. mode_t mask;
  450. int numuser, numgroup, needsort;
  451. int resultsize = 0;
  452. int i, groupi = 0, skip;
  453. ace_t *acep, *result = NULL;
  454. int hasmask;
  455. error = ln_aent_preprocess(aclent, n, &hasmask, &mask,
  456. &numuser, &numgroup, &needsort);
  457. if (error != 0)
  458. goto out;
  459. /* allow + deny for each aclent */
  460. resultsize = n * 2;
  461. if (hasmask) {
  462. /*
  463. * stick extra deny on the group_obj and on each
  464. * user|group for the mask (the group_obj was added
  465. * into the count for numgroup)
  466. */
  467. resultsize += numuser + numgroup;
  468. /* ... and don't count the mask itself */
  469. resultsize -= 2;
  470. }
  471. /* sort the source if necessary */
  472. if (needsort)
  473. ksort((caddr_t)aclent, n, sizeof (aclent_t), cmp2acls);
  474. if (cacl_malloc((void **)&result, resultsize * sizeof (ace_t)) != 0)
  475. goto out;
  476. acep = result;
  477. for (i = 0; i < n; i++) {
  478. /*
  479. * don't process CLASS_OBJ (mask); mask was grabbed in
  480. * ln_aent_preprocess()
  481. */
  482. if (aclent[i].a_type & CLASS_OBJ)
  483. continue;
  484. /* If we need an ACL_MASK emulator, prepend it now */
  485. if ((hasmask) &&
  486. (aclent[i].a_type & (USER | GROUP | GROUP_OBJ))) {
  487. acep->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
  488. acep->a_flags = 0;
  489. if (aclent[i].a_type & GROUP_OBJ) {
  490. acep->a_who = (uid_t)-1;
  491. acep->a_flags |=
  492. (ACE_IDENTIFIER_GROUP|ACE_GROUP);
  493. } else if (aclent[i].a_type & USER) {
  494. acep->a_who = aclent[i].a_id;
  495. } else {
  496. acep->a_who = aclent[i].a_id;
  497. acep->a_flags |= ACE_IDENTIFIER_GROUP;
  498. }
  499. if (aclent[i].a_type & ACL_DEFAULT) {
  500. acep->a_flags |= ACE_INHERIT_ONLY_ACE |
  501. ACE_FILE_INHERIT_ACE |
  502. ACE_DIRECTORY_INHERIT_ACE;
  503. }
  504. /*
  505. * Set the access mask for the prepended deny
  506. * ace. To do this, we invert the mask (found
  507. * in ln_aent_preprocess()) then convert it to an
  508. * DENY ace access_mask.
  509. */
  510. acep->a_access_mask = mode_to_ace_access((mask ^ 07),
  511. isdir, 0, 0);
  512. acep += 1;
  513. }
  514. /* handle a_perm -> access_mask */
  515. acep->a_access_mask = mode_to_ace_access(aclent[i].a_perm,
  516. isdir, aclent[i].a_type & USER_OBJ, 1);
  517. /* emulate a default aclent */
  518. if (aclent[i].a_type & ACL_DEFAULT) {
  519. acep->a_flags |= ACE_INHERIT_ONLY_ACE |
  520. ACE_FILE_INHERIT_ACE |
  521. ACE_DIRECTORY_INHERIT_ACE;
  522. }
  523. /*
  524. * handle a_perm and a_id
  525. *
  526. * this must be done last, since it involves the
  527. * corresponding deny aces, which are handled
  528. * differently for each different a_type.
  529. */
  530. if (aclent[i].a_type & USER_OBJ) {
  531. acep->a_who = (uid_t)-1;
  532. acep->a_flags |= ACE_OWNER;
  533. ace_make_deny(acep, acep + 1, isdir, B_TRUE);
  534. acep += 2;
  535. } else if (aclent[i].a_type & USER) {
  536. acep->a_who = aclent[i].a_id;
  537. ace_make_deny(acep, acep + 1, isdir, B_FALSE);
  538. acep += 2;
  539. } else if (aclent[i].a_type & (GROUP_OBJ | GROUP)) {
  540. if (aclent[i].a_type & GROUP_OBJ) {
  541. acep->a_who = (uid_t)-1;
  542. acep->a_flags |= ACE_GROUP;
  543. } else {
  544. acep->a_who = aclent[i].a_id;
  545. }
  546. acep->a_flags |= ACE_IDENTIFIER_GROUP;
  547. /*
  548. * Set the corresponding deny for the group ace.
  549. *
  550. * The deny aces go after all of the groups, unlike
  551. * everything else, where they immediately follow
  552. * the allow ace.
  553. *
  554. * We calculate "skip", the number of slots to
  555. * skip ahead for the deny ace, here.
  556. *
  557. * The pattern is:
  558. * MD1 A1 MD2 A2 MD3 A3 D1 D2 D3
  559. * thus, skip is
  560. * (2 * numgroup) - 1 - groupi
  561. * (2 * numgroup) to account for MD + A
  562. * - 1 to account for the fact that we're on the
  563. * access (A), not the mask (MD)
  564. * - groupi to account for the fact that we have
  565. * passed up groupi number of MD's.
  566. */
  567. skip = (2 * numgroup) - 1 - groupi;
  568. ace_make_deny(acep, acep + skip, isdir, B_FALSE);
  569. /*
  570. * If we just did the last group, skip acep past
  571. * all of the denies; else, just move ahead one.
  572. */
  573. if (++groupi >= numgroup)
  574. acep += numgroup + 1;
  575. else
  576. acep += 1;
  577. } else if (aclent[i].a_type & OTHER_OBJ) {
  578. acep->a_who = (uid_t)-1;
  579. acep->a_flags |= ACE_EVERYONE;
  580. ace_make_deny(acep, acep + 1, isdir, B_FALSE);
  581. acep += 2;
  582. } else {
  583. error = EINVAL;
  584. goto out;
  585. }
  586. }
  587. *acepp = result;
  588. *rescount = resultsize;
  589. out:
  590. if (error != 0) {
  591. if ((result != NULL) && (resultsize > 0)) {
  592. cacl_free(result, resultsize * sizeof (ace_t));
  593. }
  594. }
  595. return (error);
  596. }
  597. static int
  598. convert_aent_to_ace(aclent_t *aclentp, int aclcnt, int isdir,
  599. ace_t **retacep, int *retacecnt)
  600. {
  601. ace_t *acep;
  602. ace_t *dfacep;
  603. int acecnt = 0;
  604. int dfacecnt = 0;
  605. int dfaclstart = 0;
  606. int dfaclcnt = 0;
  607. aclent_t *aclp;
  608. int i;
  609. int error;
  610. int acesz, dfacesz;
  611. ksort((caddr_t)aclentp, aclcnt, sizeof (aclent_t), cmp2acls);
  612. for (i = 0, aclp = aclentp; i < aclcnt; aclp++, i++) {
  613. if (aclp->a_type & ACL_DEFAULT)
  614. break;
  615. }
  616. if (i < aclcnt) {
  617. dfaclstart = i;
  618. dfaclcnt = aclcnt - i;
  619. }
  620. if (dfaclcnt && isdir == 0) {
  621. return (EINVAL);
  622. }
  623. error = ln_aent_to_ace(aclentp, i, &acep, &acecnt, isdir);
  624. if (error)
  625. return (error);
  626. if (dfaclcnt) {
  627. error = ln_aent_to_ace(&aclentp[dfaclstart], dfaclcnt,
  628. &dfacep, &dfacecnt, isdir);
  629. if (error) {
  630. if (acep) {
  631. cacl_free(acep, acecnt * sizeof (ace_t));
  632. }
  633. return (error);
  634. }
  635. }
  636. if (dfacecnt != 0) {
  637. acesz = sizeof (ace_t) * acecnt;
  638. dfacesz = sizeof (ace_t) * dfacecnt;
  639. acep = cacl_realloc(acep, acesz, acesz + dfacesz);
  640. if (acep == NULL)
  641. return (ENOMEM);
  642. if (dfaclcnt) {
  643. (void) memcpy(acep + acecnt, dfacep, dfacesz);
  644. }
  645. }
  646. if (dfaclcnt)
  647. cacl_free(dfacep, dfacecnt * sizeof (ace_t));
  648. *retacecnt = acecnt + dfacecnt;
  649. *retacep = acep;
  650. return (0);
  651. }
  652. static int
  653. ace_mask_to_mode(uint32_t mask, o_mode_t *modep, int isdir)
  654. {
  655. int error = 0;
  656. o_mode_t mode = 0;
  657. uint32_t bits, wantbits;
  658. /* read */
  659. if (mask & ACE_READ_DATA)
  660. mode |= S_IROTH;
  661. /* write */
  662. wantbits = (ACE_WRITE_DATA | ACE_APPEND_DATA);
  663. if (isdir)
  664. wantbits |= ACE_DELETE_CHILD;
  665. bits = mask & wantbits;
  666. if (bits != 0) {
  667. if (bits != wantbits) {
  668. error = ENOTSUP;
  669. goto out;
  670. }
  671. mode |= S_IWOTH;
  672. }
  673. /* exec */
  674. if (mask & ACE_EXECUTE) {
  675. mode |= S_IXOTH;
  676. }
  677. *modep = mode;
  678. out:
  679. return (error);
  680. }
  681. static void
  682. acevals_init(acevals_t *vals, uid_t key)
  683. {
  684. bzero(vals, sizeof (*vals));
  685. vals->allowed = ACE_MASK_UNDEFINED;
  686. vals->denied = ACE_MASK_UNDEFINED;
  687. vals->mask = ACE_MASK_UNDEFINED;
  688. vals->key = key;
  689. }
  690. static void
  691. ace_list_init(ace_list_t *al, int dfacl_flag)
  692. {
  693. acevals_init(&al->user_obj, NULL);
  694. acevals_init(&al->group_obj, NULL);
  695. acevals_init(&al->other_obj, NULL);
  696. al->numusers = 0;
  697. al->numgroups = 0;
  698. al->acl_mask = 0;
  699. al->hasmask = 0;
  700. al->state = ace_unused;
  701. al->seen = 0;
  702. al->dfacl_flag = dfacl_flag;
  703. }
  704. /*
  705. * Find or create an acevals holder for a given id and avl tree.
  706. *
  707. * Note that only one thread will ever touch these avl trees, so
  708. * there is no need for locking.
  709. */
  710. static acevals_t *
  711. acevals_find(ace_t *ace, avl_tree_t *avl, int *num)
  712. {
  713. acevals_t key, *rc;
  714. avl_index_t where;
  715. key.key = ace->a_who;
  716. rc = avl_find(avl, &key, &where);
  717. if (rc != NULL)
  718. return (rc);
  719. /* this memory is freed by ln_ace_to_aent()->ace_list_free() */
  720. if (cacl_malloc((void **)&rc, sizeof (acevals_t)) != 0)
  721. return (NULL);
  722. acevals_init(rc, ace->a_who);
  723. avl_insert(avl, rc, where);
  724. (*num)++;
  725. return (rc);
  726. }
  727. static int
  728. access_mask_check(ace_t *acep, int mask_bit, int isowner)
  729. {
  730. int set_deny, err_deny;
  731. int set_allow, err_allow;
  732. int acl_consume;
  733. int haswriteperm, hasreadperm;
  734. if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
  735. haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 0 : 1;
  736. hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 0 : 1;
  737. } else {
  738. haswriteperm = (acep->a_access_mask & ACE_WRITE_DATA) ? 1 : 0;
  739. hasreadperm = (acep->a_access_mask & ACE_READ_DATA) ? 1 : 0;
  740. }
  741. acl_consume = (ACL_SYNCHRONIZE_ERR_DENY |
  742. ACL_DELETE_ERR_DENY |
  743. ACL_WRITE_OWNER_ERR_DENY |
  744. ACL_WRITE_OWNER_ERR_ALLOW |
  745. ACL_WRITE_ATTRS_OWNER_SET_ALLOW |
  746. ACL_WRITE_ATTRS_OWNER_ERR_DENY |
  747. ACL_WRITE_ATTRS_WRITER_SET_DENY |
  748. ACL_WRITE_ATTRS_WRITER_ERR_ALLOW |
  749. ACL_WRITE_NAMED_WRITER_ERR_DENY |
  750. ACL_READ_NAMED_READER_ERR_DENY);
  751. if (mask_bit == ACE_SYNCHRONIZE) {
  752. set_deny = ACL_SYNCHRONIZE_SET_DENY;
  753. err_deny = ACL_SYNCHRONIZE_ERR_DENY;
  754. set_allow = ACL_SYNCHRONIZE_SET_ALLOW;
  755. err_allow = ACL_SYNCHRONIZE_ERR_ALLOW;
  756. } else if (mask_bit == ACE_WRITE_OWNER) {
  757. set_deny = ACL_WRITE_OWNER_SET_DENY;
  758. err_deny = ACL_WRITE_OWNER_ERR_DENY;
  759. set_allow = ACL_WRITE_OWNER_SET_ALLOW;
  760. err_allow = ACL_WRITE_OWNER_ERR_ALLOW;
  761. } else if (mask_bit == ACE_DELETE) {
  762. set_deny = ACL_DELETE_SET_DENY;
  763. err_deny = ACL_DELETE_ERR_DENY;
  764. set_allow = ACL_DELETE_SET_ALLOW;
  765. err_allow = ACL_DELETE_ERR_ALLOW;
  766. } else if (mask_bit == ACE_WRITE_ATTRIBUTES) {
  767. if (isowner) {
  768. set_deny = ACL_WRITE_ATTRS_OWNER_SET_DENY;
  769. err_deny = ACL_WRITE_ATTRS_OWNER_ERR_DENY;
  770. set_allow = ACL_WRITE_ATTRS_OWNER_SET_ALLOW;
  771. err_allow = ACL_WRITE_ATTRS_OWNER_ERR_ALLOW;
  772. } else if (haswriteperm) {
  773. set_deny = ACL_WRITE_ATTRS_WRITER_SET_DENY;
  774. err_deny = ACL_WRITE_ATTRS_WRITER_ERR_DENY;
  775. set_allow = ACL_WRITE_ATTRS_WRITER_SET_ALLOW;
  776. err_allow = ACL_WRITE_ATTRS_WRITER_ERR_ALLOW;
  777. } else {
  778. if ((acep->a_access_mask & mask_bit) &&
  779. (acep->a_type & ACE_ACCESS_ALLOWED_ACE_TYPE)) {
  780. return (ENOTSUP);
  781. }
  782. return (0);
  783. }
  784. } else if (mask_bit == ACE_READ_NAMED_ATTRS) {
  785. if (!hasreadperm)
  786. return (0);
  787. set_deny = ACL_READ_NAMED_READER_SET_DENY;
  788. err_deny = ACL_READ_NAMED_READER_ERR_DENY;
  789. set_allow = ACL_READ_NAMED_READER_SET_ALLOW;
  790. err_allow = ACL_READ_NAMED_READER_ERR_ALLOW;
  791. } else if (mask_bit == ACE_WRITE_NAMED_ATTRS) {
  792. if (!haswriteperm)
  793. return (0);
  794. set_deny = ACL_WRITE_NAMED_WRITER_SET_DENY;
  795. err_deny = ACL_WRITE_NAMED_WRITER_ERR_DENY;
  796. set_allow = ACL_WRITE_NAMED_WRITER_SET_ALLOW;
  797. err_allow = ACL_WRITE_NAMED_WRITER_ERR_ALLOW;
  798. } else {
  799. return (EINVAL);
  800. }
  801. if (acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) {
  802. if (acl_consume & set_deny) {
  803. if (!(acep->a_access_mask & mask_bit)) {
  804. return (ENOTSUP);
  805. }
  806. } else if (acl_consume & err_deny) {
  807. if (acep->a_access_mask & mask_bit) {
  808. return (ENOTSUP);
  809. }
  810. }
  811. } else {
  812. /* ACE_ACCESS_ALLOWED_ACE_TYPE */
  813. if (acl_consume & set_allow) {
  814. if (!(acep->a_access_mask & mask_bit)) {
  815. return (ENOTSUP);
  816. }
  817. } else if (acl_consume & err_allow) {
  818. if (acep->a_access_mask & mask_bit) {
  819. return (ENOTSUP);
  820. }
  821. }
  822. }
  823. return (0);
  824. }
  825. static int
  826. ace_to_aent_legal(ace_t *acep)
  827. {
  828. int error = 0;
  829. int isowner;
  830. /* only ALLOW or DENY */
  831. if ((acep->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE) &&
  832. (acep->a_type != ACE_ACCESS_DENIED_ACE_TYPE)) {
  833. error = ENOTSUP;
  834. goto out;
  835. }
  836. /* check for invalid flags */
  837. if (acep->a_flags & ~(ACE_VALID_FLAG_BITS)) {
  838. error = EINVAL;
  839. goto out;
  840. }
  841. /* some flags are illegal */
  842. if (acep->a_flags & (ACE_SUCCESSFUL_ACCESS_ACE_FLAG |
  843. ACE_FAILED_ACCESS_ACE_FLAG |
  844. ACE_NO_PROPAGATE_INHERIT_ACE)) {
  845. error = ENOTSUP;
  846. goto out;
  847. }
  848. /* check for invalid masks */
  849. if (acep->a_access_mask & ~(ACE_VALID_MASK_BITS)) {
  850. error = EINVAL;
  851. goto out;
  852. }
  853. if ((acep->a_flags & ACE_OWNER)) {
  854. isowner = 1;
  855. } else {
  856. isowner = 0;
  857. }
  858. error = access_mask_check(acep, ACE_SYNCHRONIZE, isowner);
  859. if (error)
  860. goto out;
  861. error = access_mask_check(acep, ACE_WRITE_OWNER, isowner);
  862. if (error)
  863. goto out;
  864. error = access_mask_check(acep, ACE_DELETE, isowner);
  865. if (error)
  866. goto out;
  867. error = access_mask_check(acep, ACE_WRITE_ATTRIBUTES, isowner);
  868. if (error)
  869. goto out;
  870. error = access_mask_check(acep, ACE_READ_NAMED_ATTRS, isowner);
  871. if (error)
  872. goto out;
  873. error = access_mask_check(acep, ACE_WRITE_NAMED_ATTRS, isowner);
  874. if (error)
  875. goto out;
  876. /* more detailed checking of masks */
  877. if (acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) {
  878. if (! (acep->a_access_mask & ACE_READ_ATTRIBUTES)) {
  879. error = ENOTSUP;
  880. goto out;
  881. }
  882. if ((acep->a_access_mask & ACE_WRITE_DATA) &&
  883. (! (acep->a_access_mask & ACE_APPEND_DATA))) {
  884. error = ENOTSUP;
  885. goto out;
  886. }
  887. if ((! (acep->a_access_mask & ACE_WRITE_DATA)) &&
  888. (acep->a_access_mask & ACE_APPEND_DATA)) {
  889. error = ENOTSUP;
  890. goto out;
  891. }
  892. }
  893. /* ACL enforcement */
  894. if ((acep->a_access_mask & ACE_READ_ACL) &&
  895. (acep->a_type != ACE_ACCESS_ALLOWED_ACE_TYPE)) {
  896. error = ENOTSUP;
  897. goto out;
  898. }
  899. if (acep->a_access_mask & ACE_WRITE_ACL) {
  900. if ((acep->a_type == ACE_ACCESS_DENIED_ACE_TYPE) &&
  901. (isowner)) {
  902. error = ENOTSUP;
  903. goto out;
  904. }
  905. if ((acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) &&
  906. (! isowner)) {
  907. error = ENOTSUP;
  908. goto out;
  909. }
  910. }
  911. out:
  912. return (error);
  913. }
  914. static int
  915. ace_allow_to_mode(uint32_t mask, o_mode_t *modep, int isdir)
  916. {
  917. /* ACE_READ_ACL and ACE_READ_ATTRIBUTES must both be set */
  918. if ((mask & (ACE_READ_ACL | ACE_READ_ATTRIBUTES)) !=
  919. (ACE_READ_ACL | ACE_READ_ATTRIBUTES)) {
  920. return (ENOTSUP);
  921. }
  922. return (ace_mask_to_mode(mask, modep, isdir));
  923. }
  924. static int
  925. acevals_to_aent(acevals_t *vals, aclent_t *dest, ace_list_t *list,
  926. uid_t owner, gid_t group, int isdir)
  927. {
  928. int error;
  929. uint32_t flips = ACE_POSIX_SUPPORTED_BITS;
  930. if (isdir)
  931. flips |= ACE_DELETE_CHILD;
  932. if (vals->allowed != (vals->denied ^ flips)) {
  933. error = ENOTSUP;
  934. goto out;
  935. }
  936. if ((list->hasmask) && (list->acl_mask != vals->mask) &&
  937. (vals->aent_type & (USER | GROUP | GROUP_OBJ))) {
  938. error = ENOTSUP;
  939. goto out;
  940. }
  941. error = ace_allow_to_mode(vals->allowed, &dest->a_perm, isdir);
  942. if (error != 0)
  943. goto out;
  944. dest->a_type = vals->aent_type;
  945. if (dest->a_type & (USER | GROUP)) {
  946. dest->a_id = vals->key;
  947. } else if (dest->a_type & USER_OBJ) {
  948. dest->a_id = owner;
  949. } else if (dest->a_type & GROUP_OBJ) {
  950. dest->a_id = group;
  951. } else if (dest->a_type & OTHER_OBJ) {
  952. dest->a_id = 0;
  953. } else {
  954. error = EINVAL;
  955. goto out;
  956. }
  957. out:
  958. return (error);
  959. }
  960. static int
  961. ace_list_to_aent(ace_list_t *list, aclent_t **aclentp, int *aclcnt,
  962. uid_t owner, gid_t group, int isdir)
  963. {
  964. int error = 0;
  965. aclent_t *aent, *result = NULL;
  966. acevals_t *vals;
  967. int resultcount;
  968. if ((list->seen & (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) !=
  969. (USER_OBJ | GROUP_OBJ | OTHER_OBJ)) {
  970. error = ENOTSUP;
  971. goto out;
  972. }
  973. if ((! list->hasmask) && (list->numusers + list->numgroups > 0)) {
  974. error = ENOTSUP;
  975. goto out;
  976. }
  977. resultcount = 3 + list->numusers + list->numgroups;
  978. /*
  979. * This must be the same condition as below, when we add the CLASS_OBJ
  980. * (aka ACL mask)
  981. */
  982. if ((list->hasmask) || (! list->dfacl_flag))
  983. resultcount += 1;
  984. if (cacl_malloc((void **)&result,
  985. resultcount * sizeof (aclent_t)) != 0) {
  986. error = ENOMEM;
  987. goto out;
  988. }
  989. aent = result;
  990. /* USER_OBJ */
  991. if (!(list->user_obj.aent_type & USER_OBJ)) {
  992. error = EINVAL;
  993. goto out;
  994. }
  995. error = acevals_to_aent(&list->user_obj, aent, list, owner, group,
  996. isdir);
  997. if (error != 0)
  998. goto out;
  999. ++aent;
  1000. /* USER */
  1001. vals = NULL;
  1002. for (vals = avl_first(&list->user); vals != NULL;
  1003. vals = AVL_NEXT(&list->user, vals)) {
  1004. if (!(vals->aent_type & USER)) {
  1005. error = EINVAL;
  1006. goto out;
  1007. }
  1008. error = acevals_to_aent(vals, aent, list, owner, group,
  1009. isdir);
  1010. if (error != 0)
  1011. goto out;
  1012. ++aent;
  1013. }
  1014. /* GROUP_OBJ */
  1015. if (!(list->group_obj.aent_type & GROUP_OBJ)) {
  1016. error = EINVAL;
  1017. goto out;
  1018. }
  1019. error = acevals_to_aent(&list->group_obj, aent, list, owner, group,
  1020. isdir);
  1021. if (error != 0)
  1022. goto out;
  1023. ++aent;
  1024. /* GROUP */
  1025. vals = NULL;
  1026. for (vals = avl_first(&list->group); vals != NULL;
  1027. vals = AVL_NEXT(&list->group, vals)) {
  1028. if (!(vals->aent_type & GROUP)) {
  1029. error = EINVAL;
  1030. goto out;
  1031. }
  1032. error = acevals_to_aent(vals, aent, list, owner, group,
  1033. isdir);
  1034. if (error != 0)
  1035. goto out;
  1036. ++aent;
  1037. }
  1038. /*
  1039. * CLASS_OBJ (aka ACL_MASK)
  1040. *
  1041. * An ACL_MASK is not fabricated if the ACL is a default ACL.
  1042. * This is to follow UFS's behavior.
  1043. */
  1044. if ((list->hasmask) || (! list->dfacl_flag)) {
  1045. if (list->hasmask) {
  1046. uint32_t flips = ACE_POSIX_SUPPORTED_BITS;
  1047. if (isdir)
  1048. flips |= ACE_DELETE_CHILD;
  1049. error = ace_mask_to_mode(list->acl_mask ^ flips,
  1050. &aent->a_perm, isdir);
  1051. if (error != 0)
  1052. goto out;
  1053. } else {
  1054. /* fabricate the ACL_MASK from the group permissions */
  1055. error = ace_mask_to_mode(list->group_obj.allowed,
  1056. &aent->a_perm, isdir);
  1057. if (error != 0)
  1058. goto out;
  1059. }
  1060. aent->a_id = 0;
  1061. aent->a_type = CLASS_OBJ | list->dfacl_flag;
  1062. ++aent;
  1063. }
  1064. /* OTHER_OBJ */
  1065. if (!(list->other_obj.aent_type & OTHER_OBJ)) {
  1066. error = EINVAL;
  1067. goto out;
  1068. }
  1069. error = acevals_to_aent(&list->other_obj, aent, list, owner, group,
  1070. isdir);
  1071. if (error != 0)
  1072. goto out;
  1073. ++aent;
  1074. *aclentp = result;
  1075. *aclcnt = resultcount;
  1076. out:
  1077. if (error != 0) {
  1078. if (result != NULL)
  1079. cacl_free(result, resultcount * sizeof (aclent_t));
  1080. }
  1081. return (error);
  1082. }
  1083. /*
  1084. * free all data associated with an ace_list
  1085. */
  1086. static void
  1087. ace_list_free(ace_list_t *al)
  1088. {
  1089. acevals_t *node;
  1090. void *cookie;
  1091. if (al == NULL)
  1092. return;
  1093. cookie = NULL;
  1094. while ((node = avl_destroy_nodes(&al->user, &cookie)) != NULL)
  1095. cacl_free(node, sizeof (acevals_t));
  1096. cookie = NULL;
  1097. while ((node = avl_destroy_nodes(&al->group, &cookie)) != NULL)
  1098. cacl_free(node, sizeof (acevals_t));
  1099. avl_destroy(&al->user);
  1100. avl_destroy(&al->group);
  1101. /* free the container itself */
  1102. cacl_free(al, sizeof (ace_list_t));
  1103. }
  1104. static int
  1105. acevals_compare(const void *va, const void *vb)
  1106. {
  1107. const acevals_t *a = va, *b = vb;
  1108. if (a->key == b->key)
  1109. return (0);
  1110. if (a->key > b->key)
  1111. return (1);
  1112. else
  1113. return (-1);
  1114. }
  1115. /*
  1116. * Convert a list of ace_t entries to equivalent regular and default
  1117. * aclent_t lists. Return error (ENOTSUP) when conversion is not possible.
  1118. */
  1119. static int
  1120. ln_ace_to_aent(ace_t *ace, int n, uid_t owner, gid_t group,
  1121. aclent_t **aclentp, int *aclcnt, aclent_t **dfaclentp, int *dfaclcnt,
  1122. int isdir)
  1123. {
  1124. int error = 0;
  1125. ace_t *acep;
  1126. uint32_t bits;
  1127. int i;
  1128. ace_list_t *normacl = NULL, *dfacl = NULL, *acl;
  1129. acevals_t *vals;
  1130. *aclentp = NULL;
  1131. *aclcnt = 0;
  1132. *dfaclentp = NULL;
  1133. *dfaclcnt = 0;
  1134. /* we need at least user_obj, group_obj, and other_obj */
  1135. if (n < 6) {
  1136. error = ENOTSUP;
  1137. goto out;
  1138. }
  1139. if (ace == NULL) {
  1140. error = EINVAL;
  1141. goto out;
  1142. }
  1143. error = cacl_malloc((void **)&normacl, sizeof (ace_list_t));
  1144. if (error != 0)
  1145. goto out;
  1146. avl_create(&normacl->user, acevals_compare, sizeof (acevals_t),
  1147. offsetof(acevals_t, avl));
  1148. avl_create(&normacl->group, acevals_compare, sizeof (acevals_t),
  1149. offsetof(acevals_t, avl));
  1150. ace_list_init(normacl, 0);
  1151. error = cacl_malloc((void **)&dfacl, sizeof (ace_list_t));
  1152. if (error != 0)
  1153. goto out;
  1154. avl_create(&dfacl->user, acevals_compare, sizeof (acevals_t),
  1155. offsetof(acevals_t, avl));
  1156. avl_create(&dfacl->group, acevals_compare, sizeof (acevals_t),
  1157. offsetof(acevals_t, avl));
  1158. ace_list_init(dfacl, ACL_DEFAULT);
  1159. /* process every ace_t... */
  1160. for (i = 0; i < n; i++) {
  1161. acep = &ace[i];
  1162. /* rule out certain cases quickly */
  1163. error = ace_to_aent_legal(acep);
  1164. if (error != 0)
  1165. goto out;
  1166. /*
  1167. * Turn off these bits in order to not have to worry about
  1168. * them when doing the checks for compliments.
  1169. */
  1170. acep->a_access_mask &= ~(ACE_WRITE_OWNER | ACE_DELETE |
  1171. ACE_SYNCHRONIZE | ACE_WRITE_ATTRIBUTES |
  1172. ACE_READ_NAMED_ATTRS | ACE_WRITE_NAMED_ATTRS);
  1173. /* see if this should be a regular or default acl */
  1174. bits = acep->a_flags &
  1175. (ACE_INHERIT_ONLY_ACE |
  1176. ACE_FILE_INHERIT_ACE |
  1177. ACE_DIRECTORY_INHERIT_ACE);
  1178. if (bits != 0) {
  1179. /* all or nothing on these inherit bits */
  1180. if (bits != (ACE_INHERIT_ONLY_ACE |
  1181. ACE_FILE_INHERIT_ACE |
  1182. ACE_DIRECTORY_INHERIT_ACE)) {
  1183. error = ENOTSUP;
  1184. goto out;
  1185. }
  1186. acl = dfacl;
  1187. } else {
  1188. acl = normacl;
  1189. }
  1190. if ((acep->a_flags & ACE_OWNER)) {
  1191. if (acl->state > ace_user_obj) {
  1192. error = ENOTSUP;
  1193. goto out;
  1194. }
  1195. acl->state = ace_user_obj;
  1196. acl->seen |= USER_OBJ;
  1197. vals = &acl->user_obj;
  1198. vals->aent_type = USER_OBJ | acl->dfacl_flag;
  1199. } else if ((acep->a_flags & ACE_EVERYONE)) {
  1200. acl->state = ace_other_obj;
  1201. acl->seen |= OTHER_OBJ;
  1202. vals = &acl->other_obj;
  1203. vals->aent_type = OTHER_OBJ | acl->dfacl_flag;
  1204. } else if (acep->a_flags & ACE_IDENTIFIER_GROUP) {
  1205. if (acl->state > ace_group) {
  1206. error = ENOTSUP;
  1207. goto out;
  1208. }
  1209. if ((acep->a_flags & ACE_GROUP)) {
  1210. acl->seen |= GROUP_OBJ;
  1211. vals = &acl->group_obj;
  1212. vals->aent_type = GROUP_OBJ | acl->dfacl_flag;
  1213. } else {
  1214. acl->seen |= GROUP;
  1215. vals = acevals_find(acep, &acl->group,
  1216. &acl->numgroups);
  1217. if (vals == NULL) {
  1218. error = ENOMEM;
  1219. goto out;
  1220. }
  1221. vals->aent_type = GROUP | acl->dfacl_flag;
  1222. }
  1223. acl->state = ace_group;
  1224. } else {
  1225. if (acl->state > ace_user) {
  1226. error = ENOTSUP;
  1227. goto out;
  1228. }
  1229. acl->state = ace_user;
  1230. acl->seen |= USER;
  1231. vals = acevals_find(acep, &acl->user,
  1232. &acl->numusers);
  1233. if (vals == NULL) {
  1234. error = ENOMEM;
  1235. goto out;
  1236. }
  1237. vals->aent_type = USER | acl->dfacl_flag;
  1238. }
  1239. if (!(acl->state > ace_unused)) {
  1240. error = EINVAL;
  1241. goto out;
  1242. }
  1243. if (acep->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE) {
  1244. /* no more than one allowed per aclent_t */
  1245. if (vals->allowed != ACE_MASK_UNDEFINED) {
  1246. error = ENOTSUP;
  1247. goto out;
  1248. }
  1249. vals->allowed = acep->a_access_mask;
  1250. } else {
  1251. /*
  1252. * it's a DENY; if there was a previous DENY, it
  1253. * must have been an ACL_MASK.
  1254. */
  1255. if (vals->denied != ACE_MASK_UNDEFINED) {
  1256. /* ACL_MASK is for USER and GROUP only */
  1257. if ((acl->state != ace_user) &&
  1258. (acl->state != ace_group)) {
  1259. error = ENOTSUP;
  1260. goto out;
  1261. }
  1262. if (! acl->hasmask) {
  1263. acl->hasmask = 1;
  1264. acl->acl_mask = vals->denied;
  1265. /* check for mismatched ACL_MASK emulations */
  1266. } else if (acl->acl_mask != vals->denied) {
  1267. error = ENOTSUP;
  1268. goto out;
  1269. }
  1270. vals->mask = vals->denied;
  1271. }
  1272. vals->denied = acep->a_access_mask;
  1273. }
  1274. }
  1275. /* done collating; produce the aclent_t lists */
  1276. if (normacl->state != ace_unused) {
  1277. error = ace_list_to_aent(normacl, aclentp, aclcnt,
  1278. owner, group, isdir);
  1279. if (error != 0) {
  1280. goto out;
  1281. }
  1282. }
  1283. if (dfacl->state != ace_unused) {
  1284. error = ace_list_to_aent(dfacl, dfaclentp, dfaclcnt,
  1285. owner, group, isdir);
  1286. if (error != 0) {
  1287. goto out;
  1288. }
  1289. }
  1290. out:
  1291. if (normacl != NULL)
  1292. ace_list_free(normacl);
  1293. if (dfacl != NULL)
  1294. ace_list_free(dfacl);
  1295. return (error);
  1296. }
  1297. static int
  1298. convert_ace_to_aent(ace_t *acebufp, int acecnt, int isdir,
  1299. uid_t owner, gid_t group, aclent_t **retaclentp, int *retaclcnt)
  1300. {
  1301. int error = 0;
  1302. aclent_t *aclentp, *dfaclentp;
  1303. int aclcnt, dfaclcnt;
  1304. int aclsz, dfaclsz;
  1305. error = ln_ace_to_aent(acebufp, acecnt, owner, group,
  1306. &aclentp, &aclcnt, &dfaclentp, &dfaclcnt, isdir);
  1307. if (error)
  1308. return (error);
  1309. if (dfaclcnt != 0) {
  1310. /*
  1311. * Slap aclentp and dfaclentp into a single array.
  1312. */
  1313. aclsz = sizeof (aclent_t) * aclcnt;
  1314. dfaclsz = sizeof (aclent_t) * dfaclcnt;
  1315. aclentp = cacl_realloc(aclentp, aclsz, aclsz + dfaclsz);
  1316. if (aclentp != NULL) {
  1317. (void) memcpy(aclentp + aclcnt, dfaclentp, dfaclsz);
  1318. } else {
  1319. error = ENOMEM;
  1320. }
  1321. }
  1322. if (aclentp) {
  1323. *retaclentp = aclentp;
  1324. *retaclcnt = aclcnt + dfaclcnt;
  1325. }
  1326. if (dfaclentp)
  1327. cacl_free(dfaclentp, dfaclsz);
  1328. return (error);
  1329. }
  1330. int
  1331. acl_translate(acl_t *aclp, int target_flavor, int isdir, uid_t owner,
  1332. gid_t group)
  1333. {
  1334. int aclcnt;
  1335. void *acldata;
  1336. int error;
  1337. /*
  1338. * See if we need to translate
  1339. */
  1340. if ((target_flavor == _ACL_ACE_ENABLED && aclp->acl_type == ACE_T) ||
  1341. (target_flavor == _ACL_ACLENT_ENABLED &&
  1342. aclp->acl_type == ACLENT_T))
  1343. return (0);
  1344. if (target_flavor == -1) {
  1345. error = EINVAL;
  1346. goto out;
  1347. }
  1348. if (target_flavor == _ACL_ACE_ENABLED &&
  1349. aclp->acl_type == ACLENT_T) {
  1350. error = convert_aent_to_ace(aclp->acl_aclp,
  1351. aclp->acl_cnt, isdir, (ace_t **)&acldata, &aclcnt);
  1352. if (error)
  1353. goto out;
  1354. } else if (target_flavor == _ACL_ACLENT_ENABLED &&
  1355. aclp->acl_type == ACE_T) {
  1356. error = convert_ace_to_aent(aclp->acl_aclp, aclp->acl_cnt,
  1357. isdir, owner, group, (aclent_t **)&acldata, &aclcnt);
  1358. if (error)
  1359. goto out;
  1360. } else {
  1361. error = ENOTSUP;
  1362. goto out;
  1363. }
  1364. /*
  1365. * replace old acl with newly translated acl
  1366. */
  1367. cacl_free(aclp->acl_aclp, aclp->acl_cnt * aclp->acl_entry_size);
  1368. aclp->acl_aclp = acldata;
  1369. aclp->acl_cnt = aclcnt;
  1370. if (target_flavor == _ACL_ACE_ENABLED) {
  1371. aclp->acl_type = ACE_T;
  1372. aclp->acl_entry_size = sizeof (ace_t);
  1373. } else {
  1374. aclp->acl_type = ACLENT_T;
  1375. aclp->acl_entry_size = sizeof (aclent_t);
  1376. }
  1377. return (0);
  1378. out:
  1379. #if !defined(_KERNEL)
  1380. errno = error;
  1381. return (-1);
  1382. #else
  1383. return (error);
  1384. #endif
  1385. }
  1386. #define SET_ACE(acl, index, who, mask, type, flags) { \
  1387. acl[0][index].a_who = (uint32_t)who; \
  1388. acl[0][index].a_type = type; \
  1389. acl[0][index].a_flags = flags; \
  1390. acl[0][index++].a_access_mask = mask; \
  1391. }
  1392. void
  1393. acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1,
  1394. uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone)
  1395. {
  1396. *deny1 = *deny2 = *allow0 = *group = 0;
  1397. if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
  1398. *deny1 |= ACE_READ_DATA;
  1399. if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH)))
  1400. *deny1 |= ACE_WRITE_DATA;
  1401. if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))
  1402. *deny1 |= ACE_EXECUTE;
  1403. if (!(mode & S_IRGRP) && (mode & S_IROTH))
  1404. *deny2 = ACE_READ_DATA;
  1405. if (!(mode & S_IWGRP) && (mode & S_IWOTH))
  1406. *deny2 |= ACE_WRITE_DATA;
  1407. if (!(mode & S_IXGRP) && (mode & S_IXOTH))
  1408. *deny2 |= ACE_EXECUTE;
  1409. if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH)))
  1410. *allow0 |= ACE_READ_DATA;
  1411. if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH)))
  1412. *allow0 |= ACE_WRITE_DATA;
  1413. if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH)))
  1414. *allow0 |= ACE_EXECUTE;
  1415. *owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
  1416. ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES|
  1417. ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE;
  1418. if (mode & S_IRUSR)
  1419. *owner |= ACE_READ_DATA;
  1420. if (mode & S_IWUSR)
  1421. *owner |= ACE_WRITE_DATA|ACE_APPEND_DATA;
  1422. if (mode & S_IXUSR)
  1423. *owner |= ACE_EXECUTE;
  1424. *group = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
  1425. ACE_SYNCHRONIZE;
  1426. if (mode & S_IRGRP)
  1427. *group |= ACE_READ_DATA;
  1428. if (mode & S_IWGRP)
  1429. *group |= ACE_WRITE_DATA|ACE_APPEND_DATA;
  1430. if (mode & S_IXGRP)
  1431. *group |= ACE_EXECUTE;
  1432. *everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
  1433. ACE_SYNCHRONIZE;
  1434. if (mode & S_IROTH)
  1435. *everyone |= ACE_READ_DATA;
  1436. if (mode & S_IWOTH)
  1437. *everyone |= ACE_WRITE_DATA|ACE_APPEND_DATA;
  1438. if (mode & S_IXOTH)
  1439. *everyone |= ACE_EXECUTE;
  1440. }
  1441. int
  1442. acl_trivial_create(mode_t mode, ace_t **acl, int *count)
  1443. {
  1444. uint32_t deny1, deny2;
  1445. uint32_t allow0;
  1446. uint32_t owner, group, everyone;
  1447. int index = 0;
  1448. int error;
  1449. *count = 3;
  1450. acl_trivial_access_masks(mode, &allow0, &deny1, &deny2, &owner, &group,
  1451. &everyone);
  1452. if (allow0)
  1453. (*count)++;
  1454. if (deny1)
  1455. (*count)++;
  1456. if (deny2)
  1457. (*count)++;
  1458. if ((error = cacl_malloc((void **)acl, *count * sizeof (ace_t))) != 0)
  1459. return (error);
  1460. if (allow0) {
  1461. SET_ACE(acl, index, -1, allow0, ACE_ACCESS_ALLOWED_ACE_TYPE,
  1462. ACE_OWNER);
  1463. }
  1464. if (deny1) {
  1465. SET_ACE(acl, index, -1, deny1, ACE_ACCESS_DENIED_ACE_TYPE,
  1466. ACE_OWNER);
  1467. }
  1468. if (deny2) {
  1469. SET_ACE(acl, index, -1, deny2, ACE_ACCESS_DENIED_ACE_TYPE,
  1470. ACE_GROUP|ACE_IDENTIFIER_GROUP);
  1471. }
  1472. SET_ACE(acl, index, -1, owner, ACE_ACCESS_ALLOWED_ACE_TYPE, ACE_OWNER);
  1473. SET_ACE(acl, index, -1, group, ACE_ACCESS_ALLOWED_ACE_TYPE,
  1474. ACE_IDENTIFIER_GROUP|ACE_GROUP);
  1475. SET_ACE(acl, index, -1, everyone, ACE_ACCESS_ALLOWED_ACE_TYPE,
  1476. ACE_EVERYONE);
  1477. return (0);
  1478. }
  1479. /*
  1480. * ace_trivial:
  1481. * determine whether an ace_t acl is trivial
  1482. *
  1483. * Trivialness implies that the acl is composed of only
  1484. * owner, group, everyone entries. ACL can't
  1485. * have read_acl denied, and write_owner/write_acl/write_attributes
  1486. * can only be owner@ entry.
  1487. */
  1488. int
  1489. ace_trivial_common(void *acep, int aclcnt,
  1490. uint64_t (*walk)(void *, uint64_t, int aclcnt,
  1491. uint16_t *, uint16_t *, uint32_t *))
  1492. {
  1493. uint16_t flags;
  1494. uint32_t mask;
  1495. uint16_t type;
  1496. uint64_t cookie = 0;
  1497. while (cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask)) {
  1498. switch (flags & ACE_TYPE_FLAGS) {
  1499. case ACE_OWNER:
  1500. case ACE_GROUP|ACE_IDENTIFIER_GROUP:
  1501. case ACE_EVERYONE:
  1502. break;
  1503. default:
  1504. return (1);
  1505. }
  1506. if (flags & (ACE_FILE_INHERIT_ACE|
  1507. ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE|
  1508. ACE_INHERIT_ONLY_ACE))
  1509. return (1);
  1510. /*
  1511. * Special check for some special bits
  1512. *
  1513. * Don't allow anybody to deny reading basic
  1514. * attributes or a files ACL.
  1515. */
  1516. if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) &&
  1517. (type == ACE_ACCESS_DENIED_ACE_TYPE))
  1518. return (1);
  1519. /*
  1520. * Delete permissions are never set by default
  1521. */
  1522. if (mask & (ACE_DELETE|ACE_DELETE_CHILD))
  1523. return (1);
  1524. /*
  1525. * only allow owner@ to have
  1526. * write_acl/write_owner/write_attributes/write_xattr/
  1527. */
  1528. if (type == ACE_ACCESS_ALLOWED_ACE_TYPE &&
  1529. (!(flags & ACE_OWNER) && (mask &
  1530. (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES|
  1531. ACE_WRITE_NAMED_ATTRS))))
  1532. return (1);
  1533. }
  1534. return (0);
  1535. }
  1536. uint64_t
  1537. ace_walk(void *datap, uint64_t cookie, int aclcnt, uint16_t *flags,
  1538. uint16_t *type, uint32_t *mask)
  1539. {
  1540. ace_t *acep = datap;
  1541. if (cookie >= aclcnt)
  1542. return (0);
  1543. *flags = acep[cookie].a_flags;
  1544. *type = acep[cookie].a_type;
  1545. *mask = acep[cookie++].a_access_mask;
  1546. return (cookie);
  1547. }
  1548. int
  1549. ace_trivial(ace_t *acep, int aclcnt)
  1550. {
  1551. return (ace_trivial_common(acep, aclcnt, ace_walk));
  1552. }