[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