How to change a constant in mysql to a constant? - mysql

Within my mysql script,
I am creating a user as follows:
CREATE DATABASE fire;
after creating a table called Table1, privileges are changed
GRANT SELECT ON fire.Table1 TO 'user1'#'localhost';
In this case, fire is hardcoded, however, say in the future, I created a mysql database called called "ice" and I wanted to reuse the script above, but I want the below line to this time grant privileges for fire.TABLE1, but in this case, it is really "ice.TABLE1". How do I make mysql think that "fire" means some other variable without having to change "fire" to "ice" everywhere on my script?
GRANT SELECT ON fire.Table1 TO 'user1'#'localhost';

Do not include the database name in your grant scripts, but issue a use dbname statement to set the default database for your scripts to whatever database you want to work with.
As mysql manual on grant statement says:
If you use ON * syntax (rather than ON .), privileges are assigned at the database level for the default database. An error occurs if there is no default database.
So, your script would look like:
USE fire;
GRANT SELECT ON Table1 TO 'user1'#'localhost';

Related

Setting and Using Variables in MySQL scripts

MSSQL DBA here, I know how to do the following in TSQL, I am wondering if the same can be done in MySQL. Basically, set a variable and be able to use it throughout a script. MySQL docs have gotten me only so far, looking for some veteran MySQL devs/dbas for some detail. Thanks.
SET #newuser := `'usr652'#'%.domain.com'`;
SET #pw := `'ge?jJ!ARxbz$qiC6n'`;
CREATE USER #newuser IDENTIFIED BY #pw;
ALTER USER IF EXISTS
#newuser PASSWORD EXPIRE;
GRANT USAGE ON `POP%`.* TO #newuser;
GRANT SELECT ON `POP%`.* TO #newuser;
SHOW GRANTS FOR #newuser;

How to set table level privileges in 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.

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

Is there a way to effectively GRANT on either TRUNCATE or DROP TABLE in MySQL?

I recently tried this in MySQL 5.5.x:
GRANT
SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON crawler.*
TO 'my_user'#'localhost' WITH GRANT OPTION;
This results in an error:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'TRUNCATE ON crawler.*
TO 'my_user'#'localhost' WITH GRANT OPTION' at line 2
This used to work before I added TRUNCATE, so after a bit of research I find that this is not supported in MySQL.
The reason for this is that TRUNCATE is classified as a DDL operation, and so it doesn't use DELETE internally, it uses DROP. Alright, so I'd like to restrict this user to dropping tables (in the event of a security breach, at least a malicious user would have to determine the names of tables and drop them individually).
However, it turns out I would need to grant this user the DROP privilege, which allows the user to drop whole databases too. Given that there is not a grant for individual tables, is there another way to do this? I suppose I could hand this off to another process with a different user, but it feels a bit cumbersome for such a small issue.
For the time being, I'll stick with DELETE, even though it is rather slow! (On my laptop it takes ~55 sec to delete 1.6M small rows, and a fraction of a second to truncate the same). However, I am all ears if there is a faster and secure alternative.
To grant DROP privilege on a specific table in a specific database to a specific user in MySQL, you can use a GRANT statement like this. (This assumes that table fi exists in database fee, and this is the table you want to allow the user 'fo'#'%' to be able to TRUNCATE):
GRANT DROP ON TABLE fee.fi TO 'fo'#'%'
To see that the user has privilege to truncate that specific table:
SHOW GRANTS FOR 'fo'#'%' ;
And connect as user 'fo'#'%' to test:
TRUNCATE TABLE fee.fi ;
(Obviously, the user also has the privilege to DROP that same table. But that's just the way it is in MySQL.)
As an alternative, to allow the user to perform only the TRUNCATE operation on that specific table, without granting the user DROP privilege on the table...
create a stored procedure that performs a TRUNCATE fee.fi; (That will probably need to be executed dynamically since it's DDL.) The procedure will need to be created with DEFINER privileges, and created by a user that has the required privileges.
Then you can grant execute on the procedure to the user:
GRANT EXECUTE ON fee.truncate_table_fee_fi TO 'fo'#'%';
Then user 'fo'#'%' can
CALL fee.truncate_table_fee_fi

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.