width * popup_y - if popup -> height * online - page is online (user can access) * query_string - string to paste for popup (will change) * * HISTORY: * 2010/12/21 (cs) merge back password change interface * 2010/12/17 (cs) change that password can be blowfish encrypted, auto detects if other encryption is used (md5, std des) and tries to use them * 2007/05/29 (cs) BUG with assign query and visible sub arrays to pages * 2005/09/21 (cs) if error -> unset the session vars * 2005/07/04 (cs) add a function to write into the edit log file * 2005/07/01 (cs) start adepting login class to new edit interface layout * 2005/03/31 (cs) fixed the class call with all debug vars * 2004/11/17 (cs) unused var cleanup * 2004/11/16 (cs) rewrite login so it uses a template and not just plain html. prepare it, so it will be able to use external stuff later (some interface has to be designed for that * 2004/11/16 (cs) removed the mobile html part from login * 2004/09/30 (cs) layout fix * 2003-11-11: if user has debug 1 unset memlimit, because there can be serious problems with the query logging * 2003-06-12: added flag to PAGES array * changed the get vars from GLOBALS to _POST * changed the session registration. no more GLOBAL vars are registered * only _SESSION["..."] * 2003-06-09: added mobile phone login possibility * 2003-03-04: droped ADMIN and added GROUP_LEVEL * 2003-03-03: started to change the include file function collection * to become a class * 2003-02-28: various advances and changes, but far from perfect * decided to change it into a class for easier handling * add also possibility to change what will stored in the * login session ? * 2000-06-01: created basic idea and functions *********************************************************************/ // try to include file from LIBS path, or from normal path _spl_autoload('Class.DB.IO.inc'); class login extends db_io { private $euid; // the user id var private $permission_okay = 0; // is set to one if login okay, or EUID is set and user is okay to access this page public $login; // pressed login private $username; // login name private $password; // login password private $logout; // logout button private $login_error; // login error code, can be matched to the array login_error_msg, which holds the string private $password_change = false; // if this is set to true, the user can change passwords private $pw_change_deny_users = array (); // array of users for which the password change is forbidden // all possible login error conditions private $login_error_msg = array (); // this is an array holding all strings & templates passed from the outside (translation) private $login_template = array ('strings' => array (), 'password_change' => '', 'template' => ''); // acl vars public $acl = array ( 'acl' => array ( 'user' => array (), 'page' => array (), 'edit_access' => array () ), 'info' => array ( 'edit_access' => array () ) ); public $default_acl_list = array (); // METHOD: login // PARAMS: db_config -> array for logging in to DB where edit_users tables are // db_debug -> sets debug output for db_io (can be overruled with DB_DEBUG) // RETURN: none // DESC : cunstroctuor, does ALL, opens db, works through connection checks, closes itself public function __construct($db_config, $lang = 'en_utf8', $debug = 0, $db_debug = 0, $echo = 1, $print = 0) { // create db connection and init base class parent::__construct($db_config, $debug, $db_debug, $echo, $print); // no session could be found at all if (!session_id()) { echo "Session not started!
Use 'session_start();'.
For less problems with other session, you can set a session name with 'session_name(\"name\");'.
"; exit; } // set log file name $this->file_name_ext = '_login_'.date('Y-m-d').'.log'; // get the language sub class & init it _spl_autoload('Class.l10n.inc'); $this->l = new l10n($lang); // if we have a search path we need to set it, to use the correct DB to login // check what schema to use. if there is a login schema use this, else check if there is a schema set in the config, or fall back to DB_SCHEMA if this exists, if this also does not exists use public schema $SCHEMA = defined('LOGIN_DB_SCHEMA') ? LOGIN_DB_SCHEMA : ($db_config['db_schema'] ? $db_config['db_schema'] : (defined('DB_SCHEMA') ? DB_SCHEMA : 'public')); $this->db_exec("SET search_path TO ".$SCHEMA); $this->euid = array_key_exists('EUID', $_SESSION) ? $_SESSION['EUID'] : 0; // if there is none, there is none, saves me POST/GET check // get login vars, are so, can't be changed // prepare if (!isset($_POST['login_login'])) $_POST['login_login'] = ''; if (!isset($_POST['login_username'])) $_POST['login_username'] = ''; if (!isset($_POST['login_password'])) $_POST['login_password'] = ''; if (!isset($_POST['login_logout'])) $_POST['login_logout'] = ''; if (!isset($_POST['change_password'])) $_POST['change_password'] = ''; if (!isset($_POST['pw_username'])) $_POST['pw_username'] = ''; if (!isset($_POST['pw_old_password'])) $_POST['pw_old_password'] = ''; if (!isset($_POST['pw_new_password'])) $_POST['pw_new_password'] = ''; if (!isset($_POST['pw_new_password_confirm'])) $_POST['pw_new_password_confirm'] = ''; // pass on vars to Object vars $this->login = $_POST["login_login"]; $this->username = $_POST["login_username"]; $this->password = $_POST["login_password"]; $this->logout = $_POST["login_logout"]; // password change vars $this->change_password = $_POST["change_password"]; $this->pw_username = $_POST['pw_username']; $this->pw_old_password = $_POST['pw_old_password']; $this->pw_new_password = $_POST['pw_new_password']; $this->pw_new_password_confirm = $_POST['pw_new_password_confirm']; // logout target (from config) $this->logout_target = LOGOUT_TARGET; // disallow user list for password change $this->pw_change_deny_users = array ('admin'); // set flag if password change is okay if (defined('PASSWORD_CHANGE')) $this->password_change = PASSWORD_CHANGE; // max login counts before error reporting $this->max_login_error_count = 10; // users that never get locked, even if they are set strict $this->lock_deny_users = array ('admin'); // internal $this->class_info["login"] = array( "class_name" => "Login", "class_version" => "4.0.0", "class_created" => "2000-06-01", "class_author" => "cs/gullevek/at" ); // read the current edit_access_right list into an array $q = "SELECT level, type, name FROM edit_access_right WHERE level >= 0 ORDER BY level"; while ($res = $this->db_return($q)) { // level to description format $this->default_acl_list[$res['level']] = array ( 'type' => $res['type'], 'name' => $res['name'] ); // format type (eg read) => acl number (eg 20) $this->default_acl_list[$res['type']] = $res['level']; } // write that into the session $_SESSION['DEFAULT_ACL_LIST'] = $this->default_acl_list; // if username & password & !$euid start login $this->login_login_user(); // checks if $euid given check if user is okay for that side $this->login_check_permissions(); // logsout user $this->login_logout_user(); // if the password change flag is okay, run the password change method if ($this->password_change) $this->login_password_change(); // if !$euid || permission not okay, print login screan echo $this->login_print_login(); // closing all connections, depending on error status, exit if (!$this->login_close_class()) { // do not go anywhere, quit processing here // do something with possible debug data? if (TARGET == 'live' || TARGET == 'remote') { // login $this->debug_output_all = DEBUG ? 1 : 0; $this->echo_output_all = 0; $this->print_output_all = DEBUG ? 1 : 0; } $status_msg = $this->print_error_msg(); if ($this->echo_output_all) echo $status_msg; exit; } // set acls for this user/group and this page $this->login_set_acl(); } // METHOD: _login // PARAMS: none // RETURN: none // DESC : deconstructory, called with the last function to close DB connection public function __destruct() { parent::__destruct(); } // METHOD: login_login_user // PARAMS: none // RETURN: none // DESC : if user pressed login button this script is called, but only if there is no preview euid set private function login_login_user() { // have to get the global stuff here for setting it later if (!$this->euid && $this->login) { if (!($this->password && $this->username)) { $this->login_error = 102; } else { // we have to get the themes in here too $q = "SELECT eu.edit_user_id, username, password, eu.edit_group_id, eg.name AS edit_group_name, admin, eu.login_error_count, eu.login_error_date_last, eu.login_error_date_first, eu.strict, eu.locked, "; $q .= "debug, db_debug, "; $q .= "eareu.level AS user_level, eareu.type AS user_type, "; $q .= "eareg.level AS group_level, eareg.type AS group_type, "; $q .= "eu.enabled, el.short_name AS lang_short, el.iso_name AS lang_iso, first.header_color AS first_header_color, second.header_color AS second_header_color, second.template "; $q .= "FROM edit_user eu "; $q .= "LEFT JOIN edit_scheme second ON (second.edit_scheme_id = eu.edit_scheme_id AND second.enabled = 1), "; $q .= "edit_language el, edit_group eg, "; $q .= "edit_access_right eareu, "; $q .= "edit_access_right eareg, "; $q .= "edit_scheme first "; $q .= "WHERE first.edit_scheme_id = eg.edit_scheme_id AND eu.edit_group_id = eg.edit_group_id AND eu.edit_language_id = el.edit_language_id AND "; $q .= "eu.edit_access_right_id = eareu.edit_access_right_id AND "; $q .= "eg.edit_access_right_id = eareg.edit_access_right_id AND "; // password match is done in script, against old plain or new blowfish encypted $q .= "(LOWER(username) = '".strtolower($this->username)."') "; $res = $this->db_return($q); // username is wrong, but we throw for wrong username and wrong password the same error if (!$this->cursor_ext[md5($q)]["num_rows"]) { $this->login_error = 1010; } else { // if login errors is half of max errors and the last login error was less than 10s ago, forbid any new login try // check with what kind of prefix the password begins: // $2a$ or $2y$: BLOWFISCH // $1$: MD5 // $ and one alphanumeric letter, 13 chars long, but nor $ at the end: STD_DESC // if no $ => normal password // NOW, if we have a password encoded, but not the correct encoder available, throw special error // check flow // - user is enabled // - user is not locked // - password is readable // - encrypted password matches // - plain password matches // user is enabled if (!$res["enabled"]) { $this->login_error = 104; } // user is locked, either set or auto set elseif ($res['locked']) { $this->login_error = 105; } elseif ((preg_match("/^\\$2(a|y)\\$/", $res['password']) && CRYPT_BLOWFISH != 1) || (preg_match("/^\\$1\\$/", $res['password']) && CRYPT_MD5 != 1) || (preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password']) && CRYPT_STD_DES != 1)) { $this->login_error = 9999; // this means password cannot be decrypted because of missing crypt methods } // check passwword as crypted, $2a$ or $2y$ is blowfish start, $1$ is MD5 start, $\w{12} is standard DES elseif ((preg_match("/^\\$2(a|y)\\$/", $res['password']) || preg_match("/^\\$1\\$/", $res['password']) || preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password'])) && !$this->verifyCryptString($this->password, $res['password'])) { $this->login_error = 1011; } // check old plain password, non case sensitive elseif (!preg_match("/^\\$2(a|y)\\$/", $res['password']) && !preg_match("/^\\$1\\$/", $res['password']) && !preg_match("/^\\$[0-9A-Za-z.]{12}$/", $res['password']) && $res['password'] != $this->password) { $this->login_error = 1012; } // nromal user processing else { // set class var and session var $_SESSION["EUID"] = $this->euid = $res["edit_user_id"]; // check if user is okay $this->login_check_permissions(); if (!$this->login_error) { // now set all session vars and read page permissions $GLOBALS["DEBUG_ALL"] = $_SESSION["DEBUG_ALL"] = $res["debug"]; $GLOBALS["DB_DEBUG"] = $_SESSION["DB_DEBUG"] = $res["db_debug"]; $_SESSION["USER_NAME"] = $res["username"]; $_SESSION["ADMIN"] = $res["admin"]; $_SESSION["GROUP_NAME"] = $res["edit_group_name"]; $_SESSION["USER_ACL_LEVEL"] = $res["user_level"]; $_SESSION["USER_ACL_TYPE"] = $res["user_type"]; $_SESSION["GROUP_ACL_LEVEL"] = $res["group_level"]; $_SESSION["GROUP_ACL_TYPE"] = $res["group_type"]; $_SESSION["TEMPLATE"] = ($res["template"]) ? $res["template"] : DEFAULT_TEMPLATE; $_SESSION["HEADER_COLOR"] = ($res["second_header_color"]) ? $res["second_header_color"] : $res["first_header_color"]; $_SESSION["LANG"] = $res["lang_short"]; $_SESSION["DEFAULT_CHARSET"] = $res["lang_iso"]; $_SESSION["DEFAULT_LANG"] = $res["lang_short"].'_'.strtolower(str_replace('-', '', $res["lang_iso"])); // reset any login error count for this user if ($res['login_error_count'] > 0) { $q = "UPDATE edit_user SET login_error_count = 0, login_error_date_last = NULL, login_error_date_first = NULL WHERE edit_user_id = ".$res['edit_user_id']; $this->db_exec($q); } $pages = array(); $edit_page_ids = array(); // set pages access $q = "SELECT ep.edit_page_id, filename, ep.name AS edit_page_name, ep.order_number AS edit_page_order, menu, popup, popup_x, popup_y, online, ear.level, ear.type "; $q .= "FROM edit_page ep, edit_page_access epa, edit_access_right ear "; $q .= "WHERE ep.edit_page_id = epa.edit_page_id AND ear.edit_access_right_id = epa.edit_access_right_id "; $q .= "AND epa.enabled = 1 AND epa.edit_group_id = ".$res["edit_group_id"]." "; $q .= "ORDER BY ep.order_number"; while ($res = $this->db_return($q)) { // page id array for sub data readout $edit_page_ids[] = $res['edit_page_id']; // create the array for pages array_push($pages, array ( "edit_page_id" => $res["edit_page_id"], "filename" => $res["filename"], "page_name" => $res["edit_page_name"], "order" => $res['edit_page_order'], "menu" => $res["menu"], "popup" => $res["popup"], "popup_x" => $res["popup_x"], "popup_y" => $res["popup_y"], "online" => $res["online"], "acl_level" => $res["level"], "acl_type" => $res["type"], "query" => array (), "visible" => array () )); // make reference filename -> level $pages_acl[$res["filename"]] = $res["level"]; } // for each page // get the visible groups for all pages and write them to the pages $_edit_page_id = 0; $q = "SELECT epvg.edit_page_id, name, flag FROM edit_visible_group evp, edit_page_visible_group epvg WHERE evp.edit_visible_group_id = epvg.edit_visible_group_id AND epvg.edit_page_id IN (".join(', ', $edit_page_ids).") ORDER BY epvg.edit_page_id"; while ($res = $this->db_return($q)) { if ($res['edit_page_id'] != $_edit_page_id) { // search the pos in the array push $pos = $this->array_search_recursive($res['edit_page_id'], $pages, 'edit_page_id'); $_edit_page_id = $res['edit_page_id']; } $pages[$pos[0]]['visible'][$res['name']] = $res['flag']; } // get the same for the query strings $_edit_page_id = 0; $q = "SELECT eqs.edit_page_id, name, value, dynamic FROM edit_query_string eqs WHERE enabled = 1 AND edit_page_id IN (".join(', ', $edit_page_ids).") ORDER BY eqs.edit_page_id"; while ($res = $this->db_return($q)) { if ($res['edit_page_id'] != $_edit_page_id) { // search the pos in the array push $pos = $this->array_search_recursive($res['edit_page_id'], $pages, 'edit_page_id'); $_edit_page_id = $res['edit_page_id']; } $pages[$pos[0]]['query'][] = array ( "name" => $res['name'], "value" => $res['value'], "dynamic" => $res['dynamic'] ); } $_SESSION["PAGES"] = $pages; $_SESSION["PAGES_ACL_LEVEL"] = $pages_acl; // load the edit_access user rights $q = "SELECT ea.edit_access_id, level, type, ea.name, ea.color, edit_default "; $q .= "FROM edit_access_user eau, edit_access_right ear, edit_access ea "; $q .= "WHERE eau.edit_access_id = ea.edit_access_id AND eau.edit_access_right_id = ear.edit_access_right_id AND eau.enabled = 1 AND edit_user_id = ".$this->euid." "; $q .= "ORDER BY ea.name"; $unit_access = array(); $eauid = array(); $unit_acl = array(); while ($res = $this->db_return($q)) { $unit_access[$res['edit_access_id']] = array ( "id" => $res['edit_access_id'], "acl_level" => $res["level"], "acl_type" => $res["type"], "name" => $res["name"], "color" => $res["color"], "default" => $res["edit_default"] ); if ($res['edit_default']) $_SESSION["UNIT_DEFAULT"] = $res['edit_access_id']; array_push($eauid, $res['edit_access_id']); $unit_acl[$res['edit_access_id']] = $res['level']; } $_SESSION["UNIT"] = $unit_access; $_SESSION["UNIT_ACL_LEVEL"] = $unit_acl; $_SESSION['EAID'] = $eauid; } // user has permission to THIS page } // user was not enabled or other login error if ($this->login_error) { if ($res['login_error_count'] == 0) $login_error_date_first = ', login_error_date_first = NOW()'; // update login error count for this user $q = "UPDATE edit_user SET login_error_count = login_error_count + 1, login_error_date_last = NOW() $login_error_date_first WHERE edit_user_id = ".$res['edit_user_id']; $this->db_exec($q); // totally lock the user if error max is reached if ($res['login_error_count'] + 1 > $this->max_login_error_count) { // do some alert reporting in case this error is too big // if strict is set, lock this user // this needs manual unlocking by an admin user if ($res['strict'] && !in_array($this->username, $this->lock_deny_users)) { $q = "UPDATE edit_user SET locked = 1 WHERE edit_user_id = ".$res['edit_user_id']; } } } } // user was not found } // if not username AND password where given // if there was an login error, show login screen if ($this->login_error) { // reset the perm var, to confirm logout $this->permission_okay = 0; } } // if he pressed login at least and is not yet loggined in } // METHOD: login_check_permission // PARAMS: none // RETUNR none // DESC : for every page the user access this script checks if he is allowed to do so public function login_check_permissions() { if ($this->euid && $this->login_error != 103) { $q = "SELECT filename "; $q .= "FROM edit_page ep, edit_page_access epa, edit_group eg, edit_user eu "; $q .= "WHERE ep.edit_page_id = epa.edit_page_id AND eg.edit_group_id = epa.edit_group_id AND eg.edit_group_id = eu.edit_group_id "; $q .= "AND eu.edit_user_id = ".$this->euid." AND filename = '".$this->page_name."' AND eg.enabled = 1 AND epa.enabled = 1"; $res = $this->db_return_row($q); // unset mem limit if debug is set to 1 // if (($GLOBALS["DEBUG_ALL"] || $GLOBALS["DB_DEBUG"] || $_SESSION["DEBUG_ALL"] || $_SESSION["DB_DEBUG"]) && ini_get('memory_limit') != -1) // ini_set('memory_limit', -1); if ($res["filename"] == $this->page_name) { $this->permission_okay = 1; } else { $this->login_error = 103; $this->permission_okay = 0; } } // if called from public, so we can check if the permissions are ok return $this->permission_okay; } // METHOD: login_logout_user // PARAMS: none // RETURN: none // DESC : if a user pressed on logout, destroyes session and unsets all global vars public function login_logout_user() { if ($this->logout || $this->login_error) { // unregister and destroy session vars unset($_SESSION["EUID"]); unset($_SESSION["GROUP_LEVEL"]); unset($_SESSION["PAGES"]); unset($_SESSION["USER_NAME"]); unset($_SESSION["UNIT"]); unset($_SESSION["DEBUG_ALL"]); unset($_SESSION["DB_DEBUG"]); unset($GLOBALS["DEBUG_ALL"]); unset($GLOBALS["DB_DEBUG"]); unset($_SESSION["LANG"]); unset($_SESSION["DEFAULT_CHARSET"]); unset($_SESSION["DEFAULT_LANG"]); unset($_SESSION["GROUP_NAME"]); unset($_SESSION["HEADER_COLOR"]); session_destroy(); // he prints the login screen again $this->permission_okay = 0; } } // METHOD: login_set_acl // PARAMS: none // RETURN: none // DESC : sets all the basic ACLs // init set the basic acl the user has, based on the following rules // * init set from config DEFAULT ACL // * if group ACL is set, it overrides the default ACL // * if page ACL is set, it overrides the group ACL // * if user ACL is set, it overrides the page ACL // set the page ACL // * default ACL set // * set group ACL if not default overrides default ACL // * set page ACL if not default overrides group ACL // set edit access ACL an set default edit access group // * if an account ACL is set, set this parallel, account ACL overrides user ACL if it applies // * if edit access ACL level is set, use this, else use page // set all base ACL levels as a list keyword -> ACL number public function login_set_acl() { // set the mastser user id $this->acl['info']['euid'] = $_SESSION['EUID']; // set admin flag, if this is on, all ACLs are set 100 if ($_SESSION['ADMIN']) $this->acl['info']['admin'] = 1; else $this->acl['info']['admin'] = 0; $this->acl['acl']['admin'] = $this->acl['info']['admin']; if (!$this->acl['info']['admin']) { // this is the base if nothing is set $this->acl['acl']['user'] = DEFAULT_ACL_LEVEL; // old base ACL $this->acl['acl']['max'] = DEFAULT_ACL_LEVEL; // group ACL 0 if ($_SESSION['GROUP_ACL_LEVEL'] != -1) { $this->acl['acl']['user'] = $_SESSION['GROUP_ACL_LEVEL']; if ($this->acl['acl']['user'] > $this->acl['acl']['max']) $this->acl['acl']['max'] = $this->acl['acl']['user']; } // page ACL 2 if ($_SESSION['PAGES_ACL_LEVEL'][$this->page_name] != -1) { $this->acl['acl']['user'] = $_SESSION['PAGES_ACL_LEVEL'][$this->page_name]; if ($this->acl['acl']['user'] > $this->acl['acl']['max']) $this->acl['acl']['max'] = $this->acl['acl']['user']; } // user ACL 1 if ($_SESSION['USER_ACL_LEVEL'] != -1) { $this->acl['acl']['user'] = $_SESSION['USER_ACL_LEVEL']; if ($this->acl['acl']['user'] > $this->acl['acl']['max']) $this->acl['acl']['max'] = $this->acl['acl']['user']; } } else { // if admin is on, level is 100 (admin) $this->acl['acl']['user'] = 100; $this->acl['acl']['max'] = 100; } // set the current page acl // start with default acl // set group if not -1 // set page if not -1, overrides groug $this->acl['acl']['page'] = DEFAULT_ACL_LEVEL; if ($_SESSION['GROUP_ACL_LEVEL'] != -1) { $this->acl['acl']['page'] = $_SESSION['GROUP_ACL_LEVEL']; } if ($_SESSION['PAGES_ACL_LEVEL'][$this->page_name] != -1) { $this->acl['acl']['page'] = $_SESSION['PAGES_ACL_LEVEL'][$this->page_name]; } // PER ACCOUNT (UNIT/edit access)-> foreach ($_SESSION['UNIT'] as $unit) { // set edit access acl, unless admin, then it is default 100 $this->acl['acl']['edit_access'][$unit['id']] = !$this->acl['info']['admin'] ? ($unit['acl_level'] != -1 ? $unit['acl_level'] : $this->acl['acl']['page']) : 100; $this->acl['info']['edit_access'][$unit['id']] = $unit['name']; } // flag if to show extra edit access drop downs (because user has multiple groups assigned) if (count($_SESSION['UNIT']) > 1) $this->acl['acl']['show_ea_extra'] = 1; else $this->acl['acl']['show_ea_extra'] = 0; // set the default edit access $this->acl['info']['default_edit_access'] = $_SESSION['UNIT_DEFAULT']; // integrate the default_acl list, but only for the keyword -> level foreach ($this->default_acl_list as $key => $value) { if (!is_numeric($key)) $this->acl['list'][$key] = $value; } } // METHOD: login_check_edit_access // PARAMS: edit_access_id to check // RETURN: true/false: if the edit access is not in the valid list: false // DESC : checks if this edit access id is valid public function login_check_edit_access($edit_access_id) { if (array_key_exists($edit_access_id, $this->acl['info']['edit_access'])) return true; else return false; } // METHOD: login_password_change // PARAMS: none // RETURN: none // DESC : changes a user password private function login_password_change() { if ($this->change_password) { $event = 'Password Change'; // check that given username is NOT in the deny list, else silent skip (with error log) if (!in_array($this->pw_username, $this->pw_change_deny_users)) { if (!$this->pw_username || !$this->pw_password) { $this->login_error = 200; $data = 'Missing username or old password.'; } // check user exist, if not -> error if (!$this->login_error) { $q = "SELECT edit_user_id FROM edit_user WHERE enabled = 1 AND username = '".$this->db_escape_string($this->pw_username)."'"; list ($edit_user_id) = $this->db_return_row($q); if (!$edit_user_id) { // username wrong $this->login_error = 201; $data = 'User could not be found'; } } // check old passwords match -> error if (!$this->login_error) { $q = "SELECT edit_user_id FROM edit_user WHERE enabled = 1 AND username = '".$this->db_escape_string($this->pw_username)."' AND password = '".$this->db_escape_string($this->pw_old_password)."'"; list ($edit_user_id) = $this->db_return_row($q); if (!$edit_user_id) { // old password wrong $this->login_error = 202; $data = 'The old password does not match'; } } // check if new passwords were filled out -> error if (!$this->login_error) { if (!$this->pw_new_password || !$this->pw_new_password_confirm) { $this->login_error = 203; $data = 'Missing new password or new password confirm.'; } } // check new passwords both match -> error if (!$this->login_error) { if ($this->pw_new_password != $this->pw_new_password_confirm) { $this->login_error = 204; $data = 'The new passwords do not match: '.$this->pw_new_password.' == '.$this->pw_new_password_confirm; } } // no error change this users password if (!$this->login_error) { // update the user (edit_user_id) with the new password $q = "UPDATE edit_user SET password = '".$this->db_escape_string($this->cryptString($this->pw_new_password))."' WHERE edit_user_id = ".$edit_user_id; $this->db_exec($q); $data = 'Password change for user "'.$this->pw_username.'" from "'.$this->pw_old_password.'" to "'.$this->pw_new_password.'"'; } } else { // illegal user error $this->login_error = '220'; $data = 'Illegal user for password change: '.$this->pw_username; } // log this password change attempt $this->write_log($event, $data, $this->login_error, $pw_username, $pw_old_password); } // button pressed } // METHOD: login_print_login // PARAMS: none // RETURN: none // DESC : prints out login html part if no permission (error) is set private function login_print_login() { if (!$this->permission_okay) { // set the templates now $this->login_set_templates(); // if there is a global logout target ... if (file_exists($this->logout_target) && $this->logout_target) { $LOGOUT_TARGET = $this->logout_target; } else { $LOGOUT_TARGET = ""; } $html_string = $this->login_template['template']; // if password change is okay if ($this->password_change) { $html_string_password_change = $this->login_template['password_change']; // pre change the data in the PASSWORD_CHANGE_DIV first foreach ($this->login_template['strings'] as $string => $data) { if ($data) $html_string_password_change = str_replace("{".$string."}", $data, $html_string_password_change); } $this->login_template['strings']['PASSWORD_CHANGE_DIV'] = $html_string_password_change; } // put in the logout redirect string if ($this->logout && $LOGOUT_TARGET) $html_string = str_replace("{LOGOUT_TARGET}", '', $html_string); else $html_string = str_replace("{LOGOUT_TARGET}", '', $html_string); // print error messagae if ($this->login_error) $html_string = str_replace("{ERROR_MSG}", $this->login_error_msg[$this->login_error]."
", $html_string); else $html_string = str_replace("{ERROR_MSG}", "
", $html_string); // create the replace array context foreach ($this->login_template['strings'] as $string => $data) { $html_string = str_replace("{".$string."}", $data, $html_string); } // return the created HTML here return $html_string; } // if permission is 0 then print out login } // METHOD: login_close_class // PARAMS: none // RETURN: none // DESC : last function called, writes log and prints out error msg and exists script if permission 0 private function login_close_class() { // write to LOG table ... if ($this->login_error || $this->login || $this->logout) { $username = ''; $password = ''; // set event if ($this->login) $event = "Login"; else if ($this->logout) $event = "Logout"; else $event = "No Permission"; // prepare for log if ($this->euid) { // get user from user table $q = "SELECT username, password FROM edit_user WHERE edit_user_id = ".$this->euid; list($username, $password) = $this->db_return_row($q); } // if euid is set, get username (or try) $this->write_log($event, '', $this->login_error, $username, $password); } // write log under certain settings // now close DB connection // $this->error_msg = $this->_login(); if (!$this->permission_okay) { return false; } else { return true; } } // METHOD: login_set_templates // PARAMS: // RETURN: none // DESC : checks if there are external templates, if not uses internal fallback ones private function login_set_templates() { $strings = array ( 'HTML_TITLE' => $this->l->__("LOGIN"), 'TITLE' => $this->l->__("LOGIN"), 'USERNAME' => $this->l->__("Username"), 'PASSWORD' => $this->l->__("Password"), 'LOGIN' => $this->l->__("Login"), 'ERROR_MSG' => '', 'LOGOUT_TARGET' => '', 'PASSWORD_CHANGE_BUTTON_VALUE' => $this->l->__('Change Password') ); $error_msgs = array ( "100" => $this->l->__("Fatal Error: [EUID] came in as GET/POST!"), // actually obsolete "1010" => $this->l->__("Fatal Error: Login Failed - Wrong Username or Password"), // user not found "1011" => $this->l->__("Fatal Error: Login Failed - Wrong Username or Password"), // blowfish password wrong "1012" => $this->l->__("Fatal Error: Login Failed - Wrong Username or Password"), // fallback md5 password wrong "102" => $this->l->__("Fatal Error: Login Failed - Please enter username and password"), "103" => $this->l->__("Fatal Error: You do not have the rights to access this Page"), "104" => $this->l->__("Fatal Error: Login Failed - User not enabled"), "105" => $this->l->__("Fatal Error: Login Failed - User is locked"), "220" => $this->l->__("Fatal Error: Password change - The user could not be found"), // actually this is an illegal user, but I mask it '200' => $this->l->__("Fatal Error: Password change - Please enter username and old password"), "201" => $this->l->__("Fatal Error: Password change - The user could not be found"), "202" => $this->l->__("Fatal Error: Password change - The old password is not correct"), "203" => $this->l->__("Fatal Error: Password change - Please fill out both new password fields"), "204" => $this->l->__("Fatal Error: Password change - The new passwords do not match"), "9999" => $this->l->__("Fatal Error: necessary crypt engine could not be found. Login is impossible") // this is bad bad error ); // if password change is okay if ($this->password_change) { $strings = array_merge($strings, array ( 'TITLE_PASSWORD_CHANGE' => 'Change Password for User', 'OLD_PASSWORD' => $this->l->__("Old Password"), 'NEW_PASSWORD' => $this->l->__("New Password"), 'NEW_PASSWORD_CONFIRM' => $this->l->__("New Password confirm"), 'CLOSE' => $this->l->__('Close'), 'JS_SHOW_HIDE' => "function ShowHideDiv(id) { element = document.getElementById(id); if (element.className == 'visible' || !element.className) element.className = 'hidden'; else element.className = 'visible'; }", 'PASSWORD_CHANGE_BUTTON' => '' )); $this->login_template['password_change'] = <<