[NBLUG/talk] Integrating usernames/passwords

Justin Thiessen thiessen at sonic.net
Fri Apr 1 10:12:46 PST 2005


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



More information about the talk mailing list