You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

auth_local.plugin.php 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. /* Poweradmin, a friendly web-based admin tool for PowerDNS.
  3. * See <http://www.poweradmin.org> for more details.
  4. *
  5. * Copyright 2007-2009 Rejo Zenger <rejo@zenger.nl>
  6. * Copyright 2010-2017 Poweradmin Development Team
  7. * <http://www.poweradmin.org/credits.html>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. /**
  23. * Authentication functions
  24. *
  25. * @package Poweradmin
  26. * @copyright 2007-2010 Rejo Zenger <rejo@zenger.nl>
  27. * @copyright 2010-2017 Poweradmin Development Team
  28. * @license http://opensource.org/licenses/GPL-3.0 GPL
  29. */
  30. require_once dirname(dirname(dirname(__DIR__))) . '/vendor/poweradmin/Password.php';
  31. /** Authenticate Session
  32. *
  33. * Checks if user is logging in, logging out, or session expired and performs
  34. * actions accordingly
  35. *
  36. * @return null
  37. */
  38. function authenticate_local() {
  39. global $iface_expire;
  40. global $session_key;
  41. global $ldap_use;
  42. if (isset($_SESSION['userid']) && isset($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] == "logout") {
  43. logout(_('You have logged out.'), 'success');
  44. }
  45. // If a user had just entered his/her login && password, store them in our session.
  46. if (isset($_POST["authenticate"])) {
  47. $_SESSION["userpwd"] = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($session_key), $_POST['password'], MCRYPT_MODE_CBC, md5(md5($session_key))));
  48. $_SESSION["userlogin"] = $_POST["username"];
  49. $_SESSION["userlang"] = $_POST["userlang"];
  50. }
  51. // Check if the session hasnt expired yet.
  52. if ((isset($_SESSION["userid"])) && ($_SESSION["lastmod"] != "") && ((time() - $_SESSION["lastmod"]) > $iface_expire)) {
  53. logout(_('Session expired, please login again.'), 'error');
  54. }
  55. // If the session hasn't expired yet, give our session a fresh new timestamp.
  56. $_SESSION["lastmod"] = time();
  57. if ($ldap_use && userUsesLDAP()) {
  58. LDAPAuthenticate();
  59. } else {
  60. SQLAuthenticate();
  61. }
  62. }
  63. function userUsesLDAP() {
  64. global $db;
  65. $rowObj = $db->queryRow("SELECT id FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND use_ldap=1");
  66. if ($rowObj) {
  67. return true;
  68. }
  69. return false;
  70. }
  71. function LDAPAuthenticate() {
  72. global $db;
  73. global $session_key;
  74. global $ldap_uri;
  75. global $ldap_basedn;
  76. global $ldap_binddn;
  77. global $ldap_bindpw;
  78. global $ldap_proto;
  79. global $ldap_debug;
  80. global $ldap_user_attribute;
  81. if (isset($_SESSION["userlogin"]) && isset($_SESSION["userpwd"])) {
  82. if ($ldap_debug) {
  83. ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
  84. }
  85. $ldapconn = ldap_connect($ldap_uri);
  86. if (!$ldapconn) {
  87. if (isset($_POST["authenticate"]))
  88. log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_connect failed', $_SERVER['REMOTE_ADDR']));
  89. logout(_('Failed to connect to LDAP server!'), 'error');
  90. return;
  91. }
  92. ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, $ldap_proto);
  93. $ldapbind = ldap_bind($ldapconn, $ldap_binddn, $ldap_bindpw);
  94. if (!$ldapbind) {
  95. if (isset($_POST["authenticate"]))
  96. log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_bind failed', $_SERVER['REMOTE_ADDR']));
  97. logout(_('Failed to bind to LDAP server!'), 'error');
  98. return;
  99. }
  100. $attributes = array($ldap_user_attribute, 'dn');
  101. $filter = "(" . $ldap_user_attribute . "=" . $_SESSION["userlogin"] . ")";
  102. $ldapsearch = ldap_search($ldapconn, $ldap_basedn, $filter, $attributes);
  103. if (!$ldapsearch) {
  104. if (isset($_POST["authenticate"]))
  105. log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_search failed', $_SERVER['REMOTE_ADDR']));
  106. logout(_('Failed to search LDAP.'), 'error');
  107. return;
  108. }
  109. //Checking first that we only found exactly 1 user, get the DN of this user. We'll use this to perform the actual authentication.
  110. $entries = ldap_get_entries($ldapconn, $ldapsearch);
  111. if ($entries["count"] != 1) {
  112. if (isset($_POST["authenticate"])) {
  113. if ($entries["count"] == 0) {
  114. log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: No such user', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  115. } else {
  116. log_error(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: Duplicate usernames detected', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  117. }
  118. }
  119. logout(_('Failed to authenticate against LDAP.'), 'error');
  120. return;
  121. }
  122. $user_dn = $entries[0]["dn"];
  123. $session_pass = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($session_key), base64_decode($_SESSION["userpwd"]), MCRYPT_MODE_CBC, md5(md5($session_key))), "\0");
  124. $ldapbind = ldap_bind($ldapconn, $user_dn, $session_pass);
  125. if (!$ldapbind) {
  126. if (isset($_POST["authenticate"]))
  127. log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: Incorrect password', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  128. auth(_('LDAP Authentication failed!'), "error");
  129. return;
  130. }
  131. //LDAP AUTH SUCCESSFUL
  132. //Make sure the user is 'active' and fetch id and name.
  133. $rowObj = $db->queryRow("SELECT id, fullname FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND active=1");
  134. if (!$rowObj) {
  135. if (isset($_POST["authenticate"]))
  136. log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: User is inactive', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  137. auth(_('LDAP Authentication failed!'), "error");
  138. return;
  139. }
  140. $_SESSION["userid"] = $rowObj["id"];
  141. $_SESSION["name"] = $rowObj["fullname"];
  142. $_SESSION["auth_used"] = "ldap";
  143. if (isset($_POST["authenticate"])) {
  144. log_notice(sprintf('Successful LDAP authentication attempt from [%s] for user \'%s\'', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  145. //If a user has just authenticated, redirect him to requested page
  146. session_write_close();
  147. $redirect_url = ($_POST["query_string"] ? $_SERVER['SCRIPT_NAME'] . "?" . $_POST["query_string"] : $_SERVER['SCRIPT_NAME']);
  148. clean_page($redirect_url);
  149. exit;
  150. }
  151. } else {
  152. //No username and password set, show auth form (again).
  153. auth();
  154. }
  155. }
  156. function SQLAuthenticate() {
  157. global $db;
  158. global $password_encryption;
  159. global $session_key;
  160. if (isset($_SESSION["userlogin"]) && isset($_SESSION["userpwd"])) {
  161. //Username and password are set, lets try to authenticate.
  162. $session_pass = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($session_key), base64_decode($_SESSION["userpwd"]), MCRYPT_MODE_CBC, md5(md5($session_key))), "\0");
  163. $rowObj = $db->queryRow("SELECT id, fullname, password FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND active=1");
  164. if ($rowObj) {
  165. if (Poweradmin\Password::verify($session_pass, $rowObj['password'])) {
  166. $_SESSION["userid"] = $rowObj["id"];
  167. $_SESSION["name"] = $rowObj["fullname"];
  168. $_SESSION["auth_used"] = "internal";
  169. if (isset($_POST["authenticate"])) {
  170. log_notice(sprintf('Successful authentication attempt from [%s] for user \'%s\'', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  171. //If a user has just authenticated, redirect him to requested page
  172. session_write_close();
  173. $redirect_url = ($_POST["query_string"] ? $_SERVER['SCRIPT_NAME'] . "?" . $_POST["query_string"] : $_SERVER['SCRIPT_NAME']);
  174. clean_page($redirect_url);
  175. exit;
  176. }
  177. } else if (isset($_POST['authenticate'])) {
  178. // auth( _('Authentication failed! - <a href="reset_password.php">(forgot password)</a>'),"error");
  179. auth(_('Authentication failed!'), "error");
  180. } else {
  181. auth();
  182. }
  183. } else if (isset($_POST['authenticate'])) {
  184. log_warn(sprintf('Failed authentication attempt from [%s]', $_SERVER['REMOTE_ADDR']));
  185. //Authentication failed, retry.
  186. // auth( _('Authentication failed! - <a href="reset_password.php">(forgot password)</a>'),"error");
  187. auth(_('Authentication failed!'), "error");
  188. } else {
  189. unset($_SESSION["userpwd"]);
  190. unset($_SESSION["userlogin"]);
  191. auth();
  192. }
  193. } else {
  194. //No username and password set, show auth form (again).
  195. auth();
  196. }
  197. }