egroupware_official/api/src/Ldap/ServerInfo.php
Ralf Becker 9f9cce88b2 * ActiveDirectory: fix account-selection type groupmembers (applies only to non-admins!) and ignore Domain Users group
not setting caseIgnoreMatch for sorting, as its not supported for Windows ActiveDirectory
2020-09-08 15:29:51 +02:00

291 lines
6.6 KiB
PHP

<?php
/**
* EGroupware API - LDAP server information
*
* @link http://www.egroupware.org
* @author Lars Kneschke <l.kneschke@metaways.de>
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage ldap
*/
namespace EGroupware\Api\Ldap;
/**
* Class to store and retrieve information (eg. supported object classes) of a connected ldap server
*/
class ServerInfo
{
/**
* Unknown LDAP server
*/
const UNKNOWN = 0;
/**
* OpenLDAP server
*/
const OPENLDAP = 1;
/**
* Samba4 Active Directory server
*/
const SAMBA4 = 2;
/**
* Windows Active Directory server
*/
const WINDOWS_AD = 4;
/**
* @var array $namingContext holds the supported namingcontexts
*/
var $namingContext = array();
/**
* @var string $version holds the LDAP server version
*/
var $version = 2;
/**
* @var integer $serverType holds the type of LDAP server(OpenLDAP, ADS, NDS, ...)
*/
var $serverType = 0;
/**
* @var string $_subSchemaEntry the subschema entry DN
*/
var $subSchemaEntry = '';
/**
* @var array $supportedObjectClasses the supported objectclasses
*/
var $supportedObjectClasses = array();
/**
* @var array $supportedOIDs the supported OIDs
*/
var $supportedOIDs = array();
/**
* @var array OIDs of supported controls LDAP_CONTROL_*
*/
var $suportedControl = [];
/**
* Name of host
*
* @var string
*/
var $host;
/**
* Constructor
*
* @param string $host
*/
function __construct($host)
{
$this->host = $host;
}
/**
* gets the version
*
* @return integer the supported ldap version
*/
function getVersion()
{
return $this->version;
}
/**
* sets the namingcontexts
*
* @param array $_namingContext the supported namingcontexts
*/
function setNamingContexts($_namingContext)
{
$this->namingContext = $_namingContext;
}
/**
* sets the type of the ldap server(OpenLDAP, ADS, NDS, ...)
*
* @param integer $_serverType the type of ldap server
*/
function setServerType($_serverType)
{
$this->serverType = $_serverType;
}
/**
* @param ?bool $windows_ad true: check for windows AD, false: check for Samba4, null: check of any AD
* @return bool
*/
function activeDirectory($windows_ad=null)
{
return !isset($windows_ad) ? in_array($this->serverType, [self::WINDOWS_AD, self::SAMBA4], true) :
$this->serverType === ($windows_ad ? self::WINDOWS_AD : self::SAMBA4);
}
/**
* sets the DN for the subschema entry
*
* @param string $_subSchemaEntry the subschema entry DN
*/
function setSubSchemaEntry($_subSchemaEntry)
{
$this->subSchemaEntry = $_subSchemaEntry;
}
/**
* sets the supported objectclasses
*
* @param array $_supportedObjectClasses the supported objectclasses
*/
function setSupportedObjectClasses($_supportedObjectClasses)
{
$this->supportedOIDs = $_supportedObjectClasses;
$this->supportedObjectClasses = array_flip($_supportedObjectClasses);
}
/**
* sets the supported objectclasses
*
* @param array $_supportedControl LDAP_CONTROL_* values
*/
function setSupportedControl(array $_supportedControl)
{
unset($_supportedControl['count']);
$this->suportedControl = $_supportedControl;
}
/**
* Check if given (multiple) LDAP_CONTROL_* args are (all) supported
*
* @param int $control LDAP_CONTROL_* value(s)
* @return boolean
*/
function supportedControl($control)
{
return count(array_intersect(func_get_args(), $this->suportedControl)) === func_num_args();
}
/**
* sets the version
*
* @param integer $_version the supported ldap version
*/
function setVersion($_version)
{
$this->version = $_version;
}
/**
* checks for supported objectclasses
*
* @return bool returns true if the ldap server supports this objectclass
*/
function supportsObjectClass($_objectClass)
{
if($this->supportedObjectClasses[strtolower($_objectClass)])
{
return true;
}
return false;
}
/**
* Query given ldap connection for available information
*
* @param resource $ds
* @param string $host
* @param int $version 2 or 3
* @return ldapserverinfo
*/
public static function get($ds, $host, $version=3)
{
$filter='(objectclass=*)';
$justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry','vendorname','supportedControl','forestFunctionality');
if(($sr = @ldap_read($ds, '', $filter, $justthese)))
{
if(($info = ldap_get_entries($ds, $sr)))
{
$ldapServerInfo = new ServerInfo($host);
$ldapServerInfo->setVersion($version);
// check for naming contexts
if($info[0]['namingcontexts'])
{
for($i=0; $i<$info[0]['namingcontexts']['count']; $i++)
{
$namingcontexts[] = $info[0]['namingcontexts'][$i];
}
$ldapServerInfo->setNamingContexts($namingcontexts);
}
// check for ldap server type
if($info[0]['structuralobjectclass'])
{
switch($info[0]['structuralobjectclass'][0])
{
case 'OpenLDAProotDSE':
$ldapServerType = self::OPENLDAP;
break;
default:
$ldapServerType = self::UNKNOWN;
break;
}
$ldapServerInfo->setServerType($ldapServerType);
}
// Check for ActiveDirectory by forestFunctionality and set Samba4 if vendorName includes samba
if(!empty($info[0]['forestfunctionality'][0]))
{
$ldapServerInfo->setServerType(!empty($info[0]['vendorname']) && stripos($info[0]['vendorname'][0], 'samba') !== false ?
self::SAMBA4 : self::WINDOWS_AD);
}
// check for subschema entry dn
if($info[0]['subschemasubentry'])
{
$subschemasubentry = $info[0]['subschemasubentry'][0];
$ldapServerInfo->setSubSchemaEntry($subschemasubentry);
}
if (!empty($info[0]['supportedcontrol']) && is_array($info[0]['supportedcontrol']))
{
$ldapServerInfo->setSupportedControl($info[0]['supportedcontrol']);
}
// create list of supported objetclasses
if(!empty($subschemasubentry))
{
$filter='(objectclass=*)';
$justthese = array('objectClasses');
if(($sr = ldap_read($ds, $subschemasubentry, $filter, $justthese)))
{
if(($info = ldap_get_entries($ds, $sr)))
{
if($info[0]['objectclasses']) {
for($i=0; $i<$info[0]['objectclasses']['count']; $i++)
{
$matches = null;
if(preg_match('/^\( (.*) NAME \'(\w*)\' /', $info[0]['objectclasses'][$i], $matches))
{
#_debug_array($matches);
if(count($matches) == 3)
{
$supportedObjectClasses[$matches[1]] = strtolower($matches[2]);
}
}
}
$ldapServerInfo->setSupportedObjectClasses($supportedObjectClasses);
}
}
}
}
}
}
return $ldapServerInfo;
}
}