#!/usr/bin/perl

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


# WARNING:
# In general renaming unix accounts is not a good idea. 
# There may be programs that use the username instead of the uid.
# However, there are situations where you must do it.
#
# The script does the following:
# 1) checks the new account name for maximum length and bad characters
# 2) renames the account record key in the accounts database
# 3) renames all occurrences of account name in pseudonym und group records in the accounts database
# 4) renames the account in /etc/samba/smbpasswd
# 5) renames the account in /etc/passwd and /etc/shadow
# 6) renames the account in /etc/group
# 7) renames the home directory

# Usage: dt-rename-account account newaccount


use Errno;
use esmith::config;
use esmith::util;
use esmith::db;
tie my %accounts, 'esmith::config', '/home/e-smith/db/accounts';
tie my %conf, 'esmith::config', '/home/e-smith/db/configuration';

my $release=esmith::util::determineRelease();
$release =~ s/([0-9]+).*/$1/;

$old=$ARGV[0];
$new=$ARGV[1];

die "Usage: dt-rename-account account newaccount\n" if( not $ARGV[0] or not $ARGV[1] ) ;

# Lnge des Kontennamens
my $maxAcctNameLength = defined $conf{'maxAcctNameLength'} ?  $conf{'maxAcctNameLength'} : 12;
if ( length $new > $maxAcctNameLength )
	{
	print "Error: New account name $new is longer than '$maxAcctNameLength characters'\n";
	exit 1;
	}

# bad character test
if ( $new =~ /^\s*([a-z][a-zA-Z0-9\'\-\s]+?)\s*$/ )
	{
	$new = $1;
	}
else
	{
	print "Error: New account name $new contains bad characters'\n";
	exit 1;
	}

($type, %properties) = db_get(\%accounts, $new);
if( $type  )
	{
	print "Error: account $new already exists.\n";
	exit 1;
	}


if( $old ne $new )
	{
	($type, %properties) = db_get(\%accounts, $old);
	if( $type eq "user" )
		{
		# Rename Account Key
		$raw_value  = db_get(\%accounts, $old);
		$success = db_set(\%accounts, $new, $raw_value);
		if( $success )
			{
			db_delete( \%accounts, $old );
			print "Account $old renamed to $new.\n";
			}
		else
			{
			print "Error while creating account $new\n";
			}

		# Rename Account in pseudonyms
		@keys  = db_get(\%accounts);
		for( $i=0; $i<@keys; $i++ )
			{
			$type = db_get_type(\%accounts, $keys[$i]);
			if( $type eq "pseudonym" )
				{
				%properties = db_get_prop(\%accounts, $keys[$i]);
				if( $properties{'Account'} eq $old )
					{
					$success = db_set_prop(\%accounts, $keys[$i], "Account" => $new)
					}
				}
			elsif( $type eq "group" )
				{
				$members = db_get_prop(\%accounts, $keys[$i], "Members");
				@m = split( /,/, $members );
				for( $k=0; $k<@m; $k++ )
					{
					$m[$k] = $new if( $m[$k] eq $old );
					}
				$members = join( ",", @m );
				$success = db_set_prop(\%accounts, $keys[$i], "Members" => $members );
				}
			}

		# Rename account in /etc/samba/smbpasswd 
		system( "/bin/cp /etc/samba/smbpasswd /etc/samba/smbpasswd.$old" );
		system( "/bin/sed -e 's/^$old:/$new:/' < /etc/samba/smbpasswd > /etc/samba/smbpasswd.$new" );
		system( "/bin/cp /etc/samba/smbpasswd.$new /etc/samba/smbpasswd" );
		system( "/bin/chown admin.root /etc/samba/smbpasswd" );
		system( "/bin/chmod 600 /etc/samba/smbpasswd" );

		# Rename Unix accounts
		system( "/usr/sbin/usermod", "-l", "$new", "$old" );
		system( "/usr/sbin/groupmod", "-n", "$new", "$old" );

		# Rename home directory in /etc/passwd 
		system( "/bin/cp /etc/passwd /etc/passwd.$old" );
		system( "/bin/sed -e 's;:/home/e-smith/files/users/$old:;:/home/e-smith/files/users/$new:;' < /etc/passwd > /etc/passwd.$new" );
		system( "/bin/cp /etc/passwd.$new /etc/passwd" );
		system( "/bin/chown admin.root /etc/passwd" );
		system( "/bin/chmod 644 /etc/passwd" );

		# Update LDAP attributes dn, uid, mail, calFBURL
		system("/etc/e-smith/events/actions/ldap-delete user-delete $old");
		system("/etc/e-smith/events/actions/ldap-update user-create $new");

		# Rename Home
		system( "/bin/mv /home/e-smith/files/users/$old /home/e-smith/files/users/$new" );
		}
	else
		{
		die "Error: $old is not a valid account.\n";
		}
	}

