#!/usr/bin/perl -T use warnings; use strict; use CGI qw/:standard/; use CGI::Carp; # Debian Packages # libnet-ldap-perl # libcrypt-passwdmd5-perl # libmail-sendmail-perl use Net::LDAP; use Crypt::PasswdMD5; use Mail::Sendmail; my $LDAP_SERVER = 'csl-ldap-01.inside'; my $MAX_USER_LEN = '16'; my $MAX_PASS_LEN = '40'; my $MIN_PASS_LEN = '6'; my $g_err_msg = ''; { # MAIN print header(); my ($top_html, $main_html) = get_page(); print "$top_html"; # Application Logic # if param's are passed to the script... if (param) { if (validate_cgi_params( param('user') || '', param('magic_word') || '', param('new_pwd_1') || '', param('new_pwd_2') || '' )) { change_password(param('user') || '', param('magic_word') || '', param('new_pwd_1') || ''); } } print "$g_err_msg" if ($g_err_msg); print "$main_html"; } ###### sub get_page { # Define HTML sections of page my $top_html = << "HERE"; Community Software Lab Password Changer

Change your password (0.3)

HERE my $main_html = << "HERE";
Username:

Password:

New Password:

Repeat New Password:

HERE return ($top_html, $main_html); } sub validate_cgi_params { my ( $user, $passwd, $pwd1, $pwd2 ) = @_; unless ( $pwd1 eq $pwd2 ) { print 'Error, New passwords do not match'; return undef; } unless ( length($user) < $MAX_USER_LEN && length($passwd) < $MAX_PASS_LEN && length($pwd1) < $MAX_PASS_LEN ) { print 'Error, Input too long'; return undef; } unless ( length($pwd1) > $MIN_PASS_LEN ) { print "Error, New password must be more than $MIN_PASS_LEN characters long"; return undef; } return 1; } sub change_password { my ( $user, $pwd, $new_pwd,) = @_; my $ldapbinddn = "uid=$user,ou=People,dc=local"; my $connection; unless ($connection = Net::LDAP->new("$LDAP_SERVER")) { $g_err_msg = 'Error, Cannot connect to server'; return undef; } my $msg; unless ($msg = $connection->bind( dn => $ldapbinddn, password => $pwd )){ $g_err_msg = 'We are experiencing technical difficulties, please try back later'; return undef; } unless ($msg) { my $err = $msg->error; email_and_log_error("Bind error: $err"); } my $md5pwd = unix_md5_crypt($new_pwd); my $result = $connection->modify( "uid=$user,ou=People,dc=local", changes => [ replace => [ userPassword => "{crypt}$md5pwd" ] ] ); if ( $result->code ) { my $err = $result->error; email_and_log_error ("Password change error: $err"); $g_err_msg = 'Error, You have either entered a bad username or password, your password has not been changed'; return undef; } else { return 1; } } sub email_and_log_error { my $error_str = shift; warn $error_str; my %mail = ( To => 'csacca@thecsl.org', From => "$0 <>", Subject => "Error Message", Message => $error_str ); sendmail(%mail) or warn $Mail::Sendmail::error; }