Created
March 27, 2018 11:23
-
-
Save devthejo/7d93d9c0785173b4b18fad56e8c935e3 to your computer and use it in GitHub Desktop.
vsftpd virtual user management with quota CLI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
VIRTUAL_USERS_DIR=${VIRTUAL_USERS_DIR:-/ftp_users} | |
DISKS_DIR=${DISKS_DIR:-/ftp_disks} | |
ROOT_DIR=${ROOT_DIR:-/ftp_mountpoints} | |
USER_QUOTA=${USER_QUOTA:-100MB} | |
DEFAULT_FTP_USER_ID=${DEFAULT_FTP_USER_ID:-14} | |
DEFAULT_FTP_GROUP_ID=${DEFAULT_FTP_GROUP_ID:-50} | |
CHMOD=${CHMOD:-0777} | |
OWN_USER=$(id -u ftp 2>/dev/null) | |
OWN_GROUP=$(id -g ftp 2>/dev/null) | |
OWN_USER=${OWN_USER:-$DEFAULT_FTP_USER_ID} | |
OWN_GROUP=${OWN_GROUP:-$DEFAULT_FTP_GROUP_ID} | |
VUSER_TXT="${VIRTUAL_USERS_DIR}/virtual_users.txt" | |
VUSER_DB="${VIRTUAL_USERS_DIR}/virtual_users.db" | |
function vsftpduser_add() | |
{ | |
USER=$1 | |
PASSWORD=$2 | |
if [ "$USER" == "" ]; then | |
echo "error: missing user parameter" | |
exit 1 | |
fi | |
if [ "$PASSWORD" == "" ]; then | |
echo "error: password can not be empty" | |
exit 1 | |
fi | |
find_user $USER | |
if [ $? = 0 ]; then | |
echo "adding $USER to virtual users registry" | |
echo -e "${USER}\n${PASSWORD}" >> $VUSER_TXT | |
make_db | |
else | |
echo "user: $USER already exists in registry" | |
fi | |
make_user_disk $USER | |
make_user_dir $USER | |
mount_user_disk $USER | |
echo "new user $USER created" | |
} | |
function vsftpduser_del() | |
{ | |
USER=$1 | |
if [ "$USER" == "" ]; then | |
echo "error: missing user parameter" | |
exit 1 | |
fi | |
find_user $USER | |
if [ $? = 1 ] | |
then | |
echo "removing $USER from virtual users registry" | |
sed -i '/\<'$USER'\>/{N;d}' $VUSER_TXT > /dev/null | |
make_db | |
else | |
echo "user: $USER does not exists in registry" | |
fi | |
remove_user_storage $USER | |
} | |
function vsftpduser_passwd() | |
{ | |
USER=$1 | |
PASSWORD=$2 | |
if [ "$USER" == "" ]; then | |
echo "error: missing user parameter" | |
exit 1 | |
fi | |
if [ "$PASSWORD" == "" ]; then | |
echo "error: password can not be empty" | |
exit 1 | |
fi | |
find_user $USER | |
if [ $? = 1 ]; then | |
sed -i '/\<'$USER'\>/{n;d}' $VUSER_TXT > /dev/null | |
sed -i '/\<'$USER'\>/a\'$PASSWORD'' $VUSER_TXT > /dev/null | |
echo "password for user ${USER} has been modified" | |
make_db | |
else | |
echo "user: $USER does not exists in registry" | |
return 1 | |
fi | |
} | |
function vsftpduser_ls() | |
{ | |
echo $(sed -n '1~2p' $VUSER_TXT) | tr " " "\n" | |
} | |
function vsftpduser_rebuild() | |
{ | |
FORCE="NO" | |
POSITIONAL=() | |
while [[ $# -gt 0 ]] | |
do | |
key="$1" | |
case $key in | |
-f|--force) | |
FORCE="YES" | |
shift | |
;; | |
*) | |
POSITIONAL+=("$1") | |
shift | |
;; | |
esac | |
done | |
set -- "${POSITIONAL[@]}" # restore positional parameters | |
if [ "$1" == "" ]; then | |
rebuild_all $FORCE $@ | |
else | |
USER=$1 | |
shift | |
need_user $USER | |
rebuild_user $USER $FORCE $@ | |
fi | |
} | |
function vsftpduser_mount() | |
{ | |
if [ "$1" == "" ]; then | |
mount_all $@ | |
else | |
USER=$1 | |
shift | |
need_user $USER | |
mount_user_disk $USER | |
fi | |
} | |
function vsftpduser_umount() | |
{ | |
if [ "$1" == "" ]; then | |
umount_all $@ | |
else | |
USER=$1 | |
shift | |
need_user $USER | |
umount_user_disk $USER | |
fi | |
} | |
function vsftpduser_remount() | |
{ | |
vsftpduser_umount $@ | |
vsftpduser_mount $@ | |
} | |
function rebuild_user() | |
{ | |
USER=$1 | |
FORCE=$2 | |
echo "rebuilding user $USER" | |
if [ "$FORCE" == "YES" ]; then | |
remove_user_storage $USER | |
fi | |
make_user_disk $USER | |
make_user_dir $USER | |
mount_user_disk $USER | |
} | |
function rebuild_all() | |
{ | |
FORCE=$1 | |
USER_LIST_ARRAY=($(sed -n '1~2p' $VUSER_TXT)) | |
for USER in "${USER_LIST_ARRAY[@]}" ; do | |
rebuild_user $USER $FORCE | |
done | |
} | |
function mount_all() | |
{ | |
USER_LIST_ARRAY=($(sed -n '1~2p' $VUSER_TXT)) | |
for USER in "${USER_LIST_ARRAY[@]}" ; do | |
mount_user_disk $USER | |
done | |
} | |
function umount_all() | |
{ | |
USER_LIST_ARRAY=($(sed -n '1~2p' $VUSER_TXT)) | |
for USER in "${USER_LIST_ARRAY[@]}" ; do | |
umount_user_disk $USER | |
done | |
} | |
function need_user(){ | |
USER=$1 | |
find_user $USER | |
if [ $? = 0 ]; then | |
echo "user: $USER does not exists in registry" | |
exit 1 | |
fi | |
} | |
function find_user() | |
{ | |
if [ -f $VUSER_TXT ];then | |
ACCOUNTDB_TOTALLINES=`grep '.' -c $VUSER_TXT` | |
else | |
ACCOUNTDB_TOTALLINES=0 | |
fi | |
C=1; | |
if [ "$ACCOUNTDB_TOTALLINES" != "0" ]; then | |
while [ $C -lt $ACCOUNTDB_TOTALLINES ]; do | |
VALIDUSER=`sed -n -e "$C p" $VUSER_TXT` | |
if [ "$1" == "$VALIDUSER" ];then | |
USERNAMEOK=1 | |
break; | |
else | |
USERNAMEOK=0 | |
fi | |
let C=$C+2; | |
done | |
fi | |
return $USERNAMEOK | |
} | |
function make_db() | |
{ | |
db_load -T -t hash -f $VUSER_TXT $VUSER_DB | |
} | |
function make_user_disk() | |
{ | |
USER=$1 | |
USER_DISK="${DISKS_DIR}/${USER}.ext3" | |
if [ ! -f "$USER_DISK" ] | |
then | |
echo "creating ${USER_DISK}" | |
touch "${USER_DISK}" | |
dd if=/dev/zero of="${USER_DISK}" bs="${USER_QUOTA}" count=1 | |
/sbin/mkfs --type=ext3 -F "${USER_DISK}" | |
else | |
echo "disk allready exists ${USER_DISK}" | |
fi | |
} | |
function make_user_dir() | |
{ | |
USER_DIR="$ROOT_DIR/$1" | |
if [ ! -d "$USER_DIR" ] | |
then | |
echo "creating ${USER_DIR}" | |
mkdir -p "${USER_DIR}" | |
chown $OWN_USER:$OWN_GROUP "${USER_DIR}" | |
chmod $CHMOD "${USER_DIR}" | |
else | |
echo "directory already exists ${USER_DIR}" | |
fi | |
} | |
function mount_user_disk() | |
{ | |
USER=$1 | |
USER_DISK="${DISKS_DIR}/${USER}.ext3" | |
USER_DIR="$ROOT_DIR/$1" | |
if mount | grep $USER_DIR > /dev/null; then | |
echo "mountpoint allready mounted ${USER_DIR}" | |
elif [ ! -f "$USER_DISK" ]; then | |
echo "missing disk file ${USER_DISK} for user ${USER}" | |
else | |
echo "mounting ${USER_DISK} in ${USER_DIR}" | |
mount -o loop,rw "${USER_DISK}" "${USER_DIR}" | |
chmod $CHMOD "${USER_DIR}" | |
if [ -d "${USER_DIR}/lost+found" ]; then | |
if [ -z "$(ls -A ${USER_DIR}/lost+found)" ]; then | |
rm -r "${USER_DIR}/lost+found" | |
fi | |
fi | |
fi | |
} | |
function remove_user_storage() | |
{ | |
USER=$1 | |
USER_DIR="${ROOT_DIR}/${USER}" | |
USER_DISK="${DISKS_DIR}/${USER}.ext3" | |
umount_user_disk $USER | |
if [ -d "$USER_DIR" ]; then | |
echo "removing $USER_DIR" | |
rm -r "$USER_DIR" | |
fi | |
if [ -f "$USER_DISK" ]; then | |
echo "removing $USER_DISK" | |
unlink "$USER_DISK" | |
fi | |
} | |
function umount_user_disk(){ | |
USER=$1 | |
USER_DIR="${ROOT_DIR}/${USER}" | |
if mount | grep $USER_DIR > /dev/null; then | |
echo "unmounting $USER_DIR" | |
umount "$USER_DIR" | |
fi | |
} | |
function main() | |
{ | |
if [ $# -lt 1 ]; | |
then | |
echo "usage: vsftpduser add | del | passwd | ls | rebuild | mount | umount | remount" | |
exit 1 | |
fi | |
CMD=$1 | |
shift | |
if [ $CMD = "add" ]; then | |
vsftpduser_add $@ | |
elif [ $CMD = "del" ]; then | |
vsftpduser_del $@ | |
elif [ $CMD = "passwd" ]; then | |
vsftpduser_passwd $@ | |
elif [ $CMD = "ls" ]; then | |
vsftpduser_ls $@ | |
elif [ $CMD = "rebuild" ]; then | |
vsftpduser_rebuild $@ | |
elif [ $CMD = "mount" ]; then | |
vsftpduser_mount $@ | |
elif [ $CMD = "umount" ]; then | |
vsftpduser_umount $@ | |
elif [ $CMD = "remount" ]; then | |
vsftpduser_remount $@ | |
else | |
echo [$CMD] a bad argument. | |
fi | |
} | |
main $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment