How to grant execute on specific stored procedure to user - mysql

I have created some stored procedure on a specific schema.
In this stored procedure, I want to grant execute privilege.
So I wrote that :
GRANT EXECUTE ON PROCEDURE schema_name.proc_name TO 'user_name';
GRANT SELECT ON mysql.proc to 'user_name';
The problem is : My user can see every stored procedure.
I wish he could only see the procedure where he has the EXECUTE privilege.
Is there a way to achieve that ?
Thanks in advance.

Yes... this works as expected if you don't grant the user the SELECT privilege on the mysql.proc table, either directly or indirectly, such as with GRANT SELECT ON *.* TO ...
Without SELECT permission on this table, a user can only see the existence of stored procedures and stored functions where they have other permissions, like EXECUTE.
Under the hood, the lack of SELECT on mysql.proc also prevents the user from seeing the procedures they don't have access to via the information_schema.routines pseudo-table.
You shouldn't need to GRANT SELECT ON mysql.proc to enable the user to execute procedures or functions... and if you do, then that seems like the question.

Problem solved.
In fact, To be able to execute stored procedure within MySQLForExcel, we need to SET the DEFINER of each stored procedure that we want to be called by a MySQLForExcel user.
DELIMITER $$
DROP PROCEDURE IF EXISTS `procedure_name` $$
CREATE DEFINER=`user_mysqlforexcel` PROCEDURE `procedure_name`(param)
BEGIN
Do smth as usual
END $$
I found that here
Thank for the help.

Related

MySQL grants to create a stored procedure on performance_schema.*?

I understand why this is so locked down. If I were MySQL, I wouldn't want folks to (easily) shoot themselves in the foot on business critical/internal-use databases either. Nevertheless, it should support legitimate use cases.
Suppose I had a stored procedure:
delimiter //
CREATE DEFINER=CURRENT_USER() PROCEDURE performance_schema.sp_flush_hosts()
BEGIN
-- requires DROP privileges
TRUNCATE TABLE performance_schema.host_cache;
END
//
delimiter ;
for a user called root with ALL permissions on most databases.
In practice, MySQL seems to explicitly forbid this for performance_schema:
Because only a limited set of privileges apply to Performance Schema tables, attempts to use GRANT ALL as shorthand for granting privileges at the database or table leval fail with an error:
Fine. So let's grant some specific permissions:
mysql> GRANT CREATE ROUTINE on perforamnce_schema.host_cache to 'root'#'%';
ERROR 1144 (42000): Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used
In the same document (above), only: SELECT, UPDATE, DROP are singled out, but it does not say if those are the only available permissions. How would I grant permissions to create this routine? Is that even possible? Thanks.
Inspiration taken from this SO answer: Is there a way to effectively GRANT on either TRUNCATE or DROP TABLE in MySQL?
Perhaps:
Put your SP in your database. Or perhaps a generic database of "utilities".
Be "root" when you CREATE the SP, and declare it with SQL SECURITY DEFINER See https://dev.mysql.com/doc/refman/5.6/en/stored-objects-security.html#stored-objects-security-sql-security This provides a way to elevate the permissions just for the running of the SP. Normally, one would use SQL SECURITY INVOKER -- to use the permissions of the person CALLing the SP.

Mysql: How to set up properly a procedure call inside init_connect variable

I want to store the activity of each session user at very high level into a table.
I wrote a procedure "audit.login_trigger". I have created the schema needed(audit DB and Table). It is some thing like this.
CREATE PROCEDURE audit.login_trigger()
SQL SECURITY DEFINER
BEGIN
INSERT INTO audit.audit_connect (thread_id, user, login_ts)
VALUES (CONNECTION_ID(), USER(), NOW());
END;
I have place this inside "init_connect".
SET GLOBAL init_connect="CALL audit.login_trigger()";
I want this to be executed for every user connection. I gave EXECUTE privileges on this PROCEDURE to root user but when the root user logged in, it is not populating the audit schema as expected. What might went wrong here ?
Thanks in advance.
Since this user is named "root" I wonder if it has super privileges. If it does, then note that init_connect doesn't fire for super users.

mysql users can see stored procedures?

example:
A non-super user has been granted execute on a procedure that inserts into table "a". That user will see the database that table "a" is in with a "show databases", but will not be able see table "a" with a "show tables". But that same user can see basic procedure info with a "show procedure status".
This is for auditing and I would like to have the audit process as obscured as possible. If a user is granted execute on a procedure must that user have the ability to see the procedure? And must they be able to see the database that the procedure touches?
If you are the owner of the procedure or if you have access to mysql.proc table you can see the definition of the procedure as stated here.
So you would create the procedure as super and set DEFINER CURRENT_USER (so the procedure executes as super). Then make sure super has access to the table but that no one else does. That should protect both the table and the source but leave it possible to call on the procedure.
And it don't have to be super, can be any user that has access to the table.

What exaclty does the Security_Type column do?

I have a stored procedure in MySQL. When I run SHOW PROCEDURE STATUS LIKE 'sp_name' I get some columns that explains the stored procedure.
The definer is set to Definer root#% and Security_type is set to DEFINER. Does this mean that only the root-user can call the stored procedure?
Does this mean that only the root-user can call the stored procedure?
No, it doesn't. Any user with EXECUTE privilege can call this procedure.
From the reference - The SQL SECURITY characteristic can be used to specify whether the routine should be executed using the permissions of the user who creates the routine or the user who invokes it.
CREATE PROCEDURE Syntax.

Is `definer` required when creating a stored procedure?

I've written all of MySQL procedures as root#localhost:
CREATE DEFINER=`root`#`localhost` PROCEDURE `p_add_user`(...)
Trouble is, when deploying to another server, I have to replace root with current user and replace localhost with current IP, which is annoying.
Is there any way to write procedures so that someone who wants to use my database and procedures would not have to modify the definer of each procedure?
As stated in MySQL documentation here
CREATE
[DEFINER = { user | CURRENT_USER }]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
So, the DEFINER part is not mandatory, just CREATE PROCEDURE should work.
[EDIT: updated ref page]
You can specify execution privileges by adding the following statement in the procedure body (after declaration):
SQL SECURITY INVOKER
Example:
CREATE DEFINER=`root`#`localhost` PROCEDURE `p_add_user`()
SQL SECURITY INVOKER
(...)
Doing so, the actual invoker privileges are applied and the DEFINER part is omitted (even when it is auto-added during schema import).
Full reference here:
https://dev.mysql.com/doc/refman/5.7/en/stored-objects-security.html
CREATE DEFINER=[your_web_user]#% PROCEDURE p_add_user(...)
Check it.. probably this will help you, if you want to define the user in your procedure...