patch for http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=198920

Tomasz Kłoczko <[email protected]> Wed, 26 Jul 2006 22:44:15 +0200
Newsgroups gmane.linux.pld.shadow.general
Message-ID <1153946655.6846.4.camel@kloczek01>
--=-ts0JXOLdulSb/AI+J6i/
Content-Type: text/plain
Content-Transfer-Encoding: 7bit


OK. Patch finished and tested and is ready for review before commit.
Tomorrow I'll be busy so if nothing bad will happen in next day attached
patch will be committed.

Comments ?

kloczek

--=-ts0JXOLdulSb/AI+J6i/
Content-Disposition: attachment; filename=shadow-UID_GID.patch
Content-Type: text/x-patch; name=shadow-UID_GID.patch; charset=UTF-8
Content-Transfer-Encoding: 7bit

Index: src/groupadd.c
===================================================================
RCS file: /cvsroot/shadow/src/groupadd.c,v
retrieving revision 1.54
diff -u -r1.54 groupadd.c
--- src/groupadd.c	14 Jul 2006 19:24:40 -0000	1.54
+++ src/groupadd.c	26 Jul 2006 20:32:44 -0000
@@ -88,6 +88,7 @@
 static void close_files (void);
 static void open_files (void);
 static void fail_exit (int);
+static gid_t get_gid (const char *gidstr);
 
 /*
  * usage - display usage message and exit
@@ -370,6 +371,23 @@
 }
 
 /*
+ * 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 (*errptr || errno == ERANGE || val < 0) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+			 gidstr);
+		exit (E_BAD_ARG);
+	}
+	return val;
+}
+
+/*
  * main - groupadd command
  */
 
@@ -427,16 +445,7 @@
 				break;
 			case 'g':
 				gflg++;
-				if (!isdigit (optarg[0]))
-					usage ();
-
-				group_id = strtoul (optarg, &cp, 10);
-				if (*cp != '\0') {
-					fprintf (stderr,
-						 _("%s: invalid group %s\n"),
-						 Prog, optarg);
-					fail_exit (E_BAD_ARG);
-				}
+				group_id = get_gid (optarg);
 				break;
 			case 'h':
 				usage ();
Index: src/groupmod.c
===================================================================
RCS file: /cvsroot/shadow/src/groupmod.c,v
retrieving revision 1.40
diff -u -r1.40 groupmod.c
--- src/groupmod.c	11 Jul 2006 21:58:47 -0000	1.40
+++ src/groupmod.c	26 Jul 2006 20:32:44 -0000
@@ -90,6 +90,7 @@
 static void process_flags (int, char **);
 static void close_files (void);
 static void open_files (void);
+static gid_t get_gid (const char *gidstr);
 
 /*
  * usage - display usage message and exit
@@ -318,6 +319,23 @@
 }
 
 /*
+ * 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 (*errptr || errno == ERANGE || val < 0) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+			 gidstr);
+		exit (E_BAD_ARG);
+	}
+	return val;
+}
+
+/*
  * process_flags - perform command line argument setting
  *
  *	process_flags() interprets the command line arguments and sets the
@@ -326,7 +344,6 @@
  */
 static void process_flags (int argc, char **argv)
 {
-	char *end;
 
 	{
 		int option_index = 0;
@@ -344,18 +361,12 @@
 			switch (c) {
 			case 'g':
 				gflg++;
-				group_newid = strtoul (optarg, &end, 10);
-				if (*end != '\0') {
-					fprintf (stderr,
-						 _("%s: invalid group %s\n"),
-						 Prog, optarg);
-#ifdef WITH_AUDIT
-					audit_logger (AUDIT_USER_CHAUTHTOK,
-						      Prog, "modifying group",
-						      NULL, group_newid, 0);
+				group_newid = get_gid (optarg);
+#ifdef WITH_AUDIT
+				audit_logger (AUDIT_USER_CHAUTHTOK,
+					      Prog, "modifying group",
+					      NULL, group_newid, 0);
 #endif
-					exit (E_BAD_ARG);
-				}
 				break;
 			case 'n':
 				nflg++;
Index: src/useradd.c
===================================================================
RCS file: /cvsroot/shadow/src/useradd.c,v
retrieving revision 1.99
diff -u -r1.99 useradd.c
--- src/useradd.c	22 Jun 2006 11:30:32 -0000	1.99
+++ src/useradd.c	26 Jul 2006 20:32:44 -0000
@@ -198,42 +198,47 @@
 	exit (code);
 }
 
-static struct group *getgr_nam_gid (const char *name)
+static struct group *getgr_nam_gid (const char *grname)
 {
-	gid_t gid;
-	char *ep;
-
-	gid = strtoul (name, &ep, 10);
-	if (*name != '\0' && *ep == '\0')	/* valid numeric GID */
-		return getgrgid (gid);
+	long gid;
+	char *errptr;
 
-	return getgrnam (name);
+	gid = strtol (grname, &errptr, 10);
+	if (*errptr || errno == ERANGE || gid < 0) {
+		fprintf (stderr,
+			 _("%s: invalid numeric argument '%s'\n"), Prog, grname);
+		exit (E_BAD_ARG);
+	}
+	return getgrnam (grname);
 }
 
-static long get_number (const char *cp)
+static long get_number (const char *numstr)
 {
 	long val;
-	char *ep;
-
-	val = strtol (cp, &ep, 10);
-	if (*cp != '\0' && *ep == '\0')	/* valid number */
-		return val;
+	char *errptr;
 
-	fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, cp);
-	exit (E_BAD_ARG);
+	val = strtol (numstr, &errptr, 10);
+	if (*errptr || errno == ERANGE) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+			 numstr);
+		exit (E_BAD_ARG);
+	}
+	return val;
 }
 
-static uid_t get_uid (const char *cp)
+static uid_t get_uid (const char *uidstr)
 {
-	uid_t val;
-	char *ep;
-
-	val = strtoul (cp, &ep, 10);
-	if (*cp != '\0' && *ep == '\0')	/* valid number */
-		return val;
+	long val;
+	char *errptr;
 
-	fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, cp);
-	exit (E_BAD_ARG);
+	val = strtol (uidstr, &errptr, 10);
+	if (*errptr || errno == ERANGE || val < 0) {
+		fprintf (stderr,
+			 _("%s: invalid numeric argument '%s'\n"), Prog,
+			 uidstr);
+		exit (E_BAD_ARG);
+	}
+	return val;
 }
 
 #define MATCH(x,y) (strncmp((x),(y),strlen(y)) == 0)
Index: src/usermod.c
===================================================================
RCS file: /cvsroot/shadow/src/usermod.c,v
retrieving revision 1.70
diff -u -r1.70 usermod.c
--- src/usermod.c	12 Jul 2006 14:23:14 -0000	1.70
+++ src/usermod.c	26 Jul 2006 20:32:44 -0000
@@ -68,12 +68,12 @@
 #define E_USAGE		2	/* invalid command syntax */
 #define E_BAD_ARG	3	/* invalid argument to option */
 #define E_UID_IN_USE	4	/* UID already in use (and no -o) */
-/* #define E_BAD_PWFILE     5 *//* passwd file contains errors */
+/* #define E_BAD_PWFILE	5 *//* passwd file contains errors */
 #define E_NOTFOUND	6	/* specified user/group doesn't exist */
 #define E_USER_BUSY	8	/* user to modify is logged in */
 #define E_NAME_IN_USE	9	/* username already in use */
 #define E_GRP_UPDATE	10	/* can't update group file */
-/* #define E_NOSPACE        11 *//* insufficient space to move home dir */
+/* #define E_NOSPACE	11*//* insufficient space to move home dir */
 #define E_HOMEDIR	12	/* unable to complete home dir move */
 #define	VALID(s)	(strcspn (s, ":\n") == strlen (s))
 /*
@@ -160,16 +160,18 @@
  * "56k-family"... ergh.
  * --Pac.
  */
-static struct group *getgr_nam_gid (const char *name)
+static struct group *getgr_nam_gid (const char *grname)
 {
-	gid_t gid;
-	char *ep;
-
-	gid = strtoul (name, &ep, 10);
-	if (*name != '\0' && *ep == '\0')	/* valid numeric GID */
-		return getgrgid (gid);
+	long val;
+	char *errptr;
 
-	return getgrnam (name);
+	val = strtol (grname, &errptr, 10);
+	if (*errptr || errno == ERANGE || val < 0) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+			 grname);
+		exit (E_BAD_ARG);
+	}
+	return getgrnam (grname);
 }
 
 /*
@@ -804,30 +806,32 @@
 	return ret;
 }
 
-static long get_number (const char *cp)
+static long get_number (const char *numstr)
 {
 	long val;
-	char *ep;
-
-	val = strtol (cp, &ep, 10);
-	if (*cp != '\0' && *ep == '\0')	/* valid number */
-		return val;
+	char *errptr;
 
-	fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, cp);
-	exit (E_BAD_ARG);
+	val = strtol (numstr, &errptr, 10);
+	if (*errptr || errno == ERANGE) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+			 numstr);
+		exit (E_BAD_ARG);
+	}
+	return val;
 }
 
-static uid_t get_id (const char *cp)
+static uid_t get_id (const char *uidstr)
 {
-	uid_t val;
-	char *ep;
-
-	val = strtoul (cp, &ep, 10);
-	if (*cp != '\0' && *ep == '\0')	/* valid number */
-		return val;
+	long val;
+	char *errptr;
 
-	fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog, cp);
-	exit (E_BAD_ARG);
+	val = strtol (uidstr, &errptr, 10);
+	if (*errptr || errno == ERANGE || val < 0) {
+		fprintf (stderr, _("%s: invalid numeric argument '%s'\n"), Prog,
+			 uidstr);
+		exit (E_BAD_ARG);
+	}
+	return val;
 }
 
 /*

--=-ts0JXOLdulSb/AI+J6i/
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline