E-mail, FTP, and SQL Password Changer

I needed the ability for user to be able to update their passwords in one easy location and without requiring the domain admin to change FTP or SQL passwords for users, so I created a PHP script that provides this functionality.

The changer is based on HowTo change your Webmail password for ispCP Omega 1.0.0 • 2009-02-25. I took that code and expanded it out to include a few features:

You can easily remove the ability to change passwords by removing the appropriate <option></option> entry as you may not want users to be able to chane their SQL/FTP password.

I am by no means a proficient programmer, but feel free to update/modify/remove anything you like or let me know if something can be done better.

I installed mine under tools/passwordchanger/index.php

<?php
/*
*  ispcp Password Changer
*  author: dolomike
*  Version: 0.1
*
*  Feel free to modify and distribute
*
*  Based on http://www.isp-control.net/documentation/doku.php?id=howto:mail:change_webmailpass
*  Modified to allow password changes to e-mail, ftp, and SQL users
*  Does not require adodb but uses built in ispCP functions
*  Added javascript to check password entry requirements before submit
*/
require '../../include/ispcp-lib.php';

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ispCP Password Changer</title>
<meta name="robots" content="noindex,nofollow">
<link rel="stylesheet" type="text/css" href="/webmail/themes/css/omega.css">
<style type="text/css">
<!--
body, td, input, select, textarea {
    font-family:Tahoma, Geneva, sans-serif;
    font-size:9px;
}
input, textarea, select {
    border:#7f9db9 1px solid;
    padding:0px;
}
-->
</style>
<script type="text/javascript">
  function checkForm(form)
  {
    // check if username is blank
    if(form.username.value == "") {
      alert("Error: Username cannot be blank!");
      form.username.focus();
      return false;
    }

    // check if username contains illegal characters
    //if (form.ptype.value != "sql")
    //{
    //  re = /^\w+$/;
    //  if(!re.test(form.username.value)) {
    //    alert("Error: Username must contain only letters, numbers and underscores!");
    //    form.username.focus();
    //    return false;
    //  }
    //}

    // check if old password is blank
    if(form.oldpass.value == "") {
      alert("Error: Old password cannot be blank!");
      form.oldpass.focus();
      return false;
    }

    // check if new password is blank
    if(form.newpass.value == "") {
      alert("Error: New password cannot be blank!");
      form.newpass.focus();
      return false;
    }

    // check if repeated password is blank
    if(form.newpassr.value == "") {
      alert("Error: Please repeat the new password!");
      form.newpassr.focus();
      return false;
    }

    // ensure password has at least one number
    re = /[0-9]/;
    if(!re.test(form.newpass.value)) {
       alert("Error: password must contain at least one number (0-9)!");
       form.newpass.focus();
       return false;
     }

    // ensure password has at least one letter
    re = /[a-z]/;
    if(!re.test(form.newpass.value)) {
      alert("Error: password must contain at least one lowercase letter (a-z)!");
      form.newpass.focus();
      return false;
    }

    // check if password length is correct
    if (form.ptype.value == "sql")
    {
      if((form.newpass.value.length < 1) || (form.newpass.value.length > 32)) {
      alert("Error: Password must be between 1 and 32 characters long");
      form.newpass.focus();
      return false;
      }
    }
    else
    {
      if((form.newpass.value.length < 6) || (form.newpass.value.length > 15)) {
        alert("Error: Password must be between 6 and 15 characters long");
        form.newpass.focus();
        return false;
      }
    }


    // check if new passwords match
    if(form.newpass.value != form.newpassr.value) {
      alert("Error: New passwords do not match!");
      //form.newpass = "";
     // form.newpassr = "";
      form.newpassr.focus();
      return false;
    }

    //Optional:
//    re = /[A-Z]/;
//    if(!re.test(form.pwd1.value)) {
//      alert("Error: password must contain at least one uppercase letter (A-Z)!");
//      form.pwd1.focus();
//      return false;
//    }
//  }

// Nor problems,accept the password change request and pass on to processing by ispCP
return true;
}
</script>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#000000" vlink="#000000" alink="#000000">
<form action="" method="post" name="login_form" onSubmit="return checkForm(this);">
  <div id="container">
    <h1>ispCP Password Changer</h1>
    <fieldset class="login">
        <p class="login">
        <table cellpadding="0" cellspacing="0" style="color:#CCC">
          <tr>
            <td align ="left">&nbsp;<strong>Type:</strong></td>
            <td><select name="ptype" style="width:130px;"/>
                <option value="e-mail">E-Mail Password</option>
                <option value="ftp">FTP Password</option>
                <option value="sql">SQL Password</option>
            </td>
          </tr>
          <tr>
            <td align="left">&nbsp;<strong>Username:</strong></td>
            <td><input type="text" name="username"  style="width:130px;"/></td>
          </tr>
          <tr>
            <td align="left">&nbsp;<strong>Old Password:</strong></td>
            <td><input type="password" name="oldpass"  style="width:130px;"/></td>
          </tr>
          <tr>
            <td align="left">&nbsp;<strong>New Password:</strong></td>
            <td><input type="password" name="newpass"  style="width:130px;" maxlength="15"/></td>
          </tr>
          <tr>
            <td align="left">&nbsp;<strong>Repeat New:</strong></td>
            <td><input type="password" name="newpassr"  style="width:130px;" maxlength="15"/></td>
          </tr>
          <tr>
            <td align="left"></td>
            <td><input type="submit" name="changepass" value="Change" /></td>
          </tr>
        </table>
      </p>
    </fieldset>
  </div>
</form>


<?php

// Ensure all the required values are passed in
if(isset($_POST['changepass'])=='Change'&&!empty($_POST['username'])&&!empty($_POST['oldpass'])&&!empty($_POST['newpass'])&&!empty($_POST['newpassr']))
{
  // assign the username, password and type  to variables
  if(isset($_POST['username']))$username=$_POST['username'];
  if(isset($_POST['oldpass']))$oldpass=($_POST['oldpass']);
  if(isset($_POST['newpass']))$newpass=($_POST['newpass']);
  if(isset($_POST['ptype']))$ptype=($_POST['ptype']);
  // populate the SQL parameters based on type of password being changed
  switch ($ptype)
  {
    case "e-mail":
      $sql_table = "mail_users";
      $sql_search_id = "mail_id";
      $sql_search_field = "mail_addr";
      $sql_search_pass = "mail_pass";
      break;
    case "ftp":
      $sql_table = "ftp_users";
      $sql_search_id = "userid";
      $sql_search_field = "userid";
      $sql_search_pass = "passwd";
      break;
    case "sql":
      $sql_table = "sql_user";
      $sql_search_id = "sqlu_id";
      $sql_search_field = "sqlu_name";
      $sql_search_pass = "sqlu_pass";
      break;
  }
  // Run the SQL command to find the user and password
  $sql_result = execute_query($sql,'SELECT ' . $sql_search_id . ', ' . $sql_search_pass.' FROM '. $sql_table.' WHERE '. $sql_search_field .'= "' .$username.'"');

  // store the result for later processing
  $user_db_id = $sql_result->fields[$sql_search_id];
  $user_db_pass = $sql_result->fields[$sql_search_pass];

  // Check if the username exists
  if ($sql_result->RecordCount() == 0)
  {
    echo ('<p align="center" style="color:#F00">Incorrect username or password. Please try again ');
    return false;
  }
  elseif ($sql_result->RecordCount() > 1)
  {
    echo ('<p align="center" style="color:#F00">An error has occurred. Please contact the system administrator. ');
    return false;
  }
  // One entry found. Check if the old password match
  else
  {
    // check if the old passwords match
    // ftp passwords are stored a bit differently than e-mail and SQL
    if ($ptype == "ftp")
    {
      if (crypt($oldpass,$user_db_pass) == $user_db_pass)
        $pass_match = 1;
      else
        $pass_match = 0;
    }
    // Check e-mail and SQL users this way
    else
    {
      if (encrypt_db_password($oldpass) == $user_db_pass)
        $pass_match = 1;
      else
        $pass_match = 0;
    }

    if ($pass_match == 1)
    {

      //Encrypt the new passwords
      // ftp passwords are stored with crypt
      if ($ptype == "ftp")
      {
        $new_db_pass = crypt_user_pass_with_salt($newpass);
      }
      // otherwise md5 with e-mail and SQL
      else
      {
        $new_db_pass = encrypt_db_password($newpass);
      }
      // Perform the password update
      if ($ptype == "sql")
      {
        // Update ispCP SQL password
        $sql_result = execute_query($sql,'UPDATE ' . $sql_table . ' SET '. $sql_search_pass."='".$new_db_pass."'  WHERE ". $sql_search_id .'="'.$user_db_id.'" LIMIT 1');
        // update MYSQL login data
        $query =  execute_query($sql, 'SET PASSWORD FOR "' . $username. '"@"%" = PASSWORD("'.$newpass.'")');
        $query =  execute_query($sql, 'SET PASSWORD FOR "' . $username. '"@"localhost" = PASSWORD("'.$newpass.'")');
      }
      elseif ($ptype == "ftp")
        $sql_result = execute_query($sql,'UPDATE ' . $sql_table . ' SET '. $sql_search_pass."='".$new_db_pass."' WHERE ". $sql_search_id .'="'.$user_db_id.'" LIMIT 1');

      else
        $sql_result = execute_query($sql,'UPDATE ' . $sql_table . ' SET '. $sql_search_pass."='".$new_db_pass."', status='change' WHERE ". $sql_search_id .'="'.$user_db_id.'" LIMIT 1');

      //
      echo ('<p align="center" style="color:#F00">Password changed. ');
      // Write event to admin logfile
      write_log($username . " changed " . $ptype . " password using passwordchanger tool");
      // Trigger the ispCP manager to update
      send_request();
    }
  }
  echo '</p>';
}
?>
</body>
</html>