]> git.saurik.com Git - apple/libc.git/blob - sys/openx_np.c
Libc-498.tar.gz
[apple/libc.git] / sys / openx_np.c
1 /*
2 * Copyright (c) 2004 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 #include <sys/types.h>
24 #include <sys/acl.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <string.h>
29
30 enum {OPENX, MKFIFOX, MKDIRX};
31
32 extern int __open_extended(const char *, int, uid_t, gid_t, int, struct kauth_filesec *);
33 extern int __mkfifo_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *);
34 extern int __mkdir_extended(const char *, uid_t, gid_t, int, struct kauth_filesec *);
35
36 static int
37 _mkfilex_np(int opcode, const char *path, int flags, filesec_t fsec)
38 {
39 uid_t owner = KAUTH_UID_NONE;
40 gid_t group = KAUTH_GID_NONE;
41 mode_t mode = 0;
42 size_t size = 0;
43 int fsacl_used = 0;
44 struct kauth_filesec *fsacl = NULL;
45 struct kauth_filesec static_filesec;
46
47 /* handle extended security data */
48 if (fsec != NULL) {
49 /* fetch basic parameters */
50 if ((filesec_get_property(fsec, FILESEC_OWNER, &owner) != 0) && (errno != ENOENT))
51 return(-1);
52 if ((filesec_get_property(fsec, FILESEC_GROUP, &group) != 0) && (errno != ENOENT))
53 return(-1);
54 if ((filesec_get_property(fsec, FILESEC_MODE, &mode) != 0) && (errno != ENOENT))
55 return(-1);
56
57 /* try to fetch the ACL */
58 if (((filesec_get_property(fsec, FILESEC_ACL_RAW, &fsacl) != 0) ||
59 (filesec_get_property(fsec, FILESEC_ACL_ALLOCSIZE, &size) != 0)) &&
60 (errno != ENOENT))
61 return(-1);
62
63 /* only valid for chmod */
64 if (fsacl == _FILESEC_REMOVE_ACL) {
65 errno = EINVAL;
66 return(-1);
67 }
68
69 /* no ACL, use local filesec */
70 if (fsacl == NULL) {
71 bzero(&static_filesec, sizeof(static_filesec));
72 fsacl = &static_filesec;
73 fsacl->fsec_magic = KAUTH_FILESEC_MAGIC;
74 fsacl->fsec_entrycount = KAUTH_FILESEC_NOACL;
75 } else {
76 fsacl_used = 1;
77 }
78
79 /* grab the owner and group UUID if present */
80 if (filesec_get_property(fsec, FILESEC_UUID, &fsacl->fsec_owner) != 0) {
81 if (errno != ENOENT)
82 return(-1);
83 bzero(&fsacl->fsec_owner, sizeof(fsacl->fsec_owner));
84 } else {
85 fsacl_used = 1;
86 }
87 if (filesec_get_property(fsec, FILESEC_GRPUUID, &fsacl->fsec_group) != 0) {
88 if (errno != ENOENT)
89 return(-1);
90 bzero(&fsacl->fsec_group, sizeof(fsacl->fsec_group));
91 } else {
92 fsacl_used = 1;
93 }
94
95 /* after all this, if we didn't find anything that needs it, don't pass it in */
96 if (!fsacl_used)
97 fsacl = NULL;
98 }
99
100 switch (opcode) {
101 case OPENX:
102 return(__open_extended(path, flags, owner, group, mode, fsacl));
103 case MKFIFOX:
104 return(__mkfifo_extended(path, owner, group, mode, fsacl));
105 case MKDIRX:
106 return(__mkdir_extended(path, owner, group, mode, fsacl));
107 }
108 /* should never get here */
109 errno = EINVAL;
110 return(-1);
111 }
112
113 int
114 openx_np(const char *path, int flags, filesec_t fsec)
115 {
116 /* optimise for the simple case */
117 if (!(flags & O_CREAT) || (fsec == NULL))
118 return(open(path, flags));
119 return(_mkfilex_np(OPENX, path, flags, fsec));
120 }
121
122 int
123 mkfifox_np(const char *path, filesec_t fsec)
124 {
125 return(_mkfilex_np(MKFIFOX, path, 0, fsec));
126 }
127
128 int
129 mkdirx_np(const char *path, filesec_t fsec)
130 {
131 return(_mkfilex_np(MKDIRX, path, 0, fsec));
132 }