How can I restrict a MySQL user to a particular tables - mysql

How can I restrict a user_account in MySQL database to a particular tables. Ex:
UserName: RestrictedUser
DatabaseName: db_Payroll
TableName:
tb_Employees
tb_Users
tb_Payroll_YYMMDD
tb_Payroll_Processed
I want to restrict "RestrictedUser" to tb_Users and tb_Employees only and the rest of the tables of db_Payroll that will be created for future use is granted to have access.

Assuming the user has no current privileges, you can do the following
GRANT SELECT, INSERT, DELETE ON db_Payroll.tb_Users TO RestrictedUser#'%'
GRANT SELECT, INSERT, DELETE ON db_Payroll.tb_Employees TO RestrictedUser#'%'
Depending on exactly which privileges you wish to grant the user, you can change SELECT, INSERT, DELETE to something else, e.g. ALL PRIVILEGES.
Afterwards, remember to flush the privileges so they become effective by running
FLUSH PRIVILEGES;

You can grant access to individual tables by running:
GRANT ALL ON db_Payroll.tb_Users to RestrictedUser#RestrictedHostName;
And similarly for other tables. Use a list of operations instead of ALL if appropriate.
You cannot grant access to individual tables which do not exist yet without granting access to all tables.

Assuming the user has no current privileges, if you have a lot of tables and you only want to give the user access to a few of those tables, the simplest work-around I know of is using a technique I personally refer to as QueryCeption™ (Query Within a Query):
SELECT GROUP_CONCAT(CONCAT('grant select on `db_Payroll`.', table_name, ' to `RestrictedUser`#`%`') SEPARATOR ';
') from information_schema.tables where table_schema = 'db_Payroll' and
table_name not in ('TABLE-YOU-WANT-TO-RESTRICT-1', 'TABLE-YOU-WANT-TO-RESTRICT-2','TABLE-YOU-WANT-TO-RESTRICT-3');
This will output a text field that you can copy and paste into your editor. This particular example will grant SELECT privileges to all tables that are not within the restricted table array for that user.

Related

Mysql override permission for a single table

I've a Mysql DB with more than 250 tables, i need to block delete permissions for a single user on a single one of them.
we've already tried with grant but there's permission for delete for this DB, so the grant query for the single table doesn't take effect, i still can delete rows from this table. I did:
GRANT SELECT, INSERT, UPDATE ON db.table TO 'user'#'host';
the global permission:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER ON `db`.* TO 'user'#'host'
Is there a way to override permissions for a single table or we've to delete the global permissions and set permissions for the user in each table?
Maybe some way to set global permission for all (*) except one so the second grant will take effect?
Also tried #kiks73 post:
REVOKE DELETE ON db.table FROM 'user'#'host';
Getting:
ERROR 1147 (42000): There is no such grant defined for user 'user' on host 'host' on table 'table'
But there's the global permission set for this user, including delete permissions for this table.
thanks
I think that you need to use the REVOKE statement, because you have to remove a previously granted permission:
REVOKE DELETE ON db.table FROM 'user'#'host';
UPDATE
Referring to this Super User Q&A, if there is no specific grant to revoke on that table for that user, you should try to remove the GRANT ALL ON db.* and assign a grant to all to every single user on every single table, except the specific user on the specific table, that will be granted only for insert and update.
If you have 250 tables, you could create a script combining this SQL to get the list of user created tables:
SELECT * from information_schema.tables
WHERE table_schema not in ('information_schema', 'mysql', 'performance_schema')
and users:
SELECT User FROM mysql.user;
to create a SQL string with the grant you need.

MySQL: Explicit Hostname Vs Hostname with wildcard

Does MySQL treat an explicit hostname the same as a hostname with a wild card? For example, I have created a user via the following:
CREATE USER IF NOT EXISTS 'iga'#'ip-10-11-2-150.aws.example.hostname' IDENTIFIED BY 'SOMEPASSWORD';
Now, I want to grant the user permissions. Could I do it like the following, where the wildcard resolves any user from an ip-10-11-2-anything address?
GRANT INSERT, UPDATE, DELETE, SELECT ON iga.* TO 'iga'#'ip-10-11-2-%';
Or, do I have to explicitly put the same hostname as the user is created with, like the following:
GRANT INSERT, UPDATE, DELETE, SELECT ON iga.* TO 'iga'#'ip-10-11-2-150.aws.example.hostname';
Those are two distinct users. If we run this statement:
GRANT SELECT ON iga.* TO 'iga'#'ip-10-11-%'
Then MySQL will attempt to create a new user
'iga'#'ip-10-11-%'
This user is separate and distinct from the user created with the CREATE USER statement:
'iga'#'ip-10-11-2-150.aws.example.hostname'
which does not get the SELECT privilege. To give privileges to that user, We would need to give the full name that user in a GRANT statement:
GRANT SELECT ON iga.* TO 'iga'#'ip-10-11-2-150.aws.example.hostname'
When a session connects to MySQL, it matches one row in the mysql.user table; it will find an exact match if it exists, otherwise, it may find a wildcard match. But once it matches a user, that's the only user it matches. The session gets only the privileges associated with the one user, not privileges granted to other users that would also be wildcard matches.

How to hide column from user in MySQL table

I figured that this would be easy, but apparently (and to my frustration) it is not.
I have a user. We will say the user's name is 'user'. I simply want this user to NOT be able to see a column in my MySQL database.
I am using HeidiSQL. There seems to be no way to use the GUI to disallow users to see a column in a table. So I assumed that the following would work;
GRANT SELECT ON database_name.user TO 'user'#'%';
GRANT SELECT (column_name) ON database_name.table_name TO 'user'#'%';
REVOKE SELECT (column_name) ON database_name.table_name FROM 'user'#'%';
But it doesn't. Whenever I flush privileges and log in through the user, I still see the column that I do not want the user to see.
What is the algorithm for this, exactly? I'd like to assume this is possible.
Thanks in advance,
-Anthony
We can grant/revoke privileges at the column level as MySQL stores column privileges in the mysql.columns_priv table, and should be applied for single column in a table.
GRANT SELECT (col1), INSERT (col1,col2) ON dbname.tblname TO 'user'#'hostname';

Grant Privileges for TEMP Table(dynamically created by a Stored Proc)

List item Initially a TEMP table created by a Stored Procedure, which does some ACTIONS
There are these several TEMP tables thus created by this above said SP.
I want to give SELECT permission for some of my SQL Users for these TEMP tables which was dynamically created by the above SP's
For the above req, I tried the below query from a ROOT user to give permission for the table with the prefix temp
GRANT ALL PRIVILEGES ON dbname .`Temp%` TO 'TEST'#'%' WITH GRANT OPTION;
But, still the above privileges for the user 'TEST' can't able to SELECT these TEMP tables and gves the below err:
SELECT command denied to user 'TEST'#'localhost' for table
'temp_ccdata_20140904101131_2'
pls anyone suggest if there are any possibilities to grant SELECT access for the dynamic tables created by a Stored Procedure
THANKS IN ADVANCE
As stated by #wchiquito, the _ and % wilcards are permitted when specifying database names. A possible workaround for using wildcards in the table name of a GRANT query follows:
SELECT CONCAT('GRANT SELECT ON dbname.', TABLE_NAME, ' TO user;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'dbname' AND TABLE_NAME LIKE 'prefix%';
Replacing dbname with exampledb, user with tony42 and prefix with foo_ should return queries like:
GRANT SELECT ON exampledb.foo_usertable TO tony42
You can then use these execute these queries to achieve the permission changes you seek. It may not be the most elegant but will get the job done. Also, you may want to wrap the names in back ticks to account for spaces and such.

MySql: Hide certain tables from certain users

I want to hide certain tables (some definition tables) in the database from certain users. There is this mysql.tables_priv table which is empty. Should I insert something in that table to make it happen and what should be the value of 'table_priv' column?
You should be looking into the SQL GRANT command. With GRANT, you can assign privileges to users like this:
GRANT SELECT ON table TO user;
If the tables_priv is empty, i believe it means no privileges has been granted for that database table. You can do a quick test and grant select on database.table_name to user
and see if a row appears in that table. But normally your grants on tables appear in that table.