Can't get account's primary/main domain name

skyd

Member
Sep 6, 2012
6
1
3
cPanel Access Level
Website Owner
Hi, I followed the advice by cPanelDavidN on how to get an account's main domain name:
http://forums.cpanel.net/f42/how-ge...nt-cpanel-api-thro-2082-2083-port-207572.html

The code is something like:
https://$server:2083/xml-api/cpanel?cpanel_xmlapi_module=print&cpanel_xmlapi_apiversion=1&arg-0=%24CPDATA%7B%27DOMAIN%27%7D

But I get the following error:
"Remote execution of internal functions is not permitted in api1"

Seems like 'print' is an internal module, which is blocked on the server I'm trying to access.

Is there any other, public, API/way to get the main domain's name?

Thank you.

P.S.: What causes the above 'print' call to fail?
 

KostonConsulting

Well-Known Member
Verifed Vendor
Jun 17, 2010
255
1
68
San Francisco, CA
cPanel Access Level
Root Administrator
Looks like this error is compiled into cpsrvd (cPanel's web server). I'd normally find it in one of their uncompiled modules by searching these locations:

Code:
[/usr/local/cpanel/Cpanel]# grep -R 'Remote execution of internal functions' *
[/usr/local/cpanel/Cpanel]# cd ../bin
[/usr/local/cpanel/bin]# grep -R 'Remote execution of internal functions' *
Now, we know the main page of cPanel prints out the main domain, so I looked at the source code for what prints that. Looks like they are using CPDATA{'DNS'}:

Code:
[/usr/local/cpanel/base/frontend/x3/branding]# grep 'CPDATA' index.html 
                      var thisTheme = '<cpanel print="$CPDATA{'RS'}">';
here ------>     <td class="stats_right"><b><cpanel print="$CPDATA{'DNS'}"></b></td>
		     <cpanelif !$CPDATA{'DEMO'}>
I'm aware of 2 ways to get this info locally:

%ENV (perl) $_ENV (php) contains this info:

PHP example:
Code:
$main_domain = getenv('DNS');
In Perl, you can also use this:
Code:
BEGIN{ unshift(@INC, '/usr/local/cpanel'); }

use Cpanel::AcctUtils::Domain ();

my $main_domain = Cpanel::AcctUtils::Domain::getdomain( $user );
However, those are only valid if your script is running on the server itself. If you need to get this information remotely, I suggest adding your own API2 call.

Drop this module into /usr/local/cpanel/Cpanel/MainDomain.pm (or whatever.pm but change package Cpanel::MainDomain to Cpanel::whatever if you change the name):

Code:
#!/usr/bin/perl
#
#  MainDomain -- gets the main domain from a cPanel user's account
#
#  Created by David Koston (dave at kostonconsulting dot com) on 2013-06-14.
#  No warranty of any kind provided.
#

package Cpanel::MainDomain;

BEGIN { push( @INC, '/usr/local/cpanel' ); }
use strict;
use Cpanel::AcctUtils::Domain ();


sub api2 {
    my $func = shift;
    my %API;

    $API{'get'}{'func'}   = "api2_get";
    $API{'get'}{'engine'} = 'hasharray';

    return \%{ $API{$func} };
}

sub api2_get {
    my %OPTS = @_;

	my $return_hash = {
		status => 0,
		message => '',
		domain => '',
	};
	my $user;
	
	if( $OPTS{'user'} ){
		$user = isCpanelUsername( $OPTS{'user'} ) ? $OPTS{'user'} : '';
	}else{
		$user = $ENV{'REMOTE_USER'};
	}
	
	if( $user eq '' ){
		$return_hash->{message} = 'Invalid or empty {&user=} parameter';
	}


	my $domain = Cpanel::AcctUtils::Domain::getdomain( $user );
	if( $domain ){
		$return_hash->{status} = 1;
		$return_hash->{domain} = $domain;
		$return_hash->{message} = 'Success';
	} 


    return $return_hash;
}


sub isCpanelUsername {
    unless ( $_[0] ) { return 0; }
    return $_[0] =~ /^[a-zA-Z][a-zA-Z0-9\-]{0,7}$/
      ? 1
      : 0;                                               #alpha-numeric + dashes. starts with letter, max 8 chars
}

1;
Call the API function:
Code:
https://webserver.com:2083/cpsess2517447623/json-api/cpanel?cpanel_jsonapi_module=MainDomain&cpanel_jsonapi_func=get
and you'll get a result like:

Code:
{"cpanelresult":{"data":[{"domain":"domainname.com","status":1,"message":"Success"}],"func":"get","apiversion":2,"event":{"result":1},"module":"MainDomain"}}
You can also call it via the WHM api with a specific user=$user URL variable if you find that useful.

Sorry for any extra info. Added here as it may be useful for others looking to find out how to track this stuff down.
 

skyd

Member
Sep 6, 2012
6
1
3
cPanel Access Level
Website Owner
I was afraid that this reply.. The reason is that I do not have direct access to the server.
Nonetheless - Thank you for the comprehensive answer!

The error doesn't occur on just any server, rather in specific cases.
So far, my fallback option is exactly to try and parse the domain name from cPanel's home page.

I'd be happy to get this variable via an API call if possible.

Until then, the PHP code I use looks something like this:
PHP:
function getMainDomain( $cPanelHomePageContent )
{
	$value = null;
	$regexPattern = '|Main Domain\s*(?:<[^>]+>\s*)+([^<]+)|';
	$found = preg_match( $regexPattern, $cPanelHomePageContent, $matches );
	if ( $found === 1 )
	{
		$value = $matches[1];
	}

	return $value;
}

  • This code relies on the x3 theme
 

KostonConsulting

Well-Known Member
Verifed Vendor
Jun 17, 2010
255
1
68
San Francisco, CA
cPanel Access Level
Root Administrator
Np. With a little more thought, I believe you can use the DomainLookup::getdocroots() api2 call and look for the domain that has the document root of /home/$user/public_html as that's what cPanel believes is the main domain. That may be a little more stable as people may have branding or customer changes to x3 that could hurt pattern matching.
 

skyd

Member
Sep 6, 2012
6
1
3
cPanel Access Level
Website Owner
This is a good direction, indeed more robust. However, the root of a parked domain, for example, may also direct to /home/user/public_html.

To be on the safe side, I'll need to pull the domain of all types (addon/parked/sub) and eliminate any of them which point to the public_html.

Thank you.
 
  • Like
Reactions: KostonConsulting

DeusEx

Registered
Aug 18, 2013
1
0
1
cPanel Access Level
Root Administrator
This can be done a lot easier. All you need to - get a list of other domains using API2 AddonDomain :: listaddondomains()
PHP:
<?xml version="1.0" ?>
  <cpanelresult>
    <apiversion>2</apiversion>
    <data>
      <basedir>public_html/demodemo.com</basedir>
      <dir>/home/asdasdaf/public_html/demodemo.com</dir>
      <domain>demodemo.com.com</domain>
      <domainkey>demodemo.com_rootdomainame.com</domainkey>
      <fullsubdomain>demodemo.com.rootdomainame.com</fullsubdomain>
      <reldir>home:public_html/demodemo.com</reldir>
      <rootdomain>rootdomainame.com</rootdomain>
      <status>not redirected</status>
      <subdomain>demodemo.com</subdomain>
    </data>
    <event>
      <result>1</result>
    </event>
    <func>listaddondomains</func>
    <module>AddonDomain</module>
  </cpanelresult>
Of course the user must have at least one additional domain.