root/alternc/trunk/bureau/class/m_mail.php

Revision 1879, 24.5 kB (checked in by benjamin, 1 year ago)

we copy the default squirrelmail prefs in new accounts. Fixes #1015

Line 
1 <?php
2 /*
3  $Id: m_mail.php,v 1.31 2006/01/12 06:26:16 anarcat 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 */
33 class m_mail {
34
35   /** Liste des domaines
36    * @access private
37    */
38   var $domains;
39
40
41   /* ----------------------------------------------------------------- */
42   /**
43    * Constructeur
44    */
45   function m_mail() {
46   }
47
48   /* ----------------------------------------------------------------- */
49   /**
50    * Liste des quotas
51    */
52   function alternc_quota_names() {
53     return "mail";
54   }
55
56   /* ----------------------------------------------------------------- */
57   /** Retourne la liste des domaines hébergés en mails sur le compte.
58    * @return array Tableau indexé des domaines hébergés en mail.
59    */
60   function enum_domains() {
61     global $db,$err,$cuid;
62     $err->log("mail","enum_domains");
63     if (!is_array($this->domains)) {
64       $db->query("select * from domaines where compte='$cuid' AND gesmx=1;");
65       $this->domains=array();
66       if ($db->num_rows()>0) {
67     while ($db->next_record()) {
68       $this->domains[]=$db->f("domaine");
69     }
70       }
71     }
72     return $this->domains;
73   }
74
75   /* ----------------------------------------------------------------- */
76   /** Retourne la liste des lettres pour lesquelles un domaine $dom a
77    * des e-mails
78    * Retourne un tableau indexé où se trouvent les lettres
79    * @param string $dom Domaine dont on veut les premières lettres des mails
80   * @return array Tableau de lettres ou FALSE si erreur
81    */
82   function enum_doms_mails_letters($dom) {
83     global $err,$cuid,$db;
84     $err->log("mail","enum_doms_mails_letters",$dom);
85     $db->query("SELECT LEFT(mail,1) as letter FROM mail_domain where uid='$cuid' AND type=0 and mail like '%@".addslashes($dom)."' GROUP BY letter ORDER BY letter;");
86     $res=array();
87     while($db->next_record()) {
88       $res[]=$db->f("letter");
89     }
90     return $res;
91   }
92
93   /* ----------------------------------------------------------------- */
94   /** Retourne la liste des mails du domaine $dom et si une lettre est
95    * définie, cela retourne les mail qui commencent par celle ci
96    * Retourne un tableau indexé de tableaux associatifs sous la forme :
97    * $a["mail"]=Adresse email
98    * $a["pop"]=1 ou 0 selon s'il s'agit d'un compte pop ou pas
99    * $a["size"]=taille en octets de la boite s'il s'agit d'un compte pop.
100    * @param string $dom Domaine dont on veut les mails
101    * @param integer $sort Champs de tri (0 pour non trié (default), 1 pour email, 2 pour type)
102    * @param string $letter Première lettre des mails à retourner, ou "" pour les retourner tous
103    * @return array Tableau de mails comme indiqué ci-dessus ou FALSE si une erreur
104    *  s'est produite
105    */
106   function enum_doms_mails($dom,$sort=0,$letter="") {
107     global $err,$cuid,$db;
108     $err->log("mail","enum_doms_mails",$dom);
109     if($letter == "@")
110     $letter = "";
111     else
112     $letter .= "%";
113     $db->query("SELECT mail,pop,alias FROM mail_domain WHERE mail LIKE '".addslashes($letter)."@".addslashes($dom)."' AND uid='$cuid' AND type=0;");
114     $res=array(); $i=0;
115     while ($db->next_record()) {
116       if ($db->f("pop")) {
117     $size=0;
118         $r=mysql_query("SELECT size FROM size_mail WHERE alias='".str_replace("@","_",$db->f("mail"))."';");
119         list($size)=@mysql_fetch_array($r);
120         $size=$size*1024;
121       } else $size=0;
122       if ($db->f("pop")) {
123     $login=str_replace("@","_",$db->f("mail"));
124     $account=str_replace($login,"",$db->f("alias"));
125       } else {
126     $account=$db->f("alias");
127       }
128       $res[]=array("mail" => $db->f("mail"), "pop" => $db->f("pop"),
129            "alias"=>$account,"size"=>$size);
130       $i++;
131     }
132     if ($sort==1) {
133       usort($res,array("m_mail","_cmp_mail"));
134     }
135     if ($sort==2) {
136       usort($res,array("m_mail","_cmp_type"));
137     }
138     $res["count"]=$i;
139     return $res;
140   }
141
142   function _cmp_mail($a, $b)
143     {
144       $al = strtolower($a["mail"]);
145       $bl = strtolower($b["mail"]);
146       if ($al == $bl) return 0;
147       return ($al > $bl) ? +1 : -1;
148     }
149   function _cmp_type($a, $b)
150     {
151       $al = strtolower($a["pop"]);
152       $bl = strtolower($b["pop"]);
153       if ($al == $bl) {
154     $al = strtolower($a["mail"]);
155     $bl = strtolower($b["mail"]);
156     if ($al == $bl) return 0;
157       }
158       return ($al > $bl) ? +1 : -1;
159     }
160
161   /* ----------------------------------------------------------------- */
162   /** Retourne les détails d'un mail
163    * Le mail $mail est retourné sous la forme d'un tableaau associatif comme suit :
164    * $a["mail"]= Adresse email
165    * $a["login"]= Login pop
166    * $a["password"]= Mot de passe pop (crypté)
167    * $a["alias"]= Alias destination, 1 par ligne
168    * $a["pop"]= 1 ou 0 s'il s'agit d'un compte pop
169    * @param string $mail Mail dont on veut retourner le détail
170    * @return array Tableau associatif comme ci-dessus.
171    */
172   function get_mail_details($mail) {
173     global $err,$db,$cuid;
174     $err->log("mail","get_mail_details",$mail);
175     $db->query("SELECT mail,pop,alias FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
176     if (!$db->next_record()) {
177       $err->raise("mail",3,$mail);
178       return false;
179     }
180     $pop=$db->f("pop");
181     if ($pop) {
182       $login=str_replace("@","_",$db->f("mail"));
183       $account=str_replace($login,"",$db->f("alias"));
184     } else {
185       $account=$db->f("alias");
186     }
187     return array("mail" => $mail, "login" => $login, "alias" => $account, "pop" => $pop);
188   }
189
190   /*****************************************************************************/
191   /** Tell if a mail is available or not */
192   function available($mail) {
193     global $err,$db,$cuid;
194     $err->log("mail","available",$mail);
195     $db->query("SELECT mail FROM mail_domain WHERE mail='$mail';");
196     if ($db->next_record()) {
197       return false;
198     } else {
199       return true;
200     }
201   }
202
203   /* ----------------------------------------------------------------- */
204   /** Crée un mail 'executeur' (wrapper) pour $login@$domain
205    * @param string $login partie gauche du @ pour le mail concerné
206    * @param string $domain partie droite du @ pour le mail concerné
207    * @param string $command Commande à exécuter, sans le | ni les "" (commande brute)
208    * @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 ? )
209    * @return boolean TRUE si le wrapper a été créé, FALSE si une erreur s'est produite.
210    */
211   function add_wrapper($login,$domain,$command,$type="") {
212     global $err,$cuid,$db;
213     if (!$this->available($login."@".$domain)) {
214       $err->raise("mail",7,$login."@".$domain);
215       return false;
216     }
217     $db->query("INSERT INTO mail_domain (mail,alias,uid,pop,type) VALUES ('".$login."@".$domain."','".$login."_".$domain."','$cuid',0,1);");
218     $db->query("INSERT INTO mail_alias (mail,alias) VALUES ('".$login."_".$domain."','\"| $command\"');");
219     return true;
220   }
221
222   /* ----------------------------------------------------------------- */
223   /** Efface un mail 'executeur' (wrapper) pour $login@$domain
224    * @param string $login partie gauche du @ pour le mail concerné
225    * @param string $domain partie droite du @ pour le mail concerné
226    * @return boolean TRUE si le wrapper a été effacé, FALSE si une erreur s'est produite.
227    */
228   function del_wrapper($login,$domain) {
229     global $err,$cuid,$db;
230     $db->query("DELETE FROM mail_domain WHERE mail='".$login."@".$domain."' AND uid='$cuid' AND type=1;");
231     $db->query("DELETE FROM mail_alias WHERE mail='".$login."_".$domain."';");
232     return true;
233   }
234
235
236   /* ----------------------------------------------------------------- */
237   /** Change le mot de passe du compte pop $mail
238    * @param string $mail Compte mail concerné
239    * @param string $pass Nouveau mot de passe
240    * @return boolean TRUE si le mot de passe a été changé, FALSE si une erreur s'est produite.
241    */
242   function change_password($mail,$pass) {
243     global $err,$db,$cuid;
244     $err->log("mail","change_password",$mail);
245     $t=explode("@",$mail);
246     $email=$t[0];
247     $dom=$t[1];
248     $db->query("SELECT mail,alias,pop FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
249     if (!$db->next_record()) {
250       $err->raise("mail",3,$mail);
251       return false;
252     }
253     if (!$db->f("pop")) {
254       $err->raise("mail",15);
255       return false;
256     }
257     if (!$this->_updatepop($email,$dom,$pass)) {
258       return false;
259     }
260     return true;
261   }
262
263   /* ----------------------------------------------------------------- */
264   /** Modifie les paramètres d'un compte email
265    * Tout peut être modifié dans l'email (sauf l'adresse elle-même)
266    * @param string $mail Adresse à modifier. Le domaine doit appartenir au membre
267    * @param integer $pop Doit-il etre un compte pop (1) ou juste un alias (0)
268    * @param string $pass Nouveau mot de passe pop, si pop=1
269    * @param string $alias Liste des destinataires auxiliaires, un par ligne.
270    * @return boolean TRUE si l'email a bien été modifié, FALSE si une erreur s'est produite.
271    */
272   function put_mail_details($mail,$pop,$pass,$alias) {
273     global $err,$cuid,$db;
274     $err->log("mail","put_mail_details",$mail);
275     $mail=strtolower($mail);
276     $t=explode("@",$mail);
277     $email=$t[0];
278     $dom=$t[1];
279
280     $account=array();
281
282     if ($pop) $pop="1"; else $pop="0";
283     //vérifie si les champs obligatoires sont renseignés
284     if ($pop=="0" && $alias=="") {
285       $err->raise("mail",4);
286       return false;
287     }
288     if ($pop=="1"){
289       $account[]=$email."_".$dom;
290     }
291     //vérifie la validité des alias :
292     if ($alias){
293       $a=explode("\n",$alias);
294       if (count($a)>0) {
295     reset($a);
296     for ($i=0;$i<count($a);$i++){
297       $a[$i]=trim($a[$i]);
298       if ($a[$i]){
299         if(checkmail($a[$i])>1){
300           $err->raise("mail",14);
301           return false;
302         }
303       }
304       $account[]=$a[$i];
305     }
306       }
307     }
308
309     $db->query("SELECT mail,alias,pop FROM mail_domain WHERE mail='$mail' AND uid='$cuid' AND type=0;");
310     if (!$db->next_record()) {
311       $err->raise("mail",3,$mail);
312       return false;
313     }
314     $oldpop= $db->f("pop");
315     // When we CREATE a pop account, we MUST give a password
316     if ($pop=="1" && $oldpop!=1) {
317       if (!$pass) {
318     $err->raise("mail",4);
319     return false;
320       }
321     }
322
323     $db->query("UPDATE mail_domain SET alias='".implode("\n",$account)."', pop='$pop' WHERE mail='$mail';");
324
325     if ($pop=="1" && $oldpop!=1) { /* Creation du compte pop */
326       if (!$this->_createpop($email,$dom,$pass)) {
327     return false;
328       }
329     }
330     if ($pop!="1" && $oldpop==1) { /* Destruction du compte pop */
331       if (!$this->_deletepop($email,$dom)) {
332     return false;
333       }
334     }
335     if ($pop=="1" && $oldpop==1 && $pass!="") { /* Modification du compte pop */
336       if (!$this->_updatepop($email,$dom,$pass)) {
337     return false;
338       }
339     }
340     return true;
341   }
342
343   /* ----------------------------------------------------------------- */
344   /** Crée un compte email $mail sur le domaine $dom
345    * @param string $dom Domaine concerné, il doit appartenir au membre
346    * @param string $mail Email à créer, il ne doit pas exister ni en mail, ni en liste.
347    * @param integer $pop vaut 1 pour créer un compte pop, 0 pour un alias
348    * @param string $alias Liste des alias, un par ligne
349    * @return boolean TRUE si le compte a bien été créé, FALSE si une erreur s'est produite.
350    */
351   function add_mail($dom,$mail,$pop,$pass,$alias) {
352     global $quota,$err,$cuid,$db;
353     $err->log("mail","add_mail",$dom."/".$mail);
354     $account=array();
355     $mail=strtolower($mail);
356     if ($pop) $pop="1"; else $pop="0";
357     if ($mail) {
358       //vérifie la validité du login mail
359       if (!checkloginmail($mail)) {
360     $err->raise("mail",13);
361     return false;
362       }
363     }
364     //vérifie si les champs obligatoires sont renseignés
365     if (($pop=="1" && $pass=="")||($pop!="1" && $alias=="")){
366       $err->raise("mail",4);
367       return false;
368     }
369     if ($pop=="1"){
370       $account[]=$mail."_".$dom;
371     }
372     //vérifie la validité des alias :
373     if ($alias){
374       $a=explode("\n",$alias);
375       if (count($a)>0) {
376     reset($a);
377     for ($i=0;$i<count($a);$i++){
378       $a[$i]=trim($a[$i]);
379       if ($a[$i]){
380         if(checkmail($a[$i])>1){
381           $err->raise("mail",14);
382           return false;
383         }
384       }
385       $account[]=$a[$i];
386     }
387       }
388     }
389
390     // check that the domains is a user's one ...
391     $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$dom';");
392     if (!$db->next_record()) {
393       $err->raise("mail",6,$dom);
394       return false;
395     }   
396     $db->query("SELECT mail FROM mail_domain WHERE mail='".$mail."@".$dom."' AND uid='$cuid';");
397     if ($db->next_record()) {
398       $err->raise("mail",7,$mail."@".$dom);
399       return false;
400     }   
401
402     /* QuotaCheck */
403     if (!$quota->cancreate("mail")) {
404       $err->raise("mail",8);
405       return false;
406     }
407     $db->query("INSERT INTO mail_domain (mail,alias,uid,pop,type) VALUES ('".$mail."@".$dom."','".implode("\n",$account)."','$cuid','$pop',0);");
408
409     // Ajout du compte pop dans ldap-users
410     if ($pop=="1") {
411       if (!$this->_createpop($mail,$dom,$pass))
412     return false;
413     }
414     return true;
415   }
416
417   /* ----------------------------------------------------------------- */
418   /** Efface le compte mail $mail
419    * @param string $mail Email à effacer
420    * @return boolean TRUE si le compte mail a bien été détruit, FALSE si une erreur s'est produite.
421    */
422   function del_mail($mail) {
423     global $err,$cuid,$db;
424     $err->log("mail","del_mail",$mail);
425     $mail=strtolower($mail);
426
427     $db->query("SELECT pop,mail FROM mail_domain WHERE mail='$mail' AND uid='$cuid' AND type=0;");
428     if (!$db->next_record()) {
429       $err->raise("mail",3,$dom);
430       return false;
431     }   
432     /* Ok, le mail existe, on le detruit donc... */
433     $t=explode("@",$mail);
434     $mdom=$t[0]; $dom=$t[1];
435     $pop=$db->f("pop");
436     
437     $db->query("DELETE FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
438
439     if ($pop=="1") {
440       if (!$this->_deletepop($mdom,$dom)) {
441     return false;
442       }
443     }
444     return true;
445   }
446
447
448   /* ----------------------------------------------------------------- */
449   /**
450    * Check for a slave account (secondary mx)
451    */
452   function check_slave_account($login,$pass) {
453     global $db,$err;
454     $db->query("SELECT * FROM mxaccount WHERE login='$login' AND pass='$pass';");
455     if ($db->next_record()) {
456         return true;
457     }
458     return false;
459   }
460
461   /* ----------------------------------------------------------------- */
462   /**
463    * Out (echo) the complete mx-hosted domain list :
464    */
465   function echo_domain_list() {
466     global $db,$err;
467     $db->query("SELECT domaine FROM domaines WHERE gesmx=1 ORDER BY domaine");
468     while ($db->next_record()) {
469         echo $db->f("domaine")."\n";
470     }
471     return true;
472   }
473
474   /* ----------------------------------------------------------------- */
475   /**
476    * Return the list of allowed slave accounts (secondary-mx)
477    */
478   function enum_slave_account() {
479     global $db,$err;
480     $db->query("SELECT * FROM mxaccount;");
481     $res=array();
482     while ($db->next_record()) {
483         $res[]=$db->Record;
484     }
485     if (!count($res)) return false;
486     return $res;
487   }
488
489   /* ----------------------------------------------------------------- */
490   /**
491    * Add a slave account that will be allowed to access the mxdomain list
492    */
493   function add_slave_account($login,$pass) {
494     global $db,$err;
495     $db->query("SELECT * FROM mxaccount WHERE login='$login'");
496     if ($db->next_record()) {
497       $err->raise("err",23); // FIXME
498       return false;
499     }
500     $db->query("INSERT INTO mxaccount (login,pass) VALUES ('$login','$pass')");
501     return true;
502   }
503
504   /* ----------------------------------------------------------------- */
505   /**
506    * Remove a slave account
507    */
508   function del_slave_account($login) {
509     global $db,$err;
510     $db->query("DELETE FROM mxaccount WHERE login='$login'");
511