MySQL: Explicit Hostname Vs Hostname with wildcard - mysql

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.

Related

MYSQL 5.7 - Can't give grants with wildcard grant option [duplicate]

Is it possible in MySQL to do a GRANT to a user on a set of tables within a database, e.g. to allow CREATE AND DROP ing of some table names but not others?
Neither of these seem to work:
GRANT SELECT ON `testdb`.`%_testing` TO 'wildcardtest'#'localhost';
GRANT SELECT ON `testdb`.`testing%` TO 'wildcardtest'#'localhost';
and the MySQL manual doesn't seem to give an answer either way.
The only wildcard that works in the GRANT statement is *
GRANT SELECT ON `testdb`.* TO 'user'#'localhost';
GRANT SELECT ON *.* TO 'privilegeduser'#'localhost';
It's all or one; there's no facility for dynamic matching of table names to granted privileges.
Nope. You can separate table names with commas but can't use wildcards in a GRANT.
Create a new empty database .
Give it access to the original database ( use a user who allready have access to original database )
in this new database
CREATE VIEW test as SELECT * from originaldatabase.tablename
WHERE conditions...
Then give test user access to NewDatabase whith
GRANT select on NewDatabase.* to 'testuser'#'localhost'
Then only create views for the tables you want testuser to access.
Also remember you can do a USER() in the WHERE part of the view:
example:
create view test as
select * from original.customer where mysql_user = USER()
In the original.customer you must then have a column 'mysql_user'
and every row the test user is allowed to see must have testuser#localhost as a entry
The testuser will see all the created views as tables in the database 'test'

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.

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.

How can I restrict a MySQL user to a particular tables

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.

Can wildcards be used on tablenames for a GRANT in MySQL

Is it possible in MySQL to do a GRANT to a user on a set of tables within a database, e.g. to allow CREATE AND DROP ing of some table names but not others?
Neither of these seem to work:
GRANT SELECT ON `testdb`.`%_testing` TO 'wildcardtest'#'localhost';
GRANT SELECT ON `testdb`.`testing%` TO 'wildcardtest'#'localhost';
and the MySQL manual doesn't seem to give an answer either way.
The only wildcard that works in the GRANT statement is *
GRANT SELECT ON `testdb`.* TO 'user'#'localhost';
GRANT SELECT ON *.* TO 'privilegeduser'#'localhost';
It's all or one; there's no facility for dynamic matching of table names to granted privileges.
Nope. You can separate table names with commas but can't use wildcards in a GRANT.
Create a new empty database .
Give it access to the original database ( use a user who allready have access to original database )
in this new database
CREATE VIEW test as SELECT * from originaldatabase.tablename
WHERE conditions...
Then give test user access to NewDatabase whith
GRANT select on NewDatabase.* to 'testuser'#'localhost'
Then only create views for the tables you want testuser to access.
Also remember you can do a USER() in the WHERE part of the view:
example:
create view test as
select * from original.customer where mysql_user = USER()
In the original.customer you must then have a column 'mysql_user'
and every row the test user is allowed to see must have testuser#localhost as a entry
The testuser will see all the created views as tables in the database 'test'