sql_accounts
NAME
sql_accounts: Generate SQL statements to block/release accounts. Provide info on accounts.TYPE
ViewDESCRIPTION
sql_accounts fills in a missing feature in MySQL: the ability to temporarily block user accounts and release them, without tampering with their privileges. It hacks its way by modifying and controlling accounts' passwords in a symmetric way.
To block an account, this view generates a SQL query which changes the account's password into a blocked-password value in such way that:
- It is impossible to log in to the account with the original password
- It is impossible to log in to the account with any other password
- It is possible to detect that the password is a blocked-password
- It is possible to recover the original password
In fact, the view provides metadata for each account to explain accounts status: is it blocked? Is it released? Is the password empty? Old?
By generating the SQL statement to modify the account this view fall well onto use of eval() (see examples below).
One should note that blocking accounts does not terminate existing account sessions. To kill existing sessions use the killall() routine.
STRUCTURE
mysql> DESC common_schema.sql_accounts; +---------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------------------+--------------+------+-----+---------+-------+ | user | char(16) | NO | | | | | host | char(60) | NO | | | | | grantee | varchar(100) | YES | | NULL | | | password | char(41) | NO | | | | | is_empty_password | int(1) | NO | | 0 | | | is_new_password | int(1) | NO | | 0 | | | is_old_password | int(1) | NO | | 0 | | | is_blocked | int(1) | NO | | 0 | | | sql_block_account | longtext | YES | | NULL | | | sql_release_account | varchar(163) | YES | | NULL | | +---------------------+--------------+------+-----+---------+-------+
SYNOPSIS
Columns of this view:
- user: account user part
- host: account host part
- grantee: grantee name
- password: current password for grantee (as in mysql.user)
- is_empty_password: boolean, 1 if account's password is empty, 0 otherwise.
- is_new_password: boolean, 1 if password is in new format, 0 otherwise.
- is_old_password: boolean, 1 if password is in old format, 0 otherwise.
This is the opposite of is_new_password.
The two columns are mostly informative. - is_blocked: boolean, 1 if account is currently blocked (by logic of this very view), 0 otherwise.
- sql_block_account:
A SQL (SET PASSWORD) query to block the account, making it inaccessible.
The query has no effect on an account which is already blocked.
Use with eval() to apply query. - sql_release_account:
A SQL (SET PASSWORD) query to release an account, re-enabling it.
The query has no effect on an account which is not blocked.
Use with eval() to apply query.
EXAMPLES
Show info for 'gromit'@'localhost' account:
mysql> SELECT * FROM sql_accounts WHERE USER = 'gromit' \G user: gromit host: localhost grantee: 'gromit'@'localhost' password: *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 is_empty_password: 0 is_new_password: 1 is_old_password: 0 is_blocked: 0 sql_block_account: SET PASSWORD FOR 'gromit'@'localhost' = '752AA50E562A6B40DE87DF0FA69FACADD908EA32*' sql_release_account: SET PASSWORD FOR 'gromit'@'localhost' = '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257'
Block all accounts with user 'gromit'. Show info again:
Note that account's password is modified. It is modified to a value accepted by MySQL, but which can never be generated by the PASSWORD() function. However, it is easily reversible.mysql> CALL eval("SELECT sql_block_account FROM sql_accounts WHERE USER = 'gromit'"); mysql> SELECT * FROM sql_accounts WHERE USER = 'gromit' \G user: gromit host: localhost grantee: 'gromit'@'localhost' password: 752AA50E562A6B40DE87DF0FA69FACADD908EA32* is_empty_password: 0 is_new_password: 1 is_old_password: 0 is_blocked: 1 sql_block_account: SET PASSWORD FOR 'gromit'@'localhost' = '752AA50E562A6B40DE87DF0FA69FACADD908EA32*' sql_release_account: SET PASSWORD FOR 'gromit'@'localhost' = '*23AE809DDACAF96AF0FD78ED04B6A265E05AA257'
Release all blocked accounts. Check:
mysql> CALL eval("SELECT sql_release_account FROM sql_accounts"); mysql> SELECT COUNT(*) AS count_blocked_accounts FROM sql_accounts WHERE is_blocked; +------------------------+ | count_blocked_accounts | +------------------------+ | 0 | +------------------------+