CGI para cambiar claves con Net::LDAP
Ernesto Hernandez-Novich
emhn at telcel.net.ve
Tue Mar 18 15:42:35 CST 2003
On Tue, 18 Mar 2003, Luis M. Gallardo D. wrote:
> Ahora que esta funcionando para lo que lo pensi
> (administracisn de cuentas Linux/Samba) me voy a poner
> a estudiar la forma de usar el msdulo de perl-LDAP, y
> luego publicarlo bajo GPL ;-)
Escribí esto ésta tarde. Por lo menos funciona y es estricto con la
selección de claves para que el usuario no ponga sandeces.
#!/usr/bin/perl -w
#
# Requisitos:
#
# NET::LDAP
# Crypt::Cracklib
# Digest::SHA1
#
# apt-get install libnet-ldap-perl libcrypt-cracklib-perl libdigest-sha1-perl
use constant;
use CGI;
use Net::LDAP;
use Crypt::Cracklib;
use Digest::SHA1;
$|++;
my $ldapserver = "ldap.nuevomundo.seg";
my $basedn = "dc=nuevomundo,dc=com,dc=ve";
my %translation = (
"it is based on your username" =>
"esta basada en su nombre de usuario",
"it is based upon your password entry" =>
"esta basada en su nombre completo",
"it is derived from your password entry" =>
"es derivada de su nombre completo",
"it's derived from your password entry" =>
"es derivada de su descripcion de usuario",
"it is derivable from your password entry" =>
"puede deducirse de su descripcion de usuario",
"it's derivable from your password entry" =>
"puede deducirse de su descripcion de usuario",
"it's WAY too short" =>
"es demasiado corta",
"it is too short" =>
"es muy corta",
"it does not contain enough DIFFERENT characters" =>
"no contiene suficientes caracteres diferentes",
"it is all whitespace" =>
"esta compuesta por espacios en blanco",
"it is too simplistic/systematic" =>
"es demasiado simple o sistematica",
"it looks like a National Insurance number" =>
"parece un numero de cedula",
"it is based on a dictionary word" =>
"esta basada en una palabra del diccionario",
"it is based on a (reversed) dictionary word" =>
"esta basada en invertir una palabra del diccionario",
"ok" => "ok",
);
sub checkquality {
my $p = shift;
return("no tiene letras y numeros al mismo tiempo")
unless $p =~ m/\w/ && $p =~ m/\d/;
my $reason = fascist_check($p,"/var/cache/cracklib/cracklib_dict");
return($translation{$reason});
}
sub showpage {
my $q = shift;
my $login = shift;
my $error = shift;
print $q->header,
$q->start_html( -title => 'Cambiar clave',
-author => 'Ernesto Hernandez-Novich' ), "\n",
$q->h1('Cambiar clave'), "\n",
"Bla bla - password dificil - consejos...\n",
$q->startform(), "\n",
$q->start_table, "\n",
$q->Tr, "\n",
$q->td( { -align => 'right' },
"Usuario:"
), "\n",
$q->td( { -align => 'left' },
$q->textfield( -name => 'login',
-default => $login,
-size => 8,
-maxlength => 8)
), "\n",
$q->end_Tr, "\n",
$q->Tr, "\n",
$q->td( { -align => 'right' },
"Clave actual:"
), "\n",
$q->td( { -align => 'left' },
$q->password_field( -name => 'oldpass',
-size => 20,
-maxlength => 20)
), "\n",
$q->end_Tr, "\n",
$q->Tr, "\n",
$q->td( { -align => 'right' },
"Nueva Clave:"
), "\n",
$q->td( { -align => 'left' },
$q->password_field( -name => 'newpass1',
-size => 20,
-maxlength => 20)
), "\n",
$q->end_Tr, "\n",
$q->Tr, "\n",
$q->td( { -align => 'right' },
"Repita la Nueva Clave"
), "\n",
$q->td( { -align => 'left' },
$q->password_field( -name => 'newpass2',
-size => 20,
-maxlength => 20)
), "\n",
$q->end_Tr, "\n",
$q->Tr, "\n",
$q->td( { -colspan => '2',
-align => 'center' },
$q->submit( -value => 'Cambiar')
), "\n",
$q->end_Tr, "\n",
$q->end_table, "\n",
$q->endform, "\n",
$q->end_table, "\n",
$q->p;
if (defined($error)) {
print $error, $q->p;
}
print $q->end_html;
}
# Rutinas para interactuar con LDAP
sub checkandchange {
my $uid = shift;
my $oldpass = shift;
my $newpass = shift;
my $ldap = Net::LDAP->new($ldapserver);
my $binddn = "uid=$uid,ou=People,$basedn";
if ($ldap) {
if ($ldap->bind) {
if ($ldap->search(base => $basedn, filter => "(uid=$uid)")->count) {
$ldap->unbind;
$ldap = Net::LDAP->new($ldapserver);
if ($ldap->bind($binddn, password => $oldpass)->code) {
$ldap->unbind;
return 2;
} else {
my $h = Digest::SHA1->new;
my $p = "{SHA}";
$h->add($newpass);
$p .= $h->b64digest . "=";
if ($ldap->modify($binddn,
replace => { 'userPassword' => $p }
)->code) {
$ldap->unbind;
return 3;
} else {;
$ldap->unbind;
return 0;
}
}
return (1,undef);
} else {
$ldap->unbind;
return 1;
}
} else {
return 5;
}
} else {
return 4;
}
}
# Rutinas para reaccionar ante los posibles errores.
sub nologin {
my $q = shift;
showpage($q,undef,'¡No indicó su nombre de usuario!');
exit(0);
}
sub nooldpass {
my $q = shift;
showpage($q,undef,'¡No indicó su clave actual!');
exit(0);
}
sub nonewpass {
my $q = shift;
showpage($q,undef,'¡No indicó la clave nueva dos veces!');
exit(0);
}
sub newnomatch {
my $q = shift;
showpage($q,undef,'¡Las claves nuevas no coinciden!');
exit(0);
}
sub weakpass {
my $q = shift;
my $r = shift;
showpage($q,undef,"La nueva clave ha sido rechazada porque $r.");
exit(0);
}
my $q = new CGI;
if ($q->param) {
my ($login,$oldpass,$newpass1,$newpass2)
= map { $q->param($_) } ( 'login', 'oldpass', 'newpass1', 'newpass2' );
# Verificamos que no falte nada
nologin($q) unless $login;
nooldpass($q) unless $oldpass;
nonewpass($q) unless ($newpass1 && $newpass2);
newnomatch($q) unless ($newpass1 eq $newpass2);
# Verificamos que la nueva clave cumpla con los standards de calidad
# de organismos pluricelulares.
my $reason = checkquality($newpass1);
weakpass($q,$reason) unless $reason eq 'ok';
# Verificamos que el usuario exista, su clave actual sea correcta
# y procedemos con el cambio.
my $result = "";
for (checkandchange($login,$oldpass,$newpass1)) {
/^0$/ and do { $result = "La clave de $login fue cambiada exitosamente.";
last;
};
/^1$/ and do { $result = "El usuario $login no existe";
last;
};
/^2$/ and do { $result = "La clave actual es incorrecta";
last;
};
/^3$/ and do { $result = "No se pudo cambiar la clave";
last;
};
/^4$/ and do { $result = "No puedo conectarme a $ldapserver";
last;
};
/^5$/ and do { $result = "No puedo conectarme anonimamente a $ldapserver";
last;
};
}
showpage($q,$login,$result);
} else {
showpage($q,undef,"Por favor complete los datos");
}
--
Ernesto Hernández-Novich - Running Linux 2.4.19 i686 - Unix: Live free or die!
Geek by nature, Linux by choice, Debian of course.
If you can't apt-get it, it isn't useful or doesn't exist.
GPG Key Fingerprint = 438C 49A2 A8C7 E7D7 1500 C507 96D6 A3D6 2F4C 85E3
------------------------------------------------------------------------
Enviar e-mail a <majordomo at pm.org> colocando en el cuerpo:
"UNSUBSCRIBE caracas-pm-list" para desuscribirse.
"INFO caracas-pm-list" para conocer las reglas de etiqueta.
------------------------------------------------------------------------
More information about the caracas-pm
mailing list