]>
Commit | Line | Data |
---|---|---|
490019cf A |
1 | /* |
2 | * persona_test.h | |
3 | * | |
4 | * Jeremy C. Andrus <jeremy_andrus@apple.com> | |
5 | * | |
6 | */ | |
7 | #ifndef _PERSONA_TEST_H_ | |
8 | #define _PERSONA_TEST_H_ | |
9 | ||
10 | /* internal */ | |
11 | #include <spawn_private.h> | |
12 | #include <sys/persona.h> | |
13 | #include <sys/spawn_internal.h> | |
14 | ||
15 | //#define DEBUG | |
16 | ||
17 | enum { | |
18 | PA_NONE = 0x0000, | |
19 | PA_CREATE = 0x0001, | |
20 | PA_SHOULD_VERIFY = 0x0002, | |
21 | PA_OVERRIDE = 0x0004, | |
22 | PA_HAS_ID = 0x0100, | |
23 | PA_HAS_TYPE = 0x0200, | |
24 | PA_HAS_UID = 0x0400, | |
25 | PA_HAS_GID = 0x0800, | |
26 | PA_HAS_GROUPS = 0x1000, | |
27 | PA_HAS_LOGIN = 0x2000, | |
28 | }; | |
29 | ||
30 | struct persona_args { | |
31 | uint32_t flags; | |
32 | uid_t override_uid; | |
33 | struct kpersona_info kinfo; | |
34 | }; | |
35 | ||
36 | ||
37 | /* | |
38 | * Error codes emitted on failure | |
39 | */ | |
40 | #define ERR_SYSTEM -1 | |
41 | #define ERR_SPAWN 30 | |
42 | #define ERR_SPAWN_ATTR 31 | |
43 | #define ERR_CHILD_FAIL 40 | |
44 | #define ERR_ARGS 98 | |
45 | #define ERR_SETUP 99 | |
46 | ||
47 | #define err(fmt, ...) \ | |
48 | do { \ | |
0a7de745 A |
49 | fflush(NULL); \ |
50 | fprintf(stderr, "[%4d] [ERROR(%d:%s)] %s:%d: " fmt "\n", \ | |
51 | getuid(), errno, strerror(errno), \ | |
52 | __func__, __LINE__, ## __VA_ARGS__ ); \ | |
53 | fflush(stderr); \ | |
54 | exit(ERR_SYSTEM); \ | |
490019cf A |
55 | } while (0) |
56 | ||
57 | #define errc(code, fmt, ...) \ | |
58 | do { \ | |
0a7de745 A |
59 | fflush(NULL); \ |
60 | fprintf(stderr, "[%4d] [ERROR(%d)] %s:%d: " fmt "\n", \ | |
61 | getuid(), code, \ | |
62 | __func__, __LINE__, ## __VA_ARGS__ ); \ | |
63 | fflush(stderr); \ | |
64 | exit(code ? code : ERR_SYSTEM); \ | |
490019cf A |
65 | } while (0) |
66 | ||
67 | #define err_print(fmt, ...) \ | |
68 | do { \ | |
0a7de745 A |
69 | fflush(NULL); \ |
70 | fprintf(stderr, "[%4d] [ERROR(%d:%s)] %s:%d: " fmt "\n", \ | |
71 | getuid(), errno, strerror(errno), \ | |
72 | __func__, __LINE__, ## __VA_ARGS__ ); \ | |
73 | fflush(stderr); \ | |
490019cf A |
74 | } while (0) |
75 | ||
76 | ||
77 | #define err__start(fmt, ...) \ | |
78 | do { \ | |
0a7de745 A |
79 | fprintf(stderr, "[%4d] [ERROR] " fmt, getuid(), ## __VA_ARGS__); \ |
80 | fflush(stderr); \ | |
490019cf A |
81 | } while (0) |
82 | ||
83 | #define err__cont(fmt, ...) \ | |
84 | do { \ | |
0a7de745 A |
85 | fprintf(stderr, fmt, ## __VA_ARGS__); \ |
86 | fflush(stderr); \ | |
490019cf A |
87 | } while (0) |
88 | ||
89 | #define err__finish(fmt, ...) \ | |
90 | do { \ | |
0a7de745 A |
91 | fprintf(stderr, fmt "\n", ## __VA_ARGS__); \ |
92 | fflush(stderr); \ | |
490019cf A |
93 | } while (0) |
94 | ||
95 | ||
96 | #ifdef DEBUG | |
97 | #define dbg(fmt, ...) \ | |
98 | do { \ | |
0a7de745 A |
99 | fprintf(stdout, "[%4d] [DEBUG] " fmt "\n", getuid(), ## __VA_ARGS__ ); \ |
100 | fflush(NULL); \ | |
490019cf A |
101 | } while (0) |
102 | #define warn(fmt, ...) \ | |
103 | do { \ | |
0a7de745 A |
104 | fprintf(stdout, "[%4d] [WARN ] " fmt "\n", getuid(), ## __VA_ARGS__ ); \ |
105 | fflush(NULL); \ | |
490019cf A |
106 | } while (0) |
107 | #else | |
108 | #define dbg(...) | |
109 | #define warn(...) | |
110 | #endif | |
111 | ||
112 | #define info(fmt, ...) \ | |
113 | do { \ | |
0a7de745 A |
114 | fprintf(stdout, "[%4d] [INFO ] " fmt "\n", getuid(), ## __VA_ARGS__ ); \ |
115 | fflush(NULL); \ | |
490019cf A |
116 | } while (0) |
117 | ||
118 | #define info_start(fmt, ...) \ | |
119 | do { \ | |
0a7de745 | 120 | fprintf(stdout, "[%4d] [INFO ] " fmt, getuid(), ## __VA_ARGS__ ); \ |
490019cf A |
121 | } while (0) |
122 | ||
123 | #define info_cont(fmt, ...) \ | |
124 | do { \ | |
0a7de745 | 125 | fprintf(stdout, fmt, ## __VA_ARGS__ ); \ |
490019cf A |
126 | } while (0) |
127 | ||
128 | #define info_end() \ | |
129 | do { \ | |
0a7de745 A |
130 | fprintf(stdout, "\n"); \ |
131 | fflush(NULL); \ | |
490019cf A |
132 | } while (0) |
133 | ||
134 | #define infov(fmt, ...) \ | |
135 | if (g.verbose) { \ | |
0a7de745 A |
136 | fprintf(stdout, "[%4d] [vINFO] " fmt "\n", getuid(), ## __VA_ARGS__ ); \ |
137 | fflush(NULL); \ | |
490019cf A |
138 | } |
139 | ||
140 | #define ARRAY_SZ(a) \ | |
141 | (sizeof(a) / sizeof((a)[0])) | |
142 | ||
143 | ||
0a7de745 A |
144 | static inline void |
145 | _dump_kpersona(const char *msg, uint32_t flags, const struct kpersona_info *ki) | |
490019cf | 146 | { |
0a7de745 | 147 | if (msg) { |
490019cf | 148 | info("%s", msg); |
0a7de745 | 149 | } |
490019cf A |
150 | info("\t kpersona_info (v%d) {", ki->persona_info_version); |
151 | info("\t\t %cid: %d", flags & PA_HAS_ID ? '+' : '-', ki->persona_id); | |
152 | info("\t\t %ctype: %d", flags & PA_HAS_TYPE ? '+' : '-', ki->persona_type); | |
153 | info("\t\t %cgid: %d", flags & PA_HAS_GID ? '+' : '-', ki->persona_gid); | |
154 | ||
155 | info_start("\t\t ngroups: %d", ki->persona_ngroups); | |
156 | for (int i = 0; i < ki->persona_ngroups; i++) { | |
0a7de745 A |
157 | if (i == 0) { |
158 | info_cont(" {"); | |
159 | } | |
490019cf A |
160 | info_cont(" %d", ki->persona_groups[i]); |
161 | } | |
0a7de745 | 162 | if (ki->persona_ngroups > 0) { |
490019cf | 163 | info_cont(" }"); |
0a7de745 | 164 | } |
490019cf A |
165 | info_end(); |
166 | ||
167 | info("\t\t %cgmuid: %d (0x%x)", flags & PA_HAS_GROUPS ? '+' : '-', | |
0a7de745 | 168 | (int)ki->persona_gmuid, ki->persona_gmuid); |
490019cf A |
169 | info("\t\t %clogin: \"%s\"", flags & PA_HAS_LOGIN ? '+' : '-', ki->persona_name); |
170 | info("\t }"); | |
171 | } | |
172 | ||
173 | #define dump_kpersona(msg, ki) \ | |
174 | _dump_kpersona(msg, 0xffffffff, ki) | |
175 | ||
0a7de745 A |
176 | static inline void |
177 | dump_persona_args(const char *msg, const struct persona_args *pa) | |
490019cf A |
178 | { |
179 | const struct kpersona_info *ki = &pa->kinfo; | |
180 | ||
0a7de745 | 181 | if (msg) { |
490019cf | 182 | info("%s", msg); |
0a7de745 | 183 | } |
490019cf A |
184 | info("\t flags: 0x%x", pa->flags); |
185 | info("\t %cuid: %d", pa->flags & PA_HAS_UID ? '+' : '-', pa->override_uid); | |
186 | _dump_kpersona(NULL, pa->flags, ki); | |
187 | } | |
188 | ||
0a7de745 A |
189 | static int |
190 | parse_groupspec(struct kpersona_info *kinfo, char *spec) | |
490019cf A |
191 | { |
192 | int idx = 0; | |
193 | int grp; | |
194 | char *s, *e; | |
195 | ||
0a7de745 | 196 | if (!spec) { |
490019cf | 197 | return -1; |
0a7de745 | 198 | } |
490019cf A |
199 | s = e = spec; |
200 | while (*s) { | |
201 | int comma = 0; | |
202 | e = s; | |
0a7de745 | 203 | while (*e && *e != ',') { |
490019cf | 204 | e++; |
0a7de745 A |
205 | } |
206 | if (*e) { | |
490019cf | 207 | comma = 1; |
0a7de745 | 208 | } |
490019cf A |
209 | *e = 0; |
210 | grp = atoi(s); | |
211 | if (comma) { | |
212 | *e = ','; | |
213 | s = e + 1; | |
214 | } else { | |
215 | s = e; | |
216 | } | |
0a7de745 | 217 | if (grp < 0) { |
490019cf | 218 | return -1; |
0a7de745 | 219 | } |
490019cf A |
220 | kinfo->persona_groups[idx] = grp; |
221 | idx++; | |
222 | } | |
223 | kinfo->persona_ngroups = idx; | |
224 | ||
225 | return 0; | |
226 | } | |
227 | ||
228 | #endif /* _PERSONA_TEST_H_ */ |