Para criar novos usuários no MySQL 5 sem utilizar uma ferramenta auxiliar como o phpMyAdmin é necessário conhecer o statement GRANT, mas somente isto não é suficiente, há pequenos detalhes que sempre atrapalham.
Neste artigo irei apresentar algumas boas práticas sobre a criação de usuários de banco de dados, a sintaxe do comando GRANT e também alguns comandos prontos para criação de alguns tipos diferentes de usuários.
Normalmente o que se vê nos blogs, nos artigos, inclusive nos exemplos e em muitos paineis administrativos é a utilização de apenas uma combinação de usuário e senha para toda a aplicação. Um grande erro!
Os usuários MySQL além de terem o "nome de usuário" são associados ao endereço de origem, então você verá estes usuários normalmente no formato 'nomedeusuario'@'endereçodeorigem'. Desta forma é possível que o usuário fulano tenha diferentes privilégios se estiver conectando no banco de dados através do endereço local (localhost) ou a partir de uma máquina externa.
Na prática podemos considerar ambos os usuários diferentes, inclusive no momento da criação você não pode indicar apenas o endereço de origem ou o nome de usuário, é necessário indicar as duas informações sempre.
O símbolo % é um caractere curinga que permite especificar parte de um endereço de origem ou até um usuário "que aceita todas as origens". Por exemplo o usuário 'fulano'@'192.168.0.%' pode conectar através de qualquer máquina na rede 192.168.0.0/24, o mesmo vale para nomes de máquinas desde que o servidor consiga resolver o nome do host de origem. O usuário 'fulano'@'%' poderia conectar a partir de qualquer endereço, inclusive da mesma máquina.
Se sua aplicação está no mesmo servidor que o banco de dados, para sua segurança, você deve criar um usuário com host de origem localhost para impedir que qualquer um que possuir o seu usuário e senha possa conectar de forma remota ao banco de dados.
Outra dica importante é sempre criar os usuários somente com os privilégios necessários, nada mais que isso. Não crie super usuários com privilégios de alterar a base e criar usuários a menos que sua aplicação necessite. Normalmente as aplicações apenas realizam consultas, inserções, atualizações e deleções, em alguns casos até evitando a última opção utilizando alguma técnica de softdelete. Tenha um usuário com muitos privilégios apenas para realizar as manutenções.
Observe que ao escrever o nome de usuário é conveniente envolver o nome de usuário e o endereço de origem com
'. Eles devem ser envolvidos separadamente, o@nunca deve estar dentro das aspas.
A sintaxe completa do statement GRANT pode ser vista aqui. A sintaxe simplificada é:
GRANT <privilégios> ON <banco de dados>.<tabela> TO '<usuario>'@'<origem>' IDENTIFIED BY '<senha>';
A definição de senha por IDENTIFIED BY '<senha>' é opcional, não sendo necessária se o usuário já existe.
Os privilégios, que podem ser definidos separados por vírgula no espaço indicado, são:
ALL Equivalente ao conjunto de todos os privilégios abaixo, sem contar o privilégio de GRANT
ALTER Permite alterar as tabelas e criar índices
ALTER ROUTINE Permite alterar as stored procedures
CREATE ROUTINE Permite criar novas stored procedures
EXECUTE Permite executar stored procedures
CREATE Permite criar tabelas e bancos de dados
CREATE TEMPORARY TABLES Permite criar tabelas temporárias
CREATE USER Permite criar, remover, alterar e inclusive remover os privilégios de usuários (não é possível conceder novos privilégios)
CREATE VIEW Permite criar e alterar views
DELETE Permite apagar linhas
DROP Permite apagar views, tabelas, e bancos de dados
EVENT Permite manipular os eventos
FILE Permite com que o usuário crie e leia arquivos armazenados no servidor do banco de dados
GRANT OPTION Permite remover e conceder privilégios aos usuários
INDEX Permite criar ou apagar índices
INSERT Permite inserir novas linhas no banco de dados
LOCK TABLES Permite bloquear tabelas onde o usuário possui permissão de leitura
PROCESS Concede permissões para ler a lista de processos executando no servidor
RELOAD Permite a utilização de comandos FLUSH
SELECT Concede permissão de leitura ao banco de dados ou tabelas
SHOW DATABASES Permite ler a lista de bancos no servidor
SHOW VIEW Permite ler a estrutura (query geradora) das views
SUPER Concede poderes administrativos avançados
TRIGGER Permite criar, alterar e apagar triggers
UPDATE Permite a atualização de linhas no banco de dados
USAGE É equivalente a nenhuma permissão
O comportamento e disponibilidade dos privilégios acima podem variar de acordo com a versão do MySQL. Eventos estão disponíveis apenas na versão 5.1 para cima, enquanto as triggers só podem ser editadas por usuários com super privilégios em versões inferiores a 5.0.
##Criando alguns usuários
Agora que já temos a sintaxe básica, vamos criar alguns usuários. No exemplo abaixo utilizarei além do GRANT o statement CREATE USER para criar os usuários. Isso deixa um pouco mais organizada a criação de usuários com privilégios diferentes em tabelas diferentes.
Para o exemplo abaixo pensamos na seguinte situação: criar o usuário DBA com permissões para realizar tudo em todas as tabelas do banco de dados, e dois usuários, FULANO com permissões para uma aplicação simples que está na mesma máquina e CICLANO que será utilizado para manutenção da base cujo FULANO irá ler as informações, chamada de BD01. Para complicar um pouco a história, o CICLANO só poderá acessar esta base através de uma aplicação que está na máquina de IP 192.168.0.45.
/* Criando o usuário DBA */
CREATE USER 'dba'@'%' IDENTIFIED BY 'senhaMuitoDificil';
GRANT ALL ON *.* TO 'dba'@'%' WITH GRANT OPTION;
/* Criando o usuário FULANO */
CREATE USER 'fulano'@'localhost' IDENTIFIED BY 'outraSenha';
GRANT SELECT,UPDATE,DELETE,INSERT ON BD01.* TO 'fulano'@'localhost';
/* Criando o usuário CICLANO */
CREATE USER 'ciclano'@'192.168.0.45' IDENTIFIED BY 'ehOutraSenha';
GRANT ALL ON BD01.* TO 'ciclano'@'192.168.0.45';
/* Recarregando as permissões na memória do servidor */
FLUSH PRIVILEGES;
Caso você altere as permissões de todos os usuários, inclusive do usuário ROOT e não consiga mais acessar o banco de dados, você pode iniciar o serviço com a opção
--skip-grant-tables, conectar com qualquer usuário e senha e executarUPDATE mysql.user SET Password=PASSWORD('NovaSenhaAqui') WHERE User='root';.
Note que com esta opção o serviço do MySQL vai ignorar qualquer privilégio e dará acesso total a todos que conectarem ao banco de dados, após trocar a senha reinicie o serviço sem o parâmetro o quanto antes por razões óbvias.
Note que o MySQL permite concedeer privilégios exclusivos a nível de coluna, porém quanto maior a quantidade de regras para definir privilégios maior o trabalho necessário para conferir se o usuário que está lendo a tabela possui permissões.