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.inc.php 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  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-2014 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-2014 Poweradmin Development Team
  28. * @license http://opensource.org/licenses/GPL-3.0 GPL
  29. */
  30. /** Authenticate Session
  31. *
  32. * Checks if user is logging in, logging out, or session expired and performs
  33. * actions accordingly
  34. *
  35. * @return null
  36. */
  37. function doAuthenticate() {
  38. global $iface_expire;
  39. global $session_key;
  40. global $ldap_use;
  41. if (isset($_SESSION['userid']) && isset($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] == "logout") {
  42. logout(_('You have logged out.'), 'success');
  43. }
  44. // If a user had just entered his/her login && password, store them in our session.
  45. if (isset($_POST["authenticate"])) {
  46. $_SESSION["userpwd"] = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($session_key), $_POST['password'], MCRYPT_MODE_CBC, md5(md5($session_key))));
  47. $_SESSION["userlogin"] = $_POST["username"];
  48. $_SESSION["userlang"] = $_POST["userlang"];
  49. }
  50. // Check if the session hasnt expired yet.
  51. if ((isset($_SESSION["userid"])) && ($_SESSION["lastmod"] != "") && ((time() - $_SESSION["lastmod"]) > $iface_expire)) {
  52. logout(_('Session expired, please login again.'), 'error');
  53. }
  54. // If the session hasn't expired yet, give our session a fresh new timestamp.
  55. $_SESSION["lastmod"] = time();
  56. if ($ldap_use && userUsesLDAP()) {
  57. LDAPAuthenticate();
  58. } else {
  59. SQLAuthenticate();
  60. }
  61. }
  62. function userUsesLDAP() {
  63. global $db;
  64. $rowObj = $db->queryRow("SELECT id FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND use_ldap=1");
  65. if ($rowObj) {
  66. return true;
  67. }
  68. return false;
  69. }
  70. function LDAPAuthenticate() {
  71. global $db;
  72. global $session_key;
  73. global $ldap_uri;
  74. global $ldap_debug;
  75. global $ldap_basedn;
  76. global $ldap_binddn;
  77. global $ldap_bindpw;
  78. global $ldap_proto;
  79. global $ldap_user_attribute;
  80. if (isset($_SESSION["userlogin"]) && isset($_SESSION["userpwd"])) {
  81. if ($ldap_debug) {
  82. ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);
  83. }
  84. $ldapconn = ldap_connect($ldap_uri);
  85. if (!$ldapconn) {
  86. if (isset($_POST["authenticate"]))
  87. log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_connect failed', $_SERVER['REMOTE_ADDR']));
  88. logout(_('Failed to connect to LDAP server!'), 'error');
  89. return;
  90. }
  91. $ldapbind = ldap_bind($ldapconn, $ldap_binddn, $ldap_bindpw);
  92. ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, $ldap_proto);
  93. if (!$ldapbind) {
  94. if (isset($_POST["authenticate"]))
  95. log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_bind failed', $_SERVER['REMOTE_ADDR']));
  96. logout(_('Failed to bind to LDAP server!'), 'error');
  97. return;
  98. }
  99. $attributes = array($ldap_user_attribute, 'dn');
  100. $filter = "(" . $ldap_user_attribute . "=" . $_SESSION["userlogin"] . ")";
  101. $ldapsearch = ldap_search($ldapconn, $ldap_basedn, $filter, $attributes);
  102. if (!$ldapsearch) {
  103. if (isset($_POST["authenticate"]) )
  104. log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_search failed', $_SERVER['REMOTE_ADDR']));
  105. logout(_('Failed to search LDAP.'), 'error');
  106. return;
  107. }
  108. //Checking first that we only found exactly 1 user, get the DN of this user. We'll use this to perform the actual authentication.
  109. $entries = ldap_get_entries($ldapconn, $ldapsearch);
  110. if ($entries["count"] != 1) {
  111. if (isset($_POST["authenticate"])) {
  112. if ($entries["count"] == 0 ){
  113. log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: No such user', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  114. } else {
  115. log_error(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: Duplicate usernames detected', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  116. }
  117. }
  118. logout(_('Failed to authenticate against LDAP.'), 'error');
  119. return;
  120. }
  121. $user_dn = $entries[0]["dn"];
  122. $session_pass = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($session_key), base64_decode($_SESSION["userpwd"]), MCRYPT_MODE_CBC, md5(md5($session_key))), "\0");
  123. $ldapbind = ldap_bind($ldapconn, $user_dn, $session_pass);
  124. if (!$ldapbind) {
  125. if (isset($_POST["authenticate"]) )
  126. log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: Incorrect password', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  127. auth(_('LDAP Authentication failed!'), "error");
  128. return;
  129. }
  130. //LDAP AUTH SUCCESSFUL
  131. //Make sure the user is 'active' and fetch id and name.
  132. $rowObj = $db->queryRow("SELECT id, fullname FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND active=1");
  133. if (!$rowObj) {
  134. if (isset($_POST["authenticate"]) )
  135. log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: User is inactive', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  136. auth(_('LDAP Authentication failed!'), "error");
  137. return;
  138. }
  139. $_SESSION["userid"] = $rowObj["id"];
  140. $_SESSION["name"] = $rowObj["fullname"];
  141. $_SESSION["auth_used"] = "ldap";
  142. if (isset($_POST["authenticate"])) {
  143. log_notice( sprintf('Successful LDAP authentication attempt from [%s] for user \'%s\'', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]) );
  144. //If a user has just authenticated, redirect him to requested page
  145. session_write_close();
  146. $redirect_url = ($_POST["query_string"] ? $_SERVER['SCRIPT_NAME'] . "?" . $_POST["query_string"] : $_SERVER['SCRIPT_NAME']);
  147. clean_page($redirect_url);
  148. exit;
  149. }
  150. } else {
  151. //No username and password set, show auth form (again).
  152. auth();
  153. }
  154. }
  155. function SQLAuthenticate() {
  156. global $db;
  157. global $password_encryption;
  158. global $session_key;
  159. if (isset($_SESSION["userlogin"]) && isset($_SESSION["userpwd"])) {
  160. //Username and password are set, lets try to authenticate.
  161. $session_pass = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($session_key), base64_decode($_SESSION["userpwd"]), MCRYPT_MODE_CBC, md5(md5($session_key))), "\0");
  162. $rowObj = $db->queryRow("SELECT id, fullname, password FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND active=1");
  163. if ($rowObj) {
  164. if ($password_encryption == 'md5salt') {
  165. $session_password = mix_salt(extract_salt($rowObj["password"]), $session_pass);
  166. } else {
  167. $session_password = md5($session_pass);
  168. }
  169. if ($session_password == $rowObj["password"]) {
  170. $_SESSION["userid"] = $rowObj["id"];
  171. $_SESSION["name"] = $rowObj["fullname"];
  172. $_SESSION["auth_used"] = "internal";
  173. if (isset($_POST["authenticate"])) {
  174. log_notice(sprintf('Successful authentication attempt from [%s] for user \'%s\'', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"]));
  175. //If a user has just authenticated, redirect him to requested page
  176. session_write_close();
  177. $redirect_url = ($_POST["query_string"] ? $_SERVER['SCRIPT_NAME'] . "?" . $_POST["query_string"] : $_SERVER['SCRIPT_NAME']);
  178. clean_page($redirect_url);
  179. exit;
  180. }
  181. } else if (isset($_POST['authenticate'])) {
  182. // auth( _('Authentication failed! - <a href="reset_password.php">(forgot password)</a>'),"error");
  183. auth(_('Authentication failed!'), "error");
  184. } else {
  185. auth();
  186. }
  187. } else if (isset($_POST['authenticate'])) {
  188. log_warn(sprintf('Failed authentication attempt from [%s]', $_SERVER['REMOTE_ADDR']));
  189. //Authentication failed, retry.
  190. // auth( _('Authentication failed! - <a href="reset_password.php">(forgot password)</a>'),"error");
  191. auth(_('Authentication failed!'), "error");
  192. } else {
  193. unset($_SESSION["userpwd"]);
  194. unset($_SESSION["userlogin"]);
  195. auth();
  196. }
  197. } else {
  198. //No username and password set, show auth form (again).
  199. auth();
  200. }
  201. }
  202. /** Print the login form
  203. *
  204. * @param string $msg Error Message
  205. * @param string $type Message type [default='success', 'error']
  206. *
  207. * @return null
  208. */
  209. function auth($msg = "", $type = "success") {
  210. include_once('inc/header.inc.php');
  211. include('inc/config.inc.php');
  212. if ($msg) {
  213. print "<div class=\"$type\">$msg</div>\n";
  214. }
  215. ?>
  216. <h2><?php echo _('Log in'); ?></h2>
  217. <form method="post" action="<?php echo htmlentities($_SERVER["PHP_SELF"], ENT_QUOTES); ?>">
  218. <input type="hidden" name="query_string" value="<?php echo htmlentities($_SERVER["QUERY_STRING"]); ?>">
  219. <table border="0">
  220. <tr>
  221. <td class="n" width="100"><?php echo _('Username'); ?>:</td>
  222. <td class="n"><input type="text" class="input" name="username" id="username"></td>
  223. </tr>
  224. <tr>
  225. <td class="n"><?php echo _('Password'); ?>:</td>
  226. <td class="n"><input type="password" class="input" name="password"></td>
  227. </tr>
  228. <tr>
  229. <td class="n"><?php echo _('Language'); ?>:</td>
  230. <td class="n">
  231. <select class="input" name="userlang">
  232. <?php
  233. // List available languages (sorted alphabetically)
  234. include_once('inc/countrycodes.inc.php');
  235. $locales = scandir('locale/');
  236. foreach ($locales as $locale) {
  237. if (strlen($locale) == 5) {
  238. $locales_fullname[$locale] = $countrycodes[substr($locale, 0, 2)];
  239. }
  240. }
  241. asort($locales_fullname);
  242. foreach ($locales_fullname as $locale => $language) {
  243. if ($locale == $iface_lang) {
  244. echo _('<option selected value="' . $locale . '">' . $language);
  245. } else {
  246. echo _('<option value="' . $locale . '">' . $language);
  247. }
  248. }
  249. ?>
  250. </select>
  251. </td>
  252. </tr>
  253. <tr>
  254. <td class="n">&nbsp;</td>
  255. <td class="n">
  256. <input type="submit" name="authenticate" class="button" value=" <?php echo _('Go'); ?> ">
  257. </td>
  258. </tr>
  259. </table>
  260. </form>
  261. <script type="text/javascript">
  262. <!--
  263. document.getElementById('username').focus();
  264. //-->
  265. </script>
  266. <?php
  267. include_once('inc/footer.inc.php');
  268. exit;
  269. }
  270. /** Logout the user
  271. *
  272. * Logout the user and kickback to login form
  273. *
  274. * @param string $msg Error Message
  275. * @param string $type Message type [default='']
  276. *
  277. * @return null
  278. */
  279. function logout($msg = "", $type = "") {
  280. session_unset();
  281. session_destroy();
  282. session_write_close();
  283. auth($msg, $type);
  284. exit;
  285. }