2012-04-14 20:05:29 +04:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ownCloud – LDAP lib
|
|
|
|
|
*
|
|
|
|
|
* @author Arthur Schiwon
|
|
|
|
|
* @copyright 2012 Arthur Schiwon blizzz@owncloud.com
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 3 of the License, or any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Affero General Public
|
|
|
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
2012-04-23 23:11:54 +04:00
|
|
|
|
define('LDAP_GROUP_MEMBER_ASSOC_ATTR','uniquemember');
|
2012-04-15 15:37:35 +04:00
|
|
|
|
|
2012-04-16 20:03:02 +04:00
|
|
|
|
//needed to unbind, because we use OC_LDAP only statically
|
|
|
|
|
class OC_LDAP_DESTRUCTOR {
|
|
|
|
|
public function __destruct() {
|
|
|
|
|
OC_LDAP::destruct();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-15 15:37:35 +04:00
|
|
|
|
class OC_LDAP {
|
2012-04-14 20:05:29 +04:00
|
|
|
|
static protected $ldapConnectionRes = false;
|
|
|
|
|
static protected $configured = false;
|
|
|
|
|
|
|
|
|
|
//cached settings
|
|
|
|
|
static protected $ldapHost;
|
|
|
|
|
static protected $ldapPort;
|
|
|
|
|
static protected $ldapBase;
|
2012-04-23 15:04:58 +04:00
|
|
|
|
static protected $ldapBaseUsers;
|
|
|
|
|
static protected $ldapBaseGroups;
|
2012-04-14 20:05:29 +04:00
|
|
|
|
static protected $ldapAgentName;
|
|
|
|
|
static protected $ldapAgentPassword;
|
|
|
|
|
static protected $ldapTLS;
|
|
|
|
|
static protected $ldapNoCase;
|
2012-04-15 16:21:38 +04:00
|
|
|
|
// user and group settings, that are needed in both backends
|
2012-04-15 16:47:33 +04:00
|
|
|
|
static public $ldapUserDisplayName;
|
2012-04-15 16:21:38 +04:00
|
|
|
|
|
2012-04-14 20:05:29 +04:00
|
|
|
|
static public function init() {
|
|
|
|
|
self::readConfiguration();
|
|
|
|
|
self::establishConnection();
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-16 20:03:02 +04:00
|
|
|
|
static public function destruct() {
|
|
|
|
|
@ldap_unbind(self::$ldapConnectionRes);
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-15 16:47:33 +04:00
|
|
|
|
static public function conf($key) {
|
2012-04-16 15:27:20 +04:00
|
|
|
|
$availableProperties = array(
|
|
|
|
|
'ldapUserDisplayName',
|
|
|
|
|
);
|
2012-04-15 16:47:33 +04:00
|
|
|
|
|
|
|
|
|
if(in_array($key, $availableProperties)) {
|
|
|
|
|
return self::$$key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-23 23:11:54 +04:00
|
|
|
|
/**
|
|
|
|
|
* @brief reads a given attribute for an LDAP record identified by a DN
|
|
|
|
|
* @param $dn the record in question
|
|
|
|
|
* @param $attr the attribute that shall be retrieved
|
|
|
|
|
* @returns the value on success, false otherwise
|
|
|
|
|
*
|
|
|
|
|
* Reads an attribute from an LDAP entry
|
|
|
|
|
*/
|
|
|
|
|
static public function readAttribute($dn, $attr) {
|
|
|
|
|
$attr = strtolower($attr);
|
|
|
|
|
$cr = self::getConnectionResource();
|
|
|
|
|
|
|
|
|
|
$rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
|
|
|
|
|
$er = ldap_first_entry($cr, $rr);
|
|
|
|
|
$result = ldap_get_attributes($cr, $er);
|
|
|
|
|
if($result['count'] > 0){
|
|
|
|
|
return $result[$attr][0];
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-23 15:04:58 +04:00
|
|
|
|
/**
|
|
|
|
|
* @brief executes an LDAP search, optimized for Users
|
|
|
|
|
* @param $filter the LDAP filter for the search
|
|
|
|
|
* @param $attr optional, when a certain attribute shall be filtered out
|
|
|
|
|
* @returns array with the search result
|
|
|
|
|
*
|
|
|
|
|
* Executes an LDAP search
|
|
|
|
|
*/
|
|
|
|
|
static public function searchUsers($filter, $attr = null) {
|
|
|
|
|
return self::search($filter, self::$ldapBaseUsers, $attr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief executes an LDAP search, optimized for Groups
|
|
|
|
|
* @param $filter the LDAP filter for the search
|
|
|
|
|
* @param $attr optional, when a certain attribute shall be filtered out
|
|
|
|
|
* @returns array with the search result
|
|
|
|
|
*
|
|
|
|
|
* Executes an LDAP search
|
|
|
|
|
*/
|
|
|
|
|
static public function searchGroups($filter, $attr = null) {
|
|
|
|
|
return self::search($filter, self::$ldapBaseGroups, $attr);
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-14 20:26:46 +04:00
|
|
|
|
/**
|
|
|
|
|
* @brief executes an LDAP search
|
|
|
|
|
* @param $filter the LDAP filter for the search
|
2012-04-23 15:04:58 +04:00
|
|
|
|
* @param $base the LDAP subtree that shall be searched
|
2012-04-14 20:26:46 +04:00
|
|
|
|
* @param $attr optional, when a certain attribute shall be filtered out
|
|
|
|
|
* @returns array with the search result
|
|
|
|
|
*
|
|
|
|
|
* Executes an LDAP search
|
|
|
|
|
*/
|
2012-04-23 15:04:58 +04:00
|
|
|
|
static private function search($filter, $base, $attr = null) {
|
|
|
|
|
$sr = ldap_search(self::getConnectionResource(), $base, $filter, array($attr));
|
2012-04-14 20:05:29 +04:00
|
|
|
|
$findings = ldap_get_entries(self::getConnectionResource(), $sr );
|
|
|
|
|
|
|
|
|
|
if(!is_null($attr)) {
|
|
|
|
|
$selection = array();
|
|
|
|
|
foreach($findings as $item) {
|
|
|
|
|
if(isset($item[strtolower($attr)])) {
|
|
|
|
|
$selection[] = $item[strtolower($attr)][0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $selection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $findings;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-15 15:37:35 +04:00
|
|
|
|
/**
|
|
|
|
|
* @brief combines the input filters with AND
|
|
|
|
|
* @param $filters array, the filters to connect
|
|
|
|
|
* @returns the combined filter
|
|
|
|
|
*
|
|
|
|
|
* Combines Filter arguments with AND
|
|
|
|
|
*/
|
|
|
|
|
static public function combineFilterWithAnd($filters) {
|
|
|
|
|
return self::combineFilter($filters,'&');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief combines the input filters with AND
|
|
|
|
|
* @param $filters array, the filters to connect
|
|
|
|
|
* @returns the combined filter
|
|
|
|
|
*
|
|
|
|
|
* Combines Filter arguments with AND
|
|
|
|
|
*/
|
|
|
|
|
static public function combineFilterWithOr($filters) {
|
|
|
|
|
return self::combineFilter($filters,'|');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief combines the input filters with given operator
|
|
|
|
|
* @param $filters array, the filters to connect
|
|
|
|
|
* @param $operator either & or |
|
|
|
|
|
* @returns the combined filter
|
|
|
|
|
*
|
|
|
|
|
* Combines Filter arguments with AND
|
|
|
|
|
*/
|
|
|
|
|
static private function combineFilter($filters, $operator) {
|
|
|
|
|
$combinedFilter = '('.$operator;
|
|
|
|
|
foreach($filters as $filter) {
|
|
|
|
|
if(substr($filter,0,1) != '(') {
|
|
|
|
|
$filter = '('.$filter.')';
|
|
|
|
|
}
|
|
|
|
|
$combinedFilter.=$filter;
|
|
|
|
|
}
|
|
|
|
|
$combinedFilter.=')';
|
|
|
|
|
return $combinedFilter;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-14 20:26:46 +04:00
|
|
|
|
/**
|
|
|
|
|
* Returns the LDAP handler
|
|
|
|
|
*/
|
2012-04-14 20:05:29 +04:00
|
|
|
|
static private function getConnectionResource() {
|
|
|
|
|
if(!self::$ldapConnectionRes) {
|
|
|
|
|
self::init();
|
|
|
|
|
}
|
|
|
|
|
return self::$ldapConnectionRes;
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-14 20:26:46 +04:00
|
|
|
|
/**
|
|
|
|
|
* Caches the general LDAP configuration.
|
|
|
|
|
*/
|
2012-04-14 20:05:29 +04:00
|
|
|
|
static private function readConfiguration() {
|
|
|
|
|
if(!self::$configured) {
|
2012-04-15 16:21:38 +04:00
|
|
|
|
self::$ldapHost = OC_Appconfig::getValue('user_ldap', 'ldap_host', '');
|
|
|
|
|
self::$ldapPort = OC_Appconfig::getValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT);
|
|
|
|
|
self::$ldapAgentName = OC_Appconfig::getValue('user_ldap', 'ldap_dn','');
|
|
|
|
|
self::$ldapAgentPassword = OC_Appconfig::getValue('user_ldap', 'ldap_password','');
|
2012-04-23 15:04:58 +04:00
|
|
|
|
self::$ldapBase = OC_Appconfig::getValue('user_ldap', 'ldap_base', '');
|
|
|
|
|
self::$ldapBaseUsers = OC_Appconfig::getValue('user_ldap', 'ldap_base_users',self::$ldapBase);
|
|
|
|
|
self::$ldapBaseGroups = OC_Appconfig::getValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
|
2012-04-15 16:21:38 +04:00
|
|
|
|
self::$ldapTLS = OC_Appconfig::getValue('user_ldap', 'ldap_tls',0);
|
|
|
|
|
self::$ldapNoCase = OC_Appconfig::getValue('user_ldap', 'ldap_nocase', 0);
|
|
|
|
|
self::$ldapUserDisplayName = OC_Appconfig::getValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME);
|
2012-04-14 20:05:29 +04:00
|
|
|
|
|
2012-04-16 19:28:58 +04:00
|
|
|
|
if(
|
|
|
|
|
!empty(self::$ldapHost)
|
|
|
|
|
&& !empty(self::$ldapPort)
|
|
|
|
|
&& (
|
|
|
|
|
(!empty(self::$ldapAgentName) && !empty(self::$ldapAgentPassword))
|
|
|
|
|
|| ( empty(self::$ldapAgentName) && empty(self::$ldapAgentPassword))
|
|
|
|
|
)
|
|
|
|
|
&& !empty(self::$ldapBase)
|
2012-04-23 15:04:58 +04:00
|
|
|
|
&& !empty(self::$ldapBaseUsers)
|
|
|
|
|
&& !empty(self::$ldapBaseGroups)
|
2012-04-16 19:28:58 +04:00
|
|
|
|
&& !empty(self::$ldapUserDisplayName)
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
self::$configured = true;
|
|
|
|
|
}
|
2012-04-14 20:05:29 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-04-14 20:26:46 +04:00
|
|
|
|
/**
|
|
|
|
|
* Connects and Binds to LDAP
|
|
|
|
|
*/
|
2012-04-14 20:05:29 +04:00
|
|
|
|
static private function establishConnection() {
|
2012-04-16 19:28:58 +04:00
|
|
|
|
if(!self::$configured) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-04-14 20:05:29 +04:00
|
|
|
|
if(!self::$ldapConnectionRes) {
|
|
|
|
|
self::$ldapConnectionRes = ldap_connect(self::$ldapHost, self::$ldapPort);
|
|
|
|
|
if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
|
|
|
|
|
if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
|
|
|
|
|
if(self::$ldapTLS) {
|
|
|
|
|
ldap_start_tls(self::$ldapConnectionRes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$ldapLogin = @ldap_bind(self::$ldapConnectionRes, self::$ldapAgentName, self::$ldapAgentPassword );
|
|
|
|
|
if(!$ldapLogin) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|