xref: /xnu-11215.1.10/tools/tests/personas/persona_test.h (revision 8d741a5de7ff4191bf97d57b9f54c2f6d4a15585)
1 /*
2  * persona_test.h
3  *
4  * Jeremy C. Andrus <[email protected]>
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 _dump_kpersona(const char *msg, uint32_t flags, const struct kpersona_info *ki)
146 {
147 	if (msg) {
148 		info("%s", msg);
149 	}
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++) {
157 		if (i == 0) {
158 			info_cont(" {");
159 		}
160 		info_cont(" %d", ki->persona_groups[i]);
161 	}
162 	if (ki->persona_ngroups > 0) {
163 		info_cont(" }");
164 	}
165 	info_end();
166 
167 	info("\t\t  %cgmuid: %d (0x%x)", flags & PA_HAS_GROUPS ? '+' : '-',
168 	    (int)ki->persona_gmuid, ki->persona_gmuid);
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 
176 static inline void
dump_persona_args(const char * msg,const struct persona_args * pa)177 dump_persona_args(const char *msg, const struct persona_args *pa)
178 {
179 	const struct kpersona_info *ki = &pa->kinfo;
180 
181 	if (msg) {
182 		info("%s", msg);
183 	}
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 
189 static int
parse_groupspec(struct kpersona_info * kinfo,char * spec)190 parse_groupspec(struct kpersona_info *kinfo, char *spec)
191 {
192 	int idx = 0;
193 	int grp;
194 	char *s, *e;
195 
196 	if (!spec) {
197 		return -1;
198 	}
199 	s = e = spec;
200 	while (*s) {
201 		int comma = 0;
202 		e = s;
203 		while (*e && *e != ',') {
204 			e++;
205 		}
206 		if (*e) {
207 			comma = 1;
208 		}
209 		*e = 0;
210 		grp = atoi(s);
211 		if (comma) {
212 			*e = ',';
213 			s = e + 1;
214 		} else {
215 			s = e;
216 		}
217 		if (grp < 0) {
218 			return -1;
219 		}
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_ */
229