#!/usr/bin/perl -wT
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser); 
use DBI;
use Email::Valid;
use strict;
print header;
print start_html("Password Change Results");

my $dbh = DBI->connect( "dbi:mysql:usertable", "usertable", "jutedi2") or &dienice("Can't connect to db: $DBI::errstr");
my $username = param('username');
my $email = param('email');

unless (Email::Valid->address($email)) {
   &dienice("`$email' doesn't appear to be a valid e-mail address.");

my $sth = $dbh->prepare("select * from users where username = ?") or &dbdie;
$sth->execute($username) or &dbdie;
if (my $uinfo = $sth->fetchrow_hashref) {
   # even if the username is valid, we want to check and be sure the email
   # address matches.
   if ($uinfo->{email} !~ /$email/i) {
       &dienice("Either your username or e-mail address was not found.");
} else {
    &dienice("Either your username or e-mail address was not found.");

# ok, it's a valid user. First, we create a random password.  This uses
# the random password code from chapter 10.
my $randpass = &random_password();

# now we encrypt it:
my $encpass = &encrypt($randpass);

# now store it in the database...
$sth = $dbh->prepare("update users set password=? where username=?")  or &dbdie;
$sth->execute($encpass, $username) or &dbdie;

# ...and send email to the person telling them their new password.
# be sure to send them the un-encrypted version! 
$ENV{PATH} = "/usr/sbin";
open(MAIL,"|/usr/sbin/sendmail -t -oi");
print MAIL "To: $email\n";
print MAIL "From: webmaster\n";
print MAIL "Subject: Your FooWeb Password\n\n";
print MAIL <<EndMail;
Your FooWeb Password has been changed. The new password is '$randpass'.

You can login and change your password at 

print qq(<h2>Success!</h2>
<p>Your password has been changed!  A new password has been e-mailed to you.</p>\n);
print end_html;

sub encrypt {
    my($plain) = @_;
    my(@salt) = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/');
    return crypt($plain, $salt[int(rand(@salt))] . $salt[int(rand(@salt))] 	);

sub random_password {
    my($length) = @_;
    if ($length eq "" or $length < 3) {
        $length = 6;            # make it at least 6 chars long.
    my @letters = ('a'..'z', 'A'..'Z', '0'..'9');
    my $randpass = "";
    foreach my $i (0..$length-1) {
      $randpass .= $letters[int(rand(@letters))];
    return $randpass;

sub dienice {
    my($msg) = @_;
    print "<h2>Error</h2>\n";
    print $msg;

sub dbdie {
    my($package, $filename, $line) = caller;
    my($errmsg) = "Database error: $DBI::errstr<br>
                called from $package $filename line $line";