Quite frequently on Linux the traditional permission system gets in the way of development due to file and directory permissions being crucial to the operation of software. Suppose that a directory is mounted over the network that should be accessed by multiple users yet that directory also contains configuration files that are being read by a system daemon. In such cases, the use of the sticky bit can come in handy to ensure that newly created directories and files are created under the system daemon's user and group permissions but this solution does not scale up when multiple users and groups are involved.
The script presented in this article leverages ACL permissions in order to provide a tool that can be used to grant a user and a group permissions to a directory. The script takes care to define default ACLs based on the existing unix permissions and then adds permission for the specified user and group.
To setup the script, create a file at /etc/default/systemize
with the following contents:
# Parameters for the systemize command. # Remove previous ACLs before granting (default: yes). RESET_ACL_ENTRIES=yes # The default user to grant permissions to (default: system). GRANT_USR=administrator # The default group to grant permissions to (default: system). GRANT_GRP=administrator
Additionally, make sure that the user and group defined by GRANT_USR
, respectively GRANT_GRP
are valid users.
Then, create a file at /usr/local/bin/systemize
with the contents from the code section. Finally, grant permission for the script to be executed:
chmod ug+x /usr/local/bin/systemize
Without further ado, to grant additional ACL permissions to the user and group defined in /etc/default/systemize
, issue:
systemize DIRECTORY
where:
DIRECTORY
is the full path to a directory
The systemize script also supports specifying the user or group (or both) on the command line - in case the user and group is specified on the command line, then it takes precedence over the user and group defined in /usr/local/bin/systemize
. The invocation:
systemize -u office DIRECTORY
will:
office
permissions to the directory path DIRECTORY
,/etc/default/systemize
permissions to the directory path DIRECTORY
Furthermore, systemize can also revoke permissions by using the action flag (-a
) with the option set to either grant
(default) or revoke
. The invocation:
systemize -a revoke -u office DIRECTORY
will:
office
to the directory path DIRECTORY
,/etc/default/systemize
to the directory path DIRECTORY
#!/bin/sh ########################################################################### ## Copyright (C) Wizardry and Steamworks 2018 - License: GNU GPLv3 ## ## Please see: http://www.gnu.org/licenses/gpl.html for legal details, ## ## rights of fair usage, the disclaimer and warranty conditions. ## ########################################################################### # Set ACL permissions on a directory for a specific user and group. # ########################################################################### # Load system defaults. SCRIPT_NAME=`basename $0` [ -f "/etc/default/$SCRIPT_NAME" ] && . /etc/default/"$SCRIPT_NAME" # Check whether at least a directory was supplied. if [ "$#" -lt 1 ] ; then echo "Syntax: $0 [-a <ACTION>][-u <USER>] [-g <GROUP>] <DIRECTORY>" exit 1 fi while getopts "hu:g:a:" opt; do case "$opt" in u ) GRANT_USR="$OPTARG" ;; g ) GRANT_GRP="$OPTARG" ;; a ) ACTION="$OPTARG" ;; * ) echo "Syntax: $0 [-u <USER>] [-g <GROUP>] <DIRECTORY>" echo "Usage:" echo " $SCRIPT_NAME Display this help message." echo " $SCRIPT_NAME <directory> Set ACL on directory." echo "" echo "Options:" echo " -a action Revoke or grant (default: grant)." echo " -u user Set ACLs for user." echo " -u group Set ACLs for group." exit 0 ;; esac done shift $((OPTIND-1)) if [ -z "$@" ] || [ ! -d "$@" ] ; then echo "Directory \"$@\" not found!" exit 1 fi DIR="$@" # Acquire a lock for the directory. mkdir -p "/var/lock/$SCRIPT_NAME" LOCK_FILE="/var/lock/$SCRIPT_NAME/$DIR" while [ `mkdir "$LOCK_FILE"` ] ; do sleep 1 done trap '{ rm -rf "$LOCK_FILE"; }' KILL QUIT TERM EXIT INT HUP # Get the unix user and group. USR=`stat --format "%U" "$DIR"` GRP=`stat --format "%G" "$DIR"` # Get the unix permissions. set -- `stat -c "%A" /etc/openhab2 | \ cut -c 2- | \ sed -r 's/(.{3})/\1 /g' | \ sed 's/\-//g'` DIR_USR_PRM=$1 DIR_GRP_PRM=$2 DIR_OTR_PRM=$3 # Check that the grant user and group exist. id "$GRANT_USR" 2>/dev/null >/dev/null if [ "$?" -eq 1 ] || [ -z "$GRANT_USR" ] ; then echo "Grant user \"$GRANT_USR\" does not exist!" exit 1 fi id "$GRANT_GRP" 2>/dev/null >/dev/null if [ "$?" -eq 1 ] || [ -z "$GRANT_GRP" ] ; then echo "Grant group \"$GRANT_GRP\" does not exist!" exit 1 fi # Reset ACL entries if configured. if [ ! -z "$RESET_ACL_ENTRIES" ] && [ x"$RESET_ACL_ENTRIES" = x"yes" ] then setfacl -Rbn "$DIR" fi # Set default ACLs. setfacl -dm u::rwx,m::rwx,g::rx,o::rx "$DIR" setfacl -R -dm u::rwx,m::rwx,g::rx,o::rx "$DIR" # Grant access to dirctory user and group. setfacl -R -dm u:"$USR":"$DIR_USR_PRM",g:"$GRP":"$DIR_GRP_PRM",o::"$DIR_OTR_PRM" "$DIR" setfacl -R -m u:"$USR":"$DIR_USR_PRM",g:"$GRP":"$DIR_GRP_PRM",o::"$DIR_OTR_PRM" "$DIR" case "$ACTION" in revoke ) # Revoke access to system user. setfacl -R -dx u:"$GRANT_USR",g:"$GRANT_GRP" "$DIR" setfacl -R -x u:"$GRANT_USR",g:"$GRANT_GRP" "$DIR" ;; * ) # Grant access to system user. setfacl -R -dm u:"$GRANT_USR":rwx,g:"$GRANT_GRP":rwx "$DIR" setfacl -R -m u:"$GRANT_USR":rwx,g:"$GRANT_GRP":rwx "$DIR" ;; esac