Documentation Home> AllDocumentation>DeveloperResourcesWebHome? EditAttach

cPanel Function Hooks

ALERT! Warning: The information below is deprecated. Please see our updated function hooks documentation.

While modifying cPanel and WHM source code is prohibited by our EULA, there are many hooks in cPanel and WHM to support custom configurations.

Function Hooks

Function hooks allow you to perform an action after an API1 or API2 function is called. The data that the function outputs is the same data that the API function returns when it is called through the cPanel function in the XML API. cPanel function in the XML API.

In order to create a function hook, you must place the hook in /usr/local/cpanel/hooks/ in a subdirectory that corresponds to the module and function name you are trying to interact with. For example, if you are trying to perform an action each time an email forwarder is created by a user, you will wish to interact with the cPanel::Email::addforward function. In this case, you will need to create the following hook: /usr/local/cpanel/hooks/email/addforward

Your hook will automatically have access to the XML output of the addforward function. To see that exact XML output, call the function through the cPanel function in the XML API. In order to perform your specific actions, you'll need to interact with that XML. In the case of this function, the XML output will look similar to this:

<xml>
    <cpanelevent> 
        <errors></errors> 
        <event>listpopswithdisk</event> 
        <module>email</module> 
        <params> 1 10 
            <domain></domain> 
            <infinitylang>true</infinitylang> 
            <regex></regex> 
        </params> 
    <result> 
        <_diskquota>3000</_diskquota> 
        <_diskused&gt;0.05</_diskused> 
        <diskquota>3000</diskquota>
        <diskused>0.05</diskused> 
        <diskusedpercent>0</diskusedpercent> 0 
        <domain>testdomain.com</domain> 
        <email>test@testdomain.com</email> 
        <humandiskquota>2.93%20GB</humandiskquota> 
        <humandiskused>48.83%20KB</humandiskused> 
        <login>test@testdomain.com</login> 
        <txtdiskquota>3000</txtdiskquota> 
        <user>testdom</user> 
    </result> 
    <CPDATA>
        <BWLIMIT>5242880000</BWLIMIT> 
        <CONTACTEMAIL>testing@domain2.com</CONTACTEMAIL> 
        <DEMO>0</DEMO> 
        <DOMAIN>testdomain.com</DOMAIN> 
        <DOMAINS>sub.testdomain.com</DOMAINS> 
        <FEATURELIST>default</FEATURELIST> 
        <HASCGI>0</HASCGI> 
        <IP>192.168.1.1</IP> 
        <LANG>english</LANG> 
        <MAXADDON>5</MAXADDON> 
        <MAXFTP>0</MAXFTP> 
        <MAXLST>1</MAXLST> 
        <MAXPARK>4</MAXPARK> 
        <MAXPOP>3</MAXPOP> 
        <MAXSQL>6</MAXSQL> 
        <MAXSUB>3</MAXSUB> 
        <OWNER>root</OWNER> 
        <PLAN>5GBbasic</PLAN> 
        <RS>x3</RS> 
        <STARTDATE>1175808157</STARTDATE> 
        <USER>testdom</USER> 
    </CPDATA> 
</xml> 

You'll note that there is a section called CPDATA. This is data about the cPanel account that is available with each call.

That output resulted from running a sample script that dumps XML output to a file, like so:

#!/usr/bin/perl

my $uid = $ARGV[0];    #uid of the cPanel user

BEGIN { unshift @INC, '/usr/local/cpanel' }

use XML::Simple;
my $xmldoc;
while (<STDIN>) {
    $xmldoc .=
      $_;  #THIS DATA SHOULD NOT BE TRUSTED. IT NEEDS TO BE MADE SAFE BEFORE USE
}
chomp($xmldoc);
if ( substr( $xmldoc, 0, 1 ) ne '&lt;' || substr( $xmldoc, -1, 1 ) ne '&gt;' ) {
    die 'XML not well formed';
}    # prevent XMLin from opening a file
open FILE, "&gt; /root/sampleoutput.hook" or die "Cant open output file: $!";
print FILE $xmldoc;
close FILE;

You'll note here that the data passed to stdin in XML should not be trusted. A cPanel user could potentially attempt to inject some code in their API call which may allow for XSS or directory traversal. You should parse any XML output to ensure that it is safe, especially when using the data with SQL or performing other actions on the data.

After learning what our XML output looks like, we can now interact with the data to output the email accounts for the domain:

#!/usr/bin/perl

my $uid = $ARGV[0];    #uid of the cPanel user

BEGIN { unshift @INC, '/usr/local/cpanel' }

use XML::Simple;
my $xmldoc;
while (<STDIN>) {
    $xmldoc .=
      $_;  #THIS DATA SHOULD NOT BE TRUSTED. IT NEEDS TO BE MADE SAFE BEFORE USE
}
chomp($xmldoc);
if ( substr( $xmldoc, 0, 1 ) ne '&lt;' || substr( $xmldoc, -1, 1 ) ne '&gt;' ) {
    die 'XML not well formed';
}    # prevent XMLin from opening a file
my $dref          = XMLin($xmldoc);
my $user          = ( getpwuid($uid) )[0];
my $event         = $dref{'cpanelevent'};
my $emailaccount1 = $event->{'result'}[0]{'email'};
my $emailaccount2 = $event->{'result'}[1]{'email'};
my $errors        = $event->{'errors'};

#Be careful writing as STDOUT will be displayed in the web browser. 
#Make sure you strip out < & >'s 
#to prevent css problems and potential security issues. 
print "Email 1: $emailaccount1 ";
print "Email 2: $emailaccount2";

This custom hook simply prints out the first two email addresses associated with a domain. While it is not very useful, it is only a sample to show you how to use script hooks. Script hooks have many uses such as sending a password back to a billing system after the user changes their password, automatically notifying the server admin when a user adds a database or mailing list, automatically charging a customer when they add additional domains, etc.

Topic revision: r8 - 23 Nov 2009 - 13:42:24 - MelanieSeibert