Mini Shell

Direktori : /proc/self/root/usr/share/cagefs/
Upload File :
Current File : //proc/self/root/usr/share/cagefs/clean_user_php_sessions

#!/opt/cloudlinux/venv/bin/python3 -bb

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import *
import os
import sys
import glob
import secureio
from clcommon import login_defs
from future.utils import iteritems, itervalues
sys.path.append('/usr/share/cagefs')
from cagefslib import (
    clean_dir_from_old_session_files,
    get_opts_from_php_ini, get_alt_dirs,
    is_clean_user_php_sessions_enabled
)
from clcagefslib.domain import (
    get_docroots_of_isolated_websites,
    is_website_isolation_allowed_server_wide
)
from clcagefslib.webisolation.jail_utils import website_suffix_with_hash

VERSIONS = {}
EA_PATH = "/opt/cpanel/%s/root/etc/"
ALT_PATH = "/opt/alt/%s/etc/php.ini"

# default period 1440 sec = 24 min
_DEFAULT_TIMEOUT = 1440


def init_versions():
    global VERSIONS
    versions = lambda l: [os.path.basename(p) for p in l]
    if len(VERSIONS) == 0:
        VERSIONS["EA"] = versions(glob.glob("/etc/scl/prefixes/ea-php[0-9]*"))
        VERSIONS["ALT"] = get_alt_dirs()
    return VERSIONS


def get_ea_versions():
    versions = init_versions()
    return versions["EA"]


def get_alt_versions():
    versions = init_versions()
    return versions["ALT"]


def clean_user(pwnam, paths):
    """
    Drop permissions to given user and clean all session files given with paths dict
    :param object pwnam: pwnam object for some system user
    :param dict paths: looks like {"path": maxlifetime} where path is str and maxlifetime is int
    """
    # Drop permissions
    res = secureio.set_user_perm(pwnam.pw_uid, pwnam.pw_gid, exit=False)
    if res == -1:
        return

    for path, mlt in paths.items():
        dir_path = os.path.join(pwnam.pw_dir, ".cagefs", path.lstrip("/"))
        clean_dir_from_old_session_files(dir_path, mlt)

    # get back root permissions
    secureio.set_root_perm()


def main():
    if not is_clean_user_php_sessions_enabled():
        sys.exit(0)
    paths = {}

    def patch_paths(ini_path, default_path="/tmp", version_key=None):
        (path, mlt) = get_opts_from_php_ini(ini_path, _DEFAULT_TIMEOUT, default_path)
        if path is None or mlt is None:
            return
        if path in paths and paths[path] > mlt:
            paths[path] = mlt
        elif paths.get(path) is None:
            paths[path] = mlt

        # cleanup sessions for isolated websites
        if is_website_isolation_allowed_server_wide():
            isolated_websites_pairs = get_docroots_of_isolated_websites()
        else:
            isolated_websites_pairs = dict()
        for isolated_docroots in isolated_websites_pairs.values():
            # websites/<document_root_hash>/<version_path>
            for dr in isolated_docroots:
                website_isolation_path_rel = website_suffix_with_hash(dr)
                paths[f"{website_isolation_path_rel}/home/.cagefs/{path}"] = mlt


    for ea_php in get_ea_versions():
        _path = EA_PATH % ea_php
        # Since cPanel 65.9999, etc/php.d/local.ini is located now in etc/php.ini
        old_cpanel_path = os.path.join(_path, "php.d/local.ini")
        new_cpanel_path = os.path.join(_path, "php.ini")
        if os.path.exists(old_cpanel_path):
            ea_path = old_cpanel_path
        else:
            ea_path = new_cpanel_path
        patch_paths(ea_path, version_key=ea_php)

    for alt_php in get_alt_versions():
        alt_ini = ALT_PATH % alt_php
        patch_paths(alt_ini, version_key='alt-' + alt_php)

    min_uid = int(login_defs('UID_MIN', 500))
    for pwnam in secureio.clpwd.get_user_dict().values():
        if pwnam.pw_uid >= min_uid:
            clean_user(pwnam, paths)


if __name__ == "__main__":
    main()