ÿØÿàJFIFÿþ ÿÛC       ÿÛC ÿÀÿÄÿÄ"#QrÿÄÿÄ&1!A"2qQaáÿÚ ?Øy,æ/3JæÝ¹È߲؋5êXw²±ÉyˆR”¾I0ó2—PI¾IÌÚiMö¯–þrìN&"KgX:Šíµ•nTJnLK„…@!‰-ý ùúmë;ºgµŒ&ó±hw’¯Õ@”Ü— 9ñ-ë.²1<yà‚¹ïQÐU„ہ?.’¦èûbß±©Ö«Âw*VŒ) `$‰bØÔŸ’ëXÖ-ËTÜíGÚ3ð«g Ÿ§¯—Jx„–’U/ÂÅv_s(Hÿ@TñJÑãõçn­‚!ÈgfbÓc­:él[ðQe 9ÀPLbÃãCµm[5¿ç'ªjglå‡Ûí_§Úõl-;"PkÞÞÁQâ¼_Ñ^¢SŸx?"¸¦ùY騐ÒOÈ q’`~~ÚtËU¹CڒêV  I1Áß_ÿÙ iB^c@`s3ddlmZddlmZddlmZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddl mZmZmZmZddlmZddlmZdd lmZmZmZd d lmZd d lmZd ZddZ ddddZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+ddZ,ddZ-dZ.dZ/dZ0d Z1d!Z2d"Z3d#Z4ddd$e5d%Z6d&Z7d'Z8d(Z9dd)Z:dS(*i(tprint_function(tabsolute_import(tdivisionN(ttime(tAnyStrtListtDicttOptional(tresolve_username_and_doc_root(tCP_NAME(tNoDomaint NotSupportedt IncorrectDatai(tclprint(tClSelectExcepts/sbin/cagefs_enter_userc C`syOtj|dtddtjdtjdtd|}|j\}}Wn5ttfk r}t j |dt |nX|j dkrt j |pdd j||fn|S( s Runs external process and returns output :param cmd: command and arguments as a list :param env_data :return string tstdins /dev/nulltstdouttstderrt close_fdstenvisoutput of the command: %s %st (t subprocesstPopentopentPIPEtSTDOUTtTruet communicatetOSErrortIOErrorRtFileProcessErrortstrt returncodetExternalProgramFailedtjoin(tcmdtenv_datatoutputtstd_outtstd_errte((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt run_command"s     cC`sy[tj|dtddtjdtjd|dtd|d|}|j\}}Wn5ttfk r}tj |d t |nX|j ||fS( s Runs external process and returns output. Differs from subprocess.check_output, run_command above, and check_output below in that it does not throw an exception if process's return code != 0 :param cmd: command and arguments as a list :param env_data :param preexec_fn: Pre-exec function. None if don't need :param cwd: Directory name to set as current :return Cortege: (ret_code, stdout, stderr) Rs /dev/nullRRt preexec_fnRtcwdRi( RRRRRRRRRRRR (R#R$R*R+tprocessR&R'R(((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytrun_command_full:s      cC`sJd}y&t|}|j}|jWnttfk rEnX|S(s8 Reads file contents and returns it as a string t(RtreadtcloseRR(tfilenametdefaults_contentstf((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytread_file_as_stringUs  cO`st||dS(N(t check_output(targstkwargs((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt check_callcsc O`s8|jdd}|jd}|jdd}|jdd}|r_||7}|d=ny+tjd|dtjdtj|}Wn5ttfk r}tj |dt |nX|j \}} |r|j ||j n|dk r |jn|jr4tj|p+| p+|n|S( sv check_output(val1, val2, val3, arg4=val4) equivalent check_output(args=(val1, val2, val3), arg4=val4) or equivalent check_output(val1, args=(val2, val3), arg4=val4) DON'T USE check_output((val1, val2, val3), arg4=val4) :param tuple *args: arguments for command line :param dict **kwargs: parameters for subprocess.Popen :return str: terrorR6R%twaitRRiN(tpoptNonetgetRRRRRRRRRtwriteR0R:R R!( R6R7R9targs_from_kwargsR%R:tpR(RR((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyR5gs*         cC`sAgtj|D]-}tjjtjj||r|^qS(N(tostlistdirtpathtisdirR"(RCtd((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt list_dirsscc`sa|VxU|D]M\}}|t|Vx/|D]'}|djtt||fVq.Wq WdS(Nt.(RR"tmap(RCtversionstmajortminorstminor((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt versionings  cC`sUytj|Wn=tk rP}|jtjkrJtjj|rJqQnXdS(N(RAtmakedirsRterrnotEEXISTRCRD(RCtexc((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytmkdir_ps $cC`stjjtj|j}tjjtjj||}t||djtj }t ||fst j d||fn||fS(s Returns absolute and relative to user's home directories paths, after eliminating all symlinks :param user: Unix user whose home contains the directory :param directory: The directory to obtain absolute and relative paths for is&Directory '%s' not in user home ('%s')( RARCtrealpathtpwdtgetpwnamtpw_dirR"t s_partitiontlstriptseptallRt WrongData(tusert directorytuser_dirtabs_dirtrel_dir((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt get_abs_rels!cC`stjjdS(Ns /var/.cagefs(RARCRD(((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt in_cagefsscC`s4d}t|}z|j}Wd|jX|S(sE read litle file and close :param path: :return str: N(R<RR/R0(RCtdatatstream((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt file_reads   cC`s4g}t|}z|j}Wd|jX|S(sE read litle file and close :param path: :return str: N(Rt readlinesR0(RCRcRd((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytfile_readliness   twcC`s2t||}z|j|Wd|jXdS(sN write litle data to file and close :param path: :return str: N(RR>R0(RCtlinetmodeRd((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt file_writescC`s2t||}z|j|Wd|jXdS(sN write litle data to file and close :param path: :return str: N(Rt writelinesR0(RCtlinesRjRd((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytfile_writelinesscC`stjddkr3tjddkr3|j|S|j|d}t|dkrq|d||df}n|dddf}|S(s str.partition for all python versions :param s: string to parse :param sep: separator to split by :return: cortege - see str.partition function for python 2.5+ iiiiR.(tsyst version_infot partitiontsplittlen(tsRYts_partst ret_cortege((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyRWs& cC`sxyt|d}Wntk r'dSXd}tj|}x*|D]"}|j|rD|d7}qDqDW|j|S(s" find regex count in file triiN(RRR<tretcompiletsearchR0(tpatternRCR3tcountertregexRi((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytgreps   cC`sddlm}||S(s Determines is user should be skipped in selectorctl work :param username: user name to check :return: True - user should be skipped, False - not i(tis_admin(tclcommon.cpapiR(tusernameR((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytuser_should_be_skippedscC`stjj|sy0tjd}tj|dtj|Wqttfk r}td|dt|t j dqXndS(NiisError: failed to createt:i( RARCRDtumaskRNRRtprintRRotexit(tdest_dirt umask_savedR(((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytmake_dir scC`sNytj|Wntk r$nXtjj|rJtj|tndS(N(RAtunlinkRRCRDtshutiltrmtreeR(RC((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytremove_file_or_dir+s  cC`syhtjj|rMtj||krgtj|tj||qgnt|tj||Wn?tk r}td|d|dt |t j dnXdS(NsError: failed to create symlinks->Ri( RARCtislinktreadlinkRtsymlinkRRRRRoR(tsrctdstR(((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt make_symlink4s  cC`stj|dddddtS(Ntindentit separatorst,s: t sort_keys(Rs: (tjsontdumpsR(Rc((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt pretty_jsonBsttextcC`s |}d }ytd|d|\}}Wntk rutj|idd6dj||d6tjdntk r|rqtj|idd6dt d6tjdnFt k rtj|idd6d ||fd6tjdnX||fS( s Safely resolve username and doc_root by domain, or resolve document root by username, or resolve document root and username by effective uid :param pass_not_supported_panel: pass not supported panel for php selector :param msg_format: error messages' format (json or text) :param user: str -> name of unix user :param domain: str -> domain of panel user :return: tuple -> user, doc_root R\tdomaintERRORtstatuss(No domain found for user: {}, domain: {}tmessageis6NodeJs/Ruby/Python selector not supported for %s panels%Domain %s is not owned by the user %sN( R<RR R t print_diagtformatRoRR R R (R\Rt msg_formattpass_not_supported_panelt result_usertresult_doc_root((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pyt$safely_resolve_username_and_doc_rootGs<    cC`sdt||d}x5|D]-}t||d}||kr||SqWtdj|dS(s Transform all directories to realpath, compare and return config value :param user: str -> unix user - owner of the config :param directory: str -> wanted directory key :param config: dict -> config to get value from, should have directories as keys is%Config does not contain directory: {}N(RatKeyErrorR(R\R]tconfigt abs_directorytconf_dirt abs_conf_dir((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytget_using_realpath_keys|s   cC`st||d}t}xC|jD]5}t||d}||kr&||=t}q&q&W|s}tdj|ndS(s Transform all directories to realpath, compare and remove directory key :param user: str -> unix user - owner of the config :param directory: str -> wanted directory key :param config: dict -> config to remove key from, should have directories as keys is%Config does not contain directory: {}N(RatFalsetkeysRRR(R\R]RRtremoved_at_least_oneRR((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytdelete_using_realpath_keyss  cC`s$t||dt||dkS(s# Checks that two paths in user home directory are the same after stripping symlinks :param user: Unix user whose home directory contains both paths :type path1: str :type path2: str :return: True if paths are canonically the same otherwise False :rtype: bool i(Ra(R\tpath1tpath2((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytrealpaths_are_equals c C`si}|si}nt||g|}tj|d|dtjdtj}|j\}}|j} | r| dkridj|d6dd6td 6}n |j}||d <| |d <| rt nt |d <|S( s= Run any process using the utility cagefs_enter_user RRRisUser's process "{}" failed and didn't return anything. It could mean that user has too small limit of PMEM for running of cloudlinux-selector. Please, increase the limit to user and try run process againtdetailsR9tresultt timestampR%R tfailed( tCAGEFS_ENTER_USER_BINRRRRR RRtstripRR( R\tpath_to_utilitytargs_for_utilitytenv_varsRR#R,Rt_tretcode((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytrun_process_in_cagefss$ '     (;t __future__RRRRORARTRxRRoRRRttypingRRRRtclcommon.clpwdRRR tclcommon.cpapi.cpapiexceptionsR R R t clselectprintR tclselectexceptRRR<R)R-R4R8R5RFRMRRRaRbReRgRkRnRWR~RRRRRRRRRRR(((s?/opt/alt/python27/lib/python2.7/site-packages/clselect/utils.pytsX        "    #          5