0

I'm creating a php script that will create an email account within cpanel. I am using the uapi Email::add_pop function with the command line using shell_exec(), as I was having other issues with the liveAPI PHP class.

I did some searching and initially, it looked like this could be caused because I did not have suexec or suphp set up. However, the only thing that changed with the error is the RUID used to read 99 instead of 1001 as it does now.

I have three files. I have a simple test form located at /home/housediablo/public_html/index.php

<form action="formhandler.php" method="post">
    username: <br>
    <input type="text" name="username"><br>
    Password: <br>
    <input type="text" name="password"><br>
    <input type="submit" value="Submit">
</form>

I have the form handler located at /home/housediablo/public_html/formhandler.php

<?php
include "/usr/local/cpanel/base/frontend/paper_lantern/createmail.live.php";
?>

And I have the actual script that is using shell_exec() located at /usr/local/cpanel/base/frontend/paper_lantern/createmail.live.php

<?php
$username = $_POST['username'];
$password = $_POST['password'];
$domain = 'housediablo.com';
$cmdString =  'uapi --user=housediablo Email add_pop email=' . $username . ' password=' . 
$password . ' quota=0 domain=' . $domain . ' skip_update_db=1';
echo ($cmdString);
$output = shell_exec($cmdString . ' 2>&1');
echo "</ br><pre>$output</pre>";
?>

The expected result is an email being created in cpanel, but I am just getting this output:

[2019-07-25 23:00:22 +0000] die [uapi] setuids failed: Attempting to setuid as a normal user with RUID 1001 at /usr/local/cpanel/Cpanel/AccessIds/SetUids.pm line 89. Cpanel::AccessIds::SetUids::_log_and_die_if_not_root() called at /usr/local/cpanel/Cpanel/AccessIds/SetUids.pm line 66 Cpanel::AccessIds::SetUids::setuids("housediablo") called at bin/apitool.pl line 109 bin::apitool::run(CPANEL_HIDDEN, CPANEL_HIDDEN, CPANEL_HIDDEN, CPANEL_HIDDEN, CPANEL_HIDDEN, CPANEL_HIDDEN, CPANEL_HIDDEN, CPANEL_HIDDEN) called at bin/apitool.pl line 38 exit level [die] [pid=19664] (setuids failed: Attempting to setuid as a normal user with RUID 1001)

I can run the echoed $cmdString as root from the terminal and it will work:

uapi --user=housediablo Email add_pop email=test password=Str0ngT3stPw! quota=0 domain=housediablo.com skip_update_db=1

I can also run the php script as root from the terminal with hardcoded dummy variables in place of the variables from POST and it will also work.

Kyle Diablo
  • 61
  • 1
  • 7
  • Run it as a Cron job, that is in the root users crontab `crontab -e -u root` Then you will need some form of Queuing, such as a DB table to put the commands (insert command on the front read them on the back) that need to run in, then mark each done as it executes them. If you want to make sure only one instance runs in CRON you can use this Mutex simulator class I made its on [GitHub](https://github.com/ArtisticPhoenix/MISC/blob/master/ProcLock.php) – ArtisticPhoenix Jul 26 '19 at 02:43
  • Also please invest in [escapeshellarg](https://www.php.net/manual/en/function.escapeshellarg.php) Such as `$username = escapeshellarg($_POST['username']);` - to reduce the risk this type of code poses. PS - yes I do a fair amount of CLI work with PHP. I can see exactly how to make this work.... I built something similar (but more complex) to synchronize sFTP accounts with user accounts on our site. – ArtisticPhoenix Jul 26 '19 at 02:46
  • As I mentioned above I do something similar for creating system users (CHROOTed of course) for sFTP. We also added a blacklist of Users which cannot be modified by this code, such as `root` or `mysql` or `nobody` etc. for obvious reasons (such as changing the root password) that we use to filter the usernames. But I use an actual RabbitMq Queue for it etc... It would be a real bad day if someone created a user named "root" on our website, without it (and other security stuff, this is actually a fallback just in case sort of thing). – ArtisticPhoenix Jul 26 '19 at 02:51

0 Answers0