Grant Execute Function permission to another user - mysql

I have a database function fn_relation_isModerator, only user api has access to this function. Now I want another user to have this permission (while keeping the previous permission as well).
I checked routine name and user by following query:
select routine_name, routine_type, definer from information_schema.ROUTINES where ROUTINE_SCHEMA = 'db_name';
Which resulted:
+-------------------------+---------------+----------+
| ROUTINE_NAME | ROUTINE_TYPE | DEFINER |
+-------------------------+---------------+----------+
| | | |
| fn_relation_isModerator | FUNCTION | api#% |
+-------------------------+---------------+----------+
Approach 1:
So I ran the following query to grant this permission:
GRANT EXECUTE ON PROCEDURE db_name.fn_relation_isModerator TO 'api_worker'#'%';
But it resulted in following error:
Error Code: 1305. PROCEDURE fn_relation_isModerator does not exist
Approach 2:
Query:
GRANT EXECUTE ON FUNCTION `db_name`.`fn_relation_isModerator` TO 'api_worker'#'%';
Error
Error Code: 1133. Can't find any matching row in the user table
Approach 3:
Query:
GRANT EXECUTE ON `db_name`.`fn_relation_isModerator` TO 'api_worker'#'%';
Error:
Error Code: 1144. Illegal GRANT/REVOKE command; please consult the
manual to see which privileges can be used

You have to use grant execute on the function (Approach 2):
GRANT EXECUTE ON FUNCTION `db_name`.`fn_relation_isModerator` TO 'api_workers'#'%';
As explained in the comments by OP, there was a typo in user, it should be api_workers instead of api_worker.
All approaches failed due to the use of non-existent user.

Related

how do I grant a new user the privilege to create a new database in MySQL

how do I grant a new user the privilege to create a new database in MySQL
Specifically:
the database does not exist yet
I have successfuly created a new DB user account (that is not admin)
I want that non-admin user to create a new database
I do NOT want the 'admin' user to create the database and then grant privs to the database to the new user
as 'admin', I want to grant the new user the privilege to create a new database
I do not want to grant the new user any additional privileges on existing databases
This is not covered anywhere in the documentation that I can find.
Monday 2022-04-04
Update:
I created user 'scott' and then logged in as MySQL user 'admin' When I run this command
Note: The 'test' database does not yet exist
mysql>GRANT CREATE ON test.* to 'scott'#'localhost';
I get an error
==> ERROR 1410 (42000): You are not allowed to create a user with GRANT
Why do I get this error? I am not attempting to create a user, but rather grant a user access to a non-existent database (as is the approach with MySQL to grant a user privileges to create a database).
If up update the SQL statement to:
mysql>GRANT CREATE ON test.* to scott;
It runs OK
Query OK, 0 rows affected (0.07 sec)
And so now I login as user 'scott and run this statement:
mysql>create database rum;
==> ERROR 1049 (42000): Unknown database 'test'
Why do I get this error?
At this point, I am still not able to create a database as a non-admin user.
Example: grant "scott" the privilege to create the test3 database, which does not exist yet:
mysql> select user();
+----------------+
| user() |
+----------------+
| root#localhost |
+----------------+
mysql> grant create on test3.* to 'scott'#'localhost';
Query OK, 0 rows affected (0.01 sec)
Now try as scott to create the database:
mysql> select user();
+-----------------+
| user() |
+-----------------+
| scott#localhost |
+-----------------+
mysql> show grants;
+---------------------------------------------------------+
| Grants for scott#localhost |
+---------------------------------------------------------+
| GRANT USAGE ON *.* TO `scott`#`localhost` |
| GRANT ALL PRIVILEGES ON `test`.* TO `scott`#`localhost` |
| GRANT CREATE ON `test3`.* TO `scott`#`localhost` |
+---------------------------------------------------------+
mysql> create database test3;
Query OK, 1 row affected (0.00 sec)
mysql> use test3;
Database changed
MySQL has one privilege called CREATE which is for creating both databases and tables. See https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_create
You can either grant the user privilege to create a database of a specific name, or else grant them the privilege to create a database of any name, but that means they can also create other tables, either in the new database or in other existing databases. Sorry, there may not be a solution for you to allow them to create any new database without specifying the name when you grant the privilege, but then only have privilege in that database.
You are not allowed to create a user with GRANT
You did not create the user scott. Older versions of MySQL allows GRANT to implicitly create a user if one does not exist, but that has been disabled on more recent versions because folks realized it is a security weakness.
To be clear, the user "scott" is just an example I used. Don't literally use the name "scott" if that's not the user to whom you want to grant privileges.
The other errors you got seem to be that you granted the user privileges on a database named test.* but then you tried to create a database with a different name. The example I showed only grants the privilege to create the specific named database, not a database named rum or any other database.
I understand you want to grant privilege to create a database of any name. The syntax for that would be GRANT CREATE ON *.* TO... but that would grant the user privileges on all the other existing databases too.
There is no combination of syntax to grant privileges on any database name wildcard that means any database, provided that it is not yet created.

Query to retrieve list of privileges in different database

Is there a query (not a stored procedure or a command) which can be executed to retrieve list of privileges for objects (Tables, Views, Stored Procedures, Functions & Triggers) and users for a particular database (require following columns -- Schema name, Object type, Object name, Permission)?
MySQL --
Tried this but require a consolidate query -- SHOW GRANTS FOR 'root'#'localhost';
Oracle --
Tried this SELECT * FROM DBA_TAB_PRIVS but it provides for tables and views only
MariaDB --
SQL --
As of Oracle (I don't know other databases; by the way, I believe you wrongly used the sql tag. It is the language, while the database you're probably talking about is named the MS SQL Server), remember that you can ask the Dictionary. For example:
SQL> select * From dictionary where lower(comments) like '%grant%';
TABLE_NAME COMMENTS
-------------------- -------------------------------------------------------
<snip>
USER_ROLE_PRIVS Roles granted to current user
USER_SYS_PRIVS System privileges granted to current user
USER_TAB_PRIVS Grants on objects for which the user is the owner, gran
tor or grantee
USER_TAB_PRIVS_MADE All grants on objects owned by the user
USER_TAB_PRIVS_RECD Grants on objects for which the user is the grantee
<snip>
20 rows selected.
SQL>
Saying that DBA_TAB_PRIVS (which displays info for the whole database; I'm running this from an ordinary user, not a DBA) shows only tables and views, well - you are wrong. It displays procedures as well. How do I know?
This is my procedure and I'll grant execute privilege to mike:
SQL> select object_name, object_type from user_procedures where object_name = 'P_TEST';
OBJECT_NAME OBJECT_TYPE
--------------- -------------------
P_TEST PROCEDURE
SQL> grant execute on p_test to mike;
Grant succeeded.
What do I see?
SQL> select grantee, owner, table_name, privilege
2 from user_tab_privs
3 where table_name = 'P_TEST';
GRANTEE OWNER TABLE_NAME PRIVILEGE
---------- ---------- -------------------- ----------
MIKE SCOTT P_TEST EXECUTE
SQL>
Here it is. So yes, you were wrong.

Allowing remote access in MySql 8.0 not allowed

A lot of the existing answers are targeting the old MySQL and I haven't been able to find a solution for the new MySQL 8.0.
mysql> SELECT user FROM mysql.user;
+------------------+
| user |
+------------------+
| mysql.infoschema |
| mysql.session |
| mysql.sys |
| r00t |
| root |
+------------------+
I have already a user called r00t.
When I login as root and try to give r00t remote permission:
GRANT ALL PRIVILEGES ON *.* TO r00t#'18.132.x.xxx';
ERROR 1410 (42000): You are not allowed to create a user with GRANT
But the user already exists, so what gives?
The old way doesn't work either:
GRANT ALL PRIVILEGES ON *.* TO 'r00t'#'18.132.x.xxx' IDENTIFIED WITH caching_sha2_password BY 'myPass';
ERROR 1064 (42000): You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'IDENTIFIED WITH caching_sha2_password BY
'myPass'' at line 1
In MYSQL the users account is identified by the username and the domain i.e.
username domain
`r00t` and '18.132.x.xxx'
So if you created a 'r00t'#'localhost' it is not the same as 'r00t'#'18.132.x.xxx'
So in fact you are trying to create a new account, or rather 'r00t'#'18.132.x.xxx' does not exist yet, hence the error.
So first you should create the account 'r00t'#'18.132.x.xxx'

MySQL Error: #1142 - TRIGGER command denied

I need that my MySQL database makes a sum of some values in a specific coloumn. To do that I used trigger statement but MySQL gave me an error:
MySQL Error: #1142 - TRIGGER comand denied to user 'XXXXXX' for table wp_wpdatatable_8
the Trigger is below:
CREATE TRIGGER SumPliche AFTER INSERT ON wp_wpdatatable_8 FOR EACH ROW UPDATE wp_wpdatatable_8 SET sommapliche = tricipite + addome + soprailiaca + sottoscapolare + ascellare + pettorale + coscia
How can I do that?
thanks
It seems the issue here is with the permissions your user has on the database from which wp_wpdatatable_8.
To grant trigger permissions for a specific user and database, you may use the following command:
mysql> GRANT TRIGGER ON <DATABASE>.* TO <USER>#'<DATABASE HOST>';
Where
<DATABASE> refers to the database that contains the wp_wpdatatable_8 table.
<USER> the username that is trying to issue the CREATE TRIGGER command.
<DATABASE HOST> database host from where your user accesses the database. If you are running it locally, you can use localhost.
After flushing the privileges, creating the trigger should work normally.
For more information, check out the GRANT syntax on the MySQL.documentation
You lack the TRIGGER privilege on the database you are using.
I got this error when I did a test. Create a test user:
mysql> create user 'bill'#'localhost';
mysql> grant all privileges on test2.* to 'bill'#'localhost';
mysql> revoke trigger on test2.* from 'bill'#'localhost';
mysql> show grants for 'bill'#'localhost';
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for bill#localhost |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'bill'#'localhost' IDENTIFIED BY PASSWORD '*29A1BB43D3B9EB42028B4566E4836353285B9395' |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT ON `test2`.* TO 'bill'#'localhost' |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Now try creating a trigger as this user:
~ mysql -ubill -p
mysql> use test2
mysql> create table t ( i int);
mysql> create trigger tt before insert on t for each row set new.i = 42;
ERROR 1142 (42000): TRIGGER command denied to user 'bill'#'localhost' for table 't'
I also think your trigger might not do what you think it does, so it's just as well that you didn't create it.
CREATE TRIGGER SumPliche AFTER INSERT ON wp_wpdatatable_8
FOR EACH ROW
UPDATE wp_wpdatatable_8
SET sommapliche = tricipite + addome + soprailiaca + sottoscapolare + ascellare + pettorale + coscia
If I create this trigger in my test database (as a different user with TRIGGER privilege), and then try to insert a row:
mysql> insert into wp_wpdatatable_8 values (1, 1, 1, 1, 1, 1, 1, 1);
ERROR 1442 (HY000): Can't update table 'wp_wpdatatable_8' in
stored function/trigger because it is already used by statement which invoked
this stored function/trigger.
You probably want to set values only in the row you insert. If so, you would reference the current row being inserted with the NEW.* syntax:
CREATE TRIGGER SumPliche BEFORE INSERT ON wp_wpdatatable_8
FOR EACH ROW
SET NEW.sommapliche = NEW.tricipite + NEW.addome + NEW.soprailiaca
+ NEW.sottoscapolare + NEW.ascellare + NEW.pettorale + NEW.coscia;
Also you must use BEFORE INSERT if you want to change a value in the row before you insert it. If you use AFTER INSERT, it's too late.
Now it works:
mysql> insert into wp_wpdatatable_8 values (1, 1, 1, 1, 1, 1, 1, 1);
Query OK, 1 row affected (0.02 sec)
mysql> select * from wp_wpdatatable_8;
+-------------+-----------+--------+-------------+----------------+-----------+-----------+--------+
| sommapliche | tricipite | addome | soprailiaca | sottoscapolare | ascellare | pettorale | coscia |
+-------------+-----------+--------+-------------+----------------+-----------+-----------+--------+
| 7 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+-------------+-----------+--------+-------------+----------------+-----------+-----------+--------+
if I use
GRANT TRIGGER ON wordpress-5478r34b.* TO '_sso_67c5vh1'#'10.3.157.568'
1064 - Syntax Error in SQL query near to '-5478r34b.* TO '_sso_67c5vh1'#'10.3.157.568'' linea 1
or
GRANT TRIGGER ON 'wordpress-3236c57b'.* TO '_sso_35fd3dc2'#'10.3.156.140'
1064 - Syntax Error in SQL query near to ''wordpress-5478r34b'.* TO '_sso_67c5vh1'#'10.3.157.568'' linea 1
or
GRANT TRIGGER ON 'wordpress'-'3236c57b'.* TO '_sso_35fd3dc2'#'10.3.156.140'
1064 - Syntax Error in SQL query near to ''wordpress'-'5478r34b'.* TO '_sso_67c5vh1'#'10.3.157.568'' linea 1
whatever I do, it gives me a syntax error.
In general, what I want to do is an automatic sum when I add new datas on my database. Is there something more simple way?

Privilege for CREATE AGGREGATE FUNCTION

Why am I unable to create this aggregate function?
As far as I can tell, I've granted the appropriate privileges (CREATE ROUTINE and ALTER ROUTINE) both on *.* and on my database (peacock):
mysql> SELECT User, Host, Create_priv, Create_routine_priv, Alter_routine_priv FROM mysql.user WHERE user='glpy';
+------+-----------+-------------+---------------------+--------------------+
| User | Host | Create_priv | Create_routine_priv | Alter_routine_priv |
+------+-----------+-------------+---------------------+--------------------+
| glpy | localhost | Y | Y | Y |
+------+-----------+-------------+---------------------+--------------------+
mysql> SELECT User, Host, db, Create_priv, Create_routine_priv, Alter_routine_priv FROM mysql.db WHERE user='glpy';
+------+-----------+---------+-------------+---------------------+--------------------+
| User | Host | db | Create_priv | Create_routine_priv | Alter_routine_priv |
+------+-----------+---------+-------------+---------------------+--------------------+
| glpy | localhost | peacock | N | Y | Y |
+------+-----------+---------+-------------+---------------------+--------------------+
However, when I try to create the function, I get Access denied ... to database 'mysql':
mysql> use peacock;
mysql> CREATE AGGREGATE FUNCTION coverage RETURNS INT SONAME 'my-library.so';
ERROR 1044 (42000): Access denied for user 'glpy'#'localhost' to database 'mysql'
In particular:
Why is access required to the mysql table to create the aggregate function?
Given that I have granted the privileges on *.*, why is access denied?
I also tried granting the privileges on mysql, but access was still denied.
CREATE [AGGREGATE] FUNCTION function_name
RETURNS {STRING|INTEGER|REAL|DECIMAL}
SONAME shared_library_name;
This is the declaration for a User Defined Function, which appears to be what you are trying to install. This is not declaring a Stored Function. CREATE FUNCTION has two different uses in MySQL. This is one of them.
For this to work:
you do not need the CREATE ROUTINE privilege
it does not matter what database you're in, because User-Defined Functions, unlike stored functions, are global in scope. They extend MySQL functionality in a way that is analogous to its built-in aggregate functions, like AVG() and SUM() and MIN() and MAX().
you cannot specify a database as part of the function declaration
the following is the requirement that you are missing:
13.7.3.1. CREATE FUNCTION Syntax for User-Defined Functions
To create a function, you must have the INSERT privilege for the mysql database. This is necessary because CREATE FUNCTION adds a row to the mysql.func system table that records the function's name, type, and shared library name.
— http://dev.mysql.com/doc/refman/5.6/en/create-function-udf.html
If you don't have this privilege, the function will have to be installed by someone who holds this privilege, or it will need to be granted to you. You can't grant it to yourself.
From the manual:
CREATE PROCEDURE and CREATE FUNCTION require the CREATE ROUTINE privilege.
Make sure the privilege is on the database that you are trying to use. When you run CREATE AGGREGATE FUNCTION coverage RETURNS INT SONAME 'my-library.so';, you are trying to create the function in the mysql database (that is, the system database that is actually named mysql), so you need the CREATE ROUTINE privilege on that database. If you are trying to create it in some other database, run a USE my_database command or modify your syntax:
CREATE AGGREGATE FUNCTION my_database.coverage RETURNS INTEGER SONAME 'my-library.so';
If you are in a shared environment (pretty much anything other than a VPS or dedicated server), you probably don't have access to do anything to the mysql database and never will. So, create the function in your own database.
Edit: INT should be INTEGER.