Adding a hook with describe() method

DennisMidjord

Well-Known Member
Sep 27, 2016
365
81
78
Denmark
cPanel Access Level
Root Administrator
I'm trying to follow this documentation: Guide to Standardized Hooks - The describe() Method - Developer Documentation - cPanel Documentation
I've added a file with the following contents (just the example from the article):
PHP:
#!/usr/local/cpanel/3rdparty/bin/php -q
<?php
// file - /var/cpanel/myapp/whm.php
 
// Any switches passed to this script
$switches = (count($argv) > 1) ? $argv : array();
 
// Argument evaluation.
if (in_array('--describe', $switches)) {
    echo json_encode( describe() );
    exit;
} elseif (in_array('--add', $switches)) {
    list($status, $msg) = add();
    echo "$status $msg";
    exit;
} elseif (in_array('--remove', $switches)) {
    list($status, $msg) = remove();
    echo "$status $msg";
    exit;
} else {
    echo '0 myapp/whm.php needs a valid switch';
    exit(1);
}
 
// Embed hook attribute information.
function describe() {
    $my_add = array(
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Create',
        'stage'    => 'post',
        'hook'     => '/var/cpanel/myapp/whm.php --add',
        'exectype' => 'script',
    );
    $my_remove = array(
        'blocking' => 1,
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Remove',
        'stage'    => 'pre',
        'hook'     => '/var/cpanel/myapp/whm.php --remove',
        'exectype' => 'script',
    );
    return array($my_add, $my_remove);
}
 
function add() {
    // Your actions go here.
}
 
function remove() {
    // Your actions go here.
}
?>
How would I register this hook?

I need it to run on Accounts::Create (add()) and Accounts::Remove (remove())
 

cPanelTJ

Product Owner
Staff member
Jan 29, 2019
100
52
103
Houston, TX
cPanel Access Level
Root Administrator
Twitter
You'll need to make sure the permissions on your script file are set appropriately.

Code:
$ chmod +x /var/cpanel/myapp/whm.php
Then you should be able to register your hook without issue.
Code:
$ bin/manage_hooks add script /var/cpanel/myapp/whm.php
 

DennisMidjord

Well-Known Member
Sep 27, 2016
365
81
78
Denmark
cPanel Access Level
Root Administrator
Thank you, @cPanelTJ !
I managed to add the hook. I now have another issue. The hook prevents the killacct script from running. This is the script:
PHP:
#!/usr/local/cpanel/3rdparty/bin/php -q
<?php

// Any switches passed to this script
$switches = (count($argv) > 1) ? $argv : array();
 
// Argument evaluation.
if (in_array('--describe', $switches)) {
    echo json_encode( describe() );
    exit;
} elseif (in_array('--add', $switches)) {
    list($status, $msg) = add();
    echo "$status $msg";
    exit;
} elseif (in_array('--remove', $switches)) {
    list($status, $msg) = remove();
    echo "$status $msg";
    exit;
} else {
    echo '0 myapp/whm.php needs a valid switch';
    exit(1);
}

// Embed hook attribute information.
function describe() {
    $my_add = array(
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Create',
        'stage'    => 'post',
        'hook'     => '/usr/local/cpanel/3rdparty/bin/test.php --add',
        'exectype' => 'script',
    );
    $my_remove = array(
        'blocking' => 1,
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Remove',
        'stage'    => 'pre',
        'hook'     => '/usr/local/cpanel/3rdparty/bin/test.php --remove',
        'exectype' => 'script',
    );
    return array($my_add, $my_remove);
}

function add() {
    $vars = get_passed_data();
    $username = $vars['data']['user'];
    $plan = $vars['data']['plan'];
    $file = $strings = file("/etc/ftpusers");
    if(($plan == "LARGEMAIL" OR $plan == "MEDIUMMAIL" OR $plan == "SMALLMAIL") AND !in_array($username."\n", $file)){
        file_put_contents('/etc/ftpusers', $username . PHP_EOL, FILE_APPEND);
    }
}

function remove() {
    $vars = get_passed_data();
    $username = $vars['data']['user'];
    $plan = $vars['data']['plan'];
    $file = $strings = file("/etc/ftpusers");
    file_put_contents('/etc/ftpusers', print_r($vars, true) . PHP_EOL, FILE_APPEND);
}

function get_passed_data() {
 
    // Get input from STDIN.
    $raw_data;
    $stdin_fh = fopen('php://stdin', 'r');
    if ( is_resource($stdin_fh) ) {
        stream_set_blocking($stdin_fh, 0);
        while ( ($line = fgets( $stdin_fh, 1024 )) !== false ) {
            $raw_data .= trim($line);
        }
        fclose($stdin_fh);
    }
 
    // Process and JSON-decode the raw output.
    if ($raw_data) {
        $input_data = json_decode($raw_data, true);
    } else {
        $input_data = array('context'=>array(),'data'=>array(), 'hook'=>array());
    }
 
    // Return the output.
    return $input_data;
}

?>
This is the error log from cPanel:
Code:
[2020-03-17 11:38:35 +0100] warn [Internal Warning while parsing [stdin] 6215] Use of uninitialized value $result in string ne at /usr/local/cpanel/Cpanel/Hooks.pm line 503.
 at /usr/local/cpanel/Cpanel/Hooks.pm line 503.
        Cpanel::Hooks::_exec_script("main", HASH(0x46a36e8), HASH(0x16a5288), HASH(0x45fe450)) called at /usr/local/cpanel/Cpanel/Hooks.pm line 350
        Cpanel::Hooks::_exec_hook("main", HASH(0x46a36e8), HASH(0x16a5288), HASH(0x45fe450)) called at /usr/local/cpanel/Cpanel/Hooks.pm line 274
        eval {...} called at /usr/local/cpanel/Cpanel/Hooks.pm line 269
        Cpanel::Hooks::hook(HASH(0x16a5288), HASH(0x45fe450)) called at /usr/local/cpanel/Whostmgr/Accounts/Remove.pm line 712
        Whostmgr::Accounts::Remove::_run_pre_removal_script("killdns", 1, "keep_remote_databases", 0, "user", "atest") called at /usr/local/cpanel/Whostmgr/Accounts/Remove.pm line 299
        Whostmgr::Accounts::Remove::__ANON__() called at /usr/local/cpanel/3rdparty/perl/530/lib/perl5/cpanel_lib/Try/Tiny.pm line 95
        eval {...} called at /usr/local/cpanel/3rdparty/perl/530/lib/perl5/cpanel_lib/Try/Tiny.pm line 88
        Try::Tiny::try(CODE(0x46a3040), Try::Tiny::Catch=REF(0x467ac90)) called at /usr/local/cpanel/Whostmgr/Accounts/Remove.pm line 300
        Whostmgr::Accounts::Remove::_killacct("user", "atest", "killdns", 1, "keep_remote_databases", 0) called at /usr/local/cpanel/Whostmgr/Accounts/Remove.pm line 969
        Whostmgr::Accounts::Remove::_removeaccount("user", "atest", "keepdns", 0) called at /usr/local/cpanel/Whostmgr/API/1/Accounts.pm line 458
        Whostmgr::API::1::Accounts::removeacct(HASH(0x17e1698), Whostmgr::API::1::Utils::Metadata=HASH(0x17da588), HASH(0x3e1fec8)) called at whostmgr/bin/xml-api.pl line 3750
        whostmgr::bin::xml_api::__ANON__(Whostmgr::API::1::Utils::Metadata=HASH(0x17da588), HASH(0x17e1698), HASH(0x3e1fec8), CODE(0x3e19b78)) called at /usr/local/cpanel/Whostmgr/API/1/Data/Wrapper.pm line 234
        Whostmgr::API::1::Data::Wrapper::__ANON__() called at /usr/local/cpanel/3rdparty/perl/530/lib/perl5/cpanel_lib/Try/Tiny.pm line 97
        eval {...} called at /usr/local/cpanel/3rdparty/perl/530/lib/perl5/cpanel_lib/Try/Tiny.pm line 88
        Try::Tiny::try(CODE(0x3f9bde0), Try::Tiny::Catch=REF(0x3f9bfd8)) called at /usr/local/cpanel/Whostmgr/API/1/Data/Wrapper.pm line 253
        Whostmgr::API::1::Data::Wrapper::execute_internal(CODE(0x3e1cd90), HASH(0x17e1698), HASH(0x3e1fec8), HASH(0x3e268a8), CODE(0x3e19b78)) called at whostmgr/bin/xml-api.pl line 3925
        whostmgr::bin::xml_api::runapp("removeacct", HASH(0x3e1fec8), HASH(0x16cbee0), 0, CODE(0x3e19b78)) called at whostmgr/bin/xml-api.pl line 3619
        whostmgr::bin::xml_api::script(CODE(0x3e19b78), "-json", "./removeacct") called at whostmgr/bin/xml-api.pl line 3562


[2020-03-17 11:38:35 +0100] info [xml-api] Script hook returned an invalid response:
[2020-03-17 11:38:35 +0100] info [xml-api]    script: /usr/local/cpanel/3rdparty/bin/test.php --remove
[2020-03-17 11:38:35 +0100] info [xml-api]  response:
[2020-03-17 11:38:35 +0100] info [xml-api]  -- End Garbage output --
[2020-03-17 11:38:35 +0100] info [xml-api] Hook denied execution of killacct: no configuration found for VE 1078
Acquiring lock... Please wait...
Lock acquired
1 Ok
 [removeacct] version [1].
Even with nothing inside the "remove" function it fails. Any idea what could cause this?
 

cPanelTJ

Product Owner
Staff member
Jan 29, 2019
100
52
103
Houston, TX
cPanel Access Level
Root Administrator
Twitter
Hey @DennisMidjord ,

Your methods will need to return something, and that should solve your issue. Something like...

PHP:
function remove() {
    $vars = get_passed_data();
    $username = $vars['data']['user'];
    $plan = $vars['data']['plan'];
    $file = $strings = file("/etc/ftpusers");
    file_put_contents('/etc/ftpusers', print_r($vars, true) . PHP_EOL, FILE_APPEND);

    return ( 1, "Removal successful." );
}
 
  • Like
Reactions: cPanelLauren