rds unable to grant role to a user using root user - mysql

I have a mysql rds instance, when you make the instance you declare a root user and a password.
I am then using terraform to create a new user and give the user a role. However i get the following error:
Error running SQL (GRANT 'test_role' TO 'test_user'#'%'): Error 1227: Access denied; you need (at least one of) the WITH ADMIN, ROLE_ADMIN, SUPER privilege(s) for this operation
Putting terraform aside, if i attempt to assign a role to a user with mysql directly. I get the same error
CREATE ROLE 'test_role';
GRANT SELECT, EXECUTE ON checkpoint_gg.* TO 'test_role';
CREATE USER 'test_user'#'%' IDENTIFIED BY 'password';
GRANT 'test_role' TO 'test_user'#'%';
SHOW GRANTS FOR 'root'#'%';
'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, PROCESS, REFERENCES, INDEX, ALTER, SHOW DATABASES, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE ROLE, DROP ROLE ON *.* TO `root`#`%` WITH GRANT OPTION'
'GRANT APPLICATION_PASSWORD_ADMIN,BACKUP_ADMIN,FLUSH_OPTIMIZER_COSTS,FLUSH_STATUS,FLUSH_TABLES,FLUSH_USER_RESOURCES,INNODB_REDO_LOG_ARCHIVE,PASSWORDLESS_USER_ADMIN,SHOW_ROUTINE ON *.* TO `root`#`%` WITH GRANT OPTION'
mysql 8

I contacted aws technical support and they managed to replicate the issue and suggest a solution.
aws technical support
since RDS is a managed service, to maintain the system integrity and
stability, super user privileges are not provided even to the master
user of the DB instance, and therefore, such error message is
expected, as the RDS MySQL master user by default does not have the
ADMIN, ROLE_ADMIN, SUPER privileges.
They suggested, interestingly enough the master/root user can assign those roles to itself.
GRANT ROLE_ADMIN on *.* to root;
Once it has that privilege we can then grant a role to a user
GRANT 'test_role' TO 'test_user'#'%';
I did not know the master root user (not rdsadmin) could give it self admin role, when itself is not an admin or does not have super privileges.

Please try to create rds cluster with master username other than root, it can be reserved username.
As mentioned in the error, your user does not have ADMIN, ROLE_ADMIN or SUPER permissions. Grant one of this permission.
Also make sure that you actually use #'%' user, not #'localhost'

Related

how to give super permission to (root) user in MYSQL, despite there being no super user?

I'm using MYSQL 8.0.25, running on WAMP server.
By mistake I changed user root's privilege by unchecked (insert) privilege and pressed (go), so the changes are assigned.
The problems are:
the super user (root) can't insert, see databases, create or do anything.
there is not another super user to give super permissions to (root) again or create super user like root
I can't create super user or return super permissions to (root) because there is no super user
I want to return all permissions to root again. What should I do?
could you help me
MySQL 8.0 Reference Manual / ... / How to Reset the Root Password
Perform generic operation described in "B.3.3.2.3 Resetting the Root Password: Generic Instructions". Instead of ALTER USER ... execute the next statements:
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE,
REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES,
LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW,
SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER,
CREATE TABLESPACE, CREATE ROLE, DROP ROLE
ON *.* TO `root`#`localhost` WITH GRANT OPTION;
GRANT APPLICATION_PASSWORD_ADMIN,AUDIT_ADMIN,BACKUP_ADMIN,BINLOG_ADMIN,
BINLOG_ENCRYPTION_ADMIN,CLONE_ADMIN,CONNECTION_ADMIN,ENCRYPTION_KEY_ADMIN,
FLUSH_OPTIMIZER_COSTS,FLUSH_STATUS,FLUSH_TABLES,FLUSH_USER_RESOURCES,
GROUP_REPLICATION_ADMIN,INNODB_REDO_LOG_ARCHIVE,INNODB_REDO_LOG_ENABLE,
PERSIST_RO_VARIABLES_ADMIN,REPLICATION_APPLIER,REPLICATION_SLAVE_ADMIN,
RESOURCE_GROUP_ADMIN,RESOURCE_GROUP_USER,ROLE_ADMIN,SERVICE_CONNECTION_ADMIN,
SET_USER_ID,SHOW_ROUTINE,SYSTEM_USER,SYSTEM_VARIABLES_ADMIN,
TABLE_ENCRYPTION_ADMIN,XA_RECOVER_ADMIN
ON *.* TO `root`#`localhost` WITH GRANT OPTION;
GRANT PROXY ON ''#'' TO 'root'#'localhost' WITH GRANT OPTION;

Access denied to database that I have access to

I am trying to grant privileges to another user using phpmyadmin, I have access to the root user (cl43-flexfit) and have tried querying the following
GRANT ALL PRIVILEGES ON `cl43-flexfit`.* TO 'supuser'#'localhost';
But receive a response of:
Access denied for user 'cl43-flexfit'#'%' to database 'cl43-flexfit'
Although I use that database with the cl43-flexfit user frequently.
I have also looked at what the root users privileges are using SHOW GRANT
and was shown these:
GRANT USAGE ON *.* TO 'cl43-flexfit'#'%' IDENTIFIED BY PASSWORD 'password'
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, TRIGGER ON `cl43-flexfit`.* TO 'cl43-flexfit'#'%' WITH GRANT OPTION
and even when I try to add permissions to the user for every database (replacing cl43-flexfit.* with * .*) I get an error saying I do not have permission
Access denied for user 'cl43-flexfit'#'%' (using password: YES)
I have been in contact with my hosting service and they have said that everything is correct on their end.
I also do not have access to the privileges tab in PHPMyAdmin and therefore can not use the GUI, it must be done through written commands.
Thanks in advance and apologise if I have a lack of understanding
You cannot GRANT ALL unless you also hold all privileges, along with GRANT OPTION, which you do not.
You have to grant explictly, and list only the permissions that you have (and want to grant).
You can't grant anything ON *.* unless you globally hold the privilege you are trying to grant, on all objects, plus GRANT OPTION. Again, you don't have this.
USAGE means only that you are allowed to log in to the server, nothing more. This is a special case of ON *.* carrying no significant meaning, because merely logging into the server is associated with no particular object.
The hosting service is correct.
If you have other users, you can make only explicit grants of listed permissions, using the format shown in your own SHOW GRANTS output.
GRANT SELECT, INSERT, [more...], TRIGGER ON `cl43-flexfit`.* TO 'my-other-existing-user'#'%';

Mysql Revoke permission for root user

I need to revoke permission for root user in mySql. root user should not be able to create and drop tables in the database.
I checked revoke command but somehow it is not working for root user. If I create a new user and revoke permission, it works, what am I missing for root user or we can't revoke permission for 'root'?
SHOW GRANTS FOR root#localhost;
--Displays
GRANT RELOAD, SHUTDOWN, PROCESS, FILE, SHOW DATABASES, SUPER, REPLICATION SLAVE, REPLICATION CLIENT, CREATE USER, CREATE TABLESPACE ON *.* TO 'root'#'localhost' IDENTIFIED BY PASSWORD '*7BB96B4D3E986612D96E53E62DBE9A38AAA40A5A'
GRANT INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `%`.* TO 'root'#'localhost' WITH GRANT OPTION
GRANT PROXY ON ''#'' TO 'root'#'localhost' WITH GRANT OPTION
Then
REVOKE all on myDb.* from root#'%';
FLUSH PRIVILEGES;
Access denied for user 'root'#'localhost' to database 'myDb'
I think, you don't want to do that. Root user is made that way to have all the privileges of all CRUD operations and creating new users and giving them privileges.
If your motive is to limit the access, make different users depending upon your need. For eg: you may only want to a user to read the records. That's a safe option because you may use that user only for reading purpose. OR just for read, write and edit privileges.
Edit:
If you still want to do this, check this answers How can I restore the MySQL root user’s full privileges? . It might help you.

MySQL permissions -- can't create functions even with the 'CREATE ROUTINE' grant

When connecting to my server (from a different machine) I get
Error Code: 1044 Access denied for user 'username'#'%' to database 'dbname'
when I try to create a function. But when I look at my permissions
SHOW GRANTS FOR CURRENT_USER;
I get
'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE ROUTINE ON *.* TO ''username''#''%'' IDENTIFIED BY PASSWORD ''--stripped--'' WITH GRANT OPTION'
In particular, this includes CREATE ROUTINE. Why can't I make a function? How can I change it so I can?
I think there is a CREATE FUNCTION that is separate from CREATE ROUTINE. But either way, since it looks like your user has 100% full access anyway you could do:
GRANT ALL PRIVILEGES ON *.* TO user#'%' INDENTIFIED BY 'password' WITH GRANT OPTION
However I would note it would be much better to set the '%' to 'localhost' and only access the database in this manner from a local machine (or at least a trusted IP). The lack of security with this could cause you trouble.
Definitely don't use this user/password to connect to the database from a web script!
Edit
I forgot: routines and functions have to be granted globally. Adding . tries to add the grant to the tables themselves which is why it doesn't work. Try:
GRANT ALTER ROUTINE,CREATE ROUTINE, EXECUTE ON * TO user#'%' IDENTIFIED BY 'password'
There's a longer description of it here: http://dev.mysql.com/doc/refman/5.0/en/grant.html

Why is a "GRANT USAGE" created the first time I grant a user privileges?

I'm new to the admin side of DBMS and was setting up a new database tonight (using MySQL) when I noticed this. After granting a user a privilege for the first time, another grant is created that looks like
GRANT USAGE on *.* TO user IDENTIFIED BY PASSWORD password
The documentation says that the USAGE privilege means "no privileges," so I'm inferring thats grants work hierarchically and perhaps a user must have some kind of privilege for all databases, so this serves as a catch all?
I also dont understand why this line has an IDENTIFIED BY clause in it when the grant I created does not have one (mostly because I dont understand what purpose the IDENTIFIED BY clause serves).
Edit: Sorry for not stating this originally, the grants were
GRANT ALL PRIVILEGES ON database.* TO admin_user
GRANT SELECT, INSERT, UPDATE, DELETE ON database.* TO user
As you said, in MySQL USAGE is synonymous with "no privileges". From the MySQL Reference Manual:
The USAGE privilege specifier stands for "no privileges." It is used at the global level with GRANT to modify account attributes such as resource limits or SSL characteristics without affecting existing account privileges.
USAGE is a way to tell MySQL that an account exists without conferring any real privileges to that account. They merely have permission to use the MySQL server, hence USAGE. It corresponds to a row in the `mysql`.`user` table with no privileges set.
The IDENTIFIED BY clause indicates that a password is set for that user. How do we know a user is who they say they are? They identify themselves by sending the correct password for their account.
A user's password is one of those global level account attributes that isn't tied to a specific database or table. It also lives in the `mysql`.`user` table. If the user does not have any other privileges ON *.*, they are granted USAGE ON *.* and their password hash is displayed there. This is often a side effect of a CREATE USER statement. When a user is created in that way, they initially have no privileges so they are merely granted USAGE.
I was trying to find the meaning of GRANT USAGE on *.* TO and found here. I can clarify that GRANT USAGE on *.* TO user IDENTIFIED BY PASSWORD password will be granted when you create the user with the following command (CREATE):
CREATE USER 'user'#'localhost' IDENTIFIED BY 'password';
When you grant privilege with GRANT, new privilege s will be added on top of it.
In addition mysql passwords when not using the IDENTIFIED BY clause, may be blank values, if non-blank, they may be encrypted. But yes USAGE is used to modify an account by granting simple resource limiters such as MAX_QUERIES_PER_HOUR, again this can be specified by also
using the WITH clause, in conjuction with GRANT USAGE(no privileges added) or GRANT ALL, you can also specify GRANT USAGE at the global level, database level, table level,etc....