init.php 4.4 KB

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