]> git.wh0rd.org Git - tt-rss.git/blob - plugins/auth_ldap/init.php
1985e38e85e8293988af196221323b6ef4b8fc69
[tt-rss.git] / plugins / auth_ldap / init.php
1 <?php
2 /** 
3  * Tiny Tiny RSS plugin for LDAP authentication 
4  * @author hydrian (ben.tyger@tygerclan.net)
5  * @copyright GPL2
6  *  Requires php-ldap and PEAR Net::LDAP2
7  */
8
9 /**
10  *  Configuration
11  *  Put the following options in config.php and customize them for your environment
12  *
13  *      define('LDAP_AUTH_SERVER_URI, 'ldaps://LDAPServerHostname:port/');
14  *      define('LDAP_AUTH_USETLS, FALSE); // Enable TLS Support for ldaps://
15  *      define('LDAP_AUTH_ALLOW_UNTRUSTED_CERT', TRUE); // Allows untrusted certificate
16  *      define('LDAP_AUTH_BINDDN', 'cn=serviceaccount,dc=example,dc=com');
17  *      define('LDAP_AUTH_BINDPW', 'ServiceAccountsPassword');
18  *      define('LDAP_AUTH_BASEDN', 'dc=example,dc=com');
19  *      // ??? will be replaced with the entered username(escaped) at login 
20  *      define('LDAP_AUTH_SEARCHFILTER', '(&(objectClass=person)(uid=???))');
21  */
22
23 /**
24  *      Notes
25  *      LDAP search does not support follow ldap referals. Referals are disabled to 
26  *      allow proper login.  This is particular to Active Directory.  
27  * 
28  *      Also group membership can be supported if the user object contains the
29  *      the group membership via attributes.  The following LDAP servers can 
30  *      support this.   
31  *       * Active Directory
32  *   * OpenLDAP support with MemberOf Overlay
33  *
34  */
35 class Auth_Ldap extends Plugin implements IAuthModule {
36
37         private $link;
38         private $host;
39         private $base;
40
41         function about() {
42                 return array(0.01,
43                         "Authenticates against an LDAP server (configured in config.php)",
44                         "hydrian",
45                         true);
46         }
47
48         function init($host) {
49                 $this->link = $host->get_link();
50                 $this->host = $host;
51                 $this->base = new Auth_Base($this->link);
52
53                 $host->add_hook($host::HOOK_AUTH_USER, $this);
54         }
55         
56         private function _log($msg) {
57                 trigger_error($msg, E_USER_WARN);
58         }
59
60         function authenticate($login, $password) {
61                 if ($login && $password) {
62                         if (!function_exists('ldap_connect')) {
63                                 trigger_error('auth_ldap requires PHP\'s PECL LDAP package installed.');
64                                 return FALSE;
65                         }
66                         if (!require_once('Net/LDAP2.php')) { 
67                                 trigger_error('auth_ldap requires the PEAR package Net::LDAP2');
68                                 return FALSE;
69                         }
70                         $parsedURI=parse_url(LDAP_AUTH_SERVER_URI);
71                         if ($parsedURI === FALSE) {
72                                 $this->_log('Could not parse LDAP_AUTH_SERVER_URI in config.php');
73                                 return FALSE;
74                         }
75                         $ldapConnParams=array(
76                                 'host'=>$parsedURI['scheme'].'://'.$parsedURI['host'],
77                                 'basedn'=>LDAP_AUTH_BASEDN,
78                                 'options' => array('LDAP_OPT_REFERRALS' => 0)
79                         );
80                         $ldapConnParams['starttls']= defined('LDAP_AUTH_USETLS') ?
81                                 LDAP_AUTH_USETLS : FALSE;
82                                         
83                         if (is_int($parsedURI['port'])) {
84                                 $ldapConnParams['port']=$parsedURI['port'];
85                         }
86                         // Making connection to LDAP server
87                         if (LDAP_AUTH_ALLOW_UNTRUSTED_CERT === TRUE) {
88                                 putenv('LDAPTLS_REQCERT=never');
89                         }
90                         $ldapConn = Net_LDAP2::connect($ldapConnParams);
91                         if (Net_LDAP2::isError($ldapConn)) {
92                                 $this->_log('Could not connect to LDAP Server: '.$ldapConn->getMessage());
93                                 return FALSE;
94                         }
95                         // Bind with service account
96                         $binding=$ldapConn->bind(LDAP_AUTH_BINDDN, LDAP_AUTH_BINDPW);
97                         if (Net_LDAP2::isError($binding)) {
98                                 $this->_log('Cound not bind service account: '.$binding->getMessage());
99                                 return FALSE;
100                         } 
101                         //Searching for user
102                         $completedSearchFiler=str_replace('???',$login,LDAP_AUTH_SEARCHFILTER);
103                         $filterObj=Net_LDAP2_Filter::parse($completedSearchFiler);
104                         $searchResults=$ldapConn->search(LDAP_AUTH_BASEDN, $filterObj);
105                         if (Net_LDAP2::isError($searchResults)) {
106                                 $this->_log('LDAP Search Failed: '.$searchResults->getMessage());
107                                 return FALSE;
108                         } elseif ($searchResults->count() === 0) {
109                                 return FALSE;
110                         } elseif ($searchResults->count() > 1 ) {
111                                 $this->_log('Multiple DNs found for username '.$login);
112                                 return FALSE;
113                         }
114                         //Getting user's DN from search
115                         $userEntry=$searchResults->shiftEntry();
116                         $userDN=$userEntry->dn();
117                         //Binding with user's DN. 
118                         $loginAttempt=$ldapConn->bind($userDN, $password);
119                         $ldapConn->disconnect();
120                         if ($loginAttempt === TRUE) {
121                                 return $this->base->auto_create_user($login);
122                         } elseif ($loginAttempt->getCode() == 49) {
123                                 return FALSE;
124                         } else {
125                                 $this->_log('Unknown Error: Code: '.$loginAttempt->getCode().
126                                         ' Message: '.$loginAttempt->getMessage());
127                                 return FALSE;
128                         }
129                 }
130                 return false;
131         }
132
133 }
134
135 ?>