]> granicus.if.org Git - shadow/blobdiff - src/grpck.c
* src/newgrp.c, src/chfn.c, src/groupmems.c, src/usermod.c,
[shadow] / src / grpck.c
index 9c710c7baf89c04a55a1f35da06e7764164288f9..ca4d72e18d9c7d56a1b34106888f3bd562b7967f 100644 (file)
@@ -1,5 +1,9 @@
 /*
- * Copyright 1992 - 1994, Julianne Frances Haugh
+ * Copyright (c) 1992 - 1994, Julianne Frances Haugh
+ * Copyright (c) 1996 - 2000, Marek Michałkiewicz
+ * Copyright (c) 2001       , Michał Moskal
+ * Copyright (c) 2001 - 2006, Tomasz Kłoczko
+ * Copyright (c) 2007 - 2009, Nicolas François
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
+ * 3. The name of the copyright holders or contributors may not be used to
+ *    endorse or promote products derived from this software without
+ *    specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <config.h>
 #include "groupio.h"
 #include "nscd.h"
 #include "prototypes.h"
-extern void __gr_del_entry (const struct commonio_entry *);
-extern struct commonio_entry *__gr_get_head (void);
 
 #ifdef SHADOWGRP
 #include "sgroupio.h"
-extern void __sgr_del_entry (const struct commonio_entry *);
-extern struct commonio_entry *__sgr_get_head (void);
 #endif
 
 /*
  * Exit codes
  */
-
+/*@-exitarg@*/
 #define        E_OKAY          0
 #define        E_USAGE         1
 #define        E_BAD_ENTRY     2
@@ -64,41 +64,73 @@ extern struct commonio_entry *__sgr_get_head (void);
 /*
  * Global variables
  */
-static char *Prog;
+char *Prog;
+
 static const char *grp_file = GROUP_FILE;
-static int use_system_grp_file = 1;
+static bool use_system_grp_file = true;
 
 #ifdef SHADOWGRP
 static const char *sgr_file = SGROUP_FILE;
-static int use_system_sgr_file = 1;
-static int is_shadow = 0;
+static bool use_system_sgr_file = true;
+static bool is_shadow = false;
+static bool sgr_locked = false;
 #endif
+static bool gr_locked = false;
 /* Options */
-static int read_only = 0;
-static int sort_mode = 0;
+static bool read_only = false;
+static bool sort_mode = false;
 
 /* local function prototypes */
+static void fail_exit (int status);
 static void usage (void);
 static void delete_member (char **, const char *);
 static void process_flags (int argc, char **argv);
-static void open_files ();
-static void close_files (int changed);
+static void open_files (void);
+static void close_files (bool changed);
 static int check_members (const char *groupname,
                           char **members,
                           const char *fmt_info,
                           const char *fmt_prompt,
                           const char *fmt_syslog,
                           int *errors);
+static void check_grp_file (int *errors, bool *changed);
+#ifdef SHADOWGRP
 static void compare_members_lists (const char *groupname,
                                    char **members,
                                    char **other_members,
                                    const char *file,
                                    const char *other_file);
-static void check_grp_file (int *errors, int *changed);
-#ifdef SHADOWGRP
-static void check_sgr_file (int *errors, int *changed);
+static void check_sgr_file (int *errors, bool *changed);
 #endif
 
+/*
+ * fail_exit - exit with an error code after unlocking files
+ */
+static void fail_exit (int status)
+{
+       if (gr_locked) {
+               if (gr_unlock () == 0) {
+                       fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
+                       SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
+                       /* continue */
+               }
+       }
+
+#ifdef SHADOWGRP
+       if (sgr_locked) {
+               if (sgr_unlock () == 0) {
+                       fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
+                       SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
+                       /* continue */
+               }
+       }
+#endif
+
+       closelog ();
+
+       exit (status);
+}
+
 /*
  * usage - print syntax message and exit
  */
@@ -114,18 +146,24 @@ static void usage (void)
 
 /*
  * delete_member - delete an entry in a list of members
+ *
+ * It only deletes the first entry with the given name.
  */
 static void delete_member (char **list, const char *member)
 {
        int i;
 
-       for (i = 0; list[i]; i++)
-               if (list[i] == member)
+       for (i = 0; list[i]; i++) {
+               if (list[i] == member) {
                        break;
+               }
+       }
 
-       if (list[i])
-               for (; list[i]; i++)
+       if (list[i]) {
+               for (; list[i]; i++) {
                        list[i] = list[i + 1];
+               }
+       }
 }
 
 /*
@@ -146,10 +184,10 @@ static void process_flags (int argc, char **argv)
                        /* quiet - ignored for now */
                        break;
                case 'r':
-                       read_only = 1;
+                       read_only = true;
                        break;
                case 's':
-                       sort_mode = 1;
+                       sort_mode = true;
                        break;
                default:
                        usage ();
@@ -179,15 +217,15 @@ static void process_flags (int argc, char **argv)
         */
        if (optind != argc) {
                grp_file = argv[optind];
-               gr_name (grp_file);
-               use_system_grp_file = 0;
+               gr_setdbname (grp_file);
+               use_system_grp_file = false;
        }
 #ifdef SHADOWGRP
        if ((optind + 2) == argc) {
                sgr_file = argv[optind + 1];
-               sgr_name (sgr_file);
-               is_shadow = 1;
-               use_system_sgr_file = 0;
+               sgr_setdbname (sgr_file);
+               is_shadow = true;
+               use_system_sgr_file = false;
        } else if (optind == argc) {
                is_shadow = sgr_file_present ();
        }
@@ -200,30 +238,28 @@ static void process_flags (int argc, char **argv)
  *     In read-only mode, the databases are not locked and are opened
  *     only for reading.
  */
-static void open_files ()
+static void open_files (void)
 {
        /*
         * Lock the files if we aren't in "read-only" mode
         */
        if (!read_only) {
                if (gr_lock () == 0) {
-                       fprintf (stderr, _("%s: cannot lock file %s\n"),
+                       fprintf (stderr,
+                                _("%s: cannot lock %s; try again later.\n"),
                                 Prog, grp_file);
-                       if (use_system_grp_file) {
-                               SYSLOG ((LOG_WARN, "cannot lock %s", grp_file));
-                       }
-                       closelog ();
-                       exit (E_CANT_LOCK);
+                       fail_exit (E_CANT_LOCK);
                }
+               gr_locked = true;
 #ifdef SHADOWGRP
-               if (is_shadow && (sgr_lock () == 0)) {
-                       fprintf (stderr, _("%s: cannot lock file %s\n"),
-                                Prog, sgr_file);
-                       if (use_system_sgr_file) {
-                               SYSLOG ((LOG_WARN, "cannot lock %s", sgr_file));
+               if (is_shadow) {
+                       if (sgr_lock () == 0) {
+                               fprintf (stderr,
+                                        _("%s: cannot lock %s; try again later.\n"),
+                                        Prog, sgr_file);
+                               fail_exit (E_CANT_LOCK);
                        }
-                       closelog ();
-                       exit (E_CANT_LOCK);
+                       sgr_locked = true;
                }
 #endif
        }
@@ -233,35 +269,33 @@ static void open_files ()
         * O_RDWR otherwise.
         */
        if (gr_open (read_only ? O_RDONLY : O_RDWR) == 0) {
-               fprintf (stderr, _("%s: cannot open file %s\n"), Prog,
+               fprintf (stderr, _("%s: cannot open %s\n"), Prog,
                         grp_file);
                if (use_system_grp_file) {
                        SYSLOG ((LOG_WARN, "cannot open %s", grp_file));
                }
-               closelog ();
-               exit (E_CANT_OPEN);
+               fail_exit (E_CANT_OPEN);
        }
 #ifdef SHADOWGRP
        if (is_shadow && (sgr_open (read_only ? O_RDONLY : O_RDWR) == 0)) {
-               fprintf (stderr, _("%s: cannot open file %s\n"), Prog,
+               fprintf (stderr, _("%s: cannot open %s\n"), Prog,
                         sgr_file);
                if (use_system_sgr_file) {
                        SYSLOG ((LOG_WARN, "cannot open %s", sgr_file));
                }
-               closelog ();
-               exit (E_CANT_OPEN);
+               fail_exit (E_CANT_OPEN);
        }
 #endif
 }
 
 /*
- * close_files - close and unlock the password/shadow databases
+ * close_files - close and unlock the group/gshadow databases
  *
  *     If changed is not set, the databases are not closed, and no
  *     changes are committed in the databases. The databases are
  *     unlocked anyway.
  */
-static void close_files (int changed)
+static void close_files (bool changed)
 {
        /*
         * All done. If there were no change we can just abandon any
@@ -269,15 +303,15 @@ static void close_files (int changed)
         */
        if (changed) {
                if (gr_close () == 0) {
-                       fprintf (stderr, _("%s: cannot update file %s\n"),
-                                Prog, grp_file);
-                       exit (E_CANT_UPDATE);
+                       fprintf (stderr, _("%s: failure while writing changes to %s\n"),
+                                Prog, grp_file);
+                       fail_exit (E_CANT_UPDATE);
                }
 #ifdef SHADOWGRP
                if (is_shadow && (sgr_close () == 0)) {
-                       fprintf (stderr, _("%s: cannot update file %s\n"),
-                                Prog, sgr_file);
-                       exit (E_CANT_UPDATE);
+                       fprintf (stderr, _("%s: failure while writing changes to %s\n"),
+                                Prog, sgr_file);
+                       fail_exit (E_CANT_UPDATE);
                }
 #endif
        }
@@ -286,11 +320,23 @@ static void close_files (int changed)
         * Don't be anti-social - unlock the files when you're done.
         */
 #ifdef SHADOWGRP
-       if (is_shadow) {
-               sgr_unlock ();
+       if (sgr_locked) {
+               if (sgr_unlock () == 0) {
+                       fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname ());
+                       SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
+                       /* continue */
+               }
+               sgr_locked = false;
        }
 #endif
-       (void) gr_unlock ();
+       if (gr_locked) {
+               if (gr_unlock () == 0) {
+                       fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname ());
+                       SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
+                       /* continue */
+               }
+               gr_locked = false;
+       }
 }
 
 /*
@@ -325,10 +371,11 @@ static int check_members (const char *groupname,
        /*
         * Make sure each member exists
         */
-       for (i = 0; members[i]; i++) {
+       for (i = 0; NULL != members[i]; i++) {
                /* local, no need for xgetpwnam */
-               if (getpwnam (members[i]))
+               if (getpwnam (members[i]) != NULL) {
                        continue;
+               }
                /*
                 * Can't find this user. Remove them
                 * from the list.
@@ -337,17 +384,22 @@ static int check_members (const char *groupname,
                printf (fmt_info, groupname, members[i]);
                printf (fmt_prompt, members[i]);
 
-               if (!yes_or_no (read_only))
+               if (!yes_or_no (read_only)) {
                        continue;
+               }
 
                SYSLOG ((LOG_INFO, fmt_syslog, members[i], groupname));
                members_changed = 1;
                delete_member (members, members[i]);
+
+               /* Rewind in case of removal */
+               i--;
        }
 
        return members_changed;
 }
 
+#ifdef SHADOWGRP
 /*
  * compare_members_lists - make sure the list of members is contained in
  *                         another list.
@@ -366,10 +418,11 @@ static void compare_members_lists (const char *groupname,
 {
        char **pmem, **other_pmem;
 
-       for (pmem = members; *pmem; pmem++) {
-               for (other_pmem = other_members; *other_pmem; other_pmem++) {
-                       if (strcmp (*pmem, *other_pmem) == 0)
+       for (pmem = members; NULL != *pmem; pmem++) {
+               for (other_pmem = other_members; NULL != *other_pmem; other_pmem++) {
+                       if (strcmp (*pmem, *other_pmem) == 0) {
                                break;
+                       }
                }
                if (*other_pmem == NULL) {
                        printf
@@ -378,11 +431,12 @@ static void compare_members_lists (const char *groupname,
                }
        }
 }
+#endif                         /* SHADOWGRP */
 
 /*
  * check_grp_file - check the content of the group file
  */
-static void check_grp_file (int *errors, int *changed)
+static void check_grp_file (int *errors, bool *changed)
 {
        struct commonio_entry *gre, *tgre;
        struct group *grp;
@@ -393,34 +447,36 @@ static void check_grp_file (int *errors, int *changed)
        /*
         * Loop through the entire group file.
         */
-       for (gre = __gr_get_head (); gre; gre = gre->next) {
+       for (gre = __gr_get_head (); NULL != gre; gre = gre->next) {
                /*
                 * Skip all NIS entries.
                 */
 
-               if (gre->line[0] == '+' || gre->line[0] == '-')
+               if ((gre->line[0] == '+') || (gre->line[0] == '-')) {
                        continue;
+               }
 
                /*
                 * Start with the entries that are completely corrupt. They
                 * have no (struct group) entry because they couldn't be
                 * parsed properly.
                 */
-               if (!gre->eptr) {
+               if (NULL == gre->eptr) {
 
                        /*
                         * Tell the user this entire line is bogus and ask
                         * them to delete it.
                         */
-                       printf (_("invalid group file entry\n"));
+                       (void) puts (_("invalid group file entry"));
                        printf (_("delete line '%s'? "), gre->line);
                        *errors += 1;
 
                        /*
                         * prompt the user to delete the entry or not
                         */
-                       if (!yes_or_no (read_only))
+                       if (!yes_or_no (read_only)) {
                                continue;
+                       }
 
                        /*
                         * All group file deletions wind up here. This code
@@ -429,9 +485,9 @@ static void check_grp_file (int *errors, int *changed)
                         * to try out the next list element.
                         */
                      delete_gr:
-                       SYSLOG ((LOG_INFO, "delete group line `%s'",
-                                gre->line));
-                       *changed = 1;
+                       SYSLOG ((LOG_INFO, "delete group line '%s'",
+                                gre->line));
+                       *changed = true;
 
                        __gr_del_entry (gre);
                        continue;
@@ -445,64 +501,78 @@ static void check_grp_file (int *errors, int *changed)
                /*
                 * Make sure this entry has a unique name.
                 */
-               for (tgre = __gr_get_head (); tgre; tgre = tgre->next) {
+               for (tgre = __gr_get_head (); NULL != tgre; tgre = tgre->next) {
 
                        const struct group *ent = tgre->eptr;
 
                        /*
                         * Don't check this entry
                         */
-                       if (tgre == gre)
+                       if (tgre == gre) {
                                continue;
+                       }
 
                        /*
                         * Don't check invalid entries.
                         */
-                       if (!ent)
+                       if (NULL == ent) {
                                continue;
+                       }
 
-                       if (strcmp (grp->gr_name, ent->gr_name) != 0)
+                       if (strcmp (grp->gr_name, ent->gr_name) != 0) {
                                continue;
+                       }
 
                        /*
                         * Tell the user this entry is a duplicate of
                         * another and ask them to delete it.
                         */
-                       printf (_("duplicate group entry\n"));
+                       (void) puts (_("duplicate group entry"));
                        printf (_("delete line '%s'? "), gre->line);
                        *errors += 1;
 
                        /*
                         * prompt the user to delete the entry or not
                         */
-                       if (yes_or_no (read_only))
+                       if (yes_or_no (read_only)) {
                                goto delete_gr;
+                       }
                }
 
                /*
                 * Check for invalid group names.  --marekm
                 */
-               if (!check_group_name (grp->gr_name)) {
+               if (!is_valid_group_name (grp->gr_name)) {
                        *errors += 1;
                        printf (_("invalid group name '%s'\n"), grp->gr_name);
                }
 
+               /*
+                * Check for invalid group ID.
+                */
+               if (grp->gr_gid == (gid_t)-1) {
+                       printf (_("invalid group ID '%lu'\n"), (long unsigned int)grp->gr_gid);
+                       *errors += 1;
+               }
+
                /*
                 * Workaround for a NYS libc 5.3.12 bug on RedHat 4.2 -
                 * groups with no members are returned as groups with one
                 * member "", causing grpck to fail.  --marekm
                 */
-               if (grp->gr_mem[0] && !grp->gr_mem[1]
-                   && *(grp->gr_mem[0]) == '\0')
-                       grp->gr_mem[0] = (char *) 0;
+               if (   (NULL != grp->gr_mem[0])
+                   && (NULL == grp->gr_mem[1])
+                   && ('\0' == grp->gr_mem[0][0])) {
+                       grp->gr_mem[0] = NULL;
+               }
 
                if (check_members (grp->gr_name, grp->gr_mem,
                                   _("group %s: no user %s\n"),
                                   _("delete member '%s'? "),
-                                  "delete member `%s' from group `%s'",
+                                  "delete member '%s' from group '%s'",
                                   errors) == 1) {
-                       *changed = 1;
-                       gre->changed = 1;
+                       *changed = true;
+                       gre->changed = true;
                        __gr_set_changed ();
                }
 
@@ -514,11 +584,10 @@ static void check_grp_file (int *errors, int *changed)
                if (is_shadow) {
                        sgr = (struct sgrp *) sgr_locate (grp->gr_name);
                        if (sgr == NULL) {
-                               printf (_
-                                       ("no matching group file entry in %s\n"),
-                                       sgr_file);
-                               printf (_("add group '%s' in %s ?"),
-                                       grp->gr_name, sgr_file);
+                               printf (_("no matching group file entry in %s\n"),
+                                       sgr_file);
+                               printf (_("add group '%s' in %s? "),
+                                       grp->gr_name, sgr_file);
                                *errors += 1;
                                if (yes_or_no (read_only)) {
                                        struct sgrp sg;
@@ -530,26 +599,24 @@ static void check_grp_file (int *errors, int *changed)
                                        sg.sg_adm = &empty;
                                        sg.sg_mem = grp->gr_mem;
                                        SYSLOG ((LOG_INFO,
-                                                "add group `%s' to `%s'",
-                                                grp->gr_name, sgr_file));
-                                       *changed = 1;
+                                                "add group '%s' to '%s'",
+                                                grp->gr_name, sgr_file));
+                                       *changed = true;
 
-                                       if (!sgr_update (&sg)) {
+                                       if (sgr_update (&sg) == 0) {
                                                fprintf (stderr,
-                                                        _
-                                                        ("%s: can't update shadow entry for %s\n"),
-                                                        Prog, sg.sg_name);
-                                               exit (E_CANT_UPDATE);
+                                                        _("%s: failed to prepare the new %s entry '%s'\n"),
+                                                        Prog, sgr_dbname (), sg.sg_name);
+                                               fail_exit (E_CANT_UPDATE);
                                        }
                                        /* remove password from /etc/group */
                                        gr = *grp;
                                        gr.gr_passwd = SHADOW_PASSWD_STRING;    /* XXX warning: const */
-                                       if (!gr_update (&gr)) {
+                                       if (gr_update (&gr) == 0) {
                                                fprintf (stderr,
-                                                        _
-                                                        ("%s: can't update entry for group %s\n"),
-                                                        Prog, gr.gr_name);
-                                               exit (E_CANT_UPDATE);
+                                                        _("%s: failed to prepare the new %s entry '%s'\n"),
+                                                        Prog, gr_dbname (), gr.gr_name);
+                                               fail_exit (E_CANT_UPDATE);
                                        }
                                }
                        } else {
@@ -571,7 +638,7 @@ static void check_grp_file (int *errors, int *changed)
 /*
  * check_sgr_file - check the content of the shadowed group file (gshadow)
  */
-static void check_sgr_file (int *errors, int *changed)
+static void check_sgr_file (int *errors, bool *changed)
 {
        struct group *grp;
        struct commonio_entry *sge, *tsge;
@@ -580,28 +647,29 @@ static void check_sgr_file (int *errors, int *changed)
        /*
         * Loop through the entire shadow group file.
         */
-       for (sge = __sgr_get_head (); sge; sge = sge->next) {
+       for (sge = __sgr_get_head (); NULL != sge; sge = sge->next) {
 
                /*
                 * Start with the entries that are completely corrupt. They
                 * have no (struct sgrp) entry because they couldn't be
                 * parsed properly.
                 */
-               if (!sge->eptr) {
+               if (NULL == sge->eptr) {
 
                        /*
                         * Tell the user this entire line is bogus and ask
                         * them to delete it.
                         */
-                       printf (_("invalid shadow group file entry\n"));
+                       (void) puts (_("invalid shadow group file entry"));
                        printf (_("delete line '%s'? "), sge->line);
                        *errors += 1;
 
                        /*
                         * prompt the user to delete the entry or not
                         */
-                       if (!yes_or_no (read_only))
+                       if (!yes_or_no (read_only)) {
                                continue;
+                       }
 
                        /*
                         * All shadow group file deletions wind up here. 
@@ -610,9 +678,9 @@ static void check_sgr_file (int *errors, int *changed)
                         * of the loop to try out the next list element.
                         */
                      delete_sg:
-                       SYSLOG ((LOG_INFO, "delete shadow line `%s'",
-                                sge->line));
-                       *changed = 1;
+                       SYSLOG ((LOG_INFO, "delete shadow line '%s'",
+                                sge->line));
+                       *changed = true;
 
                        __sgr_del_entry (sge);
                        continue;
@@ -626,38 +694,42 @@ static void check_sgr_file (int *errors, int *changed)
                /*
                 * Make sure this entry has a unique name.
                 */
-               for (tsge = __sgr_get_head (); tsge; tsge = tsge->next) {
+               for (tsge = __sgr_get_head (); NULL != tsge; tsge = tsge->next) {
 
                        const struct sgrp *ent = tsge->eptr;
 
                        /*
                         * Don't check this entry
                         */
-                       if (tsge == sge)
+                       if (tsge == sge) {
                                continue;
+                       }
 
                        /*
                         * Don't check invalid entries.
                         */
-                       if (!ent)
+                       if (NULL == ent) {
                                continue;
+                       }
 
-                       if (strcmp (sgr->sg_name, ent->sg_name) != 0)
+                       if (strcmp (sgr->sg_name, ent->sg_name) != 0) {
                                continue;
+                       }
 
                        /*
                         * Tell the user this entry is a duplicate of
                         * another and ask them to delete it.
                         */
-                       printf (_("duplicate shadow group entry\n"));
+                       (void) puts (_("duplicate shadow group entry"));
                        printf (_("delete line '%s'? "), sge->line);
                        *errors += 1;
 
                        /*
                         * prompt the user to delete the entry or not
                         */
-                       if (yes_or_no (read_only))
+                       if (yes_or_no (read_only)) {
                                goto delete_sg;
+                       }
                }
 
                /*
@@ -666,11 +738,12 @@ static void check_sgr_file (int *errors, int *changed)
                grp = (struct group *) gr_locate (sgr->sg_name);
                if (grp == NULL) {
                        printf (_("no matching group file entry in %s\n"),
-                               grp_file);
+                               grp_file);
                        printf (_("delete line '%s'? "), sge->line);
                        *errors += 1;
-                       if (yes_or_no (read_only))
+                       if (yes_or_no (read_only)) {
                                goto delete_sg;
+                       }
                } else {
                        /**
                         * Verify that the all members defined in /etc/gshadow are also
@@ -687,10 +760,10 @@ static void check_sgr_file (int *errors, int *changed)
                if (check_members (sgr->sg_name, sgr->sg_adm,
                                   _("shadow group %s: no administrative user %s\n"),
                                   _("delete administrative member '%s'? "),
-                                  "delete admin `%s' from shadow group `%s'",
+                                  "delete admin '%s' from shadow group '%s'",
                                   errors) == 1) {
-                       *changed = 1;
-                       sge->changed = 1;
+                       *changed = true;
+                       sge->changed = true;
                        __sgr_set_changed ();
                }
 
@@ -700,10 +773,10 @@ static void check_sgr_file (int *errors, int *changed)
                if (check_members (sgr->sg_name, sgr->sg_mem,
                                   _("shadow group %s: no user %s\n"),
                                   _("delete member '%s'? "),
-                                  "delete member `%s' from shadow group `%s'",
+                                  "delete member '%s' from shadow group '%s'",
                                   errors) == 1) {
-                       *changed = 1;
-                       sge->changed = 1;
+                       *changed = true;
+                       sge->changed = true;
                        __sgr_set_changed ();
                }
        }
@@ -716,16 +789,16 @@ static void check_sgr_file (int *errors, int *changed)
 int main (int argc, char **argv)
 {
        int errors = 0;
-       int changed = 0;
+       bool changed = false;
 
        /*
         * Get my name so that I can use it to report errors.
         */
        Prog = Basename (argv[0]);
 
-       setlocale (LC_ALL, "");
-       bindtextdomain (PACKAGE, LOCALEDIR);
-       textdomain (PACKAGE);
+       (void) setlocale (LC_ALL, "");
+       (void) bindtextdomain (PACKAGE, LOCALEDIR);
+       (void) textdomain (PACKAGE);
 
        OPENLOG ("grpck");
 
@@ -737,9 +810,10 @@ int main (int argc, char **argv)
        if (sort_mode) {
                gr_sort ();
 #ifdef SHADOWGRP
-               if (is_shadow)
+               if (is_shadow) {
                        sgr_sort ();
-               changed = 1;
+               }
+               changed = true;
 #endif
        } else {
                check_grp_file (&errors, &changed);
@@ -758,10 +832,14 @@ int main (int argc, char **argv)
        /*
         * Tell the user what we did and exit.
         */
-       if (errors)
-               printf (changed ?
-                       _("%s: the files have been updated\n") :
-                       _("%s: no changes\n"), Prog);
+       if (0 != errors) {
+               if (changed) {
+                       printf (_("%s: the files have been updated\n"), Prog);
+               } else {
+                       printf (_("%s: no changes\n"), Prog);
+               }
+       }
 
-       exit (errors ? E_BAD_ENTRY : E_OKAY);
+       return ((0 != errors) ? E_BAD_ENTRY : E_OKAY);
 }
+