[Vsftpd] Gestion des utilisateurs virtuels

Voila, suite à un thread sur les utilisateurs virtuels pour vsftpd, je me suis dit que ce serait bien de partager mon script.

C’est du fait maison, et cela permet d’ajouter/supprimer des utilisateurs, obtenir la liste des logins et mots de passe, ainsi que de mettre à jour les mots de passe.

La configuration vsftpd utilisée est la suivante :

smhteam.info/wiki/index.linux.php5?wiki=Vsftpd

L’intérêt du script est principalement de ne pas avoir à manipuler la base de données Berkeley à la main.

Je n’ai pas encore fait d’aide mais c’est plutot simple :

  • vsftpd_am.sh -l : afficher les logins et mots de passe
  • vsftpd_am.sh -a : ajouter un utilisateur
  • vsftpd_am.sh -r : supprimer un utilisateur
  • vsftpd_am.sh -u : mettre à jour un mot de passe

La version facile a récupérer c’est par ici :
smhteam.info/upload_wiki/scripts/vsftpd_am.sh

Et pour les yeux c’est en dessous :

#!/bin/sh
# ===================================================================================================
#
# File .....: vsftp_am.sh - Manage virtual user accounts for vsftp
# Author ...: thialme at smhteam.info
# Date .....: 16/06/2007
#
#                               -------------------------------
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#                               -------------------------------
#
# Description :
#     Ce programme se place dans le contexte de l'utilisation de vsftp avec une gestion des 
# utilisateurs virtuels. Un ebase Berkeley contient le login et le mot de passe de chacun des 
# utilisateurs ayant un compte FTP sur le machine. La configuration utilisee est entierement 
# décrite a l'adresse suivante :
#
#          http://smhteam.info/wiki/index.linux.php5?wiki=Vsftpd
#
# Prerequis : le package libdb3-util doit etre installe sur votre systeme.
#
# Remarques :
#    1/ Le fichier de configuration pour l'utilisateur virtuel est creer mais vierge. C'est a 
#       l'administrateur de renseigner ces fichiers suivant les droits des utilisateurs.
#
# ===================================================================================================

# Declaration des constantes
# ----------------------------------------------
RELEASE='1.03'
VSFTPD_DIRECTORY='/etc/vsftpd/'
USER_CONF_DIRECTORY=$VSFTPD_DIRECTORY'vsftpd_user_conf/'
DB_FILENAME=$VSFTPD_DIRECTORY'login.db'

# Initialisation des variables
# ----------------------------------------------
old_db=''		# Ancienne base de donnees
new_db=''		# Nouvelle base de donnees
old_user=''		# Ancien utilisateur
new_user=''		# Nouvel utilisateur
new_password=''		# Nouveau password


# ====================================================================================================
# Recuperer les donnees de l'ancienne base
# =============================================
#
# Cette fonction permet de recuperer les donnees presentes dans la base de donnees actuelle.
# Les informations obtenues par le dump de la base sont sous forme de liste login, password, login ...
#
# Syntax : GetOldDb db_filename
#
# Return : old_db : les données de l'ancienne base de donnees

GetOldDb ()
{
  local db_filename=$1    # Nom de la base de donnees

  echo "Recuperation de la base de donnees $db_filename."

  # Extraire les informations de la base de donnees
  if [ -e "$db_filename" ]; then 
    old_db=`db3_dump -d a $db_filename | grep data: | sed 's/data: /|/g' | cut -d'|' -f2`;
  fi
}


# ====================================================================================================
# Verifier l'existence d'un utilisateur
# =============================================
#
# Cette fonction permet de vérifier l'existence ou non d'un utilisateur $user dans la base de données
# $db.
#
# Syntax : CheckExistingUser user db
#
# Return : 0 : si l'utilisateur $user existe dans la base $db
#          1 : si l'utilisateur $user n'existe pas dans la base $db

CheckExistingUser ()
{
  local password=0       # 0:champs password - 1:champs login
  local user=$1          # Login de l'utilisateur
  local db=$2            # Dump associe a la base de donnees

  echo "Vérification des utilisateurs existant dans la base."

  # Vérifier l'existence de l'utilisateur
  for field in $db; do	
    if [ "$password" = 0 ] && [ "$user" = "$field" ]; then return 0; fi
    : $((password^=1))
  done
    
  return 1
}


# ====================================================================================================
# Mettre a jour un mot de passe
# =============================================
#
# Cette fonction permet de mettre a jour le mot de passe de l'utilsateur $user dans la base $db
#
# Syntax : UpdatePassword user password db
#
# Return : 0 : si l'operation a ete faite avec succes
#          1 : si une erreur est survenue (utilisateur existant)

UpdatePassword ()
{
  local user=$1              # Login de l'utilisateur associe au mot de passe
  local password=$2          # Nouveau mot de passe
  local db=$3                # Dump associee a la base de donnees
  local replace='no'

  # Tester l'existence de l'utilisateur
  CheckExistingUser "$user" "$db"

  # Mettre fin a la mise a jour si l'utilisateur n'existe pas
  if [ "$?" -eq 1 ]; then 
  { 
    printf "\033[40m\033[1;31m[ Erreur ]: Utilisateur $user inexistant.\033[0m\n"; 
    return 1;
  }

  # Autrement continuer ...
  else
  {
    echo "Mise a jour du password pour l'utilisateur $user dans la base."
    
    # Parcourir la base de donnees pour changer le mot de passe
    for field in $db; do
    {
      if [ "$replace" = "yes" ]; then { field=$password; replace='no'; } fi
      if [ "$field" = "$user" ]; then replace='yes'; fi
      new_db=$new_db" "$field
    }
    done
  }
  fi
	
  return 0
}

# ====================================================================================================
# Ajouter un utilisateur
# =============================================
#
# Cette fonction permet d'ajouter un utilisateur a la base de donnees. Elle se charge de
# creer le repertoire personnel du nouvel utilisateur ainsi qu'un fichier de configuration "vierge".
# Le fichier de configuration est a renseigner par l'administrateur suivant les droits qu'il veut
# accorder.
#
# Syntax : AddUser user password db
#
# Return : 0 : si l'operation a ete faite avec succes
#          1 : si une erreur est survenue (utilisateur existant)

AddUser()
{
  local user=$1             # Login du nouvel utilisateur
  local password=$2         # Mot de passe du nouvel utilisateur
  local db=$3               # Dump associe a la base de donnees

  # Tester l'existence de l'utilisateur
  CheckExistingUser "$user" "$db"

  # Mettre fin a l'ajout de l'utilisateur si ce dernier existe deja
  if [ "$?" -eq 0 ]; then 
  { 
    printf "\033[40m\033[1;31m[ Erreur ]: Utilisateur $user existant.\033[0m\n"; 
    return 1; 
  }

  # Autrement formater les donnees du nouvel utilisateur
  else
  {
    echo "Ajout du nouvel utilisateur $user à  la base."
    new_db="$db"" "$user" "$password
  }	
  fi

  # Creer le repertoire personnel et ses sous repertoires
  if [ ! -d ~virtual/$user ]; then
  {
    echo "Ajout du répertoire personnel ~virtual/$user pour l'utilisateur virtuel '$user.'"
    mkdir ~virtual/$user ~virtual/$user/upload ~virtual/$user/partage1
    chmod 2750 ~virtual/$user/
    chmod 770 ~virtual/$user/upload/
    chmod 600 ~virtual/$user/partage1/
              	
    # Creer le fichier de configuration de l'utilisateur virtuel (fichier vierge)
    if [ ! -e $USER_CONF_DIRECTORY$user ]; then
    {
      echo "Ajout du fichier de configuration $USER_CONF_DIRECTORY$user pour l'utilisateur virtuel '$user.'"
      touch $USER_CONF_DIRECTORY$user
    }
              		
    else
	printf "\033[40m\033[1;33m[ Warning ]: $USER_CONF_DIRECTORY$user omission, ce fichier existe déja.\033[0m\n"
              		
    fi
  }
  
  else
      printf "\033[40m\033[1;33m[ Warning ]: ~virtual/$user  omission, ce répertoire existe déja.\033[0m\n"

  fi
	
  return 0
}


# ====================================================================================================
# Supprimer un utilisateur
# =============================================
#
# Cette fonction supprime un utilisateur virtuel. Le compte de ce dernier, ainsi que sont fichier de 
# configuration sont supprimes, et l'utilisateur est retire de la base de donnees
# accorder.
#
# Syntax : Remove user db
#
# Return : 0 : si l'operation a ete faite avec succes
#          1 : si une erreur est survenue (utilisateur inexistant)

RemoveUser()
{
  local user=$1               # Login de l'utilisateur a supprimer
  local db=$2                 # Dump associe a la base de donnees
  local remove='no'

  # Tester l'existence de l'utilisateur
  CheckExistingUser "$user" "$db"

  # Arreter la mise a jour de la base si l'utilisateur est inexistant
  if [ "$?" -eq 1 ]; then 
  { 
    printf "\033[40m\033[1;31m[ Erreur ]: Utilisateur $user inexistant.\033[0m\n"; 
    return 1; 
  }

  # Autrement continuer ...
  else
  {
    echo "Retrait de l'utilisateur $user de la base."

    # Parcourir la liste des donnees et supprimer l'utilisateur
    for field in $db; do
    {
	if [ "$remove" = "yes" ]; then { remove='no'; field=''; } fi
	if [ "$field" = "$user" ]; then { remove='yes'; field=''; } fi
    	new_db=$new_db" "$field
    }
    done
  }	
  fi

  # Suppimer le repertoire personnel
  echo "Suppresion du répertoire personnel ~virtual/$user pour l'utilisateur virtuel '$user'."
  rm -Rf ~virtual/$user

  # Supprimer le fichier de configuration
  echo "Suppression du fichier de configuration $USER_CONF_DIRECTORY$user pour l'utilisateur virtuel '$user.'"
  rm -f $USER_CONF_DIRECTORY$user

  return 0
}

# ====================================================================================================
# Creer une base de donnees
# =============================================
#
# ette fcontion permet de creer une nouvelle base de donnees Berkeley.
#
# Syntax : CreateNewDb db filename
#
# Return : 0 : si l'operation a ete faite avec succes
#          1 : si une erreur est survenue

CreateNewDb ()
{
  local db=$1               # Dump de la base de donnees a charger
  local filename=$2         # Nom de la base de donnees

  echo "Création de la nouvelle base de données ..."

  # Sauvegarder l'ancienne base de donnees
  if [ -e "$filename" ]; then mv "$filename" "$filename"".old"; fi

  # Supprimer l'ancien fichier temporaire si il existe
  if [ -e "$filename"".txt" ]; then rm -f "$filename"".txt"; fi
	
  # Creer le fichier temporaire et modifier ses droits
  touch $filename".txt"
  chmod 600 $filename".txt"

  # Charger les donnees dans le fichier
  for field in $db; do
      echo "$field" >> "$filename"".txt"
  done
	
  echo '' >> "$filename"".txt"
	
  # Creer la nouvelle base de donnees
  db3_load -T -t hash -f $filename".txt" $filename

  # Supprimer le fichier temporaire
  rm -f $filename".txt"

  # Modifier les droits sur la base de donnees
  chmod 600 $filename

  return 0
}

# Programme principal
# ----------------------------------------------

# Verifier que l'utilisateur est bien root
if (( `/usr/bin/id -u` != 0 )); then { echo "Désolé, Vous devez être root..."; exit 1; } fi

printf "\033[40m\033[1;32mScript de gestion de la base Berkeley associée à vsftpd - v$RELEASE\033[0m\n"
echo "----------------------------------------------------------------"
echo -n "Commande : "

# Prendre en compte l'argument de la commande et rediriger le script
case "$1" in
	'-a')
		echo "Add user"
		echo -n "Login du nouvel utilisateur : "
		read new_user
		echo -n "Password du nouvel utilisateur : "
		read new_password
		
		GetOldDb "$DB_FILENAME"
		
		AddUser "$new_user" "$new_password" "$old_db"
		
		if [ "$?" -eq 1 ]; then exit 1;
		else CreateNewDb "$new_db" "$DB_FILENAME";
		fi		
	;;
	'-d')
		echo "Display database"

		GetOldDb "$DB_FILENAME"
		
		if [ -z "$old_db" ]; then echo "Base de données vide";
		else
			j=0
			for i in $old_db; do

				if [ "$j" -eq 1 ]; then echo $row "(P)"$i
				else row="(L)"$i" -"						
				fi
				
				: $((j^=1))
			
			done
		fi
	;;
	'-r')
		echo "Delete user"
		echo -n "Login de l'ancien utilisateur : "
		read old_user	
		
		GetOldDb "$DB_FILENAME"
		
		RemoveUser "$old_user" "$old_db"	
		
		if [ "$?" -eq 1 ]; then exit 1;
		else CreateNewDb "$new_db" "$DB_FILENAME";
		fi			
	;;
	'-u')
		echo "Update user"
		echo -n "Mettre à  jour le password de l'utilisateur : "
		read old_user
		echo -n "par : "
		read new_password
		
		GetOldDb "$DB_FILENAME"
		
		UpdatePassword "$old_user" "$new_password" "$old_db"
	
		if [ "$?" -eq 1 ]; then exit 1;
		else CreateNewDb "$new_db" "$DB_FILENAME";
		fi
	;;	
	*)
		echo "Help"
	;;
esac

exit 0

Merci beaucoup thialme :wink:
ps: je verrai à l’usage …

Quelques suggestions :wink: :

-verifications de la suppression des dossiers lors de la suppression d’un user (eviter de perdre des donnés qui sont ds partage1/ par exemple :s)

  • remplir les fichiers des user grâce à quelques questions.

Voilà quelques trucs qui peuvent être sympa (suggestion 1 decouverte suite à une suppression de fichiers :@ lol ) , mais la base du script est très bien faite deja! Merci