TASK-221 Change the AUTH_SOURCE_DATA field from PHP-serialized format to a JSON-formatted string

This commit is contained in:
Brayan Pereyra
2025-09-16 16:03:55 +00:00
parent 8be70e0dc1
commit f908ff1346
5 changed files with 257 additions and 531 deletions

View File

@@ -1,83 +1,80 @@
<?php
use ProcessMaker\Model\RbacAuthenticationSource;
use ProcessMaker\Model\RbacUsers;
use ProcessMaker\Model\Configuration;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Cache;
class AuthSources
{
private $authSourceUid;
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 getListAuthSources($userUid, $start = 0, $limit = 0, $orderBy = '', $ascending = '' , $filter = '') {
public function getListAuthSources($userUid, $start = 0, $limit = 25, $orderBy = '', $ascending = 'asc' , $filter = '') {
try {
if ($limit == 0) {
$limit = $this->getConfigurationUser($userUid);
$limit = 25;
$filters = array(
'fields' => ['CFG_VALUE'],
'conditions' => ['CFG_UID' => 'authSourcesList', 'OBJ_UID' => 'pageSize', 'USR_UID' => $userUid]
);
$configuration = new Configuration();
$configurationReturn = $configuration->show($filters);
if ($configurationReturn['total'] > 0) {
$configValue = unserialize($configurationReturn['data'][0]['CFG_VALUE']);
$limit = $configValue['pageSize'] ?? $limit;
}
}
global $RBAC;
$criterias = $RBAC->getAuthenticationSources($start, $limit, $filter);
$dataSourceAuthentication = AuthenticationSourcePeer::doSelectRS($criterias['COUNTER']);
$dataSourceAuthentication->setFetchmode(ResultSet::FETCHMODE_ASSOC);
$dataSourceAuthentication->next();
$row = $dataSourceAuthentication->getRow();
$total_sources = $row['CNT'];
$filters = array(
'fields' => ['*'],
'start' => $start,
'limit'=> $limit
);
if (!empty($orderBy) && ($ascending !== '') && defined("AuthenticationSourcePeer::" . $orderBy)) {
if ($ascending === '1') {
$criterias['LIST']->addAscendingOrderByColumn(constant("AuthenticationSourcePeer::" . $orderBy));
if ($orderBy != '') {
if (!in_array($ascending, ['asc', 'desc'])) {
$ascending = 'asc';
}
if ($ascending === '0') {
$criterias['LIST']->addDescendingOrderByColumn(constant("AuthenticationSourcePeer::" . $orderBy));
}
} else {
$criterias['LIST']->addAscendingOrderByColumn(AuthenticationSourcePeer::AUTH_SOURCE_NAME);
$filters['orderBy'] = [$orderBy, $ascending];
}
$dataset = AuthenticationSourcePeer::doSelectRS($criterias['LIST']);
$dataset->setFetchmode(ResultSet::FETCHMODE_ASSOC);
if ($filter != '') {
$filters['conditions'] = ['text' => $filter];
}
$rbacAuthenticationSource = new RbacAuthenticationSource();
$authSourceReturn = $rbacAuthenticationSource->show($filters);
global $RBAC;
$auth = $RBAC->getAllUsersByAuthSource();
$sources = [];
while ($dataset->next()) {
$row = $dataset->getRow();
$values = explode("_", $row["AUTH_SOURCE_PASSWORD"]);
foreach ($authSourceReturn['data'] as $key => $authSourceRow) {
$values = explode('_', $authSourceRow['AUTH_SOURCE_PASSWORD']);
foreach ($values as $value) {
if ($value == "2NnV3ujj3w") {
$row["AUTH_SOURCE_PASSWORD"] = G::decrypt($values[0], $row["AUTH_SOURCE_SERVER_NAME"]);
if ($value == '2NnV3ujj3w') {
$authSourceRow['AUTH_SOURCE_PASSWORD'] = G::decrypt($values[0], $authSourceRow['AUTH_SOURCE_SERVER_NAME']);
}
}
$label = G::LoadTranslation('ID_DISABLE');
if ($row['AUTH_SOURCE_ENABLED_TLS'] === "1") {
if ($authSourceRow['AUTH_SOURCE_ENABLED_TLS'] === '1') {
$label = G::LoadTranslation('ID_ENABLE');
}
$row['AUTH_SOURCE_ENABLED_TLS_LABEL'] = $label;
$authSourceRow['AUTH_SOURCE_ENABLED_TLS_LABEL'] = $label;
//additional information
$authSourceData = unserialize($row['AUTH_SOURCE_DATA']);
$authSourceData = json_decode($authSourceRow['AUTH_SOURCE_DATA'], true);
if (is_array($authSourceData)) {
$row = array_merge($row, $authSourceData);
$authSourceRow = array_merge($authSourceRow, $authSourceData);
}
$sources[] = $row;
$authSourceRow['AUTH_ANONYMOUS'] = (string)$authSourceRow['AUTH_ANONYMOUS'];
$sources[] = $authSourceRow;
$index = sizeof($sources) - 1;
$sources[$index]['CURRENT_USERS'] = isset($auth[$sources[$index]['AUTH_SOURCE_UID']]) ? $auth[$sources[$index]['AUTH_SOURCE_UID']] : 0;
}
$response = [
'success' => true,
'sources' => $sources,
'total_sources' => $total_sources
'total_sources' => $authSourceReturn['total']
];
return $response;
} catch (Exception $exception) {
@@ -87,9 +84,10 @@ class AuthSources
public function removeAuthSource($authSourceUid) {
try {
global $RBAC;
$RBAC->removeAuthSource($authSourceUid);
return ['success' => true];
$conditions = ['AUTH_SOURCE_UID'=> $authSourceUid];
$rbacAuthenticationSource = new RbacAuthenticationSource();
$removeResponse = $rbacAuthenticationSource->remove($conditions);
return ['success' => true, 'deleteRows' => $removeResponse['deleteRows'] ];
} catch (Exception $exception) {
return ['success' => false, 'message' => $exception->getMessage()];
}
@@ -97,21 +95,24 @@ class AuthSources
public function verifyAuthSourceName($authSourceName) {
try {
$authenticationSource = RbacAuthenticationSource::query()
->select(['AUTH_SOURCE_UID', 'AUTH_SOURCE_NAME'])
->where('AUTH_SOURCE_NAME', '=', $authSourceName)
->first();
$row = false;
$suggestName = '';
if (!empty($authenticationSource)) {
$row = $authenticationSource;
$lastAuthenticationSource = RbacAuthenticationSource::query()
->select(['AUTH_SOURCE_NAME'])
->where('AUTH_SOURCE_NAME', 'LIKE', "%{$authSourceName}%")
->orderBy('AUTH_SOURCE_NAME', 'desc')
->first();
if (!empty($lastAuthenticationSource)) {
$name = $lastAuthenticationSource->AUTH_SOURCE_NAME;
$filters = [
'fields' => ['AUTH_SOURCE_UID', 'AUTH_SOURCE_NAME'],
'conditions' => ['AUTH_SOURCE_NAME' => $authSourceName]
];
$rbacAuthenticationSource = new RbacAuthenticationSource();
$authSourceReturn = $rbacAuthenticationSource->show($filters);
if ($authSourceReturn['total'] > 0) {
$row = $authSourceReturn['data'][0];
$filters['fields'] = ['AUTH_SOURCE_NAME'];
$filters['conditions'] = ['text' => $authSourceName];
$filters['orderBy'] = ['AUTH_SOURCE_NAME', 'desc'];
$lastAuthSource = $rbacAuthenticationSource->show($filters);
if ($lastAuthSource['total'] > 0) {
$name = $lastAuthSource['data'][0]['AUTH_SOURCE_NAME'];
//get suggest name
$pieces = explode( ' ', $name);
$last = array_pop($pieces);
@@ -132,7 +133,8 @@ class AuthSources
public function testConnection($authSourceData) {
try {
$authSourceConnectionData = $this->ldapConnection($authSourceData);
$ldapSource = new LdapSource();
$authSourceConnectionData = $ldapSource->ldapConnection($authSourceData);
$response = ['success' => true, 'status' => 'OK'];
if ($authSourceConnectionData['startTLS'] === false) {
@@ -146,24 +148,20 @@ class AuthSources
public function saveAuthSource($authSourceData) {
try {
global $RBAC;
$arrayAuthenticationSourceData = $authSourceData;
$arrayAuthenticationSourceData['AUTH_SOURCE_VERSION'] = 3;
$authSourceData['AUTH_SOURCE_VERSION'] = 3;
$ldapSource = new LdapSource();
$ldapConnection = $ldapSource->ldapConnection($authSourceData);
$ldapconection = $this->ldapConnection($arrayAuthenticationSourceData);
$authSourceData['AUTH_SOURCE_DATA']['LDAP_PAGE_SIZE_LIMIT'] = $this->getPageSizeLimit(
$ldapconection['connection'],
$arrayAuthenticationSourceData['AUTH_SOURCE_BASE_DN']
$authSourceData['AUTH_SOURCE_DATA']['LDAP_PAGE_SIZE_LIMIT'] = $ldapSource->getPageSizeLimit(
$ldapConnection['connection'],
$authSourceData['AUTH_SOURCE_BASE_DN']
);
$authSourceData['AUTH_SOURCE_DATA']['LDAP_PAGE_SIZE_LIMIT'] = $this->getPageSizeLimit(false);
if ($authSourceData['AUTH_SOURCE_UID'] == '') {
$RBAC->createAuthSource($authSourceData);
} else {
$RBAC->updateAuthSource($authSourceData);
}
return ['success' => true];
$rbacAuthenticationSource = new RbacAuthenticationSource();
$authSourceData['AUTH_SOURCE_ID'] = $authSourceData['AUTH_SOURCE_ID'] ?? 'vacio';
$authSourceData['AUTH_SOURCE_DATA'] = json_encode($authSourceData['AUTH_SOURCE_DATA']);
$saveDataResponse = $rbacAuthenticationSource->saveData($authSourceData);
return ['success' => true, 'saveData' => $saveDataResponse];
} catch (Exception $exception) {
return ['success' => false, 'message' => $exception->getMessage()];
}
@@ -171,34 +169,18 @@ class AuthSources
public function searchUsers($authSourceUid, $filters) {
try {
$listUsers = array();
$rbacUsers = new RbacUsers();
$usersAuthSources = $rbacUsers->listUsersAuthSources();
$criteria = new Criteria("workflow");
$criteria->addSelectColumn(UsersPeer::USR_USERNAME);
$criteria->addSelectColumn(RbacUsersPeer::UID_AUTH_SOURCE);
$criteria->addJoin(UsersPeer::USR_UID, RbacUsersPeer::USR_UID);
$criteria->add(UsersPeer::USR_STATUS, "CLOSED", Criteria::NOT_EQUAL);
$rsCriteria = UsersPeer::doSelectRS($criteria);
$rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC);
while ($rsCriteria->next()) {
$row = $rsCriteria->getRow();
foreach ($usersAuthSources['data'] as $row) {
$listUsers[strtolower($row["USR_USERNAME"])] = $row['UID_AUTH_SOURCE'];
}
//Get data
$ldapSource = new LdapSource();
$ldapSource->authSourceUid = $authSourceUid;
$result = $ldapSource->searchUsersLdap($filters['text'], $filters['start'], $filters['limit']);
$arrayData = array();
$this->authSourceUid = $authSourceUid;
$result = $this->searchUsersLdap($filters['text'], $filters['start'], $filters['limit']);
/*
$ldapAdvanced = new LdapAdvanced();
$ldapAdvanced->sAuthSource = $authSourceUid;
$result = $ldapAdvanced->searchUsers($filters['text'], $filters['start'], $filters['limit']);
*/
foreach ($result['data'] as $value) {
$listUsersData = $value;
@@ -224,16 +206,19 @@ class AuthSources
public function importUsers($authSourceUid, $usersImport) {
try {
global $RBAC;
$aFields = $RBAC->getAuthSource($authSourceUid);
$aAttributes = array();
$filters = ['conditions' => ['AUTH_SOURCE_UID'=> $authSourceUid]];
$rbacAuthenticationSource = new RbacAuthenticationSource();
$authSourceReturn = $rbacAuthenticationSource->show($filters);
$authSourceReturn = $authSourceReturn['data'][0];
if (isset($aFields['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'])) {
$aAttributes = $aFields['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'];
$aAttributes = array();
if (isset($authSourceReturn['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'])) {
$aAttributes = $authSourceReturn['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'];
}
$usersCreated = '';
$countUsers = 0;
global $RBAC;
foreach ($usersImport as $sUser) {
$aUser = (array) $sUser;
$matches = array();
@@ -252,8 +237,9 @@ class AuthSources
$aData['USR_UPDATE_DATE'] = date('Y-m-d H:i:s');
$aData['USR_BIRTHDAY'] = date('Y-m-d');
$aData['USR_STATUS'] = (isset($aUser['USR_STATUS'])) ? (($aUser['USR_STATUS'] == 'ACTIVE') ? 1 : 0) : 1;
$aData['USR_AUTH_TYPE'] = strtolower($aFields['AUTH_SOURCE_PROVIDER']);
$aData['UID_AUTH_SOURCE'] = $aFields['AUTH_SOURCE_UID'];
$aData['USR_AUTH_TYPE'] = strtolower($authSourceReturn['AUTH_SOURCE_PROVIDER']);
$aData['UID_AUTH_SOURCE'] = $authSourceReturn['AUTH_SOURCE_UID'];
// validating with regexp if there are some missing * inside the DN string
// if it's so the is changed to the ' character
preg_match('/[a-zA-Z]\*[a-zA-Z]/', $aUser['sDN'], $matches);
@@ -265,11 +251,11 @@ class AuthSources
$aData['USR_AUTH_USER_DN'] = $aUser['sDN'];
$usrRole = 'LURANA_OPERATOR';
if (!empty($aFields['AUTH_SOURCE_DATA']['USR_ROLE'])) {
//$usrRole = $aFields['AUTH_SOURCE_DATA']['USR_ROLE'];
if (!empty($authSourceReturn['AUTH_SOURCE_DATA']['USR_ROLE'])) {
//$usrRole = $authSourceReturn['AUTH_SOURCE_DATA']['USR_ROLE'];
}
$sUserUID = $RBAC->createUser($aData, $usrRole, $aFields['AUTH_SOURCE_NAME']);
$sUserUID = $RBAC->createUser($aData, $usrRole, $authSourceReturn['AUTH_SOURCE_NAME']);
$usersCreated .= $aData['USR_USERNAME'] . ' ';
$countUsers++;
@@ -301,426 +287,26 @@ class AuthSources
}
}
///=====================================================================================
///==== PRIVATE FUNCTIONS
///=====================================================================================
private static function encrypt($plaintext, $key) {
$cipher = 'AES-256-CBC';
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
private function getPageSizeLimit($ldapcnn, $baseDn = '')
{
try {
$limit = 1000;
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
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;
}
$ciphertext = base64_encode($iv . $ciphertext_raw);
return $ciphertext;
}
private function searchUsersLdap($keyword, $start = null, $limit = null) {
$arrayUser = [];
$totalUser = 0;
$countUser = 0;
private static function decrypt($ciphertext_b64, $key) {
$cipher = "AES-256-CBC";
$ivlen = openssl_cipher_iv_length($cipher);
$paged = !is_null($start) && !is_null($limit);
$ciphertext = base64_decode($ciphertext_b64);
$iv = substr($ciphertext, 0, $ivlen);
$ciphertext_raw = substr($ciphertext, $ivlen);
$rbac = RBAC::getSingleton();
if (is_null($rbac->authSourcesObj)) {
$rbac->authSourcesObj = new AuthenticationSource();
}
$arrayAuthenticationSourceData = $rbac->authSourcesObj->load($this->authSourceUid);
$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++;
/* Active Directory userAccountControl Values
Normal Day to Day Values:
512 - Enable Account
514 - Disable account
544 - Account Enabled - Require user to change password at first logon
4096 - Workstation/server
66048 - Enabled, password never expires
66050 - Disabled, password never expires
262656 - Smart Card Logon Required
532480 - Domain controller
1 - script
2 - accountdisable
8 - homedir_required
16 - lockout
32 - passwd_notreqd
64 - passwd_cant_change
128 - encrypted_text_pwd_allowed
256 - temp_duplicate_account
512 - normal_account
2048 - interdomain_trust_account
4096 - workstation_trust_account
8192 - server_trust_account
65536 - dont_expire_password
131072 - mns_logon_account
262144 - smartcard_required
524288 - trusted_for_delegation
1048576 - not_delegated
2097152 - use_des_key_only
4194304 - dont_req_preauth
8388608 - password_expired
16777216 - trusted_to_auth_for_delegation
*/
$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 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;
}
}
private function ldapConnection($authSourceData) {
$pass = explode('_', $authSourceData['AUTH_SOURCE_PASSWORD']);
// Removing sensitive data
$loggableAuthSource = $authSourceData;
unset($loggableAuthSource['AUTH_SOURCE_PASSWORD']);
foreach ($pass as $index => $value) {
if ($value == '2NnV3ujj3w') {
$authSourceData['AUTH_SOURCE_PASSWORD'] = G::decrypt($pass[0], $authSourceData['AUTH_SOURCE_SERVER_NAME']);
}
}
$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);
}
return ['connection' =>$ldapcnn, 'startTLS' => $resultLDAPStartTLS];
}
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()];
}
}
private function getConfigurationUser($userUid) {
try {
$configurations = new Configurations();
$configurationData = $configurations->getConfiguration('authSourcesList', 'pageSize', '', $userUid);
return $configurationData['pageSize'] ?? 20;
} catch (Exception $exception) {
return ['success' => false, 'message' => $exception->getMessage()];
}
$plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, OPENSSL_RAW_DATA, $iv);
return $plaintext;
}
}