Introduction
The application file contains the functions that you wish for the system to escalate.The application file performs the following steps:
- Receives and sanitizes the data.
- Authorizes the action.
- Performs the requested action.
- Returns the result.
How to write the application
You can write your AdminBin
application in any programming language. However, in cPanel & WHM version 54 and newer, we recommend that you write the file as a Perl modulino that subclasses the Cpanel::AdminBin::Script::Class
module.
- The
root
user must own the file. - You must set the file to
0700
permissions (writable, readable, and executable by owner). - You must shebang the
AdminBin
application properly, or compile it. - Store this file with the configuration file in a new namespace in the
/usr/local/cpanel/bin/admin/
directory.
- The namespace and the directory name that you create in the /
usr/local/cpanel/bin/admin/
must be identical. - For example, you could create the
TheNameSpace
namespace and/usr/local/cpanel/bin/admin/TheNameSpace
directory.
- The namespace and the directory name that you create in the /
-
The configuration file should contain the following text:
The Call Method
File
Notes:
- cPanel, Inc. introduced this functionality in cPanel & WHM version 54 for admin modules in Perl. We strongly recommend that you use this method.
- This example file uses
full
mode, which theCpanel::AdminBin::Script::Call
module requires.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
#!/usr/local/cpanel/3rdparty/bin/perl # Package the module. package MyNamespace::MyExample; # Use the strict pragma. (Manners!) use strict; #Make this module inherit from this “groundwork” admin module. #This eliminates a large swath of the boilerplate code that admin #modules used to require! use parent qw( Cpanel::AdminBin::Script::Call ); # Use any additional modules. use Cpanel::Logger (); use Cpanel::PwCache (); #Run the module as a script if (and only if) it is called that way. #This “modulino” approach helps to facilitate testing and code #reusability; for example, you could put some of this class’s methods #into a base class, then have 2 or more admin modules inherit #from that base class. __PACKAGE__->run() if ! caller ; #This special function is a “whitelist” of actions that #a caller may call. Anything not listed here cannot be called. # #By convention, these functions are named #in ALLCAPS_SNAKE_CASE. sub _actions { return qw( DEATH ECHO MIRROR BOUNCY HASHIFY ); } #If, for some reason, you want to enable an admin action for a demo account, #then list that action here. sub _demo_actions { } #------------------------ #Each “action” is its own method. #It receives the arguments in list form as they were passed #in to Cpanel::AdminBin::Call::call(). # #For example, you could call the ECHO action thusly: # #Cpanel::AdminBin::Call::call( # 'MyNamespace', # 'MyExample', # 'ECHO', # 'the string', #); # #...and ECHO would receive 'the string' as the $string argument. #----------------------- sub ECHO { my ( $self , $string ) = @_ ; return $string ; } sub MIRROR { my ( $self , $string ) = @_ ; return scalar reverse $string ; } sub BOUNCY { my ( $self , $string ) = @_ ; return _bouncy( $string ); } sub HASHIFY { my ( $self , $string ) = @_ ; return { ourdata => $string }; } sub DEATH { die 'Arrgh!' ; } #This OPTIONAL function will be called before the function invocation. # #The $metadata_hr is a hash reference that contains, as of 11.54, #a “wantarray” key that indicates the calling context: void, scalar, or list. #(cf. perldoc wantarray) # #$args_ar is the array of arguments from the caller. # #NOTE: Both of the foregoing are “live” references. Take extra care #not to modify them! # sub pre_execute_hook { my ( $self , $metadata_hr , $args_ar ) = @_ ; my $mod_name = (__PACKAGE__ =~ s<.*::><>r); Cpanel::Logger->new()-> warn ( sprintf ( "User %s called the module “%s” with the function “%s” and arguments [%s]" , $self ->get_caller_username(), $self ->get_action(), join ( q< >, @ $args_ar ), ) ); return ; #the actual return value(s) is/are ignored } sub _bouncy { my $data_in = shift ; my $data_out = q{}; for my $i ( 0 .. length ( $data_in ) - 1 ) { if ( $i % 2) { $data_out .= substr ( $data_in , $i ,1); } else { $data_out .= uc ( substr ( $data_in , $i ,1)); } } return $data_out ; } 1; |
The Standard Method
File
Warning:
Note:
This example file uses simple
mode. However, we recommend that you use full
mode whenever possible.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
#!/usr/local/cpanel/3rdparty/bin/perl use strict; use Cpanel::AdminBin::Serializer (); use Cpanel::Logger (); use Cpanel::PwCache (); my $stdin = <STDIN>; chomp $stdin ; my ( $uid , $function , $data ) = split (/ /, $stdin ,3); # sanitize the input; in this case, only alphanumeric, underscore, space, period, and exclamation are allowed $data =~ s/![\w \.\!]//g; # make a note in the logs! my $user = (Cpanel::PwCache::getpwuid($uid))[0]; my $logger = Cpanel::Logger->new(); $logger -> warn ( "Myexample called by user $user with function: $function" ); if ( $function eq 'ECHO' ) { print $data ; exit (0); } elsif ( $function eq 'MIRROR' ) { print scalar reverse ( $data ); exit (0); } elsif ( $function eq 'BOUNCY' ) { print _bouncy( $data ); exit (0); } elsif ( $function eq 'HASHIFY' ) { print ".\n" . Cpanel::AdminBin::Serializer::Dump ({ 'ourdata' => $data } ); exit (0); } else { print "Invalid function specified to MyExample adminbin function" ; exit (1); } 1; sub _bouncy { my $data_in = shift ; my $data_out = q{}; for my $i (0.. length ( $data_in )-1) { if ( $i % 2) { $data_out .= substr ( $data_in , $i ,1); } else { $data_out .= uc ( substr ( $data_in , $i ,1)); }} return $data_out ; } |
Parameters
The parameter order that the system passes to the Cpanel::Wrap::send_cpwrapd_request
method is constant. However, some parameters' behavior depends on the configuration file's mode
value.
Parameter |
Type |
Description |
Possible values |
Example |
version |
string |
Always set this value toCpanel::AdminBin::Serializer::VERSION |
Cpanel::AdminBin::Serializer::VERSION |
Cpanel::AdminBin::Serializer::VERSION |
uid |
integer |
Required The authenticated user's user ID. The system passes this value automatically. Note: The configuration file's mode value determines this parameter's behavior.
|
A valid system user ID. |
1000 |
stream |
string |
A filehandle to which the system streams the application's output. Warning: Only use this parameter if you set the action parameter to stream. |
A valid filehandle. |
Filehandle |
namespace |
string |
Required The application's namespace. |
The application's namespace. This value is identical to the directory name. |
NameSpace |
module |
string |
Required The application's filename. |
The application file's filename. |
Example |
function |
string |
Required The application's pseudo-function.
Error rendering macro 'multiexcerpt-include' : null
|
A valid string. |
ECHO |
env |
hash reference |
Required A hash reference of keys and values to set in the environment before the AdminBinapplication executes. |
|
WHM50 |
data |
scalar or data structure |
Required The data to process.
Error rendering macro 'multiexcerpt-include' : null
|
|
data |
action |
string |
Required The output's behavior. Notes:
|
run |