inc/users.inc.php
author peter
Fri, 26 Sep 2008 10:02:33 +0000
changeset 194 df674d004508
parent 192 3d18290ac993
child 195 5ac118d6556c
permissions -rw-r--r--
[feladat @ 307] Minor bug fix: bg.shiny@gmail.com reported that cyrillic characters where not supported. Applied the patch which was supplied. This closes #93.

<?php

/*  Poweradmin, a friendly web-based admin tool for PowerDNS.
 *  See <https://rejo.zenger.nl/poweradmin> for more details.
 *
 *  Copyright 2007, 2008  Rejo Zenger <rejo@zenger.nl>
 *
 *  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 <http://www.gnu.org/licenses/>.
 */

require_once("inc/toolkit.inc.php");


/* 
 *  Function to see if user has right to do something. It will check if
 *  user has "ueberuser" bit set. If it isn't, it will check if the user has
 *  the specific permission. It returns "false" if the user doesn't have the
 *  right, and "true" if the user has. 
 */

function verify_permission($permission) {

        global $db;

	if ((!isset($_SESSION['userid'])) || (!is_object($db))) {
		return 0;
	}

        // Set current user ID.
        $userid=$_SESSION['userid'];

		$query = 'SELECT id FROM perm_items WHERE name='.$db->quote('user_is_ueberuser', 'text');
		$ueberUserId = $db->queryOne($query);

        // Find the template ID that this user has been assigned.
        $query = "SELECT perm_templ
			FROM users 
			WHERE id = " . $db->quote($userid, 'integer') ;
        $templ_id = $db->queryOne($query);

        // Does this user have ueberuser rights?
        $query = "SELECT id 
			FROM perm_templ_items 
			WHERE templ_id = " . $db->quote($templ_id, 'integer') . " 
			AND perm_id = ".$ueberUserId;
        $response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
        if ( $response->numRows() > 0 ) {
                return 1;
        }

        // Find the permission ID for the requested permission.
        $query = "SELECT id 
			FROM perm_items 
			WHERE name = " . $db->quote($permission, 'text') ;
        $perm_id = $db->queryOne($query);

        // Check if the permission ID is assigned to the template ID. 
        $query = "SELECT id 
			FROM perm_templ_items 
			WHERE templ_id = " . $db->quote($templ_id, 'integer') . " 
			AND perm_id = " . $db->quote($perm_id, 'integer') ;
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
        $response = $db->query($query);
        if ( $response->numRows() > 0 ) {
                return 1;
        } else {
                return 0;
        }
}

function list_permission_templates() {
	global $db;
	$query = "SELECT * FROM perm_templ";
	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	$template_list = array();
	while ($template= $response->fetchRow()) {
		$tempate_list[] = array(
			"id"	=>	$template['id'],
			"name"	=>	$template['name'],
			"descr"	=>	$template['descr']
			);
	}
	return $tempate_list;
}

/*
 * Retrieve all users.
 * Its to show_users therefore the odd name. Has to be changed.
 * return values: an array with all users in it.
 */
function show_users($id='',$rowstart=0,$rowamount=9999999)
{
 	global $db;
	$add = '';
 	if(is_numeric($id)) {
                 //When a user id is given, it is excluded from the userlist returned.
                 $add = " WHERE users.id!=".$db->quote($id, 'integer');
	}

	// Make a huge query.
	$query = "SELECT users.id AS id,
		users.username AS username,
		users.fullname AS fullname,
		users.email AS email,
		users.description AS description,
		users.active AS active,
		users.perm_templ AS perm_templ,
		count(zones.owner) AS aantal FROM users
		LEFT JOIN zones ON users.id=zones.owner$add
		GROUP BY
			users.id,
			users.username,
			users.fullname,
			users.email,
			users.description,
			users.perm_templ,
			users.active
		ORDER BY
			users.fullname";

	// Execute the huge query.
	$db->setLimit($rowamount, $rowstart);
	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
	$ret = array();
	$retcount = 0;
	while ($r = $response->fetchRow()) {
		$ret[] = array(
		 "id"                    =>              $r["id"],
		 "username"              =>              $r["username"],
		 "fullname"              =>              $r["fullname"],
		 "email"                 =>              $r["email"],
		 "description"           =>              $r["description"],
		 "active"                =>              $r["active"],
		 "numdomains"            =>              $r["aantal"]
		);
	}
	return $ret;
}


/*
 * Check if the given $userid is connected to a valid user.
 * return values: true if user exists, false if users doesnt exist.
 */
 function is_valid_user($id)
{
	global $db;
	if(is_numeric($id)) {
		$response = $db->query("SELECT id FROM users WHERE id=".$db->quote($id, 'integer'));
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
		if ($response->numRows() == 1) {
			return true;
		} else {
			return false;
		}
	}
}


/*
 * Checks if a given username exists in the database.
 * return values: true if exists, false if not.
 */
function user_exists($user)
{
	global $db;
	$response = $db->query("SELECT id FROM users WHERE username=".$db->quote($user, 'text'));
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
	if ($response->numRows() == 0) {
                 return false;
	} elseif ($response->numRows() == 1) {
        	return true;
	} else {
        	error(ERR_UNKNOWN);
	}
}



/*
 * Delete a user from the system
 * return values: true if user doesnt exist.
 */
function delete_user($uid,$zones)
{
	global $db;

	if (($uid != $_SESSION['userid'] && !verify_permission('user_edit_others')) || ($uid == $_SESSION['userid'] && !verify_permission('user_edit_own'))) {
		 error(ERR_PERM_DEL_USER);
		 return false;
	} else {

		if (is_array($zones)) {
			foreach ($zones as $zone) {
				if ($zone['target'] == "delete") {
					delete_domain($zone['zid']);
				} elseif ($zone['target'] == "new_owner") {
					add_owner_to_zone($zone['zid'], $zone['newowner']);
				}
			}
		}

		$query = "DELETE FROM zones WHERE owner = " . $db->quote($uid, 'integer') ;
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }

		$query = "DELETE FROM users WHERE id = " . $db->quote($uid, 'integer') ;
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
	}
	return true;
}

function delete_perm_templ($ptid) {

	global $db;
	if (!(verify_permission('user_edit_templ_perm'))) {
		error(ERR_PERM_DEL_PERM_TEMPL);
	} else {
		$query = "SELECT id FROM users WHERE perm_templ = " . $ptid;
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }

		if($response->numRows() > 0) {
			error(ERR_PERM_TEMPL_ASSIGNED);
			return false;
		} else {
			$query = "DELETE FROM perm_templ_items WHERE templ_id = " . $ptid;
			$response = $db->query($query);
			if (PEAR::isError($response)) { error($response->getMessage()); return false; }

			$query = "DELETE FROM perm_templ WHERE id = " . $ptid;
			$response = $db->query($query);
			if (PEAR::isError($response)) { error($response->getMessage()); return false; }

			return true;
		}
	}
}

/*
 * Edit the information of an user.. sloppy implementation with too many queries.. (2) :)
 * return values: true if succesful
 */
function edit_user($id, $user, $fullname, $email, $perm_templ, $description, $active, $password)
{
	global $db;

	verify_permission('user_edit_own') ? $perm_edit_own = "1" : $perm_edit_own = "0" ;
	verify_permission('user_edit_others') ? $perm_edit_others = "1" : $perm_edit_others = "0" ;

	if (($id == $_SESSION["userid"] && $perm_edit_own == "1") || ($id != $_SESSION["userid"] && $perm_edit_others == "1" )) {

		if (!is_valid_email($email)) {
			error(ERR_INV_EMAIL);
			return false;
		}

		if ($active != 1) {
			$active = 0;
		}
		
		// Before updating the database we need to check whether the user wants to 
		// change the username. If the user wants to change the username, we need 
		// to make sure it doesn't already exists. 
		//
		// First find the current username of the user ID we want to change. If the 
		// current username is not the same as the username that was given by the 
		// user, the username should apparantly changed. If so, check if the "new" 
		// username already exists.

		$query = "SELECT username FROM users WHERE id = " . $db->quote($id, 'integer');
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }

		$usercheck = array();
		$usercheck = $response->fetchRow();

		if ($usercheck['username'] != $user) {
			
			// Username of user ID in the database is different from the name
			// we have been given. User wants a change of username. Now, make
			// sure it doesn't already exist.
			
			$query = "SELECT id FROM users WHERE username = " . $db->quote($user, 'integer');
			$response = $db->query($query);
			if (PEAR::isError($response)) { error($response->getMessage()); return false; }

			if($response->numRows() > 0) {
				error(ERR_USER_EXIST);
				return false;
			}
		}

		// So, user doesn't want to change username or, if he wants, there is not
		// another user that goes by the wanted username. So, go ahead!

		$query = "UPDATE users SET
				username = " . $db->quote($user, 'text') . ",
				fullname = " . $db->quote($fullname, 'text') . ",
				email = " . $db->quote($email, 'text') . ",
				perm_templ = " . $db->quote($perm_templ, 'integer') . ",
				description = " . $db->quote($description, 'text') . ", 
				active = " . $db->quote($active, 'integer') ;

		if($password != "") {
			$query .= ", password = " . $db->quote(md5($password), 'text') ;
		}

		$query .= " WHERE id = " . $db->quote($id, 'integer') ;

		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
		
	} else {
		error(ERR_PERM_EDIT_USER);
		return false;
	}
	return true;
}

/*
 * Change the pass of the user.
 * The user is automatically logged out after the pass change.
 * return values: none.
 */
function change_user_pass($details) {
	global $db;
	
	if ($details['newpass'] != $details['newpass2']) {
		error(ERR_USER_MATCH_NEW_PASS);
		return false;
	}

	$query = "SELECT id, password FROM users WHERE username = " . $db->quote($_SESSION["userlogin"], 'text');
	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	$rinfo = $response->fetchRow();

	if(md5($details['currentpass']) == $rinfo['password']) {
		$query = "UPDATE users SET password = " . $db->quote(md5($details['newpass']), 'text') . " WHERE id = " . $db->quote($rinfo['id'], 'integer') ;
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }

		logout( _('Password has been changed, please login.')); 
	} else {
		error(ERR_USER_WRONG_CURRENT_PASS);
		return false;
	}
}


/*
 * Get a fullname when you have a userid.
 * return values: gives the fullname from a userid.
 */
function get_fullname_from_userid($id) {
	global $db;
	if (is_numeric($id)) {
		$response = $db->query("SELECT fullname FROM users WHERE id=".$db->quote($id, 'integer'));
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
		$r = $response->fetchRow();
		return $r["fullname"];
	} else {
		error(ERR_INV_ARG);
		return false;
	}
}


/*
 * Get a fullname when you have a userid.
 * return values: gives the fullname from a userid.
 */
function get_owner_from_id($id)
{
	global $db;
	if (is_numeric($id))
	{
		$response = $db->query("SELECT fullname FROM users WHERE id=".$db->quote($id, 'integer'));
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
		if ($response->numRows() == 1)
		{
			$r = $response->fetchRow();
			return $r["fullname"];
		}
		else
		{
			error(ERR_USER_NOT_EXIST);
		}
	}
	error(ERR_INV_ARG);
}

/**
 * get_owners_from_domainid
 *
 * @todo also fetch the subowners
 * @param $id integer the id of the domain
 * @return String the list of owners for this domain
 */
function get_fullnames_owners_from_domainid($id) {

	global $db;
	if (is_numeric($id)) {
		$response = $db->query("SELECT users.id, users.fullname FROM users, zones WHERE zones.domain_id=".$db->quote($id, 'integer')." AND zones.owner=users.id ORDER by fullname");
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
		if ($response->numRows() == 0) {
			return "";
		} else {
			$names = array();
			while ($r = $response->fetchRow()) {
				$names[] = $r['fullname'];
			}
			return implode(', ', $names);
		}
	}
	error(ERR_INV_ARG);
}



function verify_user_is_owner_zoneid($zoneid) {
	global $db;

	$userid=$_SESSION["userid"];

	if (is_numeric($zoneid)) {
		$response = $db->query("SELECT zones.id 
				FROM zones 
				WHERE zones.owner = " . $db->quote($userid, 'integer') . "
				AND zones.domain_id = ". $db->quote($zoneid, 'integer')) ;
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
		if ($response->numRows() == 0) {
			return "0";
		} else {
			return "1";
		}
	}
	error(ERR_INV_ARG);
}


function get_user_detail_list($specific) {

	global $db;
	$userid=$_SESSION['userid'];


	if (v_num($specific)) {
		$sql_add = "AND users.id = " . $db->quote($specific, 'integer') ;
	} else {
		if (verify_permission('user_view_others')) {
			$sql_add = "";
		} else {
			$sql_add = "AND users.id = " . $db->quote($userid, 'integer') ;
		}
	}

	$query = "SELECT users.id AS uid, 
			username, 
			fullname, 
			email, 
			description AS descr,
			active,
			perm_templ.id AS tpl_id,
			perm_templ.name AS tpl_name,
			perm_templ.descr AS tpl_descr
			FROM users, perm_templ 
			WHERE users.perm_templ = perm_templ.id " 
			. $sql_add . "
			ORDER BY username";

	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
	
	while ($user = $response->fetchRow()) {
		$userlist[] = array(
			"uid"		=>	$user['uid'],
			"username"	=>	$user['username'],
			"fullname"	=>	$user['fullname'],
			"email"		=>	$user['email'],
			"descr"		=>	$user['descr'],
			"active"	=>	$user['active'],
			"tpl_id"	=>	$user['tpl_id'],
			"tpl_name"	=>	$user['tpl_name'],
			"tpl_descr"	=>	$user['tpl_descr']
			);
	}
	return $userlist;
}


// Get a list of permissions that are available. If first argument is "0", it
// should return all available permissions. If the first argument is > "0", it
// should return the permissions assigned to that particular template only. If
// second argument is true, only the permission names are returned.

function get_permissions_by_template_id($templ_id=0,$return_name_only=false) {
	global $db;
	
	if ($templ_id > 0) {
		$limit = ", perm_templ_items 
			WHERE perm_templ_items.templ_id = " . $db->quote($templ_id, 'integer') . "
			AND perm_templ_items.perm_id = perm_items.id";
	}

	$query = "SELECT perm_items.id AS id, 
			perm_items.name AS name, 
			perm_items.descr AS descr
			FROM perm_items" 
			. $limit . "
			ORDER BY descr";
	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	$permission_list = array();
	while ($permission = $response->fetchRow()) {
		if ($return_name_only == false) {
			$permission_list[] = array(
				"id"	=>	$permission['id'],
				"name"	=>	$permission['name'],
				"descr"	=>	$permission['descr']
				);
		} else {
			$permission_list[] = $permission['name'];
		}
	}
	return $permission_list;
}


// Get name and description of template based on template ID.

function get_permission_template_details($templ_id) {
	global $db;

	$query = "SELECT *
			FROM perm_templ
			WHERE perm_templ.id = " . $db->quote($templ_id, 'integer');

	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	$details = $response->fetchRow(); 
	return $details;
}	


// Get a list of all available permission templates.

function get_list_permission_templates() {
	global $db;

	$query = "SELECT * FROM perm_templ";
	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	$perm_templ_list = array();
	while ($perm_templ = $response->fetchRow()) {
		$perm_templ_list[] = array(
			"id"	=>	$perm_templ['id'],
			"name"	=>	$perm_templ['name'],
			"descr"	=>	$perm_templ['descr']
			);
	}
	return $perm_templ_list;
}


// Add a permission template.

function add_perm_templ($details) {
	global $db;

	// Fix permission template name and description first. 

	$query = "INSERT INTO perm_templ (name, descr)
			VALUES (" 
				. $db->quote($details['templ_name'], 'text') . ", " 
				. $db->quote($details['templ_descr'], 'text') . ")";

	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	$perm_templ_id = $db->lastInsertId('perm_templ', 'id');

	foreach ($details['perm_id'] AS $perm_id) {
		$query = "INSERT INTO perm_templ_items (templ_id, perm_id) VALUES (" . $db->quote($perm_templ_id, 'integer') . "," . $db->quote($perm_id, 'integer') . ")";
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
	}

	return true;
}

// Update all details of a permission template.

function update_perm_templ_details($details) {
	global $db;

	// Fix permission template name and description first. 

	$query = "UPDATE perm_templ 
			SET name = " . $db->quote($details['templ_name'], 'text') . ",
			descr = " . $db->quote($details['templ_descr'], 'text') . "
			WHERE id = " . $db->quote($details['templ_id'], 'integer') ;
	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	// Now, update list of permissions assigned to this template. We could do 
	// this The Correct Way [tm] by comparing the list of permissions that are
	// currently assigned with a list of permissions that should be assigned and
	// apply the difference between these two lists to the database. That sounds 
	// like too much work. Just delete all the permissions currently assigned to 
	// the template, than assign all the permessions the template should have.

	$query = "DELETE FROM perm_templ_items WHERE templ_id = " . $details['templ_id'] ;
	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	foreach ($details['perm_id'] AS $perm_id) {
		$query = "INSERT INTO perm_templ_items (templ_id, perm_id) VALUES (" . $db->quote($details['templ_id'], 'integer') . "," . $db->quote($perm_id, 'integer') . ")";
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }
	}

	return true;
}

function update_user_details($details) {

	global $db;

	verify_permission('user_edit_own') ? $perm_edit_own = "1" : $perm_edit_own = "0" ;
	verify_permission('user_edit_others') ? $perm_edit_others = "1" : $perm_edit_others = "0" ;
	verify_permission('templ_perm_edit') ? $perm_templ_perm_edit = "1" : $perm_templ_perm_edit = "0" ;

	if (($details['uid'] == $_SESSION["userid"] && $perm_edit_own == "1") || 
			($details['uid'] != $_SESSION["userid"] && $perm_edit_others == "1" )) {

		if (!is_valid_email($details['email'])) {
			error(ERR_INV_EMAIL);
			return false;
		}

		if (!isset($details['active']) || $details['active'] != "on" ) {
			$active = 0;
		} else {
			$active = 1;
		}

		// Before updating the database we need to check whether the user wants to 
		// change the username. If the user wants to change the username, we need 
		// to make sure it doesn't already exists. 
		//
		// First find the current username of the user ID we want to change. If the 
		// current username is not the same as the username that was given by the 
		// user, the username should apparantly changed. If so, check if the "new" 
		// username already exists.
		$query = "SELECT username FROM users WHERE id = " . $db->quote($details['uid'], 'integer');
		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }

		$usercheck = array();
		$usercheck = $response->fetchRow();

		if ($usercheck['username'] != $details['username']) {
			// Username of user ID in the database is different from the name
			// we have been given. User wants a change of username. Now, make
			// sure it doesn't already exist.
			$query = "SELECT id FROM users WHERE username = " . $db->quote($details['username'], 'text');
			$response = $db->query($query);
			if (PEAR::isError($response)) { error($response->getMessage()); return false; }

			if($response->numRows() > 0) {
				error(ERR_USER_EXIST);
				return false;
			}
		}

		// So, user doesn't want to change username or, if he wants, there is not
		// another user that goes by the wanted username. So, go ahead!

		$query = "UPDATE users SET
				username = " . $db->quote($details['username'], 'text') . ",
				fullname = " . $db->quote($details['fullname'], 'text') . ",
				email = " . $db->quote($details['email'], 'text') . ",
				description = " . $db->quote($details['descr'], 'text') . ", 
				active = " . $db->quote($active, 'integer') ;

		// If the user is alllowed to change the permission template, set it.
		if ($perm_templ_perm_edit == "1") {
			$query .= ", perm_templ = " . $db->quote($details['templ_id'], 'integer') ;

		}

		if(isset($details['password']) && $details['password'] != "") {
			$query .= ", password = " . $db->quote(md5($details['password']), 'text');
		}

		$query .= " WHERE id = " . $db->quote($details['uid'], 'integer') ;

		$response = $db->query($query);
		if (PEAR::isError($response)) { error($response->getMessage()); return false; }

	} else {
		error(ERR_PERM_EDIT_USER);
		return false;
	}
	return true;		
}

// Add a new user

function add_new_user($details) {
	global $db;

	if (!verify_permission('user_add_new')) {
		error(ERR_PERM_ADD_USER);

	} elseif (user_exists($details['username'])) {
		error(ERR_USER_EXISTS);

	} elseif (!is_valid_email($details['email'])) {
		error(ERR_INV_EMAIL);
	
	} elseif ($details['active'] == 1) {
		$active = 1;
	} else {
		$active = 0;
	}

	$query = "INSERT INTO users (username, password, fullname, email, description, perm_templ, active) VALUES ("
			. $db->quote($details['username'], 'text') . ", "
			. $db->quote(md5($details['password']), 'text') . ", "
			. $db->quote($details['fullname'], 'text') . ", "
			. $db->quote($details['email'], 'text') . ", "
			. $db->quote($details['descr'], 'text') . ", "
			. $db->quote($details['perm_templ'], 'integer') . ", "
			. $db->quote($active, 'integer') 
			. ")";

	$response = $db->query($query);
	if (PEAR::isError($response)) { error($response->getMessage()); return false; }
	
	return true;
}

			

?>