How to get the user ID from MySQL/Maria DB? - mysql

In PostgreSQL, for instance, the query SELECT * FROM pg_user return the usesysid column in which you can see the users IDs. So I can get the oldest/newest user from this table through this ID.
How can I do the same in Mysql and Maria DB?
I am surprised that there is no field that shows the creation date of each user in any driver.

Listing the users should be as simple as:
select * from mysql.user
Column user give you the user id. Combined with host, this is the unique identifier of each account.
Documentation for MariaDB.
Documentation for MySQL.
Please note, however, that MySQL / MariaDB do not track the date when users are created. A solution is to add a custom column to the users table that defaults to the current date:
ALTER TABLE mysql.users ADD date_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP;

Starting with MariaDB 10.4.1 the source for users and privileges is mysql.global_privs see MariaDB Docu.
Users, that are authorized by password have a property password_last_changed.
That's not the creation date you are looking for but can be a hint for the age of users entries, i.e.:
| localhost | phpmyadmin | {"access":0,"version_id":100515,"plugin":"mysql_native_password","authentication_string":"xxxx","password_last_changed":1660639196} |

Related

Show roles and privileges for all users in MySQL 8.0

I am trying to create a query that will show the users, their roles, and their privileges in MySQL 8.0.
Users are stored in mysql.user table.
Roles are also stored in mysql.user table but in order to identify them we filter the query like this: SELECT * FROM mysql.user WHERE host = '%'AND LENGTH(AUTHENTICATION_STRING) = 0 \G. By default roles are applied globally ('%') and they have no password
so the length would be 0 (We use strong password policy so there are
no users with no password).
The privileges, can be seen by the commands: SHOW GRANTS FOR 'username'#'hostname'; and by SELECT * FROM mysql.columns_priv, SELECT * FROM mysql.procs_priv, SELECT * FROM mysql.tables_priv tables.
I don't thing that I am missing other tables with information about the privileges, I just need to join all the data together. Has anyone tried something similar like this ? Is there a simpler way?
I am currently studying MySQL, I haven't professional experience so any help would be appreciated!

Mysql: How do I find all the users with ALTER permissions or any permissions?

I have lot of users in mysql db. How do I filter users based on a certain permission?
Like I need to find all users that have CREATE or ALTER permissions.
Mysql stores use privileges in the schema named mysql.
If you want to select users who have those privileges at global or database level,
the query you are looking for is:
SELECT user, host FROM mysql.user WHERE Alter_priv = 1 OR Create_priv = 1
UNION
SELECT user, host FROM mysql.db WHERE Alter_priv = 1 OR Create_priv = 1;
MySQL store all the privileges in mysql schema and there are various tables based on what kind of privileges you would want to look for. Below are tables in which different privileges are stored.
tables_priv
columnss_priv
procs_priv
You can have a look at what privileges you can find in each of these tables over here

How to see the create time of a MySql user?

How to see the create time of a MySql user?
I want to know the create time of a MySql user called "local".
Therefore, I have queried the mysql.user table, but that does not display the creation time for the user. Furthremore, there are no MySql logs in /var/log.
I need the information for doing forensics analysis on the system.
Is there any way to obtain the create time for MySql users?
You would query the information_schema for the create_time of the table.
For instance:
SELECT create_time FROM INFORMATION_SCHEMA.TABLES
WHERE table_schema = 'your_schema'
AND table_name = 'your_table'
Reference: http://dev.mysql.com/doc/refman/5.0/en/tables-table.html
If you want to get the user creation date then you can add a timestamp column in mysql.user table and set it to CURRENT_TIMESTAMP as default. So next time when a user is created, you will get the timestamp.

Does MySQL overwrite a column of same value on update?

When updating a table in MySQL, for example:
Table user
user_id | user_name
1 John
2 Joseph
3 Juan
If I run the query
UPDATE `user` SET user_name = 'John' WHERE user_id = 1
Will MySQL write the same value again or ignore it since it's the same content?
As the MySQL manual for the UPDATE statement implies,
If you set a column to the value it currently has, MySQL notices this
and does not update it.
So, if you run this query, MySQL will understand that the value you're trying to apply is the same as the current one for the specified column, and it won't write anything to the database.

Grant a user permission to only view a MySQL view and nothing else

This question was originally using MySQL 5.1.44, but is applicable to MySQL 8.0+ too.
Let's say I have a table with records inserted by different users of my application. How can I give a specific user access to only see his/her records in that table? I've thought about creating a VIEW with his/her records, but I don't know how to create a MySQL user that can only see that VIEW.
So, is it possible to create a MySQL user that only has access to a single VIEW? Can this user also be made so they read-only access to that VIEW?
Thanks!
PS: What I call users in my example are really subsidiary offices that want to access their records with their own applications.
GRANT SELECT ON database1.view1 TO 'someuser'#'somehost';
Besides
GRANT SELECT ON <database_name>.<view_name>
TO <user>#<host>
it's better to also do
GRANT SHOW VIEW
ON <database_name>.<view_name> TO <user>#<host>
so that a lot of SQL UI tool can get the view definition and work appropriately for the view.
I believe the original question is actually asking how to limit the rows to those owned by a given user. (The idea of creating one view per user, and then granting just that, seems like a workaround.)
You can do this by inserting the user() reference into the data table, and then filtering on that.
Using MySQL 5.6. Create a view that limits SELECT to just records owned by the current user:
-- check the current user
select user();
create table t1 (myId int, mydata varchar(200), myName varchar(200));
insert t1 select 1, 'my data yes', user();
insert t1 select 2, 'my data yes2', user();
insert t1 select 3, 'my data no', 'joe';
select * from t1;
create or replace view v1 AS
select * from t1 where myName = user();
select * from v1;
GRANT SELECT ON <database name>.<view name>
TO <user>#<host> IDENTIFIED BY '<password>'
Source: MySQL Documentation
If you want to make the view read only which I suspect you do. Then you should create the view with the ALGORITHM = TEMPTABLE clause.
This will make the view read only virtue of it having to create a temp table.
Another way to achieve read only and this is depends on your data is to stick an aggregate function. For example if you have a view which is based on a table and shows all columns then you can stick a distinct onto the select.