for more details. * * Copyright 2007-2009 Rejo Zenger * Copyright 2010-2017 Poweradmin Development Team * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /** * Authentication functions * * @package Poweradmin * @copyright 2007-2010 Rejo Zenger * @copyright 2010-2017 Poweradmin Development Team * @license http://opensource.org/licenses/GPL-3.0 GPL */ require_once dirname(dirname(dirname(__DIR__))) . '/vendor/poweradmin/Password.php'; /** Authenticate Session * * Checks if user is logging in, logging out, or session expired and performs * actions accordingly * * @return null */ function authenticate_local() { global $iface_expire; global $session_key; global $ldap_use; if (isset($_SESSION['userid']) && isset($_SERVER["QUERY_STRING"]) && $_SERVER["QUERY_STRING"] == "logout") { logout(_('You have logged out.'), 'success'); } // If a user had just entered his/her login && password, store them in our session. if (isset($_POST["authenticate"])) { $_SESSION["userpwd"] = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($session_key), $_POST['password'], MCRYPT_MODE_CBC, md5(md5($session_key)))); $_SESSION["userlogin"] = $_POST["username"]; $_SESSION["userlang"] = $_POST["userlang"]; } // Check if the session hasnt expired yet. if ((isset($_SESSION["userid"])) && ($_SESSION["lastmod"] != "") && ((time() - $_SESSION["lastmod"]) > $iface_expire)) { logout(_('Session expired, please login again.'), 'error'); } // If the session hasn't expired yet, give our session a fresh new timestamp. $_SESSION["lastmod"] = time(); if ($ldap_use && userUsesLDAP()) { LDAPAuthenticate(); } else { SQLAuthenticate(); } } function userUsesLDAP() { global $db; $rowObj = $db->queryRow("SELECT id FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND use_ldap=1"); if ($rowObj) { return true; } return false; } function LDAPAuthenticate() { global $db; global $session_key; global $ldap_uri; global $ldap_basedn; global $ldap_binddn; global $ldap_bindpw; global $ldap_proto; global $ldap_debug; global $ldap_user_attribute; if (isset($_SESSION["userlogin"]) && isset($_SESSION["userpwd"])) { if ($ldap_debug) { ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7); } $ldapconn = ldap_connect($ldap_uri); if (!$ldapconn) { if (isset($_POST["authenticate"])) log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_connect failed', $_SERVER['REMOTE_ADDR'])); logout(_('Failed to connect to LDAP server!'), 'error'); return; } ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, $ldap_proto); $ldapbind = ldap_bind($ldapconn, $ldap_binddn, $ldap_bindpw); if (!$ldapbind) { if (isset($_POST["authenticate"])) log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_bind failed', $_SERVER['REMOTE_ADDR'])); logout(_('Failed to bind to LDAP server!'), 'error'); return; } $attributes = array($ldap_user_attribute, 'dn'); $filter = "(" . $ldap_user_attribute . "=" . $_SESSION["userlogin"] . ")"; $ldapsearch = ldap_search($ldapconn, $ldap_basedn, $filter, $attributes); if (!$ldapsearch) { if (isset($_POST["authenticate"])) log_error(sprintf('Failed LDAP authentication attempt from [%s] Reason: ldap_search failed', $_SERVER['REMOTE_ADDR'])); logout(_('Failed to search LDAP.'), 'error'); return; } //Checking first that we only found exactly 1 user, get the DN of this user. We'll use this to perform the actual authentication. $entries = ldap_get_entries($ldapconn, $ldapsearch); if ($entries["count"] != 1) { if (isset($_POST["authenticate"])) { if ($entries["count"] == 0) { log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: No such user', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"])); } else { log_error(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: Duplicate usernames detected', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"])); } } logout(_('Failed to authenticate against LDAP.'), 'error'); return; } $user_dn = $entries[0]["dn"]; $session_pass = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($session_key), base64_decode($_SESSION["userpwd"]), MCRYPT_MODE_CBC, md5(md5($session_key))), "\0"); $ldapbind = ldap_bind($ldapconn, $user_dn, $session_pass); if (!$ldapbind) { if (isset($_POST["authenticate"])) log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: Incorrect password', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"])); auth(_('LDAP Authentication failed!'), "error"); return; } //LDAP AUTH SUCCESSFUL //Make sure the user is 'active' and fetch id and name. $rowObj = $db->queryRow("SELECT id, fullname FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND active=1"); if (!$rowObj) { if (isset($_POST["authenticate"])) log_warn(sprintf('Failed LDAP authentication attempt from [%s] for user \'%s\' Reason: User is inactive', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"])); auth(_('LDAP Authentication failed!'), "error"); return; } $_SESSION["userid"] = $rowObj["id"]; $_SESSION["name"] = $rowObj["fullname"]; $_SESSION["auth_used"] = "ldap"; if (isset($_POST["authenticate"])) { log_notice(sprintf('Successful LDAP authentication attempt from [%s] for user \'%s\'', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"])); //If a user has just authenticated, redirect him to requested page session_write_close(); $redirect_url = ($_POST["query_string"] ? $_SERVER['SCRIPT_NAME'] . "?" . $_POST["query_string"] : $_SERVER['SCRIPT_NAME']); clean_page($redirect_url); exit; } } else { //No username and password set, show auth form (again). auth(); } } function SQLAuthenticate() { global $db; global $password_encryption; global $session_key; if (isset($_SESSION["userlogin"]) && isset($_SESSION["userpwd"])) { //Username and password are set, lets try to authenticate. $session_pass = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($session_key), base64_decode($_SESSION["userpwd"]), MCRYPT_MODE_CBC, md5(md5($session_key))), "\0"); $rowObj = $db->queryRow("SELECT id, fullname, password FROM users WHERE username=" . $db->quote($_SESSION["userlogin"], 'text') . " AND active=1"); if ($rowObj) { if (Poweradmin\Password::verify($session_pass, $rowObj['password'])) { $_SESSION["userid"] = $rowObj["id"]; $_SESSION["name"] = $rowObj["fullname"]; $_SESSION["auth_used"] = "internal"; if (isset($_POST["authenticate"])) { log_notice(sprintf('Successful authentication attempt from [%s] for user \'%s\'', $_SERVER['REMOTE_ADDR'], $_SESSION["userlogin"])); //If a user has just authenticated, redirect him to requested page session_write_close(); $redirect_url = ($_POST["query_string"] ? $_SERVER['SCRIPT_NAME'] . "?" . $_POST["query_string"] : $_SERVER['SCRIPT_NAME']); clean_page($redirect_url); exit; } } else if (isset($_POST['authenticate'])) { // auth( _('Authentication failed! - (forgot password)'),"error"); auth(_('Authentication failed!'), "error"); } else { auth(); } } else if (isset($_POST['authenticate'])) { log_warn(sprintf('Failed authentication attempt from [%s]', $_SERVER['REMOTE_ADDR'])); //Authentication failed, retry. // auth( _('Authentication failed! - (forgot password)'),"error"); auth(_('Authentication failed!'), "error"); } else { unset($_SESSION["userpwd"]); unset($_SESSION["userlogin"]); auth(); } } else { //No username and password set, show auth form (again). auth(); } }