]> git.wh0rd.org - tt-rss.git/blob - plugins/auth_ldap/init.php
Merge branch 'master' of git://github.com/RaphaelRochet/Tiny-Tiny-RSS into RaphaelRoc...
[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 * define('LDAP_AUTH_ANONYMOUSBEFOREBIND', FALSE);
20 * // ??? will be replaced with the entered username(escaped) at login
21 * define('LDAP_AUTH_SEARCHFILTER', '(&(objectClass=person)(uid=???))');
22 */
23
24 /**
25 * Notes -
26 * LDAP search does not support follow ldap referals. Referals are disabled to
27 * allow proper login. This is particular to Active Directory.
28 *
29 * Also group membership can be supported if the user object contains the
30 * the group membership via attributes. The following LDAP servers can
31 * support this.
32 * * Active Directory
33 * * OpenLDAP support with MemberOf Overlay
34 *
35 */
36 class Auth_Ldap extends Plugin implements IAuthModule {
37
38 private $link;
39 private $host;
40 private $base;
41
42 function about() {
43 return array(0.01,
44 "Authenticates against an LDAP server (configured in config.php)",
45 "hydrian",
46 true);
47 }
48
49 function init($host) {
50 $this->link = $host->get_link();
51 $this->host = $host;
52 $this->base = new Auth_Base($this->link);
53
54 $host->add_hook($host::HOOK_AUTH_USER, $this);
55 }
56
57 private function _log($msg) {
58 trigger_error($msg, E_USER_WARNING);
59 }
60
61 function authenticate($login, $password) {
62 if ($login && $password) {
63 if (!function_exists('ldap_connect')) {
64 trigger_error('auth_ldap requires PHP\'s PECL LDAP package installed.');
65 return FALSE;
66 }
67 if (!require_once('Net/LDAP2.php')) {
68 trigger_error('auth_ldap requires the PEAR package Net::LDAP2');
69 return FALSE;
70 }
71 $parsedURI=parse_url(LDAP_AUTH_SERVER_URI);
72 if ($parsedURI === FALSE) {
73 $this->_log('Could not parse LDAP_AUTH_SERVER_URI in config.php');
74 return FALSE;
75 }
76 $ldapConnParams=array(
77 'host'=>$parsedURI['host'],
78 'basedn'=>LDAP_AUTH_BASEDN,
79 'options' => array('LDAP_OPT_REFERRALS' => 0)
80 );
81
82 if (!LDAP_AUTH_ANONYMOUSBEFOREBIND) {
83 $ldapConnParams['binddn']= LDAP_AUTH_BINDDN;
84 $ldapConnParams['bindpw']= LDAP_AUTH_BINDPW;
85 }
86 $ldapConnParams['starttls']= defined('LDAP_AUTH_USETLS') ?
87 LDAP_AUTH_USETLS : FALSE;
88
89 if (is_int($parsedURI['port'])) {
90 $ldapConnParams['port']=$parsedURI['port'];
91 }
92 // Making connection to LDAP server
93 if (LDAP_AUTH_ALLOW_UNTRUSTED_CERT === TRUE) {
94 putenv('LDAPTLS_REQCERT=never');
95 }
96 $ldapConn = Net_LDAP2::connect($ldapConnParams);
97 if (Net_LDAP2::isError($ldapConn)) {
98 $this->_log('Could not connect to LDAP Server: '.$ldapConn->getMessage());
99 return FALSE;
100 }
101 // Bind with service account if orignal connexion was anonymous
102 if (LDAP_AUTH_ANONYMOUSBEFOREBIND) {
103 $binding=$ldapConn->bind(LDAP_AUTH_BINDDN, LDAP_AUTH_BINDPW);
104 if (Net_LDAP2::isError($binding)) {
105 $this->_log('Cound not bind service account: '.$binding->getMessage());
106 return FALSE;
107 }
108 }
109 //Searching for user
110 $completedSearchFiler=str_replace('???',$login,LDAP_AUTH_SEARCHFILTER);
111 $filterObj=Net_LDAP2_Filter::parse($completedSearchFiler);
112 $searchResults=$ldapConn->search(LDAP_AUTH_BASEDN, $filterObj);
113 if (Net_LDAP2::isError($searchResults)) {
114 $this->_log('LDAP Search Failed: '.$searchResults->getMessage());
115 return FALSE;
116 } elseif ($searchResults->count() === 0) {
117 return FALSE;
118 } elseif ($searchResults->count() > 1 ) {
119 $this->_log('Multiple DNs found for username '.$login);
120 return FALSE;
121 }
122 //Getting user's DN from search
123 $userEntry=$searchResults->shiftEntry();
124 $userDN=$userEntry->dn();
125 //Binding with user's DN.
126 $loginAttempt=$ldapConn->bind($userDN, $password);
127 $ldapConn->disconnect();
128 if ($loginAttempt === TRUE) {
129 return $this->base->auto_create_user($login);
130 } elseif ($loginAttempt->getCode() == 49) {
131 return FALSE;
132 } else {
133 $this->_log('Unknown Error: Code: '.$loginAttempt->getCode().
134 ' Message: '.$loginAttempt->getMessage());
135 return FALSE;
136 }
137 }
138 return false;
139 }
140
141 }
142
143 ?>