"|(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']) { ldap_set_option($ldapcnn, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_ALLOW); $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'] . ')'; $filtersDefault = "(|(dn=$keyword)(uid=$keyword)(samaccountname=$keyword)(givenname=$keyword)(sn=$keyword)(cn=$keyword)(mail=$keyword)(userprincipalname=$keyword))"; $filter = '(&' . $filter . $filtersDefault . ')'; $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); } } } $response = [ 'numRecTotal' => $totalUser, 'data' => $arrayUser, 'context' => $context ]; return $response; } 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']) : ''), // TODO REMOVE THIS LAST INDEX, ONLY FOR REVIEW 'allAttributes' => (array)$arrayAttributes ]; } 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; } //------------------------- public function automaticRegister($authSource, $strUser, $strPass) { $rbac = RBAC::getSingleton(); $user = $this->searchUserByUid($strUser); $result = 0; if (!empty($user)) { if ($this->VerifyLogin($user['sUsername'], $strPass) === true) { $result = 1; } if ($result == 0 && $this->VerifyLogin($user['sDN'], $strPass) === true) { $result = 1; } } else { return 0; } if ($result == 0) { $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); $attributes = []; if (isset($authSource['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE'])) { $attributes = $authSource['AUTH_SOURCE_DATA']['AUTH_SOURCE_GRID_ATTRIBUTE']; } $usrRole = 'LURANA_OPERATOR'; if (!empty($authSource['AUTH_SOURCE_DATA']['USR_ROLE'])) { $usrRole = $authSource['AUTH_SOURCE_DATA']['USR_ROLE']; } $data = []; $data['USR_USERNAME'] = $user['sUsername']; $data["USR_PASSWORD"] = "00000000000000000000000000000000"; $data['USR_FIRSTNAME'] = $user['sFirstname']; $data['USR_LASTNAME'] = $user['sLastname']; $data['USR_EMAIL'] = $user['sEmail']; $data['USR_DUE_DATE'] = date('Y-m-d', mktime(0, 0, 0, date('m'), date('d'), date('Y') + 2)); $data['USR_CREATE_DATE'] = date('Y-m-d H:i:s'); $data['USR_UPDATE_DATE'] = date('Y-m-d H:i:s'); $data['USR_BIRTHDAY'] = date('Y-m-d'); $data['USR_STATUS'] = (isset($user['USR_STATUS'])) ? (($user['USR_STATUS'] == 'ACTIVE') ? 1 : 0) : 1; $data['USR_AUTH_TYPE'] = strtolower($authSource['AUTH_SOURCE_PROVIDER']); $data['UID_AUTH_SOURCE'] = $authSource['AUTH_SOURCE_UID']; $data['USR_AUTH_USER_DN'] = $user['sDN']; $data['USR_ROLE'] = $usrRole; if (!empty($attributes)) { foreach ($attributes as $value) { if (isset($user[$value['attributeUser']])) { $data[$value['attributeUser']] = str_replace("*", "'", $user[$value['attributeUser']]); if ($value['attributeUser'] == 'USR_STATUS') { $evalValue = $data[$value['attributeUser']]; $statusValue = (isset($user['USR_STATUS'])) ? $user['USR_STATUS'] : 'ACTIVE'; $data[$value['attributeUser']] = $statusValue; } } } } //req - accountexpires if (isset($user["USR_DUE_DATE"]) && $user["USR_DUE_DATE"] != '') { $data["USR_DUE_DATE"] = $this->convertDateADtoPM($user["USR_DUE_DATE"]); } //end $userUid = $rbac->createUser($data, $usrRole); $data['USR_UID'] = $userUid; $users = new Users(); $data['USR_STATUS'] = (isset($user['USR_STATUS'])) ? $user['USR_STATUS'] : 'ACTIVE'; $users->create($data); $this->log(null, "Automatic Register for user $strUser "); $result = 1; } return $result; } public function searchUserByUid($keyword, $identifier = "") { try { $arrayUserData = []; $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 User $attributeUserSet = []; $attributeSetAdd = []; if ( isset($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_GRID_ATTRIBUTE"]) && !empty($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_GRID_ATTRIBUTE"]) ) { foreach ($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_GRID_ATTRIBUTE"] as $value) { $attributeSetAdd[] = $value["attributeLdap"]; $attributeUserSet[$value["attributeUser"]] = $value["attributeLdap"]; } } $uidUserIdentifier = (isset($authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"])) ? $authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"] : "uid"; $filter2 = ""; if ($identifier != "" && $identifier != $uidUserIdentifier) { $filter2 = "($identifier=$keyword)"; } $filter = "(&(" . $this->arrayObjectClassFilter["user"] . ")(|($uidUserIdentifier=$keyword)$filter2))"; $searchResult = @ldap_search($ldapcnn, $authenticationSourceData["AUTH_SOURCE_BASE_DN"], $filter, array_merge($this->arrayAttributesForUser, $attributeSetAdd)); $context = [ "baseDN" => $authenticationSourceData["AUTH_SOURCE_BASE_DN"], "filter" => $filter, "attribute" => array_merge($this->arrayAttributesForUser, $attributeSetAdd) ]; $this->stdLog($ldapcnn, "ldap_search", $context); if ($error = ldap_errno($ldapcnn)) { $messageError = ldap_err2str($error); Cache::put('ldapMessageError', $messageError, 120); //laravel 8.x the time parameter is in seconds. // } else { if ($searchResult) { $numEntries = ldap_count_entries($ldapcnn, $searchResult); $this->stdLog($ldapcnn, "ldap_count_entries"); if ($numEntries > 0) { $entry = ldap_first_entry($ldapcnn, $searchResult); $this->stdLog($ldapcnn, "ldap_first_entry"); $arrayUserLdap = $this->ldapGetAttributes($ldapcnn, $entry); $username = (isset($arrayUserLdap[$uidUserIdentifier])) ? $arrayUserLdap[$uidUserIdentifier] : ""; if ((is_array($username) && !empty($username)) || trim($username) != "") { $userCountControl = ""; //Active Directory, OpenLDAP if (isset($arrayUserLdap["useraccountcontrol"])) { switch ($arrayUserLdap["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($arrayUserLdap["status"])) { $userCountControl = strtoupper($arrayUserLdap["status"]); } $aUserAttributes = []; foreach ($attributeUserSet as $key => $value) { if ($key == "USR_STATUS") { $aUserAttributes[$key] = ($userCountControl != "") ? $userCountControl : "ACTIVE"; } else { if (isset($arrayUserLdap[$value])) { $aUserAttributes[$key] = $arrayUserLdap[$value]; } } } $arrayUserData = array_merge($this->getUserDataFromAttribute($username, $arrayUserLdap), $aUserAttributes); } } } } return $arrayUserData; } catch (Exception $e) { throw $e; } } public function VerifyLogin($strUser, $strPass) { if (is_array($strUser)) { $strUser = $strUser[0]; } else { $strUser = trim($strUser); } if ($strUser == "") { return -1; } if (strlen($strPass) == 0) { return -2; } $userDn = $strUser; $ldapcnn = null; $validUserPass = 1; try { $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); if ( isset($authenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_SHOWGRID']) && $authenticationSourceData['AUTH_SOURCE_DATA']['AUTH_SOURCE_SHOWGRID'] == 'on' ) { $setAttributes = 1; } $filters = [ 'fields' => ['USR_USERNAME', 'USR_UID'], 'conditions' => [ 'UID_AUTH_SOURCE' => $authenticationSourceData["AUTH_SOURCE_UID"], 'USR_AUTH_USER_DN' => $strUser, ['USR_USERNAME', '!=', ''] ] ]; $rbacUsers = new RbacUsers(); $usersByAuthSource = $rbacUsers->show($filters); if (!empty($usersByAuthSource['data'] && !empty($usersByAuthSource['data'][0]))) { $usrName = $usersByAuthSource['data'][0]['USR_USERNAME']; $usrUid = $usersByAuthSource['data'][0]['USR_UID']; } else { return -1; } $verifiedUser = $this->searchUserByUid($usrName, $authenticationSourceData["AUTH_SOURCE_DATA"]["AUTH_SOURCE_IDENTIFIER_FOR_USER"]); if (empty($verifiedUser) || trim($verifiedUser["sDN"]) == null) { return -1; } /* if ($verifiedUser["sDN"] != $strUser || $setAttributes == 1) { $userDn = $verifiedUser['sDN']; // Update data $user = new User(); $arrayUserData = $user->getUserRecordByPk($usrUid, [], false); $result = $this->ldapUserUpdateByDnAndData( $this->ldapcnn, $authenticationSourceData, $userDn, [$arrayUserData['USR_USERNAME'] => $arrayUserData] ); //Update DN $con = Propel::getConnection(RbacUsersPeer::DATABASE_NAME); // select set $c1 = new Criteria("rbac"); $c1->add(RbacUsersPeer::UID_AUTH_SOURCE, $authenticationSourceData["AUTH_SOURCE_UID"]); $c1->add(RbacUsersPeer::USR_AUTH_USER_DN, $strUser); // update set $c2 = new Criteria("rbac"); $c2->add(RbacUsersPeer::USR_AUTH_USER_DN, $userDn); BasePeer::doUpdate($c1, $c2, $con); } */ //Check ldap connection for user $authenticationSourceData["AUTH_ANONYMOUS"] = "0"; $authenticationSourceData["AUTH_SOURCE_SEARCH_USER"] = $userDn; $authenticationSourceData["AUTH_SOURCE_PASSWORD"] = $strPass; $ldapcnn = $this->ldapConnection($authenticationSourceData); $ldapcnn = $ldapcnn['connection']; $flagUpdate = false; switch (hexdec(ldap_errno($ldapcnn))) { case 0: //0x00 $flagUpdate = true; $statusRbac = 1; $statusUser = 'ACTIVE'; break; case 52: case 88: case 94: //0x34, 0x58, 0x5e //LDAP_UNAVAILABLE //LDAP_USER_CANCELLED //LDAP_NO_RESULTS_RETURNED $flagUpdate = true; $statusRbac = 0; $statusUser = 'INACTIVE'; break; default: break; } if ($flagUpdate) { $setValues = [ 'USR_AUTH_USER_DN' => $userDn, 'USR_STATUS' => $statusRbac, 'USR_FIRSTNAME' => '' ]; $conditions = [ 'UID_AUTH_SOURCE' =>$authenticationSourceData["AUTH_SOURCE_UID"], 'USR_AUTH_USER_DN' => $strUser, 'USR_STATUS' => 1 ]; $rbacUsers = new RbacUsers(); $rbacUsers->updateData($setValues, $conditions); $columnsWf = []; $columnsWf['USR_UID'] = $usrUid; $columnsWf['USR_STATUS'] = $statusUser; $oUser = new Users(); $oUser->update($columnsWf); } $attributes = $authenticationSourceData["AUTH_SOURCE_DATA"]; if (!isset($attributes['AUTH_SOURCE_RETIRED_OU'])) { $attributes['AUTH_SOURCE_RETIRED_OU'] = ''; } /* $attributes["AUTH_SOURCE_RETIRED_OU"] ahora es igual a '' dd('A punto', $verifiedUser, $usrName, $attributes["AUTH_SOURCE_RETIRED_OU"]); // Check if the user is in the terminated organizational unit if (!empty($verifiedUser) && $this->userIsTerminated($usrName, $attributes["AUTH_SOURCE_RETIRED_OU"])) { $this->deactivateUser($usrName); $this->log($ldapcnn, "user $strUser is member of Remove OU, deactivating this user."); return -3; } */ $validUserPass = ldap_errno($ldapcnn) == 0; } catch (Exception $e) { $context = [ "action" => "ldapSynchronize", "authSource" => $authenticationSourceData ]; $message = $e->getMessage(); Log::channel(':ldapSynchronize')->error($message, Bootstrap::context($context)); $validUserPass = -5; } if ($validUserPass == 1) { $this->log($ldapcnn, "sucessful login user " . $userDn); } else { $this->log($ldapcnn, "failure authentication for user $strUser"); } return $validUserPass; } public function deactivateUser($userUid) { if (!class_exists('RbacUsers')) { require_once(PATH_RBAC . 'model/RbacUsers.php'); } $con = Propel::getConnection(RbacUsersPeer::DATABASE_NAME); // select set $c1 = new Criteria('rbac'); $c1->add(RbacUsersPeer::USR_USERNAME, $userUid); // update set $c2 = new Criteria('rbac'); $c2->add(RbacUsersPeer::USR_STATUS, '0'); BasePeer::doUpdate($c1, $c2, $con); if (!class_exists('Users')) { require_once('classes/model/Users.php'); } $con = Propel::getConnection(UsersPeer::DATABASE_NAME); // select set $c1 = new Criteria('workflow'); $c1->add(UsersPeer::USR_USERNAME, $userUid); // update set $c2 = new Criteria('workflow'); $c2->add(UsersPeer::USR_STATUS, 'INACTIVE'); $c2->add(UsersPeer::DEP_UID, ''); BasePeer::doUpdate($c1, $c2, $con); } public function userIsTerminated($userUid, $sOuTerminated) { $terminated = false; $aLdapUsers = $this->getUsersFromDepartmentByName($sOuTerminated); foreach ($aLdapUsers as $aLdapUser) { if ($aLdapUser['sUsername'] == $userUid) { $terminated = true; break; } } return $terminated; } public function getUsersFromDepartmentByName($departmentName) { $dFilter = "(&(" . $this->arrayObjectClassFilter["department"] . ")(ou=" . $departmentName . "))"; $aUsers = []; $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; $oSearch = @ldap_search($ldapcnn, $authenticationSourceData["AUTH_SOURCE_BASE_DN"], $dFilter, $this->arrayAttributesForUser); $context = [ "baseDN" => $authenticationSourceData["AUTH_SOURCE_BASE_DN"], "filter" => $dFilter, "attributes" => $this->arrayAttributesForUser ]; $this->stdLog($ldapcnn, "ldap_search", $context); if ($oError = ldap_errno($ldapcnn)) { return $aUsers; } else { if ($oSearch) { //get the departments from the ldap entries if (ldap_count_entries($ldapcnn, $oSearch) > 0) { $this->stdLog($ldapcnn, "ldap_count_entries"); $oEntry = ldap_first_entry($ldapcnn, $oSearch); $this->stdLog($ldapcnn, "ldap_first_entry"); do { $aAttr = $this->ldapGetAttributes($ldapcnn, $oEntry); $result = $this->ldapGetUsersFromDepartment("GET", $aAttr["dn"]); foreach ($result as $item) { $aUsers[] = $item; } } while ($oEntry = ldap_next_entry($ldapcnn, $oEntry)); } } return $aUsers; } } public function ldapGetUsersFromDepartment($option, $dn, array $arrayData = []) { try { $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > START"); $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > \$dn ----> $dn"); $arrayUser = []; $totalUser = 0; $countUser = 0; //Set variables $dn = trim($dn); $rbac = RBAC::getSingleton(); if (is_null($rbac->authSourcesObj)) { $rbac->authSourcesObj = new AuthenticationSource(); } $arrayAuthenticationSourceData = $rbac->authSourcesObj->load($this->sAuthSource); $this->ldapcnn = $this->ldapConnection($arrayAuthenticationSourceData); $ldapcnn = $this->ldapcnn; //Get Users $limit = $this->getPageSizeLimitByData($arrayAuthenticationSourceData); $flagError = false; 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"] . ")"; $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > \$filter ----> $filter"); $cookie = ''; do { $searchResult = @ldap_list( $ldapcnn, $dn, $filter, $this->arrayAttributesForUser, 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_list", ["filter" => $filter, "attributes" => $this->arrayAttributesForUser]); if ($error = ldap_errno($ldapcnn)) { $flagError = true; } else { $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > ldap_list > OK"); switch ($option) { case "GET": list($totalUser, $countUser, $arrayUser) = $this->ldapGetUsersFromDepartmentSearchResult($ldapcnn, $searchResult, $option, $dn, $uidUserIdentifier, $totalUser, $countUser, $arrayUser); break; case "SYNCHRONIZE": list($totalUser, $countUser, $arrayData) = $this->ldapGetUsersFromDepartmentSearchResult($ldapcnn, $searchResult, $option, $dn, $uidUserIdentifier, $totalUser, $countUser, $arrayData); break; } } 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); // Get Users //2 if ($flagError) { $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > Search by characters > START"); foreach ($this->characters() as $value) { $char = $value; $ldapcnn = $this->ldapConnection($arrayAuthenticationSourceData); $filter = ($filterUsers != "") ? $filterUsers : "(" . $this->arrayObjectClassFilter["user"] . ")"; $filter = "(&$filter($uidUserIdentifier=$char*))"; $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > \$filter ----> $filter"); $searchResult = @ldap_list($ldapcnn, $dn, $filter, $this->arrayAttributesForUser); $this->stdLog($ldapcnn, "ldap_list", ["attributes" => $this->arrayAttributesForUser]); if ($error = ldap_errno($ldapcnn)) { $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > ldap_list > ERROR > \$error ---->\n" . print_r($error, true)); } else { $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > ldap_list > OK"); switch ($option) { case "GET": list($totalUser, $countUser, $arrayUser) = $this->ldapGetUsersFromDepartmentSearchResult($ldapcnn, $searchResult, $option, $dn, $uidUserIdentifier, $totalUser, $countUser, $arrayUser); break; case "SYNCHRONIZE": list($totalUser, $countUser, $arrayData) = $this->ldapGetUsersFromDepartmentSearchResult($ldapcnn, $searchResult, $option, $dn, $uidUserIdentifier, $totalUser, $countUser, $arrayData); break; } } } $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > Search by characters > END"); } $this->log($ldapcnn, "Found $totalUser users in department $dn"); $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartment() > END"); // Return switch ($option) { case "GET": return $arrayUser; break; case "SYNCHRONIZE": return $arrayData; break; } } catch (Exception $e) { throw $e; } } public function characters() { try { $arrayCharacter = []; for ($i = 33; $i <= 127; $i++) { $char = trim(strtolower(chr($i))); if ($char != "") { $arrayCharacter[$i] = $char; } } unset($arrayCharacter[33]); // ! unset($arrayCharacter[38]); // & unset($arrayCharacter[40]); // ( unset($arrayCharacter[41]); // ) unset($arrayCharacter[42]); // * unset($arrayCharacter[60]); // < unset($arrayCharacter[61]); // = unset($arrayCharacter[62]); // > unset($arrayCharacter[124]); // | unset($arrayCharacter[126]); // ~ unset($arrayCharacter[127]); // DEL // Return return array_unique($arrayCharacter); } catch (Exception $e) { throw $e; } } public function ldapGetUsersFromDepartmentSearchResult($ldapcnn, $searchResult, $option, $dn, $uidUserIdentifier, $totalUser, $countUser, array $arrayData) { try { $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartmentSearchResult() > START"); if ($searchResult) { $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartmentSearchResult() > ldap_list > OK"); $numEntries = ldap_count_entries($ldapcnn, $searchResult); $this->stdLog($ldapcnn, "ldap_count_entries"); $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartmentSearchResult() > ldap_list > OK > \$numEntries ----> $numEntries"); $totalUser += $numEntries; if ($numEntries > 0) { $this->log($ldapcnn, "Search $dn accounts with identifier = $uidUserIdentifier"); $entry = ldap_first_entry($ldapcnn, $searchResult); $this->stdLog($ldapcnn, "ldap_first_entry"); do { $arrayUserLdap = $this->ldapGetAttributes($ldapcnn, $entry); $username = (isset($arrayUserLdap[$uidUserIdentifier])) ? $arrayUserLdap[$uidUserIdentifier] : ""; $countUser++; if ((is_array($username) && !empty($username)) || trim($username) != "") { $arrayUserData = $this->getUserDataFromAttribute($username, $arrayUserLdap); if (!isset($this->arrayDepartmentUserSynchronizedChecked[$arrayUserData["sUsername"]])) { $this->arrayDepartmentUserSynchronizedChecked[$arrayUserData["sUsername"]] = 1; switch ($option) { case "GET": $arrayData[] = $arrayUserData; break; case "SYNCHRONIZE": $arrayData = $this->departmentSynchronizeUser("", $arrayUserData, $arrayData); break; } } else { $this->log($ldapcnn, "User have repeated: Username \"" . $arrayUserData["sUsername"] . "\", DN \"" . $arrayUserData["sDN"] . "\""); } } if ($option == "SYNCHRONIZE") { // Progress bar //$this->frontEndShow("BAR", "Departments: " . $arrayData["i"] . "/" . $arrayData["n"] . " " . $this->progressBar($totalUser, $countUser)); } } while ($entry = ldap_next_entry($ldapcnn, $entry)); } } $this->debugLog("class.ldapAdvanced.php > function ldapGetUsersFromDepartmentSearchResult() > END"); // Return return array($totalUser, $countUser, $arrayData); } catch (Exception $e) { throw $e; } } public function departmentSynchronizeUser($departmentUid, array $arrayUserLdap, array $arrayData) { try { $this->debugLog("class.ldapAdvanced.php > function departmentSynchronizeUser() > START"); $this->debugLog("class.ldapAdvanced.php > function departmentSynchronizeUser() > \$arrayUserLdap[sUsername] ----> " . $arrayUserLdap["sUsername"]); $userUid = ""; $found = false; $arrayUserData = $this->departmentGetUserDataIfUsernameExists($arrayUserLdap["sUsername"]); if (!empty($arrayUserData)) { //User already exists in this department and there is nothing to do //User already exists $userUid = $arrayUserData["USR_UID"]; $found = true; $arrayData["already"]++; $arrayData["alreadyUsers"] .= $arrayUserData["USR_USERNAME"] . " "; } if (!$found) { //If user DO NOT exists in this department.. do: //If exists with another AuthSource -> impossible //If exists in another department, but in PM and for this authsource, we need to move it //$arrayNewUserData = $this->searchUserByUid($arrayUserLdap["sUsername"]); $arrayNewUserData = $arrayUserLdap; $arrayAux = $this->custom_ldap_explode_dn($arrayNewUserData["sDN"]); array_shift($arrayAux); $departmentUid = $this->getDepUidIfExistsDN(implode(",", $arrayAux)); //Check if exists the Department DN in DB $this->debugLog("class.ldapAdvanced.php > function departmentSynchronizeUser() > \$departmentUid ----> $departmentUid"); if ($departmentUid != "") { $arrayUserData = $this->authenticationSourceGetUserDataIfUsernameExists($arrayNewUserData["sUsername"]); if (!empty($arrayUserData)) { //User exists in this Authentication Source //Move User $userUid = $arrayUserData["USR_UID"]; $this->activateUser($arrayUserData["USR_UID"], $arrayNewUserData["sDN"], $departmentUid); $arrayData["moved"]++; $arrayData["movedUsers"] .= $arrayUserData["USR_USERNAME"] . " "; $this->setArrayAuthenticationSourceUser($userUid, $arrayNewUserData); //INITIALIZE DATA //Update User } else { $arrayUserData = $this->getUserFromPM($arrayNewUserData["sUsername"]); if (!empty($arrayUserData)) { //User exists in another Authentication Source and another Department //Impossible $userUid = $arrayUserData["USR_UID"]; $arrayData["impossible"]++; $arrayData["impossibleUsers"] .= $arrayUserData["USR_USERNAME"] . " "; } else { //User not exists //Create User $userUid = $this->createUserAndActivate($arrayNewUserData, $departmentUid); $arrayData["created"]++; $arrayData["createdUsers"] .= $arrayNewUserData["sUsername"] . " "; $this->setArrayAuthenticationSourceUser($userUid, $arrayNewUserData); //INITIALIZE DATA //Add User } } } } if ($userUid != "") { $arrayData["arrayUserUid"][] = $userUid; if (isset($arrayUserLdap["sManagerDN"]) && $arrayUserLdap["sManagerDN"] != "") { if (!isset($arrayData["managersHierarchy"][$arrayUserLdap["sManagerDN"]])) { $arrayData["managersHierarchy"][$arrayUserLdap["sManagerDN"]] = []; } $arrayData["managersHierarchy"][$arrayUserLdap["sManagerDN"]][$userUid] = $userUid; } } $this->debugLog("class.ldapAdvanced.php > function departmentSynchronizeUser() > \$userUid ----> $userUid"); $this->debugLog("class.ldapAdvanced.php > function departmentSynchronizeUser() > END"); return $arrayData; } catch (Exception $e) { throw $e; } } public function debugLog($text) { try { if ($this->debug) { $this->log(null, "DEBUG: $text"); } } catch (Exception $e) { throw $e; } } private function convertDateADtoPM($dateAD) { $unixTimestamp = ($dateAD / 10000000) - 11644560000; $datePM = date('Y-m-d', mktime(0, 0, 0, date('m'), '01', date('Y') + 2)); if ($unixTimestamp > 0) { $dateAux = date("Y-m-d", $unixTimestamp); $yearAux = date("Y", $unixTimestamp); if (strlen(trim($yearAux)) <= 4) { $datePM = $dateAux; } } return $datePM; } }