public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Commit
[Web] Initial ratelimit support, more API actions
84ad5794
data/web/admin.php | 4 +-
data/web/css/edit.css | 3 +
data/web/edit.php | 85 +++--
data/web/inc/functions.domain_admin.inc.php | 507 ++++++++++++++++++++++++
data/web/inc/functions.inc.php | 573 +---------------------------
data/web/inc/functions.mailbox.inc.php | 134 +++++--
data/web/inc/prerequisites.inc.php | 1 +
data/web/inc/sessions.inc.php | 2 +
data/web/inc/triggers.inc.php | 41 --
data/web/js/api.js | 20 +-
data/web/json_api.php | 175 +++++++--
data/web/user.php | 4 +-
12 files changed, 852 insertions(+), 697 deletions(-)
create mode 100644 data/web/inc/functions.domain_admin.inc.php
Diff
diff --git a/data/web/admin.php b/data/web/admin.php
index 0e0003a8..284bf31b 100644
--- a/data/web/admin.php
+++ b/data/web/admin.php
@@ -56,7 +56,7 @@ $tfa_data = get_tfa();
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
- <button class="btn btn-default" id="edit_selected" data-id="admin" data-item="null" data-api-url='edit/admin' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
+ <button class="btn btn-default" id="edit_selected" data-id="admin" data-item="null" data-api-url='edit/self' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
</div>
</div>
</form>
@@ -253,7 +253,7 @@ XYZ
</div>
</div>
</div>
-
+
<div class="panel panel-default">
<div class="panel-heading"><?=$lang['admin']['forwarding_hosts'];?></div>
<div class="panel-body">
diff --git a/data/web/css/edit.css b/data/web/css/edit.css
index fe4d9fff..07d4e745 100644
--- a/data/web/css/edit.css
+++ b/data/web/css/edit.css
@@ -27,3 +27,6 @@ table.footable>tbody>tr.footable-empty>td {
user-select: none;
padding:10px 0 10px 0;
}
+.inputMissingAttr {
+ border-color: #FF4136;
+}
diff --git a/data/web/edit.php b/data/web/edit.php
index d156dba0..1f250535 100644
--- a/data/web/edit.php
+++ b/data/web/edit.php
@@ -25,9 +25,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
?>
<h4><?=$lang['edit']['alias'];?></h4>
<br />
- <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+ <form class="form-horizontal" data-id="editalias" role="form" method="post">
<input type="hidden" value="0" name="active">
- <input type="hidden" name="address" value="<?=htmlspecialchars($alias);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="goto"><?=$lang['edit']['target_address'];?></label>
<div class="col-sm-10">
@@ -43,7 +42,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" name="mailbox_edit_alias" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
+ <button class="btn btn-success" id="edit_selected" data-id="editalias" data-item="<?=$alias;?>" data-api-url='edit/alias' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
@@ -55,20 +54,19 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
<?php
}
}
- elseif (isset($_GET['domainadmin']) &&
- ctype_alnum(str_replace(array('_', '.', '-'), '', $_GET["domainadmin"])) &&
- !empty($_GET["domainadmin"]) &&
- $_GET["domainadmin"] != 'admin' &&
- $_SESSION['mailcow_cc_role'] == "admin") {
+ elseif (isset($_GET['domainadmin']) &&
+ ctype_alnum(str_replace(array('_', '.', '-'), '', $_GET["domainadmin"])) &&
+ !empty($_GET["domainadmin"]) &&
+ $_GET["domainadmin"] != 'admin' &&
+ $_SESSION['mailcow_cc_role'] == "admin") {
$domain_admin = $_GET["domainadmin"];
- $result = get_domain_admin_details($domain_admin);
+ $result = domain_admin('details', $domain_admin);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['domain_admin'];?></h4>
<br />
- <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+ <form class="form-horizontal" data-id="editdomainadmin" role="form" method="post">
<input type="hidden" value="0" name="active">
- <input type="hidden" name="username" value="<?=htmlspecialchars($domain_admin);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="username_new"><?=$lang['edit']['username'];?></label>
<div class="col-sm-10">
@@ -122,7 +120,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" name="edit_domain_admin" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
+ <button class="btn btn-success" id="edit_selected" data-id="editdomainadmin" data-item="<?=$domain_admin;?>" data-api-url='edit/domain-admin' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
@@ -139,14 +137,14 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
!empty($_GET["domain"])) {
$domain = $_GET["domain"];
$result = mailbox('get', 'domain_details', $domain);
+ $rl = mailbox('get', 'domain_ratelimit', $domain);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['domain'];?></h4>
- <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+ <form data-id="editdomain" class="form-horizontal" role="form" method="post">
<input type="hidden" value="0" name="active">
<input type="hidden" value="0" name="backupmx">
<input type="hidden" value="0" name="relay_all_recipients">
- <input type="hidden" name="domain" value="<?=htmlspecialchars($domain);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="description"><?=$lang['edit']['description'];?></label>
<div class="col-sm-10">
@@ -203,7 +201,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" name="mailbox_edit_domain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
+ <button class="btn btn-success" id="edit_selected" data-id="editdomain" data-item="<?=$domain;?>" data-api-url='edit/domain' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
</div>
</div>
</form>
@@ -223,6 +221,23 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
}
?>
<hr>
+ <form data-id="domratelimit" class="form-inline well" method="post">
+ <div class="form-group">
+ <label class="control-label">Ratelimit</label>
+ <input name="rl_value" id="rl_value" type="number" value="<?=(!empty($rl['value'])) ? $rl['value'] : null;?>" class="form-control" placeholder="disabled">
+ </div>
+ <div class="form-group">
+ <select name="rl_frame" id="rl_frame" class="form-control">
+ <option value="s" <?=(isset($rl['frame']) && $rl['frame'] == 's') ? 'selected' : null;?>>msgs / second</option>
+ <option value="m" <?=(isset($rl['frame']) && $rl['frame'] == 'm') ? 'selected' : null;?>>msgs / minute</option>
+ <option value="h" <?=(isset($rl['frame']) && $rl['frame'] == 'h') ? 'selected' : null;?>>msgs / hour</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$domain;?>" data-api-url='edit/domain-ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
+ </div>
+ </form>
+ <hr>
<div class="row">
<div class="col-sm-6">
<h4><?=$lang['user']['spamfilter_wl'];?></h4>
@@ -282,12 +297,12 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
!empty($_GET["aliasdomain"])) {
$alias_domain = $_GET["aliasdomain"];
$result = mailbox('get', 'alias_domain_details', $alias_domain);
+ $rl = mailbox('get', 'domain_ratelimit', $alias_domain);
if (!empty($result)) {
?>
<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
- <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+ <form class="form-horizontal" data-id="editaliasdomain" role="form" method="post">
<input type="hidden" value="0" name="active">
- <input type="hidden" value="<?=$result['alias_domain'];?>" name="alias_domain">
<div class="form-group">
<label class="control-label col-sm-2" for="target_domain"><?=$lang['edit']['target_domain'];?></label>
<div class="col-sm-10">
@@ -303,10 +318,27 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" name="mailbox_edit_alias_domain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
+ <button class="btn btn-success" id="edit_selected" data-id="editaliasdomain" data-item="<?=$alias_domain;?>" data-api-url='edit/alias-domain' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
+ <hr>
+ <form data-id="domratelimit" class="form-inline well" method="post">
+ <div class="form-group">
+ <label class="control-label">Ratelimit</label>
+ <input name="rl_value" id="rl_value" type="number" value="<?=(!empty($rl['value'])) ? $rl['value'] : null;?>" class="form-control" placeholder="disabled">
+ </div>
+ <div class="form-group">
+ <select name="rl_frame" id="rl_frame" class="form-control">
+ <option value="s" <?=(isset($rl['frame']) && $rl['frame'] == 's') ? 'selected' : null;?>>msgs / second</option>
+ <option value="m" <?=(isset($rl['frame']) && $rl['frame'] == 'm') ? 'selected' : null;?>>msgs / minute</option>
+ <option value="h" <?=(isset($rl['frame']) && $rl['frame'] == 'h') ? 'selected' : null;?>>msgs / hour</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <button class="btn btn-default" id="edit_selected" data-id="domratelimit" data-item="<?=$alias_domain;?>" data-api-url='edit/domain-ratelimit' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
+ </div>
+ </form>
<?php
if (!empty($dkim = dkim('details', $alias_domain))) {
?>
@@ -334,10 +366,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
if (!empty($result)) {
?>
<h4><?=$lang['edit']['mailbox'];?></h4>
- <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+ <form class="form-horizontal" data-id="editmailbox" role="form" method="post">
<input type="hidden" value="0" name="sender_acl">
<input type="hidden" value="0" name="active">
- <input type="hidden" name="username" value="<?=htmlspecialchars($result['username']);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?>:</label>
<div class="col-sm-10">
@@ -355,7 +386,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
<div class="form-group">
<label class="control-label col-sm-2" for="sender_acl"><?=$lang['edit']['sender_acl'];?>:</label>
<div class="col-sm-10">
- <select data-width="100%" style="width:100%" id="sender_acl" name="sender_acl[]" size="10" multiple>
+ <select data-width="100%" style="width:100%" id="sender_acl" name="sender_acl" size="10" multiple>
<?php
$sender_acl_handles = mailbox('get', 'sender_acl_handles', $mailbox);
@@ -426,7 +457,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" name="mailbox_edit_mailbox" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
+ <button class="btn btn-success" id="edit_selected" data-id="editmailbox" data-item="<?=htmlspecialchars($result['username']);?>" data-api-url='edit/mailbox' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
@@ -439,10 +470,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
if (!empty($result)) {
?>
<h4><?=$lang['edit']['resource'];?></h4>
- <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+ <form class="form-horizontal" role="form" method="post" data-id="editresource">
<input type="hidden" value="0" name="active">
<input type="hidden" value="0" name="multiple_bookings">
- <input type="hidden" name="name" value="<?=htmlspecialchars($result['name']);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="description"><?=$lang['add']['description'];?></label>
<div class="col-sm-10">
@@ -475,7 +505,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" name="mailbox_edit_resource" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
+ <button class="btn btn-success" id="edit_selected" data-id="editresource" data-item="<?=htmlspecialchars($result['name']);?>" data-api-url='edit/resource' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
@@ -501,11 +531,10 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
if (!empty($result)) {
?>
<h4><?=$lang['edit']['syncjob'];?></h4>
- <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+ <form class="form-horizontal" data-id="editsyncjob" role="form" method="post">
<input type="hidden" value="0" name="delete2duplicates">
<input type="hidden" value="0" name="delete1">
<input type="hidden" value="0" name="active">
- <input type="hidden" name="id" value="<?=htmlspecialchars($result['id']);?>">
<div class="form-group">
<label class="control-label col-sm-2" for="host1"><?=$lang['edit']['hostname'];?></label>
<div class="col-sm-10">
@@ -587,7 +616,7 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
- <button type="submit" name="edit_syncjob" value="1" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button>
+ <button class="btn btn-success" id="edit_selected" data-id="editsyncjob" data-item="<?=htmlspecialchars($result['id']);?>" data-api-url='edit/syncjob' data-api-attr='{}' href="#"><?=$lang['edit']['save'];?></button>
</div>
</div>
</form>
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 @@
+<?php
+
+function domain_admin($_action, $_data = null) {
+ global $pdo;
+ global $lang;
+ switch ($_action) {
+ case 'add':
+ $username = strtolower(trim($_data['username']));
+ $password = $_data['password'];
+ $password2 = $_data['password2'];
+ $domains = (array)$_data['domains'];
+ $active = intval($_data['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) {
+ 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'];
- }
- }
- else {
- $username = $_SESSION['mailcow_cc_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;
}
- $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 @@
<?php
// Start session
ini_set("session.cookie_httponly", 1);
+ini_set('session.gc_maxlifetime', $SESSION_LIFETIME);
+
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == "https") {
ini_set("session.cookie_secure", 1);
diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php
index 4fd207cf..34c1e14f 100644
--- a/data/web/inc/triggers.inc.php
+++ b/data/web/inc/triggers.inc.php
@@ -54,53 +54,12 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi
}
}
}
-if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user") {
- if (isset($_POST["edit_user_account"])) {
- edit_user_account($_POST);
- }
- if (isset($_POST["edit_syncjob"])) {
- mailbox('edit', 'syncjob', $_POST);
- }
-}
if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "admin" || $_SESSION['mailcow_cc_role'] == "domainadmin")) {
- if (isset($_POST["edit_domain_admin"])) {
- edit_domain_admin($_POST);
- }
if (isset($_POST["set_tfa"])) {
set_tfa($_POST);
}
if (isset($_POST["unset_tfa_key"])) {
unset_tfa_key($_POST);
}
- if (isset($_POST["mailbox_edit_alias"])) {
- mailbox('edit', 'alias', $_POST);
- }
- if (isset($_POST["mailbox_edit_domain"])) {
- mailbox('edit', 'domain', $_POST);
- }
- if (isset($_POST["mailbox_edit_mailbox"])) {
- mailbox('edit', 'mailbox', $_POST);
- }
- if (isset($_POST["mailbox_edit_alias_domain"])) {
- mailbox('edit', 'alias_domain', $_POST);
- }
- if (isset($_POST["mailbox_edit_resource"])) {
- mailbox('edit', 'resource', $_POST);
- }
- if (isset($_POST["mailbox_delete_domain"])) {
- mailbox('delete', 'domain', $_POST);
- }
- if (isset($_POST["mailbox_delete_alias"])) {
- mailbox('delete', 'delete_alias', $_POST);
- }
- if (isset($_POST["mailbox_delete_alias_domain"])) {
- mailbox('delete', 'alias_domain', $_POST);
- }
- if (isset($_POST["mailbox_delete_mailbox"])) {
- mailbox('delete', 'mailbox', $_POST);
- }
- if (isset($_POST["mailbox_delete_resource"])) {
- mailbox('delete', 'resource', $_POST);
- }
}
?>
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']);
+ 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 {
- echo json_encode(array(
- 'type' => 'success',
- 'msg' => 'Task completed'
- ));
+ 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'
- ));
+ 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
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
- <form class="form-horizontal" role="form" method="post" autocomplete="off">
+ <form class="form-horizontal" data-id="pwchange" role="form" method="post" autocomplete="off">
<div class="form-group">
<label class="control-label col-sm-3" for="user_new_pass"><?=$lang['user']['new_password'];?></label>
<div class="col-sm-5">
@@ -380,7 +380,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "use
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
- <button type="submit" name="edit_<?=($_SESSION['mailcow_cc_role'] == "domainadmin") ? "domain_admin" : "user_account";?>" class="btn btn-sm btn-success"><?=$lang['user']['change_password'];?></button>
+ <button class="btn btn-default" id="edit_selected" data-id="pwchange" data-item="null" data-api-url='edit/self' data-api-attr='{}' href="#"><?=$lang['user']['change_password'];?></button>
</div>
</div>
</form>