]> git.saurik.com Git - apple/xnu.git/blame - tools/tests/personas/persona_test.h
xnu-7195.50.7.100.1.tar.gz
[apple/xnu.git] / tools / tests / personas / persona_test.h
CommitLineData
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
17enum {
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
30struct 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
144static 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
176static inline void
177dump_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
189static int
190parse_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_ */