Skip to content
......@@ -452,7 +452,7 @@ class bind_plugin {
//* Ensure that the named slave directory is writable by the named user
$slave_record_dir = $dns_config['bind_zonefiles_dir'].'/'.$this->slave_zone_file_prefix();
if(!@is_dir($slave_record_dir)) mkdir($slave_record_dir, 0770);
if(!@is_dir($slave_record_dir)) mkdir($slave_record_dir, 0770, true);
chown($slave_record_dir, $dns_config['bind_user']);
chgrp($slave_record_dir, $dns_config['bind_group']);
......
......@@ -136,7 +136,7 @@ class mail_plugin {
$app->system->exec_safe("su -c 'doveadm mailbox create -u ? Trash'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox create -u ? Junk'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox create -u ? Drafts'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox subscribe -u ? INBOX'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox subscribe -u ? Sent'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox subscribe -u ? Trash'", $data["new"]["email"]);
......@@ -150,26 +150,26 @@ class mail_plugin {
$app->log('Created Directory: '.$maildomain_path, LOGLEVEL_DEBUG);
$maildomain_path .= '/Maildir';
}
//* When the mail user dir exists but it is not a valid maildir, move it to corrupted maildir folder
if(!empty($maildomain_path) && is_dir($maildomain_path) && !is_dir($maildomain_path.'/new') && !is_dir($maildomain_path.'/cur')) {
if(!is_dir($mail_config['homedir_path'].'/corrupted/'.$data['new']['mailuser_id'])) $app->system->mkdirpath($mail_config['homedir_path'].'/corrupted/'.$data['new']['mailuser_id'], 0700, $mail_config['mailuser_name'], $mail_config['mailuser_group']);
$app->system->exec_safe("su -c ? vmail", "mv -f " . $data['new']['maildir']." ".$mail_config['homedir_path'].'/corrupted/'.$data['new']['mailuser_id']);
$app->log('Moved invalid maildir to corrupted Maildirs folder: '.$data['new']['maildir'], LOGLEVEL_WARN);
}
//* Create the maildir, if it doesn not exist, set permissions, set quota.
if(!empty($maildomain_path) && !is_dir($maildomain_path)) {
$app->system->maildirmake($maildomain_path, $user, '', $group);
//* This is to fix the maildrop quota not being rebuilt after the quota is changed.
if($mail_config['pop3_imap_daemon'] != 'dovecot') {
if(is_dir($maildomain_path)) $app->system->exec_safe("su -c ? ?", "maildirmake -q ".$data['new']['quota']."S ".$maildomain_path, $user); // Avoid maildirmake quota bug, see debian bug #214911
$app->log('Created Maildir: '."su -c 'maildirmake -q ".$data['new']['quota']."S ".$maildomain_path."' ".$user, LOGLEVEL_DEBUG);
}
}
if(!is_dir($data['new']['maildir'].'/.Sent')) {
$app->system->maildirmake($maildomain_path, $user, 'Sent', $group);
}
......@@ -182,11 +182,11 @@ class mail_plugin {
if(!is_dir($data['new']['maildir'].'/.Junk')) {
$app->system->maildirmake($maildomain_path, $user, 'Junk', $group);
}
// Set permissions now recursive
$app->system->exec_safe('chown -R ?:? ?', $user, $group, $data['new']['maildir']);
$app->log('Set ownership on '.$data['new']['maildir'], LOGLEVEL_DEBUG);
//* Set the maildir quota
if(is_dir($data['new']['maildir'].'/new') && $mail_config['pop3_imap_daemon'] != 'dovecot') {
if($data['new']['quota'] > 0) {
......@@ -263,9 +263,10 @@ class mail_plugin {
$additionalParameters = '-f '.$matches[1];
}
// Send the welcome email only on a "master" mail server to avoid duplicate emails
// Send the welcome email only on a "master" mail server to avoid duplicate emails, and only send them when welcome emails are enabled.
// (bypass the normal ispcmail class when creating mail accounts)
if($conf['mirror_server_id'] == 0) mail($mailTarget, $mailSubject, $welcome_mail_message, $mailHeaders, $additionalParameters);
$global_config = $app->getconf->get_global_config('mail');
if($conf['mirror_server_id'] == 0 && $global_config['enable_welcome_mail'] == 'y') mail($mailTarget, $mailSubject, $welcome_mail_message, $mailHeaders, $additionalParameters);
}
......@@ -278,7 +279,7 @@ class mail_plugin {
// Maildir-Format must not be changed on this way !!
$data['new']['maildir_format'] = $data['old']['maildir_format'];
$maildomain_path = $data['new']['maildir'];
$tmp_basepath = $data['new']['maildir'];
$tmp_basepath_parts = explode('/', $tmp_basepath);
......@@ -332,7 +333,7 @@ class mail_plugin {
$app->system->exec_safe('mv -f ? ?'. $data['old']['maildir'], $data['new']['maildir']);
$app->log('Moved Maildir from: '.$data['old']['maildir'].' to '.$data['new']['maildir'], LOGLEVEL_DEBUG);
}
//* Create the maildir, if it doesn not exist, set permissions, set quota.
if(!is_dir($data['new']['maildir'].'/mdbox')) {
$app->system->exec_safe("su -c 'doveadm mailbox create -u ? INBOX'", $data["new"]["email"]);
......@@ -340,7 +341,7 @@ class mail_plugin {
$app->system->exec_safe("su -c 'doveadm mailbox create -u ? Trash'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox create -u ? Junk'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox create -u ? Drafts'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox subscribe -u ? INBOX'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox subscribe -u ? Sent'", $data["new"]["email"]);
$app->system->exec_safe("su -c 'doveadm mailbox subscribe -u ? Trash'", $data["new"]["email"]);
......@@ -355,18 +356,18 @@ class mail_plugin {
$app->log('Created Directory: '.$base_path, LOGLEVEL_DEBUG);
$maildomain_path .= '/Maildir';
}
//* When the mail user dir exists but it is not a valid maildir, move it to corrupted maildir folder
if(!empty($maildomain_path) && is_dir($maildomain_path) && !is_dir($maildomain_path.'/new') && !is_dir($maildomain_path.'/cur')) {
if(!is_dir($mail_config['homedir_path'].'/corrupted/'.$data['new']['mailuser_id'])) $app->system->mkdirpath($mail_config['homedir_path'].'/corrupted/'.$data['new']['mailuser_id'], 0700, $mail_config['mailuser_name'], $mail_config['mailuser_group']);
$app->system->exec_safe("su -c ? ?", "mv -f ".$data['new']['maildir']." ".$mail_config['homedir_path'].'/corrupted/'.$data['new']['mailuser_id'], 'vmail');
$app->log('Moved invalid maildir to corrupted Maildirs folder: '.$data['new']['maildir'], LOGLEVEL_WARN);
}
//* Create the maildir, if it doesn not exist, set permissions, set quota.
if(!empty($maildomain_path) && !is_dir($maildomain_path.'/new')) {
$app->system->maildirmake($maildomain_path, $user, '', $group);
//* This is to fix the maildrop quota not being rebuilt after the quota is changed.
if($mail_config['pop3_imap_daemon'] != 'dovecot') {
if($data['new']['quota'] > 0) {
......@@ -378,7 +379,7 @@ class mail_plugin {
}
}
}
if(!is_dir($data['new']['maildir'].'/.Sent')) {
$app->system->maildirmake($maildomain_path, $user, 'Sent', $group);
}
......@@ -391,11 +392,11 @@ class mail_plugin {
if(!is_dir($data['new']['maildir'].'/.Junk')) {
$app->system->maildirmake($maildomain_path, $user, 'Junk', $group);
}
// Set permissions now recursive
$app->system->exec_safe('chown -R ?:? ?', $user, $group, $data['new']['maildir']);
$app->log('Set ownership on '.$data['new']['maildir'], LOGLEVEL_DEBUG);
// Move mailbox, if domain has changed and delete old mailbox
if($data['new']['maildir'] != $data['old']['maildir'] && is_dir($data['old']['maildir'])) {
if(is_dir($data['new']['maildir'])) {
......@@ -487,7 +488,7 @@ class mail_plugin {
} else {
$app->log('Possible security violation when deleting the mail domain mailfilter directory: '.$old_maildomain_path, LOGLEVEL_ERROR);
}
//* Delete the mail-backups
$server_config = $app->getconf->get_server_config($conf['server_id'], 'server');
$backup_dir = $server_config['backup_dir'];
......
......@@ -139,7 +139,7 @@ class rspamd_plugin {
$app->plugins->registerEvent('mail_forwarding_delete', $this->plugin_name, 'user_settings_update');
}
function user_settings_update($event_name, $data) {
function user_settings_update($event_name, $data, $internal = false) {
global $app, $conf;
if(!is_dir('/etc/rspamd')) {
......@@ -206,6 +206,23 @@ class rspamd_plugin {
return;
}
$entries_to_update = [
'mail_user' => [],
'mail_forwarding' => []
];
if($is_domain === true) {
// get all child records to update / delete
$mailusers = $app->db->queryAllRecords("SELECT mu.* FROM mail_user as mu LEFT JOIN spamfilter_users as su ON (su.email = mu.email) WHERE mu.email LIKE ? AND su.id IS NULL", '%' . $email_address);
if(is_array($mailusers) && !empty($mailusers)) {
$entries_to_update['mail_user'] = $mailusers;
}
$forwardings = $app->db->queryAllRecords("SELECT mf.* FROM mail_forwarding as mf LEFT JOIN spamfilter_users as su ON (su.email = mf.source) WHERE mf.source LIKE ? AND su.id IS NULL", '%' . $email_address);
if(is_array($forwardings) && !empty($forwardings)) {
$entries_to_update['mail_forwarding'] = $forwardings;
}
}
$old_settings_name = $settings_name;
$settings_name = $app->functions->idn_encode($settings_name);
......@@ -220,15 +237,24 @@ class rspamd_plugin {
$settings_file = $this->users_config_dir . str_replace('@', '_', $settings_name) . '.conf';
//$app->log('Settings file for rspamd is ' . $settings_file, LOGLEVEL_WARN);
if($mode === 'delete') {
if(is_file($settings_file)) {
$delete_file = true;
if($type === 'spamfilter_user') {
$search_for_policy[] = $email_address;
$search_for_policy[] = substr($email_address, strpos($email_address, '@'));
$policy = $app->db->queryOneRecord("SELECT p.* FROM spamfilter_users as u INNER JOIN spamfilter_policy as p ON (p.id = u.policy_id) WHERE u.server_id = ? AND u.email IN ? ORDER BY u.priority DESC", $conf['server_id'], $search_for_policy);
if($policy) {
$delete_file = false;
}
}
if($delete_file === true && is_file($settings_file)) {
unlink($settings_file);
}
} else {
$settings_priority = 20;
if(isset($data[$use_data]['priority'])) {
$settings_priority = intval($data[$use_data]['priority']);
} elseif($is_domain === true) {
$settings_priority = 18;
$settings_priority = ($is_domain ? 10 : 20) + intval($data[$use_data]['priority']);
} else {
$settings_priority = ($is_domain ? 10 : 20) + 5;
}
// get policy for entry
......@@ -319,7 +345,16 @@ class rspamd_plugin {
}
}
if($mail_config['content_filter'] == 'rspamd'){
if($is_domain === true) {
foreach($entries_to_update['mail_user'] as $entry) {
$this->user_settings_update('mail_user_' . $mode, ['old' => $entry, 'new' => $entry], true);
}
foreach($entries_to_update['mail_forwarding'] as $entry) {
$this->user_settings_update('mail_forwarding_' . $mode, ['old' => $entry, 'new' => $entry], true);
}
}
if($internal !== true && $mail_config['content_filter'] == 'rspamd'){
$app->services->restartServiceDelayed('rspamd', 'reload');
}
}
......@@ -405,8 +440,8 @@ class rspamd_plugin {
$tpl->newTemplate('rspamd_wblist.inc.conf.master');
$tpl->setVar('list_scope', ($global_filter ? 'global' : 'spamfilter'));
$tpl->setVar('record_id', $record_id);
// we need to add 10 to priority to avoid mailbox/domain spamfilter settings overriding white/blacklists
$tpl->setVar('priority', intval($data['new']['priority']) + ($global_filter ? 10 : 20));
// add 30/40 to priority to avoid collisions and prefer white/blacklists above mailbox/domain spamfilter settings
$tpl->setVar('priority', intval($data['new']['priority']) + ($global_filter ? 30 : 40));
$tpl->setVar('from', $filter_from);
$tpl->setVar('recipient', $filter_rcpt);
$tpl->setVar('hostname', $filter['hostname']);
......@@ -459,17 +494,17 @@ class rspamd_plugin {
if(is_dir('/etc/rspamd')) {
$tpl = new tpl();
$tpl->newTemplate('rspamd_users.conf.master');
$tpl->newTemplate('rspamd_options.inc.master');
$whitelist_ips = array();
$ips = $app->db->queryAllRecords("SELECT * FROM server_ip WHERE server_id = ?", $conf['server_id']);
$local_addrs = array();
$ips = $app->db->queryAllRecords('SELECT `ip_address`, `ip_type` FROM ?? WHERE `server_id` = ?', $conf['mysql']['database'].'.server_ip', $conf['server_id']);
if(is_array($ips) && !empty($ips)){
foreach($ips as $ip){
$whitelist_ips[] = array('ip' => $ip['ip_address']);
$local_addrs[] = array('quoted_ip' => "\"".$ip['ip_address']."\",\n");
}
}
$tpl->setLoop('whitelist_ips', $whitelist_ips);
$app->system->file_put_contents('/etc/rspamd/local.d/users.conf', $tpl->grab());
$tpl->setLoop('local_addrs', $local_addrs);
$app->system->file_put_contents('/etc/rspamd/local.d/options.inc', $tpl->grab());
if($mail_config['content_filter'] == 'rspamd'){
$app->services->restartServiceDelayed('rspamd', 'reload');
......