$69 GRAYBYTE WORDPRESS FILE MANAGER $87

SERVER : premium201.web-hosting.com #1 SMP Wed Mar 26 12:08:09 UTC 2025
SERVER IP : 104.21.15.130 | ADMIN IP 216.73.217.149
OPTIONS : CRL = ON | WGT = ON | SDO = OFF | PKEX = OFF
DEACTIVATED : NONE

/opt/cloudlinux/venv/lib/python3.11/site-packages/clcagefslib/webisolation/

HOME
Current File : /opt/cloudlinux/venv/lib/python3.11/site-packages/clcagefslib/webisolation//mount_ordering.py
#!/opt/cloudlinux/venv/bin/python3 -sbb
# -*- coding: utf-8 -*-
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#
"""
Module for processing and ordering mount configurations for website isolation.

This module handles the logic for ordering mounts with proper parent-child
relationships, remounting parents after children, and adding mkdir attributes
when paths are inside tmpfs mounts.

Optimization: tmpfs mounts that are inside another tmpfs are skipped because
the parent tmpfs already makes them inaccessible.
"""

from __future__ import annotations

from dataclasses import dataclass

from .mount_config import MountEntry
from .mount_types import MountType


@dataclass(frozen=True)
class DocrootTree:
    """Pre-computed tree structure for docroots."""

    children: dict[str | None, tuple[str, ...]]
    roots: tuple[str, ...]
    all_docroots: frozenset[str]


def build_docroot_tree(all_docroots: set[str]) -> DocrootTree:
    """
    Build the parent-child tree structure from docroots.

    Call this once and pass the result to process_ordered_mounts() for each
    active docroot to avoid rebuilding the tree on every call.

    Args:
        all_docroots: Set of all docroot paths

    Returns:
        DocrootTree structure to pass to process_ordered_mounts()
    """

    def get_immediate_parent(path: str) -> str | None:
        """Get the closest parent of path that exists in all_docroots."""
        pos = path.rfind("/")
        while pos > 0:
            parent = path[:pos]
            if parent in all_docroots:
                return parent
            pos = parent.rfind("/")
        return None

    children_lists: dict[str | None, list[str]] = {p: [] for p in all_docroots}
    children_lists[None] = []  # roots
    for path in all_docroots:
        parent = get_immediate_parent(path)
        children_lists[parent].append(path)

    # Sort and convert to tuples (immutable)
    children = {k: tuple(sorted(v)) for k, v in children_lists.items()}
    roots = children[None]

    return DocrootTree(children=children, roots=roots, all_docroots=frozenset(all_docroots))


def process_ordered_mounts(
    active_docroot: str, tree: DocrootTree, uid: int, gid: int
) -> list[MountEntry]:
    """
    Process docroots and return ordered mounts list.

    Mounts are generated to a fake home directory structure. The active docroot
    is mounted from its real path to the corresponding path inside the fake home.
    Other docroots are hidden with tmpfs mounts in the fake home.

    Rules:
    1. Only one record is marked as "docroot" (the active_docroot)
    2. Parents must be mounted before children
    3. If parent is mounted first, it must be rw mount with remount to ro after all child records mounted
    4. If path is inside another path that we marked as tmpfs, we must add mkdir attribute

    Args:
        active_docroot: The docroot that should be marked as "docroot" in the output
        tree: Pre-computed DocrootTree from build_docroot_tree()
        uid: User ID for tmpfs mounts
        gid: Group ID for tmpfs mounts

    Returns:
        List of MountEntry in the correct order
    """
    children = tree.children
    tmpfs_paths = tree.all_docroots - {active_docroot}
    tmpfs_attrs = (f"uid={uid}", f"gid={gid}", "mode=0750")

    mounts: list[MountEntry] = []

    def visit(path: str, inside_tmpfs: bool):
        """Process a path and its children recursively."""
        is_tmpfs = path in tmpfs_paths
        path_children = children[path]
        has_children = bool(path_children)

        # Skip tmpfs mounts that are inside another tmpfs - they're already hidden
        # Still need to recurse in case there's an active docroot nested within
        if is_tmpfs and inside_tmpfs:
            for child in path_children:
                visit(child, inside_tmpfs=True)
            return

        # Generate mount operation
        # All mounts into fake_home need mkdir since overlay storage starts empty
        if path == active_docroot:
            mounts.append(MountEntry(MountType.BIND, path, path, ("mkdir",)))
        elif is_tmpfs:
            opts = ("mkdir",) + tmpfs_attrs if has_children else ("mkdir", "ro") + tmpfs_attrs
            mounts.append(MountEntry(MountType.BIND, "tmpfs", path, opts))
        else:
            opts = ("mkdir",) if has_children else ("mkdir", "ro")
            mounts.append(MountEntry(MountType.BIND, path, path, opts))

        # Process children
        child_inside_tmpfs = inside_tmpfs or is_tmpfs
        for child in path_children:
            visit(child, child_inside_tmpfs)

        # On leave: remount if this was a tmpfs parent with children
        if has_children and is_tmpfs:
            mounts.append(MountEntry(MountType.BIND, path, path, options=("ro", "remount")))

    # Start from roots (paths with no parent in all_docroots)
    for root in tree.roots:
        visit(root, inside_tmpfs=False)

    return mounts


Current_dir [ NOT WRITEABLE ] Document_root [ WRITEABLE ]


[ Back ]
NAME
SIZE
LAST TOUCH
USER
CAN-I?
FUNCTIONS
..
--
9 Apr 2026 8.30 AM
root / root
0755
__pycache__
--
9 Apr 2026 8.30 AM
root / root
0755
crontab
--
9 Apr 2026 8.30 AM
root / root
0755
__init__.py
0.242 KB
24 Mar 2026 9.59 AM
root / root
0644
admin_config.py
3.073 KB
24 Mar 2026 9.59 AM
root / root
0644
config.py
1.737 KB
24 Mar 2026 9.59 AM
root / root
0644
jail_config.py
2.716 KB
24 Mar 2026 9.59 AM
root / root
0644
jail_config_builder.py
6.211 KB
24 Mar 2026 9.59 AM
root / root
0644
jail_utils.py
4.928 KB
24 Mar 2026 9.59 AM
root / root
0644
libenter.py
2.227 KB
24 Mar 2026 9.59 AM
root / root
0644
mount_config.py
1.38 KB
24 Mar 2026 9.59 AM
root / root
0644
mount_ordering.py
4.96 KB
24 Mar 2026 9.59 AM
root / root
0644
mount_types.py
1.261 KB
24 Mar 2026 9.59 AM
root / root
0644
php.py
3.394 KB
24 Mar 2026 9.59 AM
root / root
0644
service.py
1.758 KB
24 Mar 2026 9.59 AM
root / root
0644
triggers.py
1.899 KB
24 Mar 2026 9.59 AM
root / root
0644

GRAYBYTE WORDPRESS FILE MANAGER @ 2025 CONTACT ME
Static GIF