merging passwd and shadow files

I wrote a Perl script to merge /etc/passwd and /etc/shadow files from two hosts

In the words of Elizabeth “Now you have two problems?”

See below. Sadly wordpress doesn’t do.. well.. any job of indenting. And in case you’re wondering, I’ve munged the passwd hash in the file :P

#!/usr/bin/perl
open PASSWD, "</etc/passwd" or die $!;
open OPASSWD, "<passwd.other" or die $!;
open OSHADOW, "<shadow.other" or die $!;
# Read this hosts /etc/passwd into memory
# nfsnobody:x:4294967294:4294967294:Anonymous NFS User:/var/lib/nfs:/dev/null
while ( <PASSWD> ) {
chomp;
my ($uid,$junkpass,$pruid,$pguid,$officename,$homedir,$shell) = split(/:/,$_,7);
$THISHOST{$uid}{'junkpass'} = $junkpass;
$THISHOST{$uid}{'pruid'} = $pruid;
$THISHOST{$uid}{'pguid'} = $pguid;
$THISHOST{$uid}{'officename'} = $officename;
$THISHOST{$uid}{'homedir'} = $homedir;
$THISHOST{$uid}{'shell'} = $shell;
}
close PASSWD;
# Read other machine's /etc/passwd into memory
while (<OPASSWD>) {
chomp;
my ($uid,$junkpass,$pruid,$pguid,$officename,$homedir,$shell) = split(/:/,$_,7);
$THATHOST{$uid}{'junkpass'} = $junkpass;
$THATHOST{$uid}{'pruid'} = $pruid;
$THATHOST{$uid}{'pguid'} = $pguid;
$THATHOST{$uid}{'officename'} = $officename;
$THATHOST{$uid}{'homedir'} = $homedir;
$THATHOST{$uid}{'shell'} = $shell;
}
close OPASSWD;
# Read other machine's /etc/shadow into memory
# aua:$1$6LzssYvL$Wqs94Dv/ZSkuGl0LXQpKb1:13392:0:99999:7:::
while (<OSHADOW>) {
chomp;
my ($uid,$passstring) = split(/:/,$_,2);
$THATSHADOW{$uid} = $passstring;
}
close OSHADOW;
# Check for missing accounts
foreach $account (sort keys %THATHOST) {
if (!(defined($THISHOST{$account}))) {
print "Missing $account\n";
$passwdbuf = $passwdbuf . "$account:$THATHOST{$account}{junkpass}:$THATHOST{$account}{pruid}:$THATHOST{$account}{pguid}:$THATHOST{$account}{officename}:$THATHOST{$account}{homedir}:$THATHOST{$account}{shell}\n";
$shadowbuf = $shadowbuf . "$account:$THATSHADOW{$account}\n";
} else {
print "$account: $THISHOST{$account}{pruid} = $THATHOST{$account}{pruid}\n";
}
if ((defined($THISHOST{$account})) && ($THISHOST{$account}{pruid} ne $THATHOST{$account}{pruid})) {
$uiderrors = $uiderrors . "$account : THISHOST:$THISHOST{$account}{pruid} THATHOST:$THATHOST{$account}{pruid}\n";
}
}
# Output missing accounts for /etc/passwd
print "------------------\n";
print "Add to /etc/passwd\n";
print "$passwdbuf\n";
# Output missing accounts for /etc/shadow
print "------------------\n";
print "Add to /etc/shadow\n";
print "$shadowbuf\n";
# UID Mis-matches
print "------------------\n";
print "UID Mis-matches\n";
print "$uiderrors\n";

Leave a Reply