651 lines
28 KiB
PHP
651 lines
28 KiB
PHP
<?php
|
|
|
|
use ProcessMaker\Model\RbacAuthenticationSource;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use ProcessMaker\BusinessModel\User;
|
|
use ProcessMaker\Model\Department;
|
|
use ProcessMaker\Model\Groupwf;
|
|
|
|
class LdapSource
|
|
{
|
|
public $authSourceUid;
|
|
public $ldapcnn = null;
|
|
public $terminatedOu;
|
|
|
|
private $arrayObjectClassFilter = [
|
|
"user" => "|(objectclass=inetorgperson)(objectclass=organizationalperson)(objectclass=person)(objectclass=user)",
|
|
"group" => "|(objectclass=posixgroup)(objectclass=group)(objectclass=groupofuniquenames)",
|
|
"department" => "|(objectclass=organizationalunit)"
|
|
];
|
|
private $arrayAttributes = [
|
|
"ldap" => ["uid" => "uid", "member" => "memberuid"], //OpenLDAP
|
|
"ad" => ["uid" => "samaccountname", "member" => "member"], //Active Directory
|
|
"ds" => ["uid" => "uid", "member" => "uniquemember"] //389 DS
|
|
];
|
|
|
|
private $arrayAttributesForUser = ["dn", "uid", "samaccountname", "givenname", "sn", "cn", "mail", "userprincipalname", "useraccountcontrol", "accountexpires", "manager"];
|
|
|
|
public function __destruct() {
|
|
if ($this->ldapcnn) {
|
|
@ldap_close($this->ldapcnn);
|
|
}
|
|
}
|
|
|
|
public function ldapConnection($authSourceData) {
|
|
// Removing sensitive data
|
|
$loggableAuthSource = $authSourceData;
|
|
unset($loggableAuthSource['AUTH_SOURCE_PASSWORD']);
|
|
|
|
$ldapcnn = ldap_connect($authSourceData['AUTH_SOURCE_SERVER_NAME'], $authSourceData['AUTH_SOURCE_PORT']);
|
|
$this->stdLog($ldapcnn, 'ldap_connect', $loggableAuthSource);
|
|
|
|
$ldapServer = $authSourceData['AUTH_SOURCE_SERVER_NAME'] . ':' . $authSourceData['AUTH_SOURCE_PORT'];
|
|
|
|
ldap_set_option($ldapcnn, LDAP_OPT_PROTOCOL_VERSION, 3);
|
|
$this->stdLog($ldapcnn, 'ldap_set_option', $loggableAuthSource);
|
|
ldap_set_option($ldapcnn, LDAP_OPT_REFERRALS, 0);
|
|
$this->stdLog($ldapcnn, 'ldap_set_option', $loggableAuthSource);
|
|
|
|
$resultLDAPStartTLS = true;
|
|
if (isset($authSourceData['AUTH_SOURCE_ENABLED_TLS']) && $authSourceData['AUTH_SOURCE_ENABLED_TLS']) {
|
|
$resultLDAPStartTLS = @ldap_start_tls($ldapcnn);
|
|
$this->stdLog($ldapcnn, 'ldap_start_tls', $loggableAuthSource);
|
|
$ldapServer = 'TLS ' . $ldapServer;
|
|
}
|
|
|
|
if ($authSourceData['AUTH_ANONYMOUS'] == '1') {
|
|
$bBind = ldap_bind($ldapcnn);
|
|
$this->log($ldapcnn, 'bind $ldapServer like anonymous user');
|
|
} else {
|
|
$bBind = ldap_bind($ldapcnn, $authSourceData['AUTH_SOURCE_SEARCH_USER'], $authSourceData['AUTH_SOURCE_PASSWORD']);
|
|
$this->log($ldapcnn, 'bind $ldapServer with user ' . $loggableAuthSource['AUTH_SOURCE_SEARCH_USER']);
|
|
}
|
|
$this->stdLog($ldapcnn, 'ldap_bind', $loggableAuthSource);
|
|
$this->getDiagnosticMessage($ldapcnn);
|
|
if (!$bBind) {
|
|
$message = 'Unable to bind to server: ' . $ldapServer . 'LDAP-Errno: ' . ldap_errno($ldapcnn) . ' : ' . ldap_error($ldapcnn) . " \n";
|
|
throw new Exception($message);
|
|
}
|
|
$this->ldapcnn = $ldapcnn;
|
|
return ['connection' =>$ldapcnn, 'startTLS' => $resultLDAPStartTLS];
|
|
}
|
|
|
|
public function searchGroups() {
|
|
try {
|
|
$arrayGroup = [];
|
|
|
|
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $this->authSourceUid]];
|
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
|
$authenticationSourceData = $authSourceReturn['data'][0];
|
|
$authenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($authenticationSourceData['AUTH_SOURCE_DATA'], true);
|
|
$authenticationSourceData['AUTH_SOURCE_PASSWORD'] = G::decrypt($authenticationSourceData['AUTH_SOURCE_PASSWORD'], URL_KEY);
|
|
|
|
if (is_null($this->ldapcnn)) {
|
|
$ldapcnn = $this->ldapConnection($authenticationSourceData);
|
|
$this->ldapcnn = $ldapcnn['connection'];
|
|
}
|
|
|
|
$ldapcnn = $this->ldapcnn;
|
|
// Get Groups
|
|
$limit = $this->getPageSizeLimitByData($authenticationSourceData);
|
|
$flagError = false;
|
|
$filter = '(' . $this->arrayObjectClassFilter['group'] . ')';
|
|
$this->log($ldapcnn, 'search groups with Filter: ' . $filter);
|
|
|
|
$cookie = '';
|
|
do {
|
|
$searchResult = @ldap_search(
|
|
$ldapcnn,
|
|
$authenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
|
$filter,
|
|
['dn', 'cn'],
|
|
0,
|
|
-1,
|
|
-1,
|
|
LDAP_DEREF_NEVER,
|
|
[['oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => ['size' => $limit, 'cookie' => $cookie]]]
|
|
);
|
|
ldap_parse_result($ldapcnn, $searchResult, $errcode, $matcheddn, $errmsg, $referrals, $controls);
|
|
$this->stdLog($ldapcnn, "ldap_search", ["filter" => $filter, "attributes" => ['dn', 'cn']]);
|
|
|
|
$context = [
|
|
"baseDN" => $authenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
|
"filter" => $filter,
|
|
"attributes" => ['dn', 'cn']
|
|
];
|
|
$this->stdLog($ldapcnn, "ldap_search", $context);
|
|
|
|
if ($error = ldap_errno($ldapcnn)) {
|
|
$this->log($ldapcnn, 'Error in Search');
|
|
|
|
$flagError = true;
|
|
} else {
|
|
if ($searchResult) {
|
|
//Get groups from the ldap entries
|
|
$countEntries = ldap_count_entries($ldapcnn, $searchResult);
|
|
$this->stdLog($ldapcnn, "ldap_count_entries");
|
|
|
|
if ($countEntries > 0) {
|
|
$entry = ldap_first_entry($ldapcnn, $searchResult);
|
|
$this->stdLog($ldapcnn, "ldap_first_entry");
|
|
|
|
do {
|
|
$arrayEntryData = $this->ldapGetAttributes($ldapcnn, $entry);
|
|
|
|
if (isset($arrayEntryData['cn']) && !is_array($arrayEntryData['cn'])) {
|
|
$arrayGroup[] = [
|
|
'dn' => $arrayEntryData['dn'],
|
|
'cn' => trim($arrayEntryData['cn']),
|
|
'users' => 0,
|
|
];
|
|
}
|
|
} while ($entry = ldap_next_entry($ldapcnn, $entry));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$flagError) {
|
|
if (isset($controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
|
|
// You need to pass the cookie from the last call to the next one
|
|
$cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'];
|
|
} else {
|
|
$cookie = '';
|
|
}
|
|
}
|
|
// Empty cookie means last page
|
|
} while (!empty($cookie) && !$flagError);
|
|
|
|
$str = '';
|
|
|
|
foreach ($arrayGroup as $group) {
|
|
$str .= ' ' . $group['cn'];
|
|
}
|
|
|
|
$this->log($ldapcnn, 'found ' . count($arrayGroup) . ' groups: ' . $str);
|
|
return $arrayGroup;
|
|
} catch (Exception $e) {
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function searchDepartments() {
|
|
try {
|
|
$arrayDepartment = [];
|
|
|
|
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $this->authSourceUid]];
|
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
|
$authenticationSourceData = $authSourceReturn['data'][0];
|
|
$authenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($authenticationSourceData['AUTH_SOURCE_DATA'], true);
|
|
$authenticationSourceData['AUTH_SOURCE_PASSWORD'] = G::decrypt($authenticationSourceData['AUTH_SOURCE_PASSWORD'], URL_KEY);
|
|
|
|
if (is_null($this->ldapcnn)) {
|
|
$ldapcnn = $this->ldapConnection($authenticationSourceData);
|
|
$this->ldapcnn = $ldapcnn['connection'];
|
|
}
|
|
$this->terminatedOu = $attributes['AUTH_SOURCE_RETIRED_OU'] ?? '';
|
|
$ldapcnn = $this->ldapcnn;
|
|
|
|
//Get Departments
|
|
$limit = $this->getPageSizeLimitByData($authenticationSourceData);
|
|
$flagError = false;
|
|
$filter = '(' . $this->arrayObjectClassFilter['department'] . ')';
|
|
$this->log($ldapcnn, 'search Departments with Filter: ' . $filter);
|
|
$unitsBase = $this->custom_ldap_explode_dn($authenticationSourceData['AUTH_SOURCE_BASE_DN']);
|
|
|
|
$cookie = '';
|
|
do {
|
|
$searchResult = @ldap_search(
|
|
$ldapcnn,
|
|
$authenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
|
$filter,
|
|
['dn', 'ou'],
|
|
0,
|
|
-1,
|
|
-1,
|
|
LDAP_DEREF_NEVER,
|
|
[['oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => ['size' => $limit, 'cookie' => $cookie]]]
|
|
);
|
|
ldap_parse_result($ldapcnn, $searchResult, $errcode, $matcheddn, $errmsg, $referrals, $controls);
|
|
$this->stdLog($ldapcnn, "ldap_search", ["filter" => $filter, "attributes" => ['dn', 'ou']]);
|
|
|
|
$context = [
|
|
"baseDN" => $authenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
|
"filter" => $filter,
|
|
"attributes" => ['dn', 'ou']
|
|
];
|
|
$this->stdLog($ldapcnn, "ldap_search", $context);
|
|
|
|
if ($error = ldap_errno($ldapcnn)) {
|
|
$this->log($ldapcnn, 'Error in Search');
|
|
|
|
$flagError = true;
|
|
} else {
|
|
if ($searchResult) {
|
|
//The first node is root
|
|
if (empty($arrayDepartment)) {
|
|
$arrayDepartment[] = [
|
|
'dn' => $authenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
|
'parent' => '',
|
|
'ou' => 'ROOT',
|
|
'users' => 0
|
|
];
|
|
}
|
|
|
|
//Get departments from the ldap entries
|
|
if (ldap_count_entries($ldapcnn, $searchResult) > 0) {
|
|
$this->stdLog($ldapcnn, "ldap_count_entries");
|
|
$entry = ldap_first_entry($ldapcnn, $searchResult);
|
|
$this->stdLog($ldapcnn, "ldap_first_entry", $context);
|
|
|
|
do {
|
|
$arrayEntryData = $this->ldapGetAttributes($ldapcnn, $entry);
|
|
$unitsEqual = $this->custom_ldap_explode_dn($arrayEntryData['dn']);
|
|
|
|
if (count($unitsEqual) == 1 && $unitsEqual[0] == '') {
|
|
continue;
|
|
}
|
|
|
|
if (count($unitsEqual) > count($unitsBase)) {
|
|
unset($unitsEqual[0]);
|
|
}
|
|
|
|
if (isset($arrayEntryData['ou']) && !is_array($arrayEntryData['ou'])) {
|
|
$arrayDepartment[] = [
|
|
'dn' => $arrayEntryData['dn'],
|
|
'parent' => (isset($unitsEqual[1])) ? implode(',', $unitsEqual) : '',
|
|
'ou' => trim($arrayEntryData['ou']),
|
|
'users' => 0
|
|
];
|
|
}
|
|
} while ($entry = ldap_next_entry($ldapcnn, $entry));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!$flagError) {
|
|
if (isset($controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
|
|
// You need to pass the cookie from the last call to the next one
|
|
$cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'];
|
|
} else {
|
|
$cookie = '';
|
|
}
|
|
}
|
|
// Empty cookie means last page
|
|
} while (!empty($cookie) && !$flagError);
|
|
|
|
$str = '';
|
|
|
|
foreach ($arrayDepartment as $dep) {
|
|
$str .= ' ' . $dep['ou'];
|
|
}
|
|
|
|
$this->log($ldapcnn, 'found ' . count($arrayDepartment) . ' departments: ' . $str);
|
|
return $arrayDepartment;
|
|
} catch (Exception $e) {
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function getPageSizeLimit($ldapcnn, $baseDn = '')
|
|
{
|
|
try {
|
|
$limit = 1000;
|
|
|
|
if ($ldapcnn === false) {
|
|
return $limit;
|
|
}
|
|
|
|
$searchResult = @ldap_search($ldapcnn, $baseDn, '(|(objectclass=*))', ['dn']);
|
|
$context = [
|
|
'baseDN' => $baseDn,
|
|
'filter' => '(|(objectclass=*))',
|
|
'attributes' => ['dn']
|
|
];
|
|
$this->stdLog($ldapcnn, 'ldap_search', $context);
|
|
|
|
if ($searchResult) {
|
|
$countEntries = ldap_count_entries($ldapcnn, $searchResult);
|
|
$this->stdLog($ldapcnn, 'ldap_count_entries');
|
|
|
|
if ($countEntries > 0) {
|
|
$limit = ($countEntries > $limit) ? $limit : $countEntries;
|
|
}
|
|
}
|
|
|
|
return $limit;
|
|
} catch (Exception $e) {
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function getDiagnosticMessage($linkIdentifier)
|
|
{
|
|
//specific message
|
|
$keysError = [
|
|
[
|
|
'key' => 'USER_NOT_FOUND',
|
|
'code' => 525,
|
|
'message' => G::LoadTranslation('ID_LDAP_USER_NOT_FOUND_INVALID'),
|
|
], [
|
|
'key' => 'NOT_PERMITTED_TO_LOGON_AT_THIS_TIME',
|
|
'code' => 530,
|
|
'message' => G::LoadTranslation('ID_LDAP_NOT_PERMITTED_TO_LOGON_AT_THIS_TIME'),
|
|
], [
|
|
'key' => 'RESTRICTED_TO_SPECIFIC_MACHINES',
|
|
'code' => 531,
|
|
'message' => G::LoadTranslation('ID_LDAP_RESTRICTED_TO_SPECIFIC_MACHINES'),
|
|
], [
|
|
'key' => 'PASSWORD_EXPIRED',
|
|
'code' => 532,
|
|
'message' => G::LoadTranslation('ID_LDAP_PASSWORD_EXPIRED'),
|
|
], [
|
|
'key' => 'ACCOUNT_DISABLED',
|
|
'code' => 533,
|
|
'message' => G::LoadTranslation('ID_LDAP_ACCOUNT_DISABLED'),
|
|
], [
|
|
'key' => 'ACCOUNT_EXPIRED',
|
|
'code' => 701,
|
|
'message' => G::LoadTranslation('ID_LDAP_ACCOUNT_EXPIRED'),
|
|
], [
|
|
'key' => 'USER_MUST_RESET_PASSWORD',
|
|
'code' => 773,
|
|
'message' => G::LoadTranslation('ID_LDAP_USER_MUST_RESET_PASSWORD'),
|
|
]
|
|
];
|
|
$message = '';
|
|
ldap_get_option($linkIdentifier, LDAP_OPT_DIAGNOSTIC_MESSAGE, $messageError);
|
|
$this->stdLog($linkIdentifier, 'ldap_get_option', ['error' => $messageError]);
|
|
foreach ($keysError as $key => $value) {
|
|
if (strpos($messageError, (string) $value['code']) !== false) {
|
|
$message = $value['message'];
|
|
break;
|
|
}
|
|
}
|
|
//standard message
|
|
if (empty($message)) {
|
|
$errorNumber = ldap_errno($linkIdentifier);
|
|
$message = ldap_err2str($errorNumber) . '.';
|
|
}
|
|
if (empty($message)) {
|
|
$message = G::LoadTranslation('ID_LDAP_ERROR_CONNECTION');
|
|
}
|
|
Cache::put('ldapMessageError', $message, 120); //laravel 8.x the time parameter is in seconds.
|
|
$this->log($linkIdentifier, $messageError);
|
|
}
|
|
|
|
private function log($link, $text)
|
|
{
|
|
$logFile = PATH_DATA . 'logs/ldap.log';
|
|
|
|
if (!file_exists($logFile)) {
|
|
file_put_contents($logFile, "Start\n");
|
|
@chmod($logFile, 0644);
|
|
}
|
|
|
|
if (!is_writable($logFile)) {
|
|
error_log('Log file is not writable: ' . $logFile);
|
|
throw new Exception('Log file is not writable: ' . $logFile);
|
|
}
|
|
|
|
$fpt = fopen($logFile, 'a');
|
|
$ldapErrorMsg = '';
|
|
$ldapErrorNr = 0;
|
|
|
|
if ($link != null) {
|
|
$ldapErrorNr = ldap_errno($link);
|
|
|
|
if ($ldapErrorNr != 0) {
|
|
$ldapErrorMsg = ldap_error($link);
|
|
$text = $ldapErrorMsg . ' : ' . $text;
|
|
}
|
|
}
|
|
|
|
// Log format: date hour ipaddress workspace ldapErrorNr
|
|
fwrite($fpt, sprintf("%s %s %s %s %s \n", date('Y-m-d H:i:s'), getenv('REMOTE_ADDR'), config('system.workspace'), $ldapErrorNr, $text));
|
|
fclose($fpt);
|
|
}
|
|
|
|
private function stdLog($link, $message = "", $context = [], $level = "info")
|
|
{
|
|
try {
|
|
if (empty($link)) {
|
|
switch ($level) {
|
|
case "error":
|
|
Log::channel(':ldapAdvanced')->error($message, Bootstrap::context($context));
|
|
break;
|
|
case "info":
|
|
default:
|
|
Log::channel(':ldapAdvanced')->info($message, Bootstrap::context($context));
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
$code = ldap_errno($link);
|
|
$detail = ldap_err2str($code);
|
|
$context["detail"] = $detail;
|
|
if ($code === 0) {
|
|
Log::channel(':ldapAdvanced')->info($message, Bootstrap::context($context));
|
|
} else {
|
|
Log::channel(':ldapAdvanced')->error($message, Bootstrap::context($context));
|
|
}
|
|
} catch (Exception $exception) {
|
|
return ['success' => false, 'message' => $exception->getMessage()];
|
|
}
|
|
}
|
|
|
|
|
|
public function searchUsersLdap($keyword, $start = null, $limit = null) {
|
|
$arrayUser = [];
|
|
$totalUser = 0;
|
|
$countUser = 0;
|
|
|
|
$paged = !is_null($start) && !is_null($limit);
|
|
|
|
$filters = [
|
|
'conditions' => ['AUTH_SOURCE_UID' => $this->authSourceUid],
|
|
];
|
|
$rbacAuthenticationSource = new RbacAuthenticationSource();
|
|
$authSourceReturn = $rbacAuthenticationSource->show($filters);
|
|
$arrayAuthenticationSourceData = $authSourceReturn['data'][0];
|
|
$arrayAuthenticationSourceData['AUTH_SOURCE_DATA'] = json_decode($arrayAuthenticationSourceData['AUTH_SOURCE_DATA'], true);
|
|
$arrayAuthenticationSourceData['AUTH_SOURCE_PASSWORD'] = G::decrypt($arrayAuthenticationSourceData['AUTH_SOURCE_PASSWORD'], URL_KEY);
|
|
|
|
$attributeUserSet = [];
|
|
$attributeSetAdd = [];
|
|
|
|
if (
|
|
isset($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE']) && !empty($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'])
|
|
) {
|
|
foreach ($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'] as $value) {
|
|
$attributeSetAdd[] = $value['attributeLdap'];
|
|
$attributeUserSet[$value['attributeUser']] = $value['attributeLdap'];
|
|
}
|
|
}
|
|
|
|
$ldapcnn = $this->ldapConnection($arrayAuthenticationSourceData);
|
|
$ldapcnn = $ldapcnn['connection'];
|
|
|
|
//Get Users
|
|
if (!isset($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_USERS_FILTER'])) {
|
|
$arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_USERS_FILTER'] = '';
|
|
}
|
|
|
|
$uidUserIdentifier = (isset($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_IDENTIFIER_FOR_USER'])) ? $arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_IDENTIFIER_FOR_USER'] : 'uid';
|
|
$filterUsers = trim($arrayAuthenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_USERS_FILTER']);
|
|
$filter = ($filterUsers != '') ? $filterUsers : '(' . $this->arrayObjectClassFilter['user'] . ')';
|
|
$filter = "(&$filter(|(dn=$keyword)(uid=$keyword)(samaccountname=$keyword)(givenname=$keyword)(sn=$keyword)(cn=$keyword)(mail=$keyword)(userprincipalname=$keyword)))";
|
|
$oSearch = @ldap_search($ldapcnn, $arrayAuthenticationSourceData['AUTH_SOURCE_BASE_DN'], $filter, array_merge($this->arrayAttributesForUser, $attributeSetAdd));
|
|
$context = [
|
|
'baseDN' => $arrayAuthenticationSourceData['AUTH_SOURCE_BASE_DN'],
|
|
'filter' => $filter,
|
|
'attribute' => array_merge($this->arrayAttributesForUser, $attributeSetAdd)
|
|
];
|
|
$this->stdLog($ldapcnn, 'ldap_search', $context);
|
|
|
|
if ($oError = ldap_errno($ldapcnn)) {
|
|
$this->log($ldapcnn, 'Error in Search users');
|
|
} else {
|
|
if ($oSearch) {
|
|
$entries = ldap_count_entries($ldapcnn, $oSearch);
|
|
$this->stdLog($ldapcnn, 'ldap_count_entries');
|
|
$totalUser = $entries;
|
|
|
|
if ($entries > 0) {
|
|
$oEntry = ldap_first_entry($ldapcnn, $oSearch);
|
|
$this->stdLog($ldapcnn, 'ldap_first_entry');
|
|
$countEntries = 0;
|
|
$flagNextRecord = true;
|
|
|
|
do {
|
|
$aAttr = $this->ldapGetAttributes($ldapcnn, $oEntry);
|
|
$sUsername = (isset($aAttr[$uidUserIdentifier])) ? $aAttr[$uidUserIdentifier] : '';
|
|
|
|
if ((is_array($sUsername) && !empty($sUsername)) || trim($sUsername) != '') {
|
|
$countUser++;
|
|
$userCountControl = '';
|
|
//Active Directory, openLdap
|
|
if (isset($aAttr['useraccountcontrol'])) {
|
|
switch ($aAttr['useraccountcontrol']) {
|
|
case '512':
|
|
case '544':
|
|
case '66048':
|
|
case '66080':
|
|
$userCountControl = 'ACTIVE';
|
|
break;
|
|
case '514':
|
|
case '546':
|
|
case '66050':
|
|
case '66082':
|
|
case '2':
|
|
case '16':
|
|
case '8388608':
|
|
default:
|
|
$userCountControl = 'INACTIVE';
|
|
break;
|
|
}
|
|
}
|
|
//apache ldap
|
|
if (isset($aAttr['status'])) {
|
|
$userCountControl = strtoupper($aAttr['status']);
|
|
}
|
|
$aUserAttributes = [];
|
|
foreach ($attributeUserSet as $key => $value) {
|
|
if ($key == 'USR_STATUS') {
|
|
$aUserAttributes[$key] = ($userCountControl != '') ? $userCountControl : 'ACTIVE';
|
|
} elseif (isset($aAttr[$value])) {
|
|
$aUserAttributes[$key] = $aAttr[$value];
|
|
}
|
|
}
|
|
|
|
if ($paged) {
|
|
if ($countUser - 1 <= $start + $limit - 1) {
|
|
if ($start <= $countUser - 1) {
|
|
$arrayUser[] = array_merge($this->getUserDataFromAttribute($sUsername, $aAttr), $aUserAttributes);
|
|
}
|
|
} else {
|
|
$flagNextRecord = false;
|
|
}
|
|
} else {
|
|
$arrayUser[] = array_merge($this->getUserDataFromAttribute($sUsername, $aAttr), $aUserAttributes);
|
|
}
|
|
|
|
$countEntries++;
|
|
}
|
|
} while (($oEntry = ldap_next_entry($ldapcnn, $oEntry)) && $flagNextRecord);
|
|
}
|
|
}
|
|
}
|
|
return ($paged) ? ['numRecTotal' => $totalUser, 'data' => $arrayUser] : $arrayUser;
|
|
}
|
|
|
|
private function getUserDataFromAttribute($username, array $arrayAttributes)
|
|
{
|
|
try {
|
|
$keyMail = (isset($arrayAttributes['mail'])) ? 'mail' : ((isset($arrayAttributes['userprincipalname'])) ? 'userprincipalname' : 'nomail');
|
|
|
|
return [
|
|
'sUsername' => trim((is_array($username)) ? $username[0] : $username),
|
|
'sPassword' => trim((isset($arrayAttributes['userpassword'])) ? ((is_array($arrayAttributes['userpassword'])) ? $arrayAttributes['userpassword'][0] : $arrayAttributes['userpassword']) : ''),
|
|
'sFullname' => trim((isset($arrayAttributes['cn'])) ? ((is_array($arrayAttributes['cn'])) ? $arrayAttributes['cn'][0] : $arrayAttributes['cn']) : ''),
|
|
'sFirstname' => trim((isset($arrayAttributes['givenname'])) ? ((is_array($arrayAttributes['givenname'])) ? $arrayAttributes['givenname'][0] : $arrayAttributes['givenname']) : ''),
|
|
'sLastname' => trim((isset($arrayAttributes['sn'])) ? ((is_array($arrayAttributes['sn'])) ? $arrayAttributes['sn'][0] : $arrayAttributes['sn']) : ''),
|
|
'sEmail' => trim((isset($arrayAttributes[$keyMail])) ? ((is_array($arrayAttributes[$keyMail])) ? $arrayAttributes[$keyMail][0] : $arrayAttributes[$keyMail]) : ''),
|
|
'sDN' => trim($arrayAttributes['dn']),
|
|
'sManagerDN' => trim((isset($arrayAttributes['manager'])) ? ((is_array($arrayAttributes['manager'])) ? $arrayAttributes['manager'][0] : $arrayAttributes['manager']) : '')
|
|
];
|
|
} catch (Exception $e) {
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function getPageSizeLimitByData(array $arrayAuthSourceData)
|
|
{
|
|
if (isset($arrayAuthSourceData['AUTH_SOURCE_DATA']['LDAP_PAGE_SIZE_LIMIT'])) {
|
|
return $arrayAuthSourceData['AUTH_SOURCE_DATA']['LDAP_PAGE_SIZE_LIMIT'];
|
|
} else {
|
|
return $this->getPageSizeLimit(false);
|
|
}
|
|
}
|
|
|
|
private function ldapGetAttributes($ldapcnn, $entry)
|
|
{
|
|
try {
|
|
$arrayAttributes = [];
|
|
|
|
$arrayAttributes['dn'] = ldap_get_dn($ldapcnn, $entry);
|
|
$this->stdLog($ldapcnn, 'ldap_get_dn');
|
|
|
|
$arrayAux = ldap_get_attributes($ldapcnn, $entry);
|
|
$this->stdLog($ldapcnn, 'ldap_get_attributes');
|
|
|
|
for ($i = 0; $i <= $arrayAux['count'] - 1; $i++) {
|
|
$key = strtolower($arrayAux[$i]);
|
|
|
|
switch ($arrayAux[$arrayAux[$i]]['count']) {
|
|
case 0:
|
|
$arrayAttributes[$key] = '';
|
|
break;
|
|
case 1:
|
|
$arrayAttributes[$key] = $arrayAux[$arrayAux[$i]][0];
|
|
break;
|
|
default:
|
|
$arrayAttributes[$key] = $arrayAux[$arrayAux[$i]];
|
|
|
|
unset($arrayAttributes[$key]['count']);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isset($arrayAttributes['mail']) && isset($arrayAttributes['userprincipalname'])) {
|
|
$arrayAttributes['mail'] = $arrayAttributes['userprincipalname'];
|
|
}
|
|
|
|
return $arrayAttributes;
|
|
} catch (Exception $e) {
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
public function custom_ldap_explode_dn($dn)
|
|
{
|
|
$dn = trim($dn, ',');
|
|
$result = ldap_explode_dn($dn, 0);
|
|
$this->stdLog(null, "ldap_explode_dn", ["dn" => $dn]);
|
|
|
|
if (is_array($result)) {
|
|
unset($result['count']);
|
|
|
|
foreach ($result as $key => $value) {
|
|
$result[$key] = addcslashes(preg_replace_callback("/\\\([0-9A-Fa-f]{2})/", function ($m) {
|
|
return chr(hexdec($m[1]));
|
|
}, $value), '<>,"');
|
|
}
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
} |