summaryrefslogtreecommitdiffstats
path: root/frontends/php/include/classes
diff options
context:
space:
mode:
authorartem <artem@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2008-04-25 16:05:32 +0000
committerartem <artem@97f52cf1-0a1b-0410-bd0e-c28be96e8082>2008-04-25 16:05:32 +0000
commit96c8765eb19e1dc34d16ab6ac9260b572c6e1aba (patch)
treea34e9489f965d91c6550721542199a9ef966d51c /frontends/php/include/classes
parent26c11b74017649a63f34e2aeec68f946c6058a6c (diff)
downloadzabbix-96c8765eb19e1dc34d16ab6ac9260b572c6e1aba.tar.gz
zabbix-96c8765eb19e1dc34d16ab6ac9260b572c6e1aba.tar.xz
zabbix-96c8765eb19e1dc34d16ab6ac9260b572c6e1aba.zip
- [DEV-145] added Ldap authentication (Artem)
git-svn-id: svn://svn.zabbix.com/trunk@5657 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'frontends/php/include/classes')
-rw-r--r--frontends/php/include/classes/cldap.inc.php271
1 files changed, 271 insertions, 0 deletions
diff --git a/frontends/php/include/classes/cldap.inc.php b/frontends/php/include/classes/cldap.inc.php
new file mode 100644
index 00000000..b363a452
--- /dev/null
+++ b/frontends/php/include/classes/cldap.inc.php
@@ -0,0 +1,271 @@
+<?php
+/*
+** ZABBIX
+** Copyright (C) 2000-2008 SIA Zabbix
+**
+** 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; either version 2 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 General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**/
+// Based on LDAP authentication backend from Andreas Gohr <andi@splitbrain.org>, Chris Smith <chris@jalakaic.co.uk>
+// Modified by Aly <artem@zabbix.com>
+?>
+<?php
+class CLdap{
+ function CLdap($arg=array()){
+ $this->ds = false;
+ $this->info = array();
+
+ $this->cnf = array(
+ 'host'=> 'ldap://localhost',
+ 'port'=> '389',
+
+ 'bind_dn'=> 'uid=admin,ou=system',
+ 'bind_password'=> 'secret',
+
+ 'base_dn'=> 'ou=users,ou=system',
+
+ 'search_attribute'=> 'uid',
+ 'userfilter'=> '(%{attr}=%{user})',
+
+ 'groupkey'=> 'cn',
+
+ 'mapping'=> array(
+ 'alias'=> 'uid',
+ 'userid'=> 'uidnumber',
+ 'passwd'=> 'userpassword',
+ ),
+
+ 'referrals'=> 0,
+ 'version'=> 3,
+
+ 'starttls'=> false,
+ 'deref'=> null,
+ );
+
+
+ if(is_array($arg)){
+ $this->cnf = array_merge($this->cnf,$arg);
+ }
+
+ if(!function_exists('ldap_connect')) {
+ error('LDAP lib error. Cannot find needed functions');
+ return false;
+ }
+ }
+
+ function connect(){
+// connection already established
+ if($this->ds) return true;
+
+ $this->bound = 0;
+
+ if(!$this->ds = ldap_connect($this->cnf['host'],$this->cnf['port'])){
+ error("LDAP: couldn't connect to LDAP server");
+ return false;
+ }
+
+//set protocol version and dependend options
+ if($this->cnf['version']){
+ if(!ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, $this->cnf['version'])){
+ error('Setting LDAP Protocol version '.$this->cnf['version'].' failed');
+ }
+ else{
+//use TLS (needs version 3)
+ if(!empty($this->cnf['starttls'])){
+ if(!ldap_start_tls($this->ds)){
+ error('Starting TLS failed');
+ }
+ }
+// needs version 3
+ if(!empty($this->cnf['referrals'])) {
+ if(!ldap_set_option($this->ds, LDAP_OPT_REFERRALS,$this->cnf['referrals'])){
+ error('Setting LDAP referrals to off failed');
+ }
+ }
+ }
+ }
+
+//set deref mode
+ if(isset($this->cnf['deref'])){
+ if(!ldap_set_option($this->ds, LDAP_OPT_DEREF, $this->cnf['deref'])){
+ error('Setting LDAP Deref mode '.$this->cnf['deref'].' failed');
+ }
+ }
+
+ return true;
+ }
+
+ function checkPass($user,$pass){
+// reject empty password
+ if(empty($pass)) return false;
+ if(!$this->connect()) return false;
+
+// indirect user bind
+ if(!empty($this->cnf['bind_dn']) && !empty($this->cnf['bind_password'])){
+// use superuser credentials
+ if(!ldap_bind($this->ds,$this->cnf['bind_dn'],$this->cnf['bind_password'])){
+ error("LDAP: cannot bind by given DN");
+ return false;
+ }
+
+ $this->bound = 2;
+ }
+ else if(!empty($this->cnf['bind_dn']) && !empty($this->cnf['base_dn']) && !empty($this->cnf['userfilter'])){
+// special bind string
+ $dn = $this->makeFilter($this->cnf['bind_dn'],array('user'=>$user,'host'=>$this->cnf['host']));
+ }
+ else if(strpos($this->cnf['base_dn'], '%{user}')) {
+// direct user bind
+ $dn = $this->makeFilter($this->cnf['base_dn'],array('user'=>$user,'host'=>$this->cnf['host']));
+ }
+ else{
+// Anonymous bind
+ if(!ldap_bind($this->ds)){
+ error("LDAP: can not bind anonymously");
+ return false;
+ }
+ }
+
+// Try to bind to with the dn if we have one.
+ if(!empty($dn)) {
+// User/Password bind
+ if(!ldap_bind($this->ds,$dn,$pass)){
+ return false;
+ }
+
+ $this->bound = 1;
+ return true;
+ }
+ else{
+// See if we can find the user
+ $this->info = $this->getUserData($user);
+
+ if(empty($this->info['dn'])) {
+ return false;
+ }
+ else {
+ $dn = $this->info['dn'];
+ }
+
+//SDI($dn.' - '.$this->info['passwd'].' : '.$pass);
+
+// Try to bind with the dn provided
+ if(!ldap_bind($this->ds,$dn,$pass)){
+ return false;
+ }
+
+ $this->bound = 1;
+ return true;
+ }
+
+ return false;
+ }
+
+ function getUserData($user) {
+ if(!$this->connect()) return false;
+
+// force superuser bind if wanted and not bound as superuser yet
+ if(!empty($this->cnf['bind_dn']) && !empty($this->cnf['bind_password']) && ($this->bound < 2)){
+ if(!ldap_bind($this->ds,$this->cnf['bind_dn'],$this->cnf['bind_password'])){
+ return false;
+ }
+ $this->bound = 2;
+ }
+
+// with no superuser creds we continue as user or anonymous here
+ $info['user'] = $user;
+ $info['host'] = $this->cnf['host'];
+
+//get info for given user
+ $base = $this->makeFilter($this->cnf['base_dn'], $info);
+
+ if(isset($this->cnf['userfilter']) && !empty($this->cnf['userfilter'])) {
+ $filter = $this->makeFilter($this->cnf['userfilter'], $info);
+ }
+ else {
+ $filter = "(ObjectClass=*)";
+ }
+
+ $sr = ldap_search($this->ds, $base, $filter);
+ $result = ldap_get_entries($this->ds, $sr);
+
+// Don't accept more or less than one response
+ if($result['count'] != 1){
+// error('User not found.');
+ return false;
+ }
+
+ $user_result = $result[0];
+ ldap_free_result($sr);
+
+// general user info
+ $info['dn'] = $user_result['dn'];
+ $info['name'] = $user_result['cn'][0];
+ $info['grps'] = array();
+
+// overwrite if other attribs are specified.
+ if(is_array($this->cnf['mapping'])){
+ foreach($this->cnf['mapping'] as $localkey => $key) {
+ $info[$localkey] = $user_result[$key][0];
+ }
+ }
+ $user_result = array_merge($info,$user_result);
+
+//get groups for given user if grouptree is given
+ if(isset($this->cnf['grouptree']) && isset($this->cnf['groupfilter'])) {
+ $base = $this->makeFilter($this->cnf['grouptree'], $user_result);
+ $filter = $this->makeFilter($this->cnf['groupfilter'], $user_result);
+
+ $sr = ldap_search($this->ds, $base, $filter, array($this->cnf['groupkey']));
+
+ if(!$sr){
+ error("LDAP: Reading group memberships failed");
+ return false;
+ }
+
+ $result = ldap_get_entries($this->ds, $sr);
+
+ foreach($result as $grp){
+ if(!empty($grp[$this->cnf['groupkey']][0])){
+ $info['grps'][] = $grp[$this->cnf['groupkey']][0];
+ }
+ }
+ }
+
+// always add the default group to the list of groups
+ if(isset($conf['defaultgroup']) && !in_array($conf['defaultgroup'],$info['grps'])){
+ $info['grps'][] = $conf['defaultgroup'];
+ }
+
+ return $info;
+ }
+
+ function makeFilter($filter, $placeholders) {
+ $placeholders['attr'] = $this->cnf['search_attribute'];
+ preg_match_all("/%{([^}]+)/", $filter, $matches, PREG_PATTERN_ORDER);
+//replace each match
+ foreach ($matches[1] as $match) {
+//take first element if array
+ if(is_array($placeholders[$match])) {
+ $value = $placeholders[$match][0];
+ }
+ else{
+ $value = $placeholders[$match];
+ }
+ $filter = str_replace('%{'.$match.'}', $value, $filter);
+ }
+ return $filter;
+ }
+}
+?> \ No newline at end of file