Skip to content

Instantly share code, notes, and snippets.

@Ethorbit
Last active October 28, 2022 23:24
Show Gist options
  • Save Ethorbit/176578610919fde2a606831618758a8d to your computer and use it in GitHub Desktop.
Save Ethorbit/176578610919fde2a606831618758a8d to your computer and use it in GitHub Desktop.
Personal homenas script which can add,remove,list samba users/shares and view hardware usage & temperatures.
#!/bin/bash
# Prerequisites:
# Samba server
USER_SHARE_DIR="/home" # Each user gets their own directory, choose the path for this to take place. WARNING: permissions for this directory are handled by this script, set to a subdirectory if this worries you.
SAMBA_INCLUDES_FILE="/etc/samba/includes.conf" # This is where we will inject the includes of each user's .conf file. You need to do include = <what you set this variable to> in your smb.conf file so that our changes actually work with samba.
SAMBA_USER_CONF_DIR="/etc/samba/smb.conf.d" # This directory is where the script will add each samba user entry into.
SAMBA_GUEST_USER="guest" # If you have a guest user, put it here so that it can't get removed by this script.
help()
{
echo "Usage: "
echo " usage - Check the usage of the hardware."
echo " temp | temperature - Get the current temperature of the hardware."
echo " user"
echo " add - Add a NAS user."
echo " remove - Remove a NAS user."
echo " password - Change a NAS user's password."
echo " list - List the NAS users."
}
escape_username()
{
echo "$1" | sed "s/[^a-zA-Z0-9]\+//"
}
# Blocks process until a auth key in the form of a file name exists in the user's directory. This is a "verification"
# I know it's stupid, but it should be good enough for a home NAS.
start_file_verification()
{
username="$1"
filename=".nas_auth_$(echo $RANDOM | md5sum | head -c 7; echo)"
filepath="$USER_SHARE_DIR/$username/$filename"
if [ ! -f "$filepath" ]; then
echo "Please verify by creating a file called $filename at the root of your NAS directory.."
echo "If you are unable to access it, contact an administrator."
iterations=0
while [ ! -f "$filepath" ]; do
sleep 0.5
iterations=$(($iterations + 1))
if [ $iterations -ge 500 ]; then
echo "Verification failed, 5 minutes has passed. Please try again."
exit 1
fi
done
echo "Verification passed!"
rm "$filepath"
fi
}
samba_list_users()
{
pdbedit -L | sed 's/:[0-9]\+://'
#btrfs subvolume list -t "$USER_SHARE_DIR/" | awk 'NR>2 { $1=""; $2=""; $3=""; print $0; }' | sed 's/ //'
}
samba_user_exists()
{
username="$1"
[[ $(pdbedit -u "$username" 2> /dev/null) ]] && echo 1 || echo 0
}
update_samba_includes()
{
ls "$SAMBA_USER_CONF_DIR"/* 2> /dev/null | sed 's/^/include = /' > "$SAMBA_INCLUDES_FILE"
smbcontrol all reload-config
}
samba_add_user_share()
{
username="$1"
if [[ -f "$SAMBA_USER_CONF_DIR/$username.conf" ]]; then
echo "It seems there is already a share defined for this user. If you aren't able to connect to it, try removing and adding this user again, otherwise you can just ignore this."
else
echo "[$username]
comment = $username's storage.
path = /home/$username
browseable = yes
writable = yes
valid users = $username
force user = $username
force group = $username
create mask = 700
security mask = 700
directory mask = 700" > "$SAMBA_USER_CONF_DIR/$username.conf"
fi
update_samba_includes
}
samba_remove_user_share()
{
username="$1"
rm "$SAMBA_USER_CONF_DIR/$username.conf" 2> /dev/null
update_samba_includes
}
samba_set_user_password()
{
username="$1"
password="$2"
password_confirm="$3"
user_exists=$(samba_user_exists "$username")
if [ -z "$password" ]; then
echo "Password:"
read -rs password
echo "Confirm Password:"
read -rs password_confirm
fi
if [ "$password" != "$password_confirm" ]; then
echo "Passwords don't match. Aborting."
exit 1
fi
if [ $user_exists -eq 1 ]; then
start_file_verification "$USERNAME"
fi
(echo "$password"; echo "$password_confirm") | smbpasswd -s -a "$username"
}
missing_file()
{
echo "$1 doesn't exist"
exit 1
}
[ ! -f "$SAMBA_INCLUDES_FILE" ] && missing_file "SAMBA_INCLUDES_FILE"
[ ! -d "$USER_SHARE_DIR" ] && missing_file "USER_SHARE_DIR"
[ ! -d "$SAMBA_USER_CONF_DIR" ] && missing_file "SAMBA_USER_CONF_DIR"
groupadd nasuser 2> /dev/null
chgrp nasuser "$USER_SHARE_DIR"
chmod 710 "$USER_SHARE_DIR"
while [ -v 1 ]; do
case $1 in
usage)
echo " ___ _____ ___ ___ _ ___ ___
/ __| |_ _| / _ \ | _ \ /_\ / __| | __|
\__ \ | | | (_) | | / / _ \ | (_ | | _|
|___/ |_| \___/ |_|_\ /_/ \_\ \___| |___|
"
#echo "[------------- Storage ------------------]"
echo "| SYSTEM STORAGE:"
vgs
#lvs
for lv in $(lvs | awk 'NR >1 { print $1 }'); do
echo " $lv: $(df -h /dev/crypt-root-vg/$lv | awk 'NR==2 { print $3 " used out of " $4 }')"
done
echo -e "\n| USER STORAGE:"
#btrfs filesystem usage --human-readable -T "$USER_SHARE_DIR/"
df -h /home | awk 'NR==2 { print $3 " used out of " $4 }'
echo " ___ _ __ __
| _ \ /_\ | \/ |
| / / _ \ | |\/| |
|_|_\ /_/ \_\ |_| |_|
"
free -h
echo " ___ ___ _ _
/ __| | _ \ | | | |
| (__ | _/ | |_| |
\___| |_| \___/
"
top -bn1 | grep '%Cpu' | tail -1 | grep -P '(....|...) id,'|awk '{print "CPU Usage: " 100-$8 "%"}'
lscpu | grep MHz | awk '{ print "CPU Speed: " $3 " Mhz" }'
exit
;;
temp | temperature)
echo "--- Hard Drives ---"
for disk in $(lsblk -d | awk 'NR>1 { print "/dev/" $1 }'); do
hddtemp -w "$disk"
done
echo -e "\n--- CPU ---"
temp=$(sensors -j | jq '."k10temp-pci-00c3"."temp1"."temp1_input"')
cpumodel=$(lscpu | grep 'Model name' | cut -f 2 -d ":" | awk '{$1=$1}1')
echo " $cpumodel: $temp°C"
exit
;;
user)
case $2 in
add)
USERNAME=$(escape_username "$3")
if [ -z "$USERNAME" ]; then
echo "Please specify the username"
exit 1
fi
if [[ -d "$USER_SHARE_DIR/$USERNAME" || $(id "$USERNAME" 2> /dev/null) ]]; then
echo "User already exists."
exit 1
else
rm -d "$USER_SHARE_DIR/$USERNAME" 2> /dev/null
if [ -d "$USER_SHARE_DIR/$USERNAME" ]; then
echo "Cannot add user!"
echo "There is a non-empty directory tied to that username, even though the user itself doesn't exist. Pick a different username or contact an administrator."
exit 1
fi
useradd "$USERNAME" -G nasuser
samba_set_user_password "$USERNAME" "$PASSWORD" "$PASSWORD_CONFIRM"
mkdir "$USER_SHARE_DIR/$USERNAME"
chown "$USERNAME:$USERNAME" "$USER_SHARE_DIR/$USERNAME"
chmod 700 "$USER_SHARE_DIR/$USERNAME"
samba_add_user_share "$USERNAME"
echo "Created new NAS user $(id "$USERNAME")"
fi
;;
password)
USERNAME=$(escape_username "$3")
samba_set_user_password "$USERNAME" "$PASSWORD" "$PASSWORD_CONFIRM"
;;
remove)
USERNAME=$(escape_username "$3")
if [ -z "$USERNAME" ]; then
echo "Please specify the username"
exit 1
fi
if [ "$SAMBA_GUEST_USER" = "$USERNAME" ]; then
echo "You can't remove the guest user."
exit 1
fi
if [ $(samba_user_exists "$USERNAME") -eq 1 ]; then
if [[ $(ls "$USER_SHARE_DIR/$USERNAME" | wc -l) -gt 0 ]]; then
echo -e "Cannot remove user!"
echo "$USERNAME's directory is not empty, you must move all of their files out before you can remove them."
exit 1
fi
smbpasswd -x "$USERNAME" 2> /dev/null
userdel "$USERNAME"
rm -d "$USER_SHARE_DIR/$USERNAME"
samba_remove_user_share "$USERNAME"
echo "Deleted NAS user $USERNAME."
else
echo "NAS user $USERNAME does not exist."
if [ -d "$USER_SHARE_DIR/$USERNAME" ]; then
echo "Even though they don't exist, there is a storage directory for them. Contact an administrator to get it removed."
fi
exit 1
fi
;;
list)
samba_list_users
;;
*)
help
;;
esac
exit
;;
*)
help
exit
;;
esac
shift
done
help
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment