Merge lp:~goraxe/upstart/user_sid into lp:~canonical-scott/upstart/trunk
- user_sid
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~goraxe/upstart/user_sid |
Merge into: | lp:~canonical-scott/upstart/trunk |
Diff against target: |
616 lines (+460/-2) 8 files modified
init/job_class.c (+3/-0) init/job_class.h (+3/-0) init/job_process.c (+89/-0) init/job_process.h (+6/-1) init/parse_job.c (+85/-0) init/tests/test_job_class.c (+2/-0) init/tests/test_job_process.c (+47/-1) init/tests/test_parse_job.c (+225/-0) |
To merge this branch: | bzr merge lp:~goraxe/upstart/user_sid |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Scott James Remnant (Canonical) | Pending | ||
Review via email: mp+31905@code.launchpad.net |
This proposal has been superseded by a proposal from 2011-04-27.
Commit message
Description of the change
adds a user stanza to the config set, job_process_spawn uses this to setuid before exec-ing
proposing for merge to get feedback/review on code, approach, tests, error handling etc.
Johan Kiviniemi (ion) wrote : | # |
termie (termie) wrote : | # |
ping?
goraxe (goraxe) wrote : | # |
pong
> -----Original Message-----
> From: <email address hidden> [mailto:<email address hidden>] On Behalf Of
> termie
> Sent: January 12, 2011 1:36 PM
> To: <email address hidden>
> Subject: Re: [Merge] lp:~goraxe/upstart/user_sid into lp:upstart
>
> ping?
> --
> https:/
> You are the owner of lp:~goraxe/upstart/user_sid.
Sophos Limited, The Pentagon, Abingdon Science Park, Abingdon, OX14 3YP, United Kingdom.
Company Reg No 2096520. VAT Reg No GB 991 2418 08.
Scott James Remnant (scott) wrote : | # |
At a first pass, this looks ok to me. But I'd like to do another pass or two before approving.
Could you change the proposed branch to be the new lp:upstart to make tracking easier?
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Hey,
I've got some good news for you, read more about it here <http://
Later, <email address hidden>
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Greetings,
Just take a look at that new store, they have so many cool things, they also have a very nice on-line store <http://
philipp
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Yo!
Have you read this new book already? I'm so delighted with it, please read it here http://
Hugs, philipp
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Hey,
I'd like to show you a nice gift a friend of mine gave me recently, it's something really cool)) Please take a look http://
Hope this helps, philipp
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Hello,
I know you're interested in stuff like that, that is something really cool, just take a look http://
Hope this helps, philipp
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Dear,
I was amazed by that shocking article I've recently read, please read it and tell me your opinion http://
Warmest regards, philipp
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Hello friend,
I've recently came across that amazing stuff, it looks nice I think, take a look http://
Yours sincerely, philipp
Philipp Schlesinger (philipp-sadleder) wrote : | # |
Yo!
I've recently seen some nice stuff that might be useful for you, just take a look http://
My Best, philipp
Unmerged revisions
- 1247. By goraxe
-
fix white space
- 1246. By goraxe
-
change stanzer to uid, add gid, & initgroups
- 1245. By goraxe
-
handle errors with getpwuid and setuid, report using nih_raise_
system_ error - 1244. By goraxe
-
convert indentation to spaces, minimise white space noise
- 1243. By goraxe
-
become the user of the class
- 1242. By goraxe
-
set user to null in job_new
- 1241. By goraxe
-
add user to parser
Preview Diff
1 | === modified file 'init/job_class.c' |
2 | --- init/job_class.c 2009-07-09 11:50:19 +0000 |
3 | +++ init/job_class.c 2010-08-10 22:45:55 +0000 |
4 | @@ -218,6 +218,9 @@ |
5 | class->chroot = NULL; |
6 | class->chdir = NULL; |
7 | |
8 | + class->uid = NULL; |
9 | + class->gid = NULL; |
10 | + |
11 | class->deleted = FALSE; |
12 | |
13 | return class; |
14 | |
15 | === modified file 'init/job_class.h' |
16 | --- init/job_class.h 2009-07-09 11:01:53 +0000 |
17 | +++ init/job_class.h 2010-08-10 22:45:55 +0000 |
18 | @@ -98,6 +98,7 @@ |
19 | * @chroot: root directory of process (implies @chdir if not set), |
20 | * @chdir: working directory of process, |
21 | * @deleted: whether job should be deleted when finished. |
22 | + * @uid: holds the name or id of a user who's id should be set via setid |
23 | * |
24 | * This structure holds the configuration of a known task or service that |
25 | * should be tracked by the init daemon; as tasks and services are |
26 | @@ -146,6 +147,8 @@ |
27 | char *chroot; |
28 | char *chdir; |
29 | |
30 | + char *uid; |
31 | + char *gid; |
32 | int deleted; |
33 | } JobClass; |
34 | |
35 | |
36 | === modified file 'init/job_process.c' |
37 | --- init/job_process.c 2010-02-26 15:31:13 +0000 |
38 | +++ init/job_process.c 2010-08-10 22:45:55 +0000 |
39 | @@ -38,6 +38,8 @@ |
40 | #include <stdlib.h> |
41 | #include <string.h> |
42 | #include <unistd.h> |
43 | +#include <pwd.h> |
44 | +#include <grp.h> |
45 | |
46 | #include <nih/macros.h> |
47 | #include <nih/alloc.h> |
48 | @@ -522,6 +524,68 @@ |
49 | } |
50 | } |
51 | |
52 | + /* drop privilages */ |
53 | + if (class->uid) { |
54 | + struct passwd *pw; |
55 | + uid_t uid; |
56 | + gid_t gid; |
57 | + char *user; |
58 | + /* convet value of uid to numerical form */ |
59 | + uid = strtol(class->uid, NULL, 10); |
60 | + /* if failed assume user and lookup via nss */ |
61 | + if (uid == 0 && errno == EINVAL) { |
62 | + pw = getpwnam (class->uid); |
63 | + if (pw == NULL) { |
64 | + nih_error_raise_system (); |
65 | + job_process_error_abort (fds[1], JOB_PROCESS_ERROR_USER, 0); |
66 | + } |
67 | + } else { |
68 | + /* we need to lookup real user name */ |
69 | + pw = getpwuid (uid); |
70 | + if (pw == NULL) { |
71 | + nih_error_raise_system (); |
72 | + job_process_error_abort (fds[1], JOB_PROCESS_ERROR_USER, 0); |
73 | + } |
74 | + } |
75 | + |
76 | + uid = pw->pw_uid; |
77 | + gid = pw->pw_gid; |
78 | + user = pw->pw_name; |
79 | + /* now check to see if we have been given a group */ |
80 | + if (class->gid) { |
81 | + struct group *gr; |
82 | + |
83 | + gid = strtol(class->gid, NULL, 10); |
84 | + if (gid == 0 && errno == EINVAL) { |
85 | + gr = getgrnam(class->gid); |
86 | + if (gr == NULL) { |
87 | + nih_error_raise_system (); |
88 | + job_process_error_abort (fds[1], JOB_PROCESS_ERROR_GROUP, 0); |
89 | + } |
90 | + } else { |
91 | + gr = getgrgid (gid); |
92 | + if (gr == NULL) { |
93 | + nih_error_raise_system (); |
94 | + job_process_error_abort (fds[1], JOB_PROCESS_ERROR_GROUP, 0); |
95 | + } |
96 | + } |
97 | + |
98 | + gid = gr->gr_gid; |
99 | + } |
100 | + if (setuid (uid) < 0) { |
101 | + nih_error_raise_system (); |
102 | + job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETUID, 0); |
103 | + } |
104 | + if (setgid (gid) < 0) { |
105 | + nih_error_raise_system (); |
106 | + job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETGID, 0); |
107 | + } |
108 | + if (initgroups(user, gid) < 0) { |
109 | + nih_error_raise_system (); |
110 | + job_process_error_abort (fds[1], JOB_PROCESS_ERROR_INITGROUPS, 0); |
111 | + } |
112 | + } |
113 | + |
114 | /* Execute the process, if we escape from here it failed */ |
115 | if (execvp (argv[0], argv) < 0) { |
116 | nih_error_raise_system (); |
117 | @@ -710,6 +774,31 @@ |
118 | err, _("unable to execute: %s"), |
119 | strerror (err->errnum))); |
120 | break; |
121 | + case JOB_PROCESS_ERROR_USER: |
122 | + err->error.message = NIH_MUST (nih_sprintf ( |
123 | + err, _("unable to find user for job: %s"), |
124 | + strerror (err->errnum))); |
125 | + break; |
126 | + case JOB_PROCESS_ERROR_SETUID: |
127 | + err->error.message = NIH_MUST (nih_sprintf ( |
128 | + err, _("unable to setuid: %s"), |
129 | + strerror (err->errnum))); |
130 | + break; |
131 | + case JOB_PROCESS_ERROR_SETGID: |
132 | + err->error.message = NIH_MUST (nih_sprintf ( |
133 | + err, _("unable to setgid: %s"), |
134 | + strerror (err->errnum))); |
135 | + break; |
136 | + case JOB_PROCESS_ERROR_GROUP: |
137 | + err->error.message = NIH_MUST (nih_sprintf ( |
138 | + err, _("unable to find group for job: %s"), |
139 | + strerror (err->errnum))); |
140 | + break; |
141 | + case JOB_PROCESS_ERROR_INITGROUPS: |
142 | + err->error.message = NIH_MUST (nih_sprintf ( |
143 | + err, _("unable to initgroups: %s"), |
144 | + strerror (err->errnum))); |
145 | + break; |
146 | default: |
147 | nih_assert_not_reached (); |
148 | } |
149 | |
150 | === modified file 'init/job_process.h' |
151 | --- init/job_process.h 2009-07-09 11:01:53 +0000 |
152 | +++ init/job_process.h 2010-08-10 22:45:55 +0000 |
153 | @@ -45,7 +45,12 @@ |
154 | JOB_PROCESS_ERROR_CHROOT, |
155 | JOB_PROCESS_ERROR_CHDIR, |
156 | JOB_PROCESS_ERROR_PTRACE, |
157 | - JOB_PROCESS_ERROR_EXEC |
158 | + JOB_PROCESS_ERROR_EXEC, |
159 | + JOB_PROCESS_ERROR_USER, |
160 | + JOB_PROCESS_ERROR_GROUP, |
161 | + JOB_PROCESS_ERROR_SETUID, |
162 | + JOB_PROCESS_ERROR_SETGID, |
163 | + JOB_PROCESS_ERROR_INITGROUPS |
164 | } JobProcessErrorType; |
165 | |
166 | /** |
167 | |
168 | === modified file 'init/parse_job.c' |
169 | --- init/parse_job.c 2010-03-31 17:29:24 +0000 |
170 | +++ init/parse_job.c 2010-08-10 22:45:55 +0000 |
171 | @@ -210,6 +210,14 @@ |
172 | size_t *pos, size_t *lineno) |
173 | __attribute__ ((warn_unused_result)); |
174 | |
175 | +static int stanza_uid (JobClass *class, NihConfigStanza *stanza, |
176 | + const char *file, size_t len, |
177 | + size_t *pos, size_t *lineno) |
178 | + __attribute__ ((warn_unused_result)); |
179 | +static int stanza_gid (JobClass *class, NihConfigStanza *stanza, |
180 | + const char *file, size_t len, |
181 | + size_t *pos, size_t *lineno) |
182 | + __attribute__ ((warn_unused_result)); |
183 | |
184 | /** |
185 | * stanzas: |
186 | @@ -245,6 +253,8 @@ |
187 | { "limit", (NihConfigHandler)stanza_limit }, |
188 | { "chroot", (NihConfigHandler)stanza_chroot }, |
189 | { "chdir", (NihConfigHandler)stanza_chdir }, |
190 | + { "uid", (NihConfigHandler)stanza_uid }, |
191 | + { "gid", (NihConfigHandler)stanza_gid }, |
192 | |
193 | NIH_CONFIG_LAST |
194 | }; |
195 | @@ -2391,3 +2401,78 @@ |
196 | |
197 | return nih_config_skip_comment (file, len, pos, lineno); |
198 | } |
199 | + |
200 | + |
201 | +/** |
202 | + * stanza_uid: |
203 | + * @class: job class being parsed, |
204 | + * @stanza: stanza found, |
205 | + * @file: file or string to parse, |
206 | + * @len: length of @file, |
207 | + * @pos: offset within @file, |
208 | + * @lineno: line number. |
209 | + * |
210 | + * Parse a user stanza from @file, extracting a single argument |
211 | + * containing a user to drop priviagles to. |
212 | + * |
213 | + * Returns: zero on success, negative value on error. |
214 | + **/ |
215 | +static int |
216 | +stanza_uid (JobClass *class, |
217 | + NihConfigStanza *stanza, |
218 | + const char *file, |
219 | + size_t len, |
220 | + size_t *pos, |
221 | + size_t *lineno) |
222 | +{ |
223 | + nih_assert (class != NULL); |
224 | + nih_assert (stanza != NULL); |
225 | + nih_assert (file != NULL); |
226 | + nih_assert (pos != NULL); |
227 | + |
228 | + if (class->uid) |
229 | + nih_unref (class->uid, class); |
230 | + /* FIXME lookup uid */ |
231 | + class->uid = nih_config_next_arg (class, file, len, pos, lineno); |
232 | + if (! class->uid) |
233 | + return -1; |
234 | + |
235 | + return nih_config_skip_comment (file, len, pos, lineno); |
236 | +} |
237 | + |
238 | +/** |
239 | + * stanza_gid: |
240 | + * @class: job class being parsed, |
241 | + * @stanza: stanza found, |
242 | + * @file: file or string to parse, |
243 | + * @len: length of @file, |
244 | + * @pos: offset within @file, |
245 | + * @lineno: line number. |
246 | + * |
247 | + * Parse a gid stanza from @file, extracting a single argument |
248 | + * containing a group to drop priviagles to. |
249 | + * |
250 | + * Returns: zero on success, negative value on error. |
251 | + **/ |
252 | +static int |
253 | +stanza_gid (JobClass *class, |
254 | + NihConfigStanza *stanza, |
255 | + const char *file, |
256 | + size_t len, |
257 | + size_t *pos, |
258 | + size_t *lineno) |
259 | +{ |
260 | + nih_assert (class != NULL); |
261 | + nih_assert (stanza != NULL); |
262 | + nih_assert (file != NULL); |
263 | + nih_assert (pos != NULL); |
264 | + |
265 | + if (class->gid) |
266 | + nih_unref (class->gid, class); |
267 | + |
268 | + class->gid = nih_config_next_arg (class, file, len, pos, lineno); |
269 | + if (! class->gid) |
270 | + return -1; |
271 | + |
272 | + return nih_config_skip_comment (file, len, pos, lineno); |
273 | +} |
274 | |
275 | === modified file 'init/tests/test_job_class.c' |
276 | --- init/tests/test_job_class.c 2009-07-09 11:50:19 +0000 |
277 | +++ init/tests/test_job_class.c 2010-08-10 22:45:55 +0000 |
278 | @@ -139,6 +139,8 @@ |
279 | |
280 | TEST_EQ_P (class->chroot, NULL); |
281 | TEST_EQ_P (class->chdir, NULL); |
282 | + TEST_EQ_P (class->uid, NULL); |
283 | + TEST_EQ_P (class->gid, NULL); |
284 | TEST_FALSE (class->deleted); |
285 | |
286 | nih_free (class); |
287 | |
288 | === modified file 'init/tests/test_job_process.c' |
289 | --- init/tests/test_job_process.c 2010-02-26 15:31:13 +0000 |
290 | +++ init/tests/test_job_process.c 2010-08-10 22:45:55 +0000 |
291 | @@ -36,6 +36,7 @@ |
292 | #include <stdlib.h> |
293 | #include <string.h> |
294 | #include <unistd.h> |
295 | +#include <pwd.h> |
296 | |
297 | #include <nih/macros.h> |
298 | #include <nih/string.h> |
299 | @@ -63,7 +64,8 @@ |
300 | TEST_PIDS, |
301 | TEST_CONSOLE, |
302 | TEST_PWD, |
303 | - TEST_ENVIRONMENT |
304 | + TEST_ENVIRONMENT, |
305 | + TEST_USER |
306 | }; |
307 | |
308 | static char *argv0; |
309 | @@ -75,6 +77,8 @@ |
310 | FILE *out; |
311 | char tmpname[PATH_MAX], path[PATH_MAX]; |
312 | int i; |
313 | + struct passwd *pw; |
314 | + int uid; |
315 | |
316 | strcpy (tmpname, filename); |
317 | strcat (tmpname, ".tmp"); |
318 | @@ -104,6 +108,15 @@ |
319 | assert (getcwd (path, sizeof (path))); |
320 | fprintf (out, "wd: %s\n", path); |
321 | break; |
322 | + case TEST_USER: |
323 | + /* get our id */ |
324 | + uid = getuid(); |
325 | + |
326 | + /* find this users passwd record */ |
327 | + pw = getpwuid(uid); |
328 | + assert(pw != NULL); |
329 | + fprintf(out, "user: %s\n", pw->pw_name); |
330 | + break; |
331 | case TEST_ENVIRONMENT: |
332 | for (char **env = environ; *env; env++) |
333 | fprintf (out, "%s\n", *env); |
334 | @@ -897,6 +910,39 @@ |
335 | nih_free (class); |
336 | |
337 | |
338 | + /* Check that a job with a specified user runs as that user, requires |
339 | + * root privs to run |
340 | + */ |
341 | + TEST_FEATURE ("with user"); |
342 | + sprintf (function, "%d", TEST_USER); |
343 | + |
344 | + class = job_class_new(NULL, "test"); |
345 | + |
346 | + struct passwd *pw; |
347 | + int uid; |
348 | + /* get our id */ |
349 | + uid = getuid(); |
350 | + |
351 | + /* find this users passwd record */ |
352 | + pw = getpwuid(uid); |
353 | + class->uid = nih_strdup(class, pw->pw_name); |
354 | + |
355 | + |
356 | + pid = job_process_spawn (class, args, NULL, FALSE); |
357 | + TEST_GT(pid,0); |
358 | + |
359 | + waitpid (pid, NULL, 0); |
360 | + |
361 | + output = fopen (filename, "r"); |
362 | + |
363 | + sprintf(buf, "user: %s\n", pw->pw_name); |
364 | + TEST_FILE_EQ (output, buf); |
365 | + TEST_FILE_END (output); |
366 | + |
367 | + fclose (output); |
368 | + unlink (filename); |
369 | + |
370 | + nih_free (class); |
371 | /* Check that a job is run with only the environment variables |
372 | * specifiec in the function call. |
373 | */ |
374 | |
375 | === modified file 'init/tests/test_parse_job.c' |
376 | --- init/tests/test_parse_job.c 2009-07-09 11:01:53 +0000 |
377 | +++ init/tests/test_parse_job.c 2010-08-10 22:45:55 +0000 |
378 | @@ -7425,6 +7425,230 @@ |
379 | nih_free (err); |
380 | } |
381 | |
382 | +void |
383 | +test_stanza_uid(void) |
384 | +{ |
385 | + JobClass*job; |
386 | + NihError *err; |
387 | + size_t pos, lineno; |
388 | + char buf[1024]; |
389 | + |
390 | + TEST_FUNCTION ("stanza_uid"); |
391 | + |
392 | + /* Check that a uid stanza with an argument results in it |
393 | + * being stored in the job. |
394 | + */ |
395 | + TEST_FEATURE ("with single argument"); |
396 | + strcpy (buf, "uid nobody\n"); |
397 | + |
398 | + TEST_ALLOC_FAIL { |
399 | + pos = 0; |
400 | + lineno = 1; |
401 | + job = parse_job (NULL, "test", buf, strlen (buf), |
402 | + &pos, &lineno); |
403 | + if (test_alloc_failed) { |
404 | + TEST_EQ_P (job, NULL); |
405 | + |
406 | + err = nih_error_get (); |
407 | + TEST_EQ (err->number, ENOMEM); |
408 | + nih_free (err); |
409 | + |
410 | + continue; |
411 | + } |
412 | + TEST_EQ (pos, strlen (buf)); |
413 | + TEST_EQ (lineno, 2); |
414 | + |
415 | + TEST_ALLOC_SIZE (job, sizeof (JobClass)); |
416 | + |
417 | + TEST_ALLOC_PARENT (job->uid, job); |
418 | + TEST_EQ_STR (job->uid, "nobody"); |
419 | + nih_free (job); |
420 | + } |
421 | + |
422 | + /* Check that the last of multiple uid stanzas is used. |
423 | + */ |
424 | + TEST_FEATURE ("with multiple stanzas"); |
425 | + strcpy (buf, "uid nobody\n"); |
426 | + strcat (buf, "uid gordon\n"); |
427 | + |
428 | + TEST_ALLOC_FAIL { |
429 | + pos = 0; |
430 | + lineno = 1; |
431 | + job = parse_job (NULL, "test", buf, strlen (buf), |
432 | + &pos, &lineno); |
433 | + |
434 | + if (test_alloc_failed) { |
435 | + TEST_EQ_P (job, NULL); |
436 | + |
437 | + err = nih_error_get (); |
438 | + TEST_EQ (err->number, ENOMEM); |
439 | + nih_free (err); |
440 | + |
441 | + continue; |
442 | + } |
443 | + |
444 | + TEST_EQ (pos, strlen (buf)); |
445 | + TEST_EQ (lineno, 3); |
446 | + |
447 | + TEST_ALLOC_SIZE (job, sizeof (JobClass)); |
448 | + |
449 | + TEST_ALLOC_PARENT (job->uid, job); |
450 | + TEST_EQ_STR (job->uid, "gordon"); |
451 | + |
452 | + nih_free (job); |
453 | + } |
454 | + |
455 | + |
456 | + /* Check that a uid stanza without an argument results in |
457 | + * a syntax error. |
458 | + */ |
459 | + TEST_FEATURE ("with missing argument"); |
460 | + strcpy (buf, "uid\n"); |
461 | + |
462 | + pos = 0; |
463 | + lineno = 1; |
464 | + job = parse_job (NULL, "test", buf, strlen (buf), &pos, &lineno); |
465 | + |
466 | + TEST_EQ_P (job, NULL); |
467 | + |
468 | + err = nih_error_get (); |
469 | + TEST_EQ (err->number, NIH_CONFIG_EXPECTED_TOKEN); |
470 | + TEST_EQ (pos, 3); |
471 | + TEST_EQ (lineno, 1); |
472 | + nih_free (err); |
473 | + |
474 | + |
475 | + /* Check that a uid stanza with an extra second argument |
476 | + * results in a syntax error. |
477 | + */ |
478 | + TEST_FEATURE ("with extra argument"); |
479 | + strcpy (buf, "uid bar foo\n"); |
480 | + |
481 | + pos = 0; |
482 | + lineno = 1; |
483 | + job = parse_job (NULL, "test", buf, strlen (buf), &pos, &lineno); |
484 | + |
485 | + TEST_EQ_P (job, NULL); |
486 | + |
487 | + err = nih_error_get (); |
488 | + TEST_EQ (err->number, NIH_CONFIG_UNEXPECTED_TOKEN); |
489 | + TEST_EQ (pos, 8); |
490 | + TEST_EQ (lineno, 1); |
491 | + nih_free (err); |
492 | +} |
493 | + |
494 | +void |
495 | +test_stanza_gid(void) |
496 | +{ |
497 | + JobClass*job; |
498 | + NihError *err; |
499 | + size_t pos, lineno; |
500 | + char buf[1024]; |
501 | + |
502 | + TEST_FUNCTION ("stanza_gid"); |
503 | + |
504 | + /* Check that a gid stanza with an argument results in it |
505 | + * being stored in the job. |
506 | + */ |
507 | + TEST_FEATURE ("with single argument"); |
508 | + strcpy (buf, "gid nobody\n"); |
509 | + |
510 | + TEST_ALLOC_FAIL { |
511 | + pos = 0; |
512 | + lineno = 1; |
513 | + job = parse_job (NULL, "test", buf, strlen (buf), |
514 | + &pos, &lineno); |
515 | + if (test_alloc_failed) { |
516 | + TEST_EQ_P (job, NULL); |
517 | + |
518 | + err = nih_error_get (); |
519 | + TEST_EQ (err->number, ENOMEM); |
520 | + nih_free (err); |
521 | + |
522 | + continue; |
523 | + } |
524 | + TEST_EQ (pos, strlen (buf)); |
525 | + TEST_EQ (lineno, 2); |
526 | + |
527 | + TEST_ALLOC_SIZE (job, sizeof (JobClass)); |
528 | + |
529 | + TEST_ALLOC_PARENT (job->gid, job); |
530 | + TEST_EQ_STR (job->gid, "nobody"); |
531 | + nih_free (job); |
532 | + } |
533 | + |
534 | + /* Check that the last of multiple gid stanzas is used. |
535 | + */ |
536 | + TEST_FEATURE ("with multiple stanzas"); |
537 | + strcpy (buf, "gid nobody\n"); |
538 | + strcat (buf, "gid gordon\n"); |
539 | + |
540 | + TEST_ALLOC_FAIL { |
541 | + pos = 0; |
542 | + lineno = 1; |
543 | + job = parse_job (NULL, "test", buf, strlen (buf), |
544 | + &pos, &lineno); |
545 | + |
546 | + if (test_alloc_failed) { |
547 | + TEST_EQ_P (job, NULL); |
548 | + |
549 | + err = nih_error_get (); |
550 | + TEST_EQ (err->number, ENOMEM); |
551 | + nih_free (err); |
552 | + |
553 | + continue; |
554 | + } |
555 | + |
556 | + TEST_EQ (pos, strlen (buf)); |
557 | + TEST_EQ (lineno, 3); |
558 | + |
559 | + TEST_ALLOC_SIZE (job, sizeof (JobClass)); |
560 | + |
561 | + TEST_ALLOC_PARENT (job->gid, job); |
562 | + TEST_EQ_STR (job->gid, "gordon"); |
563 | + |
564 | + nih_free (job); |
565 | + } |
566 | + |
567 | + |
568 | + /* Check that a gid stanza without an argument results in |
569 | + * a syntax error. |
570 | + */ |
571 | + TEST_FEATURE ("with missing argument"); |
572 | + strcpy (buf, "gid\n"); |
573 | + |
574 | + pos = 0; |
575 | + lineno = 1; |
576 | + job = parse_job (NULL, "test", buf, strlen (buf), &pos, &lineno); |
577 | + |
578 | + TEST_EQ_P (job, NULL); |
579 | + |
580 | + err = nih_error_get (); |
581 | + TEST_EQ (err->number, NIH_CONFIG_EXPECTED_TOKEN); |
582 | + TEST_EQ (pos, 3); |
583 | + TEST_EQ (lineno, 1); |
584 | + nih_free (err); |
585 | + |
586 | + |
587 | + /* Check that a gid stanza with an extra second argument |
588 | + * results in a syntax error. |
589 | + */ |
590 | + TEST_FEATURE ("with extra argument"); |
591 | + strcpy (buf, "gid bar foo\n"); |
592 | + |
593 | + pos = 0; |
594 | + lineno = 1; |
595 | + job = parse_job (NULL, "test", buf, strlen (buf), &pos, &lineno); |
596 | + |
597 | + TEST_EQ_P (job, NULL); |
598 | + |
599 | + err = nih_error_get (); |
600 | + TEST_EQ (err->number, NIH_CONFIG_UNEXPECTED_TOKEN); |
601 | + TEST_EQ (pos, 8); |
602 | + TEST_EQ (lineno, 1); |
603 | + nih_free (err); |
604 | +} |
605 | + |
606 | int |
607 | main (int argc, |
608 | char *argv[]) |
609 | @@ -7466,6 +7690,7 @@ |
610 | test_stanza_oom (); |
611 | test_stanza_limit (); |
612 | test_stanza_chroot (); |
613 | + test_stanza_uid(); |
614 | test_stanza_chdir (); |
615 | |
616 | return 0; |
There’s some inconsistent use of whitespace. There also are some superfluous whitespace changes to preexisting code.
Asserting getpwnam doesn’t fail might not be the best thing to do for an init daemon.
The success of the setuid call is not verified.