Change cPanel’s email password through command line

This script will help you change any email’s account password without using cPanel, this is done through the command line. It was written in PHP but mostly uses shell commands so I guess it was easier to use elements from both worlds.

Use it at your own risk, this script requires to be executed as root and was done for educational purposes.

 <?php

// Inspired on	the following articles:
// https://cpanelgeek.wordpress.com/2015/08/26/resetting-email-account-password-from-command-line-in-cpanel/
// http://www.sudosu.in/2013/11/cpanel-bash-script-to-change-password_11.html

if (!isset($argv[1])) die("Usage: $argv[0] full@email [password]\n");

// generate random 8 character password
if (!isset($argv[2])) {
  $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!.-@';
  $argv[2] = substr(str_shuffle($chars),0,8);
}

// validate email contains at least a @ and break it
if (!preg_match("/\@/",$argv[1])) die("Invalid Email!\n");
list($name,$domain) = explode("@",trim($argv[1]));

// get domain owner
$user = trim(exec("/scripts/whoowns $domain"));
if (!$user) die("Invalid Domain!\n");

// encrypt password
$cpass = trim(exec("openssl passwd -1 '$argv[2]'"));
//echo "$name @ $domain with $argv[2] $cpass\n";

// get home folder
$path = trim(exec("grep \"^$user:\" /etc/passwd | cut -d\":\" -f6"));

// get shadow line and prepare it
$shadow = "$path/etc/$domain/shadow";
$tmpshadow = $shadow . ".tmp";
$rest = trim(exec("grep \"^$name:\" $shadow | cut -d\":\" -f3-"));
if (!$rest) die("Email $argv[1] does not exist!\n");

// create tmp shadow file without the user's email
exec("grep -v \"^$name:\" $shadow --------> $tmpshadow");
exec("chown $user:$user $tmpshadow");
exec("chmod 640 $tmpshadow");

// add the new user's password
exec("echo '$name:$cpass:$rest' >> $tmpshadow");

// swap shadow files and backup the old one
exec("mv $shadow $shadow".".".time());
exec("mv $tmpshadow $shadow");
echo "$argv[1] password changed to: $argv[2]\n";
?>

Save it as change_password.php and execute it to see how to use it: php change_password.php

cpanel 535 Incorrect authentication data

I ran into a small issue when migrating some sites to a cPanel server, tried a few “tricks” (/scripts/* –force hehe) without luck till I found a great post which pointed me the solution, and it is as simple as that!

Since I’m a very lazy guy, I wrote a tiny script which does what Jerry (from cPanel forums) said/explained. Copy the code, save it and execute it. By default it won’t do anything but show the directories and files current state and how they should be. If you see something is not as it should be then you should change the $debug var to false in order to allow the script to do the job. After that everything should be fixed and if not don’t blame me, you can always do that manually 😉

#!/usr/bin/php -q
<?
// file: fix_auth_perms.php
// turn it off if you want to fix them
// based on http://forums.cpanel.net/showpost.php?p=323248&postcount=3
$debug = true;

$maps = file("/etc/domainusers");
if (!is_array($maps)) die("No users found!\n");

foreach ($maps as $map) {
  list($user,$domain) = explode(": ",trim($map));
  if (!$user || !$domain) continue;
  echo "\nChecking $domain ...\n";
  _file_fix("/home/$user/etc",$user,"mail");
  _file_fix("/home/$user/etc/$domain",$user,"mail");
  _file_fix("/home/$user/etc/$domain/shadow","","mail","0640");
  //exit;
}

// $file = full dir/file path
// $nuser = desired user name
// $ngroup = desired group name
// $perms = desired permissions in octal mode (0640)
function _file_fix($file="",$nuser="",$ngroup="",$perms="") {
  global $debug;
  $uname_array = posix_getpwuid(fileowner($file));
  $gname_array = posix_getgrgid(filegroup($file));
  $file_perms = substr(sprintf('%o', fileperms($file)), -4);
  echo "  $file owned by $uname_array[name].$gname_array[name] ($file_perms)\n";
    //wrong ownership, fixing it now!
  if (!$debug) {
    if ($nuser && $nuser != $uname_array[name]) {
      if (!chown($file, $uname_array[name])) echo "  couldn't change file owner to $nuser\n";
      else echo "  changed file owner to $nuser\n";
    }
    if ($ngroup && $ngroup != $gname_array[name]) {
      if (!chgrp($file, $gname_array[name])) echo "  couldn't change group owner to $ngroup\n";
      else echo "  changed group owner to $ngroup\n";
    }
  }
  if ($perms && $perms != $file_perms) {
    if (!$debug) {
      if (!chmod($file,octdec($perms))) echo "  couldn't change file mode to $perms\n";
      else echo "  changed file mode to $perms\n";
    }
  }
  //making a nice output :P
  if (!$nuser) $nuser = $uname_array[name];
  if (!$ngroup) $ngroup = $gname_array[name];
  if (!$perms) $perms = $file_perms;
  echo "  $file should now be owned by $nuser.$ngroup ($perms)\n";
}

?>