Mini Shell

Direktori : /usr/share/cagefs/
Upload File :
Current File : //usr/share/cagefs/virtmp_mount.py

# -*- coding: utf-8 -*-
# Detection mount points for different control panels
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
#
#Redistribution and use in source and binary forms, with or without
#modification, are permitted provided that the following conditions
#are met:
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * The names of its contributors may not be used to endorse or
#    promote products derived from this software without specific
#    prior written permission.
#
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
#LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
#ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#POSSIBILITY OF SUCH DAMAGE.
#

# For Plesk 10.0 .. 11.5+ detection:
#
# for all system users:
#  - user domain/subdomains dirs
#  - statistics dirs
#  - php.ini dirs
#
# Retrieved data writes to user's personal virt.mp files

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 tempfile

import cagefslib
import cldetectlib
import cagefsreconfigure
from clcommon import ClPwd, mysql_lib

# Path to user config files
import secureio

PATH_TO_USER_FILES = '/var/cagefs/'


def get_data_list(plesk_main_dir, domain_names, user_home_dir):
    home_dir_parts = os.path.split(user_home_dir)
    is_home_dir_plesk = home_dir_parts[0] == plesk_main_dir

    ret_names = ['>'+plesk_main_dir]
    for domain_name in domain_names:
        if not is_home_dir_plesk or (is_home_dir_plesk and domain_name != home_dir_parts[1]):
            ret_names.append('@' + domain_name)

    return ret_names


# Create mount points for Plesk 10.0+
def get_plesk_user_mounts(domain_names, plesk_ver_major, plesk_ver_minor, user_home_dir):
    if plesk_ver_major == 10 or (plesk_ver_major == 11 and plesk_ver_minor == 0):
        # Plesk 10.0 to 11.0 (including)
        # For Plesk 10.0 to 10.4 (not incl 10.4):
        # /var/www/vhosts/<domain> - main domain and sub-domains files
        # /var/www/vhosts/<add-on domain> - sub-domains options files
        # For Plesk 10.4 (incl) .. 11.0 (incl):
        # /var/www/vhosts/<domain> - files only for main domain
        # Add- and subdomains:
        # /var/www/vhosts/<add-on domain>
        # /var/www/vhosts/<subdomain>
        plesk_main_dir = cagefslib.PLESK_VHOSTS_D
    else:
        # Plesk 11.5+
        # Dirs descriptions
        # /var/www/vhosts/system/<domain>
        # /var/www/vhosts/system/<add-on domain>
        # /var/www/vhosts/system/<subdomain>
        plesk_main_dir = os.path.join(cagefslib.PLESK_VHOSTS_D, 'system')

    ret_names = get_data_list(plesk_main_dir, domain_names, user_home_dir)
    if len(ret_names) == 1:
        return None
    return ret_names


def scan_plesk_user_domains(system_users_data, plesk_ver_major, plesk_ver_minor):
    # system_users_data - dictionary
    # key - username
    # value - user_prefix;user_home_dir
    user_name_list = list(system_users_data.keys())

    # read password
    f = open('/etc/psa/.psa.shadow', 'r')
    password = f.readline().strip()
    f.close()

    sql_query = ("SELECT sys_users.login, domains.name FROM sys_users, hosting, domains "
                 "WHERE domains.id = hosting.dom_id AND (hosting.sys_user_id = sys_users.id "
                 "OR hosting.sys_user_id = sys_users.mapped_to)")
    args = None

    if len(user_name_list) == 1:
        sql_query += " AND sys_users.login = %s;"
        args = (user_name_list[0],)

    connector = mysql_lib.MySQLConnector(host="localhost", user="admin",
                                         passwd=password, db="psa")
    with connector.connect() as db:
        data = db.execute_query(sql_query, args=args)

    domains_by_uid = {}
    # {uid: [domains]} example:  {10000: ['domain.com'], 10001: ['domain1.com', 'domain2.com']}
    clpwd_instance = ClPwd()
    for dom in data:
        user_name = dom[0]
        domain_name = dom[1]
        try:
            uid = clpwd_instance.get_uid(user_name)
        except ClPwd.NoSuchUserException:
            continue
        if uid in domains_by_uid:
            if domain_name not in domains_by_uid[uid]:
                domains_by_uid[uid].append(domain_name)
        else:
            domains_by_uid[uid] = [domain_name]

    # scan all system users
    for user_name in user_name_list:
        prefix = system_users_data[user_name][0]
        user_home_dir = system_users_data[user_name][1]
        uid = clpwd_instance.get_uid(user_name)
        if uid in domains_by_uid:
            # This is a Plesk user

            # path to file - /var/cagefs/[prefix]/[user]/virt.mp
            user_file_dir = PATH_TO_USER_FILES + prefix + '/' + user_name
            if os.path.islink(user_file_dir) or os.path.isfile(user_file_dir):
                secureio.print_error("File '" + user_file_dir + "' existing")
                sys.exit(1)

            if not os.path.isdir(user_file_dir):
                os.makedirs(user_file_dir)

            user_file_name = user_file_dir + '/virt.mp'

            # Get user mount points for specified Plesk version
            user_mp = get_plesk_user_mounts(domains_by_uid[uid], plesk_ver_major, plesk_ver_minor, user_home_dir)
            if user_mp is None:
                # no data to write, remove file
                if os.path.isfile(user_file_name):
                    os.remove(user_file_name)
            else:
                # write mount points to file /var/cagefs/[prefix]/[user]/virt.mp
                _, temp_file_name = tempfile.mkstemp(dir=user_file_dir)
                cagefslib.write_file(temp_file_name, user_mp, True)
                os.rename(temp_file_name, user_file_name)
        else:
            # Not a Plesk user, remove his file
            user_file_name = PATH_TO_USER_FILES + prefix + '/' + user_name + '/virt.mp'
            if os.path.isfile(user_file_name):
                os.remove(user_file_name)


# Generate Plesk virtual mount points for user(s)
def generate_plesk_virtmp(user_name):
    cldetectlib.getCP()
    ver_parts = cldetectlib.CP_VERSION.split('.')
    if len(ver_parts) >= 2:
        plesk_ver_major = int(ver_parts[0])
        plesk_ver_minor = int(ver_parts[1])
    else:
        sys.stderr.write('\nWARNING: Unexpected Plesk version. '
                                         'Skipping generation of virtmp files\n')
        return

    if plesk_ver_major < 10:
        sys.stderr.write('\nWARNING: Plesk below 10 version is not supported. '
                                         'Skipping generation of virtmp files\n')
        return

    # Read system users
    clpwd_instance = ClPwd()
    system_users_data = {}
    if user_name is not None:
        # defined user
        try:
            uid = clpwd_instance.get_uid(user_name)
            users_data = clpwd_instance.get_pw_by_uid(uid)
        except ClPwd.NoSuchUserException:
            secureio.print_error("user '" + user_name + "' not found")
            sys.exit(1)
        for user_data in users_data:
            user_home_dir = user_data.pw_dir
            if user_home_dir.endswith('/'):
                user_home_dir = user_home_dir[:-1]
            system_users_data[user_data.pw_name] = [str(user_data.pw_uid)[-2:], user_home_dir]
    else:
        # all system users
        users_data = clpwd_instance.get_user_dict()
        for user_data in users_data.values():
            user_home_dir = user_data.pw_dir
            if user_home_dir.endswith('/'):
                user_home_dir = user_home_dir[:-1]
            system_users_data[user_data.pw_name] = [str(user_data.pw_uid)[-2:], user_home_dir]

    scan_plesk_user_domains(system_users_data, plesk_ver_major, plesk_ver_minor)


# This called from cagefsctl.py
def create_virtmp(user_name=None):
    # Only for Plesk
    if not cldetectlib.is_plesk():
        return

    cagefsreconfigure.create_plesk_base_home_dirs()
    generate_plesk_virtmp(user_name)

Zerion Mini Shell 1.0