[Web] Queue manager for Postfix

[Web] Add sogo_access mail attribute
[Web] Allow to wipe SOGo profiles
This commit is contained in:
André
2018-10-23 21:14:57 +02:00
parent db64fa490b
commit e30dfd6751
16 changed files with 386 additions and 80 deletions

View File

@@ -0,0 +1,16 @@
<?php
session_start();
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
header('Content-Type: text/plain');
if (!isset($_SESSION['mailcow_cc_role']) || $_SESSION['mailcow_cc_role'] != 'admin') {
exit();
}
$docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq'));
if (isset($docker_return['type']['danger'])) {
echo "Cannot load mail queue: " . $docker_return['msg'];
}
else {
echo $docker_return;
}
?>

View File

@@ -1225,7 +1225,7 @@ function rspamd_ui($action, $data = null) {
);
return false;
}
$docker_return = docker('post', 'rspamd-mailcow', 'exec', array('cmd' => 'worker_password', 'raw' => $rspamd_ui_pass), array('Content-Type: application/json'));
$docker_return = docker('post', 'rspamd-mailcow', 'exec', array('cmd' => 'rspamd', 'task' => 'worker_password', 'raw' => $rspamd_ui_pass), array('Content-Type: application/json'));
if ($docker_return_array = json_decode($docker_return, true)) {
if ($docker_return_array['type'] == 'success') {
$_SESSION['return'][] = array(

View File

@@ -739,8 +739,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
array(
'force_pw_update' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update'])),
'tls_enforce_in' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_in'])),
'tls_enforce_out' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out'])))
);
'tls_enforce_out' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out'])),
'sogo_access' => strval(intval($MAILBOX_DEFAULT_ATTRIBUTES['sogo_access']))
)
);
if (!is_valid_domain_name($domain)) {
$_SESSION['return'][] = array(
'type' => 'danger',
@@ -1881,6 +1883,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
if (!empty($is_now)) {
$active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
(int)$force_pw_update = (isset($_data['force_pw_update'])) ? intval($_data['force_pw_update']) : intval($is_now['attributes']['force_pw_update']);
(int)$sogo_access = (isset($_data['sogo_access'])) ? intval($_data['sogo_access']) : intval($is_now['attributes']['sogo_access']);
$name = (!empty($_data['name'])) ? $_data['name'] : $is_now['name'];
$domain = $is_now['domain'];
$quota_m = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['quota'] / 1048576);
@@ -2082,13 +2085,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
`active` = :active,
`name`= :name,
`quota` = :quota_b,
`attributes` = JSON_SET(`attributes`, '$.force_pw_update', :force_pw_update)
`attributes` = JSON_SET(`attributes`, '$.force_pw_update', :force_pw_update),
`attributes` = JSON_SET(`attributes`, '$.sogo_access', :sogo_access)
WHERE `username` = :username");
$stmt->execute(array(
':active' => $active,
':name' => $name,
':quota_b' => $quota_b,
':force_pw_update' => $force_pw_update,
':sogo_access' => $sogo_access,
':username' => $username
));
$_SESSION['return'][] = array(
@@ -2384,20 +2389,23 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$_data = $_SESSION['mailcow_cc_username'];
}
$exec_fields = array(
'cmd' => 'sieve_list',
'cmd' => 'sieve',
'task' => 'list',
'username' => $_data
);
$filters = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
$filters = array_filter(explode(PHP_EOL, $filters));
$filters = docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
$filters = array_filter(preg_split("/(\r\n|\n|\r)/",$filters));
foreach ($filters as $filter) {
if (preg_match('/.+ ACTIVE/i', $filter)) {
$exec_fields = array(
'cmd' => 'sieve_print',
'cmd' => 'sieve',
'task' => 'print',
'script_name' => substr($filter, 0, -7),
'username' => $_data
);
$filters = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
return preg_replace('/^.+\n/', '', $filters);
$script = docker('post', 'dovecot-mailcow', 'exec', $exec_fields);
// Remove first line
return preg_replace('/^.+\n/', '', $script);
}
}
return false;
@@ -3081,6 +3089,66 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
}
break;
case 'sogo_profile':
if (!is_array($_data['username'])) {
$usernames = array();
$usernames[] = $_data['username'];
}
else {
$usernames = $_data['username'];
}
if (!isset($_SESSION['acl']['sogo_profile_reset']) || $_SESSION['acl']['sogo_profile_reset'] != "1" ) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => 'access_denied'
);
return false;
}
foreach ($usernames as $username) {
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => 'access_denied'
);
continue;
}
$stmt = $pdo->prepare("DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/" . $username . "/%' OR `c_uid` = :username");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)");
$stmt->execute(array(
':username' => $username
));
$stmt = $pdo->prepare("DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username");
$stmt->execute(array(
':username' => $username
));
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('sogo_profile_reset', htmlspecialchars($username))
);
}
break;
case 'domain':
if (!is_array($_data['domain'])) {
$domains = array();
@@ -3119,7 +3187,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
continue;
}
$exec_fields = array('cmd' => 'maildir_cleanup', 'maildir' => $domain);
$exec_fields = array('cmd' => 'maildir', 'task' => 'cleanup', 'maildir' => $domain);
$maildir_gc = json_decode(docker('post', 'dovecot-mailcow', 'exec', $exec_fields), true);
if ($maildir_gc['type'] != 'success') {
$_SESSION['return'][] = array(

View File

@@ -0,0 +1,72 @@
<?php
function mailq($_action, $_data = null) {
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array(__FUNCTION__, $_action, $_data),
'msg' => 'access_denied'
);
return false;
}
function process_mailq_output($returned_output, $_action, $_data) {
if ($returned_output !== NULL) {
if (isset($returned_output['type']) && $returned_output['type'] == 'danger') {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array('mailq', $_action, $_data),
'msg' => 'Error: ' . $returned_output['msg']
);
}
if (isset($returned_output['type']) && $returned_output['type'] == 'success') {
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array('mailq', $_action, $_data),
'msg' => 'queue_command_success'
);
}
}
else {
$_SESSION['return'][] = array(
'type' => 'danger',
'log' => array('mailq', $_action, $_data),
'msg' => 'unknown'
);
}
}
global $lang;
switch ($_action) {
case 'delete':
if (!is_array($_data['qid'])) {
$qids = array();
$qids[] = $_data['qid'];
}
else {
$qids = $_data['qid'];
}
$docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => 'delete', 'items' => $qids));
process_mailq_output(json_decode($docker_return, true), $_action, $_data);
break;
case 'edit':
if (in_array($_data['action'], array('hold', 'unhold', 'deliver'))) {
if (!is_array($_data['qid'])) {
$qids = array();
$qids[] = $_data['qid'];
}
else {
$qids = $_data['qid'];
}
if (!empty($qids)) {
$docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => $_data['action'], 'items' => $qids));
process_mailq_output(json_decode($docker_return, true), $_action, $_data);
}
}
if (in_array($_data['action'], array('flush', 'super_delete'))) {
$docker_return = docker('post', 'postfix-mailcow', 'exec', array('cmd' => 'mailq', 'task' => $_data['action']));
process_mailq_output(json_decode($docker_return, true), $_action, $_data);
}
break;
case 'get':
// todo: move get from json_api here
break;
}
}

View File

@@ -3,7 +3,7 @@ function init_db_schema() {
try {
global $pdo;
$db_version = "07102018_1502";
$db_version = "22102018_1502";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -291,6 +291,7 @@ function init_db_schema() {
"delimiter_action" => "TINYINT(1) NOT NULL DEFAULT '1'",
"syncjobs" => "TINYINT(1) NOT NULL DEFAULT '1'",
"eas_reset" => "TINYINT(1) NOT NULL DEFAULT '1'",
"sogo_profile_reset" => "TINYINT(1) NOT NULL DEFAULT '1'",
"quarantine" => "TINYINT(1) NOT NULL DEFAULT '1'",
),
"keys" => array(
@@ -963,7 +964,8 @@ DELIMITER ;';
// Migrate tls_enforce_* options and add force_pw_update attribute
$stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = '{}' WHERE `attributes` IS NULL;");
$stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.force_pw_update', 0) WHERE JSON_EXTRACT(`attributes`, '$.force_pw_update') IS NULL;");
$stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.force_pw_update', \"0\") WHERE JSON_EXTRACT(`attributes`, '$.force_pw_update') IS NULL;");
$stmt = $pdo->query("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.sogo_access', \"1\") WHERE JSON_EXTRACT(`attributes`, '$.sogo_access') IS NULL;");
foreach($tls_options as $tls_user => $tls_options) {
$stmt = $pdo->prepare("UPDATE `mailbox` SET `attributes` = JSON_SET(`attributes`, '$.tls_enforce_in', :tls_enforce_in),
`attributes` = JSON_SET(`attributes`, '$.tls_enforce_out', :tls_enforce_out)

View File

@@ -142,6 +142,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.quarantine.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.dkim.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.fwdhost.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.mailq.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.ratelimit.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.relayhost.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.rsettings.inc.php';

View File

@@ -139,3 +139,6 @@ $MAILBOX_DEFAULT_ATTRIBUTES['tls_enforce_out'] = false;
// Force password change on next login (only allows login to mailcow UI)
$MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update'] = false;
// Force password change on next login (only allows login to mailcow UI)
$MAILBOX_DEFAULT_ATTRIBUTES['sogo_access'] = true;