diff -up shadow-4.1.4.1/libmisc/find_new_gid.c.sysacc shadow-4.1.4.1/libmisc/find_new_gid.c --- shadow-4.1.4.1/libmisc/find_new_gid.c.sysacc 2009-07-16 11:51:34.807860808 +0200 +++ shadow-4.1.4.1/libmisc/find_new_gid.c 2009-07-16 14:19:08.678798578 +0200 @@ -52,7 +52,7 @@ int find_new_gid (bool sys_group, /*@null@*/gid_t const *preferred_gid) { const struct group *grp; - gid_t gid_min, gid_max, group_id; + gid_t gid_min, gid_max, group_id, id; bool *used_gids; assert (gid != NULL); @@ -61,7 +61,7 @@ int find_new_gid (bool sys_group, gid_min = (gid_t) getdef_ulong ("GID_MIN", 500UL); gid_max = (gid_t) getdef_ulong ("GID_MAX", 60000UL); } else { - gid_min = (gid_t) getdef_ulong ("SYS_GID_MIN", 1UL); + gid_min = (gid_t) getdef_ulong ("SYS_GID_MIN", 101UL); gid_max = (gid_t) getdef_ulong ("GID_MIN", 500UL) - 1; gid_max = (gid_t) getdef_ulong ("SYS_GID_MAX", (unsigned long) gid_max); } @@ -80,7 +80,6 @@ int find_new_gid (bool sys_group, return 0; } - group_id = gid_min; /* * Search the entire group file, @@ -91,13 +90,28 @@ int find_new_gid (bool sys_group, * some groups were created but the changes were not committed yet. */ if (sys_group ) { - for(group_id = gid_min; group_id<=gid_max; group_id++) { - grp = getgrgid(group_id); - if(grp) + group_id = gid_max; + for(id = gid_max; id>=gid_min; id--) { + grp = getgrgid(id); + if(grp) { + group_id = id - 1; used_gids[grp->gr_gid] = true; + } + } + + gr_rewind (); + while ((grp = gr_next ()) != NULL) { + if ((grp->gr_gid <= group_id) && (grp->gr_gid >= gid_min)) { + group_id = grp->gr_gid - 1; + } + /* create index of used GIDs */ + if (grp->gr_gid <= gid_max) { + used_gids[grp->gr_gid] = true; + } } } else { + group_id = gid_min; setgrent (); while ((grp = getgrent ()) != NULL) { if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) { @@ -109,32 +123,16 @@ int find_new_gid (bool sys_group, } } endgrent (); - } - gr_rewind (); - while ((grp = gr_next ()) != NULL) { - if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) { - group_id = grp->gr_gid + 1; - } - /* create index of used GIDs */ - if (grp->gr_gid <= gid_max) { - used_gids[grp->gr_gid] = true; - } - } - /* find free system account in reverse order */ - if (sys_group) { - for (group_id = gid_max; group_id >= gid_min; group_id--) { - if (false == used_gids[group_id]) { - break; + gr_rewind (); + while ((grp = gr_next ()) != NULL) { + if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) { + group_id = grp->gr_gid + 1; + } + /* create index of used GIDs */ + if (grp->gr_gid <= gid_max) { + used_gids[grp->gr_gid] = true; } - } - if ( group_id < gid_min ) { - fprintf (stderr, - _("%s: Can't get unique GID (no more available GIDs)\n"), - Prog); - SYSLOG ((LOG_WARN, - "no more available GID on the system")); - return -1; } } @@ -143,16 +141,35 @@ int find_new_gid (bool sys_group, * will give us GID_MAX+1 even if not unique. Search for the first * free GID starting with GID_MIN. */ - if (group_id == gid_max + 1) { - for (group_id = gid_min; group_id < gid_max; group_id++) { - if (false == used_gids[group_id]) { - break; + if (sys_group) { + if (group_id == gid_min - 1) { + for (group_id = gid_max; group_id >= gid_min; group_id--) { + if (false == used_gids[group_id]) { + break; + } + } + if ( group_id < gid_min ) { + fprintf (stderr, + _("%s: Can't get unique GID (no more available GIDs)\n"), + Prog); + SYSLOG ((LOG_WARN, + "no more available GID on the system")); + return -1; } } - if (group_id == gid_max) { - fprintf (stderr, _("%s: Can't get unique GID (no more available GIDs)\n"), Prog); - SYSLOG ((LOG_WARN, "no more available GID on the system")); - return -1; + } + else { + if (group_id == gid_max + 1) { + for (group_id = gid_min; group_id < gid_max; group_id++) { + if (false == used_gids[group_id]) { + break; + } + } + if (group_id == gid_max) { + fprintf (stderr, _("%s: Can't get unique GID (no more available GIDs)\n"), Prog); + SYSLOG ((LOG_WARN, "no more available GID on the system")); + return -1; + } } } diff -up shadow-4.1.4.1/libmisc/find_new_uid.c.sysacc shadow-4.1.4.1/libmisc/find_new_uid.c --- shadow-4.1.4.1/libmisc/find_new_uid.c.sysacc 2009-07-16 11:51:34.807860808 +0200 +++ shadow-4.1.4.1/libmisc/find_new_uid.c 2009-07-16 14:13:38.120798526 +0200 @@ -52,7 +52,7 @@ int find_new_uid (bool sys_user, /*@null@*/uid_t const *preferred_uid) { const struct passwd *pwd; - uid_t uid_min, uid_max, user_id; + uid_t uid_min, uid_max, user_id, id; bool *used_uids; assert (uid != NULL); @@ -61,7 +61,7 @@ int find_new_uid (bool sys_user, uid_min = (uid_t) getdef_ulong ("UID_MIN", 500UL); uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL); } else { - uid_min = (uid_t) getdef_ulong ("SYS_UID_MIN", 1UL); + uid_min = (uid_t) getdef_ulong ("SYS_UID_MIN", 101UL); uid_max = (uid_t) getdef_ulong ("UID_MIN", 500UL) - 1; uid_max = (uid_t) getdef_ulong ("SYS_UID_MAX", (unsigned long) uid_max); } @@ -81,8 +81,6 @@ int find_new_uid (bool sys_user, } - user_id = uid_min; - /* * Search the entire password file, * looking for the largest unused value. @@ -91,15 +89,30 @@ int find_new_uid (bool sys_user, * but we also check the local database (pw_rewind/pw_next) in case * some users were created but the changes were not committed yet. */ - /* speed up sys users look up on LDAP boxes */ if (sys_user) { - for (user_id = uid_min; user_id<=uid_max; user_id++) { - pwd = getpwuid(user_id); - if(pwd) + user_id = uid_max; + for (id = uid_max; id>=uid_min; id--) { + pwd = getpwuid(id); + if(pwd) { + user_id = id - 1; used_uids[user_id] = true; + } } + + pw_rewind (); + while ((pwd = pw_next ()) != NULL) { + if ((pwd->pw_uid <= user_id) && (pwd->pw_uid >= uid_min)) { + user_id = pwd->pw_uid - 1; + } + /* create index of used UIDs */ + if (pwd->pw_uid <= uid_max) { + used_uids[pwd->pw_uid] = true; + } + } + } else { + user_id = uid_min; setpwent (); while ((pwd = getpwent ()) != NULL) { if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) { @@ -111,51 +124,55 @@ int find_new_uid (bool sys_user, } } endpwent (); - } - pw_rewind (); - while ((pwd = pw_next ()) != NULL) { - if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) { - user_id = pwd->pw_uid + 1; - } - /* create index of used UIDs */ - if (pwd->pw_uid <= uid_max) { - used_uids[pwd->pw_uid] = true; - } - } - - /* find free system account in reverse order */ - if (sys_user) { - for (user_id = uid_max; user_id >= uid_min; user_id--) { - if (false == used_uids[user_id]) { - break; + pw_rewind (); + while ((pwd = pw_next ()) != NULL) { + if ((pwd->pw_uid >= user_id) && (pwd->pw_uid <= uid_max)) { + user_id = pwd->pw_uid + 1; + } + /* create index of used UIDs */ + if (pwd->pw_uid <= uid_max) { + used_uids[pwd->pw_uid] = true; } - } - if (user_id < uid_min ) { - fprintf (stderr, - _("%s: Can't get unique system UID (no more available UIDs)\n"), - Prog); - SYSLOG ((LOG_WARN, - "no more available UID on the system")); - return -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. */ - if (user_id == uid_max + 1) { - for (user_id = uid_min; user_id < uid_max; user_id++) { - if (false == used_uids[user_id]) { - break; + if (sys_user) { + if (user_id == uid_min - 1) { + for (user_id = uid_max; user_id >= uid_min; user_id--) { + if (false == used_uids[user_id]) { + break; + } + } + if (user_id < uid_min ) { + fprintf (stderr, + _("%s: Can't get unique system UID (no more available UIDs)\n"), + Prog); + SYSLOG ((LOG_WARN, + "no more available UID on the system")); + return -1; } } - if (user_id == uid_max) { - fprintf (stderr, _("%s: Can't get unique UID (no more available UIDs)\n"), Prog); - SYSLOG ((LOG_WARN, "no more available UID on the system")); - return -1; + } + else { + if (user_id == uid_max + 1) { + for (user_id = uid_min; user_id < uid_max; user_id++) { + if (false == used_uids[user_id]) { + break; + } + } + if (user_id == uid_max) { + fprintf (stderr, _("%s: Can't get unique UID (no more available UIDs)\n"), + Prog); + SYSLOG ((LOG_WARN, "no more available UID on the system")); + return -1; + } } }