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\';;'
Related
I(with root account) create some procedure myproc which has some part of code below:
declare cur_uname varchar(20);
select substring_index(current_user(),'#', 1) into cur_uname;
Then I create another account abc#localhost with GRANT EXECUTE ON PROCEDURE mydb.myproc TO 'abc'#'localhost';.
When I execute myproc under account abc#localhost,cur_uname is root but not abc. What should I address this problem?
CURRENT_USER():
Within a stored program or view, CURRENT_USER() returns the account for the user who defined the object (as given by its DEFINER value) unless defined with the SQL SECURITY INVOKER characteristic. In the latter case, CURRENT_USER() returns the object's invoker.
USER():
Returns the current MySQL user name and host name as a string in the utf8 character set. [...] The value indicates the user name you specified when connecting to the server, and the client host from which you connected. The value can be different from that of CURRENT_USER().
So I guess it all depends on the definition of "correct" that you need.
Sorry if I'm asking some banal question but I couldn't find out what the # symbol means in, for instance, this mysql statement: "CREATE USER 'username'#'somehost' IDENTIFIED BY 'somepassword'". Is it a delimiter in this case or something else?
I'm playing with mysql on my localhost.
Everytime I write some commands to console it starts to print "->" all the time and doesnt react to any commands except "\c" which goes back to mysql>
It looks like that:
mysql> show binary logs
->
->
->
and keeps printing "->" whenever i press Enter
Any ideas?
The semicolon is used to terminate statements in mysql.
SELECT id FROM users LIMIT 0,1; SELECT username FROM users LIMIT 0,2;
But there are some mysql command in which semicolon can be omitted.
Command provided by help like: clear, help, print, quit, use, etc
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;
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.