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
Trace
data/web/inc/functions.acl.inc.php
Trace helps you understand code history line by line. See who changed each line, when it changed, and which commit introduced it.
Author
Date
Commit
Line
Code
1
<?php
2
function acl($_action, $_scope = null, $_data = null, $_extra = null) {
3
global $pdo;
4
global $lang;
5
$_data_log = $_data;
6
switch ($_action) {
7
case 'edit':
8
switch ($_scope) {
9
case 'user':
10
if (!is_array($_data['username'])) {
11
$usernames = array();
12
$usernames[] = $_data['username'];
13
}
14
else {
15
$usernames = $_data['username'];
16
}
17
foreach ($usernames as $username) {
18
// Cast to array for single selections
19
$acls = (array)$_data['user_acl'];
20
// Create associative array from index array
21
// All set items are given 1 as value
22
foreach ($acls as $acl_key => $acl_val) {
23
$acl_post[$acl_val] = 1;
24
}
25
// Users cannot change their own ACL
26
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)
27
|| ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin' && $_SESSION['access_all_exception'] != '1')) {
28
$_SESSION['return'][] = array(
29
'type' => 'danger',
30
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
31
'msg' => 'access_denied'
32
);
33
continue;
34
}
35
// Read all available acl options by calling acl(get)
36
// Set all available acl options we cannot find in the post data to 0, else 1
37
$is_now = acl('get', 'user', $username, $_extra);
38
if (!empty($is_now)) {
39
foreach ($is_now as $acl_now_name => $acl_now_val) {
40
$set_acls[$acl_now_name] = (isset($acl_post[$acl_now_name])) ? 1 : 0;
41
}
42
}
43
else {
44
$_SESSION['return'][] = array(
45
'type' => 'danger',
46
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
47
'msg' => 'Cannot determine current ACL'
48
);
49
continue;
50
}
51
foreach ($set_acls as $set_acl_key => $set_acl_val) {
52
$stmt = $pdo->prepare("UPDATE `user_acl` SET " . $set_acl_key . " = " . intval($set_acl_val) . "
53
WHERE `username` = :username");
54
$stmt->execute(array(
55
':username' => $username,
56
));
57
}
58
$_SESSION['return'][] = array(
59
'type' => 'success',
60
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
61
'msg' => array('acl_saved', $username)
62
);
63
}
64
break;
65
case 'domainadmin':
66
if ($_SESSION['mailcow_cc_role'] != 'admin') {
67
$_SESSION['return'][] = array(
68
'type' => 'danger',
69
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
70
'msg' => 'access_denied'
71
);
72
return false;
73
}
74
if (!is_array($_data['username'])) {
75
$usernames = array();
76
$usernames[] = $_data['username'];
77
}
78
else {
79
$usernames = $_data['username'];
80
}
81
foreach ($usernames as $username) {
82
// Cast to array for single selections
83
$acls = (array)$_data['da_acl'];
84
// Create associative array from index array
85
// All set items are given 1 as value
86
foreach ($acls as $acl_key => $acl_val) {
87
$acl_post[$acl_val] = 1;
88
}
89
// Users cannot change their own ACL
90
if ($_SESSION['mailcow_cc_role'] != 'admin') {
91
$_SESSION['return'][] = array(
92
'type' => 'danger',
93
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
94
'msg' => 'access_denied'
95
);
96
continue;
97
}
98
// Read all available acl options by calling acl(get)
99
// Set all available acl options we cannot find in the post data to 0, else 1
100
$is_now = acl('get', 'domainadmin', $username);
101
if (!empty($is_now)) {
102
foreach ($is_now as $acl_now_name => $acl_now_val) {
103
$set_acls[$acl_now_name] = (isset($acl_post[$acl_now_name])) ? 1 : 0;
104
}
105
}
106
else {
107
$_SESSION['return'][] = array(
108
'type' => 'danger',
109
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
110
'msg' => 'Cannot determine current ACL'
111
);
112
continue;
113
}
114
foreach ($set_acls as $set_acl_key => $set_acl_val) {
115
$stmt = $pdo->prepare("UPDATE `da_acl` SET " . $set_acl_key . " = " . intval($set_acl_val) . "
116
WHERE `username` = :username");
117
$stmt->execute(array(
118
':username' => $username,
119
));
120
}
121
$_SESSION['return'][] = array(
122
'type' => 'success',
123
'log' => array(__FUNCTION__, $_action, $_scope, $_data_log),
124
'msg' => array('acl_saved', $username)
125
);
126
}
127
break;
128
}
129
break;
130
case 'get':
131
switch ($_scope) {
132
case 'user':
133
if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) {
134
return false;
135
}
136
$stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");
137
$stmt->execute(array(':username' => $_data));
138
$data = $stmt->fetch(PDO::FETCH_ASSOC);
139
if ($_SESSION['mailcow_cc_role'] == 'domainadmin') {
140
// Domain admins cannot see, add or remove user ACLs they don't have access to by themselves
141
// Editing a user will use acl("get", "user") to determine granted ACLs and therefore block unallowed access escalation via form editing
142
$self_da_acl = acl('get', 'domainadmin', $_SESSION['mailcow_cc_username']);
143
foreach ($self_da_acl as $self_da_acl_key => $self_da_acl_val) {
144
if ($self_da_acl_val == 0) {
145
unset($data[$self_da_acl_key]);
146
}
147
}
148
}
149
if (!empty($data)) {
150
unset($data['username']);
151
return $data;
152
}
153
else {
154
return false;
155
}
156
break;
157
case 'domainadmin':
158
if ($_SESSION['mailcow_cc_role'] != 'admin' && $_SESSION['mailcow_cc_role'] != 'domainadmin') {
159
return false;
160
}
161
if ($_SESSION['mailcow_cc_role'] == 'domainadmin' && $_SESSION['mailcow_cc_username'] != $_data) {
162
return false;
163
}
164
$stmt = $pdo->prepare("SELECT * FROM `da_acl` WHERE `username` = :username");
165
$stmt->execute(array(':username' => $_data));
166
$data = $stmt->fetch(PDO::FETCH_ASSOC);
167
if (!empty($data)) {
168
unset($data['username']);
169
return $data;
170
}
171
else {
172
return false;
173
}
174
break;
175
}
176
break;
177
case 'to_session':
178
if (!isset($_SESSION['mailcow_cc_role'])) {
179
return false;
180
}
181
unset($_SESSION['acl']);
182
$username = strtolower(trim($_SESSION['mailcow_cc_username']));
183
// Admins get access to all modules
184
if ($_SESSION['mailcow_cc_role'] == 'admin' ||
185
(isset($_SESSION["dual-login"]["role"]) && $_SESSION["dual-login"]["role"] == 'admin')) {
186
$stmt = $pdo->query("SHOW COLUMNS FROM `user_acl` WHERE `Field` != 'username';");
187
$acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
188
while ($row = array_shift($acl_all)) {
189
$acl['acl'][$row['Field']] = 1;
190
}
191
$stmt = $pdo->query("SHOW COLUMNS FROM `da_acl` WHERE `Field` != 'username';");
192
$acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
193
while ($row = array_shift($acl_all)) {
194
$acl['acl'][$row['Field']] = 1;
195
}
196
}
197
elseif ($_SESSION['mailcow_cc_role'] == 'domainadmin' ||
198
(isset($_SESSION["dual-login"]["role"]) && $_SESSION["dual-login"]["role"] == 'domainadmin')) {
199
// Read all exting user_acl modules and set to 1
200
$stmt = $pdo->query("SHOW COLUMNS FROM `user_acl` WHERE `Field` != 'username';");
201
$acl_all = $stmt->fetchAll(PDO::FETCH_ASSOC);
202
while ($row = array_shift($acl_all)) {
203
$acl['acl'][$row['Field']] = 1;
204
}
205
// Read da_acl rules for current user, OVERWRITE overlapping modules
206
// This prevents access to a users sync jobs, when a domain admins was not given access to sync jobs
207
$stmt = $pdo->prepare("SELECT * FROM `da_acl` WHERE `username` = :username");
208
$stmt->execute(array(':username' => (isset($_SESSION["dual-login"]["username"])) ? $_SESSION["dual-login"]["username"] : $username));
209
$acl_user = $stmt->fetch(PDO::FETCH_ASSOC);
210
foreach ($acl_user as $acl_user_key => $acl_user_val) {
211
$acl['acl'][$acl_user_key] = $acl_user_val;
212
}
213
unset($acl['acl']['username']);
214
}
215
elseif ($_SESSION['mailcow_cc_role'] == 'user') {
216
$stmt = $pdo->prepare("SELECT * FROM `user_acl` WHERE `username` = :username");
217
$stmt->execute(array(':username' => $username));
218
$acl['acl'] = $stmt->fetch(PDO::FETCH_ASSOC);
219
unset($acl['acl']['username']);
220
}
221
if (!empty($acl)) {
222
$_SESSION = array_merge($_SESSION, $acl);
223
}
224
break;
225
}
226
}