* @inspiration Horde's Auth class * @version 1.0 */ class AuthSQL { var $_params = array(); var $_auth_name = '_auth'; var $_authentication_tested; /** * Constructs a new authentication object. * * @access public * * @param optional array $params A hash containing parameters. */ function AuthSQL($params = array()) { global $CFG; // The name of this auth session. $this->_params['auth_name'] = isset($params['auth_name']) ? $params['auth_name'] : ''; // The database table containing users to authenticate. $this->_params['user_tbl'] = isset($params['user_tbl']) ? $params['user_tbl'] : 'user_tbl'; // The name of the primary key for the user_tbl. $this->_params['user_id_column'] = isset($params['user_id_column']) ? $params['user_id_column'] : 'user_id'; // The name of the username key for the user_tbl. $this->_params['username_column'] = isset($params['username_column']) ? $params['username_column'] : 'username'; // If using the login_tbl feature, specify the login_tbl. The primary key must match the primary key for the user_tbl. $this->_params['login_tbl'] = isset($params['login_tbl']) ? $params['login_tbl'] : 'login_tbl'; // The type of encryption to use for passwords stored in the user_tbl. Use 'md5' or 'crypt'. $this->_params['encryption_type'] = isset($params['encryption_type']) ? $params['encryption_type'] : 'md5'; // The URL the user will be directed if unsuccessfully calling requireLogin. $this->_params['login_url'] = isset($params['login_url']) ? $params['login_url'] : '/'; // The maximum amount of time a user is allowed to be logged in. They will be forced to login again if they expire. // This applies to admins and users. In seconds. 21600 seconds = 6 hours. $this->_params['login_timeout'] = isset($params['login_timeout']) ? $params['login_timeout'] : $CFG->login_timeout; // The maximum amount of time a user is allowed to be idle before their session expires. They will be forced to login again if they expire. // This applies to admins and users. In seconds. 3600 seconds = 1 hour. $this->_params['idle_timeout'] = isset($params['idle_timeout']) ? $params['idle_timeout'] : $CFG->idle_timeout; // The period of time to compare login abuse attempts. If a threshold of logins is reached in this amount of time the account is blocked. // Days and hours, like this: 'DD:HH' $this->_params['login_abuse_timeframe'] = isset($params['login_abuse_timeframe']) ? $params['login_abuse_timeframe'] : $CFG->login_abuse_timeframe; // When an account is accessed from this many different IPs, the user's password is reset and they are issued a warning. $this->_params['login_abuse_warning_ips'] = isset($params['login_abuse_warning_ips']) ? $params['login_abuse_warning_ips'] : $CFG->login_abuse_warning_ips; // The number of warnings a user will receive (and their password reset each time) before their account is completely blocked. $this->_params['login_abuse_warnings'] = isset($params['login_abuse_warnings']) ? $params['login_abuse_warnings'] : $CFG->login_abuse_warnings; // The maximum number of IP addresses a user can login with over the timeout period before their account is blocked. $this->_params['login_abuse_max_ips'] = isset($params['login_abuse_max_ips']) ? $params['login_abuse_max_ips'] : $CFG->login_abuse_max_ips; // The IP address subnet size threshold. Uses a CIDR notation network mask. Any integar between 0 and 32 is permitted. Setting this // to '24' permits any address in a class C network (255.255.255.0) to be considered the same. Setting to '32' compares each IP absolutely. // Setting to '0' ignores all IPs, thus disabling this feature. $this->_params['login_abuse_ip_bitmask'] = isset($params['login_abuse_ip_bitmask']) ? $params['login_abuse_ip_bitmask'] : $CFG->login_abuse_ip_bitmask; // Specify usernames to exclude from the account abuse detection system. This is specified as a hardcoded array provided at // class instantiation time, or can be saved in the user_tbl under the login_abuse_exempt field. $this->_params['login_abuse_exempt_usernames'] = isset($params['login_abuse_exempt_usernames']) && is_array($params['login_abuse_exempt_usernames']) ? $params['login_abuse_exempt_usernames'] : $CFG->login_abuse_exempt_usernames; $this->_params['trusted_networks'] = isset($params['trusted_networks']) && is_array($params['trusted_networks']) ? $params['trusted_networks'] : $CFG->trusted_networks; // Feature: Allow user accounts to be blocked? Requires the user table to have the columns 'blocked' and 'blocked_reason' $this->_params['features']['blocking'] = isset($params['features']['blocking']) ? $params['features']['blocking'] : false; // Feature: Use a login_tbl to detect excessive logins. This requires blocking to be enabled. $this->_params['features']['abuse_detection'] = isset($params['features']['abuse_detection']) ? $params['features']['abuse_detection'] : false; // Array of usernames which are exempt from remote_ip matching. Users behind proxy servers should be appended to this array so their shifting remote IP will not log them out. $this->_params['match_remote_ip_exempt_usernames'] = isset($params['match_remote_ip_exempt_usernames']) && is_array($params['match_remote_ip_exempt_usernames']) ? $params['match_remote_ip_exempt_usernames'] : $CFG->match_remote_ip_exempt_usernames; // Feature: Match the user's current remote IP against the one they logged in with. $this->_params['features']['match_remote_ip'] = isset($params['features']['match_remote_ip']) ? $params['features']['match_remote_ip'] : true; $this->_auth_name = '_auth_' . $this->_params['auth_name']; } /** * Clear any authentication tokens in the current session. A.K.A. logout. * * @access public */ function clearAuth() { dbQuery(" UPDATE " . $this->_params['user_tbl'] . " SET seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)), last_login_datetime = '0000-00-00 00:00:00' WHERE " . $this->_params['user_id_column'] . " = '" . $this->getVal('user_id') . "' "); $_SESSION[$this->_auth_name] = array(); $_SESSION[$this->_auth_name]['authenticated'] = false; } /** * Sets a variable into a registered auth session. * * @access public * * @param mixed $key Which value to set. * @param mixed $val Value to set variable to. */ function setVal($key, $val) { if (!isset($_SESSION[$this->_auth_name]['user_data'])) { $_SESSION[$this->_auth_name]['user_data'] = array(); } $_SESSION[$this->_auth_name]['user_data'][$key] = $val; } /** * Returns a specified value from a registered auth session. * * @access public * * @param mixed $key Which value to return. * @param mixed $default Value to return if key not found in user_data. * * @return mixed Value stored in session. */ function getVal($key, $default='') { if (isset($_SESSION[$this->_auth_name][$key])) { return $_SESSION[$this->_auth_name][$key]; } else if (isset($_SESSION[$this->_auth_name]['user_data'][$key])) { return $_SESSION[$this->_auth_name]['user_data'][$key]; } else { return $default; } } /** * Set the features of an auth object. * * @param array $features Array of feature keys and value to set. * * @return bool true on success, false on failure */ function setFeature($features=null) { if (isset($features) && is_array($features)) { // Set features for this object. $this->_params['features'] = array_merge($this->_params['features'], $features); } } /** * Return the value of a feature configuration. This usually returns a bool value. * * @access public * * @param string $feature Which feature to return. * * @return mixed Configured feature value. */ function getFeature($feature) { return $this->_params['features'][$feature]; } /** * Find out if a set of login credentials are valid. * * @access private * * @param string $username The username to check. * @param string $password The password to compare to username. * * @return mixed False if credentials not found in DB, or returns DB row matching credentials. */ function authenticate($username, $password) { // Query DB for user matching credentials. $qid = dbQuery(" SELECT *, " . $this->_params['user_id_column'] . " AS user_id FROM " . $this->_params['user_tbl'] . " WHERE BINARY username = '" . mysql_real_escape_string($username) . "' AND BINARY userpass = '" . mysql_real_escape_string($this->encryptPassword($password)) . "' "); // Return user data if found. if ($user_data = mysql_fetch_assoc($qid)) { return $user_data; } else { return false; } } /** * If user authenticated, register login into session. * * @access private * * @param string $username The username to check. * @param string $password The password to compare to username. * * @return boolean Whether or not the credentials are valid. */ function login($username, $password) { $this->clearAuth(); if (!$user_data = $this->authenticate($username, $password)) { // No login: failed authentication! return false; } // Register authenticated session. $_SESSION[$this->_auth_name] = array( 'authenticated' => true, 'user_id' => $user_data['user_id'], 'auth_name' => $this->_params['auth_name'], 'username' => $username, 'priv' => $user_data['priv'], 'login_datetime' => date('Y-m-d H:i:s'), 'last_access_datetime' => date('Y-m-d H:i:s'), 'remote_ip' => getRemoteAddr(), 'abuse_warning_level' => $user_data['abuse_warning_level'], 'login_abuse_exempt' => isset($user_data['login_abuse_exempt']) ? !empty($user_data['login_abuse_exempt']) : in_array(strtolower($username), $this->_params['login_abuse_exempt_usernames']), 'match_remote_ip_exempt'=> isset($user_data['match_remote_ip_exempt']) ? !empty($user_data['match_remote_ip_exempt']) : in_array(strtolower($username), $this->_params['match_remote_ip_exempt_usernames']), 'user_data' => $user_data ); /** * Check if the account is blocked, respond in context to reason. Cancel the login if blocked. */ if ($this->getFeature('blocking')) { if (!empty($user_data['blocked'])) { logMsg(sprintf('Login failed, blocked account. User: %s (%s) Reason: %s', $user_data['user_id'], $username, $user_data['blocked_reason']), LOG_NOTICE, __FILE__, __LINE__); switch ($user_data['blocked_reason']) { case 'account abuse' : raiseMsg(sprintf(_("This account has been blocked due to possible account abuse. Please contact us to reactivate."), null), MSG_WARNING, __FILE__, __LINE__); break; default : raiseMsg(sprintf(_("This account is currently not active. %s"), $user_data['blocked_reason']), MSG_WARNING, __FILE__, __LINE__); break; } // No login: user is blocked! $this->clearAuth(); return false; } } /** * Check the login_tbl for too many logins under this account. * (1) Count the number of unique IP addresses that logged in under this user within the login_abuse_timeframe * (2) If this number exceeds the login_abuse_max_ips, assume multiple people are logging in under the same account. **/ if ($this->getFeature('abuse_detection') && !$this->getVal('login_abuse_exempt')) { $qid = dbQuery(" SELECT COUNT(DISTINCT LEFT(remote_ip_binary, " . $this->_params['login_abuse_ip_bitmask'] . ")) FROM " . $this->_params['login_tbl'] . " WHERE " . $this->_params['user_id_column'] . " = '" . $this->getVal('user_id') . "' AND DATE_ADD(login_datetime, INTERVAL '" . $this->_params['login_abuse_timeframe'] . "' DAY_HOUR) > NOW() "); list($distinct_ips) = mysql_fetch_row($qid); if ($distinct_ips > $this->_params['login_abuse_max_ips']) { if ($this->getVal('abuse_warning_level') < $this->_params['login_abuse_warnings']) { // Warn the user with a password reset. $this->resetPassword(null, _("This is a security precaution. We have detected this account has been accessed from multiple computers simultaneously. It is against policy to share your login information with others. If further account abuse is detected your account will be blocked.")); raiseMsg(_("Your password has been reset as a security precaution. Please check your email for more information."), MSG_NOTICE, __FILE__, __LINE__); logMsg(sprintf('Account abuse detected for user %s from IP %s', $this->getVal('username'), $this->getVal('remote_ip')), LOG_WARNING, __FILE__, __LINE__); } else { // Block the account with the reason of account abuse. $this->blockAccount(null, 'account abuse'); raiseMsg(_("Your account has been blocked as a security precaution. Please contact us for more information."), MSG_NOTICE, __FILE__, __LINE__); logMsg(sprintf('Account blocked for user %s from IP %s', $this->getVal('username'), $this->getVal('remote_ip')), LOG_ALERT, __FILE__, __LINE__); } // Increment user's warning level. dbQuery("UPDATE " . $this->_params['user_tbl'] . " SET abuse_warning_level = abuse_warning_level + 1 WHERE " . $this->_params['user_id_column'] . " = '" . $this->getVal('user_id') . "'"); // Reset the login counter for this user. dbQuery("DELETE FROM " . $this->_params['login_tbl'] . " WHERE " . $this->_params['user_id_column'] . " = '" . $this->getVal('user_id') . "'"); // No login: reset password because of account abuse! $this->clearAuth(); return false; } // Update the login counter table with this login access. Convert IP to binary. dbQuery(" INSERT INTO " . $this->_params['login_tbl'] . " ( " . $this->_params['user_id_column'] . ", login_datetime, remote_ip_binary ) VALUES ( '" . $this->getVal('user_id') . "', '" . $this->getVal('login_datetime') . "', '" . sprintf('%032b', ip2long($this->getVal('remote_ip'))) . "' ) "); } // Update user table with this login. dbQuery(" UPDATE " . $this->_params['user_tbl'] . " SET last_login_datetime = '" . $this->getVal('login_datetime') . "', last_access_datetime = '" . $this->getVal('login_datetime') . "', last_login_ip = '" . $this->getVal('remote_ip') . "' WHERE " . $this->_params['user_id_column'] . " = '" . $this->getVal('user_id') . "' "); // We're logged-in! return true; } /** * Test if user has a currently logged-in session. * - authentication flag set to true * - username not empty * - total logged-in time is not greater than login_timeout * - idle time is not greater than idle_timeout * - remote address is the same as the login remote address (aol users excluded). * * @access public */ function isLoggedIn($user_id=null) { if (isset($user_id)) { // Check the login status of a specific user. $qid = dbQuery(" SELECT 1 FROM " . $this->_params['user_tbl'] . " WHERE " . $this->_params['user_id_column'] . " = '" . mysql_real_escape_string($user_id) . "' AND DATE_ADD(last_login_datetime, INTERVAL '" . $this->_params['login_timeout'] . "' SECOND) > NOW() AND DATE_ADD(last_access_datetime, INTERVAL '" . $this->_params['idle_timeout'] . "' SECOND) > NOW() "); return (mysql_num_rows($qid) > 0); } // User login test need only be run once per script execution. We cache the result in the session. if ($this->_authentication_tested && isset($_SESSION[$this->_auth_name]['authenticated'])) { return $_SESSION[$this->_auth_name]['authenticated']; } // Tesing login should occur once. This is the first time. Set flag. $this->_authentication_tested = true; // Some users will access from networks with changing IP number (i.e. behind a proxy server). These users must be allowed entry be adding their IP to the list of trusted_networks. if ($trusted_net = ipInRange(getRemoteAddr(), $this->_params['trusted_networks'])) { $user_in_trusted_network = true; logMsg(sprintf('%s%s accessing from trusted network %s', ucfirst($this->_params['auth_name']), ($this->getVal('user_id') ? ' ' . $this->getVal('user_id') . ' (' . $this->getVal('username') . ')' : ''), $trusted_net ), LOG_INFO, __FILE__, __LINE__); } else if (preg_match('/proxy.aol.com$/i', getRemoteAddr(true))) { $user_in_trusted_network = true; logMsg(sprintf('%s%s accessing from trusted network proxy.aol.com', ucfirst($this->_params['auth_name']), ($this->getVal('user_id') ? ' ' . $this->getVal('user_id') . ' (' . $this->getVal('username') . ')' : '') ), LOG_NOTICE, __FILE__, __LINE__); } else { $user_in_trusted_network = false; } // Do we match the user's remote IP at all? Yes, if set in config and not disabled for specific user. if ($this->getFeature('match_remote_ip') && !$this->getVal('match_remote_ip_exempt')) { $remote_ip_is_matched = ($_SESSION[$this->_auth_name]['remote_ip'] == getRemoteAddr() || $user_in_trusted_network); } else { logMsg(sprintf('%s%s exempt from remote_ip match.', ucfirst($this->_params['auth_name']), ($this->getVal('user_id') ? ' ' . $this->getVal('user_id') . ' (' . $this->getVal('username') . ')' : '') ), LOG_DEBUG, __FILE__, __LINE__); $remote_ip_is_matched = true; } // Test login with information stored in session. Skip IP matching for users from trusted networks. if (true === $_SESSION[$this->_auth_name]['authenticated'] && !empty($_SESSION[$this->_auth_name]['username']) && strtotime($_SESSION[$this->_auth_name]['login_datetime']) > time() - $this->_params['login_timeout'] && strtotime($_SESSION[$this->_auth_name]['last_access_datetime']) > time() - $this->_params['idle_timeout'] && $remote_ip_is_matched ) { // User is authenticated! $_SESSION[$this->_auth_name]['last_access_datetime'] = date('Y-m-d H:i:s'); // Update the DB with the last_access_datetime and increment the seconds_online. dbQuery(" UPDATE " . $this->_params['user_tbl'] . " SET seconds_online = seconds_online + (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(last_access_datetime)) + 1, last_access_datetime = '" . $this->getVal('last_access_datetime') . "' WHERE " . $this->_params['user_id_column'] . " = '" . $this->getVal('user_id') . "' "); if (mysql_affected_rows($GLOBALS['dbh']) > 0) { // User record still exists in DB. Do this to ensure user was not delete from DB between accesses. Notice "+ 1" in SQL above to ensure record is modified. return true; } else { logMsg(sprintf('User update failed. Record not found for %s %s (%s).', $this->_params['auth_name'], $this->getVal('user_id'), $this->getVal('username')), LOG_NOTICE, __FILE__, __LINE__); } } else if (true === $_SESSION[$this->_auth_name]['authenticated']) { // User is authenticated, but login has expired. raiseMsg(sprintf(_("Your %s session has closed. You need to log-in again."), strtolower($this->_params['auth_name'])), MSG_NOTICE, __FILE__, __LINE__); // Log the reason for login expiration. $expire_reasons = array(); if (empty($_SESSION[$this->_auth_name]['username'])) { $expire_reasons[] = 'username not found'; } if (strtotime($_SESSION[$this->_auth_name]['login_datetime']) <= time() - $this->_params['login_timeout']) { $expire_reasons[] = 'login_timeout expired'; } if (strtotime($_SESSION[$this->_auth_name]['last_access_datetime']) <= time() - $this->_params['idle_timeout']) { $expire_reasons[] = 'idle_timeout expired'; } if ($_SESSION[$this->_auth_name]['remote_ip'] != getRemoteAddr()) { if ($this->getFeature('match_remote_ip') && !$this->getVal('match_remote_ip_exempt')) { $expire_reasons[] = sprintf('remote_ip not matched (%s != %s)', $_SESSION[$this->_auth_name]['remote_ip'], getRemoteAddr()); } else { $expire_reasons[] = sprintf('remote_ip not matched but user was exempt from this check (%s != %s)', $_SESSION[$this->_auth_name]['remote_ip'], getRemoteAddr()); } } logMsg(sprintf('%s %s (%s) session expired: %s', ucfirst($this->_params['auth_name']), $this->getVal('user_id'), $this->getVal('username'), join(', ', $expire_reasons)), LOG_DEBUG, __FILE__, __LINE__); } // User is not authenticated. $this->clearAuth(); return false; } /** * Redirect user to login page if they are not logged in. * * @param string $msg The text description of a message to raise. * @param int $type The type of message: MSG_NOTICE, * MSG_SUCCESS, MSG_WARNING, or MSG_ERR. * @param string $file __FILE__. * @param string $line __LINE__. * * @access public */ function requireLogin($msg='', $type=MSG_NOTICE, $file=null, $line=null) { if (!$this->isLoggedIn()) { if ('' != $msg) { raiseMsg($msg, $type, $file, $line); } setBoomerangURL(absoluteMe()); dieURL($this->_params['login_url']); } } /** * This sets the 'blocked' field for a user in the user_tbl, and also * adds an optional reason * * @param string $reason The reason for blocking the account. */ function blockAccount($user_id=null, $reason='') { if ($this->getFeature('blocking')) { if (strlen(mysql_real_escape_string($reason)) > 255) { // blocked_reason field is varchar(255). logMsg(sprintf('Blocked reason provided is greater than 255 characters: %s', $reason), LOG_WARNING, __FILE__, __LINE__); } // Get user_id if specified. $user_id = isset($user_id) ? $user_id : $this->getVal('user_id'); dbQuery(" UPDATE " . $this->_params['user_tbl'] . " SET blocked = 'true', blocked_reason = '" . mysql_real_escape_string($reason) . "' WHERE " . $this->_params['user_id_column'] . " = '" . mysql_real_escape_string($user_id) . "' "); } } /** * Unblocks a user in the user_tbl, and clears any blocked_reason. */ function unblockAccount($user_id=null) { if ($this->getFeature('blocking')) { // Get user_id if specified. $user_id = isset($user_id) ? $user_id : $this->getVal('user_id'); dbQuery(" UPDATE " . $this->_params['user_tbl'] . " SET blocked = '', blocked_reason = '' WHERE " . $this->_params['user_id_column'] . " = '" . mysql_real_escape_string($user_id) . "' "); } } /** * Returns true if username already exists in database. * * @param string $username Username to look for. * * @return bool True if username exists. */ function usernameExists($username) { $qid = dbQuery("SELECT 1 FROM " . $this->_params['user_tbl'] . " WHERE username = '" . mysql_real_escape_string($username) . "'"); return (mysql_num_rows($qid) > 0); } /** * Returns a username for a specified user id. * * @param string $user_id User id to look for. * * @return string Username, or false if none found. */ function getUsername($user_id) { $qid = dbQuery("SELECT " . $this->_params['username_column'] . " FROM " . $this->_params['user_tbl'] . " WHERE " . $this->_params['user_id_column'] . " = '" . mysql_real_escape_string($user_id) . "'"); if (list($username) = mysql_fetch_row($qid)) { return $username; } else { return false; } } /** * Returns a randomly generated password based on $pattern. The pattern is any * sequence of 'x', 'V', 'C', 'v', 'c', or 'd' and if it is something like 'cvccv' this * function will generate a pronouncable password. Recommend using more complex * patterns, at minimum the US State Department standard: cvcddcvc. * * - x a random upper or lower alpha character or digit * - C a random upper or lower consanant * - V a random upper or lower vowel * - c a random lowercase consanant * - v a random lowercase vowel * - d a random digit * * @param string $pattern a sequence of character types, above. * * @return string a password */ function generatePassword($pattern='CvccvCdd') { mt_srand((double) microtime() * 10000000); for ($i=0; $i_params['encryption_type']) { case 'plain' : return $password; break; case 'crypt' : return crypt($password, crypt($password)); break; case 'sha1' : if (function_exists('sha1')) { // Only in PHP 4.3.0+ return sha1($password); break; } case 'md5' : default : return md5($password); break; } } /** * */ function setPassword($user_id=null, $password) { // Get user_id if specified. $user_id = isset($user_id) ? $user_id : $this->getVal('user_id'); // Issue the password change query. dbQuery(" UPDATE " . $this->_params['user_tbl'] . " SET userpass = '" . mysql_real_escape_string($this->encryptPassword($password)) . "' WHERE " . $this->_params['user_id_column'] . " = '" . mysql_real_escape_string($user_id) . "' "); } /** * Resets the password for the user with the specified id. * * @param string $user_id The id of the user to reset. * @param string $reason Additional message to add to the reset email. * * @return string The user's new password. */ function resetPassword($user_id=null, $reason='') { global $CFG; // Get user_id if specified. $user_id = isset($user_id) ? $user_id : $this->getVal('user_id'); // Reset password of a specific user. $qid = dbQuery(" SELECT * FROM " . $this->_params['user_tbl'] . " WHERE " . $this->_params['user_id_column'] . " = '" . mysql_real_escape_string($user_id) . "' "); $user_data = mysql_fetch_assoc($qid); // Get new password. $password = $this->generatePassword(); // Issue the password change query. dbQuery(" UPDATE " . $this->_params['user_tbl'] . " SET userpass = '" . mysql_real_escape_string($this->encryptPassword($password)) . "' WHERE " . $this->_params['user_id_column'] . " = '" . mysql_real_escape_string($user_id) . "' "); // Email the user with the new account information. // $reason is used in this template. if (include 'email_reset_password.ihtml') { mail($user_data['email'], $email_subject, $email_body, "From: $CFG->site_name <$CFG->site_email>\r\n", $CFG->envelope_sender_address); } return array('username'=>$user_data['username'], 'userpass'=>$password); } /** * If the current user has access to the specified $security_zone, return true. * If the optional $priv is supplied, test that against the zone. * * @param constant $security_zone string of comma delimited priviliges for the zone * @param string $priv a privilege that might be found in a zone * * @return bool true if user is a member of security zone, false otherwise */ function inClearanceZone($security_zone, $priv='') { $zone_members = preg_split('/,\s*/', $security_zone); $priv = empty($priv) ? $this->getVal('priv') : $priv; // If the current user's privilege level is NOT in that array or if the // user has no privilege, return false. Otherwise the user is clear. if (!in_array($priv, $zone_members) || empty($priv)) { return false; } else { return true; } } /** * This function tests a list of arguments $security_zone against the priv that the current user has. * If the user doesn't have one of the supplied privs, die. * * @param constant $security_zone string of comma delimited priviliges for the zone */ function requireAccessClearance($security_zone, $msg='') { $zone_members = preg_split('/,\s*/', $security_zone); /* If the current user's privilege level is NOT in that array or if the * user has no privilege, DIE with a message. */ if (!in_array($this->getVal('priv'), $zone_members) || !$this->getVal('priv')) { $msg = empty($msg) ? _("You have insufficient privileges to view that page.") : $msg; raiseMsg($msg, MSG_NOTICE, __FILE__, __LINE__); dieBoomerangURL(); } } } // end class // CIDR cheatsheet // // Netmask Netmask (binary) CIDR Notes // _____________________________________________________________________________ // 255.255.255.255 11111111.11111111.11111111.11111111 /32 Host (single addr) // 255.255.255.254 11111111.11111111.11111111.11111110 /31 Unuseable // 255.255.255.252 11111111.11111111.11111111.11111100 /30 2 useable // 255.255.255.248 11111111.11111111.11111111.11111000 /29 6 useable // 255.255.255.240 11111111.11111111.11111111.11110000 /28 14 useable // 255.255.255.224 11111111.11111111.11111111.11100000 /27 30 useable // 255.255.255.192 11111111.11111111.11111111.11000000 /26 62 useable // 255.255.255.128 11111111.11111111.11111111.10000000 /25 126 useable // 255.255.255.0 11111111.11111111.11111111.00000000 /24 "Class C" 254 useable // // 255.255.254.0 11111111.11111111.11111110.00000000 /23 2 Class C's // 255.255.252.0 11111111.11111111.11111100.00000000 /22 4 Class C's // 255.255.248.0 11111111.11111111.11111000.00000000 /21 8 Class C's // 255.255.240.0 11111111.11111111.11110000.00000000 /20 16 Class C's // 255.255.224.0 11111111.11111111.11100000.00000000 /19 32 Class C's // 255.255.192.0 11111111.11111111.11000000.00000000 /18 64 Class C's // 255.255.128.0 11111111.11111111.10000000.00000000 /17 128 Class C's // 255.255.0.0 11111111.11111111.00000000.00000000 /16 "Class B" // // 255.254.0.0 11111111.11111110.00000000.00000000 /15 2 Class B's // 255.252.0.0 11111111.11111100.00000000.00000000 /14 4 Class B's // 255.248.0.0 11111111.11111000.00000000.00000000 /13 8 Class B's // 255.240.0.0 11111111.11110000.00000000.00000000 /12 16 Class B's // 255.224.0.0 11111111.11100000.00000000.00000000 /11 32 Class B's // 255.192.0.0 11111111.11000000.00000000.00000000 /10 64 Class B's // 255.128.0.0 11111111.10000000.00000000.00000000 /9 128 Class B's // 255.0.0.0 11111111.00000000.00000000.00000000 /8 "Class A" // // 254.0.0.0 11111110.00000000.00000000.00000000 /7 // 252.0.0.0 11111100.00000000.00000000.00000000 /6 // 248.0.0.0 11111000.00000000.00000000.00000000 /5 // 240.0.0.0 11110000.00000000.00000000.00000000 /4 // 224.0.0.0 11100000.00000000.00000000.00000000 /3 // 192.0.0.0 11000000.00000000.00000000.00000000 /2 // 128.0.0.0 10000000.00000000.00000000.00000000 /1 // 0.0.0.0 00000000.00000000.00000000.00000000 /0 IP space ?>