2 * Copyright (c) 2001 Chris D. Faulhaber
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE VOICES IN HIS HEAD BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/types.h>
39 static int merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new);
42 merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new)
44 acl_permset_t permset;
50 id = acl_get_qualifier(*entry);
52 err(1, "acl_get_qualifier() failed");
53 id_new = acl_get_qualifier(*entry_new);
55 err(1, "acl_get_qualifier() failed");
57 /* any other matches */
58 if (acl_get_permset(*entry, &permset) == -1)
59 err(1, "acl_get_permset() failed");
60 if (acl_set_permset(*entry_new, permset) == -1)
61 err(1, "acl_set_permset() failed");
71 * merge an ACL into existing file's ACL
74 merge_acl(acl_t acl, acl_t *prev_acl)
76 acl_entry_t entry, entry_new;
77 acl_permset_t permset;
79 acl_tag_t tag, tag_new;
80 int entry_id, entry_id_new, have_entry;
82 if (acl_type == ACL_TYPE_ACCESS)
83 acl_new = acl_dup(prev_acl[ACCESS_ACL]);
85 acl_new = acl_dup(prev_acl[DEFAULT_ACL]);
87 err(1, "acl_dup() failed");
89 entry_id = ACL_FIRST_ENTRY;
91 while (acl_get_entry(acl, entry_id, &entry) == 1) {
92 entry_id = ACL_NEXT_ENTRY;
95 /* keep track of existing ACL_MASK entries */
96 if (acl_get_tag_type(entry, &tag) == -1)
97 err(1, "acl_get_tag_type() failed - invalid ACL entry");
101 /* check against the existing ACL entries */
102 entry_id_new = ACL_FIRST_ENTRY;
103 while (have_entry == 0 &&
104 acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) {
105 entry_id_new = ACL_NEXT_ENTRY;
107 if (acl_get_tag_type(entry, &tag) == -1)
108 err(1, "acl_get_tag_type() failed");
109 if (acl_get_tag_type(entry_new, &tag_new) == -1)
110 err(1, "acl_get_tag_type() failed");
117 have_entry = merge_user_group(&entry,
126 if (acl_get_permset(entry, &permset) == -1)
127 err(1, "acl_get_permset() failed");
128 if (acl_set_permset(entry_new, permset) == -1)
129 err(1, "acl_set_permset() failed");
133 /* should never be here */
134 errx(1, "Invalid tag type: %i", tag);
139 /* if this entry has not been found, it must be new */
140 if (have_entry == 0) {
141 if (acl_create_entry(&acl_new, &entry_new) == -1) {
145 if (acl_copy_entry(entry_new, entry) == -1)
146 err(1, "acl_copy_entry() failed");
150 if (acl_type == ACL_TYPE_ACCESS) {
151 acl_free(prev_acl[ACCESS_ACL]);
152 prev_acl[ACCESS_ACL] = acl_new;
154 acl_free(prev_acl[DEFAULT_ACL]);
155 prev_acl[DEFAULT_ACL] = acl_new;