Foros del Web » Programando para Internet » PHP »

Pregunta sobre el funcionamiento de mysql_connect

Estas en el tema de Pregunta sobre el funcionamiento de mysql_connect en el foro de PHP en Foros del Web. Hola, qué tal :) Recientemente estuve hablando con un amigo acerca del funcionamiento de esta función (mysql_connect()), de forma más concreta, su funcionamiento cuando dicha ...
  #1 (permalink)  
Antiguo 13/04/2009, 11:56
Avatar de Acron_0248  
Fecha de Ingreso: junio-2005
Ubicación: 127.0.0.1
Mensajes: 1.648
Antigüedad: 18 años, 9 meses
Puntos: 18
Pregunta sobre el funcionamiento de mysql_connect

Hola, qué tal :)


Recientemente estuve hablando con un amigo acerca del funcionamiento de esta función (mysql_connect()), de forma más concreta, su funcionamiento cuando dicha función es llamada con parámetros como FALSE o vacío, para que quede claro, me refiero a cosas como estas:

ejemplo 1:
Código PHP:
<?php

mysql_connect
(FALSEFALSEFALSE);

?>
ejemplo 2:
Código PHP:
<?php

mysql_connect
('''''');

?>
ejemplo 3:
Código PHP:
<?php

mysql_connect
();

?>

Lo que se me ha hecho interesante y de donde vienen mis dudas es que hay cosas en las diferentes referencias en la documentación de la función que no parecen cuadrar.


La documentación de la API de mysql (tanto para mysql_connect() como para mysql_real_connect()) dice:
Cita:
- The value of host may be either a hostname or an IP address. If host is NULL or the string "localhost", a connection to the local host is assumed. If the OS supports sockets (Unix) or named pipes (Windows), they are used instead of TCP/IP to connect to the server.

- The user parameter contains the user's MySQL login ID. If user is NULL or the empty string "", the current user is assumed. Under Unix, this is the current login name.
La documentación de PHP para mysql_connect() dice:
Cita:
- The MySQL server. It can also include a port number. e.g. "hostname:port" or a path to a local socket e.g. ":/path/to/socket" for the localhost.

If the PHP directive mysql.default_host is undefined (default), then the default value is 'localhost:3306'. In SQL safe mode, this parameter is ignored and value 'localhost:3306' is always used.

- The username. Default value is defined by mysql.default_user. In SQL safe mode, this parameter is ignored and the name of the user that owns the server process is used.

Hasta todo bien, o eso parece.

En mi servidor local root (de mysql) tiene su clave lo que significa que ese es un parámetro que deberé pasar o php dará error indiciando que el usuario X no tiene permiso para conectarse a mysql, para facilitar el entendimiento de los próximos ejemplos, digamos que la clave del root de mysql es "asdfg"

Bien, para probar el funcionamiento de esta función uso este código:
Código PHP:
<?php

var_dump 
(mysql_connect(FALSEFALSE'asdfg'));

?>
O bien este otro:
Código PHP:
<?php

var_dump 
(mysql_connect('''''asdfg'));

?>
Si ejecuto cualquiera de los dos códigos desde una cónsola (como root) con el servidor mysql activo, el resultado será:
Código:
resource(4) of type (mysql link)
Eso indica que la conexión ha sido exitosa.

Si ejecuto el mismo código como usuario normal desde una cónsola dará el siguiente error
Código:
Warning: mysql_connect(): Access denied for user 'uid0'@'localhost' 
(using password: YES) in /var/www/localhost/htdocs/test.php on line 3
Y si ejecuto el mismo código desde un navegador el error será
Código:
Warning: mysql_connect(): Access denied for user 'apache'@'localhost' 
(using password: YES) in /var/www/localhost/htdocs/test.php on line 3
Hasta acá todo parece indicar que lo que dice la documentación de la API de mysql es correcto, con la excepción tal vez del usuario Apache porque involucra la forma de trabajo de la SAPI de php, pero el punto es que el usuario activo (el que inició sesión) está siendo usado como parámetro del nombre del usuario de la función mysql_connect ya que lo se pasó fue FALSE o vacío.

Ahora bien, si activo sql.safe_mode en el php.ini y ejecuto el código desde una cónsola como root dará el siguiente error:
Código:
Warning: mysql_connect(): Access denied for user 'root'@'localhost' 
(using password: YES) in /var/www/localhost/htdocs/test.php on line 3
Una de mis preguntas es ¿por qué ocurre esto?

Para empezar, según lo que dice la documentación de PHP, si sql.safe_mode está activo, se usará el nombre del usuario que sea dueño del proceso del servidor, sin embargo, estoy ejecutando el script desde una cónsola directamente con PHP, no estoy llamando el script desde apache, y si safe_mode "ignora" el parámetro que se pasó y envía el nombre del usuario dueño del proceso del servidor, ¿por qué el usuario que se pasa es root?

Se puede pensar que es una especie de fallback, no se pudo obtener el nombre del usuario dueño del proceso del servidor (porque tal proceso no está en ejecución) y se pasó simplemente 'root', pero de ser así, ¿por qué la conexión falla?

Teniendo aún sql.safe_mode activo en el php.ini y ejecutando el mismo script desde una cónsola pero como usuario "normal" dará el mismo error con root:
Código:
Warning: mysql_connect(): Access denied for user 'root'@'localhost'
(using password: NO) in /var/www/localhost/htdocs/test.php on line 3
Esto me hace pensar que obviamente sql.safe_mode no funciona de la forma que lo hace la librería de mysql, al menos en lo que se documenta en la API ya que sin importar el nombre del usuario activo (el que inició sesión) se está enviando 'root', pero ¿cuál root?

Se puede decir también que debido al sql.safe_mode se está enviando el usuario root "del sistema", linux en este caso, que no es el mismo root "de mysql", sin embargo, la librería de mysql (si sql.safe_mode estuviera inactivo) usará el nombre del usuario que inició sesión cuando no se especifica dicho parámetro en la llamada a la función y como ya indiqué, teniendo sql.safe_mode desactivado y ejecutando el script desde una cónsola como root (root de linux) la conexión se establece correctamente, entonces ¿qué diferencia hay entre el 'root' que se envía cuando sql.safe_mode está activo y el 'root' que se envía cuando sql.safe_mode NO está activo?


Dicho esto, si alguien conoce más detalles sobre el funcionamiento de esta función más allá de lo que hay en la documentación o alguien conoce algún enlace que pueda proveer tal información, se lo agradeceré si me lo comenta :)



Salu2
__________________
Usuario Reigistrado de linux #399288

Última edición por Acron_0248; 13/04/2009 a las 19:22
  #2 (permalink)  
Antiguo 13/04/2009, 12:05
Avatar de duskrow  
Fecha de Ingreso: abril-2008
Mensajes: 267
Antigüedad: 16 años
Puntos: 8
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

mysql_connect("server" , "user sql" , "pass user de sql")
  #3 (permalink)  
Antiguo 13/04/2009, 12:37
Avatar de Acron_0248  
Fecha de Ingreso: junio-2005
Ubicación: 127.0.0.1
Mensajes: 1.648
Antigüedad: 18 años, 9 meses
Puntos: 18
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

Hola :)

Gracias por contestar pero se como se usa mysql_connect() y cómo usarla no es lo que estoy preguntando, mi pregunta va a dirigida al funcionamiento de esta función cuando parámetros como FALSE, NULL o cadenas vacías ('' o "") son pasadas como parámetros de host y nombre de usuario.



Salu2
__________________
Usuario Reigistrado de linux #399288
  #4 (permalink)  
Antiguo 13/04/2009, 13:16
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

Si lees el Manual, dice lo siguiente:
Cita:
- The username. Default value is defined by mysql.default_user. In SQL safe mode, this parameter is ignored and the name of the user that owns the server process is used.
Es decir, siempre se va a enviar, el usuario que sea el dueño del proceso del server, al server estar corriendo bajo un daemon, siempre va a ser de root, a menos que tu configures tu daemon para que corra bajo otro usuario.

Ahora, no hay ninguna diferencia entre los usuarios root que envias textual y el dueño del server ya que al final lo que se envia como login name al servidor de BDD es "root", tal cual, la diferencia es en el password que se envia, ya que si esta activado el sql safe mode, no se envia ningún password (se envia '').

Saludos.
  #5 (permalink)  
Antiguo 13/04/2009, 14:29
Avatar de Acron_0248  
Fecha de Ingreso: junio-2005
Ubicación: 127.0.0.1
Mensajes: 1.648
Antigüedad: 18 años, 9 meses
Puntos: 18
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

Hola GatorV, gracias por contestar ;)


Cita:
Iniciado por GatorV Ver Mensaje
Es decir, siempre se va a enviar, el usuario que sea el dueño del proceso del server, al server estar corriendo bajo un daemon, siempre va a ser de root, a menos que tu configures tu daemon para que corra bajo otro usuario.
¿A qué daemon te refieres?

El script lo estoy ejecutando desde una cónsola y Apache no está activo como proceso así que puedo descartar el daemon de apache, Mysql si está como daemon pero el usuario dueño de ese proceso se llama "mysql" no root (uso Gentoo por si sirve de algo), entonces, si se va a enviar el nombre del usuario dueño del proceso del server (asumiendo que te refieres al proceso de mysql) ¿por qué se envía root y no mysql en mi caso?
__________________
Usuario Reigistrado de linux #399288

Última edición por Acron_0248; 13/04/2009 a las 19:40
  #6 (permalink)  
Antiguo 13/04/2009, 21:41
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

Cierto una disculpa, cuando lo invocas desde la consola, lo haces desde el usuario que este corriendo, en este caso lo estas haciendo desde una consola root. Es por eso que pasa root como usuario.

Saludos.
  #7 (permalink)  
Antiguo 14/04/2009, 00:57
Avatar de PatomaS
Colaborador
 
Fecha de Ingreso: marzo-2004
Ubicación: En alguna otra parte
Mensajes: 4.656
Antigüedad: 20 años, 1 mes
Puntos: 63
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

Hola gente

Bueno, curioso tema este.

La verdad es que yo no puedo aportar mucho al respecto de las preguntas específicas ya que no tengo claro el funcionamiento interno del procesador de consultas.

Pero veamos.

De los ejemplos expuestos y algunas pruebas que he hecho, veo varios elementos a destacar.

Desde el punto de vista de seguridad, creo que es bastante irresponsable rellenar un usuario por defecto, más aun que dicho usuario sea root, entrar en los detalles escapa al ámbito de este tema, pero definitivamente deja puertas abiertas que no deberían estarlo.

Desde el punto de vista de la relación MySQL - PHP, si tomamos en cuenta que la instalación de MySQL configura un usuario por defecto y que este usuario es root, PHP debería forzar valores inocuos hacia la API de MySQL, es decir, no debería confiar en la seguridad del servidor o el gestor de base de datos para la seguridad. Valores que se me ocurre podrían ser usados, tenemos: false, true, phphost (valor inventado). Y valores a ser omitidos serían: NULL, localhost, root, ''.

Hablando solo del funcionamiento de PHP, vemos que este hace una transformación de valores internamente, así la llamada
Código PHP:
mysql_connectfalsefalsefalse 
se convierte en:
Código PHP:
mysql_connect(''''''
Si revisamos la documentación de PHP sobre tipos booleanos, vemos que la empty string, osea '' equivale a false, sin embargo, la relación no es recíproca, es decir

Código PHP:
false != '' 
Por lo tanto, que PHP convierta false a '' y envie eso a la API, es receta segura para que la API sustituya los valores vacíos por los valores por defecto.

Otro elemento curioso es lo que ocurre si en vez de false usamos true
Código PHP:
var_dumpmysql_connecttruetruetrue ) ); 
se convierte en:

Código PHP:
var_dumpmysql_connect'1''1''1' ) ); 
lo que genera como error lo siguiente

Código PHP:
Warningmysql_connect(): Can't connect to MySQL server on '(22
¿qué es lo que ha ocurrido aquí?

Pues el conocido type cast de PHP, el cual es útil si hacemos algo como echo( $a ); y ese $a puede ser true o false; pero definitivamente no es lo mismo en casos como mysql_connect().

Finalmente, un detalle a mi parecer muy importante; mysql_connect() es una función que realiza o intenta realizar una conexión con la base de datos de mysql, si revisamos la documentación de dicho comando, vemos que como valores devueltos especifica esto: Returns a MySQL link identifier on success, or FALSE on failure., es decir, si se conecta, devuelve un recurso y si falla, devuelve false, sin embargo, por la forma en la que PHP se conecta con MySQL, al ejecutar la secuencia mencionada por Acron_0248 en su primer ejemplo, el resultado es un puntero si se ejecuta en el navegador y false si se ejecuta en la consola.

Ejemplificado queda así:
Navegador:
comando: var_dump( mysql_connect( false, false, false ) );
respuesta: resource(2, mysql link)

Consola:
Código PHP:
php prueba_2.php

Warning
mysql_connect(): Access denied for user 'root'@'localhost' (using passwordNOin prueba_2.php on line 2

Call Stack
:
    
0.0003      96624   1. {main}() prueba_2.php:0
    0.0003      96704   2. mysql_connect
(''''''prueba_2.php:2


bool
(false
Espero que todos estos desbarruntos hayan sido de alguna utilidad, aunque seguramente no han ayudado mucho a responder las dudas planteadas.

Felicidad
__________________
¡ hey, hou, hou, hey !
  #8 (permalink)  
Antiguo 14/04/2009, 19:14
Avatar de Acron_0248  
Fecha de Ingreso: junio-2005
Ubicación: 127.0.0.1
Mensajes: 1.648
Antigüedad: 18 años, 9 meses
Puntos: 18
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

Bueno, a ver :)


Hasta ahora, varias han sido las respuestas a las dudas que planteé en un comienzo (gracias GatorV y PatomaS ;)) pero de igual forma, el mensaje de PatomaS aunque no busca contestar directamente ninguna interrogante en particular tiene mucha relación con al menos una duda y tal duda es ¿por qué mysql_connect() funciona como lo hace?

Cierto, las documentaciones dan un "por qué" y es simplemente que la API de mysql si recibe string "" (0) o NULL usará por defecto unos valores, 'localhost', 'root' y una clave en blanco, pero queda aún otro "por qué" en el aire y es ¿por qué se ha decidido implementar tal comportamiento? y como adición a ese por qué, ¿qué consecuencias tiene ese comportamiento?

Obviamente es una pregunta para los desarrolladores de MySQL y en menor parte tal vez para los desarrolladores de PHP, sin embargo, uno de mis intereses al preguntar era discutir sobre el funcionamiento de la función en cuestión.

Dejando por un momento al lado el tema de la seguridad, a nivel del programador la función realmente no hace un trabajo lógico y por lógico me refiero a que lo que se puede inferir en base a los parámetros que recibe la función es algo distinto a lo que termina usando la librería.

Cosas como cadenas vacías, FALSE o NULL son cuadros en memoria que no tienen ningún valor asignado, partiendo desde ese punto, no es algo realmente lógico que cualquiera de esos valores termine siendo equivalente a root o a localhost.

Como ya dijo PatomaS, PHP debería forzar valores para la API de mysql más aún cuando en todo momento PHP es un intermediario entre el programador y la API que es quien termina definiendo el comportamiento de las funciones mysql_connect y mysql_real_connect.

Otra cosa interesante es el type casting. Como ya dijeron, una cadena vacía es equivalente a FALSE pero no al revés, FALSE no es equivalente a una cadena vacía, entonces el casting que hace PHP para enviar una cadena vacía a la API de mysql no es realmente un funcionamiento lógico, ni a ojos del programador ni a ojos del lenguaje.

Si bien type casting es útil, no lo es para cada posible ejecución de código y algo tan importante como mysql_connect() debería tratarse de mejor forma.

Volviendo a lo que ya mencionaron, la seguridad, ciertamente no es la forma más segura de hacer las cosas, es una de las razones que me hicieron leer y preguntar acerca de la función cuando comencé a ver los resultados de las pruebas usando parámetros como FALSE o NULL.

Gran cantidad de artículos, guías y libros indican que siempre que se hace un projecto que involucre a PHP y MySQL, lo mejor es crear un usuario particular para la aplicación con privilegios limitados en el servidor MySQL que solo permita hacer las consultas necesarias para que la aplicación funcione, sin embargo, si es posible de alguna forma llamar mysql_connect() usando parámetros como false, null o cadenas vacías, la medida anterior sería completamente inútil.

Aún sigo buscando alguna documentación extra (tal vez más técnica) referente a la función por lo que si alguien tiene alguna, sería genial :) sino, pues nada, seguiré buscando.


Salu2
__________________
Usuario Reigistrado de linux #399288
  #9 (permalink)  
Antiguo 15/04/2009, 19:32
Avatar de Acron_0248  
Fecha de Ingreso: junio-2005
Ubicación: 127.0.0.1
Mensajes: 1.648
Antigüedad: 18 años, 9 meses
Puntos: 18
Respuesta: Pregunta sobre el funcionamiento de mysql_connect

Como nota interesante en relación a este tema, hace poco conseguí un post (en inglés) que muestra precisamente el tipo de problemas que pueden ocurrir al confiarse en el type casting/type juggling.

Tal como se puede ver en ese post, un código como este genera un resultado bastante erróneo a nivel lógico:
Código PHP:

$var1 
'111 ';
$var2 '21';
var_dump $var1 $var2 ); // mostrará bool (true) 
Las razones del por qué eso es erróneo son obvias, pero en lo que compete a este tema, es un ejemplo del por qué es igual de erróneo que FALSE, NULL o '' en mysql_connect() sean interpretados como 'root' o 'localhost'
__________________
Usuario Reigistrado de linux #399288
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 18:18.