]>
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 { \ | |
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_ */ |