O MySQL 5.7 chega ao estágio de RC (release candidate). Isto significa que já está na hora de voce começar a pensar em aposentar o bom, e, nada velho MySQL 5.6.

Mas, antes de fazer a migração é interessante dar uma passeada pela nova maneira do MySQL organizar suas senhas. Para quem já está acostumado com o MySQL desde as longíquas versões 3 e 4, deverá notar algumas boas mudanças.

Algumas coisas sempre me incomodaram na parte de usuários e privilégios. Por exemplo, e se eu quiser conceder acesso a um determinado usuário (digamos um desenvolvedor temporário) ao meu banco de dados, por, apenas 90 dias. Não lembro  nem o que eu acabei de almoçar, como, lembraria depois de 90 dias, de “dropar” o usuário? Há, mas poderíamos criar um script… Não! Chega de ficarmos criando lixo em todo canto de nossos servidores. O MySQL tem que resolver isso! E resolveu, agora existe essa possibilidade e algumas outras.

Vamos visitar algumas mudanças que foram implementadas na estrutura de gerenciamento de usuários.

Para quem já é do ramo, irá estranhar, logo na partida, a forma de “inicializar” o datadir (diretório de dados) do MySQL. Até a versão 5.6, usa-se o script mysql_install_db para esta finalidade. A partir da versão 5.7 utiliza-se o próprio mysqld para tal finalidade. Através do execução

shell> mysqld —initialize

E uma doce novidade. Simplória, mas, útil. Lembre-se que nas versões 5.6 e anteriores teríamos, na inicialização do banco, o usuário root com senha em branco, e, o usuário anônimo, também sem senha alguma.

Agora, ao “inicializar” o datadir ganhamos de presente uma senha! Woo-hoo!!

A temporary password is generated for root@localhost: wnWdAjS9=yD%

Notem que a senha lhe concederá acesso ao banco de dados, como root, desde a máquina local (localhost). Já tá bom né 🙂

Vamos colocar a mão na massa e criar um usuário:

mysql> create user alexandre@localhost;

mysql> SELECT user, host, password_expired, password_last_changed, password_lifetime, account_locked, authentication_string FROM mysql.user WHERE user = ‘alexandre’\G

*************************** 1. row ***************************
user: alexandre
host: localhost
password_expired:
password_last_changed: 2015-05-20 20:09:21
password_lifetime:
account_locked: N
authentication_string:

As colunas <user> e <host> são nossos velhos conhecidos. Notem que armazenam o nome do usuário e o host no qual o acesso e privilégios tem efeito. Obviamente, falta uma coluna no meu SELECT. No entanto, já adianto que a coluna <password> não existe mais na tabela <mysql>.<user>. Ela sumiu. Aonde serão armazenadas as senhas? E agora? Nunca mais vou migrar? Calma Beth! Já explico!!

<password_expired> é um pássaro novo em nosso quintal. ‘Y’ para SIM, a senha está expirada, e, portanto, não concederá acesso ao usuário dono dela. ‘N’ ou ‘ ‘ para NÃO, a senha não está expirada, portanto, poderá ser usada para autenticar o usuário em questão.

<password_last_changed> algo como data e hora da última vez que esta senha foi alterada.

<password_lifetime> tempo de vida de uma senha, graduada em DIAS.

<account_lock> ‘Y’ para iiiih, conta bloqueada, não pode ser utilizada. ‘N’ ou ‘ ‘, para conta válida e disponível para uso.

<authentication_string> Eitcha nome “bunito”. Eis a coluna substituta para a coluna <password>. Agora com nome mais pomposo, mas, para a mesma finalidade de sua antecessora: armazenar a senha de login em formato criptografado.

 É possível criar uma política global de expiração de senhas, configurando-se a variável a seguir (no arquivo my.cnf ou my.ini):

[mysqld]
default_password_lifetime=180

Logicamente, que um “SET GLOBAL” ou “SET SESSION”, também, se aplicam.

Agora, vamos incrementar meu usuário “alexandre”, declarando que sua senha irá expirar em 10 dias:

mysql> ALTER USER ‘alexandre’@’localhost’ PASSWORD EXPIRE INTERVAL 10 DAY;

E vamos conferir, claro!!!

mysql> SELECT user, host, password_expired, password_last_changed, password_lifetime, account_locked, authentication_string FROM mysql.user WHERE user = ‘alexandre’\G

*************************** 1. row ***************************
user: alexandre
host: localhost
password_expired: N
password_last_changed: 2015-05-20 20:09:21
password_lifetime: 10
account_locked: N
authentication_string:

Notem que a coluna <authentication_string> continua sem preenchimento. Vamos preenche-la… Da maneira certa! Nada de ficar dando “UPDATE” nas tabelas do banco de dados <mysql> .

mysql> SET PASSWORD FOR alexandre@localhost = PASSWORD(‘VaiQueColaEstaSenha@@@’);

Query OK, 0 rows affected, 1 warning (0.00 sec)

Uooopa! Warning? Tá de “brincadiars” comigo! Sintaxe perfeita, senha boa, vamos ver o que houve:

mysql> SHOW WARNINGS;

Warning | 1287 | ‘SET PASSWORD FOR <user> = PASSWORD(‘<plaintext_password>’)’ is deprecated and will be removed in a future release. Please use SET PASSWORD FOR <user> = ‘<plaintext_password>’ instead

Ah… Tá… Não entendi nada! Quer dizer que a “funçãozinha” PASSWORD() não vale mais? Mais ou menos, digamos que com SET PASSWORD ela não é mais necessária, veja:

mysql> SET PASSWORD FOR alexandre@localhost = ‘VaiQueColaEstaSenha@@@’;

Query OK, 0 rows affected (0.00 sec)

Show de Bola! Mas será que o MySQL preencheu a coluna de forma correta? Vejamos:

mysql> SELECT user, host, password_expired, password_last_changed, password_lifetime, account_locked, authentication_string FROM mysql.user WHERE user = ‘alexandre’\G

*************************** 1. row ***************************
user: alexandre
host: localhost
password_expired: N
password_last_changed: 2015-05-20 20:15:14
password_lifetime: 10
account_locked: N
authentication_string: *70CCAFC73D595949FFC1425DF697124855ABDF5F

Notar que agora, além de preencher com a senha de forma correta (e sem a função PASSWORD()), também foi alterada a coluna da data de última alteração de senha.

Resumindo é isso. Mudança na estrutura da tabela <mysql>.<user>, retirando 1 coluna, acrescentando mais 5. Possibilidade de controlar a expiração de senhas, e, travamento de um usuário.

Veremos mais sobre as novidades do MySQL 5.7 em relação à gestão de usuários no próximo artigo.