Alternc  latest
Alternc logiel libre pour l'hébergement
m_mail Class Reference

This class handle emails (pop and/or aliases and even wrapper for internal classes) of hosted users. More...

Public Member Functions

 m_mail ()
 Constructeur. More...
 
 hook_menu ()
 Hook called by menu class to add the email menu to the left pane. More...
 
 get_total_size_for_domain ($domain)
 
 catchall_getinfos ($domain_id)
 
 catchall_del ($domain_id)
 
 catchall_set ($domain_id, $target)
 
 hook_quota_get ()
 get_quota (hook for quota class), returns the number of used service for a quota-bound service More...
 
 alternc_password_policy ()
 Password policy kind used in this class (hook for admin class) More...
 
 enum_domains ($uid=-1)
 Returns the list of mail-hosting domains for a user. More...
 
 available ($mail)
 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. More...
 
 enum_domain_mails ($dom_id=null, $search="", $offset=0, $count=30, $show_systemmails=false)
 function used to list every mail address hosted on a domain. More...
 
 hook_mail_get_details ($detail)
 
 create ($dom_id, $mail, $type="", $dontcheck=false)
 Function used to insert a new mail into the db should be used by the web interface, not by third-party programs. More...
 
 get_details ($mail_id)
 function used to get every information we can on a mail More...
 
 is_it_my_mail ($mail_id)
 Check if an email is mine ... More...
 
 hook_dom_del_mx_domain ($dom_id)
 Hook called when the DOMAIN class will delete a domain. More...
 
 get_account_by_mail_id ($mail_id)
 return the alternc account's ID of the mail_id More...
 
 delete ($mail_id)
 Function used to delete a mail from the db should be used by the web interface, not by third-party programs. More...
 
 undelete ($mail_id)
 Function used to undelete a pending deletion mail from the db should be used by the web interface, not by third-party programs. More...
 
 set_passwd ($mail_id, $pass, $canbeempty=false)
 set the password of an email address. More...
 
 enable ($mail_id)
 Enables an email address. More...
 
 disable ($mail_id)
 Disables an email address. More...
 
 set_details ($mail_id, $islocal, $quotamb, $recipients, $delivery="dovecot", $dontcheck=false)
 Function used to update an email settings should be used by the web interface, not by third-party programs. More...
 
 add_wrapper ($dom_id, $m, $delivery)
 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. More...
 
 create_alias ($dom_id, $m, $alias, $type="", $dontcheck=false)
 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. More...
 
 del_wrapper ($mail_id)
 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. More...
 
 alternc_export_conf ()
 Export the mail information of an account. More...
 
 enum_slave_account ()
 Return the list of allowed slave accounts (secondary-mx) More...
 
 check_slave_account ($login, $pass)
 Check for a slave account (secondary mx) More...
 
 echo_domain_list ($format=null)
 Out (echo) the complete hosted domain list : More...
 
 add_slave_account ($login, $pass)
 Add a slave account that will be allowed to access the mxdomain list. More...
 
 del_slave_account ($login)
 Remove a slave account. More...
 
 hook_dom_add_slave_domain ($domain_id, $target_domain)
 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 More...
 
 hook_dom_add_mx_domain ($domain_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 More...
 
 hook_variable_set ($name, $old, $new)
 hook function called by variables when a variable is changed @access private More...
 
 set_dns_autoconf ($domain, $uid=-1)
 Add dns entries for autodiscover / autoconf on the domain. More...
 
 del_dns_autoconf ($domain)
 delete the autoconf / autodiscover vhosts when removing a domain as MX More...
 
 set_dns_spf ($domain, $spf, $previous=-1, $uid=-1, $login=-1)
 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. More...
 
 del_dns_spf ($domain)
 delete the SPF entries in the sub_domaine table for a domain called by del_domain or del_mx_domain by hooks : More...
 
 set_dns_dmarc ($domain, $dmarc, $previous=-1, $uid=-1, $login=-1)
 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. More...
 
 del_dns_dmarc ($domain)
 delete the DMARC entries in the sub_domaine table for a domain called by del_domain or del_mx_domain by hooks : More...
 
 hook_updatedomains_dns_pre ()
 Hook launched before doing anything dns-related. More...
 
 hook_updatedomains_dns_post ()
 Hook launched after doing anything dns-related. More...
 
 dkim_add ($domain, $uid)
 Add a domain into OpenDKIM configuration. More...
 
 dkim_del ($domain)
 Delete a domain from OpenDKIM configuration. More...
 
 dkim_get_entry ($domain)
 return the content of the TXT information to be added into the DB for DKIM subdomains More...
 

Public Attributes

 $domains
 domain list for this account @access private More...
 
 $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. More...
 
 $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. More...
 
 $total
 Number of results for a pager display @access public. More...
 
 $srv_postfix
 
 $srv_dovecot
 
 $cache_domain_mail_size = array()
 
 $enum_domains = array()
 
 $shouldreloaddkim
 Manage DKIM when adding / removing a domain MX management. More...
 

Private Attributes

 $isitmy_cache = array()
 

Detailed Description

This class handle emails (pop and/or aliases and even wrapper for internal classes) of hosted users.

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.

Definition at line 32 of file m_mail.php.

Member Function Documentation

◆ add_slave_account()

m_mail::add_slave_account (   $login,
  $pass 
)

Add a slave account that will be allowed to access the mxdomain list.

Parameters
string$loginthe login to add
string$passthe password to add
Returns
boolean TRUE if the account has been created, or FALSE if an error occurred.

Definition at line 898 of file m_mail.php.

898  {
899  global $db, $msg;
900  $db->query("SELECT * FROM mxaccount WHERE login= ? ;", array($login));
901  if ($db->next_record()) {
902  $msg->raise("ERROR", "mail", _("The slave MX account was not found"));
903  return false;
904  }
905  $db->query("INSERT INTO mxaccount (login,pass) VALUES (?, ?);", array($login, $pass));
906  return true;
907  }

◆ add_wrapper()

m_mail::add_wrapper (   $dom_id,
  $m,
  $delivery 
)

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.

Definition at line 744 of file m_mail.php.

744  {
745  global $msg, $mail;
746  $msg->log("mail", "add_wrapper", "creating $delivery $m address");
747 
748  $mail_id = $mail->create($dom_id, $m, $delivery);
749  $this->set_details($mail_id, 1, 0, '', $delivery);
750  // FIXME return error code
751  }
set_details($mail_id, $islocal, $quotamb, $recipients, $delivery="dovecot", $dontcheck=false)
Function used to update an email settings should be used by the web interface, not by third-party pro...
Definition: m_mail.php:675

References set_details().

◆ alternc_export_conf()

m_mail::alternc_export_conf ( )

Export the mail information of an account.

Returns
: str, string containing the complete configuration of the email for the current acccount.

Definition at line 794 of file m_mail.php.

794  {
795  global $msg;
796  $msg->log("mail", "export");
797  $domain = $this->enum_domains();
798  $str = "<mail>\n";
799  foreach ($domain as $d) {
800  $str.=" <domain>\n <name>" . xml_entities($d["domain"]) . "</name>\n";
801  $s = $this->enum_domain_mails($d["id"]);
802  if (count($s)) {
803  while (list($key, $val) = each($s)) {
804  $str.=" <address>\n";
805  $str.=" <name>" . xml_entities($val["address"]) . "</name>\n";
806  $str.=" <enabled>" . xml_entities($val["enabled"]) . "</enabled>\n";
807  if (is_array($val["islocal"])) {
808  $str.=" <islocal>1</islocal>\n";
809  $str.=" <quota>" . $val["quota"] . "</quota>\n";
810  $str.=" <path>" . $val["path"] . "</path>\n";
811  } else {
812  $str.=" <islocal>0</islocal>\n";
813  }
814  if (!empty($val["recipients"])) {
815  $r = explode("\n", $val["recipients"]);
816  foreach ($r as $recip) {
817  $str.=" <recipients>" . $recip . "<recipients>\n";
818  }
819  }
820  $str.=" </address>\n";
821  }
822  }
823  $str.=" </domain>\n";
824  }
825  $str.="</mail>\n";
826  return $str;
827  }
enum_domain_mails($dom_id=null, $search="", $offset=0, $count=30, $show_systemmails=false)
function used to list every mail address hosted on a domain.
Definition: m_mail.php:285
enum_domains($uid=-1)
Returns the list of mail-hosting domains for a user.
Definition: m_mail.php:218

References enum_domain_mails(), and enum_domains().

◆ alternc_password_policy()

m_mail::alternc_password_policy ( )

Password policy kind used in this class (hook for admin class)

Returns
array an array of policykey => "policy name (for humans)"

Definition at line 209 of file m_mail.php.

209  {
210  return array("pop" => _("Email account password"));
211  }

◆ available()

m_mail::available (   $mail)

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.

Parameters
$mailstring email to check
Returns
boolean true if the email can be installed on the server

Definition at line 254 of file m_mail.php.

254  {
255  global $db, $msg, $dom;
256  $msg->log("mail", "available");
257  list($login, $domain) = explode("@", $mail, 2);
258  // Validate the domain ownership & syntax
259  if (!($dom_id = $dom->get_domain_byname($domain))) {
260  return false;
261  }
262  // Validate the email syntax:
263  if (!filter_var($mail, FILTER_VALIDATE_EMAIL)) {
264  $msg->raise("ERROR", "mail", _("The email you entered is syntaxically incorrect"));
265  return false;
266  }
267  // Check the availability
268  $db->query("SELECT a.id FROM address a WHERE a.domain_id= ? AND a.address= ?;", array($dom_id, $login));
269  if ($db->next_record()) {
270  return false;
271  } else {
272  return true;
273  }
274  }

◆ catchall_del()

m_mail::catchall_del (   $domain_id)
Parameters
string$domain_id

Definition at line 152 of file m_mail.php.

152  {
153  $catch = $this->catchall_getinfos($domain_id);
154  if (empty($catch['mail_id'])) {
155  return false;
156  }
157  return $this->delete($catch['mail_id']);
158  }
catchall_getinfos($domain_id)
Definition: m_mail.php:121

References catchall_getinfos().

Referenced by catchall_set().

◆ catchall_getinfos()

m_mail::catchall_getinfos (   $domain_id)
Parameters
string$domain_id

Definition at line 121 of file m_mail.php.

121  {
122  global $dom, $db;
123  $rr = array(
124  'mail_id' => '',
125  'domain' => $dom->get_domain_byid($domain_id),
126  'target' => '',
127  'type' => '',
128  );
129 
130  $db->query("select r.recipients as dst, a.id mail_id from address a, recipient r where a.domain_id = ? and r.address_id = a.id and a.address='';", array($domain_id));
131  if ($db->next_record()) {
132  $rr['target'] = $db->f('dst');
133  $rr['mail_id'] = $db->f('mail_id');
134  }
135 
136  // Does it redirect to a specific mail or to a domain
137  if (empty($rr['target'])) {
138  $rr['type'] = 'none';
139  } elseif (substr($rr['target'], 0, 1) == '@') {
140  $rr['type'] = 'domain';
141  } else {
142  $rr['type'] = 'mail';
143  }
144 
145  return $rr;
146  }

Referenced by catchall_del().

◆ catchall_set()

m_mail::catchall_set (   $domain_id,
  $target 
)
Parameters
string$domain_id
string$target

Definition at line 165 of file m_mail.php.

165  {
166  global $msg;
167  $target = rtrim($target);
168  if (strlen($target) > 0 && substr_count($target, '@') == 0) { // Pas de @
169  $target = '@' . $target;
170  }
171 
172  if (substr($target, 0, 1) == '@') { // the first character is @
173  // FIXME validate domain
174  } else { // it MUST be an email
175  if (!filter_var($target, FILTER_VALIDATE_EMAIL)) {
176  $msg->raise("ERROR", "mail", _("The email you entered is syntaxically incorrect"));
177  return false;
178  }
179  }
180  $this->catchall_del($domain_id);
181  return $this->create_alias($domain_id, '', $target, "catchall", true);
182  }
create_alias($dom_id, $m, $alias, $type="", $dontcheck=false)
A function used to create an alias for a specific address @ param : $dom_id , the domain sql identifi...
Definition: m_mail.php:764
catchall_del($domain_id)
Definition: m_mail.php:152

References catchall_del(), and create_alias().

Referenced by hook_dom_add_slave_domain().

◆ check_slave_account()

m_mail::check_slave_account (   $login,
  $pass 
)

Check for a slave account (secondary mx)

Parameters
string$loginthe login to check
string$passthe password to check
Returns
boolean TRUE if the password is correct, or FALSE if an error occurred.

Definition at line 854 of file m_mail.php.

854  {
855  global $db;
856  $db->query("SELECT * FROM mxaccount WHERE login= ? AND pass= ?;", array($login, $pass));
857  if ($db->next_record()) {
858  return true;
859  }
860  return false;
861  }

◆ create()

m_mail::create (   $dom_id,
  $mail,
  $type = "",
  $dontcheck = false 
)

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

Parameters
$dom_idinteger A domain_id (owned by the user) (will be the part at the right of the @ in the email)
$mailstring the left part of the email to create (something@dom_id)
Returns
an hashtable containing the database id of the newly created mail, or false if an error occured ($msg is filled accordingly)

Definition at line 350 of file m_mail.php.

350  {
351  global $msg, $db, $quota, $dom, $hooks;
352  $msg->log("mail", "create", $mail);
353 
354  // Validate the domain id
355  if (!($domain = $dom->get_domain_byid($dom_id))) {
356  return false;
357  }
358 
359  // Validate the email syntax:
360  $m = $mail . "@" . $domain;
361  if (!filter_var($m, FILTER_VALIDATE_EMAIL) && !$dontcheck) {
362  $msg->raise("ERROR", "mail", _("The email you entered is syntaxically incorrect"));
363  return false;
364  }
365 
366  // Call other classes to check we can create it:
367  $cancreate = $hooks->invoke("hook_mail_cancreate", array($dom_id, $mail));
368  if (in_array(false, $cancreate, true)) {
369  return false;
370  }
371 
372  // Check the quota:
373  if (($type=="")&&!$quota->cancreate("mail")) {
374  $msg->raise("ALERT", "mail", _("You cannot create email addresses: your quota is over"));
375  return false;
376  }
377  // Already exists?
378  $db->query("SELECT * FROM address WHERE domain_id= ? AND address= ? ;", array($dom_id, $mail));
379  if ($db->next_record()) {
380  if ($db->f("type") == "mailman")
381  $msg->raise("ERROR", "mail", _("This email address already exists in mailman"));
382  else
383  $msg->raise("ERROR", "mail", _("This email address already exists"));
384 
385  return false;
386  }
387  // Create it now
388  $db->query("INSERT INTO address (domain_id, address,type) VALUES (?, ?, ?);", array($dom_id, $mail, $type));
389  if (!($id = $db->lastid())) {
390  $msg->raise("ERROR", "mail", _("An unexpected error occured when creating the email"));
391  return false;
392  }
393  return $id;
394  }

◆ create_alias()

m_mail::create_alias (   $dom_id,
  $m,
  $alias,
  $type = "",
  $dontcheck = false 
)

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.

Parameters
string$m
string$alias
string$dom_id

Definition at line 764 of file m_mail.php.

764  {
765  global $msg, $mail;
766  $msg->log("mail", "create_alias", "creating $m alias for $alias type $type");
767 
768  $mail_id = $mail->create($dom_id, $m, $type, $dontcheck);
769  if (!$mail_id) {
770  return false;
771  }
772  $this->set_details($mail_id, 0, 0, $alias, "dovecot", $dontcheck);
773  return true;
774  }

References set_details().

Referenced by catchall_set(), and hook_dom_add_mx_domain().

◆ del_dns_autoconf()

m_mail::del_dns_autoconf (   $domain)

delete the autoconf / autodiscover vhosts when removing a domain as MX

Definition at line 1037 of file m_mail.php.

1037  {
1038  global $db, $L_FQDN, $cuid;
1039  $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ? AND type='autodiscover' AND sub='autoconfig';", array($domain));
1040  $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ? AND type='autodiscover' AND sub='autodiscover';", array($domain));
1041  }

Referenced by hook_dom_del_mx_domain().

◆ del_dns_dmarc()

m_mail::del_dns_dmarc (   $domain)

delete the DMARC entries in the sub_domaine table for a domain called by del_domain or del_mx_domain by hooks :

Definition at line 1125 of file m_mail.php.

1125  {
1126  global $db;
1127  $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ? AND type='txt' AND sub='_dmarc' AND valeur LIKE lower('v=DMARC1;%');", array($domain));
1128  }

Referenced by hook_dom_del_mx_domain().

◆ del_dns_spf()

m_mail::del_dns_spf (   $domain)

delete the SPF entries in the sub_domaine table for a domain called by del_domain or del_mx_domain by hooks :

Definition at line 1079 of file m_mail.php.

1079  {
1080  global $db;
1081  $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ? AND type='txt' AND sub='' AND valeur LIKE 'v=spf1 %';", array($domain));
1082  }

Referenced by hook_dom_del_mx_domain().

◆ del_slave_account()

m_mail::del_slave_account (   $login)

Remove a slave account.

Parameters
string$loginthe login to delete

Definition at line 914 of file m_mail.php.

914  {
915  global $db;
916  $db->query("DELETE FROM mxaccount WHERE login= ? ;", array($login));
917  return true;
918  }

◆ del_wrapper()

m_mail::del_wrapper (   $mail_id)

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.

Definition at line 782 of file m_mail.php.

782  {
783  global $msg;
784  $msg->log("mail", "del_wrapper");
785  $this->delete($mail_id);
786  }

◆ delete()

m_mail::delete (   $mail_id)

Function used to delete a mail from the db should be used by the web interface, not by third-party programs.

Parameters
$mail_idinteger the number of the email to delete
Returns
boolean if the email has been properly deleted or false if an error occured ($msg is filled accordingly)

Definition at line 506 of file m_mail.php.

506  {
507  global $msg, $db, $hooks;
508  $msg->log("mail", "delete");
509 
510  $mail_id = intval($mail_id);
511 
512  if (!$mail_id) {
513  $msg->raise("ERROR", "mail", _("The email you entered is syntaxically incorrect"));
514  return false;
515  }
516  // Validate that this email is owned by me...
517  if (!($mail = $this->is_it_my_mail($mail_id))) {
518  return false;
519  }
520 
521  $mailinfos = $this->get_details($mail_id);
522  $hooks->invoke('hook_mail_delete', array($mail_id, $mailinfos['address'] . '@' . $mailinfos['domain']));
523 
524  // Search for that address:
525  $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= ? ;", array($mail_id));
526  if (!$db->next_record()) {
527  $msg->raise("ERROR", "mail", _("The email %s does not exist, it can't be deleted"), $mail);
528  return false;
529  }
530  if ($db->f("mail_action") != "OK" || ($db->f("islocal") && $db->f("mailbox_action") != "OK")) { // will be deleted soon ...
531  $msg->raise("ERROR", "mail", _("The email %s is already marked for deletion, it can't be deleted"), $mail);
532  return false;
533  }
534  $mail_id = $db->f("id");
535 
536  if ($db->f("islocal")) {
537  // If it's a pop/imap mailbox, mark it for deletion
538  $db->query("UPDATE address SET mail_action='DELETE', enabled=0 WHERE id= ?;", array($mail_id));
539  $db->query("UPDATE mailbox SET mail_action='DELETE' WHERE address_id= ?;", array($mail_id));
540  } else {
541  // If it's only aliases, delete it NOW.
542  $db->query("DELETE FROM address WHERE id= ? ;", array($mail_id));
543  $db->query("DELETE FROM mailbox WHERE address_id= ? ;", array($mail_id));
544  $db->query("DELETE FROM recipient WHERE address_id= ? ;", array($mail_id));
545  }
546  return true;
547  }
get_details($mail_id)
function used to get every information we can on a mail
Definition: m_mail.php:402
is_it_my_mail($mail_id)
Check if an email is mine ...
Definition: m_mail.php:436

References get_details(), and is_it_my_mail().

◆ disable()

m_mail::disable (   $mail_id)

Disables an email address.

Parameters
$mail_idinteger Email ID
Returns
boolean true if the email has been enabled.

Definition at line 651 of file m_mail.php.

651  {
652  global $db, $msg;
653  $msg->log("mail", "disable");
654  if (!($email = $this->is_it_my_mail($mail_id))) {
655  return false;
656  }
657  if (!$db->query("UPDATE address SET `enabled`=0 where id= ? ;", array($mail_id))) {
658  return false;
659  }
660  return true;
661  }

References is_it_my_mail().

◆ dkim_add()

m_mail::dkim_add (   $domain,
  $uid 
)

Add a domain into OpenDKIM configuration.

Definition at line 1178 of file m_mail.php.

1178  {
1179  global $db;
1180  $target_dir = "/etc/opendkim/keys/$domain";
1181  // Create a dkim key when it's not already there :
1182  if (!file_exists($target_dir.'/alternc.txt')) {
1183  $this->shouldreloaddkim=true;
1184  if (! is_dir($target_dir)) mkdir($target_dir); // create dir
1185  $old_dir=getcwd();
1186  chdir($target_dir);
1187  // Generate the key, 2048 bits (better than 1024)
1188  // 2048 bits is also the default in recent Debian builds of opendkim
1189  // @see man opendkim-genkey
1190  exec('opendkim-genkey -b 2048 -r -d '.escapeshellarg($domain).' -s "alternc" ');
1191  chdir($old_dir);
1192  // opendkim must be owner of the key
1193  chown("$target_dir/alternc.private", 'opendkim');
1194  chgrp("$target_dir/alternc.private", 'opendkim');
1195 
1196  add_line_to_file("/etc/opendkim/KeyTable","alternc._domainkey.".$domain." ".$domain.":alternc:/etc/opendkim/keys/".$domain."/alternc.private");
1197  add_line_to_file("/etc/opendkim/SigningTable",$domain." alternc._domainkey.".$domain);
1198  }
1199 
1200  // Search for the subdomain entry, if it's not already there, create it:
1201  $db->query("SELECT id FROM sub_domaines WHERE domaine=? AND sub='alternc._domainkey';",array($domain));
1202  if (!$db->next_record()) {
1203  // Add subdomaine entry
1204  $dkim_key=$this->dkim_get_entry($domain);
1205  $db->query("INSERT INTO sub_domaines SET domaine=?, compte=?, sub='alternc._domainkey', type='dkim', valeur=?;",array($domain,$uid,$dkim_key));
1206  // no need to do DNS_ACTION="UPDATE" => we are in the middle of a HOOK, so dns WILL BE reloaded for this domain
1207  }
1208  }
dkim_get_entry($domain)
return the content of the TXT information to be added into the DB for DKIM subdomains
Definition: m_mail.php:1238

References dkim_get_entry().

Referenced by hook_updatedomains_dns_pre().

◆ dkim_del()

m_mail::dkim_del (   $domain)

Delete a domain from OpenDKIM configuration.

Definition at line 1215 of file m_mail.php.

1215  {
1216  global $db;
1217  $target_dir = "/etc/opendkim/keys/$domain";
1218  if (file_exists($target_dir)) {
1219  $this->shouldreloaddkim=true;
1220  @unlink("$target_dir/alternc.private");
1221  @unlink("$target_dir/alternc.txt");
1222  @rmdir($target_dir);
1223  del_line_from_file("/etc/opendkim/KeyTable","alternc._domainkey.".$domain." ".$domain.":alternc:/etc/opendkim/keys/".$domain."/alternc.private");
1224  del_line_from_file("/etc/opendkim/SigningTable",$domain." alternc._domainkey.".$domain);
1225  }
1226  $db->query("DELETE FROM sub_domaines WHERE domaine=? AND sub='alternc._domainkey';",array($domain));
1227  // No need to do DNS_ACTION="UPDATE" => we are in the middle of a HOOK
1228  }

Referenced by hook_dom_del_mx_domain(), and hook_updatedomains_dns_pre().

◆ dkim_get_entry()

m_mail::dkim_get_entry (   $domain)

return the content of the TXT information to be added into the DB for DKIM subdomains

Parameters
$domainstring the name of the domain name
Returns
string the TXT entry (without quotes) or false if an error occurred

Definition at line 1238 of file m_mail.php.

1238  {
1239  global $msg;
1240  $key=file_get_contents("/etc/opendkim/keys/".$domain."/alternc.txt");
1241  // easy: monoline key
1242  if (preg_match('#alternc._domainkey IN TXT "(.*)"#',$key,$mat)) {
1243  return $mat[1];
1244  } else {
1245  // Need to parse a multiligne key:
1246  $inkey=false; $result="";
1247  $lines=explode("\n",$key);
1248  foreach($lines as $line) {
1249  if (preg_match('#alternc._domainkey\s+IN\s+TXT\s+\‍( "(.*)"#',$line,$mat)) {
1250  $result.=$mat[1]; $inkey=true; continue;
1251  }
1252  if ($inkey && preg_match('#^\s*"(.*)"\s*\‍)#',$line,$mat)) {
1253  $result.=$mat[1]; $inkey=false; break;
1254  }
1255  if ($inkey && preg_match('#^\s*"(.*)"\s*$#',$line,$mat)) {
1256  $result.=$mat[1]; $inkey=true; continue;
1257  }
1258  }
1259  if ($result)
1260  return $result;
1261  }
1262  $msg->debug("mail","dkim_get_entry($domain) failed");
1263  return false;
1264  }

Referenced by dkim_add().

◆ echo_domain_list()

m_mail::echo_domain_list (   $format = null)

Out (echo) the complete hosted domain list :

Definition at line 867 of file m_mail.php.

867  {
868  global $db;
869  $db->query("SELECT domaine FROM domaines WHERE gesmx=1 ORDER BY domaine");
870  $lst = array();
871  $tt = "";
872  while ($db->next_record()) {
873  $lst[] = $db->f("domaine");
874  $tt.=$db->f("domaine");
875  }
876 
877  // Generate an integrity check
878  $obj = array('integrity' => md5($tt), 'items' => $lst);
879 
880  switch ($format) {
881  case "json":
882  return json_encode($obj);
883  default:
884  foreach ($lst as $l) {
885  echo $l . "\n";
886  }
887  return true;
888  } // switch
889  }

◆ enable()

m_mail::enable (   $mail_id)

Enables an email address.

Parameters
$mail_idinteger Email ID
Returns
boolean true if the email has been enabled.

Definition at line 633 of file m_mail.php.

633  {
634  global $db, $msg;
635  $msg->log("mail", "enable");
636  if (!($email = $this->is_it_my_mail($mail_id))) {
637  return false;
638  }
639  if (!$db->query("UPDATE address SET `enabled`=1 where id= ? ;", array($mail_id))) {
640  return false;
641  }
642  return true;
643  }

References is_it_my_mail().

◆ enum_domain_mails()

m_mail::enum_domain_mails (   $dom_id = null,
  $search = "",
  $offset = 0,
  $count = 30,
  $show_systemmails = false 
)

function used to list every mail address hosted on a domain.

Parameters
$dom_idinteger the domain id.
$searchstring search that string in recipients or address.
$offsetinteger skip THAT much emails in the result.
$countinteger return no more than THAT much emails. -1 for ALL. Offset is ignored then.
Returns
an array of each mail hosted under the domain.

Definition at line 285 of file m_mail.php.

285  {
286  global $db, $msg, $hooks;
287  $msg->debug("mail", "enum_domains_mail");
288 
289  $query_args = array($dom_id);
290  $search = trim($search);
291  $where = " a.domain_id = ? ";
292 
293  if ($search) {
294  $where .= " AND (a.address LIKE ? OR r.recipients LIKE ? )";
295  array_push($query_args, "%" . $search . "%", "%" . $search . "%");
296  }
297  if (!$show_systemmails) {
298  $where .= " AND type='' ";
299  }
300  $db->query("SELECT count(a.id) AS total FROM address a LEFT JOIN recipient r ON r.address_id=a.id WHERE " . $where . ";", $query_args);
301  $db->next_record();
302  $this->total = $db->f("total");
303  if ($count != -1) {
304  $offset = intval($offset);
305  $count = intval($count);
306  $limit = " LIMIT $offset, $count ";
307  } else {
308  $limit = "";
309  }
310  $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, q.quota_dovecot as used, NOT ISNULL(m.id) AS islocal, a.type, r.recipients, m.lastlogin, a.domain_id
311  FROM ((domaines d, address a LEFT JOIN mailbox m ON m.address_id=a.id) LEFT JOIN dovecot_quota q ON CONCAT(a.address,'@',d.domaine) = q.user) LEFT JOIN recipient r ON r.address_id=a.id
312  WHERE " . $where . " AND d.id=a.domain_id ORDER BY a.address ASC " . $limit . " ;", $query_args);
313  if (!$db->next_record()) {
314  $msg->raise("ERROR", "mail", _("No email found for this query"));
315  return array();
316  }
317  $res = array();
318  do {
319  $details = $db->Record;
320  // if necessary, fill the typedata with data from hooks ...
321  if ($details["type"]) {
322  $result = $hooks->invoke("hook_mail_get_details", array($details)); // Will fill typedata if necessary
323  $details["typedata"] = implode("<br />", $result);
324  }
325  $res[] = $details;
326  } while ($db->next_record());
327  return $res;
328  }
$res
Definition: index.php:111

References $res.

Referenced by alternc_export_conf(), and hook_dom_del_mx_domain().

◆ enum_domains()

m_mail::enum_domains (   $uid = -1)

Returns the list of mail-hosting domains for a user.

Returns
array indexed array of hosted domains

Definition at line 218 of file m_mail.php.

218  {
219  global $db, $msg, $cuid;
220  $msg->debug("mail", "enum_domains");
221  if ($uid == -1) {
222  $uid = $cuid;
223  }
224  $db->query("
225 SELECT
226  d.id,
227  d.domaine,
228  IFNULL( COUNT(a.id), 0) as nb_mail
229 FROM
230  domaines d LEFT JOIN address a ON (d.id=a.domain_id AND a.type='')
231 WHERE
232  d.compte = ?
233  and d.gesmx = 1
234 GROUP BY
235  d.id
236 ORDER BY
237  d.domaine
238 ;
239 ", array($uid));
240  $this->enum_domains = array();
241  while ($db->next_record()) {
242  $this->enum_domains[] = $db->Record;
243  }
244  return $this->enum_domains;
245  }
$enum_domains
Definition: m_mail.php:67

References $enum_domains.

Referenced by alternc_export_conf(), and hook_menu().

◆ enum_slave_account()

m_mail::enum_slave_account ( )

Return the list of allowed slave accounts (secondary-mx)

Returns
array

Definition at line 834 of file m_mail.php.

834  {
835  global $db;
836  $db->query("SELECT login,pass FROM mxaccount;");
837  $res = array();
838  while ($db->next_record()) {
839  $res[] = $db->Record;
840  }
841  if (!count($res)) {
842  return false;
843  }
844  return $res;
845  }

References $res.

◆ get_account_by_mail_id()

m_mail::get_account_by_mail_id (   $mail_id)

return the alternc account's ID of the mail_id

Definition at line 488 of file m_mail.php.

488  {
489  global $db;
490  $db->query("select compte as uid from domaines d, address a where a.domain_id = d.id and a.id = ? ;", array($mail_id));
491  if (!$db->next_record()) {
492  return false;
493  }
494  return $db->f('uid');
495  }

◆ get_details()

m_mail::get_details (   $mail_id)

function used to get every information we can on a mail

Parameters
$mail_idinteger
Returns
array a hashtable with all the informations for that email

Definition at line 402 of file m_mail.php.

402  {
403  global $db, $msg, $hooks;
404  $msg->debug("mail", "get_details");
405 
406  $mail_id = intval($mail_id);
407  // Validate that this email is owned by me...
408  if (!($mail = $this->is_it_my_mail($mail_id))) {
409  return false;
410  }
411 
412  // We fetch all the informations for that email: these will fill the hastable :
413  $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, q.quota_dovecot AS used, NOT ISNULL(m.id) AS islocal, a.type, r.recipients, m.lastlogin, a.mail_action, m.mail_action AS mailbox_action FROM ((domaines d, address a LEFT JOIN mailbox m ON m.address_id=a.id) LEFT JOIN dovecot_quota q ON CONCAT(a.address,'@',d.domaine) = q.user) LEFT JOIN recipient r ON r.address_id=a.id WHERE a.id= ? AND d.id=a.domain_id;", array($mail_id));
414  if (!$db->next_record()) {
415  return false;
416  }
417  $details = $db->Record;
418  // if necessary, fill the typedata with data from hooks ...
419  if ($details["type"]) {
420  $result = $hooks->invoke("hook_mail_get_details", array($mail_id)); // Will fill typedata if necessary
421  $details["typedata"] = implode("<br />", $result);
422  }
423  return $details;
424  }

References is_it_my_mail().

Referenced by delete(), and set_details().

◆ get_total_size_for_domain()

m_mail::get_total_size_for_domain (   $domain)

Definition at line 102 of file m_mail.php.

102  {
103  global $db;
104  if (empty($this->cache_domain_mail_size)) {
105  $db->query("SELECT SUBSTRING_INDEX(user,'@', -1) as domain, SUM(quota_dovecot) AS sum FROM dovecot_quota group by domain ;");
106  while ($db->next_record()) {
107  $dd = $db->f('domain');
108  $this->cache_domain_mail_size[$dd] = $db->f('sum');
109  }
110  }
111  if (isset($this->cache_domain_mail_size[$domain])) {
112  return $this->cache_domain_mail_size[$domain];
113  }
114  return 0;
115  }

◆ hook_dom_add_mx_domain()

m_mail::hook_dom_add_mx_domain (   $domain_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

Parameters
string$domain_idDomain that has just been created @access private

Definition at line 947 of file m_mail.php.

947  {
948  global $msg, $mem, $db, $L_FQDN;
949  $msg->log("mail", "hook_dom_add_mx_domain", $domain_id);
950 
951  $db->query("SELECT value FROM variable where name='mailname_bounce';");
952  if (!$db->next_record()) {
953  $msg->raise("ERROR", "mail", _("Problem: can't create default bounce mail"));
954  return false;
955  }
956  $mailname = $db->f("value");
957  // set spf & dmarc for this domain
958  $db->query("SELECT domaine,compte FROM domaines WHERE id= ?;", array($domain_id));
959  if ($db->next_record()) {
960  $domaine=$db->Record["domaine"];
961  $compte=$db->Record["compte"];
962  $this->set_dns_autoconf($domaine,$compte);
963  if ($spf = variable_get("default_spf_value")) {
964  $this->set_dns_spf($domaine, $spf);
965  }
966  if ($dmarc = variable_get("default_dmarc_value")) {
967  $this->set_dns_dmarc($domaine, $dmarc);
968  }
969  }
970  return $this->create_alias($domain_id, 'postmaster', $mem->user['login'] . '@' . $mailname);
971  }
set_dns_spf($domain, $spf, $previous=-1, $uid=-1, $login=-1)
Set or UPDATE the DNS record for the domain $dom(str) to be $spf account's login is current and if no...
Definition: m_mail.php:1050
set_dns_dmarc($domain, $dmarc, $previous=-1, $uid=-1, $login=-1)
Set or UPDATE the DNS record for the domain $dom(str) to be $dmarc account's login is current and if ...
Definition: m_mail.php:1092
set_dns_autoconf($domain, $uid=-1)
Add dns entries for autodiscover / autoconf on the domain.
Definition: m_mail.php:1011

References create_alias(), set_dns_autoconf(), set_dns_dmarc(), and set_dns_spf().

◆ hook_dom_add_slave_domain()

m_mail::hook_dom_add_slave_domain (   $domain_id,
  $target_domain 
)

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

Parameters
string$domain_idDomain that has just been created
string$target_domainMaster domain @access private

Definition at line 930 of file m_mail.php.

930  {
931  global $msg;
932  $msg->log("mail", "hook_dom_add_slave_domain", $domain_id);
933  $this->catchall_set($domain_id, '@' . $target_domain);
934  return true;
935  }
catchall_set($domain_id, $target)
Definition: m_mail.php:165

References catchall_set().

◆ hook_dom_del_mx_domain()

m_mail::hook_dom_del_mx_domain (   $dom_id)

Hook called when the DOMAIN class will delete a domain.

OR when the DOMAIN class tells us we don't host the emails of this domain anymore.

Parameters
$domthe ID of the domain to delete
Returns
boolean if the email has been properly deleted or false if an error occured ($msg is filled accordingly)

Definition at line 460 of file m_mail.php.

460  {
461  global $db;
462  $list = $this->enum_domain_mails($dom_id, "", 0, -1);
463  if (is_array($list)) {
464  foreach ($list as $one) {
465  $this->delete($one["id"]);
466  }
467  }
468  $db->query("SELECT domaine FROM domaines WHERE id= ? ;", array($dom_id));
469  if (!$db->next_record()) {
470  return false;
471  }
472  $domain=$db->Record["domaine"];
473  $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE domaine= ? AND (type='defmx' OR type='defmx2');", array($domain));
474 
475  $this->del_dns_dmarc($domain);
476  $this->del_dns_spf($domain);
477  $this->del_dns_autoconf($domain);
478  $this->dkim_del($domain);
479 
480  $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE id= ? ;", array($dom_id));
481  return true;
482  }
del_dns_dmarc($domain)
delete the DMARC entries in the sub_domaine table for a domain called by del_domain or del_mx_domain ...
Definition: m_mail.php:1125
dkim_del($domain)
Delete a domain from OpenDKIM configuration.
Definition: m_mail.php:1215
del_dns_spf($domain)
delete the SPF entries in the sub_domaine table for a domain called by del_domain or del_mx_domain by...
Definition: m_mail.php:1079
del_dns_autoconf($domain)
delete the autoconf / autodiscover vhosts when removing a domain as MX
Definition: m_mail.php:1037

References del_dns_autoconf(), del_dns_dmarc(), del_dns_spf(), dkim_del(), and enum_domain_mails().

◆ hook_mail_get_details()

m_mail::hook_mail_get_details (   $detail)

Definition at line 330 of file m_mail.php.

330  {
331  if ($detail['type'] == 'catchall') {
332  return _(sprintf("Special mail address for catch-all. <a href='mail_manage_catchall.php?domain_id=%s'>Click here to manage it.</a>", $detail['domain_id']));
333  }
334  }

◆ hook_menu()

m_mail::hook_menu ( )

Hook called by menu class to add the email menu to the left pane.

Definition at line 83 of file m_mail.php.

83  {
84  $obj = array(
85  'title' => _("Email Addresses"),
86  'link' => 'toggle',
87  'pos' => 30,
88  'links' => array(),
89  );
90 
91  foreach ($this->enum_domains() as $d) {
92  $obj['links'][] = array(
93  'txt' => htmlentities($d["domaine"]) . '&nbsp;' . htmlentities("(" . $d["nb_mail"] . ")"),
94  'url' => "mail_list.php?domain_id=" . urlencode($d['id']),
95  );
96  }
97 
98  return $obj;
99  }

References enum_domains().

◆ hook_quota_get()

m_mail::hook_quota_get ( )

get_quota (hook for quota class), returns the number of used service for a quota-bound service

Parameters
$namestring the named quota we want
Returns
the number of used service for the specified quota, or false if I'm not the one for the named quota

Definition at line 192 of file m_mail.php.

192  {
193  global $db, $msg, $cuid, $quota;
194  $msg->debug("mail", "getquota");
195  $q = Array("name" => "mail", "description" => _("Email addresses"), "used" => 0);
196  $db->query("SELECT COUNT(*) AS cnt FROM address a, domaines d WHERE a.domain_id=d.id AND d.compte= ? AND a.type='';", array($cuid));
197  if ($db->next_record()) {
198  $q['used'] = $db->f("cnt");
199  $q['sizeondisk'] = $quota->get_size_mail_sum_user($cuid)/1024;
200  }
201  return $q;
202  }

◆ hook_updatedomains_dns_post()

m_mail::hook_updatedomains_dns_post ( )

Hook launched after doing anything dns-related.

Definition at line 1166 of file m_mail.php.

1166  {
1167  if ($this->shouldreloaddkim) {
1168  exec("service opendkim reload");
1169  $this->shouldreloaddkim=false;
1170  }
1171  }

◆ hook_updatedomains_dns_pre()

m_mail::hook_updatedomains_dns_pre ( )

Hook launched before doing anything dns-related.

Definition at line 1139 of file m_mail.php.

1139  {
1140  global $db;
1141  // for each domain where we don't have the MX or the DNS, remove the DKIM setup
1142  $this->shouldreloaddkim=false;
1143  $db->query("SELECT domaine,compte,gesdns,gesmx,dns_action FROM domaines WHERE dns_action!='OK';");
1144  $add=array();
1145  $del=array();
1146  while ($db->next_record()) {
1147  if ($db->Record["gesdns"]==0 || $db->Record["gesmx"]==0 || $db->Record['dns_action'] == 'DELETE') {
1148  $del[]=$db->Record;
1149  } else {
1150  $add[]=$db->Record;
1151  }
1152  }
1153  foreach($add as $domain) {
1154  $this->dkim_add($domain["domaine"],$domain["compte"]);
1155  }
1156  foreach($del as $domain) {
1157  $this->dkim_del($domain["domaine"]);
1158  }
1159  }
dkim_add($domain, $uid)
Add a domain into OpenDKIM configuration.
Definition: m_mail.php:1178

References dkim_add(), and dkim_del().

◆ hook_variable_set()

m_mail::hook_variable_set (   $name,
  $old,
  $new 
)

hook function called by variables when a variable is changed @access private

Definition at line 979 of file m_mail.php.

979  {
980  global $msg, $db;
981  $msg->log("mail", "hook_variable_set($name,$old,$new)");
982 
983  if ($name == "default_spf_value") {
984  $new = trim($new);
985  $old = trim($old);
986  $db->query("SELECT domaine,login,compte FROM domaines, membres WHERE gesdns=1 AND gesmx=1 and membres.uid=domaines.compte;");
987  $res=array();
988  while ($db->next_record()) $res[]=$db->Record;
989  foreach ($res as $record) {
990  $this->set_dns_spf($record["domaine"], $new, $old, $record["compte"], $record["login"]);
991  }
992  }
993 
994  if ($name == "default_dmarc_value") {
995  $new = trim($new);
996  $old = trim($old);
997  $db->query("SELECT domaine,login,compte FROM domaines, membres WHERE gesdns=1 AND gesmx=1 and membres.uid=domaines.compte;");
998  $res=array();
999  while ($db->next_record()) $res[]=$db->Record;
1000  foreach ($res as $record) {
1001  $this->set_dns_dmarc($record["domaine"], $new, $old, $record["compte"], $record["login"]);
1002  }
1003  }
1004  }

References $res, set_dns_dmarc(), and set_dns_spf().

◆ is_it_my_mail()

m_mail::is_it_my_mail (   $mail_id)

Check if an email is mine ...

Parameters
$mail_idinteger the number of the email to check
Returns
string the complete email address if that's mine, false if not ($msg is filled accordingly)

Definition at line 436 of file m_mail.php.

436  {
437  global $msg, $db, $cuid;
438  $mail_id = intval($mail_id);
439  // cache it (may be called more than one time in the same page).
440  if (isset($this->isitmy_cache[$mail_id])) {
441  return $this->isitmy_cache[$mail_id];
442  }
443  $db->query("SELECT concat(a.address,'@',d.domaine) AS email FROM address a, domaines d WHERE d.id=a.domain_id AND a.id= ? AND d.compte= ?;", array($mail_id, $cuid));
444  if ($db->next_record()) {
445  return $this->isitmy_cache[$mail_id] = $db->f("email");
446  } else {
447  $msg->raise("ERROR", "mail", _("This email is not yours, you can't change anything on it"));
448  return $this->isitmy_cache[$mail_id] = false;
449  }
450  }

Referenced by delete(), disable(), enable(), get_details(), set_passwd(), and undelete().

◆ m_mail()

m_mail::m_mail ( )

Constructeur.

Definition at line 73 of file m_mail.php.

73  {
74  global $L_FQDN;
75  $this->srv_postfix = variable_get('fqdn_postfix', $L_FQDN, 'FQDN name for humans for smtp services. If you change it, launch reload-certs', array('desc' => 'Name', 'type' => 'string'));
76  $this->srv_dovecot = variable_get('fqdn_dovecot', $L_FQDN, 'FQDN name for humans for pop/imap services. If you change it, launch reload-certs', array('desc' => 'Name', 'type' => 'string'));
77  }

◆ set_details()

m_mail::set_details (   $mail_id,
  $islocal,
  $quotamb,
  $recipients,
  $delivery = "dovecot",
  $dontcheck = false 
)

Function used to update an email settings should be used by the web interface, not by third-party programs.

Parameters
$mail_idinteger the number of the email to delete
integer$islocalboolean is it a POP/IMAP mailbox ?
integer$quotambinteger if islocal=1, quota in MB
string$recipientsstring recipients, one mail per line.
Returns
boolean if the email has been properly edited or false if an error occured ($msg is filled accordingly)

Definition at line 675 of file m_mail.php.

675  {
676  global $msg, $db;
677  $msg->log("mail", "set_details");
678  if (!($me = $this->get_details($mail_id))) {
679  return false;
680  }
681  if ($me["islocal"] && !$islocal) {
682  // delete pop
683  $db->query("UPDATE mailbox SET mail_action='DELETE' WHERE address_id= ? ;", array($mail_id));
684  }
685  if (!$me["islocal"] && $islocal) {
686  // create pop
687  $path = "";
688  if ($delivery == "dovecot") {
689  $path = ALTERNC_MAIL . "/" . substr($me["address"] . "_", 0, 1) . "/" . $me["address"] . "_" . $me["domain"];
690  }
691  foreach ($this->forbiddenchars as $str) {
692  if (strpos($me["address"], $str) !== false) {
693  $msg->raise("ERROR", "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"));
694  return false;
695  }
696  }
697  foreach ($this->specialchars as $str) {
698  if (strpos($me["address"], $str) !== false) {
699  $path = ALTERNC_MAIL . "/_/" . $me["id"] . "_" . $me["domain"];
700  break;
701  }
702  }
703  $db->query("INSERT INTO mailbox SET address_id= ? , delivery= ?, path= ? ;", array($mail_id, $delivery, $path));
704  }
705  if ($me["islocal"] && $islocal && $me["mailbox_action"] == "DELETE") {
706  $db->query("UPDATE mailbox SET mail_action='OK' WHERE mail_action='DELETE' AND address_id= ? ;", array($mail_id));
707  }
708 
709  if ($islocal) {
710  if ($quotamb != 0 && $quotamb < (intval($me["used"] / 1024 / 1024) + 1)) {
711  $quotamb = intval($me["used"] / 1024 / 1024) + 1;
712  $msg->raise("ALERT", "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"));
713  }
714  $db->query("UPDATE mailbox SET quota= ? WHERE address_id= ? ;", array($quotamb, $mail_id));
715  }
716 
717  $recipients = preg_replace('/[\r\t\s]/', "\n", $recipients); // Handle space AND new line
718  $r = explode("\n", $recipients);
719  $red = "";
720  foreach ($r as $m) {
721  $m = trim($m);
722  if ($m && ( filter_var($m, FILTER_VALIDATE_EMAIL) || $dontcheck) // Recipient Email is valid
723  && $m != ($me["address"] . "@" . $me["domain"])) { // And not myself (no loop allowed easily ;) )
724  $red.=$m . "\n";
725  }
726  }
727  $db->query("DELETE FROM recipient WHERE address_id= ? ;", array($mail_id));
728  if (isset($red) && $red) {
729  $db->query("INSERT INTO recipient SET address_id= ?, recipients= ? ;", array($mail_id, $red));
730  }
731  if (!$islocal && !$red) {
732  $msg->raise("ALERT", "mail", _("Warning: you created an email which is not an alias, and not a POP/IMAP mailbox. This is certainly NOT what you want to do. To fix this, edit the email address and check 'Yes' in POP/IMAP account, or set some recipients in the redirection field."));
733  }
734  return true;
735  }

References get_details().

Referenced by add_wrapper(), and create_alias().

◆ set_dns_autoconf()

m_mail::set_dns_autoconf (   $domain,
  $uid = -1 
)

Add dns entries for autodiscover / autoconf on the domain.

Definition at line 1011 of file m_mail.php.

1011  {
1012  global $db, $L_FQDN, $cuid;
1013  $changed=false;
1014  if ($uid==-1) $uid=$cuid;
1015 
1016  $db->query("SELECT domaine,sub,type,valeur FROM sub_domaines WHERE domaine=? AND sub='autodiscover' AND type='autodiscover';",array($domain));
1017  if (!$db->next_record()) {
1018  $db->query("INSERT INTO sub_domaines SET domaine=?, compte=?, sub='autodiscover', type='autodiscover', valeur='';",array($domain,$uid));
1019  $changed=true;
1020  }
1021  $db->query("SELECT domaine,sub,type,valeur FROM sub_domaines WHERE domaine=? AND sub='autoconfig' AND type='autodiscover';",array($domain));
1022  if (!$db->next_record()) {
1023  $db->query("INSERT INTO sub_domaines SET domaine=?, compte=?, sub='autoconfig', type='autodiscover', valeur='';",array($domain,$uid));
1024  $changed=true;
1025  }
1026  if ($changed) {
1027  $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine= ?;", array($domain));
1028  }
1029  return $changed;
1030  }

Referenced by hook_dom_add_mx_domain().

◆ set_dns_dmarc()

m_mail::set_dns_dmarc (   $domain,
  $dmarc,
  $previous = -1,
  $uid = -1,
  $login = -1 
)

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

Definition at line 1092 of file m_mail.php.

1092  {
1093  global $db, $cuid, $mem, $L_FQDN, $msg;
1094  $msg->debug("mail","set_dns_dmarc($domain, $dmarc, $previous, $uid, $login)");
1095  // defaults
1096  if ($uid === -1) {
1097  $uid = intval($cuid);
1098  } else {
1099  $uid = intval($uid);
1100  }
1101  if ($login === -1) {
1102  $login = $mem->user["login"];
1103  }
1104  $dmarc = str_replace("%%ADMINMAIL%%", "admin@" . $L_FQDN, $dmarc);
1105  $dmarc = str_replace("%%USERMAIL%%", $login . "@" . $L_FQDN, $dmarc);
1106 
1107  // Search for the record in sub_domaines table
1108  $db->query("SELECT * FROM sub_domaines WHERE compte= ? AND domaine= ? AND sub='_dmarc' AND type='txt' AND valeur LIKE lower('v=DMARC1;%') AND web_action!='DELETE';", array($uid, $domain));
1109  if ($db->next_record()) {
1110  if ($previous !== -1 && $db->Record["valeur"] == "v=DMARC1;" . $dmarc) {
1111  return; // skip, no change asked.
1112  }
1113  $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE id= ?;", array($db->Record["id"]));
1114  }
1115  $db->query("INSERT INTO sub_domaines SET compte= ?, domaine= ?, sub='_dmarc', type='txt', valeur= ?, web_action='UPDATE';", array($uid, $domain, "v=DMARC1;" . $dmarc));
1116  $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine= ?;", array($domain));
1117  }

Referenced by hook_dom_add_mx_domain(), and hook_variable_set().

◆ set_dns_spf()

m_mail::set_dns_spf (   $domain,
  $spf,
  $previous = -1,
  $uid = -1,
  $login = -1 
)

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

Definition at line 1050 of file m_mail.php.

1050  {
1051  global $db, $cuid, $mem, $msg;
1052  $msg->debug("mail","set_dns_spf($domain, $spf, $previous, $uid, $login)");
1053  // defaults
1054  if ($uid === -1) {
1055  $uid = intval($cuid);
1056  } else {
1057  $uid = intval($uid);
1058  }
1059  if ($login === -1) {
1060  $login = $mem->user["login"];
1061  }
1062  // Search for the record in sub_domaines table
1063  $db->query("SELECT * FROM sub_domaines WHERE compte= ? AND domaine= ? AND sub='' AND type='txt' AND valeur LIKE 'v=spf1 %' AND web_action!='DELETE';", array($uid, $domain));
1064  if ($db->next_record()) {
1065  if ($previous !== -1 && $db->Record["valeur"] == "v=spf1 " . $spf) {
1066  return; // skip, no change asked.
1067  }
1068  $db->query("UPDATE sub_domaines SET web_action='DELETE' WHERE id= ? ;",array($db->Record["id"]));
1069  }
1070  $db->query("INSERT INTO sub_domaines SET compte= ?, domaine= ?, sub='', type='txt', valeur= ? , web_action='UPDATE';", array($uid, $domain, "v=spf1 " . $spf));
1071  $db->query("UPDATE domaines SET dns_action='UPDATE' WHERE domaine= ?;", array($domain));
1072  }

Referenced by hook_dom_add_mx_domain(), and hook_variable_set().

◆ set_passwd()

m_mail::set_passwd (   $mail_id,
  $pass,
  $canbeempty = false 
)

set the password of an email address.

Parameters
$mail_idinteger email ID
$passstring the new password.
Returns
boolean true if the password has been set, false else, raise an error.

Definition at line 607 of file m_mail.php.

607  {
608  global $db, $msg, $admin;
609  $msg->log("mail", "setpasswd");
610 
611  if (!($email = $this->is_it_my_mail($mail_id))) {
612  return false;
613  }
614  if (!$admin->checkPolicy("pop", $email, $pass, $canbeempty)) {
615  return false;
616  }
617  if ($canbeempty && empty($pass)) {
618  return $db->query("UPDATE address SET password= ? where id = ? ;",
619  array(null, $mail_id ));
620  } else if (!$db->query("UPDATE address SET password= ? where id = ? ;",
621  array(_dovecot_hash($pass), $mail_id ))) {
622  return false;
623  }
624  return true;
625  }

References is_it_my_mail().

◆ undelete()

m_mail::undelete (   $mail_id)

Function used to undelete a pending deletion mail from the db should be used by the web interface, not by third-party programs.

Parameters
$mail_idinteger the email id
Returns
boolean if the email has been properly undeleted or false if an error occured ($msg is filled accordingly)

Definition at line 558 of file m_mail.php.

558  {
559  global $msg, $db;
560  $msg->log("mail", "undelete");
561 
562  $mail_id = intval($mail_id);
563 
564  if (!$mail_id) {
565  $msg->raise("ERROR", "mail", _("The email you entered does not exist"));
566  return false;
567  }
568  // Validate that this email is owned by me...
569  if (!($mail = $this->is_it_my_mail($mail_id))) {
570  return false;
571  }
572 
573  // Search for that address:
574  $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= ? ;", array($mail_id));
575  if (!$db->next_record()) {
576  $msg->raise("ERROR", "mail", _("The email %s does not exist, it can't be undeleted"), $mail);
577  return false;
578  }
579  if ($db->f("type") != "") { // Technically special : mailman, sympa ...
580  $msg->raise("ERROR", "mail", _("The email %s is special, it can't be undeleted"), $mail);
581  return false;
582  }
583  if ($db->f("mailbox_action") != "DELETE" || $db->f("mail_action") != "DELETE") { // will be deleted soon ...
584  $msg->raise("ALERT", "mail", _("Sorry, deletion of email %s is already in progress, or not marked for deletion, it can't be undeleted"), $mail);
585  return false;
586  }
587  $mail_id = $db->f("id");
588 
589  if ($db->f("islocal")) {
590  // If it's a pop/imap mailbox, mark it for deletion
591  $db->query("UPDATE address SET mail_action='OK', `enabled`=1 WHERE id= ?;", array($mail_id));
592  $db->query("UPDATE mailbox SET mail_action='OK' WHERE address_id= ? ;", array($mail_id));
593  return true;
594  } else {
595  $msg->raise("ERROR", "mail", _("-- Program Error -- The email %s can't be undeleted"), $mail);
596  return false;
597  }
598  }

References is_it_my_mail().

Member Data Documentation

◆ $cache_domain_mail_size

m_mail::$cache_domain_mail_size = array()

Definition at line 66 of file m_mail.php.

◆ $domains

m_mail::$domains

domain list for this account @access private

Definition at line 38 of file m_mail.php.

◆ $enum_domains

m_mail::$enum_domains = array()

Definition at line 67 of file m_mail.php.

Referenced by enum_domains().

◆ $forbiddenchars

m_mail::$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.

Definition at line 54 of file m_mail.php.

◆ $isitmy_cache

m_mail::$isitmy_cache = array()
private

Definition at line 426 of file m_mail.php.

◆ $shouldreloaddkim

m_mail::$shouldreloaddkim

Manage DKIM when adding / removing a domain MX management.

Definition at line 1132 of file m_mail.php.

◆ $specialchars

m_mail::$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.

Definition at line 46 of file m_mail.php.

◆ $srv_dovecot

m_mail::$srv_dovecot

Definition at line 65 of file m_mail.php.

◆ $srv_postfix

m_mail::$srv_postfix

Definition at line 64 of file m_mail.php.

◆ $total

m_mail::$total

Number of results for a pager display @access public.

Definition at line 61 of file m_mail.php.


The documentation for this class was generated from the following file: