Page MenuHomePhorge

No OneTemporary

diff --git a/config/config.ini.sample b/config/config.ini.sample
index c20a2de..b22159e 100644
--- a/config/config.ini.sample
+++ b/config/config.ini.sample
@@ -1,87 +1,87 @@
;; Kolab Free/Busy Service configuration
;; Require HTTP authentication to access this service
[httpauth]
;; Example for static auth credentials
; type = static
; username = "<user>"
; password = "<pass>"
;; Example for LDAP-based authentication
; type = ldap
; host = ldap://localhost:389
; bind_dn = "uid=kolab-service,ou=Special Users,dc=yourdomain,dc=com"
; bind_pw = "<service-bind-pw>"
; base_dn = "dc=yourdomain,dc=com"
; filter = "(&(|(mail=%s)(alias=%s)(uid=%s))(objectclass=inetorgperson))" ; optional, %s is replaced by the username
;; Allow privileged access from these IPs
[trustednetworks]
allow = 127.0.0.1,
192.168.0.0/16,
10.10.*,
::1
;; Logging configuration
[log]
driver = file ; supported drivers: file, syslog
path = ./log
name = freebusy
level = 300 ; (100 = Debug, 200 = Info, 300 = Warn, 400 = Error, 500 = Critical)
;; Directories to resolve email addresses and their f/b source locations
;; try local filesystem first
[directory "local"]
type = static
filter = "@yourdomain"
fbsource = file:/var/lib/kolab-freebusy/%s.ifb
;; check if primary email address hits a cache file (saves LDAP lookups)
[directory "local-cache"]
type = static
fbsource = file:/var/cache/kolab-freebusy/%s.ifb
expires = 10m
;; local Kolab directory server
[directory "kolab-ldap"]
type = ldap
host = ldap://localhost:389
bind_dn = "uid=kolab-service,ou=Special Users,dc=yourdomain,dc=com"
bind_pw = "<service-bind-pw>"
-base_dn = "dc=yourdomain,dc=com"
+base_dn = "People,dc=yourdomain,dc=com" ; use %dc as placeholder for the domain part extracted from the request string
filter = "(&(objectClass=kolabInetOrgPerson)(|(uid=%s)(mail=%s)(alias=%s)))"
attributes = mail, sn, alias
lc_attributes = sn
mail_attributes = mail, alias
fbsource = file:/var/lib/kolab-freebusy/%mail.ifb
loglevel = 200 ; Info
;; resolve Kolab resources from LDAP and fetch calendar from IMAP
[directory "kolab-resources"]
type = ldap
host = ldap://localhost:389
bind_dn = "uid=kolab-service,ou=Special Users,dc=yourdomain,dc=com"
bind_pw = "<service-bind-pw>"
base_dn = "ou=Resources,dc=yourdomain,dc=com"
filter = "(&(objectClass=kolabsharedfolder)(mail=%s))"
attributes = mail, kolabtargetfolder
fbsource = "imap://cyrus-admin:<admin-pass>@localhost/%kolabtargetfolder?acl=lrs"
cacheto = /var/cache/kolab-freebusy/%mail.ifb
expires = 10m
loglevel = 100 ; Debug
;; external MS Exchange 2010 server
[directory "exchange"]
type = static
filter = "@microsoft.com$"
fbsource = https://externalhost/free-busy/%s.ics
format = Exchange2010
;; further examples of fbsource URIs
; - fetch data from another server by HTTP(s)
; fbsource = "https://fb-service-user:imap-password@kolab-server/freebusy/%mail.ifb"
; - read directoy from a users calendars (all) using IMAP proxy authentication
; fbsource = "imap://%mail:<admin-pass>@localhost/?proxy_auth=cyrus-admin"
diff --git a/lib/Kolab/FreeBusy/DirectoryLDAP.php b/lib/Kolab/FreeBusy/DirectoryLDAP.php
index ea920d0..0a4ecff 100644
--- a/lib/Kolab/FreeBusy/DirectoryLDAP.php
+++ b/lib/Kolab/FreeBusy/DirectoryLDAP.php
@@ -1,132 +1,135 @@
<?php
/**
* This file is part of the Kolab Server Free/Busy Service
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\FreeBusy;
// PEAR modules operate in global namespace
use \Net_LDAP3;
use \Kolab\Config;
use \Monolog\Logger as Monolog;
/**
* Implementation of an address lookup using an LDAP directory
*/
class DirectoryLDAP extends Directory
{
private $ldap;
private $logger;
private $ready = false;
/**
* Default constructor loading directory configuration
*/
public function __construct($config)
{
$this->config = $config;
$host = parse_url($config['host']);
$ldap_config = array(
'hosts' => array($host['host']),
'port' => $host['port'] ?: 389,
'use_tls' => $host['scheme'] == 'tls' || $host['scheme'] == 'ldaps',
'root_dn' => $config['base_dn'],
'log_hook' => array($this, 'log'),
) + $config;
// instantiate Net_LDAP3 and connect with logger
$this->logger = Logger::get('ldap', intval($config['loglevel']));
$this->ldap = new Net_LDAP3($ldap_config);
// connect + bind to LDAP server
if ($this->ldap->connect()) {
$this->ready = $this->ldap->bind($config['bind_dn'], $config['bind_pw']);
}
if ($this->ready) {
$this->logger->addInfo("Connected to $config[host] with '$config[bind_dn]'");
}
else {
$this->logger->addWarning("Connectiion to $config[host] with '$config[bind_dn]' failed!");
}
}
/**
* Callback for Net_LDAP3 logging
*/
public function log($level, $msg)
{
// map PHP log levels to Monolog levels
static $loglevels = array(
LOG_DEBUG => Monolog::DEBUG,
LOG_NOTICE => Monolog::NOTICE,
LOG_INFO => Monolog::INFO,
LOG_WARNING => Monolog::WARNING,
LOG_ERR => Monolog::ERROR,
LOG_CRIT => Monolog::CRITICAL,
LOG_ALERT => Monolog::ALERT,
LOG_EMERG => Monolog::EMERGENCY,
);
$msg = is_array($msg) ? join('; ', $msg) : strval($msg);
$this->logger->addRecord($loglevels[$level], $msg);
}
/**
* @see Directory::resolve()
*/
public function resolve($user)
{
$result = array('s' => $user);
if ($this->ready) {
- // search with configured filter
- $filter = preg_replace('/%s/i', $user, $this->config['filter']);
- $ldapresult = $this->ldap->search($this->config['base_dn'], $filter, 'sub', Config::convert($this->config['attributes'], Config::ARR));
+ // search with configured base_dn and filter
+ list($u, $d) = explode('@', $user);
+ $replaces = array('%dc' => 'dc=' . str_replace('.', ',dc=', $d), '%u' => $u);
+ $base_dn = strtr($this->config['base_dn'], $replaces);
+ $filter = preg_replace('/%s/i', $user, strtr($this->config['filter'], $replaces));
+ $ldapresult = $this->ldap->search($base_dn, $filter, 'sub', Config::convert($this->config['attributes'], Config::ARR));
// got a valid result
if ($ldapresult && $ldapresult->count()) {
$ldapresult->rewind();
$entry = Net_LDAP3::normalize_entry($ldapresult->current()); // get the first entry
$this->logger->addInfo("Found " . $ldapresult->count() . " entries for $filter", $entry);
// convert entry attributes to strings and add them to the final result hash array
foreach ($entry as $k => $v) {
if (is_array($v) && count($v) > 1) {
$result[$k] = array_map('strval', $v);
}
else if (!empty($v)) {
$result[$k] = strval(is_array($v) ? $v[0] : $v);
}
}
return $result;
}
$this->logger->addInfo("No entry found for $filter");
}
return false;
}
}
diff --git a/lib/Kolab/FreeBusy/HTTPAuth.php b/lib/Kolab/FreeBusy/HTTPAuth.php
index c4bd288..4be5be4 100644
--- a/lib/Kolab/FreeBusy/HTTPAuth.php
+++ b/lib/Kolab/FreeBusy/HTTPAuth.php
@@ -1,136 +1,141 @@
<?php
/**
* This file is part of the Kolab Server Free/Busy Service
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\FreeBusy;
use \Net_LDAP3;
use \Monolog\Logger as Monolog;
/**
* Static class to process HTTP authentication to this service
*/
class HTTPAuth
{
private static $logger;
/**
* Validate HTTP basic auth against the configured backend
*/
public static function check($config)
{
$logger = Logger::get('httpauth');
// no http auth submitted, abort!
if (empty($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
$logger->addDebug('No HTTP auth submitted');
return false;
}
switch ($config['type']) {
case 'static':
return self::checkStatic($config, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
case 'ldap':
return self::checkLDAP($config, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
default:
$logger->addWarning('Unsupported auth type ' . $config['type']);
break;
}
return false;
}
/**
* Validate static user credentials from config
*/
private static function checkStatic($config, $user, $pass)
{
$valid = $user == $config['username'] && $pass == $config['password'];
Logger::get('httpauth')->addInfo("Static: authenticating user '$user': " . ($valid ? 'SUCCESS' : 'FAILURE'));
return $valid;
}
/**
* Validate user credentials against the configured LDAP backend
*/
private static function checkLDAP($config, $user, $pass)
{
self::$logger = Logger::get('httpauth', intval($config['loglevel']));
+ list($u, $d) = explode('@', $user);
+ $replaces = array('%dc' => 'dc=' . str_replace('.', ',dc=', $d), '%u' => $u);
+ $config['base_dn'] = strtr($config['base_dn'], $replaces);
+ $config['filter'] = strtr($config['filter'], $replaces);
+
$host = parse_url($config['host']);
$ldap_config = array(
'hosts' => array($host['host']),
'port' => $host['port'] ?: 389,
'use_tls' => $host['scheme'] == 'tls' || $host['scheme'] == 'ldaps',
'root_dn' => $config['base_dn'],
'filter' => $config['filter'],
'service_bind_dn' => $config['bind_dn'],
'service_bind_pw' => $config['bind_pw'],
'log_hook' => 'Kolab\FreeBusy\HTTPAuth::ldapLog',
);
// instantiate Net_LDAP3 and connect with logger
$ldap = new Net_LDAP3($ldap_config);
// connect + bind to LDAP server
if ($ldap->connect()) {
self::$logger->addDebug("LDAP: connected to $config[host] with '$config[bind_dn]'");
// extract domain part from base_dn
$dn_domain = ldap_explode_dn($config['base_dn'], 1);
unset($dn_domain['count']);
$domain = join('.', $dn_domain);
$valid = (bool)$ldap->login($user, $pass, $domain);
}
else {
self::$logger->addWarning("LDAP: connectiion to $config[host] with '$config[bind_dn]' failed!");
}
self::$logger->addInfo("LDAP: authenticating user '$user': " . ($valid ? 'SUCCESS' : 'FAILURE'));
return $valid;
}
/**
* Callback for Net_LDAP3 logging
*/
public static function ldapLog($level, $msg)
{
// map PHP log levels to Monolog levels
static $loglevels = array(
LOG_DEBUG => Monolog::DEBUG,
LOG_NOTICE => Monolog::NOTICE,
LOG_INFO => Monolog::INFO,
LOG_WARNING => Monolog::WARNING,
LOG_ERR => Monolog::ERROR,
LOG_CRIT => Monolog::CRITICAL,
LOG_ALERT => Monolog::ALERT,
LOG_EMERG => Monolog::EMERGENCY,
);
$msg = is_array($msg) ? join('; ', $msg) : strval($msg);
self::$logger->addRecord($loglevels[$level], $msg);
}
}
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Mon, Sep 15, 2:29 PM (1 d, 16 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
287569
Default Alt Text
(12 KB)

Event Timeline