Re: Determine next UID number

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



On Wed, Oct 13, 2010 at 17:16, Spiro Harvey <spiro@xxxxxxxxxxxxxx> wrote:
John Kennedy <skebi69@xxxxxxxxx> wrote:
> This also does not tell me how useradd knows that on this system at
> this time the highest UID assigned to a user is 20015.

From the source's mouth (this is from useradd.c in the shadow-utils package):

/*
 * find_new_uid - find the next available UID
 *
 *      find_new_uid() locates the next highest unused UID in the password
 *      file, or checks the given user ID against the existing ones for
 *      uniqueness.
 */
static void find_new_uid (void)
{
       const struct passwd *pwd;
       uid_t uid_min, uid_max;

       uid_min = getdef_unum ("UID_MIN", 1000);
       uid_max = getdef_unum ("UID_MAX", 60000);

       /*
        * Start with some UID value if the user didn't provide us with
        * one already.
        */
       if (!uflg)
               user_id = uid_min;

       /*
        * Search the entire password file, either looking for this
        * UID (if the user specified one with -u) or looking for the
        * largest unused value.
        */
#ifdef NO_GETPWENT
       pw_rewind ();
       while ((pwd = pw_next ())) {
#else                           /* using getpwent() we can check against NIS users etc. */
       setpwent ();
       while ((pwd = getpwent ())) {
#endif
               if (strcmp (user_name, pwd->pw_name) == 0) {
                       fprintf (stderr, _("%s: name %s is not unique\n"),
                                Prog, user_name);
#ifdef WITH_AUDIT
                       audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
                                     user_name, user_id, 0);
#endif
                       exit (E_NAME_IN_USE);
               }
               if (uflg && user_id == pwd->pw_uid) {
                       fprintf (stderr, _("%s: UID %u is not unique\n"),
                                Prog, (unsigned int) user_id);
#ifdef WITH_AUDIT
                       audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "adding user",
                                     user_name, user_id, 0);
#endif
                       exit (E_UID_IN_USE);
               }
               if (!uflg && 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 (!uflg && user_id == uid_max + 1) {
               for (user_id = uid_min; user_id < uid_max; user_id++) {
#ifdef NO_GETPWENT
                       pw_rewind ();
                       while ((pwd = pw_next ())
                              && pwd->pw_uid != user_id);
                       if (!pwd)
                               break;
#else
                       if (!getpwuid (user_id))
                               break;
#endif
               }
               if (user_id == uid_max) {
                       fprintf (stderr, _("%s: can't get unique UID\n"), Prog);
                       fail_exit (E_UID_IN_USE);
               }
       }
}



--
Spiro Harvey                  Knossos Networks Ltd
021-295-1923                  www.knossos.net.nz

_______________________________________________
CentOS mailing list
CentOS@xxxxxxxxxx
http://lists.centos.org/mailman/listinfo/centos


This looks like what I am talking about. Interesting to see that the program literally does what the code above does (as much as I can tell. I am not a coder)

Thanks Spiro.
John

--
 John Kennedy

_______________________________________________
CentOS mailing list
CentOS@xxxxxxxxxx
http://lists.centos.org/mailman/listinfo/centos

[Index of Archives]     [CentOS]     [CentOS Announce]     [CentOS Development]     [CentOS ARM Devel]     [CentOS Docs]     [CentOS Virtualization]     [Carrier Grade Linux]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Linux USB]
  Powered by Linux