When I used Solaris years and years ago there was a command that would be able to tell you the next available non-system UID number for the system (can't remember what it is now, I have slept since then...). Is there an equivalent in CentOS? Thanks, John
On Wed, Oct 13, 2010 at 16:09, Joseph L. Casale jcasale@activenetwerx.comwrote:
Is there an equivalent in CentOS?
cat /etc/passwd |cut -d ":" -f 3 |sort -n
;)
I am more looking at what the system thinks is the next UID. Does the useradd command use this when it assigns the next UID? John
On Wed, Oct 13, 2010 at 4:15 PM, John Kennedy skebi69@gmail.com wrote:
I am more looking at what the system thinks is the next UID. Does the useradd command use this when it assigns the next UID?
what about ...
# useradd nextid; id -u nextid; userdel nextid
-Bob
On Wed, 2010-10-13 at 20:09 +0000, Joseph L. Casale wrote:
Is there an equivalent in CentOS?
cat /etc/passwd |cut -d ":" -f 3 |sort -n NEXTUID=`expr $LASTUID + 1`
;) _______________________________________________ CentOS mailing list CentOS@centos.org http://lists.centos.org/mailman/listinfo/centos
LASTUID=`cat /etc/passwd |grep -v nologin|cut -d ":" -f 3 |sort -n | tail -1`; NEXTUID=`expr $LASTUID + 1`; echo $NEXTUID
On 10/13/2010 4:22 PM, Terry Polzin wrote:
On Wed, 2010-10-13 at 20:09 +0000, Joseph L. Casale wrote:
Is there an equivalent in CentOS?
cat /etc/passwd |cut -d ":" -f 3 |sort -n NEXTUID=`expr $LASTUID + 1`
;)
LASTUID=`cat /etc/passwd |grep -v nologin|cut -d ":" -f 3 |sort -n | tail -1`; NEXTUID=`expr $LASTUID + 1`; echo $NEXTUID
That assumes the highest UID number has a login shell...
On Wed, Oct 13, 2010 at 10:40 PM, Bowie Bailey Bowie_Bailey@buc.com wrote:
On 10/13/2010 4:22 PM, Terry Polzin wrote:
On Wed, 2010-10-13 at 20:09 +0000, Joseph L. Casale wrote:
Is there an equivalent in CentOS?
cat /etc/passwd |cut -d ":" -f 3 |sort -n NEXTUID=`expr $LASTUID + 1`
;)
LASTUID=`cat /etc/passwd |grep -v nologin|cut -d ":" -f 3 |sort -n | tail -1`; NEXTUID=`expr $LASTUID + 1`; echo $NEXTUID
That assumes the highest UID number has a login shell...
-- Bowie _______________________________________________
which is generally the case...
----- Original Message ----- | > > That assumes the highest UID number has a login shell... | | > which is generally the case... | > | > | Exactly, without excluding those who have a shell of nologin the last | uid on my machine is nfsnobody(65534), I don't believe that a UID can | be | greater than that. | | _______________________________________________ | CentOS mailing list | CentOS@centos.org | http://lists.centos.org/mailman/listinfo/centos
Only if authenticating against /etc/passwd. If authenticating against Kerberos, LDAP, or some other method this is not the case.
-- James A. Peltier Systems Analyst (FASNet), VIVARIUM Technical Director Simon Fraser University - Burnaby Campus Phone : 778-782-6573 Fax : 778-782-3045 E-Mail : jpeltier@sfu.ca Website : http://www.fas.sfu.ca | http://vivarium.cs.sfu.ca MSN : subatomic_spam@hotmail.com
Does your OS has a man 8 lart? http://www.xinu.nl/unix/humour/asr-manpages/lart.html
On Wed, 13 Oct 2010, James A. Peltier wrote:
| > > That assumes the highest UID number has a login shell... | | > which is generally the case... | > | | Exactly, without excluding those who have a shell of nologin the | last uid on my machine is nfsnobody(65534), I don't believe that a | UID can be greater than that. | Only if authenticating against /etc/passwd. If authenticating against Kerberos, LDAP, or some other method this is not the case.
Here's the code I use to figure out next-available [GU]IDs:
# ----- %< ----- # figure out the highest UID and GID currently in production, but # rule out really high numbers (greater than 8000) which are typically # assigned to pseudo accounts like "nobody." # AWKTEST='END { print HUID } { if (($3 > HUID) && ($3 < 8000)) HUID = $3}' HUID=$(/usr/bin/getent passwd | /bin/gawk -F: "$AWKTEST") HGID=$(/usr/bin/getent group | /bin/gawk -F: "$AWKTEST") # # increment those UID and GID numbers by 1 for use with the # new account # let HUID=$HUID+1 let HGID=$HGID+1 # ----- %< -----
The 8000 high-end number is arbitrary; it works in our environment...
On 10/13/2010 4:42 PM, Rudi Ahlers wrote:
On Wed, Oct 13, 2010 at 10:40 PM, Bowie Bailey Bowie_Bailey@buc.com wrote:
On 10/13/2010 4:22 PM, Terry Polzin wrote:
LASTUID=`cat /etc/passwd |grep -v nologin|cut -d ":" -f 3 |sort -n | tail -1`; NEXTUID=`expr $LASTUID + 1`; echo $NEXTUID
That assumes the highest UID number has a login shell...
which is generally the case...
Not on at least two of my systems.
The best solution would be to pull the UID generation code from the useradd program to create something that will simply spit out the next UID using the same algorithm.
On Wed, Oct 13, 2010 at 16:40, Bowie Bailey Bowie_Bailey@buc.com wrote:
On 10/13/2010 4:22 PM, Terry Polzin wrote:
On Wed, 2010-10-13 at 20:09 +0000, Joseph L. Casale wrote:
Is there an equivalent in CentOS?
cat /etc/passwd |cut -d ":" -f 3 |sort -n NEXTUID=`expr $LASTUID + 1`
;)
LASTUID=`cat /etc/passwd |grep -v nologin|cut -d ":" -f 3 |sort -n | tail -1`; NEXTUID=`expr $LASTUID + 1`; echo $NEXTUID
That assumes the highest UID number has a login shell...
-- Bowie
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. It will assign 20016 to the next user even though some dim bulb gave a use a UID of 4294967294 (how the hell that user can log in with a UID out of range is beyond me unless it gets truncated)... I have been able to use things like these 2 examples (cat /etc/passwd | cut -d: -f3 | sort -n | tail -2 | head -1 in this case) but I want to get the next UID from the system not by parsing /etc/passwd John
John Kennedy skebi69@gmail.com 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); } } }
On Wed, Oct 13, 2010 at 17:16, Spiro Harvey spiro@knossos.net.nz wrote:
John Kennedy skebi69@gmail.com 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@centos.org 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
On Wed, Oct 13, 2010 at 04:47:45PM -0400, John Kennedy wrote:
the next user even though some dim bulb gave a use a UID of 4294967294 (how the hell that user can log in with a UID out of range is beyond me unless it gets truncated)...
Who says 4294967294 is out of range?
# grep tstuser /etc/passwd tstuser:x:4294967294:10::/:/bin/bash # su - tstuser -bash-3.2$ id -a uid=4294967294(tstuser) gid=10(wheel) groups=10(wheel) -bash-3.2$ touch /tmp/x0 -bash-3.2$ stat /tmp/x0 File: `/tmp/x0' Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 806h/2054d Inode: 196620 Links: 1 Access: (0644/-rw-r--r--) Uid: (4294967294/ tstuser) Gid: ( 10/ wheel) Access: 2010-10-13 18:15:28.000000000 -0400 Modify: 2010-10-13 18:15:28.000000000 -0400 Change: 2010-10-13 18:15:28.000000000 -0400
Looks good to me! The file just created has an ownership with the right uid.
On 10/13/2010 5:24 PM, Stephen Harris wrote:
On Wed, Oct 13, 2010 at 04:47:45PM -0400, John Kennedy wrote:
the next user even though some dim bulb gave a use a UID of 4294967294 (how the hell that user can log in with a UID out of range is beyond me unless it gets truncated)...
Who says 4294967294 is out of range?
# grep tstuser /etc/passwd tstuser:x:4294967294:10::/:/bin/bash # su - tstuser -bash-3.2$ id -a uid=4294967294(tstuser) gid=10(wheel) groups=10(wheel) -bash-3.2$ touch /tmp/x0 -bash-3.2$ stat /tmp/x0 File: `/tmp/x0' Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: 806h/2054d Inode: 196620 Links: 1 Access: (0644/-rw-r--r--) Uid: (4294967294/ tstuser) Gid: ( 10/ wheel) Access: 2010-10-13 18:15:28.000000000 -0400 Modify: 2010-10-13 18:15:28.000000000 -0400 Change: 2010-10-13 18:15:28.000000000 -0400
Looks good to me! The file just created has an ownership with the right uid.
64-bit, I presume? Does your /var/log/lastlog look pretty big after that person logs in or did that get fixed?
On Wed, Oct 13, 2010 at 05:45:15PM -0500, Les Mikesell wrote:
On 10/13/2010 5:24 PM, Stephen Harris wrote:
On Wed, Oct 13, 2010 at 04:47:45PM -0400, John Kennedy wrote:
the next user even though some dim bulb gave a use a UID of 4294967294 (how the hell that user can log in with a UID out of range is beyond me unless it gets truncated)...
Who says 4294967294 is out of range?
64-bit, I presume? Does your /var/log/lastlog look pretty big after
Nope; 32bit CentOS 5.5
that person logs in or did that get fixed?
lastlog is a sparse file. How it looks and how big it is are two different things.
I'm not saying there aren't problems with uids that high (pwconv, for example, truncates to 2^32-1) but the number _is_ in range.
I've seen this before on systems where "nobody" was represented as "-2" (eg from NIS maps on old SunOS 4 systems) rather than 65534. When those maps were transferred to systems with 32bit uids then they became 4294967294. Funky stuff :-)
Heh, the kernel Documentation/highuid.txt file discussing 32bit uids is dated January 2000. I guess it's a little out of date, now :-)
On 10/13/2010 6:01 PM, Stephen Harris wrote:
Who says 4294967294 is out of range?
64-bit, I presume? Does your /var/log/lastlog look pretty big after
Nope; 32bit CentOS 5.5
that person logs in or did that get fixed?
lastlog is a sparse file. How it looks and how big it is are two different things.
And how long it takes to copy if you back the system up is a 3rd thing. But if you've truncated to 32 bits it might be tolerable anyway. On 64-bit centos3, nfsnobody made that somewhat awkward, at least in the early versions - it might have been fixed eventually.
On Wed, Oct 13, 2010 at 06:16:26PM -0500, Les Mikesell wrote:
On 10/13/2010 6:01 PM, Stephen Harris wrote:
lastlog is a sparse file. How it looks and how big it is are two different things.
And how long it takes to copy if you back the system up is a 3rd thing.
Get better backup software that understands sparse files. You'll have the same problem with dbm files and similar.
But if you've truncated to 32 bits it might be tolerable anyway. On
The bit-size of the OS is irrelevant to the maximum file size. Otherwise we'd still be stuck at 2Gb (maybe 4Gb) files on 32bit systems.
64-bit centos3, nfsnobody made that somewhat awkward, at least in the early versions - it might have been fixed eventually.
People logged in as nfsnobody? That's the only way lastlog should get that entry. Then you have bigger problems...
On 10/13/10 6:42 PM, Stephen Harris wrote:
On Wed, Oct 13, 2010 at 06:16:26PM -0500, Les Mikesell wrote:
On 10/13/2010 6:01 PM, Stephen Harris wrote:
lastlog is a sparse file. How it looks and how big it is are two different things.
And how long it takes to copy if you back the system up is a 3rd thing.
Get better backup software that understands sparse files. You'll have the same problem with dbm files and similar.
But if you've truncated to 32 bits it might be tolerable anyway. On
The bit-size of the OS is irrelevant to the maximum file size. Otherwise we'd still be stuck at 2Gb (maybe 4Gb) files on 32bit systems.
It isn't related to the OS maximum file size, it has to do with what happens when you take -1 as an unsigned integer: nfsnobody:x:4294967294:4294967294:Anonymous NFS User:/var/lib/nfs:/sbin/nologin and then use that as the key into a sparse file the way lastlog works. Seems to be fixed now though, I don't see the big lastlog on any of the remaining Centos3 boxes I can find.
Bowie Bailey wrote:
On 10/13/2010 4:22 PM, Terry Polzin wrote:
On Wed, 2010-10-13 at 20:09 +0000, Joseph L. Casale wrote:
Is there an equivalent in CentOS?
cat /etc/passwd |cut -d ":" -f 3 |sort -n NEXTUID=`expr $LASTUID + 1`
;)
LASTUID=`cat /etc/passwd |grep -v nologin|cut -d ":" -f 3 |sort -n | tail -1`; NEXTUID=`expr $LASTUID + 1`; echo $NEXTUID
That assumes the highest UID number has a login shell...
And that there's not nobody with a UID of 65k
mark