Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 237611 Details for
Bug 306241
newusers creates users with negative UID and GID on x86_64
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
This patch should solve negative UIDs and GIDs and also adds some tests of input data
shadow-4.0.17-newusers_negativeUIDs.patch (text/plain), 6.98 KB, created by
Michel Samia
on 2007-10-25 16:35:23 UTC
(
hide
)
Description:
This patch should solve negative UIDs and GIDs and also adds some tests of input data
Filename:
MIME Type:
Creator:
Michel Samia
Created:
2007-10-25 16:35:23 UTC
Size:
6.98 KB
patch
obsolete
>diff -up src/newusers.c.fix src/newusers.c >--- src/newusers.c.fix 2006-03-07 16:50:33.000000000 +0100 >+++ src/newusers.c 2007-10-25 17:54:10.000000000 +0200 >@@ -40,6 +40,7 @@ > #include <sys/types.h> > #include <sys/stat.h> > #include <stdio.h> >+#include <stdbool.h> > #include <pwd.h> > #include <grp.h> > #include <fcntl.h> >@@ -62,11 +63,12 @@ static int is_shadow; > > /* local function prototypes */ > static void usage (void); >-static int add_group (const char *, const char *, gid_t *); >+static int add_group (const char *, const char *, gid_t *, const char * uid); > static int add_user (const char *, const char *, uid_t *, gid_t); > static void update_passwd (struct passwd *, const char *); > static int add_passwd (struct passwd *, const char *); > >+ > /* > * usage - display usage message and exit > */ >@@ -76,16 +78,146 @@ static void usage (void) > exit (1); > } > >+ >+/* >+ * find_new_uid - find the next available UID >+ * >+ * find_new_uid() locates the next highest unused UID in the password >+ * file. >+ */ >+static uid_t find_new_uid (void) >+{ >+ const struct passwd *pwd; >+ uid_t uid_min, uid_max; >+ >+ uid_min = getdef_unum ("UID_MIN", 500); >+ uid_max = getdef_unum ("UID_MAX", 60000); >+ >+ uid_t user_id = uid_min; >+ >+ /* >+ * Search the entire password file looking for the largest unused value. >+ */ >+ >+ pw_rewind (); >+ while ((pwd = pw_next ())) { >+ if (pwd->pw_uid >= user_id) { >+ if (pwd->pw_uid > uid_max) >+ continue; >+ user_id = pwd->pw_uid + 1; >+ } >+ } >+ >+ /* >+ * If a user with UID equal to UID_MAX exists, the above algorithm >+ * will give us UID_MAX+1 even if not unique. Search for the first >+ * free UID starting with UID_MIN (it's O(n*n) but can be avoided >+ * by not having users with UID equal to UID_MAX). --marekm >+ */ >+ if (user_id == uid_max + 1) { >+ for (user_id = uid_min; user_id < uid_max; user_id++) { >+ pw_rewind (); >+ while ((pwd = pw_next ()) >+ && pwd->pw_uid != user_id); >+ if (!pwd) >+ break; >+ } >+ if (user_id == uid_max) { >+ fprintf (stderr, _("%s: can't get unique UID\n"), Prog); >+ return -1; // no free uid >+ } >+ } >+ return user_id; >+} >+ >+ /* >+ * find_new_gid - find the next available GID >+ * >+ * find_new_gid() locates the next highest unused UID in the passwd >+ * file, which is also free in group file to make GID and UID matching. >+ * Return value: >+ * true - success >+ * false - failure >+ */ >+static bool find_new_gid (const char * uid, gid_t *gid) >+{ >+ uid_t user_id; >+ char *endptr; >+ >+ if( (uid == NULL) || !isdigit(uid[0]) ) >+ user_id = find_new_uid(); >+ else { >+ user_id = strtoul(uid, &endptr,10); >+ if(*endptr != '\0') { >+ printf(_("Further characters after the UID number: %s, aborting changes\n"), endptr); >+ >+ return false; >+ } >+ } >+ const struct group *grp; >+ gid_t gid_min, gid_max; >+ char * index; >+ >+ gid_min = getdef_unum ("GID_MIN", 500); >+ gid_max = getdef_unum ("GID_MAX", 60000); >+ >+ /* >+ * Start with some GID value if the user didn't provide us with >+ * one already. >+ */ >+ gid_t user_gid = gid_min; >+ >+ /* >+ * Search the entire group file, looking for the largest unused value. >+ */ >+ gr_rewind (); >+ while ((grp = gr_next ())) >+ { >+ if (grp->gr_gid >= user_gid) { >+ if (grp->gr_gid > gid_max) >+ continue; >+ user_gid = grp->gr_gid + 1; >+ } >+ } >+ >+ /* A quick test gets here: if the UID is available >+ * as a GID, go ahead and use it */ >+ if (!getgrgid (user_id)) { >+ user_gid = user_id; >+ *gid = user_gid; >+ return true; >+ } >+ >+ if (user_gid == gid_max + 1) { >+ for (user_gid = gid_min; user_gid < gid_max; user_gid++) { >+ >+ gr_rewind (); >+ while ((grp = gr_next ()) && grp->gr_gid != user_gid); >+ if (!grp) >+ break; >+ } >+ if (user_gid == gid_max) { >+ fprintf (stderr, >+ "%s: can't get unique gid (run out of GIDs)\n", >+ Prog); >+ exit (4); >+ } >+ } >+ *gid = user_gid; >+ return true; >+} >+ > /* > * add_group - create a new group or add a user to an existing group > */ >-static int add_group (const char *name, const char *gid, gid_t * ngid) >+static int add_group (const char *name, const char *gid, gid_t * ngid, const char * uid) > { > const struct passwd *pwd; > const struct group *grp; > struct group grent; > char *members[2]; >- int i; >+ char *endptr; >+ gid_t i; > > /* > * Start by seeing if the named group already exists. This will be >@@ -114,24 +246,22 @@ static int add_group (const char *name, > * match, unless the GID is already used. > */ > if (gid[0] == '\0') { >- i = 100; >- for (pw_rewind (); (pwd = pw_next ());) { >- if (pwd->pw_uid >= i) >- i = pwd->pw_uid + 1; >- } >- for (gr_rewind (); (grp = gr_next ());) { >- if (grp->gr_gid == i) { >- i = -1; >- break; >- } >- } >- } else if (gid[0] >= '0' && gid[0] <= '9') { >+ /* if an error happened while finding new gid */ >+ if (! find_new_gid(uid, &i)) >+ return EXIT_FAILURE; >+ } >+ else if ( isdigit(gid[0]) ) { > /* > * The GID is a number, which means either this is a brand > * new group, or an existing group. For existing groups I > * just add myself as a member, just like I did earlier. > */ >- i = atoi (gid); >+ i = strtoul(gid, &endptr, 10); >+ if (*endptr != '\0') { >+ printf(_("Further characters after the GID number: %s, aborting changes\n"), endptr); >+ return EXIT_FAILURE; >+ } >+ > for (gr_rewind (); (grp = gr_next ());) > if (grp->gr_gid == i) > goto add_member; >@@ -142,15 +272,10 @@ static int add_group (const char *name, > * figure out what group ID that group name is going to > * have. > */ >- i = -1; >- >- /* >- * If I don't have a group ID by now, I'll go get the next one. >- */ >- if (i == -1) { >- for (i = 100, gr_rewind (); (grp = gr_next ());) >- if (grp->gr_gid >= i) >- i = grp->gr_gid + 1; >+ /* if an error happened while finding new gid */ >+ { >+ if (! find_new_gid(uid, &i)) >+ return EXIT_FAILURE; > } > > /* >@@ -178,22 +303,19 @@ static int add_user (const char *name, c > { > const struct passwd *pwd; > struct passwd pwent; >+ char *endptr; > uid_t i; > >- /* >- * The first guess for the UID is either the numerical UID that the >- * caller provided, or the next available UID. >- */ >- if (uid[0] >= '0' && uid[0] <= '9') { >- i = atoi (uid); >- } else if (uid[0] && (pwd = pw_locate (uid))) { >- i = pwd->pw_uid; >- } else { >- i = 100; >- for (pw_rewind (); (pwd = pw_next ());) >- if (pwd->pw_uid >= i) >- i = pwd->pw_uid + 1; >- } >+ if ( isdigit(uid[0]) ) { >+ i = strtoul(uid,&endptr,10); >+ if (*endptr != '\0') { >+ printf("Further characters after the UID number: %s, aborting changes\n", endptr); >+ return 0; >+ } >+ } else if (uid[0] && (pwd = pw_locate (uid))) { >+ i = pwd->pw_uid; >+ } else >+ i = find_new_uid(); > > /* > * I don't want to fill in the entire password structure members >@@ -421,7 +543,7 @@ int main (int argc, char **argv) > * will be made up. > */ > if (!(pw = pw_locate (fields[0])) && >- add_group (fields[0], fields[3], &gid)) { >+ add_group (fields[0], fields[3], &gid, fields[2])) { > fprintf (stderr, > _("%s: line %d: can't create GID\n"), > Prog, line);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 306241
: 237611