Hello All,
This Topic is an extension to my Samba user administration script. However, since the concept is a little changed, I decided to start a new thread.
Introduction:
In fact this is almost the same bash script but much more functional and featured, so I call it a tool. Its purpose is to simplify and facilitate the user administrations related actions for storage and file services like Samba and FTP.
As we know we have no useradd/adduser, etc on an out of the box OpenWrt install, we should build them in busybox and build the firmware again. Well, it is not much of a hard work, but even then we have to take care for user's directoried, permissions, configurations and so on....
The purpose of the tool (named "storageadm.sh") is to give us the ability to predefine several common services settings and after them control them with a stiil-not restricted flexibility. Here I have included two major storage services:
storageadm.sh:
1) Samba file Server
2) Vsftpd FTP Server
Packages required:
- bash (highly recommended)
- samba3
- vsftpd
- modules and packages needed to get your storage hw running - look here and here
Comments:
My OpenWrt box is currently running a custom build of Backfire (10.03.1-RC6, r29275) on TP-Link TL-WR1043ND, but the script is designed to be as much universal as possible, so you simply need to edit several self-explanatory variables at the beginning and feel free to use it. In general, variables defined by other variables does not need the be changes, but only the plain text ones. Of course, since it is a simple text, you may feel free to modify and alter it towards your personal needs.
It is currenlt configured for a sample directory structure, that you may see in Samba user administration script. It could be changed anytime.
- The main idea is tha we have a global Samba administrator that is owner of the whole share dir and that every user has its own directory and rw permissions only for it.
- Samba user's dir is also user's FTP directory.
- The script checks if a user exists on the system when trying to add or remove it. When you try to add a user for FTP service the script firstly configures it for Samba, thus creating user's entries and directories and implementing the correct user group and home dir.
- You may change the password of an existing user by running the add (-a for samba) and (-f for FTP) option again.
- When trying to remove an existing user, a warning prompt is displayed.
- FTP configuration is automatically generated by the tool creating a backup of the old configuration. You can also change the vsftpd configuration after that.
- Security options are enabled - the idea is to keep everything simple, flexible and secure.
I hope a web front end coulb be also written (php based) in order to make it a little more friendly to use, in spite that I particularly like the CLI style.
Get it running:
Here is the script itself. The bash package is highly recommended!
Copy -> Paste -> Save as "storageadm.sh" somewhere on your router -> make it executable (chmod +x storageadm.sh) -> run ./storageadm.sh -h for usage notes.
#!/bin/sh
#
# Version v1.8
# Script for Creating new Samba user and configuring parameters.
# Developed by dir2cas <kalin.t.ivanov@gmail.com>
#
# Additional features for vsftpd FTP server is implemented,
# allowing local samba users to have FTP access to their home directories.
#
# Required packages: samba3, vsftpd
# Recommended packages: bash
#SCRIPTNAME="${0}"
OPTION="$1"
USER="$2"
SCRIPTNAME="storageadm.sh"
################ SCRIPT CONFIGURATION ################
#Defining variables:
SAMBA_ADMIN="admin"
SAMBA_GROUP="smbusers"
SAMBA_SHARE_DIR="/mnt/storage/SHARE"
SAMBA_USER_DIR="${SAMBA_SHARE_DIR}/users/${USER}"
#SAMBA_HOME="/var"
SAMBA_HOME_ADMIN="${SAMBA_SHARE_DIR}"
SAMBA_HOME="${SAMBA_USER_DIR}"
SAMBA_SHELL="/bin/false"
SAMBA_GROUP_ID="1001"
SAMBA_USER_ID_START="1001"
FTP_ENABLE="1" # Set to "1" to enable the FTP service
VSFTPD_CONF="/etc/vsftpd.conf"
FTP_SECURE_LOGIN_FILE="/etc/vsftpd.users"
FTP_LISTEN_ADDR="192.168.1.1" # Leave blank to listen on all addresses/interfaces
FTP_LISTEN_PORT="21" # If in standalone mode, this is the port listen on for incoming FTP connections (default=21)
FTP_BANDWIDTH="8000" # Maximum data transfer rate in kbps
FTP_BANNER="Welcome to Kanzownet-Sofia FTP service." # Your FTP server welcome message
FTP_MAX_CLIENTS="15" # Maximum number of clients that may be connected
FTP_MAX_CONN_IP="2" # Maximum connections per IP
FTP_MAX_LOGIN_FAILS="3" # After this many login failures, the session is killed (default=3)
FTP_IDLE_TIMEOUT="120" # Timeout in seconds - the maximum time a remote client may spend between FTP activity
#######################################################
Usage() {
# Define the help/warning message:
echo -e "\tUsage: ${SCRIPTNAME} [OPTION] <samba/ftp username>\n\t-a - add user to the File Server (changes password if exists)\n\t-f - add user to vsftpd\n\t-d - remove user from Samba and FTP\n\t-s - display storage services status\n\t-h, --help - show this menu"
}
UserCheck() {
# This function returns "0" if the user is already configured on the system and "1" if it is not
local USER="$1"
user_check=$(grep -e "${USER}" /etc/passwd | grep "${SAMBA_GROUP}" | cut -d: -f1)
if [ "${user_check}" = "${USER}" ]; then #true(1) - the user exists; false(0) - the user does not exist
#Exists
return "0"
else
#Does NOT exist
return "1"
fi
}
VsftpdCheck() {
# This function returns "0" if vsftpd is OK and "1" if it is not
if [ "${FTP_ENABLE}" -ne "1" ]; then
echo -e "Option ${OPTION} cannot be used\nFTP service option is disabled\nPlease set FTP_ENABLE="1" in the script config section\nbut first verify that vsftpd package is installed -> $ opkg list_installed | grep vsftpd\n"
return 1
else
hash vsftpd > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e "###WARNING###\nvsftpd not found"
echo -e "Probably it is not installed on the system\nPlease, verify that vsftpd package is installed -> $ opkg list_installed | grep vsftpd and install it"
logger -t ${SCRIPTNAME} "vsftpd not found, probably it is not installed"
return 1
else
#Check if vsftpd has a configuration file
if [ ! -f ${VSFTPD_CONF} ]; then
echo -e "${VSFTPD_CONF}: does not exist as valid file argument\nProbably vsftpd is not installed\n"
logger -t ${SCRIPTNAME} "${VSFTPD_CONF}: does not exist"
return 1
elif [ ! -r ${VSFTPD_CONF} ]; then
echo -e "${VSFTPD_CONF}: can not be read\n"
logger -t ${SCRIPTNAME} "${VSFTPD_CONF}: can not be read"
return 1
fi
fi
fi
#If all above is passed without any return error code, assuming that vsftpd is OK
return 0
}
StorageStat() {
#Displaying Storage Services status
local VAR
echo -e "\nSAMBA\n---------------------------------------------------\n USER:GROUP\t\tHOME DIR:"
for VAR in $(cat /etc/samba/smbpasswd | cut -d: -f1); do
echo -e "$(echo ${VAR}):$(cat /etc/passwd | grep -e ${VAR} | cut -d: -f5) -->\t$(cat /etc/passwd | grep -e ${VAR} | cut -d: -f6)"
done
echo -e "\n---------------------------------------------------\nSamba Share Folder is --> ${SAMBA_SHARE_DIR}\nSamba Global Administrator is --> ${SAMBA_ADMIN} (uid=$(uid=$(grep -e "${SAMBA_ADMIN}" /etc/passwd | cut -d: -f3); if [ -z ${uid} ]; then uid="N/A"; fi; echo "${uid}"))\nSamba User's group is set to --> ${SAMBA_GROUP} (gid=$(gid=$(grep -e "${SAMBA_GROUP}" /etc/group | cut -d: -f3); if [ -z ${gid} ]; then gid="N/A"; fi; echo "${gid}"))"
#Check for vsftpd secure login file:
if [ ! -f ${FTP_SECURE_LOGIN_FILE} ]; then
#echo -e "${FTP_SECURE_LOGIN_FILE}: does not exist yet\ncreating...\n"
logger -t ${SCRIPTNAME} "${FTP_SECURE_LOGIN_FILE}: does not exist, probably no users are configured for FTP"
echo -e "\nFTP (vsftpd)\n---------------------------------------------------\n USER:GROUP\t\tFTP DIR:"
echo -e "STILL NO FTP ENABLED USERS"
if [ -z "$(grep -e "${SCRIPTNAME}" ${VSFTPD_CONF})" ]; then
echo -e "\n---------------------------------------------------\nSTILL NO FTP CONFIGURATION"
else
echo -e "\n---------------------------------------------------\nFTP Server Bandwidth Limit is --> ${FTP_BANDWIDTH}kbps ($(( (${FTP_BANDWIDTH} / 8) * 1024 )))Bytes/s\nFTP Server is listening on --> ${FTP_LISTEN_ADDR}\nFTP Server is currently available on port --> ${FTP_LISTEN_PORT}\nFTP Server Maximum Simultaneous Clients --> ${FTP_MAX_CLIENTS}\n"
fi
else
echo -e "\nFTP (vsftpd)\n---------------------------------------------------\n USER:GROUP\t\tFTP DIR:"
for VAR in $(cat ${FTP_SECURE_LOGIN_FILE} | awk '{print $1}'); do
echo -e "$(echo ${VAR}):$(cat /etc/passwd | grep -e ${VAR} | cut -d: -f5) -->\t$(cat /etc/passwd | grep -e ${VAR} | cut -d: -f6)"
done
if [ -z ${FTP_LISTEN_ADDR} ]; then FTP_LISTEN_ADDR="All Interfaces"; fi
echo -e "\n---------------------------------------------------\nFTP Server Bandwidth Limit is --> ${FTP_BANDWIDTH}kbps ($(( (${FTP_BANDWIDTH} / 8) * 1024 )))Bytes/s\nFTP Server is listening on --> ${FTP_LISTEN_ADDR}\nFTP Server is currently available on port --> ${FTP_LISTEN_PORT}\nFTP Server Maximum Simultaneous Clients --> ${FTP_MAX_CLIENTS}\n"
fi
}
SambaPassword() {
#Configuring the Samba passwd for the specified user
echo -ne "Please, enter SMB password for the new user ${USER}:\n"
read password
clear
sleep 1
${SAMBA_PASSWD} ${USER} ${password}
/etc/init.d/samba restart >&- 2>&-
echo -e "\tSamba password set\n"
unset password
sleep 1
}
AddUser() {
if [ ! -d "${SAMBA_SHARE_DIR}" ]; then
#echo "Directory does not exist"
echo "Creating directory"
mkdir -p ${SAMBA_SHARE_DIR}
#Setting the permission for the main share directory
chown -R ${SAMBA_ADMIN}:${SAMBA_GROUP} ${SAMBA_SHARE_DIR}
chmod -R u=rwx,g=rx,o= ${SAMBA_SHARE_DIR}
fi
# Creating the user entries:
SAMBA_ADMIN_ENTRY="${SAMBA_ADMIN}:*:${SAMBA_USER_ID_START}:${SAMBA_GROUP_ID}:${SAMBA_GROUP}:${SAMBA_HOME_ADMIN}:${SAMBA_SHELL}"
SAMBA_GROUP_ENTRY="${SAMBA_GROUP}:x:${SAMBA_GROUP_ID}:"
#Creating the new Samba group if it does not exist
grep -e "${SAMBA_GROUP_ENTRY}" /etc/group >/dev/null || echo "${SAMBA_GROUP_ENTRY}" >> /etc/group
#Creating the Samba administrator account if it does not exist
#grep -e "${SAMBA_ADMIN_ENTRY}" /etc/passwd >/dev/null || echo "${SAMBA_ADMIN_ENTRY}" >> /etc/passwd
UserCheck ${SAMBA_ADMIN}
if [ $? -eq 1 ]; then # 1 will be returned by UserCheck function showing that the admin is not set on the system
#Create the Samba administrator (smbadmin user), because it does not exist
echo -e "Creating the Samba global administrator\n"
echo "${SAMBA_ADMIN_ENTRY}" >> /etc/passwd
echo -ne "Please, enter password for the Samba global administrator ${SAMBA_ADMIN}:\n"
read password
clear
sleep 1
${SAMBA_PASSWD} ${SAMBA_ADMIN} ${password}
unset password
#Setting the permission for the main share directory
chown -R ${SAMBA_ADMIN}:${SAMBA_GROUP} ${SAMBA_SHARE_DIR}
chmod -R u=rwx,g=rx,o= ${SAMBA_SHARE_DIR}
fi
#Check if the user is already a valid Samba user
UserCheck ${USER}
if [ $? -eq 0 ]; then
echo -e "###WARNING###\nUser ${USER} is already present as valid Samba user"
echo -e "\nOnly Samba password change will be executed"
sleep 1
# Call the function to set the new samba user password
SambaPassword
exit 0
fi
#Creating the new Samba username and user on the server itself if it does not exist
#Status message:
echo -e "\nConfiguring user ${USER}...\n"
SAMBA_USER_ID=$(grep -e "${SAMBA_GROUP}" /etc/passwd | tail -n1 | cut -d: -f3)
let "SAMBA_USER_ID += 1"
SAMBA_USER_ENTRY="${USER}:*:${SAMBA_USER_ID}:${SAMBA_GROUP_ID}:${SAMBA_GROUP}:${SAMBA_HOME}:${SAMBA_SHELL}"
grep -e "${SAMBA_USER_ENTRY}" /etc/passwd >/dev/null || echo "${SAMBA_USER_ENTRY}" >> /etc/passwd
#Configuring the new user directory
mkdir -p ${SAMBA_USER_DIR}
mkdir -p ${SAMBA_USER_DIR}/Private
touch ${SAMBA_USER_DIR}/.profile
chown -R ${USER}:${SAMBA_GROUP} ${SAMBA_USER_DIR}
#Set the user permissions
chmod -R u=rwx,g=rx,o= ${SAMBA_USER_DIR}
#Prohibit access to the particular user's private folder
chmod u=rwx,go= ${SAMBA_USER_DIR}/Private
#chmod -R u=rw,go= ${SAMBA_USER_DIR}/Private/
sleep 3
# Call the function to set the new samba user password
SambaPassword
}
VsftpdAdd() {
# This function might add a Samba user to the vsftpd and grand access to the user's home dir
#Check if FTP service is enabled and if vsftpd is present on the system
VsftpdCheck
if [ $? -eq 1 ]; then
#vsftpd error detected, exiting
exit 1
fi
#Check if the new user is already a valid Samba user
UserCheck ${USER}
if [ $? -eq 1 ]; then
echo -e "###WARNING###\nUser ${USER} is NOT a valid Samba user"
echo -e "\nWe are going to configure it for Samba first"
sleep 1
AddUser
echo -e "\nSamba configuration done, proceeding to FTP service"
fi
#Check for vsftpd secure login file:
if [ ! -f ${FTP_SECURE_LOGIN_FILE} ]; then
echo -e "${FTP_SECURE_LOGIN_FILE}: does not exist yet\ncreating...\n"
logger -t ${SCRIPTNAME} "${FTP_SECURE_LOGIN_FILE}: does not exist, creating..."
touch ${FTP_SECURE_LOGIN_FILE}
chmod u=rw,go= ${FTP_SECURE_LOGIN_FILE}
fi
#Checking if vsftpd has already been configured
sleep 1
vsftpd_check=$(grep -e "${SCRIPTNAME}" ${VSFTPD_CONF})
if [ -z "${vsftpd_check}" ]; then # -n the argument is non empty, -z the argument is empty
# Backing up the if there is some old configuration first
cp ${VSFTPD_CONF} ${VSFTPD_CONF}.backup > /dev/null 2>&1
# Evaluate the FTP server bandwidth in Byte/s to be ready for the config file
FTP_BANDWIDTH_BYTES=$(( (${FTP_BANDWIDTH} / 8) * 1024 ))
# Writing the FTP server configuration (vsftpd)
echo -e "# ${VSFTPD_CONF} -- a config file for vsftpd\n###generated by ${SCRIPTNAME}\nbackground=YES\nlisten=YES\nlisten_address=${FTP_LISTEN_ADDR}\nlisten_port=${FTP_LISTEN_PORT}\nanonymous_enable=NO\nlocal_enable=YES\nwrite_enable=YES\n#chroot_list_enable=YES\n#chroot_list_file=${FTP_SECURE_LOGIN_FILE}\nchroot_local_user=YES\nuserlist_enable=YES\nuserlist_file=${FTP_SECURE_LOGIN_FILE}\nuserlist_deny=NO\nlocal_umask=027\ncheck_shell=NO\nftpd_banner=${FTP_BANNER}\nlocal_max_rate=${FTP_BANDWIDTH_BYTES} # Maximum data transfer rate in bytes per second\nmax_clients=${FTP_MAX_CLIENTS} # Maximum number of clients that may be connected\nmax_per_ip=${FTP_MAX_CONN_IP} # Maximum connections per IP\nmax_login_fails=${FTP_MAX_LOGIN_FAILS}\nidle_session_timeout=${FTP_IDLE_TIMEOUT}\nuse_localtime=YES\nsession_support=NO" > ${VSFTPD_CONF}
fi
echo -ne "Please, enter FTP password for the new user ${USER}:\n"
passwd ${USER}
#Check if the last command is successfull
while [ $? -eq 1 ]
do
echo -ne "\nIncorrect! Try again"
echo -ne "\nPlease, enter FTP password for the new user ${USER}:\n"
passwd ${USER}
done
sleep 1
#Configure the new user for FTP secure login:
grep -e "${USER}" ${FTP_SECURE_LOGIN_FILE} >/dev/null || echo "${USER}" >> ${FTP_SECURE_LOGIN_FILE}
sleep 1
# Remove the pseudo copy of /etc/passwd
rm -f /etc/passwd- > /dev/null 2>&1
# Restart the FTP service
/etc/init.d/vsftpd stop >&- 2>&-
sleep 1
/etc/init.d/vsftpd start >&- 2>&-
echo -e "FTP password set\n"
echo Finished
sleep 1
}
DelUser() {
#This function might remove all of the user files and directories as well as the user from the server itself for both Samba and FTP (if both are configured)
#First check if the new user is already a valid Samba user
UserCheck ${USER}
if [ $? -eq 1 ]; then
echo -e "###WARNING###\nUser ${USER} is NOT a valid Samba user"
echo -e "\nProbably it does not exist on the system yet"
exit 1
fi
# Check if the user data should be deleted and warn that all data would be removed
echo -e "\n### WARNING ###\nThis will remove all user data on the system for the user ${USER}\nincluding its files on the storage disk\n"
while :
do
echo -e "Proceed? (yes/no)"
read answer
case "${answer}" in
[Yy]* )
echo -e "\nThe user and its data will be deleted"
unset answer
break
;;
[Nn]* )
echo -e "\nRefused\n"
unset answer
exit 0
;;
* )
echo -e "\nWrong answer, try again\n"
unset answer
;;
esac
done
sleep 1
rm -R -f ${SAMBA_USER_DIR}
#Status message:
echo -e "Removing user ${USER}...\n"
sleep 1
#sed -i '/'"${USER}"'/ d' /etc/samba/smbpasswd
${SAMBA_PASSWD} -del ${USER} >&- 2>&-
sed -i '/'"${USER}"'/ d' /etc/passwd > /dev/null 2>&1
sed -i '/'"${USER}"'/ d' ${FTP_SECURE_LOGIN_FILE} > /dev/null 2>&1
rm -f /etc/passwd- > /dev/null 2>&1
sleep 1
# Services restart
/etc/init.d/samba restart >&- 2>&-
/etc/init.d/vsftpd stop >&- 2>&-
sleep 1
/etc/init.d/vsftpd start >&- 2>&-
echo Finished
sleep 1
exit 0
}
#################################################################################################
#MAIN
OPTION="$1"
USER="$2"
#Initialize script parameters and usage
if [ "$#" -ne "2" ] || [ "${OPTION}" = "-h" ] || [ "${OPTION}" = "--help" ] || [ "${OPTION}" = "help" ]; then
if [ "${OPTION}" != "-s" ]; then
Usage
exit 0
fi
fi
################# SCRIPT INTERNAL CHECK ###############
# Commands
SAMBA_PASSWD="$(which smbpasswd)"
# Check if needed commands and tools are present on the system:
if [ ! -x ${SAMBA_PASSWD} ]; then
echo -e "${SCRIPTNAME} Error: Samba is probably not present\nPlease verify that samba3 package is installed\n"
exit 1
fi
#######################################################
case ${OPTION} in
"-a" )
AddUser
exit 0
;;
"-f" )
VsftpdAdd
exit 0
;;
"-d" )
DelUser
;;
"-s" )
StorageStat | more
exit 0
;;
* )
echo -e "<${OPTION}> is invalid script option\n"
Usage
exit 0
;;
esac
Updated to v1.4
- optimised script source
- added check for user presnece on the system
- stability improvements
Updated to v1.5
- added several FTP (vsftpd) options to be predefined
Updated to v1.6
- added support for the default /bin/sh Busybox shell (no more bash is required, but optional)
- optimised script source
Updated to v1.7
- added smbpasswd binary path check and correct usage
- script code arrangement
Updated to v1.8
- added new option: samba and ftp services status display (-s option), see tool help
- possibility to enable/disable ftp service functions of the tool from the script config section (in case you do not need ftp functionalities)
- internal check for proper ftp service usage and configuration
- optimised script source
Regards,
dir2cas
(Last edited by dir2cas on 10 Feb 2012, 02:15)