]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/personas/persona_test.h
xnu-4903.221.2.tar.gz
[apple/xnu.git] / tools / tests / personas / persona_test.h
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 { \
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); \
55 } while (0)
56
57 #define errc(code, fmt, ...) \
58 do { \
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); \
65 } while (0)
66
67 #define err_print(fmt, ...) \
68 do { \
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); \
74 } while (0)
75
76
77 #define err__start(fmt, ...) \
78 do { \
79 fprintf(stderr, "[%4d] [ERROR] " fmt, getuid(), ## __VA_ARGS__); \
80 fflush(stderr); \
81 } while (0)
82
83 #define err__cont(fmt, ...) \
84 do { \
85 fprintf(stderr, fmt, ## __VA_ARGS__); \
86 fflush(stderr); \
87 } while (0)
88
89 #define err__finish(fmt, ...) \
90 do { \
91 fprintf(stderr, fmt "\n", ## __VA_ARGS__); \
92 fflush(stderr); \
93 } while (0)
94
95
96 #ifdef DEBUG
97 #define dbg(fmt, ...) \
98 do { \
99 fprintf(stdout, "[%4d] [DEBUG] " fmt "\n", getuid(), ## __VA_ARGS__ ); \
100 fflush(NULL); \
101 } while (0)
102 #define warn(fmt, ...) \
103 do { \
104 fprintf(stdout, "[%4d] [WARN ] " fmt "\n", getuid(), ## __VA_ARGS__ ); \
105 fflush(NULL); \
106 } while (0)
107 #else
108 #define dbg(...)
109 #define warn(...)
110 #endif
111
112 #define info(fmt, ...) \
113 do { \
114 fprintf(stdout, "[%4d] [INFO ] " fmt "\n", getuid(), ## __VA_ARGS__ ); \
115 fflush(NULL); \
116 } while (0)
117
118 #define info_start(fmt, ...) \
119 do { \
120 fprintf(stdout, "[%4d] [INFO ] " fmt, getuid(), ## __VA_ARGS__ ); \
121 } while (0)
122
123 #define info_cont(fmt, ...) \
124 do { \
125 fprintf(stdout, fmt, ## __VA_ARGS__ ); \
126 } while (0)
127
128 #define info_end() \
129 do { \
130 fprintf(stdout, "\n"); \
131 fflush(NULL); \
132 } while (0)
133
134 #define infov(fmt, ...) \
135 if (g.verbose) { \
136 fprintf(stdout, "[%4d] [vINFO] " fmt "\n", getuid(), ## __VA_ARGS__ ); \
137 fflush(NULL); \
138 }
139
140 #define ARRAY_SZ(a) \
141 (sizeof(a) / sizeof((a)[0]))
142
143
144 static inline void _dump_kpersona(const char *msg, uint32_t flags, const struct kpersona_info *ki)
145 {
146 if (msg)
147 info("%s", msg);
148 info("\t kpersona_info (v%d) {", ki->persona_info_version);
149 info("\t\t %cid: %d", flags & PA_HAS_ID ? '+' : '-', ki->persona_id);
150 info("\t\t %ctype: %d", flags & PA_HAS_TYPE ? '+' : '-', ki->persona_type);
151 info("\t\t %cgid: %d", flags & PA_HAS_GID ? '+' : '-', ki->persona_gid);
152
153 info_start("\t\t ngroups: %d", ki->persona_ngroups);
154 for (int i = 0; i < ki->persona_ngroups; i++) {
155 if (i == 0) info_cont(" {");
156 info_cont(" %d", ki->persona_groups[i]);
157 }
158 if (ki->persona_ngroups > 0)
159 info_cont(" }");
160 info_end();
161
162 info("\t\t %cgmuid: %d (0x%x)", flags & PA_HAS_GROUPS ? '+' : '-',
163 (int)ki->persona_gmuid, ki->persona_gmuid);
164 info("\t\t %clogin: \"%s\"", flags & PA_HAS_LOGIN ? '+' : '-', ki->persona_name);
165 info("\t }");
166 }
167
168 #define dump_kpersona(msg, ki) \
169 _dump_kpersona(msg, 0xffffffff, ki)
170
171 static inline void dump_persona_args(const char *msg, const struct persona_args *pa)
172 {
173 const struct kpersona_info *ki = &pa->kinfo;
174
175 if (msg)
176 info("%s", msg);
177 info("\t flags: 0x%x", pa->flags);
178 info("\t %cuid: %d", pa->flags & PA_HAS_UID ? '+' : '-', pa->override_uid);
179 _dump_kpersona(NULL, pa->flags, ki);
180 }
181
182 static int parse_groupspec(struct kpersona_info *kinfo, char *spec)
183 {
184 int idx = 0;
185 int grp;
186 char *s, *e;
187
188 if (!spec)
189 return -1;
190 s = e = spec;
191 while (*s) {
192 int comma = 0;
193 e = s;
194 while (*e && *e != ',')
195 e++;
196 if (*e)
197 comma = 1;
198 *e = 0;
199 grp = atoi(s);
200 if (comma) {
201 *e = ',';
202 s = e + 1;
203 } else {
204 s = e;
205 }
206 if (grp < 0)
207 return -1;
208 kinfo->persona_groups[idx] = grp;
209 idx++;
210 }
211 kinfo->persona_ngroups = idx;
212
213 return 0;
214 }
215
216 #endif /* _PERSONA_TEST_H_ */