#!/bin/bash
# Usage subroutine
usage() { echo "Usage: $0 [-b] [-h ] [-m] [-c <string>] [-g <string>] [-G <string>] [-i <string>] [-p <string>] [-u <string]" 1>&2; exit 1; }
# Detailed help subroutine.
showman() {
# `cat << EOF` This means that cat should stop reading when EOF is detected
cat << EOF
Usage: .IsCommandAllowed.sh [-bhmcgGipu]
Check whether command is allowed for this user.
-b Create a compressed checkpoint in /tmp/trigger<RANDOM_NUM> to preserve unmodified db.trigger database.
NOTE: This is not necessary if one has a spec server configured.
-h Display usage
-m Display detailed help
-c Command to check, e.g., "obliterate"
-g One group name, e.g., "Administrators"
-G List of groups of which user is a member. For stand-alone script, enter space-separated list of groups as string.
-i Client IP address, e.g., "192.168.0.1"
-p Server port used in p4 -p <port> command syntax, e.g., "p4 -p ssl:1999"
-u User name, e.g., "perforce"
If the command is executed from the server, e.g. the client IP is 127.0.0.1, then the command is automatically allowed.
Otherwise, to execute a command, the group name must be in the group list. Both -g and -G options are required.
Example trigger, which would call this script prior to allowing bgtask, obliterate, or triggers commands.
checkCmd command pre-user-(bgtask|obliterate|triggers) "/home/perforce/IsCommandAllowed.sh -g Administrators -G %groups% -u %user% -p %serverport% -c %command% -i %clientip%"
Note the use of pre-defined trigger parameters: %groups% %user% %serverport% %command% %clientip%
Also note that the group (-g) must be hard-coded in the trigger.
EOF
# EOF is found above and hence cat command stops reading. This is equivalent to echo but much neater when printing out.
}
# Initialize variables.
backup=0
clientIP=""
command=""
group=""
groupList=""
#grpcmd=""
port=""
user=""
# Parse parameters.
while getopts "bhmc:g:G:i:p:u:" o; do
case "${o}" in
b)
backup=1
;;
h)
usage
;;
m)
showman
;;
c)
command=${OPTARG}
# Perforce is prepending 'user-' to command. Strip it off.
command="${command#user-}"
;;
g)
group=${OPTARG}
;;
G)
groupList=${OPTARG}
;;
i)
clientIP=${OPTARG}
;;
p)
port=${OPTARG}
;;
u)
user=${OPTARG}
;;
*)
usage
;;
esac
done
shift $((OPTIND-1))
# Possible workaround if %groups% is not correct
# grpcmd=$("$P4DBIN" -p "$port" groups -i)
# groupList=$grpcmd
# Do backup if requested.
if [[ "$backup" -eq 1 ]]; then
filename="/tmp/trigger$RANDOM"
backupCmd=$("$P4DBIN" -p "$port" -z -jd "$filename")
backup="$backupCmd"
fi
# If the command comes from the localhost, then allow it automatically.
if [[ "127.0.0.1" == "$clientIP" ]]; then
exit 0;
fi
# Block command if no group and no group list.
if [[ -z "$group" || -z "$groupList" ]]; then
echo "Must specify -g and -G, a group name and group list."
exit 1;
fi
# Block command if group is not in the list of groups.
if ! echo "$groupList" | grep -q "$group"; then
echo "User $user is not allowed to run command: $command."
exit 1;
fi
# Allow user to execute command
exit 0