Child pages
  • Guide to API Privilege Escalation - Call Your Application
Skip to end of metadata
Go to start of metadata

 

Introduction

To use your AdminBin application, call the appropriate method. The method to use depends on the target cPanel & WHM version, and whether you used the Cpanel::AdminBin::Script::Call module.

Application call methods

Select a tab below to view the recommended method for your target cPanel & WHM versions.

Note:

cPanel, Inc. introduced this functionality in cPanel & WHM version 54 for admin modules in Perl.

To use your AdminBin application, call the Cpanel::AdminBin::Call::call function. This function passes your arguments to the AdminBin module. It is intended only for those admin modules that subclass the Cpanel::AdminBin::Script::Call class; to call other admin modules, use The Standard Method.

Example

The following example demonstrates how to use this functionality within a Perl script:

#!/usr/local/cpanel/3rdparty/bin/perl
 
use Data::Dumper ();
 
use Cpanel::AdminBin::Call ();
 
sub do_MyExample_stuff {
    my $thing_to_do = shift;
    my $string_to_mess_with = shift;
 
	#Prevent potential action-at-a-distance bugs.
	#(cf. documentation for CPAN's Try::Tiny module)
	local $@;

	my $val;
 
	#NOTE: call() will throw an exception if there was an error
	#while communicating with the admin module or if an exception
	#escaped from a method call within the admin module.
	my $ok = eval {
		$val = Cpanel::AdminBin::Call::call(
			'MyNamespace',
			'MyExample',
			$thing_to_do,
			$string_to_mess_with,
		);

		1;
	};

	if ($ok) {
		return ref($val) ? Data::Dumper::Dumper($val) : $val;
	}

	my $err = $@;
	return "Error: $err";
}
 
print "Content-type: text/html\r\n\r\n";

print "<pre>";

print "ECHO test:\n" . do_MyExample_stuff("ECHO","Hello, World!") . "\n\n";
print "MIRROR test:\n" . do_MyExample_stuff("MIRROR","Hello, World!") . "\n\n";
print "BOUNCY test:\n" . do_MyExample_stuff("BOUNCY","Hello, World!") . "\n\n";
print "HASHIFY test:\n" . do_MyExample_stuff("HASHIFY","Hello, World!") . "\n\n";
print "WRONG test:\n" . do_MyExample_stuff("WRONG","Hello, World!") . "\n\n";
 
print "DEATH test:\n" . do_MyExample_stuff("DEATH") . "\n\n";
 
print "test complete!\n"; 

In the same directory as the MyExample module file, you must create the MyExample.conf configuration file with the following contents:

mode=full

For more information about the configuration file, read our Configuration Files documentation.

To use your AdminBin application, call the Cpanel::Wrap::send_cpwrapd_request method. This method passes your arguments and parameters into the application via STDIN.

  • Your subroutines are private to the AdminBin application. User-level code that calls the Cpanel::Wrap::send_cpwrapd_request method cannot access these subroutines because AdminBin applications execute in a separate process.
  • The AdminBin application receives a pseudo-function name as the second argument. 
    • Use the pseudo-function name to determine the code path to execute in your AdminBin application. 
    • The simplest way to implement this is an IF block.

Example

The following LiveAPI example uses this functionality within the Perl environment.

#!/usr/local/cpanel/3rdparty/bin/perl 
 
BEGIN {
    unshift @INC, '/usr/local/cpanel';
}
 
use Cpanel::LiveAPI ();
use Data::Dumper    ();
use Cpanel::Wrap    ();
 
sub do_MyExample_stuff {
    my $thing_to_do = shift;
    my $string_to_mess_with = shift;
  
    my $result = Cpanel::Wrap::send_cpwrapd_request(
        'namespace' => 'MyNamespace',
        'module'    => 'MyExample',
        'function'  => $thing_to_do,
        'data'      => $string_to_mess_with
    );
 
    if ( $result->{'error'} ) {
        return "Error code $result->{'exit_code'} returned: $result->{'data'}";
    }
    elsif ( ref ( $result->{'data'} ) ) {
        return Data::Dumper::Dumper($result->{'data'});
    }
    elsif ( defined( $result->{'data'}) ) {
        return $result->{'data'};
    }
    return 'cpwrapd request failed: ' . $result->{'statusmsg'};
}
 
my $cpanel = Cpanel::LiveAPI->new();
 
print "Content-type: text/html\r\n\r\n";
 
print "<pre>";
 
print "ECHO test:\n".do_MyExample_stuff("ECHO","Hello, World!")."\n\n";
print "MIRROR test:\n".do_MyExample_stuff("MIRROR","Hello, World!")."\n\n";
print "BOUNCY test:\n".do_MyExample_stuff("BOUNCY","Hello, World!")."\n\n";
print "HASHIFY test:\n".do_MyExample_stuff("HASHIFY","Hello, World!")."\n\n";
print "WRONG test:\n".do_MyExample_stuff("WRONG","Hello, World!")."\n\n";
  
print "test complete!\n";
$cpanel->end();

Returns

The system sends returns from the AdminBin application via STDOUT and processes them through the AdminBin server. The system returns them via the Cpanel::Wrap::send_cpwrapd_request method.

  • The system may return data in the form of a data structure or a scalar value.
  • If the AdminBin application returns a data structure, it must serialize the output with either the Cpanel::AdminBin::Serializer::Dump module, or in the JSON format.
    • You must prefix serialized output with a period and a newline (.\n) before you send the serialized data. 
    • When the AdminBin server receives a period and a newline, it automatically treats the data as serialized and processes it with the Cpanel::AdminBin::Serializer::Load module.

Example Cpanel::AdminBin::Script::Call output

 Click to view a successful output...
{
         'statusmsg' => 'Ran AdminBin MyNamespace/MyExample/HASHIFY',
         'version' => '2.3',
         'status' => 1,
         'mode' => 'simple',
         'data' => {
                     'ourdata' => 'Hello, World!'
                   },
         'exit_code' => 0,
         'timeout' => 0,
         'action' => 'fetch',
         'error' => 0
};
 Click to view a failure...
{
          'statusmsg' => 'Ran adminbin MyNamespace/MyExample/WRONG',
          'version' => '2.3',
          'status' => 1,
          'mode' => 'simple',
          'data' => 'Invalid function specified to MyExample adminbin function',
          'exit_code' => 256,
          'timeout' => 0,
          'action' => 'run',
          'error' => 1
}