SELECT command denied to user - mysql

Im getting a funny MySQL error. Here's whats happening:
query:
SELECT COUNT(id) AS mycount FROM ip_protection.hits WHERE datetime_created>DATE_SUB(NOW(), INTERVAL 10 MINUTE) AND ip='166.248.6.19'
error:
SELECT command denied to user 'goatpric_db'#'166.248.6.19' for table 'hits'
privileges:
GRANT ALL PRIVILEGES ON `goatpric\_ip\_protection`.* TO 'goatpric_db'#'%'
'hits' is a table in ip_protection. Any thoughts?

You are using wrong database name everywhere. Use correct Database, which according to your question is ip_protection.

Add Use Procedure Bodies = false; to the connection string.
For example:
server=localhost; user id=dbuser; password=password; database=dbname; Use Procedure Bodies=false;

Related

how to drop user in mysql with incorrect host.?

I have user test with host 192.168.1.1';
I want to drop this user with an incorrect host.
I tried to type:
DROP USER 'test'#'192.168.1.1';;'
but this command is wrong.
How can I drop this user?
You should escape the apostrophe in host.
DROP USER 'test'#'192.168.1.1\';;';
Do first a
SELECT Host,User from mysql.user WHERE user = 'test';
And check the host(s) for this user
And then make
DROP USER 'test'#'192.168.1.1';
if the host is 192.168.1.1
If you have really a tick in your hist entry you must use an escape \ character before the inner apostrophe like 'test'#'192.168.1.1\';;'

What does `%`.* & 'db_user'#'% in the following sql statement means?

I can't find a good answer for the meaning of % used in the sql statement:
REVOKE SELECT ON `%`.* FROM 'db_user'#'%
Is it a wildcard value? So does % in %.* refer to all available schemaIDs and * means all tables available in each schemaID?
When I try:
GRANT INSERT, UPDATE ON `%`.tablename TO 'db_user'#'%';
I get the error:
Error Code: 1146. Table '%.tablename' doesn't exist
Shouldn't it go to the specific schemaID with the tablename and grant the rights and ignore the rest?
Then how about % in 'db_user'#%? Versus 'db_user#localhost'?
Any help is appreciated.

Issues deleting a row using OPENQUERY() with RPC enabled, obeying case sensitivity

I'm using T-SQL and I want to delete a row from a linked server using MYSQL.
For this I've tried:
delete from openquery(MYSQLServer,
'select * from dTable where date = cast(cast(date_add(now(),interval -6 day)as date) as int)
and ProductKey = 38410 and StoreKey = 3201')
But this gives the error
There was a recoverable, provider-specific error, such as an RPC failure.
I then Googled this issue and realized that I need to adjust the RPC settings in management studios by right clicking the linked server and set RPC = True and RPC Out = True. Refreshing the linked servers and executing the Query again yield the same error.
From searching the web I've also realized that delete is case sensitive.
However, using
exec sp_tables_ex MYSQLServer
showed me that I use the exact same case on the table. I've also controlled that each column has the same case. I've tried to rewrite the Query to have only upper case values just in case, but then I got the error that the table with uppercase does not exist.
I've also tried to use
SELECT * FROM MYSQLServer.Catalog.dbo.dTable
but that gave the error Invalid object name.
I've also tried:
select * from openquery(MYSQLServer,
'delete from dTable where date = cast(cast(date_add(now(),interval -6 day)as date) as int)
and ProductKey = 38410 and StoreKey = 3201')
but this gave the error that either object has no columns, or the current user does not have permissions on that object.
Does anyone have any clue?
EDIT
I've found that Another linked server, from which I have successfully deleted a row earlier, had a user name with a remote userID and password defined under Security settings at the specific Linked Server in management studios.
I tried to mimic this by using:
EXEC sp_addlinkedsrvlogin 'MYSQL_UNIC', 'false', 'uid', 'rmtid', 'rmtpw'
but this gives me the error
Access denied for user rmtid (using password: YES)
when I try to use the delete Query.
I'll try to find how to get permission to Query using a remote user.
Here’s the solution:
Make sure the RPC and RPC Out are set to TRUE on the LinkedServer’s properties.
Then use the following syntax (This is specifically for Teradata):
declare #SQL varchar(1000)
SET #SQL = ‘DELETE FROM DB.tableName ALL’
EXEC (#SQL) AT TERADATA_LINKEDSERVER

Grant select on views which use functions

I'm using postgresql 8.4 and am having a bit of a problem granting select privileges on a view from a database onwed by a different user when the view uses any of the databases functions.
As the new user, when I try to run, for example select * from users_pwd; where users_pwd is defined as:
create view users_pwd as
select *, get_pwd(id)
from users;
and get_pwd as:
CREATE OR REPLACE FUNCTION get_pwd(p_id integer)
RETURNS text AS
$BODY$
declare u record;
BEGIN
select into u * from users where id = p_id;
return u.password;
END;
$BODY$
LANGUAGE plpgsql;
I get the following error:
ERROR: permission denied for relation users
CONTEXT: SQL statement "select * from users where id = $1 "
PL/pgSQL function "get_pwd" line 3 at SQL statement
The only way to have the user query the view is to explicitly grant select on the table users which I don't want to do.
If a view doesn't use any function, but rather just other tables which the new user doesn't have explicit access to it works perfectly fine.
You could create the function with owner who can select from the table users. Such a function should be created with SECURITY DEFINER clause, so it will be executed with the owner rights.
More information you can find here: http://www.postgresql.org/docs/9.0/interactive/sql-createfunction.html
You can also GRANT EXECUTE privileges on functions. See GRANT in the docs.

Protect Stored Procedure

I would like to know if there's a way to conceal the text of a stored procedure from certain users.
I'm working with MySQL 5.1.48 and Net Connector 6.2.3 with Visual Studio 2008 SP1.
I have two users in MySQL, one is root (with all privileges for administration porpuses) and the other one is admin (with select, update, insert, delete, create_temp_table, lock_table and execute privileges in a specific schema).
All the stored procedures have been created by the root user, so the admin user can only execute them without knowing how they work or reading their content.
Everything was working fine until we started creating DataSets and using WebService, for this the admin user needed the select privilege in the column proc from the table mysql. The problem is that with this privilege, admin can see all the stored procedures including their content.
Please let me know if there's a way to protect the SP's, I don't know if this is fixed in the latest version of MySQL and it's .Net connector.
Normally when using MySQL .NET connector in conjunction with stored procedures you have to grant your "application user" select permissions on mysql.proc otherwise the connector can't see the sproc you're trying to call through it.
So usually you have the following two grants for your app user:
grant execute on foo_db.* to foo_dbo#localhost identified by 'pass';
grant select on mysql.proc to foo_dbo#localhost;
As you correctly pointed out this is a bit of a security issue but I do know one way around it which might freak you out but, it works abosultely fine and is actually as performant if not more performant than the standard approach (think - less overhead).
So after revoking grant select on mysql.proc and flushing privileges...
string sqlCmd = string.Format("call list_users({0})", userType);
MySqlConnection cn = new MySqlConnection();
cn.ConnectionString = "Server=....";
adr = new MySqlDataAdapter(sqlCmd, cn);
adr.SelectCommand.CommandType = CommandType.Text; // change from sproc to CommandType.Text
dt = new DataTable();
adr.Fill(dt); //opens and closes the DB connection automatically !!
Hope this helps :)
EDIT: as my answer was causing some confusion I thought I'd add a complete walk through of the problem as I see it...
Create demo database
Just a quick demo database (demo_db) with two users demo_dbo and demo_usr.
demo_dbo is granted full permissions on demo_db - they are the database owner (dbo) and can do as they wish inside this database e.g. create, drop, create procedure, truncate etc...
demo_usr is our application user - they have only been granted execute permimissions so all they can do is call stored procs;
call list_users();
So I login as root and run this script demo_db.sql
drop database if exists demo_db;
create database demo_db
character set latin1
default character set latin1
collate latin1_swedish_ci
default collate latin1_swedish_ci;
revoke select on mysql.* from demo_dbo#localhost;
revoke all privileges on demo_db.* from demo_dbo#localhost;
revoke grant option on *.* from demo_dbo#localhost;
drop user demo_dbo#localhost;
revoke select on mysql.* from demo_usr#localhost;
revoke all privileges on demo_db.* from demo_usr#localhost;
revoke grant option on *.* from demo_usr#localhost;
drop user demo_usr#localhost;
grant all on demo_db.* to demo_dbo#localhost identified by 'pass';
grant select on mysql.* to demo_dbo#localhost;
grant execute on demo_db.* to demo_usr#localhost identified by 'pass';
flush privileges;
select host, user from mysql.user;
Create the demo_db schema
OK now I have a database to play in so next I login as demo_dbo and start to create my schema objects: tables, triggers, sprocs, views etc... (don't forget demo_dbo is the owner and can do as they like inside demo_db)
So I login as demo_dbo and run this script demo_dbo.sql
use demo_db;
drop table if exists users;
create table users(
user_id int unsigned not null auto_increment primary key
)
engine=innodb;
insert into users values (null),(null),(null),(null),(null),(null);
drop procedure if exists list_users;
delimiter #
create procedure list_users()
begin
select * from users order by user_id;
end #
delimiter ;
Ok that's the demo_db schema created (1 table and 1 sproc) so I'd better do some testing while I'm still logged in as demo_dbo.
select from table - PASS
select * from users;
user_id
=======
1
2
3
4
5
6
Call stored procedure - PASS
call list_users();
user_id
=======
1
2
3
4
5
6
Show create procedure - PASS
show create procedure list_users;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
========= ======== ================ ==================== ==================== ==================
list_users CREATE DEFINER=`demo_dbo`#`localhost` PROCEDURE `list_users`()
begin
select * from users order by user_id;
end utf8 utf8_general_ci latin1_swedish_ci
Ok that all looks great demo_dbo (owner) can do all the things they should be able to do inside of demo_db so now we'd better test what our demo_usr can get up to.
I login as demo_usr and run the demo_usr.sql script:
show tables - FAIL
show tables;
Tables_in_demo_db
=================
NULL
Not much to see - how disappointing for demo_usr that they can't even see what tables are in the database.
select from user table - FAIL
select * from users;
SELECT command denied to user 'demo_usr'#'localhost' for table 'users'
Ok as expected - they can't access tables directly so I guess the only way they can get data is through my stored procdure API.
call stored procedure - PASS
call list_users();
user_id
=======
1
2
3
4
5
6
Finally a result but we'd better see what information about this sproc the demo_usr can see so...
show create procedure - FAIL
show create procedure list_users;
Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation
========= ======== ================ ==================== ==================== ==================
list_users utf8 utf8_general_ci latin1_swedish_ci
The demo_usr can see the stored procdure exists (well they can call it after all) but can't see the body.
Demo Application
So I knock up this quick and dirty C# app that uses MySQL .NET connector (which is great BTW) and attempt to call the list_users() stored procedure and populate a datatable as the application user demo_usr.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Data;
namespace demo_db
{
class Program
{
static void Main(string[] args)
{
MySqlConnection cn = new MySqlConnection("Server=127.0.0.1;Uid=demo_usr;Pwd=pass;Database=demo_db;");
MySqlDataAdapter adr = null;
try
{
DataTable dt = new DataTable();
adr = new MySqlDataAdapter("call list_users", cn);
adr.SelectCommand.CommandType = CommandType.StoredProcedure;
adr.Fill(dt); //opens and closes the DB connection automatically !!
foreach (DataRow dr in dt.Rows)
Console.WriteLine(string.Format("user_id = {0}", dr.Field<uint>("user_id").ToString()));
}
catch(Exception ex)
{
Console.WriteLine(string.Format("oops - {0}", ex.Message));
}
finally
{
adr.Dispose();
cn.Dispose();
}
Console.WriteLine("\nPress any key to quit.");
Console.ReadKey();
}
}
}
Ok this fails - why ?? Here's the exception message:
oops - SELECT command denied to user 'demo_usr'#'localhost' for table 'proc'
Remember we only granted execute permissions to demo_usr for demo_db - nothing else !!
Now we can fix this by granting them select perms on mysql.proc but if we do that they will be able to see the stored procedure body - which we want to avoid.
So how do we get around this ? Well we can login into mysql console as demo_usr and call a stored procedure from the command line so could perhaps do the same in the app code ?
mysql> use demo_db;
Database changed
mysql> call list_users();
+---------+
| user_id |
+---------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+---------+
So changing the line:
adr.SelectCommand.CommandType = CommandType.StoredProcedure;
to
adr.SelectCommand.CommandType = CommandType.Text;
we now get...
user_id = 1
user_id = 2
user_id = 3
user_id = 4
user_id = 5
user_id = 6
Press any key to quit.
Great - it works.
Hope this helps
Rgds f00
You can restrict premissions to your stored procedures using GRANT.
Perhaps you can use somethng like -
GRANT EXECUTE ON PROCEDURE db.storedproc TO 'username'#'somehost';
You can find the complete syntax for GRANT here
Edit -
GRANT is to provide permissions and REVOKE is to do the opposite of it. You can find more information about REVOKE here.
You can try using -
FLUSH PRIVILEGES;
This reloads the privileges from the grant tables in the mysql database.
If the user already has execute permissions and you want to revoke all the permissions for the user then you can use -
REVOKE ALL PRIVILEGES ON db.* FROM username#somehost
To revoke a user's execute grant on a specific stored procedure, you can use
REVOKE EXECUTE ON PROCEDURE db.storedproc FROM username;
Always make sure that you don't grant global privileges unnecessarily.