I have a set of databeses with names like abc_base_1, abc_base_2, abc_base_3 abc_base_n.
I'd like to grant all privileges on all tables of all this databases to one non root user.
Generally, it seems that abc_ is a common prefix of group.
Questions:
Is mysql has database groups? If yes - how to define them (something special or it just has to have same name prefix (like abc))?
Is it possible to grant privileges on group of databases (or databases with names starts with abc prefix)? If yes - how to grant?
Is this permissions distributes dynamically for all new databases, that has the same name prefix or I should grant permissions all the time, when new databases are created.
Yes. You can grant permissions to a group of MySQL databases identified by a LIKE wildcard:
mysql> GRANT ALL ON `abc\_%`.* TO username#localhost;
Permissions are checked when a user attempts to access the database -- you do not need to repeat this GRANT statement when databases are created.
I've found solution.
Privileges should be granted like this:
GRANT ALL PRIVILEGES ON `abc\_%` . * TO 'someuser'#'localhost';
This expression provides the following rights:
access to all databases started with abc_
create new databases, started with abc_
access to new databases, started with abc_ but created by other users.
Related
This question refers to MySQL and/or MariaDB specifically.
Is it possible to permit certain users to drop/create one (or more) specific databases, but not all databases? By this, I do not mean how to give users all privileges for certain specific databases with a query like:
GRANT ALL PRIVILEGES ON `example-db`.* TO 'example-user'#'localhost';
I've found some methods on how to do this for MSSQL here and a similar post for PostgreSQL.
grant privileges separately for a user account in MySQL.
When specifying the database name and table name, separate them with a. (period) and no spaces. This will give the root user fine-grain control over certain data.
Also, replace the PERMISSION_TYPE value with the kind of access you want to grant to your new user account.
Here are the most used commands in MySQL:
CREATE — enable users to create a database or table
SELECT — permit users to retrieve data
INSERT — let users add new entries in tables
UPDATE — allow users to modify existing entries in tables
DELETE — enable users to erase table entries
DROP — let users delete entire database tables
NOTE: Using the ALL PRIVILEGES permission type from before will allow
all of the permissions listed above.
To use any of these options, simply replace PERMISSION_TYPE with the appropriate keyword. To apply multiple privileges, separate them with a comma. For example, we can assign CREATE and SELECT to our non-root MySQL user account with this command:
GRANT CREATE, SELECT ON * . * TO 'user_name'#'localhost';
Sometimes, you might come across a situation where you need to revoke given privileges from a user. You can do so by entering:
REVOKE PERMISSION_TYPE ON database_name.table_name FROM ‘user_name’#‘localhost’;
For example, to withdraw all privileges for our non-root user we should use:
REVOKE ALL PRIVILEGES ON * . * FROM 'user_name'#'localhost';
Finally, you can entirely delete an existing user account by using the following command:
DROP USER ‘user_name’#‘localhost’;
Don't forget to FLUSH PRIVILEGES;
In order to find what privileges have already been granted to a MySQL user, you can use the SHOW GRANTS command:
SHOW GRANTS FOR 'user_name'#'localhost';
Let’s start by making a new user within the MySQL shell:
CREATE USER 'newuser'#'localhost' IDENTIFIED BY 'password';
To provide a specific user with permission, you can use this framework:
GRANT type_of_permission ON database_name.table_name TO 'username'#'localhost'
Once you have finalized the permissions that you want to set up for your new users, always be sure to reload all the privileges.
FLUSH PRIVILEGES;
I have multiple MySQL databases on the server, DB 1, mysql and DB 2. I created a user User A. I want to revoke access for User A only for a single DB, say mysql, as this would have several log tables. I tried basic REVOKE syntax which is not working.
revoke select on mysql.* from user#localhost;
Please note that the revoke should only happen for mysql DB and not for DB 1 and DB 2.
Before MySQL 8.0.16, you cannot substract privileges,
The privileges that a user holds for a database, table, column, or routine are formed additively as the logical OR of the account privileges at each of the privilege levels, including the global level. It is not possible to deny a privilege granted at a higher level by absence of that privilege at a lower level.
Trying to do so should give you an error like
Error Code: 1141. There is no such grant defined for user 'user' on host 'localhost'
You have to add permissions for all databases individually, e.g. allow db1 and db2 specifically, instead of allowing all and removing mysql.
Starting with MySQL 8.0.16, you can finally remove access to individual databases (but for now only on databases, not on e.g. individual tables or columns):
As of MySQL 8.0.16, it is possible to explicitly deny a privilege granted at the global level by revoking it for particular databases, if the partial_revokes system variable is enabled:
GRANT SELECT, INSERT, UPDATE ON *.* TO u1;
REVOKE INSERT, UPDATE ON db1.* FROM u1;
The partial_revokes system variable has to be set for this:
Enabling this variable makes it possible to revoke privileges partially. Specifically, for users who have privileges at the global level, partial_revokes enables privileges for specific schemas to be revoked while leaving the privileges in place for other schemas. For example, a user who has the global UPDATE privilege can be restricted from exercising this privilege on the mysql system schema. (Or, stated another way, the user is enabled to exercise the UPDATE privilege on all schemas except the mysql schema.) In this sense, the user's global UPDATE privilege is partially revoked.
The bold marked part is exactly what you are trying to do.
I know that I can create a user with the create user privileges like so:
create user primary_user identified by 'pass';
grant all on *.* to primary_user with grant option;
This will in turn allow me to create users whilst logged in with primary_user.
Now let's assume I have a subset of databases, all with prefix abc_, and that I want my primary_user to only be able to access these databases.
Then the grant query above would look like so:
grant all on `abc_%`.* to `primary_user` with grant option;
The problem now, however, is that when I log in with my primary_user and try to create a secondary_user, I get the following error:
ERROR 1227 (42000): Access denied; you need (at least one of) the
CREATE USER privilege(s) for this operation
TL;DR
Basically what I want is primary_user to only be able to access databases with the abc_ prefix, and to also be able to create secondary users that in turn also only have access to databases with an abc_ prefix.
Is this possible? Or is my only option to create the secondary users with a user account that has create user privileges on *.*?
As mentioned in MySQL Documentation:
To use CREATE USER, you must have the global CREATE USER privilege or
the INSERT privilege for the mysql database.
Thus, users with privileges in specific databases cannot create users. Ofcourse, since you have with grant option, your primary_user can grant all database level privileges to other already created users (for the abc_ databases).
Note #1: Here you can find an interesting table with the various privileges and the different levels that they can be granted.
Note #2: Be extra cautious when giving GRANT OPTIONS to non-admin users because they can modify the privileges of other users which can lead to chaos. The Open Web Application Security Project states:
[Grant privilege]... should be appropriately restricted to the DBA and Data (Table)
owners. Give specific permissions on an as needed basis and use
different logins for different purposes.
Is it possible to have database level credentials for MySQL?
In our current system we have multiple databases in one database server, if we connect to the server using any tool we can see all databases in that server, to have more secure system.
Can we have credentials for each database.
You can't have credentials for databases. But you can have credentials for created users and grant/restrict access to any tables/databases according your policy.
create user
grant
priviledges
Yes, absolutely, you can set up access privileges on per-database basis. In fact, MySQL allows very fine-grained privileges down to table and even column level. E.g.:
-- Creates a user
GRANT USAGE ON *.* TO 'username'#'hostname' IDENTIFIED BY PASSWORD '*SOMEPASSWORD';
-- Gives the user access to a single database `database_name`
GRANT SELECT, INSERT, UPDATE, DELETE ON `database_name`.* TO 'username'#'hostname';
You probably want to read more about GRANT syntax and MySQL privileges.
Worth adding, that you are allowed to have usernames identical to database names.
I want to have multiple a MySQL users to be able to issue commands like
CREATE DATABASE dbTest;
But I also want each of these users to be able to see and access only their own databases.
All I could find was how to either create the databases by a DBA and grant the privileges on this database to the specific user:
GRANT ALL PRIVILEGES ON dbTest.* TO 'user';
or grant privileges on all databases to a user:
GRANT ALL PRIVILEGES ON *.* TO 'user';
But neither is what I want, because it needs to scale and be secure.
You can use
GRANT ALL PRIVILEGES ON `testuser\_%` . * TO 'testuser'#'%';
to grant the user testuser privileges on all databases with names beginning with testuser_.
This allows the testuser to create databases limited to names starting with testuser_
You can use
GRANT ALL PRIVILEGES ON `testuser_%` . * TO 'testuser'#'%';
to grant the user testuser privileges on all databases with names beginning with testuser_.
EDIT: I'm not sure if this user is now also allowed to create databases.
Yes, this allows the testuser to create databases limited to names starting with testuser_
Create a stored procedure that is defined by the admin user and invokes with the admin user privileges by using SQL SECURITY DEFINER. In the stored procedure,
Create the database.
Set the privileges on the database so only the current user has access.
Execute FLUSH PRIVILEGES to reload the privileges from the grant tables.
Use USER() to get the current user login details.
Find out more about SQL SECURITY DEFINER.
It is impossible to do this using permissions only .
The workaround as suggested in another answer:
GRANT ALL PRIVILEGES ONtestuser_%. * TO 'testuser'#'%';
has the problem that the users must then be very careful in naming their databases.
For example if user aaa creates database bbb_xyz, it can then be accessed exclusively by user bbb but not by user aaa.