mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
fix: Remove faulty memcached code (not related to distributed polling) (#7881)
This commit is contained in:
committed by
Neil Lathwood
parent
5ff03d5942
commit
c22c879983
@@ -86,7 +86,7 @@ class ADAuthorizationAuthorizer extends AuthorizerBase
|
||||
|
||||
protected function userExistsInDb($username)
|
||||
{
|
||||
$return = dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username), true);
|
||||
$return = dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username));
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ class ADAuthorizationAuthorizer extends AuthorizerBase
|
||||
public function getUser($user_id)
|
||||
{
|
||||
// not supported so return 0
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id), true);
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -122,7 +122,7 @@ class ActiveDirectoryAuthorizer extends AuthorizerBase
|
||||
|
||||
protected function userExistsInDb($username)
|
||||
{
|
||||
$return = dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username), true);
|
||||
$return = dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username));
|
||||
return $return;
|
||||
}
|
||||
|
||||
|
@@ -165,8 +165,7 @@ abstract class AuthorizerBase implements Authorizer
|
||||
list($uname, $hash) = explode('|', $token);
|
||||
$session = dbFetchRow(
|
||||
"SELECT * FROM `session` WHERE `session_username`=? AND `session_value`=?",
|
||||
array($uname, $sess_id),
|
||||
true
|
||||
array($uname, $sess_id)
|
||||
);
|
||||
|
||||
$hasher = new PasswordHash(8, false);
|
||||
|
@@ -13,7 +13,7 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
public function authenticate($username, $password)
|
||||
{
|
||||
$encrypted_old = md5($password);
|
||||
$row = dbFetchRow('SELECT username,password FROM `users` WHERE `username`= ?', array($username), true);
|
||||
$row = dbFetchRow('SELECT username,password FROM `users` WHERE `username`= ?', array($username));
|
||||
if ($row['username'] && $row['username'] == $username) {
|
||||
// Migrate from old, unhashed password
|
||||
if ($row['password'] == $encrypted_old) {
|
||||
@@ -58,7 +58,7 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
if (empty($username) || !$this->userExists($username)) {
|
||||
return 1;
|
||||
} else {
|
||||
return dbFetchCell('SELECT can_modify_passwd FROM users WHERE username = ?', array($username), true);
|
||||
return dbFetchCell('SELECT can_modify_passwd FROM users WHERE username = ?', array($username));
|
||||
}
|
||||
}//end passwordscanchange()
|
||||
|
||||
@@ -113,20 +113,20 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
|
||||
public function userExists($username, $throw_exception = false)
|
||||
{
|
||||
$return = @dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username), true);
|
||||
$return = @dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username));
|
||||
return $return;
|
||||
}//end userExists()
|
||||
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($username), true);
|
||||
return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($username));
|
||||
}//end getUserlevel()
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($username), true);
|
||||
return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($username));
|
||||
}//end getUserid()
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ class MysqlAuthorizer extends AuthorizerBase
|
||||
|
||||
public function getUser($user_id)
|
||||
{
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id), true);
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id));
|
||||
}//end getUser()
|
||||
|
||||
|
||||
|
@@ -65,19 +65,19 @@ class RadiusAuthorizer extends AuthorizerBase
|
||||
|
||||
public function userExists($username, $throw_exception = false)
|
||||
{
|
||||
return dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username), true);
|
||||
return dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($username));
|
||||
}
|
||||
|
||||
|
||||
public function getUserlevel($username)
|
||||
{
|
||||
return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($username), true);
|
||||
return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($username));
|
||||
}
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($username), true);
|
||||
return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($username));
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ class RadiusAuthorizer extends AuthorizerBase
|
||||
|
||||
public function getUser($user_id)
|
||||
{
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id), true);
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -87,7 +87,7 @@ class SSOAuthorizer extends AuthorizerBase
|
||||
public function userExists($username, $throw_exception = false)
|
||||
{
|
||||
// A local user is always created, so we query this, as in the event of an admin choosing to manually administer user creation we should return false.
|
||||
$user = dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($this->getExternalUsername()), true);
|
||||
$user = dbFetchCell('SELECT COUNT(*) FROM users WHERE username = ?', array($this->getExternalUsername()));
|
||||
|
||||
if ($throw_exception) {
|
||||
// Hopefully the caller knows what they're doing
|
||||
@@ -101,14 +101,14 @@ class SSOAuthorizer extends AuthorizerBase
|
||||
public function getUserLevel($username)
|
||||
{
|
||||
// The user level should always be persisted to the database (and may be managed there) so we again query the database.
|
||||
return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($this->getExternalUsername()), true);
|
||||
return dbFetchCell('SELECT `level` FROM `users` WHERE `username` = ?', array($this->getExternalUsername()));
|
||||
}
|
||||
|
||||
|
||||
public function getUserid($username)
|
||||
{
|
||||
// User ID is obviously unique to LibreNMS, this must be resolved via the database
|
||||
return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($this->getExternalUsername()), true);
|
||||
return dbFetchCell('SELECT `user_id` FROM `users` WHERE `username` = ?', array($this->getExternalUsername()));
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ class SSOAuthorizer extends AuthorizerBase
|
||||
|
||||
public function getUser($user_id)
|
||||
{
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id), true);
|
||||
return dbFetchRow('SELECT * FROM `users` WHERE `user_id` = ?', array($user_id));
|
||||
}
|
||||
|
||||
public function updateUser($user_id, $realname, $level, $can_modify_passwd, $email)
|
||||
|
@@ -1,24 +0,0 @@
|
||||
source: Extensions/Memcached.md
|
||||
# Memcached
|
||||
|
||||
> At this present moment, it is not advisable to run memcached other than for Distributed Polling.
|
||||
|
||||
LibreNMS can store SQL results in memcached to achieve performance advantages of in-memory value storage and removing work load for frequent queries off the MySQL backend.
|
||||
|
||||
To enable memcached in your install you need to have `memcached` installed and the PHP extension `php5-memcached` or `php-memcached` and add the following lines to your `config.php`:
|
||||
|
||||
```php
|
||||
$config['memcached']['enable'] = true;
|
||||
$config['memcached']['host'] = "localhost";
|
||||
$config['memcached']['port'] = 11211;
|
||||
```
|
||||
|
||||
By default values are kept for 4 Minutes inside the memcached, you can adjust this retention time by modifying the `$config['memcached']['ttl']` value to any desired amount of seconds.
|
||||
|
||||
> This means that you can see what appears to be stale data for up to 4 minutes. If you edit an alert rule for example then those changes may not show immediately.
|
||||
|
||||
It's strongly discouraged to set this above `300` (5 Minutes) to avoid interference with the polling, discovery and alerting processes.
|
||||
|
||||
If you use the Distributed Poller, you can point this to the same memcached instance. However a local memcached will perform better in any case.
|
||||
|
||||
By default `memcached` on many distributions starts itself with 64 MB of memory for it to store data in. If you have lots of devices or look at graphs frequently, it might be worth it to expand `memcached`'s footprint a bit. Generally this can be done in `/etc/memcached.conf`, replacing `-m 64` with `-m 512`, or however many megs of memory you want to allocate for `memcached`. Then restart the `memcached` service.
|
@@ -48,7 +48,7 @@ if ($rowCount != -1) {
|
||||
|
||||
$sql = "SELECT D.device_id, D.hostname AS `hostname`, D.sysName, D.last_polled AS `last_polled`, `group_name`, D.last_polled_timetaken AS `last_polled_timetaken` $sql";
|
||||
|
||||
foreach (dbFetchRows($sql, array(), true) as $device) {
|
||||
foreach (dbFetchRows($sql, array()) as $device) {
|
||||
if (empty($device['group_name'])) {
|
||||
$device['group_name'] = 'General';
|
||||
}
|
||||
|
@@ -58,8 +58,6 @@ if (!file_exists('../config.php') && $_SERVER['PATH_INFO'] != '/install.php') {
|
||||
$init_modules = array('web', 'auth');
|
||||
require realpath(__DIR__ . '/..') . '/includes/init.php';
|
||||
|
||||
$config['memcached']['ttl'] = $config['time']['now']+300;
|
||||
|
||||
LibreNMS\Plugins::start();
|
||||
|
||||
$runtime_start = microtime(true);
|
||||
|
@@ -23,7 +23,7 @@ if ($vars['purge'] == 'all') {
|
||||
echo '<table class="table table-hover table-condensed">';
|
||||
echo "<tr><td>Device</td><td>Port</td><td></td><td><a href='deleted-ports/purge=all/'><i class='fa fa-times'></i> Purge All</a></td></tr>";
|
||||
|
||||
foreach (dbFetchRows("SELECT * FROM `ports` AS P, `devices` as D WHERE P.`deleted` = '1' AND D.device_id = P.device_id", array(), true) as $interface) {
|
||||
foreach (dbFetchRows("SELECT * FROM `ports` AS P, `devices` as D WHERE P.`deleted` = '1' AND D.device_id = P.device_id", array()) as $interface) {
|
||||
$interface = cleanPort($interface, $interface);
|
||||
if (port_permitted($interface['port_id'], $interface['device_id'])) {
|
||||
echo '<tr class=list>';
|
||||
|
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
$no_refresh = true;
|
||||
$config['memcached']['enable'] = false;
|
||||
|
||||
$link_array = array('page' => 'device',
|
||||
'device' => $device['device_id'],
|
||||
|
@@ -24,7 +24,6 @@
|
||||
* @author f0o <f0o@devilcode.org>
|
||||
*/
|
||||
|
||||
$config['memcached']['enable'] = false;
|
||||
?>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
@@ -1182,30 +1182,11 @@ function format_hostname($device, $hostname = '')
|
||||
|
||||
/**
|
||||
* Return valid port association modes
|
||||
* @param bool $no_cache No-Cache flag (optional, default false)
|
||||
* @return array
|
||||
*/
|
||||
function get_port_assoc_modes($no_cache = false)
|
||||
function get_port_assoc_modes()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if ($config['memcached']['enable'] && $no_cache === false) {
|
||||
$assoc_modes = $config['memcached']['resource']->get(hash('sha512', "port_assoc_modes"));
|
||||
if (! empty($assoc_modes)) {
|
||||
return $assoc_modes;
|
||||
}
|
||||
}
|
||||
|
||||
$assoc_modes = null;
|
||||
foreach (dbFetchRows("SELECT `name` FROM `port_association_mode` ORDER BY pom_id") as $row) {
|
||||
$assoc_modes[] = $row['name'];
|
||||
}
|
||||
|
||||
if ($config['memcached']['enable'] && $no_cache === false) {
|
||||
$config['memcached']['resource']->set(hash('sha512', "port_assoc_modes"), $assoc_modes, $config['memcached']['ttl']);
|
||||
}
|
||||
|
||||
return $assoc_modes;
|
||||
return dbFetchColumn("SELECT `name` FROM `port_association_mode` ORDER BY pom_id");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1221,58 +1202,21 @@ function is_valid_port_assoc_mode($port_assoc_mode)
|
||||
/**
|
||||
* Get DB id of given port association mode name
|
||||
* @param string $port_assoc_mode
|
||||
* @param bool $no_cache No-Cache flag (optional, default false)
|
||||
* @return int
|
||||
*/
|
||||
function get_port_assoc_mode_id($port_assoc_mode, $no_cache = false)
|
||||
function get_port_assoc_mode_id($port_assoc_mode)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if ($config['memcached']['enable'] && $no_cache === false) {
|
||||
$id = $config['memcached']['resource']->get(hash('sha512', "port_assoc_mode_id|$port_assoc_mode"));
|
||||
if (! empty($id)) {
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
$id = null;
|
||||
$row = dbFetchRow("SELECT `pom_id` FROM `port_association_mode` WHERE name = ?", array ($port_assoc_mode));
|
||||
if ($row) {
|
||||
$id = $row['pom_id'];
|
||||
if ($config['memcached']['enable'] && $no_cache === false) {
|
||||
$config['memcached']['resource']->set(hash('sha512', "port_assoc_mode_id|$port_assoc_mode"), $id, $config['memcached']['ttl']);
|
||||
}
|
||||
}
|
||||
|
||||
return $id;
|
||||
return (int)dbFetchCell("SELECT `pom_id` FROM `port_association_mode` WHERE name = ?", array ($port_assoc_mode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of given port association_mode ID
|
||||
* @param int $port_assoc_mode_id Port association mode ID
|
||||
* @param bool $no_cache No-Cache flag (optional, default false)
|
||||
* @return bool
|
||||
*/
|
||||
function get_port_assoc_mode_name($port_assoc_mode_id, $no_cache = false)
|
||||
function get_port_assoc_mode_name($port_assoc_mode_id)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if ($config['memcached']['enable'] && $no_cache === false) {
|
||||
$name = $config['memcached']['resource']->get(hash('sha512', "port_assoc_mode_name|$port_assoc_mode_id"));
|
||||
if (! empty($name)) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
$name = null;
|
||||
$row = dbFetchRow("SELECT `name` FROM `port_association_mode` WHERE pom_id = ?", array ($port_assoc_mode_id));
|
||||
if ($row) {
|
||||
$name = $row['name'];
|
||||
if ($config['memcached']['enable'] && $no_cache === false) {
|
||||
$config['memcached']['resource']->set(hash('sha512', "port_assoc_mode_name|$port_assoc_mode_id"), $name, $config['memcached']['ttl']);
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
return dbFetchCell("SELECT `name` FROM `port_association_mode` WHERE pom_id = ?", array ($port_assoc_mode_id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -351,17 +351,8 @@ function dbDeleteOrphans($target_table, $parents)
|
||||
* */
|
||||
|
||||
|
||||
function dbFetchRows($sql, $parameters = array(), $nocache = false)
|
||||
function dbFetchRows($sql, $parameters = array())
|
||||
{
|
||||
global $config;
|
||||
|
||||
if ($config['memcached']['enable'] && $nocache === false) {
|
||||
$result = $config['memcached']['resource']->get(hash('sha512', $sql.'|'.serialize($parameters)));
|
||||
if (!empty($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
$time_start = microtime(true);
|
||||
$result = dbQuery($sql, $parameters);
|
||||
|
||||
@@ -372,9 +363,7 @@ function dbFetchRows($sql, $parameters = array(), $nocache = false)
|
||||
}
|
||||
|
||||
mysqli_free_result($result);
|
||||
if ($config['memcached']['enable'] && $nocache === false) {
|
||||
$config['memcached']['resource']->set(hash('sha512', $sql.'|'.serialize($parameters)), $rows, $config['memcached']['ttl']);
|
||||
}
|
||||
|
||||
recordDbStatistic('fetchrows', $time_start);
|
||||
return $rows;
|
||||
}
|
||||
@@ -394,9 +383,9 @@ function dbFetchRows($sql, $parameters = array(), $nocache = false)
|
||||
* */
|
||||
|
||||
|
||||
function dbFetch($sql, $parameters = array(), $nocache = false)
|
||||
function dbFetch($sql, $parameters = array())
|
||||
{
|
||||
return dbFetchRows($sql, $parameters, $nocache);
|
||||
return dbFetchRows($sql, $parameters);
|
||||
/*
|
||||
// for now, don't do the iterator thing
|
||||
$result = dbQuery($sql, $parameters);
|
||||
@@ -416,17 +405,8 @@ function dbFetch($sql, $parameters = array(), $nocache = false)
|
||||
* */
|
||||
|
||||
|
||||
function dbFetchRow($sql = null, $parameters = array(), $nocache = false)
|
||||
function dbFetchRow($sql = null, $parameters = array())
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (isset($config['memcached']['enable']) && $config['memcached']['enable'] && $nocache === false) {
|
||||
$result = $config['memcached']['resource']->get(hash('sha512', $sql.'|'.serialize($parameters)));
|
||||
if (!empty($result)) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
$time_start = microtime(true);
|
||||
$result = dbQuery($sql, $parameters);
|
||||
if ($result) {
|
||||
@@ -434,10 +414,6 @@ function dbFetchRow($sql = null, $parameters = array(), $nocache = false)
|
||||
mysqli_free_result($result);
|
||||
|
||||
recordDbStatistic('fetchrow', $time_start);
|
||||
|
||||
if (isset($config['memcached']['enable']) && $config['memcached']['enable'] && $nocache === false) {
|
||||
$config['memcached']['resource']->set(hash('sha512', $sql.'|'.serialize($parameters)), $row, $config['memcached']['ttl']);
|
||||
}
|
||||
return $row;
|
||||
} else {
|
||||
return null;
|
||||
@@ -450,10 +426,10 @@ function dbFetchRow($sql = null, $parameters = array(), $nocache = false)
|
||||
* */
|
||||
|
||||
|
||||
function dbFetchCell($sql, $parameters = array(), $nocache = false)
|
||||
function dbFetchCell($sql, $parameters = array())
|
||||
{
|
||||
$time_start = microtime(true);
|
||||
$row = dbFetchRow($sql, $parameters, $nocache);
|
||||
$row = dbFetchRow($sql, $parameters);
|
||||
|
||||
recordDbStatistic('fetchcell', $time_start);
|
||||
if ($row) {
|
||||
@@ -470,11 +446,11 @@ function dbFetchCell($sql, $parameters = array(), $nocache = false)
|
||||
* */
|
||||
|
||||
|
||||
function dbFetchColumn($sql, $parameters = array(), $nocache = false)
|
||||
function dbFetchColumn($sql, $parameters = array())
|
||||
{
|
||||
$time_start = microtime(true);
|
||||
$cells = array();
|
||||
foreach (dbFetch($sql, $parameters, $nocache) as $row) {
|
||||
foreach (dbFetch($sql, $parameters) as $row) {
|
||||
$cells[] = array_shift($row);
|
||||
}
|
||||
|
||||
@@ -490,10 +466,10 @@ function dbFetchColumn($sql, $parameters = array(), $nocache = false)
|
||||
*/
|
||||
|
||||
|
||||
function dbFetchKeyValue($sql, $parameters = array(), $nocache = false)
|
||||
function dbFetchKeyValue($sql, $parameters = array())
|
||||
{
|
||||
$data = array();
|
||||
foreach (dbFetch($sql, $parameters, $nocache) as $row) {
|
||||
foreach (dbFetch($sql, $parameters) as $row) {
|
||||
$key = array_shift($row);
|
||||
if (sizeof($row) == 1) {
|
||||
// if there were only 2 fields in the result
|
||||
|
@@ -62,12 +62,6 @@ $config['virsh'] = '/usr/bin/virsh';
|
||||
$config['dot'] = '/usr/bin/dot';
|
||||
$config['sfdp'] = '/usr/bin/sfdp';
|
||||
|
||||
// Memcached - Keep immediate statistics
|
||||
$config['memcached']['enable'] = false;
|
||||
$config['memcached']['host'] = 'localhost';
|
||||
$config['memcached']['port'] = 11211;
|
||||
$config['memcached']['ttl'] = 240;
|
||||
|
||||
$config['slow_statistics'] = true;
|
||||
// THIS WILL CHANGE TO FALSE IN FUTURE
|
||||
// RRD Format Settings
|
||||
|
@@ -102,19 +102,6 @@ if (isset($config['php_memory_limit']) && is_numeric($config['php_memory_limit']
|
||||
}
|
||||
ini_set('display_errors', $display_bak);
|
||||
|
||||
// init memcached
|
||||
if ($config['memcached']['enable'] === true) {
|
||||
if (class_exists('Memcached')) {
|
||||
$config['memcached']['ttl'] = 60;
|
||||
$config['memcached']['resource'] = new Memcached();
|
||||
$config['memcached']['resource']->addServer($config['memcached']['host'], $config['memcached']['port']);
|
||||
} else {
|
||||
echo "WARNING: You have enabled memcached but have not installed the PHP bindings. Disabling memcached support.\n";
|
||||
echo "Try 'apt-get install php5-memcached' or 'pecl install memcached'. You will need the php5-dev and libmemcached-dev packages to use pecl.\n\n";
|
||||
$config['memcached']['enable'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!module_selected('nodb', $init_modules)) {
|
||||
// Check for testing database
|
||||
if (getenv('DBTEST')) {
|
||||
|
@@ -59,7 +59,6 @@ pages:
|
||||
- Auto-discovery Setup: Extensions/Auto-Discovery.md
|
||||
- Scaling LibreNMS: Extensions/Distributed-Poller.md
|
||||
- Extensions/RRDCached.md
|
||||
- Memcached Config: Extensions/Memcached.md
|
||||
- Sub-directory Support: Extensions/Sub-Directory.md
|
||||
- Extensions/Varnish.md
|
||||
- Poller Service (BETA): Extensions/Poller-Service.md
|
||||
|
Reference in New Issue
Block a user