We really have no information available on how to write WHM Plugins.  I have had 3 people ask me in the past 48 hours on how to write them, so I thought I might want to consolidate and post this knowledge.  A WHM plugin is merely a simple CGI application that has a couple of special comments in it to handle how it is displayed.  Any CGI language can be used here, however only perl will allow you access to some special functions that make permission handling much easier.

All WHM plugins must be placed at /usr/local/cpanel/whostmgr/docroot/cgi and must be prefixed with addon_ and end with .cgi.  These must be owned by root:root and be globally readable/executable (755), so don’t store any access credentials in these scripts – have them load from other files that are root-readable only.

As I mentioned earlier, there are a couple of special comments that need to be placed inside of WHM Addons.  The first one of these is the WHMADDON comment which sets how the plugin will be displayed in WHM:
#WHMADDON:appname:Display Name

Where it says appname it should be replaced with the actual file name of the application excluding addon_ and .cgi, so if you have addon_test.cgi, this would contain “test”.  Display Name refers to what well be displayed under the “Plugins” header of WHM.  An example of how a #WHMADDON should look for an application named “Sample Test App” would be:
#WHMADDON:test:Sample Test App

There are two parts to ACLs with WHM Plugins, that control who can display it and who can access it.  The ACLS comment controls who will see the ACL in the Plugins section of WHM.  Then there is actually enforcing the ACL which is done via the Whostmgr::ACLS perl module.  If you are not familiar with what ACLs mean in the context of WHM, these refer to the permissions that the reseller has to various aspects in WHM such as the ability to create accounts or edit DNS zones.  These are indicated by a string like “list-accts” or “all”, you can view a list of these ACLs in /usr/local/cpanel/Whostmgr/ACLS.pm.  You can see what permissions a reseller has by looking at the /var/cpanel/resellers file.

Using the ACLS comment is pretty straight forward.  You simply add #ACLS:<acl name>, this only controls which users will see the plugin in the WHM Plugins section.  If this is not set it will be viewable by ALL resellers.

With this ACL in place, only reseller accounts that have access to the list-accts ACL will be able to view this plugin.

The other type of ACL actually enforces permissions.  When this is not set, any reseller can visit cgi/addon_APPNAME.cgi and execute the application with root permissions, so this is a very critical step in WHM Plugin development.

Inside of our product, we provide a module for performing this type of check called Whostmgr::ACLS.  This module has various functions relating to how ACLs work, but the only function we are concerned with is the checkacl() function.  This operates by being passed an acl name and returning 1 or 0 depending on whether the user has access to this ACL or not.  So if passed the “all” ACL (which is indicative of “root” access) and a reseller without root access tried to access the addon script, it would return 0.  This module requires some setup, since it is located outside of perl’s normal include path, /usr/local/cpanel has to be added to the include path using “use lib”.  Also this module has a constructor called “init_acls()” that has to be called.  As an example, here’s a chunk of code that will check for the “all” (root) acl and print ‘access denied” if the reseller accessing the script does not have permission to do so.
use lib '/usr/local/cpanel/';

use Whostmgr::ACLS ();


if ( !Whostmgr::ACLS::checkacl( ‘list-accts’ ) ) {

print “Access Denied”;



Of course, this will only work when this is run inside of a perl script.  Inside of a PHP script /var/cpanel/resellers will have to be parsed manually.  If someone asks nicely, I may write this for you.

That should cover the basics of writing WHM plugins, there are of course other finer aspects of WHM plugins that can be gone into, however this covers the entire concept.