PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 131
# -*- 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 """ This module contains classes implementing X-Ray Manager behaviour for DirectAdmin """ import os import re import subprocess import urllib.parse from collections import ChainMap from glob import glob import chardet from xray import gettext as _ from xray.internal import phpinfo_utils from .base import BaseManager from ..internal.exceptions import XRayManagerError, XRayMissingDomain, XRayManagerExit from ..internal.types import DomainInfo from ..internal.user_plugin_utils import ( user_mode_verification, with_fpm_reload_restricted ) class DirectAdminManager(BaseManager): """ Class implementing an X-Ray manager behaviour for DirectAdmin """ da_options_conf = '/usr/local/directadmin/custombuild/options.conf' da_domain_pattern = '/usr/local/directadmin/data/users/*/domains/*.conf' da_subdomain_pattern = '/usr/local/directadmin/data/users/*/domains/*.subdomains' da_alias_pattern = '/usr/local/directadmin/data/users/*/domains/*.pointers' da_docroot_override_pattern = '/usr/local/directadmin/data/users/*/domains/*.subdomains.docroot.override' VERSIONS_DA = { 'php54': '/usr/local/php54/lib/php.conf.d', 'php55': '/usr/local/php55/lib/php.conf.d', 'php56': '/usr/local/php56/lib/php.conf.d', 'php70': '/usr/local/php70/lib/php.conf.d', 'php71': '/usr/local/php71/lib/php.conf.d', 'php72': '/usr/local/php72/lib/php.conf.d', 'php73': '/usr/local/php73/lib/php.conf.d', 'php74': '/usr/local/php74/lib/php.conf.d', 'php80': '/usr/local/php80/lib/php.conf.d', 'php81': '/usr/local/php81/lib/php.conf.d', 'php82': '/usr/local/php82/lib/php.conf.d', 'php83': '/usr/local/php83/lib/php.conf.d', 'php84': '/usr/local/php84/lib/php.conf.d', } def supported_versions(self) -> ChainMap: """ Get supported PHP versions :return: a chained map with basic supported versions and DirectAdmin supported versions """ return ChainMap(self.VERSIONS, self.VERSIONS_DA) def file_readlines(self, filename: str) -> list: """ Read lines from file :param filename: a name of file to read :return: list of stripped lines """ def get_file_encoding(): """ Retrieve file encoding """ with open(filename, 'rb') as f: result = chardet.detect(f.read()) return result['encoding'] try: with open(filename, encoding=get_file_encoding()) as f: return [line.strip() for line in f.readlines()] except OSError as e: self.logger.error('Failed to read [DA conf] file', extra={'fname': filename, 'err': str(e)}) raise XRayManagerExit(_('Failed to read file %s') % filename) from e @property def php_options(self) -> dict: """ Retrieve DirectAdmin PHP settings :return: dict of format {'1': {ver, fpm}, '2': {ver, fpm}...} where '1', '2' etc is an ordinal number of a handler as it is defined in options.conf """ parsed_options = dict() opts = self.file_readlines(self.da_options_conf) def inner_filter(seq, marker): """ Filter PHP release|mode items in seq by marker :param seq: initial sequence :param marker: should be contained in seq item :return: all items from seq containing marker """ return [l for l in seq if marker in l and 'php' in l and not l.startswith('#')] for index, o in enumerate(zip(inner_filter(opts, 'release'), inner_filter(opts, 'mode')), start=1): release, mode = o if 'no' not in release: parsed_options[str(index)] = { 'ver': f"php{''.join(release.split('=')[-1].split('.'))}", 'fpm': 'fpm' in mode, 'handler': mode.split('=')[-1] } return parsed_options @property def main_domains(self) -> dict: """ Retrieve main domains configuration files """ domains = dict() for dom_conf in glob(self.da_domain_pattern): name = os.path.basename(dom_conf).split('.conf')[0] domains[name] = dom_conf return domains @property def subdomains(self) -> dict: """ Retrieve subdomains configuration files """ subdomains = dict() for sub_conf in glob(self.da_subdomain_pattern): for subdom in self.file_readlines(sub_conf): sub_parent = f"{os.path.basename(sub_conf).split('.subdomains')[0]}" sub_name = f"{subdom}.{sub_parent}" subdomains[ sub_name] = f"{sub_conf.split('.subdomains')[0]}.conf" return subdomains @property def aliases(self) -> dict: """ Retrieve aliases configuration files """ aliases = dict() for alias_conf in glob(self.da_alias_pattern): parent_domain_name = alias_conf.split('.pointers')[0] for alias in self.file_readlines(alias_conf): alias_info = alias.split('=') alias_name = alias_info[0] _type = alias_info[-1] if _type == 'pointer': # pointers are not considered as domains, # because they just perform a redirect to parent domain continue aliases[alias_name] = f"{parent_domain_name}.conf" try: for sub in self.file_readlines( f"{parent_domain_name}.subdomains"): aliases[ f"{sub}.{alias_name}"] = f"{parent_domain_name}.conf" except XRayManagerError: # there could be no subdomains pass return aliases @property def subdomains_php_settings(self) -> dict: """ Retrieve subdomains_docroot_override configuration files """ sub_php_set = dict() for sub_doc_override in glob(self.da_docroot_override_pattern): for subdomline in self.file_readlines(sub_doc_override): subdompart, data = urllib.parse.unquote( subdomline).split('=', maxsplit=1) php_select_value = re.search(r'(?<=php1_select=)\d(?=&)', data) if php_select_value is not None: domname = f"{os.path.basename(sub_doc_override).split('.subdomains.docroot.override')[0]}" subdomname = f"{subdompart}.{domname}" sub_php_set[subdomname] = php_select_value.group() return sub_php_set @property def all_sites(self) -> dict: """ Retrieve all domains and subdomains, existing on DA server, including aliases in the form of dict {domain_name: domain_config} :return: {domain_name: domain_config} including subdomains """ da_sites = dict() for bunch in self.main_domains, self.subdomains, self.aliases: da_sites.update(bunch) return da_sites @user_mode_verification @with_fpm_reload_restricted def get_domain_info(self, domain_name: str) -> DomainInfo: """ Retrieve information about given domain from control panel environment: PHP version, user of domain, fpm status :param domain_name: name of domain :return: a DomainInfo object """ try: domain_conf = self.all_sites[domain_name] except KeyError: self.logger.warning( 'Domain does not exist on the server or is a pointer (no task allowed for pointers)', extra={'domain_name': domain_name}) raise XRayMissingDomain(domain_name, message=_("Domain '%(domain_name)s' does not exist on this server " "or is a pointer (no task allowed for pointers)")) data = self.file_readlines(domain_conf) def find_item(item: str) -> str: """ Get config value of item (e.g. item=value) :param item: key to get value of :return: value of item """ found = [line.strip() for line in data if item in line] try: return found[0].split('=')[-1] except IndexError: return '1' opts = self.php_options # Trying to get the subdomain handler first, # get main domain handler if nothing is set for subdomain php_selected = self.subdomains_php_settings.get( domain_name) or find_item('php1_select') # if user config has disabled php version selected -> # DirectAdmin uses the 1st one # grep php1 /usr/local/directadmin/data/users/auser/domains/auser.com.conf # php1_select=2 # cat /usr/local/directadmin/custombuild/options.conf | grep -i php # # PHP Settings # php1_release=7.4 # php1_mode=lsphp # php2_release=no if not opts.get(php_selected): php_selected = '1' if self.phpinfo_mode: config = phpinfo_utils.get_php_configuration( find_item('username'), domain=domain_name) domain_info = DomainInfo( name=domain_name, panel_php_version=config.get_full_php_version('php'), php_ini_scan_dir=config.absolute_ini_scan_dir, # indicates that there is no need to apply selector # and try to resolve php version, the one given in # php_version is final one is_selector_applied=True, user=find_item('username'), panel_fpm=config.is_php_fpm, handler=php_selected ) else: domain_info = DomainInfo(name=domain_name, panel_php_version=opts[php_selected]['ver'], user=find_item('username'), panel_fpm=opts[php_selected]['fpm'], handler=php_selected) self.logger.info( 'Retrieved domain info: domain %s owned by %s uses php version %s', domain_name, domain_info.user, domain_info.handler) return domain_info def panel_specific_selector_enabled(self, domain_info: DomainInfo) -> bool: """ Check if selector is enabled specifically for DirectAdmin Required to be implemented by child classes :param domain_info: a DomainInfo object :return: True if yes, False otherwise """ compatible_handlers = ('suphp', 'lsphp', 'fastcgi') current_handler = self.php_options[domain_info.handler]['handler'] return domain_info.handler == '1' and current_handler in compatible_handlers def fpm_service_name(self, dom_info: DomainInfo) -> str: """ Get DirectAdmin FPM service name :param dom_info: a DomainInfo object :return: FPM service name """ return f'php-fpm{dom_info.panel_php_version[-2:]}' def php_procs_reload(self, domain_info: DomainInfo) -> None: """ Copy xray.so for current version, create ini_location directory Reload FPM service or kill all *php* processes of user :param domain_info: a DomainInfo object """ try: subprocess.run(['/usr/share/alt-php-xray/da_cp_xray', domain_info.panel_php_version[-2:]], capture_output=True, text=True) except self.subprocess_errors as e: self.logger.error('Failed to copy xray.so', extra={'err': str(e), 'info': domain_info}) if self.php_options[domain_info.handler]['handler'] == 'mod_php': try: subprocess.run(['/usr/sbin/service', 'httpd', 'restart'], capture_output=True, text=True) self.logger.info('httpd restarted') except self.subprocess_errors as e: self.logger.error('Failed to restart httpd', extra={'err': str(e), 'info': domain_info}) super().php_procs_reload(domain_info)