MySQL tiene un sistema avanzado pero no estándard de seguridad y privilegios. Esta sección describe su funcionamiento.
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 SELECT
, INSERT
,
UPDATE
, y DELETE
.
Funcionalidad adicional incluye la habilidad de tener usuarios
anónimos y de dar privilegios para funciones específicas de
MySQL tales como LOAD DATA INFILE
y
operaciones administrativas.
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 joe
que
conecta desde office.com
no tiene porqué ser
la misma persona que el usuario joe
que
conecta desde elsewhere.com
. MySQL trata esto
permitiendole distinguir usuarios en diferentes equipos que
tienen el mismo nombre. Puede otorgar un conjunto de privilegios
para conexiones de joe
desde
office.com
, y un conjunto distinto para
conexiones de joe
desde
elsewhere.com
.
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
SELECT
para la tabla o el permisoDROP
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 mysql
(esto es,
en la base de datos llamada mysql
). 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 GRANT
y
REVOKE
para configurar cuentas y controlar
los privilegios disponibles para cada una. Consulte
Sección 13.5.1.3, “Sintaxis de GRANT
y REVOKE
”. 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 user
,
db
, y host
en la base de
datos mysql
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 |
Host
|
Host
|
Host
|
User
|
Db
|
Db
|
|
Password
|
User
|
||
Columnas privilegios |
Select_priv
|
Select_priv
|
Select_priv
|
Insert_priv
|
Insert_priv
|
Insert_priv
|
|
Update_priv
|
Update_priv
|
Update_priv
|
|
Delete_priv
|
Delete_priv
|
Delete_priv
|
|
Index_priv
|
Index_priv
|
Index_priv
|
|
Alter_priv
|
Alter_priv
|
Alter_priv
|
|
Create_priv
|
Create_priv
|
Create_priv
|
|
Drop_priv
|
Drop_priv
|
Drop_priv
|
|
Grant_priv
|
Grant_priv
|
Grant_priv
|
|
Create_view_priv
|
Create_view_priv
|
Create_view_priv
|
|
Show_view_priv
|
Show_view_priv
|
Show_view_priv
|
|
Create_routine_priv
|
Create_routine_priv
|
||
Alter_routine_priv
|
Alter_routine_priv
|
||
References_priv
|
References_priv
|
References_priv
|
|
Reload_priv
|
|||
Shutdown_priv
|
|||
Process_priv
|
|||
File_priv
|
|||
Show_db_priv
|
|||
Super_priv
|
|||
Create_tmp_table_priv
|
Create_tmp_table_priv
|
Create_tmp_table_priv
|
|
Lock_tables_priv
|
Lock_tables_priv
|
Lock_tables_priv
|
|
Execute_priv
|
|||
Repl_slave_priv
|
|||
Repl_client_priv
|
|||
Columnas seguridad |
ssl_type
|
||
ssl_cipher
|
|||
x509_issuer
|
|||
x509_subject
|
|||
Columnas recursos control |
max_questions
|
||
max_updates
|
|||
max_connections
|
|||
max_user_connections
|
Execute_priv
se presentó en MySQL 5.0.0,
pero no fue operacional hasta MySQL 5.0.3.
Las columnas Create_view_priv
y
Show_view_priv
se añadieron en MySQL 5.0.1.
Las columnas Create_routine_priv
,
Alter_routine_priv
, y
max_user_connections
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
user
, db
, y
host
, el servidor puede consultar las tablas
tables_priv
y columns_priv
para peticiones que impliquen tablas. Las tablas
tables_priv
y columns_priv
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 |
Host
|
Host
|
Db
|
Db
|
|
User
|
User
|
|
Table_name
|
Table_name
|
|
Column_name
|
||
Columnas privilegios |
Table_priv
|
Column_priv
|
Column_priv
|
||
Otras columnas |
Timestamp
|
Timestamp
|
Grantor
|
Las columnas Timestamp
y
Grantor
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
procs_priv
. Esta tabla tiene las siguientes
columnas:
Nombre tabla | procs_priv |
Alcance de columnas |
Host
|
Db
|
|
User
|
|
Routine_name
|
|
Routine_type
|
|
Columnas privilegios |
Proc_priv
|
Otras columnas |
Timestamp
|
Grantor
|
La tabla procs_priv
existe desde MySQL 5.0.3.
La columna Routine_type
se añadió en MySQL
5.0.6. Hay una columna ENUM
con valores de
'FUNCTION'
o 'PROCEDURE'
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 Timestamp
y
Grantor
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
user
con los valoresHost
yUser
de'thomas.loc.gov'
y'bob'
se usarían para autenticar conexiones hechas al servidor desde el equipothomas.loc.gov
por un cliente que especifique un nombre de usuario debob
. De forma similar, un registro de la tabladb
con las columnasHost
,User
, yDb
con valores'thomas.loc.gov'
,'bob'
y'reports'
se usaría cuandobob
conectase desde el equipothomas.loc.gov
para acceder a la base de datosreports
. Las tablastables_priv
ycolumns_priv
contienen columnas de alcance indicando tablas o combinaciones de tabla/columna para las que cada registro se aplica. La columna de alcanceprocs_priv
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 |
Host
|
CHAR(60)
|
User
|
CHAR(16)
|
Password
|
CHAR(16)
|
Db
|
CHAR(64)
|
Table_name
|
CHAR(64)
|
Column_name
|
CHAR(64)
|
Routine_name
|
CHAR(64)
|
Con propósito de chequeos de acceso, las comparaciones de los
valores de Host
no tienen en cuenta
mayúsculas y minúsculas. Los valores de
User
, Password
,
Db
, y Table_name
son
sensibles a mayúsculas y minúsuclas. Los valores de
Column_name
no son sensibles a mayúsculas y
minúsculas.
En las tablas user
, db
, y
host
, cada privilegio se lista en una
columna separada que se declara como ENUM('N','Y')
DEFAULT 'N'
. En otras palabras, cada privilegio puede
estar desactivado o activado, estando desactivados por defecto.
En las tablas tables_priv
,
columns_priv
, and
procs_priv
, las columnas de privilegios se
declaran como columnas de tipo SET
. 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 |
tables_priv
|
Table_priv
|
'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop',
'Grant', 'References', 'Index', 'Alter'
|
tables_priv
|
Column_priv
|
'Select', 'Insert', 'Update', 'References'
|
columns_priv
|
Column_priv
|
'Select', 'Insert', 'Update', 'References'
|
procs_priv
|
Proc_priv
|
'Execute', 'Alter Routine', 'Grant'
|
Brevemente, el servidor usa las tablas de permisos como sigue:
-
Las columnas de alcance de la tabla
user
determinan si se rechazan o permiten conexiones entrantes. Para conexiones permitidas, cualquier privilegio otorgado en la tablauser
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
db
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
host
se usa en conjunción con la tabladb
cuando desea que un registro de la tabladb
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 valorHost
vacío en el registro de usuario de la tabladb
, luego rellene la tablahost
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
host
no se ve afectada por los comandosGRANT
niREVOKE
. La mayoría de instalaciones MySQSL no necesitan usar esta tabla en absoluto. -
Las tablas
tables_priv
ycolumns_priv
son similares a la tabladb
, 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
procs_priv
se aplica a rutinas almacenadas. Un privilegio otorgado a nivel de rutina se aplica sólo a una única rutina.
Permisos administrativos (tales como RELOAD
o
SHUTDOWN
) se especifican sólo en la tabla
user
. 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
user
.
El privilegio FILE
también se especifica
sólo en la tabla user
. 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 FLUSH
PRIVILEGES
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 SHOW GRANTS
. Por ejemplo, para
determinar los permisos que se otorgan a una cuenta con valores
Host
y User
de
pc84.example.com
y bob
,
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
--help
para ver cómo funciona. Note que
mysqlaccess chequea acceso usando sólo las
tablas user
, db
, y
host
. No chequea los privilegios de tabla,
columna, o rutina especificados en las tablas
tables_priv
, columns_priv
,
o procs_priv
.
Para ayuda adicional en problemas relacionados con el
diagnóstico de permisos, consulte
Sección 5.6.8, “Causas de errores Access denied
”. Para consejos generales sobre
seguridad , consulte Sección 5.5, “Cuestiones de seguridad general”.
La información sobre los privilegios de las cuentas está
almacenada en las tablas user
,
db
, host
,
tables_priv
, columns_priv
,
y procs_priv
de la base de datos
mysql
. 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
GRANT
y REVOKE
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 GRANT
y REVOKE
”.
Privilegio | Columna | Contexto |
CREATE
|
Create_priv
|
bases de datos, tablas, o índices |
DROP
|
Drop_priv
|
bases de datos o tablas |
GRANT OPTION
|
Grant_priv
|
bases de datos, tablas, o procedimientos almacenados |
REFERENCES
|
References_priv
|
bases de datos o tables |
ALTER
|
Alter_priv
|
tablas |
DELETE
|
Delete_priv
|
tablas |
INDEX
|
Index_priv
|
tablas |
INSERT
|
Insert_priv
|
tablas |
SELECT
|
Select_priv
|
tablas |
UPDATE
|
Update_priv
|
tablas |
CREATE VIEW
|
Create_view_priv
|
vistas |
SHOW VIEW
|
Show_view_priv
|
vistas |
ALTER ROUTINE
|
Alter_routine_priv
|
procedimientos almacenados |
CREATE ROUTINE
|
Create_routine_priv
|
procedimientos almacenados |
EXECUTE
|
Execute_priv
|
procedimientos almacenados |
FILE
|
File_priv
|
acceso a archivos en la máquina del servidor |
CREATE TEMPORARY TABLES
|
Create_tmp_table_priv
|
administración del servidor |
LOCK TABLES
|
Lock_tables_priv
|
administración del servidor |
CREATE USER
|
Create_user_priv
|
administración del servidor |
PROCESS
|
Process_priv
|
administración del servidor |
RELOAD
|
Reload_priv
|
administración del servidor |
REPLICATION CLIENT
|
Repl_client_priv
|
administración del servidor |
REPLICATION SLAVE
|
Repl_slave_priv
|
administración del servidor |
SHOW DATABASES
|
Show_db_priv
|
administración del servidor |
SHUTDOWN
|
Shutdown_priv
|
administración del servidor |
SUPER
|
Super_priv
|
administración del servidor |
CREATE VIEW
y SHOW VIEW
fueron añadidos en MySQL 5.0.1. CREATE USER
,
CREATE ROUTINE
, y ALTER
ROUTINE
fueron añaidos en MySQL 5.0.3. Aunque
EXECUTE
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 SUPER
, tal y como se explica en
Sección 19.3, “Registro binario de procedimientos almacenados y disparadores”.
Los privilegios CREATE
y
DROP
permiten crear nuevas bases de datos y
tablas, o eliminar las existentes. Si otorga el
privilegio DROP
para la base de datos
mysql
a un usuario, ese usuario puede
eliminar la base de datos en la que MySQL almacena los
privilegios de acceso.
Los privilegios SELECT
,
INSERT
, UPDATE
, and
DELETE
permiten realizar operaciones en
registros de tablas existentes en una base de datos.
Las sentencias SELECT
requieren el privilegio
SELECT
sólo si realmente extraen registros
de una tabla. Algunas sentencias SELECT
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 INDEX
permite crear o eliminar
índices. INDEX
es aplicable a tablas
existentes. Si tiene el privilegio CREATE
para una tabla, entonces puede incluir definiciones de índices
en la sentencia CREATE TABLE
.
El privilegio ALTER
permite utilizar
ALTER TABLE
para cambiar la estructura de o
renombrar tablas.
El privilegio CREATE ROUTINE
es necesario
para crear procedimientos almacenados (funciones y
procedimientos). El privilegio ALTER ROUTINE
se necesita para modificar o eliminar procedimientos
almacenados, y EXECUTE
es necesario para
ejecutarlos.
El privilegio GRANT
permite dar a otros
usuarios las privilegios que uno mismo posee. Puede ser
utilizado para bases de datos, tablas, y procedimientos
almacenados.
El privilegio FILE
otorga permiso para leer y
escribir archivos en la máquina del servidor utilizando las
sentencias LOAD DATA INFILE
y SELECT
... INTO OUTFILE
. Un usuario que tiene el privilegio
FILE
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 FILE
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 |
RELOAD
|
flush-hosts , flush-logs ,
flush-privileges ,
flush-status ,
flush-tables ,
flush-threads ,
refresh , reload |
SHUTDOWN
|
shutdown
|
PROCESS
|
processlist
|
SUPER
|
kill
|
El comando reload
comunica al servidor que
debe releer las tablas grant a memoria.
flush-privileges
es un sinónimo de
reload
. El comando reload
cierra y vuelve a abrir los archivos de registro y vuelca todas
las tablas. Los otros comandos
flush-
xxx
realizan
funciones similares a refresh
, pero son más
específicas y pueden ser preferibles en algunos casos. Por
ejemplo, si quiere tan solo volcar los archivos de registro,
flush-logs
es mejor opción que
refresh
.
El comando shutdown
apaga el servidor. Este
comando puede ejecutarse únicamente desde
mysqladmin. No hay sentencia SQL equivalente.
El comando processlist
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
kill
mata los subprocesos del servidor.
Siempre puede mostrar información sobre sus propios
subprocesos, o matarlos, pero necesita el privilegio
PROCESS
para ver subprocesos iniciados por
otros usuarios, y el privilegio SUPER
para
matarlos. Consulte Sección 13.5.5.3, “Sintaxis de KILL
”.
El privilegio CREATE TEMPORARY TABLES
permite
la utilización de la palabra clave TEMPORARY
en sentencias CREATE TABLE
.
El privilegio LOCK TABLES
permite la
utilización de sentencias LOCK TABLES
explícitas para bloquear tablas para las que tiene el
privilegio SELECT
. Esto incluye el uso de
bloqueos de escritura, que evita que cualquier otra persona lea
la tabla bloqueada.
El privilegio REPLICATION CLIENT
permite la
utilización de las sentencias SHOW MASTER
STATUS
y SHOW SLAVE STATUS
.
El privilegio REPLICATION SLAVE
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 SHOW DATABASES
permite a la
cuenta ver los nombres de las bases de datos mediante la
ejecución de la sentencia SHOW DATABASE
.
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 --skip-show-database
.
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 FILE
:
-
El privilegio
FILE
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 sentenciaSELECT
para transferir sus contenidos a la máquina cliente. -
El privilegio
GRANT
permite a los usuarios otorgar sus mismos privilegios a otros usuarios. Dos usuarios con diferentes privilegios y con el privilegioGRANT
pueden combinar sus privilegios. -
El privilegio
ALTER
puede ser utilizado inadecuadamente para sabotear el sistema de privilegios mediante el renombrado de tablas. -
El privilegio
SHUTDOWN
puede utilizarse inadecuadamente para denegar el servicio a otros usuarios de manera total, cerrando el servidor. -
El privilegio
PROCESS
puede utilizarse para ver el texto de las consultas que se estén ejecutando actualmente, incluyendo consultas que establecen o modifican passwords. -
El privilegio
SUPER
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
mysql
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 columnaPassword
de la tablauser
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.
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 shell>
) de la siguiente manera:
shell> mysql -hnombre_host
-unombre_usuario
-psu_clave
Las sintaxis alternativas de las opciones -h
,
-u
, y -p
son
--host=
nombre_host
,
--user=
nombre_usuario
,
y
--password=
su_clave
.
Nótese que no hay espacios entre
-p
o --password=
y la
clave que le sigue.
Si utiliza una opción -p
o
--password
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
localhost
. -
El nombre de usuario por defecto es
ODBC
en Windows y su nombre de usuario de Unix en Unix. -
No se aplica ninguna clave si
-p
no está especificado.
De esta manera, para un usuario de Unix con un nombre de usuario
de jose
, 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
[client]
de un archivo de opciones. La sección relevante del archivo debería tener el siguiente aspecto:[client] host=
nombre_servidor
user=nombre_usuario
password=su_clave
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
MYSQL_HOST
. El nombre de usuario MySQL puede especificarse medianteUSER
(esto es para Windows y Netware únicamente). La clave se puede especificar utilizandoMYSQL_PWD
, 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.
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 user
(Host
, User
, y
Password
). El servidor sólo acepta la
conexión si las columnas Host
y
User
de alguna de las tablas
user
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 Host
en la tabla
user
pueden ser especificados de las
siguientes maneras:
-
Un valor de
Host
debe ser un nombre de máquina o un número IP, o'localhost'
para indicar la máquina local. -
Puede utilizar los carácteres comodín '
%
' y '_
' en los valores de las columnasHost
. Estos tienen el mismo significado que en las operaciones de búsqueda de patrones realizadas mediante el operadorLIKE
. Por ejemplo, un valor deHost
igual a'%'
retorna cualquier nombre de máquina, así como un valor de'%.mysql.com'
retorna cualquier nombre de máquina en el dominiomysql.com
. -
Para valores de
Host
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
david
conectarse desde cualquier cliente que tenga un número IPclient_ip
para el que la siguiente condición sea cierta:client_ip & netmask = host_ip
Es decir, para la sentencia
GRANT
recientemente mostrada: That is, for theGRANT
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
192.58.197.0
hasta192.58.197.255
. -
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
Host
en un registro de la tabladb
significa que los privilegios de dicho registro deben ser combinados con aquellos que se encuentren en el registro de la tablahost
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 tablahost
en Sección 5.6.6, “Control de acceso, nivel 2: comprobación de solicitudes”.Un valor de
Host
en blanco en las otras tablas grant lo mismo que'%'
.
Debido a que puede usar comodines en los valores IP de la
columna Host
(por ejemplo,
'144.155.166.%'
para conseguir cualquier IP
en una subred), alguien podría intentar explotar esta capacidad
poniéndole a su cliente el nombre
144.155.166.cualquierhost.com
. 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
1.2.cualquierhost.com
, su nombre nunca
concordará con la columna Host
de las tablas
grant. Un comodín de IP solo puede concordar con números IP,
no nombres de cliente.
En la columna User
, 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 user
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 Password
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 Password
en la tabla user
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 PASSWORD()
). 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
mysql
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 mysql
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 Host
y User
de la tabla user
.
Cliente Valor |
Usuario Valor |
Conexiones que concuerdan con la entrada Entry |
'thomas.loc.gov'
|
'fred'
|
fred , conectando desde
thomas.loc.gov |
'thomas.loc.gov'
|
''
|
Cualquier usuario, conectando desde thomas.loc.gov |
'%'
|
'fred'
|
fred , conectando desde cualquier cliente |
'%'
|
''
|
Cualquier usuario conectando desde cualquier cliente |
'%.loc.gov'
|
'fred'
|
fred , conectando desde cualquier cliente en el
dominio loc.gov |
'x.y.%'
|
'fred'
|
fred , conectando desde x.y.net ,
x.y.com , x.y.edu ,
etc. (esto, probablemente, no es útil) |
'144.155.166.177'
|
'fred'
|
fred , conectando desde el cliente con dirección IP
144.155.166.177 |
'144.155.166.%'
|
'fred'
|
fred , conectando desde cualquier cliente en la subred
de clase C 144.155.166 |
'144.155.166.0/255.255.255.0'
|
'fred'
|
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
user
. El conjunto de ejemplos precedentes
demuestra esto: Algunas de las entradas mostradas concuerdan con
una conexión de fred
desde
thomas.loc.gov
.
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
user
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
user
es como esta:
+-----------+----------+- | Host | User | … +-----------+----------+- | % | root | … | % | jeffrey | … | localhost | root | … | localhost | | … +-----------+----------+-
Cuando el servidor lee la tabla, ordena las entradas con los
valores de Host
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 Host
se ordenan con el valor
de User
más específico (un valor de
User
en blanco significa ``cualquier
usuario'' y es menos específico). En la tabla
user
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 localhost
por
jeffrey
, dos de las entradas de la tabla
concuerdan: la primera con los valores
'localhost'
y ''
de
Host
y User
respectivamente, y el registro con los valores
'%'
y 'jeffrey'
. El
registro con valor 'localhost'
aparece
primero en la tabla ordenada, así que es el que el servidor
utiliza.
Aquí hay otro ejemplo. Supongamos que la tabla
user
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 jeffrey
desde
thomas.loc.gov
concuerda con el primer
registro, mientras que una conexión de
jeffrey
desde
whitehouse.gov
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 jeffrey
desde
thomas.loc.gov
no concuerda primero con el
registro que contiene 'jeffrey'
como valor en
la columna User
, sino que ha concordado con
el registro que no contiene nombre de usuario. Como resultado,
jeffrey
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
CURRENT_USER()
. Devuelve un valor en formato
user_name
@host_name
que indica los valores de User
y
Host
del registro concordante en la tabla
user
. Suponga que jeffrey
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 user
tiene un valor vacío en la
columna User
. En otras palabras, el servidor
trata a jeffrey
como a un usuario anónimo.
Otra cosa que puede hacer para localizar problemas de
autentificación es imprimir por pantalla la tabla
user
y ordenarla a mano para ver donde está
la primera concordancia. Consulte
Sección 12.9.3, “Funciones de información”.
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 user
,
db
, host
,
tables_priv
, o
columns_priv
.(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 user
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
user
le otorga el privilegio
DELETE
, usted podrá borrar registros de
cualquier tabla en cualquier base de datos en todo el servidor.
En otras palabras, los privilegios de la tabla
user
son privilegios de superusuario. Es
aconsejable otorgar privilegios en la tabla
user
sólo a superusuarios tales como
administradores de base de datos. Para otros usuarios, debería
dejar los privilegios de la tabla user
con el
valor 'N'
y otorgar los privilegios
únicamente a niveles más específicos. Puede otorgar
privilegios para bases de datos, tablas o columnas particulares.
Las tablas db
y host
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 columnasDb
de cualquiera de las tablas. Estos tienen el mismo significado que en las operaciones de reconocimiento de patrones efectuadas con el operadorLIKE
. 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 sentenciaGRANT
. -
Un valor de
'%'
en la columnaHost
de la tabladb
significa ``cualquier host.'' Un valor vacío en la columnaHost
de la tabladb
significa ``consulta la tablahost
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 columnaHost
de la tablahost
significa ``cualquier host.'' -
Un valor de
'%'
o en blanco de la columnaDb
en cualquiera de las dos tablas, significa ``cualquier base de datos.'' -
Un valor en blanco de la columna
User
en cualquiera de las tablas concuerda con el usuario anónimo.
El servidor lee y ordena las tablas db
y
host
al mismo tiempo que lee la tabla
user
. El servidor ordena la tabla
db
basándose en el rango de las columnas
Host
, Db
y
User
, y ordena la tabla
host
basándose en el rango de las columnas
Host
y Db
. Igual que con
la tabla user
, 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 tables_priv
y
columns_priv
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 columnaHost
de cualquiera de las tablas. Estos comodines tienen el mismo significado que en las operaciones de búsqueda de patrones realizadas con el operadorLIKE
. -
Un valor de
'%'
o vacío en la columnaHost
de cualquiera de las tablas significa ``cualquier host.'' -
Las columnas
Db
,Table_name
yColumn_name
no pueden contener carácteres comodín ni estar en blanco en ninguna de las tablas.
El servidor ordena las tablas tables_priv
y
columns_priv
basándose en las columnas
Host
, Db
, y
User
. Esto es similar a la ordenación de la
tabla db
, pero más simple, porque
únicamente la columna Host
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
SHUTDOWN
o RELOAD
, el
servidor comprueba únicamente el registro de la tabla
user
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 user
no le otorga el privilegio
SHUTDOWN
, el servidor deniega el acceso sin
ni siquiera codnsultar las tablas db
o
host
. (No contienen ninguna columna
Shutdown_priv
, así que no hay necesidad de
hacerlo.)
Para peticiones sobre bases de datos (INSERT
,
UPDATE
, etc.), el servidor primero comprueba
los privilegios globales del usuario (superuser) mirando el
registro de la tabla user
. Si el registro
permite la operación demandada, se otorga el acceso. Si los
privilegios globales de la tabla user
son
insuficientes, el servidor determina los privilegios
específicos sobre la base de datos comprobando las tablas
db
y host
:
-
El servidor busca en la tabla
db
una concordancia en las columnasHost
,Db
yUser
. Las columnasHost
yUser
se hacen concordar con el nombre de host y de usuario MySQL. La columnaDb
se hace concordar con la base de datos a la que el usuario quiere acceder. Si no hay ningún registro paraHost
yUser
, se deniega el acceso. -
Si hay un registro que concuerda en el registro de la tabla
db
y su columnaHost
no está vacía, ese registro define los privilegios específicos del usuario en la base de datos. -
Si la columna
Host
del registro concordante de la tabladb
se encuentra vacía, significa que la tablahosts
enumera qué hosts pueden tener acceso a la base de datos. En este caso, una comprobación más se realiza en la tablahost
para encontrar una concordancia en las columnasHost
yDb
. Si ningún registro de la tablahost
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 tablasdb
yhost
; es decir, los privilegios que tienen valor'Y'
en ambos registros. (De esta manera puede otorgar privilegios en el registro de la tabladb
y entonces restringir selectivamente host a host utilizando los registros de la tablahosts
.)
Tras determinar los privilegios específicos de la base de datos
otorgados por los registros de las tablas db
y host
, el servidor los añade a los
privilegios globales otorgados por la tabla
user
. 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 tables_priv
y
columns_priv
, 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 user
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 INSERT INTO ... SELECT
,
necesita tanto el privilegio INSERT
como el
privilegio SELECT
. Sus privilegios podrían
estar configurados de manera que la tabla
user
otorgue un privilegio, y la tabla
db
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 host
no es afectada por sentencias
GRANT
o REVOKE
, 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 host
contiene una lista de todas las máquinas en la red local.
Éstas tienen otorgados todos los privilegios.
También puede utilizar la tabla host
para
indicar hosts que no son seguros.
Supongamos que tiene una máquina
public.su.dominio
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 host
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 SHOW
GRANTS
o mysqlaccess) para estar
seguro de que sus privilegios de acceso son realmente los que
piensa que son.
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
USE
db_name
. -
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
GRANT
, REVOKE
, o
SET PASSWORD
,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 INSERT
,
UPDATE
, o DELETE
, 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 FLUSH
PRIVILEGES
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.
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 '
host_name
' (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
--port
para indicar el puerto adecuado, o la opción--socket
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
mysql
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
mysql
bajo el directorio de datos. (El directorio de datos normalmente se llamadata
ovar
y se encuentra bajo su directorio de instalación de MySQL.) Asegúrese de que tiene un archivo llamadouser.MYD
en el directoriomysql
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
root
no tiene clave de acceso inicialmente. Esto, además, es un riesgo de seguridad, así que asignar la clave de acceso para las cuentasroot
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, “
Client does not support authentication protocol
”. -
Si intenta conectarse como
root
y obtiene el siguiente error, significa que usted no tiene un registro en la tablauser
con un valor en la columnaUser
de'root'
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
--skip-grant-tables
y editar su archivo/etc/hosts
o\windows\hosts
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
Access denied
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
--no-default
. 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
root
incorrecta:shell> mysqladmin -u root -p
xxxx
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
--no-defaults
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
root
, puede reiniciar mysqld con--skip-grant-tables
para cambiar la clave. Consulte Sección A.4.1, “Cómo reiniciar la contraseña de root”. -
Si usted cambia la clave utilizando
SET PASSWORD
,INSERT
, oUPDATE
, debe cifrar la clave utilizando la funciónPASSWORD()
. Si no utilizaPASSWORD()
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'@'
host_name
' = 'eagle';En vez de esto, debe establecer la clave así:
mysql> SET PASSWORD FOR 'abe'@'
host_name
' = PASSWORD('eagle');La función
PASSWORD()
no es necesaria cuando se especifica la clave utilizando sentenciasGRANT
o (a partir de MySQL 5.0.2)CREATE USER
, o también con el comando mysqladmin password, los cuales utilizan automáticamentePASSWORD()
para cifrar la clave. Consulte Sección 5.7.5, “Asignar contraseñas a cuentas” y Sección 13.5.1.1, “Sintaxis deCREATE USER
”. -
localhost
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
--host=127.0.0.1
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--host
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 tablauser
del servidor, aun cuando el cliente esté corriendo en la misma máquina que el servidor. -
Si obtiene un error
Access denied
cuando intenta conectarse a la base de datos conmysql- u user_name
, puede que tenga un problema con la tablauser
. Compruebe esto ejecutandomysql -u root mysql
e introduciendo esta sentencia SQL:mysql> SELECT * FROM user;
El resultado debería incluir una fila cuyas columnas
Host
yUser
coincidan con el nombre de su máquina y su nombre de usuario MySQL. -
El mensaje de error
Access denied
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 tablauser
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 contieneusing password: NO
, 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
user
con un valorHost
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 columnaHost
de la tablauser
, y reiniciar mysqld en el servidor con la opción--log
. 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 tablauser
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
glibc
de la que usted está utilizando. En este caso, usted debería actualizar su sistema operativo oglibc
, 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
xxxx
-hsome-hostname
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
/etc/hosts
. -
Ejecute mysqld con la opción
--skip-name-resolve
. -
Ejecute mysqld con la opción
--skip-host-cache
. -
En Unix, si está ejecutando el servidor y el cliente en la misma máquina, conéctese a
localhost
. Las conexiones alocalhost
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
mysql -u root test
funciona peromysql -h
your_hostname
-u root test termina con unAccess denied
(dondeyour_hostname
es el nombre real de su máquina local), puede que no haya especificado correctamente el nombre de su máquina en la tablauser
. Un problema común es que el valor deHost
en la fila de la tablauser
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'tcx'
enHost
de la tablauser
, pero sus DNS dicen qeu su nombre de máquina es'tcx.subnet.se'
, esta entrada no funcionará. Intente añadir una entrada a la tablauser
con un valor deHost
que contenga un comodín; por ejemplo'tcx.%'
. ¡En cualquier caso, el uso de nombres que acaben con '%
' es inseguro y no recomendado! -
Si
mysql -u
user_name
test funciona peromysql -u
user_name
other_db_name
no funcionado, entonces es que no tiene concedidos los permisos para acceder a la base de datosother_db_name
para ese usuario dado. -
Si
mysql -u
user_name
funciona cuando se ejecuta en la máquina del servidor, peromysql -h
host_name
-uuser_name
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
Access denied
, borre de la tablauser
todos los valores que contengan comodines (que contengan carácteres '%
' o '_
'). Un error muy común es insertar un nuevo registro conHost
='%'
yUser
='
some_user
', pensando que esto permite especificar quelocalhost
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 conHost
='localhost'
yUser
=''
. Debido a que ese registro es más específico que'%'
, se utiliza preferentemente frente al nuevo registro cuando conecta desdelocalhost
. El procedimiento correcto es insertar una segunda entrada conHost
='localhost'
yUser
='
some_user
', o borrar la entrada conHost
='localhost'
yUser
=''
. Tras borrar la entrada, recuerde ejecutar una sentenciaFLUSH PRIVILEGES
para recargar las tablas grant. -
Si obtiene el siguiente error, puede ser que tenga un problema con las tablas
db
ohost
:Access to database denied
Si la entrada seleccionada de la tabla
db
contiene un valor vacio en la columnaHost
, asegúrese de que hay una o más entradas correspondientes en la tablahost
especificando a qué máquinas se aplica la entrada de la tabladb
. -
Si usted puede conectar al servidor MySQL, pero obtiene un mensaje
Access denied
siempre que ejecuta una sentenciaSELECT ... INTO OUTFILE
oLOAD DATA INFILE
, su entrada en la tablauser
no tiene el privilegioFILE
activado. -
Si cambia las tablas grant directamente (por ejemplo, mediante sentencias
INSERT
,UPDATE
, oDELETE
) y sus cambios parecen que son ignorados, recuerde que debe ejecutar la sentenciaFLUSH PRIVILEGES
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 deroot
con un comandoUPDATE
, 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
mysql -u
user_name
db_name
omysql -u
user_name
-pyour_pass
db_name
. 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-p
y la clave; también puede utilizar la sintaxis--password=
your_pass
para especificar la clave. Si utiliza la opción-p
sola, MySQL le preguntará por la clave.) -
Para hacer comprobaciones, inicie el servidor mysqld con la opción
--skip-grant-tables
. 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--skip-grant-tables
. 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,
--debug=d,general,query
). 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
--skip-grant-tables
para ejecutar mysqldump.
Las cuentas de usuario de MySQL se listan en la tabla
user
de la base de datos
mysql
. Cada cuenta MySQL tiene una
contraseña asiganada, aunque lo que se guarda en la columna
Password
de la tabla user
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
PASSWORD()
.
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
user
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
user
. El cliente puede hacerlo mediante la funciónPASSWORD()
para generar el hash de la contraseña, o mediante los comandosGRANT
oSET PASSWORD
.
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 PASSWORD()
o usa los
comandos GRANT
o SET
PASSWORD
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, “Client does not support authentication protocol
”. 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 PASSWORD()
tienen una longitud de 16
bytes. Tales hashes tienen este aspecto:
mysql> SELECT PASSWORD('mypass'); +--------------------+ | PASSWORD('mypass') | +--------------------+ | 6f8c114b58f2ce9e | +--------------------+
La columna Password
de la tabla
user
(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 PASSWORD()
se
modificó para producir un valor hash más largo de 41-bytes:
mysql> SELECT PASSWORD('mypass'); +-----------------------------------------------+ | PASSWORD('mypass') | +-----------------------------------------------+ | *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 | +-----------------------------------------------+
Por consiguiene, la columna Password
en la
tabla user
debe tener una longitud de 41
bytes para almacenar estos valores:
-
Si realiza una nueva instalación de MySQL 5.0, la columna
Password
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 Password
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 Password
:
-
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 Password
y por la opción
--old-passwords
. Un servidor 4.1. o posterior
genera hashes largos sólo si se cumplen ciertas condiciones: La
columna Password
debe ser lo suficientemente
larga para guardar valores largos y no debe darse la opción
--old-passwords
. Estas condiciones se aplican
como sigue:
-
La columna
Password
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 mediantePASSWORD()
,GRANT
, oSET PASSWORD
. 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 columnaPassword
. -
Si la columna
Password
es amplia, puede almacenar tanto hashes de contraseñas largos como cortos. En este caso,PASSWORD()
,GRANT
, ySET PASSWORD
generan hashes largos a no ser que el servidor se haya iniciado con la opción--old-passwords
. Este opción fuerza al servidor a generar hashes de contraseñas cortos.
El propósito de la opción --old-passwords
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
user
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
--old-passwords
, 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
--old-passwords
, 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 --old-passwords
. Ejecutando el
servidor con --old-passwords
, 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 --old-passwords
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 --old-passwords
.
Los siguientes escenarios son posibles al ejecutar un servidor 4.1 o posterior, incluyendo servidores MySQL 5.0:
Escenario 1:Columna
Password
corta en tabla de usuario:
-
Sólo se pueden guardar hashes cortos en la columna
Password
. -
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
PASSWORD()
,GRANT
, oSET PASSWORD
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
--old-passwords
puede usarse pero es supérflua ya que con una columnaPassword
corta, el servidor genera sólo hashes de contraseña cortos de todas formas..
Escenario 2: Columna
Password
larga; servidor no arrancado con la
opción --old-passwords
:
-
Hashes cortos o largos pueden almacenarse en la columna
Password
. -
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
PASSWORD()
,GRANT
, oSET PASSWORD
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
GRANT
, PASSWORD()
, o
SET PASSWORD
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 SET
PASSWORD
como sigue para cambiar una contraseña de
cuenta:
mysql> SET PASSWORD FOR 'some_user
'@'some_host
' = PASSWORD('mypass');
Para cambiar la contraseña pero crear un hash corto, use la
función OLD_PASSWORD()
en su lugar:
mysql> SET PASSWORD FOR 'some_user
'@'some_host
' = OLD_PASSWORD('mypass');
OLD_PASSWORD()
es útil para situaciones en
que explícitamente quiera generar un hash corto.
Escenario 3: Columna
Password
larga; servidor 4.1 o posterior
arrancado con la opción --old-passwords
:
-
Hashes crotos o largos pueden guardarse en la columna
Password
. -
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
--old-passwords
). -
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
PASSWORD()
,GRANT
, oSET PASSWORD
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
--old-passwords
evita la generación de
hashes largos. También, si crea una cuenta con hashes largos
antes de usar la opción --old-passwords
,
cambiar la contraseña de la cuenta mientras
--old-passwords
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 OLD_PASSWORD()
.
En el escenario 3, --old-passwords
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
--old-passwords
tenga efecto.
Una actualización a MySQL 4.1 o posterior puede provocar
problemas de compatibilidad para aplicaciones que usen
PASSWORD()
para generar contraseñas para
sus propios propósitos. Las aplicaciones no deben hacer esto,
ya que PASSWORD()
debe usarse sólo para
administrar contraseñas para cuentas MySQL. Pero algunas
aplicaciones usan PASSWORD()
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
PASSWORD()
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
SHA1()
o MD5()
, para
producir hashes de valores. Si esto no es posible, puede usar
la función OLD_PASSWORD()
, que se
proporciona para generar hashes cortos en el viejo formato.
Sin embargo, debe tener en cuenta que
OLD_PASSWORD()
puede dejar de ser soportado
en alguna futura versión.
Si el servidor está ejecutándose bajo circunstancias donde
genera hashes cortos, OLD_PASSWORD()
está
disponible pero es equivalente a
PASSWORD()
.
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.