XOOPS Brasil

 

4.3. Detalhes Gerais de Segurança e o Sistema de Privilégio de Acesso do MySQL

O MySQL tem um sistema de segurança/privilégios avançado mas não padrão. A próxima seção descreve como ele funciona.

4.3.1. Segurança Geral

Qualquer um usando o MySQL em um computador conectado à internet deve ler esta seção para evitar os erros de segurança mais comuns.

Discutindo segurança, nós enfatizamos a a necessidade de proteger completamente o servidor (não simplesmente o servidor MySQL) contra todos os tipos de ataques aplicáveis: eavesdropping, altering, playback e denial of service. Não cobriremos todos os aspectos de disponibilidade e tolerância a falhas aqui.

O MySQL utiliza a segurança baseado em Listas de Controle de Acesso (ACL) para todas conexões, consultas e outras operações que um utilizador pode tentar realizar. Existe também algum suporte para conexões criptografadasSSL entre clientes MySQL e servidores. Vários dos conceitos discutidos aqui não são específicos do MySQL; as mesmas idéias podem ser aplicadas para a maioria das aplicações.

Quando executando o MySQL, siga estes procedimentos sempre que possível:

  • nunca conceda a alguém (exceto ao utilizador root do mysql) acesso à tabela user no banco de dados mysql!. Isto é perigoso. A senha criptografada é a senha real no MySQL. Se você conhece a senha listada na tabela user para um determinado utilizador, você pode facilmente logar como este utilizador se tiver acesso à máquina relacionada para aquela conta.

  • Aprenda o sistema de controle de acessos do MySQL. Os comandos GRANT e REVOKE são usados para controlar o acesso ao MySQL. Não conceda mais privilégios do que o necessário. Nunca conceda privilégios para todas as máquinas.

    Checklist:

    • Tente mysql -u root. Se você conseguir conectar com sucesso ao servidor sem a solicitação de uma senha, você tem problemas. Qualquer um pode conectar ao seu servidor MySQL como o utilizador root com privilégios plenos! Revise as instruções de instalação do MySQL, prestando atenção particularmente ao item sobre configuração da senha do utilizador root.

    • Utilize o comando SHOW GRANTS e confira para ver quem tem acesso a o que. Remova aqueles privilégios que não são necessários utilizando o comando REVOKE.

  • Não mantenha nenhuma senha de texto puro no seu banco de dados. Quando seu computador fica comprometido, o intruso pode obter a lista completa de senhas e utilizá-las. Utilize a função MD5(), SHA1() ou qualquer função de embaralhamento de via única.

  • Não escolha senhas de dicionários. Existem programas especiais para quebrá-las. Mesmo senhas como ``xfish98'' não sao boas. Muito melhor seria ``duag98'' que contém a mesma palavra 'fish mas digitada uma letra a esquerda em um teclado QWERTY convencional. Outro método seria usar ``Mhall'' que é obtido dos primeiros caracteres de cada palavra na frase ``Mary has a litle lamb''. Isto é fácil de lembrar e digitar, mas dificulta que alguém que não a conheça a advinhe.

  • Invista em um firewall. Ele protege você de pelo menos 50% de todos os tipos de exploits em qualquer software. Coloque o MySQL atrás do firewall ou em uma zona desmilitarizada (DMZ).

    Checklist:

    • Tente examinar suas portas da Internet utilizando alguma ferramenta como o nmap. O MySQL utiliza a porta 3306 por padrão. Esta porta não deve ser acessível para máquinas não confiáveis. Outra maneira simples para conferir se sua porta do MySQL está aberta ou não é tentar o seguinte comando de alguma máquina remota, onde nome_máquina é o nome da máquina ou o endereço IP de seu servidor MySQL:

      shell> telnet nome_máquina 3306
      

      Se você obter uma conexão e alguns caracteres, a porta está aberta e deve ser fechada no seu firewall ou roteador, a menos que você realmente tenha uma boa razão para mantê-la aberta. Se o telnet apenas parar ou a conexão for recusada, tudo está bem; a porta está bloqueada.

  • Não confie em nenhum dado incluídos pelos seus utilizadores. Eles podem tentar enganar seu código entrando com caracteres especiais ou sequencias de escape nos formulários Web, URLS ou qualquer aplicação que você construa. Tenha certeza que sua aplicação continua segura se um utilizador entrar com algo do tipo ``; DROP DATABASE mysql;''. Este é um exemplo extremo, mas grandes falhas de segurança ou perda de dados podem ocorrer como o resultado de hackers utilizando técnicas similares, se você não estiver preparado para eles.

    Também lembre de conferir dados numéricos. Um erro comum é proteger somente as strings. Em alguns casos as pessoas pensam que se um banco de dados contém somente dados disponíveis publicamente, ele não precisa ser protegido. Isto não é verdade. No mínimo ataques do tipo denial-of-service podem ser feitos nestes bancos de dados. A maneira mais simples para proteger deste tipo de ataque é usar apóstrofos em torno das contantes numéricas: SELECT * FROM tabela WHERE ID='234' em vez de SELECT * FROM table WHERE ID=234. O MySQL automaticamente converte esta string para um número e corta todos os símbolos não-numéricos dela.

    Checklist:

    • Todas aplicações Web:

      • Tente inserir ‘'’ e ‘"’ em todos seus formulários Web. Se você obter qualquer tipo de erro do MySQL, investigue o problema imediatamente.

      • Tente modificar qualquer URL dinâmica adicionando %22 (‘"’), %23 (‘#’) e %27 (‘'’) na URL.

      • Tente modificar os tipos de dados nas URLs dinâmicas de numérico para caractere contendo caracteres dos exemplos anteriores. Sua aplicação deve ser segura contra estes ataques e similares.

      • Tente inserir caracteres, espaços e símbolos especiais no lugar de número nos campos numéricos. Sua aplicação deve removê-los antes de passá-los para o MySQL ou sua aplicação deve gerar um erro. Passar valores não verificados ao MySQL é extramente perigoso!

      • Confira o tamanho dos dados antes de passá-los ao MySQL.

      • Considere ter sua aplicação conectando ao banco de dados utilizando um utilizador diferente doq ue o que é utilizado com propósitos administrativos. Não forneça às suas aplicações mais privilégios de acesso do que elas necessitam.

    • Utilizadores do PHP:

      • Confira a função addslashes(). No PHP 4.0.3, uma função mysql_escape_string() está disponível e é baseada na função com o mesmo nome da API C do MySQL.

    • Utilizadores do API C do MySQL:

      • Confira a chamada API mysql_escape_string().

    • Utilizadores do MySQL:

      • Confira os modificadores escape e quote para consultas streams.

    • Utilizadores do Perl DBI:

      • Confira o método quote() ou utilize aspas simples ou duplas.

    • Utilizadores do Java JDBC:

      • Utilize um objeto PreparedStatement e aspas simples ou duplas.

  • Não transmita dados sem criptografia na Internet. Estes dados são acessíveis para todos que tenham o tempo e habilidade para interceptá-lo e usá-lo para seu propósito próprio. No lugar, utilize um protocolo de criptografia como o SSL ou SSH. O MySQL suporta conexões SSL interno desde a versão 3.23.9. O repasse de portas do SSH pode ser usado para criar um tunel criptografado (e com compressão) para a comunicação.

  • Aprenda a usar os utilitários tcpdump e strings. Para a maioria dos casos você pode conferir se o fluxo de dados do MySQL está ou não criptografado utilizando um comando parecido com este:

    shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
    

    (Isto funciona sobre Linux e deve funcionar com pequenas modificações sob outros sistemas.) Alerta: Se você não ver dados não significa sempre que esteja criptografado. Se você necessita de alta segurança, você deve consultar um especialista em segurança.

4.3.2. Como Tornar o MySQL Seguro contra Crackers

Quando você conectar a um servidor MySQL, você normalmente deve usar uma senha. A senha não é transmitida em texto puro sobre a conexão, porém o algorítimo de criptografica não é muito forte e com algum esforço um atacante engenhoso pode quebrar a senha se ele conseguir capturar o tráfego entre o cliente e o servidor. Se a conexão entre o cliente e o servidor passar por uma rede não confiável, você deve usar um tunnel SSH para criptografar a comunicação.

Todas outras informações são transferidas como texto que podem ser lido por qualquer um que consiga ver a conexão. Se você se preocupa com isto, você pode usar o protocol de compressão (No MySQL versão 3.22 e superiores) para tornar o tráfico muito mais dificil de decifrar. Para deixar tudo ainda mais seguro você deve usar ssh. Você pode encontrar um cliente ssh open source em http://www.openssh.org, e um cliente ssh comercial em http://www.ssh.com. Com isto, você pode obter uma conexão TCP/IP critografada entre um servidor MySQL e um cliente MySQL.

Se você estiver usando o MySQL 4.0, você também pode usar o suporte interno OpenSSL Veja mais informações sobre isto na Seção 4.4.10, “Usando Conexões Seguras”.

Para deixar um sistema MySQL seguro, você deve considerar as seguintes sugestões:

  • Utilize senhas para todos os utilizadores MySQL. Lembre-se que qualquer um pode logar como qualquer outra pessoa simplesmente com mysql -u outro_utilizador nome_bd se outro_utilizador não tiver senha. Isto é um procedimento comum com aplicações cliente/servidor que o cliente pode especificar qualquer nome de utilizador. Você pode alterar a senha de todos seus utilizadores editando o script mysql_install_db antes de executá-lo ou somente a senha para o utilizador root do MySQL desta forma:

    shell> mysql -u root mysql
    mysql> UPDATE user SET Password=PASSWORD('nova_senha')
    -> WHERE user='root';
    mysql> FLUSH PRIVILEGES;
    
  • Não execute o daemon do MySQL como o utilizador root do Unix. Isto é muito perigoso, porque qualquer utilizador com privilégios FILE estará apto a criar arquivos como o root (por exemplo, ~root/.bashrc). Para prevenir esta situação, mysqld irá recusar a execução como root a menos que ele seja especificado diretamente usando a opção --user=root.

    O mysqld pode ser executado como um utilizador normal sem privilégios. Você pode também criar um novo utilizador Unix mysql para tornar tudo mais seguro. Se você executar o mysqld como outro utilizador Unix, você não precisará alterar o utilizador root na tabela user, porque nomes de utilizador do MySQL não tem nada a ver com nomes de utilizadores Unix. Para iniciar o mysqld como outro utilizador Unix, adicione uma linha user que especifica o nome de utilizador para o grupo [mysqld] do arquivo de opções /etc/my.cnf ou o arquivo de opções my.cnf no diretório de dados do servidor. Por exemplo:

    [mysqld]
    user=mysql
    

    Estas opções configuram o servidor para iniciar como o utilizador designado quando você o inicia manualmente ou usando mysqld_safe ou mysql.server. Para maiores detalhes, veja Seção A.3.2, “Como Executar o MySQL Como Um Utilizador Normal”.

  • Não suportar links simbólicos para tabelas (Isto pode ser desabilitado com a opção --skip-symlink. Isto é muito importante caso você execute o mysqld como root, assim qualquer um que tenha acesso à escrita aos dados do diretório do mysqld podem apagar qualquer arquivo no sistema! Veja mais informações sobre isto na Seção 5.6.1.2, “Utilizando Links Simbólicos para Tabelas”.

  • Verfique se o utilizador Unix que executa o mysqld é o único utilizador com privilégios de leitura/escrita nos diretórios de bancos de dados.

  • Não forneça o privilégio PROCESS para todos os utilizadores. A saída de mysqladmin processlits mostra as consultas atualmente em execução, portanto qualquer utilizador que consiga executar este comando deve ser apto a ver se outro utilizador entra com uma consulta do tipo UPDATE user SET password=PASSWORD('não_seguro').

    O mysqld reserva uma conexão extra para utilizadores que tenham o privilégio process, portanto o utilizador root do MySQL pode logar e verificar a atividade do servidor mesmo se todas as conexões normais estiverem em uso.

  • Não conceda o privilégio FILE a todos os utilizadores. Qualquer utilizador que possua este privilégio pode gravar um arquivo em qualquer lugar no sistema de arquivos com os privilégios do daemon mysqld! Para tornar isto um pouco mais seguro, todos os arquivos gerados com SELECT ... INTO OUTFILE são lidos por todos, e não se pode sobrescrever arquivos existentes.

    O privilégio FILE pode também ser usado para ler qualquer arquivo acessível para o utilizador Unix com o qual o servidor está sendo executado. Pode ocorrer abusos como, por exemplo, usar LOAD DATA para carregar o arquivo /etc/passwd em uma tabela, que pode então ser lido com SELECT.

  • Se você não confia em seu DNS, você deve utilizar números IP no lugar de nomes de máquinas nas tabelas de permissão. De qualquer forma, você deve ter muito cuidado ao criar entradas de concessão utilizando valores de nomes de máquinas que contenham metacaractes!

  • Se você deseja restrigir o número de conexões para um único utilizador, você pode faze-lo configurando a variável max_user_connections no mysqld.

4.3.3. Opções de Inicialização para o mysqld em Relação a Segurança.

As seguintes opções do mysqld afetam a segurança:

  • --local-infile[=(0|1)]

    Se alguém usa --local-infile=0 então não de pode usar LOAD DATA LOCAL INFILE.

  • --safe-show-database

    Com esta opção, SHOW DATABASES retorna somente os bancos de dados nos quais o utilizador tem algum tipo de privilégio. A partir da versão 4.0.2 esta opção está obsoleta e não faz nada (a opção está habilitada por padrão) já que agora temos o privilégio SHOW DATABASES. Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

  • --safe-user-create

    Se for habilitado, um utilizador não consegue criar novos utilizadores com o comando GRANT, se o utilizador não tiver privilégio de INSERT na tabela mysql.user. Se você desejar fornecer a um utilizador acesso para só criar novos utilizadores com privilégios que o utilizador tenha direito a conceder, você deve dar ao utilizador o seguinte privilégio:

    mysql> GRANT INSERT(user) ON mysql.user TO 'user'@'hostname';
    

    Isto irá assegurar que o utilizador não poderá alterar nenhuma coluna de privilégios diretamente, mas tem que usar o comando GRANT para conceder direitos para outros utilizadores.

  • --skip-grant-tables

    Esta opção desabilita no servidor o uso do sistema de privilégios. Isto dá a todos os utilizadores acesso total a todos os bancos de dados! (Você pode dizer a um servidor em execução para para uar as tabelas de permissões executando mysqladmin flush-privileges ou mysqladmin reload.)

  • --skip-name-resolve

    Nomes de máquinas não são resolvidos. Todos os valores da coluna Host nas tabelas de permissões devem ser números IP ou localhost.

  • --skip-networking

    Não permitir conexões TCP/IP sobre a rede. Todas as conexões para mysqld devem ser feitas via Sockets Unix. Esta opção não é possível em sistemas que usam MIT-pthreads, porque o pacote MIT-pthreads não suporta sockets Unix.

  • --skip-show-database

    Não permite o comando SHOW DATABASES, a menos que o utilizador tenha o privilégio SHOW DATABASES. A partie da versão 4.0.2 você não deve mais precisar desta opção, já que o aceesso pode agora ser concedido especificamente com o privilégio SHOW DATABASES.

4.3.4. Detalhes de Segurança com LOAD DATA LOCAL

No MySQL 3.23.49 e MySQL 4.0.2 (4.0.13 no Windows), adicionamos algumas novas opções para lidar com possíveis detalhes de segurança junto ao LOAD DATA LOCAL.

Exstem dois problemas possíveis com o suporte a este comando:

Como a leitura deste arquivo é iniciada por um servidor, pode-se teoricamente criar um servidor MySQL corrigido que poderia ler qualquer arquivo na máquina cliente na qual o utilizador atual tenha acesso, quando o cliente envia uma consulta a tabela.

Em um ambiente web onde os clientes estão conectados a um servidor web, um utilizador poderia usar LOAD DATA LOCAL para ler qualquer arquivo no qual o processo do servidor web tenha acesso de leitura (assumindo que um utilizador poderia executar qualquer comando no servidor SQL).

Existem dois arquivos separados para isto:

Se você não configurar o MySQL com --enable-local-infile, então LOAD DATA LOCAL será disabilitado por todos os clientes, a menos que se chame mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0) no cliente. Veja mais informações sobre isto na Seção 12.1.3.40, “mysql_options().

Para o cliente de linha de comando mysql, LOAD DATA LOCAL pode ser habilitado especificado a opção --local-infile[=1], ou disabilitando com --local-infile=0.

Por padrão, todos os clientes e bibliotacas MySQL são compilados com --enable-local-infile, para ser compatível com o MySQL 3.23.48 e anterior.

Pode se desabilitar todos os comandos LOAD DATA LOCAL no servidor MySQL iniciando o mysqld com --local-infile=0.

No caso em que LOAD DATA LOCAL INFILE está disabilitado no servidor ou no cliente, você receberá a seguinte mensagem de erro (1148):

The used command is not allowed with this MySQL version

4.3.5. O Que o Sistema de Privilégios Faz

A função primária do sistema de privilégios do MySQL é autenticar um utilizador a partir de uma determinada máquina e associar este utilizador com privilégios a banco de dados como como select, insert, update e delete.

Funcionalidades adicionais incluem a habilidade de ter um utilizador anônimo e conceder privilégio para funções específicas do MySQL como em LOAD DATA INFILE e operações administrativas.

4.3.6. Como o Sistema de Privilégios Funciona

O sistema de privilégios do MySQL garante que todos utilizadores possam fazer exatamente as operações que lhe é permitido. Quando você conecta a um servidor MySQL, sua identidade é determinada pela maquina de onde você conectou e o nome de utilizador que você especificou. O sistema concede privilégios de acordo com sua identidade e com o que você deseja fazer.

O MySQL considera tanto os nomes de máquinas como os nomes de utilizadores porque existem poucas razões para assumir que um determinado nome de utilizador pertence a mesma pessoa em todo lugar na Internet. Por exemplo, o utilizador bill que conecta de whitehouse.gov não deve necessariamente ser a mesma pessoa que o utilizador bill que conecta da microsoft.com O MySQL lida com isto, permitindo a distinção de utilizadores em diferentes máquinas que podem ter o mesmo nome: Você pode conceder a bill um conjunto de privilégios para conexões de whitehouse.gov e um conjunto diferente de privilégios para conexões de microsoft.com.

O controle de acesso do MySQL é composto de dois estágios:

  • Estágio 1: O servidor confere se você pode ter acesso ou não.

  • Estágio 2: Assumindo que você pode conectar, o servidor verifica cada requisição feita para saber se você tem ou não privilégios suficientes para realizar a operação. Por exemplo, se você tentar selecionar linha de uma tabela em um banco de dados ou apagar uma tabela do banco de dados, o servidor se certifica que você tem o privilégio select para a tabela ou o privilégio drop para o banco de dados.

Note que se os seus privilégios são alterados (tanto por você quanto por outro) enquanto você está conectado, estas alterações não irão necessariamente ter efeito com a sus próxima consulta ou consultas. Veja Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito” para maiores detalhes.

O servidor utiliza as tabelas user, db e host no banco de dados mysql em ambos estágios do controle de acesso. Os campos nestas tabelas de permissão são detalhados abaixo:

Nome da Tabelauserdbhost
Campos de EscopoHostHostHost
 UserDbDb
 PasswordUser 
Campos de PrivilégioSelect_privSelect_privSelect_priv
 Insert_privInsert_privInsert_priv
 Update_privUpdate_privUpdate_priv
 Delete_privDelete_privDelete_priv
 Index_privIndex_privIndex_priv
 Alter_privAlter_privAlter_priv
 Create_privCreate_privCreate_priv
 Drop_privDrop_privDrop_priv
 Grant_privGrant_privGrant_priv
 References_privReferences_privReferences_priv
 Reload_priv  
 Shutdown_priv  
 Process_priv  
 File_priv  
 Show_db_priv  
 Super_priv  
 Create_tmp_table_privCreate_tmp_table_privCreate_tmp_table_priv
 Lock_tables_privLock_tables_privLock_tables_priv
 Execute_priv  
 Repl_slave_priv  
 Repl_client_priv  
 ssl_type  
 ssl_cypher  
 x509_issuer  
 x509_cubject  
 max_questions  
 max_updates  
 max_connections  

No segundo estágio do controle de acesso (verificação da solicitação), o servidor pode, se a solicitação involver tabelas, consultar adicionalmente as tabelas tables_priv e columns_priv. Os campos nestas tabelas são mostrados abaixo:

Nome da tabelatables_privcolumns_priv
Campos de escopopHostHost
 DbDb
 UserUser
 Table_nameTable_name
  Column_name
Campos de privilégioTable_privColumn_priv
 Column_priv 
Outros camposTimestampTimestamp
 Grantor 

Cada tabela de permissões contêm campos de escopo e campos de privilégios.

Campos de escopo determinam o escopo de cada entrada nas tabelas, isto é, o contexto no qual a entrada se aplica. Por exemplo, uma entrada na tabela user com valores Host e User de 'thomas.loc.gov' e 'bob' devem ser usados para autenticar conexões feitas ao servidor por bob da máquina thomas.loc.gov. De maneira similar, uma entrada na tabela db com campos Host, User e Db de 'thomas.loc.gov', 'bob' e 'reports' devem ser usados quando bob conecta da máquina thomas.loc.gov para acessar o banco de dados reports. As tabelas tables_priv e columns_priv contem campos de escopo indicando as combinações de tabelas ou tabela/coluna para o qual cada entrada se aplica.

Para propósitos de verificação de acessos, comparações de valores Host são caso insensitivo, valores User, Password, Db e Table_name são caso sensitivo. Valores Column_name são caso insensitivo no MySQL versão 3.22.12 ou posterior.

Campos de privilégios indicam os privilégios concedidos por uma entrada na tabela, isto é, quais operações podem ser realizadas. O servidor combina as informações de várias tabelas de concessão para formar uma descrição completa dos privilégios de um utilizador. As regras usadas para fazer isto são descritas em Seção 4.3.10, “Controle de Acesso, Estágio 2: Verificação da Requisição”.

Campos de escopo são strings, declaradas como mostrado abaixo; os valores padrão para cada é a string vazia:

Nome do CampoTipo 
HostCHAR(60) 
UserCHAR(16) 
PasswordCHAR(16) 
DbCHAR(64)(CHAR(60) para as tabelas tables_priv e columns_priv)
Table_nameCHAR(60) 
Column_nameCHAR(60) 

Nas tabelas user, db e host, todos campos de privilégios são declarados como ENUM('N','Y') --- cada um pode ter um valor de 'N' ou 'Y' e o valor padrão é 'N'.

Nas tabelas tables_ e columns_priv, os campos de privilégios são declarados como campos SET:

Nome de tabelaNome do campoPossíveis elementos do conjunto
tables_privTable_priv'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'
tables_privColumn_priv'Select', 'Insert', 'Update', 'References'
columns_privColumn_priv'Select', 'Insert', 'Update', 'References'

De maneira resumida, o servidor utiliza as tabelas de permissões desta forma:

  • Os campos de escopo da tabela user determinam quando permitir ou aceitar conexões. Para conexões permitidas, qualquer privilégio concedido em uma tabela user indica o privilégio global (superutilizador) do utilizador. Estes privilégios se aplicam a todos os bancos de dados no servidor.

  • As tabelas db e host são usadas juntas:

    • Os campos de escopo da tabela db determinam quais utilizadores podem acessar determinados bancos de dados de máquinas determinadas. Os campos de privilégios determinam quais operações são permitidas.

    • A tabela host é usada como uma extensão da tabela db quando você quer que uma certa entrada na tabela db seja aplicada a diversas máquinas. Por exemplo, se você deseja que um utilizador esteja apto a usar um banco de dados a partir de diversas máquinas em sua rede, deixe o campo Host vazio no registro da tabela db, então popule a tabela Host com uma entrada para cada uma das máquinas. Este mecanismo é descrito com mais detalhes em Seção 4.3.10, “Controle de Acesso, Estágio 2: Verificação da Requisição”.

  • As tabelas tables_priv e columns_priv são similares à tabela db, porém são mais finas: Elas se aplicam ao nível de tabelas e colunas em vez do nível dos bancos de dados.

Perceba que os privilégios administrativos (RELOAD, SHUTDOWN e etc) são especificados somente na tabela user. Isto ocorre porque operações administrativas são operações no próprio servidor e não são específicas e não específicas dos bancos de dados, portanto não existe razão para listar tais privilégios nas outras tabelas de permissão. De fato, somente a tabela user necessita ser consultada para determinar se você pode ou não realizar uma operação administrativa.

O privilégio FILE também só é especificado na tabela user. Ele não é um privilégio administrativo, mas sua habilidade para ler ou escrever arquivo no servidor é independtende do banco de dados que você está acessando.

O servidor mysqld le o conteúdo das tabelas de permissões uma vez, quando é iniciado. Alterações nas tabelas de permissões tem efeito como indicado em Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito”.

Quando você modifica o conteúdo das tabelas de permissões, é uma boa idéia ter certeza que suas alterações configuraram os privilégios da forma desejada. Para ajuda no diagnostico de problemas, veja Seção 4.3.12, “Causas dos Erros de Accesso Negado. Para conselhos sobre asssuntos de segurança, Veja mais informações sobre isto na Seção 4.3.2, “Como Tornar o MySQL Seguro contra Crackers”.

Uma ferramenta de diagnóstico útil é o script mysqlaccess, que Yves Carlier fornece na distribuição MySQL. Chame mysqlaccess com a opção --help para descobrir como ele funciona. Perceba que o mysqlaccess confere o acesso usando somente as tabelas user, db e host. Ele não confere privilégios no nível de tabelas ou colunas.

4.3.7. Privilégios Fornecidos pelo MySQL

Informações sobre privilégios de utilizadores são armazenados nas tabelas user, db, host, tables_priv e columns_priv no banco de dados chamado mysql. O servidor MySQL lê o conteúdo destas tabelas quando ele inicia e sob as circunstâncias indicadas em Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito”.

Os nomes usados neste manual que se referem-se aos privilégios fornecidos pelo MySQL são vistos abaixo juntos com o nome da coluna associada com cada privilégio nas tabelas de permissão e o contexto em que o privilégio se aplica. Informações adicionais sobre o significado de cada privilégio pode ser encontrado em Seção 4.4.1, “A Sintaxe de GRANT e REVOKE.

PrivilégioColunaContexto
ALTERAlter_privtabelas
DELETEDelete_privtabelas
INDEXIndex_privtabelas
INSERTInsert_privtabelas
SELECTSelect_privtabelas
UPDATEUpdate_privtabelas
CREATECreate_privbanco de dados, tabelas, ou índices
DROPDrop_privbanco de dados ou tabelas
GRANTGrant_privbanco de dados ou tabelas
REFERENCESReferences_privbanco de dados ou tabelas
CREATE TEMPORARY TABLESCreate_tmp_tabela_privadministração do servidor
EXECUTEExecute_privadministração do servidor
FILEFile_privacessa a arquivos no servidor
LOCK TABLESLock_tabelas_privadministração do servidor
PROCESSProcess_privadministração do servidor
RELOADReload_privadministração do servidor
REPLICATION CLIENTRepl_client_privadministração do servidor
REPLICATION SLAVERepl_slave_privadministração do servidor
SHOW DATABASESShow_db_privadministração do servidor
SHUTDOWNShutdown_privadministração do servidor
SUPERSuper_privadministração do servidor

Os priviláegios SELECT, INSERT, UPDATE e DELETE permitem realizar operações em registros nas tabelas existentes em um banco de dados.

Instruções SELECT necessitam do privilégio select somente se ele precisar recuperar registros de uma tabela. Você pode executar certas instruções SELECT mesmo sem permissão para acessar algum dos bancos de dados no servidor. Por exemplo, você pode usar o cliente mysql como uma simples calculadora:

mysql> SELECT 1+1;
mysql> SELECT PI()*2;

O privilégio INDEX permite a criação ou remoção de índices.

O privilégio ALTER permite utilizar ALTER TABLE.

Os privilégios CREATE e DROP permitem a criação de novos bancos de dados e tabelas, ou a remoção de bancos de dados e tabelas existentes.

Perceba que se for concedido o privilégio DROP no banco de dados mysql para algum utilizador, este utilizador pode remover o banco de dados no qual os privilégios de acesso do MySQL estão armazenados!

O privilégio GRANT permite a você fornecer a outros utilizadores os privilégios que você mesmo possui.

O privilégio FILE fornece permissão para ler e escrever arquivos no servidor usando instruções LOAD DATA INFILE e SELECT ... INTO OUTFILE. Qualquer utilizador que tenha este privilégio pode ler ou gravar qualquer arquivo que o servidor MySQL possa ler ou escrever. O utilizador também pode ler qualquer arquivo no diretório de banco de dados atual. O utilizador não pode, no entanto, alterar qualquer arquivo existente.

Os privilégios restantes são usados para operações administrativas, que são realizadas utilizando o programa mysqladmin. A tabela abaixo mostra quais comandos do mysqladmin cada privilégio administrativos permite a execução:

PrivilégioComandos permitidos
RELOADreload, refresh, flush-privileges, flush-hosts, flush-logs, and flush-tables
SHUTDOWNshutdown
PROCESSprocesslist
SUPERkill

O comando reload diz ao servidor para recarregar as tabelas de permissões. O comando refresh descarrega todas as tabelas e abre e fecha os arquivos de log. flush-privileges é um sinônimo para reload. Os outros comandos flush-* realizam funções similares ao refresh mas são mais limitados no escopo e podem ser preferíveis em alguns casos. Por exemplo, se você deseja descarregar apenas os arquivos log, flush-logs é uma melhor escolha do que refresh.

O comando shutdown desliga o servidor.

O comando processlist mostra informações sobre as threads em execução no servidor. O comando kill mata threads no servidor. Você sempre poderá mostrar ou matar suas próprias threads, mas você precisa do privilégio PROCESS para mostrar e privilégio SUPER para matar threads iniciadas por outros utilizadores. Veja mais informações sobre isto na Seção 4.6.7, “Sintaxe de KILL.

É uma boa idéia em geral conceder privilégios somente para aqueles utilizadores que necessitem deles, mas você deve ter muito cuidado ao conceder certos privilégios:

  • O privilégio grant permite aos utilizadores repassarem seus privilégios a outros utilizadores. Dois utilizadores com diferentes privilégios e com o privilégio grant conseguem combinar seus privilégios.

  • O privilégio alter pode ser usado para subverter o sistema de privilégios renomeando as tabelas.

  • O privilégio FILE pode ser usado com abuso para ler qualquer arquivo de leitura no servidor em uma tabela de banco de dados, o conteúdo pode ser acessando utilizando SELECT. Isto inclui o conteúdo de todos os bancos de dados hospedados pelo servidor!

  • O privilégio SHUTDOWN pode ser utilizado para negar inteiramente serviços para oturos utilizadores, terminando o servidor.

  • O privilégio PROCESS pode ser usado para ver o texto das consultas atualmente em execução, incluindo as consultas que configuram ou alteram senhas.

  • Privilégios no banco de dados mysql pode ser utilizado para alterar senhas e outras informações de privilégio de acesso. (Senhas são armazenadas criptografadas, portanto um utilizador malicioso não pode simplesmente lê-las para saber as senhas em texto puro). Se fosse possível acessar a coluna password do banco mysql.user, seria possível logar ao servidor MySQL como outro utilizador. (Com privilégios suficientes, o mesmo utilizador pode trocar a senha por outra diferente.)

Existema algumas coisas que você não pode fazer com o sistem de privilégios do MySQL:

  • Você não pode especificar explicitamente que um determinado utilizador deve ter acesso negado. Você não pode explicitamente comparar um utilizador e depois recusar sua conexão.

  • Você não pode especificar que um utilizador tenha privilégios para criar ou remover tabelas em um banco de dados, mas não possa criar ou remover o banco de dados.

4.3.8. Conectando ao Servidor MySQL

Programas clientes do MySQL geralmente necessitam de parâmetros de conexão quando você precisar acessar um servidor MySQL: a máquina na qual você deseja se conectar, seu nome de utilizador e sua senha. Por exemplo, o cliente mysql pode ser iniciado desta forma (argumentos opcionais são colocandos entre ‘[’ e ‘]’):

shell> mysql [-h nome_máquina] [-u nome_utilizador] [-psua_senha]

Formas alternativas das opções -h, -u e -p são --host=nome_máquina, --user=nome_utilizador e --password=sua_senha. Perceba que não existe espaço entre -p ou --password= e a senha que deve vir a seguir.

NOTA: Especificar a senha na linha de comando não é seguro! Qualquer utilizador no seus sistema pode saber sua senha digitando um comando do tipo: ps auxww. Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

O mysql utiliza valores padrão para parâmetros de conexão que não são passados pela linha de comando:

  • O nome padrão da máquina (hostname) é localhost.

  • O nome de utilizador padrão é o mesmo nome do seu utilizador no Unix.

  • Nenhuma senha é fornecida se faltar o parâmetro -p.

Então, para um utilizador Unix joe, os seguintes comandos são equivalentes:

shell> mysql -h localhost -u joe
shell> mysql -h localhost
shell> mysql -u joe
shell> mysql

Outros clientes MySQL comportam-se de forma similar.

Em sistemas Unix, você pode especificar valores padrões diferentes para serem usados quendo você faz uma conexão, assim você não precisa digitá-los na linha de comando sempre que chamar o programa cliente. Isto pode ser feito de várias maneiras:

  • Podem ser especificados parâmetros de conexão na seção [client] do arquivo de configuração .my.cnf no seu diretório home. A seção relevante do arquivo deve se parecer com isto:

    [client]
    host=nome_máquina
    user=nome_utilizador
    password=senha_utilizador
    

    Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

  • Você pode especificar parâmetros de conexão utilizando variáveis de ambiente. O nome de máquina pode ser especificado para o mysql utilizando a variável MYSQL_HOST. O nome do utilizador MySQL pode ser especificado utilizando USER (isto é somente para Windows). A senha pode ser especificada utilizando MYSQL_PWD (mas isto não é seguro; veja a próxima seção). Veja mais informações sobre isto na Apêndice F, Variáveis de Ambientes do MySQL.

4.3.9. Controle de Acesso, Estágio 1: Verificação da Conexão

Quando você tenta se conectar a um servidor MySQL, o servidor aceita ou rejeita a conexão baseado na sua identidade e se pode ou não verificar sua identidade fornecendo a senha correta. Senão, o servidor nega o acesso a você completamente. De outra forma, o servidor aceita a conexão, entra no estágio 2 e espera por requisiçiões.

Sua identidade é baseada em duas partes de informação:

  • A máquina de onde está conectando

  • Seu nome de utilizador no MySQL

A conferência da identidade é feita utilizando os tres campos de escopo da tabela user (Host, User e Password). O servidor aceita a conexão somente se uma entrada na tabela user coincidir com a máquina, nome de utilizador e a senha fornecidos.

Valores dos campos escopo na tabela user podem ser especificados como segue:

  • Um valor Host deve ser um nome de máquina ou um número IP ou 'localhost' para indicar a máquina local.

  • Você pode utilizar os metacaracteres ‘%’ e ‘_’ no campo Host.

  • Um valor Host de '%' coincide com qualquer nome de máquina.

  • Um valor Host em branco significa que o privilégio deve ser adicionado com a entrada na tabela host que coincide com o nome de máquina fornecido. Você pode encontrar mais informações sobre isto no próximo capítulo.

  • Como no MySQL Versão 3.23, para valores Host especificados como números IP, você pode especificar uma máscara de rede indicando quantos bits de endereço serão usados para o número da rede. Por exemplo:

    mysql> GRANT ALL PRIVILEGES ON db.*
    -> TO david@'192.58.197.0/255.255.255.0';
    

    Isto permitirá que todos a se conectarem a partir de determinado IP cuja condição seguinte seja verdadeira:

    IP_utilizador & máscara_rede = ip_maquina.
    

    No exemplo acima todos IPs no Intervalo 192.58.197.0 - 192.58.197.255 podem se conectar ao servidor MySQL.

  • Metacaracteres não são permitidos no campo User, mas você pode especificar um valor em branco, que combina com qualquer nome. Se a entrada na tabela user que casa com uma nova conexão tem o nome do utilizador em branco, o utilizador é considerado como um utilizador anônimo (o utilizador sem nome), em vez do nome que o cliente especificou. Isto significa que um nome de utilizador em branco é usado para todos as verificações de acessos durante a conexão. (Isto é, durante o estágio 2).

  • O campo Password pode ficar em branco. O que não significa que qualquer senha possa ser usada, significa que o utilizador deve conectar sem especificar uma senha.

Valores de Password que não estão em branco são apresentados como senhas criptografadas. O MySQL não armazena senhas na forma de texto puro para qualquer um ver. Em vez disso, a senha fornecida por um utilizador que está tentando se conectar é criptografada (utilizando a função PASSWORD()). A senha criptografada é então usada quando o cliente/servidor estiver conferindo se a senha é correta (Isto é feito sem a senha criptografada sempre trafegando sobre a conexão.) Perceba que do ponto de vista do MySQL a senha criptografada é a senha REAL, portanto você não deve passá-la para ninguém! Em particular, não forneça a utilizadores normais acesso de leitura para as tabelas no banco de dados mysql! A partir da versão 4.1, o MySQL emprega um mecanismo de senha e login diferente que é seguro mesmo se fizerem um sniff nos pacotes TCP/IP e/ou o banco de dados mysql é capturado.

Os exemplos abaixo mostram várias combinações de valores de Host e User nos registros da tabela user aplicando a novas conexões:

Valor em hostValor em userConexões casadas com o registro
'thomas.loc.gov'''Qualquer utilizador, conectando de thomas.loc.gov
'%''fred'fred, conectando a partir de qualquer máquina
'%'''Qualquer utilizador, conectando a partir de qualquer máquina
'%.loc.gov''fred'fred, conectando de qualquer máquina do domínio loc.gov
'x.y.%''fred'fred, conectando de x.y.net, x.y.com,x.y.edu, etc. (Isto provavelmente não é útil)
'144.155.166.177''fred'fred, conectando da máquina com endereço IP 144.155.166.177
'144.155.166.%''fred'fred, conectando de qualquer máquina na subrede de classe C 144.155.166
'144.155.166.0/255.255.255.0''fred'o mesmo que no exemplo anterior

Como você pode usar valores coringas de IP no campo Host (por exemplo, '144.155.166.%' combina com todas máquinas em uma subrede), existe a possibilidade que alguém possa tentar explorar esta capacidade nomeando a máquina como 144.155.166.algumlugar.com. Para evitar tais tentativas, O MySQL desabilita a combinação com nomes de máquina que iniciam com dígitos e um ponto. Portanto se você possui uma máquina nomeada como 1.2.foo.com, este nome nunca irá combinar com uma coluna Host das tabelas de permissões. Somente um número IP pode combinar com um valor coringa de IP.

Uma conexão de entrada pode coincidir com mais de uma entrada na tabela user. Por exemplo, uma conexão a partir de thomas.loc.gov pelo utilizador fred pode combinar com diversas das entradas vistas na tabela anterior. Como o servidor escolhe qual entrada usar se mais de uma coincide? O servidor resolve esta questão ordenando a tabela user no tempo de inicialização, depois procura pelas entradas na ordem da classificação quando um utilizador tenta se conectar. A primeira entrada que coincidir é a que será usada.

A ordenação da tabela user funciona da forma mostrada a seguir. Suponha que a tabela user se pareça com isto:

+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-

Quando o servidor lê a tabela, ele ordena as entradas com os valores mais específicos de Host primeiro ('%' na coluna Host significa ``qualquer máquina'' e é menos específico). Entradas com o mesmo valor Host são ordenadas com os valores mais específicos de User primeiro (um valor em branco na coluna User significa ``qualquer utilizador'' e é menos específico). O resultado da tabela user ordenada ficaria assim:

+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| localhost | root | ...
| localhost | | ...
| % | jeffrey | ...
| % | root | ...
+-----------+----------+-

Quando uma conexão é iniciada, o servidor procura entre as entradas ordenadas e utiliza a primeira entrada coincidente. Para uma conexão a partir de localhost feito por jeffrey, as entradas com 'localhost' na coluna Host coincide primeiro. Destas, a entrada com o nome do utilizador em branco combina com o nome da máquina e o nome do utilizador. (A entrada '%'/'jeffrey' também casaria, mas ela não é a primeira entrada coincidente na tabela.

Aqui está outro exemplo. Suponha que a tabela user fosse assim:

+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| % | jeffrey | ...
| thomas.loc.gov | | ...
+----------------+----------+-

A tabela ordenada pareceria com isto:

+----------------+----------+-
| Host | User | ...
+----------------+----------+-
| thomas.loc.gov | | ...
| % | jeffrey | ...
+----------------+----------+-

Uma conexão a partir de thomas.loc.gov feita por jeffrey coincide com a primeira entrada, no entanto, uma conexão de whitehouse.gov fetia por jeffrey coincidiria com a segunda entrada na tabela.

Um erro comum é pensar que para um determinado utilizador, todas as entradas que citam explicitamente este utilizador serão usadas primeiro quando o utilizador tentar encontrar uma combinação para a conexão. Simplesmente isto não é verdade. O exemplo anterior ilustra isto, onde uma conexão de thomas.loc.gov feita por jeffrey combina primeiro não com a entrada contendo 'jeffrey' no valor do campo user, mas sim pela entrada sem o nome de utilizador!

Se você tiver problemas conectando ao servidor, imprima a tabela user e ordene-a na manualmente para ver onde se deu o primeiro coincidência de valores. Se a conexão obtiver sucesso mas os seus privilégios não são os esperados, você pode usar a função CURRENT_USER() (nova na versão 4.0.6) para ver com qual combinação utilizador/máquina a sua conexão coincide. Veja mais informações sobre isto na Seção 6.3.6.2, “Funções Diversas”.

4.3.10. Controle de Acesso, Estágio 2: Verificação da Requisição

Uma vez estabelecida uma conexão, o servidor entra no 2o estágio. Para cada requisição que vem na conexão, o servidor verifica se você tem privilégios suficientes para realizá-la, baseado nas operações que você deseja fazer. É aqui que os campos de concessões nas tabelas de permissões entram em ação. Estes privilégios pode vir de qualquer uma das tabelas user, db, host, tables_priv ou columns_priv. As tabelas de permissões são manipuladas com os comandos GRANT e REVOKE. Veja mais informações sobre isto na Seção 4.4.1, “A Sintaxe de GRANT e REVOKE. (Você pode achar útil fazer referencia a Seção 4.3.6, “Como o Sistema de Privilégios Funciona”, que lista os campos presentes em cada uma das tabelas de permissões.)

A tabela user concede privilégios que são especificados por você em uma base global e que se aplicam sem importar qual é o banco de dados atual. Por exemplo, se a tabela user concede a alguém o privilégio delete, este utilizador pode apagar linhas de qualquer banco de dados no servidor! Em outras palavras, privilégios na tabela user são privilégios de superutilizador. O correto é conceder privilégios na tabela user apenas para superutilizadores tais como os administradores de servidor ou de bancos de dados. Para outros utilizadores, você deve deixar os privilégios na tabela user configurados para 'N' e conceder privilégios somente em bancos de dados específicos, utilizando as tabelas db e host.

As tabelas db e host concedem privilégios para bancos de dados específicos. Valores nos campos de escopo podem ser especificados como a seguir:

  • Os metacaracteres ‘%’ e ‘_’ podem ser usados nos campos Host e Db de ambas tabelas. Se você deseja usar um caracter ‘_’ como parte de um nome de banco de dados, especifique-o como '\_' no comando GRANT.

  • O valor '%' em Host na tabela db significa ``qualquer máquina.'' Um valor em branco em Host na tabela db significa ``consulte a tabela host para informação adicional.''

  • O valor '%' ou em branco no campo Host na tabela host significa ``qualquer máquina.''

  • O valor '%' ou em branco no campo Db de ambas as tabelas significa ``qualquer banco de dados.''

  • O valor em branco no campo User em ambas tabelas coincide com o utilizador anônimo.

As tabelas db e host são lidas e ordenadas quando o servidor inicia (ao mesmo tempo que ele lê a tabela user). A tabela db é ordenada nos campos de escopo Host, Db e User e a tabela host é ordenada nos campos de escopo Host e Db. Assim como na tabela user, a ordenação coloca os valores mais específicos no início e os menos específicos por último, e quando o servidor procura por entradas coincidentes, ele usa a primeira combinação que encontrar.

As tabelas tables_priv e columns_priv concedem privilégios específicos para tabelas e campos. Valores nos campos escopo podem ser especificados como a seguir:

  • Os meta caracteres ‘%’ e ‘_’ podem ser usados no campo Host de ambas tabelas.

  • O valor '%' ou em branco no campo Host em ambas tabelas significam ``qualquer máquina''

  • Os campos Db, Table_name e Column_name não podem conter meta caracteres ou serem brancos em ambas tabelas.

As tabelas tables_priv e columns_priv são ordenadas nos campos Host, DB e User. Isto é parecido com a ordenação da tabela db, no entanto, a ordenação é mais simples porque somente o campo Host pode conter meta caracteres.

O processo de verificação da requisição é descrito abaixo. (Se você já está familiarizado com o código de verificação de acesso, você irá perceber que a descrição aqui é um pouco diferente do algorítimo usado no código. A descrição é equivalente ao que o código realmente faz; ele só é diferente para tornar a explicação mais simples.)

Para requisições administrativas (SHUTDOWN, RELOAD, etc.), o servidor confere somente a entrada da tabela user, porque ela é a única tabela que especifica privilégios administrativos. O acesso é concedido se o registro permitir a operação requisitada ou negado caso o contrário. Por exemplo, se você deseja executar mysqladmin shutdown mas a entrada em sua tabela user não lhe concede o privilégio SHUTDOWN, o acesso é negado mesmo sem consultar as tabelas db ou host. (elas não contém o campo Shutdown_priv, portanto não existe esta necessidade.)

Para requisições relacionadas aos bancos de dados (insert, udpdate, etc.), o servidor primeiro confere os privilégios globais do utilizador consultando as entradas da tabela user. Se a entrada permitir a operação requisitada, o acesso é concedido. Se os privilégios globais na tabela user são insuficientes, o servidor determina os privilégios específicos de banco de dados para o utilizador consultando as tabelas db e host:

  1. O servidor consulta a tabela db por uma combinação nos campos Host, Db e User. Os campos Host e User são comparados com o nome da máquina e o nome do utilizador que faz a requisição. O campo Db é comparado com o banco de dados que o utilizador deseja acessar. Se não existir entradas coincidentes para o Host e User, o acesso é negado.

  2. Se existir uma combincação com a entrada da tabela db e seu campo Host não estiver em branco, aquela entrada define os privilégios especificos do banco de dados do usuario.

  3. Se o registro coincidente da tabela db tiver o campo Host em branco, significa que a tabela host enumera quais máquinas são permitidas acessar o banco de dados. Neste caso, uma consulta adicional é feita na tabela host para encontrar uma valores coincidentes nos campos Host e Db. Se nenhuma entrada na tabela host coincide, o acesso é negado. Se existir uma coincidência, os privilégios específicos de bancos de dados para o utilizador são computados como a interseção (não a união!) dos privilégios nas entradas das tabelas db e host, isto é, os privilégios que são 'Y' em ambas entradas. (Desta forma você pode conceder privilégios gerais em entradas na tabela db e então restringi-los em uma base de máquina a máquina utilizando as entradas da tabela host.)

Depois de determinar os privilégios específicos do banco de dados concedido pelas entradas nas tabelas db e host, o servidor os adiciona aos privilégios globais concedidos pela tabela user. Se o resultado permitir a operação requisitada, o acesso será concedido. De outra forma, o servidor consulta os privilégios de tabelas e campos do usuario nas tabelas tables_priv e columns_priv e os adiciona aos privilégios do utilizador. O acesso será permitido ou negado baseado no resultado.

Expresso em termos booleanos, a descrição precedente de como os privilégios de um utilizador são calculados podem ser resumido assim:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

Ele pode não ser aparente porque, se os privilégios da entrada global de user são inicialmente insuficientes para a operação requisitada, o servidor adiciona estes privilégios mais tarde aos privilégios específicos de banco de dados, tabelas e colunas. A razão é que uma requisição pode exigir mais que um tipo de privilégio. Por exemplo, se você executar uma instrução INSERT ... SELECT, você precisa dos privilégios INSERT e SELECT. Seu privilégio pode ser tal que a entrada da tabela user concede um privilégio e a entrada da tabela db concede o outro. Neste caso, você tem os privilégios necessários para realizar a requisição, mas o servidor não pode obtê-los de ambas as tabelas por si próprio; os privilégios concedidos pelas entradas em ambas as tabelas de ser combinados.

A tabela host pode ser usada para manter uma lista dos servidores seguros.

Na Tcx, a tabela host contém uma lista de todas as máquina na rede local. A elas são concedidos todos os privilégios.

Você pode também usar a tabela host para indicar máquinas que não são seguras. Suponha que você tenha uma máquina public.your.domain que está localizada em uma área pública que você não considera segura. Você pode permitir o acesso a todas as máquinas de sua rede exceto a esta máquina usando entradas na tabela host desta forma:

+--------------------+----+-
| Host | Db | ...
+--------------------+----+-
| public.your.domain | % | ... (todos os privilégios configurados para 'N')
| %.your.domain | % | ... (todos os privilégios configurados para 'Y')
+--------------------+----+-

Naturalmente, você deve sempre testar suas entradas nas tabelas de permissões (por exemplo, usar o mysqlaccess para ter certeza que os privilégios de acesso estão atualmente configurados da forma que você imagina.

4.3.11. Hashing de Senhas no MySQL 4.1

As contas de utilizadores do MySQL estão lisatadas na tabela user do banco de dados mysql. Para cada conta do MySQL é definida uma senha, no entanto o que está armazenado na coluna Password da tabela user não seja uma versão da senha em texto puro, mas um valor hash computado para ela. Valores hash de senha são calculados pela função PASSWORD().

O MySQL usa senhas em duas fases da comunicação cliente/servidor:

  • Primeiro, quando um cliente tenta se conectar ao servidor, existe uma etapa de autenticação inicial na qual o cliente deve apresentar uma senha que combina com o valor hash armazenado na tabela de utilizadores para a conta que aquele cliente deseja usar.

  • Em segundo lugar, depois que o cliente conecta, ele pode configurar ou alterar o hash da senha para as contas listadas na tabela de utilizador (se ele tiver privilégios suficientes).O cliente pode fazer isto usando a função PASSWORD() para gerar uma hash da senha ou usando as instruções GRANT ou SET PASSWORD.

Em outra palavras, o servidor usa valores hash durante a autenticação quando um cliente tenta a primeira conexão. O servidor gera os valores hash se um cliente conectado chama a função PASSWORD() ou usa uma instrução GRANT ou SET PASSWORD para definir ou alterar uma senha.

O mecanismo de hash da senha foi atualizado no MySQL 4.1 para fornecer melhor segurança e reduzir os riscos de senhas serem roubadas. No entanto, Este novo mecanismo só é interpretado pelo servidor 4.1 e clientes 4.1, que podem resultar em alguns problemas de compatibilidade. Um cliente 4.1 pode conectar a um servidor pre-4.1, porque o cliente entende tanto o antigo quanto o novo mecanismo hash de senha. No entanto, um cliente pre-4.1 que tentar se conectar a um servidor 4.1 pode encontrar dificuldades. Por exemplo, um cliente mysql 4.0 que tentar se conectar a um servidor 4.1 pode falhar com a seguinte mensagem de erro:

shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

A seguinte discussão descreve a diferença entre o antigo e o novo mecanismo de senha, e o que você deve fazer se você atualizar o seu servidor para a versão 4.1 mas precizar de manter compatibilidade com clientes pre-4.1.

Nota: Esta discussão contrasta no comportamento da versão 4.1 com o comportamento da pre-4.1, mas o da versão 4.1 descrito aqui começa relamente na versão 4.1.1. O MySQL é uma distribuição ``disferente'' porque ela tem um mecanismo um pouco diferente daquele implementado na 4.1.1 e acima. Diferenças entre a versão 4.1.0 e as versões mais recentes são descritas posteriormente.

Antes do MySQL 4.1, o hash de senha calculado pela função PASSWORD() tem tamanho de 16 bytes. Este hash se parece com:

mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e |
+--------------------+

A coluna Password da tabela user (na qual estes hashes são armazenados) também têm 16 bytes de tamanho antes do MySQL 4.1.

A partir do MySQL 4.1, a função PASSWORD() foi modificada para produzir um valor hash de 41 bytes.

mysql> SELECT PASSWORD('mypass');
+-----------------------------------------------+
| PASSWORD('mypass') |
+-----------------------------------------------+
| *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
+-----------------------------------------------+

De acordo com o mostrado, a coluna Password na tabela user também deve ter 41 bytes para armazeanar estes valores.

  • Se você realiza uma nova instalação do MySQL 4.1, a coluna Password será convertida para o tamanho de 41 bytes automaticamente.

  • Se você atualizar uma instalação mais antiga para a versão 4.1, você executar o script mysql_fix_privilege_tables para atualizar o tamanho da coluna Password de 16 para 41 bytes. (O script não altera valores de senhas existentes, que continuam com 16 bytes.)

Uma coluna Password mais larga pode armazenar hashes de senha no formato novo e no antigo. O formato de qualquer valor de hash de senha dado podeser determinado de dois modos:

  • A diferença óbvia é o tamanho (16 bytes versus 41 bytes)

  • A segunda diferença é que os hashes de senha no novo formato sempre começam com um caracter ‘*’, que as senhas no formato antigo nunca faziam.

O formato maior do hash de senha tetm melhores propriedades criptográficas, e a autenticação do cliente baseada em hashs mais longos é mais segura que aquela baseada nos antigos hashes menores.

A diferença entre os hashs de senhas menores e maiores são relevantes em como o servidor usa as senhas durante a autenticação e como ela gera hash de senhas para clientes conectados que realizam operações de alteração de senha.

O modo no qual o servidor usa o hash de senha durante a autenticação é afetada pela largura da coluna Password:

  • Se a coluna não for larga, apenas a autenticação de hash curto é usada.

  • Se a coluna é larga, ela pode guardar tanto hash curtas quanto hashs longas, e o servidor pode usar ambos os formatos:

    • Clientes pre-4.1 podem conectar, mas como els só conhecem o mecanismo hash antigo, eles só podem se conectar pelas contas com hashes curtos.

    • Clientes 4.1 podem autenticar contas com hashes longos ou curtos.

Para contas com o hash curto, o processo de autenticação é na verdade um pouco mais seguro para clientes 4.1 que para clientes mais antigos. Em termos de segurança, o gradiente do menos para o mais seguro é:

  • Clientes pre-4.1 autenticando em contas com hash de senha curto

  • Clientes 4.1 autenticando em contas com hash de senha curto

  • Clientes 4.1 autenticando em contas com hash de senha longo

O modo no qual o servidor gera hashes de senhas para clientes conectados é afetado pela largura da coluna Password e pela opção --old-passwords. Um servidor 4.1 gera hashes longos apenas se certas condicões forem encontradas: A coluna Password deve ser grande o suficiente para armazenar valores longos e a opção --old-passwords não deve ser dada. Estas condições se aplicam da seguinte forma:

  • A coluna Password deve ser grande o suficiente para armazenar hashes longos (41 bytes). Se a coluna não foi atualizada e ainda tem a largura de 16 bytes (antes da 4.1), o servidor avisa que o hash não pode caber nela e gera apenas hashes curtos quando um cliente realiza a operação de troca de senha usando PASSWORD(), GRANT, ou SET PASSWORD. (Este comportamento ocoree se você tiver atualizado para a versão 4.1 mas não executou o script mysql_fix_privilege_tables para aumentar a coluna Password.)

  • Se a coluna Password for larga, ela poderá aramazenar tanto os hashes de senha curtos quanto os longos. Neste caso, PASSWORD(), GRANT, e SET PASSWORD irão gerar hashes longos a menos que o servidor tenha sido iniciado com a opção --old-passwords. Esta opção força o servidor a gerar hashes de senha curtos.

O propósito da opção --old-passwords é permitir que você mantenha compatibilidade com clientes com versões anteriores à 4.1 sob circunstâncias nas quais os servidores gerariam hashes de senha longos. Ele não afeta a autenticação (clientes 4.1 podem ainda usar contas que possuem hash de senha longo), mas ele não previne a criaçõa de um hash de senha longo na tabela user como resultado de uma operação de troca de senha. Onde isto ocorrer, a conta não mais poderá ser usada por clientes pré-4.1. Se a opção --old-passwords, o seguinte cenário é possível:

  • Um cliente antigo conecta a uma conta que têm um hash de senha curto.

  • O cliente altera a senha das contas. Sem --old-passwords, isto resulta na conta que têm um hash de senha longo.

  • A próxima vez que o cliente antigo tentar se conectar à conta, ele não conseguirá, porque a conta agora exige o novo mecanismo de hash durante a autenticação. (Uma vez que uma conta tem um hash de senha longo na tabela de utilizador, apenas os clientes 4.1 poderão ser autenticados, porque clientes de versões anteriores a 4.1 não entendem o hash longo.)

Este cenário mostra que é perigoso executar um servidor 4.1 sem usar a opção --old-passwords, operações de alteração de senha não irão gerar hashes de senha longos e assim não faz com que as contas se tornem inacessíveis para clientes mais antigos. (Estes clientes não podem bloquear eles mesmos inadivertidamente alterando suas senhas e ficando com um hash de senha longo.

A desvantagem da opção --old-passwords é que qualquer senha que você criar ou alterar usará hashes curtos, mesmo para clientes 4.1. Assim, você perde a segurança adicional fornecida pelos hashes de senha longos. Se você quiser criar uma conta qye tenha um hash longo (por exemplom parr uso pelos clientes 4.1), você deve fazê-lo enquanto executa o servidor sem a opção --old-passwords.

Os seguintes cenários são possíveis para executar um servidor 4.1:

Cenario 1) Coluna Password menor na tabela de utilizadores

  • Apenas hashes curtos podem ser armazenados na coluna Password.

  • O servidor usa apenas hasghes curtos durante a autenticação do cliente.

  • Para clientes conectados, operações de geração de hash de senha envolvendo PASSWORD(), GRANT ou SET PASSWORD usa hashes curtos exclusivamebnte. Qualquer alteração a senha de uma conta faz com que a conta tenha um hash de senha curto.

  • A opção --old-passwords pode ser usada mas é superflua porque com uma coluna Password menor, o servidor irá gerar hashes de senha curtos de qualquer forma.

Cenário 2) Colunas Password longas; servidor não iniciado com a opção --old-passwords

  • Hashes de senha longos e curtos podem ser armazenados na coluna Password.

  • Clientes 4.1 podem autenticar contas com hashes curtos ou longos.

  • Clientes anteioriores ao 4.1 só podem autenticar contas com hash curto.

  • Para clientes conectados, operações de geração de hash de senha envolvendo PASSWORD(), GRANT, ou SET PASSWORD usam hashes longos exclusivamente. Qualquer mudança na senha de uma conta fará com que ela possua um hash de senha longo.

  • OLD_PASSWORD() pode ser usado para gerar explicitamente um hash curto. Por exemplo, para atribuir uma senha curta a uma conta, use UPDATE da seguinte forma:

    mysql> UPDATE user SET Password = OLD_PASSWORD('mypass')
    -> WHERE Host = 'some_host' AND User = 'some_user';
    mysql> FLUSH PRIVILEGES;
    

Como indicado anteriormente, o perigoso neste cenário é que é possível que contas com hashes de senha curtos se tornem inacessíveis para cliente anteriores ao 4.1. Qualquer alteração a senha de uma conta feita via GRANT, SET PASSWORD, ou PASSWORD() faz com que a conta tenha um hash de senha longo, e a partir deste ponto, nenhum cliente anterior ao 4.1 poderá autenticar esta conta até que ele seja atualizado para a versão 4.1.

Cenário 3) Coluna Password longa; servidor iniciado com a opção --old-passwords

  • Hashes longos e curtos podem ser armazenados na coluna Password.

  • Clientes 4.1 podem autenticar contas que tenham hashes longos ou curtos (mas note que é possível criar hashes longos apenas quando o servidor é iniciado sem --old-passwords).

  • Clientes anteriores ao 4.1 podem autentticar apenas contas com hashes curtos.

  • Para clientes conectados, operações de geração de hash de senha envolvendo PASSWORD(), GRANT, ou SET PASSWORD usa hashes curtos exclusivamente. Qualquer alteração em uma senha de conta faz com que a conta tenha um hash de senha curto.

Neste cenário, você não pode criar contas que tenham hashes de senha longo, porque --old-passwords previne a criação de hashes longos. Também, se você criar uma conta com um hash longo antes de usar a opção --old-passwords, alterar a senha da conta enquanto --old-passwords está funcionando faz com que seja dada a conta uma sena curta, fazendo com que ela perca os benefícios de segurança de um hash longo.

As disvantagens para este cenário pode ser resumido como a seguir:

Cenário 1) Você não pode tirar vantagem do hash longo que fornece mais autenticação segura.

Cenário 2) Contas com hashes curtos tornam clientes anteriores ao 4.1 inacessíveis se você alterar a senha deles sem usar OLD_PASSWORD() explicitamente.

Cenário 3) --old-passwords evita que as contas com hashes curtos se tornem inacessíveis, mas operações de alteração de senhas fazem com que as contas com hashes longos seja revertida para hashes curtos, e você não pode alterá-las de volta para hashes longos enquanto --old-passwords está em efeito.

Implicações de Alteração de Hashes de Senha para Aplicativos

Um atualização para o MySQL 4.1 para trazer problemas de compatibilidade para aplicações que usam PASSWORD() para gerar senha para os seus próprios propósitos. (Aplicativos não devem fazer isto, porque PASSWORD() deve ser usado paenas para gerenciar contas do MySQL. Mas algumas aplicações usam PASSWORD() para seus próprios propósitos.) Se você atualizar para o MySQL 4.1 e executar o servidor sob condições onde ele gera hashes de senha longo, uma aplicação que usa PASSWORD() para as suas próprias senhas irá falhar. O curso de ação recomendado é modificar o aplicativo para usar outras funções como SHA1() ou MD5() para produzir valores de hash. Se isto não for possível você pode utilizar a função OLD_PASSWORD(), que é fornecida para gerar hashes curtos no formato antigo. (Mas note que OLD_PASSWORD() pode vir a não ser mais suportado.)

Se o servidor está rodando sob circuntâncias onde ele gera hashes de senha curtos, OLD_PASSWORD() está disponível mas é equivalente a PASSWORD().

Hash de senhas no MySQL 4.1.0 difere do hash no 4.1.1 e acima. As diferenças da versão 4.1.0 são as seguintes:

  • Hashes de senhas de 45 bytes em vez de 41 bytes.

  • A função PASSWORD() não é repetitível. Isto é, com um dado argumento X, successivas chamadas a PASSWORD(X) geram diferentes resultados.

4.3.12. Causas dos Erros de Accesso Negado

Se você encontrar erros de Accesso Negado (Access denied) quando tentar conectar-se ao servidor MySQL, a lista abaixo indica alguns caminhos que você pode seguir para corrigir o problema:

  • Depois de instalar o MySQL, você executou o script mysql_install_db para configurar o conteúdo inicial das tabelas de permissões ? Se não, faça isto. Veja mais informações sobre isto na Seção 4.4.4, “Configurando os Privilégios Iniciais do MySQL”. Testes os privilégios iniciais executando este comando:

    shell> mysql -u root test
    

    O servidor deve deixar você conectar sem erros. Você também deve assegurar que exista o arquivo user.MYD no diretório do banco de dados do MySQL. Normalmente ele fica em CAMINHO/var/mysql/user.MYD. onde CAMINHO é o caminho para a raiz da instalação do MySQL.

  • Depois de terminar uma instalação, você deve conectar ao servidor e configurar seus utilizadores e suas permissões de acesso.

    shell> mysql -u root mysql
    

    O servidor deve permitir a conexão pois o utilizador root MySQL vem inicialmente configurado sem senha. Isto também é um risco de segurança, portanto configurar a senha do utilizador root é algo que deve ser feito enquanto você configura os outros utilizadores do MySQL.

    Se você tentar se conectar como root e obter este erro:

    Access denied for user: '@unknown' to database mysql
    

    isto significa que você não possui um registro na tabela user com o valor 'root' no campo User e que o mysqld não pode rsolver o nome de máquina do cliente. Neste caso, você deve reiniciar o servidor com a opção --skip-grant-tables e editar seu arquivo /etc/hosts ou o \Windows\hosts para adicionar uma entrada para sua máquina.

  • Se você obter um erro como o seguinte:

    shell> mysqladmin -u root -pxxxx ver
    Access denied for user: 'root@localhost' (Using password: YES)
    

    Significa que você está usando uma senha incorreta. Veja mais informações sobre isto na Seção 4.4.8, “Configurando Senhas”.

    Se você esqueceu a senha de root, você pode reiniciar o mysqld com a opção --skip-grant-tables para alterar a senha. Veja mais informações sobre isto na Seção A.4.2, “Como Recuperar uma Senha de Root Esquecida”.

    Se você obter o erro acima mesmo se não tiver configurado uma senha, significa que você tem algum arquivo my.ini configurado para passar alguma senha incorreta. Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf. Você pode evitar o uso de arquivos de opções com a opção --no-defaults, como a seguir:

    shell> mysqladmin --no-defaults -u root ver
    
  • Se você atualizou uma instalação existente do MySQL de um versão anterior à versão 3.22.11 para a Versão 3.22.11 ou posterior, você executou o script mysql_fix_privilege_tabels ? Se não faça isto. A estrutura das tabelas de permissões alteraram com a Versão 3.22.11 do MySQL quando a instrução GRANT se tornou funcional. Veja mais informações sobre isto na Seção 2.5.6, “Atualizando a Tabela de Permissões”.

  • Se os seus privilégios parecerem alterados no meio de uma sessão, pode ser que o superutilizador os alterou. A recarga das tabelas de permissões afeta novas conexões dos clientes, mas ela também afeta conexões existentes como indicado em Seção 4.4.3, “Quando as Alterações nos Privilégios tem Efeito”.

  • Se você não consegue fazer a sua senha funcionar, lembre-se que você deve usar a função PASSWORD() se você configurar a senha com instruções INSERT, UPDATE ou SET PASSWORD. A função PASSWORD() é desnecessária se você especificar a senha usando a instrução GRANT ... IDENTIFIED BY ou o comando mysqladmin password. Veja mais informações sobre isto na Seção 4.4.8, “Configurando Senhas”.

  • localhost é um sinônimo para seu nome de máquina local, e é também a máquina padrão em que clientes tentam se conectar se você não especificar explicitamente o nome da máquina. Entretanto, conexões para localhost não funcionam se você estiver executando em um sistema que utilize MIT-pthreads (conexões localhost são feitas utilizando sockets Unix, que não são suportadas pelas MIT-pthreads). Para evitar este problema nestes sistemas, você deve utilizar a opção --host para nomear explicitamente o servidor. Isto fará uma conexão TCP/IP ao servidor myssqld. Neste caso, você deve ter seu nome de máquina real nos registros da tabela user no servidor. (Isto é verdadeiro mesmo se você estiver executando um programa cliente na mesma máquina que o servidor.)

  • Se você obter o erro Access denied quando tentando conectar ao banco de dados com mysql -u nome_utilizador _nome_bd, você pode ter um problema com a tabela user. Verifique isto executando mysql -u root mysql e usando esta sentença SQL:

    mysql> SELECT * FROM user;
    

    O resultado deve incluir uma entrada com as colunas Host e User combinando com o nome de seu computador e seu nome de utilizador no MySQL.

  • A mensagem de erro Access denied irá dizer a você com qual utilizador você está tentando se logar, a máquina que está tentando conectar e se você está utilizando uma senha ou não. Normalmente, você deve ter um registro na tabela user que combine exatamente com o nome de máquina e o nome de utilizador que forem fornecidos na mensagem de erro. Por exemplo, se você obter uma mensagem de erro que contenha Using password: NO, isto significa que você está tentando se conectar sem uma senha.

  • Se você obter o seguinte erro quando estiver tentando conectar de uma máquina diferente da que o servidor MySQL estiver executando, então não deve existir um registro na tabela user que combine com esta máquina:

    Host ... is not allowed to connect to this MySQL server
    

    Você pode corrigir isto utilizando a ferramenta de linha de comando mysql (no servidor!) para adicionar um registro à tabela user, db ou host para coincidir com o utilizador e nome de máquina de onde você está tentando conectar, depois execute o comando mysqladmin flush-privileges. Se você não estiver executando o MySQL Versão 3.22 e você não sabe o número IP ou o nome da máquina da qual estiver conectando, você deve colocar uma entrada com o valor '%' na coluna Host da tabela user e reiniciar o mysqld com a opção --log na máquina onde é executado o servidor. Depois tente conectar a partir da máquina cliente, a informação no log do MySQL irá indicar como você está realmente conectando. (Então troque o '%' na tabela user com o nome da máquina mostrado pelo log. De outra forma você teria um sistema que seria inseguro.)

    Outra razão para este erro no Linux pode ser porque você está utilizando uma versão binária do MySQL que é compilada com uma versão diferente da glibc que você está usando. Neste caso você deve atualizar seu SO/Glibc ou fazer o download da versão fonte do MySQL e compilá-la. Um RPM fonte é, normalmente, fácil de compilar e instalar, logo, isto não é um grande problema.

  • Se você obter uma mensagem de erro onde o nome da máquina não é exibido ou, no lugar do nome da máquina existir um IP, mesmo se você tenta a conexão com um nome de máquina:

    shell> mysqladmin -u root -pxxxx -h some-hostname ver
    Access denied for user: 'root@' (Using password: YES)
    

    Isto significa que o MySQL obteve algum erro quando tentava resolver o IP para um nome de maquina. Neste caso você pode executar mysqladmin flush-hosts para zerar o cache DNS interno. Veja mais informações sobre isto na Seção 5.5.5, “Como o MySQL Utiliza o DNS”.

    Algumas soluções permanentes são:

    • Tente descobrir o que está errado com seu servidor DNS e corrija os erros.

    • Especifique números IPs no lugar de nomes nas tabelas de privilégios do MySQL.

    • Inicie o mysqld com --skip-name-resolve.

    • Inicie o mysqld com --skip-host-cache.

    • Conecte à localhost se você estiver executando o servidor e o cliente na mesma máquina.

    • Coloque os nomes das máquinas clientes em /etc/hosts.

  • Se mysql -u root test funciona mas mysql -h nome_servidor -u root test resultar em Access denied, então você pode não ter o nome correto para a sua máquina na tabela user. Um problema comum é quando o valor de Host na entrada da tabela user especifica um nome de máquina não qualificado, mas as rotinas de resolução de nomes de seu sistema retornam um nome qualificado completo do domínio (ou vice-versa). Por exemplo, se você tem uma entrada com o nome 'tcx' na tabela user, mas seu DNS diz ao MySQL que o nome da máquina é 'tcx.subnet.se', a entrada não irá funcionar. Tente adicionar um registro à tabela user que contenha o número IP de sua máquina como o valor da coluna Host. (Uma alternativa, seria adicionar um registro à tabela user com o valor de Host contendo um metacaracter, por exemplo, 'tcx.%'. Entretanto, o uso de nomes de máquinas terminando com ‘%’ é inseguro e não é recomendado!)

  • Se mysql -u nome_utilizador test funciona mas mysql -u nome_utilizador outro_bd não funconar, você não possui uma entrada para outro_bd listado na tabela db.

  • Se mysql -u nome_utilizador nome_bd funciona quando executado no próprio servidor, mas mysql -u nome_máquina -u nome_utilizador nome_bd não funciona quando executado em outra máquina cliente, você não possui o nome da máquina cliente listado na tabela user ou na tabela db.

  • Se você não estiver entendendo porque obtem Access denied, remova da tabela user todas as entradas da coluna Host que contenham meta caracteres (entradas que contenham ‘$’ ou ‘_’). Um erro muito comum é inserir uma nova entrada com Host='%' e User='algum utilizador', pensando que isto irá permitir a você especificar localhost para conectar da mesma máquina. A razão disto não funcionar é que os privilégios padrões incluem uma entrada com Host='localhost' e User=''. Como esta entrada tem o valor 'localhost' em Host que é mais específica que '%', ela é usada no lugar da nova entrada quando se conectar de localhost! O procedimento correto é inserir uma segunda entrada com Host='localhost' e User='algum_utilizador', ou remover a entrada com Host='localhost' e User= ''.

  • Se você obter o seguinte erro, você pode ter um problema com a tabela db ou a tabela host:

    Access to database denied
    

    Se a entrada selecionada da tabela db tiver um valor vazio na coluna Host, tenha certeza que exista uma ou mais entradas correspondentes na tabela host especificando quais máquinas aplicam-se à tabela db.

    Se você obter o erro quando estiver utilizando comandos SQL SELECT ... INTO OUTFILE ou LOAD DATA INFILE, a entrada na tabela user provavelmente não tem o privilégio file habilitado.

  • Lembre-se que programas clientes irão usar parâmetros de conexões especificados em arquivos de configuração ou variáveis ambientais. Veja mais informações sobre isto na Apêndice F, Variáveis de Ambientes do MySQL. Se parecer que algum cliente está enviando parâmetros errados para a conexão e você não os especificou na linha de comando, verifique seu ambiente e o arquivo .my.cnf no seu diretório home. Você pode também conferir os arquivos de configurações do servidor MySQL, apesar de não ser interessante gravar configurações de cliente nestes arquivos. Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf. Se você obter a mensagem de acesso negado (Access denied) quando estiver executando um cliente sem opções, tenha certeza que você não especificou uma senha antiga em nenhum de seus arquivos de opções! Veja mais informações sobre isto na Seção 4.1.2, “Arquivo de Opções my.cnf.

  • Se você fizer alterações para as tabelas de permissões diretamente (utilizando uma instrução INSERT ou UPDATE) e suas alterações parecem ser ignoradas, lembre que você deve usar uma instrução FLUSH PRIVILEGES ou executar um comando mysqladmin flush-privileges para o servidor ler novamente as tabelas com os privilégios. De outra forma, suas alterações não farão efeito até que o servidor seja reiniciado. Lembre-se que depois de configurar a senha de root com um comando UPDATE, não será necessário especificar a senha até que você atualize os privilégios, pois o servidor ainda não saberá que você alterou a senha!

  • Se você tiver problemas de acesso com Perl, PHP, Python ou um programa ODBC, tente conectar ao servidor com mysql -u nome_utilizador nome_bd ou mysql -u nome_utilizador -psua_senha nome_bd. Se você consegue conectar com o cliente mysql, existe algum problema com seu programa e não o acesso aos privilégios (Note que não espaço entre -p e a senha; você também pode utilizar a sintaxe --password=sua_senha para especificar a senha. Se você utilizar a opção -p sozinha, o MySQL irá lhe solicitar a senha.)

  • Para testar, iniciae o daemon mysqld com a opção --skip-grant-tables. Então você pode alterar as tabelas de permissões do MySQL e utilizar o script mysqlaccess para conferir se suas modificações fizeram o não o efeito desejado. Quando você estiver satisfeito com suas alterações, execute mysqladmin flush-privileges para dizer ao servidor mysqld para iniciar utilizando as novas tabelas com os privilégios. Nota: Recarregar as tabelas de permissões sobrescreve a opção --skip-grant-tables. Isto lhe permite dizer ao servidor para começar a utilizar as tabelas de permissões novamente sem reiniciá-lo.

  • Se tudo mais falhar, inicie o servidor mysqld com uma opção de depuração (por exemplo, --debug=d,general,query). Isto irá imprimir informações de máquinas e utilizadores sobre tentativas de conexões, e também informações sobre cada comando disparado. Veja mais informações sobre isto na Seção E.1.2, “Criando Arquivos Trace (Rastreamento)”.

  • Se você tiver outros problemas com as tabelas de permissões do MySQL e sente que deve enviar o problema para a lista de discussão, sempre forneça um descarga das tabelas de permissões do seu MySQL. Você pode descarregar as tabelas com o comando mysqldump mysql. Como sempre, envie seus problemas utilizando o script mysqlbug. Veja mais informações sobre isto na Seção 1.7.1.3, “Como relatar erros ou problemas”. Em alguns casos você pode precisar reiniciar o mysqld com a opção --skip-grant-tables para executar o mysqldump.