Revoke access for one of the many databases in MySQL - mysql

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.

Related

how to revoke privileges for a MySQL user

There is a MySQL user with database level privileges, as shown in the screen shot below. However, when an attempt is made to revoke privileges for this user, an error 1141 is the result. Why is this error being generated? How can the privileges be revoked?
I entered show grants for 'api_user'#'localhost'; and got the ERROR 1141 message.
Edit:
Here I entered REVOKE ALL PRIVILEGES FROM 'api_user'#'localhost'; and got a syntax error message.
Since the user only has grants on a single database, I think you need to specify that database in the REVOKE command:
REVOKE ALL PRIVILEGES ON api_example.* FROM api_user#localhost;
If that doesn't work, try dropping the user:
DROP USER api_user#localhost;
From the documentation:
The DROP USER statement removes one or more MySQL accounts and their privileges. It removes privilege rows for the account from all grant tables.
If the grant tables hold privilege rows that contain mixed-case database or table names and the lower_case_table_names system variable is set to a nonzero value, REVOKE cannot be used to revoke these privileges. It will be necessary to manipulate the grant tables directly. (GRANT will not create such rows when lower_case_table_names is set, but such rows might have been created prior to setting the variable.)
MySQL Revoke LowerCase

Grant all privileges on set of databeses with same prefix

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.

MySQL Permission for performing backup

What are the minimum required permissions for a mysql user to perform a backup using mysqldump/xtrabackup? I do not want permissions to power like root, but just enough to perform a backup. This is becasue innobackupex requires you to add the password on command line, which is not too secure. So i would like to create another user with not so much privileges to be used.
On MySQL this would be these permissions as far as I know:
GRANT SELECT, LOCK TABLES, RELOAD, SHOW VIEW ON *.* TO 'user'#'localhost' IDENTIFIED BY 'password';
Note that it may vary if you use views, functions, procedures etc

Allow MySQL user with limited database access to create more users with similar access

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.

MySQL database level credentials

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.