On Wed, Oct 13, 2010 at 17:16, Spiro Harvey <spiro@xxxxxxxxxxxxxx> wrote:
John Kennedy <skebi69@xxxxxxxxx> wrote:From the source's mouth (this is from useradd.c in the shadow-utils package):
> 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.
/*
* 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