#!/usr/bin/perl

# v1.0 Programme de Guillaume Lehmann. Programme protégé par la licence GNU Public Licence version 3.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# CONSOLE D'ADMINISTRATION POUR FREERADIUS #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#


# ÉTAT DES TESTS :
# --help : Affichage de l'aide ==> OK.
# 0 : Sortie du menu si 0 ==> OK.
# 11 : Ajouter un utilisateur ==> OK.
# 12 : Suppression utilisateur ==> OK.
# 13 : Modifier le mot de passe d'un utilisateur ==> OK
# 14 : Ajout d'un attribut à un utilisateur ==> OK
# 15 : Lister les utilisateurs => OK
# 21 : Ajouter un attribut de requête à un groupe ==> OK
# 22 : Ajouter un attribut de réponse à un groupe ==> OK
# 23 : Lister les attributs de requête ==> OK
# 24 : Lister les attributs de réponse ==> OK
# 25 : Supprimer un attribut de requête à un groupe ==> OK
# 26 : Supprimer un attribut de réponse à un groupe ==> OK
# 27 : Supprimer un groupe et tous ses attributs ==> OK
# 31 : Ajouter un nas ==> OK
# 32 : Suppression nas ==> OK
# 33 : Lister les nas ==> OK
# 41 : Synchroniser du principal vers le secours ==> OK
# 42 : Lancer une sauvegarde ==> OK
# 43 : Afficher les tentatives de connexion erronées ==> OK
# 44 : Afficher les tentatives de connexions réussies ==> OK
# 45 : Afficher les dernières connexions au système ==> OK
# 46 : Afficher un état des serveurs ==> OK
# 47 : Vérifier l'état des services et déclencher watchdog si nécessaire ==> OK


use DBI ;
use Time::localtime ;
use Getopt::Long ;



# Définition de tous les formatages
format ListUsers = 
|@||||||||||||| |@||||||||||||||||||| |@||||||||||||||||| |
$ResReqLign->{'UserName'}, $ResReqLign->{'Value'}, $ResReqLign->{'GroupName'}
.
    
    format ListReqRep =
|@|||| |@|||||||||||| |@|||||||||||||||||||||||||| |@||||||| |@||||||||||||||||||||||||| |
$ResReqLign->{'id'}, $ResReqLign->{'GroupName'}, $ResReqLign->{'Attribute'}, $ResReqLign->{'op'}, $ResReqLign->{'Value'}
.
    format ListNas = 
|@|||||||||||||| |@|||||||||||||| |@|||||| |@||| |@|||||||||||||| |@||||||||||| |@|||||||| |@|||||||||||||||||||| |
$ResReqLign->{'nasname'}, $ResReqLign->{'shortname'}, $ResReqLign->{'type'}, $ResReqLign->{'ports'}, $ResReqLign->{'secret'}, $ResReqLign->{'groupe'}, $ResReqLign->{'community'}, $ResReqLign->{'description'}
.
    
    format ListConnOK =
|@|||| |@||||||||||||||| |@|||||||||||||||||||| |@|||||||||||||||||||| |
$ResReqLign->{'id'}, $ResReqLign->{'user'}, $ResReqLign->{'reply'}, $ResReqLign->{'date'}
.


# Récupération des éventuels arguments de la commande.
    GetOptions("A!" => \$Option, "choix=s" => \$Choix, "sschoix=s" => \$SousChoix, "nom:s" => \$Nom, "mdp:s" => \$MdP, "groupe:s" => \$Group, "newmdp:s" => \$NewMdP, "attribute:s" => \$Attribute, "op:s" => \$Op, "value:s" => \$Value, "nasname:s" => \$Nasname, "shortname:s" => \$Shortname, "type:s" => \$Type, "port:i" => \$Ports, "secret:s" => \$Secret, "description:s" => \$Description, "help" => \$Help) ;

# Affichage du menu d'aide si --help est indiqué.
if ($Help) {
    print "\n                                          -==Introduction==-" ;
    print "\nL'ordre des options importe peu. Il n'est pas nécessaire de mettre en entier le nom des options (juste assez de lettres que ce ne soit pas ambigüe). En revanche les valeurs des options ne doivent pas être abrégées.\n" ;
    print "Mettre \"-\" ou \"--\" devant les noms des options revient au même.\n" ;
    print "La casse du nom des options n'a pas d'influence.\n\n" ;
    print "                                            -==Arguments==-\n" ;
    print "--choix [1|user, 2|group, 3|nas, 4|adm] : choix dans menu.\n" ;
    print "--sschoix [11|adduser, 12|del, 13|modpass, 14|addatt, 15|list]\n" ;
    print "          [21|addreq, 22|addrep, 23|listreq, 24|listrep, 25|delreq, 26|delrep,  27|delgroup]\n" ;
    print "          [31|add, 32|del, 33|list]\n" ;
    print "          [41|sync, 42|sauv, 43|listerr, 44|listok, 45|last, 46|state, 47|watch]\n" ;
    print "    choix dans sous-menu.\n" ;
    print "--nom : nom\n" ;
    print "--mdp : mot de passe\n" ;
    print "--groupe : groupe\n" ;
    print "--newmdp : nouveau mot de passe lors d'un changement de mot de passe (l'actuel est indiqué alors par --MdP).\n" ;
    print "--attribute : nom de l'attribut manipulé\n" ;
    print "--op : opérateur qui sera appliqué à l'attribut --Attribute\n" ;
    print "--value : valeur d'un attribut --Attribute en fonction de l'opérateur --Op.\n" ;
    print "--nasname : élément identifiant l'équipement réseau (généralement son adresse IP).\n" ;
    print "--shortname : nom court de l'équipement réseau.\n" ;
    print "--type : type d'équipement (\"other\" pour un switch).\n" ;
    print "--port : port de l'équipement réseau duquel doit venir la requête (0 par défaut).\n" ;
    print "--secret : secret partagé à la création d'un équipement réseau.\n" ;
    print "--description : description ou commentaire à la création d'un équipement réseau.\n" ;
    print "--loginrootdb : login de l'administrateur de la base de données.\n" ;
    print "--passwordrootdb : mot de passe de l'administrateur de la base de données.\n" ;
    print "--help : affiche le menu présent.\n\n" ;
    print "                             -==Listing des arguments pour chaque menu==-\n" ;
    print "Menu 11 : --nom  --mdp  --groupe\n" ;
    print "Menu 12 : --nom  --mdp\n" ;
    print "Menu 13 : --nom  --newmdp\n" ;
    print "Menu 14 : --nom  --attribute  --op  --value  --mdp\n" ;
    print "Menu 15 : Pas d'argument si on veut tout lister, sinon --nom\n" ;
    print "Menu 21 : --groupe  --attribute  --op  --value\n" ;
    print "Menu 22 : --groupe  --attribute  --op  --value\n" ;
    print "Menu 23 : Pas d'argument\n" ;
    print "Menu 24 : Pas d'argument\n" ;
    print "Menu 25 : --groupe  --attribute\n" ;
    print "Menu 26 : --groupe  --attribute\n" ;
    print "Menu 27 : --groupe  --mdp\n" ;
    print "Menu 31 : --nasname  --shortname  --type  --port  --secret  --groupe  --description\n" ;
    print "Menu 32 : --nasname  --mdp\n" ;
    print "Menu 33 : Pas d'argument si on veut tout lister, sinon --nom\n" ;
    print "Menu 41 : Pas d'argument\n" ;
    print "Menu 42 : --logindb  --passworddb\n" ;
    print "Menu 43 : Pas d'argument\n" ;
    print "Menu 44 : --mdp\n" ;
    print "Menu 45 : Pas d'argument\n" ;
    print "Menu 46 : Pas d'argument\n" ;
    print "Menu 47 : Pas d'argument\n" ;
    print "\nProgramme sous licence GPLv3. Guillaume Lehmann\n" ;
    exit(1) ;
}

# Si -A n'est pas rentré comme option, alors on n'est pas en mode Automatique mais en mode Intéractif.
if (!$Option) {
    # Initialisation de la variable pour pouvoir rentrer dans la boucle while.
    $Choix = "1" ;
}
else {
    $reponse = "o" ;
}


while ($Choix ne "0") {
    if (!$Option) {	
	$reponse = "" ;
    }
    else {
	$reponse = "o" ;
    }
    

    # Affichage du menu si on n'est pas en mode Automatique.
    if (!$Option) {
	print "\n\n#############################################\n" ;
	print "#### CONSOLE D'ADMINISTRATION FreeRADIUS ####\n" ;
	    print " 0 - Quitter l'application\n" ;
	print " 1 - Gestion des utilisateurs\n" ;
	print " 2 - Gestion des groupes\n" ;
	print " 3 - Gestion des équipements réseaux\n" ;
	print " 4 - Administration\n" ;
	print "#############################################\n" ;
    }
    # Récupération des identifiants pour accéder à la base de données.
    open(ACCESBD, '/adminradius/AccesBD.txt') || die "Problème à l'accès au fichier AccesBD.txt" ;
#    open(ACCESBD, 'AccesBD.txt') || die "Problème à l'accès au fichier AccesBD.txt" ;
    $resultat = <ACCESBD> ;
    close (ACCESBD) ;
    ($DatabaseDB, $HostnameDB, $LoginDB, $PasswordDB, $TypDB) = $resultat =~ /^(\w*)\s*(\w*)\s*(\w*)\s*(\w*)\s*(\w*)\s*$/ ;
    
    $dsn = "DBI:$TypDB:database=$DatabaseDB;host=$HostnameDB" ;

    # Ouverture de la base de données.
    $dbh = DBI->connect($dsn, $LoginDB, $PasswordDB) ;

    # Lecture du choix de l'utilisateur en mode Intéractif
    if (!$Option) {
	print "Choix : " ;
	$Choix = <STDIN> ;
	chomp $Choix ;
    }
    

    # GESTION DES UTILISATEURS
    if ($Choix eq "1" or $Choix eq "user") {
	# Affichage du menu si l'on n'est pas en mode Automatique.
	if (!$Option) {
	    print "\n\n#############################################\n" ;
	    print "11 - Ajouter un utilisateur\n" ;
	    print "12 - Supprimer un utilisateur\n" ;
	    print "13 - Modifier le mot de passe d'un utilisateur\n" ;
	    print "14 - Ajout d'un attribut à un utilisateur\n" ;
	    print "15 - Lister un ou tous les utilisateurs\n" ;
	    print "#############################################\n" ;

	    # Lecture du choix de l'utilisateur en mode Intéractif
	    print "Choix : " ;
	    $SousChoix = <STDIN> ;
	    chomp $SousChoix ;
	}
	if ($SousChoix eq "11" or $SousChoix eq "adduser") {
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Nom) {
		print "Nom : " ;
		$Nom = <STDIN> ;
		chomp $Nom ;
	    }
	    if (!$MdP) {
		print "\nMot de passe : " ;
		$MdP = <STDIN> ;
		chomp $MdP ;
	    }
	    if (!$Group) {
		print "\nGroupe : " ;
		$Group = <STDIN> ;
		chomp $Group ;
	    }

	    # Rajouter un utilisateurs dans la base de données après avoir vérifié qu'il n'existe pas déjà et que sont login et mdp ne sont pas nuls
	    if ($Nom eq "" or $MdP eq "") {
		# Ne rien faire car le login ou le mot de passe est vide.
		print "[NOK] Le login ou le mot de passe est vide\n" ;
	    }
	    else {
		$ResReq = $dbh->prepare("SELECT UserName FROM radcheck WHERE UserName LIKE \"$Nom\";") ;
		$ResReq->execute() ;
		$ResReqLign = $ResReq->fetchrow_hashref() ;
		if ($ResReqLign->{'UserName'} ne "") {
		    # Ne rien faire car l'utilisateur existe déjà
		    print "[NOK] L'utilisateur existe déjà\n" ;
		    $ResReq->finish() ;
		}
		else {
		    # Nettoyer requête.
		    $ResReq->finish() ;
		    # Création des paramètres de création du mot de passe système.
		    $chaine = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
		    # Création de la graine.
		    for ($i = 0; $i < 8; $i++) {
			$graine .= substr($chaine, rand(length($chaine)), 1);
		    }
		    # Création du mot de passe chiffré au format MD5 (donc graine au format $1$ suivi de 8 caract$
		    $mdpCrypt = crypt($MdP, '$1$'.$graine.'$') ;
		    
		    # Faire l'insertion.
		    $ResReq = $dbh->do("INSERT INTO radcheck (UserName, Attribute, op, Value) VALUES (\"$Nom\", \"Crypt-Password\", \"==\", \"$MdP\") ;") ;
		    $ResReq = $dbh->do("INSERT INTO usergroup (UserName, GroupName) VALUES (\"$Nom\", \"$Group\") ;") ;
		    print "[OK] Utilisateur créé sous FreeRADIUS\n\n" ;
		    sleep 1 ;	    
		    
		    # Création de l'utilisateur dans le système.
		    print `adduser --system --home /home/RADIUSuser --shell /adminradius/chroot --ingroup RADIUSgroup $Nom` ;
		    # Changement/Définition du mot de passe.
		    print `usermod -p '$mdpCrypt' $Nom` ;
		    print "Sauf si erreur ci-dessus, utilisateur créé dans le système\n" ;
		    sleep 1 ;
		} # Fin if ($ResReqLign->{'UserName'} ne "") ELSE
	    } # Fin if ($Nom eq "" or $MdP eq "") {} ELSE
	} # Fin if ($SousChoix eq "11")

	if ($SousChoix eq "12" or $SousChoix eq "del") {
	    # SUPPRIMER UN UTILISATEUR
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Nom) {
		print "Nom : " ;
		$Nom = <STDIN> ;
		chomp $Nom ;
	    }
	    if (!$MdP) {
		print "\nMot de passe de l'utilisateur de la base : " ;
		$MdP = <STDIN> ;
		chomp $MdP ;
	    }
	    if (!$reponse) {
		# Demander une confirmation avant de faire l'irrémédiable.
		print "Confirmer suppression ? (o/n)" ;
		$reponse = <STDIN> ;
		chomp $reponse ;
	    }
	    
	    # Il faut le mot de passe user valide et la confirmation de la suppression pour l'effectuer.
	    if (($reponse eq "o") and ($MdP eq $PasswordDB)) {
		# Supprimer l'utilisateur dans la base de données.
		$ResReq = $dbh->do("DELETE FROM radcheck WHERE UserName LIKE \"$Nom\" ;") ;
		$ResReq = $dbh->do("DELETE FROM radreply WHERE UserName LIKE \"$Nom\" ;") ;
		$ResReq = $dbh->do("DELETE FROM usergroup WHERE UserName LIKE \"$Nom\" ;") ;
		print "\n[OK] Suppression effectuée sous FreeRADIUS\n\n" ;
		
		print `userdel $Nom` ;
		print "[OK] Suppression effectuée dans le système\n" ;
		sleep 1 ;
	    }
	    else {
		# Ne rien faire.
		print "\n[NOK] Suppression non-réalisée (mauvais mot de passe ou action suspendue par l'utilisateur)\n" ;
	    }
	    
	} # Fin if ($SousChoix eq "12")
	
	if ($SousChoix eq "13" or $SousChoix eq "motpass") {
	    # MODIFIER LE MOT DE PASSE D'UN UTILISATEUR
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Nom) {
		print "Nom : " ;
		$Nom = <STDIN> ;
		chomp $Nom ;
	    }
	    if (!$NewMdP) {
		print "\nNouveau mot de passe : " ;
		$NewMdP = <STDIN> ;
		chomp $NewMdP ;
	    }

	    # Création des paramètres de création du mot de passe système.
	    $chaine = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
	    # Création de la graine.
	    for ($i = 0; $i < 8; $i++) {
		$graine .= substr($chaine, rand(length($chaine)), 1);
	    }
	    # Création du mot de passe chiffré au format MD5 (donc graine au format $1$ suivi de 8 caractères puis de $).
	    $mdpCrypt = crypt($NewMdP, '$1$'.$graine.'$');

	    # Si on trouve l'utilisateur avec son ancien mot de passe, alors on met à jour son mot de passe.
	    $ResReq = $dbh->prepare("SELECT UserName FROM radcheck WHERE UserName LIKE \"$Nom\" ;") ;
	    $ResReq->execute() ;
	    
	    $ResReqLign = $ResReq->fetchrow_hashref() ;
	    if ($ResReqLign->{'UserName'} eq "") {
		# Ne rien faire car l'utilisateur n'existe pas ou le mot de passe n'est pas le bon.
		print "[NOK] Impossible de trouve l'utilisateur.\n" ;
		$ResReq->finish() ;
	    }
	    else {
		# Nettoyer requête et faire la mise à jour du mot de passe.
		$ResReq->finish() ;
		$ResReq = $dbh->do("UPDATE radcheck SET Value = \"$mdpCrypt\", Attribute = \"Crypt-Password\" WHERE UserName LIKE \"$Nom\" ;") ;
		
		print "[OK] Modification de mot de passe réalisée pour FreeRADIUS\n\n" ;
		
		# Changement/Définition du mot de passe.
		print `usermod -p '$mdpCrypt' $Nom` ;
		print "Sauf si erreur ci-dessus (et non seulement des warnings), le mot de passe est également modifié dans le système\n" ;
		sleep 1;
	    }
	} # Fin if ($SousChoix eq "13")

	if ($SousChoix eq "14" or $SousChoix eq "addatt") {
	    # AJOUTER UN ATTRIBUT A UN UTILISATEUR
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Nom) {
		print "Nom : " ;
		$Nom = <STDIN> ;
		chomp $Nom ;
	    }
	    if (!$Attribute) {
		print "\nAttribut (Password, ...) : " ;
		$Attribute = <STDIN> ;
		chomp $Attribute ;
	    }
	    if (!$Op) {
		print "\nOpérateur : " ;
		$Op = <STDIN> ;
		chomp $Op ;
	    }
	    if (!$Value) {
		print "\nValeur attribut : ";
		$Value = <STDIN> ;
		chomp $Value ;
	    }
	    if (!$MdP) {
		print "\nMot de passe de l'utilisateur de la base :" ;
		$MdP = <STDIN> ;
		chomp $MdP ;
	    }
	    # Il faut que le mot de passe du user soit correct pour effectuer l'insertion.
	    if ($MdP eq $PasswordDB) {
		$ResReq = $dbh->do("INSERT INTO radcheck (UserName, Attribute, op, Value) VALUES (\"$Nom\", \"$Attribute\", \"$Op\", \"$Value\") ;") ;
		
		print "[OK] Insertion effectuée\n" ;
		sleep 1 ;
	    }
	    else {
		# Ne rien faire, le mot de passe user n'est pas le bon.
		print "[NOK] Action non-réalisée, le mot de passe utilisateur n'est pas le bon\n" ;
	    }
	} # Fin if ($SousChoix eq "14")
	
	if ($SousChoix eq "15" or $SousChoix eq "list") {
	    # LISTER LES UTILISATEURS
	    # .. Demande de l'utilisateur à afficher si l'on n'est pas en mode Automatique
	    if (!$Option) {
		print "Nom (laisser vide pour tout afficher) : " ;
		$Nom = <STDIN> ;
		chomp $Nom ;
	    }
	    # .. Si on a un login, on ne liste pas tout.
	    if ($Nom =~ /\w+/) {
		$ResReq = $dbh->prepare("SELECT radcheck.UserName, radcheck.Attribute, radcheck.op, radcheck.Value, usergroup.GroupName FROM radcheck, usergroup WHERE radcheck.UserName = usergroup.UserName AND radcheck.UserName LIKE \"$Nom\" ;") ;
	    }
	    else {
		$ResReq = $dbh->prepare("SELECT radcheck.UserName, radcheck.Attribute, radcheck.op, radcheck.Value, usergroup.GroupName FROM radcheck, usergroup WHERE radcheck.UserName = usergroup.UserName ;") ;
	    }
	    $ResReq->execute() ;
	    # Ligne de titre
	    print "-----------------------------------------------------------\n" ;
	    print "|     Nom       |     Mot de passe    |      Groupe       |\n" ;
	    print "-----------------------------------------------------------\n" ;
	    # Résultat
	    $~ = "ListUsers" ;
	    while ($ResReqLign = $ResReq->fetchrow_hashref()) {
		write() ;
	    }
	    print "-----------------------------------------------------------\n" ;
	    # Nettoyer la requête
	    $ResReq->finish() ;
	} # Fin if ($SousChoix eq "15")

    } # Fin if (Choix eq "1")


    if ($Choix eq "2" or $Choix eq "group") {
	# Affichage du menu si l'on n'est pas en mode Automatique.
	if (!$Option) {
	    print "\n\n#############################################\n" ;
	    print "21 - Ajouter un attribut de requête à un groupe\n" ;
	    print "22 - Ajouter un attribut de réponse à un groupe\n" ;
	    print "23 - Lister les attributs de requête\n" ;
	    print "24 - Lister les attributs de réponse\n" ;
	    print "25 - Supprimer un attribut de requête à un groupe\n" ;
	    print "26 - Supprimer un attribut de réponse à un groupe\n" ;
	    print "27 - Supprimer un groupe et tous ses attributs\n" ;
	    print "#############################################\n" ;

	    # Lecture du choix de l'utilisateur en mode Intéractif
	    print "Choix : " ;
	    $SousChoix = <STDIN> ;
	    chomp $SousChoix ;
	}

	if ($SousChoix eq "21" or $SousChoix eq "addreq") {
	    # AJOUTER UN ATTRIBUT DE REQUÊTE À UN GROUPE
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Group) {
		print "Groupe : " ;
		$Group = <STDIN> ;
		chomp $Group ;
	    }
	    if (!$Attribute) {
		print "\nAttribut : " ;
		$Attribute = <STDIN> ;
		chomp $Attribute ;
	    }
	    if (!$Op) {
		print "Opérateur : " ;
		$Op = <STDIN> ;
		chomp $Op ;
	    }
	    if (!$Value) {
		print "Valeur de l'attribut : " ;
		$Value = <STDIN> ;
		chomp $Value ;
	    }
	    # Réaliser l'insertion.
	    $ResReq = $dbh->do("INSERT INTO radgroupcheck (GroupName, Attribute, op, Value) VALUES (\"$Group\", \"$Attribute\", \"$Op\", \"$Value\") ;") ;
	    print "[OK] Insertion effectuée\n" ;
	    sleep 1 ;

	} # Fin if ($SousChoix eq "21" or $SousChoix eq "addreq")

	if ($SousChoix eq "22" or $SousChoix eq "addrep") {
	    # AJOUTER UN ATTRIBUT DE RÉPONSE À UN GROUPE
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Group) {
		print "Groupe : " ;
		$Group = <STDIN> ;
		chomp $Group ;
	    }
	    if (!$Attribute) {
		print "\nAttribut : " ;
		$Attribute = <STDIN> ;
		chomp $Attribute ;
	    }
	    if (!$Op) {
		print "Opérateur : " ;
		$Op = <STDIN> ;
		chomp $Op ;
	    }
	    if (!$Value) {
		print "Valeur de l'attribut : " ;
		$Value = <STDIN> ;
		chomp $Value ;
	    }
	    # Réaliser l'insertion.
	    $ResReq = $dbh->do("INSERT INTO radgroupreply(GroupName, Attribute, op, Value) VALUES (\"$Group\", \"$Attribute\", \"$Op\", \"$Value\") ;") ;
	    print "[OK] Insertion effectuée\n" ;
	    sleep 1 ;
	} # Fin du if ($SousChoix eq "22" or $SousChoix eq "addrep")

	if ($SousChoix eq "23" or $SousChoix eq "listreq") {
	    # LISTER LES ATTRIBUTS DE REQUÊTE
	    # Construction et exécution de la requête.
	    $ResReq = $dbh->prepare("SELECT * FROM radgroupcheck ;") ;
	    $ResReq->execute() ;
	    # Ligne de titre
	    print "------------------------------------------------------------------------------------------\n" ;
	    print "|  id  |    Groupe    |          Attribut          |Opérateur|           Valeur          |\n" ;
	    print "------------------------------------------------------------------------------------------\n" ;
	    # Résultat
	    $~ = "ListReqRep" ;
	    while ($ResReqLign = $ResReq->fetchrow_hashref()) {
		write() ;
	    }
	    print "------------------------------------------------------------------------------------------\n" ;
	    # Nettoyer la requête
	    $ResReq->finish() ;
	} # Fin if ($SousChoix eq "23" or $SousChoix eq "listreq")

	if ($SousChoix eq "24" or $SousChoix eq "listrep") {
	    # LISTER LES ATTRIBUTS DE RÉPONSE
	    # Construction et exécution de la requête.
	    $ResReq = $dbh->prepare("SELECT * FROM radgroupreply ;") ;
	    $ResReq->execute() ;
	    # Ligne de titre
	    print "------------------------------------------------------------------------------------------\n" ;
	    print "|  id  |    Groupe    |          Attribut          |Opérateur|           Valeur          |\n" ;
	    print "------------------------------------------------------------------------------------------\n" ;
	    # Résultat
	    $~ = "ListReqRep" ;
	    while ($ResReqLign = $ResReq->fetchrow_hashref()) {
		write() ;
	    }
	    print "------------------------------------------------------------------------------------------\n" ;
	    # Nettoyer la requête
	    $ResReq->finish() ;
	} # Fin if ($SousChoix eq "24" or $SousChoix eq "listrep")

	if ($SousChoix eq "25" or $SousChoix eq "delreq") {
	    # SUPPRIMER UN ATTRIBUT DE REQUÊTE À UN GROUPE
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Group) {
		print "Groupe : " ;
		$Group = <STDIN> ;
		chomp $Group ;
	    }
	    if (!$Attribute) {
		print "\nAttribut : " ;
		$Attribute = <STDIN> ;
		chomp $Attribute ;
	    }
	    if (!$reponse) {
		# Demander une confirmation avant de faire l'irrémédiable.
		print "Confirmer suppression ? (o/n)" ;
		$reponse = <STDIN> ;
		chomp $reponse ;
	    }
	    # Réaliser la suppression.
	    if ($reponse eq "o") {
		$ResReq = $dbh->do("DELETE FROM radgroupcheck WHERE GroupName=\"$Group\" AND Attribute=\"$Attribute\" ;") ;
		print "[OK] Suppression effectuée\n" ;
		sleep 1 ;
	    }
	    else {
		# Ne rien faire
		print "\n[NOK] Suppression non-réalisée (action suspendue par l'utilisateur)\n" ;
	    }
	} # Fin du if ($SousChoix eq "25" or $SousChoix eq "delreq")

	if ($SousChoix eq "26" or $SousChoix eq "delrep") {
	    # SUPPRIMER UN ATTRIBUT DE RÉPONSE A UN GROUPE
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Group) {
		print "Groupe : " ;
		$Group = <STDIN> ;
		chomp $Group ;
	    }
	    if (!$Attribute) {
		print "\nAttribut : " ;
		$Attribute = <STDIN> ;
		chomp $Attribute ;
	    }
	    if (!$reponse) {
		# Demander une confirmation avant de faire l'irrémédiable.
		print "Confirmer suppression ? (o/n)" ;
		$reponse = <STDIN> ;
		chomp $reponse ;
	    }
	    # Réaliser la suppression.
	    if ($reponse eq "o") {
		$ResReq = $dbh->do("DELETE FROM radgroupreply WHERE GroupName=\"$Group\" AND Attribute=\"$Attribute\" ;") ;
		print "[OK] Suppression effectuée\n" ;
		sleep 1 ;
	    }
	    else {
		# Ne rien faire
		print "\n[NOK] Suppression non-réalisée (action suspendue par l'utilisateur)\n" ;
	    }
	} # Fin du if ($SousChoix eq "26" or $SousChoix eq "delrep")

	if ($SousChoix eq "27" or $SousChoix eq "delgroup") {
	    # SUPPRIMER UN GROUPE ET TOUS SES ATTRIBUTS
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Group) {
		print "Groupe : " ;
		$Group = <STDIN> ;
		chomp $Group ;
	    }
	    if (!$MdP) {
		print "\nMot de passe de l'utilisateur de la base : " ;
		$MdP = <STDIN> ;
		chomp $MdP ;
	    }
	    if (!$reponse) {
		# Demander une confirmation avant de faire l'irrémédiable.
		print "Confirmer suppression ? (o/n)" ;
		$reponse = <STDIN> ;
		chomp $reponse ;
	    }

	    # Il faut le mot de passe user valide et la confirmation de la suppression pour l'effectuer.
	    if (($reponse eq "o") and ($MdP eq $PasswordDB)) {
		# Supprimer le groupe dans la base de données.
		$ResReq = $dbh->do ("DELETE FROM radgroupcheck WHERE GroupName LIKE \"$Group\" ;") ;
		$ResReq = $dbh->do ("DELETE FROM radgroupreply WHERE GroupName LIKE \"$Group\" ;") ;
		$ResReq = $dbh->do ("DELETE FROM usergroup WHERE GroupName LIKE \"$Group\" ;") ;
		print "\n[OK] Suppression effectuée\n" ;
	    }
	    else {
		# Ne rien faire.
		print "\n[NOK] Suppression non-réalisée (mauvais mot de passe ou action suspendue par l'utilisateur)\n" ;
	    }
	} # Fin if ($SousChoix eq "27" or $SousChoix eq "delgroup")

    } # Fin if ($Choix eq "2")

    if ($Choix eq "3" or $Choix eq "nas") {
	# Affichage du menu si l'on n'est pas en mode Automatique.
	if (!$Option) {
	    print "\n\n#############################################\n" ;
	    print "31 - Ajouter un équipement réseau\n" ;
	    print "32 - Supprimer un équipement réseau\n" ;
	    print "33 - Lister un ou tous les équipements réseaux\n" ;
	    print "#############################################\n" ;

	    # Lecture du choix de l'utilisateur en mode Intéractif
	    print "Choix : " ;   
	    $SousChoix = <STDIN> ;
	    chomp $SousChoix ;
	}
	if ($SousChoix eq "31" or $SousChoix eq "add") {
	    # AJOUTER UN NAS
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Nasname) {
		print "Adresse IP de l'équipement réseau : " ;
		$Nasname = <STDIN> ;
		chomp $Nasname ;
	    }
	    if (!$Shortname) {
		print "\nNom court : " ;
		$Shortname = <STDIN> ;
		chomp $Shortname ;
	    }
	    if (!$Type) {
		print "\nType d'équipement réseau : " ;
		$Type = <STDIN> ;
		chomp $Type ;
	    }
	    if (!$Ports || $Ports != 0) {
		print "\nPort : " ;
		$Ports = <STDIN> ;
		chomp $Ports ;
	    }
	    if (!$Secret) {
		print "\nMot de passe partagé : " ;
		$Secret = <STDIN> ;
		chomp $Secret ;
	    }
	    if (!$Group) {
		print "\nGroupe : " ;
		$Group = <STDIN> ;
		chomp $Group ;
	    }
	    if (!$Description) {
		print "\nDescription ou commentaire : " ;
		$Description = <STDIN> ;
		chomp $Description ;
	    }

	    # Rajouter un NAS dans la base de donénes après avoir vérifié qu'il n'existe pas déjà.
	    # .. Vérification sur le nas.nasname
	    $ResReq = $dbh->prepare("SELECT nasname FROM nas WHERE nasname LIKE \"$Nasname\" and groupe LIKE \"$Group\" ;") ;
	    $ResReq->execute() ;
	    $ResReqLign = $ResReq->fetchrow_hashref() ;
	    if ($ResReqLign->{'nasname'} ne "") {
		# Ne rien faire car le nas existe déjà.
		print "[NOK] L'équipement réseau existe déjà pour ce groupe\n" ;
		$ResReq->finish() ;
	    }
	    else {
		# Nettoyer la requête et faire l'insertion.
		$ResReq->finish() ;
		$ResReq = $dbh->do("INSERT INTO nas (nasname, shortname, type, ports, secret, description, groupe) VALUES (\"$Nasname\", \"$Shortname\", \"$Type\", $Ports, \"$Secret\", \"$Description\", \"$Group\") ;") ;
		# Si cet équipement n'a pas été affecté à admin, alors le rajouter
		$ResReqInterm = $dbh->prepare("SELECT * FROM nas WHERE nasname LIKE \"$Nasname\" and groupe LIKE \"admin\" ;") ;
		$ResReqInterm->execute() ;
		if (! $ResReqInterm->fetchrow_hashref()) {
		    $ResReq = $dbh->do("INSERT INTO nas (nasname, shortname, type, ports, secret, description, groupe) VALUES (\"$Nasname\", \"$Shortname\", \"$Type\", $Ports, \"$Secret\", \"$Description\", \"admin\") ;") ;
		    print "[OK] Insertion effectuée avec ajout du groupe admin.\n" ;
		}
		else {
		    print "[OK] Insertion effectuée.\n" ;
		}
		$ResReqInterm->finish() ;
		# Si on n'est pas en mode automatique, on redémarre FreeRADIUS à chaque modification.
		if (!$Option) {
		    print "Redémarrage de FreeRADIUS pour prise en compte.\n" ;
		    sleep 1 ;
		    print `/etc/init.d/freeradius restart` ;
		}
	    }

	} # Fin if ($SousChoix "31")

	if ($SousChoix eq "32" or $SousChoix eq "del") {
	    # SUPPRIMER UN NAS
	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$Nasname) {
		print "Adresse IP de l'équipement réseau : " ;
		$Nasname = <STDIN> ;
		chomp $Nasname ;
	    }
	    if (!$MdP) {
		print "\nMot de passe de l'utilisateur de la base : " ;
		$MdP = <STDIN> ;
		chomp $MdP ;
		
		# Demander une confirmation avant de faire l'irrémédiable.
		print "Confirmer suppression ? (o/n)" ;
		$reponse = <STDIN> ;
		chomp $reponse ;
	    }

	    # Il faut le mot de passe user valide et la confirmation de la suppresion pour l'effectuer.
	    if (($reponse eq "o") and ($MdP eq $PasswordDB)) {
		# Suppremier le nas dans la base de données.
		$ResReq = $dbh->do ("DELETE FROM nas WHERE nasname LIKE \"$Nasname\" ;") ;
		print "\n[OK] Suppression effectuée. Redémarrage de FreeRADIUS pour prise en compte.\n" ;
		sleep 1 ;
		print `/etc/init.d/freeradius restart` ;

	    }
	    else {
		# Ne rien faire.
		print "\nSuppression non-réalisée (mauvais mot de passe ou action suspendue par l'utilisateur)\n" ;
	    }
	    sleep 1 ;
	} # Fin if ($SousChoix eq "32")

	if ($SousChoix eq "33" or $SousChoix eq "list") {
	    # LISTER LE NAS DÉFINI SINON LISTER TOUS LES NAS.
	    # .. Demande du nas à afficher si l'on n'est pas en mode Automatique.
	    if (!$Option) {
		print "Nom (laisser vide pour tout afficher) : " ;
		$Nom = <STDIN> ;
		chomp $Nom ;
	    }
	    # .. Si on a une adresse IP, on ne liste pas tout.
	    if ($Nom =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {
		$ResReq = $dbh->prepare("SELECT * FROM nas WHERE nasname LIKE \"$Nom\" ORDER by id ;") ;
	    }
	    else {
		$ResReq = $dbh->prepare("SELECT * FROM nas ORDER by id ;") ;
	    }
	    $ResReq->execute() ;
	    # Ligne de titre
 	    print "-------------------------------------------------------------------------------------------------------------------\n" ;
	    print "|      Nom       |   Nom court    |  Type  |Ports|     Secret     |   Groupe    |Communauté|      Description     |\n" ;
	    print "-------------------------------------------------------------------------------------------------------------------\n" ;
	    # Résultat
	    $~ = "ListNas" ;
	    while ($ResReqLign = $ResReq->fetchrow_hashref()) {
		write() ;
	    }
	    print "-------------------------------------------------------------------------------------------------------------------\n" ;
	    # Nettoyer la requête
	    $ResReq->finish() ;
	} # Fin if ($SousChoix eq "33")

    } # Fin if ($Choix eq "3")


    if ($Choix eq "4" or $Choix eq "adm") {
	# Affichage du menu si l'on n'est pas en mode Automatique.
	if (!$Option) {
	    print "\n\n#############################################\n" ;
	    print "41 - Synchroniser les BD du serveur principal vers le secours\n" ;
	    print "42 - Lancer une sauvegarde\n" ;
	    print "43 - Afficher les tentatives de connexion erronées\n" ;
	    print "44 - Afficher les tentatives de connexion réussies\n" ;
	    print "45 - Afficher les dernières connexions au système\n" ;
	    print "46 - Afficher l'état des serveurs\n" ;
	    print "47 - Watchdog (services lancés ?)\n" ;
	    print "#############################################\n" ;

	    # Lecture du choix de l'utilisateur en mode Intéractif
	    print "Choix : " ;   
	    $SousChoix = <STDIN> ;
	    chomp $SousChoix ;
	}
	if ($SousChoix eq "41" or $SousChoix eq "sync") {
	    # SYNCHRONISER les BD DU SERVEUR PRINCIPAL VERS LE SERVEUR DE SECOURS
	    # dump de la base injecté sur le serveur distant (par tunnel ssh).
	    print `mysqldump -h localhost -P 3306 -u $LoginDB -p$PasswordDB $DatabaseDB | mysql -h 127.0.0.1 -P 30000 -u $LoginDB -p$PasswordDB $DatabaseDB` ;
	    print "Sauf si erreur ci-dessus, base du serveur de secours mise à jour par rapport à la base du serveur principal.\n" ;
	} # Fin if ($SousChoix eq "41")

	if ($SousChoix eq "42" or $SousChoix eq "sauv") {
	    # LANCER UNE SAUVEGARDE
	    $DateAnnee = localtime->year + 1900 ;
	    $DateMois = localtime->mon + 1 ;
	    $DateJour = localtime->mday ;
	    $DateHeure = localtime->hour ;
	    $DateMinute = localtime->min ;
	    $DateSeconde = localtime->sec ;
	    $NomBase = "RADIUS".$DateAnnee."_".$DateMois."_".$DateJour."_".$DateHeure."_".$DateMinute."_".$DateSeconde ;

	    # Récupérer les informations en mode Intéractif, sinon en mode Automatique utiliser les arguments de la commande
	    if (!$LoginDB) {
		print "Veuillez indiquer le login administrateur de la base de données : " ;
		$LoginDB = <STDIN> ;
		chomp $LoginDB ;
	    }
	    if (!$PasswordDB) {
		print "Veuillez indiquer le mot de passe administrateur de la base de données : " ;
		$PasswordDB = <STDIN> ;
		chomp $PasswordDB ;
	    }
	    # dump de la base dans un fichier et dans une base de sauvegarde.
	    print `mysqldump -h localhost -P 3306 -u $LoginDB -p$PasswordDB $DatabaseDB > /adminradius/FichierSauvegarde_$NomBase` ;

	    # Vérification que les tables radcheck, nas et usergroup ne sont pas vides dans la table de sauvegarde.
	    ## Préparation des requêtes sur la base de production et sur la base de sauvegarde. 	
	    $ResReq = $dbh->prepare("SELECT count(*) FROM radcheck ;") ;
	    $ResReqBis = $dbh->prepare("SELECT count(*) FROM nas ;") ;
	    $ResReqTri = $dbh->prepare("SELECT count(*) FROM usergroup ;") ;

	    ## Exécution des requêtes.
	    $ResReq->execute() ;
	    $ResReqBis->execute() ;
	    $ResReqTri->execute() ;

	    ## Récupération des résultats.
	    $ResReqLign = $ResReq->fetchrow_hashref() ;
	    $ResReqBisLign = $ResReqBis->fetchrow_hashref() ;
	    $ResReqTriLign = $ResReqTri->fetchrow_hashref() ;


	    ## Vérification et affichage du résultat de la vérification.
	    print "\n" ;
	    $ComptPb = 0 ;
	    if ($ResReqLign->{'count(*)'} > 0) {
		print "Vérification de la table radcheck sur base de production : OK\n" ;
	    }
	    else {
		print "Vérification de la table radcheck sur base de production : NOK, pb sauvegarde !\n" ;
		$ComptPb ++ ;
	    }
	    if ($ResReqBisLign->{'count(*)'} > 0) {
		print "Vérification de la table nas sur base de production : OK\n" ;
	    }
	    else {
		print "Vérification de la table nas sur base de production : NOK, pb sauvegarde !\n" ;
		$ComptPb ++ ;
	    }
	    if ($ResReqTriLign->{'count(*)'} > 0) {
		print "Vérification de la table usergroup sur base de production : OK\n" ;
	    }
	    else {
		print "Vérification de la table usergroup sur base de production : NOK, pb sauvegarde !\n" ;
		$ComptPb ++ ;
	    }
	    if (-e "/adminradius/FichierSauvegarde_$NomBase") {
		print "Vérification existance du fichier de sauvegarde : OK\n" ;
	    }
	    else {
		print "Vérification existance du fichier de sauvegarde : NOK, pb sauvegarde !\n" ;
		$ComptPb ++ ;
	    }	    

	    if ($ComptPb != 0) {
		print "\n[NOK] La sauvegarde ne s'est pas correctement réalisée\n" ;
	    }
	    else {
		print "\n[OK] La sauvegarde s'est correctement déroulée\n" ;
	    }

	    # Nettoyage des requêtes
	    $ResReq->finish() ;
	    $ResReqBis->finish() ;
	    $ResReqTri->finish() ;
	} # Fin if ($SousChoix eq "42")

	if ($SousChoix eq "43" or $SousChoix eq "listerr") {
	    # AFFICHER LES TENTATIVES DE CONNEXION ERRONEES
	    # Ouvrir le fichier de log.
	    open (LOGFREERADIUS, '/var/log/freeradius/radius.log') || die "Problème à l'accès au fichier /var/log/freeradius/radius.log" ;
	    # Tant qu'il y a une ligne à lire, si elle a le bon format, l'afficher.
	    while ($ligneFichierLog = <LOGFREERADIUS>) {
#		if (($ligneFichierLogOK) = $ligneFichierLog =~ /(.*No matching entry in the database for request from user.*)/) {
		if (($ligneFichierLogOK) = $ligneFichierLog =~ /(.*Auth: Login incorrect.*)/) {
		    print "$ligneFichierLogOK\n" ;
		}
	    }
	    # Fermer le fichier de log.
	    close (LOGFREERADIUS) ;
	} # Fin if ($SousChoix eq "43")

	if ($SousChoix eq "44" or $SousChoix eq "listok") {
	    # AFFICHER LES TENTATIVES DE CONNEXION REUSSIES
	    # En mode non Automatique, utiliser les arguments de la commande
	    # Affichage de la table radpostauthsous forme d'un tableau.
	    $ResReq = $dbh->prepare("SELECT * FROM radpostauth ;") ;
	    $ResReq->execute() ;
	    print "------------------------------------------------------------------------\n" ;
	    print "|  id  |      user       |         reply        |         date         |\n" ;
	    print "------------------------------------------------------------------------\n" ;
	    $~ = "ListConnOK" ;
	    while ($ResReqLign = $ResReq->fetchrow_hashref()) {
		write() ;
	    }
	    print "------------------------------------------------------------------------\n" ;
	    $ResReq->finish() ;
	    sleep 1 ;
	} # Fin if ($SousChoix eq "44")
	
	if ($SousChoix eq "45" or $SousChoix eq "last") {
	    # AFFICHER LES DERNIÈRES CONNEXIONS AU SYSTÈME
	    print `last` ;
	    sleep 1 ;
	} # Fin if ($SousChoix eq "45")

	if ($SousChoix eq "46" or $SousChoix eq "state") {
	    # AFFICHER UN ETAT DES SERVEURS
	    print "Appuyer sur ENTREE quand vous voudrez passer d'une rubrique à l'autre...\n" ;
	    sleep 2 ;

	    print "Uptime du serveur principal :\n" ;
	    print `uptime` ;
	    if (!$Option) {
		$Entree = <STDIN> ;
	    }		    
	    print "\n\nEspace disque du serveur principal : \n" ;
	    print `df` ;
	    if (!$Option) {
		$Entree = <STDIN> ;
	    }
	    print "\n\nUtilisation de la swap du serveur principal :\n" ;
	    print `free`;
	    if (!$Option) {
		$Entree = <STDIN> ;
	    }
	    print `netstat -i` ; # Information sur les interfaces réseaux
	    if (!$Option) {
		$Entree = <STDIN> ;
	    }
	    print `netstat -r` ; # Information sur la table de routage
	    if (!$Option) {
		$Entree = <STDIN> ;
	    }
	    print `netstat -s` ; # Information sur les stats des couches réseaux (cf SNMP)
	    if (!$Option) {
		$Entree = <STDIN> ;
	    }
	    print `netstat -ople` ; # Information sur les sockets avec timers, programme et owner.
	    if (!$Option) {
		$Entree = <STDIN> ;
	    }

	    print "S'il est nécessaire de faire la même analyse sur le serveur de secours, soit se connecter sur celui-ci et taper la ligne de commande :\n" ;
	    print "uptime && sleep 10 && df && sleep 10 && free && sleep 10 && netstat -i && sleep 10 && netstat -r && sleep 10 && netstat -s && sleep 10 && netstat -ople\n" ;
	    print "soit depuis le serveur principal taper la commande suivante (avec les bonnes valeurs) :\n" ;
	    print "ssh <login>\@<adresseIPServeurSecours> \"uptime && df && free && netstat -i && netstat -r && netstat -s && netstat -ople\"\n" ;
	    sleep 1 ;
	} # Fin if ($SousChoix eq "46")

	if ($SousChoix eq "47" or $SousChoix eq "watch") {
	    # VERIFIER QUE LES SERVICES SONT ACTIFS
	    $ErreurService = 0 ;
	    # Vérification de FreeRADIUS.
	    ## Est-ce que le ficher pid existe ?
	    if (-e "/var/run/freeradius/freeradius.pid") {
		## Est-ce que le processus indiqué existe ?
		open (PIDFILE, "/var/run/freeradius/freeradius.pid") ;
		$pid = <PIDFILE> ;
		chomp $pid ;
		close (PIDFILE) ;
		if (-e "/proc/$pid") {
		    print "[OK] FreeRADIUS est lancé\n" ;
		}
		else {
		    print "[NOK] FreeRADIUS planté\n" ;
		}
	    }
	    else {
		print "[NOK] FreeRADIUS non lancé\n" ;
		$ErreurService = $ErreurService + 1 ;
	    }
	    # Vérification de syslogd.
	    ## Est-ce que le fichier pid existe ?
	    if (-e "/var/run/syslogd.pid") {
		## Est-ce que le processus indiqué existe ?
		open (PIDFILE, "/var/run/syslogd.pid") ;
		$pid = <PIDFILE> ;
		chomp $pid ;
		close (PIDFILE) ;
		if (-e "/proc/$pid") {
		    print "[OK] Syslogd est lancé\n" ;
		}
		else {
		    print "[NOK] Syslogd planté\n" ;
		}
	    }
	    else {
		print "[NOK] Syslogd non lancé" ;
		$ErreurService = $ErreurService + 1 ;
	    }	
	    # Vérification de mysqld.
	    ## Est-ce que le fichier pid existe ?
	    if (-e "/var/run/mysqld/mysqld.pid") {
		## Est-ce que le processus indiqué existe ?
		open (PIDFILE, "/var/run/mysqld/mysqld.pid") ;
		$pid = <PIDFILE> ;
		chomp $pid ;
		close (PIDFILE) ;
		if (-e "/proc/$pid") {
		    print "[OK] MySQL est lancé\n" ;
		}
		else {
		    print "[NOK] MySQL est planté\n" ;
		}
	    }
	    else {
		print "[NOK] MySQL non lancé\n" ;
		$ErreurService = $ErreurService + 1 ;
	    }	
	    # Vérification de sshd.
	    ## Est-ce que le fichier pid existe ?
	    if (-e "/var/run/sshd.pid") {
		## Est-ce que le processus indiqué existe ?
		open (PIDFILE, "/var/run/sshd.pid") ;
		$pid = <PIDFILE> ;
		chomp $pid ;
		close (PIDFILE) ;
		if (-e "/proc/$pid") {
		    print "[OK] SSHD est lancé\n" ;
		}
		else {
		    print "[NOK] SSHD est planté\n" ;
		}
	    }
	    else {
		print "[NOK] SSHD non lancé\n" ;
		$ErreurService = $ErreurService + 1 ;
	    }
	    # Vérification de openntpd.
	    print "[WA] Openntpd ne peut être vérifié\n" ;
	    # Synthèse
	    if ($ErreurService != 0) {
		print "[NOK] Déclenchement du watchdog\n" ;
		sleep 2 ;
		open(WATCHDOG, "/dev/watchdog") || die "Pb ouverture /dev/watchdog. Le module softdog est-il chargé ?" ;
		close(WATCHDOG) ;
	    }
	} # Fin if ($SousChoix eq "47" or $SousChoix eq "watch")

    } # Fin if ($Choix eq "4")

    # Purge de toutes les variables.
    $Nom = "" ;
    $MdP = "" ;
    $Group = "" ;
    $NewMdP = "" ;
    $Attribute = "" ;
    $Op = "" ;
    $Value = "" ;
    $Nasname = "" ;
    $Shortname = "" ;
    $Type = "" ;
    $Ports = "" ;
    $Secret = "" ;
    $Description = "" ;
    $LoginRootDB = "" ;
    $PasswordRootDB = "" ;

    # Pour ne pas boucler indéfiniement en mode Automatique et sortir une fois l'action réalisée ...
    if ($Option == 1) {
	$Choix = 0 ;
    }

} # fin du while ($Choix ne "0")

# Fermeture de la base de données
$dbh->disconnect() ;
