• Publicidad

Problema para ejecutar script en Perl vía web

Todo lo relacionado con el desarrollo Web con Perl: desde CGI hasta Mojolicious

Problema para ejecutar script en Perl vía web

Notapor palafox87 » 2012-05-06 01:35 @107

Hola amigos, mi nombre es Guillermo y me estoy iniciando en el mundo de Perl.

Les comento que estoy escribiendo un script, el cual, recibiendo los datos de un formulario me permita crear cuentas de usuario en Linux.

Hasta la parte de recibir datos desde un formulario, todo va excelente. El problema es cuando el script se ejecuta desde el navegador: simplemente no se ejecuta el comando 'adduser'. Pero, si el script lo ejecuto desde la línea de comando, se ejecuta perfecto.

¿Alguien que me pueda orientar de por qué sucede esto?

Les dejo mi script:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! /usr/bin/perl
  2.  
  3. use CGI qw(:all);
  4. my $cgi = new CGI;
  5.  
  6. #Por motivos de pruebas no recibo la variables desde el formulario
  7. #Lleno las variables directamente
  8.  
  9. #my $n = $cgi->param('nombre');
  10. #my $c = $cgi->param('codigo');
  11. #my $p = $cgi->param('password');
  12.  
  13. my $nombre = "Pedro Pérez";
  14. my $codigo = "123456";
  15. my $pass = "abcdef";
  16.  
  17. my $useradd = "/usr/sbin/useradd";
  18.  
  19. print "Content-type:text/html\n\n";
  20.  
  21. #Si el usuario ya existe entonces...
  22. if(getpwnam($codigo))
  23. {
  24.         print "El usuario ya existe!";
  25. }else{
  26.  
  27.         system qq($useradd -g users -d /home/$codigo -p`mkpasswd -m sha-512 -S abc12345 -s $pass` -c $nombre $codigo);
  28.  
  29.         if ( $? == -1 ) {
  30.                 print "El comando fallo!: $!\n";
  31.         }
  32.         else
  33.         {
  34.                 printf "Salida del comando: %d", $? >> 8;
  35.         }
  36.  
  37. }
  38.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Comentarios extra:

  • Ya intenté usar el comando 'useradd' directo, sin especificar la ruta del comando
  • Ya he configurado el módulo de Perl en Apache
    - Utilicé el siguiente handler para el Apache:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    1.     AddHandler cgi-script .cgi .pl
    2.     <Files ~ "\.pl$">
    3.     Options +ExecCGI
    4.     </Files>
    5.     <Files ~ "\.cgi$">
    6.     Options +ExecCGI
    7.     </Files>
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
  • La dirección para ejecutar el script en el navegador es: 192.168.1.10/perl/crear_usuario.pl (es una máquina virtual)
  • Utilizo Ubuntu Server 11.10. Tengo instalado webmin del cual utiliza bastantes módulos en Perl y tal vez esté haciendo fallar mis scripts
  • Por si ocupan el 'mkpasswd' les dejo la dirección de descarga:
    - http://mirrors.kernel.org/ubuntu/pool/u ... _amd64.deb
    - http://mirrors.kernel.org/ubuntu/pool/u ... 3_i386.deb


De antemano, ¡muchas gracias!
palafox87
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-05-06 00:54 @079

Publicidad

Re: Problema para ejecutar script en Perl vía web

Notapor explorer » 2012-05-06 07:33 @356

Bienvenido a los foros de Perl en Español, palafox87.

Si el programa funciona bien desde la línea de comandos, pero no desde el navegador, es muy posible que el fallo esté en el usuario que ejecuta el servidor web.

Me explico: los cgi son programas que lanza el servidor web a petición del usuario externo (nosotros desde el navegador). Los cgi -en principio- adoptan la personalidad del usuario que ejecuta el servidor web.

Por ejemplo, al arrancar el sistema, o desde la línea de comandos, arrancamos el servidor web, éste podría ser el usuario www-data, apache, httpd o cualquier otro usuario definido para que ejecute el servidor (incluso he visto que puede ser el usuario nobody). Eso está definido en los archivos de configuración del Apache:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
User www-data
Group www-data
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Y... claro... el usuario www-data, es difícil que tenga permisos de ejecución de adduser:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
explorer@hs-1590:~$ /usr/sbin/adduser rober
adduser: Sólo root puede añadir un usuario o un grupo al sistema.
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El propio comando adduser comprueba si está siendo ejecutado por el usuario con id igual 0 (el root), así que aquí no vale el truco de darle permisos al directorio/programa. Lo que debe hacer el servidor web es cambiar la personalidad del cgi para que adopte la de root.

Un primer intento es: darle la propiedad del cgi al root y concederle permisos de ejecución para todo el mundo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
chown root.root programa.cgi
chmod 4755 programa.cgi
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Prueba a ver. Lo malo es que en los Linux modernos, esta posibilidad está desactivada.

Otra opción: ya que lo que se suele bloquear es la ejecución del intérprete en modo setuid, lo que se debe hacer es ejecutar nuestro script desde un programa que sí parezca legal al sistema.

Crea un programa en C como este:
Sintáxis: [ Descargar ] [ Ocultar ]
Using c Syntax Highlighting
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/types.h>
  4. #include <unistd.h>
  5.  
  6. int main()
  7. {
  8.    setuid( 0 );
  9.    system( "/ruta/al/script.cgi" );
  10.  
  11.    return 0;
  12. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Lo compilas y le das los mismos permisos y propiedad que los del root:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
gcc runscript.c -o runscript
chown root:root runscript
chmod 4755 runscript
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Ahora, prueba a ejecutar este programa desde el navegador. Seguramente antes tendrás que darle una extensión, como '.exe', por ejemplo, y agregar esa extensión a los tipos de archivos ejecutables por Apache.

Otra opción (no recomendable): cambiar las opciones User y Group de antes a las del root y reiniciar el servidor web con su nueva personalidad.

Otra opción: no usar adduser para añadir usuarios al sistema. Quizás valdría con un conjunto de operaciones simples (que son las que realiza adduser).

Otra opción es utilizar el módulo suexec de Apache. Para ver si tu servidor tiene soporte de suexec, ejecuta apachectl -V y busca por la línea SUEXEC_BIN:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
root@hs-1590:/etc/apache2# apachectl -V
Server version: Apache/2.2.16 (Debian)
Server built:   Sep 29 2011 20:59:05
Server's Module Magic Number: 20051115:24
Server loaded:  APR 1.4.2, APR-Util 1.3.9
Compiled using: APR 1.4.2, APR-Util 1.3.9
Architecture:   64-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT="/etc/apache2"
 -D SUEXEC_BIN="/usr/lib/apache2/suexec"
 -D DEFAULT_PIDLOG="/var/run/apache2.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="/var/run/apache2/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="mime.types"
 -D SERVER_CONFIG_FILE="apache2.conf"
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Luego, ejecutas el binario que te indica esa línea:
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
root@hs-1590:/etc/apache2# /usr/lib/apache2/suexec -V
 -D AP_DOC_ROOT="/var/www"
 -D AP_GID_MIN=100
 -D AP_HTTPD_USER="www-data"
 -D AP_LOG_EXEC="/var/log/apache2/suexec.log"
 -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin"
 -D AP_UID_MIN=100
 -D AP_USERDIR_SUFFIX="public_html"
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Y ya vemos un problema: el UID mínimo del programa que permitirá ejecutar es 100, por lo que no podremos usar esta opción para ejecutar un programa como root. La opción pasa por recompilar una versión nueva de /usr/lib/apache2/suexec que sí lo permita. Y luego...
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problema para ejecutar script en Perl vía web

Notapor palafox87 » 2012-05-06 17:11 @758

Hola, explorer, antes que nada, muchas gracias por tu tiempo y tu excelente respuesta.

Te comento que ya logré hacer funcionar mi script. Te explico:

Basándome en tu respuesta, necesitaba hacer que el comando 'useradd' se ejecutara como root, por lo tanto es necesario usar 'sudo', pero es obvio que se me solicitaría la contraseña, entonces se me ocurrió hacer algo que hice hace un tiempo... permitirle a un usuario hacer sudo sin contraseña.

En este caso el usuario apache, el nombre de este usuario varía con cada distribución de Linux. En mi caso uso Ubuntu Server 11.10 y se llama 'www-data'.

Para darle esta propiedad al usuario edité mi archivo 'sudoers' con el comando 'visudo', quedando de la siguiente manera:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults        env_reset

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
www-data ALL=NOPASSWD:/usr/sbin/useradd       # <-------

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL


#includedir /etc/sudoers.d
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Como puedes ver solo le doy permiso que cuando sea sudo solo pueda usar el comando 'useradd'.

Y esto es todo.

Mi script quedo prácticamente igual, a excepción que antes del comando 'useradd' antepongo sudo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #! /usr/bin/perl
  2.  
  3. use CGI qq(:all);
  4. my $cgi = new CGI;
  5.  
  6. my $nombre = $cgi->param('nombre');
  7. my $codigo = $cgi->param('codigo');
  8. my $pass = $cgi->param('password');
  9.  
  10. my $useradd = "/usr/sbin/useradd";
  11.  
  12. print "Content-type:text/html\n\n";
  13.  
  14. if(getpwnam($codigo))
  15. {
  16.         print "El usuario ya existe!";
  17. }else{
  18.  
  19.         system qq(sudo $useradd -g users -d /home/$codigo -m -p`mkpasswd -m sha-512 -S abc12345 -s $pass` -c $nombre $codigo);
  20.  
  21.         if ( $? == 0 ) {
  22.  
  23.                 print "Usuario creado exitosamente!";
  24.  
  25.         }
  26.         else
  27.         {
  28.                 printf "Error!: %d", $? >> 8;
  29.         }
  30.  
  31. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¡De nuevo, muchas gracias!
palafox87
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-05-06 00:54 @079

Re: Problema para ejecutar script en Perl vía web

Notapor explorer » 2012-05-06 18:08 @797

Enhorabuena... sí, esa era otra opción... y desde luego, mucho más cómoda que otras que te he comentado.

En cuanto al código, decirte que si estás usando el módulo CGI, no necesitas escribir todo eso de Content-type...

Con un print head(); es más que suficiente.

Mira mi CGI mínimo, como ejemplo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problema para ejecutar script en Perl vía web

Notapor palafox87 » 2012-05-06 18:22 @807

Explorer una molestia más...

Como puedo ejecutar el siguiente comando:

Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
  1. sudo mysql -u root -p123456 -e "GRANT ALL PRIVILEGES ON \`$codigo\_%\` . * TO  '$codigo'@'%' IDENTIFIED BY '$pass';"
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Este último lo ejecuto desde un shell script y funciona, pero en perl tengo problemas con las dobles comillas de la query de mysql, ya las escape, pero no funciona.

Estoy haciendo lo siguiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $query = "sudo mysql -u root -p123456 -e \"GRANT ALL PRIVILEGES ON \`$codigo\_%\` . * TO '$codigo'\@'%' IDENTIFIED BY '$pass';\"";
  2.  
  3. system $query;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



Saludos.
palafox87
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-05-06 00:54 @079

Re: Problema para ejecutar script en Perl vía web

Notapor explorer » 2012-05-07 05:52 @286

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $query = qq(sudo mysql -u root -p123456 -e "GRANT ALL PRIVILEGES ON `$codigo\_%` . * TO '$codigo'@'%' IDENTIFIED BY '$pass';");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problema para ejecutar script en Perl vía web

Notapor palafox87 » 2012-05-08 01:11 @091

Hola explorer, de nueva cuenta te agradezco mucho por tu tiempo, pero no me funcionó esa línea. Pude lograrlo de otra manera... Hice un script en shell al cual le paso los parámetros necesarios.

Y anteponiendo una disculpa y aprovechándome una vez de tu amabilidad, te comento que a mi script en Perl, con el cual genero los usuarios, le agregué estas líneas para identificar los posibles errores, pero no logro que se impriman en pantalla:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         given("$?"){
  2.  
  3.                 when(1){
  4.                 print "No se pudo actualizar el archivo password (Error 1 verificar man useradd)"
  5.                 }
  6.                 when(2){
  7.                 print "Sintaxis del comando invalida (Error 2 verificar man useradd)"
  8.                 }
  9.  
  10.                 when(3){
  11.                 print "Argumento inválido para opción (Error 3 verificar man useradd)"
  12.                 }
  13.  
  14.                 when(4){
  15.                 print "EL UID ya existe (no -o) (Error 4 verificar man useradd)"
  16.                 }
  17.  
  18.                 when(6){
  19.                 printf "El grupo especificado no existe (Error 6 verificar man useradd)"
  20.                 }
  21.  
  22.                 when(9){
  23.                 print "El nombre de usuario ya esta en uso (Error 9 verificar man useradd)"
  24.                 }
  25.  
  26.                 when(10){
  27.                 print "No se pudo actualizar el archivo group (Error 10 verificar man useradd)"
  28.                 }
  29.  
  30.                 when(12){
  31.                 print "No se pudo crear el directorio Home (Error 12 verificar man useradd)"
  32.                 }
  33.  
  34.                 when(13){
  35.                 print "No se pudo crear el mail spool (Error 13 verificar man useradd)"
  36.                 }
  37.  
  38.         }
  39.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Me podrías ayudar? ;P

¡Saludos!
palafox87
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-05-06 00:54 @079

Re: Problema para ejecutar script en Perl vía web

Notapor explorer » 2012-05-08 05:19 @263

palafox87 escribiste:Hola explorer, de nueva cuenta te agradezco mucho por tu tiempo, pero no me funcionó esa línea. Pude lograrlo de otra manera... Hice un script en shell al cual le paso los parámetros necesarios.
¡Puf! ¡Qué complicado! Yo hubiera usado DBI, y listo.

palafox87 escribiste:Y anteponiendo una disculpa y aprovechándome una vez de tu amabilidad, te comento que a mi script en Perl, con el cual genero los usuarios, le agregué estas líneas para identificar los posibles errores, pero no logro que se impriman en pantalla:
Yo no veo nada raro en ese código... solo algunos detalles ortográficos, como que sobran las comillas en el given(), o que yo cambiaría los print() por say().

Quizás... lo que quieres obtener de $? es el resultado de la ejecución. Según perldoc perlvar, esa variable es de 16 bits, almacenando el resultado de la ejecución en el byte más alto. Si ese es el valor que quieres obtener, tiene que cambiar el given($?) por given($? >> 8).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Problema para ejecutar script en Perl vía web

Notapor palafox87 » 2012-05-08 09:37 @442

¡Muchas gracias explorer! ¡Ya funciona!

Me queda mucho por leer acerca de Perl :P

¡¡Gracias!!
palafox87
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2012-05-06 00:54 @079


Volver a Web

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 5 invitados