]> git.wh0rd.org - tt-rss.git/commitdiff
Merge pull request #61 from hydrian/master
authorAndrew Dolgov <cthulhoo@gmail.com>
Tue, 19 Mar 2013 15:41:04 +0000 (08:41 -0700)
committerAndrew Dolgov <cthulhoo@gmail.com>
Tue, 19 Mar 2013 15:41:04 +0000 (08:41 -0700)
Initial pull req. for auth_ldap

plugins/auth_ldap/init.php [new file with mode: 0644]

diff --git a/plugins/auth_ldap/init.php b/plugins/auth_ldap/init.php
new file mode 100644 (file)
index 0000000..e1a4c49
--- /dev/null
@@ -0,0 +1,135 @@
+<?php
+/** 
+ * Tiny Tiny RSS plugin for LDAP authentication 
+ * @author hydrian (ben.tyger@tygerclan.net)
+ * @copyright GPL2
+ *  Requires php-ldap and PEAR Net::LDAP2
+ */
+
+/**
+ *  Configuration
+ *  Put the following options in config.php and customize them for your environment
+ *
+ *     define('LDAP_AUTH_SERVER_URI, 'ldaps://LDAPServerHostname:port/');
+ *     define('LDAP_AUTH_USETLS, FALSE); // Enable TLS Support for ldaps://
+ *     define('LDAP_AUTH_ALLOW_UNTRUSTED_CERT', TRUE); // Allows untrusted certificate
+ *     define('LDAP_AUTH_BINDDN', 'cn=serviceaccount,dc=example,dc=com');
+ *     define('LDAP_AUTH_BINDPW', 'ServiceAccountsPassword');
+ *     define('LDAP_AUTH_BASEDN', 'dc=example,dc=com');
+ *     // ??? will be replaced with the entered username(escaped) at login 
+ *     define('LDAP_AUTH_SEARCHFILTER', '(&(objectClass=person)(uid=???))');
+ */
+
+/**
+ *     Notes -
+ *     LDAP search does not support follow ldap referals. Referals are disabled to 
+ *     allow proper login.  This is particular to Active Directory.  
+ * 
+ *     Also group membership can be supported if the user object contains the
+ *     the group membership via attributes.  The following LDAP servers can 
+ *     support this.   
+ *      * Active Directory
+ *   * OpenLDAP support with MemberOf Overlay
+ *
+ */
+class Auth_Ldap extends Plugin implements IAuthModule {
+
+       private $link;
+       private $host;
+       private $base;
+
+       function about() {
+               return array(0.01,
+                       "Authenticates against an LDAP server (configured in config.php)",
+                       "hydrian",
+                       true);
+       }
+
+       function init($host) {
+               $this->link = $host->get_link();
+               $this->host = $host;
+               $this->base = new Auth_Base($this->link);
+
+               $host->add_hook($host::HOOK_AUTH_USER, $this);
+       }
+       
+       private function _log($msg) {
+               trigger_error($msg, E_USER_WARN);
+       }
+
+       function authenticate($login, $password) {
+               if ($login && $password) {
+                       if (!function_exists('ldap_connect')) {
+                               trigger_error('auth_ldap requires PHP\'s PECL LDAP package installed.');
+                               return FALSE;
+                       }
+                       if (!require_once('Net/LDAP2.php')) { 
+                               trigger_error('auth_ldap requires the PEAR package Net::LDAP2');
+                               return FALSE;
+                       }
+                       $parsedURI=parse_url(LDAP_AUTH_SERVER_URI);
+                       if ($parsedURI === FALSE) {
+                               $this->_log('Could not parse LDAP_AUTH_SERVER_URI in config.php');
+                               return FALSE;
+                       }
+                       $ldapConnParams=array(
+                               'host'=>$parsedURI['scheme'].'://'.$parsedURI['host'],
+                               'basedn'=>LDAP_AUTH_BASEDN,
+                               'options' => array('LDAP_OPT_REFERRALS' => 0)
+                       );
+                       $ldapConnParams['starttls']= defined('LDAP_AUTH_USETLS') ?
+                               LDAP_AUTH_USETLS : FALSE;
+                                       
+                       if (is_int($parsedURI['port'])) {
+                               $ldapConnParams['port']=$parsedURI['port'];
+                       }
+                       // Making connection to LDAP server
+                       if (LDAP_AUTH_ALLOW_UNTRUSTED_CERT === TRUE) {
+                               putenv('LDAPTLS_REQCERT=never');
+                       }
+                       $ldapConn = Net_LDAP2::connect($ldapConnParams);
+                       if (Net_LDAP2::isError($ldapConn)) {
+                               $this->_log('Could not connect to LDAP Server: '.$ldapConn->getMessage());
+                               return FALSE;
+                       }
+                       // Bind with service account
+                       $binding=$ldapConn->bind(LDAP_AUTH_BINDDN, LDAP_AUTH_BINDPW);
+                       if (Net_LDAP2::isError($binding)) {
+                               $this->_log('Cound not bind service account: '.$binding->getMessage());
+                               return FALSE;
+                       } 
+                       //Searching for user
+                       $completedSearchFiler=str_replace('???',$login,LDAP_AUTH_SEARCHFILTER);
+                       $filterObj=Net_LDAP2_Filter::parse($completedSearchFiler);
+                       $searchResults=$ldapConn->search(LDAP_AUTH_BASEDN, $filterObj);
+                       if (Net_LDAP2::isError($searchResults)) {
+                               $this->_log('LDAP Search Failed: '.$searchResults->getMessage());
+                               return FALSE;
+                       } elseif ($searchResults->count() === 0) {
+                               return FALSE;
+                       } elseif ($searchResults->count() > 1 ) {
+                               $this->_log('Multiple DNs found for username '.$login);
+                               return FALSE;
+                       }
+                       //Getting user's DN from search
+                       $userEntry=$searchResults->shiftEntry();
+                       $userDN=$userEntry->dn();
+                       //Binding with user's DN. 
+                       $loginAttempt=$ldapConn->bind($userDN, $password);
+                       $ldapConn->disconnect();
+                       if ($loginAttempt === TRUE) {
+                               return $this->base->auto_create_user($login);
+                       } elseif ($loginAttempt->getCode() == 49) {
+                               return FALSE;
+                       } else {
+                               $this->_log('Unknown Error: Code: '.$loginAttempt->getCode().
+                                       ' Message: '.$loginAttempt->getMessage());
+                               return FALSE;
+                       }
+               }
+               return false;
+       }
+
+}
+
+?>