#!/bin/bash

#/**
#         setsmbpass
#@file    setsmbpass [ogLive]
#@brief   Cambia la contraseña del usuario del cliente para acceder a los servicios Samba.
#@warning Se modifica el Initrd del cliente y se cambia la clave en el servidor.
#@warning No se modifica el usuario de acceso (usuario "opengnsys").
#@version 1.0.2 - Versión inicial.
#@author  Ramón M. Gómez - ETSII Univ. Sevilla
#@date    2011-07-28
#@version 1.1.0 - Soporte para varios clientes ogLive.
#@author  Ramón M. Gómez - ETSII Univ. Sevilla
#@date    2017-06-20
#*/ ##


# Variables.
PROG=$(basename "$0")
PATH=$PATH:$(dirname "$(realpath "$0")")
OPENGNSYS=${OPENGNSYS:-"/opt/opengnsys"}
OGCFGFILE=$OPENGNSYS/etc/opengnsys.json
SAMBAUSER="opengnsys"				# Usuario por defecto.
TFTPDIR=$OPENGNSYS/tftpboot
INITRD=oginitrd.img
TMPDIR=/tmp/oglive$$
let CHANGES=0

# Control básico de errores.
if [ "$USER" != "root" ]; then
    echo "$PROG: Error: solo ejecutable por root" >&2
    exit 1
fi
case $# in
    0)  # Cambios en todos los clientes ogLive instalados.
        if which oglivecli &>/dev/null; then
            LIST=$(oglivecli list | awk '{print $2}')
        else
            LIST="ogclient"
        fi ;;
    1)  # Cambios en único ogLive (AVISO: puede crear inconsistencias con otros ogLive).
        LIST="$1" ;;
    *)	# Error de formato.
        echo "$PROG: Error de ejecución" >&2
        echo "Formato: $PROG ogLive"
        exit 1 ;;
esac

# Recuperar eco de consola si se corta el proceso.
trap "stty echo 2>/dev/null" KILL
# Buscar todos los clients ogLive instalados.
for OGLIVE in $LIST; do
    # Crear clave para usuario de acceso a los recursos.
    CLIENTINITRD="$TFTPDIR/$OGLIVE/$INITRD"
    if [ -r "$CLIENTINITRD" ]; then
        if [ -z "$SAMBAPASS" ]; then
	    # Obtener clave del teclado sin eco en pantalla.
	    stty -echo 2>/dev/null
	    echo -n "Clave del usuario Samba: "
	    read -r SAMBAPASS
	    # Solo se deben aceptar números y letras para la clave de acceso.
	    if [[ "$SAMBAPASS" =~ [^a-zA-Z0-9] ]]; then
		echo
		echo "$PROG: Error: la clave solo debe contener caracteres alfanuméricos" >&2
		stty echo 2>/dev/null
		exit 2
	    fi
	    echo
	    # Obtener confirmación clave sin eco en pantalla.
	    echo -n "Confirmar clave: "
	    read -r SAMBAPASS2
	    echo
	    stty echo 2>/dev/null
	    if [ "$SAMBAPASS" != "$SAMBAPASS2" ]; then
		echo "$PROG: Error: las claves no coinciden" >&2
		exit 2
	    fi
	fi
	# Editar la parte de acceso del cliente:
	#    descomprimir Initrd, sustituir clave y recomprimir Initrd).
	echo "Configurando cliente \"$OGLIVE\" ..."
	mkdir -p $TMPDIR
	cd $TMPDIR || { echo "Error: no se pudo cambiar al directorio temporal."; exit 3; }
	
    # Verificar si el archivo es gzip o lz4 antes de descomprimir.
    if file "$CLIENTINITRD" | grep -q "gzip compressed data"; then
        if ! gzip -dc "$CLIENTINITRD" | cpio -im; then
            echo "Error: No se pudo descomprimir y extraer $CLIENTINITRD con gzip."
            exit 4
        fi
        COMPRESS_CMD="gzip -9c"
    elif file "$CLIENTINITRD" | grep -q "LZ4 compressed data"; then
        if ! lz4 -d "$CLIENTINITRD" | cpio -im; then
            echo "Error: No se pudo descomprimir y extraer $CLIENTINITRD con lz4."
            exit 4
        fi
        COMPRESS_CMD="lz4 -c"
    else
        echo "Error: $CLIENTINITRD no está en formato gzip o lz4."
        exit 4
    fi
	if [ -f scripts/ogfunctions ]; then
		sed -i "s/OPTIONS=\(.*\)user=\w*\(.*\)pass=\w*\(.*\)/OPTIONS=\1user=$SAMBAUSER\2pass=$SAMBAPASS\3/" scripts/ogfunctions
		# TEMPORAL: solución ticket 554, actualizar cliente en caché (ogLive r3257).
		sed -i "s/busybox reboot/reboot/" scripts/ogfunctions
		# FIN CÓDIGO TEMPORAL.
		# Ticket 565, preparar acceso Rsync cliente.
		echo "$SAMBAPASS" > scripts/passrsync
		# Guardar tokens de seguridad.
		cat << EOT > scripts/client.cfg
CLIENTID=$(jq -r .client.id $OGCFGFILE)
CLIENTSECRET=$(jq -r .client.secret $OGCFGFILE)
EOT
		chown root.root scripts/passrsync scripts/client.cfg
		chmod 400 scripts/passrsync scripts/client.cfg
		# Generar Initrd del cliente.
		if ! find . | cpio -H newc -oa | $COMPRESS_CMD > "$CLIENTINITRD"; then
            echo "Error: No se pudo recomprimir $CLIENTINITRD."
            exit 5
        fi
	else
		echo "$PROG: Aviso: no se ha modificado la clave del cliente \"$OGLIVE\"."
	fi
	rm -fr $TMPDIR
	# Calcular suma de comprobación.
	md5sum "$CLIENTINITRD" | cut -f1 -d" " > "$CLIENTINITRD.sum"
	let CHANGES++
    else
        echo "$PROG: Cliente \"$OGLIVE\" no accesible."
    fi
done
if [[ $CHANGES != 0 ]]; then
    # Ticket 565, preparar acceso Rsync servidor.
    echo "$SAMBAUSER:$SAMBAPASS" > /etc/rsyncd.secrets
    chown root.root /etc/rsyncd.secrets
    chmod 600 /etc/rsyncd.secrets
    # Cambiar clave Samba.
    echo -ne "$SAMBAPASS\n$SAMBAPASS\n" | smbpasswd -a -s $SAMBAUSER
else
    echo "$PROG: Aviso: no se ha modificado la clave de ningún cliente."
fi

