ѠgXdZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z m Z ddl mZddlZddlmZmZmZmZmZmZmZddlmZddlmZdd lmZmZdd lm Z m!Z!m"Z"m#Z#m$Z$m%Z%dd l&m'Z'm(Z(m)Z)dd l*m+Z,dd l-m.Z.ddl/m0Z0m1Z1m2Z2m3Z3m4Z4dZ5dZ6ej78e6dZ9ej78e6dZ:ej78e6dZ;ej78e:dZdZ?ej78e:dZ@ej78e@dZAej78e@dZBejCdejDe>ZEdZFdZGdZHd ZId!ZJdEd#ZKdFd%ZLdGd'ZMd(ZNd)ZOd*ZPd+ZQd,ZRd-ZSd.ZTdHd/ZUd0ZVd1ZWe(jXe?g2d3e eYeYffd4ZZd5Z[dId6Z\d7Z+d8Z]d9Z^d:Z_d;Z`d<Zad=Zbd>Zcd?Zdd@ZedAZfdBZgGdCdDe(ZhdS)Jz. CloudLinux API for DirectAdmin control panel N) format_exc)DictListTuple)urlparse)WebConfigMissingWebConfigParsingErrorapache_conf_parser load_fastnginx_conf_parseropenlitespeed_conf_parser&read_unicode_file_with_decode_fallback)load)ClPwd)"_docroot_under_user_via_custom_binget_domains_via_custom_binary)CpApiTypeErrorNoDBAccessDataNoDomain NoPanelUser ParsingError ReadFileError)DomainDescriptionGeneralPanelPluginV1PHPDescriptionget_admin_email)Feature)ExternalProgramFailedfind_module_param_in_configget_file_linesgrepget_modules_dir_for_alt_php DirectAdminz/usr/local/directadminzconf/directadmin.confdatazconf/mysql.confusers custombuildz options.confz user.confz/etc/virtual/domainownersadminz reseller.list admin.listz.+/(.+)/c~tjdptjdS)N"/usr/local/directadmin/directadminz(/usr/local/directadmin/custombuild/build)ospathisfile/builddir/build/BUILDROOT/alt-python27-cllib-3.4.22-1.el8.cloudlinux.x86_64/opt/cloudlinux/venv/lib/python3.11/site-packages/clcommon/cpapi/plugins/directadmin.pydetectr2Ms2 7>>> ? ? F 7>>D E EFr0ci} tt}|d|d<|d|d<nW#t$r%}tdt |z|d}~wt $r}tdt|d}~wwxYw|S)Nuserloginpasswdpassz0Can not open file with data to database access; z+Can not get database access data from file ) loadconfig DA_DB_CONFIOErrorrstrKeyError)access login_dataerrs r1 db_accessr@Rs F  ++ $V,w#H-v  >S I     F* F F    Ms */ B A B&A>>Bcdtjtjtdt D}d|D}t |S)NcBg|]}t|Sr/) USER_PATTERNmatch).0r-s r1 zcpusers..ds&nnnt,$$T**nnnr0*c<g|]}||dS))group)rErDs r1rFzcpusers..es'BBBUEB%++a..BBBr0)globr,r-join DA_USERS_PATH USER_CONFtuple) match_list users_lists r1cpusersrRcsTnntym]`bkAlAl7m7mnnnJBBjBBBJ   r0cttd5}d|D}dddn #1swxYwYt|S)Nutf-8encodingc6g|]}|Sr/striprElines r1rFzresellers..ks 5554$**,,555r0)openRESELLERS_LISTrO)fresellers_lists r1 resellersr`is nw / / /61551555666666666666666   044cttd5}d|D}dddn #1swxYwYt|S)NrTrUc6g|]}|Sr/rXrZs r1rFzadmins..qs 222tzz||222r0)r\ ADMINS_LISTset)r^ admins_lists r1adminsrgos kG , , ,322222 333333333333333 {  raFcddlm}t}|||}|r6|tt t z }|S)Nr)_dblogin_cplogin_pairs) cplogin_lstr=) clcommon.cpapi.plugins.universalrir@rO get_da_userrMitems)rjwith_system_usersrir=r%s r1dblogin_cplogin_pairsrouseGGGGGG [[F ! !k& I I ID: k-006688999 Kr0Tc,i}tj}tj|tjd}|D]}tj|r|dz|zdz} t |d5}t|dkr|dd}|||<dddn #1swxYwY#t$r'|s"tj d|zYwxYwtj||S) Nz./*/z /domains.listrTrUrzNo file ) r,getcwdchdirrKr-isdirr\lenreadliner:sysstderrwrite) r-quietr&cur_dirdir_listuser_dir file_domainsr^ user_names r1rlrl~sk EikkGHTNNNyH @ @ 7== " " @#:0?BL @,9995Q1::<<((1,,$,QRRL +4i(555555555555555 @ @ @@J$$Z,%>??? @ @HW Ls6-C >5B?3 C ?C C C C  .C<;C<cploginpackagemailresellerdnslocalecF g}t|tr|g}nat|ttfrt|}n5|t }n$t ddt |jddddfdd d d  fd |D}|D]|}tj t|t}tj |r0t| | fd |D}|S)Ncpinfozstr|unicode|list|tuple)funcnamesupportedtypes received_typec|ddkr|dS|dS)Nusertyperusernamecreatorgetconfigs r1 _get_resellerzcpinfo.._get_resellers= ::j ! !Z / /::j)) )zz)$$$r0c,|dS)Nrrrs r1zcpinfo..s :0F0Fr0c,|dS)Nrrrs r1rzcpinfo..s 90E0Er0c,|dS)Nemailrrs r1rzcpinfo..sVZZ-@-@r0c|SNr/)rrs r1rzcpinfo..sv1F1Fr0c,|dS)Ndomainrrs r1rzcpinfo..sFJJx,@,@r0c,|dS)Nlanguagerrs r1rzcpinfo..svzz*/E/Er0rc g|] }| Sr/r/)rEkey_user_conf_maps r1rFzcpinfo..s 3 3 3cnS! 3 3 3r0c&g|] }|Sr/r/)rEr user_configs r1rFzcpinfo..s#@@@#SS--@@@r0) isinstancer;listrOrRrtype__name__r,r-rLrMrNexistsr append) cpuserkeylssearch_sys_usersreturned cpusers_listkeyls_ruser_conf_filerrrs @@@r1rrsdH&#Bx FT5M * *BV}} yy h?W+/<<+@BBB B%%% "G!F!E!E@@"F"F"F"F@@ E E GGN 4 3 3 3U 3 3 3F BBmXyII 7>>. ) ) B#N33K OO@@@@@@@ A A A Or0cd}t}t|D]*}||ks|d|r ||}n+|g}nt |}|D]}||vr |d|fcSdS)z Old method for getting doc_root for domain under root Method reads DA config :return: (doc_root, username) cortege N.rI)_load_domains_ownersrkeysendswith userdomains)rr_domain_to_user_map main_domain domains_listds r1_docroot_under_rootrsI.00/446677 [ FOO4E 4E4E$F$F +K8I E ! "9-- ## Q;;Q4? " " " ##r0ct}|tjd}t |j}|D]}|d|kr|d|jfcS dS)z Old method for getting doc_root for domain under user Method parses /home//domains directory :return: (doc_root, username) cortege r server_name document_rootN)r get_pw_by_uidr,getuid_get_domains_list_as_userpw_dirpw_name)rclpwduser_pwlist_domains_and_doc_roots domain_datas r1!_docroot_under_user_old_mechanismrs GGE!!")++..q1G!:7>!J!J1AA } % / //@ @ @ @ 0AAr0cd}|}tj}tj}|dkr|dkrt |}nt |}||St d|d)z Retrieves document root for domain :param domain: Domain to determine doc_root :return: Cortege: (doc_root, domain_user) Nrz'Can't obtain document root for domain '')rYr,rgeteuidrrr)rresuideuids r1docrootrs C \\^^F )++C :< Check if OpenLiteSpeed is installed via custombuild; openlitespeedrrrs r1_is_openlitespeed_installedrs5 F FJJ2233 4 44r0c tr.ttj|d}nit r.t tj|d}n-ttj|d}n4#t$r}t|j |d}~wt$rgcYSwxYw|S)z Get domains list for user from httpd or nginx config as root :param user_path: path to DA directory of user's profile :return: parsed httpd or nginx config :rtype: list z nginx.confzopenlitespeed.confz httpd.confN) rr r,r-rLrr r r rmessager) user_path httpd_confes r1_get_domains_list_as_rootrs    S*27<< <+P+PQQJJ ( * * S227<< K_3`3`aaJJ+BGLLL,Q,QRRJ ---19%%1,   sB%B(( C2CCCcd}d}g}tj||}tj|D]}tj||}tj|||}tj|r9tj|r|||dd|S)aT Get domains list for user from ~/domains directory as user. Method DOESN'T search subdomains, because it's almost impossible detect by user's folders without privileges escalation :param user_home: path to user home :return: list of dictionaries {'server_name': 'domain', 'document_root': 'doc_root', 'ssl': False} domains public_htmlF)rrssl)r,r-rLlistdirrur) user_home domains_dir doc_root_dirr domains_path domain_dir domain_path doc_root_paths r1rrsK LL7<< ;77Lj..   gll<<<  \:|LL 7== % % "'-- *F*F    #-%2 !!      r0cxg}tjt|}tj}d}tj|sgStjd|z}tj|d}tj|r>tj|rtj|}|dks|rst|}|D]_} | ddur | d|vr%| d| d| df<| | d| df`|St\} } | dkr| S| d krtd |d td | ) aD Get user's domains list :return list: domain names Example: [('cltest1.com', '/home/cltest1/domains/cltest1.com/public_html'), ('mk.cltest1.com', '/home/cltest1/domains/cltest1.com/public_html/mk'), ('cltest11.com', '/home/cltest1/domains/cltest11.com/public_html') ] ~rrrTrr zUser z not found in the databasezFailed to get userdomains: )r,r-rLrMrr expanduserislinkrealpathrinsertrrrr) ras_rootrrrmain_domain_pathr public_pathrrrcrs r1rr;sL ]F33I :<>) $ $ ""3<00I',,y-88K w~~k""9rw~~k'B'B97++K88 qyyGy.y99   V VFe}$$m$(888##A}(=vo?V'WXXXX##VM%:F?>) $ $ $ww~66H MM( # # #  ??r0cFt|dS)z Return domain's owner :param domain: Domain/sub-domain/add-domain name :return: user name or None if domain not found N)rrrs r1 domain_ownerr{s ! ! % %fd 3 33r0) panel_parkerreturnc tt}n6#ttf$r"}t t ||d}~wwxYwi}|D]^}|}|s|d\}}|}|}|||<_|S)zC Get domain<->user map from /etc/virtual/domainowners file N:) r DOMAINOWNERS splitlinesOSErrorr:rr;rYsplit) domains_linesrrline_domain_user_s r1rrs +>|LLWWYY W +++CFF##*+ - -   S))--// ',G$$ s&)AAAc|gSt}tjt |d} t |d5}d|D}||tt|t|zcdddS#1swxYwYdS#ttf$rgcYSwxYw)z Return list of reseller users :param resellername: reseller name; return empty list if None :return list[str]: user names list Nz users.listrTrUc6g|]}|Sr/rX)rEitems r1rFz"reseller_users..s >>>4$**,,>>>r0) rrr,r-rLrMr\rrrer:r) resellernameall_users_dictusers_list_filerQs r1reseller_usersrs&  WW**,,Ngll=, MMO /G 4 4 4 ? >>:>>>J   l + + +N++c*oo=>>  ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? W  s7 CA B7* C7B;;C>B;?CCCcd|gSt|}tt|dS)z Get pairs user <=> domain for given reseller; Empty list if cannot get or no users found; :type resellername: str :return list[tuple[str, str]]: tuple[username, main_domain] N)rr)r)rdictr)rr&s r1reseller_domainsrs8 < ( (E u$6777 8 88r0ctjtdt}t |}|dtS)Nr(r)r,r-rLrMrNr8runiversal_get_admin_email)admin_user_filecnfs r1rrsAgll='9EEO _ % %C 777577 8 88r0ctjt|t}tj|r< t |ddkS#t$r}td|d}~wwxYwdS)z{ Check if given user is reseller; :type username: str :rtype: bool :raise: ParsingError, ReadFileError rrz)User config exists, but no usertype givenNF) r,r-rLrMrNrr8 IndexErrorr)rrrs r1 is_resellerr$s',,}h BBK w~~k""S Sk**:6*D D S S SJKKQR R S 5s A%% B/A??Bcd|dS)Nzhttp://z:2222r/rs r1get_user_login_urlr&s "V " " ""r0c`i} tt}n#ttf$rYdSwxYwd}d|d|vrsd|d|vrki|t |<|d|d|t |d<|d|d|t |d<|dz }d|d|vrd|d|vk|S)zJ Return map (PHP_DA_CODE:{PHP_HANDLER, PHP_VERSION}) :return: NrIphp_mode_release handler_typephp_version_id)r8 DA_OPT_PATHr:rr;) _php_da_mapphp_cfgis r1_get_da_php_configr1s  K[)) W tt A ...G # #(9a(9(9(9W(D(D CFF.5nAnnn.E CFFN+078Ia8I8I8I0J CFF,- Q ...G # #(9a(9(9(9W(D(D s ..ctjtt |dt |dz} t |}n#t tf$rYdSwxYw|d}||dkrd}|S)z Return php code from domain config :param domain: :param owner: :return: string '1' or '2' - php code in DA rz.conf1 php1_selectN0) r,r-rLrMr;r8r:rr)rownerdomain_config_file domain_config domain_phps r1_get_php_code_info_for_domainr:smSZZCPVKKZaLabb"#566 W ss""=11JZ3.. sAA+*A+cg}|D]:}|d|vr||d;|S)Nr)rr) all_domainsmapped_all_domains subdomainsrs r1_get_subdomainsr?sVJ%% !9*//11 1 1 &)$$$$ r0c t}i}t}||Si}|D].\}}||g|/|D]\}}t |} t ||}n#t$rg}YnwxYw|D]}t||} | |vs|| ddkrd} || } t||} n#t$rg} YnwxYw|g|z| zD]A} t|| d| dd| d dd || <B|S) a Return php version information for each domain :return: domain to php info mapping Example output: {'cltest.com': {'handler_type': 'mod_php', 'php_version_id': '7.1', 'username': 'cltest'}, 'cltest2.com': {'handler_type': 'fastcgi', 'php_version_id': '7.3', 'username': 'kek_2'}, 'cltest3.com': {'handler_type': 'suphp', 'php_version_id': '5.5', 'username': 'cltest3'}, 'omg.kek': {'handler_type': 'php-fpm', 'php_version_id': '5.2', 'username': 'cltest'}} :rtype: dict[str, dict] Nr,nor3r+r(rr)rr,r+display_version) rr1rm setdefaultrrr? Exceptionr: _useraliasesrreplace) map_domain_user result_map php_da_mapowner_to_domainsrr6rall_domains_in_httpd_filer> php_info_codephp_infodomain_aliases domain_entitys r1get_domains_php_inforPs(+,,OJ#%%J-/(..00>> ##E2..55f====*0022  w$/$6$6! ()BOTTJJ   JJJ   F9&%HHMJ..!-01ABdJJ!$ !-0H $!-eV!  / / /1BC        r0cpt}|gS|}g}|D] }|d}|dkrd|ddd}tj|sLt |}|r|}|td|dd|tj ||tj |d tj |d   |S) zL Gets compiled phpXY - could be chosen via DirectAdmin PHP Selector Nr,rAz/usr/local/phprrrqr(zbin/phpz lib/php.inirR) r1valuesrFr,r-rrhrYrrrL)rIinstalled_php_datar[ version_inforTrgmodules_dir_paths r1"_get_compiled_custombuild_versionsrnssL$%%J $**,,N+  /0 d?? JwsB/G/GJJJw~~122  45HII  8/5577 n7W__S"5577 011( 0)<< 0-@@         r0c Xtj|sgSg} t|d5}|}dddn #1swxYwYn=#t $r0}t jt jd|d|dYd}~nd}~wwxYwd|DS)z1 Parse user aliases file and return data rTrUNzCan`t open file "z " due to : ""chg|]/}|dd0S)=r)rYr)rErecords r1rFz _get_aliases..s3 < < >$   DV $ ) ) ) !Q;;==D ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! VVV f(*Td*T*TPQ*T*T*TUUUUUUUUV < z1PanelPlugin.get_cp_description..s.GG4T[[..GGGGGGr0cR|ddS)Nrr)rFisdigit)ss r1 _is_floatz1PanelPlugin.get_cp_description.._is_floats"yyb))11333r0r)namerTadditional_info) rdPopenPIPE communicaternextfilterrrD)rpout_ version_wordsrrTs r1get_cp_descriptionzPanelPlugin.get_cp_descriptions  !5s;!!  ) Q  ) ) ) ) ) ) ) ) ) ) ) ) ) ) )HG399;;GGGM 4 4 46)];;R@@G&7tTT T   44 s5.B)A B)AB)AA B)) B76B7ctS)z Getting root access to mysql database. For example {'login': 'root', 'db': 'mysql', 'host': 'localhost', 'pass': '9pJUv38sAqqW'} :return: root access to mysql database :rtype: dict :raises: NoDBAccessData )r@rs r1r@zPanelPlugin.db_accesss{{r0ctS)z Generates a list of cpusers registered in the control panel :return: list of cpusers registered in the control panel :rtype: tuple )rRrs r1rRzPanelPlugin.cpuserssyyr0ctS)z Generates a list of resellers in the control panel :return: list of cpusers registered in the control panel :rtype: tuple )r`rs r1r`zPanelPlugin.resellerss{{r0c t|S)zc Check if given user is reseller; :type username: str :rtype: bool )r$)rrs r1r$zPanelPlugin.is_resellers 8$$$r0ctjt|t}tj|sdSt |}|ddkS)z| Return True if username is in admin names :param str username: user to check :return: bool Frr()r,r-rLrMrNrr )rrrrs r1is_adminzPanelPlugin.is_admin sS mXyIIw~~n-- 5// :&'11r0NFc"t||S)a  Get mapping between system and DB users @param cplogin_lst :list: list with usernames for generate mapping @param with_system_users :bool: add system users to result list or no. default: False )ro)rrjrns r1roz!PanelPlugin.dblogin_cplogin_pairss%[2CDDDr0rTc&t|||S)a Retrieves info about panel user(s) :param str|unicode|list|tuple|None cpuser: user login :param keyls: list of data which is necessary to obtain the user, the valuescan be: cplogin - name/login user control panel mail - Email users reseller - name reseller/owner users locale - localization of the user account package - User name of the package dns - domain of the user :param bool search_sys_users: search for cpuser in sys_users or in control panel users (e.g. for Plesk) :return: returns a tuple of tuples of data in the same sequence as specified keys in keylst :rtype: tuple )r)r)rrrrs r1rzPanelPlugin.cpinfo"s"fe6FGGGGr0ctS)zR Retrieve admin email address :return: Host admin's email rrs r1rzPanelPlugin.get_admin_email5s    r0c t|S)z Return document root for domain :param str|unicode domain: :return Cortege: (document_root, owner) )rrrs r1rzPanelPlugin.docroot<s vr0c"t||Sr)rE)rrs r1 useraliaseszPanelPlugin.useraliasesDsFF+++r0c t|S)z Return domain and document root pairs for control panel user first domain is main domain :param str|unicode cpuser: user login :return list of tuples (domain_name, documen_root) )r)rrs r1rzPanelPlugin.userdomainsHs6"""r0ctS)z Detects and returns list of folders contained the home dirs of users of the cPanel :return: list of folders, which are parent of home dirs of users of the panel )rrs r1rzPanelPlugin.homedirsQs zzr0c t|S)z Return reseller users :param resellername: reseller name; autodetect name if None :return list[str]: user names list )rrrs r1rzPanelPlugin.reseller_usersXs l+++r0c t|S)z Get dict[user, domain] :param reseller_name: reseller's name :rtype: dict[str, str|None] :raises DomainException: if cannot obtain domains )rrs r1rzPanelPlugin.reseller_domains`s ---r0c t|S)z` Get login url for current panel; :type domain: str :rtype: str )r&rs r1r&zPanelPlugin.get_user_login_urlis "&)))r0ctS)z_ List all admins names in given control panel :return: list of strings )rgrs r1rgzPanelPlugin.adminsqs xxr0c t|S)z Return domain's owner :param domain: Domain/sub-domain/add-domain name :rtype: str :return: user name or None if domain not found )rrs r1rzPanelPlugin.domain_ownerxsF###r0ctS)z Return php version information for each domain :return: domain to php info mapping :rtype: dict[str, dict] )rPrs r1rPz PanelPlugin.get_domains_php_infos $%%%r0ctt}d|vr|dS|dd}|dS|ddS)zf Retrieve current DA skin name :return: Current DA skin name. None if unknown system_skindocsrootNrq)r8rrr)rrs r1_get_da_skin_namezPanelPlugin._get_da_skin_names` G$$ F " "-( (::j$//  4~~c""2&&r0ctjtd}d}t}|dkr%t |}|d|S|S)zZ Retrieve encoding name, used for package/reseller names :return: z,data/skins/enhanced/lang/en/lf_standard.htmlutf8enhanced lang_encoding)r,r-rLDA_DIRr{rr8r)enhanced_skin_configdefault_encoding current_skin skin_configs r1get_encoding_namezPanelPlugin.get_encoding_namesh "w||F4bcc!"4466 : % %%%9::K???4DEE Er0r .ctjfSr)r RUBY_SELECTORrs r1get_unsupported_cl_featuresz'PanelPlugin.get_unsupported_cl_featuress  !  r0cg} ttj}n#ttf$rYdSwxYwd|D}t ddd|D][} t |dd}||vr||E#ttf$rYXwxYw|s|d |S) zl Retrieves active httpd's ports from httpd's config :return: list of apache's ports Nc6g|]}|Sr/rXrZs r1rFz5PanelPlugin.get_apache_ports_list..s 000$000r0ListenFT)match_any_positionmultiple_searchdata_from_file rIP) r!r{HTTPD_CONFIG_FILErr:r"rrrr# ValueError)_httpd_ports_listlinesr[values r1get_apache_ports_listz!PanelPlugin.get_apache_ports_lists ";#@AAEE!   44 00%000eTbghhh  D DJJsOOA.// 111%,,U333 +      )  $ $R ( ( (  s33ABB.-B.c rd}d} tt}ttdddd|}|D]Y}|d}|ddkr|d }|dd kr|d }|d krd }Zn#t ttf$rYnwxYw||fS) a Determines active web server from options.conf, directive 'webserver' :return: tuple (active_web_server_name, apache_active_module_name) active_web_server_name: 'apache', 'nginx', 'nginx_apache', 'litespeed', 'openlitespeed', etc apache_active_module_name: 'prefork', 'event', 'worker' (None, None) if DA options.conf read/parse error Nz^apache_mpm|^webserverFT) fixed_stringrrrrrr webserverrI apache_mpmautoworker) r!r-rr"rYrrr:r#)web_server_nameapache_active_module_name options_linesgrep_result_listr[ line_partss r1_get_active_web_server_paramsz)PanelPlugin._get_active_web_server_paramss$(! +;77M#D)APUjo9=m%]%]%] ^ ^ ) = =!ZZ\\//44 a=K//&0mOa=L000:1 -0F::4<1 =*-    D  999sBBB21B2apache_module_namec t|j|dS#tttt f$rdt fcYSwxYw)a Determine MaxRequestWorkers directive value for specified apache module. Reads config file /etc/httpd/conf/extra/httpd-mpm.conf :param apache_module_name: Current apache's module name: 'prefork', 'event', 'worker' :return: tuple (max_req_num, message) max_req_num - Maximum request apache workers number or 0 if error message - OK/Error message MaxRequestWorkersr)r HTTPD_MPM_CONFIGrr:r#rr)rrs r1#_get_max_request_workers_for_modulez/PanelPlugin._get_max_request_workers_for_modulesa #.t/D/A/BDD D*j9 # # #jll? " " " #s-AAc|\}}|| ddtdfS|dkrdd|dfS||S)z Get current maximum request apache workers from httpd's config :return: tuple (max_req_num, message) max_req_num - Maximum request apache workers number or 0 if error message - OK/Error message Nr"There was error during read/parse . Apache collector will not workapache!DA is configured for web server '9'; but 'apache' is needed. Apache collector will not work)rr-r)rrrs r1get_apache_max_request_workersz*PanelPlugin.get_apache_max_request_workerss6:5W5W5Y5Y22  "&?&Gh;hhhh h h & &7/7777 7778QRRRr0cxd} t|j}d}d}|D]}|}||r|}.|dr@|r>||ddd}nn#t t f$rYnwxYw|S)z Determine apache mod_status URI from /etc/httpd/conf/extra/httpd-info.conf config :return Apache mod_status URI or None if error/not found Nz )r!HTTPD_INFO_CONFIGrY startswithrFrr:)r location_uri info_lineslocation_directive location_liner[s r1_get_httpd_status_uriz!PanelPlugin._get_httpd_status_uri s    ((>??J!,  M"  zz||??#566$(M??#=>>=#0#8#89KR#P#P#X#XY\^`#a#a#g#g#i#iLE!    D sBB##B76B7cj|\}}| ddtdfS|dkrdd|dfS |}|dSd |d }tj|d }|jd krdd|d|jfS|jd}|d}ttd|}|ddd } t| dfS#t$rdtfcYSwxYw)z Retrieves Apache's connections number (from apache's mod_status) :return: tuple (conn_num, message) conn_num - current connections number, 0 if error message - OK/Trace Nrrrrrr)rz%Can't found mod_status URI in configszhttp://127.0.0.1z?auto)timeoutzGET z response code is rT zTotal Accesses)rr rIOK)rr-rrequestsr status_codecontentdecoderrr"rYrrDr) rrrrurlresponse s_responses_response_listout_lists_total_accessess r1get_apache_connections_numberz)PanelPlugin.get_apache_connections_number(s"??AA  "h;hhhh h h & &7/7777 7 # 5577L#AA8\888C|C333H#s**NNN8LNNNN!)0099J(..t44OD!1/RRRSSH'{0055a8>>@@ '(($. . # # #jll? " " " #sD5DBDD21D2c<ttzS)a  Returns installed alt-php(s) on the server compiled phpXY via custombuild and alt-phpXY has different paths also user could choose version via PHP selector which was not compiled with custombuild (will be absent in DA configs) )r_rnr/r0r1get_installed_php_versionsz&PanelPlugin.get_installed_php_versionsHs/003U3W3WWWr0cd}tj|sdSt|d5}|}dddn #1swxYwY|sdS|dS)Nz)/usr/local/directadmin/data/admin/ip.listrrTrUr)r,r-rr\rtrY)r ip_list_filer^ipss r1 get_server_ipzPanelPlugin.get_server_ipSsB w~~l++ 2 , 1 1 1 Q++--C                21v||~~sAAArrcd|d}tj|sdSt|}|ddS)Nryz /user.confrr)r,r-rr r)rr user_confs r1get_user_emails_listz PanelPlugin.get_user_emails_list`sNMMMM w~~i(( 2i(( }}Wb)))r0ctjddd|gdddj}t|dkrdSt |}|jd |jd S) Nr+z--create-login-urlzuser=TF)rbrarcrrz://rq)rdrerfrvrschemenetloc)rgenerated_loginparseds r1panel_login_linkzPanelPlugin.panel_login_linkis$.*N*>@R@R@R*T8<4uVVVV\    1 $ $2/**-44FM4444r0ct|d}t|dkrdS|dS)Nrqrrz/evo/user/plugins/awp#/)r{rrstriprv)rlinks r1panel_awp_linkzPanelPlugin.panel_awp_linktsF++H55<>2////r0c@t}g}|D]}tjt|t }tj|sMt|}|ddkr| ||S)N suspendedyes) rRr,r-rLrMrNrr rr)r all_userssuspended_usersr4rrs r1suspended_users_listz PanelPlugin.suspended_users_list{sII  - -DW\\-yIIN7>>.11 #N33K{++u44&&t,,,r0NFNrTr)2r __module__ __qualname__rrrr~rrr@rRr`r$rrorrr staticmethodrrrrrr&rgrrPrrrOrrrrrrr;rrrrrrr r rrr __classcell__)rs@r1r{r{s4=?AAAAA:   %%% 2 2 2EEEE)d $HHHH&!!!,,\,###,,,,....***$$$&&&''\'$  \  U7C<-@    !49!!!\!4:5c?:::\:>#c#eTWY\T\o#### Sc3h S S S Ss8###@XX\X   *s*C***\*55\500\0       r0r{r)Tr)Fr)i__doc__rKr,rYrdrxru tracebackrtypingrrr urllib.parserrclcommon.clconfparsrr r r r r rrr8clcommon.clpwdrclcommon.cpapi.cpapicustombinrrclcommon.cpapi.cpapiexceptionsrrrrrrclcommon.cpapi.GeneralPanelrrrrkrrclcommon.featuresrclcommon.utilsrr r!r"r#rrr-rLr DA_DATA_DIRr9rMr-rNr rr]rdrZescaperCr2r@rRr`rgrorlrrrrrrrrrrr cache_callr;rrrr$r&r1r:r?rPr_rhrnrwrEr{r/r0r1r1s  $$$$$$$$$$!!!!!!322222  &%%%%%  " ',,v6 7 7gll66** W\\&"3 4 4  ['22 gll6=.AA  * GLLg . . i99gll9l33 rz=2. 9 9 9 9999    ###*(@@@F2   (((V = = =   PPPPP&PPPPPr0