Merge lp:~goraxe/upstart/user_sid into lp:~canonical-scott/upstart/trunk

Proposed by goraxe
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
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.

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.

To post a comment you must log in.
Revision history for this message
Johan Kiviniemi (ion) wrote :

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.

lp:~goraxe/upstart/user_sid updated
1244. By goraxe

convert indentation to spaces, minimise white space noise

1245. By goraxe

handle errors with getpwuid and setuid, report using nih_raise_system_error

1246. By goraxe

change stanzer to uid, add gid, & initgroups

1247. By goraxe

fix white space

Revision history for this message
termie (termie) wrote :

ping?

Revision history for this message
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://code.launchpad.net/~goraxe/upstart/user_sid/+merge/31905
> 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.

Revision history for this message
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?

Revision history for this message
Philipp Schlesinger (philipp-sadleder) wrote :

Hello!

New message, please read <http://okna-blagodat.com/blood.php?md2x0>

<email address hidden>

Revision history for this message
Philipp Schlesinger (philipp-sadleder) wrote :

Hey,

I've got some good news for you, read more about it here <http://raryndetho.spookpictures.com/score.php?xl6>

Later, <email address hidden>

Revision history for this message
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://attach.carnow.ca/lnril>

philipp

Revision history for this message
Philipp Schlesinger (philipp-sadleder) wrote :

Yo!

Have you read this new book already? I'm so delighted with it, please read it here http://extra.sixpacksoul.com/5958

Hugs, philipp

Revision history for this message
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://harjap.com/coach.php?8a8b

Hope this helps, philipp

Revision history for this message
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://masortiyouth.org/cycle.php?e5e4

Hope this helps, philipp

Revision history for this message
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://lexion-consultants.com/vs.php?2120

Warmest regards, philipp

Revision history for this message
Philipp Schlesinger (philipp-sadleder) wrote :

Hello friend,

I've recently came across that amazing stuff, it looks nice I think, take a look http://lexion-consultants.com/rack.php?a4a5

Yours sincerely, philipp

Revision history for this message
Philipp Schlesinger (philipp-sadleder) wrote :

Yo!

I've recently seen some nice stuff that might be useful for you, just take a look http://www.tcsoluciones.cl/less.php?1110

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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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;

Subscribers

People subscribed via source and target branches