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/conf/phpfpm/crons/ldap-sync.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
3
require_once(__DIR__ . '/../web/inc/vars.inc.php');
4
if (file_exists(__DIR__ . '/../web/inc/vars.local.inc.php')) {
5
include_once(__DIR__ . '/../web/inc/vars.local.inc.php');
6
}
7
require_once __DIR__ . '/../web/inc/lib/vendor/autoload.php';
9
// Init database
10
//$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name;
11
$dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name;
12
$opt = [
13
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
14
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
15
PDO::ATTR_EMULATE_PREPARES => false,
16
];
17
try {
18
$pdo = new PDO($dsn, $database_user, $database_pass, $opt);
19
}
20
catch (PDOException $e) {
21
logMsg("err", $e->getMessage());
22
session_destroy();
23
exit;
24
}
26
// Init Redis
27
$redis = new Redis();
28
try {
29
if (!empty(getenv('REDIS_SLAVEOF_IP'))) {
30
$redis->connect(getenv('REDIS_SLAVEOF_IP'), getenv('REDIS_SLAVEOF_PORT'));
31
}
32
else {
33
$redis->connect('redis-mailcow', 6379);
34
}
35
$redis->auth(getenv("REDISPASS"));
36
}
37
catch (Exception $e) {
38
echo "Exiting: " . $e->getMessage();
39
session_destroy();
40
exit;
41
}
43
function logMsg($priority, $message, $task = "LDAP Sync") {
44
global $redis;
46
$finalMsg = array(
47
"time" => time(),
48
"priority" => $priority,
49
"task" => $task,
50
"message" => $message
51
);
52
$redis->lPush('CRON_LOG', json_encode($finalMsg));
53
}
55
// Load core functions first
56
require_once __DIR__ . '/../web/inc/functions.inc.php';
57
require_once __DIR__ . '/../web/inc/functions.auth.inc.php';
58
require_once __DIR__ . '/../web/inc/sessions.inc.php';
59
require_once __DIR__ . '/../web/inc/functions.mailbox.inc.php';
60
require_once __DIR__ . '/../web/inc/functions.ratelimit.inc.php';
61
require_once __DIR__ . '/../web/inc/functions.acl.inc.php';
63
$_SESSION['mailcow_cc_username'] = "admin";
64
$_SESSION['mailcow_cc_role'] = "admin";
65
$_SESSION['acl']['tls_policy'] = "1";
66
$_SESSION['acl']['quarantine_notification'] = "1";
67
$_SESSION['acl']['quarantine_category'] = "1";
68
$_SESSION['acl']['ratelimit'] = "1";
69
$_SESSION['acl']['sogo_access'] = "1";
70
$_SESSION['acl']['protocol_access'] = "1";
71
$_SESSION['acl']['mailbox_relayhost'] = "1";
72
$_SESSION['acl']['unlimited_quota'] = "1";
74
$iam_settings = identity_provider('get');
75
if ($iam_settings['authsource'] != "ldap" || (intval($iam_settings['periodic_sync']) != 1 && intval($iam_settings['import_users']) != 1)) {
76
session_destroy();
77
exit;
78
}
80
// Set pagination variables
81
$start = 0;
82
$max = 100;
84
// lock sync if already running
85
$lock_file = '/tmp/iam-sync.lock';
86
if (file_exists($lock_file)) {
87
$lock_file_parts = explode("\n", file_get_contents($lock_file));
88
$pid = $lock_file_parts[0];
89
if (count($lock_file_parts) > 1){
90
$last_execution = $lock_file_parts[1];
91
$elapsed_time = (time() - $last_execution) / 60;
92
if ($elapsed_time < intval($iam_settings['sync_interval'])) {
93
logMsg("warning", "Sync not ready (".number_format((float)$elapsed_time, 2, '.', '')."min / ".$iam_settings['sync_interval']."min)");
94
session_destroy();
95
exit;
96
}
97
}
99
if (posix_kill($pid, 0)) {
100
logMsg("warning", "Sync is already running");
101
session_destroy();
102
exit;
103
} else {
104
unlink($lock_file);
105
}
106
}
107
$lock_file_handle = fopen($lock_file, 'w');
108
fwrite($lock_file_handle, getmypid());
109
fclose($lock_file_handle);
111
// Init Provider
112
$iam_provider = identity_provider('init');
114
// Get ldap users
115
$ldap_query = $iam_provider->query();
116
if (!empty($iam_settings['filter'])) {
117
$ldap_query = $ldap_query->rawFilter($iam_settings['filter']);
118
}
119
$response = $ldap_query->where($iam_settings['username_field'], "*")
120
->where($iam_settings['attribute_field'], "*")
121
->select([$iam_settings['username_field'], $iam_settings['attribute_field'], 'displayname'])
122
->paginate($max);
124
// Process the users
125
foreach ($response as $user) {
126
// try get mailbox user
127
$stmt = $pdo->prepare("SELECT
128
mailbox.*,
129
domain.active AS d_active
130
FROM `mailbox`
131
INNER JOIN domain on mailbox.domain = domain.domain
132
WHERE `kind` NOT REGEXP 'location|thing|group'
133
AND `username` = :user");
134
$stmt->execute(array(':user' => $user[$iam_settings['username_field']][0]));
135
$row = $stmt->fetch(PDO::FETCH_ASSOC);
137
// check if matching attribute mapping exists
138
$user_template = $user[$iam_settings['attribute_field']][0];
139
$mapper_key = array_search($user_template, $iam_settings['mappers']);
141
if (empty($user[$iam_settings['username_field']][0])){
142
logMsg("warning", "Skipping user " . $user['displayname'][0] . " due to empty LDAP ". $iam_settings['username_field'] . " property.");
143
continue;
144
}
146
$_SESSION['access_all_exception'] = '1';
147
if (!$row && intval($iam_settings['import_users']) == 1){
148
if ($mapper_key === false){
149
if (!empty($iam_settings['default_template'])) {
150
$mbox_template = $iam_settings['default_template'];
151
} else {
152
logMsg("warning", "No matching attribute mapping found for user " . $user[$iam_settings['username_field']][0]);
153
continue;
154
}
155
} else {
156
$mbox_template = $iam_settings['templates'][$mapper_key];
157
}
158
// mailbox user does not exist, create...
159
logMsg("info", "Creating user " . $user[$iam_settings['username_field']][0]);
160
$create_res = mailbox('add', 'mailbox_from_template', array(
161
'domain' => explode('@', $user[$iam_settings['username_field']][0])[1],
162
'local_part' => explode('@', $user[$iam_settings['username_field']][0])[0],
163
'name' => $user['displayname'][0],
164
'authsource' => 'ldap',
165
'template' => $mbox_template
166
));
167
if (!$create_res){
168
logMsg("err", "Could not create user " . $user[$iam_settings['username_field']][0]);
169
continue;
170
}
171
} else if ($row && intval($iam_settings['periodic_sync']) == 1 && $row['authsource'] == "ldap") {
172
if ($mapper_key === false){
173
logMsg("warning", "No matching attribute mapping found for user " . $user[$iam_settings['username_field']][0]);
174
continue;
175
}
176
$mbox_template = $iam_settings['templates'][$mapper_key];
177
// mailbox user does exist, sync attribtues...
178
logMsg("info", "Syncing attributes for user " . $user[$iam_settings['username_field']][0]);
179
mailbox('edit', 'mailbox_from_template', array(
180
'username' => $user[$iam_settings['username_field']][0],
181
'name' => $user['displayname'][0],
182
'template' => $mbox_template
183
));
184
} else {
185
// skip mailbox user
186
logMsg("info", "Skipping user " . $user[$iam_settings['username_field']][0]);
187
}
188
$_SESSION['access_all_exception'] = '0';
190
sleep(0.025);
191
}
193
logMsg("info", "DONE!");
194
// add last execution time to lock file
195
$lock_file_handle = fopen($lock_file, 'w');
196
fwrite($lock_file_handle, getmypid() . "\n" . time());
197
fclose($lock_file_handle);
198
session_destroy();