source: bureau/class/m_mail.php @ 348

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

[project @ alternc: changeset 2004-06-03 14:25:28 by anonymous]
fix parse errors Patch by: Guillaume <guillaume@…>

Original author: anonymous
Date: 2004-06-03 14:25:28

Line 
1<?php
2/*
3 $Id: m_mail.php,v 1.12 2004/06/03 14:25:28 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    } else {
163        $account=$db->f("alias");
164    }
165    $res=array("mail" => $mail, "login" => $login, "password" => $pass, "alias" => $account, "pop" => $pop);
166    return $res;
167  }
168
169  /*****************************************************************************/
170  /** Tell if a mail is available or not */
171  function available($mail) {
172    global $err,$db,$cuid;
173    $err->log("mail","available",$mail);
174    $db->query("SELECT mail FROM mail_domain WHERE mail='$mail';");
175    if ($db->next_record()) {
176        return false;
177    } else {
178        return true;
179    }
180  }
181
182  /* ----------------------------------------------------------------- */
183  /** Crée un mail 'executeur' (wrapper) pour $login@$domain
184   * @param string $login partie gauche du @ pour le mail concerné
185   * @param string $domain partie droite du @ pour le mail concerné
186   * @param string $command Commande à exécuter, sans le | ni les "" (commande brute)
187   * @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 ? )
188   * @return boolean TRUE si le wrapper a été créé, FALSE si une erreur s'est produite.
189   */
190  function add_wrapper($login,$domain,$command,$type="") {
191    global $err,$cuid,$db;
192    if (!$this->available($login."@".$domain)) {
193      $err->raise("mail",7,$login."@".$domain);
194      return false;
195    }
196    $db->query("INSERT INTO mail_domain (mail,alias,uid,pop,type) VALUES ('".$login."@".$domain."','".$login."_".$domain."','$cuid',0,1);");
197    $db->query("INSERT INTO mail_alias (mail,alias) VALUES ('".$login."_".$domain."','\"| $command\"');");
198    return true;
199  }
200
201  /* ----------------------------------------------------------------- */
202  /** Efface un mail 'executeur' (wrapper) pour $login@$domain
203   * @param string $login partie gauche du @ pour le mail concerné
204   * @param string $domain partie droite du @ pour le mail concerné
205   * @return boolean TRUE si le wrapper a été effacé, FALSE si une erreur s'est produite.
206   */
207  function del_wrapper($login,$domain) {
208    global $err,$cuid,$db;
209    $db->query("DELETE FROM mail_domain WHERE mail='".$login."@".$domain."' AND uid='$cuid' AND type=1;");
210    $db->query("DELETE FROM mail_alias WHERE mail='".$login."_".$domain."';");
211    return true;
212  }
213
214
215  /* ----------------------------------------------------------------- */
216  /** Change le mot de passe du compte pop $mail
217   * @param string $mail Compte mail concerné
218   * @param string $pass Nouveau mot de passe
219   * @return boolean TRUE si le mot de passe a été changé, FALSE si une erreur s'est produite.
220   */
221  function change_password($mail,$pass) {
222    global $err,$db,$cuid;
223    $err->log("mail","change_password",$mail);
224    $t=explode("@",$mail);
225    $email=$t[0];
226    $dom=$t[1];
227    $db->query("SELECT mail,alias,pop FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
228    if (!$db->next_record()) {
229      $err->raise("mail",3,$mail);
230      return false;
231    }
232    if (!$db->f("pop")) {
233      $err->raise("mail",15);
234      return false;
235    }
236    if (!$this->_updatepop($email,$dom,$pass)) {
237      return false;
238    }
239    return true;
240  }
241
242  /* ----------------------------------------------------------------- */
243  /** Modifie les paramètres d'un compte email
244   * Tout peut être modifié dans l'email (sauf l'adresse elle-même)
245   * @param string $mail Adresse à modifier. Le domaine doit appartenir au membre
246   * @param integer $pop Doit-il etre un compte pop (1) ou juste un alias (0)
247   * @param string $pass Nouveau mot de passe pop, si pop=1
248   * @param string $alias Liste des destinataires auxiliaires, un par ligne.
249   * @return boolean TRUE si l'email a bien été modifié, FALSE si une erreur s'est produite.
250   */
251  function put_mail_details($mail,$pop,$pass,$alias) {
252    global $err,$cuid,$db;
253    $err->log("mail","put_mail_details",$mail);
254    $mail=strtolower($mail);
255    $t=explode("@",$mail);
256    $email=$t[0];
257    $dom=$t[1];
258
259    if ($pop) $pop="1"; else $pop="0";
260    //vérifie si les champs obligatoires sont renseignés
261    if ($pop=="0" && $alias=="") {
262      $err->raise("mail",4);
263      return false;
264    }
265    if ($pop=="1"){
266      $alias=$mail."_".$dom;
267    }
268    //vérifie la validité des alias :
269    if ($alias){
270      $a=explode("\n",$alias);
271      if (count($a)>0) {
272        reset($a);
273        for ($i=0;$i<count($a);$i++){
274          $a[$i]=trim($a[$i]);
275          if ($a[$i]){
276            if(checkmail($a[$i])!=0){
277              $err->raise("mail",14);
278              return false;
279            }
280          }
281        }
282      }
283    }
284
285    $db->query("SELECT mail,alias,pop FROM mail_domain WHERE mail='$mail' AND uid='$cuid' AND type=0;");
286    if (!$db->next_record()) {
287      $err->raise("mail",3,$mail);
288      return false;
289    }
290    $oldpop= $db->f("pop");
291    // When we CREATE a pop account, we MUST give a password
292    if ($pop=="1" && $oldpop!=1) {
293      if (!$pass) {
294        $err->raise("mail",4);
295        return false;
296      }
297    }
298
299    $db->query("UPDATE mail_domain SET alias='$alias', pop='$pop' WHERE mail='$mail';");
300
301    if ($pop=="1" && $oldpop!=1) { /* Creation du compte pop */
302      if (!$this->_createpop($email,$dom,$pass)) {
303        return false;
304      }
305    }
306    if ($pop!="1" && $oldpop==1) { /* Destruction du compte pop */
307      if (!$this->_deletepop($email,$dom)) {
308        return false;
309      }
310    }
311    if ($pop=="1" && $oldpop==1 && $pass!="") { /* Modification du compte pop */
312      if (!$this->_updatepop($email,$dom,$pass)) {
313        return false;
314      }
315    }
316    return true;
317  }
318
319  /* ----------------------------------------------------------------- */
320  /** Crée un compte email $mail sur le domaine $dom
321   * @param string $dom Domaine concerné, il doit appartenir au membre
322   * @param string $mail Email à créer, il ne doit pas exister ni en mail, ni en liste.
323   * @param integer $pop vaut 1 pour créer un compte pop, 0 pour un alias
324   * @param string $alias Liste des alias, un par ligne
325   * @return boolean TRUE si le compte a bien été créé, FALSE si une erreur s'est produite.
326   */
327  function add_mail($dom,$mail,$pop,$pass,$alias) {
328    global $quota,$err,$cuid,$db;
329    $err->log("mail","add_mail",$dom."/".$mail);
330    $account=array();
331    $mail=strtolower($mail);
332    if ($pop) $pop="1"; else $pop="0";
333    if ($mail) {
334      //vérifie la validité du login mail
335      if (!checkloginmail($mail)) {
336        $err->raise("mail",13);
337        return false;
338      }
339    }
340    //vérifie si les champs obligatoires sont renseignés
341    if (($pop=="1" && $pass=="")||($pop!="1" && $alias=="")){
342      $err->raise("mail",4);
343      return false;
344    }
345    if ($pop=="1"){
346      $alias=$mail."_".$dom;
347    }
348    //vérifie la validité des alias :
349    if ($alias){
350      $a=explode("\n",$alias);
351      if (count($a)>0) {
352        reset($a);
353        for ($i=0;$i<count($a);$i++){
354          $a[$i]=trim($a[$i]);
355          if ($a[$i]){
356            if(checkmail($a[$i])!=0){
357              $err->raise("mail",14);
358              return false;
359            }
360          }
361        }
362      }
363    }
364
365    // check that the domains is a user's one ...
366    $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$dom';");
367    if (!$db->next_record()) {
368      $err->raise("mail",6,$dom);
369      return false;
370    }   
371    $db->query("SELECT mail FROM mail_domain WHERE mail='".$mail."@".$dom."' AND uid='$cuid';");
372    if ($db->next_record()) {
373      $err->raise("mail",7,$dom);
374      return false;
375    }   
376
377    /* QuotaCheck */
378    if (!$quota->cancreate("mail")) {
379      $err->raise("mail",8);
380      return false;
381    }
382    $quota->inc("mail");
383    $db->query("INSERT INTO mail_domain (mail,alias,uid,pop,type) VALUES ('".$mail."@".$dom."','$alias','$cuid','$pop',0);");
384
385    // Ajout du compte pop dans ldap-users
386    if ($pop=="1") {
387      if (!$this->_createpop($mail,$dom,$pass))
388        return false;
389    }
390    return true;
391  }
392
393  /* ----------------------------------------------------------------- */
394  /** Efface le compte mail $mail
395   * @param string $mail Email à effacer
396   * @return boolean TRUE si le compte mail a bien été détruit, FALSE si une erreur s'est produite.
397   */
398  function del_mail($mail) {
399    global $quota,$err,$cuid,$db;
400    $err->log("mail","del_mail",$mail);
401    $mail=strtolower($mail);
402
403    $db->query("SELECT pop,mail FROM mail_domain WHERE mail='$mail' AND uid='$cuid' AND type=0;");
404    if (!$db->next_record()) {
405      $err->raise("mail",3,$dom);
406      return false;
407    }   
408    /* Ok, le mail existe, on le detruit donc... */
409    $t=explode("@",$mail);
410    $mdom=$t[0]; $dom=$t[1];
411    $quota->dec("mail");
412    $pop=$db->f("pop");
413   
414    $db->query("DELETE FROM mail_domain WHERE mail='$mail' AND uid='$cuid';");
415
416    if ($pop=="1") {
417      if (!$this->_deletepop($mdom,$dom)) {
418        return false;
419      }
420    }
421    return true;
422  }
423
424  /* ----------------------------------------------------------------- */
425  /** Crée le compte pop $mail@$dom, avec pour mot de passe $pass
426   * @param string $mail Compte email à créer en pop
427   * @param string $dom Domaine sur lequel on crée le compte email
428   * @param string $pass Mot de passe du compte email.
429   * @return boolean TRUE si le compte pop a bien été créé, FALSE si une erreur est survenur
430   * @access private
431   */
432  function _createpop($mail,$dom,$pass) {
433    global $err,$cuid,$db;
434    $err->log("mail","_createpop",$mail."@".$dom);
435    $m=substr($mail,0,1);
436    $gecos=$mail;
437    if (!$mail) {
438      // Cas du CATCH-ALL
439      $gecos="Catch-All";
440      $m="_";
441    }
442    $db->query("INSERT INTO mail_users (uid,alias,path,password) VALUES ('$cuid','".$mail."_".$dom."','/var/alternc/mail/".$m."/".$mail."_".$dom."','"._md5cr($pass)."');");
443    $db->query("INSERT INTO mail_users (uid,alias,path,password) VALUES ('$cuid','".$mail."@".$dom."','/var/alternc/mail/".$m."/".$mail."_".$dom."','"._md5cr($pass)."');");
444
445    $f=fopen("/var/lib/squirrelmail/data/".$mail."_".$dom.".pref","wb");
446    fputs($f,"email_address=$mail@$dom\nchosen_theme=default_theme.php\n");
447    fclose($f);
448    $f=fopen("/var/lib/squirrelmail/data/".$mail."@".$dom.".pref","wb");
449    fputs($f,"email_address=$mail@$dom\nchosen_theme=default_theme.php\n");
450    fclose($f);
451    exec("/usr/lib/alternc/mail_add ".$mail."_".$dom." ".$cuid);
452    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -c -p ".$mail."@".$dom);
453    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -c -p ".$mail."_".$dom);
454    return true;
455  }
456
457  /* ----------------------------------------------------------------- */
458  /** Met à jour un compte pop existant
459   * @param string $mail mail à modifier
460   * @param string $dom Domaine dont on modifie le compte pop
461   * @param string $pass Nouveau mot de passe.
462   * @return boolean TRUE si le compte pop a bien été modifié, FALSE si une erreur s'est produite.
463   * @access private
464   */
465  function _updatepop($mail,$dom,$pass) {
466    global $err,$cuid,$db;
467    $err->log("mail","_updatepop",$mail."@".$dom);
468    $m=substr($mail,0,1);
469    $gecos=$mail;
470    $db->query("UPDATE mail_users SET password='"._md5cr($pass)."' WHERE ( alias='". $mail."_".$dom."' OR alias='". $mail."@".$dom."' ) AND uid='$cuid';");
471    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -p ".$mail."@".$dom);
472    exec("/bin/echo ".escapeshellarg($pass)." | /usr/sbin/saslpasswd -u postfix -p ".$mail."_".$dom);
473    return true;
474  }
475
476  /* ----------------------------------------------------------------- */
477  /** Détruit le compte pop $mail@$dom.
478   * @param string $mail Email dont on souhaite détruire le compte pop
479   * @param string $dom Domaine dont on souhaite détuire le compte pop.
480   * @return boolean TRUE si le compte pop a bien été détruit, FALSE si une erreur s'est produite.
481   * @access private
482   */
483  function _deletepop($mail,$dom) {
484    global $err,$cuid,$db;
485    $err->log("mail","_deletepop",$mail."@".$dom);
486    $db->query("DELETE FROM mail_users WHERE uid='$cuid' AND (  alias='". $mail."_".$dom."' OR alias='". $mail."@".$dom."' ) ;");
487    @unlink("/var/lib/squirrelmail/data/".$mail."_".$dom.".pref");
488    @unlink("/var/lib/squirrelmail/data/".$mail."_".$dom.".abook");
489    @unlink("/var/lib/squirrelmail/data/".$mail."@".$dom.".pref");
490    @unlink("/var/lib/squirrelmail/data/".$mail."@".$dom.".abook");
491    exec("/usr/lib/alternc/mail_del ".$mail."_".$dom);
492    exec("/usr/sbin/saslpasswd -u postfix -d ".$mail."@".$dom);
493    exec("/usr/sbin/saslpasswd -u postfix -d ".$mail."_".$dom);
494    return true;
495  }
496
497  /* ----------------------------------------------------------------- */
498  /** Fonction appellée par domaines lorsqu'un domaine est effacé.
499   * Cette fonction efface tous les comptes mails du domaine concerné.
500   * @param string $dom Domaine à effacer
501   * @return boolean TRUE si le domaine a bien été effacé, FALSE si une erreur s'est produite.
502   * @access private
503   */
504  function alternc_del_mx_domain($dom) {
505    global $err,$quota,$db,$cuid;
506    $err->error=0;
507    $err->log("mail","del_dom",$dom);
508
509    $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$dom';");
510    if (!$db->next_record()) {
511      $err->raise("mail",6,$dom);
512      return false;
513    }   
514
515    /* Effacement de tous les mails de ce domaine : */
516    $a=$this->enum_doms_mails($dom);
517    if (is_array($a)) {
518      reset($a);
519      for($i=0;$i<$a["count"];$i++) {
520        $val=$a[$i];
521        if (!$this->del_mail($val["mail"])) {
522          $err->raise("mail",5);
523        }
524      }
525      /* Mise à jour des quotas mails*/
526      $q=$quota->getquota("mail");
527      if (!is_array($q)) {
528        $err->raise("mail",10);
529        return false;
530      } else {
531        $u=$q["u"];
532        $new=$u-$a["count"];
533        if(!$quota->setquota("mail",$new,1)){
534          $err->raise("mail",10);
535          return false;
536        }
537      }
538    }
539    /* Effacement du domaine himself */
540    $db->query("DELETE FROM mail_domain WHERE mail LIKE '%@$dom';");     
541    $db->query("DELETE FROM mail_users WHERE alias LIKE '%@$dom' OR alias LIKE '%_$dom';");     
542    $db->query("DELETE FROM mail_alias WHERE mail LIKE '%_$dom';");     
543    $db->query("DELETE FROM mail_domain WHERE mail='$dom';");
544    return true;
545  }
546
547  /* ----------------------------------------------------------------- */
548  /** Fonction appellée par domaines lorsqu'un domaine est créé.
549   * Cette fonction crée les comptes par défaut du domaine concerné.
550   * @param string $dom Domaine à créer
551   * @return boolean TRUE si le domaine a bien été créé, FALSE si une erreur s'est produite.
552   * @access private
553   * TODO : ne créer les entrées que si le MX est à true ! (déplacer a alternc_add_mx_domain
554   */
555  function alternc_add_mx_domain($dom) {
556    global $err,$cuid,$db;
557    $err->log("mail","add_dom",$dom);
558
559    $db->query("SELECT domaine FROM domaines WHERE compte='$cuid' AND domaine='$dom';");
560    if ($db->next_record()) {
561      $err->raise("mail",9,$dom);
562      return false;
563    }   
564
565    $db->query("INSERT INTO mail_domain (mail,alias) VALUES ('$dom','$dom');");
566    return true;
567  }
568
569  /* TODO : alternc_quota_check */
570  function alternc_quota_check($id=-1) {
571    global $quota,$err,$cuid,$db;
572    $db->query("SELECT COUNT(*) AS cnt FROM mail_domain WHERE type=0;");
573    $db->next_record();
574    $quota->setquota("mail",$db->f("cnt"),1);
575    return true;
576  }
577
578
579} /* Class m_mail */
580
581?>
Note: See TracBrowser for help on using the repository browser.