669 lines
17 KiB
PHP
Executable File
669 lines
17 KiB
PHP
Executable File
<?php
|
|
|
|
/**------------------------------------------------
|
|
*
|
|
* Rooty, 2018 <rooty@rooty.me>
|
|
*
|
|
*
|
|
* This software is protected by copyright, please
|
|
* read the file COPYRIGHT.
|
|
* This program is distributed in the hope that it
|
|
* will be useful, but without any warranty; without
|
|
* even the implied warranty of merchantability or
|
|
* fitness for a particular purpose. Please
|
|
* read the file LICENCE.
|
|
*
|
|
* @link www.rooty.me
|
|
* @copyright Copyright © 2004-2005, ARD Limousin
|
|
* @author Rooty <www.rooty.me|rooty@rooty.me>
|
|
* @since 2004/09/03
|
|
* @version 0.3
|
|
* @package package
|
|
* @subpackage backupFile
|
|
*/
|
|
|
|
if ( !defined('SYSTEM_IN') )
|
|
{
|
|
//die("Hacking attempt");
|
|
}
|
|
|
|
/**
|
|
* classe de gestion de gestion de l'arborescence système.
|
|
* @package package
|
|
* @subpackage backupFile
|
|
*/
|
|
Class backupFile
|
|
{
|
|
|
|
/**
|
|
*Liste le contenu d'un répertoire
|
|
* @access public
|
|
* @param chaine path vers le répertoire à lister
|
|
* @return tableau tableau deux dimensions avec chemin+nom de fichier, type de fichier(rep="Directory", fichier="File", other="Inconnu"), nom fichier
|
|
*/
|
|
function getContentDir($path)
|
|
{
|
|
$cptfile=0;
|
|
$tabFile=array();
|
|
|
|
//Test de l'existence du répertoire
|
|
if (is_dir($path))
|
|
{
|
|
//Ouverture du répertoire
|
|
if ($rep = opendir($path))
|
|
{
|
|
//Lecture et stockage du contenu du repertoire dans le tableau en précisant le type du fichier lu
|
|
//les répertoires "." et ".." sont ignorés
|
|
while (($file = readdir($rep)) !== false )
|
|
{
|
|
if ($file != "." && $file != "..")
|
|
{
|
|
$tabFile[$cptfile][2]=$file;
|
|
$file=$path.$file;
|
|
$tabFile[$cptfile][0]=$file;
|
|
if (is_dir($file))
|
|
{
|
|
$tabFile[$cptfile][1]="Directory";
|
|
}
|
|
else
|
|
{
|
|
if (is_file($file))
|
|
{
|
|
$tabFile[$cptfile][1]="File";
|
|
}
|
|
else
|
|
{
|
|
$tabFile[$cptfile][1]="Inconnu";
|
|
}
|
|
}
|
|
$cptfile++;
|
|
}
|
|
}
|
|
}
|
|
closedir($rep);
|
|
}
|
|
else
|
|
{
|
|
addError(3 , "BackUpFile", "chemin non valide ".$path, __line__, __file__);
|
|
}
|
|
return $tabFile;
|
|
}
|
|
|
|
/**
|
|
* Suppresion d'un repertoire (récursivement)
|
|
* @access public
|
|
* @param chaine path vers le fichier à tester
|
|
* @param chaine droit à tester sur le fichier(r:read,w:write,x:execute)==>exemple(rwx)
|
|
* @return booleen
|
|
*/
|
|
function deleteDir($path)
|
|
{
|
|
$cptfile=0;
|
|
if ($rep = opendir($path))
|
|
{
|
|
//Lecture et stockage du contenu du repertoire dans le tableau en précisant le type du fichier lu
|
|
//les répertoires "." et ".." sont ignorés
|
|
while (($file = readdir($rep)) !== false )
|
|
{
|
|
if ($file != "." && $file != "..")
|
|
{
|
|
if (is_dir($file))
|
|
{
|
|
$this->deleteDir($path."/".$file);
|
|
}
|
|
else
|
|
{
|
|
@unlink($path."/".$file);
|
|
}
|
|
$cptfile++;
|
|
}
|
|
}
|
|
}
|
|
closedir($rep);
|
|
@rmdir($path);
|
|
}
|
|
|
|
/**
|
|
*Test les droits sur un fichier
|
|
* @access public
|
|
* @param chaine path vers le fichier à tester
|
|
* @param chaine droit à tester sur le fichier(r:read,w:write,x:execute)==>exemple(rwx)
|
|
* @return booleen
|
|
*/
|
|
function verifFilePerm($filePath, $droit)
|
|
{
|
|
$nbtest=strlen($droit);
|
|
|
|
//Recupere le nombre de test de droit à effectuer
|
|
switch ($nbtest)
|
|
{
|
|
case 1:
|
|
if ($droit=="r"){
|
|
if (is_readable($filePath)){
|
|
return true;
|
|
}
|
|
}
|
|
if ($droit=="w"){
|
|
if (is_writable($filePath)){
|
|
return true;
|
|
}
|
|
}
|
|
if ($droit=="x"){
|
|
if (is_executable($filePath)){
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
case 2:
|
|
if ( $droit=="rw" || $droit=="wr"){
|
|
if (is_readable($filePath) && is_writable($filePath)){
|
|
return true;
|
|
}
|
|
}
|
|
if ( $droit=="rx" || $droit=="xr"){
|
|
if (is_readable($filePath) && is_executable($filePath)){
|
|
return true;
|
|
}
|
|
}
|
|
if ( $droit=="xw" || $droit=="wx"){
|
|
if (is_executable($filePath) && is_writable($filePath)){
|
|
return true;
|
|
}
|
|
}
|
|
break;
|
|
case 3:
|
|
if (is_readable($filePath) && is_writable($filePath) && is_executable($filePath)){
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
*Renomme un fichier
|
|
* @access public
|
|
* @param chaine path vers le fichier à renommer
|
|
* @param chaine nouveau nom (penser à préciser l'extension!)
|
|
* @return booleen
|
|
*/
|
|
function renameFile($sourcepath, $destination_name)
|
|
{
|
|
//Teste de l'existence du fichier
|
|
if (file_exists($sourcepath))
|
|
{
|
|
//On renomme le fichier
|
|
if (rename($sourcepath,$destination_name))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
*Renomme les fichiers éxistant pour un éventuel backup
|
|
* @access public
|
|
* @param chaine path vers le fichier à renommer
|
|
* @param chaine extension du fichier sauvegardé
|
|
* @return tableau tableau contenant l'ancien nom [oldname], le nouveau nom [newname], et le status de reussite ou non du renommage (true or false)
|
|
*/
|
|
function rename($sourcepath,$ext=".bkp")
|
|
{
|
|
$tabbackup=array();
|
|
|
|
//On change l'extension en gardant le path
|
|
$pos=strrpos($sourcepath,".");
|
|
$ch=substr($sourcepath,0,$pos);
|
|
$ch=$ch.$ext;
|
|
|
|
//On renomme le fichier
|
|
if ($this->renameFile($sourcepath,$ch))
|
|
{
|
|
$tabbackup["oldname"]=$sourcepath;
|
|
$tabbackup["newname"]=$ch;
|
|
$tabbackup["success"]=true;
|
|
}
|
|
else
|
|
{
|
|
$tabbackup["oldname"]=$sourcepath;
|
|
$tabbackup["newname"]=$ch;
|
|
$tabbackup["success"]=false;
|
|
}
|
|
return $tabbackup;
|
|
}
|
|
|
|
/**
|
|
*copie un fichier
|
|
* @access public
|
|
* @param chaine path vers le fichier à renommer
|
|
* @param chaine nouveau nom (penser à préciser l'extension!)
|
|
* @return booleen
|
|
*/
|
|
function copyFile($sourcepath, $destination_name){
|
|
//Teste de l'existence du fichier
|
|
if (file_exists($sourcepath))
|
|
{
|
|
//On renomme le fichier
|
|
if (copy($sourcepath,$destination_name))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
*Supprime un répertoire
|
|
*Utilisation de la récursivité pour supprimé les sous-répertoire du répertoire racine passé en paramétre
|
|
*Retourne TRUE si suppression reussie, retourne FALSE si un répertoire n'est pas vide
|
|
* @access public
|
|
* @param chaine path vers le répertoire a supprimer
|
|
* @return booleen
|
|
*/
|
|
function EraseDir($sourcepath)
|
|
{
|
|
$tabficdir=$this->getContentDir($sourcepath);
|
|
|
|
if (count($tabficdir)==0)
|
|
{
|
|
rmdir($sourcepath);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
foreach ($tabficdir as $key=>$val)
|
|
{
|
|
if ($tabficdir[$key][1]=="Directory")
|
|
{
|
|
$this->EraseDir($tabficdir[$key][0]);
|
|
}
|
|
else
|
|
{
|
|
return False;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*copie les fichiers éxistant pour un éventuel backup
|
|
* @access public
|
|
* @param chaine path vers le fichier à renommer
|
|
* @param chaine extension du fichier sauvegardé
|
|
* @return tableau tableau contenant l'ancien nom [oldname], le nouveau nom [newname], et le status de reussite ou non du renommage (true or false)
|
|
*/
|
|
function copy($sourcepath,$ext=".bkp")
|
|
{
|
|
$tabbackup=array();
|
|
|
|
//On change l'extension en gardant le path
|
|
$pos=strrpos($sourcepath,".");
|
|
$ch=substr($sourcepath,0,$pos);
|
|
$ch=$ch.$ext;
|
|
//On renomme le fichier
|
|
if ($this->copyFile($sourcepath,$ch))
|
|
{
|
|
$tabbackup["oldname"]=$sourcepath;
|
|
$tabbackup["newname"]=$ch;
|
|
$tabbackup["success"]=true;
|
|
}
|
|
else
|
|
{
|
|
$tabbackup["oldname"]=$sourcepath;
|
|
$tabbackup["newname"]=$ch;
|
|
$tabbackup["success"]=false;
|
|
}
|
|
return $tabbackup;
|
|
}
|
|
|
|
/**
|
|
*Cette fonction permet d'attribuée des droits à un fichier
|
|
* @access public
|
|
* @param chaine path vers le fichier
|
|
* @param entier droits à attribuer (ex:0775==>droits de lecture et d'écriture pour l'utilisateur et le groupe, droits d'exécution pour tous)
|
|
* @return booleen
|
|
*/
|
|
function setFilePerm($Path,$FileMode)
|
|
{
|
|
//Test de l'existence du fichier
|
|
if (file_exists($Path))
|
|
{
|
|
//Affectation des droits si l'utilisateur éxécutant le script est autorisé
|
|
if (@chmod($Path, $FileMode))
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
echo "<br>Le fichier n'existe pas!";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*Fonction permettant d'affecter des droits à un répertoire de maniére recurssive
|
|
* @access public
|
|
* @param chaine path vers le repertoire
|
|
* @param entier droit à attribuer (ex:0775==>droits de lecture et d'écriture pour l'utilisateur et le groupe, droits d'exécution pour tous)
|
|
* @return tableau tableau 2 dimensions avec une dimension pour la profondeur et une dimension pour les path du fichier, les droits tester et la reussite ou non de l'affection des doits
|
|
*/
|
|
function setTreePerm($dirPath, $chmod)
|
|
{
|
|
$tabarbo=array();
|
|
$tabarbo=$this->getContentDir($dirPath);
|
|
$tabresult=array();
|
|
$cpt=0;
|
|
|
|
//Parcours du repertoire
|
|
for ($i=0;$i < count($tabarbo);$i++) {
|
|
if ($tabarbo[$i][1]=="Directory")
|
|
{
|
|
//Parcours des sous-répertoire de maniére recursive
|
|
$tabresult=array_merge($tabresult,$this->setTreePerm($tabarbo[$i][0]."/", $chmod));
|
|
$cpt=count($tabresult);
|
|
}
|
|
//Affectation des droits et enregistrement des opérations dans le tableau
|
|
else if ($tabarbo[$i][1]=="File")
|
|
{
|
|
$tabresult[$cpt]["path"]=$tabarbo[$i][0];
|
|
$tabresult[$cpt]["perm"]=$chmod;
|
|
if ($this->setFilePerm($tabarbo[$i][0],$chmod))
|
|
{
|
|
$tabresult[$cpt]["success"]=true;
|
|
}
|
|
else
|
|
{
|
|
$tabresult[$cpt]["success"]=false;
|
|
}
|
|
$cpt++;
|
|
}
|
|
}
|
|
return $tabresult;
|
|
}
|
|
|
|
/**
|
|
* Fonction qui parcours le fichier .ini et verifie l'existence des fichiers sources
|
|
* @access public
|
|
* @param chaine path vers le fichier ini
|
|
* @return tableau tableau assosiatif du contenu du fichier .ini
|
|
*/
|
|
function parcoursInitoTab($PathIni, $path="./", $chmod)
|
|
{
|
|
$tabresult=array();
|
|
$tabini=array();
|
|
//Copie des fichiers dans l'arbo avec enregistrement dans le tableau du resultat de la copie
|
|
//enregistrement également des paths source et destination
|
|
if ($tabini=parse_ini_file($PathIni))
|
|
{
|
|
foreach ($tabini as $key=>$val)
|
|
{
|
|
//Verifie l'existence du fichier source
|
|
$tabresult[$key][0]=$val;
|
|
if (file_exists($path.$key) && $this->setFilePerm($path.$key, $chmod))
|
|
{
|
|
$tabresult[$key][0]=$val;
|
|
$tabresult[$key][1]=True;
|
|
}
|
|
else
|
|
{
|
|
$tabresult[$key][1]=False;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
echo "<br>Erreur de lecture du fichier .ini!";
|
|
}
|
|
return $tabresult;
|
|
}
|
|
|
|
/**
|
|
* Création d'un répertoire
|
|
* Ne gére pas un path absolu
|
|
* @access public
|
|
* @param tableau tableau associatif du fichier ini
|
|
* @param entier droit à attribuer à la création d'un répertoire
|
|
* @return tableau tableau associatif des états de création des reps
|
|
*/
|
|
function createRep($tab, $chmod)
|
|
{
|
|
$tabTmp=array();
|
|
$tabresult=array();
|
|
$cpt=0;
|
|
//Création de l'arbo avec les valeurs contenues dans le fichier .ini
|
|
foreach ($tab as $key=>$val)
|
|
{
|
|
$tabTmp=mb_split('/',$this->getSystemPath($val[0]));
|
|
$pathTmp="";
|
|
$tabresult[$cpt][0]=$this->getSystemPath($val[0]);
|
|
$tabresult[$cpt][1]=true;
|
|
for ($i=0; $i<(count($tabTmp)-1); $i++)
|
|
{
|
|
$pathTmp.=$tabTmp[$i]."/";
|
|
if ( !is_dir($pathTmp) )
|
|
{
|
|
if(mkdir($pathTmp,$chmod)===true){
|
|
$tabresult[$cpt][1]=true;
|
|
chmod($pathTmp, $chmod);
|
|
}else{
|
|
$tabresult[$cpt][1]=false;
|
|
return $tabresult;
|
|
}
|
|
}
|
|
}
|
|
$cpt++;
|
|
}
|
|
return $tabresult;
|
|
}
|
|
|
|
/**
|
|
*Cette fonction charge un fichier ini, qui indique ou copier les fichier dans l'arbo granilim
|
|
*Le fichier .ini doit etre strucuturé comme suit:
|
|
*[source]
|
|
*testsource="./test/testdestination/"
|
|
* @access public
|
|
* @param chaine path vers le fichier ini
|
|
* @param entier valeur du umask
|
|
* @return tableau tableau d'état des fichier copier avec les paths sources et destinations et le status de la copie (true or false)
|
|
*/
|
|
function copyFileFromTab($tabini, $pkgname ,$chmod)
|
|
{
|
|
$tabresultcopie=array();
|
|
$tabperm=array();
|
|
$tabrep=array();
|
|
$tabbackup=array();
|
|
$cpt=0;
|
|
|
|
//Création des répertoires inexistant
|
|
//Appel fonction création rep, avec un umask en lecture et écriture sur tous les reps créés et les fichiers copiés
|
|
$tabrep=$this->createRep($tabini,$chmod);
|
|
|
|
if (count($tabini)>0){
|
|
foreach ($tabini as $key=>$struct)
|
|
{
|
|
$val=$this->getSystemPath($struct[0]);
|
|
//On verifie les permissions pour écraser le fichier s'il existe
|
|
if ($tabini[$key][1]===true && $tabrep[$cpt][1]===true)
|
|
{
|
|
if ($this->rename($val, ".php~")!==false)
|
|
{
|
|
if (copy($GLOBALS["CONF_DATA_PATH"]."data/upload/install/package/".$pkgname."/".$key, $val))
|
|
{
|
|
$tabresultcopie[$key][0]=$val;
|
|
$tabresultcopie[$key][1]=$this->setFilePerm($val, $chmod);
|
|
if (file_exists($val."~"))
|
|
{
|
|
@unlink($val."~");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$tabresultcopie[$key][0]=$val;
|
|
$tabresultcopie[$key][1]=false;
|
|
}
|
|
}else{
|
|
$tabresultcopie[$key][0]=$val;
|
|
$tabresultcopie[$key][1]=false;
|
|
}
|
|
}
|
|
$cpt++;
|
|
}
|
|
}
|
|
return $tabresultcopie;
|
|
}
|
|
|
|
/**
|
|
*Fonction qui verifie que les fichiers distants existent, et si ils existent qu'on a les droits pour les écraser.
|
|
* @access public
|
|
* @param tableau type tableau renvoyé par ParcoursIniTab
|
|
* @return tableau tableau contenant le path vers le fichier dont on veut vérifier les perms, et l'état de la permission testée (true or false)
|
|
*/
|
|
function verifFilePermFromTab($tab, $chmod)
|
|
{
|
|
$tabresult=array();
|
|
if (count($tab)>0)
|
|
{
|
|
//Vérification que les fichiers a copier existent, et si ils existent qu'on a les droits pour les écraser.
|
|
foreach ($tab as $key=>$val)
|
|
{
|
|
$tabresult[$key][0]=$this->getSystemPath($tab[$key][0]);
|
|
if (file_exists($this->getSystemPath($tab[$key][0])))
|
|
{
|
|
//Test des permission pour l'écraser
|
|
if ($this->verifFilePerm($this->getSystemPath($tab[$key][0]), "rw")) {
|
|
$tabresult[$key][1]=true;
|
|
}else{//Pas les droit pour écraser
|
|
if ($this->setFilePerm($this->getSystemPath($tab[$key][0]), $chmod)){
|
|
$tabresult[$key][1]=true;
|
|
}else{
|
|
$tabresult[$key][1]=false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Le fichier n'existe pas
|
|
$tabresult[$key][1]=true;
|
|
}
|
|
}
|
|
}
|
|
return $tabresult;
|
|
}
|
|
|
|
/**
|
|
* Permet de récupérer le bon path en fonction de la configuration serveur
|
|
* Ce path s'appuira sur les variables:
|
|
* - CONF_LIB_PATH (chemin d'accés à lib)<br/>
|
|
* - CONF_DATA_PATH (chemin d'accés aux données)<br/>
|
|
* - CONF_LOG_PATH (chemin d'accés aux logs)<br/>
|
|
* - $COMMUN_PATH_CONFIG (chemin d'accés aux fichiers de configuration)<br/>
|
|
* @return float version du fichier sinon 0
|
|
*/
|
|
function getSystemPath($pathFile){
|
|
$tabTmp=mb_split('/',$pathFile);
|
|
if ( (is_null($tabTmp[0])) || ($tabTmp[0]==".") ){
|
|
unset($tabTmp[0]);
|
|
return ($this->getSystemPath(implode("/", $tabTmp)));
|
|
}
|
|
# pathFile doit être correct maintenant
|
|
if(substr($pathFile, 0, 4)=="data")
|
|
return $GLOBALS["CONF_DATA_PATH"].$pathFile;
|
|
elseif(substr($pathFile, 0, 3)=="lib")
|
|
return $GLOBALS["CONF_LIB_PATH"].$pathFile;
|
|
elseif(substr($pathFile, 0, 3)=="log")
|
|
return $GLOBALS["CONF_LOG_PATH"].$pathFile;
|
|
elseif(substr($pathFile, 0, 6)=="config")
|
|
return $GLOBALS["COMMUN_PATH_CONFIG"].$pathFile;
|
|
elseif(substr($pathFile, 0, 7)=="install")
|
|
return "./".$pathFile;
|
|
return $pathFile;
|
|
}
|
|
|
|
/**
|
|
* Vérifie la configuration des droits systéme (droit php && utilisateur)
|
|
* retourne faux si les fichiers uploadés ne sont pas accessibles via php sinon int pour les droits à passer en chmod!!!
|
|
* @return entier droits a affecter aux fichiers && faux si inaccessibles
|
|
*/
|
|
function checkConfigForPerms($path=null){
|
|
if ($path==null)
|
|
{
|
|
$path=$GLOBALS["CONF_DATA_PATH"]."data/upload/install/";
|
|
}
|
|
|
|
//
|
|
// Gestion des droits d'acces
|
|
//
|
|
$ok = false;
|
|
$self = basename($_SERVER['PHP_SELF']);
|
|
$uid = @fileowner('.');
|
|
$uid2 = @fileowner($self);
|
|
$gid = @filegroup('.');
|
|
$gid2 = @filegroup($self);
|
|
$perms = @fileperms($self);
|
|
// var_dump(intval(substr(decoct( fileperms($self) ), 2)));
|
|
|
|
// Comparer l'appartenance d'un fichier cree par PHP
|
|
// avec celle du script et du repertoire courant
|
|
if (is_dir($path.'test')){
|
|
@rmdir($path.'test');
|
|
}elseif(is_file($path.'test')){
|
|
@unlink($path.'test'); // effacer au cas ou
|
|
}
|
|
|
|
@touch($path.'test');
|
|
if ($uid > 0 && $uid == $uid2 && @fileowner($path.'test') == $uid)
|
|
$chmod = 0700;
|
|
else if ($gid > 0 && $gid == $gid2 && @filegroup($path.'test') == $gid)
|
|
$chmod = 0770;
|
|
else
|
|
$chmod = 0775;
|
|
|
|
// Appliquer de plus les droits d'acces du script
|
|
if ($perms > 0) {
|
|
$perms = ($perms & 0775) | (($perms & 0444) >> 2);
|
|
$chmod |= $perms;
|
|
}
|
|
@unlink($path.'test');
|
|
|
|
// Verifier que les valeurs sont correctes
|
|
@mkdir($path.'test', $chmod);
|
|
@chmod($path.'test', $chmod);
|
|
$f = @fopen($path.'test/test.php', 'w');
|
|
if ($f) {
|
|
@fputs($f, '<?php $ok = true; ?>');
|
|
@fclose($f);
|
|
@chmod($path.'test/test.php', $chmod);
|
|
include($path.'test/test.php');
|
|
}
|
|
|
|
if (!$ok) {
|
|
return false;
|
|
}else{
|
|
@unlink($path.'test/test.php');
|
|
@rmdir($path.'test');
|
|
return $chmod;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* chown et chgrp en recursif !!!!
|
|
* merci php.net
|
|
* @link http://fr3.php.net/manual/fr/function.chown.php
|
|
*/
|
|
function recurse_chown_chgrp($path2dir, $uid, $gid){
|
|
$dir = new dir($path2dir);
|
|
while(($file = $dir->read()) !== false) {
|
|
if(is_dir($dir->path.$file)) {
|
|
recurse_chown_chgrp($dir->path.$file, $uid, $gid);
|
|
} else {
|
|
chown($file, $uid);
|
|
chgrp($file, $gid);
|
|
}
|
|
}
|
|
$dir->close();
|
|
}
|
|
}
|
|
?>
|