5.6. El sistema de privilegios de acceso de MySQL

MySQL 5.0

5.6. El sistema de privilegios de acceso de MySQL

MySQL tiene un sistema avanzado pero no estándard de seguridad y privilegios. Esta sección describe su funcionamiento.

5.6.1. Qué hace el sistema de privilegios

La función primaria del sistema de privilegios de MySQL es autenticar un usuario conectándose desde un equipo dado, y asociar dicho usuario con privilegios en una base de datos tales como , , , y .

Funcionalidad adicional incluye la habilidad de tener usuarios anónimos y de dar privilegios para funciones específicas de MySQL tales como y operaciones administrativas.

5.6.2. Cómo funciona el sistema de privilegios

El sistema de privilegios de MySQL asegura que todos los usuarios pueden ejecutar sólo la operación permitida a los mismos. Como usuario, cuando conecta a un servidor MySQL, su identidad se determina mediante el equipo desde el que se conecta y el nombre de usuario que especifique. Cuando efectúe peticiones tras conectar, el sistema le otorga privilegios acorde a su identidad y lo que quiera hacer.

MySQL considera tanto su nombre de usuario y su equipo a la hora de identificarle, ya que no hay razón para asumir que un nombre de usuario pertenece a la misma persona en cualquier sitio de Internet. Por ejemplo, el usuario que conecta desde no tiene porqué ser la misma persona que el usuario que conecta desde . MySQL trata esto permitiendole distinguir usuarios en diferentes equipos que tienen el mismo nombre. Puede otorgar un conjunto de privilegios para conexiones de desde , y un conjunto distinto para conexiones de desde .

El control de acceso de MySQL implica dos etapas:

  • Etapa 1: El servidor comprueba si debe permitirle conectarse.

  • Etapa 2: Asumiendo que se conecta, el servidor comprueba cada comando que ejecuta para ver si tiene suficientes permisos para hacerlo. Por ejemplo, si intenta seleccionar registros de una tabla en una base de datos o eliminar una tabla de la base de datos, el servidor verifica que tenga el permiso para la tabla o el permiso para la base de datos.

Si sus permisos cambian (por usted mismo o alguien distinto) mientras está conectado, estos cambios no tienen porqué tener efecto inmediatamente para el siguiente comando que ejecute. Consulte Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios” para más detalles.

El servidor guarda información de privilegios en las tablas de permisos de la base de datos (esto es, en la base de datos llamada ). El servidor MySQL lee el contenido de dichas tablas en memoria cuando arranca y las vuelve a leer bajo las circunstancias indicadas en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”. Las decisiones acerca de control de acceso se basan en las copias en memoria de las tablas de permisos.

Normalmente, manipula los contenidos de las tablas de permisos indirectamente usando los comandos y para configurar cuentas y controlar los privilegios disponibles para cada una. Consulte Sección 13.5.1.3, “Sintaxis de y . La discusión aquí describe la estructura subyacente de las tablas de permisos y cómo el servidor usa sus contenidos cuando interactúa con clientes.

El servidor usa las tablas , , y en la base de datos en ambas etapas de control de acceso. Las columnas en estas tablas de permisos se muestran a continuación:

Nombre tabla user db host
Alcance columnas
 
   
Columnas privilegios
 
 
 
 
 
 
 
 
 
 
   
   
 
     
     
     
     
     
     
 
 
     
     
     
Columnas seguridad    
     
     
     
Columnas recursos control    
     
     
     

se presentó en MySQL 5.0.0, pero no fue operacional hasta MySQL 5.0.3.

Las columnas y se añadieron en MySQL 5.0.1.

Las columnas , , y se añadieron en MySQL 5.0.3.

Durante la segunda etapa de control de acceso, el servidor efectúa una verificación de petición para asegurar que cada cliente tiene suficientes privilegios para cada petición que recibe. Adicionalmente las tablas de permisos , , y , el servidor puede consultar las tablas y para peticiones que impliquen tablas. Las tablas y proveen de un control de privilegios más fino a nivel de tabla y columna. Tienen las siguientes columnas:

Nombre tabla tables_priv columns_priv
Alcance de columnas
 
 
 
   
Columnas privilegios
   
Otras columnas
   

Las columnas y actualmente no se usan y no se discuten más en esta sección.

Para verificación de peticiones que impliquen rutinas almacenadas, el servidor puede consultar la tabla . Esta tabla tiene las siguientes columnas:

Nombre tabla procs_priv
Alcance de columnas
 
 
 
 
Columnas privilegios
Otras columnas
 

La tabla existe desde MySQL 5.0.3. La columna se añadió en MySQL 5.0.6. Hay una columna con valores de o para indicar el tipo de rutina a que se refiere el registro. Esta columna permite que los privilegios se otorgen separadamente para una función y para un procedimiento con el mismo nombre.

Las columnas y no se usan actualmente y no se discuten más aquí.

Cada tabla de permisos contiene columnas de alcance y columnas de privilegios:

  • Las columnas de alcance determinan el alcance de cada entrada (registro) en las tablas; esto es, el contexto en que el registro se aplica. Por ejemplo, un registro de la tabla con los valores y de y se usarían para autenticar conexiones hechas al servidor desde el equipo por un cliente que especifique un nombre de usuario de . De forma similar, un registro de la tabla con las columnas , , y con valores , y se usaría cuando conectase desde el equipo para acceder a la base de datos . Las tablas y contienen columnas de alcance indicando tablas o combinaciones de tabla/columna para las que cada registro se aplica. La columna de alcance indica la rutina de almacenamiento que se aplica a cada registro.

  • Las columnas de privilegios indican qué privilegios se otorgan a un registro de la tabla; esto es, qué operaciones pueden ejecutarse. El servidor combina la información de diversas tablas de permisos para tener una descripción completa de los permisos de un usuario. Las reglas usadas para ello se describen en Sección 5.6.6, “Control de acceso, nivel 2: comprobación de solicitudes”.

Las columnas de alcance contienen cadenas de carácteres. Se declaran tal y como se muestra a continuación; el valor por defecto es la cadena de carácteres vacía:

Nombre de columna Tipo

Con propósito de chequeos de acceso, las comparaciones de los valores de no tienen en cuenta mayúsculas y minúsculas. Los valores de , , , y son sensibles a mayúsculas y minúsuclas. Los valores de no son sensibles a mayúsculas y minúsculas.

En las tablas , , y , cada privilegio se lista en una columna separada que se declara como . En otras palabras, cada privilegio puede estar desactivado o activado, estando desactivados por defecto.

En las tablas , , and , las columnas de privilegios se declaran como columnas de tipo . Los valores en estas columnas pueden contener cualquier combinación de los privilegios controlados por la tabla:

Nombre de tabla Nombre de columna Posible conjunto de elementos

Brevemente, el servidor usa las tablas de permisos como sigue:

  • Las columnas de alcance de la tabla determinan si se rechazan o permiten conexiones entrantes. Para conexiones permitidas, cualquier privilegio otorgado en la tabla indica los privilegios globales del usuario (superusuario). Estos privilegios se aplican a todas las bases de datos en el servidor.

  • Las columnas de alcance de la tabla determinan qué usuarios pueden acceder a qué bases de datos desde qué equipo. La columna de privilegios determina qué operaciones se permiten. Un privilegio otorgado a nivel de base de datos se aplica a la base de datos y a todas sus tablas.

  • La tabla se usa en conjunción con la tabla cuando desea que un registro de la tabla se aplique a varios equipos. Por ejemplo, si queiere que un usuario sea capaz de usar una base de datos desde varios equipos en su red, deje el valor vacío en el registro de usuario de la tabla , luego rellene la tabla con un registro para cada uno de estos equipos. Este mecanismo se describe con mayor detalle en Sección 5.6.6, “Control de acceso, nivel 2: comprobación de solicitudes”.

    Nota: La tabla no se ve afectada por los comandos ni . La mayoría de instalaciones MySQSL no necesitan usar esta tabla en absoluto.

  • Las tablas y son similares a la tabla , pero son más detalladas: se aplican a nivel de tabla y de columna en lugar de a nivel de base de datos. Un privilegio otorgado a nivel de tabla se aplica a la tabla y a todas sus columnas. Un privilegio otorgado a nivel de columna se aplica sólo a la columna especificada.

  • La tabla se aplica a rutinas almacenadas. Un privilegio otorgado a nivel de rutina se aplica sólo a una única rutina.

Permisos administrativos (tales como o ) se especifican sólo en la tabla . Esto es debido a que las operaciones administrativas son operaciones del propio servidor y no específicas de bases de datos, así que no hay ninguna razón para listar estos privilegios en las otras tablas de permisos. De hecho, para determinar si puede realizar una operación administrativa, el servidor sólo necesita consultar la tabla .

El privilegio también se especifica sólo en la tabla . No es un privilegio administrativo como tal, pero la habilidad de leer o escribir archivos en el equipo servidor es independiente de las bases de datos a las que acceda.

El servidor mysqld lee los contenidos de las tablas de permisos en memoria cuando arranca. Puede decirle que las vuelva a leer mediante el comando o ejecutando los comandos mysqladmin flush-privileges o mysqladmin reload . Los cambios en las tablas de permisos tienen efecto como se indica en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”.

Cuando modifica los contenidos de las tablas de permisos, es una buena idea asegurarse que sus cambios configuran permisos tal y como desea. Para consultar los permisos de una cuenta dada, use el comando . Por ejemplo, para determinar los permisos que se otorgan a una cuenta con valores y de y , use este comando:

mysql> SHOW GRANTS FOR 'bob'@'pc84.example.com';

Una herramienta de diagnóstico útil es el script mysqlaccess , proporcionado por Yves Carlier para la distribución MySQL. Invoque mysqlaccess con la opción para ver cómo funciona. Note que mysqlaccess chequea acceso usando sólo las tablas , , y . No chequea los privilegios de tabla, columna, o rutina especificados en las tablas , , o .

Para ayuda adicional en problemas relacionados con el diagnóstico de permisos, consulte Sección 5.6.8, “Causas de errores . Para consejos generales sobre seguridad , consulte Sección 5.5, “Cuestiones de seguridad general”.

5.6.3. Privilegios de los que provee MySQL

La información sobre los privilegios de las cuentas está almacenada en las tablas , , , , , y de la base de datos . El servidor MySQL lee el contenido de estas tablas y lo almacena en memoria cuando se inicia, y lo relee bajo ciertas circunstancias indicadas en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”. Las decisiones de control de acceso se basan en la copia en memoria de las tablas grant.

Los nombres utilizados en las sentencias y para referirse a privilegios se muestran en la siguiente tabla, junto al nombre de columna asociado con cada privilegio en las tablas grant y el contexto en que el privilegio se aplica. Más información sobre el significado de cada privilegio se puede encontrar en Sección 13.5.1.3, “Sintaxis de y .

Privilegio Columna Contexto
bases de datos, tablas, o índices
bases de datos o tablas
bases de datos, tablas, o procedimientos almacenados
bases de datos o tables
tablas
tablas
tablas
tablas
tablas
tablas
vistas
vistas
procedimientos almacenados
procedimientos almacenados
procedimientos almacenados
acceso a archivos en la máquina del servidor
administración del servidor
administración del servidor
administración del servidor
administración del servidor
administración del servidor
administración del servidor
administración del servidor
administración del servidor
administración del servidor
administración del servidor

y fueron añadidos en MySQL 5.0.1. , , y fueron añaidos en MySQL 5.0.3. Aunque ya estaba presente en MySQL 5.0.0, no se activó hasta MySQL 5.0.3. Para utilizar estos privilegios cuando se actualice desde una versión más antigua de MySQL que no los tiene, debe actualizar sus tablas grant utilizando el script mysql_fix_privilege_tables proporcionado con la distribución MySQL. Consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

Para crear o modificar procedimientos almacenados cuando el registro binario está activado, debe también tener el privilegio , tal y como se explica en Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.

Los privilegios y permiten crear nuevas bases de datos y tablas, o eliminar las existentes. Si otorga el privilegio para la base de datos a un usuario, ese usuario puede eliminar la base de datos en la que MySQL almacena los privilegios de acceso.

Los privilegios , , , and permiten realizar operaciones en registros de tablas existentes en una base de datos.

Las sentencias requieren el privilegio sólo si realmente extraen registros de una tabla. Algunas sentencias no acceden a tablas, y pueden ser ejecutados por tanto sin permiso para ninguna base de datos. Por ejemplo, podría utilizar el cliente mysql como una simple calculadora para evaluar expresiones que no hacen referencia a tablas:

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

El privilegio permite crear o eliminar índices. es aplicable a tablas existentes. Si tiene el privilegio para una tabla, entonces puede incluir definiciones de índices en la sentencia .

El privilegio permite utilizar para cambiar la estructura de o renombrar tablas.

El privilegio es necesario para crear procedimientos almacenados (funciones y procedimientos). El privilegio se necesita para modificar o eliminar procedimientos almacenados, y es necesario para ejecutarlos.

El privilegio permite dar a otros usuarios las privilegios que uno mismo posee. Puede ser utilizado para bases de datos, tablas, y procedimientos almacenados.

El privilegio otorga permiso para leer y escribir archivos en la máquina del servidor utilizando las sentencias y . Un usuario que tiene el privilegio puede leer cualquier archivo de la máquina del servidor que sea legible por cualquiera o por el usuario que ejecuta el servidor MySQL. (Esto implica que el usuario puede leer cualquier archivo en el directorio de datos, porque el servidor puede acceder a cualquiera de estos archivos.) El privilegio también permite al usuario crear archivos nuevos en cualquier directorio en que el servidor MySQL tiene acceso de escritura. Los archivos existentes no pueden ser sobreescritos.

Los privilegios restantes son utilizados para operaciones administrativas. Muchas de ellas puede ser realizadas utilizando el programa mysqladmin o mediante sentencias SQL. La siguiente tabla muestra qué comandos de mysqladmin permite ejecutar cada privilegio administrativo.

Privilegio Comandos permitidos a los poseedores del privilegio Holders
, , , , , , ,

El comando comunica al servidor que debe releer las tablas grant a memoria. es un sinónimo de . El comando cierra y vuelve a abrir los archivos de registro y vuelca todas las tablas. Los otros comandos realizan funciones similares a , pero son más específicas y pueden ser preferibles en algunos casos. Por ejemplo, si quiere tan solo volcar los archivos de registro, es mejor opción que .

El comando apaga el servidor. Este comando puede ejecutarse únicamente desde mysqladmin. No hay sentencia SQL equivalente.

El comando muestra información sobre los subprocesos que se están ejecutando en el servidor (es decir, sobre las sentencias que se están ejecutando por parte de clientes asociados con otras cuentas). El comando mata los subprocesos del servidor. Siempre puede mostrar información sobre sus propios subprocesos, o matarlos, pero necesita el privilegio para ver subprocesos iniciados por otros usuarios, y el privilegio para matarlos. Consulte Sección 13.5.5.3, “Sintaxis de .

El privilegio permite la utilización de la palabra clave en sentencias .

El privilegio permite la utilización de sentencias explícitas para bloquear tablas para las que tiene el privilegio . Esto incluye el uso de bloqueos de escritura, que evita que cualquier otra persona lea la tabla bloqueada.

El privilegio permite la utilización de las sentencias y .

El privilegio debería otorgarse a cuentas que son utilizadas por servidores esclavos para conectarse al servidor actual como su maestro. Sin este privilegio, la cuenta esclava no puede pedir actualizaciones que se hayan hecho a las bases de datos del servidor maestro.

El privilegio permite a la cuenta ver los nombres de las bases de datos mediante la ejecución de la sentencia . Cuentas que no tengan este privilegio solo pueden ver las bases de datos para las que tienen privilegios, y no pueden utilizar la sentencia de ninguna manera si el servidor ha sido iniciado con la opción .

En general, es una buena idea garantizar a una cuenta solo aquellos privilegios que necesita. Se debe tener especial cuidado en seguir esta regla con los privilegios administrativos y :

  • El privilegio puede utilizarse inadecuadamente para introducir en una tabla de la base de datos cualquier archivo que el servidor MySQL sea capaz de leer en la máquina del servidor. Esto incluye todos los archivos que sean legibles para cualquiera, además de los archivos almacenados en el directorio de datos del servidor. Esta tabla puede entonces ser accedida utilizando una sentencia para transferir sus contenidos a la máquina cliente.

  • El privilegio permite a los usuarios otorgar sus mismos privilegios a otros usuarios. Dos usuarios con diferentes privilegios y con el privilegio pueden combinar sus privilegios.

  • El privilegio puede ser utilizado inadecuadamente para sabotear el sistema de privilegios mediante el renombrado de tablas.

  • El privilegio puede utilizarse inadecuadamente para denegar el servicio a otros usuarios de manera total, cerrando el servidor.

  • El privilegio puede utilizarse para ver el texto de las consultas que se estén ejecutando actualmente, incluyendo consultas que establecen o modifican passwords.

  • El privilegio puede utilizarse para cerrar la conexión a otros clientes o cambiar como el servidor funciona.

  • Los privilegios otorgados para la propia base de datos pueden utilizarse para cambiar passwords y otra información de privilegios de acceso. Las passwords se almacenan cifradas, así que un usuario malicioso no puede simplemente leerlas para conocer la password. Aún así, el usuario con privlegio de escritura a la columna de la tabla puede cambiar la password de una cuenta, y seguidamente conectarse al servidor MySQL utilizando esa cuenta.

Hay algunas cosas que no se pueden hacer con el sistema de privilegios de MySQL:

  • No se puede especificar explícitamente que a un usuario se le deba denegar el acceso.

  • No se puede especificar que un usuario tenga privilegios para crear o eliminar tablas en una base de datos, pero que no pueda crear o eliminar la propia base de datos.

5.6.4. Conectarse al servidor MySQL

Los programas cliente de MySQL espera por lo general que usted especifique los parámetros de conexión cuando quiere acceder a un servidor MySQL:

  • El nombre de la máquina donde se está ejecutando el servidor MySQL

  • Su nombre de usuario

  • Su password

Por ejemplo, el cliente mysql puede ejecutarse desde un prompt de línea de comandos (indicado aquí por ) de la siguiente manera:

shell> mysql -h  -u  -p

Las sintaxis alternativas de las opciones , , y son , , y . Nótese que no hay espacios entre o y la clave que le sigue.

Si utiliza una opción o pero no especifica un valor para la clave, el programa cliente le pedirá que introduzca la clave. La clave no se mostrará mientras la introduce. Esto es más seguro que especificar la clave en la línea de comandos. Cualquier usuario de su sistema podría ser capaz de ver la clave especificada en la línea de comandos ejecutando un comando como ps auxww. Consulte Sección 5.7.6, “Guardar una contraseña de forma segura”.

Los programas clientes de MySQL utilizan valores por defecto para cualquier parámetro que no se especifique:

  • El nombre de servidor por defecto es .

  • El nombre de usuario por defecto es en Windows y su nombre de usuario de Unix en Unix.

  • No se aplica ninguna clave si no está especificado.

De esta manera, para un usuario de Unix con un nombre de usuario de , todos los siguientes comandos son equivalentes:

shell> mysql -h localhost -u jose
shell> mysql -h localhost
shell> mysql -u jose
shell> mysql

Otros clientes MySQL se comportan de manera similar.

Puede especificar valores diferentes para que se utilicen cuando se realiza una conexión de manera que no tenga que introducirlos en la línea de comandos cada vez que invoca un programa cliente. Esto puede llevarse a cabo de diversas maneras:

  • Puede especificar los parámetros de conexión en la sección de un archivo de opciones. La sección relevante del archivo debería tener el siguiente aspecto:

    [client]
    host=
    user=
    password=
    

    Los archivos de opciones son explicados en profundidad en Sección 4.3.2, “Usar ficheros de opciones”.

  • Puede especificar algunos parámetros de conexión utilizando variables de ambiente. El nombre del servidor para mysql puede ser especificado utilizando . El nombre de usuario MySQL puede especificarse mediante (esto es para Windows y Netware únicamente). La clave se puede especificar utilizando , aunque esto es inseguro; consulte Sección 5.7.6, “Guardar una contraseña de forma segura”. Para ver la lista de variables, consulte Apéndice E, Variables de entorno.

5.6.5. Control de acceso, nivel 1: Comprobación de la conexión

Cuando intente conectar a un servidor MySQL, el servidor aceptará o rechazará la conexión basándose en su identidad y si usted puede identificar su identidad proporcionando la clave correcta. Si no es así, el servidor le denegará el acceso completamente. En caso contrario, el servidor acepta la conexión, y entra en el Estado 2, y espera peticiones.

Su identidad se basa en dos elementos de información:

  • El nombre de máquina cliente (o ip) desde donde usted se conecta

  • Su nombre de usuario MySQL

La comprobación de la identidad se realiza utilizando las tres columnas de la tabla (, , y ). El servidor sólo acepta la conexión si las columnas y de alguna de las tablas es coincidente con el nombre de máquina y usuario del cliente, y además el cliente proporciona la clave especificada en ese registro.

Los valores de en la tabla pueden ser especificados de las siguientes maneras:

  • Un valor de debe ser un nombre de máquina o un número IP, o para indicar la máquina local.

  • Puede utilizar los carácteres comodín '' y '' en los valores de las columnas . Estos tienen el mismo significado que en las operaciones de búsqueda de patrones realizadas mediante el operador . Por ejemplo, un valor de igual a retorna cualquier nombre de máquina, así como un valor de retorna cualquier nombre de máquina en el dominio .

  • Para valores de especificados como números IP, puede especificar una máscara de red indicando cuantos bits de la dirección utilizar para el número de red. Por ejemplo:

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

    Esto permite a conectarse desde cualquier cliente que tenga un número IP para el que la siguiente condición sea cierta:

    client_ip & netmask = host_ip
    

    Es decir, para la sentencia recientemente mostrada: That is, for the statement just shown:

    client_ip & 255.255.255.0 = 192.58.197.0
    

    Los números IP que satisfagan esta condición y pueden conectar al servidor MySQL son lo que están en el rango desde hasta .

  • Nota: La máscara de red solo puede ser utilizada para decirle al servidor que use 8, 16, 24 o 32 bits para la dirección, por ejemplo:

    192.0.0.0/255.0.0.0 (cualquier dirección de la red clase A 192)
    192.168.0.0/255.255.0.0 (cualquier dirección de la red clase B 192.168)
    192.168.1.0/255.255.255.0 (cualquier dirección de la red clase C 192.168.1)
    192.168.1.1 (solo esta IP específica) 
         

    La siguiente máscara de red (28 bits) no funcionará:

    192.168.0.1/255.255.255.240
         

  • Un valor vacío de en un registro de la tabla significa que los privilegios de dicho registro deben ser combinados con aquellos que se encuentren en el registro de la tabla que concuerde con el nombre del cliente. Los privilegios se combinan utilizando operaciones AND (intersección), no OR (union). Puede encontrar más información sobre la tabla en Sección 5.6.6, “Control de acceso, nivel 2: comprobación de solicitudes”.

    Un valor de en blanco en las otras tablas grant lo mismo que .

Debido a que puede usar comodines en los valores IP de la columna (por ejemplo, para conseguir cualquier IP en una subred), alguien podría intentar explotar esta capacidad poniéndole a su cliente el nombre . Para evitar estos intentos, MySQL no permite que los comodines sean utilizados para los nombres de cliente que empiezan con dígitos y un punto. Así que si tiene un cliente con nombre similar a , su nombre nunca concordará con la columna de las tablas grant. Un comodín de IP solo puede concordar con números IP, no nombres de cliente.

En la columna , los carácteres comodín no están permitidos, pero puede especificar un valor en blanco, que será válido para cualquier nombre. Si el registro de la tabla que concuerda con una conexión entrante tiene un valor vacio, el usuario es considerado anónimo, sin nombre de usuario, no un usuario con el nombre que el cliente especificó realmente. Esto significa que el nombre de usuario vacío es utilizado para todas las comprobaciones de acceso posteriores durante la duración de la conexión (es decir, durante el Estado 2).

La columna puede estar vacía. Esto no es un comodín que permite que cualquier clave sea permitida. Significa que el usuario debe conectarse sin especificar una clave.

Los valores que no están vacíos de en la tabla representan claves cifradas. MySQL no almacena las claves en forma de texto llano para que cualquiera pueda verlo. En vez de esto, la clave suministrada por un usuario que se está intentando conetar es cifrada (utilizando la función ). La clave cifrada se utiliza entonces durante el proceso de conexión en el momento de comprobar si es correcta. (Esto se realiza sin que la clave cifrada viaje nunca sobre la conexión.) Desde el punto de vista de MySQL, la clave cifrada es la clave REAL, así que no debería darse acceso a ella a nadie. En concreto, no de acceso de lectura a las tablas de la base de datos a usuarios no-administrativos.

MySQL 5.0 utiliza el método de autenticación más fuerte (implementado primeramente en MySQL 4.1) y que tiene una mejor protección de la clave durante el proceso de conexión que versiones previas. Es seguro aún cuando los paquetes TCP/IP fuesen interceptados o la base de datos capturada. El cifrado de claves es comentado en mayor profundida en Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1”.

Los siguientes ejemplos nos enseñan como se aplicarían a las conexiones entrantes diferentes combinaciones de los valores de las columnas y de la tabla .

Valor Valor Conexiones que concuerdan con la entrada Entry
, conectando desde
Cualquier usuario, conectando desde
, conectando desde cualquier cliente
Cualquier usuario conectando desde cualquier cliente
, conectando desde cualquier cliente en el dominio
, conectando desde , , , etc. (esto, probablemente, no es útil)
, conectando desde el cliente con dirección IP
, conectando desde cualquier cliente en la subred de clase C
Idéntico al ejemplo anterior

Es posible que el nobre del cliente y del usuario de una conexión entrante concuerde con más de un registro en la tabla . El conjunto de ejemplos precedentes demuestra esto: Algunas de las entradas mostradas concuerdan con una conexión de desde .

Cuando hay la posibilidad de múltiples concordancias, el servidor debe determinar cual de ellas utilizar. El problema se resuelve de la siguiente manera:

  • Siempre que el servidor lee la tabla a memoria, ordena los registros.

  • Cuando un cliente intenta conectar, el servidor mira a través de los registros en el orden establecido.

  • El servidor utiliza el primer registro que concuerda con el nombre y usuario del cliente.

Para ver como esto ocurre, supongamos que la tabla es como esta:

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

Cuando el servidor lee la tabla, ordena las entradas con los valores de más específicos primero. Los nombres de cliente y números de IP son los más específicos. El comodín significa ``cualquier cliente'' y es menos específico. Registros con el mismo valor de se ordenan con el valor de más específico (un valor de en blanco significa ``cualquier usuario'' y es menos específico). En la tabla recién mostrada, el resultado después de ordenar sería el siguiente:

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

Cuando un cliente intenta conectar, el servidor mira los registros ordenados y utiliza la primera concordancia. Para una conexión desde por , dos de las entradas de la tabla concuerdan: la primera con los valores y de y respectivamente, y el registro con los valores y . El registro con valor aparece primero en la tabla ordenada, así que es el que el servidor utiliza.

Aquí hay otro ejemplo. Supongamos que la tabla tiene el siguiente aspecto:

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

La tabla ordenada sería:

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

Una conexión de desde concuerda con el primer registro, mientras que una conexión de desde concuerda con el segundo.

Es una confusión común el pensar que, para un nombre de usuario dado, todos los registros que nombran explícitamente con a ese usuario son utilizadas primero cuando el servidor intenta encontrar una concordancia para una conexión. Esto es sencillamente falso. El ejemplo anterior ilustra esto, donde una conexión de desde no concuerda primero con el registro que contiene como valor en la columna , sino que ha concordado con el registro que no contiene nombre de usuario. Como resultado, es tratado como un usuario anónimo aunque ha especificado un nombre de usuario al conectarse.

Si puede conectar al servidor, pero sus privilegios no son los que espera, probablemente está siendo identificado como algún otro usuario. Para averiguar qué cuenta de usuario utilizó el servidor para identificarle, use la función . Devuelve un valor en formato @ que indica los valores de y del registro concordante en la tabla . Suponga que conecta y ejecuta la siguiente sentencia:

mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost     |
+----------------+

El resultado mostrado indica que el registro que concuerda en la tabla tiene un valor vacío en la columna . En otras palabras, el servidor trata a como a un usuario anónimo.

Otra cosa que puede hacer para localizar problemas de autentificación es imprimir por pantalla la tabla y ordenarla a mano para ver donde está la primera concordancia. Consulte Sección 12.9.3, “Funciones de información”.

5.6.6. Control de acceso, nivel 2: comprobación de solicitudes

Una vez establecida una conexión, el servidor entra en el estado 2 del control de acceso. Por cada petición que viene en la conexión, el servidor determina que operación realizar, y entonces comprueba si tiene suficientes privilegios para hacerlo. Aquí es donde las columnas de privilegios de las tablas grant entran en juego. Esots privilegios puede venir de cualquiera de las tablas , , , , o .(Puede encontrar útil consultar Sección 5.6.2, “Cómo funciona el sistema de privilegios”, que enumera las columnas presentes en cada una de las tablas grant.)

La tabla otorga privilegios que se asignan de manera global, y que se aplican sin importar sobre qué base de datos trabajamos. Por ejemplo, si la tabla le otorga el privilegio , usted podrá borrar registros de cualquier tabla en cualquier base de datos en todo el servidor. En otras palabras, los privilegios de la tabla son privilegios de superusuario. Es aconsejable otorgar privilegios en la tabla sólo a superusuarios tales como administradores de base de datos. Para otros usuarios, debería dejar los privilegios de la tabla con el valor y otorgar los privilegios únicamente a niveles más específicos. Puede otorgar privilegios para bases de datos, tablas o columnas particulares.

Las tablas y otorgan privilegios específicos para una base de datos. Los valores en las columnas de estas tablas pueden tener los siguientes formatos:

  • Los carácteres comodín '' y '' pueden utilizarse en las columnas de cualquiera de las tablas. Estos tienen el mismo significado que en las operaciones de reconocimiento de patrones efectuadas con el operador . Si quiere utilizar cualquiera de estos carácteres literales al otorgar privilegios, debe incluirlos en una secuencia de escape con una barra invertida. Por ejemplo, para incluir el carácter '' como parte del nombre de una base de datos, especifíquelo como '' en la sentencia .

  • Un valor de en la columna de la tabla significa ``cualquier host.'' Un valor vacío en la columna de la tabla significa ``consulta la tabla para más información'' (un proceso que se describe más adelante en esta sección).

  • Un valor de o en blanco en la columna de la tabla significa ``cualquier host.''

  • Un valor de o en blanco de la columna en cualquiera de las dos tablas, significa ``cualquier base de datos.''

  • Un valor en blanco de la columna en cualquiera de las tablas concuerda con el usuario anónimo.

El servidor lee y ordena las tablas y al mismo tiempo que lee la tabla . El servidor ordena la tabla basándose en el rango de las columnas , y , y ordena la tabla basándose en el rango de las columnas y . Igual que con la tabla , la ordenación coloca los valores menos específicos en última posición, y cuando el servidor busca correspondencias, utiliza la primera que encuentra.

Las tablas y otorgan privilegios específicos para tablas y columnas respectivamente. Los valores en las columnas de rango de estas tablas pueden tener los siguientes formatos:

  • Los carácteres comodín '' y '' pueden ser utilizados en la columna de cualquiera de las tablas. Estos comodines tienen el mismo significado que en las operaciones de búsqueda de patrones realizadas con el operador .

  • Un valor de o vacío en la columna de cualquiera de las tablas significa ``cualquier host.''

  • Las columnas , y no pueden contener carácteres comodín ni estar en blanco en ninguna de las tablas.

El servidor ordena las tablas y basándose en las columnas , , y . Esto es similar a la ordenación de la tabla , pero más simple, porque únicamente la columna puede contener comodines.

El proceso de verificación de peticiones se describe aquí. (Si usted está familirizado con el código fuente de control de acceso, se dará cuenta de que la descripción aquí contenida difiere ligeramente de el algoritmo utilizado en el código. La descripción es equivalente a lo que el código hace realmente; solo difiere para hacer la explicación más simple.)

Para peticiones que requieran privilegios de administrador, como o , el servidor comprueba únicamente el registro de la tabla porque es la única tabla que especifica los privilegios administrativos. El acceso se otorga si el registro permita la operación demandada, y es denegado en caso contrario. Por ejemplo, si usted quisiera ejecutar mysqladmin shutdown, pero su registro de la tabla no le otorga el privilegio , el servidor deniega el acceso sin ni siquiera codnsultar las tablas o . (No contienen ninguna columna , así que no hay necesidad de hacerlo.)

Para peticiones sobre bases de datos (, , etc.), el servidor primero comprueba los privilegios globales del usuario (superuser) mirando el registro de la tabla . Si el registro permite la operación demandada, se otorga el acceso. Si los privilegios globales de la tabla son insuficientes, el servidor determina los privilegios específicos sobre la base de datos comprobando las tablas y :

  1. El servidor busca en la tabla una concordancia en las columnas , y . Las columnas y se hacen concordar con el nombre de host y de usuario MySQL. La columna se hace concordar con la base de datos a la que el usuario quiere acceder. Si no hay ningún registro para y , se deniega el acceso.

  2. Si hay un registro que concuerda en el registro de la tabla y su columna no está vacía, ese registro define los privilegios específicos del usuario en la base de datos.

  3. Si la columna del registro concordante de la tabla se encuentra vacía, significa que la tabla enumera qué hosts pueden tener acceso a la base de datos. En este caso, una comprobación más se realiza en la tabla para encontrar una concordancia en las columnas y . Si ningún registro de la tabla concuerda, se deniega el acceso. Si hay una concordancia, los privilegios específicios sobre la base de datos del usuario son calculados como la intersección (¡no unión!) de los privilegios en los registros de las tablas y ; es decir, los privilegios que tienen valor en ambos registros. (De esta manera puede otorgar privilegios en el registro de la tabla y entonces restringir selectivamente host a host utilizando los registros de la tabla .)

Tras determinar los privilegios específicos de la base de datos otorgados por los registros de las tablas y , el servidor los añade a los privilegios globales otorgados por la tabla . Si el resultado permite la operación demandada, se otorga el acceso. En caso contrario, el servidor comprueba sucesivamente la tabla del usuario y los privilegios de las columnas en las tablas y , los añade a los privilegios del usuario, y permite o deniega el acceso basándose en el resultado.

Expresado en términos booleanos, la descripción precedente de como se calculan los privilegios de un usuario, se puede resumir en:

privilegios globales
O (privilegios de base de datos Y privilegios de host)
O privilegios de tabla
O privilegios de columna

Puede no ser evidente por qué, si los privilegios globales del registro en la tabla no han sido inicialmente suficientes para la operación demandada, el servidor añado estos privilegios a los de base de datos, tabla y columna más tarde. La razón es que una petición puede requerir más de un tipo de privilegio. Por ejemplo, si usted ejecuta una sentencia , necesita tanto el privilegio como el privilegio . Sus privilegios podrían estar configurados de manera que la tabla otorgue un privilegio, y la tabla otorgue el otro. En este caso, necesita ambos privilegios para realizar la sentencia, pero el servidor no puede saberlo desde cada una de las tablas únicamente; los privilegios otorgados por los registros de ambas tablas deben ser combinados.

La tabla no es afectada por sentencias o , así que en la mayoría de las instalaciones MySQL queda sin utilizar. Si usted la modifica directamente, puede utilizarla para algunos propósitos específicos, como mantener una lista de servidores seguros. Por ejemplo, en TcX, la tabla contiene una lista de todas las máquinas en la red local. Éstas tienen otorgados todos los privilegios.

También puede utilizar la tabla para indicar hosts que no son seguros. Supongamos que tiene una máquina que está situada en un lugar público que no considera seguro. Puede permitir el acceso a todos los hosts de su red excepto a esa máquina utilizando registros de la tabla como este:

+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (all privileges set to 'N')
| %.your.domain      | %  | ... (all privileges set to 'Y')
+--------------------+----+-

Nauturalmente, usted debe siempre comprobar sus entradas en las tablas grant (por ejemplo, utilizando o mysqlaccess) para estar seguro de que sus privilegios de acceso son realmente los que piensa que son.

5.6.7. Cuándo tienen efecto los camios de privilegios

Cuando mysqld se inicia, todos los contenidos de las tablas grant se leen a memoria y se hacen efectivas para el control de acceso en ese punto.

Cuando el servidor recarga las tablas grant, los privilegios para los conexiones de clientes existentes se ven afectadas de la siguiente manera:

  • Los cambios en los privilegios de tabla y columna toman efecto en la siguiente petición del cliente.

  • Los cambios en privilegio sde base de datos toman efecto en la siguiente sentencia .

  • Los cambios a los privilegios globales y las claves de acceso toman efecto la próxima vez que el cliente se conecte.

Si usted modifica las tablas grant utilizando , , o ,el servidor se da cuenta de estos cambios y recarga las tablas grant en la memoria inmediatamente.

Si usted modifica las tablas grant directamente utilizando sentencias como , , o , los cambios no tendrán efecto en la comprobación de privilegios hasta que se reinicie el servidor, o bien se le comunique a éste que debe recargar las tablas. Para recargar las tablas manualmente, ejecute la sentencia o los comandos mysqladmin flush-privileges o mysqladmin reload.

Si usted cambia las tablas grant directamnete pero olvida recargarlas, sus cambios no tienen efecto hasta que reinicie el servidor. Esto podría confundirle intentando averiguar por qué sus cambios no parecen tener efecto.

5.6.8. Causas de errores Access denied

Si usted se encuentra problemas cuando intenta conectar al servidor MySQL, los siguientes elementos explican algunas medidas que se pueden tomar para corregir el problema.

  • Asegúrese de que el servidor se está ejecutando. Si no se está ejecutando, no puede conectarse a él. Por ejemplo, si intenta conectarse a el servidor y ve un mensaje como cualquiera de los siguientes, podría ser que el servidor no se esté ejecutando:

    shell> mysql
    ERROR 2003: Can't connect to MySQL server on '' (111)
    shell> mysql
    ERROR 2002: Can't connect to local MySQL server through socket
    '/tmp/mysql.sock' (111)
    

    También podría ser que el servidor se esté ejecutando, pero usted se esté intentando conectar utilizando un puerto TCP/IP, named pipe, o archivo socket de Unix diferentes de aquellos a los que el servidor atiende. Para corregir esto cuando invoca a un programa cliente, especifique la opción para indicar el puerto adecuado, o la opción para indicar la named pipi o el archivo socket de Unix apropiados. Para averiguar dónde se encuentra el archivo socket, puede ejecutar:

    shell> netstat -ln | grep mysql
    
  • Las tablas grant deben estar correctamente configuradas para que el servidor pueda utilizarlas en el control de acceso. Para algunos tipos de distribución (como las distribuciones binarias de Windows, o las distribuciones RPM de Linux), el proceso de instalación inicializa la base de datos que contiene las tablas grant. Para distribuciones que no hacen esto, usted debe inicializar las tablas grant manualmente ejecutando el script mysql_install_db. Para más detalles, consulte Sección 2.9.2, “Pasos a seguir después de la instalación en Unix”.

    Una manera de determinar si debe inicializar las tablas grant es buscar un directorio bajo el directorio de datos. (El directorio de datos normalmente se llama o y se encuentra bajo su directorio de instalación de MySQL.) Asegúrese de que tiene un archivo llamado en el directorio de la base de datos. Si no, ejecute el script mysql_install_db. Tras ejecutar este script e iniciar el servidor, compruebe los privilegio siniciales ejecutando este comando:

    shell> mysql -u root test
    

    El servidor debería dejarle conectar sin error.

  • Tras una nueva instalación, usted debería conectarse al servidor y configurar sus usuarios y sus permisos de acceso:

    shell> mysql -u root mysql
    

    El servidor debería dejarle conectar porque el usuario MySQL no tiene clave de acceso inicialmente. Esto, además, es un riesgo de seguridad, así que asignar la clave de acceso para las cuentas es algo que debe hacer mientras se configuran el resto de usuarios. Puede consultar las instrucciones para asignar las claves iniciales aquí Sección 2.9.3, “Hacer seguras las cuentas iniciales de MySQL”.

  • Si usted ha actualizado una instalación MySQL existente a una nueva versión, ¿ejecutó el script mysql_fix_privilege_tables? En caso negativo, hágalo. La estructura de las tablas grant cambia ocasionalmente cuando se añaden nuevas características, así que tras una actualización debería siempre asegurarse de que sus tablas tienen la estructura actual. Para más instrucciones, consulte Sección 2.10.2, “Aumentar la versión de las tablas de privilegios”.

  • Si un programa cliente recibe el siguiente mensaje de error cuando intenta conectar, significa que el servidor está esperando las claves de acceso en un formato más nuevo del que el cliente es capaz de generar:

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

    Para más información sobre atajar este problema, consulte Sección 5.6.9, “Hashing de contraseñas en MySQL 4.1” y Sección A.2.3, “.

  • Si intenta conectarse como y obtiene el siguiente error, significa que usted no tiene un registro en la tabla con un valor en la columna de y que mysqld no puede resolver el nombre de host para su cliente:

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

    En este caso, debería reiniciar el servidor con la opción y editar su archivo o para añadir una entrada para su host.

  • Recuerde que los programas cliente utilizan parámetros de conexión especificados en archivos de opciones o variables de entorno. Si un programa cliente parece estar enviando parámetros de conexión por defecto incorrectos cuando no los especifica en línea de comandos, compruebe su entorno y cualquier archivo de opciones implicado. Por ejemplo, si obtiene cuando intenta ejecutar un cliente sin ninguna opción, asegúrese de que no ha especificado una clave de acceso antigua en sus archivos de opciones.

    Puede suprimir el uso de archivos de opciones por parte de un programa cliente invocándolo con la opción . Por ejemplo:

    shell> mysqladmin --no-defaults -u root version
    

    Los archivos de opciones que los clientes utilizan están enumerados en Sección 4.3.2, “Usar ficheros de opciones”. Las variables de entorno se enumeran en Apéndice E, Variables de entorno.

  • Si obtiene el siguiente error, significa que está utilizando una clave de incorrecta:

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

    Si este error precedente ocurre aún cuando usted no ha especificado ninguna clave de acceso, significa que tiene una clave incorrecta en algún archivo de opciones. Intente utilizar la opción como se explica en el punto anterior.

    Para más información sobre el cambio de claves, consulte Sección 5.7.5, “Asignar contraseñas a cuentas”.

    Si usted ha perdido u olvidado la clave de , puede reiniciar mysqld con para cambiar la clave. Consulte Sección A.4.1, “Cómo reiniciar la contraseña de root”.

  • Si usted cambia la clave utilizando , , o , debe cifrar la clave utilizando la función . Si no utiliza para estas sentencias, la clave no funcionará. Por ejemplo, la siguiente sentencia asigna una clave, pero no la cifra, así que el usuario no es capaz de conectar tras ella:

    mysql> SET PASSWORD FOR 'abe'@'' = 'eagle';
    

    En vez de esto, debe establecer la clave así:

    mysql> SET PASSWORD FOR 'abe'@'' = PASSWORD('eagle');
    

    La función no es necesaria cuando se especifica la clave utilizando sentencias o (a partir de MySQL 5.0.2) , o también con el comando mysqladmin password, los cuales utilizan automáticamente para cifrar la clave. Consulte Sección 5.7.5, “Asignar contraseñas a cuentas” y Sección 13.5.1.1, “Sintaxis de .

  • es un sinónimo para su nombre de máquina local, y también es la máquina por defecto al que los clientes se intentan conectar si no se especifica explícitamente.

    Para evitar este problema en sistemas como ese, puede utilizar la opción para mencionar la máquina t explícitamente. Esto crea una conexión TCP/IP al servidor mysqld local. También puede utilizar TCP/IP especificando una opción que utilice el nombre real de la máquina local. En este caso, el nombre de host debe ser especificado en una fila de la tabla del servidor, aun cuando el cliente esté corriendo en la misma máquina que el servidor.

  • Si obtiene un error cuando intenta conectarse a la base de datos con , puede que tenga un problema con la tabla . Compruebe esto ejecutando e introduciendo esta sentencia SQL:

    mysql> SELECT * FROM user;
    

    El resultado debería incluir una fila cuyas columnas y coincidan con el nombre de su máquina y su nombre de usuario MySQL.

  • El mensaje de error indica con qué nombre de usuario se está intentando entrar al sistema, la máquina cliente desde la que se está intentando conectar, y si se está utilizando clave de acceso o no. Normalmente, debería tener una línea en la tabla que concuerde exactamente con el nombre de máquina y el nombre de usuario que se ha obtenido en el mensaje de error. Por ejemplo, si obtiene un mensaje de error que contiene , significa que se ha intentado entrar sin utilizar una clave de acceso.

  • Si el siguiente error aparece cuando se intenta conectar desde una máquina diferente a la que está ejecutando el servidor MySQL, significa que no hay ninguna fila en la tabla con un valor que concuerde con la máquina cliente:

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

    Puede corregir esto estableciendo una cuenta para la combinación de nombre de máquina y usuario que está utilizando cuando se intenta conectar.

    Si usted no conoce el número de IP o el nombre de máquina del ordenador desde el que se está conectando, debería poner una fila con un valor de en la columna de la tabla , y reiniciar mysqld en el servidor con la opción . Tras intentar conectar desde la máquina cliente, la información en el log de MySQL indica desde donde se conectó realmente. (Entonces cambie el valor en la tabla para introducir el nombre real de la máquina que se muestra en el log. De otra manera obtendría un sistema inseguro, porque permitiría conexiones desde cualquier máquina para ese usuario dado.)

    En Linux, hay otra razón por la que este error puede ocurrir, y es que esté utilizando una versión binaria de MySQL que haya sido compilada con una versión diferente de la librería de la que usted está utilizando. En este caso, usted debería actualizar su sistema operativo o , o descargarse una distribución MySQL en código fuente y compilarla usted mismo. Un paquete RPM de código fuente es, normalmente, trivial de compilar e instalar, así que esto no es un gran problema.

  • Si especifica un nombre de máquina cuando se intenta conectar, pero obtiene un mensaje de error donde el nombre de máquina no se muestra, o es un número IP, significa que el servidor MySQL obtuvo un error al intentar resolver el número IP de el cliente a un nombre:

    shell> mysqladmin -u root -p -h  ver
    Access denied for user 'root'@'' (using password: YES)
    

    Esto indica que existe un problema con DNS. Para arreglarlo, ejecute mysqladmin flush-hosts para reestablecer la cache interna de DNS. Consulte Sección 7.5.6, “Cómo usa MySQL las DNS”.

    Estas son algunas soluciones permanentes:

    • Intente encontrar qué le ocurre a su servidor DNS y arréglelo.

    • Especifique números IP en vez de nombres de máquina en las tablas grant de MySQL

    • Introduzca una línea para la máquina cliente en .

    • Ejecute mysqld con la opción .

    • Ejecute mysqld con la opción .

    • En Unix, si está ejecutando el servidor y el cliente en la misma máquina, conéctese a . Las conexiones a en Unix utilizan un archivo socket en vez de TCP/IP.

    • En Windows, si está ejecutando cliente y servidor en la misma máquina, y el servidor tiene activada la característica de conexión mediante named pipe, conéctese a (punto). Las conexiones a utilizan una named pipe en vez de TCP/IP.

  • Si el comando funciona pero -u root test termina con un (donde es el nombre real de su máquina local), puede que no haya especificado correctamente el nombre de su máquina en la tabla . Un problema común es que el valor de en la fila de la tabla especifique un nombre de máquina incompleto, pero las rutinas de resolución de nombres de dominio de su sistema retornen un nombre de dominio completo (o viceversa). Por ejemplo, si tiene una entrada con valor en de la tabla , pero sus DNS dicen qeu su nombre de máquina es , esta entrada no funcionará. Intente añadir una entrada a la tabla con un valor de que contenga un comodín; por ejemplo . ¡En cualquier caso, el uso de nombres que acaben con '' es inseguro y no recomendado!

  • Si test funciona pero no funcionado, entonces es que no tiene concedidos los permisos para acceder a la base de datos para ese usuario dado.

  • Si funciona cuando se ejecuta en la máquina del servidor, pero -u no lo hace cuando se ejecuta en una máquina cliente remota, entonces no tiene activado el acceso a el servidor para el usuario dado en la máquina remota.

  • Si no es capaz de averiguar por qué obtiene el error de , borre de la tabla todos los valores que contengan comodines (que contengan carácteres '' o ''). Un error muy común es insertar un nuevo registro con = y =', pensando que esto permite especificar que se conecte desde la misma máquina. La razón por la que esto no funciona es que los privilegios por defecto incluyen un registro con = y =. Debido a que ese registro es más específico que , se utiliza preferentemente frente al nuevo registro cuando conecta desde . El procedimiento correcto es insertar una segunda entrada con = y =', o borrar la entrada con = y =. Tras borrar la entrada, recuerde ejecutar una sentencia para recargar las tablas grant.

  • Si obtiene el siguiente error, puede ser que tenga un problema con las tablas o :

    Access to database denied
    

    Si la entrada seleccionada de la tabla contiene un valor vacio en la columna , asegúrese de que hay una o más entradas correspondientes en la tabla especificando a qué máquinas se aplica la entrada de la tabla .

  • Si usted puede conectar al servidor MySQL, pero obtiene un mensaje siempre que ejecuta una sentencia o , su entrada en la tabla no tiene el privilegio activado.

  • Si cambia las tablas grant directamente (por ejemplo, mediante sentencias , , o ) y sus cambios parecen que son ignorados, recuerde que debe ejecutar la sentencia statement or el comando mysqladmin flush-privileges para que el servidor relea las tablas de privilegios. En otro caso, los cambios no tendrán efecto hasta la próxima vez que el servidor sea reiniciado. Recuerde que tras cambiar la clave de con un comando , no necesita especificar la nueva clave hasta que se haga la relectura de privilegios, porque el servidor no sabrá que la clave ha cambiado hasta ese momento.

  • Si sus privilegios parecen haber cambiado en el medio de una sesión, podría ser que un administrador de MySQL los haya cambiado. La recarga de las tablas grant afecta a las nuevas conexiones de cliente, pero también a las ya existentes tal y como se indica en Sección 5.6.7, “Cuándo tienen efecto los camios de privilegios”.

  • Si tiene problemas de acceso con un programa Perl, PHP, Python u ODBC, intente conectar al servidor con o -p . Si puede conectar utilizando el programa cliente mysql, el problema está en su programa, no en los privilegios de acceso. (No hay ningún espacio entre y la clave; también puede utilizar la sintaxis para especificar la clave. Si utiliza la opción sola, MySQL le preguntará por la clave.)

  • Para hacer comprobaciones, inicie el servidor mysqld con la opción . Puede cambiar las tablas grant y utilizar el script mysqlaccess para comprobar que sus modificaciones tienen el efecto deseado. Cuando esté satisfecho con los cambios, ejecute mysqladmin flush-privileges para decirle al servidor mysqld que comience a utilizar las nuevas tablas grant. (Recargar las tablas sobresee la opción . Esto permite decirle al servidor que comience a utilizar las tablas sin tener que reiniciarlo.)

  • Si todo lo anterior falla, inicie el servidor mysqld con una opción de depuración (por ejemplo, ). Esto imprime la información de host y usuario sobre los intentos de conexión, así como información sobre cada comando ejecutado. Consulte Sección D.1.2, “Crear ficheros de traza”.

  • Si tiene cualquier otro problema con las tablas grant de MySQL y cree que debe enviar el problema a la lista de correo, proporcione siempre un volcado de las tablas grant MySQL. Puede hacer ete volcado con el comando mysqldump mysql. Como siempre, envíe su problema utilizando el script mysqlbug. Consulte Sección 1.6.1.3, “Cómo informar de bugs y problemas”. En elgunos casos, podría necesitar reiniciar mysqld con para ejecutar mysqldump.

5.6.9. Hashing de contraseñas en MySQL 4.1

Las cuentas de usuario de MySQL se listan en la tabla de la base de datos . Cada cuenta MySQL tiene una contraseña asiganada, aunque lo que se guarda en la columna de la tabla no es una versión en texto plano de la contraseña, si no un valor hash computado a partir de la misma. Los valores hash de las contraseñas se obtienen a partir de la función .

MySQL usa contraseñas en dos fases de la comunicación cliente/servidor:

  • Cuando un cliente trata de conectar al servidor, hay un paso inicial de autenticación en el que el cliente debe presentar una contraseña cuyo valor hash coincida con el valor hash almacenado en la tabla para la cuenta que el cliente quiere usar.

  • Una vez que el cliente conecta, puede (si tiene los suficientes permisos) cambiar o incializar los hashes de las contraseñas para las cuentas listadas en la tabla . El cliente puede hacerlo mediante la función para generar el hash de la contraseña, o mediante los comandos o .

En otras palabras, el servidor usa los valores hash durante la autenticación cuando un cliente trata de conectar por primera vez. El servidor genera valores hash si un cliente conectado invoca la función o usa los comandos o para inicializar o cambiar una contraseña.

El mecanismo de hash de contraseñas se actualizó en MySQL 4.1. para proporcionar una mejor seguridad y para reducir el riesgo de intercepción de contraseñas. Sin embargo, este nuevo mecanismo sólo lo entienden los servidores y clientes MySQL 4.1. (y versiones posteriores), lo cual puede acarrear algunos problemas de compatibilidad. Un cliente 4.1. o posterior puede conectar a un servidor pre-4.1, ya que el cliente entiende los mecanismos de hashing de contraseñas antiguos y nuevos. Sin embargo, un cliente pre-4.1. que trate de conectar a un servidor 4.1. o posterior puede tener problemas. Por ejemplo, un cliente 3.23 mysql que trate de conectar a un servidor 5.0 puede fallar con el siguiente mensaje de error:

shell> mysql -h localhost -u root
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

Otro ejemplo común es cuando se trata de usar la antigua extensión de mysql para PHP tras actualizar a MySQL 4.1 o posterior. (Consulte Sección 24.4.1, “Problemas comunes con MySQL y PHP”.)

La siguiente discusión describe las diferencias entre el antiguo y nuevo mecanismo de contraseñas, y qué debe hacer si actualiza su servidor pero necesita matener compatibilidad con clientes versión pre-4.1. Puede encontrar información adicional en Sección A.2.3, “. Esta información es de especial importancia para programadores de PHP que migran de versiones de bases de datos MySQL 4.0 o anteriores a versiones 4.1. o posteriores.

Nota: Esta discusión contrasta el comportamiento 4.1. con el pre-4.1, pero el comportamiento 4.1 descrito aquí realmente empieza en el 4.1.1. MySQL 4.1.0 es una versión ``particular'' ya que tiene mecanismos ligeramente distintos a los implementados en 4.1.1 y posteriormente. Las diferencias entre 4.1.0 y reciones más recientes se describen con más detalle en Manual de referencia de MySQL 4.1.

Antes de MySQL 4.1, los hashes de contraseñas computados por la función tienen una longitud de 16 bytes. Tales hashes tienen este aspecto:

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

La columna de la tabla (en la que se guardan los hashes) también tiene una longitud de 16 bytes antes de MySQL 4.1.

En MySQL 4.1, la función se modificó para producir un valor hash más largo de 41-bytes:

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

Por consiguiene, la columna en la tabla debe tener una longitud de 41 bytes para almacenar estos valores:

  • Si realiza una nueva instalación de MySQL 5.0, la columna se amplía a 41 bytes automáticamente.

  • Actualizar desde MySQL 4.1 (4.1.1 o posterior en la serie 4.1 ) a MySQL 5.0 no debería afectar a nada de todo esto, ya que ambas versiones usan el mismo mecanismo de hash de contraseñas. Si desea actualizar una versión antorior de MySQL a 5.0, debe actualizar primero a la versión 4.1, y luego actualizar la instalación de 4.1. a 5.0.

Una columna más amplia puede almacenar hashes de contraseñas en el antiguo y nuevo formato. El formato de cualquier valor hash de una contraseña puede determinarse de dos formas:

  • La diferencia óbvia es la longitud (16 bytes contra 41 bytes).

  • Una segunda diferencia es que los hashes de contraseñas en el nuevo formato simpre empieza con un carácter '', mientras que una contraseña en el antiguo formato nunca lo hace.

El hash de la contraseña más larga tiene mejores propiedades criptográficas, y la autenticación de clientes basada en hashes largos es más segura que la basada en los antiguos hashes cortos.

Las diferencias entre hashes cortos y largos son relevantes para cómo el servidor usa las contraseñas durante la autenticación y por cómo genera los hashes de contraseñas para clientes conectados que realizan operaciones de cambio de contraseña.

La forma en que el servidor usa los hashes de contraseñas durante la autenticación se ve afectada por la longitud de la columna :

  • Si la columna es corta, sólo se usa autenticación de hash cortos.

  • Si la columna es larga, puede soportar hashes cortos o largos, y el servidor puede usar cualquier formato:

    • Clientes pre-4.1 pueden conectar, aunque sólo conocen el antiguo mecanismo de hash, pueden autenticar sólo para cuentas que tengan hashes cortos.

    • Clientes 4.1 y posterior pueden autenticar para cuentas que tengan hashes cortos o largos.

Para cuentas con hash corto, el proceso de autenticación es un poco más seguro para clientes 4.1 y posteriores que para clientes más antiguos. Respecto a seguridad, el gradienet de menos a más seguro es:

  • Cliente pre-4.1 autenticando con hash de contraseña corto

  • Cliente 4.1 o posterior autenticando con hash de contraseña corto.

  • Cliente 4.1 o posterior autenticando con hash de contraseña largo.

La forma en que el servidor genera los hashes de contraseña para clientes conectados se ve afectado por la longitud de la columna y por la opción . Un servidor 4.1. o posterior genera hashes largos sólo si se cumplen ciertas condiciones: La columna debe ser lo suficientemente larga para guardar valores largos y no debe darse la opción . Estas condiciones se aplican como sigue:

  • La columna debe ser lo suficientemente grande para guardar hashes largos (41 bytes). Si la columna no se ha actualizado y todavía tiene la longitud pre-4.1 de 16 bytes, el servidor entiende que no puede guardar hashes largos y genere sólo hashes cortos cuando un cliente realiza opraciones de cambio de contraseña mediante , , o . Este es el comportamiento que ocurre si ha actualizado a 4.1 pero no ha ejecutado todavía el script mysql_fix_privilege_tables para ensanchar la columna .

  • Si la columna es amplia, puede almacenar tanto hashes de contraseñas largos como cortos. En este caso, , , y generan hashes largos a no ser que el servidor se haya iniciado con la opción . Este opción fuerza al servidor a generar hashes de contraseñas cortos.

El propósito de la opción es permitirle mantener compatibilidad con clientes anteriores a 4.1 bajo circunstancias donde el servidor generaría hashes de contraseñas largos. La opción no afecta la autenticación (clientes 4.1. y posteriores pueden usar cuentas que tengan hashes largos de contraseña), pero no evita la creación de hashes largos de contraseñas en la tabla como resultado de una operación de cambio de contraseña. Si eso ocurre, la cuenta no puede usarse por clientes pre-4.1. Sin la opción , es posible el siguiente escenario no deseable:

  • Un cliente viejo trata de conectar a una cuenta que tenga hash de contraseña corto.

  • El cliente cambia su propia contraseña. Sin , esto acaba con la cuenta con un hash de contraseña largo.

  • La siguiente vez que el viejo cliente trate de conectar a la cuenta, no podrá, ya que la cuenta tiene un hash de contraseña largo que requiere un nuevo mecanismo de hash durante la autenticación. (Una vez que una cuenta tiene un hash de contraseña largo en la tabla de usuario, sólo clientes 4.1. y posteriores pueden autenticar, ya que clientes pre-4.1. no entienden hashes largos.)

Este escenario ilustra que, si debe soportar clientes pre-4.1, es peligroso ejecutar un servidor 4.1 o posterior sin usar la opción . Ejecutando el servidor con , las operaciones de cambio de contraseña no generan hashes largos de contraseña y por lo tanto, no provocan que las cuentas sean inaccesibles para clientes antiguos. (Aquellos clientes no pueden bloquearse a ellos mismos mediante el cambio de su contraseña y acabando con un hash de contraseña largo.)

La desventaja de la opción es que cualquier contraseña que cree o cambie usará hashes cortos, incluso para clientes 4.1. Así, pierde la seguridad adicional proporcionada por los hashes de contraseña largos. Si quiere crear una cuenta que tiene un hash largo (por ejemplo, para usar con un cliente 4.1), debe hacerlo mientras el servidor se esté ejecutando sin .

Los siguientes escenarios son posibles al ejecutar un servidor 4.1 o posterior, incluyendo servidores MySQL 5.0:

Escenario 1:Columna corta en tabla de usuario:

  • Sólo se pueden guardar hashes cortos en la columna .

  • El servidor usa sólo hashes cortos durante la autenticación del cliente.

  • Para clientes conectados, las operaciones de generación de hashes de contraseñas mediante , , o usan hashes cortos exclusivamente. Cualquier cambio a una contraseña de una cuenta resulta en una cuenta teniendo un hash de contraseña corto.

  • La opción puede usarse pero es supérflua ya que con una columna corta, el servidor genera sólo hashes de contraseña cortos de todas formas..

Escenario 2: Columna larga; servidor no arrancado con la opción :

  • Hashes cortos o largos pueden almacenarse en la columna .

  • Clientes 4.1 y posteriores (incluyendo clientes 5.0) pueden autenticar para cuentas que tengan tanto hashes cortos como largos.

  • Clientes pre-4.1 pueden autenticar sólo para cuentas que tengan hashes cortos.

  • Para clientes conectados, operaciones generadoras de hash como , , o usan hashes largos exclusivamente. Un cambio en la contraseña de una cuenta resulta en dicha cuenta con un hash largo.

Como se ha indicado, un peligro en este escenario es que es posible para cuentas con hash corto quedar inaccesibles para clientes pre-4.1. Un cambio en tales contraseñas hecho via , , o resulta en la cuenta con una contraseña larga. A partir de ahí, ningún cliente pre-4.1 puede autenticar a dicha cuenta hasta que el cliente actualice a 4.1.

Para tratar este problema, puede cambiar una contraseña de forma especial. Por ejemplo, normalmente usa como sigue para cambiar una contraseña de cuenta:

mysql> SET PASSWORD FOR ''@'' = PASSWORD('mypass');

Para cambiar la contraseña pero crear un hash corto, use la función en su lugar:

mysql> SET PASSWORD FOR ''@'' = OLD_PASSWORD('mypass');

es útil para situaciones en que explícitamente quiera generar un hash corto.

Escenario 3: Columna larga; servidor 4.1 o posterior arrancado con la opción :

  • Hashes crotos o largos pueden guardarse en la columna .

  • Clientes 4.1 y posteriores pueden autenticar para cuentas que tengan hashes cortos o largos ( pero tenga en cuenta que es posible crear hashes largos sólo cuando el servidor se arranca sin ).

  • Clientes pre-4.1 clients pueden autenticar sólo para cuentas que tengan hashes cortos.

  • Para clientes conectados, operaciones de generación de hashes como , , o usan hashes cortos exclusivamente. Cualquier cambio en la contraseña de una cuenta resulta en que dicha cuenta tenga un hash de contraseña corto.

En este escenario, no puede crear cuentas que tengan hashes de contraseña cortos, ya que la opción evita la generación de hashes largos. También, si crea una cuenta con hashes largos antes de usar la opción , cambiar la contraseña de la cuenta mientras está en efecto resulta en la cuenta teniendo una contraseña corta, causando que se pierdan los beneficios de seguridad de un hash más largo.

Las desventajas de estos escenarios pueden resumirse así:

En el escenario 1, no puede beneficiarse de hashes largos que proporcionan más seguridad de autenticación.

En el escenario 2, las cuentas con hashes cortos son inaccesibles para clientes pre-4.1 si cambia sus contraseñas sin usar explícitamente .

En el escenario 3, evita que las cuentas con hashes cortos sean inaccesibles, pero las operaciones de cambio de contraseña causa que las cuentas con hashes largos vuelvan a ser hashes cortos, y no puede volver a hacerlos hashes largos mientras tenga efecto.

5.6.9.1. Implicación del cambio en el hashing de contraseñas en aplicativos

Una actualización a MySQL 4.1 o posterior puede provocar problemas de compatibilidad para aplicaciones que usen para generar contraseñas para sus propios propósitos. Las aplicaciones no deben hacer esto, ya que debe usarse sólo para administrar contraseñas para cuentas MySQL. Pero algunas aplicaciones usan para sus propios propósitos de todas formas.

Si actualiza a 4.1 o posterior desde versiones pre-4.1 de MySQL y ejecuta el servidor bajo condiciones donde genera hashes largos de contraseñas, una apliación usando para sus propias contraseñas falla. El curso recomendado de ación en tales casos es modificar la aplicación para usar otra función, tal como o , para producir hashes de valores. Si esto no es posible, puede usar la función , que se proporciona para generar hashes cortos en el viejo formato. Sin embargo, debe tener en cuenta que puede dejar de ser soportado en alguna futura versión.

Si el servidor está ejecutándose bajo circunstancias donde genera hashes cortos, está disponible pero es equivalente a .

Los programadores de PHP migrando sus bases de datos MySQL de la versión 4.0 o anteriores a la versión 4.1 o posterior deben consultar Old Client.