#!/usr/bin/env bash #=============================================================================== # FILE: samba.sh # # USAGE: ./samba.sh # # DESCRIPTION: Entrypoint for samba docker container # # OPTIONS: --- # REQUIREMENTS: --- # BUGS: --- # NOTES: --- # AUTHOR: David Personette (dperson@gmail.com), # ORGANIZATION: # CREATED: 09/28/2014 12:11 # REVISION: 1.0 #=============================================================================== set -o nounset # Treat unset variables as an error ### import: import a smbpasswd file # Arguments: # file) file to import # Return: user(s) added to container import() { local name id file="${1}" while read name id; do useradd "$name" -M -u "$id" done < <(cut -d: -f1,2 --output-delimiter=' ' $file) pdbedit -i smbpasswd:$file } ### perms: fix ownership and permissions of share paths # Arguments: # none) # Return: result perms() { local i file=/etc/samba/smb.conf for i in $(awk -F ' = ' '/ path = / {print $2}' $file); do chown -Rh smbuser. $i find $i -type d -exec chmod 775 {} \; find $i -type f -exec chmod 664 {} \; done } ### share: Add share # Arguments: # share) share name # path) path to share # browsable) 'yes' or 'no' # readonly) 'yes' or 'no' # guest) 'yes' or 'no' # users) list of allowed users # admins) list of admin users # Return: result share() { local share="$1" path="$2" browsable=${3:-yes} ro=${4:-yes} \ guest=${5:-yes} users=${6:-""} admins=${7:-""} \ file=/etc/samba/smb.conf sed -i "/\\[$share\\]/,/^\$/d" $file echo "[$share]" >>$file echo " path = $path" >>$file echo " browsable = $browsable" >>$file echo " read only = $ro" >>$file echo " guest ok = $guest" >>$file [[ ${users:-""} && ! ${users:-""} =~ all ]] && echo " valid users = $(tr ',' ' ' <<< $users)" >>$file [[ ${admins:-""} && ! ${admins:-""} =~ none ]] && echo " admin users = $(tr ',' ' ' <<< $admins)" >>$file echo -e "" >>$file } ### timezone: Set the timezone for the container # Arguments: # timezone) for example EST5EDT # Return: the correct zoneinfo file will be symlinked into place timezone() { local timezone="${1:-EST5EDT}" [[ -e /usr/share/zoneinfo/$timezone ]] || { echo "ERROR: invalid timezone specified: $timezone" >&2 return } if [[ -w /etc/timezone && $(cat /etc/timezone) != $timezone ]]; then echo "$timezone" >/etc/timezone ln -sf /usr/share/zoneinfo/$timezone /etc/localtime dpkg-reconfigure -f noninteractive tzdata >/dev/null 2>&1 fi } ### user: add a user # Arguments: # name) for user # password) for user # id) for user # Return: user added to container user() { local name="${1}" passwd="${2}" id="${3:-""}" useradd "$name" -M ${id:+-u $id} echo -e "$passwd\n$passwd" | smbpasswd -s -a "$name" } ### workgroup: set the workgroup # Arguments: # workgroup) the name to set # Return: configure the correct workgroup workgroup() { local workgroup="${1}" file=/etc/samba/smb.conf sed -i 's|^\( *workgroup = \).*|\1'"$workgroup"'|' $file } ### usage: Help # Arguments: # none) # Return: Help text usage() { local RC=${1:-0} echo "Usage: ${0##*/} [-opt] [command] Options (fields in '[]' are optional, '<>' are required): -h This help -i \"\" Import smbpassword required arg: \"\" - full file path in container -n Start the 'nmbd' daemon to advertise the shares -p Set ownership and permissions on the shares -s \"[;browsable;readonly;guest;users;admins]\" Configure a share required arg: \";;\" is how it's called for clients path to share NOTE: for the default value, just leave blank [browsable] default:'yes' or 'no' [readonly] default:'yes' or 'no' [guest] allowed default:'yes' or 'no' [users] allowed default:'all' or list of allowed users [admins] allowed default:'none' or list of admin users -t \"\" Configure timezone possible arg: \"[timezone]\" - zoneinfo timezone for container -u \"\" Add a user required arg: \";\" for user for user [ID] for user -w \"\" Configure the workgroup (domain) samba should use required arg: \"\" for samba The 'command' (if provided and valid) will be run instead of samba " >&2 exit $RC } while getopts ":hi:nps:t:u:w:" opt; do case "$opt" in h) usage ;; i) import "$OPTARG" ;; n) NMBD="true" ;; p) PERMISSIONS="true" ;; s) eval share $(sed 's/^\|$/"/g; s/;/" "/g' <<< $OPTARG) ;; t) timezone "$OPTARG" ;; u) eval user $(sed 's|;| |g' <<< $OPTARG) ;; w) workgroup "$OPTARG" ;; "?") echo "Unknown option: -$OPTARG"; usage 1 ;; ":") echo "No argument value for option: -$OPTARG"; usage 2 ;; esac done shift $(( OPTIND - 1 )) [[ "${TZ:-""}" ]] && timezone "$TZ" [[ "${WORKGROUP:-""}" ]] && workgroup "$WORKGROUP" [[ "${PERMISSIONS:-""}" ]] && perms if [[ $# -ge 1 && -x $(which $1 2>&-) ]]; then exec "$@" elif [[ $# -ge 1 ]]; then echo "ERROR: command not found: $1" exit 13 elif ps -ef | egrep -v grep | grep -q smbd; then echo "Service already running, please restart container to apply changes" else [[ ${NMBD:-""} ]] && ionice -c 3 nmbd -D exec ionice -c 3 smbd -FS