.htpasswd Change Script

On a recent project the client needed a password change script for an htpasswd file, but nothing really fit the bill. I grabbed one by David A. Horner , and modified it to bit a bit more versatile.
The script:

 <?php
/* --------------------------------------------------------------------
-- Configurable script to change users in htpasswd
-----------------------------------------------------------------------
-- This script will change users in an htpasswd file using
-- the PEAR Basic Authentication library. It imports header/footer files
-- if they are found so you can customize the look.
--
-- Installation:
--   Copy this file into a directory that is web protected and
-- update the script to point to the path of your actual htpasswd file.
-- You will need to make the htpasswd file is writable by the web server
-- user.
--
-- Author: Dan Afonso
-- Based on: David A. Horner (DAH) http://dave.thehorners.com
-- License: Public Domain
---------------------------------------------------------------------- */
// Edit the following to setup your script
$HTPASSWD_PATH = "/etc/svn/htpasswd";
$REDIRECT_URL = "/";
$MIN_PASSLEN = 6;
$MAX_PASSLEN = -1;
$HEADER_FILE = 'password_change_header.html';
$FOOTER_FILE = 'password_change_footer.html';
// Check for header template, and display it if it's there
if (is_readable($HEADER_FILE)){
  $fh = fopen($HEADER_FILE, 'r');
  fpassthru($fh);
  fclose($fh);
} else {
?>
<html><head><title>Change Password Script</title></head><body>
<style>
  .error_box {
    font-color: red;
    margin: 5px;
    border: thin solid red;
    background: goldenrod;
  }
</style>
<?php
}
if(!include('File/Passwd/Authbasic.php')) {
?>
<div class="error_box"><h1>Installation Error</h1>
Your PEAR configuration is missing some required modules. You can install these
by running:
<pre>
[machine ~]# <b>pear install Auth</b>
[machine ~]# <b>pear install File_Passwd</b>
</pre>
</div>
<?php
   exit();
}
if(strlen($_SERVER["REMOTE_USER"])==0) {
?>
<div class="error_box"><h1>Installation Error</h1>
This script must be run from a password protected directory on your web site.
Please visit <a href="http://wiki.apache.org/httpd/PasswordBasicAuth"> the
Apache Wiki</a> for more information
</div>
<?php
  exit(0);
}
/// Check if we can write to the htpasswd file
if (!is_writable($HTPASSWD_PATH)){
?>
<div class="error_box"><h1>Installation Error</h1>
Your htpasswd file is not writable. You can change this by either:
<pre>
[machine ~]> <b>chmod a+w <?php echo $HTPASSWD_PATH; ?></b>
</pre>
... or if you prefer more security, as root you can do:
<pre>
[machine ~]# <b>chown <?php
        $a = posix_getpwuid(posix_getuid());
        echo $a["name"] . ' ' . $HTPASSWD_PATH; ?></b>
</pre>
</div>
<?php
   exit();
}
// Start processing
$user=$_SERVER["REMOTE_USER"];
$save_changes=false;
$passfile = new File_Passwd_Authbasic($HTPASSWD_PATH);
$ret = $passfile->load();
if(!PEAR::isError($ret)) {
  echo "Hello $user, welcome to the password change script.<br>";
  $verified=false;
  if(isset($_REQUEST["currpass"]) && strlen($_REQUEST["currpass"])) {
    // The PEAR library does not handle the (defaut) crypt() password
    // hash. So we have to decode it manually. Luckally, all the SHA1
    // hashes start with {SHA1}, and '{' is not present in crypt()
    // hashes.
    $users = $passfile->listUser();
    $salt = substr($users[$_SERVER["REMOTE_USER"]], 0, 2);
    // Check SHA1 passwords
    if(isset($users[$_SERVER["REMOTE_USER"]]) &&
       $salt == '{S' &&
       $passfile->verifyPasswd($user,$_REQUEST["currpass"])
      ) {
      $verified=true;
      echo "Password validated via SHA1<br/>\n";
    }
    // Check crypt()
    elseif (isset($users[$_SERVER["REMOTE_USER"]]) &&
            (crypt($_REQUEST["currpass"], $salt) ==
             $users[$_SERVER["REMOTE_USER"]])) {
      $verified=true;
      echo "Password validated via crypt()<br/>\n";
    } else {
      echo '<div><b>Failed:</b> Your password did not match </div><br>';
    }
   }
   // Make sure the 2 passwords match
   $confirmed=false;
   if(isset($_REQUEST["newpass"]) && strlen($_REQUEST["newpass"]) > $MIN_PASSLEN) {
      if(strcmp($_REQUEST["newpass"],$_REQUEST["newpass2"]) == 0) {
         $confirmed=true;
      } else {
         echo '<div><b>Failed</b>: new password and confirmed password don\'t match.';
      }
   } else if($verified) {
      echo "<div class=\"error_box\"><b>Failed</b>: you must supply a new password
             and it must be at least $MIN_PASSLEN characters long.</div>";
   }
   if($verified && $confirmed) {
      $passfile->changePasswd($user, $_REQUEST["newpass"]);
      $save_changes=true;
   } else {
?>
<form method="post">
  <table border=0>
    <tr>
      <td colspan=2 bgcolor=cccccc>Change your password</td>
    </tr>
    <tr>
      <td>Verify Current Password: </td>
      <td><input type="password" name="currpass"></td>
    </tr>
    <tr>
      <td>New Password: </td>
      <td><input type="password" name="newpass"></td>
    </tr>
    <tr>
      <td>New Password Again(to confirm): </td>
      <td><input type="password" name="newpass2"></td>
    </tr>
    <tr>
      <td colspan=2><input type="submit" name="submit" value="Change Pass">
      <input type="hidden" name="redirect" value="true"></td>
    </tr>
  </table>
</form>
<?php
   }
   if($save_changes) {
      echo "Saving password file...<br/>";
      $ret=$passfile->save();
      if(!PEAR::isError($ret)) {
         echo "Password file successfully updated!<br/>";
         if(isset($_REQUEST["redirect"])) {
            echo "The browser will request your new username/password in
                  5 seconds....<br>";
            echo "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"5; URL=$REDIRECT_URL\">";
         }
      } else {
         echo '<div><b>Failed</b>: Failed to write password file!<br>';
         echo "(".$ret->getMessage().")<br></div>";
      }
   }
} else {
   echo '<div><b>Failed</b>:Failed to open password file!<br>';
   echo "(".$ret->getMessage().")<br></div>";
}
// Display the footer
if (is_readable($FOOTER_FILE)){
  $fh = fopen($FOOTER_FILE, 'r');
  fpassthru($fh);
  fclose($fh);
} else {
  echo "</body></html>";
}
?>