%PDF- %PDF-
| Direktori : /proc/self/root/proc/10577/cwd/home/bitrix/www/bitrix/modules/ldap/classes/general/ |
| Current File : //proc/self/root/proc/10577/cwd/home/bitrix/www/bitrix/modules/ldap/classes/general/ldap_server.php |
<?php
IncludeModuleLangFile(__FILE__);
class CLdapServer
{
public $arFields = array();
public static $syncErrors = array();
/**
*
* @param $arOrder
* @param $arFilter
* @return __CLDAPServerDBResult
*/
public static function GetList($arOrder=Array(), $arFilter=Array())
{
global $USER, $DB, $APPLICATION;
$strSql =
"SELECT ls.*, ".
" ".$DB->DateToCharFunction("ls.TIMESTAMP_X")." as TIMESTAMP_X, ".
" ".$DB->DateToCharFunction("ls.SYNC_LAST")." as SYNC_LAST ".
"FROM b_ldap_server ls ";
if(!is_array($arFilter))
$arFilter = Array();
$arSqlSearch = Array();
$filter_keys = array_keys($arFilter);
$fkCount = count($filter_keys);
for($i=0; $i<$fkCount; $i++)
{
$val = $arFilter[$filter_keys[$i]];
$key=$filter_keys[$i];
$res = CLdapUtil::MkOperationFilter($key);
$key = strtoupper($res["FIELD"]);
$cOperationType = $res["OPERATION"];
switch($key)
{
case "ACTIVE":
case "SYNC":
case "CONVERT_UTF8":
case "USER_GROUP_ACCESSORY":
$arSqlSearch[] = CLdapUtil::FilterCreate("ls.".$key, $val, "string_equal", $cOperationType);
break;
case "ID":
case "PORT":
case "MAX_PAX_SIZE":
case "CONNECTION_TYPE":
$arSqlSearch[] = CLdapUtil::FilterCreate("ls.".$key, $val, "number", $cOperationType);
break;
case "TIMESTAMP_X":
$arSqlSearch[] = CLdapUtil::FilterCreate("ls.".$key, $val, "date", $cOperationType);
break;
case "SYNC_LAST":
$arSqlSearch[] = CLdapUtil::FilterCreate("ls.".$key, $val, "date", $cOperationType);
break;
case "CODE":
case "NAME":
case "DESCRIPTION":
case "SERVER":
case "ADMIN_LOGIN":
case "ADMIN_PASSWORD":
case "BASE_DN":
case "GROUP_FILTER":
case "GROUP_ID_ATTR":
case "GROUP_NAME_ATTR":
case "GROUP_MEMBERS_ATTR":
case "USER_FILTER":
case "USER_ID_ATTR":
case "USER_NAME_ATTR":
case "USER_LAST_NAME_ATTR":
case "USER_EMAIL_ATTR":
case "USER_GROUP_ATTR":
$arSqlSearch[] = CldapUtil::FilterCreate("ls.".$key, $val, "string", $cOperationType);
break;
}
}
$is_filtered = false;
$strSqlSearch = "";
for($i=0, $ssCount=count($arSqlSearch); $i<$ssCount; $i++)
{
if(strlen($arSqlSearch[$i])>0)
{
$is_filtered = true;
$strSqlSearch .= " AND (".$arSqlSearch[$i].") ";
}
}
$arSqlOrder = Array();
foreach($arOrder as $by=>$order)
{
$order = strtolower($order);
if ($order!="asc")
$order = "desc".($DB->type=="ORACLE"?" NULLS LAST":"");
else
$order = "asc".($DB->type=="ORACLE"?" NULLS FIRST":"");
switch(strtoupper($by))
{
case "ID":
case "NAME":
case "CODE":
case "ACTIVE":
case "CONVERT_UTF8":
case "SERVER":
case "PORT":
case "ADMIN_LOGIN":
case "ADMIN_PASSWORD":
case "BASE_DN":
case "GROUP_FILTER":
case "SYNC":
case "SYNC_LAST":
case "GROUP_ID_ATTR":
case "GROUP_NAME_ATTR":
case "GROUP_MEMBERS_ATTR":
case "USER_FILTER":
case "USER_ID_ATTR":
case "USER_NAME_ATTR":
case "USER_LAST_NAME_ATTR":
case "USER_EMAIL_ATTR":
case "USER_GROUP_ATTR":
case "USER_GROUP_ACCESSORY":
case "MAX_PAX_SIZE":
case "CONNECTION_TYPE":
$arSqlOrder[] = " ls.".$by." ".$order." ";
break;
default:
$arSqlOrder[] = " ls.TIMESTAMP_X ".$order." ";
}
}
$strSqlOrder = "";
DelDuplicateSort($arSqlOrder);
for ($i=0, $c=count($arSqlOrder); $i < $c; $i++)
{
if($i==0)
$strSqlOrder = " ORDER BY ";
else
$strSqlOrder .= ",";
$strSqlOrder .= strtolower($arSqlOrder[$i]);
}
$strSql .= " WHERE 1=1 ".$strSqlSearch.$strSqlOrder;
$res = $DB->Query($strSql);
$res = new __CLDAPServerDBResult($res);
return $res;
}
/**
*
* @param $ID
* @return __CLDAPServerDBResult
*/
public static function GetByID($ID)
{
return CLdapServer::GetList(Array(), $arFilter=Array("ID"=>IntVal($ID)));
}
public static function CheckFields($arFields, $ID=false)
{
global $DB, $APPLICATION;
$strErrors = "";
$arMsg = Array();
if(($ID===false || is_set($arFields, "NAME")) && strlen($arFields["NAME"])<1)
$arMsg[] = array("id"=>"NAME", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_NAME"));
//$strErrors .= GetMessage("LDAP_ERR_NAME").", ";
if(($ID===false || is_set($arFields, "SERVER")) && strlen($arFields["SERVER"])<1)
$arMsg[] = array("id"=>"SERVER", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_SERVER"));
//$strErrors .= GetMessage("LDAP_ERR_SERVER").", ";
if(($ID===false || is_set($arFields, "PORT")) && strlen($arFields["PORT"])<1)
$arMsg[] = array("id"=>"PORT", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_PORT"));
//$strErrors .= GetMessage("LDAP_ERR_PORT").", ";
if(($ID===false || is_set($arFields, "BASE_DN")) && strlen($arFields["BASE_DN"])<1)
//$strErrors .= GetMessage("LDAP_ERR_BASE_DN").", ";
$arMsg[] = array("id"=>"BASE_DN", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_BASE_DN"));
if(($ID===false || is_set($arFields, "GROUP_FILTER")) && strlen($arFields["GROUP_FILTER"])<1)
//$strErrors .= GetMessage("LDAP_ERR_GROUP_FILT").", ";
$arMsg[] = array("id"=>"GROUP_FILTER", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_GROUP_FILT"));
if(($ID===false || is_set($arFields, "GROUP_ID_ATTR")) && strlen($arFields["GROUP_ID_ATTR"])<1)
$arMsg[] = array("id"=>"GROUP_ID_ATTR", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_GROUP_ATTR"));
//$strErrors .= GetMessage("LDAP_ERR_GROUP_ATTR").", ";
if(($ID===false || is_set($arFields, "USER_FILTER")) && strlen($arFields["USER_FILTER"])<1)
$arMsg[] = array("id"=>"USER_FILTER", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_USER_FILT"));
//$strErrors .= GetMessage("LDAP_ERR_USER_FILT").", ";
if(($ID===false || is_set($arFields, "USER_ID_ATTR")) && strlen($arFields["USER_ID_ATTR"])<1)
$arMsg[] = array("id"=>"USER_ID_ATTR", "text"=> GetMessage("LDAP_ERR_EMPTY")." ".GetMessage("LDAP_ERR_USER_ATTR"));
//$strErrors .= GetMessage("LDAP_ERR_USER_ATTR").", ";
//if(strlen($strErrors)>0)
//{
// $APPLICATION->throwException(GetMessage("LDAP_ERR_EMPTY").substr($strErrors, 0, -2));
// return false;
//}
if(!empty($arMsg))
{
$e = new CAdminException($arMsg);
$GLOBALS["APPLICATION"]->ThrowException($e);
return false;
}
return true;
}
public static function Add($arFields)
{
global $DB, $APPLICATION;
$APPLICATION->ResetException();
if(is_set($arFields, "ACTIVE") && $arFields["ACTIVE"]!="Y")
$arFields["ACTIVE"]="N";
if(is_set($arFields, "SYNC") && $arFields["SYNC"]!="Y")
$arFields["SYNC"]="N";
if(is_set($arFields, "CONVERT_UTF8") && $arFields["CONVERT_UTF8"]!="Y")
$arFields["CONVERT_UTF8"]="N";
if(is_set($arFields, "USER_GROUP_ACCESSORY") && $arFields["USER_GROUP_ACCESSORY"]!="Y")
$arFields["USER_GROUP_ACCESSORY"]="N";
if(!CLdapServer::CheckFields($arFields))
return false;
if(is_set($arFields, "ADMIN_PASSWORD"))
$arFields["ADMIN_PASSWORD"]=CLdapUtil::Crypt($arFields["ADMIN_PASSWORD"]);
if(is_set($arFields, "FIELD_MAP") && is_array($arFields["FIELD_MAP"]))
{
$arFields["USER_NAME_ATTR"] = "".$arFields["FIELD_MAP"]["NAME"];
$arFields["USER_LAST_NAME_ATTR"] = "".$arFields["FIELD_MAP"]["LAST_NAME"];
$arFields["USER_EMAIL_ATTR"] = "".$arFields["FIELD_MAP"]["EMAIL"];
$arFields["FIELD_MAP"] = serialize($arFields["FIELD_MAP"]);
}
$ID = CDatabase::Add("b_ldap_server", $arFields);
if(is_set($arFields, 'GROUPS'))
CLdapServer::SetGroupMap($ID, $arFields['GROUPS']);
if($arFields["SYNC"]=="Y")
CLdapServer::__UpdateAgentPeriod($ID, $arFields["SYNC_PERIOD"]);
return $ID;
}
public static function __UpdateAgentPeriod($server_id, $time)
{
$server_id = IntVal($server_id);
$time = IntVal($time);
CAgent::RemoveAgent("CLdapServer::SyncAgent(".$server_id.");", "ldap");
if($time>0)
CAgent::AddAgent("CLdapServer::SyncAgent(".$server_id.");", "ldap", "N", $time*60*60);
}
public static function SyncAgent($id)
{
CLdapServer::Sync($id);
return "CLdapServer::SyncAgent(".$id.");";
}
/*********************************************************************
*********************************************************************/
public static function Update($ID, $arFields)
{
global $DB, $APPLICATION;
$APPLICATION->ResetException();
$ID = IntVal($ID);
if(is_set($arFields, "ACTIVE") && $arFields["ACTIVE"]!="Y")
$arFields["ACTIVE"]="N";
if(is_set($arFields, "SYNC") && $arFields["SYNC"]!="Y")
$arFields["SYNC"]="N";
if(is_set($arFields, "SYNC_USER_ADD") && $arFields["SYNC_USER_ADD"] != "Y")
$arFields["SYNC_USER_ADD"] = "N";
if(is_set($arFields, "CONVERT_UTF8") && $arFields["CONVERT_UTF8"]!="Y")
$arFields["CONVERT_UTF8"]="N";
if(is_set($arFields, "USER_GROUP_ACCESSORY") && $arFields["USER_GROUP_ACCESSORY"]!="Y")
$arFields["USER_GROUP_ACCESSORY"]="N";
if(is_set($arFields, "IMPORT_STRUCT") && $arFields["IMPORT_STRUCT"]!="Y")
$arFields["IMPORT_STRUCT"]="N";
if(is_set($arFields, "STRUCT_HAVE_DEFAULT") && $arFields["STRUCT_HAVE_DEFAULT"]!="Y")
$arFields["STRUCT_HAVE_DEFAULT"]="N";
if(!CLdapServer::CheckFields($arFields, $ID))
return false;
if(is_set($arFields, "ADMIN_PASSWORD"))
$arFields["ADMIN_PASSWORD"]=CLdapUtil::Crypt($arFields["ADMIN_PASSWORD"]);
if(is_set($arFields, "FIELD_MAP") && is_array($arFields["FIELD_MAP"]))
{
$arFields["USER_NAME_ATTR"] = "".$arFields["FIELD_MAP"]["NAME"];
$arFields["USER_LAST_NAME_ATTR"] = "".$arFields["FIELD_MAP"]["LAST_NAME"];
$arFields["USER_EMAIL_ATTR"] = "".$arFields["FIELD_MAP"]["EMAIL"];
$arFields["FIELD_MAP"] = serialize($arFields["FIELD_MAP"]);
}
if(isset($arFields["SYNC"]) || isset($arFields["SYNC_PERIOD"]))
{
$dbld = CLdapServer::GetById($ID);
$arLdap = $dbld->Fetch();
}
$strUpdate = $DB->PrepareUpdate("b_ldap_server", $arFields);
$strSql =
"UPDATE b_ldap_server SET ".
$strUpdate." ".
"WHERE ID=".$ID;
$DB->Query($strSql);
if(is_set($arFields, 'GROUPS'))
CLdapServer::SetGroupMap($ID, $arFields['GROUPS']);
if(isset($arFields["SYNC"]) || isset($arFields["SYNC_PERIOD"]))
{
if($arLdap)
{
if(isset($arFields["SYNC"]))
{
if($arFields["SYNC"]!="Y" && $arLdap["SYNC"]=="Y")
CLdapServer::__UpdateAgentPeriod($ID, 0);
elseif($arFields["SYNC"]=="Y" && $arLdap["SYNC"]!="Y")
CLdapServer::__UpdateAgentPeriod($ID, (isset($arFields["SYNC_PERIOD"])? $arFields["SYNC_PERIOD"] : $arLdap["SYNC_PERIOD"]));
elseif(isset($arFields["SYNC_PERIOD"]) && $arLdap["SYNC_PERIOD"]!=$arFields["SYNC_PERIOD"])
CLdapServer::__UpdateAgentPeriod($ID, $arFields["SYNC_PERIOD"]);
}
elseif($arLdap["SYNC_PERIOD"]!=$arFields["SYNC_PERIOD"])
CLdapServer::__UpdateAgentPeriod($ID, $arFields["SYNC_PERIOD"]);
}
}
return true;
}
public static function Delete($ID)
{
global $DB;
$ID = IntVal($ID);
$strSql = "DELETE FROM b_ldap_group WHERE LDAP_SERVER_ID=".$ID;
if(!$DB->Query($strSql, true))
return false;
$strSql = "DELETE FROM b_ldap_server WHERE ID=".$ID;
return $DB->Query($strSql, true);
}
public static function GetGroupMap($ID)
{
global $DB, $APPLICATION;
$ID = IntVal($ID);
return $DB->Query("SELECT GROUP_ID, LDAP_GROUP_ID FROM b_ldap_group WHERE LDAP_SERVER_ID=".$ID." AND NOT (GROUP_ID=-1)");
}
public static function GetGroupBan($ID)
{
global $DB, $APPLICATION;
$ID = IntVal($ID);
return $DB->Query("SELECT LDAP_GROUP_ID FROM b_ldap_group WHERE LDAP_SERVER_ID=".$ID." AND GROUP_ID=-1");
}
public static function SetGroupMap($ID, $arFields)
{
global $DB, $APPLICATION;
$ID = IntVal($ID);
$DB->Query("DELETE FROM b_ldap_group WHERE LDAP_SERVER_ID=".$ID);
foreach($arFields as $arGroup)
{
// check whether entry is valid, and if it is - add it
if(array_key_exists('GROUP_ID',$arGroup) && ($arGroup['GROUP_ID']>0 || $arGroup['GROUP_ID']==-1) && strlen($arGroup['LDAP_GROUP_ID'])>0)
{
$strSql =
"SELECT 'x' ".
"FROM b_ldap_group ".
"WHERE LDAP_SERVER_ID=".$ID." ".
" AND GROUP_ID = ".IntVal($arGroup['GROUP_ID'])." ".
" AND LDAP_GROUP_ID = '".$DB->ForSQL($arGroup['LDAP_GROUP_ID'], 255)."' ";
$r = $DB->Query($strSql);
if(!$r->Fetch())
{
$strSql =
"INSERT INTO b_ldap_group(GROUP_ID, LDAP_GROUP_ID, LDAP_SERVER_ID)".
"VALUES(".IntVal($arGroup['GROUP_ID']).", '".$DB->ForSQL($arGroup['LDAP_GROUP_ID'], 255)."', ".$ID.")";
$DB->Query($strSql);
}
}
}
}
public static function Sync($ldap_server_id)
{
global $DB, $USER, $APPLICATION;
$bUSERGen = false;
self::$syncErrors = array();
if(!is_object($USER))
{
$USER = new CUser();
$bUSERGen = true;
}
$dbLdapServers = CLdapServer::GetByID($ldap_server_id);
if(!($oLdapServer = $dbLdapServers->GetNextServer()))
return false;
if(!$oLdapServer->Connect())
return false;
if(!$oLdapServer->BindAdmin())
{
$oLdapServer->Disconnect();
return false;
}
$APPLICATION->ResetException();
$db_events = GetModuleEvents("ldap", "OnLdapBeforeSync");
while($arEvent = $db_events->Fetch())
{
$arParams['oLdapServer'] = $oLdapServer;
if(ExecuteModuleEventEx($arEvent, array(&$arParams))===false)
{
if(!($err = $APPLICATION->GetException()))
$APPLICATION->ThrowException("Unknown error");
return false;
}
}
// select all users from LDAP
$arLdapUsers = array();
$ldapLoginAttr = strtolower($oLdapServer->arFields["~USER_ID_ATTR"]);
$APPLICATION->ResetException();
$dbLdapUsers = $oLdapServer->GetUserList();
$ldpEx = $APPLICATION->GetException();
while($arLdapUser = $dbLdapUsers->Fetch())
$arLdapUsers[strtolower($arLdapUser[$ldapLoginAttr])] = $arLdapUser;
unset($dbLdapUsers);
// select all Bitrix CMS users for this LDAP
$arUsers = Array();
CTimeZone::Disable();
$dbUsers = CUser::GetList(($o=""), ($b=""), Array("EXTERNAL_AUTH_ID"=>"LDAP#".$ldap_server_id));
CTimeZone::Enable();
while($arUser = $dbUsers->Fetch())
$arUsers[strtolower($arUser["LOGIN"])] = $arUser;
unset($dbUsers);
$arDelLdapUsers = array();
if(!$ldpEx || $ldpEx->msg != 'LDAP_SEARCH_ERROR')
$arDelLdapUsers = array_diff(array_keys($arUsers), array_keys($arLdapUsers));
if(strlen($oLdapServer->arFields["SYNC_LAST"]) > 0)
$syncTime = MakeTimeStamp($oLdapServer->arFields["SYNC_LAST"]);
else
$syncTime = 0;
$cnt = 0;
$departmentCache = array();
// have to update $oLdapServer->arFields["FIELD_MAP"] for user fields
// for each one of them looking for similar in user list
foreach($arLdapUsers as $userLogin => $arLdapUserFields)
{
if(!is_array($arUsers[$userLogin]))
{
//For manual users import - always add
if($oLdapServer->arFields["SYNC_USER_ADD"] != "Y")
continue;
// if user is not found among already existing ones, then import him
// $arLdapUserFields - user fields from ldap
$userActive = $oLdapServer->getLdapValueByBitrixFieldName("ACTIVE", $arLdapUserFields);
if($userActive != "Y")
continue;
$arUserFields = $oLdapServer->GetUserFields($arLdapUserFields, $departmentCache);
if(self::isUserInBannedGroups($ldap_server_id, $arUserFields))
continue;
if($oLdapServer->SetUser($arUserFields))
$cnt++;
}
else
{
// if date of update is set, then compare it
$ldapTime = time();
if($syncTime > 0
&& strlen($oLdapServer->arFields["SYNC_ATTR"])>0
&& preg_match("'([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})\.0Z'", $arLdapUserFields[strtolower($oLdapServer->arFields["SYNC_ATTR"])], $arTimeMatch)
)
{
$ldapTime = gmmktime($arTimeMatch[4], $arTimeMatch[5], $arTimeMatch[6], $arTimeMatch[2], $arTimeMatch[3], $arTimeMatch[1]);
$userTime = MakeTimeStamp($arUsers[$userLogin]["TIMESTAMP_X"]);
}
if($syncTime < $ldapTime || $syncTime < $userTime)
{
$arUserFields = $oLdapServer->GetUserFields($arLdapUserFields, $departmentCache);
if(self::isUserInBannedGroups($ldap_server_id, $arUserFields))
continue;
$arUserFields["ID"] = $arUsers[$userLogin]["ID"];
if($oLdapServer->SetUser($arUserFields))
$cnt++;
}
}
if($USER->LAST_ERROR != '')
{
self::$syncErrors[] = $userLogin.': '.$USER->LAST_ERROR;
$USER->LAST_ERROR = '';
}
}
foreach ($arDelLdapUsers as $userLogin)
{
$USER = new CUser();
if (isset($arUsers[$userLogin]) && $arUsers[$userLogin]['ACTIVE'] == 'Y')
{
$ID = intval($arUsers[$userLogin]["ID"]);
$USER->Update($ID, array('ACTIVE' => 'N'));
}
}
$oLdapServer->Disconnect();
CLdapServer::Update($ldap_server_id, Array("~SYNC_LAST"=>$DB->CurrentTimeFunction()));
if(CModule::IncludeModule('intranet'))
{
\Bitrix\Intranet\Internals\UserSubordinationTable::performReInitialization();
\Bitrix\Intranet\Internals\UserToDepartmentTable::performReInitialization();
}
if($bUSERGen)
unset($USER);
return $cnt;
}
protected static function isUserInBannedGroups($ldap_server_id, $arUserFields)
{
static $noImportGroups = null;
if($noImportGroups === null)
{
$noImportGroups = array();
$dbGroups = CLdapServer::GetGroupBan($ldap_server_id);
while($arGroup = $dbGroups->Fetch())
$noImportGroups[md5($arGroup['LDAP_GROUP_ID'])] = $arGroup['LDAP_GROUP_ID'];
}
if(empty($noImportGroups))
return false;
$allUserGroups = $arUserFields['LDAP_GROUPS'];
$result = false;
foreach($allUserGroups as $groupId)
{
$groupId = trim($groupId);
if(!empty($groupId) && array_key_exists(md5($groupId), $noImportGroups))
{
$result = true;
break;
}
}
return $result;
}
}
class __CLDAPServerDBResult extends CDBResult
{
function Fetch()
{
if($res = parent::Fetch())
{
$res["ADMIN_PASSWORD"] = CLdapUtil::Decrypt($res["ADMIN_PASSWORD"]);
$res["FIELD_MAP"] = unserialize($res["FIELD_MAP"]);
if(!is_array($res["FIELD_MAP"]))
$res["FIELD_MAP"] = Array();
}
return $res;
}
function GetNextServer()
{
if(!($r = $this->GetNext()))
return $r;
$ldap = new CLDAP();
$ldap->arFields = $r;
return $ldap;
}
}