<?php
/************************************************************************
* *
* Copyright (C) 2002 Stuart Reeves *
* *
* 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 2 *
* 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. *
* *
* The GNU General Public License is available from: *
* http://www.gnu.org/copyleft/gpl.html *
* *
************************************************************************/
/* Stuart's lns (lame node system) */
// Alphabet limit chars
define(CHAR_UC_MIN, 65);
define(CHAR_UC_MAX, 90);
define(CHAR_LC_MIN, 97);
define(CHAR_LC_MAX, 122);
/* The Auth object provides facilities to create new users, authenticate
* existing ones and returns information about a given set of users (such as
* profile information) */
class Auth
{
// Basic database information
var $host,
$dbuser,
$dbpasswd,
$db,
$table;
// Data for the login session
var $username,
$maxPasswordLength;
// Constructor
function Auth($host, $dbuser, $dbpasswd, $db, $table) {
$this->host = $host;
$this->dbuser = $dbuser;
$this->dbpasswd = $dbpasswd;
$this->db = $db;
$this->table = $table;
$this->maxPasswordLength = 0;
}
/* Checks a username/password combination against the database and stores current values for
* all user information fields.
*
* Args: $authPassword (string) - Password to authenticate user with
* $loginState (boolean) - Whether the user is being logged in or out
* (true indicates a log-in)
*
* Returns: 0 (integer) - Failed authentication
* $ts (integer) - Successful authentication, return timestamp of last login
* -1 (integer) - Bad number of results (i.e. > 1) */
function authUser($authPassword, $loginState) {
$query = "SELECT * FROM $this->table WHERE username = '$this->username'";
// Connect to the database
$link = mysql_connect($this->host, $this->dbuser, $this->dbpasswd);
$dbselect = mysql_select_db($this->db, $link);
$dbquery = mysql_query($query, $link);
// Store the maximum length of the password if this method is being called by
// updatePassword()
$this->maxPasswordLength = mysql_field_len($dbquery, 0);
// Get the number of rows for the error conditions
$rows = mysql_num_rows($dbquery);
if ($rows == 0) {
return 0;
} else if ($rows == 1) {
$authdata = mysql_fetch_object($dbquery);
if (MD5_PASSWORD)
$authPassword = md5($authPassword);
if (strcmp($authdata->password, $authPassword) == 0) {
$query = "";
// Set the user's login state
if ($loginState)
$query = "UPDATE $this->table SET ts = NOW(), loginstate = 't' " .
"WHERE username = '$this->username'";
else
$query = "UPDATE $this->table SET loginstate = 'f' " .
"WHERE username = '$this->username'";
$dbquery = mysql_query($query, $link);
return $authdata->ts;
} else {
return 0;
}
} else // Too many results (i.e. some database inconsistencies are present)
return -1;
mysql_close($link);
}
function setUsername($username) {
$this->username = $username;
}
function getUsername() {
return $this->username;
}
/* Returns all usernames.
*
* Args: $getLoggedIn (boolean) - Whether to display only logged in users
*
* Returns: $userList (object) - Array of associative user data arrays
* 0 (integer) - Either no users currently logged in or no users
* exist in database */
function getUserList($getLoggedIn) {
$query = "";
if ($getLoggedIn)
$query = "SELECT username FROM $this->table WHERE loginstate = 't'";
else
$query = "SELECT username, ts, superuser FROM $this->table";
// Connect to the database
$link = mysql_connect($this->host, $this->dbuser, $this->dbpasswd);
$dbselect = mysql_select_db($this->db, $link);
$dbquery = mysql_query($query, $link);
// Get the number of rows for the error conditions
$rows = mysql_num_rows($dbquery);
$code = 0;
$userList = array();
if ($rows > 0) {
$i = 0;
while ($data = mysql_fetch_object($dbquery)) {
$userData = array();
$userData["username"] = $data->username;
$userData["ts"] = $data->ts;
$userData["superuser"] = $data->superuser;
$userList[$i++] = $userData;
}
$code = $userList;
}
mysql_close($link);
return $code;
}
/* Checks whether this user has been granted superuser status or not.
*
* Returns: 1 (integer) - This user is a superuser
* 0 (integer) - This user is not a superuser
* -1 (integer) - User does not exist or a database error is present (i.e.
* more than one user with this name) */
function isSuperuser() {
$query = "SELECT superuser FROM $this->table WHERE username = '$this->username'";
// Connect to the database
$link = mysql_connect($this->host, $this->dbuser, $this->dbpasswd);
$dbselect = mysql_select_db($this->db, $link);
$dbquery = mysql_query($query, $link);
$rows = mysql_num_rows($dbquery);
$code = 0;
if ($rows == 1) {
$nodedata = mysql_fetch_object($dbquery);
if ($nodedata->superuser == 't')
$code = 1;
else
$code = 0;
} else
$code = -1;
mysql_close($link);
return $code;
}
/* Creates a new username/password combination.
*
* Args: $username (string) - Username to create
* $superuser (boolean) - Whether this user is an admin or not
*
* Returns: 0 (integer) - Failed authentication
* $password (string) - Successful authentication
* -1 (integer) - Bad number of results (i.e. > 1) */
function createUser($username, $superuser) {
$query = "SELECT password FROM $this->table WHERE username = '$username'";
// Connect to the database
$link = mysql_connect($this->host, $this->dbuser, $this->dbpasswd);
$dbselect = mysql_select_db($this->db, $link);
$dbquery = mysql_query($query, $link);
// Get the number of rows for the error conditions
$rows = mysql_num_rows($dbquery);
if ($rows == 0) { // Username is available
$plainPassword = $this->generatePassword();
// Create new password for user
if (MD5_PASSWORD)
$storedPassword = md5($plainPassword);
else
$storedPassword = $plainPassword;
$suText = "f";
if ($superuser)
$suText = "t";
$query = "INSERT INTO $this->table VALUES (NULL, NULL, '$username', '$storedPassword',
'', '', '', '$suText', 'f')";
mysql_query($query, $link);
return $plainPassword;
} else if ($rows == 1) {
return 0;
} else // Too many results (i.e. some database inconsistencies are present)
return -1;
mysql_close($link);
}
/* Gets the profile data for a user.
*
* Args: $args[0] (string) - Optional argument for retrieving data for another user
* (can be used statically, but $tablename must be set)
*
* Returns: 0 (integer) - User does not exist
* $userData (array) - An associative array of this user's profile */
function getUserData() {
$args = func_get_args();
$query = "";
// Construct query; make sure we do not go anywhere near the user's password
if (isset($args[0])) {
$query = "SELECT username, ts, created, email, website, profile FROM $this->table
WHERE username = '" . $args[0] . "'";
} else {
$query = "SELECT username, ts, created, email, website, profile FROM $this->table
WHERE username = '$this->username'";
}
// Connect to the database
$link = mysql_connect($this->host, $this->dbuser, $this->dbpasswd);
$dbselect = mysql_select_db($this->db, $link);
$dbquery = mysql_query($query, $link);
$rows = mysql_num_rows($dbquery);
if ($rows != 0) {
$authdata = mysql_fetch_object($dbquery);
$userData = array();
$userData["username"] = $authdata->username;
$userData["ts"] = $authdata->ts;
$userData["created"] = $authdata->created;
$userData["email"] = $authdata->email;
$userData["website"] = $authdata->website;
$userData["profile"] = $authdata->profile;
} else
$userData = 0;
mysql_close($link);
return $userData;
}
function setUserData($email, $website, $profile) {
$query = "UPDATE $this->table SET email = '$email',
website = '$website',
profile = '$profile'
WHERE username = '$this->username'";
// Connect to the database
$link = mysql_connect($this->host, $this->dbuser, $this->dbpasswd);
$dbselect = mysql_select_db($this->db, $link);
$dbquery = mysql_query($query, $link);
mysql_close($link);
}
/* Update the user's password. The password entered must be within the limits set by
* GEN_PASSWORD_MIN and the maximum length of the field.
*
* Args: $currPassword (string) - The user's current password
* $newPassword (string) - The replacement password
*
* Return: 0 (integer) - The user did not type their current password in
* correctly
* -1 (integer) - The new password is either too short or too long
* 1 (integer) - Successful password change
*/
function updatePassword($currPassword, $newPassword) {
if ($this->authUser($currPassword, true) > 0 && $this->maxPasswordLength > 0) {
$len = strlen($newPassword);
if ($len >= GEN_PASSWORD_MIN && $len < $this->maxPasswordLength) {
if (MD5_PASSWORD)
$newPassword = md5($newPassword);
$query = "UPDATE $this->table SET password = '$newPassword'
WHERE username = '$this->username'";
// Connect to the database and perform update
$link = mysql_connect($this->host, $this->dbuser, $this->dbpasswd);
$dbselect = mysql_select_db($this->db, $link);
$dbquery = mysql_query($query, $link);
mysql_close($link);
return 1;
} else
return -1;
} else
return 0;
}
/* Generates an alphanumeric password between GEN_PASSWORD_MIN/MAX characters long
*
* Returns: $password (string) - The generated password string */
function generatePassword() {
$password = "";
Util::reseed();
// Create a password with varying number of characters
$numchars = rand(GEN_PASSWORD_MIN, GEN_PASSWORD_MAX);
for ($i = 0; $i < $numchars; ++$i) {
Util::reseed();
// Character can be number
if (rand(0, 1) == 0)
$password .= rand(0, 9);
else {
Util::reseed();
// Choose lowercase letter
if (rand(0, 1) == 0) {
Util::reseed();
$password .= chr(rand(CHAR_LC_MIN, CHAR_LC_MAX));
} else { // or uppercase
Util::reseed();
$password .= chr(rand(CHAR_UC_MIN, CHAR_UC_MAX));
}
}
}
return $password;
}
} // End class Auth