From 81b2ea1a64279d9d90af8028369b034a04fb4545 Mon Sep 17 00:00:00 2001 From: "Ramón M. Gómez" Date: Tue, 25 Feb 2020 10:50:37 +0100 Subject: #957 #958: `setclientlive` and `setclientmode` script are adapted to global functions and avoid SQL injectionn. --- server/bin/setclientlive | 77 ++++++++++++--------------------- server/bin/setclientmode | 110 +++++++++++++++++++++-------------------------- 2 files changed, 77 insertions(+), 110 deletions(-) (limited to 'server') diff --git a/server/bin/setclientlive b/server/bin/setclientlive index 3ce417cb..42e55e4b 100755 --- a/server/bin/setclientlive +++ b/server/bin/setclientlive @@ -1,73 +1,52 @@ #!/bin/bash #/** -# setclientlive DirOGLive | IndiceOGLive { NombrePC | NombreAula } Modo_trabajo #@file setclientlive -#@brief Configura el archivo de arranque de PXE para asignar el cliente ogLive, ya sea a un equipo o a un aula -#@param $1 DirOGLive, IndiceOGLive o "default" (según script "oglivecli") -#@param $2 Ámbito { NombrePC | NombreAula } +#@brief Asignar un cliente de inicio ogLive a un ordenador o a un aula +#@usage setclientlive { DirOGLive | IndiceOGLive } Ambito +#@param DirOGLive subdirectorio del cliente ogLive ("default" para definido por defecto) +#@param IndiceOGLive nº de índice de cliente ogLive (según script "oglivecli") +#@param Ámbito nombre de ordenador o nombre de aula #warning No se admiten cambios temporales. #@version 1.1.0 - Versión inicial basada en script "setclientmode". #@author Ramón M. Gómez - Univ. Sevilla, junio 2017 #*/ ## -# Variables. -PROG=$(basename "$0") -PATH=$PATH:$(dirname $(realpath "$0")) +# Variables y funciones globales. +PROG="$(basename "$0")" OPENGNSYS=${OPENGNSYS:-"/opt/opengnsys"} +PATH=$PATH:$OPENGNSYS/bin SERVERCONF=$OPENGNSYS/etc/ogAdmServer.cfg TFTPDIR=$OPENGNSYS/tftpboot LOGFILE=$OPENGNSYS/log/opengnsys.log -MYCNF=/tmp/.my.cnf.$$ + +source $OPENGNSYS/lib/ogfunctions.sh || exit 1 # Control básico de errores. -if [ $# -ne 2 ]; then - echo "$PROG: Error de ejecución" >&2 - echo "Formato: $PROG {DIR_OGLIVE|INDICE_OGLIVE|default} {NOMBRE_PC|NOMBRE_AULA}" >&2 - exit 1 -fi -if [ ! -r $SERVERCONF ]; then - echo "$PROG: Sin acceso a fichero de configuración" >&2 - exit 2 -fi +[ "$*" == "help" ] && help +[ "$*" == "version" ] && version +[ $# -eq 2 ] || raiseError usage +[ "$USER" != "root" ] && raiseError access "Need to be root" +source $SERVERCONF 2>/dev/null || raiseError access "Sin acceso a fichero de configuración" + case "$1" in - [0-9]*) DIR=$(oglivecli search $1 2>/dev/null) ;; - "default") DIR="ogLive" ;; - *) if oglivecli search "$1" 2>/dev/null; then DIR="$1"; fi ;; + [0-9]*) DIR=$(oglivecli search $1 2>/dev/null) ;; + "default") DIR="ogLive" ;; + *) if oglivecli search "$1" &>/dev/null; then DIR="$1"; fi ;; esac -if [ -z "$DIR" ]; then - echo "$PROG: ogLive no ecncontrado, listar ejecutando \"oglivecli list\"" >&2 - exit 1 -fi -if [ ! -e "$TFTPDIR/$DIR" ]; then - echo "$PROG: directorio de ogLive no ecncontrado: \"DIR\"" >&2 - exit 1 -fi +[ "$DIR" ] || raiseError notfound "Cliente ogLive \"$1\", listar ejecutando \"oglivecli list\"" +[ -e "$TFTPDIR/$DIR" ] || raiseError notfound "Directorio de ogLive \"$DIR\"" -# Obtener datos de acceso a la Base de datos. -source $SERVERCONF # Sustituir caracteres ' por \' para evitar inyección SQL. -OGLIVEDIR="${DIR//\'/\'}" -RESOURCE="${2//\'/\'}" -# Componer fichero con credenciales de conexión. -touch $MYCNF -chmod 600 $MYCNF -cat << EOT > $MYCNF -[client] -user=$USUARIO -password=$PASSWORD -EOT -# Borrar el fichero temporal si termina el proceso. -trap "rm -f $MYCNF" 0 1 2 3 6 9 15 +OGLIVEDIR="${DIR//\'/\\\'}" +RESOURCE="${2//\'/\\\'}" # Actualizar ogLive asignado al aula. -mysql --defaults-extra-file="$MYCNF" -D "$CATALOG" -e \ - "UPDATE aulas SET oglivedir='$OGLIVEDIR' WHERE nombreaula='$RESOURCE';" +dbexec "UPDATE aulas SET oglivedir='$OGLIVEDIR' WHERE nombreaula='$RESOURCE';" # Actualizar ogLive para todos los clientes y reasignar plantilla PXE. listclientmode "$RESOURCE" | awk -F\" '{print $2,$4}' | \ while read -r PC BOOTMODE; do - date +"%b %d %T $PROG: Configurando \"$PC\" con cliente \"$OGLIVEDIR\"" | tee -a $LOGFILE - mysql --defaults-extra-file="$MYCNF" -D "$CATALOG" -e \ - "UPDATE ordenadores SET oglivedir='$OGLIVEDIR' WHERE nombreordenador='$PC';" - setclientmode "$BOOTMODE" "$PC" PERM >/dev/null - done + date +"%b %d %T $PROG: Configurando \"$PC\" con cliente \"$OGLIVEDIR\"" | tee -a $LOGFILE + dbexec "UPDATE ordenadores SET oglivedir='$OGLIVEDIR' WHERE nombreordenador = '$PC';" + setclientmode "$BOOTMODE" "$PC" PERM >/dev/null + done diff --git a/server/bin/setclientmode b/server/bin/setclientmode index af417c1e..2806c0ca 100755 --- a/server/bin/setclientmode +++ b/server/bin/setclientmode @@ -2,12 +2,12 @@ #/** #@file setclientmode -#@brief Configura el archivo de arranque de PXE para los clientes, ya sea un equipo o un aula, generando enlaces a archivos usados como plantilla. +#@brief Configura el archivo de arranque de PXE para los clientes, ya sea un equipo o un aula, generando enlaces a archivos usados como plantilla. #@usage setclientmode Plantilla Ambito Modo #@warning El archivo PXE por defecto "default" se deja en modo de ejecución "user" y se eliminan los enlaces para equipos con la plantilla por defecto. -#@param Plantilla: nombre de plantilla PXE -#@param Ambito: nombre de cliente o aula -#@param Modo: "TEMP" (temporal) o "PERM" (permanente) +#@param Plantilla nombre de plantilla PXE +#@param Ambito nombre de ordenador o nombre de aula +#@param Modo "TEMP" (temporal) o "PERM" (permanente) #@version 1.0 - Versión inicial. #@author Irina Gomez y Ramon Gomez - Univ. Sevilla, noviembre 2010 #@version 1.0.1 - Identificacion de la plantilla por nombre en consola = en primera linea de la plantilla @@ -27,19 +27,19 @@ #@date 2019-02-13 #*/ ## -# Variables. -PROG=$(basename $0) +# Variables y funciones globales. +PROG="$(basename "$0")" OPENGNSYS=${OPENGNSYS:-"/opt/opengnsys"} SERVERCONF=$OPENGNSYS/etc/ogAdmServer.cfg PXEDIR[0]=$OPENGNSYS/tftpboot/menu.lst PXEDIR[1]=$OPENGNSYS/tftpboot/grub LOGFILE=$OPENGNSYS/log/opengnsys.log -MYCNF=/tmp/.my.cnf.$$ source $OPENGNSYS/lib/ogfunctions.sh # Mostrar ayuda. [ "$*" == "help" ] && help +[ "$*" == "version" ] && version # Control básico de errores. [ $# -ne 3 ] && raiseError usage # Comprobar si el usuario es "root" o el del servicio web. @@ -48,8 +48,7 @@ CALLER=$(getcaller) [ "$USER" != "root" -a "$USER" != "$WEBUSER" -a "$CALLER" != "ogAdmServerAux" ] && raiseError access "Need to be root (or webserver user)" # El acceso a mysql por las variables pasadas o por el fichero de configuarción. if [ -z "$USUARIO" ] || [ -z "$PASSWORD" ] || [ -z "$CATALOG" ]; then - [ ! -r "$SERVERCONF" ] && raiseError access "Cannot read access configuration file" - source $SERVERCONF + source $SERVERCONF 2>/dev/null || raiseError access "Server configuration file" fi TEMPLATE[0]=$(grep -l "^#.* $1 *$" ${PXEDIR[0]}/templates/* 2>/dev/null) TEMPLATE[1]=$(grep -l "^#.* $1 *$" ${PXEDIR[1]}/templates/* 2>/dev/null) @@ -62,24 +61,14 @@ case "${3^^}" in esac # Sustituir caracteres ' por \' para evitar inyección SQL. -BOOTMODE="${1//\'/\'}" -RESOURCE="${2//\'/\'}" -# Componer fichero con credenciales de conexión. -touch $MYCNF -chmod 600 $MYCNF -cat << EOT > $MYCNF -[client] -user=$USUARIO -password=$PASSWORD -EOT -# Borrar el fichero temporal si termina el proceso. -trap "rm -f $MYCNF" 0 1 2 3 6 9 15 +BOOTMODE="${1//\'/\\\'}" +RESOURCE="${2//\'/\\\'}" # Buscar ordenador individual o todos los de una aula. -ETHERNET=$(mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -s -N -e \ - "SELECT mac FROM ordenadores - JOIN aulas USING (idaula) - WHERE aulas.nombreaula='$RESOURCE' - OR nombreordenador='$RESOURCE';") +ETHERNET=$(dbexec " + SELECT mac FROM ordenadores + JOIN aulas USING (idaula) + WHERE aulas.nombreaula ='$RESOURCE' + OR nombreordenador = '$RESOURCE';") if [ -z "$ETHERNET" ]; then date +"%b %d %T $PROG: No existe aula o equipo con el nombre \"$2\"" >> $LOGFILE raiseError notfound "Client or lab name \"$2\"" @@ -102,38 +91,38 @@ for MAC in $ETHERNET; do # Si no está definida la variable LANG, usar idioma inglés por defecto. [ -z "$LANG" -o "$LANG" == "C" ] && LANG="en" # Obtener de la BD los parámetros de arranque asociados (separador es TAB). - DATOS=$(mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -s -N -e \ - "SELECT ' LANG=$LANG', - ' ip=', CONCAT_WS(':', ordenadores.ip, - (SELECT (@serverip:=ipserveradm) FROM entornos LIMIT 1), - aulas.router, aulas.netmask, - ordenadores.nombreordenador, ordenadores.netiface, 'none'), - ' group=', REPLACE(TRIM(aulas.nombreaula), ' ', '_'), - ' ogrepo=', (@repoip:=IFNULL(repositorios.ip, '')), - ' oglive=', @serverip, - ' oglog=', @serverip, - ' ogshare=', @serverip, - ' oglivedir=', ordenadores.oglivedir, - ' ogprof=', IF(ordenadores.idordenador=aulas.idordprofesor, 'true', 'false'), - IF(perfileshard.descripcion<>'', CONCAT(' hardprofile=', REPLACE(TRIM(perfileshard.descripcion), ' ', '_')), ''), - IF(aulas.ntp<>'', CONCAT(' ogntp=', aulas.ntp), ''), - IF(aulas.dns<>'', CONCAT(' ogdns=', aulas.dns), ''), - IF(aulas.proxy<>'', CONCAT(' ogproxy=', aulas.proxy), ''), - IF(entidades.ogunit=1 AND NOT centros.directorio='', CONCAT(' ogunit=', centros.directorio), ''), - CASE - WHEN menus.resolucion IS NULL THEN '' - WHEN menus.resolucion <= '999' THEN CONCAT(' vga=', menus.resolucion) - WHEN menus.resolucion LIKE '%:%' THEN CONCAT(' video=', menus.resolucion) - ELSE menus.resolucion - END - FROM ordenadores - JOIN aulas USING(idaula) - JOIN centros USING(idcentro) - JOIN entidades USING(identidad) - LEFT JOIN repositorios USING(idrepositorio) - LEFT JOIN perfileshard USING(idperfilhard) - LEFT JOIN menus USING(idmenu) - WHERE ordenadores.mac='$MAC';") + DATOS=$(dbexec " +SELECT ' LANG=$LANG', + ' ip=', CONCAT_WS(':', ordenadores.ip, + (SELECT (@serverip:=ipserveradm) FROM entornos LIMIT 1), + aulas.router, aulas.netmask, + ordenadores.nombreordenador, ordenadores.netiface, 'none'), + ' group=', REPLACE(TRIM(aulas.nombreaula), ' ', '_'), + ' ogrepo=', (@repoip:=IFNULL(repositorios.ip, '')), + ' oglive=', @serverip, + ' oglog=', @serverip, + ' ogshare=', @serverip, + ' oglivedir=', ordenadores.oglivedir, + ' ogprof=', IF(ordenadores.idordenador=aulas.idordprofesor, 'true', 'false'), + IF(perfileshard.descripcion<>'', CONCAT(' hardprofile=', REPLACE(TRIM(perfileshard.descripcion), ' ', '_')), ''), + IF(aulas.ntp<>'', CONCAT(' ogntp=', aulas.ntp), ''), + IF(aulas.dns<>'', CONCAT(' ogdns=', aulas.dns), ''), + IF(aulas.proxy<>'', CONCAT(' ogproxy=', aulas.proxy), ''), + IF(entidades.ogunit=1 AND NOT centros.directorio='', CONCAT(' ogunit=', centros.directorio), ''), + CASE + WHEN menus.resolucion IS NULL THEN '' + WHEN menus.resolucion <= '999' THEN CONCAT(' vga=', menus.resolucion) + WHEN menus.resolucion LIKE '%:%' THEN CONCAT(' video=', menus.resolucion) + ELSE menus.resolucion + END + FROM ordenadores + JOIN aulas USING(idaula) + JOIN centros USING(idcentro) + JOIN entidades USING(identidad) + LEFT JOIN repositorios USING(idrepositorio) + LEFT JOIN perfileshard USING(idperfilhard) + LEFT JOIN menus USING(idmenu) + WHERE ordenadores.mac='$MAC';") # Quitar tabuladores, sustituir acentos y dejar resolución por defecto. DATOS=$(echo ${DATOS// /} | tr 'áéíóúñçÁÉÍÓÚÑÇ' 'aeiouncAEIOUNC') [[ "$DATOS" =~ (vga|video) ]] || DATOS="$DATOS vga=788" @@ -160,7 +149,6 @@ for MAC in $ETHERNET; do [ -n "$WEBUSER" ] && chown $WEBUSER:$WEBGROUP ${PXEDIR[$BOOTTYPE]}/${PXEFILEE[$BOOTTYPE]} done - # Si el modo de trabajo es temporal (0) mete un retardo, restaura el fichero PXE a su estado original y no toca la base de datos if [ "$MODE" == "TEMP" ]; then sleep 60 @@ -178,10 +166,10 @@ for MAC in $ETHERNET; do # Si no existe la plantilla de tipo BIOS tomo el nombre de la UEFI [ -z "${TEMPLATE[0]}" ] && TEMPLATE[0]=${TEMPLATE[1]} - mysql --defaults-extra-file=$MYCNF -D "$CATALOG" -e \ - "UPDATE ordenadores SET arranque='$(basename ${TEMPLATE[0]})' WHERE mac='$MAC';" + dbexec "UPDATE ordenadores SET arranque='$(basename ${TEMPLATE[0]})' WHERE mac='$MAC';" fi fi let NPC=NPC+1 done date +"%b %d %T $PROG: $NPC equipo(s) configurado(s)" | tee -a $LOGFILE + -- cgit v1.2.3-18-g5258