patternbashMinor
Script to temporarily drop admin privileges
Viewed 0 times
scriptadminprivilegesdroptemporarily
Problem
Description
The aim of my project is to allow administrators to drop privileges for reasons of self-control. Currently, it works only on MacOS Sierra but the concept should be extensible to any Unix compatible system.
The sudoers mechanism is the workhorse. By adding a file in
The
Files
admin-helper
admin.sudoers
Usage
This is the installation process:
The subsequent usage is:
or
Review
Some of the points I want a review for include:
The aim of my project is to allow administrators to drop privileges for reasons of self-control. Currently, it works only on MacOS Sierra but the concept should be extensible to any Unix compatible system.
The sudoers mechanism is the workhorse. By adding a file in
sudoers.d/ the administrator user (let's call him my-admin) is given permissions to run the script admin-helper as root.The
admin-helper script when run, toggles my-admin's membership from the admin group. When the my-admin is not in the admin group, the user is only added after the script sleeps for 20 min.Files
admin-helper
#!/bin/bash
set -e -u
username=$SUDO_USER
delay=$((60*20)) #20 minutes
uGuid=$(dscl . -read /Users/$username/ GeneratedUID | sed -nE 's/GeneratedUID: (.*$)/\1/p')
if groups "$username" | grep -q -w admin; then
dscl . -delete /Groups/admin GroupMembers "$uGuid"
echo "Removed '$username' from admin. You may need to logout for changes to take effect."
else
echo "'$username' is not an admin"
echo "Sleeping for $delay seconds staring from $(date '+%D %T')"
sleep "$delay"
if [[ -z "${1+x}" ]]; then
echo "Adding '$username' to admin group"
dscl . -append /Groups/admin GroupMembers "$uGuid"
else
echo "Executing command as root"
$1
fi
fiadmin.sudoers
User_Alias DELAYED_ADMINS = my-admin
Cmnd_Alias ADMIN_HELPERS = /usr/local/bin/admin-helper
DELAYED_ADMINS ALL=(root) ADMIN_HELPERSUsage
This is the installation process:
sudo mkdir -p /private/etc/sudoers.d/
EDITOR="cp admin.sudoers" sudo visudo -f /private/etc/sudoers.d/admin
sudo cp admin-helper /usr/local/bin/admin-helperThe subsequent usage is:
sudo admin-helperor
sudo admin-helper "whoami"Review
Some of the points I want a review for include:
- The way to add/remove user from the
admingroup. Perhaps there is a better cross-platform way of doing this.
- Potential security is
Solution
Usability
The current script works in a dual mode:
I find the conditional execution in the second mode a bit confusing.
That is, when a parameter is given, but the user is admin,
the command won't be executed.
Instead the script will drop membership.
If you really want to execute the command you have to re-run the same command line, which could be annoying.
I suggest to change the behavior so that when a parameter is given,
execute it always, after the delay, regardless of the membership status.
I think this won't conflict with your main purpose,
but it would improve the usability of the script.
Cross-platform way to add/remove users
As a first step to making the script more portable,
it would be good to separate the platform dependent parts from the platform independents ones, for example:
You could have the platform-specific implementations in separate files,
and then source the appropriate flavors as needed.
Minor technical improvements
Instead of
it would be simpler to use
This seems to check if
Unless I'm missing something, this is equivalent but simpler:
When
it can be hard to remember where it comes from and what it's supposed to be.
It's better to assign command line arguments to a meaningful variable early in the script, and refer to them by that name.
That also makes it easier to find all locations where it is used.
For example, you could put near the top of the file:
The current script works in a dual mode:
- When run without parameters, it toggles group membership
- When run with a parameter, the parameter is executed as root, on the condition that the user is not currently an admin
I find the conditional execution in the second mode a bit confusing.
That is, when a parameter is given, but the user is admin,
the command won't be executed.
Instead the script will drop membership.
If you really want to execute the command you have to re-run the same command line, which could be annoying.
I suggest to change the behavior so that when a parameter is given,
execute it always, after the delay, regardless of the membership status.
I think this won't conflict with your main purpose,
but it would improve the usability of the script.
Cross-platform way to add/remove users
As a first step to making the script more portable,
it would be good to separate the platform dependent parts from the platform independents ones, for example:
add_to_admin() {
dscl . -append /Groups/admin GroupMembers "$uGuid"
}
remove_from_admin() {
dscl . -delete /Groups/admin GroupMembers "$uGuid"
}You could have the platform-specific implementations in separate files,
and then source the appropriate flavors as needed.
Minor technical improvements
Instead of
sed -nE 's/GeneratedUID: (.*$)/\1/p' to get the UID part,it would be simpler to use
cut -f2 -d' ' or awk '{ print $2 }'.This seems to check if
$1 empty:if [[ -z "${1+x}" ]]; thenUnless I'm missing something, this is equivalent but simpler:
if [ -z "$1" ]; thenWhen
$1 appears in the middle or near the end of a script,it can be hard to remember where it comes from and what it's supposed to be.
It's better to assign command line arguments to a meaningful variable early in the script, and refer to them by that name.
That also makes it easier to find all locations where it is used.
For example, you could put near the top of the file:
cmd=$1Code Snippets
add_to_admin() {
dscl . -append /Groups/admin GroupMembers "$uGuid"
}
remove_from_admin() {
dscl . -delete /Groups/admin GroupMembers "$uGuid"
}if [[ -z "${1+x}" ]]; thenif [ -z "$1" ]; thenContext
StackExchange Code Review Q#162129, answer score: 3
Revisions (0)
No revisions yet.