Sindbad~EG File Manager

Current Path : /opt/cloudlinux/venv/lib/python3.11/site-packages/xray/reconfiguration/
Upload File :
Current File : //opt/cloudlinux/venv/lib/python3.11/site-packages/xray/reconfiguration/global_ini.py

# -*- 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/LICENSE.TXT
import logging
import os
from contextlib import suppress
from glob import iglob
from typing import Tuple
from secureio import disable_quota

from xray.internal.utils import user_context
from xray.reconfiguration.xray_ini import (
    INI_LOCATIONS,
    INI_USER_LOCATIONS,
    INI_USER_LOCATIONS_WEBSITE_ISOLATION,
    is_excluded_path
)

logger = logging.getLogger()

GLOBAL_INI_MARKER = '/opt/cloudlinux/flags/enabled-flags.d/xray-ini-global-mode.flag'


# Try to import website isolation check from securelve (cagefs)
try:
    from clcagefslib.domain import is_website_isolation_allowed_server_wide
except ImportError:
    def is_website_isolation_allowed_server_wide():
        return False



def _iter_existing_ini_locations() -> Tuple[Tuple[int, int], str]:
    """
    Generator of existing paths (matching known wildcard locations)
    for additional ini files
    Returns tuple of (uid, gid) and path.
    """
    for location in INI_LOCATIONS:
        for dir_path in iglob(location):
            if is_excluded_path(dir_path):
                continue
            yield (0, 0), dir_path

    for location in INI_USER_LOCATIONS:
        for dir_path in iglob(location['path']):
            if is_excluded_path(dir_path):
                continue

            try:
                pw_record = location['user'](dir_path)
            except:
                logger.info('Unable to get information about user '
                            'owning %s directory (maybe he`s already terminated?), '
                            'skip updating', dir_path)
                continue
            else:
                yield (pw_record.pw_uid, pw_record.pw_gid), dir_path

    # Copy to per-website directories
    # (only when path exists! which means per website php selector is set)
    if is_website_isolation_allowed_server_wide():
        for location in INI_USER_LOCATIONS_WEBSITE_ISOLATION:
            for dir_path in iglob(location['path']):
                if is_excluded_path(dir_path):
                    continue

                try:
                    pw_record = location['user'](dir_path)
                except:
                    logger.info('Unable to get information about user '
                                'owning %s directory (maybe he`s already terminated?), '
                                'skip updating', dir_path)
                    continue
                else:
                    yield (pw_record.pw_uid, pw_record.pw_gid), dir_path


def _create_single_ini(uid: int, gid: int, ini_path: str):
    # write counter of tasks so during mode switch
    # we can still safely cleanup ini files not
    # bound to any exiting tasks
    ini_content = ';xray.tasks=0\nextension=xray.so'

    path = os.path.join(ini_path, 'xray.ini')
    if os.path.exists(path):
        return

    with user_context(uid, gid), \
            disable_quota(), \
            open(path, 'w') as ini:
        logger.info('Generating %s file...', path)
        ini.write(ini_content)


def is_global_ini_mode():
    return os.path.exists(GLOBAL_INI_MARKER)


def create_global_ini_mode_marker():
    open(GLOBAL_INI_MARKER, 'w').close()


def remove_global_ini_mode_marker():
    with suppress(FileNotFoundError):
        os.remove(GLOBAL_INI_MARKER)


def create_ini_files() -> None:
    """
    Place xray.ini into each existing Additional ini path,
    including cagefs ones.
    """
    logger.info('Generating xray.ini files...')
    for (uid, gid), ini_path in _iter_existing_ini_locations():
        try:
            _create_single_ini(uid, gid, ini_path)
        except PermissionError:
            logger.warning('Unable to update file %s, '
                           'possible permission misconfiguration', ini_path)
            continue
        except Exception as e:
            logger.warning('Unexpected error happened during file processing: '
                           '"%s", error: "%s"', ini_path, str(e), exc_info=True)
            continue
    logger.info('Finished!')


def remove_ini_files() -> None:
    """
    Remove all gathered clos_ssa.ini files
    """
    logger.info('Removing clos_ssa.ini files...')
    for (uid, gid), clos_ini_dir in _iter_existing_ini_locations():
        ini_file = os.path.join(clos_ini_dir, 'xray.ini')
        try:
            with user_context(uid, gid), open(ini_file) as f:
                contents = f.read()

                # unlink file only if there are no linked tasks
                # case with minus sign covers negative values
                if "xray.tasks=0" in contents or \
                        "xray.tasks=-" in contents:
                    os.unlink(ini_file)
        except FileNotFoundError:
            continue
        except Exception as e:
            logger.warning('Unable to remove file: "%s", error: "%s"', ini_file, str(e))
            continue

    logger.info('Finished!')

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists