~ubuntu-branches/ubuntu/raring/shadow/raring-proposed

« back to all changes in this revision

Viewing changes to src/newgrp.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2009-05-05 09:45:21 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090505094521-wpk2wn3q7957tlah
Tags: 1:4.1.3.1-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Ubuntu specific:
    + debian/login.defs: use SHA512 by default for password crypt routine.
  - debian/patches/stdout-encrypted-password.patch: chpasswd can report
    password hashes on stdout (debian bug 505640).
  - debian/login.pam: Enable SELinux support (debian bug 527106).
  - debian/securetty.linux: support Freescale MX-series (debian bug 527095).
* Add debian/patches/300_lastlog_failure: fixed upstream (debian bug 524873).
* Drop debian/patches/593_omit_lastchange_field_if_clock_is_misset: fixed
  upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright 1990 - 1994, Julianne Frances Haugh
 
2
 * Copyright (c) 1990 - 1994, Julianne Frances Haugh
 
3
 * Copyright (c) 1996 - 2000, Marek Michałkiewicz
 
4
 * Copyright (c) 2001 - 2006, Tomasz Kłoczko
 
5
 * Copyright (c) 2007 - 2008, Nicolas François
3
6
 * All rights reserved.
4
7
 *
5
8
 * Redistribution and use in source and binary forms, with or without
10
13
 * 2. Redistributions in binary form must reproduce the above copyright
11
14
 *    notice, this list of conditions and the following disclaimer in the
12
15
 *    documentation and/or other materials provided with the distribution.
13
 
 * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
14
 
 *    may be used to endorse or promote products derived from this software
15
 
 *    without specific prior written permission.
 
16
 * 3. The name of the copyright holders or contributors may not be used to
 
17
 *    endorse or promote products derived from this software without
 
18
 *    specific prior written permission.
16
19
 *
17
 
 * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
18
 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 
 * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
21
 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 
 * SUCH DAMAGE.
 
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
21
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
22
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
23
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
 
24
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
25
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
26
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
27
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
28
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
29
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
30
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
31
 */
29
32
 
30
33
#include <config.h>
31
34
 
32
 
#ident "$Id: newgrp.c 1876 2008-03-07 20:21:15Z nekral-guest $"
 
35
#ident "$Id: newgrp.c 2348 2008-09-06 12:51:53Z nekral-guest $"
33
36
 
34
37
#include <errno.h>
35
38
#include <grp.h>
42
45
/*
43
46
 * Global variables
44
47
 */
 
48
char *Prog;
 
49
 
45
50
extern char **newenvp;
46
51
extern char **environ;
47
52
 
50
55
static GETGROUPS_T *grouplist;
51
56
#endif
52
57
 
53
 
static char *Prog;
54
 
static int is_newgrp;
 
58
static bool is_newgrp;
 
59
 
 
60
#ifdef WITH_AUDIT
 
61
char audit_buf[80];
 
62
#endif
55
63
 
56
64
/* local function prototypes */
57
65
static void usage (void);
65
73
 */
66
74
static void usage (void)
67
75
{
68
 
        if (is_newgrp)
 
76
        if (is_newgrp) {
69
77
                fputs (_("Usage: newgrp [-] [group]\n"), stderr);
70
 
        else
 
78
        } else {
71
79
                fputs (_("Usage: sg group [[-c] command]\n"), stderr);
 
80
        }
72
81
}
73
82
 
74
83
/*
79
88
{
80
89
        struct group *gr;
81
90
        char **look;
82
 
        int notfound = 1;
 
91
        bool notfound = true;
83
92
 
84
93
        setgrent ();
85
94
        while ((gr = getgrent ()) != NULL) {
92
101
                 * Test for membership of 'name'.
93
102
                 */
94
103
                look = gr->gr_mem;
95
 
                while (*look && (notfound = strcmp (*look++, name)));
96
 
                if (!notfound)
 
104
                while ((NULL != *look) && notfound) {
 
105
                        notfound = (strcmp (*look, name) != 0);
 
106
                        look++;
 
107
                }
 
108
                if (!notfound) {
97
109
                        break;
 
110
                }
98
111
        }
99
112
        endgrent ();
100
113
        return gr;
111
124
                         struct passwd *pwd,
112
125
                         const char *groupname)
113
126
{
114
 
        int needspasswd = 0;
 
127
        bool needspasswd = false;
115
128
        struct spwd *spwd;
116
129
        char *cp;
117
130
        const char *cpasswd;
125
138
         * anyway.
126
139
         *
127
140
         */
128
 
        if (grp->gr_gid != pwd->pw_gid && !is_on_list (grp->gr_mem, pwd->pw_name))
129
 
                needspasswd = 1;
 
141
        if (   (grp->gr_gid != pwd->pw_gid)
 
142
            && !is_on_list (grp->gr_mem, pwd->pw_name)) {
 
143
                needspasswd = true;
 
144
        }
130
145
 
131
146
        /*
132
147
         * If she does not have either a shadowed password, or a regular
134
149
         * group password.
135
150
         */
136
151
        spwd = xgetspnam (pwd->pw_name);
137
 
        if (NULL != spwd)
 
152
        if (NULL != spwd) {
138
153
                pwd->pw_passwd = spwd->sp_pwdp;
 
154
        }
139
155
 
140
 
        if (pwd->pw_passwd[0] == '\0' && grp->gr_passwd[0])
141
 
                needspasswd = 1;
 
156
        if ((pwd->pw_passwd[0] == '\0') && (grp->gr_passwd[0] != '\0')) {
 
157
                needspasswd = true;
 
158
        }
142
159
 
143
160
        /*
144
161
         * Now I see about letting her into the group she requested. If she
146
163
         * the password. Otherwise I ask for a password if she flunked one
147
164
         * of the tests above.
148
165
         */
149
 
        if (getuid () != 0 && needspasswd) {
 
166
        if ((getuid () != 0) && needspasswd) {
150
167
                /*
151
168
                 * get the password from her, and set the salt for
152
169
                 * the decryption from the group file.
153
170
                 */
154
171
                cp = getpass (_("Password: "));
155
 
                if (NULL == cp)
 
172
                if (NULL == cp) {
156
173
                        goto failure;
 
174
                }
157
175
 
158
176
                /*
159
177
                 * encrypt the key she gave us using the salt from the
167
185
                    strcmp (cpasswd, grp->gr_passwd) != 0) {
168
186
#ifdef WITH_AUDIT
169
187
                        snprintf (audit_buf, sizeof(audit_buf),
170
 
                                  "authentication new-gid=%d", grp->gr_gid);
 
188
                                  "authentication new-gid=%lu",
 
189
                                  (unsigned long) grp->gr_gid);
171
190
                        audit_logger (AUDIT_GRP_AUTH, Prog,
172
 
                                      audit_buf, NULL, getuid (), 0);
 
191
                                      audit_buf, NULL,
 
192
                                      (unsigned int) getuid (), 0);
173
193
#endif
174
194
                        SYSLOG ((LOG_INFO,
175
 
                                 "Invalid password for group `%s' from `%s'",
 
195
                                 "Invalid password for group '%s' from '%s'",
176
196
                                 groupname, pwd->pw_name));
177
197
                        sleep (1);
178
198
                        fputs (_("Invalid password.\n"), stderr);
180
200
                }
181
201
#ifdef WITH_AUDIT
182
202
                snprintf (audit_buf, sizeof(audit_buf),
183
 
                          "authentication new-gid=%d", grp->gr_gid);
 
203
                          "authentication new-gid=%lu",
 
204
                          (unsigned long) grp->gr_gid);
184
205
                audit_logger (AUDIT_GRP_AUTH, Prog,
185
 
                              audit_buf, NULL, getuid (), 1);
 
206
                              audit_buf, NULL,
 
207
                              (unsigned int) getuid (), 1);
186
208
#endif
187
209
        }
188
210
 
198
220
                snprintf (audit_buf, sizeof(audit_buf),
199
221
                          "changing new-group=%s", groupname);
200
222
                audit_logger (AUDIT_CHGRP_ID, Prog,
201
 
                              audit_buf, NULL, getuid (), 0);
 
223
                              audit_buf, NULL,
 
224
                              (unsigned int) getuid (), 0);
202
225
        } else {
203
 
                audit_logger (AUDIT_CHGRP_ID, Prog, "changing",
204
 
                              NULL, getuid (), 0);
 
226
                audit_logger (AUDIT_CHGRP_ID, Prog,
 
227
                              "changing", NULL,
 
228
                              (unsigned int) getuid (), 0);
205
229
        }
206
230
#endif
207
231
        exit (1);
219
243
        const char *loginname = getlogin ();
220
244
        const char *tty = ttyname (0);
221
245
 
222
 
        if (loginname != NULL)
 
246
        if (loginname != NULL) {
223
247
                loginname = xstrdup (loginname);
224
 
        if (tty != NULL)
 
248
        }
 
249
        if (tty != NULL) {
225
250
                tty = xstrdup (tty);
 
251
        }
226
252
 
227
 
        if (loginname == NULL)
 
253
        if (loginname == NULL) {
228
254
                loginname = "???";
229
 
        if (tty == NULL)
 
255
        }
 
256
        if (tty == NULL) {
230
257
                tty = "???";
231
 
        else if (strncmp (tty, "/dev/", 5) == 0)
 
258
        } else if (strncmp (tty, "/dev/", 5) == 0) {
232
259
                tty += 5;
 
260
        }
233
261
        SYSLOG ((LOG_INFO,
234
 
                 "user `%s' (login `%s' on %s) switched to group `%s'",
 
262
                 "user '%s' (login '%s' on %s) switched to group '%s'",
235
263
                 name, loginname, tty, group));
236
264
#ifdef USE_PAM
237
265
        /*
253
281
        {
254
282
                pid_t child, pid;
255
283
 
256
 
                signal (SIGINT, SIG_IGN);
257
 
                signal (SIGQUIT, SIG_IGN);
258
 
                signal (SIGHUP, SIG_IGN);
259
 
                signal (SIGTSTP, SIG_IGN);
260
 
                signal (SIGTTIN, SIG_IGN);
261
 
                signal (SIGTTOU, SIG_IGN);
 
284
                /* Ignore these signals. The signal handlers will later be
 
285
                 * restored to the default handlers. */
 
286
                (void) signal (SIGINT, SIG_IGN);
 
287
                (void) signal (SIGQUIT, SIG_IGN);
 
288
                (void) signal (SIGHUP, SIG_IGN);
 
289
                (void) signal (SIGTSTP, SIG_IGN);
 
290
                (void) signal (SIGTTIN, SIG_IGN);
 
291
                (void) signal (SIGTTOU, SIG_IGN);
262
292
                child = fork ();
263
 
                if (child < 0) {
 
293
                if ((pid_t)-1 == child) {
264
294
                        /* error in fork() */
265
295
                        fprintf (stderr, _("%s: failure forking: %s\n"),
266
296
                                 is_newgrp ? "newgrp" : "sg", strerror (errno));
269
299
                                snprintf (audit_buf, sizeof(audit_buf),
270
300
                                          "changing new-group=%s", group);
271
301
                                audit_logger (AUDIT_CHGRP_ID, Prog,
272
 
                                              audit_buf, NULL, getuid (), 0);
 
302
                                              audit_buf, NULL,
 
303
                                              (unsigned int) getuid (), 0);
273
304
                        } else {
274
 
                                audit_logger (AUDIT_CHGRP_ID, Prog, "changing",
275
 
                                              NULL, getuid (), 0);
 
305
                                audit_logger (AUDIT_CHGRP_ID, Prog,
 
306
                                              "changing", NULL,
 
307
                                              (unsigned int) getuid (), 0);
276
308
                        }
277
309
#endif
278
310
                        exit (1);
279
 
                } else if (child) {
 
311
                } else if (child != 0) {
280
312
                        /* parent - wait for child to finish, then log session close */
281
313
                        int cst = 0;
282
314
                        gid_t gid = getgid();
285
317
                        do {
286
318
                                errno = 0;
287
319
                                pid = waitpid (child, &cst, WUNTRACED);
288
 
                                if (pid == child && WIFSTOPPED (cst)) {
 
320
                                if ((pid == child) && (WIFSTOPPED (cst) != 0)) {
289
321
                                        /* stop when child stops */
290
 
                                        raise (SIGSTOP);
 
322
                                        kill (getpid (), WSTOPSIG(cst));
291
323
                                        /* wake child when resumed */
292
324
                                        kill (child, SIGCONT);
293
325
                                }
294
 
                        } while ((pid == child && WIFSTOPPED (cst)) ||
295
 
                                 (pid != child && errno == EINTR));
 
326
                        } while (   ((pid == child) && (WIFSTOPPED (cst) != 0))
 
327
                                 || ((pid != child) && (errno == EINTR)));
296
328
                        /* local, no need for xgetgrgid */
297
329
                        if (NULL != grp) {
298
330
                                SYSLOG ((LOG_INFO,
299
 
                                         "user `%s' (login `%s' on %s) returned to group `%s'",
 
331
                                         "user '%s' (login '%s' on %s) returned to group '%s'",
300
332
                                         name, loginname, tty, grp->gr_name));
301
333
                        } else {
302
334
                                SYSLOG ((LOG_INFO,
303
 
                                         "user `%s' (login `%s' on %s) returned to group `%d'",
304
 
                                         name, loginname, tty, gid));
 
335
                                         "user '%s' (login '%s' on %s) returned to group '%lu'",
 
336
                                         name, loginname, tty,
 
337
                                         (unsigned long) gid));
305
338
                                /* Either the user's passwd entry has a
306
339
                                 * GID that does not match with any group,
307
340
                                 * or the group was deleted while the user
308
341
                                 * was in a newgrp session.*/
309
342
                                SYSLOG ((LOG_WARN,
310
 
                                         "unknown GID `%u' used by user `%s'",
311
 
                                         gid, name));
 
343
                                         "unknown GID '%lu' used by user '%s'",
 
344
                                         (unsigned long) gid, name));
312
345
                        }
313
346
                        closelog ();
314
347
                        exit (0);
315
348
                }
316
349
 
317
350
                /* child - restore signals to their default state */
318
 
                signal (SIGINT, SIG_DFL);
319
 
                signal (SIGQUIT, SIG_DFL);
320
 
                signal (SIGHUP, SIG_DFL);
321
 
                signal (SIGTSTP, SIG_DFL);
322
 
                signal (SIGTTIN, SIG_DFL);
323
 
                signal (SIGTTOU, SIG_DFL);
 
351
                (void) signal (SIGINT, SIG_DFL);
 
352
                (void) signal (SIGQUIT, SIG_DFL);
 
353
                (void) signal (SIGHUP, SIG_DFL);
 
354
                (void) signal (SIGTSTP, SIG_DFL);
 
355
                (void) signal (SIGTTIN, SIG_DFL);
 
356
                (void) signal (SIGTTOU, SIG_DFL);
324
357
        }
325
358
#endif                          /* USE_PAM */
326
359
}
331
364
 */
332
365
int main (int argc, char **argv)
333
366
{
334
 
        int initflag = 0;
 
367
        bool initflag = false;
335
368
        int i;
336
 
        int cflag = 0;
 
369
        bool cflag = false;
337
370
        int err = 0;
338
371
        gid_t gid;
339
372
        char *cp;
349
382
#endif
350
383
 
351
384
#ifdef WITH_AUDIT
352
 
        char audit_buf[80];
353
 
 
354
385
        audit_help_open ();
355
386
#endif
356
 
        setlocale (LC_ALL, "");
357
 
        bindtextdomain (PACKAGE, LOCALEDIR);
358
 
        textdomain (PACKAGE);
 
387
        (void) setlocale (LC_ALL, "");
 
388
        (void) bindtextdomain (PACKAGE, LOCALEDIR);
 
389
        (void) textdomain (PACKAGE);
359
390
 
360
391
        /*
361
392
         * Save my name for error messages and save my real gid incase of
390
421
        initenv ();
391
422
 
392
423
        pwd = get_my_pwent ();
393
 
        if (!pwd) {
394
 
                fprintf (stderr, _("unknown UID: %u\n"), getuid ());
 
424
        if (NULL == pwd) {
 
425
                fprintf (stderr, _("%s: Cannot determine your user name.\n"),
 
426
                         Prog);
395
427
#ifdef WITH_AUDIT
396
 
                audit_logger (AUDIT_CHGRP_ID, Prog, "changing", NULL,
397
 
                              getuid (), 0);
 
428
                audit_logger (AUDIT_CHGRP_ID, Prog,
 
429
                              "changing", NULL,
 
430
                              (unsigned int) getuid (), 0);
398
431
#endif
399
 
                SYSLOG ((LOG_WARN, "unknown UID %u", getuid ()));
 
432
                SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
 
433
                         (unsigned long) getuid ()));
400
434
                closelog ();
401
435
                exit (1);
402
436
        }
419
453
         *      sg [-]
420
454
         *      sg [-] groupid [[-c command]
421
455
         */
422
 
        if (argc > 0 && (!strcmp (argv[0], "-") || !strcmp (argv[0], "-l"))) {
 
456
        if (   (argc > 0)
 
457
            && (   (strcmp (argv[0], "-")  == 0)
 
458
                || (strcmp (argv[0], "-l") == 0))) {
423
459
                argc--;
424
460
                argv++;
425
 
                initflag = 1;
 
461
                initflag = true;
426
462
        }
427
463
        if (!is_newgrp) {
428
464
                /* 
429
465
                 * Do the command line for everything that is
430
466
                 * not "newgrp".
431
467
                 */
432
 
                if (argc > 0 && argv[0][0] != '-') {
 
468
                if ((argc > 0) && (argv[0][0] != '-')) {
433
469
                        group = argv[0];
434
470
                        argc--;
435
471
                        argv++;
445
481
                         * "sg group -c command" (as in the man page) or
446
482
                         * "sg group command" (as in the usage message).
447
483
                         */
448
 
                        if (argc > 1 && strcmp (argv[0], "-c") == 0)
 
484
                        if ((argc > 1) && (strcmp (argv[0], "-c") == 0)) {
449
485
                                command = argv[1];
450
 
                        else
 
486
                        } else {
451
487
                                command = argv[0];
452
 
                        cflag++;
 
488
                        }
 
489
                        cflag = true;
453
490
                }
454
491
        } else {
455
492
                /*
456
493
                 * Do the command line for "newgrp". It's just making sure
457
494
                 * there aren't any flags and getting the new group name.
458
495
                 */
459
 
                if (argc > 0 && argv[0][0] == '-') {
 
496
                if ((argc > 0) && (argv[0][0] == '-')) {
460
497
                        usage ();
461
498
                        goto failure;
462
499
                } else if (argv[0] != (char *) 0) {
471
508
                         */
472
509
                        grp = xgetgrgid (pwd->pw_gid);
473
510
                        if (NULL == grp) {
474
 
                                fprintf (stderr, _("unknown GID: %lu\n"),
475
 
                                         (unsigned long) pwd->pw_gid);
476
 
                                SYSLOG ((LOG_CRIT, "unknown GID: %lu",
477
 
                                         (unsigned long) pwd->pw_gid));
 
511
                                fprintf (stderr,
 
512
                                         _("%s: GID '%lu' does not exist\n"),
 
513
                                         Prog, (unsigned long) pwd->pw_gid);
 
514
                                SYSLOG ((LOG_CRIT, "GID '%lu' does not exist",
 
515
                                        (unsigned long) pwd->pw_gid));
478
516
                                goto failure;
479
 
                        } else
 
517
                        } else {
480
518
                                group = grp->gr_name;
 
519
                        }
481
520
                }
482
521
        }
483
522
 
493
532
        for (;;) {
494
533
                grouplist = (GETGROUPS_T *) xmalloc (i * sizeof (GETGROUPS_T));
495
534
                ngroups = getgroups (i, grouplist);
496
 
                if (i > ngroups && !(ngroups == -1 && errno == EINVAL))
 
535
                if (i > ngroups && !(ngroups == -1 && errno == EINVAL)) {
497
536
                        break;
 
537
                }
498
538
                /* not enough room, so try allocating a larger buffer */
499
539
                free (grouplist);
500
540
                i *= 2;
506
546
                        snprintf (audit_buf, sizeof(audit_buf),
507
547
                                  "changing new-group=%s", group);
508
548
                        audit_logger (AUDIT_CHGRP_ID, Prog,
509
 
                                      audit_buf, NULL, getuid (), 0);
 
549
                                      audit_buf, NULL,
 
550
                                      (unsigned int) getuid (), 0);
510
551
                } else {
511
552
                        audit_logger (AUDIT_CHGRP_ID, Prog,
512
 
                                      "changing", NULL, getuid (), 0);
 
553
                                      "changing", NULL,
 
554
                                      (unsigned int) getuid (), 0);
513
555
                }
514
556
#endif
515
557
                exit (1);
558
600
         */
559
601
        grp = getgrnam (group); /* local, no need for xgetgrnam */
560
602
        if (NULL == grp) {
561
 
                fprintf (stderr, _("unknown group: %s\n"), group);
 
603
                fprintf (stderr, _("%s: group '%s' does not exist\n"), Prog, group);
562
604
                goto failure;
563
605
        }
564
606
 
568
610
         * membership of the current user.
569
611
         */
570
612
        grp = find_matching_group (name, grp->gr_gid);
571
 
        if (!grp) {
 
613
        if (NULL == grp) {
572
614
                /*
573
615
                 * No matching group found. As we already know that
574
616
                 * the group exists, this happens only in the case
611
653
         * part.
612
654
         */
613
655
        for (i = 0; i < ngroups; i++) {
614
 
                if (gid == grouplist[i])
 
656
                if (gid == grouplist[i]) {
615
657
                        break;
 
658
                }
616
659
        }
617
660
        if (i == ngroups) {
618
661
                if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
619
662
                        fputs (_("too many groups\n"), stderr);
620
663
                } else {
621
664
                        grouplist[ngroups++] = gid;
622
 
                        if (setgroups (ngroups, grouplist)) {
 
665
                        if (setgroups (ngroups, grouplist) != 0) {
623
666
                                perror ("setgroups");
624
667
                        }
625
668
                }
631
674
         * to the real UID. For root, this also sets the real GID to the
632
675
         * new group id.
633
676
         */
634
 
        if (setgid (gid)) {
 
677
        if (setgid (gid) != 0) {
635
678
                perror ("setgid");
636
679
#ifdef WITH_AUDIT
637
680
                snprintf (audit_buf, sizeof(audit_buf),
638
 
                          "changing new-gid=%d", gid);
 
681
                          "changing new-gid=%lu", (unsigned long) gid);
639
682
                audit_logger (AUDIT_CHGRP_ID, Prog,
640
 
                              audit_buf, NULL, getuid (), 0);
 
683
                              audit_buf, NULL,
 
684
                              (unsigned int) getuid (), 0);
641
685
#endif
642
686
                exit (1);
643
687
        }
644
688
 
645
 
        if (setuid (getuid ())) {
 
689
        if (setuid (getuid ()) != 0) {
646
690
                perror ("setuid");
647
691
#ifdef WITH_AUDIT
648
692
                snprintf (audit_buf, sizeof(audit_buf),
649
 
                          "changing new-gid=%d", gid);
 
693
                          "changing new-gid=%lu", (unsigned long) gid);
650
694
                audit_logger (AUDIT_CHGRP_ID, Prog,
651
 
                              audit_buf, NULL, getuid (), 0);
 
695
                              audit_buf, NULL,
 
696
                              (unsigned int) getuid (), 0);
652
697
#endif
653
698
                exit (1);
654
699
        }
662
707
                execl ("/bin/sh", "sh", "-c", command, (char *) 0);
663
708
#ifdef WITH_AUDIT
664
709
                snprintf (audit_buf, sizeof(audit_buf),
665
 
                          "changing new-gid=%d", gid);
 
710
                          "changing new-gid=%lu", (unsigned long) gid);
666
711
                audit_logger (AUDIT_CHGRP_ID, Prog,
667
 
                              audit_buf, NULL, getuid (), 0);
 
712
                              audit_buf, NULL,
 
713
                              (unsigned int) getuid (), 0);
668
714
#endif
669
715
                perror ("/bin/sh");
670
716
                exit (errno == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
687
733
         * problem, try using $SHELL as a workaround; also please notify me
688
734
         * at jparmele@wildbear.com -- JWP
689
735
         */
690
 
        if (!initflag && (cp = getenv ("SHELL")))
 
736
        cp = getenv ("SHELL");
 
737
        if (!initflag && (NULL != cp)) {
691
738
                prog = cp;
692
 
        else if (pwd->pw_shell && pwd->pw_shell[0])
 
739
        } else if ((NULL != pwd->pw_shell) && ('\0' != pwd->pw_shell[0])) {
693
740
                prog = pwd->pw_shell;
694
 
        else
 
741
        } else {
695
742
                prog = "/bin/sh";
 
743
        }
696
744
 
697
745
        /*
698
 
         * Now i try to find the basename of the login shell. This will
 
746
         * Now I try to find the basename of the login shell. This will
699
747
         * become argv[0] of the spawned command.
700
748
         */
701
749
        cp = Basename ((char *) prog);
712
760
         * initialization.
713
761
         */
714
762
        if (initflag) {
715
 
                if (chdir (pwd->pw_dir))
 
763
                if (chdir (pwd->pw_dir) != 0) {
716
764
                        perror ("chdir");
 
765
                }
717
766
 
718
 
                while (*envp) {
 
767
                while (NULL != *envp) {
719
768
                        if (strncmp (*envp, "PATH=", 5) == 0 ||
720
769
                            strncmp (*envp, "HOME=", 5) == 0 ||
721
770
                            strncmp (*envp, "SHELL=", 6) == 0 ||
725
774
                        envp++;
726
775
                }
727
776
        } else {
728
 
                while (*envp)
729
 
                        addenv (*envp++, NULL);
 
777
                while (NULL != *envp) {
 
778
                        addenv (*envp, NULL);
 
779
                        envp++;
 
780
                }
730
781
        }
731
782
 
732
783
#ifdef WITH_AUDIT
733
 
        snprintf (audit_buf, sizeof(audit_buf), "changing new-gid=%d", gid);
734
 
        audit_logger (AUDIT_CHGRP_ID, Prog, audit_buf, NULL, getuid (), 1);
 
784
        snprintf (audit_buf, sizeof(audit_buf), "changing new-gid=%lu",
 
785
                  (unsigned long) gid);
 
786
        audit_logger (AUDIT_CHGRP_ID, Prog,
 
787
                      audit_buf, NULL,
 
788
                      (unsigned int) getuid (), 1);
735
789
#endif
736
790
        /*
737
791
         * Exec the login shell and go away. We are trying to get back to
754
808
         */
755
809
        closelog ();
756
810
#ifdef WITH_AUDIT
757
 
        if (group) {
 
811
        if (NULL != group) {
758
812
                snprintf (audit_buf, sizeof(audit_buf),
759
813
                          "changing new-group=%s", group);
760
814
                audit_logger (AUDIT_CHGRP_ID, Prog, 
761
 
                              audit_buf, NULL, getuid (), 0);
 
815
                              audit_buf, NULL,
 
816
                              (unsigned int) getuid (), 0);
762
817
        } else {
763
818
                audit_logger (AUDIT_CHGRP_ID, Prog,
764
 
                              "changing", NULL, getuid (), 0);
 
819
                              "changing", NULL,
 
820
                              (unsigned int) getuid (), 0);
765
821
        }
766
822
#endif
767
823
        exit (1);
768
824
}
 
825