diff --git a/phpgwapi/inc/class.ldap.inc.php b/phpgwapi/inc/class.ldap.inc.php new file mode 100644 index 0000000000..96d12e90da --- /dev/null +++ b/phpgwapi/inc/class.ldap.inc.php @@ -0,0 +1,251 @@ + * + * View and manipulate contact records using LDAP * + * ------------------------------------------------------------------------ * + * This library is part of the eGroupWare API * + * http://www.egroupware.org/api * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; version 2 of the License. * + \**************************************************************************/ + + /* $Id$ */ + + include_once(EGW_INCLUDE_ROOT.'/phpgwapi/inc/class.ldapserverinfo.inc.php'); + + /*! + @class contacts + @abstract Contact List System + @discussion Author: jengo/Milosch
+ This class provides a contact database scheme.
+ It attempts to be based on the vcard 2.1 standard, with mods as needed to make for more reasonable sql storage.
+ The LDAP schema used here may require installation of schema files available in the phpgwapi/doc/ldap dir. + Please see the README file there. + Syntax: CreateObject('phpgwapi.contacts');
+ Example1: $contacts = CreateObject('phpgwapi.contacts'); + */ + class ldap + { + /** + * @var resource $ds holds the LDAP link identifier + */ + var $ds; + + /** + * @var array $ldapServerInfo holds the detected information about the different ldap servers + */ + var $ldapServerInfo; + + /** + * the constructor for this class + */ + function ldap() { + $this->restoreSessionData(); + } + + /** + * escapes a string for use in searchfilters meant for ldap_search. + * + * Escaped Characters are: '*', '(', ')', ' ', '\', NUL + * It's actually a PHP-Bug, that we have to escape space. + * For all other Characters, refer to RFC2254. + * @param $string either a string to be escaped, or an array of values to be escaped + */ + function getLDAPServerInfo($_host) + { + if(is_a($this->ldapServerInfo[$_host], 'ldapserverinfo')) { + return $this->ldapServerInfo[$_host]; + } + + return false; + } + + /** + * escapes a string for use in searchfilters meant for ldap_search. + * + * Escaped Characters are: '*', '(', ')', ' ', '\', NUL + * It's actually a PHP-Bug, that we have to escape space. + * For all other Characters, refer to RFC2254. + * @param $string either a string to be escaped, or an array of values to be escaped + */ + function ldapAddslashes($string='') + { + return str_replace(array('\\','*','(',')','\0',' '),array('\\\\','\*','\(','\)','\\0','\20'),$string); + } + + /** + * connect to the ldap server and return a handle + * + * @param $host ldap host + * @param $dn ldap dn + * @param $passwd ldap pw + */ + function ldapConnect($host='', $dn='', $passwd='') + { + if(!function_exists('ldap_connect')) + { + /* log does not exist in setup(, yet) */ + if(is_object($GLOBALS['egw']->log)) + { + $GLOBALS['egw']->log->message('F-Abort, LDAP support unavailable'); + $GLOBALS['egw']->log->commit(); + } + + printf('Error: LDAP support unavailable
',$host); + return False; + } + + if(!$host) + { + $host = $GLOBALS['egw_info']['server']['ldap_host']; + } + + if(!$dn) + { + $dn = $GLOBALS['egw_info']['server']['ldap_root_dn']; + } + + if(!$passwd) + { + $passwd = $GLOBALS['egw_info']['server']['ldap_root_pw']; + } + + // connects to ldap server + if(!$this->ds = ldap_connect("ldap://$host", 389)) + { + /* log does not exist in setup(, yet) */ + if(is_object($GLOBALS['egw']->log)) + { + $GLOBALS['egw']->log->message('F-Abort, Failed connecting to LDAP server'); + $GLOBALS['egw']->log->commit(); + } + + printf("Error: Can't connect to LDAP server %s!
",$host); + echo function_backtrace(1); + return False; + } + + if(!isset($this->ldapServerInfo[$host])) { + //print "no ldap server info found
"; + $ldapbind = ldap_bind($this->ds, '', ''); + $filter='(objectclass=*)'; + $justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry'); + + if($sr=ldap_read($this->ds, '', $filter, $justthese)) { + if($info = ldap_get_entries($this->ds, $sr)) { + + $ldapServerInfo = new ldapserverinfo(); + + // check for supported ldap version + if($info[0]['supportedldapversion']) { + for($i=0; $i<$info[0]['supportedldapversion']['count']; $i++) { + $supportedVersion = ($supportedVersion < $info[0]['supportedldapversion'][$i] ? $info[0]['supportedldapversion'][$i] : $supportedVersion); + } + $ldapServerInfo->setVersion($supportedVersion); + } + + // 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 = OPENLDAP_LDAPSERVER; + break; + default: + $ldapServerType = UNKNOWN_LDAPSERVER; + break; + } + $ldapServerInfo->setServerType($ldapServerType); + } + + // check for subschema entry dn + if($info[0]['subschemasubentry']) { + $subschemasubentry = $info[0]['subschemasubentry'][0]; + $ldapServerInfo->setSubSchemaEntry($subschemasubentry); + } + + // create list of supported objetclasses + if(!empty($subschemasubentry)) { + $filter='(objectclass=*)'; + $justthese = array('objectClasses'); + + if($sr=ldap_read($this->ds, $subschemasubentry, $filter, $justthese)) { + if($info = ldap_get_entries($this->ds, $sr)) { + if($info[0]['objectclasses']) { + for($i=0; $i<$info[0]['objectclasses']['count']; $i++) { + $pattern = '/^\( (.*) NAME \'(\w*)\' /'; + if(preg_match($pattern, $info[0]['objectclasses'][$i], $matches)) { + if(count($matches) == 3) { + $supportedObjectClasses[$matches[1]] = strtolower($matches[2]); + } + } + } + $ldapServerInfo->setSupportedObjectClasses($supportedObjectClasses); + } + } + } + } + $this->ldapServerInfo[$host] = $ldapServerInfo; + } + } else { + $this->ldapServerInfo[$host] = false; + } + $this->saveSessionData(); + } else { + $ldapServerInfo = $this->ldapServerInfo[$host]; + } + + if(is_a($ldapServerInfo, 'ldapserverinfo') && $ldapServerInfo->getVersion() > 2) { + ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3); + } + + if(!ldap_bind($this->ds,$dn,$passwd)) + { + if(is_object($GLOBALS['egw']->log)) + { + $GLOBALS['egw']->log->message('F-Abort, Failed binding to LDAP server'); + $GLOBALS['egw']->log->commit(); + } + + printf("Error: Can't bind to LDAP server: %s!
",$dn); + echo function_backtrace(1); + return False; + } + + return $this->ds; + } + + /** + * disconnect from the ldap server + */ + function ldapDisconnect() { + if(is_resource($this->ds)) { + ldap_unbind($this->ds); + } + } + + /** + * restore the session data + */ + function restoreSessionData() { + $this->ldapServerInfo = $GLOBALS['egw']->session->appsession('ldapServerInfo'); + } + /** + * save the session data + */ + function saveSessionData() { + $GLOBALS['egw']->session->appsession('ldapServerInfo','',$this->ldapServerInfo); + } + + } +?> diff --git a/phpgwapi/inc/class.ldapserverinfo.inc.php b/phpgwapi/inc/class.ldapserverinfo.inc.php new file mode 100644 index 0000000000..1983a320b0 --- /dev/null +++ b/phpgwapi/inc/class.ldapserverinfo.inc.php @@ -0,0 +1,137 @@ + * + * View and manipulate contact records using LDAP * + * ------------------------------------------------------------------------ * + * This library is part of the eGroupWare API * + * http://www.egroupware.org/api * + * -------------------------------------------- * + * This program is free software; you can redistribute it and/or modify it * + * under the terms of the GNU General Public License as published by the * + * Free Software Foundation; version 2 of the License. * + \**************************************************************************/ + + /* $Id$ */ + + define('UNKNOWN_LDAPSERVER',0); + define('OPENLDAP_LDAPSERVER',1); + + /*! + @class contacts + @abstract Contact List System + @discussion Author: jengo/Milosch
+ This class provides a contact database scheme.
+ It attempts to be based on the vcard 2.1 standard, with mods as needed to make for more reasonable sql storage.
+ The LDAP schema used here may require installation of schema files available in the phpgwapi/doc/ldap dir. + Please see the README file there. + Syntax: CreateObject('phpgwapi.contacts');
+ Example1: $contacts = CreateObject('phpgwapi.contacts'); + */ + class ldapserverinfo + { + /** + * @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(); + + /** + * the constructor for this class + */ + /*function ldapserverinfo() { + }*/ + + /** + * 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; + } + + /** + * 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 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; + } else { + return false; + } + } + } +?>