É sempre uma dor de cabeça... você precisa adicionar uma nova função de usuário ou alterar alguns privilégios, e você precisa atribuir um... por... um. Este é um dever regular, especialmente em grandes organizações, ou em uma empresa onde você tem uma estrutura de privilégios complexa, ou mesmo se você precisa gerenciar um grande número de usuários de banco de dados.
Por exemplo, digamos que você precise adicionar o privilégio UPDATE a um banco de dados específico para toda a equipe de controle de qualidade, se for uma equipe de cinco não há problema, mas se forem 50... ou 100... ficar duro. Claro, você sempre pode escrever um script para isso, mas dessa forma sempre há risco.
Neste blog, veremos como podemos resolver esse problema de gerenciamento de usuários de banco de dados usando funções e com dicas específicas de como usá-las com o MariaDB.
O que é uma função?
No mundo do banco de dados, uma função é um grupo de privilégios que pode ser atribuído a um ou mais usuários, e um usuário pode ter uma ou mais funções atribuídas a ele. Para fazer uma comparação, é como um grupo no sistema operacional Linux.
Se virmos o exemplo anterior sobre o privilégio UPDATE na equipe de QA, se tivermos a função QA criada e todos os membros do QA tiverem essa função atribuída, não importa o número de membros, você só precisa alterar o privilégio nesta função de controle de qualidade e será propagado para todos os usuários de controle de qualidade.
Funções no MariaDB
Para gerenciar funções no MariaDB, você deve criar a função com a instrução CREATE ROLE, atribuir o privilégio a essa função com uma instrução GRANT e, em seguida, atribuir o privilégio ao usuário para poder usar essa função. Você também pode definir uma função padrão, para que o usuário a use ao se conectar.
Como usuário do banco de dados, você deve definir a função ao acessar o banco de dados (se não houver uma função padrão) e pode alterar a função, se necessário, com uma instrução SET ROLE.
Do lado do aplicativo, você deve poder definir a função (ou usar o padrão) antes de consultar para fazer isso funcionar, portanto, em aplicativos antigos, pode ser complexo de implementar.
Vamos ver algumas especificações para Roles no MariaDB.
- Somente uma função pode estar ativa ao mesmo tempo para o usuário atual.
- Desde o MariaDB 10.1, temos uma função padrão. Essa função é ativada automaticamente quando o usuário se conecta.
- Os papéis são armazenados na memória.
Como verificar as funções
No MariaDB existem várias maneiras de verificar:
- MOSTRAR GRANTS [ FOR (user | role) ]:Liste os grants para o usuário atual ou para um específico.
MariaDB [testing]> SHOW GRANTS for [email protected]'%'; +----------------------------------------------------------------------------------------------------------+ | Grants for [email protected]% | +----------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'testuser'@'%' IDENTIFIED BY PASSWORD '*FAAFFE644E901CFAFAEC7562415E5FAEC243B8B2' | +----------------------------------------------------------------------------------------------------------+ 1 row in set (0.000 sec)
- SELECT user FROM mysql.user WHERE is_role='Y':Lista os papéis criados no banco de dados.
MariaDB [testing]> SELECT user FROM mysql.user WHERE is_role='Y'; +--------+ | user | +--------+ | qateam | +--------+ 1 row in set (0.000 sec)
- SELECT * FROM information_schema.applicable_roles:é uma lista de funções disponíveis para o usuário atual.
MariaDB [testing]> SELECT * FROM information_schema.applicable_roles; +-------------+-----------+--------------+------------+ | GRANTEE | ROLE_NAME | IS_GRANTABLE | IS_DEFAULT | +-------------+-----------+--------------+------------+ | [email protected]% | qateam | NO | NO | +-------------+-----------+--------------+------------+ 1 row in set (0.000 sec)
- SELECT * FROM information_schema.enabled_roles:lista as funções ativas atuais.
MariaDB [testing]> SELECT * FROM information_schema.enabled_roles; +-----------+ | ROLE_NAME | +-----------+ | qateam | +-----------+ 1 row in set (0.000 sec)
- SELECT * FROM mysql.roles_mapping:Lista as relações entre papéis e concessões de usuário.
MariaDB [testing]> SELECT * FROM mysql.roles_mapping; +-----------+-----------+--------+--------------+ | Host | User | Role | Admin_option | +-----------+-----------+--------+--------------+ | localhost | root | qateam | Y | | % | testuser | qateam | N | +-----------+-----------+--------+--------------+ 2 rows in set (0.000 sec)
Como gerenciar funções no MariaDB
Vamos ver um exemplo de como gerenciá-lo no MariaDB. Neste caso, usaremos a versão MariaDB 10.3 rodando no CentOS 7.
Primeiro, vamos criar um novo usuário de banco de dados:
MariaDB [testing]> CREATE USER [email protected]'%' IDENTIFIED BY 'PASSWORD';
Se verificarmos as concessões para este novo usuário, veremos algo assim:
MariaDB [testing]> SHOW GRANTS for [email protected]'%';
+----------------------------------------------------------------------------------------------------------+
| Grants for [email protected]% |
+----------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'testuser'@'%' IDENTIFIED BY PASSWORD '*FAAFFE644E901CFAFAEC7562415E5FAEC243B8B2' |
+----------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
Agora, vamos tentar fazer o login com este usuário e conectar-se ao banco de dados de testes:
$ mysql -utestuser -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 54
Server version: 10.3.16-MariaDB-log MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> use testing
ERROR 1044 (42000): Access denied for user 'testuser'@'%' to database 'testing'
Como pudemos ver, não podemos nos conectar ao banco de testes com este usuário, então, agora, vamos criar um papel “qateam” com os privilégios e atribuir este papel a este novo usuário.
MariaDB [testing]> CREATE ROLE qateam;
Query OK, 0 rows affected (0.001 sec)
MariaDB [testing]> GRANT SELECT,INSERT,UPDATE,DELETE ON testing.* TO qateam;
Query OK, 0 rows affected (0.000 sec)
Se tentarmos usar essa função sem o GRANT, veremos o seguinte erro:
MariaDB [(none)]> SET ROLE qateam;
ERROR 1959 (OP000): Invalid role specification `qateam`
Então, agora vamos executar o GRANT para permitir que o usuário o use:
MariaDB [(none)]> GRANT qateam TO [email protected]'%';
Query OK, 0 rows affected (0.000 sec)
Defina a função para o usuário atual:
MariaDB [(none)]> SET ROLE qateam;
Query OK, 0 rows affected (0.000 sec)
E tente acessar o banco de dados:
MariaDB [(none)]> use testing;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [testing]>
Podemos verificar as concessões para o usuário atual:
MariaDB [(none)]> SHOW GRANTS for [email protected]'%';
+----------------------------------------------------------------------------------------------------------+
| Grants for [email protected]% |
+----------------------------------------------------------------------------------------------------------+
| GRANT qateam TO 'testuser'@'%' |
| GRANT USAGE ON *.* TO 'testuser'@'%' IDENTIFIED BY PASSWORD '*FAAFFE644E901CFAFAEC7562415E5FAEC243B8B2' |
+----------------------------------------------------------------------------------------------------------+
2 rows in set (0.000 sec)
E a função atual:
MariaDB [testing]> SELECT CURRENT_ROLE;
+--------------+
| CURRENT_ROLE |
+--------------+
| qateam |
+--------------+
1 row in set (0.000 sec)
Aqui podemos ver a concessão para o papel qateam, e pronto, não temos o privilégio atribuído diretamente ao usuário, temos os privilégios para o papel, e o usuário tira os privilégios de lá.
Conclusão
O gerenciamento de funções pode facilitar nossa vida em grandes empresas ou bancos de dados com grande número de usuários que o acessam. Se quisermos usá-lo em nosso aplicativo, devemos levar em consideração que o aplicativo também deve ser capaz de gerenciá-lo.