]>
Commit | Line | Data |
---|---|---|
3d9156a7 | 1 | /* |
1f2f436a | 2 | * Copyright (c) 2004, 2011 Apple Inc. All rights reserved. |
3d9156a7 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * This file contains Original Code and/or Modifications of Original Code | |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. Please obtain a copy of the License at | |
10 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
11 | * file. | |
12 | * | |
13 | * The Original Code and all software distributed under the License are | |
14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
18 | * Please see the License for the specific language governing rights and | |
19 | * limitations under the License. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | #include <sys/appleapiopts.h> | |
25 | #include <sys/types.h> | |
26 | #include <sys/acl.h> | |
27 | #include <errno.h> | |
28 | #include <stdlib.h> | |
29 | #include <string.h> | |
30 | ||
31 | #include "aclvar.h" | |
32 | ||
1f2f436a A |
33 | #if __DARWIN_ACL_EXTENDED_ALLOW != KAUTH_ACE_PERMIT |
34 | # error __DARWIN_ACL_EXTENDED_ALLOW != KAUTH_ACE_PERMIT | |
35 | #endif | |
36 | #if __DARWIN_ACL_EXTENDED_DENY != KAUTH_ACE_DENY | |
37 | # error __DARWIN_ACL_EXTENDED_DENY != KAUTH_ACE_DENY | |
38 | #endif | |
39 | ||
3d9156a7 A |
40 | int |
41 | acl_copy_entry(acl_entry_t dest, acl_entry_t src) | |
42 | { | |
43 | /* validate arguments */ | |
44 | _ACL_VALIDATE_ENTRY(dest); | |
45 | _ACL_VALIDATE_ENTRY(src); | |
46 | if (dest == src) { | |
47 | errno = EINVAL; | |
48 | return(-1); | |
49 | } | |
50 | bcopy(src, dest, sizeof(*src)); | |
51 | return(0); | |
52 | } | |
53 | ||
54 | int | |
55 | acl_create_entry_np(acl_t *acl_p, acl_entry_t *entry_p, int index) | |
56 | { | |
57 | struct _acl *ap = *acl_p; | |
58 | int i; | |
59 | ||
60 | /* validate arguments */ | |
61 | _ACL_VALIDATE_ACL(ap); | |
62 | if (ap->a_entries >= ACL_MAX_ENTRIES) { | |
63 | errno = ENOMEM; | |
64 | return(-1); | |
65 | } | |
66 | if (index == ACL_LAST_ENTRY) | |
67 | index = ap->a_entries; | |
68 | if (index > ap->a_entries) { | |
69 | errno = ERANGE; | |
70 | return(-1); | |
71 | } | |
72 | ||
73 | /* move following entries out of the way */ | |
74 | for (i = ap->a_entries; i > index; i--) | |
75 | ap->a_ace[i] = ap->a_ace[i - 1]; | |
76 | ap->a_entries++; | |
77 | ||
78 | /* initialise new entry */ | |
1f2f436a | 79 | memset(&ap->a_ace[index], 0, sizeof(ap->a_ace[index])); |
3d9156a7 A |
80 | ap->a_ace[index].ae_magic = _ACL_ENTRY_MAGIC; |
81 | ap->a_ace[index].ae_tag = ACL_UNDEFINED_TAG; | |
82 | ||
83 | *entry_p = &ap->a_ace[index]; | |
84 | return(0); | |
85 | } | |
86 | ||
87 | int | |
88 | acl_create_entry(acl_t *acl_p, acl_entry_t *entry_p) | |
89 | { | |
90 | return(acl_create_entry_np(acl_p, entry_p, ACL_LAST_ENTRY)); | |
91 | } | |
92 | ||
93 | int | |
94 | acl_delete_entry(acl_t acl, acl_entry_t entry) | |
95 | { | |
96 | int i; | |
97 | ||
98 | _ACL_VALIDATE_ACL(acl); | |
99 | _ACL_VALIDATE_ENTRY(entry); | |
100 | _ACL_VALIDATE_ENTRY_CONTAINED(acl, entry); | |
101 | ||
102 | /* copy following entries down & invalidate last slot */ | |
103 | acl->a_entries--; | |
104 | for (i = entry - &acl->a_ace[0]; i < acl->a_entries; i++) | |
105 | acl->a_ace[i] = acl->a_ace[i + 1]; | |
106 | acl->a_ace[acl->a_entries].ae_magic = 0; | |
107 | /* Sync up the iterator's position if necessary */ | |
108 | if (acl->a_last_get >= (entry - &acl->a_ace[0])) | |
109 | acl->a_last_get--; | |
110 | ||
111 | return(0); | |
112 | } | |
113 | ||
114 | int | |
115 | acl_get_entry(acl_t acl, int entry_id, acl_entry_t *entry_p) | |
116 | { | |
117 | ||
118 | _ACL_VALIDATE_ACL(acl); | |
119 | if ((entry_id != ACL_FIRST_ENTRY) && | |
120 | (entry_id != ACL_NEXT_ENTRY) && | |
121 | (entry_id != ACL_LAST_ENTRY) && | |
122 | ((entry_id < 0) || (entry_id >= acl->a_entries))) { | |
123 | errno = EINVAL; | |
124 | return(-1); | |
125 | } | |
126 | if (entry_id == ACL_FIRST_ENTRY) | |
127 | entry_id = 0; | |
128 | else | |
129 | if (entry_id == ACL_NEXT_ENTRY) { | |
130 | entry_id = acl->a_last_get + 1; | |
131 | } | |
132 | else | |
133 | if (entry_id == ACL_LAST_ENTRY) | |
134 | entry_id = acl->a_entries - 1; | |
135 | ||
136 | if (entry_id >= acl->a_entries) { | |
137 | errno = EINVAL; | |
138 | return (-1); | |
139 | } | |
140 | ||
141 | *entry_p = &acl->a_ace[entry_id]; | |
142 | acl->a_last_get = entry_id; | |
143 | ||
144 | return(0); | |
145 | } | |
146 | ||
147 | void * | |
148 | acl_get_qualifier(acl_entry_t entry) | |
149 | { | |
150 | acl_tag_t tag_type; | |
151 | void *result; | |
152 | int error; | |
153 | ||
154 | result = NULL; | |
155 | if (!_ACL_VALID_ENTRY(entry)) { | |
156 | errno = EINVAL; | |
157 | } else if ((error = acl_get_tag_type(entry, &tag_type)) != 0) { | |
158 | /* errno is set by acl_get_tag_type */ | |
159 | } else { | |
160 | switch(tag_type) { | |
161 | case ACL_EXTENDED_ALLOW: | |
162 | case ACL_EXTENDED_DENY: | |
163 | if ((result = malloc(sizeof(guid_t))) != NULL) | |
164 | bcopy(&entry->ae_applicable, result, sizeof(guid_t)); | |
165 | break; | |
166 | default: | |
167 | errno = EINVAL; | |
168 | break; | |
169 | } | |
170 | } | |
171 | return(result); | |
172 | } | |
173 | ||
174 | int | |
175 | acl_get_tag_type(acl_entry_t entry, acl_tag_t *tag_type_p) | |
176 | { | |
177 | _ACL_VALIDATE_ENTRY(entry); | |
178 | ||
179 | *tag_type_p = entry->ae_tag; | |
180 | return(0); | |
181 | } | |
182 | ||
183 | int | |
184 | acl_set_qualifier(acl_entry_t entry, const void *tag_qualifier_p) | |
185 | { | |
186 | acl_tag_t tag_type; | |
3d9156a7 A |
187 | |
188 | _ACL_VALIDATE_ENTRY(entry); | |
34e8f829 A |
189 | if (acl_get_tag_type(entry, &tag_type) != 0) |
190 | return(-1); | |
3d9156a7 A |
191 | |
192 | switch(tag_type) { | |
193 | case ACL_EXTENDED_ALLOW: | |
194 | case ACL_EXTENDED_DENY: | |
195 | bcopy(tag_qualifier_p, &entry->ae_applicable, sizeof(guid_t)); | |
3d9156a7 A |
196 | break; |
197 | default: | |
34e8f829 A |
198 | errno = EINVAL; |
199 | return(-1); | |
3d9156a7 | 200 | } |
34e8f829 | 201 | return(0); |
3d9156a7 A |
202 | } |
203 | ||
204 | int | |
205 | acl_set_tag_type(acl_entry_t entry, acl_tag_t tag_type) | |
206 | { | |
207 | _ACL_VALIDATE_ENTRY(entry); | |
208 | ||
209 | switch(tag_type) { | |
210 | case ACL_EXTENDED_ALLOW: | |
211 | case ACL_EXTENDED_DENY: | |
212 | entry->ae_tag = tag_type; | |
213 | break; | |
214 | default: | |
34e8f829 A |
215 | errno = EINVAL; |
216 | return(-1); | |
3d9156a7 A |
217 | } |
218 | return(0); | |
219 | } |