#!/opt/imh-python/bin/python3
Quickly and accurately return the document root of a given domain
owned by the current cPanel user as reported by cPanel userdata
from getpass import getuser
def load_yaml(filename, exit_on_fail=False):
return yaml object from filename and
handle exceptions according exit_on_fail
with open(filename) as f:
sys.exit("Could not read file: %s" % filename)
return yaml.load(yaml_text, Loader=yaml.SafeLoader)
except yaml.YAMLError as err:
sys.exit(f"Unable to parse YAML from {filename}:\n{err}")
def get_docroot(user, vhost, exit_on_fail=False):
Get the full path to a domain/vhost's document root.
If exit_on_fail is True, the process will exit upon failure
This is in place for use as a module
If disabled, throws: yaml.YAMLError, IOError,
sys.exit("cPanel user was not specified")
raise ValueError("User must have value")
sys.exit("Domain was not specified")
raise ValueError("vhost must have value")
# We process everything in lowercase to avoid casing issues
userdata_file = "/var/cpanel/userdata/%s/main" % user
userdata = load_yaml(userdata_file, exit_on_fail)
if vhost.startswith("www."):
# This check is in defense against a subdomain
# "www.example.domain.com" which may or may not be possible, but we
# do not want to risk the confusion.
if vhost not in userdata["sub_domains"]:
# Otherwise, strip the first "www" from vhost
vhost = vhost.split("www.", 1)[1]
# locate the data file that contains vhost information
if userdata["main_domain"] == vhost or vhost in userdata["sub_domains"]:
domain_datafile = f"/var/cpanel/userdata/{user}/{vhost}"
elif vhost in userdata["parked_domains"]:
domain_datafile = "/var/cpanel/userdata/{}/{}".format(
user, userdata["main_domain"]
elif vhost in userdata["addon_domains"]:
domain_datafile = "/var/cpanel/userdata/{}/{}".format(
user, userdata["addon_domains"][vhost]
sys.exit("Unable to find vhost in userdata")
domain_data = load_yaml(domain_datafile, exit_on_fail)
# Double check this file actually contains our vhost
if domain_data["servername"] == vhost or re.search(
"(^| )%s( |$)" % vhost, domain_data["serveralias"]
return domain_data["documentroot"]
f"Something is wrong, the domain was not found in {domain_datafile}"
def whoowns(domain, exit_on_fail=False):
Implement whoowns without forcing a fork.
with open("/etc/userdomains") as f:
userdomains = f.read().splitlines()
sys.exit("Could not read file: /etc/userdomains")
for userdomain in userdomains:
split = userdomain.partition(": ")
sys.exit("Domain not found in /etc/userdomains")
if len(argv) < 2 or argv[1] is None or "-h" in argv or "--help" in argv:
"""Usage: docroot.py domain
Quickly and accurately return the document root of a given domain
owned by the current cPanel user as reported by cPanel userdata"""
# strip protocol, perform basic validation
validation_result = re.match(
r"^(https?://)?([^/]+\.[^/]+)/?$", argv[1], re.I
vhost = validation_result.group(2)
sys.exit("Invalid domain/vhost specified")
user = whoowns(vhost, exit_on_fail=True)
print(get_docroot(user, vhost, exit_on_fail=True))
if __name__ == "__main__":