#!/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] ) ; # Länge 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"; } }