#!/bin/bash
. /usr/lib/eole/diagnose.sh

#Set context for AD
#In case seth, DC is in root container
#In case scribeAD, DC is in addc container only if DC is local

SAMBA4_VARS=/etc/eole/samba4-vars.conf
if [[ -f "$SAMBA4_VARS" ]]
then
    declare -a SAMBA_CONFS=($SAMBA4_VARS $(find -H /var/lib/lxc -type f -wholename "**/rootfs$SAMBA4_VARS" 2>/dev/null))
else
    declare -a SAMBA_CONFS=($(find -H /var/lib/lxc -type f -wholename "**/rootfs$SAMBA4_VARS" 2>/dev/null))
fi
if [[ ${#SAMBA_CONFS[@]} -lt 1 ]]
then
    # No templates found
    echo "Samba is disabled"
    exit 0
fi

function test_configuration()
{
    cmd_wrapper="$1"
    container_path="$2"
    echo "Fichier de configuration :"
    printf ".  %${len_pf}s => " "Syntaxe"
    $cmd_wrapper samba-tool testparm --suppress-prompt >/dev/null 2>&1
    if [[ $? -eq 0 ]]
    then
        EchoVert "Ok"
    else
        EchoRouge "Erreur"
    fi
    echo
}

function test_dns()
{
    cmd_wrapper="$1"
    container_path="$2"
    echo "DNS AD :"
    printf ".  %${len_pf}s => " "Enregistrements SRV"
    CDU=NOK
    if host -t SRV _ldap._tcp.dc._msdcs.${AD_REALM}. >/dev/null 2>&1
    then
        DNS_LDAP_SCE=$(mktemp)
        host -t SRV _ldap._tcp.${AD_REALM}. > $DNS_LDAP_SCE
        if [ $? -eq 0 ]
        then
            # Hostname des controleurs de domaine dans le tableau DCS
            read -a DCS <<< $(sed -e 's/.* \([^ ].*\)./\1/' ${DNS_LDAP_SCE})
            if host -t SRV _kerberos._udp.${AD_REALM}. >/dev/null 2>&1
            then
                CDU=OK
            fi
        fi
        rm -rf $DNS_LDAP_SCE
    fi
    if [ "$CDU" = "OK" ]
    then
        EchoVert "Ok"
    else
        EchoRouge "Erreur (Vérifier 'Nom DNS du réseau local')"
    fi
    if [ "${AD_SERVER_ROLE}" == "controleur de domaine" ] && [ -z "${AD_SERVER_MODE}" ]; then
        # Attention au é qui compte 2 caractères
        printf ".   %${len_pf}s => " "Résolution ${AD_HOST_NAME}.${AD_REALM}"
        $cmd_wrapper dig @localhost ${AD_HOST_NAME}.${AD_REALM} >/dev/null 2>&1
        if [ $? = 0 ]
        then
            EchoVert "Ok"
        else
            EchoRouge "Erreur"
        fi
        echo
    else
        echo
    fi
}

function test_certificate()
{
    cmd_wrapper="$1"
    container_path="$2"
    if [ "${AD_SERVER_ROLE}" == "controleur de domaine" ] && [ -z "${AD_SERVER_MODE}" ]; then
        echo "Certificat LDAPS :"
        TLS_ENABLED=$($cmd_wrapper samba-tool testparm --suppress-prompt --parameter-name='tls enabled' 2>/dev/null)
        if [ "${TLS_ENABLED^^}" = YES ]
        then
            TLS_CERTFILE=$($cmd_wrapper samba-tool testparm --suppress-prompt --parameter-name='tls certfile' 2>/dev/null)
            if [ -n "${TLS_CERTFILE}" ]
            then
                if [ "$TLS_CERTFILE" = "tls/cert.pem" ]; then
                    TLS_CERTFILE="/var/lib/samba/private/tls/cert.pem"
                fi
                printf ".  %${len_pf}s => " "Certificat"
                if [ -f "${container_path}${TLS_CERTFILE}" ]
                then
                    if ! openssl x509 -enddate -noout -in "${container_path}${TLS_CERTFILE}" -checkend 604800 >/tmp/samba_cert.info
                    then
                        if ! openssl x509 -enddate -noout -in "${container_path}${TLS_CERTFILE}" -checkend 0 >/tmp/samba_cert.info
                        then
                            MSG=$(awk -F= '/notAfter/ { print $2; }' /tmp/samba_cert.info)
                            EchoOrange "Expiré (${MSG})"
                        else
                            MSG=$(awk -F= '/notAfter/ { print $2; }' /tmp/samba_cert.info)
                            EchoOrange "Expiration dans moins d'une semaine (${MSG})"
                        fi
                    else
                        MSG=$(awk -F= '/notAfter/ { print $2; }' /tmp/samba_cert.info)
                        EchoVert "Ok (${MSG})"
                    fi
                else
                    EchoRouge "Fichier ${TLS_CERTFILE} manquant"
                fi
            fi
            TLS_CAFILE=$($cmd_wrapper samba-tool testparm --suppress-prompt --parameter-name='tls cafile' 2>/dev/null)
            if [ -n "${TLS_CAFILE}" ]
            then
                if [ "$TLS_CAFILE" = "tls/ca.pem" ]; then
                    TLS_CAFILE="/var/lib/samba/private/tls/ca.pem"
                fi
                printf ".  %${len_pf}s => " "CA"
                if [ -f "${container_path}${TLS_CAFILE}" ]
                then
                    if ! openssl x509 -enddate -noout -in "${container_path}${TLS_CAFILE}" -checkend 604800 >/tmp/samba_cert.info
                    then
                        if ! openssl x509 -enddate -noout -in "${container_path}${TLS_CAFILE}" -checkend 0 >/tmp/samba_cert.info
                        then
                            MSG=$(awk -F= '/notAfter/ { print $2; }' /tmp/samba_cert.info)
                            EchoRouge "Expiré (${MSG})"
                        else
                            MSG=$(awk -F= '/notAfter/ { print $2; }' /tmp/samba_cert.info)
                            EchoOrange "Expiration dans moins d'une semaine (${MSG})"
                        fi
                    else
                        MSG=$(awk -F= '/notAfter/ { print $2; }' /tmp/samba_cert.info)
                        EchoVert "Ok (${MSG})"
                    fi
                else
                    EchoRouge "Fichier ${TLS_CAFILE} manquant"
                fi
            fi
        else
            printf ".  %${len_pf}s => " "LDAPS"
            EchoVert "Supportée"
        fi
        echo
        #echo | openssl s_client -servername shellhacks.com -connect shellhacks.com:443 2>/dev/null | openssl x509
    fi
}

function test_repl()
{
    cmd_wrapper="$1"
    container_path="$2"
    if [ "${AD_SERVER_ROLE}" == "controleur de domaine" ] && [ -z "${AD_SERVER_MODE}" ]; then
        echo "Réplication :"
        printf ".  %${len_pf}s => " "Statut"
        TestService "Port de réplication" ${AD_HOST_NAME}.${AD_REALM}:135 > /dev/null
        if [ $? -ne 0 ]
        then
            EchoRouge "Port de réplication 135 non accessible"
        else
            $cmd_wrapper samba-tool drs bind |grep -qe "DRSUAPI_SUPPORTED_EXTENSION_BASE.* Yes"
            if [ $? -ne 0 ]
            then
                EchoRouge "Non supportée"
            else
                EchoVert "Supportée"
                LOCAL_DC=$($cmd_wrapper hostname -f)
                # DN of the Naming Context dans la variable NC
                IFS='.' read -a DN <<<$AD_REALM
                NC="DC=${DN[0]}"
                for ((i=1;i<${#DN[@]};i++))
                do
                    NC="${NC},DC=${DN[$i]}"
                done

                # Etat de la replication entre chaque DC
                declare -a ONLINE_DCS
                for ((i=0; i<${#DCS[@]}; i++))
                do
                    DC=${DCS[$i]}
                    if [ "${DC}" != "${LOCAL_DC}" ]
                    then
                        $cmd_wrapper /usr/bin/tcpcheck 2 ${DC}:135 >> /dev/null 2>&1
                        if [ $? -eq 0 ]
                        then
                            ONLINE_DCS[$i]="0"
                        else
                            ONLINE_DCS[$i]="1"
                        fi
                    fi
                done
                TMP_SHOWREPL=$(mktemp)
                $cmd_wrapper samba-tool drs showrepl > $TMP_SHOWREPL
                IN_REPL=$(sed -n '/==== INBOUND NEIGHBORS ====/,/==== OUTBOUND NEIGHBORS ====/p' $TMP_SHOWREPL)
                OUT_REPL=$(IFS="\n" sed -n '/==== OUTBOUND NEIGHBORS ====/,/==== KCC CONNECTION OBJECTS ====/p' $TMP_SHOWREPL)
                rm -rf $TMP_SHOWREPL
                for ((i=0; i<${#DCS[@]}; i++))
                do
                    DC=${DCS[$i]}
                    if [ "${DC}" != "${LOCAL_DC}" ]
                    then
                        if [ "${ONLINE_DCS[$i]}" == "0" ]
                        then
                            printf ".  %${len_pf}s => " "Depuis ${DC}"
                            DC_INFO=$(grep -ie "$(cut -d'.' -f1 <<< $DC)" -A2 <<< $IN_REPL)
                            if [ $? -eq 0 ]
                            then
                                grep -qe "Last attempt.*was successful" <<< $DC_INFO
                                if [ $? -eq 0 ]
                                then
                                    EchoVert "OK"
                                else
                                    EchoRouge "Erreur"
                                fi
                            else
                                EchoOrange "Inconnu"
                            fi
                            printf ".  %${len_pf}s => " "Vers ${DC}"
                            DC_INFO=$(grep -ie "$(cut -d'.' -f1 <<< $DC)" -A2 <<< $OUT_REPL)
                            if [ $? -eq 0 ]
                            then
                                grep -qe "Last attempt.*was successful" <<< $DC_INFO
                                if [ $? -eq 0 ]
                                then
                                    EchoVert "OK"
                                else
                                    EchoRouge "Erreur"
                                fi
                            else
                                EchoOrange "Inconnu"
                            fi
                        else
                            printf ".  %${len_pf}s => " "Avec ${DC}"
                            if [ "${ONLINE_DCS[$i]}" == "1" ]
                            then
                                EchoRouge "Erreur"
                            else
                                EchoRouge "Injoignable"
                            fi
                        fi
                    fi
                done
            fi
        fi
        echo
    else
        echo
    fi
}

function test_database()
{
    if [ "${AD_SERVER_ROLE}" == "controleur de domaine" ] && [ -z "${AD_SERVER_MODE}" ]; then
        stfile="/var/lib/eole/reports/samba-dbcheck.log"
        echo "Base de données samba :"
        printf ".  %${len_pf}s => " "Nombre d'erreurs "
        if [[ -e ${stfile} ]]
        then
            read -a db_status <<< $(cat /var/lib/eole/reports/samba-dbcheck.log)
            db_errors=${db_status[0]}
            if [[ -z "$db_errors" ]]
            then
                EchoOrange "Information indisponible"
            elif [[ "$db_errors" -eq 0 ]]
            then
                EchoVert "${db_errors}"
            else
                EchoRouge "${db_errors}"
		EchoRouge "Consulter le rapport complet /var/lib/eole/reports/samba-dbcheck.full_report pour plus de détails"
            fi
        else
            EchoOrange "fichier de status non présent"
        fi
        echo
    fi
}


EchoGras "*** Serveur Active Directory"
echo
for samba_conf in ${SAMBA_CONFS[@]}
do
    container_path="${samba_conf%${SAMBA4_VARS}}"
    container="$(echo $container_path | sed 's,/var/lib/lxc/\(.*\)/rootfs,\1,')"
    if [[ -n "$container" ]]
    then
        cmd_wrapper="lxc-attach -n $container -- "
        EchoGras "**** Conteneur $container"
    else
        EchoGras "**** Hôte"
        cmd_wrapper=""
    fi
    (source "$samba_conf"; test_configuration "$cmd_wrapper" "$container_path"; test_dns "$cmd_wrapper" "$container_path"; test_certificate "$cmd_wrapper" "$container_path"; test_repl "$cmd_wrapper" "$container_path" ; test_database)
done
