Mini Shell
Direktori : /opt/sharedrads/ |
|
Current File : //opt/sharedrads/docroot.py |
#!/opt/imh-python/bin/python3
"""
@noaha
Quickly and accurately return the document root of a given domain
owned by the current cPanel user as reported by cPanel userdata
"""
import yaml
from getpass import getuser
from sys import argv
import sys
from os import geteuid
import re
def load_yaml(filename, exit_on_fail=False):
"""
return yaml object from filename and
handle exceptions according exit_on_fail
"""
try:
with open(filename) as f:
yaml_text = f.read()
except OSError:
if exit_on_fail:
sys.exit("Could not read file: %s" % filename)
else:
raise
try:
return yaml.load(yaml_text, Loader=yaml.SafeLoader)
except yaml.YAMLError as err:
if exit_on_fail:
sys.exit(f"Unable to parse YAML from {filename}:\n{err}")
else:
raise
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,
"""
if not user:
if exit_on_fail:
sys.exit("cPanel user was not specified")
raise ValueError("User must have value")
if not vhost:
if exit_on_fail:
sys.exit("Domain was not specified")
raise ValueError("vhost must have value")
# We process everything in lowercase to avoid casing issues
vhost = vhost.lower()
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]
)
else:
if exit_on_fail:
sys.exit("Unable to find vhost in userdata")
return None
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"]
if exit_on_fail:
sys.exit(
f"Something is wrong, the domain was not found in {domain_datafile}"
)
return None
def whoowns(domain, exit_on_fail=False):
"""
Implement whoowns without forcing a fork.
"""
try:
with open("/etc/userdomains") as f:
userdomains = f.read().splitlines()
except OSError:
if exit_on_fail:
sys.exit("Could not read file: /etc/userdomains")
else:
raise
for userdomain in userdomains:
split = userdomain.partition(": ")
if split[0] == domain:
return split[2]
sys.exit("Domain not found in /etc/userdomains")
def main():
if len(argv) < 2 or argv[1] is None or "-h" in argv or "--help" in argv:
sys.exit(
"""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
)
if validation_result:
vhost = validation_result.group(2)
else:
sys.exit("Invalid domain/vhost specified")
if geteuid() == 0:
user = whoowns(vhost, exit_on_fail=True)
else:
user = getuser()
print(get_docroot(user, vhost, exit_on_fail=True))
if __name__ == "__main__":
main()
Zerion Mini Shell 1.0