Benutzer:Kirmse/delixs-userpasswd
delixs-userpasswd
- dieses Script ändert das Linux- und Sambapasswortes von Usern. Aufruf ist nur als root möglich
- Parameter: --help oder -h, --user oder -u, --pass oder -p
- Aufruf: delixs-userpasswd -u mmustermann -p geheim
Hinweis: Dieses Script ist eine Modifikation des Scripts 'smbldap-passwd'. Es wurden die Parameter des Originalscripts "stillgelegt" und "neue" Parameter in der Art der anderen Scripte für Delixs ergänzt. Zudem wurden Teil des Codes entfernt, der nur als "normaler" User ausgeführt wurde.
das Script
<source lang="perl">
- !/usr/bin/perl -w
- untaint environment
$ENV{'PATH'}= '/bin:/usr/bin'; $ENV{'SHELL'}= '/bin/sh'; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
use strict; use FindBin; use FindBin qw($RealBin); use lib "$RealBin/"; use smbldap_tools;
use Crypt::SmbHash; use Digest::MD5 qw(md5); use Digest::SHA1 qw(sha1); use MIME::Base64 qw(encode_base64);
- ergaenzt
use Getopt::Long;
- function declaration
sub make_hash; sub make_salt;
- my $user= undef;
my $oldpass= undef;
my $arg; my $update_samba_passwd= 1; my $update_unix_passwd= 1; my $force_update_samba_passwd=0;
- die Original-Behandlung der Parameter wurde komplett entfernt und
- durch die delixs-typische Parameterabfrage ersetzt
- Initialisieren der Variablen fuer die Parameter
my $user = ; my $password = ; my $pass;
- wir holen uns zuerst die Parameter,
- falls --help, dann Ausgabe der Hilfe (siehe &help) und beenden
GetOptions('user=s' => \$user,
'pass=s' => \$password, 'help' => \&help);
- Wenn kein Parameter -u oder --user uebergeben wurde, dann Abbruch
if ($user eq ) {
die "Abbruch: es wurde der Parameter --user nicht uebergeben!\n";
}
- Wenn der User nicht den/meinen Konventionen entspricht, dann Abbruch
unless ($user =~ /^[a-zA-Z]\w{1,13}$/) {
die "Abbruch: Der Name fuer den User $user ist nicht korrekt!\n";
}
- Wenn kein Parameter -p oder --pass uebergeben wurde, dann Abbruch
if ($password eq ) {
die "Abbruch: es wurde der Parameter --pass nicht uebergeben!\n";
}
- -------------- jetzt wieder im Original weiter
- check if $user variable is not tainted
- [TODO] create proper user mask
$user =~ /^([-\@\ \w.]+\$?)$/ and $user = $1 or
die "$0: username '$user' is tainted\n";
my ($dn,$ldap_master);
- First, connecting to the directory
if ($< == 0) {
# root user $ldap_master=connect_ldap_master(); # test existence of user in LDAP my $dn_line; if (!defined($dn_line = get_user_dn($user))) {
print "$0: user $user doesn't exist\n"; exit (10);
} $dn = get_dn_from_line($dn_line);
}
my $samba = is_samba_user($user);
- prompt for new password
my $pass1; my $pass2;
- um die Stuktur des Originals zu erhalten, sollte einfach die Variable des
- Parameter hier zugewiesen werden
$pass1 = $password; $pass2 = $pass1; $pass = $password;
- hier wurden etliche Zeilen geloescht
- Prepare '$hash_password' for 'userPassword'
my $hash_password;
- Generate password hash
if ($config{with_slappasswd}) {
# checking if password is tainted: nothing is changed!!!! # essential for perl 5.8 ($pass =~ /^(.*)$/ and $pass=$1) or
die "$0: user password is tainted\n";
# use slappasswd to generate hash if ( $config{hash_encrypt} eq "CRYPT" && defined($config{crypt_salt_format}) ) {
open BUF, "-|" or exec "$config{slappasswd}", "-h","{$config{hash_encrypt}}", "-c","$config{crypt_salt_format}", "-s","$pass"; $hash_password = <BUF>; close BUF;
} else {
open(BUF, "-|") or exec "$config{slappasswd}", "-h","{$config{hash_encrypt}}", "-s","$pass"; $hash_password = <BUF>; close BUF;
}
} else {
# use perl libraries to generate hash $hash_password = make_hash($pass,$config{hash_encrypt},$config{crypt_salt_format});
}
- check if a hash was generated, otherwise die
defined($hash_password) or
die "I cannot generate the proper hash!\n";
chomp($hash_password);
- only modify smb passwords if smb user
if ( $samba and $update_samba_passwd ) {
if (!$config{with_smbpasswd}) {
# generate LanManager and NT clear text passwords my ($sambaLMPassword,$sambaNTPassword) = ntlmgen $pass; # the sambaPwdLastSet must be updating my $date=time; my @mods; push(@mods, 'sambaLMPassword' => $sambaLMPassword); push(@mods, 'sambaNTPassword' => $sambaNTPassword); push(@mods, 'sambaPwdLastSet' => $date); if (defined $config{defaultMaxPasswordAge}) { my $new_sambaPwdMustChange=$date+$config{defaultMaxPasswordAge}*24*60*60; push(@mods, 'sambaPwdMustChange' => $new_sambaPwdMustChange); if ($< ==0) { push(@mods, 'sambaAcctFlags' => '[U]'); } } if ($force_update_samba_passwd == 1) { # To force a user to change his password: # . the attribut sambaPwdLastSet must be != 0 # . the attribut sambaAcctFlags must not match the 'X' flag my $winmagic = 2147483647; my $valacctflags = "[U]"; push(@mods, 'sambaPwdMustChange' => 0); push(@mods, 'sambaPwdLastSet' => $winmagic); push(@mods, 'sambaAcctFlags' => $valacctflags); } # Let's change nt/lm passwords my $modify = $ldap_master->modify ( "$dn", 'replace' => { @mods } ); $modify->code && warn "Failed to modify SMB password: ", $modify->error ;
} else {
if ($< != 0) { my $FILE="|$config{smbpasswd} -s >/dev/null"; open (FILE, $FILE) || die "$!\n"; print FILE <<EOF; $oldpass $pass $pass EOF ; close FILE; } else { open FILE,"|-" or exec "$config{smbpasswd}","$user","-s"; local $SIG{PIPE} = sub {die "buffer pipe terminated" }; print FILE <<EOF; $pass $pass EOF ; close FILE; }
}
}
- Update 'userPassword' field
if ( $update_unix_passwd ) {
my $shadowLastChange=int(time()/86400); my $modify; if ($< != 0) {
$modify = $ldap_master->modify ( "$dn", changes => [ replace => [userPassword => "$hash_password"], replace => [shadowLastChange => "$shadowLastChange"] ] );
} else {
$modify = $ldap_master->modify ( "$dn", changes => [ replace => [userPassword => "$hash_password"], replace => [shadowLastChange => "$shadowLastChange"], replace => [shadowMax => "$config{defaultMaxPasswordAge}"] ] );
} $modify->code && warn "Failed to modify UNIX password: ", $modify->error ;
}
- take down session
$ldap_master->unbind;
exit 0;
- Programm-Ende #####################################
- Generates hash to be one of the following RFC 2307 schemes:
- CRYPT, MD5, SMD5, SHA, SSHA, and CLEARTEXT
- SSHA is default
- '%s' is a default crypt_salt_format
- A substitute for slappasswd tool
sub make_hash {
my $hash_encrypt; my $crypt_salt_format;
my $clear_pass=$_[0] or return undef; $hash_encrypt='{' . $_[1] . '}' or $hash_encrypt = "{SSHA}"; $crypt_salt_format=$_[2] or $crypt_salt_format = '%s';
my $hash_pass; if ($hash_encrypt eq "{CRYPT}" && defined($crypt_salt_format)) {
# Generate CRYPT hash # for unix md5crypt $crypt_salt_format = '$1$%.8s' my $salt = sprintf($crypt_salt_format,make_salt()); $hash_pass = "{CRYPT}" . crypt($clear_pass,$salt);
} elsif ($hash_encrypt eq "{MD5}") {
# Generate MD5 hash $hash_pass = "{MD5}" . encode_base64( md5($clear_pass), );
} elsif ($hash_encrypt eq "{SMD5}") {
# Generate SMD5 hash (MD5 with salt) my $salt = make_salt(4); $hash_pass = "{SMD5}" . encode_base64( md5($clear_pass . $salt) . $salt,);
} elsif ($hash_encrypt eq "{SHA}") {
# Generate SHA1 hash $hash_pass = "{SHA}" . encode_base64( sha1($clear_pass), );
} elsif ($hash_encrypt eq "{SSHA}") {
# Generate SSHA hash (SHA1 with salt) my $salt = make_salt(4); $hash_pass = "{SSHA}" . encode_base64( sha1($clear_pass . $salt) . $salt, );
} elsif ($hash_encrypt eq "{CLEARTEXT}") {
$hash_pass=$clear_pass;
} else {
$hash_pass=undef;
} return $hash_pass;
}
- Generates salt
- Similar to Crypt::Salt module from CPAN
sub make_salt {
my $length=32; $length = $_[0] if exists($_[0]); my @tab = ('.', '/', 0..9, 'A'..'Z', 'a'..'z'); return join "",@tab[map {rand 64} (1..$length)];
}
- - The End
- Wenn Parameter -h uebergeben wurde, dann Hilfe ausgegeben und beenden
sub help {
print "Hilfe muss noch erstellt werden.\n"; exit (0);
}
</source>