]> git.saurik.com Git - apple/libc.git/blame - gen/filesec.c
Libc-391.tar.gz
[apple/libc.git] / gen / filesec.c
CommitLineData
3d9156a7
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
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/types.h>
25#include <sys/acl.h>
26#include <stdlib.h>
27#include <fcntl.h>
28#include <strings.h>
29#include <errno.h>
30#include <uuid/uuid.h>
31
32
33struct _filesec {
34 int fs_valid;
35#define FS_VALID_UID (1<<0)
36#define FS_VALID_GID (1<<1)
37#define FS_VALID_UUID (1<<2)
38#define FS_VALID_GRPUUID (1<<3)
39#define FS_VALID_MODE (1<<4)
40#define FS_VALID_ACL (1<<5)
41 uid_t fs_uid;
42 gid_t fs_gid;
43 uuid_t fs_uuid;
44 uuid_t fs_grpuuid;
45 mode_t fs_mode;
46 size_t fs_aclsize;
47 void *fs_aclbuf;
48};
49
50#define FS_ISVALID(_fsec, _bit) ((_fsec)->fs_valid & (_bit))
51#define FS_CLEAR(_fsec, _bit) ((_fsec)->fs_valid &= ~(_bit))
52#define FS_SET(_fsec, _bit) ((_fsec)->fs_valid |= (_bit))
53
54static void filesec_discard_aclbuf(struct _filesec *fsec);
55
56filesec_t
57filesec_init(void)
58{
59 struct _filesec *fsp;
60
61 fsp = malloc(sizeof(*fsp));
62 if (fsp != NULL)
63 fsp->fs_valid = 0;
64 return(fsp);
65}
66
67filesec_t
68filesec_dup(filesec_t fsec)
69{
70 struct _filesec *fsp;
71
72 fsp = malloc(sizeof(*fsp));
73 if (fsp != NULL) {
74 *fsp = *fsec;
75 if (FS_ISVALID(fsec, FS_VALID_ACL)) {
76 if (fsec->fs_aclbuf != _FILESEC_REMOVE_ACL) {
77 fsp->fs_aclbuf = malloc(fsec->fs_aclsize);
78 if (fsp->fs_aclbuf == NULL) {
79 free(fsp);
80 return(NULL);
81 }
82 bcopy(fsec->fs_aclbuf, fsp->fs_aclbuf, fsec->fs_aclsize);
83 }
84 }
85 }
86 return(fsp);
87}
88
89void
90filesec_free(filesec_t fsec)
91{
92 filesec_discard_aclbuf(fsec);
93 free(fsec);
94}
95
96int
97filesec_get_property(filesec_t fsec, filesec_property_t property, void *propptr)
98{
99 int error;
100
101 error = 0;
102 switch(property) {
103 case FILESEC_OWNER:
104 if (!FS_ISVALID(fsec, FS_VALID_UID)) {
105 error = ENOENT;
106 break;
107 }
108 if (propptr != NULL)
109 *(uid_t *)propptr = fsec->fs_uid;
110 break;
111 case FILESEC_GROUP:
112 if (!FS_ISVALID(fsec, FS_VALID_GID)) {
113 error = ENOENT;
114 break;
115 }
116 if (propptr != NULL)
117 *(gid_t *)propptr = fsec->fs_gid;
118 break;
119 case FILESEC_UUID:
120 if (!FS_ISVALID(fsec, FS_VALID_UUID)) {
121 error = ENOENT;
122 break;
123 }
124 if (propptr != NULL)
125 uuid_copy(*(uuid_t *)propptr, fsec->fs_uuid);
126 break;
127 case FILESEC_GRPUUID:
128 if (!FS_ISVALID(fsec, FS_VALID_GRPUUID)) {
129 error = ENOENT;
130 break;
131 }
132 if (propptr != NULL)
133 uuid_copy(*(uuid_t *)propptr, fsec->fs_grpuuid);
134 break;
135 case FILESEC_MODE:
136 if (!FS_ISVALID(fsec, FS_VALID_MODE)) {
137 error = ENOENT;
138 break;
139 }
140 if (propptr != NULL)
141 *(mode_t *)propptr = fsec->fs_mode;
142 break;
143 case FILESEC_ACL:
144 if (!FS_ISVALID(fsec, FS_VALID_ACL)) {
145 error = ENOENT;
146 break;
147 }
148 if (propptr != NULL) {
149 if (fsec->fs_aclbuf == _FILESEC_REMOVE_ACL) {
150 *(acl_t *)propptr = _FILESEC_REMOVE_ACL;
151 } else {
152 *(acl_t *)propptr = acl_copy_int(fsec->fs_aclbuf);
153 if (*(acl_t *)propptr == NULL)
154 error = errno;
155 }
156 }
157 break;
158 case FILESEC_ACL_RAW:
159 if (!FS_ISVALID(fsec, FS_VALID_ACL)) {
160 error = ENOENT;
161 break;
162 }
163 if (propptr != NULL)
164 *(void **)propptr = fsec->fs_aclbuf;
165 break;
166 case FILESEC_ACL_ALLOCSIZE:
167 if (!FS_ISVALID(fsec, FS_VALID_ACL)) {
168 error = ENOENT;
169 break;
170 }
171 if (propptr != NULL)
172 *(size_t *)propptr = fsec->fs_aclsize;
173 break;
174 default:
175 error = EINVAL;
176 break;
177 }
178 if (error) {
179 errno = error;
180 return(-1);
181 }
182 return(0);
183}
184
185int
186filesec_set_property(filesec_t fsec, filesec_property_t property, const void *propptr)
187{
188 void *aclbuf;
189 ssize_t aclsize, copysize;
190 acl_t acl;
191 int error;
192
193 error = 0;
194 switch(property) {
195 case FILESEC_OWNER:
196 if (propptr == _FILESEC_UNSET_PROPERTY) {
197 FS_CLEAR(fsec, FS_VALID_UID);
198 } else {
199 fsec->fs_uid = *(uid_t *)propptr;
200 FS_SET(fsec, FS_VALID_UID);
201 }
202 break;
203 case FILESEC_GROUP:
204 if (propptr == _FILESEC_UNSET_PROPERTY) {
205 FS_CLEAR(fsec, FS_VALID_GID);
206 } else {
207 fsec->fs_gid = *(gid_t *)propptr;
208 FS_SET(fsec, FS_VALID_GID);
209 }
210 break;
211 case FILESEC_UUID:
212 if (propptr == _FILESEC_UNSET_PROPERTY) {
213 FS_CLEAR(fsec, FS_VALID_UUID);
214 } else {
215 uuid_copy(fsec->fs_uuid, *(uuid_t *)propptr);
216 FS_SET(fsec, FS_VALID_UUID);
217 }
218 break;
219 case FILESEC_GRPUUID:
220 if (propptr == _FILESEC_UNSET_PROPERTY) {
221 FS_CLEAR(fsec, FS_VALID_GRPUUID);
222 } else {
223 uuid_copy(fsec->fs_grpuuid, *(uuid_t *)propptr);
224 FS_SET(fsec, FS_VALID_GRPUUID);
225 }
226 break;
227 case FILESEC_MODE:
228 if (propptr == _FILESEC_UNSET_PROPERTY) {
229 FS_CLEAR(fsec, FS_VALID_MODE);
230 } else {
231 fsec->fs_mode = *(mode_t *)propptr;
232 FS_SET(fsec, FS_VALID_MODE);
233 }
234 break;
235 case FILESEC_ACL:
236 if (propptr == _FILESEC_UNSET_PROPERTY) {
237 filesec_discard_aclbuf(fsec);
238 FS_CLEAR(fsec, FS_VALID_ACL);
239 } else if (propptr == _FILESEC_REMOVE_ACL) {
240 filesec_discard_aclbuf(fsec);
241 fsec->fs_aclbuf = _FILESEC_REMOVE_ACL;
242 fsec->fs_aclsize = 0;
243 FS_SET(fsec, FS_VALID_ACL);
244 } else {
245 acl = *(acl_t *)propptr;
246 aclsize = acl_size(acl);
247 if (aclsize < 0) {
248 error = errno;
249 break;
250 }
251 if ((aclbuf = malloc(aclsize)) == NULL) {
252 error = errno;
253 break;
254 }
255 copysize = acl_copy_ext(aclbuf, acl, aclsize);
256 if (copysize < 0) {
257 free(aclbuf);
258 error = EINVAL;
259 break;
260 }
261 filesec_discard_aclbuf(fsec);
262 fsec->fs_aclbuf = aclbuf;
263 fsec->fs_aclsize = aclsize;
264 FS_SET(fsec, FS_VALID_ACL);
265 }
266 break;
267 case FILESEC_ACL_RAW:
268 filesec_discard_aclbuf(fsec);
269 if ((propptr != NULL) && (*(void **)propptr != NULL)) {
270 fsec->fs_aclbuf = *(void **)propptr;
271 FS_SET(fsec, FS_VALID_ACL);
272 }
273 break;
274 case FILESEC_ACL_ALLOCSIZE:
275 if (propptr != NULL) {
276 fsec->fs_aclsize = *(size_t *)propptr;
277 } else {
278 error = EINVAL;
279 }
280 break;
281 default:
282 error = EINVAL;
283 break;
284 }
285 if (error != 0) {
286 errno = error;
287 return (-1);
288 }
289 return (0);
290}
291
292int
293filesec_query_property(filesec_t fsec, filesec_property_t property, int *validptr)
294{
295 int valid, error;
296
297 error = 0;
298 switch(property) {
299 case FILESEC_OWNER:
300 valid = FS_ISVALID(fsec, FS_VALID_UID);
301 break;
302 case FILESEC_GROUP:
303 valid = FS_ISVALID(fsec, FS_VALID_GID);
304 break;
305 case FILESEC_UUID:
306 valid = FS_ISVALID(fsec, FS_VALID_UUID);
307 break;
308 case FILESEC_GRPUUID:
309 valid = FS_ISVALID(fsec, FS_VALID_GRPUUID);
310 break;
311 case FILESEC_MODE:
312 valid = FS_ISVALID(fsec, FS_VALID_MODE);
313 break;
314 case FILESEC_ACL:
315 case FILESEC_ACL_RAW:
316 case FILESEC_ACL_ALLOCSIZE:
317 valid = FS_ISVALID(fsec, FS_VALID_ACL);
318 break;
319 default:
320 error = EINVAL;
321 break;
322 }
323
324 if (error != 0) {
325 errno = error;
326 return(-1);
327 }
328 *validptr = valid;
329 return(0);
330}
331
332static void
333filesec_discard_aclbuf(struct _filesec *fsec)
334{
335 if (FS_ISVALID(fsec, FS_VALID_ACL)) {
336 if (fsec->fs_aclbuf != _FILESEC_REMOVE_ACL)
337 free(fsec->fs_aclbuf);
338 fsec->fs_aclbuf = NULL;
339 fsec->fs_aclsize = 0;
340 FS_CLEAR(fsec, FS_VALID_ACL);
341 }
342}