@@ -587,7 +616,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
diff --git a/data/web/inc/functions.domain_admin.inc.php b/data/web/inc/functions.domain_admin.inc.php
new file mode 100644
index 00000000..aa434079
--- /dev/null
+++ b/data/web/inc/functions.domain_admin.inc.php
@@ -0,0 +1,507 @@
+ 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (empty($domains)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
+ WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+ $stmt = $pdo->prepare("SELECT `username` FROM `admin`
+ WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+
+ $stmt = $pdo->prepare("SELECT `username` FROM `domain_admins`
+ WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ foreach ($num_results as $num_results_each) {
+ if ($num_results_each != 0) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
+ );
+ return false;
+ }
+ }
+ if (!empty($password) && !empty($password2)) {
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
+ }
+ if ($password != $password2) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password);
+ foreach ($domains as $domain) {
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
+ VALUES (:username, :domain, :created, :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ domain_admin('delete', $username);
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
+ VALUES (:username, :password_hashed, '0', :active)");
+ $stmt->execute(array(
+ ':username' => $username,
+ ':password_hashed' => $password_hashed,
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_empty'])
+ );
+ return false;
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_added'], htmlspecialchars($username))
+ );
+ break;
+ case 'edit':
+ if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ // Administrator
+ if ($_SESSION['mailcow_cc_role'] == "admin") {
+ if (!is_array($_data['username'])) {
+ $usernames = array();
+ $usernames[] = $_data['username'];
+ }
+ else {
+ $usernames = $_data['username'];
+ }
+ foreach ($usernames as $username) {
+ $is_now = domain_admin('details', $username);
+ $domains = (isset($_data['domains'])) ? (array)$_data['domains'] : null;
+ if (!empty($is_now)) {
+ $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
+ $domains = (!empty($domains)) ? $domains : $is_now['selected_domains'];
+ $username_new = (!empty($_data['username_new'])) ? $_data['username_new'] : $is_now['username'];
+ }
+ else {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $password = $_data['password'];
+ $password2 = $_data['password2'];
+
+ if (!empty($domains)) {
+ foreach ($domains as $domain) {
+ if (!is_valid_domain_name($domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['domain_invalid'])
+ );
+ return false;
+ }
+ }
+ }
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username_new))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ if ($username_new != $username) {
+ if (!empty(domain_admin('details', $username_new)['username'])) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+
+ if (!empty($domains)) {
+ foreach ($domains as $domain) {
+ try {
+ $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
+ VALUES (:username_new, :domain, :created, :active)");
+ $stmt->execute(array(
+ ':username_new' => $username_new,
+ ':domain' => $domain,
+ ':created' => date('Y-m-d H:i:s'),
+ ':active' => $active
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ }
+
+ if (!empty($password) && !empty($password2)) {
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
+ }
+ if ($password != $password2) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password);
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':username_new' => $username_new,
+ ':username' => $username,
+ ':active' => $active
+ ));
+ if (isset($_data['disable_tfa'])) {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ }
+ else {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
+ $stmt->execute(array(':username_new' => $username_new, ':username' => $username));
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username_new' => $username_new,
+ ':username' => $username,
+ ':active' => $active
+ ));
+ if (isset($_data['disable_tfa'])) {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
+ $stmt->execute(array(':username' => $username));
+ }
+ else {
+ $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
+ $stmt->execute(array(':username_new' => $username_new, ':username' => $username));
+ }
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars(implode(', ', $usernames)))
+ );
+ }
+ // Domain administrator
+ // Can only edit itself
+ elseif ($_SESSION['mailcow_cc_role'] == "domainadmin") {
+ $username = $_SESSION['mailcow_cc_username'];
+ $password_old = $_data['user_old_pass'];
+ $password_new = $_data['user_new_pass'];
+ $password_new2 = $_data['user_new_pass2'];
+
+ $stmt = $pdo->prepare("SELECT `password` FROM `admin`
+ WHERE `username` = :user");
+ $stmt->execute(array(':user' => $username));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (!verify_ssha256($row['password'], $password_old)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+
+ if (!empty($password_new2) && !empty($password_new)) {
+ if ($password_new2 != $password_new) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_mismatch'])
+ );
+ return false;
+ }
+ if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password_new)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['password_complexity'])
+ );
+ return false;
+ }
+ $password_hashed = hash_password($password_new);
+ try {
+ $stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
+ $stmt->execute(array(
+ ':password_hashed' => $password_hashed,
+ ':username' => $username
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
+ );
+ }
+ break;
+ case 'delete':
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ $usernames = (array)$_data['username'];
+ foreach ($usernames as $username) {
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['username_invalid'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ $stmt = $pdo->prepare("DELETE FROM `admin` WHERE `username` = :username");
+ $stmt->execute(array(
+ ':username' => $username,
+ ));
+ }
+ catch (PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ return false;
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_admin_removed'], htmlspecialchars(implode(', ', $usernames)))
+ );
+ break;
+ case 'get':
+ $domainadmins = array();
+ if ($_SESSION['mailcow_cc_role'] != "admin") {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ try {
+ $stmt = $pdo->query("SELECT DISTINCT
+ `username`
+ FROM `domain_admins`
+ WHERE `username` IN (
+ SELECT `username` FROM `admin`
+ WHERE `superadmin`!='1'
+ )");
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while ($row = array_shift($rows)) {
+ $domainadmins[] = $row['username'];
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ return $domainadmins;
+ break;
+ case 'details':
+ $domainadmindata = array();
+
+ if ($_SESSION['mailcow_cc_role'] == "domainadmin" && $_data != $_SESSION['mailcow_cc_username']) {
+ return false;
+ }
+ elseif ($_SESSION['mailcow_cc_role'] != "admin" || !isset($_data)) {
+ return false;
+ }
+
+ if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $_data))) {
+ return false;
+ }
+ try {
+ $stmt = $pdo->prepare("SELECT
+ `tfa`.`active` AS `tfa_active_int`,
+ CASE `tfa`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `tfa_active`,
+ `domain_admins`.`username`,
+ `domain_admins`.`created`,
+ `domain_admins`.`active` AS `active_int`,
+ CASE `domain_admins`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
+ FROM `domain_admins`
+ LEFT OUTER JOIN `tfa` ON `tfa`.`username`=`domain_admins`.`username`
+ WHERE `domain_admins`.`username`= :domain_admin");
+ $stmt->execute(array(
+ ':domain_admin' => $_data
+ ));
+ $row = $stmt->fetch(PDO::FETCH_ASSOC);
+ if (empty($row)) {
+ return false;
+ }
+ $domainadmindata['username'] = $row['username'];
+ $domainadmindata['tfa_active'] = $row['tfa_active'];
+ $domainadmindata['active'] = $row['active'];
+ $domainadmindata['tfa_active_int'] = $row['tfa_active_int'];
+ $domainadmindata['active_int'] = $row['active_int'];
+ $domainadmindata['modified'] = $row['created'];
+ // GET SELECTED
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain` IN (
+ SELECT `domain` FROM `domain_admins`
+ WHERE `username`= :domain_admin)");
+ $stmt->execute(array(':domain_admin' => $_data));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domainadmindata['selected_domains'][] = $row['domain'];
+ }
+ // GET UNSELECTED
+ $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
+ WHERE `domain` NOT IN (
+ SELECT `domain` FROM `domain_admins`
+ WHERE `username`= :domain_admin)");
+ $stmt->execute(array(':domain_admin' => $_data));
+ $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
+ while($row = array_shift($rows)) {
+ $domainadmindata['unselected_domains'][] = $row['domain'];
+ }
+ if (!isset($domainadmindata['unselected_domains'])) {
+ $domainadmindata['unselected_domains'] = "";
+ }
+ }
+ catch(PDOException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'MySQL: '.$e
+ );
+ }
+ return $domainadmindata;
+ break;
+ }
+}
\ No newline at end of file
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php
index b3420530..66dad50f 100644
--- a/data/web/inc/functions.inc.php
+++ b/data/web/inc/functions.inc.php
@@ -73,7 +73,6 @@ function generate_tlsa_digest($hostname, $port, $starttls = null) {
unset($lines[0]);
return base64_decode(implode('', $lines));
}
-
if (empty($starttls)) {
$context = stream_context_create(array("ssl" => array("capture_peer_cert" => true, 'verify_peer' => false, 'allow_self_signed' => true)));
$stream = stream_socket_client('tls://' . $hostname . ':' . $port, $error_nr, $error_msg, 5, STREAM_CLIENT_CONNECT, $context);
@@ -113,7 +112,6 @@ function generate_tlsa_digest($hostname, $port, $starttls = null) {
stream_socket_enable_crypto($stream, true, STREAM_CRYPTO_METHOD_ANY_CLIENT);
stream_set_blocking($stream, false);
}
-
$params = stream_context_get_params($stream);
if (!empty($params['options']['ssl']['peer_certificate'])) {
$key_resource = openssl_pkey_get_public($params['options']['ssl']['peer_certificate']);
@@ -142,30 +140,6 @@ function verify_ssha256($hash, $password) {
return false;
}
}
-function doveadm_authenticate($hash, $algorithm, $password) {
- $descr = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
- $pipes = array();
- $process = proc_open("/usr/bin/doveadm pw -s ".$algorithm." -t '".$hash."'", $descr, $pipes);
- if (is_resource($process)) {
- fputs($pipes[0], $password);
- fclose($pipes[0]);
- while ($f = fgets($pipes[1])) {
- if (preg_match('/(verified)/', $f)) {
- proc_close($process);
- return true;
- }
- return false;
- }
- fclose($pipes[1]);
- while ($f = fgets($pipes[2])) {
- proc_close($process);
- return false;
- }
- fclose($pipes[2]);
- proc_close($process);
- }
- return false;
-}
function check_login($user, $pass) {
global $pdo;
global $redis;
@@ -272,7 +246,6 @@ function edit_admin_account($postarray) {
);
return false;
}
-
if (!empty($password) && !empty($password2)) {
if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
$_SESSION['return'] = array(
@@ -348,28 +321,20 @@ function edit_admin_account($postarray) {
function edit_user_account($postarray) {
global $lang;
global $pdo;
- if (isset($postarray['username']) && filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $postarray['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- else {
- $username = $postarray['username'];
- }
+ $username = $_SESSION['mailcow_cc_username'];
+ $role = $_SESSION['mailcow_cc_role'];
+ $password_old = $postarray['user_old_pass'];
+ if (filter_var($username, FILTER_VALIDATE_EMAIL === false) || $role != 'user') {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
}
- else {
- $username = $_SESSION['mailcow_cc_username'];
- }
- $password_old = $postarray['user_old_pass'];
-
if (isset($postarray['user_new_pass']) && isset($postarray['user_new_pass2'])) {
$password_new = $postarray['user_new_pass'];
$password_new2 = $postarray['user_new_pass2'];
}
-
$stmt = $pdo->prepare("SELECT `password` FROM `mailbox`
WHERE `kind` NOT REGEXP 'location|thing|group'
AND `username` = :user");
@@ -382,7 +347,6 @@ function edit_user_account($postarray) {
);
return false;
}
-
if (isset($password_new) && isset($password_new2)) {
if (!empty($password_new2) && !empty($password_new)) {
if ($password_new2 != $password_new) {
@@ -486,293 +450,12 @@ function is_valid_domain_name($domain_name) {
&& preg_match("/^.{1,253}$/", $domain_name)
&& preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name));
}
-function add_domain_admin($postarray) {
- global $lang;
- global $pdo;
- $username = strtolower(trim($postarray['username']));
- $password = $postarray['password'];
- $password2 = $postarray['password2'];
- $domains = (array)$postarray['domains'];
- $active = intval($postarray['active']);
-
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- if (empty($domains)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username)) || empty ($username)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT `username` FROM `mailbox`
- WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
-
- $stmt = $pdo->prepare("SELECT `username` FROM `admin`
- WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
-
- $stmt = $pdo->prepare("SELECT `username` FROM `domain_admins`
- WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- $num_results[] = count($stmt->fetchAll(PDO::FETCH_ASSOC));
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- foreach ($num_results as $num_results_each) {
- if ($num_results_each != 0) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($username))
- );
- return false;
- }
- }
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- if ($password != $password2) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- $password_hashed = hash_password($password);
- foreach ($domains as $domain) {
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
- VALUES (:username, :domain, :created, :active)");
- $stmt->execute(array(
- ':username' => $username,
- ':domain' => $domain,
- ':created' => date('Y-m-d H:i:s'),
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- delete_domain_admin(array('username' => $username));
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- try {
- $stmt = $pdo->prepare("INSERT INTO `admin` (`username`, `password`, `superadmin`, `active`)
- VALUES (:username, :password_hashed, '0', :active)");
- $stmt->execute(array(
- ':username' => $username,
- ':password_hashed' => $password_hashed,
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_empty'])
- );
- return false;
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_added'], htmlspecialchars($username))
- );
-}
-function delete_domain_admin($postarray) {
- global $pdo;
- global $lang;
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $usernames = (array)$postarray['username'];
- foreach ($usernames as $username) {
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- try {
- $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- $stmt = $pdo->prepare("DELETE FROM `admin` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_removed'], htmlspecialchars(implode(', ', $usernames)))
- );
-}
-function get_domain_admins() {
- global $pdo;
- global $lang;
- $domainadmins = array();
- if ($_SESSION['mailcow_cc_role'] != "admin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- try {
- $stmt = $pdo->query("SELECT DISTINCT
- `username`
- FROM `domain_admins`
- WHERE `username` IN (
- SELECT `username` FROM `admin`
- WHERE `superadmin`!='1'
- )");
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while ($row = array_shift($rows)) {
- $domainadmins[] = $row['username'];
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $domainadmins;
-}
-function get_domain_admin_details($domain_admin) {
- global $pdo;
-
- global $lang;
- $domainadmindata = array();
- if (isset($domain_admin) && $_SESSION['mailcow_cc_role'] != "admin") {
- return false;
- }
- if (!isset($domain_admin) && $_SESSION['mailcow_cc_role'] != "domainadmin") {
- return false;
- }
- (!isset($domain_admin)) ? $domain_admin = $_SESSION['mailcow_cc_username'] : null;
-
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $domain_admin))) {
- return false;
- }
- try {
- $stmt = $pdo->prepare("SELECT
- `tfa`.`active` AS `tfa_active_int`,
- CASE `tfa`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `tfa_active`,
- `domain_admins`.`username`,
- `domain_admins`.`created`,
- `domain_admins`.`active` AS `active_int`,
- CASE `domain_admins`.`active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`
- FROM `domain_admins`
- LEFT OUTER JOIN `tfa` ON `tfa`.`username`=`domain_admins`.`username`
- WHERE `domain_admins`.`username`= :domain_admin");
- $stmt->execute(array(
- ':domain_admin' => $domain_admin
- ));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if (empty($row)) {
- return false;
- }
- $domainadmindata['username'] = $row['username'];
- $domainadmindata['tfa_active'] = $row['tfa_active'];
- $domainadmindata['active'] = $row['active'];
- $domainadmindata['tfa_active_int'] = $row['tfa_active_int'];
- $domainadmindata['active_int'] = $row['active_int'];
- $domainadmindata['modified'] = $row['created'];
- // GET SELECTED
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain` IN (
- SELECT `domain` FROM `domain_admins`
- WHERE `username`= :domain_admin)");
- $stmt->execute(array(':domain_admin' => $domain_admin));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $domainadmindata['selected_domains'][] = $row['domain'];
- }
- // GET UNSELECTED
- $stmt = $pdo->prepare("SELECT `domain` FROM `domain`
- WHERE `domain` NOT IN (
- SELECT `domain` FROM `domain_admins`
- WHERE `username`= :domain_admin)");
- $stmt->execute(array(':domain_admin' => $domain_admin));
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- while($row = array_shift($rows)) {
- $domainadmindata['unselected_domains'][] = $row['domain'];
- }
- if (!isset($domainadmindata['unselected_domains'])) {
- $domainadmindata['unselected_domains'] = "";
- }
- }
- catch(PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- }
- return $domainadmindata;
-}
function set_tfa($postarray) {
global $lang;
global $pdo;
global $yubi;
global $u2f;
global $tfa;
-
if ($_SESSION['mailcow_cc_role'] != "domainadmin" &&
$_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
@@ -847,7 +530,6 @@ function set_tfa($postarray) {
'msg' => sprintf($lang['success']['object_modified'], htmlspecialchars($username))
);
break;
-
case "u2f":
$key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
try {
@@ -871,7 +553,6 @@ function set_tfa($postarray) {
return false;
}
break;
-
case "totp":
$key_id = (!isset($postarray["key_id"])) ? 'unidentified' : $postarray["key_id"];
if ($tfa->verifyCode($_POST['totp_secret'], $_POST['totp_confirm_token']) === true) {
@@ -900,7 +581,6 @@ function set_tfa($postarray) {
);
}
break;
-
case "none":
try {
$stmt = $pdo->prepare("DELETE FROM `tfa` WHERE `username` = :username");
@@ -977,7 +657,6 @@ function get_tfa($username = null) {
elseif (empty($username)) {
return false;
}
-
$stmt = $pdo->prepare("SELECT * FROM `tfa`
WHERE `username` = :username AND `active` = '1'");
$stmt->execute(array(':username' => $username));
@@ -1041,7 +720,6 @@ function verify_tfa_login($username, $token) {
global $yubi;
global $u2f;
global $tfa;
-
$stmt = $pdo->prepare("SELECT `authmech` FROM `tfa`
WHERE `username` = :username AND `active` = '1'");
$stmt->execute(array(':username' => $username));
@@ -1126,237 +804,6 @@ function verify_tfa_login($username, $token) {
}
return false;
}
-function edit_domain_admin($postarray) {
- global $lang;
- global $pdo;
-
- if ($_SESSION['mailcow_cc_role'] != "admin" && $_SESSION['mailcow_cc_role'] != "domainadmin") {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- // Administrator
- if ($_SESSION['mailcow_cc_role'] == "admin") {
- if (!is_array($postarray['username'])) {
- $usernames = array();
- $usernames[] = $postarray['username'];
- }
- else {
- $usernames = $postarray['username'];
- }
- foreach ($usernames as $username) {
- $is_now = get_domain_admin_details($username);
- $domains = (isset($postarray['domains'])) ? (array)$postarray['domains'] : null;
- if (!empty($is_now)) {
- $active = (isset($postarray['active'])) ? $postarray['active'] : $is_now['active_int'];
- $domains = (!empty($domains)) ? $domains : $is_now['selected_domains'];
- $username_new = (!empty($postarray['username_new'])) ? $postarray['username_new'] : $is_now['username'];
- }
- else {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
- $password = $postarray['password'];
- $password2 = $postarray['password2'];
-
- if (!empty($domains)) {
- foreach ($domains as $domain) {
- if (!is_valid_domain_name($domain)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['domain_invalid'])
- );
- return false;
- }
- }
- }
- if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username_new))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- if ($username_new != $username) {
- if (!empty(get_domain_admin_details($username_new)['username'])) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['username_invalid'])
- );
- return false;
- }
- }
- try {
- $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username");
- $stmt->execute(array(
- ':username' => $username,
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
-
- if (!empty($domains)) {
- foreach ($domains as $domain) {
- try {
- $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`)
- VALUES (:username_new, :domain, :created, :active)");
- $stmt->execute(array(
- ':username_new' => $username_new,
- ':domain' => $domain,
- ':created' => date('Y-m-d H:i:s'),
- ':active' => $active
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- }
-
- if (!empty($password) && !empty($password2)) {
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- if ($password != $password2) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- $password_hashed = hash_password($password);
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active, `password` = :password_hashed WHERE `username` = :username");
- $stmt->execute(array(
- ':password_hashed' => $password_hashed,
- ':username_new' => $username_new,
- ':username' => $username,
- ':active' => $active
- ));
- if (isset($postarray['disable_tfa'])) {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- }
- else {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
- $stmt->execute(array(':username_new' => $username_new, ':username' => $username));
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- else {
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `username` = :username_new, `active` = :active WHERE `username` = :username");
- $stmt->execute(array(
- ':username_new' => $username_new,
- ':username' => $username,
- ':active' => $active
- ));
- if (isset($postarray['disable_tfa'])) {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `active` = '0' WHERE `username` = :username");
- $stmt->execute(array(':username' => $username));
- }
- else {
- $stmt = $pdo->prepare("UPDATE `tfa` SET `username` = :username_new WHERE `username` = :username");
- $stmt->execute(array(':username_new' => $username_new, ':username' => $username));
- }
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
- }
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars(implode(', ', $usernames)))
- );
- }
- // Domain administrator
- // Can only edit itself
- elseif ($_SESSION['mailcow_cc_role'] == "domainadmin") {
- $username = $_SESSION['mailcow_cc_username'];
- $password_old = $postarray['user_old_pass'];
- $password_new = $postarray['user_new_pass'];
- $password_new2 = $postarray['user_new_pass2'];
-
- $stmt = $pdo->prepare("SELECT `password` FROM `admin`
- WHERE `username` = :user");
- $stmt->execute(array(':user' => $username));
- $row = $stmt->fetch(PDO::FETCH_ASSOC);
- if (!verify_ssha256($row['password'], $password_old)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['access_denied'])
- );
- return false;
- }
-
- if (!empty($password_new2) && !empty($password_new)) {
- if ($password_new2 != $password_new) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_mismatch'])
- );
- return false;
- }
- if (!preg_match('/' . $GLOBALS['PASSWD_REGEP'] . '/', $password_new)) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['password_complexity'])
- );
- return false;
- }
- $password_hashed = hash_password($password_new);
- try {
- $stmt = $pdo->prepare("UPDATE `admin` SET `password` = :password_hashed WHERE `username` = :username");
- $stmt->execute(array(
- ':password_hashed' => $password_hashed,
- ':username' => $username
- ));
- }
- catch (PDOException $e) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => 'MySQL: '.$e
- );
- return false;
- }
- }
-
- $_SESSION['return'] = array(
- 'type' => 'success',
- 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username))
- );
- }
-}
function get_admin_details() {
// No parameter to be given, only one admin should exist
global $pdo;
@@ -1438,4 +885,4 @@ function get_logs($container, $lines = 100) {
}
return false;
}
-?>
+?>
\ No newline at end of file
diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php
index 597d9d87..de8bf0ac 100644
--- a/data/web/inc/functions.mailbox.inc.php
+++ b/data/web/inc/functions.mailbox.inc.php
@@ -879,7 +879,7 @@ function mailbox($_action, $_type, $_data = null) {
$alias_domain = idn_to_ascii(strtolower(trim($alias_domain)));
$is_now = mailbox('get', 'alias_domain_details', $alias_domain);
if (!empty($is_now)) {
- $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
$target_domain = (!empty($_data['target_domain'])) ? idn_to_ascii(strtolower(trim($_data['target_domain']))) : $is_now['target_domain'];
}
else {
@@ -903,7 +903,7 @@ function mailbox($_action, $_type, $_data = null) {
);
return false;
}
- if (empty(mailbox('get', 'domain_details', $target_domain))) {
+ if (empty(mailbox('get', 'domain_details', $target_domain)) || !empty(mailbox('get', 'alias_domain_details', $target_domain))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['target_domain_invalid'])
@@ -950,12 +950,10 @@ function mailbox($_action, $_type, $_data = null) {
);
return false;
}
- $tls_enforce_out = intval($_data['tls_enforce_out']);
- $tls_enforce_in = intval($_data['tls_enforce_in']);
$is_now = mailbox('get', 'tls_policy', $username);
if (!empty($is_now)) {
- $tls_enforce_in = (isset($_data['tls_enforce_in'])) ? $_data['tls_enforce_in'] : $is_now['tls_enforce_in'];
- $tls_enforce_out = (isset($_data['tls_enforce_out'])) ? $_data['tls_enforce_out'] : $is_now['tls_enforce_out'];
+ $tls_enforce_in = (isset($_data['tls_enforce_in'])) ? intval($_data['tls_enforce_in']) : $is_now['tls_enforce_in'];
+ $tls_enforce_out = (isset($_data['tls_enforce_out'])) ? intval($_data['tls_enforce_out']) : $is_now['tls_enforce_out'];
}
else {
$_SESSION['return'] = array(
@@ -1136,6 +1134,63 @@ function mailbox($_action, $_type, $_data = null) {
'msg' => sprintf($lang['success']['mailbox_modified'], implode(', ', $usernames))
);
break;
+ case 'domain_ratelimit':
+ $rl_value = intval($_data['rl_value']);
+ $rl_frame = $_data['rl_frame'];
+ if (!in_array($rl_frame, array('s', 'm', 'h'))) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Ratelimit time frame is incorrect'
+ );
+ return false;
+ }
+ if (!is_array($_data['domain'])) {
+ $domains = array();
+ $domains[] = $_data['domain'];
+ }
+ else {
+ $domains = $_data['domain'];
+ }
+ foreach ($domains as $domain) {
+ if (!is_valid_domain_name($domain) || !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => sprintf($lang['danger']['access_denied'])
+ );
+ return false;
+ }
+ if (empty($rl_value)) {
+ try {
+ $redis->hDel('RL_OBJECT', $domain);
+ $redis->hDel('RL_VALUE', $domain);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ }
+ else {
+ try {
+ $redis->hSet('RL_OBJECT', $domain, '1');
+ $redis->hSet('RL_VALUE', $domain, $rl_value . ' / 1' . $rl_frame);
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ }
+ }
+ $_SESSION['return'] = array(
+ 'type' => 'success',
+ 'msg' => sprintf($lang['success']['domain_modified'], implode(', ', $domains))
+ );
+ break;
case 'syncjob':
if (!is_array($_data['id'])) {
$ids = array();
@@ -1149,9 +1204,9 @@ function mailbox($_action, $_type, $_data = null) {
if (!empty($is_now)) {
$username = $is_now['user2'];
$user1 = (!empty($_data['user1'])) ? $_data['user1'] : $is_now['user1'];
- $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
- $delete2duplicates = (isset($_data['delete2duplicates'])) ? $_data['delete2duplicates'] : $is_now['delete2duplicates'];
- $delete1 = (isset($_data['delete1'])) ? $_data['delete1'] : $is_now['delete1'];
+ $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
+ $delete2duplicates = (isset($_data['delete2duplicates'])) ? intval($_data['delete2duplicates']) : $is_now['delete2duplicates'];
+ $delete1 = (isset($_data['delete1'])) ? intval($_data['delete1']) : $is_now['delete1'];
$port1 = (!empty($_data['port1'])) ? $_data['port1'] : $is_now['port1'];
$password1 = (!empty($_data['password1'])) ? $_data['password1'] : $is_now['password1'];
$host1 = (!empty($_data['host1'])) ? $_data['host1'] : $is_now['host1'];
@@ -1253,7 +1308,7 @@ function mailbox($_action, $_type, $_data = null) {
foreach ($addresses as $address) {
$is_now = mailbox('get', 'alias_details', $address);
if (!empty($is_now)) {
- $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
$goto = (!empty($_data['goto'])) ? $_data['goto'] : $is_now['goto'];
}
else {
@@ -1383,9 +1438,9 @@ function mailbox($_action, $_type, $_data = null) {
elseif ($_SESSION['mailcow_cc_role'] == "admin") {
$is_now = mailbox('get', 'domain_details', $domain);
if (!empty($is_now)) {
- $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
- $backupmx = (isset($_data['backupmx'])) ? $_data['backupmx'] : $is_now['backupmx_int'];
- $relay_all_recipients = (isset($_data['relay_all_recipients'])) ? $_data['relay_all_recipients'] : $is_now['relay_all_recipients_int'];
+ $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
+ $backupmx = (isset($_data['backupmx'])) ? intval($_data['backupmx']) : $is_now['backupmx_int'];
+ $relay_all_recipients = (isset($_data['relay_all_recipients'])) ? intval($_data['relay_all_recipients']) : $is_now['relay_all_recipients_int'];
$aliases = (!empty($_data['aliases'])) ? $_data['aliases'] : $is_now['max_num_aliases_for_domain'];
$mailboxes = (!empty($_data['mailboxes'])) ? $_data['mailboxes'] : $is_now['max_num_mboxes_for_domain'];
$maxquota = (!empty($_data['maxquota'])) ? $_data['maxquota'] : ($is_now['max_quota_for_mbox'] / 1048576);
@@ -1524,7 +1579,7 @@ function mailbox($_action, $_type, $_data = null) {
}
$is_now = mailbox('get', 'mailbox_details', $username);
if (!empty($is_now)) {
- $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
+ $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
$name = (!empty($_data['name'])) ? $_data['name'] : $is_now['name'];
$domain = $is_now['domain'];
$quota_m = (!empty($_data['quota'])) ? $_data['quota'] : ($is_now['quota'] / 1048576);
@@ -1588,19 +1643,15 @@ function mailbox($_action, $_type, $_data = null) {
mailbox('get', 'sender_acl_handles', $username)['sender_acl_addresses']['ro']
);
// Get sender_acl items from POST array
- $sender_acl_domain_admin = ($_data['sender_acl'] == "0") ? array() : $_data['sender_acl'];
+ $sender_acl_domain_admin = ($_data['sender_acl'] == "0") ? array() : (array)$_data['sender_acl'];
if (!empty($sender_acl_domain_admin) || !empty($sender_acl_admin)) {
- // Check items in POST array
- foreach ($sender_acl_domain_admin as $sender_acl) {
- if (!filter_var($sender_acl, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name(ltrim($sender_acl, '@'))) {
- $_SESSION['return'] = array(
- 'type' => 'danger',
- 'msg' => sprintf($lang['danger']['sender_acl_invalid'])
- );
- return false;
+ // Check items in POST array and skip invalid
+ foreach ($sender_acl_domain_admin as $key => $val) {
+ if (!filter_var($val, FILTER_VALIDATE_EMAIL) && !is_valid_domain_name(ltrim($val, '@'))) {
+ unset($sender_acl_domain_admin[$key]);
}
- if (is_valid_domain_name(ltrim($sender_acl, '@'))) {
- if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], ltrim($sender_acl, '@'))) {
+ if (is_valid_domain_name(ltrim($val, '@'))) {
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], ltrim($val, '@'))) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['sender_acl_invalid'])
@@ -1608,8 +1659,8 @@ function mailbox($_action, $_type, $_data = null) {
return false;
}
}
- if (filter_var($sender_acl, FILTER_VALIDATE_EMAIL)) {
- if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $sender_acl)) {
+ if (filter_var($val, FILTER_VALIDATE_EMAIL)) {
+ if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $val)) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['sender_acl_invalid'])
@@ -1761,8 +1812,8 @@ function mailbox($_action, $_type, $_data = null) {
foreach ($names as $name) {
$is_now = mailbox('get', 'resource_details', $name);
if (!empty($is_now)) {
- $active = (isset($_data['active'])) ? $_data['active'] : $is_now['active_int'];
- $multiple_bookings = (isset($_data['multiple_bookings'])) ? $_data['multiple_bookings'] : $is_now['multiple_bookings_int'];
+ $active = (isset($_data['active'])) ? intval($_data['active']) : $is_now['active_int'];
+ $multiple_bookings = (isset($_data['multiple_bookings'])) ? intval($_data['multiple_bookings']) : $is_now['multiple_bookings_int'];
$description = (!empty($_data['description'])) ? $_data['description'] : $is_now['description'];
$kind = (!empty($_data['kind'])) ? $_data['kind'] : $is_now['kind'];
}
@@ -2267,6 +2318,31 @@ function mailbox($_action, $_type, $_data = null) {
}
return $aliases;
break;
+ case 'domain_ratelimit':
+ $aliases = array();
+ if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
+ return false;
+ }
+ try {
+ if (($rl_value = $redis->hGet('RL_VALUE', $_data)) && $redis->hGet('RL_OBJECT', $_data)) {
+ $rl = explode(' / 1', $rl_value);
+ $data['value'] = $rl[0];
+ $data['frame'] = $rl[1];
+ return $data;
+ }
+ else {
+ return false;
+ }
+ }
+ catch (RedisException $e) {
+ $_SESSION['return'] = array(
+ 'type' => 'danger',
+ 'msg' => 'Redis: '.$e
+ );
+ return false;
+ }
+ return false;
+ break;
case 'alias_details':
$aliasdata = array();
try {
diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php
index e00fd31a..ebc453f8 100644
--- a/data/web/inc/prerequisites.inc.php
+++ b/data/web/inc/prerequisites.inc.php
@@ -61,6 +61,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.en.php';
include $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.mailbox.inc.php';
+require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.domain_admin.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';
diff --git a/data/web/inc/sessions.inc.php b/data/web/inc/sessions.inc.php
index e2919f7a..d23d2cba 100644
--- a/data/web/inc/sessions.inc.php
+++ b/data/web/inc/sessions.inc.php
@@ -1,6 +1,8 @@
diff --git a/data/web/js/api.js b/data/web/js/api.js
index ec26709a..1fd962fb 100644
--- a/data/web/js/api.js
+++ b/data/web/js/api.js
@@ -64,8 +64,23 @@ $(document).ready(function() {
// If clicked element #edit_selected is in a form with the same data-id as the button,
// we merge all input fields by {"name":"value"} into api-attr
if ($(this).closest("form").data('id') == id) {
- var attr_to_merge = $(this).closest("form").serializeObject();
- var api_attr = $.extend(api_attr, attr_to_merge)
+ var req_empty = false;
+ $(this).closest("form").find('select, textarea, input').each(function() {
+ if ($(this).prop('required')) {
+ if (!$(this).val()) {
+ req_empty = true;
+ $(this).addClass('inputMissingAttr');
+ } else {
+ $(this).removeClass('inputMissingAttr');
+ }
+ }
+ });
+ if (!req_empty) {
+ var attr_to_merge = $(this).closest("form").serializeObject();
+ var api_attr = $.extend(api_attr, attr_to_merge)
+ } else {
+ return false;
+ }
}
// If clicked element #edit_selected has data-item attribute, it is added to "items"
if (typeof $(this).data('item') !== 'undefined') {
@@ -77,6 +92,7 @@ $(document).ready(function() {
}
if (typeof multi_data[id] == "undefined") return;
api_items = multi_data[id];
+ // alert(JSON.stringify(api_attr));
if (Object.keys(api_items).length !== 0) {
$.ajax({
type: "POST",
diff --git a/data/web/json_api.php b/data/web/json_api.php
index e4086520..56d4e741 100644
--- a/data/web/json_api.php
+++ b/data/web/json_api.php
@@ -426,7 +426,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
case "domain-admin":
if (isset($_POST['attr'])) {
$attr = (array)json_decode($_POST['attr'], true);
- if (add_domain_admin($attr) === false) {
+ if (domain_admin('add', $attr) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -826,10 +826,10 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
case "domain-admin":
switch ($object) {
case "all":
- $domain_admins = get_domain_admins();
+ $domain_admins = domain_admin('get');
if (!empty($domain_admins)) {
foreach ($domain_admins as $domain_admin) {
- if ($details = get_domain_admin_details($domain_admin)) {
+ if ($details = domain_admin('details', $domain_admin)) {
$data[] = $details;
}
else {
@@ -849,7 +849,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
break;
default:
- $data = get_domain_admin_details($object);
+ $data = domain_admin('details', $object);
if (!isset($data) || empty($data)) {
echo '{}';
}
@@ -1385,7 +1385,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
if (isset($_POST['items'])) {
$items = (array)json_decode($_POST['items'], true);
if (is_array($items)) {
- if (delete_domain_admin(array('username' => $items)) === false) {
+ if (domain_admin('delete', array('username' => $items)) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -1603,6 +1603,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
}
break;
case "mailbox":
+ // sender_acl:0 removes all entries
if (isset($_POST['items']) && isset($_POST['attr'])) {
$items = (array)json_decode($_POST['items'], true);
$attr = (array)json_decode($_POST['attr'], true);
@@ -1778,6 +1779,50 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
));
}
break;
+ case "domain-ratelimit":
+ if (isset($_POST['items']) && isset($_POST['attr'])) {
+ $items = (array)json_decode($_POST['items'], true);
+ $attr = (array)json_decode($_POST['attr'], true);
+ $postarray = array_merge(array('domain' => $items), $attr);
+ if (is_array($postarray['domain'])) {
+ if (mailbox('edit', 'domain_ratelimit', $postarray) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ break;
case "alias-domain":
if (isset($_POST['items']) && isset($_POST['attr'])) {
$items = (array)json_decode($_POST['items'], true);
@@ -1822,7 +1867,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
));
}
break;
- case "spam_score":
+ case "spam-score":
if (isset($_POST['items']) && isset($_POST['attr'])) {
$items = (array)json_decode($_POST['items'], true);
$attr = (array)json_decode($_POST['attr'], true);
@@ -1872,7 +1917,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
$attr = (array)json_decode($_POST['attr'], true);
$postarray = array_merge(array('username' => $items), $attr);
if (is_array($postarray['username'])) {
- if (edit_domain_admin($postarray) === false) {
+ if (domain_admin('edit', $postarray) === false) {
if (isset($_SESSION['return'])) {
echo json_encode($_SESSION['return']);
}
@@ -1989,39 +2034,109 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
));
}
break;
- case "admin":
- // No items as there is only one admin
- if (isset($_POST['attr'])) {
- $attr = (array)json_decode($_POST['attr'], true);
- if (edit_admin_account($attr) === false) {
- if (isset($_SESSION['return'])) {
- echo json_encode($_SESSION['return']);
+ case "self":
+ // No items, logged-in user, users and domain admins
+ if ($_SESSION['mailcow_cc_role'] == "domainadmin") {
+ if (isset($_POST['attr'])) {
+ $attr = (array)json_decode($_POST['attr'], true);
+ if (domain_admin('edit', $attr) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
}
else {
- echo json_encode(array(
- 'type' => 'error',
- 'msg' => 'Edit failed'
- ));
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
}
- exit();
}
else {
- if (isset($_SESSION['return'])) {
- echo json_encode($_SESSION['return']);
- }
- else {
- echo json_encode(array(
- 'type' => 'success',
- 'msg' => 'Task completed'
- ));
- }
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
}
}
- else {
- echo json_encode(array(
- 'type' => 'error',
- 'msg' => 'Incomplete post data'
- ));
+ elseif ($_SESSION['mailcow_cc_role'] == "user") {
+ if (isset($_POST['attr'])) {
+ $attr = (array)json_decode($_POST['attr'], true);
+ if (edit_user_account($attr) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
+ }
+ elseif ($_SESSION['mailcow_cc_role'] == "admin") {
+ if (isset($_POST['attr'])) {
+ $attr = (array)json_decode($_POST['attr'], true);
+ if (edit_admin_account($attr) === false) {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Edit failed'
+ ));
+ }
+ exit();
+ }
+ else {
+ if (isset($_SESSION['return'])) {
+ echo json_encode($_SESSION['return']);
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'success',
+ 'msg' => 'Task completed'
+ ));
+ }
+ }
+ }
+ else {
+ echo json_encode(array(
+ 'type' => 'error',
+ 'msg' => 'Incomplete post data'
+ ));
+ }
}
break;
}
diff --git a/data/web/user.php b/data/web/user.php
index 77ccc62d..b283894c 100644
--- a/data/web/user.php
+++ b/data/web/user.php
@@ -357,7 +357,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "use