]> granicus.if.org Git - shadow/commitdiff
* NEWS, src/newusers.c, src/usermod.c, src/useradd.c,
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sun, 8 Mar 2009 20:43:15 +0000 (20:43 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sun, 8 Mar 2009 20:43:15 +0000 (20:43 +0000)
src/groupmod.c, src/groupadd.c: Make sure no user or group are
created with an ID set to -1.

ChangeLog
src/groupadd.c
src/groupmod.c
src/newusers.c
src/useradd.c
src/usermod.c

index dcecd4a682df8795660720d128637e9b3f9afede..43203efe394625b01dda4efa88e391ce83bd790e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,9 @@
        group IDs.
        * NEWS, src/grpck.c, src/pwck.c: Issue a warning if an ID is set
        to -1.
+       * NEWS, src/newusers.c, src/usermod.c, src/useradd.c,
+       src/groupmod.c, src/groupadd.c: Make sure no user or group are
+       created with an ID set to -1.
 
 2009-03-07  Nicolas François  <nicolas.francois@centraliens.net>
 
index 45f5d5b3f25f3cd86019a3fbb6a6c84ca65490ac..b00e3cdc33e36a1ef98e8371cf3a21d5f14273d1 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1991 - 1993, Julianne Frances Haugh
  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
  * Copyright (c) 2000 - 2006, Tomasz Kłoczko
- * Copyright (c) 2007 - 2008, Nicolas François
+ * Copyright (c) 2007 - 2009, Nicolas François
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -98,7 +98,6 @@ static void grp_update (void);
 static void check_new_name (void);
 static void close_files (void);
 static void open_files (void);
-static gid_t get_gid (const char *gidstr);
 static void process_flags (int argc, char **argv);
 static void check_flags (void);
 static void check_perms (void);
@@ -362,23 +361,6 @@ static void open_files (void)
 #endif                         /* SHADOWGRP */
 }
 
-/*
- * get_id - validate and get group ID
- */
-static gid_t get_gid (const char *gidstr)
-{
-       long val;
-       char *errptr;
-
-       val = strtol (gidstr, &errptr, 10);
-       if (('\0' != *errptr) || (errno == ERANGE) || (val < 0)) {
-               fprintf (stderr, _("%s: invalid numeric argument '%s'\n"),
-                        Prog, gidstr);
-               exit (E_BAD_ARG);
-       }
-       return (gid_t) val;
-}
-
 /*
  * process_flags - parse the command line options
  *
@@ -419,7 +401,13 @@ static void process_flags (int argc, char **argv)
                        break;
                case 'g':
                        gflg = true;
-                       group_id = get_gid (optarg);
+                       if (   (get_gid (optarg, &group_id) == 0)
+                           || (group_id == (gid_t)-1)) {
+                               fprintf (stderr,
+                                        _("%s: invalid group ID '%s'\n"),
+                                        Prog, optarg);
+                               exit (E_BAD_ARG);
+                       }
                        break;
                case 'h':
                        usage ();
index 90e7ab0a7f1deb48b99d734798f378e36bc5d666..8a0b2c88dc205f3150d0f86270deb2be1af429cf 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1991 - 1994, Julianne Frances Haugh
  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
  * Copyright (c) 2000 - 2006, Tomasz Kłoczko
- * Copyright (c) 2007 - 2008, Nicolas François
+ * Copyright (c) 2007 - 2009, Nicolas François
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -104,7 +104,6 @@ static void lock_files (void);
 static void prepare_failure_reports (void);
 static void open_files (void);
 static void close_files (void);
-static gid_t get_gid (const char *gidstr);
 static void update_primary_groups (gid_t ogid, gid_t ngid);
 
 /*
@@ -324,24 +323,6 @@ static void check_new_name (void)
        exit (E_BAD_ARG);
 }
 
-/*
- * get_id - validate and get group ID
- */
-static gid_t get_gid (const char *gidstr)
-{
-       long val;
-       char *errptr;
-
-       val = strtol (gidstr, &errptr, 10); /* FIXME: Should be strtoul ? */
-       if (('\0' != *errptr) || (ERANGE == errno) || (val < 0)) {
-               fprintf (stderr,
-                        _("%s: invalid numeric argument '%s'\n"),
-                        Prog, gidstr);
-               exit (E_BAD_ARG);
-       }
-       return (gid_t) val;
-}
-
 /*
  * process_flags - perform command line argument setting
  *
@@ -367,7 +348,13 @@ static void process_flags (int argc, char **argv)
                switch (c) {
                case 'g':
                        gflg = true;
-                       group_newid = get_gid (optarg);
+                       if (   (get_gid (optarg, &group_newid) == 0)
+                           || (group_newid == (gid_t)-1)) {
+                               fprintf (stderr,
+                                        _("%s: invalid group ID '%s'\n"),
+                                        Prog, optarg);
+                               exit (E_BAD_ARG);
+                       }
                        break;
                case 'n':
                        nflg = true;
index 209a4b4e093b2ceb13a3e82131a46c8885a0235b..c2d32a3e48f700c2f1a4eb172b2f3f6e1b0d8292 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1990 - 1993, Julianne Frances Haugh
  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
  * Copyright (c) 2000 - 2006, Tomasz Kłoczko
- * Copyright (c) 2007 - 2008, Nicolas François
+ * Copyright (c) 2007 - 2009, Nicolas François
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -89,7 +89,7 @@ static bool spw_locked = false;
 static void usage (void);
 static void fail_exit (int);
 static int add_group (const char *, const char *, gid_t *, gid_t);
-static int get_uid (const char *, uid_t *);
+static int get_user_id (const char *, uid_t *);
 static int add_user (const char *, uid_t, gid_t);
 static void update_passwd (struct passwd *, const char *);
 static int add_passwd (struct passwd *, const char *);
@@ -193,25 +193,32 @@ static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid)
                 * The GID is a number, which means either this is a brand
                 * new group, or an existing group.
                 */
-               char *endptr;
-               unsigned long int i = strtoul (gid, &endptr, 10);
-               if ((*endptr != '\0') || (ERANGE == errno)) {
+
+               if (get_gid (gid, &grent.gr_gid) == 0) {
                        fprintf (stderr,
-                                _("%s: group ID '%s' is not valid\n"),
+                                _("%s: invalid group ID '%s'\n"),
                                 Prog, gid);
                        return -1;
                }
+
                /* Look in both the system database (getgrgid) and in the
                 * internal database (gr_locate_gid), which may contain
                 * uncommitted changes */
-               if (   (getgrgid ((gid_t) i) != NULL)
-                   || (gr_locate_gid ((gid_t) i) != NULL)) {
+               if (   (getgrgid ((gid_t) grent.gr_gid) != NULL)
+                   || (gr_locate_gid ((gid_t) grent.gr_gid) != NULL)) {
                        /* The user will use this ID for her
                         * primary group */
-                       *ngid = (gid_t) i;
+                       *ngid = (gid_t) grent.gr_gid;
                        return 0;
                }
-               grent.gr_gid = (gid_t) i;
+
+               /* Do not create groups with GID == (gid_t)-1 */
+               if (grent.gr_gid == (gid_t)-1) {
+                       fprintf (stderr,
+                                _("%s: invalid group ID '%s'\n"),
+                                Prog, gid);
+                       return -1;
+               }
        } else {
                /* The gid parameter can be "" or a name which is not
                 * already the name of an existing group.
@@ -282,22 +289,19 @@ static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid)
        return 0;
 }
 
-static int get_uid (const char *uid, uid_t *nuid) {
+static int get_user_id (const char *uid, uid_t *nuid) {
 
        /*
         * The first guess for the UID is either the numerical UID that the
         * caller provided, or the next available UID.
         */
        if (isdigit (uid[0])) {
-               char *endptr;
-               unsigned long int i = strtoul (uid, &endptr, 10);
-               if (('\0' != *endptr) || (ERANGE == errno)) {
+               if ((get_uid (uid, nuid) == 0) || (*nuid == (uid_t)-1)) {
                        fprintf (stderr,
-                                _("%s: user ID '%s' is not valid\n"),
+                                _("%s: invalid user ID '%s'\n"),
                                 Prog, uid);
                        return -1;
                }
-               *nuid = (uid_t) i;
        } else {
                if ('\0' != uid[0]) {
                        const struct passwd *pwd;
@@ -824,7 +828,7 @@ int main (int argc, char **argv)
                }
 
                if (   (NULL == pw)
-                   && (get_uid (fields[2], &uid) != 0)) {
+                   && (get_user_id (fields[2], &uid) != 0)) {
                        fprintf (stderr,
                                 _("%s: line %d: can't create user\n"),
                                 Prog, line);
index a8a7b32e8e58bf7793fa589f4e6191099253533b..9753e3575b111aca5b17ebb7ae94dc133fcfdbeb 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1991 - 1994, Julianne Frances Haugh
  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
  * Copyright (c) 2000 - 2006, Tomasz Kłoczko
- * Copyright (c) 2007 - 2008, Nicolas François
+ * Copyright (c) 2007 - 2009, Nicolas François
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -171,7 +171,6 @@ static bool home_added = false;
 static void fail_exit (int);
 static struct group *getgr_nam_gid (const char *);
 static long get_number (const char *);
-static uid_t get_uid (const char *);
 static void get_defaults (void);
 static void show_defaults (void);
 static int set_defaults (void);
@@ -268,11 +267,15 @@ static void fail_exit (int code)
 
 static struct group *getgr_nam_gid (const char *grname)
 {
-       long gid;
-       char *errptr;
-
-       gid = strtol (grname, &errptr, 10);
-       if (*grname != '\0' && *errptr == '\0' && errno != ERANGE && gid >= 0) {
+       long long int gid;
+       char *endptr;
+
+       errno = 0;
+       gid = strtoll (grname, &errptr, 10);
+       if (   ('\0' != *grname)
+           && ('\0' == *endptr)
+           && (ERANGE != errno)
+           && (gid == (gid_t)gid)) {
                return xgetgrgid ((gid_t) gid);
        }
        return xgetgrnam (grname);
@@ -284,27 +287,13 @@ static long get_number (const char *numstr)
        char *errptr;
 
        val = strtol (numstr, &errptr, 10);
-       if (('\0' != *errptr) || (ERANGE == errno)) {
-               fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
-                        numstr);
-               exit (E_BAD_ARG);
-       }
-       return val;
-}
-
-static uid_t get_uid (const char *uidstr)
-{
-       long val;
-       char *errptr;
-
-       val = strtol (uidstr, &errptr, 10);
-       if (('\0' != *errptr) || (ERANGE == errno) || (val < 0)) {
+       if (('\0' == *numstr) || ('\0' != *errptr) || (ERANGE == errno)) {
                fprintf (stderr,
-                        _("%s: invalid numeric argument '%s'\n"), Prog,
-                        uidstr);
+                        _("%s: invalid numeric argument '%s'\n"),
+                        Prog, numstr);
                exit (E_BAD_ARG);
        }
-       return (uid_t) val;
+       return val;
 }
 
 #define MATCH(x,y) (strncmp((x),(y),strlen(y)) == 0)
@@ -352,27 +341,14 @@ static void get_defaults (void)
                 * Primary GROUP identifier
                 */
                if (MATCH (buf, DGROUP)) {
-                       unsigned int val = (unsigned int) strtoul (cp, &ep, 10);
-                       const struct group *grp;
-
-                       if (*cp != '\0' && *ep == '\0') { /* valid number */
-                               def_group = val;
-                               /* local, no need for xgetgrgid */
-                               grp = getgrgid (def_group);
-                               if (NULL != grp) {
-                                       def_gname = xstrdup (grp->gr_name);
-                               } else {
-                                       fprintf (stderr,
-                                                _("%s: GID '%s' does not exist\n"),
-                                                Prog, cp);
-                               }
-                       /* local, no need for xgetgrnam */
-                       } else if ((grp = getgrnam (cp)) != NULL) {
-                               def_group = grp->gr_gid;
-                               def_gname = xstrdup (cp);
-                       } else {
+                       const struct group *grp = getgr_nam_gid (cp);
+                       if (NULL == grp) {
                                fprintf (stderr,
-                                        _("%s: group '%s' does not exist\n"), Prog, cp);
+                                        _("%s: group '%s' does not exist\n"),
+                                        Prog, cp);
+                       } else {
+                               def_group = grp->gr_gid;
+                               def_gname = xstrdup (grp->gr_name);
                        }
                }
 
@@ -396,7 +372,10 @@ static void get_defaults (void)
                else if (MATCH (buf, INACT)) {
                        long val = strtol (cp, &ep, 10);
 
-                       if (('\0' != *cp) || (ERANGE == errno)) {
+                       if (   ('\0' != *cp)
+                           && ('\0' == *ep)
+                           && (ERANGE != errno)
+                           && (val >= 0)) {
                                def_inactive = val;
                        } else {
                                def_inactive = -1;
@@ -1173,7 +1152,13 @@ static void process_flags (int argc, char **argv)
                                sflg = true;
                                break;
                        case 'u':
-                               user_id = get_uid (optarg);
+                               if (   (get_uid (optarg, &user_id) == 0)
+                                   || (user_id == (gid_t)-1)) {
+                                       fprintf (stderr,
+                                                _("%s: invalid user ID '%s'\n"),
+                                                Prog, optarg);
+                                       exit (E_BAD_ARG);
+                               }
                                uflg = true;
                                break;
                        case 'U':
index d5bb3ba435e34dc457aa06881e217869bac31d2e..76c3b4f6e7749e049e846a3e6858fdb6ec2a097c 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1991 - 1994, Julianne Frances Haugh
  * Copyright (c) 1996 - 2000, Marek Michałkiewicz
  * Copyright (c) 2000 - 2006, Tomasz Kłoczko
- * Copyright (c) 2007 - 2008, Nicolas François
+ * Copyright (c) 2007 - 2009, Nicolas François
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -154,7 +154,6 @@ static void update_gshadow (void);
 static void grp_update (void);
 
 static long get_number (const char *);
-static uid_t get_id (const char *);
 static void process_flags (int, char **);
 static void close_files (void);
 static void open_files (void);
@@ -193,11 +192,15 @@ static void date_to_str (char *buf, size_t maxsize,
  */
 static struct group *getgr_nam_gid (const char *grname)
 {
-       long val;
-       char *errptr;
-
-       val = strtol (grname, &errptr, 10);
-       if (*grname != '\0' && *errptr == '\0' && errno != ERANGE && val >= 0) {
+       long long int val;
+       char *endptr;
+
+       errno = 0;
+       val = strtoll (grname, &errptr, 10);
+       if (   ('\0' != *grname)
+           && ('\0' == *endptr)
+           && (ERANGE != errno)
+           && (val == (gid_t)val)) {
                return xgetgrgid ((gid_t) val);
        }
        return xgetgrnam (grname);
@@ -795,20 +798,6 @@ static long get_number (const char *numstr)
        return val;
 }
 
-static uid_t get_id (const char *uidstr)
-{
-       long val;
-       char *errptr;
-
-       val = strtol (uidstr, &errptr, 10);
-       if (('\0' != *errptr) || (ERANGE == errno) || (val < 0)) {
-               fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
-                        uidstr);
-               exit (E_BAD_ARG);
-       }
-       return (uid_t) val;
-}
-
 /*
  * process_flags - perform command line argument setting
  *
@@ -1003,7 +992,13 @@ static void process_flags (int argc, char **argv)
                                sflg = true;
                                break;
                        case 'u':
-                               user_newid = get_id (optarg);
+                               if (   (get_uid (optarg, &user_newid) ==0)
+                                   || (user_newid == (uid_t)-1)) {
+                                       fprintf (stderr,
+                                                _("%s: invalid user ID '%s'\n"),
+                                                Prog, optarg);
+                                       exit (E_BAD_ARG);
+                               }
                                uflg = true;
                                break;
                        case 'U':