source: bureau/class/m_mail.php @ 324

Revision 324, 19.9 KB checked in by anarcat, 7 years ago (diff)

[project @ alternc: changeset 2004-06-01 12:46:43 by anonymous]
Suppression de ldap, remplacement par du code mysql ;) A TESTER bien
sur ...

Original author: anonymous
Date: 2004-06-01 12:46:43

Line 
1<?php
2/*
3 $Id: m_mail.php,v 1.11 2004/06/01 12:46:43 anonymous Exp $
4 ----------------------------------------------------------------------
5 LICENSE
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License (GPL)
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 To read the license please visit http://www.gnu.org/copyleft/gpl.html
18 ----------------------------------------------------------------------
19 Original Author of file: Benjamin Sonntag, Franck Missoum
20 Purpose of file: Manage Email accounts and aliases.
21 ----------------------------------------------------------------------
22*/
23/**
24* Classe de gestion des comptes mails de l'hébergé.
25*
26* Cette classe permet de gérer les comptes pop, alias
27* mail des domaines d'un membre hébergé.<br />
28* Copyleft {@link http://alternc.net/ AlternC Team}
29*
30* @copyright    AlternC-Team 2002-11-01 http://alternc.net/
31*
32*/
33class m_mail {
34
35  /** Connexion ldap
36   * @access private
37   */
38  var $ds=-1;
39
40  /** Liste des domaines
41   * @access private
42   */
43  var $domains;
44
45
46  /* ----------------------------------------------------------------- */
47  /**
48   * Constructeur
49   */
50  function m_mail() {
51  }
52
53  /* ----------------------------------------------------------------- */
54  /**
55   * Liste des quotas
56   */
57  function alternc_quota_names() {
58    return "mail";
59  }
60
61  /* ----------------------------------------------------------------- */
62  /** Retourne la liste des domaines hébergés en mails sur le compte.
63   * @return array Tableau indexé des domaines hébergés en mail.
64   */
65  function enum_domains() {
66    global $db,$err,$cuid;
67    $err->log("mail","enum_domains");
68    if (!is_array($this->domains)) {
69      $db->query("select * from domaines where compte='$cuid' AND gesmx=1;");
70      $this->domains=array();
71      if ($db->num_rows()>0) {
72        while ($db->next_record()) {
73          $this->domains[]=$db->f("domaine");
74        }
75      }
76    }
77    return $this->domains;
78  }
79
80  /* ----------------------------------------------------------------- */
81  /** Retourne la liste des mails du domaine $dom
82   * Retourne un tableau indexé de tableaux associatifs sous la forme :
83   * $a["mail"]=Adresse email
84   * $a["pop"]=1 ou 0 selon s'il s'agit d'un compte pop ou pas
85   * $a["size"]=taille en octets de la boite s'il s'agit d'un compte pop.
86   * @param string $dom Domaine dont on veut les mails
87   * @param integer $sort Champs de tri (0 pour non trié (default), 1 pour email, 2 pour type)
88   * @return array Tableau de mails comme indiqué ci-dessus ou FALSE si une erreur
89   *  s'est produite
90   */
91  function enum_doms_mails($dom,$sort=0) {
92    global $err,$cuid,$db;
93    $err->log("mail","enum_doms_mails",$dom);
94    $db->query("SELECT mail,pop FROM mail_domain WHERE mail LIKE '%@$dom' AND uid='$cuid';");
95    $res=array(); $i=0;
96    while ($db->next_record()) {
97        if ($db->f("pop")) { 
98        /*
99        $size=exec("/usr/lib/alternc/du.pl /var/alternc/mail/".substr($info[$i]["mail"][0],0,1)."/".str_replace("@","_",$info[$i]["mail"][0]));
100        $size=$size*1024;
101        */
102        $size=0;
103        } else $size=0;
104        $res[]=array("mail" => $db->f("mail"),  "pop" => $db->f("pop"),"size"=>$size);
105        $i++;
106    }
107    if ($sort==1) {
108        usort($res,array("m_mail","_cmp_mail"));
109    }
110    if ($sort==2) {
111        usort($res,array("m_mail","_cmp_type"));
112    }
113    $res["count"]=$i;
114    return $res;
115  }
116
117 function _cmp_mail($a, $b)
118    {
119        $al = strtolower($a["mail"]);
120        $bl = strtolower($b["mail"]);
121        if ($al == $bl) return 0;
122        return ($al > $bl) ? +1 : -1;
123    }
124 function _cmp_type($a, $b)
125    {
126        $al = strtolower($a["pop"]);
127        $bl = strtolower($b["pop"]);
128        if ($al == $bl) {
129          $al = strtolower($a["mail"]);
130          $bl = strtolower($b["mail"]);
131          if ($al == $bl) return 0;
132        }
133        return ($al > $bl) ? +1 : -1;
134    }
135
136  /* ----------------------------------------------------------------- */
137  /** Retourne les détails d'un mail
138   * Le mail $mail est retourné sous la forme d'un tableaau associatif comme suit :
139   * $a["mail"]= Adresse email
140   * $a["login"]= Login pop
141   * $a["password"]= Mot de passe pop (crypté)
142   * $a["alias"]= Alias destination, 1 par ligne
143   * $a["pop"]= 1 ou 0 s'il s'agit d'un compte pop
144   * @param string $mail Mail dont on veut retourner le détail
145   * @return array Tableau associatif comme ci-dessus.
146   */
147  function get_mail_details($mail) {
148    global $err,$db,$cuid;
149    $err->log("mail","get_mail_details",$mail);
150    $db->query("SELECT mail,pop,alias FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
151    if (!$db->next_record()) { 
152      $err->raise("mail",3,$mail);
153      return false;
154    }
155    $pop=$db->f("pop"); 
156    if ($pop) {
157        $login=$db->f("alias");
158        $db->query("SELECT password FROM mail_users WHERE alias='$login' AND uid='$cuid';");
159        if ($db->next_record()) {
160                $pass=$db->f("password");
161        }
162      }
163    } else {
164        $account=$db->f("alias");
165    }
166    $res=array("mail" => $mail, "login" => $login, "password" => $pass, "alias" => $account, "pop" => $pop);
167    return $res;
168  }
169
170  /*****************************************************************************/
171  /** Tell if a mail is available or not */
172  function available($mail) {
173    global $err,$db,$cuid;
174    $err->log("mail","available",$mail);
175    $db->query("SELECT mail FROM mail_domain WHERE mail='$mail';");
176    if ($db->next_record()) {
177        return false;
178    } else {
179        return true;
180    }
181  }
182
183  /* ----------------------------------------------------------------- */
184  /** Crée un mail 'executeur' (wrapper) pour $login@$domain
185   * @param string $login partie gauche du @ pour le mail concerné
186   * @param string $domain partie droite du @ pour le mail concerné
187   * @param string $command Commande à exécuter, sans le | ni les "" (commande brute)
188   * @param string $type ignoré désormais (plus de ldap...) TODO : remplacer cela par une appropriation de wrapper par une classe (donc mettre dans ce champ le nom de la classe appelante ? )
189   * @return boolean TRUE si le wrapper a été créé, FALSE si une erreur s'est produite.
190   */
191  function add_wrapper($login,$domain,$command,$type="") {
192    global $err,$cuid,$db;
193    if (!$this->available($login."@".$domain)) {
194      $err->raise("mail",7,$login."@".$domain);
195      return false;
196    }
197    $db->query("INSERT INTO mail_domain (mail,alias,uid,pop,type) VALUES ('".$login."@".$domain."','".$login."_".$domain."','$cuid',0,1);");
198    $db->query("INSERT INTO mail_alias (mail,alias) VALUES ('".$login."_".$domain."','\"| $command\"');");
199    return true;
200  }
201
202  /* ----------------------------------------------------------------- */
203  /** Efface un mail 'executeur' (wrapper) pour $login@$domain
204   * @param string $login partie gauche du @ pour le mail concerné
205   * @param string $domain partie droite du @ pour le mail concerné
206   * @return boolean TRUE si le wrapper a été effacé, FALSE si une erreur s'est produite.
207   */
208  function del_wrapper($login,$domain) {
209    global $err,$cuid,$db;
210    $db->query("DELETE FROM mail_domain WHERE mail='".$login."@".$domain."' AND uid='$cuid' AND type=1;");
211    $db->query("DELETE FROM mail_alias WHERE mail='".$login."_".$domain."';");
212    return true;
213  }
214
215
216  /* ----------------------------------------------------------------- */
217  /** Change le mot de passe du compte pop $mail
218   * @param string $mail Compte mail concerné
219   * @param string $pass Nouveau mot de passe
220   * @return boolean TRUE si le mot de passe a été changé, FALSE si une erreur s'est produite.
221   */
222  function change_password($mail,$pass) {
223    global $err,$db,$cuid
224    $err->log("mail","change_password",$mail);
225    $t=explode("@",$mail);
226    $email=$t[0];
227    $dom=$t[1];
228    $db->query("SELECT mail,alias,pop FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
229    if (!$db->next_record()) {
230      $err->raise("mail",3,$mail);
231      return false;
232    }
233    if (!$db->f("pop")) {
234      $err->raise("mail",15);
235      return false;
236    }
237    if (!$this->_updatepop($email,$dom,$pass)) {
238      return false;
239    }
240    return true;
241  }
242
243  /* ----------------------------------------------------------------- */
244  /** Modifie les paramètres d'un compte email
245   * Tout peut être modifié dans l'email (sauf l'adresse elle-même)
246   * @param string $mail Adresse à modifier. Le domaine doit appartenir au membre
247   * @param integer $pop Doit-il etre un compte pop (1) ou juste un alias (0)
248   * @param string $pass Nouveau mot de passe pop, si pop=1
249   * @param string $alias Liste des destinataires auxiliaires, un par ligne.
250   * @return boolean TRUE si l'email a bien été modifié, FALSE si une erreur s'est produite.
251   */
252  function put_mail_details($mail,$pop,$pass,$alias) {
253    global $err,$cuid,$db;
254    $err->log("mail","put_mail_details",$mail);
255    $mail=strtolower($mail);
256    $t=explode("@",$mail);
257    $email=$t[0];
258    $dom=$t[1];
259
260    if ($pop) $pop="1"; else $pop="0";
261    //vérifie si les champs obligatoires sont renseignés
262    if ($pop=="0" && $alias=="") {
263      $err->raise("mail",4);
264      return false;
265    }
266    if ($pop=="1"){
267      $alias=$mail."_".$dom;
268    }
269    //vérifie la validité des alias :
270    if ($alias){
271      $a=explode("\n",$alias);
272      if (count($a)>0) {
273        reset($a);
274        for ($i=0;$i<count($a);$i++){
275          $a[$i]=trim($a[$i]);
276          if ($a[$i]){
277            if(checkmail($a[$i])!=0){
278              $err->raise("mail",14);
279              return false;
280            }
281          }
282        }
283      }
284    }
285
286    $db->query("SELECT mail,alias,pop FROM mail_domain WHERE mail='$mail' AND uid='$cuid' AND type=0;");
287    if (!$db->next_record()) {
288      $err->raise("mail",3,$mail);
289      return false;
290    }
291    $oldpop= $db->f("pop");
292    // When we CREATE a pop account, we MUST give a password
293    if ($pop=="1" && $oldpop!=1) {
294      if (!$pass) {
295        $err->raise("mail",4);
296        return false;
297      }
298    }
299
300    $db->query("UPDATE mail_domain SET alias='$alias', pop='$pop' WHERE mail='$mail';");
301
302    if ($pop=="1" && $oldpop!=1) { /* Creation du compte pop */
303      if (!$this->_createpop($email,$dom,$pass)) {
304        return false;
305      }
306    }
307    if ($pop!="1" && $oldpop==1) { /* Destruction du compte pop */
308      if (!$this->_deletepop($email,$dom)) {
309        return false;
310      }
311    }
312    if ($pop=="1" && $oldpop==1 && $pass!="") { /* Modification du compte pop */
313      if (!$this->_updatepop($email,$dom,$pass)) {
314        return false;
315      }
316    }
317    return true;
318  }
319
320  /* ----------------------------------------------------------------- */
321  /** Crée un compte email $mail sur le domaine $dom
322   * @param string $dom Domaine concerné, il doit appartenir au membre
323   * @param string $mail Email à créer, il ne doit pas exister ni en mail, ni en liste.
324   * @param integer $pop vaut 1 pour créer un compte pop, 0 pour un alias
325   * @param string $alias Liste des alias, un par ligne
326   * @return boolean TRUE si le compte a bien été créé, FALSE si une erreur s'est produite.
327   */
328  function add_mail($dom,$mail,$pop,$pass,$alias) {
329    global $quota,$err,$cuid,$db;
330    $err->log("mail","add_mail",$dom."/".$mail);
331    $account=array();
332    $mail=strtolower($mail);
333    if ($pop) $pop="1"; else $pop="0";
334    if ($mail) {
335      //vérifie la validité du login mail
336      if (!checkloginmail($mail)) {
337        $err->raise("mail",13);
338        return false;
339      }
340    }
341    //vérifie si les champs obligatoires sont renseignés
342    if (($pop=="1" && $pass=="")||($pop!="1" && $alias=="")){
343      $err->raise("mail",4);
344      return false;
345    }
346    if ($pop=="1"){
347      $alias=$mail."_".$dom;
348    }
349    //vérifie la validité des alias :
350    if ($alias){
351      $a=explode("\n",$alias);
352      if (count($a)>0) {
353        reset($a);
354        for ($i=0;$i<count($a);$i++){
355          $a[$i]=trim($a[$i]);
356          if ($a[$i]){
357            if(checkmail($a[$i])!=0){
358              $err->raise("mail",14);
359              return false;
360            }
361          }
362        }
363      }
364    }
365
366    // check that the domains is a user's one ...
367    $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$dom';")
368    if (!$db->next_record()) {
369      $err->raise("mail",6,$dom);
370      return false;
371    }   
372    $db->query("SELECT mail FROM mail_domain WHERE mail='".$mail."@".$dom."' AND uid='$cuid';")
373    if ($db->next_record()) {
374      $err->raise("mail",7,$dom);
375      return false;
376    }   
377
378    /* QuotaCheck */
379    if (!$quota->cancreate("mail")) {
380      $err->raise("mail",8);
381      return false;
382    }
383    $quota->inc("mail");
384    $db->query("INSERT INTO mail_domain (mail,alias,uid,pop,type) VALUES ('".$mail."@".$dom."','$alias','$cuid','$pop',0);");
385
386    // Ajout du compte pop dans ldap-users
387    if ($pop=="1") {
388      if (!$this->_createpop($mail,$dom,$pass))
389        return false;
390    }
391    return true;
392  }
393
394  /* ----------------------------------------------------------------- */
395  /** Efface le compte mail $mail
396   * @param string $mail Email à effacer
397   * @return boolean TRUE si le compte mail a bien été détruit, FALSE si une erreur s'est produite.
398   */
399  function del_mail($mail) {
400    global $quota,$err,$cuid,$db;
401    $err->log("mail","del_mail",$mail);
402    $mail=strtolower($mail);
403
404    $db->query("SELECT pop,mail FROM mail_domain WHERE mail='$mail' AND uid='$cuid' AND type=0;")
405    if (!$db->next_record()) {
406      $err->raise("mail",3,$dom);
407      return false;
408    }   
409    /* Ok, le mail existe, on le detruit donc... */
410    $t=explode("@",$mail);
411    $mdom=$t[0]; $dom=$t[1];
412    $quota->dec("mail");
413    $pop=$db->f("pop");
414   
415    $db->query("DELETE FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
416
417    if ($pop=="1") {
418      if (!$this->_deletepop($mdom,$dom)) {
419        return false;
420      }
421    }
422    return true;
423  }
424
425  /* ----------------------------------------------------------------- */
426  /** Crée le compte pop $mail@$dom, avec pour mot de passe $pass
427   * @param string $mail Compte email à créer en pop
428   * @param string $dom Domaine sur lequel on crée le compte email
429   * @param string $pass Mot de passe du compte email.
430   * @return boolean TRUE si le compte pop a bien été créé, FALSE si une erreur est survenur
431   * @access private
432   */
433  function _createpop($mail,$dom,$pass) {
434    global $err,$cuid,$db;
435    $err->log("mail","_createpop",$mail."@".$dom);
436    $m=substr($mail,0,1);
437    $gecos=$mail;
438    if (!$mail) {
439      // Cas du CATCH-ALL
440      $gecos="Catch-All";
441      $m="_";
442    }
443    $db->query("INSERT INTO mail_users (uid,alias,path,password) VALUES ('$cuid','".$mail."_".$dom."','/var/alternc/mail/".$m."/".$mail."_".$dom."','"._md5cr($pass)."');");
444    $db->query("INSERT INTO mail_users (uid,alias,path,password) VALUES ('$cuid','".$mail."@".$dom."','/var/alternc/mail/".$m."/".$mail."_".$dom."','"._md5cr($pass)."');");
445
446    $f=fopen("/var/lib/squirrelmail/data/".$mail."_".$dom.".pref","wb");
447    fputs($f,"email_address=$mail@$dom\nchosen_theme=default_theme.php\n");
448    fclose($f);
449    $f=fopen("/var/lib/squirrelmail/data/".$mail."@".$dom.".pref","wb");
450    fputs($f,"email_address=$mail@$dom\nchosen_theme=default_theme.php\n");
451    fclose($f);
452    exec("/usr/lib/alternc/mail_add ".$mail."_".$dom." ".$cuid);
453    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -c -p ".$mail."@".$dom);
454    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -c -p ".$mail."_".$dom);
455    return true;
456  }
457
458  /* ----------------------------------------------------------------- */
459  /** Met à jour un compte pop existant
460   * @param string $mail mail à modifier
461   * @param string $dom Domaine dont on modifie le compte pop
462   * @param string $pass Nouveau mot de passe.
463   * @return boolean TRUE si le compte pop a bien été modifié, FALSE si une erreur s'est produite.
464   * @access private
465   */
466  function _updatepop($mail,$dom,$pass) {
467    global $err,$cuid,$db;
468    $err->log("mail","_updatepop",$mail."@".$dom);
469    $m=substr($mail,0,1);
470    $gecos=$mail;
471    $db->query("UPDATE mail_users SET password='"._md5cr($pass)."' WHERE ( alias='". $mail."_".$dom."' OR alias='". $mail."@".$dom."' ) AND uid='$cuid';");
472    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -p ".$mail."@".$dom);
473    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -p ".$mail."_".$dom);
474    return true;
475  }
476
477  /* ----------------------------------------------------------------- */
478  /** Détruit le compte pop $mail@$dom.
479   * @param string $mail Email dont on souhaite détruire le compte pop
480   * @param string $dom Domaine dont on souhaite détuire le compte pop.
481   * @return boolean TRUE si le compte pop a bien été détruit, FALSE si une erreur s'est produite.
482   * @access private
483   */
484  function _deletepop($mail,$dom) {
485    global $err,$cuid,$db;
486    $err->log("mail","_deletepop",$mail."@".$dom);
487    $db->query("DELETE FROM mail_users WHERE uid='$cuid' AND (  alias='". $mail."_".$dom."' OR alias='". $mail."@".$dom."' ) ;");
488    @unlink("/var/lib/squirrelmail/data/".$mail."_".$dom.".pref");
489    @unlink("/var/lib/squirrelmail/data/".$mail."_".$dom.".abook");
490    @unlink("/var/lib/squirrelmail/data/".$mail."@".$dom.".pref");
491    @unlink("/var/lib/squirrelmail/data/".$mail."@".$dom.".abook");
492    exec("/usr/lib/alternc/mail_del ".$mail."_".$dom);
493    exec("/usr/sbin/saslpasswd -u postfix -d ".$mail."@".$dom);
494    exec("/usr/sbin/saslpasswd -u postfix -d ".$mail."_".$dom);
495    return true;
496  }
497
498  /* ----------------------------------------------------------------- */
499  /** Fonction appellée par domaines lorsqu'un domaine est effacé.
500   * Cette fonction efface tous les comptes mails du domaine concerné.
501   * @param string $dom Domaine à effacer
502   * @return boolean TRUE si le domaine a bien été effacé, FALSE si une erreur s'est produite.
503   * @access private
504   */
505  function alternc_del_mx_domain($dom) {
506    global $err,$quota,$db,$cuid;
507    $err->error=0;
508    $err->log("mail","del_dom",$dom);
509
510    $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$dom';")
511    if (!$db->next_record()) {
512      $err->raise("mail",6,$dom);
513      return false;
514    }   
515
516    /* Effacement de tous les mails de ce domaine : */
517    $a=$this->enum_doms_mails($dom);
518    if (is_array($a)) {
519      reset($a);
520      for($i=0;$i<$a["count"];$i++) {
521        $val=$a[$i];
522        if (!$this->del_mail($val["mail"])) {
523          $err->raise("mail",5);
524        }
525      }
526      /* Mise à jour des quotas mails*/
527      $q=$quota->getquota("mail");
528      if (!is_array($q)) {
529        $err->raise("mail",10);
530        return false;
531      } else {
532        $u=$q["u"];
533        $new=$u-$a["count"];
534        if(!$quota->setquota("mail",$new,1)){
535          $err->raise("mail",10);
536          return false;
537        }
538      }
539    }
540    /* Effacement du domaine himself */
541    $db->query("DELETE FROM mail_domain WHERE mail LIKE '%@$dom';");     
542    $db->query("DELETE FROM mail_users WHERE alias LIKE '%@$dom' OR alias LIKE '%_$dom';");     
543    $db->query("DELETE FROM mail_alias WHERE mail LIKE '%_$dom';");     
544    $db->query("DELETE FROM mail_domain WHERE mail='$dom';");
545    return true;
546  }
547
548  /* ----------------------------------------------------------------- */
549  /** Fonction appellée par domaines lorsqu'un domaine est créé.
550   * Cette fonction crée les comptes par défaut du domaine concerné.
551   * @param string $dom Domaine à créer
552   * @return boolean TRUE si le domaine a bien été créé, FALSE si une erreur s'est produite.
553   * @access private
554   * TODO : ne créer les entrées que si le MX est à true ! (déplacer a alternc_add_mx_domain
555   */
556  function alternc_add_mx_domain($dom) {
557    global $err,$cuid,$db;
558    $err->log("mail","add_dom",$dom);
559
560    $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$dom';")
561    if ($db->next_record()) {
562      $err->raise("mail",9,$dom);
563      return false;
564    }   
565
566    $db->query("INSERT INTO mail_domain (mail,alias) VALUES ('$dom','$dom');");
567    return true;
568  }
569
570  /* TODO : alternc_quota_check */
571  function alternc_quota_check($id=-1) {
572    global $quota,$err,$cuid,$db;
573    $db->query("SELECT COUNT(*) AS cnt FROM mail_domain WHERE type=0;");
574    $db->next_record();
575    $quota->setquota("mail",$db->f("cnt"),1);
576    return true;
577  }
578
579
580} /* Class m_mail */
581
582?>
Note: See TracBrowser for help on using the repository browser.