Can I use wildcards to see the grants of all users in MySQL 8.0 ?
SHOW GRANTS FOR '%'#'%'; doesn't work.
I 've had exported all the SHOW GRANT statements for all users into a text like this:
SELECT CONCAT('SHOW GRANTS FOR ''',user,'''#''',host,''';') FROM mysql.user WHERE mysql.user.user NOT IN ('mysql.infoschema','mysql.session','mysql.sys') INTO outfile '/var/lib/mysql-files/show_grants.txt';
but I don't know how to use it in order to create a table with 2 columns (1 for the user and 1 for the grants).
Related
Currently I perform a manual two-step procedure to get the grants information for all the users.
Step 1:
SELECT user, host FROM mysql.user;
Step 2:
SHOW GRANTS FOR '«user»'#'«host»'; -- Repeated for all user-host pairs.
Is there a single command to give me this information?
You should be able to retrieve privileges for all users from information_schema:
select grantee, group_concat(privilege_type) from information_schema.user_privileges group by grantee
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.
I want to create multiple users on MySQL and allow them to create databases and access the databases which are only created by them. Is there a way to do this?
If so what permission I need to give?
Instead of giving "create database" permission to a user, from "root" you can just create the database and grant all privileges on the database to the specific users. That's what I am using in my world. I don't think "create database" privileges available in MySQL especially.
Using the below approach you have the control of database level because the user can do anything in the specific database where they had the permission, not at the instance level (mean they can't create junk databases).
Friday 28> mysql -uroot -p
mysql> create user test identified by 'test';
mysql> create database x1;
mysql> grant all privileges on x1.* to 'test'#'%';
Friday 28> mysql -utest -p
Enter password:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| x1 |
+--------------------+
2 rows in set (0.00 sec)
mysql> use x1;
Database changed
mysql> create table test(c int);
seQuery OK, 0 rows affected (0.44 sec)
mysql> select * from test;
Empty set (0.00 sec)
To allow someuser to do SELECTs on mydb, I can execute the following statement:
GRANT SELECT ON mydb.* TO 'someuser'#'somehost';
Suppose that I want allow SELECTs on only two tables: event and event_detail.
I guess I can do the following:
GRANT SELECT ON mydb.event TO 'someuser'#'somehost';
GRANT SELECT ON mydb.event_detail TO 'someuser'#'somehost';
Would the following also work? (Supposing no other tables are matched)
GRANT SELECT ON mydb.event* TO 'someuser'#'somehost';
No - wildcards can only be used for entire table or database names.
You'll have to either type the grant statement for every table explicitly, or write a script or program to do it for you.
Based on the GRANT syntax:
GRANT
... priv_level ...
priv_level:
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
| db_name.routine_name
So I guess you can't. You can, anyway, use the INFORMATION_SCHEMA to find those tables with the name prefix you desire, and then iterate through them.
I'm facing a problem with user access control. To be more clear, the mysql user I create has access to other tables than what I've given access to.
Let's say I log in as root into mysql and there are many databases, and in database "test", there are many tables one of which is "news".
I want to create user specifically having access only to "select" values from "test.news". This is how it looked:
mysql> grant select on test.news to 'new_user2'#'localhost' identified by 'XXXXXXX';
Query OK, 0 rows affected (0.00 sec)
Flushed privileges: flush privileges;
Now, log out, and I login as new_user2:
/opt/lampp/bin/./mysql -u new_user2 -p
and want to see databases there:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| test |
+--------------------+
2 rows in set (0.00 sec)
This was good, in the sense, there were other databases in the "root" account which were not visible to new_user2. Then, I wanted to see tables in test. So-
use test;
show tables;
This is the first shock for me..
I saw all the tables in the "test" database, which I was not expecting. All I wanted to see was "news" table. Or is it normal that all users who have been given access to one table in a database, can actually view all the tables?
second shock, I used select * for another table- "user", which is essentially another table in "test", and I could see all the contents in user table.
So, when I created "new_user2" and granted permission only to access test.news, how can it access test.user? select * from news is working fine..
Did I really restrict access to all other tables in "test" database? If not, how do I do it?
OK. As if this is not sufficient, I can actually delete tables created by 'root'..
mysql> drop table member;
Query OK, 0 rows affected (0.42 sec)
These are the grants for 'new_user2'#'localhost' when logged in root...
mysql> SHOW GRANTS FOR 'new_user2'#'localhost';
+------------------------------------------------------------------------------------------------------------------+
| Grants for new_user2#localhost |
+------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'new_user2'#'localhost' IDENTIFIED BY PASSWORD '*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' |
| GRANT SELECT ON `test`.`news` TO 'new_user2'#'localhost' |
+------------------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
I feel, I'm missing something basic here. Please help me this. Thank you so much.