#!/usr/bin/perl -T
# 
#  update.cgi  --  Allow a new user to update the Apache database.
#

use CGI;
use lib '/usr/local/apache/lib';
use AuthDB;

my $inputform  = '<HTML> <BODY> <H1>Subscriber update form</H1>

<b>$msg</b>

<P>
account name: <b>$username</b> <BR>

<FORM ACTION="update.cgi" method="post">
<P>
           <INPUT TYPE="hidden" NAME="name"  VALUE="$username">
 first name <INPUT TYPE="text"   NAME="first"  VALUE="$userrec->{first}"> <BR>
 last name <INPUT TYPE="text"   NAME="last"  VALUE="$userrec->{last}"> <BR>
email addr <INPUT TYPE="text"   NAME="email" VALUE="$userrec->{email}"><BR>

<h3>Change password</h3>

current password <INPUT TYPE="password" NAME="pass_old"> <BR>
    new password <INPUT TYPE="password" NAME="pass_1"> <BR>
          confirm <INPUT TYPE="password" NAME="pass_2"> <BR>

<P>
<INPUT TYPE="SUBMIT" VALUE="UPDATE">

</FORM>
</BODY></HTML>';


my $thanksform = '<HTML><BODY> <H2>Thanks, $userrec->{"first"}</H2>

    Your record has been updated.

</BODY></HTML>';

my $username = $ENV{'REMOTE_USER'};
my $userrec;
my $form;
my $msg = '';

unless ($username) {
    print 'Content-type: text/plain

I cannot determine your username, please contact the webmaster 
for this site because there is a configuration problem.
';
    die "Config error in update.cgi: REMOTE_USER was not set.\n";
}

unless ($ENV{"CONTENT_LENGTH"}) {
# No input? Fill in the HTML form with input from the database.

    $userrec = authdb_get($username);
    send_page($inputform);

} else {
# Process the input from the filled in form.

    $q    = new CGI;
    $form = $q->Vars;

    $userrec = authdb_get($form->{"name"});

    if (update_db() != 0) {
    # Something was wrong, send more instructions and get new input.
      send_page($inputform);

    } else {
      send_page($thanksform);
    }
}

sub update_db {
    my $error  = 0;
    my $pass   = $userrec->{"password"}; # current encrypted password

    # Check to make sure all the fields are filled in. 
    # (except password fields which are handled separately)

    foreach (keys %$form) { 
      next if /^pass_/;
      $error++ unless $form->{$_}; 
    }

    if ($error) {
      $msg .= "You must enter something in each field.
               Please fill in the rest of the form and re-submit it.<BR>\n";

    } elsif ($form->{"pass_old"}) {

      # We're processing a password change attempt.
      # Encrypt the password entered as the old password on the form
      # with the salt from the password in the database and compare them.

      my $old_salt = substr($pass, 0,2);
      my $old_crypt = crypt($form->{"pass_old"}, $old_salt);

      unless ($old_crypt eq $userrec->{"password"}) {
          $msg .= "You did not enter your old password correctly. <BR>\n";
          $error++;
      }

      if ($form->{"pass_1"} ne $form->{"pass_2"}) {
          $msg .= "Your new password fields did not match. 
               You have to enter the same password in both fields. <BR>\n";
          $error++;

      } else {
          # We're okay to update the password.

          $pass = crypt($form->{"pass_1"}, salt());
      }

    }

    if (!$error) {
      # Save the updated record.

      my $key,$val;
      while (($key,$val) = each %$form) {
          next if $key eq 'name';   # skip this, it's redundant
          next if $key =~ /^pass_/; # don't save plaintext copies
          $userrec->{$key} = $val;
      }

      delete $userrec->{'password'}; # don't write this to the record

      authdb_put($username, $pass, %$userrec);
    }

    return $error;
}

sub send_page {
    my $page = shift;
    $page =~ s/([\"\@])/\\$1/g; # escape quotes and @ signs
    print "Content-type: text/html\n\n" . eval "\"$page\"";
}