]> granicus.if.org Git - shadow/commitdiff
2009-07-18 Peter Vrabec <pvrabec@redhat.com>
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sat, 18 Jul 2009 00:35:35 +0000 (00:35 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sat, 18 Jul 2009 00:35:35 +0000 (00:35 +0000)
* NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Since
system accounts are allocated from SYS_?ID_MIN to SYS_?ID_MAX in
reverse order, accounts are packed close to SYS_?ID_MAX if
SYS_?ID_MIN is already used but there are still dome gaps.

ChangeLog
NEWS
libmisc/find_new_gid.c
libmisc/find_new_uid.c

index a29a2e2f62f9e9aa8f7c4597a20ba32836eeaf11..cda9709a1c5496d44aff068fed3a3226e49be561 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,10 @@
        getpwent / getgrent for system accounts. Trying the low-IDs with
        getpwuid / getgrgid should be more efficient on LDAP configured
        systems with many accounts.
+       * NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Since
+       system accounts are allocated from SYS_?ID_MIN to SYS_?ID_MAX in
+       reverse order, accounts are packed close to SYS_?ID_MAX if
+       SYS_?ID_MIN is already used but there are still dome gaps.
 
 2009-07-05  Piarres Beobide  <pi+debian@beobide.net>
 
diff --git a/NEWS b/NEWS
index 170fe29b6d1161dc129f363aa5c6aa04baf1e7a3..f489dd403f294c50124ee151ba157ce0cd5d13cd 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,9 @@ shadow-4.1.4.1 -> shadow-4.1.4.2                                                UNRELEASED
 - addition of system users or groups
   * Speed improvement. This should be noticeable in case of LDAP configured
     systems. This should impact useradd, groupadd, and newusers
+  * Since system accounts are allocated from SYS_?ID_MIN to SYS_?ID_MAX in
+    reverse order, accounts are packed close to SYS_?ID_MAX if SYS_?ID_MIN
+    is already used but there are still dome gaps.
 
 - su
   * Preserve the DISPLAY and XAUTHORITY environment variables. This was
index ed72f289097c6d9ce488d6af06ea4fda05b9a6b8..19bc19661333356026d1a2dd1bda1ee83121c35c 100644 (file)
@@ -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", 1000UL);
                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", 1000UL) - 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,
@@ -90,19 +89,33 @@ int find_new_gid (bool sys_group,
         * but we also check the local database (gr_rewind/gr_next) in case
         * some groups were created but the changes were not committed yet.
         */
-       if (sys_group ) {
+       if (sys_group) {
                /* setgrent / getgrent / endgrent can be very slow with
                 * LDAP configurations (and many accounts).
                 * Since there is a limited amount of IDs to be tested
                 * for system accounts, we just check the existence
                 * of IDs with getgrgid.
                 */
-               for (group_id = gid_min; group_id <= gid_max; group_id++) {
-                       if (getgrgid (group_id) != NULL) {
+               group_id = gid_max;
+               for (id = gid_max; id >= gid_min; id--) {
+                       if (getgrgid (id) != NULL) {
+                               group_id = id - 1;
+                               used_gids[id] = 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)) {
@@ -114,32 +127,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;
                }
        }
 
@@ -148,16 +145,36 @@ 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 system 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;
+                       }
                }
        }
 
index 3f3d0a95256d20985f3f21b0ca4ae9ec2b5f2d39..b1a188afd94bff42e8a07d4cf6189d1971b971af 100644 (file)
@@ -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", 1000UL);
                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", 1000UL) - 1;
                uid_max = (uid_t) getdef_ulong ("SYS_UID_MAX", (unsigned long) uid_max);
        }
@@ -80,7 +80,6 @@ int find_new_uid (bool sys_user,
                return 0;
        }
 
-       user_id = uid_min;
 
        /*
         * Search the entire password file,
@@ -97,12 +96,26 @@ int find_new_uid (bool sys_user,
                 * for system accounts, we just check the existence
                 * of IDs with getpwuid.
                 */
-               for (user_id = uid_min; user_id <= uid_max; user_id++) {
-                       if (getpwuid (user_id) != NULL) {
-                               used_uids[user_id] = true;
+               user_id = uid_max;
+               for (id = uid_max; id >= uid_min; id--) {
+                       if (getpwuid (id) != NULL) {
+                               user_id = id - 1;
+                               used_uids[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)) {
@@ -114,32 +127,16 @@ 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;
                }
        }
 
@@ -148,16 +145,36 @@ int find_new_uid (bool sys_user,
         * 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;
+                       }
                }
        }