[NBLUG/talk] Integrating usernames/passwords
Justin Thiessen
thiessen at sonic.net
Fri Apr 1 11:17:25 PST 2005
Ok, I'm committing the sin of following up on my own post/email, but...
This script should start at the lowest unused ID number and use the lowest
possible un-assigned numbers. If you wanted to start from a higher number -
say to have all new users fit in a specific range, you'd just change the
starting value for ID in the script.
----------
#!/bin/bash
#get all ID numbers. I have used X and a space as a bookend to force inclusion
#of spaces at the beginning and end of the variable OLDIDLIST. Otherwise
#grepping for " $ID " would potentially fail on numbers matching the 1st and
#last in the list. Silly bash string concatenation keeps dropping leading and
#trailing spaces.
OLDIDLIST="X "`cat passwd.old | awk -F : '{ printf "%u\n%u\n",$3,$4 }' `" X" ;
# Set lowest possible ID number.
ID=0 ;
#dodge problems parsing lines
OLDIFS=$IFS ;
IFS="
"
for i in `cat passwd.new` ;
do
if [ $( grep -c "^`echo $i | sed s/:.*$// -`" passwd.old) -eq 0 ] ;
#Find next unused ID number
then while [ `echo $OLDIDLIST | grep -c " $ID " -` -ne 0 ] ;
do ID=$(( ID + 1 )) ;
done ;
echo $i | sed s/:x:[0-9]*:[0-9]*/:x:$ID:$ID/ - >> passwd.old ;
ID=$(( ID + 1 )) ;
fi ;
done ;
IFS=$OLDIFS ;
------------
Justin
On Fri, Apr 01, 2005 at 10:12:46AM -0800, Justin Thiessen wrote:
> On Fri, Apr 01, 2005 at 08:53:29AM -0800, Steve Johnson wrote:
> > On Apr 1, 2005 7:55 AM, Justin Thiessen <thiessen at sonic.net> wrote:
> > > On Fri, Apr 01, 2005 at 07:01:33AM -0800, Todd Cary wrote:
> > > Copy the password file on machine B to "passwd.old", and the password file on
> > > machine A to "passwd.new", then try the following (note the carriage return
> > > between the quotes in my reassignation of IFS):
> > >
> > > #!/bin/bash
> > >
> > > OLDIFS=$IFS ;
> > > IFS="
> > > "
> > > for i in `cat passwd.new` ;
> > > do
> > > if [ $( grep -c `echo $i | sed s/:.*$// -` passwd.old) -eq 0 ] ;
> > > then echo $i >> passwd.old ;
> > > fi ;
> > > done ;
> > > IFS=$OLDIFS ;
> > >
> > > -----
> >
> > This will work sorta, just be aware, you may have conflicting UID# in
> > the new file, it would be best to write something in PERL, and have it
> > verify uid's also.
>
> Ah. Yep. My fault for tossing off something without more than a cursory
> test.
>
> And if nothing else,
>
> if [ $( grep -c `echo $i | sed s/:.*$// -` passwd.old) -eq 0 ] ;
>
> Really ought to be something more like:
>
> if [ $( grep -c "^`echo $i | sed s/:.*$// -`" passwd.old) -eq 0 ] ;
>
> ^^^
> (Force match with start of line)
>
> To avoid collisions between usernames and other strings in the password
> file.
>
> If we can assume that every entry in the password file has a shadow password
> entry, which means that each line in the password file ought to start out
> like:
>
> username:x:
>
> and we are content with the UID = GID for each added user, then the following
> might work:
> ------------------
>
> #!/bin/bash
>
> #get highest ID number
>
> ID=$(( `cat passwd.old | awk -F : '{ printf "%u\n%u\n",$3,$4 }' | sort -n | tail -n 1` + 1 ))
>
> #dodge problems parsing lines
>
> OLDIFS=$IFS ;
> IFS="
> "
> for i in `cat passwd.new` ;
> do
> if [ $( grep -c "^`echo $i | sed s/:.*$// -`" passwd.old) -eq 0 ] ;
> then echo $i | sed s/:x:[0-9]*:[0-9]*/:x:$ID:$ID/ - >> passwd.old ;
> ID=$(( ID + 1 )) ;
> fi ;
> done ;
> IFS=$OLDIFS ;
>
> ------------------------
>
> Although I don't know if there is an upper limit to the UID/GUID number.
> On my system nfsnobody is UID 65534. If UIDs are limited to 2^16, then
> the script is in trouble as written. Obviously we could have the script
> keep track of unused numbers (or at the very least, start at the lowest
> unused UID number and increment from there, checking that the chosen UID
> number is not in use), but that would require a bit more intelligence
> (bookkeeping) of the script
>
> Justin
>
>
> > I had to do this once, and I used perl to build a hash of the new
> > password file, useing the login name as the key and the uid as the
> > value, then load in the old password file, if the hash entry allready
> > was there, then it would drop the name, if it wasn't there, it would
> > add it to the hash. The new hash entries value would be a new uid,
> > starting at whatever was the last one in the new passwd file.
> >
> > Once I was done with parsing the files, I would then dump the hash to
> > a file in the proper format for /etc/passwd.. Now if I was also moving
> > over home directories or any other user directories, I would make sure
> > to chown those directories, this would insure that the new uid would
> > stick on them.
> >
> > I wish I had access to the code I originally used, I would share it,
> > but the idea should at least get you pointed in the right direction.
> >
> > -Steve
> >
> >
> >
> > --
> > "Knowing others is wisdom, knowing your self is Enlightenment."
> > -- Lao-Tzu
> > |C8H10N4O2|
> >
> > _______________________________________________
> > talk mailing list
> > talk at nblug.org
> > http://nblug.org/cgi-bin/mailman/listinfo/talk
>
> _______________________________________________
> talk mailing list
> talk at nblug.org
> http://nblug.org/cgi-bin/mailman/listinfo/talk
More information about the talk
mailing list