MariaDB procedure and functions privileges - mysql

Good day everyone, i cant figure out what to do anymore. I've imported my database to the server remotely.
So here is my procedure, i have a definer db_hrmis#127.0.0.1:
DELIMITER //
CREATE DEFINER=`db_hrmis`#`127.0.0.1` PROCEDURE `proce_give_employee_leave_credits`()
BEGIN
UPDATE inf_employee_leaves lv SET lv.earnings = (lv.leaveMinutesPerMonth + lv.earnings), lv.allowedLeaveInMinutes = ((lv.noOfDays - (CONVERT((lv.earnings/480), DECIMAL(10,2)))) * 480), lv.noOfDays = CONVERT((lv.allowedLeaveInMinutes / 480), DECIMAL(10,2)) WHERE MONTH(lv.lastUpdated) <> MONTH(CURDATE());
END//
DELIMITER ;
since im accessing it remotely i've also created a database user from my server(e.g. db_hrmis#myipaddress).
The problem is after importing the procedures the definers changed and i cant alter my procedure, and when i try to export it mysql dump shows only like this
DELIMITER //
END//
DELIMITER ;
empty structure, i tried granting permissions(execute, create routine, alter routine) but nothing seems to work.
here is a screenshot of its current state.
as you can see, the definers does not state 127.0.0.1 and i have "You have no privilege to this routine" problem, if its a privilege problem, what privilege should i grant to the user?
Thank you so much for the help.

It might be because mysql user has no execute privilege on that particular sp on your_db.table.
Can you please Post the output of # mysql> show grants for <your user>;
Or else you may confirm this by running procedure after granting full privilege for that particular user on all databases.
# mysql> grant all privileges on *.* to 'user'#'host';
# mysql> flush privileges;

Related

MySQL 5.6 - User cannot view stored procedure code

We created a user/login for some devs, and we have an issue where this user/login cannot view stored procedure code.
This is for MySQL 5.6.
I checked the GRANTS and also the information_schema (schema_privileges) and things look "good" to me.
Here are the commands I used to GRANT the database access and privileges:
GRANT SELECT, INSERT, UPDATE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON `mydatabase`.* TO 'dev-user'#'%' ;
After that, I run the FLUSH PRIVILEGES command.
And, when I run SHOW GRANTS for `dev-user` , I get the following response:
GRANT SELECT, INSERT, UPDATE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE ON mydatabase.* TO 'dev-user'#'%'
After that the user runs the command SHOW CREATE procedure mydatabase.sp_test and the output has NULL in the CREATE PROCEDURE Column.
This same user/login can create a new procedure and running SHOW CREATE procedure has the procedure code visible in that CREATE PROCEDURE column.
And, as a quick test, i created another user with GRANT ALL PRIVILEGES on the database and i get the same results. That user also not see the stored procedure code.
When I run a query on the information_schema.SCHEMA_PRIVILEGES system table, i can see that the user has included:
ALTER
ALTER ROUTINE
CREATE
CREATE ROUTINE
Does anyone have any suggestions or can see something i am missing, or forgot?
Thanks for any help
As stated in the documentation:
To use either statement, you must be the user named in the routine DEFINER clause or have SELECT access to the mysql.proc table.
So grant them that access:
GRANT SELECT ON mysql.proc TO 'dev-user'#'%';
BTW, it's not necessary to use FLUSH PRIVILEGES after the GRANT statement. See MySQL: When is Flush Privileges in MySQL really needed?

Access denied; you need (at least one of) the SUPER privilege(s)

We are using mysql 5.7.22 on centos and I have created user with this command:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, ALTER, CREATE
TEMPORARY TABLES , CREATE ROUTINE, ALTER ROUTINE ,SHOW VIEW,EVENT ON
`s_ws`.* TO test#'%' IDENTIFIED BY 'Test#123';
GRANT SELECT ON mysql.proc TO test#'%'; FLUSH PRIVILEGES;
Now I want to create SP through above user with this definer (we cant remove definer clause s_sp#localhost):
DELIMITER $$
USE `s_ws`$$
DROP PROCEDURE IF EXISTS `aaa`$$
CREATE DEFINER=`s_sp`#`localhost` PROCEDURE `aaa`()
SQL SECURITY INVOKER BEGIN SELECT 'hello-world';
END$$
DELIMITER ;
Please suggest me.
Super is global privileges. You also need the EXECUTE on the s_ws schema:
GRANT EXECUTE ON `s_ws`.* TO test#'%'
GRANT SUPER ON *.* TO test#'%';
FLUSH PRIVILEGES;

Provide only GRANT EXECUTE 'procedure' to a user (No select or insert permissions)

I was wondering if it's possible to grant EXECUTE permissions to a user without granting SELECT, INSERT etc. permissions on the table that a procedure runs on?
Using it for a Logins table for a webapp. MySQL is running in a Docker container. SQL for creating procedures is copied across as part of the docker build process (when run, the sql is used in entrypoint.sh). Login_db is created when running the container (-e flag).
I'd like to remove the GRANT SELECT line from below so, no matter what happens, the webapp server can never run a SELECT query - such as doing SELECT * FROM logins.
CREATE USER 'logins'#'172.24.0.7' IDENTIFIED BY 'some-password';
GRANT SELECT, INSERT, UPDATE on logins_db.login TO 'logins'#'172.24.0.7';
GRANT EXECUTE ON PROCEDURE logins_db.sp_login16 TO 'logins'#'172.24.0.7';
FLUSH PRIVILEGES;
This doesn't solve it - as being the table owner would expose the same privileges:
Execute stored proc fails with GRANT EXECUTE because of table permissions
This might explain why I can't, but the table names are a bit odd to me (MySQL newbie - I'm under the impression that mysql.proc is a system table, so not sure if it applies):
How to grant execute on specific stored procedure to user
Could it be that root doesn't have SELECT privileges when creating the procedure and so the the logins user cannot run it? (Because Docker MySQL runs entrypoint.sh and then the environment variable)?
The procedure code is here (I know, not the most elegant) - could I GRANT and then REVOKE privileges for the logins user within this, considering the DEFINER is root ?
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_login16`(
IN p_email VARCHAR(120),
IN p_password VARCHAR(120))
BEGIN
SELECT user_id,user_password FROM login WHERE user_email = p_email;
Yes, you can do this by using sql security definer while declaring the stored procedure:
The SQL SECURITY characteristic can be DEFINER or INVOKER to specify
the security context; that is, whether the routine executes using the
privileges of the account named in the routine DEFINER clause or the
user who invokes it. This account must have permission to access the
database with which the routine is associated. The default value is
DEFINER. The user who invokes the routine must have the EXECUTE
privilege for it, as must the DEFINER account if the routine executes
in definer security context.
The DEFINER clause specifies the MySQL account to be used when
checking access privileges at routine execution time for routines that
have the SQL SECURITY DEFINER characteristic.
If a user value is given for the DEFINER clause, it should be a MySQL
account specified as 'user_name'#'host_name', CURRENT_USER, or
CURRENT_USER(). The default DEFINER value is the user who executes the
CREATE PROCEDURE or CREATE FUNCTION statement. This is the same as
specifying DEFINER = CURRENT_USER explicitly.
To sum it up: the user in the definer clause has to have the select / insert privileges to the underlying table in this ase, while the user who executes the stored proc must have execute privileges to the stored proc.
Added a new user ADMIN#localhost with SELECT, INSERT and UPDATE privileges. ADMIN then became the DEFINER for all the procedures, with 'logins'#'172.24.0.7' only being granted EXECUTE permissions. Runs perfectly now!
Apparently you can't use root in the way I was trying to. Kudos to #Shadow for pointing me in the right direction.
Setting up the admin user:
CREATE USER 'admin'#'localhost' IDENTIFIED BY '<password>';
GRANT SELECT, INSERT, UPDATE, DELETE ON db.table_name TO 'admin'#'localhost';
GRANT ALTER ROUTINE, CREATE ROUTINE, EXECUTE ON *.* TO 'admin'#'localhost';
FLUSH PRIVILEGES;
Defining a stored procedure that creates a entry using the limited admin user
DELIMITER $$
CREATE DEFINER=`admin`#`localhost` PROCEDURE `sp_createTableEntry`(
IN value_one VARCHAR(120),
IN value_two VARCHAR(200)
)
BEGIN
IF ( select exists (select 1 from table_name where column_one = value_one) ) THEN
select 'Column One Exists !!';
ELSE
insert into table_name
(
column_one,
column_two
)
values
(
value_one,
value_two
);
END IF ;
END $$
DELIMITER ;

How to view only procedure related grants in MySQL?

I want to see only grant privileges on a particular procedure in MySQL. This documentation shows all grants.
Is there a way to see grants only for a particular procedure in a db.
The below command gives all grants including select, update etc. :
SHOW GRANTS FOR 'root'#'localhost';
Try this:
SELECT *
FROM mysql.procs_priv A
WHERE A.Db = 'DatabaseName' AND A.User = 'root' AND
A.host = 'localhost' AND A.Routine_name = 'ProcedureName' AND
FIND_IN_SET('Grant', A.proc_priv);
Use this command to grant execute privileges on specific procedure:
GRANT EXECUTE ON PROCEDURE schema_name.proc_name TO 'user_name';
Reference
Suppose, you want to create a procedure called MyFirstProc and you wanted to grant ALL users the ability to EXECUTE this procedure. You would run the following GRANT statement:
GRANT EXECUTE ON PROCEDURE MyFirstProc TO '*'#'localhost';

Meaning of Execute_priv on mysql.db table

I created user 'restriceduser' on my mysql server that is 'locked down'. The mysql.user table has a N for all priveledges for that account. The mysql.db table has Y for only Select, Insert, Update, Delete, Create, Drop; all other privileges are N for that account. I tried to create a stored procedure and then grant him access to run only that procedure, no others, but it does not work.
The user receives: Error: execute command denied to user 'restricteduser'#'%' for routine 'mydb.functionname'
The stored procedure:
CREATE DEFINER = 'restriceduser'#'%' FUNCTION `functionname`(sIn MEDIUMTEXT, sformat MEDIUMTEXT)
RETURNS int(11)
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
....
END;
The grant statement I tried:
GRANT EXECUTE ON PROCEDURE mydb.functionname TO 'restricteduser'#'%';
I was able to work around by modifying his mysql.db entry with
update mysql.db set execute_priv='Y' where user='restricteduser'
This seems to be more then I want, because it opens up permissions for him to run any stored procedure in that database, while I only wanted him to have permissions to run the designated function.
Does anyone see where my issue may lie?
The user table for the restricted user that you have created
will need execute_priv = 'Y'. This grant supersedes the db grant.