diff --git a/bureau/admin/adm_doms_def_type.php b/bureau/admin/adm_doms_def_type.php index 3cc2b613..76e4a9c7 100644 --- a/bureau/admin/adm_doms_def_type.php +++ b/bureau/admin/adm_doms_def_type.php @@ -2,92 +2,90 @@ require_once("../class/config.php"); if (!$admin->enabled) { - __("This page is restricted to authorized staff"); + __("This page is restricted to authorized staff"); exit(); - } +} - include_once("head.php"); +include_once("head.php"); +?> +
+"._("Uncompressing through TAR")."
";
- passthru("tar -xf ".escapeshellarg($file)." -C ".escapeshellarg($dest)." 2>&1", $ret);
- }
- if (substr($lfile,-4)==".zip") {
- echo ""._("Uncompressing through UNZIP")."
";
- $cmd="unzip -o ".escapeshellarg($file)." -d ".escapeshellarg($dest)." 2>&1";
- passthru($cmd, $ret);
- }
- if (substr($lfile,-3)==".gz") {
- echo ""._("Uncompressing through GUNZIP")."
";
- $cmd="gunzip ".escapeshellarg($file)." 2>&1";
- passthru($cmd, $ret);
- }
- echo "
";
- if ($ret) {
- $err->raise("bro",_("I cannot find a way to extract the file %s, it is an unsupported compressed format"), $file);
- }
- // fix the perms of the extracted archive TODO: does it work???
- $action->fix_dir($dest_to_fix);
- return $ret;
- }
-
- /**
- * Copy many files from point A to point B
- *
- * @global m_err $err
- * @param array $d List of files to move
- * @param string $old
- * @param string $new
- * @return boolean
- */
- function CopyFile($d,$old,$new) {
- global $err;
- $old=$this->convertabsolute($old,false);
- if (!$old) {
- $err->raise("bro",_("File or folder name is incorrect"));
- return false;
+ /**
+ * Crée un fichier vide dans un dossier
+ *
+ * @global m_mysql $db
+ * @global m_err $err
+ * @global int $cuid
+ * @param string $dir Dossier dans lequel on veut crer un sous-dossier
+ * @param string $file Nom du dossier à créer
+ * @return boolean TRUE si le dossier a été créé, FALSE si une erreur s'est produite.
+ */
+ function CreateFile($dir, $file) {
+ global $db, $err, $cuid;
+ $file = ssla($file);
+ $absolute = $this->convertabsolute($dir . "/" . $file, false);
+ if (!$absolute || file_exists($absolute)) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ if (!file_exists($absolute)) {
+ if (!@touch($absolute)) {
+ $err->raise("bro", _("Cannot create the requested file. Please check the permissions"));
+ return false;
+ }
+ }
+ $db->query("UPDATE browser SET crff=0 WHERE uid='$cuid';");
+ return true;
}
- $new=$this->convertabsolute($new,false);
- if (!$new) {
- $err->raise("bro",_("File or folder name is incorrect"));
- return false;
+
+ /**
+ * Efface les fichiers du tableau $file_list dans le dossier $R
+ *
+ * @global m_err $err
+ * @global m_mem $mem
+ * @param array $file_list Liste des fichiers effacer.
+ * @param string $R Dossier dans lequel on efface les fichiers
+ * @return boolean TRUE si les fichiers ont t effacs, FALSE si une erreur s'est produite.
+ */
+ function DeleteFile($file_list, $R) {
+ global $err;
+ $root = realpath(getuserpath());
+ $absolute = $this->convertabsolute($R, false);
+ if (!$absolute && strpos($root, $absolute) === 0 && strlen($absolute) > (strlen($root) + 1)) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ for ($i = 0; $i < count($file_list); $i++) {
+ $file_list[$i] = ssla($file_list[$i]);
+ if (!strpos($file_list[$i], "/") && file_exists($absolute . "/" . $file_list[$i])) { // Character / forbidden in a FILE name
+ $this->_delete($absolute . "/" . $file_list[$i]);
+ }
+ }
+ return true;
}
- if ($old == $new) {
- $err->raise("bro",_("You cannot move or copy a file to the same folder"));
- return false;
+
+ /**
+ * Renomme les fichier de $old du dossier $R en $new
+ *
+ * @global m_err $err
+ * @param string $R Dossier dans lequel se trouve les fichiers renommer.
+ * @param array $old Ancien nom des fichiers
+ * @param array $new Nouveau nom des fichiers
+ * @return boolean TRUE si les fichiers ont t renomms, FALSE si une erreur s'est produite.
+ */
+ function RenameFile($R, $old, $new) {
+ global $err;
+ $absolute = $this->convertabsolute($R, false);
+ if (!$absolute) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ $alea = "." . time() . rand(1000, 9999);
+ for ($i = 0; $i < count($old); $i++) {
+ $old[$i] = ssla($old[$i]); // strip slashes if needed
+ $new[$i] = ssla($new[$i]);
+ if (!strpos($old[$i], "/") && !strpos($new[$i], "/")) { // caractre / interdit dans old ET dans new...
+ @rename($absolute . "/" . $old[$i], $absolute . "/" . $old[$i] . $alea);
+ }
+ }
+ for ($i = 0; $i < count($old); $i++) {
+ if (!strpos($old[$i], "/") && !strpos($new[$i], "/")) { // caractre / interdit dans old ET dans new...
+ @rename($absolute . "/" . $old[$i] . $alea, $absolute . "/" . $new[$i]);
+ }
+ }
+
+ return true;
}
- for ($i=0;$iCopyOneFile($old."/".$d[$i],$new);
- }
+
+ /**
+ * Déplace les fichier de $d du dossier $old vers $new
+ *
+ * @global m_err $err
+ * @param array $d Liste des fichiers du dossier $old dplacer
+ * @param string $old Dossier dans lequel se trouve les fichiers dplacer.
+ * @param string $new Dossier vers lequel seront dplacs les fichiers.
+ * @return boolean TRUE si les fichiers ont t renomms, FALSE si une erreur s'est produite.
+ */
+ function MoveFile($d, $old, $new) {
+ global $err;
+ $old = $this->convertabsolute($old, false);
+ if (!$old) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+
+ if ($new[0] != '/') {
+ $new = $old . '/' . $new;
+ }
+ $new = $this->convertabsolute($new, false);
+
+ if (!$new) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ if ($old == $new) {
+ $err->raise("bro", _("You cannot move or copy a file to the same folder"));
+ return false;
+ }
+ for ($i = 0; $i < count($d); $i++) {
+ $d[$i] = ssla($d[$i]); // strip slashes if needed
+ if (!strpos($d[$i], "/") && file_exists($old . "/" . $d[$i]) && !file_exists($new . "/" . $d[$i])) {
+ if (!rename($old . "/" . $d[$i], $new . "/" . $d[$i])) {
+ $err->raise("bro", "error renaming $old/$d[$i] -> $new/$d[$i]");
+ }
+ }
+ }
+ return true;
}
- return true;
- }
+ /**
+ * Change les droits d'acces aux fichier de $d du dossier $R en $p
+ *
+ * @param string $R Dossier dans lequel se trouve les fichiers renommer.
+ * @param string $d list of files whose permission must be changed
+ * @param string $perm the permission to change
+ * @param boolean $verbose Shall we 'echo' what we did ?
+ * @return boolean TRUE Si les fichiers ont t renomms, FALSE si une erreur s'est produite.
+ */
+ function ChangePermissions($R, $d, $perm, $verbose = false) {
+ global $err, $action;
+ $absolute = $this->convertabsolute($R, false);
+ if (!$absolute) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ for ($i = 0; $i < count($d); $i++) {
+ $d[$i] = ssla($d[$i]); // strip slashes if needed
+ if (!strpos($d[$i], "/")) { // caractre / interdit dans le nom du fichier
+ $m = fileperms($absolute . "/" . $d[$i]);
- /**
- * Copy a source to a destination by either copying recursively a
- * directory or by downloading a file with a URL (only http:// is
- * supported)
- *
- * Note that we assume that the inputs have been convertabsolute()'d
- *
- * @global m_err $err
- * @param string $src Path or URL
- * @param string $dest Absolute path inside the users directory
- * @return boolean false on error
- */
- function CopyOneFile($src, $dest) {
- global $err;
- exec("cp -Rpf ".escapeshellarg($src)." ".escapeshellarg($dest), $void, $ret);
- if ($ret) {
- $err->raise("bro","Errors happened while copying the source to destination. cp return value: %d", $ret);
- return false;
+ // pour l'instant on se limite a "write" pour owner, puisque c'est le seul
+ // cas interessant compte tenu de la conf de Apache pour AlternC..
+ if ($perm[$i]['w']) {
+ $m = $m | 0220; // ug+w
+ } else {
+ $m = $m & (~ 0222); // ugo-w
+ }
+ $action->chmod($absolute . "/" . $d[$i], $m);
+ if ($verbose) {
+ echo "chmod " . sprintf('%o', $m) . " file, was " . sprintf('%o', fileperms($absolute . "/" . $d[$i])) . " -- " . $perm[$i]['w'];
+ }
+ }
+ }
+
+ return true;
}
- return true;
- }
-
- /**
- * Affiche le chemin et les liens de la racine au dossier $path
- * Affiche autant de liens HTML (anchor) que le chemin $path contient de
- * niveaux de dossier. Chaque lien est associ la page web $action
- * laquelle on ajoute le paramtre R=+Le nom du dossier courant.
- *
- * @param string $path Dossier vers lequel on trace le chemin
- * @param string $action Page web de destination des liens
- * @param boolean $justparent
- * @return string Le code HTML ainsi obtenu.
- */
- function PathList($path,$action, $justparent=false) {
- $path=$this->convertabsolute($path,true);
- $a=explode("/",$path);
- if (!is_array($a)) $a=array($a);
- $c='';
- $R='';
- if ($justparent) {
- return "↑";
+ /**
+ * Recoit un champ file upload (Global) et le stocke dans le dossier $R
+ * Le champ file-upload originel doit s'appeler "userfile" et doit
+ * bien être un fichier d'upload.
+ *
+ *
+ * @global array $_FILES
+ * @global m_err $err
+ * @global int $cuid
+ * @global m_action $action
+ * @param string $R Dossier dans lequel on upload le fichier
+ * @returns string The path where the file resides or false if upload failed
+ */
+ function UploadFile($R) {
+ global $_FILES, $err, $cuid, $action;
+ $absolute = $this->convertabsolute($R, false);
+ if (!$absolute) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ if (!strpos($_FILES['userfile']['name'], "/")) {
+ if ($_FILES['userfile']['error'] == UPLOAD_ERR_OK && is_uploaded_file($_FILES['userfile']['tmp_name'])) {
+ if (!file_exists($absolute . "/" . $_FILES['userfile']['name'])) {
+ @touch($absolute . "/" . $_FILES['userfile']['name']);
+ }
+ if (@move_uploaded_file($_FILES['userfile']['tmp_name'], $absolute . "/" . $_FILES['userfile']['name'])) {
+ $action->fix_file($absolute . "/" . $_FILES['userfile']['name']);
+ return $absolute . "/" . $_FILES['userfile']['name'];
+ } else {
+ $err->raise("bro", _("Cannot create the requested file. Please check the permissions"));
+ return false;
+ }
+ } else {
+ // there was an error, raise it
+ $err->log("bro", "uploadfile", "Problem when uploading a file");
+ switch ($_FILES['userfile']['error']) {
+ case UPLOAD_ERR_INI_SIZE:
+ $erstr = _("The uploaded file exceeds the max file size allowed");
+ break;
+ case UPLOAD_ERR_FORM_SIZE:
+ case UPLOAD_ERR_PARTIAL:
+ case UPLOAD_ERR_NO_FILE:
+ case UPLOAD_ERR_NO_TMP_DIR:
+ case UPLOAD_ERR_CANT_WRITE:
+ case UPLOAD_ERR_EXTENSION:
+ default:
+ $erstr = _("Undefined error ") . $_FILES['userfile']['error'];
+ break;
+ }
+ $err->raise("bro", _("Error during the upload of the file: ") . $erstr);
+ return false;
+ }
+ }
+ return $absolute . "/" . $_FILES['userfile']['name'];
}
- for($i=0;$i".$a[$i]." / ";
- }
+
+ /**
+ * Extract an archive by using GNU and non-GNU tools
+ *
+ * @global m_err $err
+ * @global int $cuid
+ * @global m_mem $mem
+ * @global m_action $action
+ * @param string $file Full or relative path to the archive
+ * @param string $dest Path of the extract destination, the
+ * same directory as the archive by default
+ * @return integer|null != 0 on error
+ */
+ function ExtractFile($file, $dest = null) {
+ global $err, $action;
+ $file = $this->convertabsolute($file, false);
+ if (is_null($dest)) {
+ $dest = dirname($file);
+ } else {
+ $dest = $this->convertabsolute($dest, false);
+ }
+ if (!$file || !$dest || !is_readable($file)) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return 1;
+ }
+ $lfile = strtolower($file);
+ if (substr($lfile, -4) == ".tar" || substr($lfile, -8) == ".tar.bz2" || substr($lfile, -7) == ".tar.gz" || substr($lfile, -6) == ".tar.z") {
+ // TODO new version of tar supports `tar xf ...` so there is no
+ // need to specify the compression format
+ echo "" . _("Uncompressing through TAR") . "
";
+ $ret = 0;
+ passthru("tar -xf " . escapeshellarg($file) . " -C " . escapeshellarg($dest) . " 2>&1", $ret);
+ }
+ if (substr($lfile, -4) == ".zip") {
+ echo "" . _("Uncompressing through UNZIP") . "
";
+ $cmd = "unzip -o " . escapeshellarg($file) . " -d " . escapeshellarg($dest) . " 2>&1";
+ passthru($cmd, $ret);
+ }
+ if (substr($lfile, -3) == ".gz") {
+ echo "" . _("Uncompressing through GUNZIP") . "
";
+ $cmd = "gunzip " . escapeshellarg($file) . " 2>&1";
+ passthru($cmd, $ret);
+ }
+ echo "
";
+ if ($ret) {
+ $err->raise("bro", _("I cannot find a way to extract the file %s, it is an unsupported compressed format"), $file);
+ }
+ // fix the perms of the extracted archive TODO: does it work??? | note: it was using a wrong variable name !
+ $action->fix_dir($dest);
+ return $ret;
}
- return $c;
- }
-
- /**
- * Affiche le contenu d'un fichier pour un champ VALUE de textarea
- *
- * Affiche le contenu du fichier $file dans le dossier $R. Le contenu
- * du fichier est reformat pour pouvoir entrer dans un champs TextArea
- *
- * @global m_err $err
- * @param string $R Dossier dans lequel on cherche le fichier
- * @param string $file Fichier dont on souhaite obtenir le contenu.
- * @return string|false TRUE si le fichier a bien été mis sur
- * echo, ou FALSE si une erreur est survenue.
- */
- function content($R,$file) {
- global $err;
- $absolute=$this->convertabsolute($R,false);
- if (!strpos($file,"/")) {
- $absolute.="/".$file;
- if (file_exists($absolute)) {
- $std=str_replace("<","<",str_replace("&","&",file_get_contents($absolute)));
- return $std;
- } else {
- $err->raise("bro",_("Cannot read the requested file. Please check the permissions"));
- return false;
- }
- } else {
- $err->raise("bro",_("File or folder name is incorrect"));
- return false;
+ /**
+ * Copy many files from point A to point B
+ *
+ * @global m_err $err
+ * @param array $d List of files to move
+ * @param string $old
+ * @param string $new
+ * @return boolean
+ */
+ function CopyFile($d, $old, $new) {
+ global $err;
+ $old = $this->convertabsolute($old, false);
+ if (!$old) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ $new = $this->convertabsolute($new, false);
+ if (!$new) {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ if ($old == $new) {
+ $err->raise("bro", _("You cannot move or copy a file to the same folder"));
+ return false;
+ }
+ for ($i = 0; $i < count($d); $i++) {
+ $d[$i] = ssla($d[$i]); // strip slashes if needed
+ if (!strpos($d[$i], "/") && file_exists($old . "/" . $d[$i]) && !file_exists($new . "/" . $d[$i])) {
+ $this->CopyOneFile($old . "/" . $d[$i], $new);
+ }
+ }
+ return true;
}
- }
+ /**
+ * Copy a source to a destination by either copying recursively a
+ * directory or by downloading a file with a URL (only http:// is
+ * supported)
+ *
+ * Note that we assume that the inputs have been convertabsolute()'d
+ *
+ * @global m_err $err
+ * @param string $src Path or URL
+ * @param string $dest Absolute path inside the users directory
+ * @return boolean false on error
+ */
+ function CopyOneFile($src, $dest) {
+ global $err;
+ exec("cp -Rpf " . escapeshellarg($src) . " " . escapeshellarg($dest), $void, $ret);
+ if ($ret) {
+ $err->raise("bro", "Errors happened while copying the source to destination. cp return value: %d", $ret);
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Affiche le chemin et les liens de la racine au dossier $path
+ * Affiche autant de liens HTML (anchor) que le chemin $path contient de
+ * niveaux de dossier. Chaque lien est associ la page web $action
+ * laquelle on ajoute le paramtre R=+Le nom du dossier courant.
+ *
+ * @param string $path Dossier vers lequel on trace le chemin
+ * @param string $action Page web de destination des liens
+ * @param boolean $justparent
+ * @return string Le code HTML ainsi obtenu.
+ */
+ function PathList($path, $action, $justparent = false) {
+ $path = $this->convertabsolute($path, true);
+ $a = explode("/", $path);
+ if (!is_array($a)) {
+ $a = array($a);
+ }
+ $c = '';
+ $R = '';
+ if ($justparent) {
+ return "↑";
+ }
+ for ($i = 0; $i < count($a); $i++) {
+ if ($a[$i]) {
+ $R.=$a[$i] . "/";
+ $c.="" . $a[$i] . " / ";
+ }
+ }
+ return $c;
+ }
- /**
- * Retourne une url de navigation pour le fichier $name du dossier $dir
- * Les url sont mises en caches. Il se peut qu'aucune url n'existe, ou que
- * celle-ci soit protge par un .htaccess.
- *
- * Return a browsing url if available.
- * Maintain a url cache (positive AND negative(-) cache)
- *
- * @global m_mysql $db
- * @global int $cuid
- *
- * @param string $dir Dossier concerné
- * @param string $name Fichier dont on souhaite obtenir une URL
- * @return string URL concerne, ou FALSE si aucune URL n'est disponible pour ce fichier
- */
- function viewurl($dir,$name) {
- global $db,$cuid;
- // Is it in cache ?
- if (substr($dir,0,1) == "/") $dir=substr($dir,1);
- if (substr($dir,-1) == "/") $dir=substr($dir,0,-1);
- $dir=str_replace("%2F", "/", urlencode($dir));
- $name=urlencode($name);
- if (!@$this->cacheurl["d".$dir]) {
- // On parcours $dir en remontant les /
- $end=""; $beg=$dir; $tofind=true;
- while ($tofind) {
- $db->query("SELECT sub,domaine FROM sub_domaines WHERE compte='$cuid'
+ /**
+ * Affiche le contenu d'un fichier pour un champ VALUE de textarea
+ *
+ * Affiche le contenu du fichier $file dans le dossier $R. Le contenu
+ * du fichier est reformat pour pouvoir entrer dans un champs TextArea
+ *
+ * @global m_err $err
+ * @param string $R Dossier dans lequel on cherche le fichier
+ * @param string $file Fichier dont on souhaite obtenir le contenu.
+ * @return string|false TRUE si le fichier a bien été mis sur
+ * echo, ou FALSE si une erreur est survenue.
+ */
+ function content($R, $file) {
+ global $err;
+ $absolute = $this->convertabsolute($R, false);
+ if (!strpos($file, "/")) {
+ $absolute.="/" . $file;
+ if (file_exists($absolute)) {
+ $std = str_replace("<", "<", str_replace("&", "&", file_get_contents($absolute)));
+ return $std;
+ } else {
+ $err->raise("bro", _("Cannot read the requested file. Please check the permissions"));
+ return false;
+ }
+ } else {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ }
+
+ /**
+ * Retourne une url de navigation pour le fichier $name du dossier $dir
+ * Les url sont mises en caches. Il se peut qu'aucune url n'existe, ou que
+ * celle-ci soit protge par un .htaccess.
+ *
+ * Return a browsing url if available.
+ * Maintain a url cache (positive AND negative(-) cache)
+ *
+ * @global m_mysql $db
+ * @global int $cuid
+ *
+ * @param string $dir Dossier concerné
+ * @param string $name Fichier dont on souhaite obtenir une URL
+ * @return string URL concerne, ou FALSE si aucune URL n'est disponible pour ce fichier
+ */
+ function viewurl($dir, $name) {
+ global $db, $cuid;
+ // Is it in cache ?
+ if (substr($dir, 0, 1) == "/") {
+ $dir = substr($dir, 1);
+ }
+ if (substr($dir, -1) == "/") {
+ $dir = substr($dir, 0, -1);
+ }
+ $dir = str_replace("%2F", "/", urlencode($dir));
+ $name = urlencode($name);
+ if (!@$this->cacheurl["d" . $dir]) {
+ // On parcours $dir en remontant les /
+ $end = "";
+ $beg = $dir;
+ $tofind = true;
+ while ($tofind) {
+ $db->query("SELECT sub,domaine FROM sub_domaines WHERE compte='$cuid'
AND type=0 AND (valeur='/$beg/' or valeur='/$beg');");
- $db->next_record();
- if ($db->num_rows()) {
- $tofind=false;
- $this->cacheurl["d".$dir]="http://".$db->f("sub").ife($db->f("sub"),".").$db->f("domaine").$end;
- }
- if (!$beg && $tofind) {
- $tofind=false;
- $this->cacheurl["d".$dir]="-";
- // We did not find it ;(
- }
- if (($tt=strrpos($beg,"/"))!==false) {
- $end=substr($beg,$tt).$end; //=/topdir$end so $end starts AND ends with /
- $beg=substr($beg,0,$tt);
- } else {
- $end="/".$beg.$end;
- $beg="/";
- }
- }
- }
- if ($this->cacheurl["d".$dir] && $this->cacheurl["d".$dir]!="-") {
- return $this->cacheurl["d".$dir]."/".$name;
- } else {
- return false;
- }
- }
-
- /**
- *
- * @global m_mem $mem
- * @global m_err $err
- * @param string $dir
- * @param string $name
- * @return null|boolean
- */
- function can_edit($dir,$name) {
- global $mem,$err;
- $absolute="$dir/$name";
- $absolute=$this->convertabsolute($absolute,false);
- if (!$absolute) {
- $err->raise('bro',_("File not in authorized directory"));
- include('foot.php');
- exit;
- }
- $finfo=finfo_open(FILEINFO_MIME_TYPE);
- $mime=finfo_file($finfo,$absolute);
- if ( substr($mime,0,5) == "text/" || $mime == "application/x-empty" || $mime == "inode/x-empty") {
- return true;
- }
- return false;
- }
-
-
- /**
- * Return a HTML snippet representing an extraction function only if the mimetype of $name is supported
- *
- * @param string $name
- * @return boolean
- */
- function is_extractable($name) {
- if ($parts=explode(".", $name)) {
- $ext=array_pop($parts);
- switch ($ext) {
- case "gz":
- case "bz":
- case "bz2":
- $ext=array_pop($parts).$ext;
- /* FALLTHROUGH */
- case "tar.gz":
- case "tar.bz":
- case "tar.bz2":
- case "tgz":
- case "tbz":
- case "tbz2":
- case "tar":
- case "Z":
- case "zip":
- return true;
- }
- }
- return false;
- }
-
- /**
- * return true if file is a sql dump (end with .sql or .sql.gz)
- *
- * @param type $dir
- * @param type $name
- * @return boolean
- */
- function is_sqlfile($name) {
- if ($parts=explode(".", $name)) {
- $ext=array_pop($parts);
- $ext2=array_pop($parts).'.'.$ext;
- if ( $ext == 'sql' or $ext2 == 'sql.gz') return true;
- }
- return false;
- }
-
- /**
- *
- * @global m_err $err
- * @param string $dir
- * @param string $file
- */
- function download_link($dir,$file){
- global $err;
- $err->log("bro","download_link");
- header("Content-Disposition: attachment; filename=$file");
- header("Content-Type: application/force-download");
- header("Content-Transfer-Encoding: binary");
- $this->content_send($dir,$file);
- }
-
-
- /**
- * Echoes the content of the file $file located in directory $R
- *
- * @global m_err $err
- * @param string $R
- * @param string $file
- * @return null|false
- */
- function content_send($R,$file) {
- global $err;
- $absolute=$this->convertabsolute($R,false);
- if (!strpos($file,"/")) {
- $absolute.="/".$file;
- if (file_exists($absolute)) {
- readfile($absolute);
- }
- } else {
- $err->raise("bro",_("File or folder name is incorrect"));
- return false;
- }
- }
-
-
- /**
- * Sauve le fichier $file dans le dossier $R avec pour contenu $texte
- * le contenu est issu d'un textarea, et ne DOIT PAS contenir de \ ajouts
- * automatiquement par addslashes
- *
- * @global m_err $err
- * @param string $file Nom du fichier sauver. S'il existe déjà , il sera
- * écrasé sans confirmation.
- * @param string $R Dossier dans lequel on modifie le fichier
- * @param string $texte Texte du fichier à sauver dedans
- * @return false|null TRUE si tout s'est bien pass, FALSE si une erreur s'est produite.
- */
- function save($file,$R,$texte) {
- global $err;
- $absolute=$this->convertabsolute($R,false);
- if (!strpos($file,"/")) {
- $absolute.="/".$file;
- if (file_exists($absolute)) {
- if (! file_put_contents($absolute, $texte ) ) {
- $err->raise("bro",_("Cannot edit the requested file. Please check the permissions"));
- return false;
- }
- }
- } else {
- $err->raise("bro",_("File or folder name is incorrect"));
- return false;
- }
- }
-
-
- /**
- * Echo d'un flux .tar.Z contenant tout le contenu du dossier $dir
- *
- * @global m_mem $mem
- * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
- * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
- */
- function DownloadZ($dir="") {
- global $mem;
- header("Content-Disposition: attachment; filename=".$mem->user["login"].".Z");
- header("Content-Type: application/x-Z");
- header("Content-Transfer-Encoding: binary");
- $d=escapeshellarg(".".$this->convertabsolute($dir,true));
- set_time_limit(0);
- passthru("/bin/tar -cZ -C ".getuserpath()."/".$mem->user["login"]."/ $d");
- }
-
-
- /**
- * Echo d'un flux .tgz contenant tout le contenu du dossier $dir
- *
- * @global type $mem
- * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
- * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
- */
- function DownloadTGZ($dir="") {
- global $mem;
- header("Content-Disposition: attachment; filename=".$mem->user["login"].".tgz");
- header("Content-Type: application/x-tgz");
- header("Content-Transfer-Encoding: binary");
- $d=escapeshellarg(".".$this->convertabsolute($dir,true));
- set_time_limit(0);
- passthru("/bin/tar -cz -C ".getuserpath()."/ $d");
- }
-
-
- /**
- * Echo d'un flux .tar.bz2 contenant tout le contenu du dossier $dir
- *
- * @global type $mem
- * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
- * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
- */
- function DownloadTBZ($dir="") {
- global $mem;
- header("Content-Disposition: attachment; filename=".$mem->user["login"].".tar.bz2");
- header("Content-Type: application/x-bzip2");
- header("Content-Transfer-Encoding: binary");
- $d=escapeshellarg(".".$this->convertabsolute($dir,true));
- set_time_limit(0);
- passthru("/bin/tar -cj -C ".getuserpath()."/ $d");
- }
-
-
-
- /**
- * Echo d'un flux .ZIP contenant tout le contenu du dossier $dir
- *
- * @global type $mem
- * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
- * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
- */
- function DownloadZIP($dir="") {
- global $mem;
- header("Content-Disposition: attachment; filename=".$mem->user["login"].".zip");
- header("Content-Type: application/x-zip");
- header("Content-Transfer-Encoding: binary");
- $d=escapeshellarg($this->convertabsolute($dir,false));
- set_time_limit(0);
- passthru("/usr/bin/zip -r - $d");
- }
-
-
- /**
- * Fonction de tri perso utilis par filelist.
- *
- * @access private
- * @param string $a
- * @param string $b
- * @return int
- */
- function _sort_filelist_name($a,$b) {
- if ($a["type"] && !$b["type"]) return 1;
- if ($b["type"] && !$a["type"]) return -1;
- return $a["name"]>$b["name"];
- }
-
-
- /**
- * Efface $file et tous ses sous-dossiers s'il s'agit d'un dossier
- * A UTILISER AVEC PRECAUTION !!!
- * @param string $file Fichier ou dossier supprimer.
- * @access private
- */
- function _delete($file) {
- global $err;
- // permet d'effacer de nombreux fichiers
- @set_time_limit(0);
- //chmod($file,0777);
- $err->log("bro", "_delete($file)");
- if (is_dir($file)) {
- $handle=opendir($file);
- while (($filename=readdir($handle)) !== false) {
- if ($filename != "." && $filename != "..") {
- $this->_delete($file."/".$filename);
- }
- }
- closedir($handle);
- rmdir($file);
- } else {
- unlink($file);
- }
- }
-
-
- /**
- * Function d'exportation de configuration appelé par la classe m_export via un hooks
- * Produit en sorti un tableau formatté ( pour le moment) en HTML
- *
- * @global m_mysql $db
- * @global m_err $err
- * @return string
- */
- function alternc_export_conf() {
- global $db,$err;
- $err->log("bro","export_conf");
- $str=" Browser \n";
- $str.=" \n";
- $pref=$this->GetPrefs();
-
- $i=1;
- foreach ($pref as $k=>$v) {
- if (($i % 2) == 0){
- $str.=" <$k>$v$k>\n";
- }
- $i++;
- }
- $str.=" \n";
-
- return $str;
- }
-
-
- /**
- * Function d'exportation des données appelé par la classe m_export via un hooks
- *
- * @global m_mem $mem
- * @global m_err $err
- * @param string $dir Le chemin destination du tarball produit
- * @return boolean|null
- */
- function alternc_export_data($dir){
- global $mem,$err;
- $err->log("bro","export_data");
- $dir.="html/";
- if(!is_dir($dir)){
- if(!mkdir($dir))
- $err->raise("bro",_("Cannot create the requested directory. Please check the permissions"));
- }
- $timestamp=date("H:i:s");
-
- if(exec("/bin/tar cvf - ".escapeshellarg(getuserpath()."/")."| gzip -9c > ".escapeshellarg($dir."/".$mem->user['login']."_html_".$timestamp.".tar.gz"))) {
- $err->log("bro","export_data_succes");
- } else {
- $err->log("bro","export_data_failed");
+ $db->next_record();
+ if ($db->num_rows()) {
+ $tofind = false;
+ $this->cacheurl["d" . $dir] = "http://" . $db->f("sub") . ife($db->f("sub"), ".") . $db->f("domaine") . $end;
+ }
+ if (!$beg && $tofind) {
+ $tofind = false;
+ $this->cacheurl["d" . $dir] = "-";
+ // We did not find it ;(
+ }
+ if (($tt = strrpos($beg, "/")) !== false) {
+ $end = substr($beg, $tt) . $end; //=/topdir$end so $end starts AND ends with /
+ $beg = substr($beg, 0, $tt);
+ } else {
+ $end = "/" . $beg . $end;
+ $beg = "/";
+ }
+ }
+ }
+ if ($this->cacheurl["d" . $dir] && $this->cacheurl["d" . $dir] != "-") {
+ return $this->cacheurl["d" . $dir] . "/" . $name;
+ } else {
+ return false;
+ }
}
- }
+ /**
+ *
+ * @global m_mem $mem
+ * @global m_err $err
+ * @param string $dir
+ * @param string $name
+ * @return null|boolean
+ */
+ function can_edit($dir, $name) {
+ global $err;
+ $absolute = "$dir/$name";
+ $absolute = $this->convertabsolute($absolute, false);
+ if (!$absolute) {
+ $err->raise('bro', _("File not in authorized directory"));
+ include('foot.php');
+ exit;
+ }
+ $finfo = finfo_open(FILEINFO_MIME_TYPE);
+ $mime = finfo_file($finfo, $absolute);
+ if (substr($mime, 0, 5) == "text/" || $mime == "application/x-empty" || $mime == "inode/x-empty") {
+ return true;
+ }
+ return false;
+ }
- function getMaxAllowedUploadSize() {
- return min(ini_get('post_max_size'), ini_get('upload_max_filesize'));
- }
+ /**
+ * Return a HTML snippet representing an extraction function only if the mimetype of $name is supported
+ *
+ * @param string $name
+ * @return boolean
+ */
+ function is_extractable($name) {
+ if (($parts = explode(".", $name))) {
+ $ext = array_pop($parts);
+ switch ($ext) {
+ case "gz":
+ case "bz":
+ case "bz2":
+ $ext = array_pop($parts) . $ext;
+ /* FALLTHROUGH */
+ case "tar.gz":
+ case "tar.bz":
+ case "tar.bz2":
+ case "tgz":
+ case "tbz":
+ case "tbz2":
+ case "tar":
+ case "Z":
+ case "zip":
+ return true;
+ }
+ }
+ return false;
+ }
-} /* Class Browser */
+ /**
+ * return true if file is a sql dump (end with .sql or .sql.gz)
+ *
+ * @param type $dir
+ * @param type $name
+ * @return boolean
+ */
+ function is_sqlfile($name) {
+ if (($parts = explode(".", $name))) {
+ $ext = array_pop($parts);
+ $ext2 = array_pop($parts) . '.' . $ext;
+ if ($ext == 'sql' or $ext2 == 'sql.gz') {
+ return true;
+ }
+ }
+ return false;
+ }
+ /**
+ *
+ * @global m_err $err
+ * @param string $dir
+ * @param string $file
+ */
+ function download_link($dir, $file) {
+ global $err;
+ $err->log("bro", "download_link");
+ header("Content-Disposition: attachment; filename=$file");
+ header("Content-Type: application/force-download");
+ header("Content-Transfer-Encoding: binary");
+ $this->content_send($dir, $file);
+ }
+
+ /**
+ * Echoes the content of the file $file located in directory $R
+ *
+ * @global m_err $err
+ * @param string $R
+ * @param string $file
+ * @return null|false
+ */
+ function content_send($R, $file) {
+ global $err;
+ $absolute = $this->convertabsolute($R, false);
+ if (!strpos($file, "/")) {
+ $absolute.="/" . $file;
+ if (file_exists($absolute)) {
+ readfile($absolute);
+ }
+ } else {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ }
+
+ /**
+ * Sauve le fichier $file dans le dossier $R avec pour contenu $texte
+ * le contenu est issu d'un textarea, et ne DOIT PAS contenir de \ ajouts
+ * automatiquement par addslashes
+ *
+ * @global m_err $err
+ * @param string $file Nom du fichier sauver. S'il existe déjà , il sera
+ * écrasé sans confirmation.
+ * @param string $R Dossier dans lequel on modifie le fichier
+ * @param string $texte Texte du fichier à sauver dedans
+ * @return false|null TRUE si tout s'est bien pass, FALSE si une erreur s'est produite.
+ */
+ function save($file, $R, $texte) {
+ global $err;
+ $absolute = $this->convertabsolute($R, false);
+ if (!strpos($file, "/")) {
+ $absolute.="/" . $file;
+ if (file_exists($absolute)) {
+ if (!file_put_contents($absolute, $texte)) {
+ $err->raise("bro", _("Cannot edit the requested file. Please check the permissions"));
+ return false;
+ }
+ }
+ } else {
+ $err->raise("bro", _("File or folder name is incorrect"));
+ return false;
+ }
+ }
+
+ /**
+ * Echo d'un flux .tar.Z contenant tout le contenu du dossier $dir
+ *
+ * @global m_mem $mem
+ * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
+ * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
+ */
+ function DownloadZ($dir = "") {
+ global $mem;
+ header("Content-Disposition: attachment; filename=" . $mem->user["login"] . ".Z");
+ header("Content-Type: application/x-Z");
+ header("Content-Transfer-Encoding: binary");
+ $d = escapeshellarg("." . $this->convertabsolute($dir, true));
+ set_time_limit(0);
+ passthru("/bin/tar -cZ -C " . getuserpath() . "/" . $mem->user["login"] . "/ $d");
+ }
+
+ /**
+ * Echo d'un flux .tgz contenant tout le contenu du dossier $dir
+ *
+ * @global type $mem
+ * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
+ * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
+ */
+ function DownloadTGZ($dir = "") {
+ global $mem;
+ header("Content-Disposition: attachment; filename=" . $mem->user["login"] . ".tgz");
+ header("Content-Type: application/x-tgz");
+ header("Content-Transfer-Encoding: binary");
+ $d = escapeshellarg("." . $this->convertabsolute($dir, true));
+ set_time_limit(0);
+ passthru("/bin/tar -cz -C " . getuserpath() . "/ $d");
+ }
+
+ /**
+ * Echo d'un flux .tar.bz2 contenant tout le contenu du dossier $dir
+ *
+ * @global type $mem
+ * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
+ * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
+ */
+ function DownloadTBZ($dir = "") {
+ global $mem;
+ header("Content-Disposition: attachment; filename=" . $mem->user["login"] . ".tar.bz2");
+ header("Content-Type: application/x-bzip2");
+ header("Content-Transfer-Encoding: binary");
+ $d = escapeshellarg("." . $this->convertabsolute($dir, true));
+ set_time_limit(0);
+ passthru("/bin/tar -cj -C " . getuserpath() . "/ $d");
+ }
+
+ /**
+ * Echo d'un flux .ZIP contenant tout le contenu du dossier $dir
+ *
+ * @global type $mem
+ * @param string $dir Dossier à dumper, relatif la racine du compte du membre.
+ * @return void NE RETOURNE RIEN, et il faut Quitter le script immdiatement aprs
+ */
+ function DownloadZIP($dir = "") {
+ global $mem;
+ header("Content-Disposition: attachment; filename=" . $mem->user["login"] . ".zip");
+ header("Content-Type: application/x-zip");
+ header("Content-Transfer-Encoding: binary");
+ $d = escapeshellarg($this->convertabsolute($dir, false));
+ set_time_limit(0);
+ passthru("/usr/bin/zip -r - $d");
+ }
+
+ /**
+ * Fonction de tri perso utilis par filelist.
+ *
+ * @access private
+ * @param string $a
+ * @param string $b
+ * @return int
+ */
+ function _sort_filelist_name($a, $b) {
+ if ($a["type"] && !$b["type"]) {
+ return 1;
+ }
+ if ($b["type"] && !$a["type"]) {
+ return -1;
+ }
+ return $a["name"] > $b["name"];
+ }
+
+ /**
+ * Efface $file et tous ses sous-dossiers s'il s'agit d'un dossier
+ * A UTILISER AVEC PRECAUTION !!!
+ * @param string $file Fichier ou dossier supprimer.
+ * @access private
+ */
+ function _delete($file) {
+ global $err;
+ // permet d'effacer de nombreux fichiers
+ @set_time_limit(0);
+ //chmod($file,0777);
+ $err->log("bro", "_delete($file)");
+ if (is_dir($file)) {
+ $handle = opendir($file);
+ while (($filename = readdir($handle)) !== false) {
+ if ($filename != "." && $filename != "..") {
+ $this->_delete($file . "/" . $filename);
+ }
+ }
+ closedir($handle);
+ rmdir($file);
+ } else {
+ unlink($file);
+ }
+ }
+
+ /**
+ * Function d'exportation de configuration appelé par la classe m_export via un hooks
+ * Produit en sorti un tableau formatté ( pour le moment) en HTML
+ *
+ * @global m_mysql $db
+ * @global m_err $err
+ * @return string
+ */
+ function alternc_export_conf() {
+ global $err;
+ $err->log("bro", "export_conf");
+ $str = " Browser \n";
+ $str.=" \n";
+ $pref = $this->GetPrefs();
+
+ $i = 1;
+ foreach ($pref as $k => $v) {
+ if (($i % 2) == 0) {
+ $str.=" <$k>$v$k>\n";
+ }
+ $i++;
+ }
+ $str.=" \n";
+
+ return $str;
+ }
+
+ /**
+ * Function d'exportation des données appelé par la classe m_export via un hooks
+ *
+ * @global m_mem $mem
+ * @global m_err $err
+ * @param string $dir Le chemin destination du tarball produit
+ * @return boolean|null
+ */
+ function alternc_export_data($dir) {
+ global $mem, $err;
+ $err->log("bro", "export_data");
+ $dir.="html/";
+ if (!is_dir($dir)) {
+ if (!mkdir($dir))
+ $err->raise("bro", _("Cannot create the requested directory. Please check the permissions"));
+ }
+ $timestamp = date("H:i:s");
+
+ if (exec("/bin/tar cvf - " . escapeshellarg(getuserpath() . "/") . "| gzip -9c > " . escapeshellarg($dir . "/" . $mem->user['login'] . "_html_" . $timestamp . ".tar.gz"))) {
+ $err->log("bro", "export_data_succes");
+ } else {
+ $err->log("bro", "export_data_failed");
+ }
+ }
+
+ function getMaxAllowedUploadSize() {
+ return min(ini_get('post_max_size'), ini_get('upload_max_filesize'));
+ }
+
+}
+
+/* Class Browser */
diff --git a/bureau/class/m_cron.php b/bureau/class/m_cron.php
index d00ffc0b..bf6d0b0f 100644
--- a/bureau/class/m_cron.php
+++ b/bureau/class/m_cron.php
@@ -1,364 +1,404 @@
1440, 'name'=>_("Daily")),
- Array('unit'=>60, 'name'=>_("Hour")),
- Array('unit'=>30, 'name'=>_("Half Hour")),
- );
- }
-
-
- /*---------------------------------------------------------------------------*/
- /** List the crontab for the current user.
- * @return array an hash for each crontab.
- */
- function lst_cron() {
- global $cuid,$db,$err;
- $err->log("cron","lst_cron");
- $db->query("SELECT * FROM cron WHERE uid = $cuid ORDER BY url;");
- $r=Array();
- while ($db->next_record()) {
- $tmp=Array();
- $tmp['id']=$db->f('id');
- $tmp['url']=urldecode($db->f('url'));
- $tmp['user']=urldecode($db->f('user'));
- $tmp['password']=urldecode($db->f('password'));
- $tmp['schedule']=$db->f('schedule');
- $tmp['email']=urldecode($db->f('email'));
- $tmp['next_execution']=$db->f('next_execution');
- $r[]=$tmp;
- }
- return $r;
- }
-
- function hook_menu() {
- $obj = array(
- 'title' => _("Scheduled tasks"),
- 'ico' => 'images/schedule.png',
- 'link' => 'cron.php',
- 'pos' => 90,
- ) ;
-
- return $obj;
- }
-
- /*---------------------------------------------------------------------------*/
- /** update the crontab
- * @param $arr array the crontab information, including its ID
- * @return boolean TRUE if the crontab has been edited
- */
- function update($arr) {
- $ok=true;
- foreach ($arr as $a) {
- if (! isset($a['id'])) $a['id']=null;
- if (empty($a['url']) && is_null($a['id'])) continue;
- if (! $this->_update_one($a['url'], $a['user'], $a['password'], $a['email'], $a['schedule'], $a['id']) ) {
- $ok=false;
- }
- }
- return $ok;
- }
-
-
- /*---------------------------------------------------------------------------*/
- /** delete a crontab
- * @param $id the id of the crontab to delete
- * @return boolean TRUE if the crontab has been deleted
- */
- function delete_one($id) {
- global $db,$err,$cuid;
- $err->log("cron","delete_one");
- return $db->query("DELETE FROM cron WHERE id=".intval($id)." AND uid=$cuid LIMIT 1;");
- }
-
-
- /*---------------------------------------------------------------------------*/
- /** update a crontab,
- * @return boolean TRUE if the crontab has been edited
- */
- private function _update_one($url, $user, $password, $email, $schedule, $id=null) {
- global $db,$err,$quota,$cuid;
- $err->log("cron","update_one");
-
- if (empty($url) && !is_null($id)) {
- return $this->delete_one($id);
+ /** Constructor
+ */
+ function m_cron() {
+
}
-
- if(filter_var($url,FILTER_VALIDATE_URL)===false){
- $err->raise("cron",_("URL not valid"));
- return false;
+ function schedule() {
+ return Array(
+ Array('unit' => 1440, 'name' => _("Daily")),
+ Array('unit' => 60, 'name' => _("Hour")),
+ Array('unit' => 30, 'name' => _("Half Hour")),
+ );
}
- $url=urlencode($url);
- $user=urlencode($user);
- if (empty($user)) $password='';
- $password=urlencode($password);
-
- //@todo remove checkmail cf functions.php
- if (!empty($email) && ! checkmail($email) == 0 ){
- $err->raise("cron",_("Email address is not valid"));
- return false;
+
+ /* --------------------------------------------------------------------------- */
+
+ /** List the crontab for the current user.
+ * @return array an hash for each crontab.
+ */
+ function lst_cron() {
+ global $cuid, $db, $err;
+ $err->log("cron", "lst_cron");
+ $db->query("SELECT * FROM cron WHERE uid = $cuid ORDER BY url;");
+ $r = Array();
+ while ($db->next_record()) {
+ $tmp = Array();
+ $tmp['id'] = $db->f('id');
+ $tmp['url'] = urldecode($db->f('url'));
+ $tmp['user'] = urldecode($db->f('user'));
+ $tmp['password'] = urldecode($db->f('password'));
+ $tmp['schedule'] = $db->f('schedule');
+ $tmp['email'] = urldecode($db->f('email'));
+ $tmp['next_execution'] = $db->f('next_execution');
+ $r[] = $tmp;
+ }
+ return $r;
}
- $email=urlencode($email);
- if (! $this->valid_schedule($schedule)) return false;
- if (is_null($id)) { // if a new insert, quotacheck
- $q = $quota->getquota("cron");
- if ( $q["u"] >= $q["t"] ) {
- $err->raise("cron",_("You quota of cron entries is over. You cannot create more cron entries"));
- return false;
- }
- } else { // if not a new insert, check the $cuid
- $db->query("SELECT uid FROM cron WHERE id = $id;");
- if (! $db->next_record()) {
- return "false";
- } // return false if pb
- if ( $db->f('uid') != $cuid ) {
- $err->raise("cron",_("Identity problem"));
- return false;
- }
+ function hook_menu() {
+ $obj = array(
+ 'title' => _("Scheduled tasks"),
+ 'ico' => 'images/schedule.png',
+ 'link' => 'cron.php',
+ 'pos' => 90,
+ );
+
+ return $obj;
}
- $query = "REPLACE INTO cron (id, uid, url, user, password, schedule, email) VALUES ('$id', '$cuid', '$url', '$user', '$password', '$schedule', '$email') ;";
- return $db->query("$query");
- }
+ /* --------------------------------------------------------------------------- */
- /*---------------------------------------------------------------------------*/
- /** validate a crontab schedule
- * @param $s array schedule paramters
- * @return boolean TRUE if the schedule is valid
- */
- function valid_schedule($s) {
- $s2 = intval($s);
- if ($s2 != $s) return false;
- $r=false;
- foreach ($this->schedule() as $cs ) {
- if ($cs['unit'] == $s) return true;
+ /** update the crontab
+ * @param $arr array the crontab information, including its ID
+ * @return boolean TRUE if the crontab has been edited
+ */
+ function update($arr) {
+ $ok = true;
+ foreach ($arr as $a) {
+ if (!isset($a['id'])) {
+ $a['id'] = null;
+ }
+ if (empty($a['url']) && is_null($a['id'])) {
+ continue;
+ }
+ if (!$this->_update_one($a['url'], $a['user'], $a['password'], $a['email'], $a['schedule'], $a['id'])) {
+ $ok = false;
+ }
+ }
+ return $ok;
}
- return $r;
- }
- /*---------------------------------------------------------------------------*/
- /** hook for quota computation
- */
- function hook_quota_get() {
- global $cuid,$db,$err;
- $err->log("cron","alternc_get_quota");
- $q=Array("name"=>"cron", "description"=>_("Scheduled tasks"), "used"=>0);
- $db->query("select count(*) as cnt from cron where uid = $cuid;");
- if ($db->next_record()) {
- $q['used']=$db->f('cnt');
+ /* --------------------------------------------------------------------------- */
+
+ /** delete a crontab
+ * @param $id the id of the crontab to delete
+ * @return boolean TRUE if the crontab has been deleted
+ */
+ function delete_one($id) {
+ global $db, $err, $cuid;
+ $err->log("cron", "delete_one");
+ return $db->query("DELETE FROM cron WHERE id=" . intval($id) . " AND uid=$cuid LIMIT 1;");
}
- return $q;
- }
- /*---------------------------------------------------------------------------*/
- /**
- * Execute the required crontab of AlternC users
- * this function EXIT at the end.
- */
- function execute_cron() {
- global $db;
+ /* --------------------------------------------------------------------------- */
- if (!isset($GLOBALS["DEBUG"])) $GLOBALS["DEBUG"]=false;
- $db->query("SELECT id, url, email, schedule, user, password FROM cron WHERE next_execution <= NOW();");
- $urllist=array();
-
- while ($db->next_record()) {
- $db->Record["url"]=urldecode($db->Record["url"]); $db->Record["user"]=urldecode($db->Record["user"]);
- $db->Record["email"]=urldecode($db->Record["email"]); $db->Record["password"]=urldecode($db->Record["password"]);
+ /** update a crontab,
+ * @return boolean TRUE if the crontab has been edited
+ */
+ private function _update_one($url, $user, $password, $email, $schedule, $id = null) {
+ global $db, $err, $quota, $cuid;
+ $err->log("cron", "update_one");
- // we support only http or https schemes:
- if (substr($db->Record["url"],0,7)=="http://" || substr($db->Record["url"],0,8)=="https://") {
- $u=array(
- "url" => $db->Record["url"],
- "id" => $db->Record["id"], "email" =>$db->Record["email"],
- );
-
- if ($db->Record["user"] && $db->Record["password"]) {
- $u["login"]=$db->Record["user"];
- $u["password"]=$db->Record["password"];
- }
- if ($GLOBALS["DEBUG"]) echo "Will run cron :\n".print_r($u,true)."\n";
- $urllist[]=$u;
- }
-
- if (empty($urllist)) { // nothing to do :
- exit(0);
- }
-
- // cron_callback($url, $content, $curlobj) will be called at the end of each http call.
- $this->rolling_curl($urllist, array("m_cron","cron_callback"));
+ if (empty($url) && !is_null($id)) {
+ return $this->delete_one($id);
+ }
+
+
+ if (filter_var($url, FILTER_VALIDATE_URL) === false) {
+ $err->raise("cron", _("URL not valid"));
+ return false;
+ }
+ $url = urlencode($url);
+ $user = urlencode($user);
+ if (empty($user)) {
+ $password = '';
+ }
+ $password = urlencode($password);
+
+ //@todo remove checkmail cf functions.php
+ if (!empty($email) && !checkmail($email) == 0) {
+ $err->raise("cron", _("Email address is not valid"));
+ return false;
+ }
+ $email = urlencode($email);
+ if (!$this->valid_schedule($schedule)) {
+ return false;
+ }
+
+ if (is_null($id)) { // if a new insert, quotacheck
+ $q = $quota->getquota("cron");
+ if ($q["u"] >= $q["t"]) {
+ $err->raise("cron", _("You quota of cron entries is over. You cannot create more cron entries"));
+ return false;
+ }
+ } else { // if not a new insert, check the $cuid
+ $db->query("SELECT uid FROM cron WHERE id = $id;");
+ if (!$db->next_record()) {
+ return "false";
+ } // return false if pb
+ if ($db->f('uid') != $cuid) {
+ $err->raise("cron", _("Identity problem"));
+ return false;
+ }
+ }
+ $query = "REPLACE INTO cron (id, uid, url, user, password, schedule, email) VALUES ('$id', '$cuid', '$url', '$user', '$password', '$schedule', '$email') ;";
+ return $db->query("$query");
}
- }
-
-
- /*---------------------------------------------------------------------------*/
- /**
- * Callback function called by rolling_curl when a cron resulr has been received
- * schedule it for next run and send the mail if needed
- */
- function cron_callback($url,$content,$curl) {
- global $db,$L_FQDN;
- if (empty($url["id"])) return; // not normal...
- $id=intval($url["id"]);
+ /* --------------------------------------------------------------------------- */
- if ($curl["http_code"]==200) {
- $ok=true;
- } else {
- $ok=false;
+ /** validate a crontab schedule
+ * @param $s array schedule paramters
+ * @return boolean TRUE if the schedule is valid
+ */
+ function valid_schedule($s) {
+ $s2 = intval($s);
+ if ($s2 != $s) {
+ return false;
+ }
+ $r = false;
+ foreach ($this->schedule() as $cs) {
+ if ($cs['unit'] == $s) {
+ return true;
+ }
+ }
+ return $r;
}
- if (isset($url["email"]) && $url["email"] && $content) {
- if (!mail($url["email"],"AlternC Cron #$id - Report ".date("r"),"Please find below the stdout content produced by your cron task.\n------------------------------------------------------------\n\n".$content,"From: postmaster@$L_FQDN")) {
- echo "Error sending mail for cron #$id to address '".$url["email"]."'\n";
- }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** hook for quota computation
+ */
+ function hook_quota_get() {
+ global $cuid, $db, $err;
+ $err->log("cron", "alternc_get_quota");
+ $q = Array("name" => "cron", "description" => _("Scheduled tasks"), "used" => 0);
+ $db->query("select count(*) as cnt from cron where uid = $cuid;");
+ if ($db->next_record()) {
+ $q['used'] = $db->f('cnt');
+ }
+ return $q;
}
- // now schedule it for next run:
- $db->query("UPDATE cron SET next_execution=FROM_UNIXTIME( UNIX_TIMESTAMP(NOW()) + schedule * 60) WHERE id=$id");
- }
-
+ /* --------------------------------------------------------------------------- */
- /*---------------------------------------------------------------------------*/
- /**
- * Launch parallel (using MAX_SOCKETS sockets maximum) retrieval
- * of URL using CURL
- * @param $urls array of associative array, each having the following keys :
- * url = url to get (of the form http[s]://login:password@host/path/file?querystring )
- * login & password = if set, tell the login and password to use as simple HTTP AUTH.
- * - any other key will be sent as it is to the callback function
- * @param $callback function called for each request when completing. First argument is the $url object, second is the content (output)
- * third is the info structure from curl for the returned page. 200 for OK, 403 for AUTH FAILED, 0 for timeout, dump it to know it ;)
- * this function should return as soon as possible to allow other curl calls to complete properly.
- * @param $cursom_options array of custom CURL options for all transfers
- */
- function rolling_curl($urls, $callback, $custom_options = null) {
- // make sure the rolling window isn't greater than the # of urls
- if (!isset($GLOBALS["DEBUG"])) $GLOBALS["DEBUG"]=false;
- $rolling_window = m_cron::MAX_SOCKETS;
- $rolling_window = (count($urls) < $rolling_window) ? count($urls) : $rolling_window;
-
- $master = curl_multi_init();
- $curl_arr = array();
-
- // add additional curl options here
- $std_options = array(CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FOLLOWLOCATION => false,
- CURLOPT_CONNECTTIMEOUT => 5,
- CURLOPT_TIMEOUT => 240, // 4 minutes timeout for a page
- CURLOPT_USERAGENT => "AlternC (Cron Daemon)",
- CURLOPT_MAXREDIRS => 0);
+ /**
+ * Execute the required crontab of AlternC users
+ * this function EXIT at the end.
+ */
+ function execute_cron() {
+ global $db;
- if ($GLOBALS["DEBUG"]) $std_options[CURLOPT_VERBOSE]=true;
- $options = ($custom_options) ? ($std_options + $custom_options) : $std_options;
-
- // start the first batch of requests
- for ($i = 0; $i < $rolling_window; $i++) {
- $ch = curl_init();
- $options[CURLOPT_URL] = $urls[$i]["url"];
- if ($GLOBALS["DEBUG"]) echo "URL: ".$urls[$i]["url"]."\n";
- curl_setopt_array($ch,$options);
- // Handle custom cafile for some https url
- if (strtolower(substr($options[CURLOPT_URL],0,5))=="https") {
- curl_setopt($ch,CURLOPT_CAINFO,m_cron::DEFAULT_CAFILE);
- if ($GLOBALS["DEBUG"]) echo "cainfo set to DEFAULT\n";
- }
- if (isset($urls[$i]["login"]) && isset($urls[$i]["password"])) { // set basic http authentication
- curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_BASIC);
- curl_setopt($ch,CURLOPT_USERPWD,$urls[$i]["login"].":".$urls[$i]["password"]);
- if ($GLOBALS["DEBUG"]) echo "set basic auth\n";
- }
- curl_multi_add_handle($master, $ch);
+ if (!isset($GLOBALS["DEBUG"])) {
+ $GLOBALS["DEBUG"] = false;
+ }
+ $db->query("SELECT id, url, email, schedule, user, password FROM cron WHERE next_execution <= NOW();");
+ $urllist = array();
+
+ while ($db->next_record()) {
+ $db->Record["url"] = urldecode($db->Record["url"]);
+ $db->Record["user"] = urldecode($db->Record["user"]);
+ $db->Record["email"] = urldecode($db->Record["email"]);
+ $db->Record["password"] = urldecode($db->Record["password"]);
+
+ // we support only http or https schemes:
+ if (substr($db->Record["url"], 0, 7) == "http://" || substr($db->Record["url"], 0, 8) == "https://") {
+ $u = array(
+ "url" => $db->Record["url"],
+ "id" => $db->Record["id"], "email" => $db->Record["email"],
+ );
+
+ if ($db->Record["user"] && $db->Record["password"]) {
+ $u["login"] = $db->Record["user"];
+ $u["password"] = $db->Record["password"];
+ }
+ if ($GLOBALS["DEBUG"])
+ echo "Will run cron :\n" . print_r($u, true) . "\n";
+ $urllist[] = $u;
+ }
+
+ if (empty($urllist)) { // nothing to do :
+ exit(0);
+ }
+
+ // cron_callback($url, $content, $curlobj) will be called at the end of each http call.
+ $this->rolling_curl($urllist, array("m_cron", "cron_callback"));
+ }
}
-
- do {
- while(($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM);
- if($execrun != CURLM_OK)
- break;
- // a request was just completed -- find out which one
- while($done = curl_multi_info_read($master)) {
- $info = curl_getinfo($done['handle']);
- // TODO : since ssl_verify_result is buggy, if we have [header_size] => 0 && [request_size] => 0 && [http_code] => 0, AND https, we can pretend the SSL certificate is buggy.
- if ($GLOBALS["DEBUG"]) { echo "Info for ".$done['handle']." \n"; print_r($info); }
- if ($info['http_code'] == 200) {
- $output = curl_multi_getcontent($done['handle']);
- } else {
- // request failed. add error handling.
- $output="";
- }
- // request terminated. process output using the callback function.
- // Pass the url array to the callback, so we need to search it
- foreach($urls as $url) {
- if ($url["url"]==$info["url"]) {
- call_user_func($callback,$url,$output,$info);
- break;
- }
- }
-
- // If there is more: start a new request
- // (it's important to do this before removing the old one)
- if ($iquery("UPDATE cron SET next_execution=FROM_UNIXTIME( UNIX_TIMESTAMP(NOW()) + schedule * 60) WHERE id=$id");
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /**
+ * Launch parallel (using MAX_SOCKETS sockets maximum) retrieval
+ * of URL using CURL
+ * @param $urls array of associative array, each having the following keys :
+ * url = url to get (of the form http[s]://login:password@host/path/file?querystring )
+ * login & password = if set, tell the login and password to use as simple HTTP AUTH.
+ * - any other key will be sent as it is to the callback function
+ * @param $callback function called for each request when completing. First argument is the $url object, second is the content (output)
+ * third is the info structure from curl for the returned page. 200 for OK, 403 for AUTH FAILED, 0 for timeout, dump it to know it ;)
+ * this function should return as soon as possible to allow other curl calls to complete properly.
+ * @param $cursom_options array of custom CURL options for all transfers
+ */
+ function rolling_curl($urls, $callback, $custom_options = null) {
+ // make sure the rolling window isn't greater than the # of urls
+ if (!isset($GLOBALS["DEBUG"]))
+ $GLOBALS["DEBUG"] = false;
+ $rolling_window = m_cron::MAX_SOCKETS;
+ $rolling_window = (count($urls) < $rolling_window) ? count($urls) : $rolling_window;
+
+ $master = curl_multi_init();
+
+ // add additional curl options here
+ $std_options = array(CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_FOLLOWLOCATION => false,
+ CURLOPT_CONNECTTIMEOUT => 5,
+ CURLOPT_TIMEOUT => 240, // 4 minutes timeout for a page
+ CURLOPT_USERAGENT => "AlternC (Cron Daemon)",
+ CURLOPT_MAXREDIRS => 0);
+
+ if ($GLOBALS["DEBUG"]) {
+ $std_options[CURLOPT_VERBOSE] = true;
+ }
+ $options = ($custom_options) ? ($std_options + $custom_options) : $std_options;
+
+ // start the first batch of requests
+ for ($i = 0; $i < $rolling_window; $i++) {
+ $ch = curl_init();
+ $options[CURLOPT_URL] = $urls[$i]["url"];
+ if ($GLOBALS["DEBUG"]) {
+ echo "URL: " . $urls[$i]["url"] . "\n";
+ }
+ curl_setopt_array($ch, $options);
+ // Handle custom cafile for some https url
+ if (strtolower(substr($options[CURLOPT_URL], 0, 5)) == "https") {
+ curl_setopt($ch, CURLOPT_CAINFO, m_cron::DEFAULT_CAFILE);
+ if ($GLOBALS["DEBUG"]) {
+ echo "cainfo set to DEFAULT\n";
+ }
+ }
+ if (isset($urls[$i]["login"]) && isset($urls[$i]["password"])) { // set basic http authentication
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ curl_setopt($ch, CURLOPT_USERPWD, $urls[$i]["login"] . ":" . $urls[$i]["password"]);
+ if ($GLOBALS["DEBUG"]) {
+ echo "set basic auth\n";
+ }
+ }
+ curl_multi_add_handle($master, $ch);
+ }
+
+ do {
+ while (($execrun = curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM);
+ if ($execrun != CURLM_OK) {
+ break;
+ }
+ // a request was just completed -- find out which one
+ while ($done = curl_multi_info_read($master)) {
+ $info = curl_getinfo($done['handle']);
+ // TODO : since ssl_verify_result is buggy, if we have [header_size] => 0 && [request_size] => 0 && [http_code] => 0, AND https, we can pretend the SSL certificate is buggy.
+ if ($GLOBALS["DEBUG"]) {
+ echo "Info for " . $done['handle'] . " \n";
+ print_r($info);
+ }
+ if ($info['http_code'] == 200) {
+ $output = curl_multi_getcontent($done['handle']);
+ } else {
+ // request failed. add error handling.
+ $output = "";
+ }
+ // request terminated. process output using the callback function.
+ // Pass the url array to the callback, so we need to search it
+ foreach ($urls as $url) {
+ if ($url["url"] == $info["url"]) {
+ call_user_func($callback, $url, $output, $info);
+ break;
+ }
+ }
+
+ // If there is more: start a new request
+ // (it's important to do this before removing the old one)
+ if ($i < count($urls)) {
+ $ch = curl_init();
+ $options[CURLOPT_URL] = $urls[$i++]; // increment i
+ curl_setopt_array($ch, $options);
+ if (strtolower(substr($options[CURLOPT_URL], 0, 5)) == "https") {
+ curl_setopt($ch, CURLOPT_CAINFO, m_cron::DEFAULT_CAFILE);
+ if ($GLOBALS["DEBUG"]) {
+ echo "cainfo set to DEFAULT\n";
+ }
+ }
+ if (isset($urls[$i]["login"]) && isset($urls[$i]["password"])) { // set basic http authentication
+ curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
+ curl_setopt($ch, CURLOPT_USERPWD, urlencode($urls[$i]["login"]) . ":" . urlencode($urls[$i]["password"]));
+ if ($GLOBALS["DEBUG"]) {
+ echo "set basic auth\n";
+ }
+ }
+ curl_multi_add_handle($master, $ch);
+ }
+ // remove the curl handle that just completed
+ curl_multi_remove_handle($master, $done['handle']);
+ }
+ } while ($running);
+
+ curl_multi_close($master);
+ return true;
+ }
+
+}
+
+/* Class cron */
diff --git a/bureau/class/m_crypto.php b/bureau/class/m_crypto.php
index 2fc844bc..de8d15fb 100644
--- a/bureau/class/m_crypto.php
+++ b/bureau/class/m_crypto.php
@@ -1,44 +1,31 @@
status=true;
- ini_set('display_errors', '1');
+ var $infos = "";
+ var $status = false;
+ var $nb_sql_query = 0;
+ var $tps_sql_query = 0;
+ var $generation_started = null;
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Constructor
+ */
+ function m_debug_alternc() {
+ if (isset($_COOKIE['alternc_debugme']) && $_COOKIE['alternc_debugme']) {
+ $this->status = true;
+ ini_set('display_errors', '1');
+ }
+ $this->nb_sql_query = 0;
+ $this->tps_sql_query = 0;
+ $this->generation_started = microtime(true);
}
- $this->nb_sql_query=0;
- $this->tps_sql_query=0;
- $this->generation_started=microtime(true);
- }
- function activate() {
- setcookie('alternc_debugme','1', time()+3600); // expire in 1 hour
- $this->status="";
- return true;
- }
+ function activate() {
+ setcookie('alternc_debugme', '1', time() + 3600); // expire in 1 hour
+ $this->status = "";
+ return true;
+ }
- function desactivate() {
- setcookie('alternc_debugme','0');
- $this->status=false;
- return true;
- }
+ function desactivate() {
+ setcookie('alternc_debugme', '0');
+ $this->status = false;
+ return true;
+ }
- function add($txt) {
- $this->infos .= "\n$txt";
- return true;
- }
+ function add($txt) {
+ $this->infos .= "\n$txt";
+ return true;
+ }
- function dump() {
- global $cuid;
- if ( $cuid!=2000 ) return false;
- if ( ! $this->status ) return false;
+ function dump() {
+ global $cuid;
+ if ($cuid != 2000) {
+ return false;
+ }
+ if (!$this->status) {
+ return false;
+ }
- $generation_time = (microtime(true) - $this->generation_started) * 1000;
+ $generation_time = (microtime(true) - $this->generation_started) * 1000;
- echo "";
- return true;
- }
+ echo "";
+ return true;
+ }
-} /* Class debug_alternc */
+}
-?>
+/* Class debug_alternc */
diff --git a/bureau/class/m_dom.php b/bureau/class/m_dom.php
index 90b1f9eb..be144747 100644
--- a/bureau/class/m_dom.php
+++ b/bureau/class/m_dom.php
@@ -85,7 +85,7 @@ class m_dom {
* Constructeur
*/
function m_dom() {
- global $L_FQDN;
+ global $L_FQDN;
$this->tld_no_check_at_all = variable_get('tld_no_check_at_all', 0, 'Disable ALL check on the TLD (users will be able to add any domain)', array('desc' => 'Disabled', 'type' => 'boolean'));
variable_get('mailname_bounce', $L_FQDN, 'FQDN of the mail server, used to create vhost virtual mail_adress.', array('desc' => 'FQDN', 'type' => 'string'));
}
@@ -105,16 +105,16 @@ class m_dom {
* @param string $fqdn
*/
public static function get_sub_domain_id_and_member_by_name($fqdn) {
- global $db, $err, $cuid;
+ global $db, $err;
$err->log("dom", "get_sub_domain_by_name");
$fqdn = mysql_real_escape_string($fqdn);
$db->query("select sd.* from sub_domaines sd where if(length(sd.sub)>0,concat_ws('.',sd.sub,sd.domaine),sd.domaine) = '$fqdn';");
- if (!$db->next_record())
+ if (!$db->next_record()) {
return false;
+ }
return array('sub_id' => intval($db->f('id')), 'member_id' => intval($db->f('compte')));
}
-
function hook_menu() {
global $quota;
$obj = array(
@@ -123,22 +123,20 @@ class m_dom {
'link' => 'toggle',
'pos' => 20,
'links' => array(),
- );
+ );
if ($quota->cancreate("dom")) {
- $obj['links'][] =
- array(
- 'ico' => 'images/new.png',
- 'txt' => _("Add a domain"),
- 'url' => "dom_add.php",
+ $obj['links'][] = array(
+ 'ico' => 'images/new.png',
+ 'txt' => _("Add a domain"),
+ 'url' => "dom_add.php",
);
}
foreach ($this->enum_domains() as $d) {
- $obj['links'][] =
- array(
- 'txt' => htmlentities($d),
- 'url' => "dom_edit.php?domain=" . urlencode($d),
+ $obj['links'][] = array(
+ 'txt' => htmlentities($d),
+ 'url' => "dom_edit.php?domain=" . urlencode($d),
);
}
@@ -186,7 +184,7 @@ class m_dom {
* @param integer $type
*/
function domains_type_target_values($type = null) {
- global $db, $err, $cuid;
+ global $db, $err;
$err->log("dom", "domains_type_target_values");
if (is_null($type)) {
$db->query("desc domaines_type;");
@@ -202,8 +200,9 @@ class m_dom {
return $r;
} else {
$db->query("select target from domaines_type where name='$type';");
- if (!$db->next_record())
+ if (!$db->next_record()) {
return false;
+ }
return $db->f('target');
}
}
@@ -220,8 +219,9 @@ class m_dom {
$val = array();
foreach (explode("\n", $zone) as $z) {
$z = trim($z);
- if (empty($z))
+ if (empty($z)) {
continue;
+ }
$val[] = $this->import_manual_dns_entry($z, $domain, $detect_redirect, $save);
}
return $val;
@@ -231,11 +231,12 @@ class m_dom {
* @param string $zone
*/
function import_manual_dns_entry($zone, $domain, $detect_redirect = true, $save = false) {
- global $cuid, $err;
+ global $err;
$err->log("dom", "import_manual_dns_entry");
$zone = trim($zone);
- if (empty($zone))
+ if (empty($zone)) {
return false;
+ }
$domain = trim($domain);
if (empty($domain)) {
@@ -409,7 +410,6 @@ class m_dom {
}
private function import_manual_dns_entry_doit($entry) {
- global $err;
$entry['did_it'] = 0;
if ($entry['status'] == 'err') {
return $entry;
@@ -417,14 +417,14 @@ class m_dom {
$val = $entry['entry_new'];
- if (empty($val['type']))
+ if (empty($val['type'])) {
return false;
+ }
switch ($val['type']) {
case "set_ttl":
$entry['did_it'] = $this->set_ttl($this->get_domain_byname($val['domain']), $val['value']);
return $entry;
- break;
}
// If it is an unknown domains type
@@ -435,8 +435,9 @@ class m_dom {
}
// If the subdomain is @, we want an empty subdomain
- if ($val['sub'] == '@')
+ if ($val['sub'] == '@') {
$val['sub'] = '';
+ }
$this->lock();
$entry['did_it'] = $this->set_sub_domain($val['domain'], $val['sub'], $val['type'], $val['value']);
@@ -492,7 +493,6 @@ class m_dom {
if ($result === false) {
throw new Exception("Could not read data from {$url}");
- return false;
}
if (strstr($http_response_header[0], '301') || strstr($http_response_header[0], '302')) {
// This is a redirection
@@ -528,7 +528,7 @@ class m_dom {
}
function domains_type_get($name) {
- global $db, $err, $cuid;
+ global $db;
$name = mysql_real_escape_string($name);
$db->query("select * from domaines_type where name='$name' ;");
$db->next_record();
@@ -536,14 +536,14 @@ class m_dom {
}
function domains_type_del($name) {
- global $db, $err, $cuid;
+ global $db;
$name = mysql_real_escape_string($name);
$db->query("delete domaines_type where name='$name';");
return true;
}
function domains_type_update($name, $description, $target, $entry, $compatibility, $enable, $only_dns, $need_dns, $advanced, $create_tmpdir, $create_targetdir) {
- global $err, $cuid, $db;
+ global $err, $db;
// The name MUST contain only letter and digits, it's an identifier after all ...
if (!preg_match("#^[a-z0-9]+$#", $name)) {
$err->raise("dom", _("The name MUST contain only letter and digits"));
@@ -565,12 +565,13 @@ class m_dom {
}
function sub_domain_change_status($sub_id, $status) {
- global $db, $err, $cuid;
+ global $db, $err;
$err->log("dom", "sub_domain_change_status");
$sub_id = intval($sub_id);
$status = strtoupper($status);
- if (!in_array($status, array('ENABLE', 'DISABLE')))
+ if (!in_array($status, array('ENABLE', 'DISABLE'))) {
return false;
+ }
$jh = $this->get_sub_domain_all($sub_id);
if ($status == 'ENABLE') { // check compatibility with existing sub_domains
@@ -618,9 +619,7 @@ class m_dom {
$dom = strtolower($dom);
$db->query("UPDATE sub_domaines SET web_action='UPDATE' WHERE domaine='$dom';");
$this->set_dns_action($dom, 'UPDATE');
-
# TODO : some work with domain sensitive classes
-
return true;
}
@@ -638,7 +637,7 @@ class m_dom {
* @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon.
*/
function del_domain($dom) {
- global $db, $err, $classes, $cuid, $hooks;
+ global $db, $err, $hooks;
$err->log("dom", "del_domain", $dom);
$dom = strtolower($dom);
@@ -689,7 +688,7 @@ class m_dom {
$ @return boolean Retourne FALSE si une erreur s'est produite, TRUE sinon.
*/
function add_domain($domain, $dns, $noerase = false, $force = false, $isslave = false, $slavedom = "") {
- global $db, $err, $quota, $classes, $L_MX, $L_FQDN, $tld, $cuid, $bro, $hooks;
+ global $db, $err, $quota, $L_FQDN, $tld, $cuid, $hooks;
$err->log("dom", "add_domain", $domain);
// Locked ?
@@ -740,14 +739,15 @@ class m_dom {
return false;
}
- if ($dns)
+ if ($dns) {
$dns = "1";
- else
+ } else {
$dns = "0";
-
+ }
// mode 5 : force DNS to NO.
- if ($tld[$v] == 5)
+ if ($tld[$v] == 5) {
$dns = 0;
+ }
// It must be a real domain (no subdomain)
if (!$dns) {
$v = checkhostallow_nodns($domain);
@@ -762,14 +762,16 @@ class m_dom {
$err->raise("dom", _("Your domain quota is over, you cannot create more domain names"));
return false;
}
- if ($noerase)
+ if ($noerase) {
$noerase = "1";
- else
+ } else {
$noerase = "0";
- if ($dns)
+ }
+ if ($dns) {
$gesmx = "1";
- else
+ } else {
$gesmx = "0"; // do not host mx by default if not hosting the DNS
+ }
$db->query("INSERT INTO domaines (compte,domaine,gesdns,gesmx,noerase,dns_action) VALUES ('$cuid','$domain','$dns','$gesmx','$noerase','UPDATE');");
if (!($id = $db->lastid())) {
$err->raise("dom", _("An unexpected error occured when creating the domain"));
@@ -798,8 +800,9 @@ class m_dom {
}
// New Hooks:
$hooks->invoke("hook_dom_add_domain", array($id));
- if ($gesmx)
+ if ($gesmx) {
$hooks->invoke("hook_dom_add_mx_domain", array($id));
+ }
if ($isslave) {
$hooks->invoke("hook_dom_add_slave_domain", array($id, $slavedom));
}
@@ -834,13 +837,11 @@ class m_dom {
* @param string $domain
*/
function domdefaultdir($domain) {
- global $bro, $cuid;
- $dest_root = $bro->get_userid_root($cuid);
- # return $dest_root."/www/".$this->domshort($domain);
return "/www/" . $this->domshort($domain);
}
function dump_axfr($domain, $ns = 'localhost') {
+ $axfr = array();
exec('/usr/bin/dig AXFR "' . escapeshellcmd($domain) . '" @"' . escapeshellcmd($ns) . '"', $axfr);
return $axfr;
}
@@ -858,7 +859,7 @@ class m_dom {
'domain_type_parameter' => $db->f('domain_type_parameter'),
'concerned' => $db->f('concerned'),
'enabled' => $db->f('enabled')
- );
+ );
}
return $c;
@@ -869,12 +870,14 @@ class m_dom {
$err->log("dom", "update_default_subdomains");
$ok = true;
foreach ($arr as $a) {
- if (!isset($a['id']))
+ if (!isset($a['id'])) {
$a['id'] = null;
+ }
if (!empty($a['sub']) || !empty($a['domain_type_parameter'])) {
- if (!isset($a['enabled']))
+ if (!isset($a['enabled'])) {
$a['enabled'] = 0;
+ }
if (!$this->update_one_default($a['domain_type'], $a['sub'], $a['domain_type_parameter'], $a['concerned'], $a['enabled'], $a['id'])) {
$ok = false;
}
@@ -887,10 +890,11 @@ class m_dom {
global $db, $err;
$err->log("dom", "update_one_default");
- if ($id == null)
+ if ($id == null) {
$db->query("INSERT INTO default_subdomains values ('','" . addslashes($sub) . "','" . addslashes($domain_type) . "','" . addslashes($domain_type_parameter) . "','" . addslashes($concerned) . "','" . addslashes($enabled) . "');");
- else
+ } else {
$db->query("UPDATE default_subdomains set sub='" . addslashes($sub) . "', domain_type='" . addslashes($domain_type) . "',domain_type_parameter='" . addslashes($domain_type_parameter) . "',concerned='" . addslashes($concerned) . "',enabled='" . addslashes($enabled) . "' where id=" . addslashes($id) . ";");
+ }
return true;
//update
}
@@ -924,7 +928,7 @@ class m_dom {
*
*/
function whois($domain) {
- global $db, $err;
+ global $err;
$err->log("dom", "whois", $domain);
// pour ajouter un nouveau TLD, utiliser le code ci-dessous.
// echo "whois : $domain
";
@@ -978,16 +982,19 @@ class m_dom {
if (preg_match("#Name Server:#", $ligne)) {
$found = true;
$tmp = strtolower(str_replace(chr(10), "", str_replace(chr(13), "", str_replace(" ", "", str_replace("Name Server:", "", $ligne)))));
- if ($tmp)
+ if ($tmp) {
$serveurList[] = $tmp;
+ }
}
break;
case "cx":
$ligne = str_replace(chr(10), "", str_replace(chr(13), "", str_replace(" ", "", $ligne)));
- if ($ligne == "" && $state == 1)
+ if ($ligne == "" && $state == 1) {
$state = 2;
- if ($state == 1)
+ }
+ if ($state == 1) {
$serveurList[] = strtolower($ligne);
+ }
if ($ligne == "Nameservers:" && $state == 0) {
$state = 1;
$found = true;
@@ -996,10 +1003,12 @@ class m_dom {
case "eu":
case "be":
$ligne = preg_replace("/^ *([^ ]*) \(.*\)$/", "\\1", trim($ligne));
- if ($found)
+ if ($found) {
$tmp = trim($ligne);
- if ($tmp)
+ }
+ if ($tmp) {
$serveurList[] = $tmp;
+ }
if ($ligne == "Nameservers:") {
$state = 1;
$found = true;
@@ -1011,16 +1020,18 @@ class m_dom {
// weird regexp (trailing garbage after name server), but I could not make it work otherwise
$tmp = strtolower(preg_replace('/Name Server: ([^ ]+)\..$/', "\\1", $ligne));
$tmp = preg_replace('/[^-_a-z0-9\.]/', '', $tmp);
- if ($tmp)
+ if ($tmp) {
$serveurList[] = $tmp;
+ }
}
break;
case "it":
if (preg_match("#nserver:#", $ligne)) {
$found = true;
$tmp = strtolower(preg_replace("/nserver:\s*[^ ]*\s*([^\s]*)$/", "\\1", $ligne));
- if ($tmp)
+ if ($tmp) {
$serveurList[] = $tmp;
+ }
}
break;
case "fr":
@@ -1028,8 +1039,9 @@ class m_dom {
if (preg_match("#nserver:#", $ligne)) {
$found = true;
$tmp = strtolower(preg_replace("#nserver:\s*([^\s]*)\s*.*$#", "\\1", $ligne));
- if ($tmp)
+ if ($tmp) {
$serveurList[] = $tmp;
+ }
}
break;
case "ca":
@@ -1082,6 +1094,8 @@ class m_dom {
function checkmx($domaine, $ref_domain = '') {
global $L_DEFAULT_MX, $L_DEFAULT_SECONDARY_MX;
+ $ref_mx = array();
+ $mxhosts = array();
if (!empty($ref_domain)) {
getmxrr($ref_domain, $ref_mx);
} else {
@@ -1114,9 +1128,6 @@ class m_dom {
return 0;
}
-//checkmx
-
-
/* ----------------------------------------------------------------- */
/**
@@ -1245,7 +1256,7 @@ class m_dom {
* @param string $value
*/
function check_type_value($type, $value) {
- global $db, $err, $cuid;
+ global $err;
// check the type we can have in domaines_type.target
switch ($this->domains_type_target_values($type)) {
@@ -1273,7 +1284,6 @@ class m_dom {
return false;
}
return true;
- break;
case 'IP':
if (checkip($value)) {
return true;
@@ -1309,14 +1319,10 @@ class m_dom {
default:
$err->raise("dom", _("Invalid domain type selected, please check"));
return false;
- break;
}
return false;
}
-//check_type_value
-
-
/* ----------------------------------------------------------------- */
/**
@@ -1328,13 +1334,14 @@ class m_dom {
* @return boolean tell you if the subdomain can be installed there
*/
function can_create_subdomain($dom, $sub, $type, $sub_domain_id = 'null') {
- global $db, $err, $cuid;
+ global $db, $err;
$err->log("dom", "can_create_subdomain", $dom . "/" . $sub);
// Get the compatibility list for this domain type
$db->query("select upper(compatibility) as compatibility from domaines_type where upper(name)=upper('$type');");
- if (!$db->next_record())
+ if (!$db->next_record()) {
return false;
+ }
$compatibility_lst = explode(",", $db->f('compatibility'));
// Get the list of type of subdomains already here who have the same name
@@ -1342,8 +1349,9 @@ class m_dom {
#$db->query("select * from sub_domaines where sub='$sub' and domaine='$dom';");
while ($db->next_record()) {
// And if there is a domain with a incompatible type, return false
- if (!in_array(strtoupper($db->f('type')), $compatibility_lst))
+ if (!in_array(strtoupper($db->f('type')), $compatibility_lst)) {
return false;
+ }
}
// All is right, go ! Create ur domain !
@@ -1393,7 +1401,7 @@ class m_dom {
}
// On a épuré $dir des problémes eventuels ... On est en DESSOUS du dossier de l'utilisateur.
- if ($t = checkfqdn($dom)) {
+ if (($t = checkfqdn($dom))) {
$err->raise("dom", _("The domain name is syntaxically incorrect"));
return false;
}
@@ -1415,7 +1423,7 @@ class m_dom {
// Create TMP dir and TARGET dir if needed by the domains_type
$dest_root = $bro->get_userid_root($cuid);
- $domshort = $this->domshort($dom, $sub);
+ //$domshort = $this->domshort($dom, $sub);
$db->query("select create_tmpdir, create_targetdir from domaines_type where name = '$type';");
$db->next_record();
if ($db->f('create_tmpdir')) {
@@ -1444,9 +1452,6 @@ class m_dom {
return true;
}
-// set_sub_domain
-
-
/* ----------------------------------------------------------------- */
/**
@@ -1456,7 +1461,7 @@ class m_dom {
*
*/
function del_sub_domain($sub_domain_id) {
- global $db, $err, $cuid;
+ global $db, $err;
$err->log("dom", "del_sub_domain", $sub_domain_id);
// Locked ?
if (!$this->islocked) {
@@ -1473,8 +1478,6 @@ class m_dom {
return true;
}
-// del_sub_domain
-
/**
* @param integer $dom_id
*/
@@ -1505,7 +1508,7 @@ class m_dom {
*
*/
function edit_domain($dom, $dns, $gesmx, $force = false, $ttl = 86400) {
- global $db, $err, $L_MX, $classes, $cuid, $hooks;
+ global $db, $err, $hooks;
$err->log("dom", "edit_domain", $dom . "/" . $dns . "/" . $gesmx);
// Locked ?
if (!$this->islocked && !$force) {
@@ -1544,8 +1547,9 @@ class m_dom {
$err->raise("dom", _("The domain name %s does not exist"), $dom);
return false;
}
- if ($dns != "1")
+ if ($dns != "1") {
$dns = "0";
+ }
// On vérifie que des modifications ont bien eu lieu :)
if ($r["dns"] == $dns && $r["mail"] == $gesmx && $r["zonettl"] == $ttl) {
$err->raise("dom", _("No change has been requested..."));
@@ -1579,14 +1583,10 @@ class m_dom {
return true;
}
-// edit_domain
-
-
/* * ************************* */
/* Slave dns ip managment */
/* * ************************* */
-
/* ----------------------------------------------------------------- */
/** Return the list of ip addresses and classes that are allowed access to domain list
@@ -1616,8 +1616,9 @@ class m_dom {
return false;
}
$class = intval($class);
- if ($class < 8 || $class > 32)
+ if ($class < 8 || $class > 32) {
$class = 32;
+ }
$db->query("SELECT * FROM slaveip WHERE ip='$ip' AND class='$class';");
if ($db->next_record()) {
$err->raise("err", _("The requested domain is forbidden in this server, please contact the administrator"));
@@ -1652,7 +1653,7 @@ class m_dom {
/** Check for a slave account
*/
function check_slave_account($login, $pass) {
- global $db, $err;
+ global $db;
$db->query("SELECT * FROM slaveaccount WHERE login='$login' AND pass='$pass';");
if ($db->next_record()) {
return true;
@@ -1665,7 +1666,7 @@ class m_dom {
/** Out (echo) the complete hosted domain list :
*/
function echo_domain_list($integrity = false) {
- global $db, $err;
+ global $db;
$db->query("SELECT domaine FROM domaines WHERE gesdns=1 ORDER BY domaine");
$tt = "";
while ($db->next_record()) {
@@ -1684,7 +1685,7 @@ class m_dom {
/** Returns the complete hosted domain list :
*/
function get_domain_list($uid = -1) {
- global $db, $err;
+ global $db;
$uid = intval($uid);
$res = array();
$sql = "";
@@ -1703,7 +1704,7 @@ class m_dom {
* @return array
*/
function get_domain_all_summary() {
- global $db, $err;
+ global $db;
$res = array();
$db->query("SELECT domaine, gesdns, gesmx, dns_action, zonettl FROM domaines ORDER BY domaine");
while ($db->next_record()) {
@@ -1770,7 +1771,7 @@ class m_dom {
/** Count all domains, for all users
*/
function count_domains_all() {
- global $db, $err, $cuid;
+ global $db;
$db->query("SELECT COUNT(*) AS count FROM domaines;");
if ($db->next_record()) {
return $db->f('count');
@@ -1784,14 +1785,15 @@ class m_dom {
/** Return the list of allowed slave accounts
*/
function enum_slave_account() {
- global $db, $err;
+ global $db;
$db->query("SELECT * FROM slaveaccount;");
$res = array();
while ($db->next_record()) {
$res[] = $db->Record;
}
- if (!count($res))
+ if (!count($res)) {
return false;
+ }
return $res;
}
@@ -1831,7 +1833,7 @@ class m_dom {
* @access private
*/
function lock() {
- global $db, $err;
+ global $err;
$err->log("dom", "lock");
if ($this->islocked) {
$err->raise("dom", _("--- Program error --- Lock already obtained!"));
@@ -1850,7 +1852,7 @@ class m_dom {
* @access private
*/
function unlock() {
- global $db, $err;
+ global $err;
$err->log("dom", "unlock");
if (!$this->islocked) {
$err->raise("dom", _("--- Program error --- No lock on the domains!"));
@@ -1914,10 +1916,10 @@ class m_dom {
* No parameters needed
* */
function alternc_export_conf() {
- global $db, $err;
+ global $err;
$err->log("dom", "export");
$this->enum_domains();
- $str="";
+ $str = "";
foreach ($this->domains as $d) {
$str.= " \n";
$str.=" " . $d . " \n";
@@ -1975,6 +1977,7 @@ class m_dom {
if ($only_apache) {
$params.=" and dt.only_dns is false ";
}
+
// BUG BUG BUG FIXME
// Suppression de comptes -> membres existe pas -> domaines a supprimer ne sont pas lister
$db->query("
@@ -2017,8 +2020,9 @@ order by
global $dom;
$d = array();
foreach ($dom->domains_type_lst() as $k => $v) {
- if ($v['only_dns'] == true)
+ if ($v['only_dns'] == true) {
continue;
+ }
if (!$j = file_get_contents(ALTERNC_APACHE2_GEN_TMPL_DIR . '/' . strtolower($k) . '.conf')) {
die("Error: missing file for $k");
}
@@ -2030,9 +2034,9 @@ order by
// Launch old fashionned hooks as there was in AlternC 1.0
function generate_conf_oldhook($action, $lst_sub, $sub_obj = null) {
- if (is_null($sub_obj))
+ if (is_null($sub_obj)) {
$sub_obj = $this->generation_parameters(null, false);
-
+ }
if (!isset($lst_sub[strtoupper($action)]) || empty($lst_sub[strtoupper($action)])) {
return false;
}
@@ -2173,12 +2177,14 @@ order by
// by subdomain
$tmp = array();
foreach ($da['sub'] as $sub) {
- if ($sub['web_action']!='OK') continue;
+ if ($sub['web_action'] != 'OK') {
+ continue;
+ }
if (!$sub['only_dns']) {
if (!isset($tmp[$sub['fqdn']])) {
$tmp[$sub['fqdn']] = 0;
}
- $tmp[$sub['fqdn']]++;
+ $tmp[$sub['fqdn']] ++;
if ($tmp[$sub['fqdn']] >= 2) {
$errors[$sub['fqdn']] = sprintf(_("Problem on %s: there is more than 1 web configuration going to be generated for this sub-domain."), $sub['fqdn']);
}
diff --git a/bureau/class/m_err.php b/bureau/class/m_err.php
index ed201cfc..f6e644c2 100644
--- a/bureau/class/m_err.php
+++ b/bureau/class/m_err.php
@@ -1,142 +1,144 @@
Cette classe gère les erreurs qui peuvent apparaitre lors d'appels
-* à l'API d'AlternC. Ces erreurs sont stockées sous la forme de 2 nombres
-* (Classe ID et Numéro d'erreur) ainsi qu'un texte facultatif associé.
-* Des textes d'erreurs localisés sont aussi disponibles.
-* Cette classe se charge aussi d'insérer les appels à l'API d'AlternC
-* dans les logs du système dans /var/log/alternc/bureau.log
-*
-* Copyleft {@link http://alternc.net/ AlternC Team}
-*
-* @copyright AlternC-Team 2002-11-01 http://alternc.net/
-*/
+ * Classe de gestion des erreurs apparaissant lors d'appels API.
+ *
+ * Cette classe gère les erreurs qui peuvent apparaitre lors d'appels
+ * à l'API d'AlternC. Ces erreurs sont stockées sous la forme de 2 nombres
+ * (Classe ID et Numéro d'erreur) ainsi qu'un texte facultatif associé.
+ * Des textes d'erreurs localisés sont aussi disponibles.
+ * Cette classe se charge aussi d'insérer les appels à l'API d'AlternC
+ * dans les logs du système dans /var/log/alternc/bureau.log
+ *
+ * Copyleft {@link http://alternc.net/ AlternC Team}
+ *
+ * @copyright AlternC-Team 2002-11-01 http://alternc.net/
+ */
class m_err {
- /** Numero de classe d'erreur actuelle */
- var $clsid=0;
+ /** Numero de classe d'erreur actuelle */
+ var $clsid = 0;
- /** Dernière erreur enregistrée par la classe */
- var $error=0;
+ /** Dernière erreur enregistrée par la classe */
+ var $error = 0;
- /** Paramètre chaine eventuellement associé à la dernière erreur */
- var $param="";
+ /** Paramètre chaine eventuellement associé à la dernière erreur */
+ var $param = "";
- /** Emplacement du fichier de logs d'AlternC */
- var $logfile="/var/log/alternc/bureau.log";
+ /** Emplacement du fichier de logs d'AlternC */
+ var $logfile = "/var/log/alternc/bureau.log";
- /**
- * Leve une erreur, signale celle-ci dans les logs et stocke le code erreur
- *
- * Cette fonction lance une erreur, l'ajoute dans les logs d'AlternC,
- * et la met à disposition pour le bureau virtuel pour affichage ultérieur.
- *
- * @todo ne plus utiliser $error de façon numérique, nulle part
- *
- * @param integer $clsid Classe qui lève l'erreur
- * @param mixed $error Numéro de l'erreur ou chaîne décrivant l'erreur
- * @param string $param Paramètre chaine associé à l'erreur (facultatif)
- * @return boolean TRUE si l'erreur est connue, FALSE sinon.
- *
- */
- function raise($clsid,$error,$param="") {
- /* Leve une exception. Si elle existe, sinon, stocke un message d'erreur sur erreur ...*/
- if (_("err_".$clsid."_".$error)!="err_".$clsid."_".$error || is_string($error)) {
- $this->clsid=$clsid;
- $this->error=$error;
- $args = func_get_args();
- $this->param=array_slice($args, 2);
- $this->logerr();
- return true;
- } else {
- $this->clsid="err";
- $this->error=1;
- $this->param="Error # $error in Class $clsid, Value is $param. (sorry, no text for this error in your language at the moment)";
- $this->logerr();
- return false;
+ /**
+ * Leve une erreur, signale celle-ci dans les logs et stocke le code erreur
+ *
+ * Cette fonction lance une erreur, l'ajoute dans les logs d'AlternC,
+ * et la met à disposition pour le bureau virtuel pour affichage ultérieur.
+ *
+ * @todo ne plus utiliser $error de façon numérique, nulle part
+ *
+ * @param integer $clsid Classe qui lève l'erreur
+ * @param mixed $error Numéro de l'erreur ou chaîne décrivant l'erreur
+ * @param string $param Paramètre chaine associé à l'erreur (facultatif)
+ * @return boolean TRUE si l'erreur est connue, FALSE sinon.
+ *
+ */
+ function raise($clsid, $error, $param = "") {
+ /* Leve une exception. Si elle existe, sinon, stocke un message d'erreur sur erreur ... */
+ if (_("err_" . $clsid . "_" . $error) != "err_" . $clsid . "_" . $error || is_string($error)) {
+ $this->clsid = $clsid;
+ $this->error = $error;
+ $args = func_get_args();
+ $this->param = array_slice($args, 2);
+ $this->logerr();
+ return true;
+ } else {
+ $this->clsid = "err";
+ $this->error = 1;
+ $this->param = "Error # $error in Class $clsid, Value is $param. (sorry, no text for this error in your language at the moment)";
+ $this->logerr();
+ return false;
+ }
}
- }
- /**
- * Retourne la chaine d'erreur correspondant à la dernière erreur rencontrée
- *
- * Si la dernière erreur rencontrée est connue, retourne l'erreur en toute lettre
- * dans la langue actuellement sélectionnée, ou en anglais par défaut.
- * Si l'erreur n'est pas connue, retourne son numéro de classe et d'ereur.
- *
- * @return string Chaine d'erreur.
- *
- */
- function errstr() {
- if (is_string($this->error)) {
- // new way of handling errors: message directly in the class
- $str = $this->error."\n";
- } else {
- // old way: message in the locales files (ugly)
- $str = _("err_".$this->clsid."_".$this->error)."\n";
+ /**
+ * Retourne la chaine d'erreur correspondant à la dernière erreur rencontrée
+ *
+ * Si la dernière erreur rencontrée est connue, retourne l'erreur en toute lettre
+ * dans la langue actuellement sélectionnée, ou en anglais par défaut.
+ * Si l'erreur n'est pas connue, retourne son numéro de classe et d'ereur.
+ *
+ * @return string Chaine d'erreur.
+ *
+ */
+ function errstr() {
+ if (is_string($this->error)) {
+ // new way of handling errors: message directly in the class
+ $str = $this->error . "\n";
+ } else {
+ // old way: message in the locales files (ugly)
+ $str = _("err_" . $this->clsid . "_" . $this->error) . "\n";
+ }
+ $args = $this->param;
+ if (is_array($args)) {
+ array_unshift($args, $str);
+ $msg = call_user_func_array("sprintf", $args);
+ return $msg;
+ } else {
+ return $args;
+ }
}
- $args = $this->param;
- if (is_array($args)) {
- array_unshift($args, $str);
- $msg = call_user_func_array("sprintf", $args);
- return $msg;
- } else {
- return $args;
+
+ /**
+ * Envoi un log d'erreur dans /var/log/alternc/bureau.log
+ *
+ * Cette fonction Loggue la dernière erreur dans /var/log sur la machine,
+ * permettant ainsi aux admins de savoir ce qu'il se passe...
+ * Elle est appelée automatiquement par error
+ * @access private
+ */
+ function logerr() {
+ global $mem;
+ @file_put_contents($this->logfile, date("d/m/Y H:i:s") . " - ERROR - " . $mem->user["login"] . " - " . $this->errstr(), FILE_APPEND);
}
- }
- /**
- * Envoi un log d'erreur dans /var/log/alternc/bureau.log
- *
- * Cette fonction Loggue la dernière erreur dans /var/log sur la machine,
- * permettant ainsi aux admins de savoir ce qu'il se passe...
- * Elle est appelée automatiquement par error
- * @access private
- */
- function logerr() {
- global $mem;
- @file_put_contents($this->logfile, date("d/m/Y H:i:s")." - ERROR - ".$mem->user["login"]." - ".$this->errstr(), FILE_APPEND );
- }
+ /**
+ * Envoi un log d'appel d'API dans /var/log/alternc/bureau.log
+ *
+ * Cette fonction loggue dans /var/log l'appel à la fonction de l'API
+ * d'AlternC.
+ *
+ * @param integer $clsid Numéro de la classe dont on a appelé une fonction
+ * @param string $function Nom de la fonction appelée
+ * @param string $param Paramètre (facultatif) passés à la fonction de l'API.
+ * @return boolean TRUE si le log a été ajouté, FALSE sinon
+ *
+ */
+ function log($clsid, $function, $param = "") {
+ global $mem;
+ return @file_put_contents($this->logfile, date("d/m/Y H:i:s") . " - " . get_remote_ip() . " - CALL - " . $mem->user["login"] . " - $clsid - $function - $param\n", FILE_APPEND);
+ }
- /**
- * Envoi un log d'appel d'API dans /var/log/alternc/bureau.log
- *
- * Cette fonction loggue dans /var/log l'appel à la fonction de l'API
- * d'AlternC.
- *
- * @param integer $clsid Numéro de la classe dont on a appelé une fonction
- * @param string $function Nom de la fonction appelée
- * @param string $param Paramètre (facultatif) passés à la fonction de l'API.
- * @return boolean TRUE si le log a été ajouté, FALSE sinon
- *
- */
- function log($clsid,$function,$param="") {
- global $mem,$cuid;
- return @file_put_contents($this->logfile,date("d/m/Y H:i:s")." - " .get_remote_ip(). " - CALL - ".$mem->user["login"]." - $clsid - $function - $param\n", FILE_APPEND );
- }
+}
-}; /* Classe m_err */
-
-?>
+/* Classe m_err */
diff --git a/bureau/class/m_export.php b/bureau/class/m_export.php
index 9289ea38..dfb0c2a4 100644
--- a/bureau/class/m_export.php
+++ b/bureau/class/m_export.php
@@ -1,29 +1,35 @@
invoke('alternc_export_conf');
+ $config = $hooks->invoke('alternc_export_conf');
return $config;
}
-/** le repertoire de base est passé en paramettre puis en construit une arborescence de la forme
-////invoke('alternc_export_data', Array($dir));
}
-}// export Class end
+}
+
+// export Class end
diff --git a/bureau/class/m_ftp.php b/bureau/class/m_ftp.php
index 56fe7d97..df536fdb 100644
--- a/bureau/class/m_ftp.php
+++ b/bureau/class/m_ftp.php
@@ -1,4 +1,5 @@
srv_name = variable_get('ftp_human_name', $L_FQDN,'Human name for FTP server', array('desc'=>'Name','type'=>'string'));
- }
+ /* ----------------------------------------------------------------- */
-
- /* ----------------------------------------------------------------- */
- /**
- * Password kind used in this class (hook for admin class)
- */
- function alternc_password_policy() {
- return array("ftp"=>"FTP accounts");
- }
-
- function hook_menu() {
- global $quota;
- $q = $quota->getquota("ftp");
-
- $obj = array(
- 'title' => _("FTP accounts"),
- 'ico' => 'images/ftp.png',
- 'link' => 'toggle',
- 'pos' => 60,
- 'links' => array(),
- ) ;
-
- if ( $quota->cancreate("ftp") ) {
- $obj['links'][] =
- array (
- 'ico' => 'images/new.png',
- 'txt' => _("Create a new ftp account"),
- 'url' => "ftp_edit.php?create=1",
- 'class' => '',
- );
- }
-
- if ( $q['u'] > 0 ) { // if there are some FTP accounts
- $obj['links'][] =
- array (
- 'txt' => _("FTP accounts list"),
- 'url' => "ftp_list.php"
- );
- }
-
- return $obj;
- }
-
- // Return the values needed to activate security access. See get_auth_class()
- // in authip for more informations
- function authip_class() {
- $c = Array();
- $c['name']="FTP";
- $c['protocol']="ftp";
- $c['values']=Array();
-
- $tt = $this->get_list();
- if (empty($tt) || !is_array($tt)) return $c;
- foreach ($this->get_list() as $v ) {
- $c['values'][$v['id']]=$v['login'];
+ /**
+ * Constructeur
+ */
+ function m_ftp() {
+ global $L_FQDN;
+ $this->srv_name = variable_get('ftp_human_name', $L_FQDN, 'Human name for FTP server', array('desc' => 'Name', 'type' => 'string'));
}
- return $c;
- }
+ /* ----------------------------------------------------------------- */
- // Switch enabled status of an account
- function switch_enabled($id,$status=null) {
- global $cuid, $db, $err;
- if (! $jj = $this->get_ftp_details($id)) {
- $err->raise('ftp', _("This account do not exist or is not of this account"));
- return false;
- }
- if ( $status == null ){
- if ($jj[0]['enabled'] == true ) { $status=0;}
- else { $status=1; }
- }
-
- // Be sure what is in $status, in case of it was a parameter
- $status = ($status?'true':'false');
-
- if ( ! $db->query("UPDATE ftpusers SET enabled = $status WHERE uid = '$cuid' AND id = '$id' ;") ) {
- $err->raise('ftp', _("Error during update"));
- return false;
- } else {
- return true ;
- }
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Retourne la liste des comptes FTP du compte hébergé
- * Retourne la liste des comptes FTP sous forme de tableau indexé de
- * tableaus associatifs comme suit :
- * $a["id"]= ID du compte ftp
- * $a["login"]= Nom de login du compte
- * $a["dir"]= Dossier relatif à la racine du compte de l'utilisateur
- * @return array Retourne le tableau des comptes
- */
- function get_list() {
- global $db,$err,$cuid, $bro;
- $err->log("ftp","get_list");
- $r=array();
- $db->query("SELECT id, name, homedir, enabled FROM ftpusers WHERE uid='$cuid' ORDER BY name;");
- if ($db->num_rows()) {
- while ($db->next_record()) {
- $r[]=array(
- "id"=>$db->f("id"),
- "login"=>$db->f("name"),
- "enabled"=>$db->f("enabled"),
- //"dir"=>$match[1]
- "dir"=>$db->f("homedir")
- );
- }
- return $r;
- } else {
- $err->raise("ftp",_("No FTP account found"));
- return array();
- }
- }
-
- /* ----------------------------------------------------------------- */
- /** Retourne les détails d'un compte FTP (voir get_list)
- * Le tableau est celui du compte d'id spécifié
- * @param integer $id Numéro du compte dont on souhaite obtenir les détails
- * @return array Tableau associatif contenant les infos du comptes ftp
- */
- function get_ftp_details($id) {
- global $db,$err,$cuid;
- $err->log("ftp","get_ftp_details",$id);
- $r=array();
- $db->query("SELECT id, name, homedir, enabled FROM ftpusers WHERE uid='$cuid' AND id='$id';");
- if ($db->num_rows()) {
- $db->next_record();
-
- $regexp="/^".preg_quote(getuserpath(),"/")."\/(.*)$/";
- preg_match($regexp, $db->f("homedir"),$match);
-
- $lg=explode("_",$db->f("name"));
- if ((!is_array($lg)) || (count($lg)!=2)) {
- $lg[0]=$db->f("name");
- $lg[1]="";
- }
- $r[]=array(
- "id"=>$db->f("id"),
- "prefixe"=> $lg[0],
- "login"=>$lg[1],
- "dir"=>$match[1],
- "enabled"=>$db->f("enabled")
- );
- return $r;
- } else {
- $err->raise("ftp",_("This FTP account does not exist"));
- return false;
- }
- }
-
- /* ----------------------------------------------------------------- */
- /** Retourne la liste des prefixes utilisables par le compte courant
- * @return array tableau contenant la liste des prefixes (domaines + login)
- * du compte actuel.
- */
- function prefix_list() {
- global $db,$mem,$cuid;
- $r=array();
- $r[]=$mem->user["login"];
- $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' ORDER BY domaine;");
- while ($db->next_record()) {
- $r[]=$db->f("domaine");
- }
- return $r;
- }
-
- /**
- * Check if the login is fine (syntax)
- *
- * @param string $l
- */
- function check_login($l) {
- global $err;
-
- // special chars and the max numbers of them allowed
- // to be able to give a specific error
- $vv = array('_'=>'1', ' '=>0);
- foreach ($vv as $k=>$n) {
- if (substr_count($l, $k) > $n ) { // if there is more than $n $k
- $err->raise('ftp', sprintf(_("FTP login is incorrect: too many '%s'"), $k));
- return false;
- }
+ /**
+ * Password kind used in this class (hook for admin class)
+ */
+ function alternc_password_policy() {
+ return array("ftp" => "FTP accounts");
}
- // Explicitly look for only allowed chars
- if ( ! preg_match("/^[A-Za-z0-9]+[A-Za-z0-9_\.\-]*$/", $l) ) {
- $err->raise('ftp', _("FTP login is incorrect"));
- return false;
- }
- return true;
- }
+ function hook_menu() {
+ global $quota;
+ $q = $quota->getquota("ftp");
- /* ----------------------------------------------------------------- */
- /** Affiche (ECHO) la liste des prefixes disponibles sous forme de champs d'option
- * Les champs sont affichés sous la forme ...
- * La valeur $current se voit affublée de la balise SELECTED.
- * @param string $current Prefixe sélectionné par défaut
- * @return boolean TRUE.
- */
- function select_prefix_list($current) {
- $r=$this->prefix_list();
- reset($r);
- while (list($key,$val)=each($r)) {
- if ($current==$val) $c=" selected=\"selected\""; else $c="";
- echo "";
- }
- return true;
- }
+ $obj = array(
+ 'title' => _("FTP accounts"),
+ 'ico' => 'images/ftp.png',
+ 'link' => 'toggle',
+ 'pos' => 60,
+ 'links' => array(),
+ );
- /* ----------------------------------------------------------------- */
- /** Modifie les paramètres du comptes FTP $id.
- * @param integer $id Numéro du compte dont on veut modifier les paramètres
- * @param string $prefixe Prefixe du compte FTP
- * @param string $login login ajouté au préfixe ($prefixe_$login)
- * @param string $pass mot de passe
- * @param string $dir Répertoire racine du compte
- * @return boolean TRUE si le compte a été modifié, FALSE si une erreur est survenue.
- */
- function put_ftp_details($id,$prefixe,$login,$pass,$dir) {
- global $mem,$db,$err,$bro,$cuid,$admin;
- $err->log("ftp","put_ftp_details",$id);
- $db->query("SELECT count(*) AS cnt FROM ftpusers WHERE id='$id' and uid='$cuid';");
- $db->next_record();
- if (!$db->f("cnt")) {
- $err->raise("ftp",_("This FTP account does not exist"));
- return false;
- }
- $dir=$bro->convertabsolute($dir);
- if (substr($dir,0,1)=="/") {
- $dir=substr($dir,1);
- }
- $r=$this->prefix_list();
- if (!in_array($prefixe,$r)) {
- $err->raise("ftp",_("The chosen prefix is not allowed"));
- return false;
- }
-
- $full_login=$prefixe;
- if ($login) $full_login.="_".$login;
- if (! $this->check_login($full_login) ) return false;
- $db->query("SELECT COUNT(*) AS cnt FROM ftpusers WHERE id!='$id' AND name='$full_login';");
- $db->next_record();
- if ($db->f("cnt")) {
- $err->raise("ftp",_("This FTP account already exists"));
- return false;
- }
- $absolute=getuserpath()."/$dir";
- if (!file_exists($absolute)) {
- system("/bin/mkdir -p $absolute");
- }
- if (!is_dir($absolute)) {
- $err->raise("ftp",_("The directory cannot be created"));
- return false;
- }
- if (trim($pass)) {
-
- // Check this password against the password policy using common API :
- if (is_callable(array($admin,"checkPolicy"))) {
- if (!$admin->checkPolicy("ftp",$full_login,$pass)) {
- return false; // The error has been raised by checkPolicy()
+ if ($quota->cancreate("ftp")) {
+ $obj['links'][] = array(
+ 'ico' => 'images/new.png',
+ 'txt' => _("Create a new ftp account"),
+ 'url' => "ftp_edit.php?create=1",
+ 'class' => '',
+ );
}
- }
- $encrypted_password = _md5cr($pass,strrev(microtime(true)));
- $db->query("UPDATE ftpusers SET name='".$full_login."', password='', encrypted_password='$encrypted_password', homedir='$absolute', uid='$cuid' WHERE id='$id';");
- } else {
- $db->query("UPDATE ftpusers SET name='".$full_login."', homedir='$absolute', uid='$cuid' WHERE id='$id';");
- }
- return true;
- }
+ if ($q['u'] > 0) { // if there are some FTP accounts
+ $obj['links'][] = array(
+ 'txt' => _("FTP accounts list"),
+ 'url' => "ftp_list.php"
+ );
+ }
- /* ----------------------------------------------------------------- */
- /** Efface le compte ftp spécifié.
- * @param integer $id Numéro du compte FTP à supprimer.
- * @return boolean TRUE si le compte a été effacé, FALSE sinon.
- */
- function delete_ftp($id) {
- global $db,$err,$cuid;
- $err->log("ftp","delete_ftp",$id);
- $db->query("SELECT name FROM ftpusers WHERE id='$id' and uid='$cuid';");
- $db->next_record();
- $name=$db->f("name");
- if (!$name) {
- $err->raise("ftp",_("This FTP account does not exist"));
- return false;
- }
- $db->query("DELETE FROM ftpusers WHERE id='$id'");
- return $name;
- }
-
- /* ----------------------------------------------------------------- */
- /** Crée un nouveau compte FTP.
- * @param string $prefixe Prefixe au login
- * @param string $login Login ftp (login=prefixe_login)
- * @param string $pass Mot de passe FTP
- * @param string $dir Répertoire racine du compte relatif à la racine du membre
- * @return boolean TRUE si le compte a été créé, FALSE sinon.
- *
- */
- function add_ftp($prefixe,$login,$pass,$dir) {
- global $mem,$db,$err,$quota,$bro,$cuid,$admin;
- $err->log("ftp","add_ftp",$prefixe."_".$login);
- $dir=$bro->convertabsolute($dir);
- if (substr($dir,0,1)=="/") {
- $dir=substr($dir,1);
- }
- $r=$this->prefix_list();
- if (empty($pass)) {
- $err->raise("ftp",_("Password can't be empty"));
- return false;
- }
- if (!in_array($prefixe,$r) || $prefixe=="") {
- $err->raise("ftp",_("The chosen prefix is not allowed"));
- return false;
- }
- $full_login=$prefixe;
- if ($login) $full_login.="_".$login;
- if ( !$this->check_login($full_login) ) return false;
- $db->query("SELECT count(*) AS cnt FROM ftpusers WHERE name='".$full_login."'");
- $db->next_record();
- if ($db->f("cnt")) {
- $err->raise("ftp",_("This FTP account already exists"));
- return false;
- }
- $db->query("SELECT login FROM membres WHERE uid='$cuid';");
- $db->next_record();
- $absolute=getuserpath()."/$dir";
- if (!file_exists($absolute)) {
- system("/bin/mkdir -p $absolute"); // FIXME replace with action
- }
- if (!is_dir($absolute)) {
- $err->raise("ftp",_("The directory cannot be created"));
- return false;
+ return $obj;
}
- // Check this password against the password policy using common API :
- if (is_callable(array($admin,"checkPolicy"))) {
- if (!$admin->checkPolicy("ftp",$full_login,$pass)) {
- return false; // The error has been raised by checkPolicy()
- }
+ // Return the values needed to activate security access. See get_auth_class()
+ // in authip for more informations
+ function authip_class() {
+ $c = Array();
+ $c['name'] = "FTP";
+ $c['protocol'] = "ftp";
+ $c['values'] = Array();
+
+ $tt = $this->get_list();
+ if (empty($tt) || !is_array($tt)) {
+ return $c;
+ }
+ foreach ($this->get_list() as $v) {
+ $c['values'][$v['id']] = $v['login'];
+ }
+
+ return $c;
}
- if ($quota->cancreate("ftp")) {
- $encrypted_password = _md5cr($pass,strrev(microtime(true)));
- $db->query("INSERT INTO ftpusers (name,password, encrypted_password,homedir,uid) VALUES ('".$full_login."', '', '$encrypted_password', '$absolute', '$cuid')");
- return true;
- } else {
- $err->raise("ftp",_("Your FTP account quota is over. You cannot create more ftp accounts"));
- return false;
+ // Switch enabled status of an account
+ function switch_enabled($id, $status = null) {
+ global $cuid, $db, $err;
+ if (!$jj = $this->get_ftp_details($id)) {
+ $err->raise('ftp', _("This account do not exist or is not of this account"));
+ return false;
+ }
+ if ($status == null) {
+ if ($jj[0]['enabled'] == true) {
+ $status = 0;
+ } else {
+ $status = 1;
+ }
+ }
+
+ // Be sure what is in $status, in case of it was a parameter
+ $status = ($status ? 'true' : 'false');
+
+ if (!$db->query("UPDATE ftpusers SET enabled = $status WHERE uid = '$cuid' AND id = '$id' ;")) {
+ $err->raise('ftp', _("Error during update"));
+ return false;
+ } else {
+ return true;
+ }
}
- }
- /* ----------------------------------------------------------------- */
- /** Retourne TRUE si $dir possède un compte FTP
- * @param string $dir Dossier à tester, relatif à la racine du compte courant
- * @return boolean retourne TRUE si $dir à un compte FTP, FALSE sinon.
- */
- function is_ftp($dir) {
- global $mem,$db,$err;
- $err->log("ftp","is_ftp",$dir);
- if (substr($dir,0,1)=="/") $dir=substr($dir,1);
- $db->query("SELECT id FROM ftpusers WHERE homedir='".getuserpath()."/$dir';");
- if ($db->num_rows()) {
- $db->next_record();
- return $db->f("id");
- } else {
- return false;
+ /* ----------------------------------------------------------------- */
+
+ /** Retourne la liste des comptes FTP du compte h�berg�
+ * Retourne la liste des comptes FTP sous forme de tableau index� de
+ * tableaus associatifs comme suit :
+ * $a["id"]= ID du compte ftp
+ * $a["login"]= Nom de login du compte
+ * $a["dir"]= Dossier relatif � la racine du compte de l'utilisateur
+ * @return array Retourne le tableau des comptes
+ */
+ function get_list() {
+ global $db, $err, $cuid;
+ $err->log("ftp", "get_list");
+ $r = array();
+ $db->query("SELECT id, name, homedir, enabled FROM ftpusers WHERE uid='$cuid' ORDER BY name;");
+ if ($db->num_rows()) {
+ while ($db->next_record()) {
+ $r[] = array(
+ "id" => $db->f("id"),
+ "login" => $db->f("name"),
+ "enabled" => $db->f("enabled"),
+ //"dir"=>$match[1]
+ "dir" => $db->f("homedir")
+ );
+ }
+ return $r;
+ } else {
+ $err->raise("ftp", _("No FTP account found"));
+ return array();
+ }
}
- }
- /* ----------------------------------------------------------------- */
- /** Fonction appellée par domains quand un domaine est supprimé pour le membre
- * @param string $dom Domaine à détruire.
- * @access private
- */
- function alternc_del_domain($dom) {
- global $db,$err,$cuid;
- $err->log("ftp","alternc_del_domain",$dom);
- $db->query("DELETE FROM ftpusers WHERE uid='$cuid' AND ( name LIKE '$dom\_%' OR name LIKE '$dom') ");
- return true;
- }
+ /* ----------------------------------------------------------------- */
- /* ----------------------------------------------------------------- */
- /** Fonction appellée par membres quand un membre est effacé.
- * @access private
- */
- function alternc_del_member() {
- global $db,$err,$cuid;
- $err->log("ftp","alternc_del_member");
- $db->query("DELETE FROM ftpusers WHERE uid='$cuid'");
- return true;
- }
+ /** Retourne les details d'un compte FTP (voir get_list)
+ * Le tableau est celui du compte d'id specifie
+ * @param integer $id Numero du compte dont on souhaite obtenir les d�tails
+ * @return array Tableau associatif contenant les infos du comptes ftp
+ */
+ function get_ftp_details($id) {
+ global $db, $err, $cuid;
+ $err->log("ftp", "get_ftp_details", $id);
+ $r = array();
+ $db->query("SELECT id, name, homedir, enabled FROM ftpusers WHERE uid='$cuid' AND id='$id';");
+ if ($db->num_rows()) {
+ $db->next_record();
- /* ----------------------------------------------------------------- */
- /**
- * Returns the used quota for the $name service for the current user.
- * @param $name string name of the quota
- * @return integer the number of service used or false if an error occured
- * @access private
- */
- function hook_quota_get() {
- global $db,$err,$cuid;
- $err->log("ftp","getquota");
- $q=Array("name"=>"ftp", "description"=>_("FTP accounts"), "used"=>0);
- $db->query("SELECT COUNT(*) AS cnt FROM ftpusers WHERE uid='$cuid'");
- if ($db->next_record()) {
- $q['used']=$db->f("cnt");
+ $regexp = "/^" . preg_quote(getuserpath(), "/") . "\/(.*)$/";
+ $match = array();
+ preg_match($regexp, $db->f("homedir"), $match);
+
+ $lg = explode("_", $db->f("name"));
+ if ((!is_array($lg)) || (count($lg) != 2)) {
+ $lg[0] = $db->f("name");
+ $lg[1] = "";
+ }
+ $r[] = array(
+ "id" => $db->f("id"),
+ "prefixe" => $lg[0],
+ "login" => $lg[1],
+ "dir" => $match[1],
+ "enabled" => $db->f("enabled")
+ );
+ return $r;
+ } else {
+ $err->raise("ftp", _("This FTP account does not exist"));
+ return false;
+ }
}
- return $q;
- }
+ /* ----------------------------------------------------------------- */
- /* ----------------------------------------------------------------- */
- /**
- * Exporte toutes les informations ftp du compte AlternC
- * @access private
- * EXPERIMENTAL 'sid' function ;)
- */
- function alternc_export_conf() {
- global $db,$err;
- $err->log("ftp","export");
- $f=$this->get_list();
- $str=" ";
- foreach ($f as $d=>$v) {
- $str.=" ".($v["login"])." \n";
- $str.=" ".($v["encrypted_password"])." \n";
- $str.=" ".($v["dir"])."\n";
+ /** Retourne la liste des prefixes utilisables par le compte courant
+ * @return array tableau contenant la liste des prefixes (domaines + login)
+ * du compte actuel.
+ */
+ function prefix_list() {
+ global $db, $mem, $cuid;
+ $r = array();
+ $r[] = $mem->user["login"];
+ $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' ORDER BY domaine;");
+ while ($db->next_record()) {
+ $r[] = $db->f("domaine");
+ }
+ return $r;
}
- $str.=" \n";
- return $str;
- }
+ /**
+ * Check if the login is fine (syntax)
+ *
+ * @param string $l
+ */
+ function check_login($l) {
+ global $err;
- /* ----------------------------------------------------------------- */
- /** hook function called by AlternC-upnp to know which open
- * tcp or udp ports this class requires or suggests
- * @return array a key => value list of port protocol name mandatory values
- * @access private
- */
- function hook_upnp_list() {
- return array(
- "ftp" => array("port" => 21, "protocol" => "tcp", "mandatory" => 1),
- );
- }
-
-} /* Class m_ftp */
+ // special chars and the max numbers of them allowed
+ // to be able to give a specific error
+ $vv = array('_' => '1', ' ' => 0);
+ foreach ($vv as $k => $n) {
+ if (substr_count($l, $k) > $n) { // if there is more than $n $k
+ $err->raise('ftp', sprintf(_("FTP login is incorrect: too many '%s'"), $k));
+ return false;
+ }
+ }
+ // Explicitly look for only allowed chars
+ if (!preg_match("/^[A-Za-z0-9]+[A-Za-z0-9_\.\-]*$/", $l)) {
+ $err->raise('ftp', _("FTP login is incorrect"));
+ return false;
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Affiche (ECHO) la liste des prefixes disponibles sous forme de champs d'option
+ * Les champs sont affich�s sous la forme ...
+ * La valeur $current se voit affubl�e de la balise SELECTED.
+ * @param string $current Prefixe s�lectionn� par d�faut
+ * @return boolean TRUE.
+ */
+ function select_prefix_list($current) {
+ $r = $this->prefix_list();
+ reset($r);
+ while (list($key, $val) = each($r)) {
+ if ($current == $val) {
+ $c = " selected=\"selected\"";
+ } else {
+ $c = "";
+ }
+ echo "";
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Modifie les param�tres du comptes FTP $id.
+ * @param integer $id Num�ro du compte dont on veut modifier les param�tres
+ * @param string $prefixe Prefixe du compte FTP
+ * @param string $login login ajout� au pr�fixe ($prefixe_$login)
+ * @param string $pass mot de passe
+ * @param string $dir R�pertoire racine du compte
+ * @return boolean TRUE si le compte a �t� modifi�, FALSE si une erreur est survenue.
+ */
+ function put_ftp_details($id, $prefixe, $login, $pass, $dir) {
+ global $db, $err, $bro, $cuid, $admin;
+ $err->log("ftp", "put_ftp_details", $id);
+ $db->query("SELECT count(*) AS cnt FROM ftpusers WHERE id='$id' and uid='$cuid';");
+ $db->next_record();
+ if (!$db->f("cnt")) {
+ $err->raise("ftp", _("This FTP account does not exist"));
+ return false;
+ }
+ $dir = $bro->convertabsolute($dir);
+ if (substr($dir, 0, 1) == "/") {
+ $dir = substr($dir, 1);
+ }
+ $r = $this->prefix_list();
+ if (!in_array($prefixe, $r)) {
+ $err->raise("ftp", _("The chosen prefix is not allowed"));
+ return false;
+ }
+
+ $full_login = $prefixe;
+ if ($login) {
+ $full_login.="_" . $login;
+ }
+ if (!$this->check_login($full_login)) {
+ return false;
+ }
+ $db->query("SELECT COUNT(*) AS cnt FROM ftpusers WHERE id!='$id' AND name='$full_login';");
+ $db->next_record();
+ if ($db->f("cnt")) {
+ $err->raise("ftp", _("This FTP account already exists"));
+ return false;
+ }
+ $absolute = getuserpath() . "/$dir";
+ if (!file_exists($absolute)) {
+ system("/bin/mkdir -p $absolute");
+ }
+ if (!is_dir($absolute)) {
+ $err->raise("ftp", _("The directory cannot be created"));
+ return false;
+ }
+ if (trim($pass)) {
+
+ // Check this password against the password policy using common API :
+ if (is_callable(array($admin, "checkPolicy"))) {
+ if (!$admin->checkPolicy("ftp", $full_login, $pass)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ }
+ $encrypted_password = _md5cr($pass, strrev(microtime(true)));
+ $db->query("UPDATE ftpusers SET name='" . $full_login . "', password='', encrypted_password='$encrypted_password', homedir='$absolute', uid='$cuid' WHERE id='$id';");
+ } else {
+ $db->query("UPDATE ftpusers SET name='" . $full_login . "', homedir='$absolute', uid='$cuid' WHERE id='$id';");
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Efface le compte ftp specifie
+ * @param integer $id Numero du compte FTP a supprimer.
+ * @return boolean TRUE si le compte a ete efface, FALSE sinon.
+ */
+ function delete_ftp($id) {
+ global $db, $err, $cuid;
+ $err->log("ftp", "delete_ftp", $id);
+ $db->query("SELECT name FROM ftpusers WHERE id='$id' and uid='$cuid';");
+ $db->next_record();
+ $name = $db->f("name");
+ if (!$name) {
+ $err->raise("ftp", _("This FTP account does not exist"));
+ return false;
+ }
+ $db->query("DELETE FROM ftpusers WHERE id='$id'");
+ return $name;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Cree un nouveau compte FTP.
+ * @param string $prefixe Prefixe au login
+ * @param string $login Login ftp (login=prefixe_login)
+ * @param string $pass Mot de passe FTP
+ * @param string $dir Repertoire racine du compte relatif à la racine du membre
+ * @return boolean TRUE si le compte a ete cree, FALSE sinon.
+ *
+ */
+ function add_ftp($prefixe, $login, $pass, $dir) {
+ global $db, $err, $quota, $bro, $cuid, $admin;
+ $err->log("ftp", "add_ftp", $prefixe . "_" . $login);
+ $dir = $bro->convertabsolute($dir);
+ if (substr($dir, 0, 1) == "/") {
+ $dir = substr($dir, 1);
+ }
+ $r = $this->prefix_list();
+ if (empty($pass)) {
+ $err->raise("ftp", _("Password can't be empty"));
+ return false;
+ }
+ if (!in_array($prefixe, $r) || $prefixe == "") {
+ $err->raise("ftp", _("The chosen prefix is not allowed"));
+ return false;
+ }
+ $full_login = $prefixe;
+ if ($login) {
+ $full_login.="_" . $login;
+ }
+ if (!$this->check_login($full_login)) {
+ return false;
+ }
+ $db->query("SELECT count(*) AS cnt FROM ftpusers WHERE name='" . $full_login . "'");
+ $db->next_record();
+ if ($db->f("cnt")) {
+ $err->raise("ftp", _("This FTP account already exists"));
+ return false;
+ }
+ $db->query("SELECT login FROM membres WHERE uid='$cuid';");
+ $db->next_record();
+ $absolute = getuserpath() . "/$dir";
+ if (!file_exists($absolute)) {
+ system("/bin/mkdir -p $absolute"); // FIXME replace with action
+ }
+ if (!is_dir($absolute)) {
+ $err->raise("ftp", _("The directory cannot be created"));
+ return false;
+ }
+
+ // Check this password against the password policy using common API :
+ if (is_callable(array($admin, "checkPolicy"))) {
+ if (!$admin->checkPolicy("ftp", $full_login, $pass)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ }
+
+ if ($quota->cancreate("ftp")) {
+ $encrypted_password = _md5cr($pass, strrev(microtime(true)));
+ $db->query("INSERT INTO ftpusers (name,password, encrypted_password,homedir,uid) VALUES ('" . $full_login . "', '', '$encrypted_password', '$absolute', '$cuid')");
+ return true;
+ } else {
+ $err->raise("ftp", _("Your FTP account quota is over. You cannot create more ftp accounts"));
+ return false;
+ }
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Retourne TRUE si $dir possee un compte FTP
+ * @param string $dir Dossier a tester, relatif a la racine du compte courant
+ * @return boolean retourne TRUE si $dir a un compte FTP, FALSE sinon.
+ */
+ function is_ftp($dir) {
+ global $db, $err;
+ $err->log("ftp", "is_ftp", $dir);
+ if (substr($dir, 0, 1) == "/") {
+ $dir = substr($dir, 1);
+ }
+ $db->query("SELECT id FROM ftpusers WHERE homedir='" . getuserpath() . "/$dir';");
+ if ($db->num_rows()) {
+ $db->next_record();
+ return $db->f("id");
+ } else {
+ return false;
+ }
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Fonction appellee par domains quand un domaine est supprime pour le membre
+ * @param string $dom Domaine à detruire.
+ * @access private
+ */
+ function alternc_del_domain($dom) {
+ global $db, $err, $cuid;
+ $err->log("ftp", "alternc_del_domain", $dom);
+ $db->query("DELETE FROM ftpusers WHERE uid='$cuid' AND ( name LIKE '$dom\_%' OR name LIKE '$dom') ");
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Fonction appellee par membres quand un membre est efface
+ * @access private
+ */
+ function alternc_del_member() {
+ global $db, $err, $cuid;
+ $err->log("ftp", "alternc_del_member");
+ $db->query("DELETE FROM ftpusers WHERE uid='$cuid'");
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Returns the used quota for the $name service for the current user.
+ * @param $name string name of the quota
+ * @return integer the number of service used or false if an error occured
+ * @access private
+ */
+ function hook_quota_get() {
+ global $db, $err, $cuid;
+ $err->log("ftp", "getquota");
+ $q = Array("name" => "ftp", "description" => _("FTP accounts"), "used" => 0);
+ $db->query("SELECT COUNT(*) AS cnt FROM ftpusers WHERE uid='$cuid'");
+ if ($db->next_record()) {
+ $q['used'] = $db->f("cnt");
+ }
+ return $q;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Exporte toutes les informations ftp du compte AlternC
+ * @access private
+ * EXPERIMENTAL 'sid' function ;)
+ */
+ function alternc_export_conf() {
+ global $db, $err;
+ $err->log("ftp", "export");
+ $f = $this->get_list();
+ $str = " ";
+ foreach ($f as $d => $v) {
+ $str.=" " . ($v["login"]) . " \n";
+ $str.=" " . ($v["encrypted_password"]) . " \n";
+ $str.=" " . ($v["dir"]) . "\n";
+ }
+ $str.=" \n";
+ return $str;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** hook function called by AlternC-upnp to know which open
+ * tcp or udp ports this class requires or suggests
+ * @return array a key => value list of port protocol name mandatory values
+ * @access private
+ */
+ function hook_upnp_list() {
+ return array(
+ "ftp" => array("port" => 21, "protocol" => "tcp", "mandatory" => 1),
+ );
+ }
+
+}
+
+/* Class m_ftp */
diff --git a/bureau/class/m_hooks.php b/bureau/class/m_hooks.php
index 673b18d2..58a92b04 100644
--- a/bureau/class/m_hooks.php
+++ b/bureau/class/m_hooks.php
@@ -1,4 +1,5 @@
"Protected folders passwords");
- }
-
- /**
- *
- * @return array
- */
- function hook_menu() {
- $obj = array(
- 'title' => _("Protected folders"),
- 'ico' => 'images/password.png',
- 'link' => 'hta_list.php',
- 'pos' => 50,
- ) ;
-
- return $obj;
- }
-
+ /**
+ * Constructor
+ */
+ function m_webaccess() {
+
+ }
/**
- * Create a protected folder (.htaccess et .htpasswd)
- * @param string $dir Folder to protect (relative to user root)
- * @return boolean TRUE if the folder has been protected, or FALSE if an error occurred
- *
- * @global m_mem $mem
- * @global m_bro $bro
- * @global m_err $err
- * @param string $dir
- * @return boolean
- */
- function CreateDir($dir) {
- global $mem,$bro,$err;
- $err->log("hta","createdir",$dir);
- $absolute = $bro->convertabsolute($dir,0);
- if (!$absolute) {
- $err->raise("hta",printf(_("The folder '%s' does not exist"),$dir));
- return false;
+ * Password kind used in this class (hook for admin class)
+ *
+ * @return array
+ */
+ function alternc_password_policy() {
+ return array("hta" => "Protected folders passwords");
}
- if (!file_exists($absolute)) {
- @mkdir($absolute,00777);
- }
- if (!file_exists("$absolute/.htaccess")) {
- if (!@touch("$absolute/.htaccess")) {
- $err->raise("hta",_("File already exist"));
- return false;
- }
- $file = @fopen("$absolute/.htaccess","r+");
- if (!$file) {
- $err->raise("hta",_("File already exist"));
- return false;
- }
- fseek($file,0);
- $param = "AuthUserFile \"$absolute/.htpasswd\"\nAuthName \""._("Restricted area")."\"\nAuthType Basic\nrequire valid-user\n";
- fwrite($file, $param);
- fclose($file);
- }
- if (!file_exists("$absolute/.htpasswd")) {
- if (!touch("$absolute/.htpasswd")) {
- $err->raise("hta",_("File already exist"));
- return false;
- }
- return true;
- }
- return true;
- }
-
/**
- * Returns the list of all user folder currently protected by a .htpasswd file
- *
- * @global m_err $err
- * @global m_mem $mem
- * @return array Array containing user folder list
- */
- function ListDir(){
- global$err,$mem;
- $err->log("hta","listdir");
- $sortie = array();
- $absolute = ALTERNC_HTML."/".substr($mem->user["login"],0,1)."/".$mem->user["login"];
- exec("find ".escapeshellarg($absolute)." -name .htpasswd|sort",$sortie);
- if(!count($sortie)){
- $err->raise("hta",_("No protected folder"));
- return false;
+ *
+ * @return array
+ */
+ function hook_menu() {
+ $obj = array(
+ 'title' => _("Protected folders"),
+ 'ico' => 'images/password.png',
+ 'link' => 'hta_list.php',
+ 'pos' => 50,
+ );
+
+ return $obj;
}
- $pattern = "/^".preg_quote(ALTERNC_HTML,"/")."\/.\/[^\/]*\/(.*)\/\.htpasswd/";
-
- $r = array();
- for($i = 0;$ilog("hta","is_protected",$dir);
- $absolute = ALTERNC_HTML."/".substr($mem->user["login"],0,1)."/".$mem->user["login"]."/$dir";
- if (file_exists("$absolute/.htpasswd")){
- return true;
- } else {
- return false;
+ * Create a protected folder (.htaccess et .htpasswd)
+ * @param string $dir Folder to protect (relative to user root)
+ * @return boolean TRUE if the folder has been protected, or FALSE if an error occurred
+ *
+ * @global m_mem $mem
+ * @global m_bro $bro
+ * @global m_err $err
+ * @param string $dir
+ * @return boolean
+ */
+ function CreateDir($dir) {
+ global $bro, $err;
+ $err->log("hta", "createdir", $dir);
+ $absolute = $bro->convertabsolute($dir, 0);
+ if (!$absolute) {
+ $err->raise("hta", printf(_("The folder '%s' does not exist"), $dir));
+ return false;
+ }
+ if (!file_exists($absolute)) {
+ @mkdir($absolute, 00777);
+ }
+ if (!file_exists("$absolute/.htaccess")) {
+ if (!@touch("$absolute/.htaccess")) {
+ $err->raise("hta", _("File already exist"));
+ return false;
+ }
+ $file = @fopen("$absolute/.htaccess", "r+");
+ if (!$file) {
+ $err->raise("hta", _("File already exist"));
+ return false;
+ }
+ fseek($file, 0);
+ $param = "AuthUserFile \"$absolute/.htpasswd\"\nAuthName \"" . _("Restricted area") . "\"\nAuthType Basic\nrequire valid-user\n";
+ fwrite($file, $param);
+ fclose($file);
+ }
+ if (!file_exists("$absolute/.htpasswd")) {
+ if (!touch("$absolute/.htpasswd")) {
+ $err->raise("hta", _("File already exist"));
+ return false;
+ }
+ return true;
+ }
+ return true;
}
- }
-
/**
- * Returns the list of login for a protected folder.
- *
- * @global m_mem $mem
- * @global m_err $err
- * @param string $dir The folder to lookup (relative to user root)
- * @return array An array containing the list of logins from the .htpasswd file, or FALSE
- */
- function get_hta_detail($dir) {
- global $mem,$err;
- $err->log("hta","get_hta_detail");
- $absolute = ALTERNC_HTML."/".substr($mem->user["login"],0,1)."/".$mem->user["login"]."/$dir";
- if (file_exists("$absolute/.htaccess")) {
- /* if (!_reading_htaccess($absolute)) {
- return false;
- }
- */ }
- $file = @fopen("$absolute/.htpasswd","r");
- $i = 0;
- $res = array();
- if (!$file) {
- return false;
- }
- // TODO: Tester la validité du .htpasswd
- while (!feof($file)) {
- $s = fgets($file,1024);
- $t = explode(":",$s);
- if ($t[0]!=$s) {
- $res[$i] = $t[0];
- $i = $i+1;
- }
- }
- fclose($file);
- return $res;
- }
+ * Returns the list of all user folder currently protected by a .htpasswd file
+ *
+ * @global m_err $err
+ * @global m_mem $mem
+ * @return array Array containing user folder list
+ */
+ function ListDir() {
+ global$err, $mem;
+ $err->log("hta", "listdir");
+ $sortie = array();
+ $absolute = ALTERNC_HTML . "/" . substr($mem->user["login"], 0, 1) . "/" . $mem->user["login"];
+ exec("find " . escapeshellarg($absolute) . " -name .htpasswd|sort", $sortie);
+ if (!count($sortie)) {
+ $err->raise("hta", _("No protected folder"));
+ return false;
+ }
+ $pattern = "/^" . preg_quote(ALTERNC_HTML, "/") . "\/.\/[^\/]*\/(.*)\/\.htpasswd/";
+ $r = array();
+ for ($i = 0; $i < count($sortie); $i++) {
+ $matches = array();
+ preg_match($pattern, $sortie[$i], $matches);
+ $tmpm = isset($matches[1]) ? '/' . $matches[1] : '';
+ $r[$i] = $tmpm . "/";
+ }
+ return $r;
+ }
/**
- * Unprotect a folder
- *
- * @global m_mem $mem
- * @global m_bro $bro
- * @global m_err $err
- * @param string $dir Folder to unprotect, relative to user root
- * @param boolean $skip For testing purpose mainly, skips the full user path search
- * @return boolean TRUE if the folder has been unprotected, or FALSE if an error occurred
- */
- function DelDir($dir,$skip = false) {
- global $mem,$bro,$err;
- $err->log("hta","deldir",$dir);
- $dir = $bro->convertabsolute($dir,$skip);
- if (!$dir) {
- $err->raise("hta",printf(("The folder '%s' does not exist"),$dir));
- return false;
+ * Tells if a folder is protected.
+ *
+ * @global m_mem $mem
+ * @global m_err $err
+ * @param string $dir Folder to check
+ * @return boolean If the folder is protected, or FALSE if it is not
+ */
+ function is_protected($dir) {
+ global $mem, $err;
+ $err->log("hta", "is_protected", $dir);
+ $absolute = ALTERNC_HTML . "/" . substr($mem->user["login"], 0, 1) . "/" . $mem->user["login"] . "/$dir";
+ if (file_exists("$absolute/.htpasswd")) {
+ return true;
+ } else {
+ return false;
+ }
}
- $htaccess_file = "$dir/.htaccess";
- if( !is_readable($htaccess_file)){
- $err->raise("hta",printf(_("I cannot read the file '%s'"),$htaccess_file));
- }
- $fileLines = file($htaccess_file);
- $patternList = array(
- "AuthUserFile.*$",
- "AuthName.*$",
- "AuthType Basic.*$",
- "require valid-user.*$"
- );
- $count_lines = 0;
- foreach($fileLines as $key => $line){
- foreach ($patternList as $pattern) {
- if(preg_match("/".$pattern."/", $line)){
- $count_lines++;
- unset($fileLines[$key]);
+
+ /**
+ * Returns the list of login for a protected folder.
+ *
+ * @global m_mem $mem
+ * @global m_err $err
+ * @param string $dir The folder to lookup (relative to user root)
+ * @return array An array containing the list of logins from the .htpasswd file, or FALSE
+ */
+ function get_hta_detail($dir) {
+ global $mem, $err;
+ $err->log("hta", "get_hta_detail");
+ $absolute = ALTERNC_HTML . "/" . substr($mem->user["login"], 0, 1) . "/" . $mem->user["login"] . "/$dir";
+ if (file_exists("$absolute/.htaccess")) {
+ /* if (!_reading_htaccess($absolute)) {
+ return false;
+ }
+ */
+ }
+ $file = @fopen("$absolute/.htpasswd", "r");
+ $i = 0;
+ $res = array();
+ if (!$file) {
+ return false;
+ }
+ // TODO: Tester la validité du .htpasswd
+ while (!feof($file)) {
+ $s = fgets($file, 1024);
+ $t = explode(":", $s);
+ if ($t[0] != $s) {
+ $res[$i] = $t[0];
+ $i = $i + 1;
}
}
+ fclose($file);
+ return $res;
}
- // If no changes
- if( ! $count_lines ){
- $err->raise("hta",printf(_("Unexpected: No changes made to '%s'"),$htaccess_file));
- }
- // If file is empty, remove it
- if( !count($fileLines)){
- if( ! unlink( $htaccess_file)){
- $err->raise("hta",printf(_("I could not delete the file '%s'"),$htaccess_file));
+
+ /**
+ * Unprotect a folder
+ *
+ * @global m_mem $mem
+ * @global m_bro $bro
+ * @global m_err $err
+ * @param string $dir Folder to unprotect, relative to user root
+ * @param boolean $skip For testing purpose mainly, skips the full user path search
+ * @return boolean TRUE if the folder has been unprotected, or FALSE if an error occurred
+ */
+ function DelDir($dir, $skip = false) {
+ global $bro, $err;
+ $err->log("hta", "deldir", $dir);
+ $dir = $bro->convertabsolute($dir, $skip);
+ if (!$dir) {
+ $err->raise("hta", printf(("The folder '%s' does not exist"), $dir));
+ return false;
+ }
+ $htaccess_file = "$dir/.htaccess";
+ if (!is_readable($htaccess_file)) {
+ $err->raise("hta", printf(_("I cannot read the file '%s'"), $htaccess_file));
+ }
+ $fileLines = file($htaccess_file);
+ $patternList = array(
+ "AuthUserFile.*$",
+ "AuthName.*$",
+ "AuthType Basic.*$",
+ "require valid-user.*$"
+ );
+ $count_lines = 0;
+ foreach ($fileLines as $key => $line) {
+ foreach ($patternList as $pattern) {
+ if (preg_match("/" . $pattern . "/", $line)) {
+ $count_lines++;
+ unset($fileLines[$key]);
+ }
+ }
+ }
+ // If no changes
+ if (!$count_lines) {
+ $err->raise("hta", printf(_("Unexpected: No changes made to '%s'"), $htaccess_file));
+ }
+ // If file is empty, remove it
+ if (!count($fileLines)) {
+ if (!unlink($htaccess_file)) {
+ $err->raise("hta", printf(_("I could not delete the file '%s'"), $htaccess_file));
+ }
+ } else {
+ file_put_contents($htaccess_file, implode("\n", $fileLines));
+ }
+ $htpasswd_file = "$dir/.htpasswd";
+ if (!is_writable($htpasswd_file)) {
+ $err->raise("hta", printf(_("I cannot read the file '%s'"), $htpasswd_file));
+ } else if (!unlink($htpasswd_file)) {
+ $err->raise("hta", printf(_("I cannot delete the file '%s/.htpasswd'"), $dir));
+ return false;
}
- }else{
- file_put_contents($htaccess_file, implode("\n",$fileLines));
- }
- $htpasswd_file = "$dir/.htpasswd";
- if( ! is_writable($htpasswd_file)){
- $err->raise("hta",printf(_("I cannot read the file '%s'"),$htpasswd_file));
- }
- else if ( ! unlink($htpasswd_file)) {
- $err->raise("hta",printf(_("I cannot delete the file '%s/.htpasswd'"),$dir));
- return false;
- }
-
- return true;
- }
+ return true;
+ }
/**
- * Add a user to a protected folder
- *
- * @global m_err $err
- * @global m_bro $bro
- * @global m_admin $admin
- * @param string $user
- * @param string $password
- * @param string $dir
- * @param string $password The password to add (cleartext)
- * @param string $dir The folder we add it to (relative to user root).
- * @return boolean TRUE if the user has been added, or FALSE if an error occurred
- */
- function add_user($user,$password,$dir) {
- global $err, $bro, $admin;
- $err->log("hta","add_user",$user."/".$dir);
- if (empty($user)) {
- $err->raise('hta',_("Please enter a user"));
- return false;
- }
- if (empty($password)) {
- $err->raise('hta',_("Please enter a password"));
- return false;
- }
- $absolute = $bro->convertabsolute($dir,0);
- if (!file_exists($absolute)) {
- $err->raise("hta",printf(("The folder '%s' does not exist"),$dir));
- return false;
- }
- // @todo delete cf!. functions.php checkloginemail definition
- if (checkloginmail($user)){
- // Check this password against the password policy using common API :
- if (is_callable(array($admin,"checkPolicy"))) {
- if (!$admin->checkPolicy("hta",$user,$password)) {
- return false; // The error has been raised by checkPolicy()
- }
- }
+ * Add a user to a protected folder
+ *
+ * @global m_err $err
+ * @global m_bro $bro
+ * @global m_admin $admin
+ * @param string $user
+ * @param string $password
+ * @param string $dir
+ * @param string $password The password to add (cleartext)
+ * @param string $dir The folder we add it to (relative to user root).
+ * @return boolean TRUE if the user has been added, or FALSE if an error occurred
+ */
+ function add_user($user, $password, $dir) {
+ global $err, $bro, $admin;
+ $err->log("hta", "add_user", $user . "/" . $dir);
+ if (empty($user)) {
+ $err->raise('hta', _("Please enter a user"));
+ return false;
+ }
+ if (empty($password)) {
+ $err->raise('hta', _("Please enter a password"));
+ return false;
+ }
+ $absolute = $bro->convertabsolute($dir, 0);
+ if (!file_exists($absolute)) {
+ $err->raise("hta", printf(("The folder '%s' does not exist"), $dir));
+ return false;
+ }
+ // @todo delete cf!. functions.php checkloginemail definition
+ if (checkloginmail($user)) {
+ // Check this password against the password policy using common API :
+ if (is_callable(array($admin, "checkPolicy"))) {
+ if (!$admin->checkPolicy("hta", $user, $password)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ }
- $file = @fopen("$absolute/.htpasswd","a+");
- if (!$file) {
- $err->raise("hta",_("File already exist"));
- return false;
- }
- fseek($file,0);
- while (!feof($file)) {
- $s = fgets($file,1024);
- $t = explode(":",$s);
- if ($t[0]==$user) {
- $err->raise("hta",_("The user '%s' already exist for this folder"),$user);
- return false;
- }
- }
- fseek($file,SEEK_END);
- if ( empty($t[1]) || substr($t[1],-1)!="\n") {
- fwrite($file,"\n");
- }
- fwrite($file, "$user:"._md5cr($password)."\n");
- fclose($file);
- return true;
- } else {
- $err->raise("hta",_("Please enter a valid username"));
- return false;
+ $file = @fopen("$absolute/.htpasswd", "a+");
+ if (!$file) {
+ $err->raise("hta", _("File already exist"));
+ return false;
+ }
+ fseek($file, 0);
+ while (!feof($file)) {
+ $s = fgets($file, 1024);
+ $t = explode(":", $s);
+ if ($t[0] == $user) {
+ $err->raise("hta", _("The user '%s' already exist for this folder"), $user);
+ return false;
+ }
+ }
+ fseek($file, SEEK_END);
+ if (empty($t[1]) || substr($t[1], -1) != "\n") {
+ fwrite($file, "\n");
+ }
+ fwrite($file, "$user:" . _md5cr($password) . "\n");
+ fclose($file);
+ return true;
+ } else {
+ $err->raise("hta", _("Please enter a valid username"));
+ return false;
+ }
}
- }
-
/**
- */
- /**
- * Delete a user from a protected folder.
- *
- * @global m_bro $bro
- * @global m_err $err
- * @param array $lst An array with login to delete.
- * @param string $dir The folder, relative to user root, where we want to delete users.
- * @return boolean TRUE if users has been deleted, or FALSE if an error occurred.
- */
- function del_user($lst,$dir) {
- global $bro,$err;
- $err->log("hta","del_user",$lst."/".$dir);
- $absolute = $bro->convertabsolute($dir,0);
- if (!file_exists($absolute)) {
- $err->raise("hta",printf(_("The folder '%s' does not exist"),$dir));
- return false;
+ * Delete a user from a protected folder.
+ *
+ * @global m_bro $bro
+ * @global m_err $err
+ * @param array $lst An array with login to delete.
+ * @param string $dir The folder, relative to user root, where we want to delete users.
+ * @return boolean TRUE if users has been deleted, or FALSE if an error occurred.
+ */
+ function del_user($lst, $dir) {
+ global $bro, $err;
+ $err->log("hta", "del_user", $lst . "/" . $dir);
+ $absolute = $bro->convertabsolute($dir, 0);
+ if (!file_exists($absolute)) {
+ $err->raise("hta", printf(_("The folder '%s' does not exist"), $dir));
+ return false;
+ }
+ touch("$absolute/.htpasswd.new");
+ $file = fopen("$absolute/.htpasswd", "r");
+ $newf = fopen("$absolute/.htpasswd.new", "a");
+ if (!$file || !$newf) {
+ $err->raise("hta", _("File already exist"));
+ return false;
+ }
+ reset($lst);
+ fseek($file, 0);
+ while (!feof($file)) {
+ $s = fgets($file, 1024);
+ $t = explode(":", $s);
+ if (!in_array($t[0], $lst) && ($t[0] != "\n")) {
+ fseek($newf, 0);
+ fwrite($newf, "$s");
+ }
+ }
+ fclose($file);
+ fclose($newf);
+ unlink("$absolute/.htpasswd");
+ rename("$absolute/.htpasswd.new", "$absolute/.htpasswd");
+ return true;
}
- touch("$absolute/.htpasswd.new");
- $file = fopen("$absolute/.htpasswd","r");
- $newf = fopen("$absolute/.htpasswd.new","a");
- if (!$file || !$newf) {
- $err->raise("hta",_("File already exist"));
- return false;
- }
- reset($lst);
- fseek($file,0);
- while (!feof($file)) {
- $s = fgets($file,1024);
- $t = explode(":",$s);
- if (!in_array($t[0],$lst) && ($t[0]!="\n")) {
- fseek($newf,0);
- fwrite($newf, "$s");
- }
- }
- fclose($file);
- fclose($newf);
- unlink("$absolute/.htpasswd");
- rename("$absolute/.htpasswd.new", "$absolute/.htpasswd");
- return true;
- }
-
/**
- * @param string $user The users whose password should be changed
- * @param string $newpass The new password of this user
- * @param string $dir The folder, relative to user root, in which we will change a password
- * @return boolean TRUE if the password has been changed, or FALSE if an error occurred
- */
- /**
- * Change the password of a user in a protected folder
- *
- * @global m_bro $bro
- * @global m_err $err
- * @global m_admin $admin
- * @param string $user
- * @param string $newpass
- * @param string $dir
- * @return boolean
- */
- function change_pass($user,$newpass,$dir) {
- global $bro,$err,$admin;
- $err->log("hta","change_pass",$user."/".$dir);
- $absolute = $bro->convertabsolute($dir,0);
- if (!file_exists($absolute)) {
- $err->raise("hta",printf(_("The folder '%s' does not exist"),$dir));
- return false;
- }
+ * Change the password of a user in a protected folder
+ * @param string $user The users whose password should be changed
+ * @param string $newpass The new password of this user
+ * @param string $dir The folder, relative to user root, in which we will change a password
+ * @return boolean TRUE if the password has been changed, or FALSE if an error occurred
+ */
+ function change_pass($user, $newpass, $dir) {
+ global $bro, $err, $admin;
+ $err->log("hta", "change_pass", $user . "/" . $dir);
+ $absolute = $bro->convertabsolute($dir, 0);
+ if (!file_exists($absolute)) {
+ $err->raise("hta", printf(_("The folder '%s' does not exist"), $dir));
+ return false;
+ }
- // Check this password against the password policy using common API :
- if (is_callable(array($admin,"checkPolicy"))) {
- if (!$admin->checkPolicy("hta",$user,$newpass)) {
- return false; // The error has been raised by checkPolicy()
- }
- }
+ // Check this password against the password policy using common API :
+ if (is_callable(array($admin, "checkPolicy"))) {
+ if (!$admin->checkPolicy("hta", $user, $newpass)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ }
- touch("$absolute/.htpasswd.new");
- $file = fopen("$absolute/.htpasswd","r");
- $newf = fopen("$absolute/.htpasswd.new","a");
- if (!$file || !$newf) {
- $err->raise("hta",_("File already exist"));
- return false;
+ touch("$absolute/.htpasswd.new");
+ $file = fopen("$absolute/.htpasswd", "r");
+ $newf = fopen("$absolute/.htpasswd.new", "a");
+ if (!$file || !$newf) {
+ $err->raise("hta", _("File already exist"));
+ return false;
+ }
+ while (!feof($file)) {
+ $s = fgets($file, 1024);
+ $t = explode(":", $s);
+ if ($t[0] != $user) {
+ fwrite($newf, "$s");
+ }
+ }
+ fwrite($newf, "$user:" . _md5cr($newpass) . "\n");
+ fclose($file);
+ fclose($newf);
+ unlink("$absolute/.htpasswd");
+ rename("$absolute/.htpasswd.new", "$absolute/.htpasswd");
+ return true;
}
- while (!feof($file)) {
- $s = fgets($file,1024);
- $t = explode(":",$s);
- if ($t[0]!=$user) {
- fwrite($newf, "$s");
- }
- }
- fwrite($newf, "$user:"._md5cr($newpass)."\n");
- fclose($file);
- fclose($newf);
- unlink("$absolute/.htpasswd");
- rename("$absolute/.htpasswd.new", "$absolute/.htpasswd");
- return true;
- }
-
/**
- * Check that a .htaccess file is valid (for authentication)
- *
- * @global m_err $err
- * @param type $absolute
- * @param string $absolute Folder we want to check (relative to user root)
- * @return boolean TRUE is the .htaccess is protecting this folder, or FALSE else
- */
- private function _reading_htaccess($absolute) {
- global $err;
- $err->log("hta","_reading_htaccess",$absolute);
- $file = fopen("$absolute/.htaccess","r+");
- $lignes = array(1,1,1);
- $errr = 0;
- if (!$file) {
- return false;
+ * Check that a .htaccess file is valid (for authentication)
+ *
+ * @global m_err $err
+ * @param type $absolute
+ * @param string $absolute Folder we want to check (relative to user root)
+ * @return boolean TRUE is the .htaccess is protecting this folder, or FALSE else
+ */
+ private function _reading_htaccess($absolute) {
+ global $err;
+ $err->log("hta", "_reading_htaccess", $absolute);
+ $file = fopen("$absolute/.htaccess", "r+");
+ $lignes = array(1, 1, 1);
+ $errr = 0;
+ if (!$file) {
+ return false;
+ }
+ while (!feof($file) && !$errr) {
+ $s = fgets($file, 1024);
+ if (substr($s, 0, 12) != "RewriteCond " && substr($s, 0, 14) != "ErrorDocument " && substr($s, 0, 12) != "RewriteRule " && substr($s, 0, 14) != "RewriteEngine " && trim($s) != "") {
+ $errr = 1;
+ }
+ if (strtolower(trim($s)) == strtolower("authuserfile $absolute/.htpasswd")) {
+ $lignes[0] = 0;
+ $errr = 0;
+ } // authuserfile
+ if (strtolower(trim($s)) == "require valid-user") {
+ $lignes[1] = 0;
+ $errr = 0;
+ } //require
+ if (strtolower(trim($s)) == "authtype basic") {
+ $lignes[2] = 0;
+ $errr = 0;
+ } //authtype
+ } // Reading config file
+ fclose($file);
+ if ($errr || in_array(0, $lignes)) {
+ $err->raise("hta", _("An incompatible .htaccess file exists in this folder"));
+ return false;
+ }
+ return true;
}
- while (!feof($file) && !$errr) {
- $s = fgets($file,1024);
- if (substr($s,0,12)!="RewriteCond " && substr($s,0,14)!="ErrorDocument " && substr($s,0,12)!="RewriteRule " && substr($s,0,14)!="RewriteEngine " && trim($s)!="") {
- $errr = 1;
- }
- if (strtolower(trim($s))==strtolower("authuserfile $absolute/.htpasswd")) {
- $lignes[0] = 0;
- $errr = 0;
- } // authuserfile
- if (strtolower(trim($s))=="require valid-user") {
- $lignes[1] = 0;
- $errr = 0;
- } //require
- if (strtolower(trim($s))=="authtype basic") {
- $lignes[2] = 0;
- $errr = 0;
- } //authtype
- } // Reading config file
- fclose($file);
- if ($errr || in_array(0,$lignes)) {
- $err->raise("hta",_("An incompatible .htaccess file exists in this folder"));
- return false;
- }
- return true;
- }
-
-} /* CLASS m_hta */
+}
+/* CLASS m_hta */
diff --git a/bureau/class/m_log.php b/bureau/class/m_log.php
index 6c2bedaa..eabe4ad0 100644
--- a/bureau/class/m_log.php
+++ b/bureau/class/m_log.php
@@ -1,4 +1,5 @@
log("log","list_logs_directory");
-
- $c=array();
- foreach( glob("${dir}/*log*") as $absfile) {
- $c[]=array("name"=>basename($absfile),
- "creation_date"=>date("F d Y H:i:s", filectime($absfile)),
- "mtime" => filemtime($absfile),
- "filesize"=>filesize($absfile),
- "downlink"=>urlencode(basename($absfile)),
- );
+ function m_log() {
+
}
- usort($c,"m_log::compare_logtime");
- return $c;
- }//list_logs
+ function list_logs_directory($dir) {
+ global $cuid, $err;
+ $err->log("log", "list_logs_directory");
- // Used by list_logs_directory to sort
- private function compare_logname($a, $b) {
- return strcmp($a['name'],$b['name']);
- }
-
- // Used by list_logs_directory to sort
- private function compare_logtime($a, $b) {
- return $b['mtime']-$a['mtime'];
- }
-
-
- function hook_menu() {
- $obj = array(
- 'title' => _("Logs"),
- 'ico' => 'images/logs.png',
- 'link' => 'logs_list.php',
- 'pos' => 130,
- ) ;
-
- return $obj;
- }
-
- function list_logs_directory_all($dirs){
- global $err;
- $err->log("log","get_logs_directory_all");
- $c=array();
- foreach($dirs as $dir=>$val){
- $c[$dir]=$this->list_logs_directory($val);
+ $c = array();
+ foreach (glob("${dir}/*log*") as $absfile) {
+ $c[] = array("name" => basename($absfile),
+ "creation_date" => date("F d Y H:i:s", filectime($absfile)),
+ "mtime" => filemtime($absfile),
+ "filesize" => filesize($absfile),
+ "downlink" => urlencode(basename($absfile)),
+ );
+ }
+ usort($c, "m_log::compare_logtime");
+ return $c;
}
- return $c;
- }
-
- function get_logs_directory(){
- global $cuid,$mem,$err;
- $err->log("log","get_logs_directory");
- // Return an array to allow multiple directory in the future
- if(defined('ALTERNC_LOGS_ARCHIVE')){
- $c=array("dir"=>ALTERNC_LOGS_ARCHIVE."/".$cuid."-".$mem->user["login"]);
- }else{
- $c=array("dir"=>ALTERNC_LOGS."/".$cuid."-".$mem->user["login"]);
+ // Used by list_logs_directory to sort
+ private function compare_logname($a, $b) {
+ return strcmp($a['name'], $b['name']);
}
- return $c;
- }
-
- function download_link($file){
- global $err,$mem;
- $err->log("log","download_link");
- header("Content-Disposition: attachment; filename=".$file."");
- header("Content-Type: application/force-download");
- header("Content-Transfer-Encoding: binary");
- $f=$this->get_logs_directory();
- $ff=$f['dir']."/".basename($file);
- set_time_limit(0);
- readfile($ff);
- }
- function tail($file,$lines=20) {
- global $err,$mem;
- $err->log("log","tail");
- $lines=intval($lines); if ($lines<=0) $lines=20;
- $f=$this->get_logs_directory();
- $ff=$f['dir']."/".basename($file);
- unset($out);
- exec("tail -".$lines." ".escapeshellarg($ff),$out);
- return implode("\n",$out);
- }
+ // Used by list_logs_directory to sort
+ private function compare_logtime($a, $b) {
+ return $b['mtime'] - $a['mtime'];
+ }
+ function hook_menu() {
+ $obj = array(
+ 'title' => _("Logs"),
+ 'ico' => 'images/logs.png',
+ 'link' => 'logs_list.php',
+ 'pos' => 130,
+ );
-} // end class
+ return $obj;
+ }
+ function list_logs_directory_all($dirs) {
+ global $err;
+ $err->log("log", "get_logs_directory_all");
+ $c = array();
+ foreach ($dirs as $dir => $val) {
+ $c[$dir] = $this->list_logs_directory($val);
+ }
+ return $c;
+ }
+
+ function get_logs_directory() {
+ global $cuid, $mem, $err;
+ $err->log("log", "get_logs_directory");
+ // Return an array to allow multiple directory in the future
+ if (defined('ALTERNC_LOGS_ARCHIVE')) {
+ $c = array("dir" => ALTERNC_LOGS_ARCHIVE . "/" . $cuid . "-" . $mem->user["login"]);
+ } else {
+ $c = array("dir" => ALTERNC_LOGS . "/" . $cuid . "-" . $mem->user["login"]);
+ }
+ return $c;
+ }
+
+ function download_link($file) {
+ global $err;
+ $err->log("log", "download_link");
+ header("Content-Disposition: attachment; filename=" . $file . "");
+ header("Content-Type: application/force-download");
+ header("Content-Transfer-Encoding: binary");
+ $f = $this->get_logs_directory();
+ $ff = $f['dir'] . "/" . basename($file);
+ set_time_limit(0);
+ readfile($ff);
+ }
+
+ function tail($file, $lines = 20) {
+ global $err;
+ $err->log("log", "tail");
+ $lines = intval($lines);
+ if ($lines <= 0) {
+ $lines = 20;
+ }
+ $f = $this->get_logs_directory();
+ $ff = $f['dir'] . "/" . basename($file);
+ $out=array();
+ exec("tail -" . $lines . " " . escapeshellarg($ff), $out);
+ return implode("\n", $out);
+ }
+
+}
+
+// end class
diff --git a/bureau/class/m_lxc.php b/bureau/class/m_lxc.php
index 8bba638c..89fb591c 100644
--- a/bureau/class/m_lxc.php
+++ b/bureau/class/m_lxc.php
@@ -1,197 +1,192 @@
IP = variable_get('lxc_ip', '', "IP address of the Alternc's LXC server. If empty, no LXC server.", array('desc'=>'IP address','type'=>'ip'));
- $this->PORT = variable_get('lxc_port', '6504', "Port of the Alternc's LXC server", array('desc'=>'Port','type'=>'integer'));
- $this->KEY = variable_get('lxc_key', '', "Shared key with the Alternc's LXC server", array('desc'=>'Shared key','type'=>'string'));
- $this->maxtime = variable_get('lxc_maxtime', '4', "How many hours do we allow to have a server before shutting it down", array('desc'=>'Max time','type'=>'integer'));
- }
-
-
- /**
- * HOOK: add the "Console Access" to AlternC's main menu
- */
- function hook_menu() {
- if ( empty($this->IP)) return ; // No menu if no server
-
- $obj = array(
- 'title' => _("Console access"),
- 'ico' => 'images/ssh.png',
- 'link' => 'vm.php',
- 'pos' => 95,
- ) ;
-
- return $obj;
- }
-
-
- /**
- * HOOK: remove VM history for AlternC account
- */
- function hook_admin_del_member() {
- global $db,$err,$cuid;
- $err->log("lxc","alternc_del_member");
- $db->query("DELETE FROM vm_history WHERE uid='$cuid'");
- return true;
- }
-
-
- /**
- * Send a message to a remote VM manager instance
- * $params are the parameters to send as serialized data
- * to the listening server.
- * Return the unserialized response data, if the message has been sent successfully
- * or FALSE if an error occurred. In that case $error[] is set.
- */
- private function sendMessage($params) {
- global $L_FQDN,$hooks;
- $fp = @fsockopen($this->IP, $this->PORT, $errno, $errstr, $this->TIMEOUT);
- if (!$fp) {
- $this->error[] = 'Unable to connect';
- return FALSE;
- }
- // Authenticate:
- $params['server']=$L_FQDN;
- $params['key']=$this->KEY;
- // MySQL Host for this user ?
- $moreparams=$hooks->invoke("lxc_params",array($params));
- foreach($moreparams as $p) {
- foreach($p as $k=>$v)
- $params[$k]=$v;
+ /**
+ * Constructor, initialize the class informations from AlternC's variables
+ */
+ function m_lxc() {
+ $this->IP = variable_get('lxc_ip', '', "IP address of the Alternc's LXC server. If empty, no LXC server.", array('desc' => 'IP address', 'type' => 'ip'));
+ $this->PORT = variable_get('lxc_port', '6504', "Port of the Alternc's LXC server", array('desc' => 'Port', 'type' => 'integer'));
+ $this->KEY = variable_get('lxc_key', '', "Shared key with the Alternc's LXC server", array('desc' => 'Shared key', 'type' => 'string'));
+ $this->maxtime = variable_get('lxc_maxtime', '4', "How many hours do we allow to have a server before shutting it down", array('desc' => 'Max time', 'type' => 'integer'));
}
- $msg = serialize($params);
- if (fwrite ($fp, $msg."\n") < 0) {
- $this->error[] = 'Unable to send data';
- return FALSE;
+ /**
+ * HOOK: add the "Console Access" to AlternC's main menu
+ */
+ function hook_menu() {
+ if (empty($this->IP))
+ return; // No menu if no server
+
+ $obj = array(
+ 'title' => _("Console access"),
+ 'ico' => 'images/ssh.png',
+ 'link' => 'vm.php',
+ 'pos' => 95,
+ );
+
+ return $obj;
}
- $resp = fgets($fp, 8192);
- fclose ($fp);
- $data = @unserialize($resp);
-
- if (isset($data['error']) && $data['error']>0) {
- $this->error[] = $data['msg'];
- return FALSE;
- } else {
- return $resp;
+ /**
+ * HOOK: remove VM history for AlternC account
+ */
+ function hook_admin_del_member() {
+ global $db, $err, $cuid;
+ $err->log("lxc", "alternc_del_member");
+ $db->query("DELETE FROM vm_history WHERE uid='$cuid'");
+ return true;
}
- }
+ /**
+ * Send a message to a remote VM manager instance
+ * $params are the parameters to send as serialized data
+ * to the listening server.
+ * Return the unserialized response data, if the message has been sent successfully
+ * or FALSE if an error occurred. In that case $error[] is set.
+ */
+ private function sendMessage($params) {
+ global $L_FQDN, $hooks;
+ $fp = @fsockopen($this->IP, $this->PORT, $errno, $errstr, $this->TIMEOUT);
+ if (!$fp) {
+ $this->error[] = 'Unable to connect';
+ return FALSE;
+ }
+ // Authenticate:
+ $params['server'] = $L_FQDN;
+ $params['key'] = $this->KEY;
+ // MySQL Host for this user ?
+ $moreparams = $hooks->invoke("lxc_params", array($params));
+ foreach ($moreparams as $p) {
+ foreach ($p as $k => $v) {
+ $params[$k] = $v;
+ }
+ }
- /**
- * START a Virtual Machine on the remote VM manager
- * for user $login having hashed password $pass and uid $uid
- */
- public function start($login = FALSE, $pass = FALSE, $uid = FALSE) {
- global $mem, $db, $err, $mysql;
+ $msg = serialize($params);
+ if (fwrite($fp, $msg . "\n") < 0) {
+ $this->error[] = 'Unable to send data';
+ return FALSE;
+ }
+ $resp = fgets($fp, 8192);
+ fclose($fp);
- if ($this->getvm() !== FALSE) {
- $err->raise('lxc', _('VM already started'));
- return FALSE;
+ $data = @unserialize($resp);
+
+ if (isset($data['error']) && $data['error'] > 0) {
+ $this->error[] = $data['msg'];
+ return FALSE;
+ } else {
+ return $resp;
+ }
}
- unset($this->error);
- $login = $login ? $login : $mem->user['login'];
- $pass = $pass ? $pass : $mem->user['pass'];
- $uid = $uid ? $uid : $mem->user['uid'];
+ /**
+ * START a Virtual Machine on the remote VM manager
+ * for user $login having hashed password $pass and uid $uid
+ */
+ public function start($login = FALSE, $pass = FALSE, $uid = FALSE) {
+ global $mem, $db, $err, $mysql;
- $msgg = array('action'=>'start', 'login'=>$login, 'pass' => $pass, 'uid'=> $uid);
- $msgg['mysql_host'] = $mysql->dbus->Host;
+ if ($this->getvm() !== FALSE) {
+ $err->raise('lxc', _('VM already started'));
+ return FALSE;
+ }
+ unset($this->error);
- $res = $this->sendMessage($msgg);
- if ($res === FALSE) {
- return $this->error;
- } else {
- $data = unserialize($res);
- $error = (int)$data['error'];
- $hostname = $data['hostname'];
- $msg = $data['msg'];
- $date_start = 'NOW()';
- $uid = $mem->user['uid'];
+ $login = $login ? $login : $mem->user['login'];
+ $pass = $pass ? $pass : $mem->user['pass'];
+ $uid = $uid ? $uid : $mem->user['uid'];
- if ($error != 0) {
- $err->raise('lxc', _($msg));
- return FALSE;
- }
- $db->query("INSERT INTO vm_history (ip,date_start,uid,serialized_object) VALUES ('$hostname', $date_start, '$uid', '$res')");
- return $res;
+ $msgg = array('action' => 'start', 'login' => $login, 'pass' => $pass, 'uid' => $uid);
+ $msgg['mysql_host'] = $mysql->dbus->Host;
+
+ $res = $this->sendMessage($msgg);
+ if ($res === FALSE) {
+ return $this->error;
+ } else {
+ $data = unserialize($res);
+ $error = (int) $data['error'];
+ $hostname = $data['hostname'];
+ $msg = $data['msg'];
+ $date_start = 'NOW()';
+ $uid = $mem->user['uid'];
+
+ if ($error != 0) {
+ $err->raise('lxc', _($msg));
+ return FALSE;
+ }
+ $db->query("INSERT INTO vm_history (ip,date_start,uid,serialized_object) VALUES ('$hostname', $date_start, '$uid', '$res')");
+ return $res;
+ }
}
- }
+ /**
+ *
+ */
+ public function getvm($login = FALSE) {
+ global $mem;
- /**
- *
- */
- public function getvm($login = FALSE) {
- global $db, $mem, $cuid;
+ $login = $login ? $login : $mem->user['login'];
+ $msgg = array('action' => 'get', 'login' => $login);
+ $res = $this->sendMessage($msgg);
+ if (!$res) {
+ return FALSE;
+ }
+ return unserialize($res);
+ }
- $login = $login ? $login : $mem->user['login'];
- $msgg = array('action'=>'get', 'login'=>$login);
- $res = $this->sendMessage($msgg);
- if (!$res) return FALSE;
- return unserialize($res);
- }
+ /**
+ * Stop the currently running VM
+ */
+ public function stop() {
+ $vm = $this->getvm();
+ if ($vm === FALSE) {
+ return FALSE;
+ }
+ if ($this->sendMessage(array('action' => 'stop', 'vm' => $vm['vm'])) === FALSE) {
+ return FALSE;
+ }
+ return TRUE;
+ }
+}
- /**
- * Stop the currently running VM
- */
- public function stop() {
- global $db, $mem;
- $vm = $this->getvm();
- if ($vm === FALSE)
- return FALSE;
-
- if ($this->sendMessage(array('action' => 'stop', 'vm' => $vm['vm'])) === FALSE)
- return FALSE;
- return TRUE;
- }
-
-
-
-} // class m_lxc
+// class m_lxc
diff --git a/bureau/class/m_mail.php b/bureau/class/m_mail.php
index cfc4e47d..250f23aa 100644
--- a/bureau/class/m_mail.php
+++ b/bureau/class/m_mail.php
@@ -1,4 +1,5 @@
invoke in the code.
-*/
+ * This class handle emails (pop and/or aliases and even wrapper for internal
+ * classes) of hosted users.
+ *
+ * @copyright AlternC-Team 2012-09-01 http://alternc.com/
+ * This class is directly using the following alternc MySQL tables:
+ * address = any used email address will be defined here, mailbox = pop/imap mailboxes, recipient = redirection from an email to another
+ * and indirectly the domain class, to know domain names from their id in the DB.
+ * This class is also defining a few hooks, search ->invoke in the code.
+ */
class m_mail {
+ /* ----------------------------------------------------------------- */
+ /** domain list for this account
+ * @access private
+ */
+ var $domains;
- /* ----------------------------------------------------------------- */
- /** domain list for this account
- * @access private
- */
- var $domains;
+ /* ----------------------------------------------------------------- */
+ /** If an email has those chars, 'not nice in shell env' ;)
+ * we don't store the email in $mail/u/{user}_domain, but in $mail/_/{address_id}_domain
+ * @access private
+ */
+ var $specialchars = array('"', "'", '\\', '/');
- /* ----------------------------------------------------------------- */
- /** If an email has those chars, 'not nice in shell env' ;)
- * we don't store the email in $mail/u/{user}_domain, but in $mail/_/{address_id}_domain
- * @access private
- */
- var $specialchars=array('"',"'",'\\','/');
+ /* ----------------------------------------------------------------- */
+ /** If an email has those chars, we will ONLY allow RECIPIENTS, NOT POP/IMAP for DOVECOT !
+ * Since Dovecot doesn't allow those characters
+ * @access private
+ */
+ var $forbiddenchars = array('"', "'", '\\', '/', '?', '!', '*', '$', '|', '#', '+');
- /* ----------------------------------------------------------------- */
- /** If an email has those chars, we will ONLY allow RECIPIENTS, NOT POP/IMAP for DOVECOT !
- * Since Dovecot doesn't allow those characters
- * @access private
- */
- var $forbiddenchars=array('"',"'",'\\','/','?','!','*','$','|','#','+');
+ /* ----------------------------------------------------------------- */
+ /** Number of results for a pager display
+ * @access public
+ */
+ var $total;
+ // Human server name for help
+ var $srv_submission;
+ var $srv_smtp;
+ var $srv_smtps;
+ var $srv_imap;
+ var $srv_imaps;
+ var $srv_pop3;
+ var $srv_pop3s;
+ var $cache_domain_mail_size = array();
+ var $enum_domains = array();
- /* ----------------------------------------------------------------- */
- /** Number of results for a pager display
- * @access public
- */
- var $total;
+ /* ----------------------------------------------------------------- */
-
- // Human server name for help
- var $srv_submission;
- var $srv_smtp;
- var $srv_smtps;
- var $srv_imap;
- var $srv_imaps;
- var $srv_pop3;
- var $srv_pop3s;
-
- var $cache_domain_mail_size = array();
- var $enum_domains=array();
- /* ----------------------------------------------------------------- */
- /**
- * Constructeur
- */
- function m_mail() {
- global $L_FQDN;
- $this->srv_submission = variable_get('mail_human_submission', $L_FQDN,'Human name for mail server (submission protocol), leave empty to disable help', array('desc'=>'Name','type'=>'string'));
- $this->srv_smtp = variable_get('mail_human_smtp', $L_FQDN,'Human name for mail server (SMTP protocol), leave empty to disable help', array('desc'=>'Name','type'=>'string'));
- $this->srv_smtps = variable_get('mail_human_smtps', $L_FQDN,'Human name for mail server (SMTPS protocol), leave empty to disable help', array('desc'=>'Name','type'=>'string'));
- $this->srv_imap = variable_get('mail_human_imap', $L_FQDN,'Human name for IMAP mail server', array('desc'=>'Name','type'=>'string'));
- $this->srv_imaps = variable_get('mail_human_imaps', $L_FQDN,'Human name for IMAPS mail server', array('desc'=>'Name','type'=>'string'));
- $this->srv_pop3 = variable_get('mail_human_pop3', $L_FQDN,'Human name for POP3 mail server', array('desc'=>'Name','type'=>'string'));
- $this->srv_pop3s = variable_get('mail_human_pop3s', $L_FQDN,'Human name for POP3s mail server', array('desc'=>'Name','type'=>'string'));
- }
-
- function hook_menu() {
- $obj = array(
- 'title' => _("Email Addresses"),
- 'ico' => 'images/mail.png',
- 'link' => 'toggle',
- 'pos' => 30,
- 'links' => array(),
- ) ;
-
- foreach ($this->enum_domains() as $d) {
- $obj['links'][] =
- array (
- 'txt' => htmlentities($d["domaine"]).' '.htmlentities("(".$d["nb_mail"].")"),
- 'url' => "mail_list.php?domain_id=".urlencode($d['id']),
- );
- }
-
- return $obj;
- }
-
- function get_total_size_for_domain($domain) {
- global $db;
- if (empty($this->cache_domain_mail_size)) {
- $db->query("SELECT SUBSTRING_INDEX(user,'@', -1) as domain, SUM(quota_dovecot) AS sum FROM dovecot_view group by domain ;");
- while ($db->next_record() ) {
- $dd = $db->f('domain');
- $this->cache_domain_mail_size[ $dd ] = $db->f('sum');
- }
- }
- if ( isset( $this->cache_domain_mail_size[$domain]) ) return $this->cache_domain_mail_size[$domain];
- return 0;
- }
-
- // FIXME documenter
-
- /**
- * @param string $domain_id
- */
- function catchall_getinfos($domain_id) {
- global $dom, $db;
- $rr=array(
- 'mail_id'=>'',
- 'domain' =>$dom->get_domain_byid($domain_id),
- 'target' => '',
- 'type' => '',
- );
-
- $db->query("select r.recipients as dst, a.id mail_id from address a, recipient r where a.domain_id = $domain_id and r.address_id = a.id and a.address='';");
- if ($db->next_record()) {
- $rr['target'] = $db->f('dst');
- $rr['mail_id'] = $db->f('mail_id');
+ /**
+ * Constructeur
+ */
+ function m_mail() {
+ global $L_FQDN;
+ $this->srv_submission = variable_get('mail_human_submission', $L_FQDN, 'Human name for mail server (submission protocol), leave empty to disable help', array('desc' => 'Name', 'type' => 'string'));
+ $this->srv_smtp = variable_get('mail_human_smtp', $L_FQDN, 'Human name for mail server (SMTP protocol), leave empty to disable help', array('desc' => 'Name', 'type' => 'string'));
+ $this->srv_smtps = variable_get('mail_human_smtps', $L_FQDN, 'Human name for mail server (SMTPS protocol), leave empty to disable help', array('desc' => 'Name', 'type' => 'string'));
+ $this->srv_imap = variable_get('mail_human_imap', $L_FQDN, 'Human name for IMAP mail server', array('desc' => 'Name', 'type' => 'string'));
+ $this->srv_imaps = variable_get('mail_human_imaps', $L_FQDN, 'Human name for IMAPS mail server', array('desc' => 'Name', 'type' => 'string'));
+ $this->srv_pop3 = variable_get('mail_human_pop3', $L_FQDN, 'Human name for POP3 mail server', array('desc' => 'Name', 'type' => 'string'));
+ $this->srv_pop3s = variable_get('mail_human_pop3s', $L_FQDN, 'Human name for POP3s mail server', array('desc' => 'Name', 'type' => 'string'));
}
- // Does it redirect to a specific mail or to a domain
- if (empty($rr['target'])) {
- $rr['type']='none';
- } elseif (substr($rr['target'],0,1)=='@') {
- $rr['type']='domain';
- } else {
- $rr['type']='mail';
+ function hook_menu() {
+ $obj = array(
+ 'title' => _("Email Addresses"),
+ 'ico' => 'images/mail.png',
+ 'link' => 'toggle',
+ 'pos' => 30,
+ 'links' => array(),
+ );
+
+ foreach ($this->enum_domains() as $d) {
+ $obj['links'][] = array(
+ 'txt' => htmlentities($d["domaine"]) . ' ' . htmlentities("(" . $d["nb_mail"] . ")"),
+ 'url' => "mail_list.php?domain_id=" . urlencode($d['id']),
+ );
+ }
+
+ return $obj;
}
-
- return $rr;
- }
- /**
- * @param string $domain_id
- */
- function catchall_del($domain_id) {
- $catch = $this->catchall_getinfos($domain_id);
- if (empty($catch['mail_id'])) return false;
- return $this->delete($catch['mail_id']);
- }
-
- /**
- * @param string $domain_id
- * @param string $target
- */
- function catchall_set($domain_id, $target) {
- global $err;
- // target :
- $target=rtrim($target);
- if ( substr_count($target,'@') == 0 ) { // Pas de @
- $target = '@'.$target;
- }
-
- if ( substr($target,0,1) == '@' ) { // le premier caractere est un @
- // FIXME validate domain
- } else { // ca doit être un mail
- if (!filter_var($target,FILTER_VALIDATE_EMAIL)) {
- $err->raise("mail",_("The email you entered is syntaxically incorrect"));
- return false;
- }
+ function get_total_size_for_domain($domain) {
+ global $db;
+ if (empty($this->cache_domain_mail_size)) {
+ $db->query("SELECT SUBSTRING_INDEX(user,'@', -1) as domain, SUM(quota_dovecot) AS sum FROM dovecot_view group by domain ;");
+ while ($db->next_record()) {
+ $dd = $db->f('domain');
+ $this->cache_domain_mail_size[$dd] = $db->f('sum');
+ }
+ }
+ if (isset($this->cache_domain_mail_size[$domain])) {
+ return $this->cache_domain_mail_size[$domain];
+ }
+ return 0;
}
- $this->catchall_del($domain_id);
- $err->error="";
- return $this->create_alias($domain_id, '', $target, "catchall", true);
- }
+ // FIXME documenter
- /* ----------------------------------------------------------------- */
- /** get_quota (hook for quota class), returns the number of used
- * service for a quota-bound service
- * @param $name string the named quota we want
- * @return the number of used service for the specified quota,
- * or false if I'm not the one for the named quota
- */
- function hook_quota_get() {
- global $db,$err,$cuid;
- $err->log("mail","getquota");
- $q=Array("name"=>"mail", "description"=>_("Email addresses"), "used"=>0);
- $db->query("SELECT COUNT(*) AS cnt FROM address a, domaines d WHERE a.domain_id=d.id AND d.compte=$cuid AND a.type='';");
- if ($db->next_record()) {
- $q['used']=$db->f("cnt");
+ /**
+ * @param string $domain_id
+ */
+ function catchall_getinfos($domain_id) {
+ global $dom, $db;
+ $rr = array(
+ 'mail_id' => '',
+ 'domain' => $dom->get_domain_byid($domain_id),
+ 'target' => '',
+ 'type' => '',
+ );
+
+ $db->query("select r.recipients as dst, a.id mail_id from address a, recipient r where a.domain_id = $domain_id and r.address_id = a.id and a.address='';");
+ if ($db->next_record()) {
+ $rr['target'] = $db->f('dst');
+ $rr['mail_id'] = $db->f('mail_id');
+ }
+
+ // Does it redirect to a specific mail or to a domain
+ if (empty($rr['target'])) {
+ $rr['type'] = 'none';
+ } elseif (substr($rr['target'], 0, 1) == '@') {
+ $rr['type'] = 'domain';
+ } else {
+ $rr['type'] = 'mail';
+ }
+
+ return $rr;
}
- return $q;
- }
+ /**
+ * @param string $domain_id
+ */
+ function catchall_del($domain_id) {
+ $catch = $this->catchall_getinfos($domain_id);
+ if (empty($catch['mail_id'])) {
+ return false;
+ }
+ return $this->delete($catch['mail_id']);
+ }
- /* ----------------------------------------------------------------- */
- /** Password policy kind used in this class (hook for admin class)
- * @return array an array of policykey => "policy name (for humans)"
- */
- function alternc_password_policy() {
- return array("pop"=>_("Email account password"));
- }
+ /**
+ * @param string $domain_id
+ * @param string $target
+ */
+ function catchall_set($domain_id, $target) {
+ global $err;
+ $target = rtrim($target);
+ if (substr_count($target, '@') == 0) { // Pas de @
+ $target = '@' . $target;
+ }
+ if (substr($target, 0, 1) == '@') { // le premier caractere est un @
+ // FIXME validate domain
+ } else { // ca doit être un mail
+ if (!filter_var($target, FILTER_VALIDATE_EMAIL)) {
+ $err->raise("mail", _("The email you entered is syntaxically incorrect"));
+ return false;
+ }
+ }
+ $this->catchall_del($domain_id);
+ $err->error = "";
+ return $this->create_alias($domain_id, '', $target, "catchall", true);
+ }
- /* ----------------------------------------------------------------- */
- /** Returns the list of mail-hosting domains for a user
- * @return array indexed array of hosted domains
- */
- function enum_domains($uid=-1) {
- global $db,$err,$cuid;
- $err->log("mail","enum_domains");
- if ($uid == -1) { $uid = $cuid; }
- $db->query("
+ /* ----------------------------------------------------------------- */
+
+ /** get_quota (hook for quota class), returns the number of used
+ * service for a quota-bound service
+ * @param $name string the named quota we want
+ * @return the number of used service for the specified quota,
+ * or false if I'm not the one for the named quota
+ */
+ function hook_quota_get() {
+ global $db, $err, $cuid;
+ $err->log("mail", "getquota");
+ $q = Array("name" => "mail", "description" => _("Email addresses"), "used" => 0);
+ $db->query("SELECT COUNT(*) AS cnt FROM address a, domaines d WHERE a.domain_id=d.id AND d.compte=$cuid AND a.type='';");
+ if ($db->next_record()) {
+ $q['used'] = $db->f("cnt");
+ }
+ return $q;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Password policy kind used in this class (hook for admin class)
+ * @return array an array of policykey => "policy name (for humans)"
+ */
+ function alternc_password_policy() {
+ return array("pop" => _("Email account password"));
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Returns the list of mail-hosting domains for a user
+ * @return array indexed array of hosted domains
+ */
+ function enum_domains($uid = -1) {
+ global $db, $err, $cuid;
+ $err->log("mail", "enum_domains");
+ if ($uid == -1) {
+ $uid = $cuid;
+ }
+ $db->query("
SELECT
d.id,
d.domaine,
@@ -244,793 +247,832 @@ ORDER BY
d.domaine
;
");
- $this->enum_domains=array();
- while($db->next_record()){
- $this->enum_domains[]=$db->Record;
- }
- return $this->enum_domains;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** available: tells if an email address can be installed in the server
- * check the domain part (is it mine too), the syntax, and the availability.
- * @param $mail string email to check
- * @return boolean true if the email can be installed on the server
- */
- function available($mail){
- global $db,$err,$dom;
- $err->log("mail","available");
- list($login,$domain)=explode("@",$mail,2);
- // Validate the domain ownership & syntax
- if (!($dom_id=$dom->get_domain_byname($domain))) {
- return false;
+ $this->enum_domains = array();
+ while ($db->next_record()) {
+ $this->enum_domains[] = $db->Record;
+ }
+ return $this->enum_domains;
}
- // Validate the email syntax:
- if (!filter_var($mail,FILTER_VALIDATE_EMAIL)) {
- $err->raise("mail",_("The email you entered is syntaxically incorrect"));
- return false;
+
+ /* ----------------------------------------------------------------- */
+
+ /** available: tells if an email address can be installed in the server
+ * check the domain part (is it mine too), the syntax, and the availability.
+ * @param $mail string email to check
+ * @return boolean true if the email can be installed on the server
+ */
+ function available($mail) {
+ global $db, $err, $dom;
+ $err->log("mail", "available");
+ list($login, $domain) = explode("@", $mail, 2);
+ // Validate the domain ownership & syntax
+ if (!($dom_id = $dom->get_domain_byname($domain))) {
+ return false;
+ }
+ // Validate the email syntax:
+ if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
+ $err->raise("mail", _("The email you entered is syntaxically incorrect"));
+ return false;
+ }
+ // Check the availability
+ $db->query("SELECT a.id FROM address a WHERE a.domain_id=" . $dom_id . " AND a.address='" . addslashes($login) . "';");
+ if ($db->next_record()) {
+ return false;
+ } else {
+ return true;
+ }
}
- // Check the availability
- $db->query("SELECT a.id FROM address a WHERE a.domain_id=".$dom_id." AND a.address='".addslashes($login)."';");
- if ($db->next_record()) {
- return false;
- } else {
- return true;
- }
- }
+ /* ----------------------------------------------------------------- */
+ /* function used to list every mail address hosted on a domain.
+ * @param $dom_id integer the domain id.
+ * @param $search string search that string in recipients or address.
+ * @param $offset integer skip THAT much emails in the result.
+ * @param $count integer return no more than THAT much emails. -1 for ALL. Offset is ignored then.
+ * @result an array of each mail hosted under the domain.
+ */
- /* ----------------------------------------------------------------- */
- /* function used to list every mail address hosted on a domain.
- * @param $dom_id integer the domain id.
- * @param $search string search that string in recipients or address.
- * @param $offset integer skip THAT much emails in the result.
- * @param $count integer return no more than THAT much emails. -1 for ALL. Offset is ignored then.
- * @result an array of each mail hosted under the domain.
- */
- function enum_domain_mails($dom_id = null, $search="", $offset=0, $count=30, $show_systemmails=false){
- global $db,$err,$cuid,$hooks;
- $err->log("mail","enum_domains_mail");
+ function enum_domain_mails($dom_id = null, $search = "", $offset = 0, $count = 30, $show_systemmails = false) {
+ global $db, $err, $hooks;
+ $err->log("mail", "enum_domains_mail");
- $search=trim($search);
+ $search = trim($search);
- $where="a.domain_id=$dom_id";
- if ($search) $where.=" AND (a.address LIKE '%".addslashes($search)."%' OR r.recipients LIKE '%".addslashes($search)."%')";
- if (!$show_systemmails) $where.=" AND type='' ";
- $db->query("SELECT count(a.id) AS total FROM address a LEFT JOIN recipient r ON r.address_id=a.id WHERE $where;");
- $db->next_record();
- $this->total=$db->f("total");
- if ($count!=-1) $limit="LIMIT $offset,$count"; else $limit="";
- $db->query("SELECT a.id, a.address, a.password, a.`enabled`, a.mail_action, d.domaine AS domain, m.quota, m.quota*1024*1024 AS quotabytes, m.bytes AS used, NOT ISNULL(m.id) AS islocal, a.type, r.recipients, m.lastlogin, a.domain_id
+ $where = "a.domain_id=$dom_id";
+ if ($search) {
+ $where.=" AND (a.address LIKE '%" . addslashes($search) . "%' OR r.recipients LIKE '%" . addslashes($search) . "%')";
+ }
+ if (!$show_systemmails) {
+ $where.=" AND type='' ";
+ }
+ $db->query("SELECT count(a.id) AS total FROM address a LEFT JOIN recipient r ON r.address_id=a.id WHERE $where;");
+ $db->next_record();
+ $this->total = $db->f("total");
+ if ($count != -1) {
+ $limit = "LIMIT $offset,$count";
+ } else {
+ $limit = "";
+ }
+ $db->query("SELECT a.id, a.address, a.password, a.`enabled`, a.mail_action, d.domaine AS domain, m.quota, m.quota*1024*1024 AS quotabytes, m.bytes AS used, NOT ISNULL(m.id) AS islocal, a.type, r.recipients, m.lastlogin, a.domain_id
FROM (address a LEFT JOIN mailbox m ON m.address_id=a.id) LEFT JOIN recipient r ON r.address_id=a.id, domaines d
WHERE $where AND d.id=a.domain_id $limit ;");
- if (! $db->next_record()) {
- $err->raise("mail",_("No email found for this query"));
- return array();
- }
- $res=array();
- do {
- $details=$db->Record;
- // if necessary, fill the typedata with data from hooks ...
- if ($details["type"]) {
- $result=$hooks->invoke("hook_mail_get_details",array($details)); // Will fill typedata if necessary
- $details["typedata"]=implode("
",$result);
- }
- $res[]=$details;
- } while ($db->next_record());
- return $res;
- }
-
-
- function hook_mail_get_details($detail) {
- if ($detail['type']=='catchall') return _(sprintf("Special mail address for catch-all. Click here to manage it.",$detail['domain_id']));
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Function used to insert a new mail into the db
- * should be used by the web interface, not by third-party programs.
- *
- * This function calls the hook "hooks_mail_cancreate"
- * which must return FALSE if the user can't create this email, and raise and error accordingly
- *
- * @param $dom_id integer A domain_id (owned by the user)
- * (will be the part at the right of the @ in the email)
- * @param $mail string the left part of the email to create (something@dom_id)
- * @return an hashtable containing the database id of the newly created mail,
- * or false if an error occured ($err is filled accordingly)
- */
- function create($dom_id, $mail,$type="",$dontcheck=false){
- global $err,$db,$cuid,$quota,$dom,$hooks;
- $err->log("mail","create",$mail);
-
- // Validate the domain id
- if (!($domain=$dom->get_domain_byid($dom_id))) {
- return false;
- }
-
- // Validate the email syntax:
- $m=$mail."@".$domain;
- if (!filter_var($m,FILTER_VALIDATE_EMAIL) && !$dontcheck) {
- $err->raise("mail",_("The email you entered is syntaxically incorrect"));
- return false;
- }
-
- // Call other classes to check we can create it:
- $cancreate=$hooks->invoke("hook_mail_cancreate",array($dom_id,$mail));
- if (in_array(false,$cancreate,true)) {
- return false;
- }
-
- // Check the quota:
- if (!$quota->cancreate("mail")) {
- $err->raise("mail",_("You cannot create email addresses: your quota is over"));
- return false;
- }
- // Already exists?
- $db->query("SELECT * FROM address WHERE domain_id=".$dom_id." AND address='".addslashes($mail)."';");
- if ($db->next_record()) {
- $err->raise("mail",_("This email address already exists"));
- return false;
- }
- // Create it now
- $db->query("INSERT INTO address (domain_id, address,type) VALUES ($dom_id, '".addslashes($mail)."','$type');");
- if (!($id=$db->lastid())) {
- $err->raise("mail",_("An unexpected error occured when creating the email"));
- return false;
- }
- return $id;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** function used to get every information we can on a mail
- * @param $mail_id integer
- * @return array a hashtable with all the informations for that email
- */
- function get_details($mail_id) {
- global $db, $err, $cuid, $hooks;
- $err->log("mail","get_details");
-
- $mail_id=intval($mail_id);
- // Validate that this email is owned by me...
- if (!($mail=$this->is_it_my_mail($mail_id))) {
- return false;
- }
-
- // We fetch all the informations for that email: these will fill the hastable :
- $db->query("SELECT a.id, a.address, a.password, a.enabled, d.domaine AS domain, m.path, m.quota, m.quota*1024*1024 AS quotabytes, m.bytes AS used, NOT ISNULL(m.id) AS islocal, a.type, r.recipients, m.lastlogin, a.mail_action, m.mail_action AS mailbox_action FROM (address a LEFT JOIN mailbox m ON m.address_id=a.id) LEFT JOIN recipient r ON r.address_id=a.id, domaines d WHERE a.id=".$mail_id." AND d.id=a.domain_id;");
- if (! $db->next_record()) return false;
- $details=$db->Record;
- // if necessary, fill the typedata with data from hooks ...
- if ($details["type"]) {
- $result=$hooks->invoke("hook_mail_get_details",array($mail_id)); // Will fill typedata if necessary
- $details["typedata"]=implode("
",$result);
- }
- return $details;
- }
-
-
- private $isitmy_cache=array();
-
- /* ----------------------------------------------------------------- */
- /** Check if an email is mine ...
- *
- * @param $mail_id integer the number of the email to check
- * @return string the complete email address if that's mine, false if not
- * ($err is filled accordingly)
- */
- function is_it_my_mail($mail_id){
- global $err,$db,$cuid;
- $mail_id=intval($mail_id);
- // cache it (may be called more than one time in the same page).
- if (isset($this->isitmy_cache[$mail_id])) return $this->isitmy_cache[$mail_id];
-
- $db->query("SELECT concat(a.address,'@',d.domaine) AS email FROM address a, domaines d WHERE d.id=a.domain_id AND a.id=$mail_id AND d.compte=$cuid;");
- if ($db->next_record()) {
- return $this->isitmy_cache[$mail_id]=$db->f("email");
- } else {
- $err->raise("mail",_("This email is not yours, you can't change anything on it"));
- return $this->isitmy_cache[$mail_id]=false;
- }
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Hook called when the DOMAIN class will delete a domain.
- *
- * @param $dom integer the number of the email to delete
- * @return boolean if the email has been properly deleted
- * or false if an error occured ($err is filled accordingly)
- */
- function hook_dom_del_mx_domain($dom_id) {
- global $db;
- $list=$this->enum_domain_mails($dom_id,"",0,-1);
- if (is_array($list)) {
- foreach($list as $one) {
- $this->delete($one["id"]);
- }
- }
- $db->query("SELECT domaine FROM domaines WHERE id=$domain_id;");
- if ($db->next_record()) {
- $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine='".addslashes($db->Record["domaine"])."' AND type='txt' AND (sub='' AND valeur LIKE 'v=spf1 %') OR (sub='_dmarc' AND valeur LIKE 'v=dmarc1;%');");
- $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE id=$domain_id;");
- }
-
- return true;
- }
-
- // return the alternc account's ID of the mail_id
- function get_account_by_mail_id($mail_id) {
- global $db,$err;
- $db->query("select compte as uid from domaines d, address a where a.domain_id = d.id and a.id = $mail_id");
- if ( !$db->next_record()) {
- return false;
- }
- return $db->f('uid');
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Function used to delete a mail from the db
- * should be used by the web interface, not by third-party programs.
- *
- * @param $mail_id integer the number of the email to delete
- * @return boolean if the email has been properly deleted
- * or false if an error occured ($err is filled accordingly)
- */
- function delete($mail_id){
- global $err,$db,$cuid,$quota,$dom,$hooks;
- $err->log("mail","delete");
-
- $mail_id=intval($mail_id);
-
- if (!$mail_id) {
- $err->raise("mail",_("The email you entered is syntaxically incorrect"));
- return false;
- }
- // Validate that this email is owned by me...
- if (!($mail=$this->is_it_my_mail($mail_id))) {
- return false;
- }
-
- $mailinfos=$this->get_details($mail_id);
- $hooks->invoke('hook_mail_delete', array($mail_id, $mailinfos['address'].'@'.$mailinfos['domain'] ));
-
- // Search for that address:
- $db->query("SELECT a.id, a.type, a.mail_action, m.mail_action AS mailbox_action, NOT ISNULL(m.id) AS islocal FROM address a LEFT JOIN mailbox m ON m.address_id=a.id WHERE a.id='$mail_id';");
- if (!$db->next_record()) {
- $err->raise("mail",_("The email %s does not exist, it can't be deleted"),$mail);
- return false;
- }
- if ($db->f("mail_action")!="OK" || ($db->f("islocal") && $db->f("mailbox_action")!="OK")) { // will be deleted soon ...
- $err->raise("mail",_("The email %s is already marked for deletion, it can't be deleted"),$mail);
- return false;
- }
- $mail_id=$db->f("id");
-
- if ($db->f("islocal")) {
- // If it's a pop/imap mailbox, mark it for deletion
- $db->query("UPDATE address SET mail_action='DELETE', enabled=0 WHERE id='$mail_id';");
- $db->query("UPDATE mailbox SET mail_action='DELETE' WHERE address_id='$mail_id';");
- $err->raise("mail",_("The email %s has been marked for deletion"),$mail);
- } else {
- // If it's only aliases, delete it NOW.
- $db->query("DELETE FROM address WHERE id='$mail_id';");
- $db->query("DELETE FROM mailbox WHERE address_id='$mail_id';");
- $db->query("DELETE FROM recipient WHERE address_id='$mail_id';");
- $err->raise("mail",_("The email %s has been successfully deleted"),$mail);
- }
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Function used to undelete a pending deletion mail from the db
- * should be used by the web interface, not by third-party programs.
- *
- * @param $mail_id integer the email id
- * @return boolean if the email has been properly undeleted
- * or false if an error occured ($err is filled accordingly)
- */
- function undelete($mail_id){
- global $err,$db,$cuid,$quota,$dom,$hooks;
- $err->log("mail","undelete");
-
- $mail_id=intval($mail_id);
-
- if (!$mail_id) {
- $err->raise("mail",_("The email you entered is syntaxically incorrect"));
- return false;
- }
- // Validate that this email is owned by me...
- if (!($mail=$this->is_it_my_mail($mail_id))) {
- return false;
- }
-
- // Search for that address:
- $db->query("SELECT a.id, a.type, a.mail_action, m.mail_action AS mailbox_action, NOT ISNULL(m.id) AS islocal FROM address a LEFT JOIN mailbox m ON m.address_id=a.id WHERE a.id='$mail_id';");
- if (!$db->next_record()) {
- $err->raise("mail",_("The email %s does not exist, it can't be undeleted"),$mail);
- return false;
- }
- if ($db->f("type")!="") { // Technically special : mailman, sympa ...
- $err->raise("mail",_("The email %s is special, it can't be undeleted"),$mail);
- return false;
- }
- if ($db->f("mailbox_action")!="DELETE" || $db->f("mail_action")!="DELETE") { // will be deleted soon ...
- $err->raise("mail",_("Sorry, deletion of email %s is already in progress, or not marked for deletion, it can't be undeleted"),$mail);
- return false;
- }
- $mail_id=$db->f("id");
-
- if ($db->f("islocal")) {
- // If it's a pop/imap mailbox, mark it for deletion
- $db->query("UPDATE address SET mail_action='OK', `enabled`=1 WHERE id='$mail_id';");
- $db->query("UPDATE mailbox SET mail_action='OK' WHERE address_id='$mail_id';");
- $err->raise("mail",_("The email %s has been undeleted"),$mail);
- return true;
- } else {
- $err->raise("mail",_("-- Program Error -- The email %s can't be undeleted"),$mail);
- return false;
- }
- }
-
-
- /* ----------------------------------------------------------------- */
- /** set the password of an email address.
- * @param $mail_id integer email ID
- * @param $pass string the new password.
- * @return boolean true if the password has been set, false else, raise an error.
- */
- function set_passwd($mail_id,$pass){
- global $db,$err,$admin;
- $err->log("mail","setpasswd");
-
- if (!($email=$this->is_it_my_mail($mail_id))) return false;
- if (!$admin->checkPolicy("pop",$email,$pass)) return false;
- if (!$db->query("UPDATE address SET password='"._md5cr($pass)."' where id=$mail_id;")) return false;
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Enables an email address.
- * @param $mail_id integer Email ID
- * @return boolean true if the email has been enabled.
- */
- function enable($mail_id){
- global $db,$err;
- $err->log("mail","enable");
- if (!($email=$this->is_it_my_mail($mail_id))) return false;
- if (!$db->query("UPDATE address SET `enabled`=1 where id=$mail_id;")) return false;
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Disables an email address.
- * @param $mail_id integer Email ID
- * @return boolean true if the email has been enabled.
- */
- function disable($mail_id){
- global $db,$err;
- $err->log("mail","disable");
- if (!($email=$this->is_it_my_mail($mail_id))) return false;
- if (!$db->query("UPDATE address SET `enabled`=0 where id=$mail_id;")) return false;
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Function used to update an email settings
- * should be used by the web interface, not by third-party programs.
- *
- * @param $mail_id integer the number of the email to delete
- * @param integer $islocal boolean is it a POP/IMAP mailbox ?
- * @param integer $quotamb integer if islocal=1, quota in MB
- * @param string $recipients string recipients, one mail per line.
- * @return boolean if the email has been properly edited
- * or false if an error occured ($err is filled accordingly)
- */
- function set_details($mail_id, $islocal, $quotamb, $recipients,$delivery="dovecot",$dontcheck=false) {
- global $err,$db,$cuid,$quota,$dom,$hooks;
- $delivery=mysql_real_escape_string($delivery);
- $err->log("mail","set_details");
- if (!($me=$this->get_details($mail_id))) {
- return false;
- }
- if ($me["islocal"] && !$islocal) {
- // delete pop
- $db->query("UPDATE mailbox SET mail_action='DELETE' WHERE address_id=".$mail_id.";");
- }
- if (!$me["islocal"] && $islocal) {
- // create pop
- $path="";
- if($delivery=="dovecot"){
- $path=ALTERNC_MAIL."/".substr($me["address"]."_",0,1)."/".$me["address"]."_".$me["domain"];
- }
- foreach($this->forbiddenchars as $str) {
- if (strpos($me["address"],$str)!==false) {
- $err->raise("mail",_("There is forbidden characters in your email address. You can't make it a POP/IMAP account, you can only use it as redirection to other emails"));
- return false;
- break;
+ if (!$db->next_record()) {
+ $err->raise("mail", _("No email found for this query"));
+ return array();
}
- }
- foreach($this->specialchars as $str) {
- if (strpos($me["address"],$str)!==false) {
- $path=ALTERNC_MAIL."/_/".$me["id"]."_".$me["domain"];
- break;
- }
- }
- $db->query("INSERT INTO mailbox SET address_id=$mail_id, delivery='$delivery', path='".addslashes($path)."';");
- }
- if ($me["islocal"] && $islocal && $me["mailbox_action"]=="DELETE") {
- $db->query("UPDATE mailbox SET mail_action='OK' WHERE mail_action='DELETE' AND address_id=".$mail_id.";");
+ $res = array();
+ do {
+ $details = $db->Record;
+ // if necessary, fill the typedata with data from hooks ...
+ if ($details["type"]) {
+ $result = $hooks->invoke("hook_mail_get_details", array($details)); // Will fill typedata if necessary
+ $details["typedata"] = implode("
", $result);
+ }
+ $res[] = $details;
+ } while ($db->next_record());
+ return $res;
}
- if ($islocal) {
- if ($quotamb!=0 && $quotamb<(intval($me["used"]/1024/1024)+1)) {
- $quotamb=intval($me["used"]/1024/1024)+1;
- $err->raise("mail",_("You set a quota smaller than the current mailbox size. Since it's not allowed, we set the quota to the current mailbox size"));
- }
- $db->query("UPDATE mailbox SET quota=".intval($quotamb)." WHERE address_id=".$mail_id.";");
+ function hook_mail_get_details($detail) {
+ if ($detail['type'] == 'catchall') {
+ return _(sprintf("Special mail address for catch-all. Click here to manage it.", $detail['domain_id']));
+ }
}
- $recipients=preg_replace('/[\r\t\s]/', "\n", $recipients); // Handle space AND new line
- $r=explode("\n",$recipients);
- $red="";
- foreach($r as $m) {
- $m=trim($m);
- if ($m && ( filter_var($m,FILTER_VALIDATE_EMAIL) || $dontcheck) // Recipient Email is valid
- && $m!=($me["address"]."@".$me["domain"])) { // And not myself (no loop allowed easily ;) )
- $red.=$m."\n";
- }
+ /* ----------------------------------------------------------------- */
+
+ /** Function used to insert a new mail into the db
+ * should be used by the web interface, not by third-party programs.
+ *
+ * This function calls the hook "hooks_mail_cancreate"
+ * which must return FALSE if the user can't create this email, and raise and error accordingly
+ *
+ * @param $dom_id integer A domain_id (owned by the user)
+ * (will be the part at the right of the @ in the email)
+ * @param $mail string the left part of the email to create (something@dom_id)
+ * @return an hashtable containing the database id of the newly created mail,
+ * or false if an error occured ($err is filled accordingly)
+ */
+ function create($dom_id, $mail, $type = "", $dontcheck = false) {
+ global $err, $db, $quota, $dom, $hooks;
+ $err->log("mail", "create", $mail);
+
+ // Validate the domain id
+ if (!($domain = $dom->get_domain_byid($dom_id))) {
+ return false;
+ }
+
+ // Validate the email syntax:
+ $m = $mail . "@" . $domain;
+ if (!filter_var($m, FILTER_VALIDATE_EMAIL) && !$dontcheck) {
+ $err->raise("mail", _("The email you entered is syntaxically incorrect"));
+ return false;
+ }
+
+ // Call other classes to check we can create it:
+ $cancreate = $hooks->invoke("hook_mail_cancreate", array($dom_id, $mail));
+ if (in_array(false, $cancreate, true)) {
+ return false;
+ }
+
+ // Check the quota:
+ if (!$quota->cancreate("mail")) {
+ $err->raise("mail", _("You cannot create email addresses: your quota is over"));
+ return false;
+ }
+ // Already exists?
+ $db->query("SELECT * FROM address WHERE domain_id=" . $dom_id . " AND address='" . addslashes($mail) . "';");
+ if ($db->next_record()) {
+ $err->raise("mail", _("This email address already exists"));
+ return false;
+ }
+ // Create it now
+ $db->query("INSERT INTO address (domain_id, address,type) VALUES ($dom_id, '" . addslashes($mail) . "','$type');");
+ if (!($id = $db->lastid())) {
+ $err->raise("mail", _("An unexpected error occured when creating the email"));
+ return false;
+ }
+ return $id;
}
- $db->query("DELETE FROM recipient WHERE address_id=".$mail_id.";");
- if (isset($red) && $red) {
- $db->query("INSERT INTO recipient SET address_id=".$mail_id.", recipients='".addslashes($red)."';");
+
+ /* ----------------------------------------------------------------- */
+
+ /** function used to get every information we can on a mail
+ * @param $mail_id integer
+ * @return array a hashtable with all the informations for that email
+ */
+ function get_details($mail_id) {
+ global $db, $err, $hooks;
+ $err->log("mail", "get_details");
+
+ $mail_id = intval($mail_id);
+ // Validate that this email is owned by me...
+ if (!($mail = $this->is_it_my_mail($mail_id))) {
+ return false;
+ }
+
+ // We fetch all the informations for that email: these will fill the hastable :
+ $db->query("SELECT a.id, a.address, a.password, a.enabled, d.domaine AS domain, m.path, m.quota, m.quota*1024*1024 AS quotabytes, m.bytes AS used, NOT ISNULL(m.id) AS islocal, a.type, r.recipients, m.lastlogin, a.mail_action, m.mail_action AS mailbox_action FROM (address a LEFT JOIN mailbox m ON m.address_id=a.id) LEFT JOIN recipient r ON r.address_id=a.id, domaines d WHERE a.id=" . $mail_id . " AND d.id=a.domain_id;");
+ if (!$db->next_record()) {
+ return false;
+ }
+ $details = $db->Record;
+ // if necessary, fill the typedata with data from hooks ...
+ if ($details["type"]) {
+ $result = $hooks->invoke("hook_mail_get_details", array($mail_id)); // Will fill typedata if necessary
+ $details["typedata"] = implode("
", $result);
+ }
+ return $details;
}
- return true;
- }
- /* ----------------------------------------------------------------- */
- /** A wrapper used by mailman class to create it's needed addresses
- * @ param : $dom_id , the domain id associated to a given address
- * @ param : $m , the left part of the mail address being created
- * @ param : $delivery , the delivery used to deliver the mail
- */
+ private $isitmy_cache = array();
- function add_wrapper($dom_id,$m,$delivery){
- global $err,$db,$mail;
- $err->log("mail","add_wrapper","creating $delivery $m address");
+ /* ----------------------------------------------------------------- */
- $mail_id=$mail->create($dom_id,$m,$delivery);
- $this->set_details($mail_id,1,0,'',$delivery);
- // FIXME return error code
- }
-
- /* ----------------------------------------------------------------- */
- /** A function used to create an alias for a specific address
- * @ param : $dom_id , the domain sql identifier
- * @ param : $m , the alias we want to create
- * @ param : $alias , the already existing aliased address
- * @ param : $type, the type of the alias created
- * @param string $m
- * @param string $alias
- * @param string $dom_id
- */
- function create_alias($dom_id,$m,$alias,$type="",$dontcheck=false) {
- global $err,$db,$mail;
- $err->log("mail","create_alias","creating $m alias for $alias type $type");
-
- $mail_id=$mail->create($dom_id,$m,$type,$dontcheck);
- if (!$mail_id) return false;
- $this->set_details($mail_id,0,0,$alias,"dovecot",$dontcheck);
- return true;
- }
-
-
-
- /* ----------------------------------------------------------------- */
- /** A wrapper used by mailman class to create it's needed addresses
- * @ param : $mail_id , the mysql id of the mail address we want to delete
- * of the email for the current acccount.
- */
- function del_wrapper($mail_id){
- global $err,$db;
- $err->log("mail","del_wrapper");
- $this->delete($mail_id);
- }
-
- /* ----------------------------------------------------------------- */
- /** Export the mail information of an account
- * @return: str, string containing the complete configuration
- * of the email for the current acccount.
- */
- function alternc_export_conf() {
- global $db,$err,$mail_localbox;
- $err->log("mail","export");
- $domain=$this->enum_domains();
- $str="\n";
- foreach ($domain as $d) {
- $str.=" \n ".xml_entities($d["domain"])." \n";
- $s=$this->enum_domain_mails($d["id"]);
- if (count($s)) {
- while (list($key,$val)=each($s)){
- $str.=" \n";
- $str.=" ".xml_entities($val["address"])." \n";
- $str.=" ".xml_entities($val["enabled"])." \n";
- if(is_array($val["islocal"])){
- $str.=" 1 \n";
- $str.=" ".$val["quota"]." \n";
- $str.=" ".$val["path"]." \n";
- }else{
- $str.=" 0 \n";
- }
- if(!empty($val["recipients"])){
- $r=explode("\n",$val["recipients"]);
- foreach($r as $recip){
- $str.=" ".$recip."\n";
- }
- }
- $str.=" \n";
- }
- }
- $str.=" \n";
- }
- $str.=" \n";
- return $str;
- }
-
-
- /* ----------------------------------------------------------------- */
- /**
- * Return the list of allowed slave accounts (secondary-mx)
- * @return array
- */
- function enum_slave_account() {
- global $db,$err;
- $db->query("SELECT login,pass FROM mxaccount;");
- $res=array();
- while ($db->next_record()) {
- $res[]=$db->Record;
+ /** Check if an email is mine ...
+ *
+ * @param $mail_id integer the number of the email to check
+ * @return string the complete email address if that's mine, false if not
+ * ($err is filled accordingly)
+ */
+ function is_it_my_mail($mail_id) {
+ global $err, $db, $cuid;
+ $mail_id = intval($mail_id);
+ // cache it (may be called more than one time in the same page).
+ if (isset($this->isitmy_cache[$mail_id])) {
+ return $this->isitmy_cache[$mail_id];
+ }
+ $db->query("SELECT concat(a.address,'@',d.domaine) AS email FROM address a, domaines d WHERE d.id=a.domain_id AND a.id=$mail_id AND d.compte=$cuid;");
+ if ($db->next_record()) {
+ return $this->isitmy_cache[$mail_id] = $db->f("email");
+ } else {
+ $err->raise("mail", _("This email is not yours, you can't change anything on it"));
+ return $this->isitmy_cache[$mail_id] = false;
+ }
}
- if (!count($res)) return false;
- return $res;
- }
- /* ----------------------------------------------------------------- */
- /**
- * Check for a slave account (secondary mx)
- * @param string $login the login to check
- * @param string $pass the password to check
- * @return boolean TRUE if the password is correct, or FALSE if an error occurred.
- */
- function check_slave_account($login,$pass) {
- global $db,$err;
- $login=mysql_real_escape_string($login);
- $pass=mysql_real_escape_string($pass);
- $db->query("SELECT * FROM mxaccount WHERE login='$login' AND pass='$pass';");
- if ($db->next_record()) {
+ /* ----------------------------------------------------------------- */
+
+ /** Hook called when the DOMAIN class will delete a domain.
+ *
+ * @param $dom integer the number of the email to delete
+ * @return boolean if the email has been properly deleted
+ * or false if an error occured ($err is filled accordingly)
+ */
+ function hook_dom_del_mx_domain($dom_id) {
+ global $db;
+ $list = $this->enum_domain_mails($dom_id, "", 0, -1);
+ if (is_array($list)) {
+ foreach ($list as $one) {
+ $this->delete($one["id"]);
+ }
+ }
+ $db->query("SELECT domaine FROM domaines WHERE id=$domain_id;");
+ if ($db->next_record()) {
+ $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine='" . addslashes($db->Record["domaine"]) . "' AND type='txt' AND (sub='' AND valeur LIKE 'v=spf1 %') OR (sub='_dmarc' AND valeur LIKE 'v=dmarc1;%');");
+ $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE id=$domain_id;");
+ }
+
return true;
}
- return false;
- }
-
- /* ----------------------------------------------------------------- */
- /** Out (echo) the complete hosted domain list :
- */
- function echo_domain_list($format=null) {
- global $db,$err;
- $db->query("SELECT domaine FROM domaines WHERE gesmx=1 ORDER BY domaine");
- $lst=array();
- $tt="";
- while ($db->next_record()) {
- $lst[]=$db->f("domaine");
- $tt.=$db->f("domaine");
+ // return the alternc account's ID of the mail_id
+ function get_account_by_mail_id($mail_id) {
+ global $db;
+ $db->query("select compte as uid from domaines d, address a where a.domain_id = d.id and a.id = $mail_id");
+ if (!$db->next_record()) {
+ return false;
+ }
+ return $db->f('uid');
}
- # Generate an integrity check
- $obj=array('integrity'=>md5($tt),'items'=>$lst);
+ /* ----------------------------------------------------------------- */
- switch($format) {
- case "json":
- return json_encode($obj);
- break;
- default:
- foreach ($lst as $l) { echo $l."\n"; }
+ /** Function used to delete a mail from the db
+ * should be used by the web interface, not by third-party programs.
+ *
+ * @param $mail_id integer the number of the email to delete
+ * @return boolean if the email has been properly deleted
+ * or false if an error occured ($err is filled accordingly)
+ */
+ function delete($mail_id) {
+ global $err, $db, $hooks;
+ $err->log("mail", "delete");
+
+ $mail_id = intval($mail_id);
+
+ if (!$mail_id) {
+ $err->raise("mail", _("The email you entered is syntaxically incorrect"));
+ return false;
+ }
+ // Validate that this email is owned by me...
+ if (!($mail = $this->is_it_my_mail($mail_id))) {
+ return false;
+ }
+
+ $mailinfos = $this->get_details($mail_id);
+ $hooks->invoke('hook_mail_delete', array($mail_id, $mailinfos['address'] . '@' . $mailinfos['domain']));
+
+ // Search for that address:
+ $db->query("SELECT a.id, a.type, a.mail_action, m.mail_action AS mailbox_action, NOT ISNULL(m.id) AS islocal FROM address a LEFT JOIN mailbox m ON m.address_id=a.id WHERE a.id='$mail_id';");
+ if (!$db->next_record()) {
+ $err->raise("mail", _("The email %s does not exist, it can't be deleted"), $mail);
+ return false;
+ }
+ if ($db->f("mail_action") != "OK" || ($db->f("islocal") && $db->f("mailbox_action") != "OK")) { // will be deleted soon ...
+ $err->raise("mail", _("The email %s is already marked for deletion, it can't be deleted"), $mail);
+ return false;
+ }
+ $mail_id = $db->f("id");
+
+ if ($db->f("islocal")) {
+ // If it's a pop/imap mailbox, mark it for deletion
+ $db->query("UPDATE address SET mail_action='DELETE', enabled=0 WHERE id='$mail_id';");
+ $db->query("UPDATE mailbox SET mail_action='DELETE' WHERE address_id='$mail_id';");
+ $err->raise("mail", _("The email %s has been marked for deletion"), $mail);
+ } else {
+ // If it's only aliases, delete it NOW.
+ $db->query("DELETE FROM address WHERE id='$mail_id';");
+ $db->query("DELETE FROM mailbox WHERE address_id='$mail_id';");
+ $db->query("DELETE FROM recipient WHERE address_id='$mail_id';");
+ $err->raise("mail", _("The email %s has been successfully deleted"), $mail);
+ }
return true;
- break;
- } // switch
- }
-
-
- /* ----------------------------------------------------------------- */
- /**
- * Add a slave account that will be allowed to access the mxdomain list
- * @param string $login the login to add
- * @param string $pass the password to add
- * @return boolean TRUE if the account has been created, or FALSE if an error occurred.
- */
- function add_slave_account($login,$pass) {
- global $db,$err;
- $login=mysql_real_escape_string($login);
- $pass=mysql_real_escape_string($pass);
- $db->query("SELECT * FROM mxaccount WHERE login='$login'");
- if ($db->next_record()) {
- $err->raise("mail",_("The slave MX account was not found"));
- return false;
}
- $db->query("INSERT INTO mxaccount (login,pass) VALUES ('$login','$pass')");
- return true;
- }
+ /* ----------------------------------------------------------------- */
- /* ----------------------------------------------------------------- */
- /**
- * Remove a slave account
- * @param string $login the login to delete
- */
- function del_slave_account($login) {
- global $db,$err;
- $login=mysql_real_escape_string($login);
- $db->query("DELETE FROM mxaccount WHERE login='$login'");
- return true;
- }
+ /** Function used to undelete a pending deletion mail from the db
+ * should be used by the web interface, not by third-party programs.
+ *
+ * @param $mail_id integer the email id
+ * @return boolean if the email has been properly undeleted
+ * or false if an error occured ($err is filled accordingly)
+ */
+ function undelete($mail_id) {
+ global $err, $db;
+ $err->log("mail", "undelete");
- /* ----------------------------------------------------------------- */
- /** hook function called by AlternC when a domain is created for
- * the current user account using the SLAVE DOMAIN feature
- * This function create a CATCHALL to the master domain
- * @param string $domain_id Domain that has just been created
- * @param string $target_domain Master domain
- * @access private
- */
- function hook_dom_add_slave_domain($domain_id,$target_domain) {
- global $err;
- $err->log("mail","hook_dom_add_slave_domain",$domain_id);
- $this->catchall_set($domain_id,'@'.$target_domain);
- return true;
- }
+ $mail_id = intval($mail_id);
- /* ----------------------------------------------------------------- */
- /** hook function called by AlternC when a domain is created for
- * the current user account
- * This function create a postmaster mail which is an alias to LOGIN @ FQDN
- * wich is a dynamic alias to the alternc's account mail
- * @param string $domain_id Domain that has just been created
- * @access private
- */
- function hook_dom_add_mx_domain($domain_id) {
- global $err, $mem, $L_FQDN,$db;
- $err->log("mail","hook_dom_add_mx_domain",$domain_id);
+ if (!$mail_id) {
+ $err->raise("mail", _("The email you entered is syntaxically incorrect"));
+ return false;
+ }
+ // Validate that this email is owned by me...
+ if (!($mail = $this->is_it_my_mail($mail_id))) {
+ return false;
+ }
- $db->query("SELECT value FROM variable where name='mailname_bounce';");
- if (!$db->next_record()) {
- $err->raise("mail",_("Problem: can't create default bounce mail"));
- return false;
+ // Search for that address:
+ $db->query("SELECT a.id, a.type, a.mail_action, m.mail_action AS mailbox_action, NOT ISNULL(m.id) AS islocal FROM address a LEFT JOIN mailbox m ON m.address_id=a.id WHERE a.id='$mail_id';");
+ if (!$db->next_record()) {
+ $err->raise("mail", _("The email %s does not exist, it can't be undeleted"), $mail);
+ return false;
+ }
+ if ($db->f("type") != "") { // Technically special : mailman, sympa ...
+ $err->raise("mail", _("The email %s is special, it can't be undeleted"), $mail);
+ return false;
+ }
+ if ($db->f("mailbox_action") != "DELETE" || $db->f("mail_action") != "DELETE") { // will be deleted soon ...
+ $err->raise("mail", _("Sorry, deletion of email %s is already in progress, or not marked for deletion, it can't be undeleted"), $mail);
+ return false;
+ }
+ $mail_id = $db->f("id");
+
+ if ($db->f("islocal")) {
+ // If it's a pop/imap mailbox, mark it for deletion
+ $db->query("UPDATE address SET mail_action='OK', `enabled`=1 WHERE id='$mail_id';");
+ $db->query("UPDATE mailbox SET mail_action='OK' WHERE address_id='$mail_id';");
+ $err->raise("mail", _("The email %s has been undeleted"), $mail);
+ return true;
+ } else {
+ $err->raise("mail", _("-- Program Error -- The email %s can't be undeleted"), $mail);
+ return false;
+ }
}
- $mailname=$db->f("value");
- // set spf & dmarc for this domain
- $db->query("SELECT domaine FROM domaines WHERE id=$domain_id;");
- if ($db->next_record()) {
- if ($spf=variable_get("default_spf_value")) {
- $this->set_dns_spf($db->Record["domaine"],$spf);
- }
- if ($dmarc=variable_get("default_dmarc_value")) {
- $this->set_dns_dmarc($db->Record["domaine"],$dmarc);
- }
+
+ /* ----------------------------------------------------------------- */
+
+ /** set the password of an email address.
+ * @param $mail_id integer email ID
+ * @param $pass string the new password.
+ * @return boolean true if the password has been set, false else, raise an error.
+ */
+ function set_passwd($mail_id, $pass) {
+ global $db, $err, $admin;
+ $err->log("mail", "setpasswd");
+
+ if (!($email = $this->is_it_my_mail($mail_id))) {
+ return false;
+ }
+ if (!$admin->checkPolicy("pop", $email, $pass)) {
+ return false;
+ }
+ if (!$db->query("UPDATE address SET password='" . _md5cr($pass) . "' where id=$mail_id;")) {
+ return false;
+ }
+ return true;
}
- return $this->create_alias($domain_id, 'postmaster', $mem->user['login'].'@'.$mailname );
- }
+ /* ----------------------------------------------------------------- */
- /* ----------------------------------------------------------------- */
- /** hook function called by variables when a variable is changed
- * @access private
- */
- function hook_variable_set($name,$old,$new) {
- global $err, $db;
- $err->log("mail","hook_variable_set($name,$old,$new)");
+ /** Enables an email address.
+ * @param $mail_id integer Email ID
+ * @return boolean true if the email has been enabled.
+ */
+ function enable($mail_id) {
+ global $db, $err;
+ $err->log("mail", "enable");
+ if (!($email = $this->is_it_my_mail($mail_id))) {
+ return false;
+ }
+ if (!$db->query("UPDATE address SET `enabled`=1 where id=$mail_id;")) {
+ return false;
+ }
+ return true;
+ }
- if ($name=="default_spf_value") {
- $new=trim($new);
- $old=trim($old);
- $db->query("SELECT domaine,login,compte FROM domaines, membres WHERE gesdns=1 AND gesmx=1 and membres.uid=domaines.compte;");
- while ($db->next_record()) {
- $this->set_dns_spf($db->Record["domaine"],$new,$old,$db->Record["compte"],$db->Record["login"]);
- }
- }
+ /* ----------------------------------------------------------------- */
- if ($name=="default_dmarc_value") {
- $new=trim($new);
- $old=trim($old);
- $db->query("SELECT domaine,login,compte FROM domaines, membres WHERE gesdns=1 AND gesmx=1 and membres.uid=domaines.compte;");
- while ($db->next_record()) {
- $this->set_dns_dmarc($db->Record["domaine"],$new,$old,$db->Record["compte"],$db->Record["login"]);
- }
- }
-
- }
+ /** Disables an email address.
+ * @param $mail_id integer Email ID
+ * @return boolean true if the email has been enabled.
+ */
+ function disable($mail_id) {
+ global $db, $err;
+ $err->log("mail", "disable");
+ if (!($email = $this->is_it_my_mail($mail_id))) {
+ return false;
+ }
+ if (!$db->query("UPDATE address SET `enabled`=0 where id=$mail_id;")) {
+ return false;
+ }
+ return true;
+ }
+ /* ----------------------------------------------------------------- */
- /* ----------------------------------------------------------------- */
- /** Set or UPDATE the DNS record for the domain $dom(str) to be $spf
- * account's login is current and if not it's $login.
- * don't change spf if current value is not $old
- * @access private
- */
- function set_dns_spf($domain, $spf, $previous=-1, $uid=-1, $login=-1) {
- global $db, $cuid, $dom, $mem;
- // defaults
- if ($uid===-1) $uid=intval($cuid); else $uid=intval($uid);
- if ($login===-1) $login=$mem->user["login"];
- // Search for the record in sub_domaines table
- $db->query("SELECT * FROM sub_domaines WHERE compte=$uid AND domaine='".addslashes($domain)."' AND sub='' AND type='txt' AND valeur LIKE 'v=spf1 %' AND web_action!='DELETE';");
- if ($db->next_record()) {
- if ($previous!==-1 && $db->Record["valeur"]=="v=spf1 ".$spf) {
- return; // skip, no change asked.
- }
- $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE id='".$db->Record["id"]."';");
- }
- $db->query("INSERT INTO sub_domaines SET compte=$uid, domaine='".addslashes($domain)."', sub='', type='txt', valeur='".addslashes("v=spf1 ".$spf)."', web_action='UPDATE';");
- $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine='".addslashes($domain)."';");
- }
+ /** Function used to update an email settings
+ * should be used by the web interface, not by third-party programs.
+ *
+ * @param $mail_id integer the number of the email to delete
+ * @param integer $islocal boolean is it a POP/IMAP mailbox ?
+ * @param integer $quotamb integer if islocal=1, quota in MB
+ * @param string $recipients string recipients, one mail per line.
+ * @return boolean if the email has been properly edited
+ * or false if an error occured ($err is filled accordingly)
+ */
+ function set_details($mail_id, $islocal, $quotamb, $recipients, $delivery = "dovecot", $dontcheck = false) {
+ global $err, $db;
+ $delivery = mysql_real_escape_string($delivery);
+ $err->log("mail", "set_details");
+ if (!($me = $this->get_details($mail_id))) {
+ return false;
+ }
+ if ($me["islocal"] && !$islocal) {
+ // delete pop
+ $db->query("UPDATE mailbox SET mail_action='DELETE' WHERE address_id=" . $mail_id . ";");
+ }
+ if (!$me["islocal"] && $islocal) {
+ // create pop
+ $path = "";
+ if ($delivery == "dovecot") {
+ $path = ALTERNC_MAIL . "/" . substr($me["address"] . "_", 0, 1) . "/" . $me["address"] . "_" . $me["domain"];
+ }
+ foreach ($this->forbiddenchars as $str) {
+ if (strpos($me["address"], $str) !== false) {
+ $err->raise("mail", _("There is forbidden characters in your email address. You can't make it a POP/IMAP account, you can only use it as redirection to other emails"));
+ return false;
+ }
+ }
+ foreach ($this->specialchars as $str) {
+ if (strpos($me["address"], $str) !== false) {
+ $path = ALTERNC_MAIL . "/_/" . $me["id"] . "_" . $me["domain"];
+ break;
+ }
+ }
+ $db->query("INSERT INTO mailbox SET address_id=$mail_id, delivery='$delivery', path='" . addslashes($path) . "';");
+ }
+ if ($me["islocal"] && $islocal && $me["mailbox_action"] == "DELETE") {
+ $db->query("UPDATE mailbox SET mail_action='OK' WHERE mail_action='DELETE' AND address_id=" . $mail_id . ";");
+ }
+ if ($islocal) {
+ if ($quotamb != 0 && $quotamb < (intval($me["used"] / 1024 / 1024) + 1)) {
+ $quotamb = intval($me["used"] / 1024 / 1024) + 1;
+ $err->raise("mail", _("You set a quota smaller than the current mailbox size. Since it's not allowed, we set the quota to the current mailbox size"));
+ }
+ $db->query("UPDATE mailbox SET quota=" . intval($quotamb) . " WHERE address_id=" . $mail_id . ";");
+ }
+ $recipients = preg_replace('/[\r\t\s]/', "\n", $recipients); // Handle space AND new line
+ $r = explode("\n", $recipients);
+ $red = "";
+ foreach ($r as $m) {
+ $m = trim($m);
+ if ($m && ( filter_var($m, FILTER_VALIDATE_EMAIL) || $dontcheck) // Recipient Email is valid
+ && $m != ($me["address"] . "@" . $me["domain"])) { // And not myself (no loop allowed easily ;) )
+ $red.=$m . "\n";
+ }
+ }
+ $db->query("DELETE FROM recipient WHERE address_id=" . $mail_id . ";");
+ if (isset($red) && $red) {
+ $db->query("INSERT INTO recipient SET address_id=" . $mail_id . ", recipients='" . addslashes($red) . "';");
+ }
+ return true;
+ }
- /* ----------------------------------------------------------------- */
- /** Set or UPDATE the DNS record for the domain $dom(str) to be $dmarc
- * account's login is current and if not it's $login.
- * don't change dmarc if current value is not $old
- * @access private
- */
- function set_dns_dmarc($domain, $dmarc, $previous=-1, $uid=-1, $login=-1) {
- global $db, $cuid, $dom, $mem, $L_FQDN;
- // defaults
- if ($uid===-1) $uid=intval($cuid); else $uid=intval($uid);
- if ($login===-1) $login=$mem->user["login"];
- $dmarc=str_replace("%%ADMINMAIL%%","admin@".$L_FQDN,$dmarc);
- $dmarc=str_replace("%%USERMAIL%%",$login."@".$L_FQDN,$dmarc);
+ /* ----------------------------------------------------------------- */
- // Search for the record in sub_domaines table
- $db->query("SELECT * FROM sub_domaines WHERE compte=$uid AND domaine='".addslashes($domain)."' AND sub='_dmarc' AND type='txt' AND valeur LIKE 'v=dmarc1;%' AND web_action!='DELETE';");
- if ($db->next_record()) {
- if ($previous!==-1 && $db->Record["valeur"]=="v=dmarc1;".$dmarc) {
- return; // skip, no change asked.
- }
- $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE id='".$db->Record["id"]."';");
- }
- $db->query("INSERT INTO sub_domaines SET compte=$uid, domaine='".addslashes($domain)."', sub='_dmarc', type='txt', valeur='".addslashes("v=dmarc1;".$dmarc)."', web_action='UPDATE';");
- $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine='".addslashes($domain)."';");
- }
+ /** A wrapper used by mailman class to create it's needed addresses
+ * @ param : $dom_id , the domain id associated to a given address
+ * @ param : $m , the left part of the mail address being created
+ * @ param : $delivery , the delivery used to deliver the mail
+ */
+ function add_wrapper($dom_id, $m, $delivery) {
+ global $err, $mail;
+ $err->log("mail", "add_wrapper", "creating $delivery $m address");
+ $mail_id = $mail->create($dom_id, $m, $delivery);
+ $this->set_details($mail_id, 1, 0, '', $delivery);
+ // FIXME return error code
+ }
+ /* ----------------------------------------------------------------- */
+ /** A function used to create an alias for a specific address
+ * @ param : $dom_id , the domain sql identifier
+ * @ param : $m , the alias we want to create
+ * @ param : $alias , the already existing aliased address
+ * @ param : $type, the type of the alias created
+ * @param string $m
+ * @param string $alias
+ * @param string $dom_id
+ */
+ function create_alias($dom_id, $m, $alias, $type = "", $dontcheck = false) {
+ global $err, $mail;
+ $err->log("mail", "create_alias", "creating $m alias for $alias type $type");
- /* ----------------------------------------------------------------- */
- /** hook function called by AlternC-upnp to know which open
- * tcp or udp ports this class requires or suggests
- * @return array a key => value list of port protocol name mandatory values
- * @access private
- */
- function hook_upnp_list() {
- return array(
- "imap" => array("port" => 143, "protocol" => "tcp", "mandatory" => 1),
- "imaps" => array("port" => 993, "protocol" => "tcp", "mandatory" => 1),
- "pop" => array("port" => 110, "protocol" => "tcp", "mandatory" => 1),
- "pops" => array("port" => 995, "protocol" => "tcp", "mandatory" => 1),
- "smtp" => array("port" => 25, "protocol" => "tcp", "mandatory" => 1),
- "sieve" => array("port" => 2000, "protocol" => "tcp", "mandatory" => 1),
- "submission" => array("port" => 587, "protocol" => "tcp", "mandatory" => 0),
- );
- }
+ $mail_id = $mail->create($dom_id, $m, $type, $dontcheck);
+ if (!$mail_id) {
+ return false;
+ }
+ $this->set_details($mail_id, 0, 0, $alias, "dovecot", $dontcheck);
+ return true;
+ }
-
+ /* ----------------------------------------------------------------- */
-} /* Class m_mail */
+ /** A wrapper used by mailman class to create it's needed addresses
+ * @ param : $mail_id , the mysql id of the mail address we want to delete
+ * of the email for the current acccount.
+ */
+ function del_wrapper($mail_id) {
+ global $err;
+ $err->log("mail", "del_wrapper");
+ $this->delete($mail_id);
+ }
+ /* ----------------------------------------------------------------- */
+ /** Export the mail information of an account
+ * @return: str, string containing the complete configuration
+ * of the email for the current acccount.
+ */
+ function alternc_export_conf() {
+ global $err;
+ $err->log("mail", "export");
+ $domain = $this->enum_domains();
+ $str = "\n";
+ foreach ($domain as $d) {
+ $str.=" \n " . xml_entities($d["domain"]) . " \n";
+ $s = $this->enum_domain_mails($d["id"]);
+ if (count($s)) {
+ while (list($key, $val) = each($s)) {
+ $str.=" \n";
+ $str.=" " . xml_entities($val["address"]) . " \n";
+ $str.=" " . xml_entities($val["enabled"]) . " \n";
+ if (is_array($val["islocal"])) {
+ $str.=" 1 \n";
+ $str.=" " . $val["quota"] . " \n";
+ $str.=" " . $val["path"] . " \n";
+ } else {
+ $str.=" 0 \n";
+ }
+ if (!empty($val["recipients"])) {
+ $r = explode("\n", $val["recipients"]);
+ foreach ($r as $recip) {
+ $str.=" " . $recip . "\n";
+ }
+ }
+ $str.=" \n";
+ }
+ }
+ $str.=" \n";
+ }
+ $str.=" \n";
+ return $str;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Return the list of allowed slave accounts (secondary-mx)
+ * @return array
+ */
+ function enum_slave_account() {
+ global $db;
+ $db->query("SELECT login,pass FROM mxaccount;");
+ $res = array();
+ while ($db->next_record()) {
+ $res[] = $db->Record;
+ }
+ if (!count($res)) {
+ return false;
+ }
+ return $res;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Check for a slave account (secondary mx)
+ * @param string $login the login to check
+ * @param string $pass the password to check
+ * @return boolean TRUE if the password is correct, or FALSE if an error occurred.
+ */
+ function check_slave_account($login, $pass) {
+ global $db;
+ $login = mysql_real_escape_string($login);
+ $pass = mysql_real_escape_string($pass);
+ $db->query("SELECT * FROM mxaccount WHERE login='$login' AND pass='$pass';");
+ if ($db->next_record()) {
+ return true;
+ }
+ return false;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Out (echo) the complete hosted domain list :
+ */
+ function echo_domain_list($format = null) {
+ global $db;
+ $db->query("SELECT domaine FROM domaines WHERE gesmx=1 ORDER BY domaine");
+ $lst = array();
+ $tt = "";
+ while ($db->next_record()) {
+ $lst[] = $db->f("domaine");
+ $tt.=$db->f("domaine");
+ }
+
+ # Generate an integrity check
+ $obj = array('integrity' => md5($tt), 'items' => $lst);
+
+ switch ($format) {
+ case "json":
+ return json_encode($obj);
+ default:
+ foreach ($lst as $l) {
+ echo $l . "\n";
+ }
+ return true;
+ } // switch
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Add a slave account that will be allowed to access the mxdomain list
+ * @param string $login the login to add
+ * @param string $pass the password to add
+ * @return boolean TRUE if the account has been created, or FALSE if an error occurred.
+ */
+ function add_slave_account($login, $pass) {
+ global $db, $err;
+ $login = mysql_real_escape_string($login);
+ $pass = mysql_real_escape_string($pass);
+ $db->query("SELECT * FROM mxaccount WHERE login='$login'");
+ if ($db->next_record()) {
+ $err->raise("mail", _("The slave MX account was not found"));
+ return false;
+ }
+ $db->query("INSERT INTO mxaccount (login,pass) VALUES ('$login','$pass')");
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Remove a slave account
+ * @param string $login the login to delete
+ */
+ function del_slave_account($login) {
+ global $db;
+ $login = mysql_real_escape_string($login);
+ $db->query("DELETE FROM mxaccount WHERE login='$login'");
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** hook function called by AlternC when a domain is created for
+ * the current user account using the SLAVE DOMAIN feature
+ * This function create a CATCHALL to the master domain
+ * @param string $domain_id Domain that has just been created
+ * @param string $target_domain Master domain
+ * @access private
+ */
+ function hook_dom_add_slave_domain($domain_id, $target_domain) {
+ global $err;
+ $err->log("mail", "hook_dom_add_slave_domain", $domain_id);
+ $this->catchall_set($domain_id, '@' . $target_domain);
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** hook function called by AlternC when a domain is created for
+ * the current user account
+ * This function create a postmaster mail which is an alias to LOGIN @ FQDN
+ * wich is a dynamic alias to the alternc's account mail
+ * @param string $domain_id Domain that has just been created
+ * @access private
+ */
+ function hook_dom_add_mx_domain($domain_id) {
+ global $err, $mem, $db;
+ $err->log("mail", "hook_dom_add_mx_domain", $domain_id);
+
+ $db->query("SELECT value FROM variable where name='mailname_bounce';");
+ if (!$db->next_record()) {
+ $err->raise("mail", _("Problem: can't create default bounce mail"));
+ return false;
+ }
+ $mailname = $db->f("value");
+ // set spf & dmarc for this domain
+ $db->query("SELECT domaine FROM domaines WHERE id=$domain_id;");
+ if ($db->next_record()) {
+ if ($spf = variable_get("default_spf_value")) {
+ $this->set_dns_spf($db->Record["domaine"], $spf);
+ }
+ if ($dmarc = variable_get("default_dmarc_value")) {
+ $this->set_dns_dmarc($db->Record["domaine"], $dmarc);
+ }
+ }
+ return $this->create_alias($domain_id, 'postmaster', $mem->user['login'] . '@' . $mailname);
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** hook function called by variables when a variable is changed
+ * @access private
+ */
+ function hook_variable_set($name, $old, $new) {
+ global $err, $db;
+ $err->log("mail", "hook_variable_set($name,$old,$new)");
+
+ if ($name == "default_spf_value") {
+ $new = trim($new);
+ $old = trim($old);
+ $db->query("SELECT domaine,login,compte FROM domaines, membres WHERE gesdns=1 AND gesmx=1 and membres.uid=domaines.compte;");
+ while ($db->next_record()) {
+ $this->set_dns_spf($db->Record["domaine"], $new, $old, $db->Record["compte"], $db->Record["login"]);
+ }
+ }
+
+ if ($name == "default_dmarc_value") {
+ $new = trim($new);
+ $old = trim($old);
+ $db->query("SELECT domaine,login,compte FROM domaines, membres WHERE gesdns=1 AND gesmx=1 and membres.uid=domaines.compte;");
+ while ($db->next_record()) {
+ $this->set_dns_dmarc($db->Record["domaine"], $new, $old, $db->Record["compte"], $db->Record["login"]);
+ }
+ }
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Set or UPDATE the DNS record for the domain $dom(str) to be $spf
+ * account's login is current and if not it's $login.
+ * don't change spf if current value is not $old
+ * @access private
+ */
+ function set_dns_spf($domain, $spf, $previous = -1, $uid = -1, $login = -1) {
+ global $db, $cuid, $mem;
+ // defaults
+ if ($uid === -1) {
+ $uid = intval($cuid);
+ } else {
+ $uid = intval($uid);
+ }
+ if ($login === -1) {
+ $login = $mem->user["login"];
+ }
+ // Search for the record in sub_domaines table
+ $db->query("SELECT * FROM sub_domaines WHERE compte=$uid AND domaine='" . addslashes($domain) . "' AND sub='' AND type='txt' AND valeur LIKE 'v=spf1 %' AND web_action!='DELETE';");
+ if ($db->next_record()) {
+ if ($previous !== -1 && $db->Record["valeur"] == "v=spf1 " . $spf) {
+ return; // skip, no change asked.
+ }
+ $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE id='" . $db->Record["id"] . "';");
+ }
+ $db->query("INSERT INTO sub_domaines SET compte=$uid, domaine='" . addslashes($domain) . "', sub='', type='txt', valeur='" . addslashes("v=spf1 " . $spf) . "', web_action='UPDATE';");
+ $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine='" . addslashes($domain) . "';");
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Set or UPDATE the DNS record for the domain $dom(str) to be $dmarc
+ * account's login is current and if not it's $login.
+ * don't change dmarc if current value is not $old
+ * @access private
+ */
+ function set_dns_dmarc($domain, $dmarc, $previous = -1, $uid = -1, $login = -1) {
+ global $db, $cuid, $mem, $L_FQDN;
+ // defaults
+ if ($uid === -1) {
+ $uid = intval($cuid);
+ } else {
+ $uid = intval($uid);
+ }
+ if ($login === -1) {
+ $login = $mem->user["login"];
+ }
+ $dmarc = str_replace("%%ADMINMAIL%%", "admin@" . $L_FQDN, $dmarc);
+ $dmarc = str_replace("%%USERMAIL%%", $login . "@" . $L_FQDN, $dmarc);
+
+ // Search for the record in sub_domaines table
+ $db->query("SELECT * FROM sub_domaines WHERE compte=$uid AND domaine='" . addslashes($domain) . "' AND sub='_dmarc' AND type='txt' AND valeur LIKE 'v=dmarc1;%' AND web_action!='DELETE';");
+ if ($db->next_record()) {
+ if ($previous !== -1 && $db->Record["valeur"] == "v=dmarc1;" . $dmarc) {
+ return; // skip, no change asked.
+ }
+ $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE id='" . $db->Record["id"] . "';");
+ }
+ $db->query("INSERT INTO sub_domaines SET compte=$uid, domaine='" . addslashes($domain) . "', sub='_dmarc', type='txt', valeur='" . addslashes("v=dmarc1;" . $dmarc) . "', web_action='UPDATE';");
+ $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine='" . addslashes($domain) . "';");
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** hook function called by AlternC-upnp to know which open
+ * tcp or udp ports this class requires or suggests
+ * @return array a key => value list of port protocol name mandatory values
+ * @access private
+ */
+ function hook_upnp_list() {
+ return array(
+ "imap" => array("port" => 143, "protocol" => "tcp", "mandatory" => 1),
+ "imaps" => array("port" => 993, "protocol" => "tcp", "mandatory" => 1),
+ "pop" => array("port" => 110, "protocol" => "tcp", "mandatory" => 1),
+ "pops" => array("port" => 995, "protocol" => "tcp", "mandatory" => 1),
+ "smtp" => array("port" => 25, "protocol" => "tcp", "mandatory" => 1),
+ "sieve" => array("port" => 2000, "protocol" => "tcp", "mandatory" => 1),
+ "submission" => array("port" => 587, "protocol" => "tcp", "mandatory" => 0),
+ );
+ }
+
+}
+
+/* Class m_mail */
diff --git a/bureau/class/m_mem.php b/bureau/class/m_mem.php
index b2d433ca..8952bdff 100644
--- a/bureau/class/m_mem.php
+++ b/bureau/class/m_mem.php
@@ -1,454 +1,483 @@
"AlternC's account password");
- }
+ /** Tableau contenant les champs de la table "local" du membre courant
+ * Ce tableau est utilisable globalement par toutes les classes filles.
+ * Note : les champs de "local" sont specifiques a l'hebergeur.
+ */
+ var $local;
- function hook_menu() {
- $obj = array(
- 'title' => _("Settings"),
- 'ico' => 'images/settings.png',
- 'link' => 'mem_param.php',
- 'pos' => 160,
- ) ;
+ /* ----------------------------------------------------------------- */
- return $obj;
- }
-
- /* ----------------------------------------------------------------- */
- /** Check that the current user is an admnistrator.
- * @return boolean TRUE if we are super user, or FALSE if we are not.
- */
- function checkright() {
- return ($this->user["su"]=="1");
- }
-
- /* ----------------------------------------------------------------- */
- /** Start a session in the web desktop. Check username and password.
- * Note : If the user entered a bas password, the failure will be logged
- * and told to the corresponding user on next successfull login.
- * @param $username string Username that want to get connected.
- * @param $password string User Password.
- * @return boolean TRUE if the user has been successfully connected, or FALSE if an error occured.
- */
- function login($username,$password,$restrictip=0,$authip_token=false) {
- global $db,$err,$cuid,$authip,$admin;
- $err->log("mem","login",$username);
- // $username=addslashes($username);
- // $password=addslashes($password);
- $db->query("select * from membres where login='$username';");
- if ($db->num_rows()==0) {
- $err->raise("mem",_("User or password incorrect"));
- return false;
- }
- $db->next_record();
- if (_md5cr($password,$db->f("pass"))!=$db->f("pass")) {
- $db->query("UPDATE membres SET lastfail=lastfail+1 WHERE uid='".$db->f("uid")."';");
- $err->raise("mem",_("User or password incorrect"));
- return false;
- }
- if (!$db->f("enabled")) {
- $err->raise("mem",_("This account is locked, contact the administrator."));
- return false;
- }
- $this->user=$db->Record;
- $cuid=$db->f("uid");
-
- if (panel_islocked() && $cuid != 2000) {
- $err->raise("mem",_("This website is currently under maintenance, login is currently disabled."));
- return false;
+ /**
+ * Constructeur
+ */
+ function m_mem() {
+
}
- // AuthIP
- $allowed_ip=false;
- if ( $authip_token ) $allowed_ip = $this->authip_tokencheck($authip_token);
+ /* ----------------------------------------------------------------- */
- $aga = $authip->get_allowed('panel');
- foreach ($aga as $k=>$v ) {
- if ( $authip->is_in_subnet(get_remote_ip(), $v['ip'], $v['subnet']) ) $allowed=true ;
+ /**
+ * Password kind used in this class (hook for admin class)
+ */
+ function alternc_password_policy() {
+ return array("mem" => "AlternC's account password");
}
- // Error if there is rules, the IP is not allowed and it's not in the whitelisted IP
- if ( sizeof($aga)>1 && !$allowed_ip && !$authip->is_wl(get_remote_ip()) ) {
- $err->raise("mem",_("Your IP isn't allowed to connect"));
- return false;
+ function hook_menu() {
+ $obj = array(
+ 'title' => _("Settings"),
+ 'ico' => 'images/settings.png',
+ 'link' => 'mem_param.php',
+ 'pos' => 160,
+ );
+
+ return $obj;
}
- // End AuthIP
- if ($restrictip) {
- $ip="'".get_remote_ip()."'";
- } else $ip="''";
- /* Close sessions that are more than 2 days old. */
- $db->query("DELETE FROM sessions WHERE DATE_ADD(ts,INTERVAL 2 DAY)query("insert into sessions (sid,ip,uid) values ('$sess',$ip,'$cuid');");
- setcookie("session",$sess,0,"/");
- $err->error=0;
- /* Fill in $local */
- $db->query("SELECT * FROM local WHERE uid='$cuid';");
- if ($db->num_rows()) {
- $db->next_record();
- $this->local=$db->Record;
+ /* ----------------------------------------------------------------- */
+
+ /** Check that the current user is an admnistrator.
+ * @return boolean TRUE if we are super user, or FALSE if we are not.
+ */
+ function checkright() {
+ return ($this->user["su"] == "1");
}
- return true;
- }
- /* ----------------------------------------------------------------- */
- /** Start a session as another user from an administrator account.
- * This function is not the same as su. setid connect the current user in the destination
- * account (for good), and su allow any user to become another account for some commands only.
- * (del_user, add_user ...) and allow to bring back admin rights with unsu
- *
- * @param $id integer User id where we will connect to.
- * @return boolean TRUE if the user has been successfully connected, FALSE else.
- */
- function setid($id) {
- global $db,$err,$cuid,$mysql,$quota;
- $err->log("mem","setid",$id);
- $db->query("select * from membres where uid='$id';");
- if ($db->num_rows()==0) {
- $err->raise("mem",_("User or password incorrect"));
- return false;
+ /* ----------------------------------------------------------------- */
+
+ /** Start a session in the web desktop. Check username and password.
+ * Note : If the user entered a bas password, the failure will be logged
+ * and told to the corresponding user on next successfull login.
+ * @param $username string Username that want to get connected.
+ * @param $password string User Password.
+ * @return boolean TRUE if the user has been successfully connected, or FALSE if an error occured.
+ */
+ function login($username, $password, $restrictip = 0, $authip_token = false) {
+ global $db, $err, $cuid, $authip;
+ $err->log("mem", "login", $username);
+ // $username=addslashes($username);
+ // $password=addslashes($password);
+ $db->query("select * from membres where login='$username';");
+ if ($db->num_rows() == 0) {
+ $err->raise("mem", _("User or password incorrect"));
+ return false;
+ }
+ $db->next_record();
+ if (_md5cr($password, $db->f("pass")) != $db->f("pass")) {
+ $db->query("UPDATE membres SET lastfail=lastfail+1 WHERE uid='" . $db->f("uid") . "';");
+ $err->raise("mem", _("User or password incorrect"));
+ return false;
+ }
+ if (!$db->f("enabled")) {
+ $err->raise("mem", _("This account is locked, contact the administrator."));
+ return false;
+ }
+ $this->user = $db->Record;
+ $cuid = $db->f("uid");
+
+ if (panel_islocked() && $cuid != 2000) {
+ $err->raise("mem", _("This website is currently under maintenance, login is currently disabled."));
+ return false;
+ }
+
+ // AuthIP
+ $allowed_ip = false;
+ if ($authip_token) {
+ $allowed_ip = $this->authip_tokencheck($authip_token);
+ }
+
+ $aga = $authip->get_allowed('panel');
+ foreach ($aga as $k => $v) {
+ if ($authip->is_in_subnet(get_remote_ip(), $v['ip'], $v['subnet'])) {
+ $allowed = true;
+ }
+ }
+
+ // Error if there is rules, the IP is not allowed and it's not in the whitelisted IP
+ if (sizeof($aga) > 1 && !$allowed_ip && !$authip->is_wl(get_remote_ip())) {
+ $err->raise("mem", _("Your IP isn't allowed to connect"));
+ return false;
+ }
+ // End AuthIP
+
+ if ($restrictip) {
+ $ip = "'" . get_remote_ip() . "'";
+ } else {
+ $ip = "''";
+ }
+ /* Close sessions that are more than 2 days old. */
+ $db->query("DELETE FROM sessions WHERE DATE_ADD(ts,INTERVAL 2 DAY)query("insert into sessions (sid,ip,uid) values ('$sess',$ip,'$cuid');");
+ setcookie("session", $sess, 0, "/");
+ $err->error = 0;
+ /* Fill in $local */
+ $db->query("SELECT * FROM local WHERE uid='$cuid';");
+ if ($db->num_rows()) {
+ $db->next_record();
+ $this->local = $db->Record;
+ }
+ return true;
}
- $db->next_record();
- $this->user=$db->Record;
- $cuid=$db->f("uid");
- // And recreate the $db->dbus
- $mysql->reload_dbus();
- $ip=get_remote_ip();
- $sess=md5(uniqid(mt_rand()));
- $_REQUEST["session"]=$sess;
- $db->query("insert into sessions (sid,ip,uid) values ('$sess','$ip','$cuid');");
- setcookie("session",$sess,0,"/");
- $err->error=0;
- /* Fill in $local */
- $db->query("SELECT * FROM local WHERE uid='$cuid';");
- if ($db->num_rows()) {
- $db->next_record();
- $this->local=$db->Record;
+ /* ----------------------------------------------------------------- */
+
+ /** Start a session as another user from an administrator account.
+ * This function is not the same as su. setid connect the current user in the destination
+ * account (for good), and su allow any user to become another account for some commands only.
+ * (del_user, add_user ...) and allow to bring back admin rights with unsu
+ *
+ * @param $id integer User id where we will connect to.
+ * @return boolean TRUE if the user has been successfully connected, FALSE else.
+ */
+ function setid($id) {
+ global $db, $err, $cuid, $mysql, $quota;
+ $err->log("mem", "setid", $id);
+ $db->query("select * from membres where uid='$id';");
+ if ($db->num_rows() == 0) {
+ $err->raise("mem", _("User or password incorrect"));
+ return false;
+ }
+ $db->next_record();
+ $this->user = $db->Record;
+ $cuid = $db->f("uid");
+ // And recreate the $db->dbus
+ $mysql->reload_dbus();
+
+ $ip = get_remote_ip();
+ $sess = md5(uniqid(mt_rand()));
+ $_REQUEST["session"] = $sess;
+ $db->query("insert into sessions (sid,ip,uid) values ('$sess','$ip','$cuid');");
+ setcookie("session", $sess, 0, "/");
+ $err->error = 0;
+ /* Fill in $local */
+ $db->query("SELECT * FROM local WHERE uid='$cuid';");
+ if ($db->num_rows()) {
+ $db->next_record();
+ $this->local = $db->Record;
+ }
+ $quota->getquota('', true);
+ return true;
}
- $quota->getquota('', true);
- return true;
- }
- /* ----------------------------------------------------------------- */
- /** Suite à la connexion de l'utilisateur, réinitialise ses paramètres de dernière connexion
- */
- function resetlast() {
- global $db,$cuid;
- $ip=addslashes(getenv("REMOTE_HOST"));
- if (!$ip) $ip=addslashes(get_remote_ip());
- $db->query("UPDATE membres SET lastlogin=NOW(), lastfail=0, lastip='$ip' WHERE uid='$cuid';");
- }
+ /* ----------------------------------------------------------------- */
- function authip_token($bis=false) {
- global $db,$cuid;
- $db->query("select pass from membres where uid='$cuid';");
- $db->next_record();
- $i=intval(time()/3600);
- if ($bis) ++$i;
- return md5("$i--".$db->f('pass'));
- }
+ /** Suite � la connexion de l'utilisateur, r�initialise ses param�tres de derni�re connexion
+ */
+ function resetlast() {
+ global $db, $cuid;
+ $ip = addslashes(getenv("REMOTE_HOST"));
+ if (!$ip) {
+ $ip = addslashes(get_remote_ip());
+ }
+ $db->query("UPDATE membres SET lastlogin=NOW(), lastfail=0, lastip='$ip' WHERE uid='$cuid';");
+ }
- /**
- * @param boolean $t
- */
- function authip_tokencheck($t) {
- if ($t==$this->authip_token() || $t==$this->authip_token(true) ) return true;
- return false;
- }
+ function authip_token($bis = false) {
+ global $db, $cuid;
+ $db->query("select pass from membres where uid='$cuid';");
+ $db->next_record();
+ $i = intval(time() / 3600);
+ if ($bis) {
+ ++$i;
+ }
+ return md5("$i--" . $db->f('pass'));
+ }
-/* Faut finir de l'implémenter :) * /
- function authip_class() {
- global $cuid;
- $c = Array();
- $c['name']="Panel access";
- $c['protocol']="mem";
- $c['values']=Array($cuid=>'');
+ /**
+ * @param boolean $t
+ */
+ function authip_tokencheck($t) {
+ return ($t == $this->authip_token() || $t == $this->authip_token(true));
+ }
- return $c;
- }
-/* */
+ /* Faut finir de l'implementer :) * /
+ function authip_class() {
+ global $cuid;
+ $c = Array();
+ $c['name']="Panel access";
+ $c['protocol']="mem";
+ $c['values']=Array($cuid=>'');
- /* ----------------------------------------------------------------- */
- /** Vérifie que la session courante est correcte (cookie ok et ip valide).
- * Si besoin, et si réception des champs username & password, crée une nouvelle
- * session pour l'utilisateur annoncé.
- * Cette fonction doit être appellée à chaque page devant être authentifiée.
- * et AVANT d'émettre des données. (un cookie peut être envoyé)
- * @global string $session Le cookie de session eventuel
- * @global string $username/password le login/pass de l'utilisateur
- * @return boolean TRUE si la session est correcte, FALSE sinon.
- */
- function checkid() {
- global $db,$err,$cuid,$restrictip,$authip;
- if (isset($_REQUEST["username"])) {
- if ( empty($_REQUEST['password']) ) {
- $err->raise("mem",_("Missing password"));
- return false;
+ return $c;
}
- if ($_REQUEST["username"] && $_REQUEST["password"]) {
- return $this->login($_REQUEST["username"],$_REQUEST["password"], (isset($_REQUEST["restrictip"])?$_REQUEST["restrictip"]:0) );
- }
- } // end isset
- $_COOKIE["session"]=isset($_COOKIE["session"])?addslashes($_COOKIE["session"]):"";
- if (strlen($_COOKIE["session"])!=32) {
- $err->raise("mem",_("Identity lost or unknown, please login"));
- return false;
- }
- $ip=get_remote_ip();
- $db->query("select uid,'$ip' as me,ip from sessions where sid='".$_COOKIE["session"]."'");
- if ($db->num_rows()==0) {
- $err->raise("mem",_("Session unknown, contact the administrator"));
- return false;
- }
- $db->next_record();
- if ($db->f("ip")) {
- if ($db->f("me")!=$db->f("ip")) {
- $err->raise("mem",_("IP address incorrect, please contact the administrator"));
- return false;
- }
- }
- $cuid=$db->f("uid");
+ /* */
- if (panel_islocked() && $cuid != 2000) {
- $err->raise("mem",_("This website is currently under maintenance, login is currently disabled."));
- return false;
+ /* ----------------------------------------------------------------- */
+
+ /** Verifie que la session courante est correcte (cookie ok et ip valide).
+ * Si besoin, et si reception des champs username & password, cree une nouvelle
+ * session pour l'utilisateur annonce.
+ * Cette fonction doit etre appellee a chaque page devant etre authentifiee.
+ * et AVANT d'emettre des donnees. (un cookie peut etre envoye)
+ * @global string $session Le cookie de session eventuel
+ * @global string $username/password le login/pass de l'utilisateur
+ * @return boolean TRUE si la session est correcte, FALSE sinon.
+ */
+ function checkid() {
+ global $db, $err, $cuid;
+ if (isset($_REQUEST["username"])) {
+ if (empty($_REQUEST['password'])) {
+ $err->raise("mem", _("Missing password"));
+ return false;
+ }
+ if ($_REQUEST["username"] && $_REQUEST["password"]) {
+ return $this->login($_REQUEST["username"], $_REQUEST["password"], (isset($_REQUEST["restrictip"]) ? $_REQUEST["restrictip"] : 0));
+ }
+ } // end isset
+ $_COOKIE["session"] = isset($_COOKIE["session"]) ? addslashes($_COOKIE["session"]) : "";
+ if (strlen($_COOKIE["session"]) != 32) {
+ $err->raise("mem", _("Identity lost or unknown, please login"));
+ return false;
+ }
+ $ip = get_remote_ip();
+ $db->query("select uid,'$ip' as me,ip from sessions where sid='" . $_COOKIE["session"] . "'");
+ if ($db->num_rows() == 0) {
+ $err->raise("mem", _("Session unknown, contact the administrator"));
+ return false;
+ }
+ $db->next_record();
+ if ($db->f("ip")) {
+ if ($db->f("me") != $db->f("ip")) {
+ $err->raise("mem", _("IP address incorrect, please contact the administrator"));
+ return false;
+ }
+ }
+ $cuid = $db->f("uid");
+
+ if (panel_islocked() && $cuid != 2000) {
+ $err->raise("mem", _("This website is currently under maintenance, login is currently disabled."));
+ return false;
+ }
+
+ $db->query("select * from membres where uid='$cuid';");
+ $db->next_record();
+ $this->user = $db->Record;
+ $err->error = 0;
+ /* Remplissage de $local */
+ $db->query("SELECT * FROM local WHERE uid='$cuid';");
+ if ($db->num_rows()) {
+ $db->next_record();
+ $this->local = $db->Record;
+ }
+ return true;
}
- $db->query("select * from membres where uid='$cuid';");
- $db->next_record();
- $this->user=$db->Record;
- $err->error=0;
- /* Remplissage de $local */
- $db->query("SELECT * FROM local WHERE uid='$cuid';");
- if ($db->num_rows()) {
- $db->next_record();
- $this->local=$db->Record;
- }
- return true;
- }
+ /* ----------------------------------------------------------------- */
- /* ----------------------------------------------------------------- */
- /** Change l'identité d'un utilisateur temporairement.
- * @global string $uid Utilisateur dont on prends l'identité
- * @return TRUE si la session est correcte, FALSE sinon.
- */
- function su($uid) {
- global $cuid,$db,$err,$mysql;
- if (!$this->olduid)
- $this->olduid=$cuid;
- $db->query("select * from membres where uid='$uid';");
- if ($db->num_rows()==0) {
- $err->raise("mem",_("User or password incorrect"));
- return false;
- }
- $db->next_record();
- $this->user=$db->Record;
- $cuid=$db->f("uid");
+ /** Change l'identite d'un utilisateur temporairement.
+ * @global string $uid Utilisateur dont on prends l'identite
+ * @return TRUE si la session est correcte, FALSE sinon.
+ */
+ function su($uid) {
+ global $cuid, $db, $err, $mysql;
+ if (!$this->olduid) {
+ $this->olduid = $cuid;
+ }
+ $db->query("select * from membres where uid='$uid';");
+ if ($db->num_rows() == 0) {
+ $err->raise("mem", _("User or password incorrect"));
+ return false;
+ }
+ $db->next_record();
+ $this->user = $db->Record;
+ $cuid = $db->f("uid");
- // And recreate the $db->dbus
- $mysql->reload_dbus();
- return true;
- }
+ // And recreate the $db->dbus
+ $mysql->reload_dbus();
+ return true;
+ }
- /* ----------------------------------------------------------------- */
- /** Retourne a l'identite d'origine de l'utilisateur apres su.
- * @return boolean TRUE si la session est correcte, FALSE sinon.
- */
- function unsu() {
- global $cuid,$mysql;
- if (!$this->olduid)
- return false;
- $this->su($this->olduid);
- $this->olduid=0;
- // And recreate the $db->dbus
- $mysql->reload_dbus();
- return true;
- }
+ /* ----------------------------------------------------------------- */
+ /** Retourne a l'identite d'origine de l'utilisateur apres su.
+ * @return boolean TRUE si la session est correcte, FALSE sinon.
+ */
+ function unsu() {
+ global $mysql;
+ if (!$this->olduid) {
+ return false;
+ }
+ $this->su($this->olduid);
+ $this->olduid = 0;
+ // And recreate the $db->dbus
+ $mysql->reload_dbus();
+ return true;
+ }
- /* ----------------------------------------------------------------- */
- /** Termine une session du bureau virtuel (logout)
- * @return boolean TRUE si la session a bien été détruite, FALSE sinon.
- */
- function del_session() {
- global $db,$user,$err,$cuid,$classes,$hooks;
- $_COOKIE["session"]=addslashes(isset($_COOKIE["session"])?$_COOKIE["session"]:'');
- setcookie("session","",0,"/");
- setcookie("oldid","",0,"/");
- if ($_COOKIE["session"]=="") {
- $err->error=0;
- return true;
- }
- if (strlen($_COOKIE["session"])!=32) {
- $err->raise("mem",_("Cookie incorrect, please accept the session cookie"));
- return false;
- }
- $ip=get_remote_ip();
- $db->query("select uid,'$ip' as me,ip from sessions where sid='".$_COOKIE["session"]."'");
- if ($db->num_rows()==0) {
- $err->raise("mem",_("Session unknown, contact the administrator"));
- return false;
- }
- $db->next_record();
- if ($db->f("me")!=$db->f("ip")) {
- $err->raise("mem",_("IP address incorrect, please contact the administrator"));
- return false;
- }
- $cuid=$db->f("uid");
- $db->query("delete from sessions where sid='".$_COOKIE["session"]."';");
- $err->error=0;
-
- # Invoker le logout dans toutes les autres classes
- /*
- foreach($classes as $c) {
- if (method_exists($GLOBALS[$c],"alternc_del_session")) {
- $GLOBALS[$c]->alternc_del_session();
- }
- }
- */
- $hooks->invoke("alternc_del_session");
-
- session_unset();
- @session_destroy();
- return true;
- }
+ /* ----------------------------------------------------------------- */
- /* ----------------------------------------------------------------- */
- /** Change le mot de passe de l'utilisateur courant.
- * @param string $oldpass Ancien mot de passe.
- * @param string $newpass Nouveau mot de passe
- * @param string $newpass2 Nouveau mot de passe (à nouveau)
- * @return boolean TRUE si le mot de passe a été changé, FALSE sinon.
- */
- function passwd($oldpass,$newpass,$newpass2) {
- global $db,$err,$cuid,$admin;
- $err->log("mem","passwd");
- $oldpass=stripslashes($oldpass);
- $newpass=stripslashes($newpass);
- $newpass2=stripslashes($newpass2);
- if (!$this->user["canpass"]) {
- $err->raise("mem",_("You are not allowed to change your password."));
- return false;
- }
- if ($this->user["pass"]!=_md5cr($oldpass,$this->user["pass"])) {
- $err->raise("mem",_("The old password is incorrect"));
- return false;
- }
- if ($newpass!=$newpass2) {
- $err->raise("mem",_("The new passwords are differents, please retry"));
- return false;
- }
- $db->query("SELECT login FROM membres WHERE uid='$cuid';");
- $db->next_record();
- $login=$db->Record["login"];
- if (!$admin->checkPolicy("mem",$login,$newpass)) {
- return false; // The error has been raised by checkPolicy()
- }
- $newpass=_md5cr($newpass);
- $db->query("UPDATE membres SET pass='$newpass' WHERE uid='$cuid';");
- $err->error=0;
- return true;
- }
+ /** Termine une session du bureau virtuel (logout)
+ * @return boolean TRUE si la session a bien ete detruite, FALSE sinon.
+ */
+ function del_session() {
+ global $db, $user, $err, $cuid, $hooks;
+ $_COOKIE["session"] = addslashes(isset($_COOKIE["session"]) ? $_COOKIE["session"] : '');
+ setcookie("session", "", 0, "/");
+ setcookie("oldid", "", 0, "/");
+ if ($_COOKIE["session"] == "") {
+ $err->error = 0;
+ return true;
+ }
+ if (strlen($_COOKIE["session"]) != 32) {
+ $err->raise("mem", _("Cookie incorrect, please accept the session cookie"));
+ return false;
+ }
+ $ip = get_remote_ip();
+ $db->query("select uid,'$ip' as me,ip from sessions where sid='" . $_COOKIE["session"] . "'");
+ if ($db->num_rows() == 0) {
+ $err->raise("mem", _("Session unknown, contact the administrator"));
+ return false;
+ }
+ $db->next_record();
+ if ($db->f("me") != $db->f("ip")) {
+ $err->raise("mem", _("IP address incorrect, please contact the administrator"));
+ return false;
+ }
+ $cuid = $db->f("uid");
+ $db->query("delete from sessions where sid='" . $_COOKIE["session"] . "';");
+ $err->error = 0;
- /* ----------------------------------------------------------------- */
- /** Change les préférences administrateur d'un compte
- * @param integer $admlist Mode de visualisation des membres (0=large 1=courte)
- * @return boolean TRUE si les préférences ont été changées, FALSE sinon.
- */
- function adminpref($admlist) {
- global $db,$err,$cuid;
- $err->log("mem","admlist");
- if (!$this->user["su"]) {
- $err->raise("mem",_("You must be a system administrator to do this."));
- return false;
- }
- $db->query("UPDATE membres SET admlist='$admlist' WHERE uid='$cuid';");
- $err->error=0;
- return true;
- }
+ # Invoker le logout dans toutes les autres classes
+ /*
+ foreach($classes as $c) {
+ if (method_exists($GLOBALS[$c],"alternc_del_session")) {
+ $GLOBALS[$c]->alternc_del_session();
+ }
+ }
+ */
+ $hooks->invoke("alternc_del_session");
- /* ----------------------------------------------------------------- */
- /** Envoie en mail le mot de passe d'un compte.
- * Note : On ne peut demander le mot de passe qu'une seule fois par jour.
- * TODO : Translate this mail into the localization program.
- * TODO : Check this function's !
- * @return boolean TRUE si le mot de passe a été envoyé avec succès, FALSE sinon.
- */
- function send_pass($login) {
- global $err,$db,$L_HOSTING,$L_FQDN;
- $err->log("mem","send_pass");
- $db->query("SELECT * FROM membres WHERE login='$login';");
- if (!$db->num_rows()) {
- $err->raise("mem",_("This account is locked, contact the administrator."));
- return false;
+ session_unset();
+ @session_destroy();
+ return true;
}
- $db->next_record();
- if (time()-$db->f("lastaskpass")<86400) {
- $err->raise("mem",_("The new passwords are differents, please retry"));
- return false;
+
+ /* ----------------------------------------------------------------- */
+
+ /** Change le mot de passe de l'utilisateur courant.
+ * @param string $oldpass Ancien mot de passe.
+ * @param string $newpass Nouveau mot de passe
+ * @param string $newpass2 Nouveau mot de passe (a nouveau)
+ * @return boolean TRUE si le mot de passe a ete change, FALSE sinon.
+ */
+ function passwd($oldpass, $newpass, $newpass2) {
+ global $db, $err, $cuid, $admin;
+ $err->log("mem", "passwd");
+ $oldpass = stripslashes($oldpass);
+ $newpass = stripslashes($newpass);
+ $newpass2 = stripslashes($newpass2);
+ if (!$this->user["canpass"]) {
+ $err->raise("mem", _("You are not allowed to change your password."));
+ return false;
+ }
+ if ($this->user["pass"] != _md5cr($oldpass, $this->user["pass"])) {
+ $err->raise("mem", _("The old password is incorrect"));
+ return false;
+ }
+ if ($newpass != $newpass2) {
+ $err->raise("mem", _("The new passwords are differents, please retry"));
+ return false;
+ }
+ $db->query("SELECT login FROM membres WHERE uid='$cuid';");
+ $db->next_record();
+ $login = $db->Record["login"];
+ if (!$admin->checkPolicy("mem", $login, $newpass)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ $newpass = _md5cr($newpass);
+ $db->query("UPDATE membres SET pass='$newpass' WHERE uid='$cuid';");
+ $err->error = 0;
+ return true;
}
- $txt=sprintf(_("Hello,
+
+ /* ----------------------------------------------------------------- */
+
+ /** Change les preferences administrateur d'un compte
+ * @param integer $admlist Mode de visualisation des membres (0=large 1=courte)
+ * @return boolean TRUE si les preferences ont ete changees, FALSE sinon.
+ */
+ function adminpref($admlist) {
+ global $db, $err, $cuid;
+ $err->log("mem", "admlist");
+ if (!$this->user["su"]) {
+ $err->raise("mem", _("You must be a system administrator to do this."));
+ return false;
+ }
+ $db->query("UPDATE membres SET admlist='$admlist' WHERE uid='$cuid';");
+ $err->error = 0;
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Envoie en mail le mot de passe d'un compte.
+ * Note : On ne peut demander le mot de passe qu'une seule fois par jour.
+ * TODO : Translate this mail into the localization program.
+ * TODO : Check this function's !
+ * @return boolean TRUE si le mot de passe a ete envoye avec succes, FALSE sinon.
+ */
+ function send_pass($login) {
+ global $err, $db, $L_HOSTING, $L_FQDN;
+ $err->log("mem", "send_pass");
+ $db->query("SELECT * FROM membres WHERE login='$login';");
+ if (!$db->num_rows()) {
+ $err->raise("mem", _("This account is locked, contact the administrator."));
+ return false;
+ }
+ $db->next_record();
+ if (time() - $db->f("lastaskpass") < 86400) {
+ $err->raise("mem", _("The new passwords are differents, please retry"));
+ return false;
+ }
+ $txt = sprintf(_("Hello,
You requested the modification of your password for your
account %s on %s
@@ -467,33 +496,34 @@ If it happens again, please contact your server's Administrator.
Cordially.
"), $login, $L_HOSTING, $db->f("login"), $db->f("pass"));
- mail($db->f("mail"),"Your password on $L_HOSTING",$txt,"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
- $db->query("UPDATE membres SET lastaskpass=".time()." WHERE login='$login';");
- return true;
- }
-
- /* ----------------------------------------------------------------- */
- /** Change le mail d'un membre (première etape, envoi du CookiE)
- * TODO : insert this mail string into the localization system
- * @param string $newmail Nouveau mail souhaité pour le membre.
- * @return string le cookie si le mail a bien été envoyé, FALSE sinon
- */
- function ChangeMail1($newmail) {
- global $err,$db,$L_HOSTING,$L_FQDN,$cuid;
- $err->log("mem","changemail1",$newmail);
- $db->query("SELECT * FROM membres WHERE uid='$cuid';");
- if (!$db->num_rows()) {
- $err->raise("mem",_("This account is locked, contact the administrator."));
- return false;
+ mail($db->f("mail"), "Your password on $L_HOSTING", $txt, "From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
+ $db->query("UPDATE membres SET lastaskpass=" . time() . " WHERE login='$login';");
+ return true;
}
- $db->next_record();
- // un cookie de 20 caractères pour le mail
- $COOKIE=substr(md5(uniqid(rand(), true)),0,20);
- // et de 6 pour la clé à entrer. ca me semble suffisant...
- $KEY=substr(md5(uniqid(rand(), true)),0,6);
- $link="https://$L_FQDN/mem_cm.php?usr=$cuid&cookie=$COOKIE";
- $txt=sprintf(_("Hello,
+ /* ----------------------------------------------------------------- */
+
+ /** Change le mail d'un membre (premiere etape, envoi du CookiE)
+ * TODO : insert this mail string into the localization system
+ * @param string $newmail Nouveau mail souhaite pour le membre.
+ * @return string le cookie si le mail a bien ete envoye, FALSE sinon
+ */
+ function ChangeMail1($newmail) {
+ global $err, $db, $L_HOSTING, $L_FQDN, $cuid;
+ $err->log("mem", "changemail1", $newmail);
+ $db->query("SELECT * FROM membres WHERE uid='$cuid';");
+ if (!$db->num_rows()) {
+ $err->raise("mem", _("This account is locked, contact the administrator."));
+ return false;
+ }
+ $db->next_record();
+
+ // un cookie de 20 caract�res pour le mail
+ $COOKIE = substr(md5(uniqid(rand(), true)), 0, 20);
+ // et de 6 pour la cl� � entrer. ca me semble suffisant...
+ $KEY = substr(md5(uniqid(rand(), true)), 0, 6);
+ $link = "https://$L_FQDN/mem_cm.php?usr=$cuid&cookie=$COOKIE";
+ $txt = sprintf(_("Hello,
Someone (maybe you) requested an email's address modification of the account
%s on %s
@@ -512,152 +542,160 @@ again, please contact your server's administrator.
Cordially.
"), $db->f("login"), $L_HOSTING, $link);
- mail($newmail,"Email modification request on $L_HOSTING",$txt,"From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
- // Supprime les demandes précédentes de ce compte !
- $db->query("DELETE FROM chgmail WHERE uid='$cuid';");
- $db->query("INSERT INTO chgmail (cookie,ckey,uid,mail,ts) VALUES ('$COOKIE','$KEY','$cuid','$newmail',".time().");");
- // Supprime les cookies de la veille :)
- $lts=time()-86400;
- $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
- return $KEY;
- }
-
- /* ----------------------------------------------------------------- */
- /** Change le mail d'un membre (seconde etape, CookiE+clé = application)
- * @param string $COOKIE Cookie envoyé par mail
- * @param string $KEY clé affichée à l'écran
- * @param integer $uid Utilisateur concerné (on est hors session)
- * @return boolean TRUE si le mail a bien été modifié, FALSE sinon
- */
- function ChangeMail2($COOKIE,$KEY,$uid) {
- global $err,$db,$L_HOSTING,$L_FQDN;
- $err->log("mem","changemail2",$uid);
- $db->query("SELECT * FROM chgmail WHERE cookie='$COOKIE' and ckey='$KEY' and uid='$uid';");
- if (!$db->num_rows()) {
- $err->raise("mem",_("The information you entered is incorrect."));
- return false;
- }
- $db->next_record();
-
- // met à jour le compte :
- $db->query("UPDATE membres SET mail='".$db->f("mail")."' WHERE uid='$uid';");
-
- $db->query("DELETE FROM chgmail WHERE uid='$uid';");
- // Supprime les cookies de la veille :)
- $lts=time()-86400;
- $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
- return true;
+ mail($newmail, "Email modification request on $L_HOSTING", $txt, "From: postmaster@$L_FQDN\nReply-to: postmaster@$L_FQDN");
+ // Supprime les demandes pr�c�dentes de ce compte !
+ $db->query("DELETE FROM chgmail WHERE uid='$cuid';");
+ $db->query("INSERT INTO chgmail (cookie,ckey,uid,mail,ts) VALUES ('$COOKIE','$KEY','$cuid','$newmail'," . time() . ");");
+ // Supprime les cookies de la veille :)
+ $lts = time() - 86400;
+ $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
+ return $KEY;
}
/* ----------------------------------------------------------------- */
- /** Modifie le paramètre d'aide en ligne (1/0)
+
+ /** Change le mail d'un membre (seconde etape, CookiE+cle = application)
+ * @param string $COOKIE Cookie envoye par mail
+ * @param string $KEY cle affichee a l'ecran
+ * @param integer $uid Utilisateur concerne (on est hors session)
+ * @return boolean TRUE si le mail a bien ete modifie, FALSE sinon
+ */
+ function ChangeMail2($COOKIE, $KEY, $uid) {
+ global $err, $db;
+ $err->log("mem", "changemail2", $uid);
+ $db->query("SELECT * FROM chgmail WHERE cookie='$COOKIE' and ckey='$KEY' and uid='$uid';");
+ if (!$db->num_rows()) {
+ $err->raise("mem", _("The information you entered is incorrect."));
+ return false;
+ }
+ $db->next_record();
+
+ // met a jour le compte :
+ $db->query("UPDATE membres SET mail='" . $db->f("mail") . "' WHERE uid='$uid';");
+
+ $db->query("DELETE FROM chgmail WHERE uid='$uid';");
+ // Supprime les cookies de la veille :)
+ $lts = time() - 86400;
+ $db->query("DELETE FROM chgmail WHERE ts<'$lts';");
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Modifie le parametre d'aide en ligne (1/0)
* @param integer $show Faut-il (1) ou non (0) afficher l'aide en ligne
*/
function set_help_param($show) {
- global $db,$err,$cuid;
- $err->log("mem","set_help_param",$show);
- $db->query("UPDATE membres SET show_help='$show' WHERE uid='$cuid';");
+ global $db, $err, $cuid;
+ $err->log("mem", "set_help_param", $show);
+ $db->query("UPDATE membres SET show_help='$show' WHERE uid='$cuid';");
}
/* ----------------------------------------------------------------- */
- /** Dit si l'aide en ligne est demandée
- * @return boolean TRUE si l'aide en ligne est demandée, FALSE sinon.
+
+ /** Dit si l'aide en ligne est demandee
+ * @return boolean TRUE si l'aide en ligne est demandee, FALSE sinon.
*/
function get_help_param() {
- return $this->user["show_help"];
+ return $this->user["show_help"];
}
/* ----------------------------------------------------------------- */
+
/** Affiche (echo) l'aide contextuelle
- * @param integer $file Numéro de fichier d'aide à afficher.
- * @return boolean TRUE si l'aide contextuelle a été trouvée, FALSE sinon
+ * @param integer $file Numero de fichier d'aide a afficher.
+ * @return boolean TRUE si l'aide contextuelle a ete trouvee, FALSE sinon
*/
- function show_help($file,$force=false) {
- global $err;
- if ($this->user["show_help"] || $force) {
- $hlp=_("hlp_$file");
- if ($hlp!="hlp_$file") {
- $hlp=preg_replace(
- "#HELPID_([0-9]*)#",
- "
",$hlp);
- echo "".$hlp."
";
- return true;
- }
- return false;
- } else {
- return true;
- }
- }
-
- /**
- * @param integer $uid
- */
- function get_creator_by_uid($uid) {
- global $db,$err;
- $err->log("dom","get_creator_by_uid");
- $uid=mysql_real_escape_string(intval($uid));
- $db->query("select creator from membres where uid = '$uid';");
- if (! $db->next_record()) return false;
- return intval($db->f('creator') );
- }
-
-
- /* ----------------------------------------------------------------- */
- /**
- * Exports all the personnal user related information for an account.
- * @access private
- */
- function alternc_export_conf() {
- global $db,$err;
- $err->log("mem","export");
- $str=" \n";
- $users=$this->user;
- $str.=" ".$users["uid"]." \n";
- $str.=" ".$users["login"]." \n";
- $str.=" ".$users["enabled"]." \n";
- $str.=" ".$users["su"]." \n";
- $str.=" ".$users["pass"]." \n";
- $str.=" ".$users["mail"]." \n";
- $str.=" ".$users["created"]." \n";
- $str.=" ".$users["lastip"]." \n";
- $str.=" ".$users["lastlogin"]." \n";
- $str.=" ".$users["lastfail"]." \n";
- $str.=" \n";
- return $str;
- }
-
- function session_tempo_params_get($v) {
- global $uid;
- if (empty($_COOKIE['session'])) return false;
- $sid=$_COOKIE['session'];
- if ( empty($_SESSION[$sid.'-'.$uid]) ) { // si pas de session de params tempo
- return false;
- }
- $j=$_SESSION[$sid.'-'.$uid];
- $j=json_decode($j, true);
- if ( ! empty($j[$v] ) ) { // si on a bien qque chose a retourner :)
- return $j[$v];
- }
- return false;
- }
-
- function session_tempo_params_set($k, $v, $ecrase=false) {
- global $uid;
- if (empty($_COOKIE['session'])) return false;
- $sid=$_COOKIE['session'];
- $p=Array();
- if ( ! empty($_SESSION[$sid.'-'.$uid]) ) {
- $p = json_decode($_SESSION[$sid.'-'.$uid], true);
- }
- if (! $ecrase && (isset($p[$k]) && is_array($p[$k])) && is_array($v) ) {
- $v=array_merge($p[$k], $v); // overwrite entry with the same name
+ function show_help($file, $force = false) {
+ if ($this->user["show_help"] || $force) {
+ $hlp = _("hlp_$file");
+ if ($hlp != "hlp_$file") {
+ $hlp = preg_replace(
+ "#HELPID_([0-9]*)#", "
", $hlp);
+ echo "" . $hlp . "
";
+ return true;
+ }
+ return false;
+ } else {
+ return true;
+ }
}
- $p[$k]=$v;
- $_SESSION[$sid.'-'.$uid]=json_encode($p);
- return true;
- }
+ /**
+ * @param integer $uid
+ */
+ function get_creator_by_uid($uid) {
+ global $db, $err;
+ $err->log("dom", "get_creator_by_uid");
+ $uid = mysql_real_escape_string(intval($uid));
+ $db->query("select creator from membres where uid = '$uid';");
+ if (!$db->next_record()) {
+ return false;
+ }
+ return intval($db->f('creator'));
+ }
-} /* Classe Membre */
+ /* ----------------------------------------------------------------- */
-?>
+ /**
+ * Exports all the personal user related information for an account.
+ * @access private
+ */
+ function alternc_export_conf() {
+ global $db, $err;
+ $err->log("mem", "export");
+ $str = " \n";
+ $users = $this->user;
+ $str.=" " . $users["uid"] . " \n";
+ $str.=" " . $users["login"] . " \n";
+ $str.=" " . $users["enabled"] . " \n";
+ $str.=" " . $users["su"] . " \n";
+ $str.=" " . $users["pass"] . " \n";
+ $str.=" " . $users["mail"] . " \n";
+ $str.=" " . $users["created"] . " \n";
+ $str.=" " . $users["lastip"] . " \n";
+ $str.=" " . $users["lastlogin"] . " \n";
+ $str.=" " . $users["lastfail"] . " \n";
+ $str.=" \n";
+ return $str;
+ }
+
+ function session_tempo_params_get($v) {
+ global $uid;
+ if (empty($_COOKIE['session'])) {
+ return false;
+ }
+ $sid = $_COOKIE['session'];
+ if (empty($_SESSION[$sid . '-' . $uid])) { // si pas de session de params tempo
+ return false;
+ }
+ $j = $_SESSION[$sid . '-' . $uid];
+ $j = json_decode($j, true);
+ if (!empty($j[$v])) { // si on a bien qque chose a retourner :)
+ return $j[$v];
+ }
+ return false;
+ }
+
+ function session_tempo_params_set($k, $v, $ecrase = false) {
+ global $uid;
+ if (empty($_COOKIE['session'])) {
+ return false;
+ }
+ $sid = $_COOKIE['session'];
+ $p = Array();
+ if (!empty($_SESSION[$sid . '-' . $uid])) {
+ $p = json_decode($_SESSION[$sid . '-' . $uid], true);
+ }
+ if (!$ecrase && (isset($p[$k]) && is_array($p[$k])) && is_array($v)) {
+ $v = array_merge($p[$k], $v); // overwrite entry with the same name
+ }
+
+ $p[$k] = $v;
+ $_SESSION[$sid . '-' . $uid] = json_encode($p);
+ return true;
+ }
+
+}
+
+/* Classe Membre */
diff --git a/bureau/class/m_menu.php b/bureau/class/m_menu.php
index 131e98a5..597a1027 100644
--- a/bureau/class/m_menu.php
+++ b/bureau/class/m_menu.php
@@ -1,4 +1,5 @@
getquota("",true); // rebuild quota
-
- // Get menu objects
- $lsto = $hooks->invoke('hook_menu');
-
- // Get system menu
- $sm = $this->system_menu();
-
- // Merge it !
- $lst = array_merge($sm,$lsto);
-
- // Sort it
- uasort($lst, 'm_menu::order_menu');
-
- // Get user specific menu visibility options
- $mop = $mem->session_tempo_params_get('menu_toggle') ;
-
- foreach( $lst as $k => $v ) {
-
- if (empty($v)) {
- unset($lst[$k]);
- continue;
- }
-
- // Set the javascript toggle link for menu asking for it
- if ($v['link'] == 'toggle') {
- $lst[$k]['link'] = 'javascript:menu_toggle(\'menu-'.$k.'\');';
- }
-
- // Be sure that the default visibility is true
- if (! isset($lst[$k]['visibility'])) $lst[$k]['visibility'] = true;
-
- // Set the user's specific visibility option
- if (isset($mop["menu-$k"])) {
- if ($mop["menu-$k"] == "hidden") $lst[$k]['visibility'] = false;
- if ($mop["menu-$k"] == "visible") $lst[$k]['visibility'] = true;
- }
-
- if ( isset($mesq[$k])) { // if there are some quota for this class
- // Hide the menu if there are none and not allowed to create
- if ( $mesq[$k]['t'] < 1 && $mesq[$k]['u'] < 1 ) {
- unset($lst[$k]);
- continue;
- }
-
- // Set the quota in the menu object
- $lst[$k]['quota_used'] = $mesq[$k]['u'] ;
- $lst[$k]['quota_total'] = $mesq[$k]['t'] ;
-
- } // end if there are some quota for this class
-
+ /** Constructor
+ * menu([$mid]) Constructeur de la classe menu, ne fait rien pour le moment
+ */
+ function m_menu() {
+
}
- return $lst;
- } //getmenu
+ function getmenu() {
+ global $hooks, $quota, $mem;
- function order_menu($a, $b) {
- // Use to order the menu with a usort
- return $a['pos'] > $b['pos'];
- }
+ // Force rebuilding quota, in case of add or edit of the quota and cache not up-to-date
+ $mesq = $quota->getquota("", true); // rebuild quota
+ // Get menu objects
+ $lsto = $hooks->invoke('hook_menu');
- function system_menu() {
- // Here some needed menu who don't have a class
- global $help_baseurl, $lang_translation, $locales;
+ // Get system menu
+ $sm = $this->system_menu();
- $m =
- array(
- 'home' =>
- array(
- 'title' => _("Home / Information"),
- 'ico' => 'images/home.png',
- 'link' => 'main.php',
- 'pos' => 0,
- ),
- 'logout' =>
- array(
- 'title' => _("Logout"),
- 'ico' => 'images/exit.png',
- 'link' => 'mem_logout.php',
- 'pos' => 170,
- ),
- 'help' =>
- array(
- 'title' => _("Online help"),
- 'ico' => 'images/help.png',
- 'target' => 'help',
- 'link' => $help_baseurl,
- 'pos' => 140,
- ),
- 'lang' =>
- array(
- 'title' => _("Languages"),
- 'ico' => '/images/lang.png',
- 'visibility' => false,
- 'link' => 'toggle',
- 'links' => array(),
- 'pos' => 150,
- )
- ) ;
- foreach($locales as $l) {
- $m['lang']['links'][] = array ( 'txt' => (isset($lang_translation[$l]))?$lang_translation[$l]:$l, 'url' => "/login.php?setlang=$l");
- }
- return $m;
+ // Merge it !
+ $lst = array_merge($sm, $lsto);
+ // Sort it
+ uasort($lst, 'm_menu::order_menu');
-/*
+ // Get user specific menu visibility options
+ $mop = $mem->session_tempo_params_get('menu_toggle');
-
+ foreach ($lst as $k => $v) {
+ if (empty($v)) {
+ unset($lst[$k]);
+ continue;
+ }
+ // Set the javascript toggle link for menu asking for it
+ if ($v['link'] == 'toggle') {
+ $lst[$k]['link'] = 'javascript:menu_toggle(\'menu-' . $k . '\');';
+ }
+ // Be sure that the default visibility is true
+ if (!isset($lst[$k]['visibility'])) {
+ $lst[$k]['visibility'] = true;
+ }
+ // Set the user's specific visibility option
+ if (isset($mop["menu-$k"])) {
+ if ($mop["menu-$k"] == "hidden") {
+ $lst[$k]['visibility'] = false;
+ }
+ if ($mop["menu-$k"] == "visible") {
+ $lst[$k]['visibility'] = true;
+ }
+ }
-*/
- } //system_menu
+ if (isset($mesq[$k])) { // if there are some quota for this class
+ // Hide the menu if there are none and not allowed to create
+ if ($mesq[$k]['t'] < 1 && $mesq[$k]['u'] < 1) {
+ unset($lst[$k]);
+ continue;
+ }
-} /* Class menu */
+ // Set the quota in the menu object
+ $lst[$k]['quota_used'] = $mesq[$k]['u'];
+ $lst[$k]['quota_total'] = $mesq[$k]['t'];
+ } // end if there are some quota for this class
+ }
+ return $lst;
+ }
+
+ function order_menu($a, $b) {
+ // Use to order the menu with a usort
+ return $a['pos'] > $b['pos'];
+ }
+
+ function system_menu() {
+ // Here some needed menu who don't have a class
+ global $help_baseurl, $lang_translation, $locales;
+
+ $m = array(
+ 'home' =>
+ array(
+ 'title' => _("Home / Information"),
+ 'ico' => 'images/home.png',
+ 'link' => 'main.php',
+ 'pos' => 0,
+ ),
+ 'logout' =>
+ array(
+ 'title' => _("Logout"),
+ 'ico' => 'images/exit.png',
+ 'link' => 'mem_logout.php',
+ 'pos' => 170,
+ ),
+ 'help' =>
+ array(
+ 'title' => _("Online help"),
+ 'ico' => 'images/help.png',
+ 'target' => 'help',
+ 'link' => $help_baseurl,
+ 'pos' => 140,
+ ),
+ 'lang' =>
+ array(
+ 'title' => _("Languages"),
+ 'ico' => '/images/lang.png',
+ 'visibility' => false,
+ 'link' => 'toggle',
+ 'links' => array(),
+ 'pos' => 150,
+ )
+ );
+ foreach ($locales as $l) {
+ $m['lang']['links'][] = array('txt' => (isset($lang_translation[$l])) ? $lang_translation[$l] : $l, 'url' => "/login.php?setlang=$l");
+ }
+ return $m;
+ }
+
+}
+
+/* Class menu */
diff --git a/bureau/class/m_mysql.php b/bureau/class/m_mysql.php
index a9b10bbf..3971379f 100644
--- a/bureau/class/m_mysql.php
+++ b/bureau/class/m_mysql.php
@@ -1,1158 +1,1150 @@
query("select db_servers.* from db_servers, membres where membres.uid=$cuid and membres.db_server_id=db_servers.id;");
- if (!$db->next_record()) {
- $err->raise('db_user', _("There are no databases in db_servers for this user. Please contact your administrator."));
- die();
+ /**
+ * Creator
+ */
+ function DB_users($empty = false) { // Sometimes we need to create this object with empty parameters, but by default we fill them with those of the current user's DB
+ global $cuid, $db, $err;
+
+ if (!$empty) {
+ $db->query("select db_servers.* from db_servers, membres where membres.uid=$cuid and membres.db_server_id=db_servers.id;");
+ if (!$db->next_record()) {
+ $err->raise('db_user', _("There are no databases in db_servers for this user. Please contact your administrator."));
+ die();
+ }
+
+ # Create the object
+ $this->HumanHostname = $db->f('name');
+ $this->Host = $db->f('host');
+ $this->User = $db->f('login');
+ $this->Password = $db->f('password');
+ $this->Client = $db->f('client');
+
+ $this->Database = "mysql"; # We have to define a dabatase when we connect, and the database must exist.
+ } else {
+ # Create the object without any parameter
+ $this->HumanHostname = "";
+ $this->Host = "";
+ $this->User = "";
+ $this->Password = "";
+ $this->Client = "";
+
+ $this->Database = "mysql"; # We have to define a dabatase when we connect, and the database must exist.
+ }
}
- # Create the object
- $this->HumanHostname = $db->f('name');
- $this->Host = $db->f('host');
- $this->User = $db->f('login');
- $this->Password = $db->f('password');
- $this->Client = $db->f('client');
-
- $this->Database = "mysql"; # We have to define a dabatase when we connect, and the database must exist.
- }else{
- # Create the object without any parameter
- $this->HumanHostname = "";
- $this->Host = "";
- $this->User = "";
- $this->Password = "";
- $this->Client = "";
-
- $this->Database = "mysql"; # We have to define a dabatase when we connect, and the database must exist.
- }
- }
-
}
-
class m_mysql {
- var $dbus;
- /*---------------------------------------------------------------------------*/
- /** Constructor
- * m_mysql([$mid]) Constructeur de la classe m_mysql, initialise le membre concerne
- */
- function m_mysql() {
- global $cuid;
- if (!empty($cuid)) {
- $this->dbus = new DB_users();
- }
- variable_get('sql_allow_users_backups', 1,'Set 1 to allow users to configure backup of their databases, 0 if you want do disable this feature. Warning: it will not stop configured backup made by sqlbackup.sh');
- }
+ var $dbus;
- function reload_dbus() {
- $this->dbus = new DB_users();
- }
+ /* --------------------------------------------------------------------------- */
- function list_db_servers() {
- global $db;
- $db->query("select d.*, IFNULL(count(m.uid),0) as nb_users from db_servers d left join membres m on d.id = m.db_server_id group by d.id,m.db_server_id order by d.name,d.id;");
- $c=array();
- while ($db->next_record()) {
- $c[]=$db->Record;
- }
- return $c;
- }
-
- function hook_menu() {
- global $quota;
- $q = $quota->getquota("mysql");
-
- $obj = array(
- 'title' => _("MySQL"),
- 'ico' => 'images/mysql.png',
- 'link' => 'toggle',
- 'pos' => 100,
- 'links' => array(),
- ) ;
-
- $obj['links'][] =
- array (
- 'txt' => _("Databases"),
- 'url' => "sql_list.php",
- );
- $obj['links'][] =
- array (
- 'txt' => _("MySQL Users"),
- 'url' => "sql_users_list.php",
- );
- if ($q["u"] > 0 ) {
- $obj['links'][] =
- array (
- 'txt' => _("PhpMyAdmin"),
- 'url' => "sql_pma_sso.php",
- 'target' => '_blank',
- );
- }
- return $obj;
- }
-
-
-
- /* ----------------------------------------------------------------- */
- /**
- * Password kind used in this class (hook for admin class)
- */
- function alternc_password_policy() {
- return array("mysql"=>"MySQL users");
- }
-
- /*---------------------------------------------------------------------------*/
- /** Get the list of the database for the current user.
- * @return array returns an associative array as follow :
- * "db" => database name "bck" => backup mode for this db
- * "dir" => Backup folder.
- * Returns an array (empty) if no databases
- */
- function get_dblist() {
- global $db,$err,$bro,$cuid;
- $err->log("mysql","get_dblist");
- $db->free();
- $db->query("SELECT login,pass,db, bck_mode, bck_dir FROM db WHERE uid='$cuid' ORDER BY db;");
- $c=array();
- while ($db->next_record()) {
- list($dbu,$dbn)=split_mysql_database_name($db->f("db"));
- $c[]=array("db"=>$db->f("db"), "name"=>$db->f('db'),"bck"=>$db->f("bck_mode"), "dir"=>$db->f("bck_dir"), "login"=>$db->f("login"), "pass"=>$db->f("pass"));
- }
- return $c;
- }
-
- /*---------------------------------------------------------------------------*/
- /** Get the login and password of the special user able to connect to phpmyadmin
- * @return array returns an associative array with login and password
- * Returns FALSE if error
- */
- function php_myadmin_connect(){
- global $db,$cuid,$err;
- $err->log("mysql","php_myadmin_connect");
- $db->query("SELECT dbu.name,dbu.password, dbs.host FROM dbusers dbu, db_servers dbs, membres m WHERE dbu.uid='$cuid' and enable='ADMIN' and dbs.id=m.db_server_id and m.uid='$cuid';");
- if (!$db->num_rows()) {
- $err->raise("mysql",_("Cannot connect to PhpMyAdmin"));
- return false;
- }
- $db->next_record();
- $info=array(
- "login"=>$db->f("name"),
- "pass"=>$db->f("password"),
- "host"=>$db->f("host")
- );
- return $info;
- }
-
-
- /*---------------------------------------------------------------------------*/
- /** Returns the details of a user's database.
- * $dbn is the name of the database (after the _) or nothing for the database "$user"
- * @return string returns an associative array as follow :
- * "db" => Name of the database
- * "bck" => Current bckup mode
- * "dir" => Backup directory
- * "size" => Size of the database (in bytes)
- * "pass" => Password of the user
- * "history" => Number of backup we keep
- * "gzip" => Does we compress the dumps ?
- * Returns FALSE if the user has no database of if the database does not exist.
- */
- function get_mysql_details($dbn) {
- global $db,$err,$bro,$mem,$cuid;
- $root=getuserpath();
- $err->log("mysql","get_mysql_details");
- $pos=strpos($dbn,'_');
- if($pos === false){
- $dbname=$dbn;
- }else{
- $dbncomp=explode('_',$dbn);
- $dbname=$dbn;
- $dbn=$dbncomp[1];
- }
- $size=$this->get_db_size($dbname);
- $db->query("SELECT login,pass,db, bck_mode, bck_gzip, bck_dir, bck_history FROM db WHERE uid='$cuid' AND db='$dbname';");
- if (!$db->num_rows()) {
- $err->raise("mysql",_("Database %s not found"),$dbn);
- return array("enabled"=>false);
- }
- $db->next_record();
- list($dbu,$dbn)=split_mysql_database_name($db->f("db"));
- return array("enabled"=>true,"login"=>$db->f("login"),"db"=>$db->f("db"), "name"=>$dbn,"bck"=>$db->f("bck_mode"), "dir"=>substr($db->f("bck_dir"),strlen($root)), "size"=>$size, "pass"=>$db->f("pass"), "history"=>$db->f("bck_history"), "gzip"=>$db->f("bck_gzip"));
- }
-
- function test_get_param($dbname){
- global $db,$err,$cuid;
- $db->query("SELECT ");
-
-
- }
-
- /*---------------------------------------------------------------------------*/
- /** Create a new database for the current user.
- * @param $dbn string Database name ($user_$dbn is the mysql db name)
- * @return boolean if the database $user_$db has been successfully created, or FALSE if
- * an error occured, such as over quota user.
- */
- function add_db($dbn) {
- global $db,$err,$quota,$mem,$cuid,$admin;
- $err->log("mysql","add_db",$dbn);
- $password_user="";
- if (!$quota->cancreate("mysql")) {
- $err->raise("mysql",_("Your databases quota is over. You cannot create more databases"));
- return false;
- }
- $pos=strpos($dbn,'_');
- if($pos === false){
- $dbname=$dbn;
- }else{
- $dbncomp=explode('_',$dbn);
- $dbname=$dbn;
- $dbn=$dbncomp[1];
- if (empty($dbn)) { // If nothing after the '_'
- $err->raise("mysql",_("Database can't have empty suffix"));
- return false;
- }
- }
- if (!preg_match("#^[0-9a-z]*$#",$dbn)) {
- $err->raise("mysql",_("Database name can contain only letters and numbers"));
- return false;
- }
-
-
- if (strlen($dbname) > 64) {
- $err->raise("mysql",_("Database name cannot exceed 64 characters"));
- return false;
- }
- $db->query("SELECT * FROM db WHERE db='$dbname';");
- if ($db->num_rows()) {
- $err->raise("mysql",_("Database %s already exists"),$dbn);
- return false;
- }
-
- $db->query("SELECT name from dbusers where name='".$dbname."' and enable='ACTIVATED' ;");
- if(!$db->num_rows()){
- $password_user=create_pass(8);
- if(!$this->add_user($dbn,$password_user,$password_user)){
- }
- }
-
- //checking for the phpmyadmin user
- $db->query("SELECT * FROM dbusers WHERE uid=$cuid AND enable='ADMIN';");
- if ($db->num_rows()) {
- $db->next_record();
- $myadm=$db->f("name");
- $password=$db->f("password");
- }else{
- $err->raise("mysql",_("There is a problem with the special PhpMyAdmin user. Contact the administrator"));
- return false;
- }
-
- //Grant the special user every rights.
- if ($this->dbus->query("CREATE DATABASE `$dbname`;")) {
- $err->log("mysql","add_db_succes",$dbn);
- // Ok, database does not exist, quota is ok and dbname is compliant. Let's proceed
- $db->query("INSERT INTO db (uid,login,pass,db,bck_mode) VALUES ('$cuid','$myadm','$password','$dbname',0);");
- $dbuser=$dbname;
- $dbname=str_replace('_','\_',$dbname);
- $this->grant($dbname,$myadm,"ALL PRIVILEGES",$password);
- if(!empty($password_user)){
- $this->grant($dbname,$dbuser,"ALL PRIVILEGES",$password_user);
- }
- $this->dbus->query("FLUSH PRIVILEGES;");
- return true;
- } else {
- $err->log("mysql","add_db",$dbn);
- $err->raise("mysql",_("An error occured. The database could not be created"));
- return false;
- }
- }
-
-
- /*---------------------------------------------------------------------------*/
- /** Delete a database for the current user.
- * @param $dbn string Name of the database to delete. The db name is $user_$dbn
- * @return boolean if the database $user_$db has been successfully deleted, or FALSE if
- * an error occured, such as db does not exist.
- */
- function del_db($dbn) {
- global $db,$err,$mem,$cuid;
- $err->log("mysql","del_db",$dbn);
- $dbname=addslashes($dbn);
- $db->query("SELECT uid FROM db WHERE db='$dbname';");
- if (!$db->num_rows()) {
- $err->raise("mysql",_("The database was not found. I can't delete it"));
- return false;
- }
- $db->next_record();
-
- // Ok, database exists and dbname is compliant. Let's proceed
- $db->query("DELETE FROM size_db WHERE db='$dbname';");
- $db->query("DELETE FROM db WHERE uid='$cuid' AND db='$dbname';");
- $this->dbus->query("DROP DATABASE `$dbname`;");
-
- $db_esc=str_replace('_','\_',$dbname);
- $this->dbus->query("DELETE FROM mysql.db WHERE Db='$db_esc';");
-
- #We test if the user created with the database is associated with more than 1 database.
- $this->dbus->query("select User from mysql.db where User='".$dbname."' and (Select_priv='Y' or Insert_priv='Y' or Update_priv='Y' or Delete_priv='Y' or Create_priv='Y' or Drop_priv='Y' or References_priv='Y' or Index_priv='Y' or Alter_priv='Y' or Create_tmp_table_priv='Y' or Lock_tables_priv='Y');");
- if(($this->dbus->num_rows()) == 0){
- #If not we can delete it.
- $this->del_user($dbname);
- }
- return true;
- }
-
-
-
-
- /*---------------------------------------------------------------------------*/
- /** Set the backup parameters for the database $db
- * @param $db string database name
- * @param $bck_mode integer Backup mode (0 = none 1 = daily 2 = weekly)
- * @param $bck_history integer How many backup should we keep ?
- * @param $bck_gzip boolean shall we compress the backup ?
- * @param $bck_dir string Directory relative to the user account where the backup will be stored
- * @return boolean true if the backup parameters has been successfully changed, false if not.
- */
- function put_mysql_backup($dbn,$bck_mode,$bck_history,$bck_gzip,$bck_dir) {
- global $db,$err,$mem,$bro,$cuid;
- $err->log("mysql","put_mysql_backup");
-
- if ( ! variable_get('sql_allow_users_backups') ) {
- $err->raise("mysql",_("User aren't allowed to configure their backups"));
- return false;
- }
-
- $pos=strpos($dbn,'_');
- if($pos === false){
- $dbname=$dbn;
- }else{
- $dbncomp=explode('_',$dbn);
- $dbname=$dbn;
- $dbn=$dbncomp[1];
- }
- if (!preg_match("#^[0-9a-z]*$#",$dbn)) {
- $err->raise("mysql",_("Database name can contain only letters and numbers"));
- return false;
- }
- $db->query("SELECT * FROM db WHERE uid='$cuid' AND db='$dbname';");
- if (!$db->num_rows()) {
- $err->raise("mysql",_("Database %s not found"),$dbn);
- return false;
- }
- $db->next_record();
- $bck_mode=intval($bck_mode);
- $bck_history=intval($bck_history);
- if ($bck_gzip)
- $bck_gzip="1";
- else
- $bck_gzip="0";
- if (!$bck_mode)
- $bck_mode="0";
- if (!$bck_history) {
- $err->raise("mysql",_("You have to choose how many backups you want to keep"));
- return false;
- }
- if (($bck_dir=$bro->convertabsolute($bck_dir,0))===false) { // return a full path or FALSE
- $err->raise("mysql",_("Directory does not exist"));
- return false;
- }
- $db->query("UPDATE db SET bck_mode='$bck_mode', bck_history='$bck_history', bck_gzip='$bck_gzip', bck_dir='$bck_dir' WHERE uid='$cuid' AND db='$dbname';");
- return true;
- }
-
-
- /*---------------------------------------------------------------------------*/
- /** Change the password of the user in MySQL
- * @param $password string new password (cleartext)
- * @return boolean TRUE if the password has been successfully changed, FALSE else.
- */
- function put_mysql_details($password) {
- global $db,$err,$mem,$cuid,$admin;
- $err->log("mysql","put_mysql_details");
- $db->query("SELECT * FROM db WHERE uid='$cuid';");
- if (!$db->num_rows()) {
- $err->raise("mysql",_("Database not found"));
- return false;
- }
- $db->next_record();
- $login=$db->f("login");
-
- if (!$password) {
- $err->raise("mysql",_("The password is mandatory"));
- return false;
- }
-
- if (strlen($password)>16) {
- $err->raise("mysql",_("MySQL password cannot exceed 16 characters"));
- return false;
- }
-
- // Check this password against the password policy using common API :
- if (is_callable(array($admin,"checkPolicy"))) {
- if (!$admin->checkPolicy("mysql",$login,$password)) {
- return false; // The error has been raised by checkPolicy()
- }
- }
-
- // Update all the "pass" fields for this user :
- $db->query("UPDATE db SET pass='$password' WHERE uid='$cuid';");
- $this->dbus->query("SET PASSWORD FOR ".$login."@".$this->dbus->Client." = PASSWORD('$password');");
- return true;
- }
-
- /**
- * Function used to grant SQL rights to users:
- * @base :database
- * @user : database user
- * @rights : rights to apply ( optional, every rights apply given if missing
- * @pass : user password ( optional, if not given the pass stays the same, else it takes the new value )
- * @table : sql tables to apply rights
- **/
- function grant($base,$user,$rights=null,$pass=null,$table='*'){
- global $err,$db;
- $err->log("mysql","grant",$base."-".$rights."-".$user);
-
- if(!preg_match("#^[0-9a-z_\\*\\\\]*$#",$base)){
- $err->raise("mysql",_("Database name can contain only letters and numbers"));
- return false;
- } elseif (!$this->dbus->query("select db from db where db='$base';")){
- $err->raise("mysql",_("Database not found"));
- return false;
- }
-
- if($rights==null){
- $rights='ALL PRIVILEGES';
- }elseif(!preg_match("#^[a-zA-Z,\s]*$#",$rights)){
- $err->raise("mysql",_("Databases rights are not correct"));
- return false;
- }
-
- if (!preg_match("#^[0-9a-z]#",$user)) {
- $err->raise("mysql",_("The username can contain only letters and numbers."));
- return false;
- }
- $db->query("select name from dbusers where name='".$user."' ;");
-
- if(!$db->num_rows()){
- $err->raise("mysql",_("Database user not found"));
- return false;
- }
-
- # Protect database name if not wildcard
- if ($base != '*' ) $base = "`".$base."`" ;
-
- $grant="grant ".$rights." on ".$base.".".$table." to '".$user."'@'".$this->dbus->Client."'" ;
-
- if($pass){
- $grant .= " identified by '".$pass."';";
- }else{
- $grant .= ";";
- }
- if(!$this->dbus->query($grant)){
- $err->raise("mysql",_("Could not grant rights"));
- return false;
- }
- return true;
-
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Restore a sql database.
- * @param $file string The filename, relative to the user root dir, which contains a sql dump
- * @param $stdout boolean shall-we dump the error to stdout ?
- * @param $id integer The ID of the database to dump to.
- * @return boolean TRUE if the database has been restored, or FALSE if an error occurred
- */
- function restore($file,$stdout,$id) {
- global $err,$bro,$mem,$L_MYSQL_HOST,$db;
- if (empty($file)) {
- $err->raise("mysql",_("No file specified"));
- return false;
- }
- if (!$r=$this->get_mysql_details($id)) {
- return false;
- }
- if (!($fi=$bro->convertabsolute($file,0))) {
- $err->raise("mysql",_("File not found"));
- return false;
- }
- if (!file_exists($fi)) {
- $err->raise("mysql",_("File not found"));
- return false;
- }
-
- if (substr($fi,-3)==".gz") {
- $exe="/bin/gzip -d -c <".escapeshellarg($fi)." | /usr/bin/mysql -h".escapeshellarg($this->dbus->Host)." -u".escapeshellarg($r["login"])." -p".escapeshellarg($r["pass"])." ".escapeshellarg($r["db"]);
- } elseif (substr($fi,-4)==".bz2") {
- $exe="/usr/bin/bunzip2 -d -c <".escapeshellarg($fi)." | /usr/bin/mysql -h".escapeshellarg($this->dbus->Host)." -u".escapeshellarg($r["login"])." -p".escapeshellarg($r["pass"])." ".escapeshellarg($r["db"]);
- } else {
- $exe="/usr/bin/mysql -h".escapeshellarg($this->dbus->Host)." -u".escapeshellarg($r["login"])." -p".escapeshellarg($r["pass"])." ".escapeshellarg($r["db"])." <".escapeshellarg($fi);
- }
- $exe .= " 2>&1";
-
- echo "" ;
- if ($stdout) {
- passthru($exe,$ret);
- } else {
- exec ($exe,$ret);
- }
- echo "" ;
- if ($ret != 0) {
- return false ;
- } else {
- return true ;
- }
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Get the size of a database
- * @param $dbname name of the database
- * @return integer database size
- * @access private
- */
- function get_db_size($dbname) {
- global $db,$err;
-
- $this->dbus->query("SHOW TABLE STATUS FROM `$dbname`;");
- $size = 0;
- while ($db->next_record()) {
- $size += $db->f('Data_length') + $db->f('Index_length');
- if ( $db->f('Engine') != 'InnoDB') $size += $db->f('Data_free');
- }
- return $size;
- }
-
-
- /* ------------------------------------------------------------ */
- /**
- * Returns the list of database users of an account
- **/
- function get_userslist($all=null) {
- global $db,$err,$bro,$cuid;
- $err->log("mysql","get_userslist");
- $c=array();
- if(!$all){
- $db->query("SELECT name FROM dbusers WHERE uid='$cuid' and enable not in ('ADMIN','HIDDEN') ORDER BY name;");
- }else{
- $db->query("SELECT name FROM dbusers WHERE uid='$cuid' ORDER BY name;");
- }
- while ($db->next_record()) {
- $pos=strpos($db->f("name"),"_");
- if($pos === false){
- $c[]=array("name"=>($db->f("name")));
- }else{
- $c[]=array("name"=>($db->f("name")));
- //$c[]=array("name"=>substr($db->f("name"),strpos($db->f("name"),"_")+1));
- }
- }
-
- return $c;
- }
-
- function get_defaultsparam($dbn){
- global $db,$err,$bro,$cuid;
- $err->log("mysql","getdefaults");
-
- $dbu=$dbn;
- $r=array();
- $dbn=str_replace('_','\_',$dbn);
- $this->dbus->query("Select * from mysql.db where Db='".$dbn."' and User!='".$cuid."_myadm';");
-
- if(!$db->num_rows()){
- return $r;
- }
- while ($db->next_record()) {
- $variable = $db->Record;
- if($variable['User'] == $dbu){
- $r['Host']=$db->f('Host');
-
- if($db->f('Select_priv') !== "Y"){
- return $r;
- }
- if($db->f('Insert_priv') !== "Y"){
- return $r;
- }
- if($db->f('Update_priv') !== "Y"){
- return $r;
- }
- if($db->f('Delete_priv') !== "Y"){
- return $r;
- }
- if($db->f('Create_priv') !== "Y"){
- return $r;
- }
- if($db->f('Drop_priv') !== "Y"){
- return $r;
- }
- if($db->f('References_priv') !== "Y"){
- return $r;
- }
- if($db->f('Index_priv') !== "Y"){
- return $r;
- }
- if($db->f('Alter_priv') !== "Y"){
- return $r;
- }
- if($db->f('Create_tmp_table_priv') !== "Y"){
- return $r;
- }
- if($db->f('Lock_tables_priv') !== "Y"){
- return $r;
- }
- if($db->f('Create_view_priv') !== "Y"){
- return $r;
- }
- if($db->f('Show_view_priv') !== "Y"){
- return $r;
- }
- if($db->f('Create_routine_priv') !== "Y"){
- return $r;
- }
- if($db->f('Alter_routine_priv') !== "Y"){
- return $r;
- }
- if($db->f('Execute_priv') !== "Y"){
- return $r;
- }
- if($db->f('Event_priv') !== "Y"){
- return $r;
- }
- if($db->f('Trigger_priv') !== "Y"){
- return $r;
- }
- }
- }//endwhile
- if(!$db->query("SELECT name,password from dbusers where name='".$dbu."';")){
- return $r;
- }
-
- if(!$db->num_rows()){
- return $r;
- }
- $db->next_record();
- $r['user']=$db->f('name');
- $r['password']=$db->f('password');
- return $r;
-
- }
-
-
- /* ------------------------------------------------------------ */
- /**
- * Create a new user in MySQL rights tables
- * @param $usern the username (we will add _[alternc-account] to it)
- * @param string $password The password for this username
- * @param string $passconf The password confirmation
- * @return boolean if the user has been created in MySQL or FALSE if an error occurred
- **/
- function add_user($usern,$password,$passconf) {
- global $db,$err,$quota,$mem,$cuid,$admin;
- $err->log("mysql","add_user",$usern);
-
- $usern=trim($usern);
- $login=$mem->user["login"];
- if($login != $usern){
- $user=addslashes($login."_".$usern);
- }else{
- $user=$usern;
- }
- $pass=addslashes($password);
-
- if (!$usern) {
- $err->raise("mysql",_("The username is mandatory"));
- return false;
- }
- if (!$pass) {
- $err->raise("mysql",_("The password is mandatory"));
- return false;
- }
- if (!preg_match("#^[0-9a-z]#",$usern)) {
- $err->raise("mysql",_("The username can contain only letters and numbers"));
- return false;
- }
-
-
- // We check the length of the COMPLETE username, not only the part after _
- if (strlen($user) > 16) {
- $err->raise("mysql",_("MySQL username cannot exceed 16 characters"));
- return false;
- }
- $db->query("SELECT * FROM dbusers WHERE name='$user';");
- if ($db->num_rows()) {
- $err->raise("mysql",_("The database user already exists"));
- return false;
- }
- if ($password != $passconf || !$password) {
- $err->raise("mysql",_("The passwords do not match"));
- return false;
- }
-
- // Check this password against the password policy using common API :
- if (is_callable(array($admin,"checkPolicy"))) {
- if (!$admin->checkPolicy("mysql",$user,$password)) {
- return false; // The error has been raised by checkPolicy()
- }
- }
-
- // We add him to the user table
- $db->query("INSERT INTO dbusers (uid,name,password,enable) VALUES($cuid,'$user','$password','ACTIVATED');");
-
- $this->grant("*",$user,"USAGE",$pass);
- return true;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Change a user's MySQL password
- * @param $usern the username
- * @param $password The password for this username
- * @param $passconf The password confirmation
- * @return boolean if the password has been changed in MySQL or FALSE if an error occurred
- **/
- function change_user_password($usern,$password,$passconf) {
- global $db,$err,$quota,$mem,$cuid,$admin;
- $err->log("mysql","change_user_pass",$usern);
-
- $usern=trim($usern);
- $user=addslashes($usern);
- $pass=addslashes($password);
- if ($password != $passconf || !$password) {
- $err->raise("mysql",_("The passwords do not match"));
- return false;
- }
-
- // Check this password against the password policy using common API :
- if (is_callable(array($admin,"checkPolicy"))) {
- if (!$admin->checkPolicy("mysql",$user,$password)) {
- return false; // The error has been raised by checkPolicy()
- }
- }
- $this->dbus->query("SET PASSWORD FOR '".$user."'@'".$this->dbus->Client."' = PASSWORD('".$pass."');");
- $db->query("UPDATE dbusers set password='".$pass."' where name='".$usern."' and uid=$cuid ;");
- return true;
- }
-
-
-
- /* ------------------------------------------------------------ */
- /**
- * Delete a user in MySQL rights tables
- * @param $user the username (we will add "[alternc-account]_" to it) to delete
- * @param integer $all
- * @return boolean if the user has been deleted in MySQL or FALSE if an error occurred
- **/
- function del_user($user,$all=null) {
- global $db,$err,$mem,$cuid;
- $err->log("mysql","del_user",$user);
- if (!preg_match("#^[0-9a-z]#",$user)) {
- $err->raise("mysql",_("The username can contain only letters and numbers"));
- return false;
- }
- if(!$all){
- $db->query("SELECT name FROM dbusers WHERE name='".$user."' and enable not in ('ADMIN','HIDDEN');");
- }else{
- $db->query("SELECT name FROM dbusers WHERE uid='".$cuid."' ;");
- }
-
- if (!$db->num_rows()) {
- $err->raise("mysql",_("The username was not found"));
- return false;
- }
- $db->next_record();
- $login=$db->f("name");
-
- // Ok, database exists and dbname is compliant. Let's proceed
- $this->dbus->query("REVOKE ALL PRIVILEGES ON *.* FROM '".$user."'@'".$this->dbus->Client."';");
- $this->dbus->query("DELETE FROM mysql.db WHERE User='".$user."' AND Host='".$this->dbus->Client."';");
- $this->dbus->query("DELETE FROM mysql.user WHERE User='".$user."' AND Host='".$this->dbus->Client."';");
- $this->dbus->query("FLUSH PRIVILEGES");
-
- $db->query("DELETE FROM dbusers WHERE uid='$cuid' AND name='".$user."';");
- return true;
- }
-
-
- /* ------------------------------------------------------------ */
- /**
- * Return the list of the database rights of user $user
- * @param $user the username
- * @return array An array of database name and rights
- **/
-
- function get_user_dblist($user){
- global $db,$err,$mem,$cuid;
-
- $this->dbus->query("SELECT * FROM mysql.user WHERE User='".$user."' AND Host='".$this->dbus->Client."';");
- if (!$this->dbus->next_record() ) {
- $err->raise('mysql',_("This user does not exist in the MySQL/User database"));
- return false;
- }
-
- $r=array();
- $db->free();
- $dblist=$this->get_dblist();
- foreach($dblist as $tab){
- $pos=strpos($tab['db'],"_");
- if($pos === false){
- $this->dbus->query("SELECT * FROM mysql.db WHERE User='".$user."' AND Host='".$this->dbus->Client."' AND Db='".$tab["db"]."';");
- }else{
- $dbname=str_replace('_','\_',$tab['db']);
- $this->dbus->query("SELECT * FROM mysql.db WHERE User='".$user."' AND Host='".$this->dbus->Client."' AND Db='".$dbname."';");
- }
- if ($this->dbus->next_record()){
- $r[]=array("db"=>$tab["db"], "select"=>$this->dbus->f("Select_priv"), "insert"=>$this->dbus->f("Insert_priv"), "update"=>$this->dbus->f("Update_priv"), "delete"=>$this->dbus->f("Delete_priv"), "create"=>$this->dbus->f("Create_priv"), "drop"=>$this->dbus->f("Drop_priv"), "references"=>$this->dbus->f("References_priv"), "index"=>$this->dbus->f("Index_priv"), "alter"=>$this->dbus->f("Alter_priv"), "create_tmp"=>$this->dbus->f("Create_tmp_table_priv"), "lock"=>$this->dbus->f("Lock_tables_priv"),
- "create_view"=>$this->dbus->f("Create_view_priv"),
- "show_view"=>$this->dbus->f("Show_view_priv"),
- "create_routine"=>$this->dbus->f("Create_routine_priv"),
- "alter_routine"=>$this->dbus->f("Alter_routine_priv"),
- "execute"=>$this->dbus->f("Execute_priv"),
- "event"=>$this->dbus->f("Event_priv"),
- "trigger"=>$this->dbus->f("Trigger_priv")
- );
- }else{
- $r[]=array("db"=>$tab['db'], "select"=>"N", "insert"=>"N", "update"=>"N", "delete"=>"N", "create"=>"N", "drop"=>"N", "references"=>"N", "index"=>"N", "alter"=>"N", "create_tmp"=>"N", "lock"=>"N","create_view"=>"N","show_view"=>"N","create_routine"=>"N","alter_routine"=>"N","execute"=>"N","event"=>"N","trigger"=>"N");
-
- }
-
- }
- return $r;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Set the access rights of user $user to database $dbn to be rights $rights
- * @param $user the username to give rights to
- * @param $dbn The database to give rights to
- * @param $rights The rights as an array of MySQL keywords (insert, select ...)
- * @return boolean TRUE if the rights has been applied or FALSE if an error occurred
- *
- **/
- function set_user_rights($user,$dbn,$rights) {
- global $mem,$err,$db;
- $err->log("mysql","set_user_rights");
-
- $usern=addslashes($user);
- $dbname=addslashes($dbn);
- $dbname=str_replace('_','\_',$dbname);
- // On génère les droits en fonction du tableau de droits
- $strrights="";
- for( $i=0 ; $idbus->query("SELECT * FROM mysql.db WHERE User = '$usern' AND Db = '$dbname';");
- if($this->dbus->num_rows())
- $this->dbus->query("REVOKE ALL PRIVILEGES ON `$dbname`.* FROM '$usern'@'".$this->dbus->Client."';");
- if( $strrights ){
- $strrights=substr($strrights,0,strlen($strrights)-1);
- $this->grant($dbname,$usern,$strrights);
- }
- $this->dbus->query("FLUSH PRIVILEGES");
- return TRUE;
- }
-
- function available_sql_rights(){
- return Array('select','insert','update','delete','create','drop','references','index','alter','create_tmp','lock','create_view','show_view','create_routine','alter_routine','execute','event','trigger');
-
-
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Hook function called by the lxc class to set mysql_host and port
- * parameters
- * @param $name string name of the quota
- * @return integer the number of service used or false if an error occured
- * @access private
- */
- function hook_lxc_params($params) {
- global $err;
- $err->log("mysql","alternc_get_quota");
- $p=array();
- if (isset($this->dbus["Host"]) && $this->dbus["Host"]!="") {
- $p["mysql_host"] = $this->dbus["Host"];
- $p["mysql_port"] = 3306;
- }
- return $p;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Hook function called by the quota class to compute user used quota
- * Returns the used quota for the $name service for the current user.
- * @param $name string name of the quota
- * @return integer the number of service used or false if an error occured
- * @access private
- */
- function hook_quota_get() {
- global $err,$db,$cuid;
- $err->log("mysql","alternc_get_quota");
- $q=Array("name"=>"mysql", "description"=>_("MySQL Databases"), "used"=>0);
- $c=$this->get_dblist();
- if (is_array($c)) {
- $q['used']=count($c);
- }
- return $q;
- }
-
- /* ----------------------------------------------------------------- */
- /** Hook function called when a user is created.
- * AlternC's standard function that create a member
- * @access private
- */
- function alternc_add_member() {
- global $db,$err,$cuid,$mem;
- $err->log("mysql","alternc_add_member");
- //checking for the phpmyadmin user
- $db->query("SELECT name,password FROM dbusers WHERE uid=$cuid AND Type='ADMIN';");
- if ($db->num_rows()) {
- $myadm=$db->f("name");
- $password=$db->f("password");
- }else{
- $myadm=$cuid."_myadm";
- $password=create_pass(8);
- }
-
-
- $db->query("INSERT INTO dbusers (uid,name,password,enable) VALUES ('$cuid','$myadm','$password','ADMIN');");
-
- return true;
- }
-
-
-
-
- /* ----------------------------------------------------------------- */
- /** Hook function called when a user is deleted.
- * AlternC's standard function that delete a member
- * @access private
- */
- function alternc_del_member() {
- global $db,$err,$cuid;
- $err->log("mysql","alternc_del_member");
- $c=$this->get_dblist();
- if (is_array($c)) {
- for($i=0;$idel_db($c[$i]["name"]);
- }
- }
- $d=$this->get_userslist(1);
- if (!empty($d)) {
- for($i=0;$idel_user($d[$i]["name"],1);
- }
- }
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Hook function called when a user is logged out.
- * We just remove the cookie created in admin/sql_admin.php
- a @access private
- */
- function alternc_del_session() {
- $_SESSION['PMA_single_signon_user'] = '';
- $_SESSION['PMA_single_signon_password'] = '';
- $_SESSION['PMA_single_signon_host'] = '';
- }
-
-
- /* ----------------------------------------------------------------- */
- /**
- * Exporte all the mysql information of an account
- * @access private
- * EXPERIMENTAL 'sid' function ;)
- */
- function alternc_export_conf() {
- //TODO don't work with separated sql server for dbusers
- global $db,$err,$cuid;
- $err->log("mysql","export");
- $db->query("SELECT login, pass, db, bck_mode, bck_dir, bck_history, bck_gzip FROM db WHERE uid='$cuid';");
- $str="";
- if ($db->next_record()) {
- $str.=" \n";
- $str.=" ".$db->Record["login"]." \n";
- $str.=" ".$db->Record["pass"]." \n";
- do {
- $filename=$tmpdir."/mysql.".$db->Record["db"].".sql.gz"; // FIXME not used
- $str.=" ".($db->Record["db"])." \n";
- $str.=" ".($db->Record["pass"])." \n";
- if ($s["bck_mode"]!=0) { // FIXME what is $s ?
- $str.=" ".($db->Record["bck_mode"])." \n";
- $str.=" ".($db->Record["bck_dir"])." \n";
- $str.=" ".($db->Record["bck_history"])." \n";
- $str.=" ".($db->Record["bck_gzip"])." \n";
+ /** Constructor
+ * m_mysql([$mid]) Constructeur de la classe m_mysql, initialise le membre concerne
+ */
+ function m_mysql() {
+ global $cuid;
+ if (!empty($cuid)) {
+ $this->dbus = new DB_users();
}
- } while ($db->next_record());
- $str.=" \n";
+ variable_get('sql_allow_users_backups', 1, 'Set 1 to allow users to configure backup of their databases, 0 if you want do disable this feature. Warning: it will not stop configured backup made by sqlbackup.sh');
}
- return $str;
- }
- /* ----------------------------------------------------------------- */
- /**
- * Exporte all the mysql databases a of give account to $dir directory
- * @access private
- * EXPERIMENTAL 'sid' function ;)
- */
- function alternc_export_data ($dir){
- global $db, $err, $cuid,$mem;
- $err->log("mysql","export_data");
- $db->query("SELECT db.login, db.pass, db.db, dbusers.name FROM db,dbusers WHERE db.uid='$cuid' AND dbusers.uid=db.uid;");
- $dir.="sql/";
- if(!is_dir($dir)){
- if(!mkdir($dir)){
- $err->raise('mysql',_("The directory could not be created"));
- }
+ function reload_dbus() {
+ $this->dbus = new DB_users();
}
- // on exporte toutes les bases utilisateur.
- while($db->next_record()){
- $filename=$dir."mysql.".$db->Record["db"].".".date("H:i:s").".sql.gz";
- exec ("/usr/bin/mysqldump --defaults-file=/etc/alternc/my.cnf --add-drop-table --allow-keywords -Q -f -q -a -e ".escapeshellarg($db->Record["db"])." |/bin/gzip >".escapeshellarg($filename));
+
+ function list_db_servers() {
+ global $db;
+ $db->query("select d.*, IFNULL(count(m.uid),0) as nb_users from db_servers d left join membres m on d.id = m.db_server_id group by d.id,m.db_server_id order by d.name,d.id;");
+ $c = array();
+ while ($db->next_record()) {
+ $c[] = $db->Record;
+ }
+ return $c;
}
- }
- /* ----------------------------------------------------------------- */
- /**
- * Return the size of each databases in a SQL Host given in parameter
- * @param $db_name the human name of the host
- * @param $db_host the host hosting the SQL databases
- * @param $db_login the login to access the SQL db
- * @param $db_password the password to access the SQL db
- * @param $db_client the client to access the SQL db
- * @return an array associating the name of the databases to their sizes : array(dbname=>size)
- */
- function get_dbus_size($db_name,$db_host,$db_login,$db_password,$db_client) {
- global $db,$err;
- $err->log("mysql","get_dbus_size",$db_host);
+ function hook_menu() {
+ global $quota;
+ $q = $quota->getquota("mysql");
- # We create the object with empty parameters
- $this->dbus=new DB_users(true);
- # Modify the object with right parameters
- $this->dbus->HumanHostname = $db_name;
- $this->dbus->Host = $db_host;
- $this->dbus->User = $db_login;
- $this->dbus->Password = $db_password;
- $this->dbus->Client = $db_client;
+ $obj = array(
+ 'title' => _("MySQL"),
+ 'ico' => 'images/mysql.png',
+ 'link' => 'toggle',
+ 'pos' => 100,
+ 'links' => array(),
+ );
- $this->dbus->query("show databases;");
- $res=array();
- while($this->dbus->next_record()) {
- $dbname=$this->dbus->f("Database");
- $c=mysql_query("SHOW TABLE STATUS FROM $dbname;");
- $size=0;
- while ($d=mysql_fetch_array($c)) {
- $size+=$d["Data_length"]+$d["Index_length"];
- }
- $res["$dbname"]="$size";
+ $obj['links'][] = array(
+ 'txt' => _("Databases"),
+ 'url' => "sql_list.php",
+ );
+ $obj['links'][] = array(
+ 'txt' => _("MySQL Users"),
+ 'url' => "sql_users_list.php",
+ );
+ if ($q["u"] > 0) {
+ $obj['links'][] = array(
+ 'txt' => _("PhpMyAdmin"),
+ 'url' => "sql_pma_sso.php",
+ 'target' => '_blank',
+ );
+ }
+ return $obj;
}
- return $res;
- }
-} /* Class m_mysql */
+ /* ----------------------------------------------------------------- */
-?>
+ /**
+ * Password kind used in this class (hook for admin class)
+ */
+ function alternc_password_policy() {
+ return array("mysql" => "MySQL users");
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Get the list of the database for the current user.
+ * @return array returns an associative array as follow :
+ * "db" => database name "bck" => backup mode for this db
+ * "dir" => Backup folder.
+ * Returns an array (empty) if no databases
+ */
+ function get_dblist() {
+ global $db, $err, $bro, $cuid;
+ $err->log("mysql", "get_dblist");
+ $db->free();
+ $db->query("SELECT login,pass,db, bck_mode, bck_dir FROM db WHERE uid='$cuid' ORDER BY db;");
+ $c = array();
+ while ($db->next_record()) {
+ list($dbu, $dbn) = split_mysql_database_name($db->f("db"));
+ $c[] = array("db" => $db->f("db"), "name" => $db->f('db'), "bck" => $db->f("bck_mode"), "dir" => $db->f("bck_dir"), "login" => $db->f("login"), "pass" => $db->f("pass"));
+ }
+ return $c;
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Get the login and password of the special user able to connect to phpmyadmin
+ * @return array returns an associative array with login and password
+ * Returns FALSE if error
+ */
+ function php_myadmin_connect() {
+ global $db, $cuid, $err;
+ $err->log("mysql", "php_myadmin_connect");
+ $db->query("SELECT dbu.name,dbu.password, dbs.host FROM dbusers dbu, db_servers dbs, membres m WHERE dbu.uid='$cuid' and enable='ADMIN' and dbs.id=m.db_server_id and m.uid='$cuid';");
+ if (!$db->num_rows()) {
+ $err->raise("mysql", _("Cannot connect to PhpMyAdmin"));
+ return false;
+ }
+ $db->next_record();
+ $info = array(
+ "login" => $db->f("name"),
+ "pass" => $db->f("password"),
+ "host" => $db->f("host")
+ );
+ return $info;
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Returns the details of a user's database.
+ * $dbn is the name of the database (after the _) or nothing for the database "$user"
+ * @return string returns an associative array as follow :
+ * "db" => Name of the database
+ * "bck" => Current bckup mode
+ * "dir" => Backup directory
+ * "size" => Size of the database (in bytes)
+ * "pass" => Password of the user
+ * "history" => Number of backup we keep
+ * "gzip" => Does we compress the dumps ?
+ * Returns FALSE if the user has no database of if the database does not exist.
+ */
+ function get_mysql_details($dbn) {
+ global $db, $err, $cuid;
+ $root = getuserpath();
+ $err->log("mysql", "get_mysql_details");
+ $pos = strpos($dbn, '_');
+ if ($pos === false) {
+ $dbname = $dbn;
+ } else {
+ $dbncomp = explode('_', $dbn);
+ $dbname = $dbn;
+ $dbn = $dbncomp[1];
+ }
+ $size = $this->get_db_size($dbname);
+ $db->query("SELECT login,pass,db, bck_mode, bck_gzip, bck_dir, bck_history FROM db WHERE uid='$cuid' AND db='$dbname';");
+ if (!$db->num_rows()) {
+ $err->raise("mysql", _("Database %s not found"), $dbn);
+ return array("enabled" => false);
+ }
+ $db->next_record();
+ list($dbu, $dbn) = split_mysql_database_name($db->f("db"));
+ return array("enabled" => true, "login" => $db->f("login"), "db" => $db->f("db"), "name" => $dbn, "bck" => $db->f("bck_mode"), "dir" => substr($db->f("bck_dir"), strlen($root)), "size" => $size, "pass" => $db->f("pass"), "history" => $db->f("bck_history"), "gzip" => $db->f("bck_gzip"));
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Create a new database for the current user.
+ * @param $dbn string Database name ($user_$dbn is the mysql db name)
+ * @return boolean if the database $user_$db has been successfully created, or FALSE if
+ * an error occured, such as over quota user.
+ */
+ function add_db($dbn) {
+ global $db, $err, $quota, $cuid;
+ $err->log("mysql", "add_db", $dbn);
+ $password_user = "";
+ if (!$quota->cancreate("mysql")) {
+ $err->raise("mysql", _("Your databases quota is over. You cannot create more databases"));
+ return false;
+ }
+ $pos = strpos($dbn, '_');
+ if ($pos === false) {
+ $dbname = $dbn;
+ } else {
+ $dbncomp = explode('_', $dbn);
+ $dbname = $dbn;
+ $dbn = $dbncomp[1];
+ if (empty($dbn)) { // If nothing after the '_'
+ $err->raise("mysql", _("Database can't have empty suffix"));
+ return false;
+ }
+ }
+ if (!preg_match("#^[0-9a-z]*$#", $dbn)) {
+ $err->raise("mysql", _("Database name can contain only letters and numbers"));
+ return false;
+ }
+
+ if (strlen($dbname) > 64) {
+ $err->raise("mysql", _("Database name cannot exceed 64 characters"));
+ return false;
+ }
+ $db->query("SELECT * FROM db WHERE db='$dbname';");
+ if ($db->num_rows()) {
+ $err->raise("mysql", _("Database %s already exists"), $dbn);
+ return false;
+ }
+
+ $db->query("SELECT name from dbusers where name='" . $dbname . "' and enable='ACTIVATED' ;");
+ if (!$db->num_rows()) {
+ $password_user = create_pass(8);
+ if (!$this->add_user($dbn, $password_user, $password_user)) {
+
+ }
+ }
+
+ //checking for the phpmyadmin user
+ $db->query("SELECT * FROM dbusers WHERE uid=$cuid AND enable='ADMIN';");
+ if ($db->num_rows()) {
+ $db->next_record();
+ $myadm = $db->f("name");
+ $password = $db->f("password");
+ } else {
+ $err->raise("mysql", _("There is a problem with the special PhpMyAdmin user. Contact the administrator"));
+ return false;
+ }
+
+ //Grant the special user every rights.
+ if ($this->dbus->query("CREATE DATABASE `$dbname`;")) {
+ $err->log("mysql", "add_db_succes", $dbn);
+ // Ok, database does not exist, quota is ok and dbname is compliant. Let's proceed
+ $db->query("INSERT INTO db (uid,login,pass,db,bck_mode) VALUES ('$cuid','$myadm','$password','$dbname',0);");
+ $dbuser = $dbname;
+ $dbname = str_replace('_', '\_', $dbname);
+ $this->grant($dbname, $myadm, "ALL PRIVILEGES", $password);
+ if (!empty($password_user)) {
+ $this->grant($dbname, $dbuser, "ALL PRIVILEGES", $password_user);
+ }
+ $this->dbus->query("FLUSH PRIVILEGES;");
+ return true;
+ } else {
+ $err->log("mysql", "add_db", $dbn);
+ $err->raise("mysql", _("An error occured. The database could not be created"));
+ return false;
+ }
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Delete a database for the current user.
+ * @param $dbn string Name of the database to delete. The db name is $user_$dbn
+ * @return boolean if the database $user_$db has been successfully deleted, or FALSE if
+ * an error occured, such as db does not exist.
+ */
+ function del_db($dbn) {
+ global $db, $err, $cuid;
+ $err->log("mysql", "del_db", $dbn);
+ $dbname = addslashes($dbn);
+ $db->query("SELECT uid FROM db WHERE db='$dbname';");
+ if (!$db->num_rows()) {
+ $err->raise("mysql", _("The database was not found. I can't delete it"));
+ return false;
+ }
+ $db->next_record();
+
+ // Ok, database exists and dbname is compliant. Let's proceed
+ $db->query("DELETE FROM size_db WHERE db='$dbname';");
+ $db->query("DELETE FROM db WHERE uid='$cuid' AND db='$dbname';");
+ $this->dbus->query("DROP DATABASE `$dbname`;");
+
+ $db_esc = str_replace('_', '\_', $dbname);
+ $this->dbus->query("DELETE FROM mysql.db WHERE Db='$db_esc';");
+
+ #We test if the user created with the database is associated with more than 1 database.
+ $this->dbus->query("select User from mysql.db where User='" . $dbname . "' and (Select_priv='Y' or Insert_priv='Y' or Update_priv='Y' or Delete_priv='Y' or Create_priv='Y' or Drop_priv='Y' or References_priv='Y' or Index_priv='Y' or Alter_priv='Y' or Create_tmp_table_priv='Y' or Lock_tables_priv='Y');");
+ if (($this->dbus->num_rows()) == 0) {
+ #If not we can delete it.
+ $this->del_user($dbname);
+ }
+ return true;
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Set the backup parameters for the database $db
+ * @param $dbn string database name
+ * @param $bck_mode integer Backup mode (0 = none 1 = daily 2 = weekly)
+ * @param $bck_history integer How many backup should we keep ?
+ * @param $bck_gzip boolean shall we compress the backup ?
+ * @param $bck_dir string Directory relative to the user account where the backup will be stored
+ * @return boolean true if the backup parameters has been successfully changed, false if not.
+ */
+ function put_mysql_backup($dbn, $bck_mode, $bck_history, $bck_gzip, $bck_dir) {
+ global $db, $err, $bro, $cuid;
+ $err->log("mysql", "put_mysql_backup");
+
+ if (!variable_get('sql_allow_users_backups')) {
+ $err->raise("mysql", _("User aren't allowed to configure their backups"));
+ return false;
+ }
+
+ $pos = strpos($dbn, '_');
+ if ($pos === false) {
+ $dbname = $dbn;
+ } else {
+ $dbncomp = explode('_', $dbn);
+ $dbname = $dbn;
+ $dbn = $dbncomp[1];
+ }
+ if (!preg_match("#^[0-9a-z]*$#", $dbn)) {
+ $err->raise("mysql", _("Database name can contain only letters and numbers"));
+ return false;
+ }
+ $db->query("SELECT * FROM db WHERE uid='$cuid' AND db='$dbname';");
+ if (!$db->num_rows()) {
+ $err->raise("mysql", _("Database %s not found"), $dbn);
+ return false;
+ }
+ $db->next_record();
+ $bck_mode = intval($bck_mode);
+ $bck_history = intval($bck_history);
+ if ($bck_gzip) {
+ $bck_gzip = "1";
+ } else {
+ $bck_gzip = "0";
+ }
+ if (!$bck_mode) {
+ $bck_mode = "0";
+ }
+ if (!$bck_history) {
+ $err->raise("mysql", _("You have to choose how many backups you want to keep"));
+ return false;
+ }
+ if (($bck_dir = $bro->convertabsolute($bck_dir, 0)) === false) { // return a full path or FALSE
+ $err->raise("mysql", _("Directory does not exist"));
+ return false;
+ }
+ $db->query("UPDATE db SET bck_mode='$bck_mode', bck_history='$bck_history', bck_gzip='$bck_gzip', bck_dir='$bck_dir' WHERE uid='$cuid' AND db='$dbname';");
+ return true;
+ }
+
+ /* --------------------------------------------------------------------------- */
+
+ /** Change the password of the user in MySQL
+ * @param $password string new password (cleartext)
+ * @return boolean TRUE if the password has been successfully changed, FALSE else.
+ */
+ function put_mysql_details($password) {
+ global $db, $err, $cuid, $admin;
+ $err->log("mysql", "put_mysql_details");
+ $db->query("SELECT * FROM db WHERE uid='$cuid';");
+ if (!$db->num_rows()) {
+ $err->raise("mysql", _("Database not found"));
+ return false;
+ }
+ $db->next_record();
+ $login = $db->f("login");
+
+ if (!$password) {
+ $err->raise("mysql", _("The password is mandatory"));
+ return false;
+ }
+
+ if (strlen($password) > 16) {
+ $err->raise("mysql", _("MySQL password cannot exceed 16 characters"));
+ return false;
+ }
+
+ // Check this password against the password policy using common API :
+ if (is_callable(array($admin, "checkPolicy"))) {
+ if (!$admin->checkPolicy("mysql", $login, $password)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ }
+
+ // Update all the "pass" fields for this user :
+ $db->query("UPDATE db SET pass='$password' WHERE uid='$cuid';");
+ $this->dbus->query("SET PASSWORD FOR " . $login . "@" . $this->dbus->Client . " = PASSWORD('$password');");
+ return true;
+ }
+
+ /**
+ * Function used to grant SQL rights to users:
+ * @base :database
+ * @user : database user
+ * @rights : rights to apply ( optional, every rights apply given if missing
+ * @pass : user password ( optional, if not given the pass stays the same, else it takes the new value )
+ * @table : sql tables to apply rights
+ * */
+ function grant($base, $user, $rights = null, $pass = null, $table = '*') {
+ global $err, $db;
+ $err->log("mysql", "grant", $base . "-" . $rights . "-" . $user);
+
+ if (!preg_match("#^[0-9a-z_\\*\\\\]*$#", $base)) {
+ $err->raise("mysql", _("Database name can contain only letters and numbers"));
+ return false;
+ } elseif (!$this->dbus->query("select db from db where db='$base';")) {
+ $err->raise("mysql", _("Database not found"));
+ return false;
+ }
+
+ if ($rights == null) {
+ $rights = 'ALL PRIVILEGES';
+ } elseif (!preg_match("#^[a-zA-Z,\s]*$#", $rights)) {
+ $err->raise("mysql", _("Databases rights are not correct"));
+ return false;
+ }
+
+ if (!preg_match("#^[0-9a-z]#", $user)) {
+ $err->raise("mysql", _("The username can contain only letters and numbers."));
+ return false;
+ }
+ $db->query("select name from dbusers where name='" . $user . "' ;");
+
+ if (!$db->num_rows()) {
+ $err->raise("mysql", _("Database user not found"));
+ return false;
+ }
+
+ # Protect database name if not wildcard
+ if ($base != '*') {
+ $base = "`" . $base . "`";
+ }
+ $grant = "grant " . $rights . " on " . $base . "." . $table . " to '" . $user . "'@'" . $this->dbus->Client . "'";
+
+ if ($pass) {
+ $grant .= " identified by '" . $pass . "';";
+ } else {
+ $grant .= ";";
+ }
+ if (!$this->dbus->query($grant)) {
+ $err->raise("mysql", _("Could not grant rights"));
+ return false;
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Restore a sql database.
+ * @param $file string The filename, relative to the user root dir, which contains a sql dump
+ * @param $stdout boolean shall-we dump the error to stdout ?
+ * @param $id integer The ID of the database to dump to.
+ * @return boolean TRUE if the database has been restored, or FALSE if an error occurred
+ */
+ function restore($file, $stdout, $id) {
+ global $err, $bro;
+ if (empty($file)) {
+ $err->raise("mysql", _("No file specified"));
+ return false;
+ }
+ if (!$r = $this->get_mysql_details($id)) {
+ return false;
+ }
+ if (!($fi = $bro->convertabsolute($file, 0))) {
+ $err->raise("mysql", _("File not found"));
+ return false;
+ }
+ if (!file_exists($fi)) {
+ $err->raise("mysql", _("File not found"));
+ return false;
+ }
+
+ if (substr($fi, -3) == ".gz") {
+ $exe = "/bin/gzip -d -c <" . escapeshellarg($fi) . " | /usr/bin/mysql -h" . escapeshellarg($this->dbus->Host) . " -u" . escapeshellarg($r["login"]) . " -p" . escapeshellarg($r["pass"]) . " " . escapeshellarg($r["db"]);
+ } elseif (substr($fi, -4) == ".bz2") {
+ $exe = "/usr/bin/bunzip2 -d -c <" . escapeshellarg($fi) . " | /usr/bin/mysql -h" . escapeshellarg($this->dbus->Host) . " -u" . escapeshellarg($r["login"]) . " -p" . escapeshellarg($r["pass"]) . " " . escapeshellarg($r["db"]);
+ } else {
+ $exe = "/usr/bin/mysql -h" . escapeshellarg($this->dbus->Host) . " -u" . escapeshellarg($r["login"]) . " -p" . escapeshellarg($r["pass"]) . " " . escapeshellarg($r["db"]) . " <" . escapeshellarg($fi);
+ }
+ $exe .= " 2>&1";
+
+ echo "";
+ $ret = 0;
+ if ($stdout) {
+ passthru($exe, $ret);
+ } else {
+ exec($exe, $ret);
+ }
+ echo "";
+ if ($ret != 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Get the size of a database
+ * @param $dbname name of the database
+ * @return integer database size
+ * @access private
+ */
+ function get_db_size($dbname) {
+ global $db;
+
+ $this->dbus->query("SHOW TABLE STATUS FROM `$dbname`;");
+ $size = 0;
+ while ($db->next_record()) {
+ $size += $db->f('Data_length') + $db->f('Index_length');
+ if ($db->f('Engine') != 'InnoDB') {
+ $size += $db->f('Data_free');
+ }
+ }
+ return $size;
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Returns the list of database users of an account
+ * */
+ function get_userslist($all = null) {
+ global $db, $err, $cuid;
+ $err->log("mysql", "get_userslist");
+ $c = array();
+ if (!$all) {
+ $db->query("SELECT name FROM dbusers WHERE uid='$cuid' and enable not in ('ADMIN','HIDDEN') ORDER BY name;");
+ } else {
+ $db->query("SELECT name FROM dbusers WHERE uid='$cuid' ORDER BY name;");
+ }
+ while ($db->next_record()) {
+ $pos = strpos($db->f("name"), "_");
+ if ($pos === false) {
+ $c[] = array("name" => ($db->f("name")));
+ } else {
+ $c[] = array("name" => ($db->f("name")));
+ //$c[]=array("name"=>substr($db->f("name"),strpos($db->f("name"),"_")+1));
+ }
+ }
+
+ return $c;
+ }
+
+ function get_defaultsparam($dbn) {
+ global $db, $err, $cuid;
+ $err->log("mysql", "getdefaults");
+
+ $dbu = $dbn;
+ $r = array();
+ $dbn = str_replace('_', '\_', $dbn);
+ $this->dbus->query("Select * from mysql.db where Db='" . $dbn . "' and User!='" . $cuid . "_myadm';");
+
+ if (!$db->num_rows()) {
+ return $r;
+ }
+ while ($db->next_record()) {
+ $variable = $db->Record;
+ if ($variable['User'] == $dbu) {
+ $r['Host'] = $db->f('Host');
+
+ if ($db->f('Select_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Insert_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Update_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Delete_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Create_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Drop_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('References_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Index_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Alter_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Create_tmp_table_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Lock_tables_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Create_view_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Show_view_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Create_routine_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Alter_routine_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Execute_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Event_priv') !== "Y") {
+ return $r;
+ }
+ if ($db->f('Trigger_priv') !== "Y") {
+ return $r;
+ }
+ }
+ } //endwhile
+ if (!$db->query("SELECT name,password from dbusers where name='" . $dbu . "';")) {
+ return $r;
+ }
+
+ if (!$db->num_rows()) {
+ return $r;
+ }
+ $db->next_record();
+ $r['user'] = $db->f('name');
+ $r['password'] = $db->f('password');
+ return $r;
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Create a new user in MySQL rights tables
+ * @param $usern the username (we will add _[alternc-account] to it)
+ * @param string $password The password for this username
+ * @param string $passconf The password confirmation
+ * @return boolean if the user has been created in MySQL or FALSE if an error occurred
+ * */
+ function add_user($usern, $password, $passconf) {
+ global $db, $err, $mem, $cuid, $admin;
+ $err->log("mysql", "add_user", $usern);
+
+ $usern = trim($usern);
+ $login = $mem->user["login"];
+ if ($login != $usern) {
+ $user = addslashes($login . "_" . $usern);
+ } else {
+ $user = $usern;
+ }
+ $pass = addslashes($password);
+
+ if (!$usern) {
+ $err->raise("mysql", _("The username is mandatory"));
+ return false;
+ }
+ if (!$pass) {
+ $err->raise("mysql", _("The password is mandatory"));
+ return false;
+ }
+ if (!preg_match("#^[0-9a-z]#", $usern)) {
+ $err->raise("mysql", _("The username can contain only letters and numbers"));
+ return false;
+ }
+
+ // We check the length of the COMPLETE username, not only the part after _
+ if (strlen($user) > 16) {
+ $err->raise("mysql", _("MySQL username cannot exceed 16 characters"));
+ return false;
+ }
+ $db->query("SELECT * FROM dbusers WHERE name='$user';");
+ if ($db->num_rows()) {
+ $err->raise("mysql", _("The database user already exists"));
+ return false;
+ }
+ if ($password != $passconf || !$password) {
+ $err->raise("mysql", _("The passwords do not match"));
+ return false;
+ }
+
+ // Check this password against the password policy using common API :
+ if (is_callable(array($admin, "checkPolicy"))) {
+ if (!$admin->checkPolicy("mysql", $user, $password)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ }
+
+ // We add him to the user table
+ $db->query("INSERT INTO dbusers (uid,name,password,enable) VALUES($cuid,'$user','$password','ACTIVATED');");
+
+ $this->grant("*", $user, "USAGE", $pass);
+ return true;
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Change a user's MySQL password
+ * @param $usern the username
+ * @param $password The password for this username
+ * @param $passconf The password confirmation
+ * @return boolean if the password has been changed in MySQL or FALSE if an error occurred
+ * */
+ function change_user_password($usern, $password, $passconf) {
+ global $db, $err, $cuid, $admin;
+ $err->log("mysql", "change_user_pass", $usern);
+
+ $usern = trim($usern);
+ $user = addslashes($usern);
+ $pass = addslashes($password);
+ if ($password != $passconf || !$password) {
+ $err->raise("mysql", _("The passwords do not match"));
+ return false;
+ }
+
+ // Check this password against the password policy using common API :
+ if (is_callable(array($admin, "checkPolicy"))) {
+ if (!$admin->checkPolicy("mysql", $user, $password)) {
+ return false; // The error has been raised by checkPolicy()
+ }
+ }
+ $this->dbus->query("SET PASSWORD FOR '" . $user . "'@'" . $this->dbus->Client . "' = PASSWORD('" . $pass . "');");
+ $db->query("UPDATE dbusers set password='" . $pass . "' where name='" . $usern . "' and uid=$cuid ;");
+ return true;
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Delete a user in MySQL rights tables
+ * @param $user the username (we will add "[alternc-account]_" to it) to delete
+ * @param integer $all
+ * @return boolean if the user has been deleted in MySQL or FALSE if an error occurred
+ * */
+ function del_user($user, $all = null) {
+ global $db, $err, $cuid;
+ $err->log("mysql", "del_user", $user);
+ if (!preg_match("#^[0-9a-z]#", $user)) {
+ $err->raise("mysql", _("The username can contain only letters and numbers"));
+ return false;
+ }
+ if (!$all) {
+ $db->query("SELECT name FROM dbusers WHERE name='" . $user . "' and enable not in ('ADMIN','HIDDEN');");
+ } else {
+ $db->query("SELECT name FROM dbusers WHERE uid='" . $cuid . "' ;");
+ }
+
+ if (!$db->num_rows()) {
+ $err->raise("mysql", _("The username was not found"));
+ return false;
+ }
+ $db->next_record();
+ $login = $db->f("name");
+
+ // Ok, database exists and dbname is compliant. Let's proceed
+ $this->dbus->query("REVOKE ALL PRIVILEGES ON *.* FROM '" . $user . "'@'" . $this->dbus->Client . "';");
+ $this->dbus->query("DELETE FROM mysql.db WHERE User='" . $user . "' AND Host='" . $this->dbus->Client . "';");
+ $this->dbus->query("DELETE FROM mysql.user WHERE User='" . $user . "' AND Host='" . $this->dbus->Client . "';");
+ $this->dbus->query("FLUSH PRIVILEGES");
+
+ $db->query("DELETE FROM dbusers WHERE uid='$cuid' AND name='" . $user . "';");
+ return true;
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Return the list of the database rights of user $user
+ * @param $user the username
+ * @return array An array of database name and rights
+ * */
+ function get_user_dblist($user) {
+ global $db, $err;
+
+ $this->dbus->query("SELECT * FROM mysql.user WHERE User='" . $user . "' AND Host='" . $this->dbus->Client . "';");
+ if (!$this->dbus->next_record()) {
+ $err->raise('mysql', _("This user does not exist in the MySQL/User database"));
+ return false;
+ }
+
+ $r = array();
+ $db->free();
+ $dblist = $this->get_dblist();
+ foreach ($dblist as $tab) {
+ $pos = strpos($tab['db'], "_");
+ if ($pos === false) {
+ $this->dbus->query("SELECT * FROM mysql.db WHERE User='" . $user . "' AND Host='" . $this->dbus->Client . "' AND Db='" . $tab["db"] . "';");
+ } else {
+ $dbname = str_replace('_', '\_', $tab['db']);
+ $this->dbus->query("SELECT * FROM mysql.db WHERE User='" . $user . "' AND Host='" . $this->dbus->Client . "' AND Db='" . $dbname . "';");
+ }
+ if ($this->dbus->next_record()) {
+ $r[] = array("db" => $tab["db"], "select" => $this->dbus->f("Select_priv"), "insert" => $this->dbus->f("Insert_priv"), "update" => $this->dbus->f("Update_priv"), "delete" => $this->dbus->f("Delete_priv"), "create" => $this->dbus->f("Create_priv"), "drop" => $this->dbus->f("Drop_priv"), "references" => $this->dbus->f("References_priv"), "index" => $this->dbus->f("Index_priv"), "alter" => $this->dbus->f("Alter_priv"), "create_tmp" => $this->dbus->f("Create_tmp_table_priv"), "lock" => $this->dbus->f("Lock_tables_priv"),
+ "create_view" => $this->dbus->f("Create_view_priv"),
+ "show_view" => $this->dbus->f("Show_view_priv"),
+ "create_routine" => $this->dbus->f("Create_routine_priv"),
+ "alter_routine" => $this->dbus->f("Alter_routine_priv"),
+ "execute" => $this->dbus->f("Execute_priv"),
+ "event" => $this->dbus->f("Event_priv"),
+ "trigger" => $this->dbus->f("Trigger_priv")
+ );
+ } else {
+ $r[] = array("db" => $tab['db'], "select" => "N", "insert" => "N", "update" => "N", "delete" => "N", "create" => "N", "drop" => "N", "references" => "N", "index" => "N", "alter" => "N", "create_tmp" => "N", "lock" => "N", "create_view" => "N", "show_view" => "N", "create_routine" => "N", "alter_routine" => "N", "execute" => "N", "event" => "N", "trigger" => "N");
+ }
+ }
+ return $r;
+ }
+
+ /* ------------------------------------------------------------ */
+
+ /**
+ * Set the access rights of user $user to database $dbn to be rights $rights
+ * @param $user the username to give rights to
+ * @param $dbn The database to give rights to
+ * @param $rights The rights as an array of MySQL keywords (insert, select ...)
+ * @return boolean TRUE if the rights has been applied or FALSE if an error occurred
+ *
+ * */
+ function set_user_rights($user, $dbn, $rights) {
+ global $err;
+ $err->log("mysql", "set_user_rights");
+
+ $usern = addslashes($user);
+ $dbname = addslashes($dbn);
+ $dbname = str_replace('_', '\_', $dbname);
+ // On genere les droits en fonction du tableau de droits
+ $strrights = "";
+ for ($i = 0; $i < count($rights); $i++) {
+ switch ($rights[$i]) {
+ case "select":
+ $strrights.="SELECT,";
+ break;
+ case "insert":
+ $strrights.="INSERT,";
+ break;
+ case "update":
+ $strrights.="UPDATE,";
+ break;
+ case "delete":
+ $strrights.="DELETE,";
+ break;
+ case "create":
+ $strrights.="CREATE,";
+ break;
+ case "drop":
+ $strrights.="DROP,";
+ break;
+ case "references":
+ $strrights.="REFERENCES,";
+ break;
+ case "index":
+ $strrights.="INDEX,";
+ break;
+ case "alter":
+ $strrights.="ALTER,";
+ break;
+ case "create_tmp":
+ $strrights.="CREATE TEMPORARY TABLES,";
+ break;
+ case "lock":
+ $strrights.="LOCK TABLES,";
+ break;
+ case "create_view":
+ $strrights.="CREATE VIEW,";
+ break;
+ case "show_view":
+ $strrights.="SHOW VIEW,";
+ break;
+ case "create_routine":
+ $strrights.="CREATE ROUTINE,";
+ break;
+ case "alter_routine":
+ $strrights.="ALTER ROUTINE,";
+ break;
+ case "execute":
+ $strrights.="EXECUTE,";
+ break;
+ case "event":
+ $strrights.="EVENT,";
+ break;
+ case "trigger":
+ $strrights.="TRIGGER,";
+ break;
+ }
+ }
+
+ // We reset all user rights on this DB :
+ $this->dbus->query("SELECT * FROM mysql.db WHERE User = '$usern' AND Db = '$dbname';");
+ if ($this->dbus->num_rows()) {
+ $this->dbus->query("REVOKE ALL PRIVILEGES ON `$dbname`.* FROM '$usern'@'" . $this->dbus->Client . "';");
+ }
+ if ($strrights) {
+ $strrights = substr($strrights, 0, strlen($strrights) - 1);
+ $this->grant($dbname, $usern, $strrights);
+ }
+ $this->dbus->query("FLUSH PRIVILEGES");
+ return TRUE;
+ }
+
+ function available_sql_rights() {
+ return Array('select', 'insert', 'update', 'delete', 'create', 'drop', 'references', 'index', 'alter', 'create_tmp', 'lock', 'create_view', 'show_view', 'create_routine', 'alter_routine', 'execute', 'event', 'trigger');
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Hook function called by the lxc class to set mysql_host and port
+ * parameters
+ * @access private
+ */
+ function hook_lxc_params($params) {
+ global $err;
+ $err->log("mysql", "alternc_get_quota");
+ $p = array();
+ if (isset($this->dbus["Host"]) && $this->dbus["Host"] != "") {
+ $p["mysql_host"] = $this->dbus["Host"];
+ $p["mysql_port"] = 3306;
+ }
+ return $p;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Hook function called by the quota class to compute user used quota
+ * Returns the used quota for the $name service for the current user.
+ * @param $name string name of the quota
+ * @return integer the number of service used or false if an error occured
+ * @access private
+ */
+ function hook_quota_get() {
+ global $err;
+ $err->log("mysql", "alternc_get_quota");
+ $q = Array("name" => "mysql", "description" => _("MySQL Databases"), "used" => 0);
+ $c = $this->get_dblist();
+ if (is_array($c)) {
+ $q['used'] = count($c);
+ }
+ return $q;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Hook function called when a user is created.
+ * AlternC's standard function that create a member
+ * @access private
+ */
+ function alternc_add_member() {
+ global $db, $err, $cuid, $mem;
+ $err->log("mysql", "alternc_add_member");
+ //checking for the phpmyadmin user
+ $db->query("SELECT name,password FROM dbusers WHERE uid=$cuid AND Type='ADMIN';");
+ if ($db->num_rows()) {
+ $myadm = $db->f("name");
+ $password = $db->f("password");
+ } else {
+ $myadm = $cuid . "_myadm";
+ $password = create_pass(8);
+ }
+
+
+ $db->query("INSERT INTO dbusers (uid,name,password,enable) VALUES ('$cuid','$myadm','$password','ADMIN');");
+
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Hook function called when a user is deleted.
+ * AlternC's standard function that delete a member
+ * @access private
+ */
+ function alternc_del_member() {
+ global $err;
+ $err->log("mysql", "alternc_del_member");
+ $c = $this->get_dblist();
+ if (is_array($c)) {
+ for ($i = 0; $i < count($c); $i++) {
+ $this->del_db($c[$i]["name"]);
+ }
+ }
+ $d = $this->get_userslist(1);
+ if (!empty($d)) {
+ for ($i = 0; $i < count($d); $i++) {
+ $this->del_user($d[$i]["name"], 1);
+ }
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Hook function called when a user is logged out.
+ * We just remove the cookie created in admin/sql_admin.php
+ a @access private
+ */
+ function alternc_del_session() {
+ $_SESSION['PMA_single_signon_user'] = '';
+ $_SESSION['PMA_single_signon_password'] = '';
+ $_SESSION['PMA_single_signon_host'] = '';
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Exporte all the mysql information of an account
+ * @access private
+ * EXPERIMENTAL 'sid' function ;)
+ */
+ function alternc_export_conf() {
+ //TODO don't work with separated sql server for dbusers
+ global $db, $err, $cuid;
+ $err->log("mysql", "export");
+ $db->query("SELECT login, pass, db, bck_mode, bck_dir, bck_history, bck_gzip FROM db WHERE uid='$cuid';");
+ $str = "";
+ if ($db->next_record()) {
+ $str.=" \n";
+ $str.=" " . $db->Record["login"] . " \n";
+ $str.=" " . $db->Record["pass"] . " \n";
+ do {
+ $filename = $tmpdir . "/mysql." . $db->Record["db"] . ".sql.gz"; // FIXME not used
+ $str.=" " . ($db->Record["db"]) . " \n";
+ $str.=" " . ($db->Record["pass"]) . " \n";
+ if ($s["bck_mode"] != 0) { // FIXME what is $s ?
+ $str.=" " . ($db->Record["bck_mode"]) . " \n";
+ $str.=" " . ($db->Record["bck_dir"]) . " \n";
+ $str.=" " . ($db->Record["bck_history"]) . " \n";
+ $str.=" " . ($db->Record["bck_gzip"]) . " \n";
+ }
+ } while ($db->next_record());
+ $str.=" \n";
+ }
+ return $str;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Exporte all the mysql databases a of give account to $dir directory
+ * @access private
+ * EXPERIMENTAL 'sid' function ;)
+ */
+ function alternc_export_data($dir) {
+ global $db, $err, $cuid;
+ $err->log("mysql", "export_data");
+ $db->query("SELECT db.login, db.pass, db.db, dbusers.name FROM db,dbusers WHERE db.uid='$cuid' AND dbusers.uid=db.uid;");
+ $dir.="sql/";
+ if (!is_dir($dir)) {
+ if (!mkdir($dir)) {
+ $err->raise('mysql', _("The directory could not be created"));
+ }
+ }
+ // on exporte toutes les bases utilisateur.
+ while ($db->next_record()) {
+ $filename = $dir . "mysql." . $db->Record["db"] . "." . date("H:i:s") . ".sql.gz";
+ exec("/usr/bin/mysqldump --defaults-file=/etc/alternc/my.cnf --add-drop-table --allow-keywords -Q -f -q -a -e " . escapeshellarg($db->Record["db"]) . " |/bin/gzip >" . escapeshellarg($filename));
+ }
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Return the size of each databases in a SQL Host given in parameter
+ * @param $db_name the human name of the host
+ * @param $db_host the host hosting the SQL databases
+ * @param $db_login the login to access the SQL db
+ * @param $db_password the password to access the SQL db
+ * @param $db_client the client to access the SQL db
+ * @return an array associating the name of the databases to their sizes : array(dbname=>size)
+ */
+ function get_dbus_size($db_name, $db_host, $db_login, $db_password, $db_client) {
+ global $err;
+ $err->log("mysql", "get_dbus_size", $db_host);
+
+ # We create the object with empty parameters
+ $this->dbus = new DB_users(true);
+ # Modify the object with right parameters
+ $this->dbus->HumanHostname = $db_name;
+ $this->dbus->Host = $db_host;
+ $this->dbus->User = $db_login;
+ $this->dbus->Password = $db_password;
+ $this->dbus->Client = $db_client;
+
+ $this->dbus->query("show databases;");
+ $res = array();
+ while ($this->dbus->next_record()) {
+ $dbname = $this->dbus->f("Database");
+ $c = mysql_query("SHOW TABLE STATUS FROM $dbname;");
+ $size = 0;
+ while ($d = mysql_fetch_array($c)) {
+ $size+=$d["Data_length"] + $d["Index_length"];
+ }
+ $res["$dbname"] = "$size";
+ }
+ return $res;
+ }
+
+}
+
+/* Class m_mysql */
diff --git a/bureau/class/m_quota.php b/bureau/class/m_quota.php
index 68ea15cb..8554cf91 100644
--- a/bureau/class/m_quota.php
+++ b/bureau/class/m_quota.php
@@ -1,4 +1,5 @@
disk_quota_enable = variable_get('disk_quota_enable', 1,'Are disk quota enabled for this server', array('desc'=>'Enabled','type'=>'boolean'));
- if ( $this->disk_quota_enable ) {
- $this->disk = Array( "web"=>"web" );
+ /**
+ * Constructor
+ */
+ function m_quota() {
+ $this->disk_quota_enable = variable_get('disk_quota_enable', 1, 'Are disk quota enabled for this server', array('desc' => 'Enabled', 'type' => 'boolean'));
+ if ($this->disk_quota_enable) {
+ $this->disk = Array("web" => "web");
+ }
}
- }
-
- private function dummy_for_translation() {
- _("quota_web");
- }
-
- function hook_menu() {
- $obj = array(
- 'title' => _("Show my quotas"),
- 'ico' => 'images/quota.png',
- 'link' => 'toggle',
- 'pos' => 110,
- 'divclass' => 'menu-quota',
- 'links' => array(),
- ) ;
-
- $q=$this->getquota();
-
- foreach ( array('web', 'bw_web') as $key ) {
- if ( ! isset($q[$key]["u"]) || empty($q[$key]["t"])) continue;
- $usage_percent = (int) ($q[$key]["u"] / $q[$key]["t"] * 100);
- $obj['links'][] = array( 'txt'=>_("quota_".$key) . " " . sprintf(_("%s%% of %s"),$usage_percent,format_size($q[$key]["t"]*1024)), 'url'=>($key == 'bw_web' ? 'stats_show_per_month.php' : 'quota_show.php') );
- $obj['links'][] = array( 'txt'=>'progressbar', 'total' => $q[$key]["t"], 'used' => $q[$key]["u"]);
- }
-
- return $obj;
- }
-
- /* ----------------------------------------------------------------- */
- /** Check if a user can use a ressource.
- * @param string $ressource the ressource name (a named quota)
- * @Return TRUE if the user can create a ressource (= is there any quota left ?)
- * @return boolean
- */
- function cancreate($ressource="") {
- $t=$this->getquota($ressource);
- return $t["u"]<$t["t"];
- }
-
-
- /* ----------------------------------------------------------------- */
- /** List the quota-managed services in the server
- * @Return array the quota names and description (translated)
- */
- function qlist() {
- global $classes,$hooks;
- $qlist=array();
- reset($this->disk);
- while (list($key,$val)=each($this->disk)) {
- $qlist[$key]=_("quota_".$key); // those are specific disks quotas.
+ private function dummy_for_translation() {
+ _("quota_web");
}
- foreach($this->getquota() as $qq) {
- if (isset($qq['name'])) {
- $qlist[$qq['name']]=$qq['description'];
- }
- }
- return $qlist;
- }
-
+ function hook_menu() {
+ $obj = array(
+ 'title' => _("Show my quotas"),
+ 'ico' => 'images/quota.png',
+ 'link' => 'toggle',
+ 'pos' => 110,
+ 'divclass' => 'menu-quota',
+ 'links' => array(),
+ );
- /**
- * Synchronise the quotas of the users with the quota of the
- * user's profile.
- * If the user have a greater quota than the profile, no change.
- * If the quota entry doesn't exist for the user, create it with
- * the defaults value.
- */
- function synchronise_user_profile() {
- global $db,$err;
- $err->log("quota","synchronise_user_profile");
- $q="insert into quotas select m.uid as uid, d.quota as name, d.value as total from membres m, defquotas d left join quotas q on q.name=d.quota where m.type=d.type ON DUPLICATE KEY UPDATE total = greatest(d.value, quotas.total);";
- if (!$db->query($q)) return false;
- return true;
- }
+ $q = $this->getquota();
- /*
- * Create default quota in the profile
- * when a new quota appear
- *
- */
- function create_missing_quota_profile() {
- global $db,$quota,$err;
- $err->log("quota","create_missing_quota_profile");
- $qt=$quota->getquota('',true);
- $type=$quota->listtype();
- foreach($type as $t) {
- foreach($qt as $q=>$vv) {
- $db->query("INSERT IGNORE defquotas (value,quota,type) VALUES (0,'$q','$t');");
- }
- }
- return true;
- }
-
- /* ----------------------------------------------------------------- */
- /** Return a ressource usage (u) and total quota (t)
- * @param string $ressource ressource to get quota of
- * @Return array the quota used and total for this ressource (or for all ressource if unspecified)
- */
- function getquota($ressource="",$recheck=false) {
- global $db,$err,$cuid,$get_quota_cache,$hooks,$mem;
- $err->log("quota","getquota",$ressource);
- if ($recheck) { // rebuilding quota
- $get_quota_cache=null;
- $this->quotas=array();
- }
- if (! empty($get_quota_cache[$cuid]) ) {
- // This function is called many time each webpage, so I cache the result
- $this->quotas = $get_quota_cache[$cuid];
- } else {
- $res=$hooks->invoke("hook_quota_get");
- foreach($res as $r) {
- $this->quotas[$r['name']]=$r;
- $this->quotas[$r['name']]['u']=$r['used']; // retrocompatibilité
- $this->quotas[$r['name']]['t']=0; // Default quota = 0
- }
- reset($this->disk);
-
- if (!empty ($this->disk)) { // Check if there are some disk quota to check
- // Look if there are some cached value
- $disk_cached = $mem->session_tempo_params_get('quota_cache_disk');
-
- while (list($key,$val)=each($this->disk)) {
- $a=array();
- if (
- isset($disk_cached[$val])
- && !empty($disk_cached[$val])
- && $disk_cached[$val]['uid'] == $cuid
- && $disk_cached[$val]['timestamp'] > ( time() - (90) ) // Cache, en seconde
- ) {
- // If there is a cached value
- $a = $disk_cached[$val];
- } else {
- exec("/usr/lib/alternc/quota_get ".intval($cuid) ,$ak);
- $a['u']=intval($ak[0]);
- $a['t']=@intval($ak[1]);
- $a['timestamp'] = time();
- $a['uid'] = $cuid;
- $disk_cached = $mem->session_tempo_params_set('quota_cache_disk', array($val=>$a));
+ foreach (array('web', 'bw_web') as $key) {
+ if (!isset($q[$key]["u"]) || empty($q[$key]["t"])) {
+ continue;
}
- $this->quotas[$val]=array("name"=>"$val", 'description'=>_("quota_".$val), "t"=>$a['t'],"u"=>$a['u']);
- }
+ $usage_percent = (int) ($q[$key]["u"] / $q[$key]["t"] * 100);
+ $obj['links'][] = array('txt' => _("quota_" . $key) . " " . sprintf(_("%s%% of %s"), $usage_percent, format_size($q[$key]["t"] * 1024)), 'url' => ($key == 'bw_web' ? 'stats_show_per_month.php' : 'quota_show.php'));
+ $obj['links'][] = array('txt' => 'progressbar', 'total' => $q[$key]["t"], 'used' => $q[$key]["u"]);
}
- // Get the allowed quota from database.
- $db->query("select name, total from quotas where uid='$cuid';");
- while ( $db->next_record() ) {
- $this->quotas[$db->f('name')]['t']=$db->f('total');
+ return $obj;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Check if a user can use a ressource.
+ * @param string $ressource the ressource name (a named quota)
+ * @Return TRUE if the user can create a ressource (= is there any quota left ?)
+ * @return boolean
+ */
+ function cancreate($ressource = "") {
+ $t = $this->getquota($ressource);
+ return $t["u"] < $t["t"];
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** List the quota-managed services in the server
+ * @Return array the quota names and description (translated)
+ */
+ function qlist() {
+ $qlist = array();
+ reset($this->disk);
+ while (list($key, $val) = each($this->disk)) {
+ $qlist[$key] = _("quota_" . $key); // those are specific disks quotas.
}
- $get_quota_cache[$cuid] = $this->quotas;
- }
-
- if ($ressource) {
- if (isset($this->quotas[$ressource]) ) {
- return $this->quotas[$ressource];
- } else {
- return 0;
- }
- } else {
- return $this->quotas;
- }
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Set the quota for a user (and for a ressource)
- * @param string $ressource ressource to set quota of
- * @param integer size of the quota (available or used)
- */
- function setquota($ressource,$size) {
- global $err,$db,$cuid;
- $err->log("quota","setquota",$ressource."/".$size);
- if (floatval($size)==0) $size="0";
- if (isset($this->disk[$ressource])) {
- // It's a disk resource, update it with shell command
- exec("sudo /usr/lib/alternc/quota_edit ".intval($cuid)." ".intval($size)." &> /dev/null &");
- // Now we check that the value has been written properly :
- exec("sudo /usr/lib/alternc/quota_get ".intval($cuid)." &> /dev/null &",$a);
- if (!isset($a[1]) || $size!=$a[1]) {
- $err->raise("quota",_("Error writing the quota entry!"));
- return false;
- }
- }
- // We check that this ressource exists for this client :
- $db->query("SELECT * FROM quotas WHERE uid='$cuid' AND name='$ressource'");
- if ($db->num_rows()) {
- $db->query("UPDATE quotas SET total='$size' WHERE uid='$cuid' AND name='$ressource';");
- } else {
- $db->query("INSERT INTO quotas (uid,name,total) VALUES ('$cuid','$ressource','$size');");
- }
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /**
- * Erase all quota information about the user.
- */
- function delquotas() {
- global $db,$err,$cuid;
- $err->log("quota","delquota");
- $db->query("DELETE FROM quotas WHERE uid='$cuid';");
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Get the default quotas as an associative array
- * @return array the array of the default quotas
- */
- function getdefaults() {
- global $db;
- $c=array();
-
- $db->query("SELECT type,quota FROM defquotas WHERE type='default'");
- if(!$db->next_record())
- $this->addtype('default');
-
- $db->query("SELECT value,quota,type FROM defquotas ORDER BY type,quota");
- while($db->next_record()) {
- $type = $db->f("type");
- $c[$type][$db->f("quota")] = $db->f("value");
- }
- return $c;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Set the default quotas
- * @param array associative array of quota (key=>val)
- */
- function setdefaults($newq) {
- global $db;
- $qlist=$this->qlist();
-
- foreach($newq as $type => $quotas) {
- foreach($quotas as $qname => $value) {
- if(array_key_exists($qname, $qlist)) {
- if(!$db->query("REPLACE INTO defquotas (value,quota,type) VALUES ($value,'$qname','$type');"))
- return false;
- }
- }
- }
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Add an account type for quotas
- * @param string $type account type to be added
- * @return boolean true if all went ok
- */
- function addtype($type) {
- global $db,$err;
- $qlist=$this->qlist();
- if(empty($type)) return false;
- $type=strtolower($type);
- if (!preg_match("#^[a-z0-9]*$#",$type)) {
- $err->raise("quota", "Type can only contains characters a-z and 0-9");
- return false;
- }
- while (list($key,$val)=each($qlist)) {
- if(!$db->query("INSERT IGNORE INTO defquotas (quota,type) VALUES('$key', '$type');")
- || $db->affected_rows() == 0)
- return false;
- }
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** List for quotas
- * @return array
- */
- function listtype() {
- global $db;
- $db->query("SELECT distinct(type) FROM defquotas ORDER by type");
- $t=array();
- while ($db->next_record()) {
- $t[] = $db->f("type");
- }
- return $t;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Delete an account type for quotas
- * @param string $type account type to be deleted
- * @return boolean true if all went ok
- */
- function deltype($type) {
- global $db;
-
- if($db->query("UPDATE membres SET type='default' WHERE type='$type'") &&
- $db->query("DELETE FROM defquotas WHERE type='$type'")) {
- return true;
- } else {
- return false;
- }
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Create default quotas entries for a new user.
- * The user we are talking about is in the global $cuid.
- */
- function addquotas() {
- global $db,$err,$cuid;
- $err->log("quota","addquota");
- $ql=$this->qlist();
- reset($ql);
-
- $db->query("SELECT type,quota FROM defquotas WHERE type='default'");
- if(!$db->next_record())
- $this->addtype('default');
-
- $db->query("SELECT type FROM membres WHERE uid='$cuid'");
- $db->next_record();
- $t = $db->f("type");
-
- foreach($ql as $res => $val) {
- $db->query("SELECT value FROM defquotas WHERE quota='$res' AND type='$t'");
- $q = $db->next_record() ? $db->f("value") : 0;
- $this->setquota($res, $q);
- }
- return true;
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Return a quota value with its unit (when it is a space quota)
- * in MB, GB, TB ...
- * @param string $type The quota type
- * @param integer $value The quota value
- * @return string a quota value with its unit.
- */
- function display_val($type, $value) {
- switch ($type) {
- case 'bw_web':
- return format_size($value);
- case 'web':
- return format_size($value*1024);
- default:
- return $value;
- }
- }
-
-
- /* get size_xx function (filled by spoolsize.php) */
- function _get_sum_sql($sql) {
- global $db,$err,$cuid;
- $db->query($sql);
- if ($db->num_rows() == 0) {
- return -1;
- } else {
- $db->next_record();
- $r = $db->Record;
- return $r['sum'];
- }
- }
-
- function _get_count_sql($sql) {
- global $db,$err,$cuid;
- $db->query($sql);
- if ($db->num_rows() == 0) {
- return 0;
- } else {
- $db->next_record();
- $r = $db->Record;
- return $r['count'];
- }
- }
-
- function _get_size_and_record_sql($sql) {
- global $db,$err,$cuid;
- $db->query($sql);
- if ($db->num_rows() == 0) {
- return array();
- } else {
- $ret = array();
- while ($db->next_record()) {
- $ret[] = $db->Record;
- }
- return $ret;
- }
- }
-
- /* sum of websites sizes from all users */
- function get_size_web_sum_all() {
- return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_web;");
- }
-
- /* sum of websites sizes from one user */
- function get_size_web_sum_user($u) {
- return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_web WHERE uid='$u';");
- }
-
- /* sum of mailbox sizes from all domains */
- function get_size_mail_sum_all() {
- return $this->_get_sum_sql("SELECT SUM(bytes) AS sum FROM mailbox;");
- }
-
- /* sum of mailbox sizes for one domain */
- function get_size_mail_sum_domain($dom) {
- global $mail;
- return $mail->get_total_size_for_domain($dom);
- }
-
- /* count of mailbox sizes from all domains */
- function get_size_mail_count_all() {
- return $this->_get_count_sql("SELECT COUNT(*) AS count FROM mailbox;");
- }
-
- /* count of mailbox for one domain */
- function get_size_mail_count_domain($dom) {
- return $this->_get_count_sql("SELECT COUNT(*) AS count FROM dovecot_view WHERE user LIKE '%@{$dom}'");
- }
-
- /* get list of mailbox alias and size for one domain */
- function get_size_mail_details_domain($dom) {
- return $this->_get_size_and_record_sql("SELECT user as alias,quota_dovecot as size FROM dovecot_view WHERE user LIKE '%@{$dom}' ORDER BY alias;");
- }
-
- /* sum of mailman lists sizes from all domains */
- function get_size_mailman_sum_all() {
- return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman;");
- }
-
- /* sum of mailman lists sizes for one domain */
- function get_size_mailman_sum_domain($dom) {
- return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman WHERE list LIKE '%@{$dom}'");
- }
-
- /* sum of mailman lists for one user */
- function get_size_mailman_sum_user($u) {
- return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman WHERE uid = '{$u}'");
- }
-
- /* count of mailman lists sizes from all domains */
- function get_size_mailman_count_all() {
- return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_mailman;");
- }
-
- /* count of mailman lists for one user */
- function get_size_mailman_count_user($u) {
- return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_mailman WHERE uid = '{$u}'");
- }
-
- /* get list of mailman list and size for one user */
- function get_size_mailman_details_user($u) {
- return $this->_get_size_and_record_sql("SELECT s.size,CONCAT(m.list,'@',m.domain) as list FROM size_mailman s LEFT JOIN mailman m ON s.list=m.name WHERE s.uid='{$u}' ORDER BY s.list ASC");
- }
-
- /* sum of databases sizes from all users */
- function get_size_db_sum_all() {
- return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_db;");
- }
-
- /* sum of databases sizes for one user */
- function get_size_db_sum_user($u) {
- return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_db WHERE db = '{$u}' OR db LIKE '{$u}\_%'");
- }
-
- /* count of databases from all users */
- function get_size_db_count_all() {
- return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_db;");
- }
-
- /* count of databases for one user */
- function get_size_db_count_user($u) {
- return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_db WHERE db = '{$u}' OR db LIKE '{$u}\_%'");
- }
-
- /* get list of databases name and size for one user */
- function get_size_db_details_user($u) {
- return $this->_get_size_and_record_sql("SELECT db,size FROM size_db WHERE db='{$u}' OR db LIKE '{$u}\_%';");
- }
-
- /* Return appropriate value and unit of a size given in Bytes (e.g. 1024 Bytes -> return 1 KB) */
- function get_size_unit($size) {
- $units=array(1073741824=>_("GB"), 1048576=>_("MB"), 1024=>_("KB"), 0=>_("B"));
- foreach($units as $value=>$unit){
- if($size>=$value){
- $size=str_pad(round($size/($value ? $value : 1), 1), 5, ' ', STR_PAD_LEFT);
- return array('size'=>$size, 'unit'=>$unit);
- }
- }
- }
-
- // Affiche des barres de progression
- // color_type :
- // 0 = Pas de changement de couleur
- // 1 = Progression du vert vers le rouge en fonction du porcentage
- // 2 = Progression du rouge vers le vert en fonction du porcentage
- function quota_displaybar($usage, $color_type=1) {
- if ($color_type == 1) {
- $csscolor = " background-color:".PercentToColor($usage);
- } elseif ($color_type == 2) {
- $csscolor = " background-color:".PercentToColor(100-$usage);
- } else {
- $csscolor = "";
+ foreach ($this->getquota() as $qq) {
+ if (isset($qq['name'])) {
+ $qlist[$qq['name']] = $qq['description'];
+ }
+ }
+ return $qlist;
}
-
- echo '';
- }
-
-
- /* ==== Hook functions ==== */
-
- /* ----------------------------------------------------------------- */
- /** Hook function call when a user is deleted
- * AlternC's standard function called when a user is deleted
- * globals $cuid is the appropriate user
- */
- function hook_admin_del_member() {
- $this->delquotas();
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Hook function called when a user is created
- * This function initialize the user's quotas.
- * globals $cuid is the appropriate user
- */
- function hook_admin_add_member() {
- global $err;
- $err->log("quota","hook_admin_add_member");
- $this->addquotas();
- $this->getquota('',true); // actualise quota
- }
-
-
- /* ----------------------------------------------------------------- */
- /** Exports all the quota related information for an account.
- * @access private
- * EXPERIMENTAL function ;)
- */
- function alternc_export_conf() {
- global $db,$err;
- $err->log("quota","export");
- $str=" ";
-
- $q=$this->getquota();
- foreach ($q as $k=>$v) {
- $str.=" <$k>\n";
- $str.=" ".($v["u"])." \n";
- $str.=" ".($v["t"])." \n";
- $str.=" $k>\n";
+ /**
+ * Synchronise the quotas of the users with the quota of the
+ * user's profile.
+ * If the user have a greater quota than the profile, no change.
+ * If the quota entry doesn't exist for the user, create it with
+ * the defaults value.
+ */
+ function synchronise_user_profile() {
+ global $db, $err;
+ $err->log("quota", "synchronise_user_profile");
+ $q = "insert into quotas select m.uid as uid, d.quota as name, d.value as total from membres m, defquotas d left join quotas q on q.name=d.quota where m.type=d.type ON DUPLICATE KEY UPDATE total = greatest(d.value, quotas.total);";
+ if (!$db->query($q)) {
+ return false;
+ }
+ return true;
}
- $str.=" \n";
- return $str;
- }
+
+ /*
+ * Create default quota in the profile
+ * when a new quota appear
+ *
+ */
+
+ function create_missing_quota_profile() {
+ global $db, $quota, $err;
+ $err->log("quota", "create_missing_quota_profile");
+ $qt = $quota->getquota('', true);
+ $type = $quota->listtype();
+ foreach ($type as $t) {
+ foreach ($qt as $q => $vv) {
+ $db->query("INSERT IGNORE defquotas (value,quota,type) VALUES (0,'$q','$t');");
+ }
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Return a ressource usage (u) and total quota (t)
+ * @param string $ressource ressource to get quota of
+ * @Return array the quota used and total for this ressource (or for all ressource if unspecified)
+ */
+ function getquota($ressource = "", $recheck = false) {
+ global $db, $err, $cuid, $get_quota_cache, $hooks, $mem;
+ $err->log("quota", "getquota", $ressource);
+ if ($recheck) { // rebuilding quota
+ $get_quota_cache = null;
+ $this->quotas = array();
+ }
+ if (!empty($get_quota_cache[$cuid])) {
+ // This function is called many time each webpage, so I cache the result
+ $this->quotas = $get_quota_cache[$cuid];
+ } else {
+ $res = $hooks->invoke("hook_quota_get");
+ foreach ($res as $r) {
+ $this->quotas[$r['name']] = $r;
+ $this->quotas[$r['name']]['u'] = $r['used']; // retrocompatibilité
+ $this->quotas[$r['name']]['t'] = 0; // Default quota = 0
+ }
+ reset($this->disk);
+
+ if (!empty($this->disk)) { // Check if there are some disk quota to check
+ // Look if there are some cached value
+ $disk_cached = $mem->session_tempo_params_get('quota_cache_disk');
+
+ while (list($key, $val) = each($this->disk)) {
+ $a = array();
+ if (
+ isset($disk_cached[$val]) && !empty($disk_cached[$val]) && $disk_cached[$val]['uid'] == $cuid && $disk_cached[$val]['timestamp'] > ( time() - (90) ) // Cache, en seconde
+ ) {
+ // If there is a cached value
+ $a = $disk_cached[$val];
+ } else {
+ exec("/usr/lib/alternc/quota_get " . intval($cuid), $ak);
+ $a['u'] = intval($ak[0]);
+ $a['t'] = @intval($ak[1]);
+ $a['timestamp'] = time();
+ $a['uid'] = $cuid;
+ $disk_cached = $mem->session_tempo_params_set('quota_cache_disk', array($val => $a));
+ }
+ $this->quotas[$val] = array("name" => "$val", 'description' => _("quota_" . $val), "t" => $a['t'], "u" => $a['u']);
+ }
+ }
+
+ // Get the allowed quota from database.
+ $db->query("select name, total from quotas where uid='$cuid';");
+ while ($db->next_record()) {
+ $this->quotas[$db->f('name')]['t'] = $db->f('total');
+ }
+
+ $get_quota_cache[$cuid] = $this->quotas;
+ }
+
+ if ($ressource) {
+ if (isset($this->quotas[$ressource])) {
+ return $this->quotas[$ressource];
+ } else {
+ return 0;
+ }
+ } else {
+ return $this->quotas;
+ }
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Set the quota for a user (and for a ressource)
+ * @param string $ressource ressource to set quota of
+ * @param integer size of the quota (available or used)
+ */
+ function setquota($ressource, $size) {
+ global $err, $db, $cuid;
+ $err->log("quota", "setquota", $ressource . "/" . $size);
+ if (floatval($size) == 0) {
+ $size = "0";
+ }
+ if (isset($this->disk[$ressource])) {
+ // It's a disk resource, update it with shell command
+ exec("sudo /usr/lib/alternc/quota_edit " . intval($cuid) . " " . intval($size) . " &> /dev/null &");
+ // Now we check that the value has been written properly :
+ $a = array();
+ exec("sudo /usr/lib/alternc/quota_get " . intval($cuid) . " &> /dev/null &", $a);
+ if (!isset($a[1]) || $size != $a[1]) {
+ $err->raise("quota", _("Error writing the quota entry!"));
+ return false;
+ }
+ }
+ // We check that this ressource exists for this client :
+ $db->query("SELECT * FROM quotas WHERE uid='$cuid' AND name='$ressource'");
+ if ($db->num_rows()) {
+ $db->query("UPDATE quotas SET total='$size' WHERE uid='$cuid' AND name='$ressource';");
+ } else {
+ $db->query("INSERT INTO quotas (uid,name,total) VALUES ('$cuid','$ressource','$size');");
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /**
+ * Erase all quota information about the user.
+ */
+ function delquotas() {
+ global $db, $err, $cuid;
+ $err->log("quota", "delquota");
+ $db->query("DELETE FROM quotas WHERE uid='$cuid';");
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Get the default quotas as an associative array
+ * @return array the array of the default quotas
+ */
+ function getdefaults() {
+ global $db;
+ $c = array();
+
+ $db->query("SELECT type,quota FROM defquotas WHERE type='default'");
+ if (!$db->next_record()) {
+ $this->addtype('default');
+ }
+ $db->query("SELECT value,quota,type FROM defquotas ORDER BY type,quota");
+ while ($db->next_record()) {
+ $type = $db->f("type");
+ $c[$type][$db->f("quota")] = $db->f("value");
+ }
+ return $c;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Set the default quotas
+ * @param array associative array of quota (key=>val)
+ */
+ function setdefaults($newq) {
+ global $db;
+ $qlist = $this->qlist();
+
+ foreach ($newq as $type => $quotas) {
+ foreach ($quotas as $qname => $value) {
+ if (array_key_exists($qname, $qlist)) {
+ if (!$db->query("REPLACE INTO defquotas (value,quota,type) VALUES ($value,'$qname','$type');")) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Add an account type for quotas
+ * @param string $type account type to be added
+ * @return boolean true if all went ok
+ */
+ function addtype($type) {
+ global $db, $err;
+ $qlist = $this->qlist();
+ if (empty($type)) {
+ return false;
+ }
+ $type = strtolower($type);
+ if (!preg_match("#^[a-z0-9]*$#", $type)) {
+ $err->raise("quota", "Type can only contains characters a-z and 0-9");
+ return false;
+ }
+ while (list($key, $val) = each($qlist)) {
+ if (!$db->query("INSERT IGNORE INTO defquotas (quota,type) VALUES('$key', '$type');") || $db->affected_rows() == 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** List for quotas
+ * @return array
+ */
+ function listtype() {
+ global $db;
+ $db->query("SELECT distinct(type) FROM defquotas ORDER by type");
+ $t = array();
+ while ($db->next_record()) {
+ $t[] = $db->f("type");
+ }
+ return $t;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Delete an account type for quotas
+ * @param string $type account type to be deleted
+ * @return boolean true if all went ok
+ */
+ function deltype($type) {
+ global $db;
+
+ if ($db->query("UPDATE membres SET type='default' WHERE type='$type'") &&
+ $db->query("DELETE FROM defquotas WHERE type='$type'")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Create default quotas entries for a new user.
+ * The user we are talking about is in the global $cuid.
+ */
+ function addquotas() {
+ global $db, $err, $cuid;
+ $err->log("quota", "addquota");
+ $ql = $this->qlist();
+ reset($ql);
+
+ $db->query("SELECT type,quota FROM defquotas WHERE type='default'");
+ if (!$db->next_record()) {
+ $this->addtype('default');
+ }
+ $db->query("SELECT type FROM membres WHERE uid='$cuid'");
+ $db->next_record();
+ $t = $db->f("type");
+
+ foreach ($ql as $res => $val) {
+ $db->query("SELECT value FROM defquotas WHERE quota='$res' AND type='$t'");
+ $q = $db->next_record() ? $db->f("value") : 0;
+ $this->setquota($res, $q);
+ }
+ return true;
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Return a quota value with its unit (when it is a space quota)
+ * in MB, GB, TB ...
+ * @param string $type The quota type
+ * @param integer $value The quota value
+ * @return string a quota value with its unit.
+ */
+ function display_val($type, $value) {
+ switch ($type) {
+ case 'bw_web':
+ return format_size($value);
+ case 'web':
+ return format_size($value * 1024);
+ default:
+ return $value;
+ }
+ }
+
+ /* get size_xx function (filled by spoolsize.php) */
+
+ function _get_sum_sql($sql) {
+ global $db;
+ $db->query($sql);
+ if ($db->num_rows() == 0) {
+ return -1;
+ } else {
+ $db->next_record();
+ $r = $db->Record;
+ return $r['sum'];
+ }
+ }
+
+ function _get_count_sql($sql) {
+ global $db;
+ $db->query($sql);
+ if ($db->num_rows() == 0) {
+ return 0;
+ } else {
+ $db->next_record();
+ $r = $db->Record;
+ return $r['count'];
+ }
+ }
+
+ function _get_size_and_record_sql($sql) {
+ global $db;
+ $db->query($sql);
+ if ($db->num_rows() == 0) {
+ return array();
+ } else {
+ $ret = array();
+ while ($db->next_record()) {
+ $ret[] = $db->Record;
+ }
+ return $ret;
+ }
+ }
+
+ /* sum of websites sizes from all users */
+
+ function get_size_web_sum_all() {
+ return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_web;");
+ }
+
+ /* sum of websites sizes from one user */
+
+ function get_size_web_sum_user($u) {
+ return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_web WHERE uid='$u';");
+ }
+
+ /* sum of mailbox sizes from all domains */
+
+ function get_size_mail_sum_all() {
+ return $this->_get_sum_sql("SELECT SUM(bytes) AS sum FROM mailbox;");
+ }
+
+ /* sum of mailbox sizes for one domain */
+
+ function get_size_mail_sum_domain($dom) {
+ global $mail;
+ return $mail->get_total_size_for_domain($dom);
+ }
+
+ /* count of mailbox sizes from all domains */
+
+ function get_size_mail_count_all() {
+ return $this->_get_count_sql("SELECT COUNT(*) AS count FROM mailbox;");
+ }
+
+ /* count of mailbox for one domain */
+
+ function get_size_mail_count_domain($dom) {
+ return $this->_get_count_sql("SELECT COUNT(*) AS count FROM dovecot_view WHERE user LIKE '%@{$dom}'");
+ }
+
+ /* get list of mailbox alias and size for one domain */
+
+ function get_size_mail_details_domain($dom) {
+ return $this->_get_size_and_record_sql("SELECT user as alias,quota_dovecot as size FROM dovecot_view WHERE user LIKE '%@{$dom}' ORDER BY alias;");
+ }
+
+ /* sum of mailman lists sizes from all domains */
+
+ function get_size_mailman_sum_all() {
+ return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman;");
+ }
+
+ /* sum of mailman lists sizes for one domain */
+
+ function get_size_mailman_sum_domain($dom) {
+ return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman WHERE list LIKE '%@{$dom}'");
+ }
+
+ /* sum of mailman lists for one user */
+
+ function get_size_mailman_sum_user($u) {
+ return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman WHERE uid = '{$u}'");
+ }
+
+ /* count of mailman lists sizes from all domains */
+
+ function get_size_mailman_count_all() {
+ return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_mailman;");
+ }
+
+ /* count of mailman lists for one user */
+
+ function get_size_mailman_count_user($u) {
+ return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_mailman WHERE uid = '{$u}'");
+ }
+
+ /* get list of mailman list and size for one user */
+
+ function get_size_mailman_details_user($u) {
+ return $this->_get_size_and_record_sql("SELECT s.size,CONCAT(m.list,'@',m.domain) as list FROM size_mailman s LEFT JOIN mailman m ON s.list=m.name WHERE s.uid='{$u}' ORDER BY s.list ASC");
+ }
+
+ /* sum of databases sizes from all users */
+
+ function get_size_db_sum_all() {
+ return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_db;");
+ }
+
+ /* sum of databases sizes for one user */
+
+ function get_size_db_sum_user($u) {
+ return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_db WHERE db = '{$u}' OR db LIKE '{$u}\_%'");
+ }
+
+ /* count of databases from all users */
+
+ function get_size_db_count_all() {
+ return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_db;");
+ }
+
+ /* count of databases for one user */
+
+ function get_size_db_count_user($u) {
+ return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_db WHERE db = '{$u}' OR db LIKE '{$u}\_%'");
+ }
+
+ /* get list of databases name and size for one user */
+
+ function get_size_db_details_user($u) {
+ return $this->_get_size_and_record_sql("SELECT db,size FROM size_db WHERE db='{$u}' OR db LIKE '{$u}\_%';");
+ }
+
+ /* Return appropriate value and unit of a size given in Bytes (e.g. 1024 Bytes -> return 1 KB) */
+
+ function get_size_unit($size) {
+ $units = array(1073741824 => _("GB"), 1048576 => _("MB"), 1024 => _("KB"), 0 => _("B"));
+ foreach ($units as $value => $unit) {
+ if ($size >= $value) {
+ $size = str_pad(round($size / ($value ? $value : 1), 1), 5, ' ', STR_PAD_LEFT);
+ return array('size' => $size, 'unit' => $unit);
+ }
+ }
+ }
+
+ // Affiche des barres de progression
+ // color_type :
+ // 0 = Pas de changement de couleur
+ // 1 = Progression du vert vers le rouge en fonction du porcentage
+ // 2 = Progression du rouge vers le vert en fonction du porcentage
+ function quota_displaybar($usage, $color_type = 1) {
+ if ($color_type == 1) {
+ $csscolor = " background-color:" . PercentToColor($usage);
+ } elseif ($color_type == 2) {
+ $csscolor = " background-color:" . PercentToColor(100 - $usage);
+ } else {
+ $csscolor = "";
+ }
-} /* Class m_quota */
+ echo '';
+ }
+
+ /* ==== Hook functions ==== */
+
+ /* ----------------------------------------------------------------- */
+
+ /** Hook function call when a user is deleted
+ * AlternC's standard function called when a user is deleted
+ * globals $cuid is the appropriate user
+ */
+ function hook_admin_del_member() {
+ $this->delquotas();
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Hook function called when a user is created
+ * This function initialize the user's quotas.
+ * globals $cuid is the appropriate user
+ */
+ function hook_admin_add_member() {
+ global $err;
+ $err->log("quota", "hook_admin_add_member");
+ $this->addquotas();
+ $this->getquota('', true); // actualise quota
+ }
+
+ /* ----------------------------------------------------------------- */
+
+ /** Exports all the quota related information for an account.
+ * @access private
+ * EXPERIMENTAL function ;)
+ */
+ function alternc_export_conf() {
+ global $err;
+ $err->log("quota", "export");
+ $str = " ";
+
+ $q = $this->getquota();
+ foreach ($q as $k => $v) {
+ $str.=" <$k>\n";
+ $str.=" " . ($v["u"]) . " \n";
+ $str.=" " . ($v["t"]) . " \n";
+ $str.=" $k>\n";
+ }
+ $str.=" \n";
+ return $str;
+ }
+
+}
+
+/* Class m_quota */