Quem mexe no dia a dia com hospedagem de sites sabe que até painéis consolidados como o cPanel têm seus momentos de falha. O cPanel usa um sistema de login único (Single Sign-On) para autenticar automaticamente as contas no phpMyAdmin. O problema começa quando o mapeamento interno do painel perde o sincronismo com as tabelas de permissões do MariaDB ou MySQL.
Recentemente passei exatamente por essa situação. Ao clicar no ícone do phpMyAdmin dentro de uma conta no cPanel, a tela retornou esta mensagem em vermelho:
mysqli_sql_exception: Access denied for user 'usuario'@'localhost' (using password: YES)
O phpMyAdmin tenta se conectar ao socket local usando as credenciais do usuário usuario, mas o motor do banco rejeita a conexão porque a senha não confere.
Abaixo mostro a investigação que fiz, os comandos que falharam no caminho e como redefinir a autenticação direto no banco para restaurar o acesso sem quebrar a conta.
1. O Sintoma e a Dessincronização entre cPanel, MariaDB e phpMyAdmin#
O cPanel gerencia bancos de dados relacionando o nome da conta do cliente aos seus respectivos bancos e usuários. Quando você entra no cPanel e clica em phpMyAdmin, o painel gera um token de acesso temporário e faz a ponte via socket local no localhost.
Se a senha registrada nas tabelas internas do cPanel diverge da senha gravada na tabela de usuários do MariaDB (mysql.user), o phpMyAdmin não consegue abrir. O usuário final fica bloqueado e você não consegue gerenciar tabelas nem rodar consultas pelo navegador.
2. Primeira Linha de Ação com Utilitários Nativos do cPanel#
A reação imediata ao lidar com cPanel é recorrer aos scripts nativos que o próprio painel disponibiliza para manutenção de contas.
Acessei o terminal do servidor como root para verificar a integridade da conta e dos privilégios:
[root@servidor ~]# /usr/local/cpanel/scripts/updateuserdomains
[root@servidor ~]# /scripts/whoowns meudominio.com.br
usuario
O domínio pertencia de fato ao usuário usuario. Em seguida, executei o script restoregrants para reconstruir todas as permissões de banco daquela conta:
[root@servidor ~]# /usr/local/cpanel/bin/restoregrants --cpuser=usuario --db=mysql --all
info [restoregrants] Updating grants for usuario
O comando retornou sucesso. Porém, reconstruir privilégios resolve apenas problemas de permissão (GRANT). Se o hash da senha estiver dessincronizado no banco, o erro de acesso negado persiste.
Tentei forçar a atualização de senhas da conta através do utilitário chpass:
[root@servidor ~]# ALLOW_PASSWORD_CHANGE=1 /usr/local/cpanel/scripts/chpass usuario SenhaSegura2026!
warn [realchpass] Insecure passing of password on ARGV.
Password for “usuario” has been changed.
O cPanel confirmou a troca da senha com a mensagem Password for “usuario” has been changed. Só que, ao testar novamente o acesso ao phpMyAdmin pela interface web, a mesma exceção continuou aparecendo na tela:
mysqli_sql_exception: Access denied for user 'usuario'@'localhost' (using password: YES)
Isolando a discrepância entre painel e banco de dados#
Para entender por que o painel afirmava ter trocado a senha enquanto o phpMyAdmin continuava bloqueado, precisei testar a conexão direta no terminal do MariaDB com a senha recém-definida:
[root@servidor ~]# mysql -u usuario -p'SenhaSegura2026!' -e "FLUSH PRIVILEGES;"
ERROR 1045 (28000): Access denied for user 'usuario'@'localhost' (using password: YES)
O MariaDB rejeitou imediatamente as credenciais.
Isso comprovou o ponto central da falha: o comando chpass do cPanel alterou apenas a senha de sistema do usuário Linux (autenticação PAM/shadow), mas falhou em propagar a nova senha para a tabela mysql.user do MariaDB. O painel assumiu que tudo estava certo, enquanto o banco permaneceu com o hash antigo ou corrompido.
3. Mapeamento de Bancos e Usuários via dbmaptool e Arquivos JSON#
Quem administra contas e servidores com cPanel sabe que a interface web às vezes deixa de mostrar bancos de dados ou perde o vínculo dos usuários com suas respectivas tabelas. Esse descompasso costuma acontecer após migrações manuais de contas, restaurações de backups interrompidos ou pequenas inconsistências entre o MariaDB e os metadados do painel.
Recentemente lidei com esse problema em uma conta grande (empresaweb) que mantinha mais de 150 bancos de dados ativos. Dois bancos específicos (empresaweb_turismo e empresaweb_basilica) sumiram da lista do painel, e seus respectivos usuários perderam o acesso às aplicações, gerando erros de conexão nos sites.
Abaixo documento por que o comando nativo do cPanel falhou nessa situação e como resolvi o problema no arquivo de metadados JSON usando substituições pontuais via linha de comando, sem colocar em risco os outros 150 bancos da conta.
A primeira reação ao notar bancos ausentes na interface do cPanel é tentar o utilitário nativo de mapeamento de banco de dados (dbmaptool), fornecido pela própria infraestrutura do painel.
Acessei o terminal do servidor como root e tentei vincular novamente o banco de dados e o usuário à conta correspondente:
[root@servidor ~]# /usr/local/cpanel/bin/dbmaptool empresaweb --type mysql --dbs empresaweb_turismo --dbusers empresaweb_turismo
O comando retornou imediatamente esta mensagem:
empresaweb_turismo is already owned by empresaweb
O dbmaptool apenas checou a titularidade primária do banco. Como o cPanel já reconhecia que o banco pertencia àquela conta raiz, ele abortou a rotina sem processar os argumentos secundários (o --dbusers). Com isso, o vínculo interno entre o usuário do banco e o esquema SQL continuou quebrado e invisível para o cliente no painel.
Estrutura interna do arquivo JSON de bancos do cPanel#
O cPanel não faz consultas diretas ao MariaDB toda vez que renderiza a interface web. Ele mantém o inventário de bancos, servidores e privilégios de cada conta em arquivos estruturados em formato JSON no diretório /var/cpanel/databases/.
Ao inspecionar o arquivo da conta:
cat /var/cpanel/databases/empresaweb.json
O conteúdo revelou exatamente o que estava quebrando o vínculo (abaixo mostro o trecho resumido focado nos bancos afetados):
{
"MYSQL": {
"owner": "empresaweb",
"server": "198.51.100.42",
"noprefix": {},
"dbs": {
"empresaweb_turismo": "198.51.100.42",
"empresaweb_basilica": "198.51.100.42"
},
"dbusers": {
"empresaweb_turismo": {
"server": "198.51.100.42",
"dbs": {}
},
"empresaweb_basilic": {
"server": "198.51.100.42",
"dbs": {
"empresaweb_basilica": "198.51.100.42"
}
}
}
},
"version": 1
}
Dois problemas claros apareceram na estrutura:
- Objeto de banco vazio no usuário de turismo: O banco existia no nó principal
"dbs", mas dentro do objeto"dbusers" -> "empresaweb_turismo", o bloco"dbs": {}estava completamente vazio. O cPanel sabia que o usuário existia, mas não sabia que ele tinha privilégio no banco correspondente. - Nome de usuário truncado pelo limite histórico de caracteres: O banco no MySQL chamava-se
empresaweb_basilica, mas o usuário de banco criado no cPanel havia sido truncado paraempresaweb_basilic(limite clássico de 16 caracteres em versões anteriores). O vínculo de privilégio interno precisava ser validado para evitar falhas na tabela visual de usuários privilegiados.
4. Correção Cirúrgica do Mapeamento JSON com sed em Contas Críticas#
Abrir um arquivo JSON com mais de 150 bancos de dados em um editor de texto interativo (como nano ou vim) em ambiente de produção é arriscado. Um parêntese ou vírgula fora do lugar invalida a sintaxe do JSON inteiro, corrompendo o painel de todos os outros sites daquela conta.
Para aplicar a alteração de forma cirúrgica e segura, usei o sed diretamente no arquivo.
Primeiro, criei uma cópia de segurança preventiva:
cp /var/cpanel/databases/empresaweb.json /var/cpanel/databases/empresaweb.json.bak
Em seguida, injetei o banco de dados dentro do objeto "dbs" do usuário de turismo:
sed -i 's/"empresaweb_turismo":{"server":"198.51.100.42","dbs":{}}/"empresaweb_turismo":{"server":"198.51.100.42","dbs":{"empresaweb_turismo":"198.51.100.42"}}/g' /var/cpanel/databases/empresaweb.json
Para o banco com o usuário truncado, reescrevi o bloco correspondente garantindo que o apontamento estivesse exato:
sed -i 's/"empresaweb_basilic":{"server":"198.51.100.42","dbs":{[^}]*}}/"empresaweb_basilic":{"server":"198.51.100.42","dbs":{"empresaweb_basilica":"198.51.100.42"}}/g' /var/cpanel/databases/empresaweb.json
Validei se a sintaxe do arquivo JSON continuava íntegra após as substituições:
python3 -m json.tool /var/cpanel/databases/empresaweb.json > /dev/null
echo $?
O retorno 0 confirmou que o JSON permaneceu válido e legível para os daemons do cPanel.
5. Intervenção Direta nas Tabelas de Privilégios do MariaDB#
Com a causa isolada, entrei diretamente no console do MariaDB como root para auditar os registros do usuário:
[root@servidor ~]# mysql
Dentro do monitor do MariaDB, consultei a tabela de usuários:
MariaDB [(none)]> SELECT User, Host, plugin FROM mysql.user WHERE User='usuario';
+---------+----------------------------+-----------------------+
| User | Host | plugin |
+---------+----------------------------+-----------------------+
| usuario | servidor.hospedagem.com | mysql_native_password |
| usuario | localhost | mysql_native_password |
| usuario | 198.51.100.42 | mysql_native_password |
+---------+----------------------------+-----------------------+
3 rows in set (0.002 sec)
A consulta revelou três linhas para o mesmo usuário: localhost, o IP público do servidor e o FQDN (servidor.hospedagem.com). Todos estavam utilizando o plugin padrão mysql_native_password.
O problema não era o método de autenticação, mas a inconsistência do hash de senha para as conexões locais. Como o phpMyAdmin se comunica estritamente através do localhost, apliquei a redefinição manual diretamente para este host:
MariaDB [(none)]> SET PASSWORD FOR 'usuario'@'localhost' = PASSWORD('SenhaSegura2026!');
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON `usuario\_%`.* TO 'usuario'@'localhost' WITH GRANT OPTION;
Query OK, 0 rows affected (0.005 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.072 sec)
MariaDB [(none)]> EXIT;
Se você tentar rodar o SET PASSWORD para o hostname completo e receber ERROR 1133 (28000): Can't find any matching row in the user table, não se preocupe. Muitas vezes há diferenças de formatação ou caracteres residuais no host cadastrado. Para o phpMyAdmin do cPanel funcionar, a linha crítica é usuario@localhost.
6. Invalidação de Cache, Sessões do phpMyAdmin e Checklist de Validação#
Depois de executar as queries e recarregar os privilégios com FLUSH PRIVILEGES, voltei ao terminal do Linux para validar se a conexão local funcionava com a senha definida:
[root@servidor ~]# mysql -u usuario -p'SenhaSegura2026!' -e "SHOW DATABASES;"
+--------------------+
| Database |
+--------------------+
| information_schema |
| usuario_dados |
| usuario_wp |
+--------------------+
O comando listou todos os bancos de dados da conta sem nenhum erro de acesso.
Com o banco de dados corrigido, restava apenas um obstáculo comum: o cache de sessão do navegador. O Single Sign-On do cPanel armazena tokens de autenticação temporários. Se você tentar simplesmente atualizar a página do phpMyAdmin que já estava aberta com erro, o navegador enviará o token antigo que foi invalidado durante as tentativas anteriores.
Para concluir o teste com sucesso:
- Feche as abas antigas do phpMyAdmin.
- Abra uma janela anônima no navegador (ou limpe os cookies de sessão do painel).
- Faça login novamente no cPanel com o usuário e a nova senha.
- Clique no ícone do phpMyAdmin.
O painel gerou um novo token, autenticou no MariaDB via localhost e abriu a interface completa de gerenciamento dos bancos sem qualquer aviso de erro.
Atualização de cache e reconstrução dos metadados de usuário#
Editar o arquivo .json no disco atualiza os dados persistidos, mas o cPanel armazena metadados em cache de memória para acelerar o carregamento da interface. Se você não invalidar esse cache, o painel continuará renderizando as tabelas antigas ou poderá sobrescrever o arquivo no próximo salvamento de formulário pelo usuário.
Para forçar a reconstrução imediata dos metadados da conta, executei o script nativo com a flag --force:
/usr/local/cpanel/scripts/updateuserdatacache --force empresaweb
Esse comando lê novamente a árvore em /var/cpanel/databases/, atualiza os índices locais e sincroniza as permissões de exibição do painel.
Checklist final de validação e cuidados operacionais#
Logo após a execução do updateuserdatacache, acessei a interface do cPanel na seção Bancos de dados MySQL:
- O banco
empresaweb_turismovoltou a figurar normalmente na lista de bancos ativos. - O banco
empresaweb_basilicarestabeleceu seu vínculo e exibição visual. - A coluna Usuários Privilegiados voltou a mostrar os respectivos usuários atribuídos a cada banco de dados, permitindo alterar senhas e privilégios normalmente pela web.
Para quem cuida de contas com dezenas ou centenas de bancos de dados, manipular o arquivo de metadados via scripts em lote ou comandos diretos como sed é muito mais rápido e seguro do que recriar conexões pela interface web, evitando downtime e retrabalho manual.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários