# \[Vsftpd\] Gestion des utilisateurs virtuels

**URL:** <https://www.debian-fr.org/t/vsftpd-gestion-des-utilisateurs-virtuels/8138>\
**Category:** Programmation\
**Created:** [Février 20, 2016, 4:00 UTC](https://www.debian-fr.org/t/vsftpd-gestion-des-utilisateurs-virtuels/8138 "2016-02-20T16:00:43Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![thialme](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/50afbb/32.png) [@thialme](https://www.debian-fr.org/u/thialme)\
**Post date:** [Février 20, 2016, 4:00 UTC](https://www.debian-fr.org/t/vsftpd-gestion-des-utilisateurs-virtuels/8138/1 "2016-02-20T16:00:43Z")

</div>

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](http://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](http://smhteam.info/upload_wiki/scripts/vsftpd_am.sh)

Et pour les yeux c’est en dessous :

```auto
#!/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
```

---

<div class="post-metadata">

**Author:** ![usinagaz](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/u/ecae2f/32.png) [@usinagaz](https://www.debian-fr.org/u/usinagaz)\
**Post date:** [Février 20, 2016, 4:00 UTC](https://www.debian-fr.org/t/vsftpd-gestion-des-utilisateurs-virtuels/8138/2 "2016-02-20T16:00:53Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![K0t0x](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/k/c2a13f/32.png) [@K0t0x](https://www.debian-fr.org/u/K0t0x)\
**Post date:** [Février 20, 2016, 4:08 UTC](https://www.debian-fr.org/t/vsftpd-gestion-des-utilisateurs-virtuels/8138/3 "2016-02-20T16:08:31Z")

</div>

Quelques suggestions 😉 :

-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
