Reputation: 214
I am trying to keep my MySQL user accounts as restricted as possible with privileges, only granting the bare minimum for what I need.
I have a user called creator
which I want to use to create new users, create new databases, and assign those users privileges to those databases, but only to a database of a certain format.
To create the creator
user, I have the following (run as root):
GRANT CREATE USER, CREATE ON *.* TO 'creator'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON `my_prefix\_%`.* TO 'creator'@'localhost' WITH GRANT OPTION;
Now I would assume that this would give me the ability to create a new user, and assign it any privileges to a table matching my_prefix_%, but that does not seem to be the case. Running the following queries as the creator
user gives me an error.
CREATE DATABASE IF NOT EXISTS `my_prefix_test`;
CREATE USER 'test'@'localhost' IDENTIFIED BY 'password';
These work and I can create the user and the database just fine. Then trying to assign the privileges to the new user on the new database I get the following:
GRANT ALL PRIVILEGES ON `my_prefix_test`.* TO 'test'@'localhost';
> ERROR 1044 (42000): Access denied for user 'creator'@'localhost' to database 'my_prefix_test'
I also flushed privileges to be safe.
Does anyone have any insight into the issue? Would this be more easily accomplished with stored procedures? Thanks!
Upvotes: 3
Views: 4784
Reputation: 270617
According to the MySQL GRANT
documentation, wildcard characters _
and %
need to be backslash-escaped to be used as literals in the database name. In your attempt at the top, you have escaped one _
as \_
but not the other. If you do escape both underscores, you can achieve correct grants. The trick though, is that you must also escape them later when issuing the GRANT
statement as the creator
user to the test
user:
Login as root (or a fully privileged user):
-- As root:
GRANT CREATE USER, CREATE ON *.* TO 'creator'@'localhost' IDENTIFIED BY 'password';
-- Escape both underscores here
GRANT ALL PRIVILEGES ON `my\_prefix\_%`.* TO 'creator'@'localhost' WITH GRANT OPTION;
Login as creator
:
CREATE DATABASE IF NOT EXISTS `my_prefix_test`;
Query OK, 1 row affected (0.00 sec)
CREATE USER 'test'@'localhost' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
-- Issue the GRANT but escape the underscores.
-- because creator@localhost does not have permission to grant on
-- a pattern like myXprefixXtest, as the unescaped _ wildcards would allow
GRANT ALL PRIVILEGES ON `my\_prefix\_test`.* TO 'test'@'localhost';
Query OK, 0 rows affected (0.00 sec)
Login as test
, the grant works:
USE my_prefix_test;
CREATE TABLE t (id INT);
Query OK, 0 rows affected (0.00 sec)
Upvotes: 5