How to set table level privileges in MySQL - mysql

I am trying to revoke select privilege from a particular table from a MySQL DB.
Database level restriction is working but table level is not.
When I write "show grants"
This is what I get :
| GRANT USAGE ON *.* TO 'rachit'#'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' |
| GRANT ALL PRIVILEGES ON `test123`.* TO 'rachit'#'localhost' |
| GRANT INSERT, UPDATE, DELETE ON `test123`.`names123` TO 'rachit'#'localhost'
As you can see above I want to
revoke select privilege from rachit user on 'names123' table of 'test123' database, but SELECT is working.
I have attached a screenshot below for better understanding.
https://ibb.co/GRtjXX7

If you GRANT ALL ON test123.* TO 'rachit'#'localhost' you cannot remove one table by running REVOKE ALL ON test123.* TO 'rachit'#'localhost'.
some DBMS systems specifically DENY option for specifically denying access to specific table but this is not the case for mysql.
you may consider to write script and give access to each table one by one

Discussion:
If it wasn't specifically GRANTed, it can't be REVOKEd. This is an unfortunate side effect of the not-so-user-friendly Grant/Revoke syntax and implementation.
You can use a SELECT against information_schema.TABLES to automate the discovery of all the other tables. And have the SELECT build the desired GRANTs.
Possible workaround:
Another approach to your particular problem is to move that one table to a different database. Then GRANT different permissions to that db.

Related

Is it possible to grant only metadata privileges in MySQL

TLDR;
Target:
Is it possible to grant privileges to a certain "audit" user to access to MySQL metadata only (schema,table,column at least) without access to exact data in tables?
Version
MySQL 8+
Try:
Before this issues,
I've been already tried or known:
review MySQL official docs on privileges (notice me if I missed the answer in it)
search keywords on SOF: mysql, privilege, metadata, etc.
find solutions with my DBA friends
grant show databases to users, but it could get the schema lists only
all grants to infomatica_schema was in vain, as known to all
SELECT ON *.* is another answer, but my leader dont wanna data leak through it
Background:
My company ordered devops to collect MySQL metadata for some issues of audits or security monitoring or else (I don't know the details of whole story). Unnecessary data leak would not be expected to my leader.
BTW, I dont know the specific method where they, audit depts maybe, are going to collect metadata. All I've been required to do is to create a granted user for them.
I think I found a workaround for this, but it's kind of a hack, not a true solution.
https://dev.mysql.com/doc/refman/8.0/en/show-tables.html says:
If you have no privileges for a base table or view, it does not show up in the output from SHOW TABLES or mysqlshow db_name.
That is, you can't use SHOW TABLES, or see the tables in queries against INFORMATION_SCHEMA (because SHOW TABLES is really just a query against those system views).
But the language of "no privileges" got me thinking. Is there a privilege that the user could have, but which does not allow reading or writing data?
https://dev.mysql.com/doc/refman/8.0/en/grant.html says:
The permissible priv_type values at the table level are ALTER, CREATE VIEW, CREATE, DELETE, DROP, GRANT OPTION, INDEX, INSERT, REFERENCES, SELECT, SHOW VIEW, TRIGGER, and UPDATE.
How about SHOW VIEW? This would only allow viewing metadata, not querying a table or a view.
So I tried it:
mysql> create user 'auditor'#'%';
mysql> grant show view on test.* to 'auditor'#'%';
Then I logged in as that user, and tried it:
mysql> show grants;
+----------------------------------------------+
| Grants for auditor#% |
+----------------------------------------------+
| GRANT USAGE ON *.* TO `auditor`#`%` |
| GRANT SHOW VIEW ON `test`.* TO `auditor`#`%` |
+----------------------------------------------+
mysql> use test
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| Accounts |
| Bugs |
| BugsProducts |
| BugStatus |
...
I could also view columns, etc.
To be clear, those are concrete tables, not views. But since my auditor user has more than no privileges on the tables (even an irrelevant privilege), it qualifies for purposes of letting them view metadata about the tables.
In MySQL 8.0.20, they added the SHOW ROUTINES privilege. Prior to that, you needed SELECT privilege to view the body of stored procedure or functions. But you didn't mention auditors viewing routines in your question.

MySql: Restrict update permission on one column in one table

I have a table, lets call it student, in a schema called enrollment. Table student has a column called address that I don't want a certain user to update (other permissions are fine such as select, insert). All other columns in that table AND in that schema should have the update privilege.
Is this doable?
You can set privileges on database / table / column. But I really would not try to use MySQL's privilege mechanism at that level. I would instead write application code to decide who can see/change what. This is more flexible in the long run. And more graceful to the user -- instead of getting a cryptic MySQL error message about permissions, the UI would simply not show what should not be shown. For updating, the UI would not even give the user the option.
In my case, I wanted a specific application to be able to update only 1 field (my_field) in only 1 table (table_name) while being able to read the entire database.
I created a special user for that purpose:
CREATE USER 'restrictedUser'#'%' IDENTIFIED BY 'PASSWORD_HERE';
SET PASSWORD FOR 'restrictedUser'#'%' = PASSWORD('PASSWORD_HERE');
GRANT USAGE ON *.* TO 'restrictedUser'#'%';
GRANT SELECT ON DATABASE_NAME.* TO 'restrictedUser'#'%';
GRANT UPDATE (my_field) ON DATABASE_NAME.table_name TO 'restrictedUser'#'%';
Documentation for Column privilege can be found here for mariaDb and here for mysql

Grant CREATE TABLE permission to MySQL User

I have a database that is shared between some users, and I want to manage their permissions on this.
I want to give permission for creating a new table, and accessing (select, insert, update, delete) to that table of course, to a user that doesn't have full permission on the database (only he has SELECT access to some tables).
So, I executed this query:
GRANT CREATE ON eh1 TO user1
Then, when I logged in with that user and tried to create a new table, I got this error:
1142 - CREATE command denied to user 'user1'#'localhost' for table 'folan'
What is the problem here? How can I do that?
UPDATE
The problem solved partially by changing the command to this:
GRANT CREATE ON eh1.* TO user1
Now there is another problem, that the user1 cannot select or insert into the newly created table. The reason is understandable, but is there a way to solve this?
Thanks
use as per below-
GRANT CREATE ON eh1.* TO user1#'%' IDENTIFIED BY 'user1_password';
Note: '%' will provide access from all ips, so we should provide rights to specific ip instead of all ips, so change '%' with any ip like '191.161.3.1'
If user need select/insert/update/delete/create rights then syntax will be -
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ON eh1.* TO user1#'%' IDENTIFIED BY 'user1_password';
Update as per user requirement:
GRANT CREATE ON eh1.* TO user1#'%' IDENTIFIED BY 'user1_password';
GRANT SELECT, INSERT, UPDATE ON eh1.table1 TO user1#'%';
GRANT SELECT, INSERT, UPDATE ON eh1.table2 TO user1#'%';
Following this, correct syntax is
GRANT CREATE ON eh1.* TO user1
With eh1 a database.
If you don't use ".*", your database is considered a table.

SQL Grant SELECT

I want to create a user and only allow them to use select statements on the cameracircle database. So I have the following code:
CREATE USER 'hoeym'#'localhost' IDENTIFIED BY 'password';
CREATE DATABASE cameracircle;
GRANT SELECT ON cameracircle TO 'hoeym'#'localhost';
But the phpmyadmin doesn't like that. If I run this it says there is an error cause I don't have a databases selected, and if I add in USE cameracircle; before the GRANT statement it says that there is no table inside the database with the same name as the database. What have I done wrong?
Before you issue a GRANT statement, check that the
derby.database.sqlAuthorization
property is set to true. The derby.database.sqlAuthorization property enables the SQL Authorization mode.
Solved it with
GRANT SELECT ON cameracircle.* TO 'hoeym'#'localhost';
phpMyAdmin lets you do this graphically. From the Users tab, look for Add User then don't select anything for the Global Privileges area. Go ahead and create the user, then edit the privileges. Halfway down the page there's a area for "Database-specific privileges" where you can specify the permissions on a database (or even table-) level.

Is there a database tool which shows a list of sql commands I have permission for?

I talked to the developer of HeidiSQL about it and he told me I can query it by "show grants" command of sql, but i don't understand the result set coming from it.
show grants // I execute query here
GRANT USAGE ON . TO 'fsdb1user1'#'%' IDENTIFIED BY PASSWORD
'something'
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP,
REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON
fsdb1.* TO 'fsdb1user1'#'%'
mysql documentation says
SHOW GRANTS displays only the privileges granted explicitly to the
named account. Other privileges might be available to the account, but
they are not displayed. For example, if an anonymous account exists,
the named account might be able to use its privileges, but SHOW GRANTS
will not display them.
I think there might be some software somewhere trying some queries and checks grants that way.
It appears that this user is allowed to do a lot. Here is actually a good reference on all of these http://dev.mysql.com/doc/refman/5.1/en/grant.html#grant-privileges.
The user in question can run SELECT, UPDATE, and DELETE queries. They can CREATE tables and databases. They can DROP tables, databases, and views. They can create and alter INDEXes. They can ALTER table structures. They can use CREATE TEMPORARY TABLE. And finally, they can LOCK TABLES that they have SELECT privileges on. In this case, the user can do this on any table in this database (fsdb1) and from any host.