]>
Commit | Line | Data |
---|---|---|
0c4677bf | 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 | * | |
02be0aef W |
13 | * define('LDAP_AUTH_SERVER_URI', 'ldaps://LDAPServerHostname:port/'); |
14 | * define('LDAP_AUTH_USETLS', FALSE); // Enable TLS Support for ldaps:// | |
0c4677bf | 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'); | |
02be0aef | 19 | * define('LDAP_AUTH_ANONYMOUSBEFOREBIND', FALSE); |
0c4677bf | 20 | * // ??? will be replaced with the entered username(escaped) at login |
21 | * define('LDAP_AUTH_SEARCHFILTER', '(&(objectClass=person)(uid=???))'); | |
22 | */ | |
23 | ||
24 | /** | |
8d0da886 | 25 | * Notes - |
0c4677bf | 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) { | |
02be0aef | 58 | trigger_error($msg, E_USER_WARNING); |
0c4677bf | 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( | |
02be0aef | 77 | 'host'=>$parsedURI['host'], |
0c4677bf | 78 | 'basedn'=>LDAP_AUTH_BASEDN, |
79 | 'options' => array('LDAP_OPT_REFERRALS' => 0) | |
80 | ); | |
02be0aef W |
81 | |
82 | if (!LDAP_AUTH_ANONYMOUSBEFOREBIND) { | |
83 | $ldapConnParams['binddn']= LDAP_AUTH_BINDDN; | |
84 | $ldapConnParams['bindpw']= LDAP_AUTH_BINDPW; | |
85 | } | |
0c4677bf | 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 | } | |
02be0aef W |
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 | } | |
0c4677bf | 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 | ?> |