]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
usermod: check only local groups with -G option
authorikerexxe <ipedrosa@redhat.com>
Fri, 27 Mar 2020 13:23:02 +0000 (14:23 +0100)
committerikerexxe <ipedrosa@redhat.com>
Mon, 30 Mar 2020 11:07:32 +0000 (13:07 +0200)
Check only local groups when adding new supplementary groups to a user

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1727236

src/usermod.c

index 05b9871596803b9010dd3cb113785d59e53a3941..ef430296eaabcf539f271f5c8bd78504b956ae1d 100644 (file)
@@ -183,6 +183,7 @@ static bool sub_gid_locked = false;
 static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize,
                          long int date);
 static int get_groups (char *);
+static struct group * get_local_group (char * grp_name);
 static /*@noreturn@*/void usage (int status);
 static void new_pwent (struct passwd *);
 static void new_spent (struct spwd *);
@@ -196,7 +197,9 @@ static void grp_update (void);
 
 static void process_flags (int, char **);
 static void close_files (void);
+static void close_group_files (void);
 static void open_files (void);
+static void open_group_files (void);
 static void usr_update (void);
 static void move_home (void);
 static void update_lastlog (void);
@@ -253,6 +256,11 @@ static int get_groups (char *list)
                return 0;
        }
 
+       /*
+        * Open the group files
+        */
+       open_group_files ();
+
        /*
         * So long as there is some data to be converted, strip off each
         * name and look it up. A mix of numerical and string values for
@@ -272,7 +280,7 @@ static int get_groups (char *list)
                 * Names starting with digits are treated as numerical GID
                 * values, otherwise the string is looked up as is.
                 */
-               grp = prefix_getgr_nam_gid (list);
+               grp = get_local_group (list);
 
                /*
                 * There must be a match, either by GID value or by
@@ -322,6 +330,8 @@ static int get_groups (char *list)
                gr_free ((struct group *)grp);
        } while (NULL != list);
 
+       close_group_files ();
+
        user_groups[ngroups] = (char *) 0;
 
        /*
@@ -334,6 +344,44 @@ static int get_groups (char *list)
        return 0;
 }
 
+/*
+ * get_local_group - checks if a given group name exists locally
+ *
+ *     get_local_group() checks if a given group name exists locally.
+ *     If the name exists the group information is returned, otherwise NULL is
+ *     returned.
+ */
+static struct group * get_local_group(char * grp_name)
+{
+       const struct group *grp;
+       struct group *result_grp = NULL;
+       long long int gid;
+       char *endptr;
+
+       gid = strtoll (grp_name, &endptr, 10);
+       if (   ('\0' != *grp_name)
+               && ('\0' == *endptr)
+               && (ERANGE != errno)
+               && (gid == (gid_t)gid)) {
+               grp = gr_locate_gid ((gid_t) gid);
+       }
+       else {
+               grp = gr_locate(grp_name);
+       }
+
+       if (grp != NULL) {
+               result_grp = __gr_dup (grp);
+               if (NULL == result_grp) {
+                       fprintf (stderr,
+                                       _("%s: Out of memory. Cannot find group '%s'.\n"),
+                                       Prog, grp_name);
+                       fail_exit (E_GRP_UPDATE);
+               }
+       }
+
+       return result_grp;
+}
+
 #ifdef ENABLE_SUBIDS
 struct ulong_range
 {
@@ -1447,50 +1495,7 @@ static void close_files (void)
        }
 
        if (Gflg || lflg) {
-               if (gr_close () == 0) {
-                       fprintf (stderr,
-                                _("%s: failure while writing changes to %s\n"),
-                                Prog, gr_dbname ());
-                       SYSLOG ((LOG_ERR,
-                                "failure while writing changes to %s",
-                                gr_dbname ()));
-                       fail_exit (E_GRP_UPDATE);
-               }
-#ifdef SHADOWGRP
-               if (is_shadow_grp) {
-                       if (sgr_close () == 0) {
-                               fprintf (stderr,
-                                        _("%s: failure while writing changes to %s\n"),
-                                        Prog, sgr_dbname ());
-                               SYSLOG ((LOG_ERR,
-                                        "failure while writing changes to %s",
-                                        sgr_dbname ()));
-                               fail_exit (E_GRP_UPDATE);
-                       }
-               }
-#endif
-#ifdef SHADOWGRP
-               if (is_shadow_grp) {
-                       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
-               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 */
-               }
+               close_group_files ();
        }
 
        if (is_shadow_pwd) {
@@ -1559,6 +1564,60 @@ static void close_files (void)
 #endif
 }
 
+/*
+ * close_group_files - close all of the files that were opened
+ *
+ *     close_group_files() closes all of the files that were opened related
+ *  with groups. This causes any modified entries to be written out.
+ */
+static void close_group_files (void)
+{
+       if (gr_close () == 0) {
+               fprintf (stderr,
+                                       _("%s: failure while writing changes to %s\n"),
+                                       Prog, gr_dbname ());
+               SYSLOG ((LOG_ERR,
+                                       "failure while writing changes to %s",
+                                       gr_dbname ()));
+               fail_exit (E_GRP_UPDATE);
+       }
+#ifdef SHADOWGRP
+       if (is_shadow_grp) {
+               if (sgr_close () == 0) {
+                       fprintf (stderr,
+                                               _("%s: failure while writing changes to %s\n"),
+                                               Prog, sgr_dbname ());
+                       SYSLOG ((LOG_ERR,
+                                               "failure while writing changes to %s",
+                                               sgr_dbname ()));
+                       fail_exit (E_GRP_UPDATE);
+               }
+       }
+#endif
+#ifdef SHADOWGRP
+       if (is_shadow_grp) {
+               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
+       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 */
+       }
+}
+
 /*
  * open_files - lock and open the password files
  *
@@ -1594,38 +1653,7 @@ static void open_files (void)
        }
 
        if (Gflg || lflg) {
-               /*
-                * Lock and open the group file. This will load all of the
-                * group entries.
-                */
-               if (gr_lock () == 0) {
-                       fprintf (stderr,
-                                _("%s: cannot lock %s; try again later.\n"),
-                                Prog, gr_dbname ());
-                       fail_exit (E_GRP_UPDATE);
-               }
-               gr_locked = true;
-               if (gr_open (O_CREAT | O_RDWR) == 0) {
-                       fprintf (stderr,
-                                _("%s: cannot open %s\n"),
-                                Prog, gr_dbname ());
-                       fail_exit (E_GRP_UPDATE);
-               }
-#ifdef SHADOWGRP
-               if (is_shadow_grp && (sgr_lock () == 0)) {
-                       fprintf (stderr,
-                                _("%s: cannot lock %s; try again later.\n"),
-                                Prog, sgr_dbname ());
-                       fail_exit (E_GRP_UPDATE);
-               }
-               sgr_locked = true;
-               if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
-                       fprintf (stderr,
-                                _("%s: cannot open %s\n"),
-                                Prog, sgr_dbname ());
-                       fail_exit (E_GRP_UPDATE);
-               }
-#endif
+               open_group_files ();
        }
 #ifdef ENABLE_SUBIDS
        if (vflg || Vflg) {
@@ -1661,6 +1689,44 @@ static void open_files (void)
 #endif                         /* ENABLE_SUBIDS */
 }
 
+/*
+ * open_group_files - lock and open the group files
+ *
+ *     open_group_files() loads all of the group entries.
+ */
+static void open_group_files (void)
+{
+       if (gr_lock () == 0) {
+               fprintf (stderr,
+                                       _("%s: cannot lock %s; try again later.\n"),
+                                       Prog, gr_dbname ());
+               fail_exit (E_GRP_UPDATE);
+       }
+       gr_locked = true;
+       if (gr_open (O_CREAT | O_RDWR) == 0) {
+               fprintf (stderr,
+                                       _("%s: cannot open %s\n"),
+                                       Prog, gr_dbname ());
+               fail_exit (E_GRP_UPDATE);
+       }
+
+#ifdef SHADOWGRP
+       if (is_shadow_grp && (sgr_lock () == 0)) {
+               fprintf (stderr,
+                                       _("%s: cannot lock %s; try again later.\n"),
+                                       Prog, sgr_dbname ());
+               fail_exit (E_GRP_UPDATE);
+       }
+       sgr_locked = true;
+       if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
+               fprintf (stderr,
+                                       _("%s: cannot open %s\n"),
+                                       Prog, sgr_dbname ());
+               fail_exit (E_GRP_UPDATE);
+       }
+#endif
+}
+
 /*
  * usr_update - create the user entries
  *