#!/usr/bin/perl 
# (C) 2007 Michael Weinberger
# See http://wiki.contribs.org/Dirty_Tools for full documentation

use Getopt::Long;
my %opts;
my $getRes = GetOptions( 
	"dry-run"=>\$opts{'dry-run'},
	"ibays"=>\$opts{'ibays'},
	"all"=>\$opts{'all'},
);


if( ($opts{'all'} and not $ARGV[0]) or (not $opts{'all'} and not $ARGV[1]) )
	{
	die "Usage: dt-passwords-sync [--dry-run] [--ibays] [--all] SOURESERVER [ACCOUNT]\n" 
	}
$server=$ARGV[0];
$dryrun= $opts{'dry-run'};

if( $opts{'all'} )
	{
	$type=$opts{'ibays'} ? "ibay" : "user";
	$u=`/sbin/e-smith/db accounts show|grep '=$type\$'|/bin/sed 's/=.*//'`;
	chomp($u);
	@users=split( /\n/, $u );
	}
else
	{
	@users=($ARGV[1]);
	}

# shadow
$res = `ssh $server /bin/cat /etc/shadow`;
@shadow=split(/\n/, $res );

# smbpasswd
if( not $opts{'ibays'} )
	{
	$res = `ssh $server /bin/cat /etc/samba/smbpasswd`;
	@smbpasswd=split(/\n/, $res );
	}


for( $i=0; $i<@users; $i++ )
	{
	$done=0;
	$account=$users[$i];
	printf '%-10s: %s', $account, $dryrun ? "(dryrun) " : "";

	# shadow
	@u= grep( /^$account:/, @shadow);
	$res=$u[0];
	chomp($res);
	if( not $res )
		{
		print "does not exist.\n";
		next;
		}
	@pe = split( /:/, $res );
	$upw=$pe[1];
	$pwset = $upw =~ /^\!\!/ ? 0 : 1;
	open( IN, "/etc/shadow" );
	open( OUT, ">/etc/shadow.pwsync" );
	while( <IN> )
		{
		chomp($_);
		@e=split( /:/, $_ );
		if( $e[0] eq $account and $e[1] ne $upw)
			{
			print "shadow synced. ";
			$e[1]=$upw;
			for( $k=0; $k<9; $k++ )
				{
				print OUT ':' if $k>0;
				print OUT $e[$k];
				}
			print OUT "\n";
			$done=1;
			}
		else
			{
			print OUT "$_\n";;
			}
		}
	close( OUT );
	close( IN );

	if( not $opts{'ibays'} )
		{
		# smbpasswd
		@u= grep( /^$account:/, @smbpasswd);
		$res=$u[0];
		chomp($res);
		@pe = split( /:/, $res );
		$lanman_hash=$pe[2];
		$nt_hash=$pe[3];
		$flags=$pe[4];
		$lct=$pe[5];
		$smb_pwset = $flags =~ /D/ ? 0 : 1;
		open( IN, "/etc/samba/smbpasswd" );
		open( OUT, ">/etc/samba/smbpasswd.pwsync" );
		while( <IN> )
			{
			chomp($_);
			@e=split( /:/, $_ );
			if( $e[0] eq $account and ( $e[2] ne $lanman_hash or $e[3] ne $nt_hash or $flags ne $e[4] or $lct ne $e[5] ) )
				{
				print "smbpasswd synced. ";
				$e[2]=$lanman_hash;
				$e[3]=$nt_hash;
				$e[4]=$flags;
				$e[5]=$lct;
				for( $k=0; $k<7; $k++ )
					{
					print OUT ':' if $k>0;
					print OUT $e[$k];
					}
				print OUT "\n";
				$done=1;
				}
			else
				{
				print OUT "$_\n";;
				}
			}
		close( OUT );
		close( IN );
		}

	if( not $dryrun )
		{
		if( not $opts{'ibays'} )
			{
			system( "/bin/chmod --reference /etc/samba/smbpasswd /etc/samba/smbpasswd.pwsync" );
			system( "/bin/chown --reference /etc/samba/smbpasswd /etc/samba/smbpasswd.pwsync" );
			system( "/bin/mv -f /etc/samba/smbpasswd.pwsync /etc/samba/smbpasswd" );
			}
		system( "/bin/chmod --reference /etc/shadow /etc/shadow.pwsync" );
		system( "/bin/chown --reference /etc/shadow /etc/shadow.pwsync" );
		system( "/bin/mv -f /etc/shadow.pwsync /etc/shadow" );
		system( "/sbin/e-smith/db accounts setprop $account PasswordSet " . ( ($pwset and ($smb_pwset or $opts{'ibays'})) ? 'yes' : 'no' ));

		}
	if( $done )
		{
		print "ok.";
		}
	else
		{
		print "nothing to be done.";
		}
	print "\n";
	}
