views:

429

answers:

2

I need to create an ejabberd user from a PHP script. I also need to be able to add the new user to a predefined shared roster.

Should I just call ejabberdctl using exec() or is there a better way?

+1  A: 

ejabberdctl is by far the easiest in this specific case. The other options are:

  • Implement a full client XMPP in PHP (!)

  • Implement a module in Erlang that proxies the requests: the PHP<-->Erlang communication would need to be through a socket and lots of marshaling would be involved (!)

jldupont
Hmmmm... I seem to be having trouble with limited privileges (or something). Whenever I try to run the `ejabberdctl` command using `exec()` I get this back: `erlexec: HOME must be set`
Andrew
Ok - got it figured out. I'll post my solution soon. Thanks for the advice.
Andrew
A: 

Here's my final solution:

Thanks to jldupont's advice that ejabberdctl would be the easiest solution, I pressed on through the obstacles I ran into and have a working solution.

By default, apache's user doesn't have the right privileges to successfully run ejabberdctl (and for good reason). So in order for it to work, you have to call it with sudo. But... sudo requires a password, which presents 2 problems:

  1. The apache user doesn't have a password.
  2. Even if it did, there's no way to enter it from PHP.

Solution (for Ubuntu) - add this line at the end of /etc/sudoers:

www-data ALL= NOPASSWD: /usr/sbin/ejabberdctl

The path to the sudoers file and ejabberdctl may vary for other Linux distros. This allows apache's user (www-data) to run only ejabberdctl with elevated privileges and without requiring a password.

All that's left is the PHP code:

<?php
    $username = 'tester';
    $password = 'testerspassword';
    $node = 'myserver.com';
    exec('sudo /usr/sbin/ejabberdctl register '.$username.' '.$node.' '.$password.' 2>&1',$output,$status);
    if($output == 0)
    {
        // Success!
    }
    else
    {
        // Failure, $output has the details
        echo '<pre>';
        foreach($output as $o)
        {
            echo $o."\n";
        }
        echo '</pre>';
    }
?>

Security

It's important to note that this does present a significant security risk even though you're only allowing one command to be run by www-data. If you use this approach, you need to make sure you protect the PHP code behind some sort of authentication so that not just anybody can make it execute. Beyond the obvious security risks, it could open your server up to a Denial of Service attack.

Andrew