Temporary admin rights via Self Service policy

Valued Contributor

I have read several threads here talking about granting temporary admin rights via Self Service. Has anyone created a procedure that works? Ideally, I would like for standard users to be able to click the button in Self Service to get elevated to admin, and then have that expire after X amount of minutes. So far, it looks like all of the procedures I have found have problems.


Contributor II

I think it was JNUC 2013 @Andrina showed an amazing set of scripts that she put together to make a user a temporary admin. It might give you a pretty good jump off point. https://github.com/andrina/JNUC2013/tree/master/Users%20Do%20Your%20Job

I think it was part of this presentation : https://www.youtube.com/watch?v=AzlWdrRc1rY&list=PLlxHm_Px-Ie01lK6FgfdXhk-YuByY6X27&index=14

Valued Contributor

You are correct @rcorbin and I tried it back in the day and it worked pretty well. We decided to forgo it as we aren't currently enforcing the admins rights stuff on Macs. This was a nice solution. I also think my other concern was needing to be connected to the JSS for the policy to work. For instance, someone working from home and needing to add a printer or some other reason, if they aren't connected to the JSS, the policy wouldn't run. I'm sure there is a way around it, we just didn't explore it much though.

Contributor II

Just a warning with this, we were going to implement this solution but realised you could walk up to any machine login to your AD account, run the self service policy and then gain access to the entire computer.

We looked at making sure the computer was registered to the logged in user using an API lookup, but then we also have a self service policy which updates JAMF Pro so you are registered against the machine.

Esteemed Contributor II

@BOBW is the Assigned User logic something you can share (sanitized)? :) We're looking to pul that with API.


Contributor II

@donmontalvo let me take a look, its my last day at work till next year so will try to get it through later today

Contributor II

@donmontalvo found it....

hope I cleaned it up :) . Not sure whether I borrowed some of this code from or if I did it myself. it was a while ago.....

it also need another script ran from Phone Support guys to genrate a code based on date/ time to work correctly. Let me know if you cannot work it out and I will send it over.

I think the main part you are after is the lookup of the username through the API which is at the top.


## Created by David Coupe##
## Apologies for any script or partial script I may have borrowed to create this##

comp_name=$(scutil --get ComputerName)

response=$(curl https://**JSSURL**/JSSResource/computers/name/$comp_name -u **apiuser:apipass**)

response2=$(echo $response | /usr/bin/awk -F'<username>|</username>' '{print $2}')

echo "response2 = $response2"

USERNAME=`who | grep console| awk '{print $1}'`


if [[ $USERNAME == $response2 ]]
    #   echo "match"
    #   else
    #   echo "mismatch"
    #   fi
#Cocoa Dialog path

# request user enter daily code
    q1=($($CD standard-inputbox --title "Admin Access" --string-output --no-newline --informative-text "Please Call 17000 and request an admin code - Enter the code below"  --quiet))

# build daily code
    code=$(date "+%y%m%d" | tr -d '' | cut -c 1-8 | rev)

        if [[ $pass == $code ]]

    # Place launchd plist to call JSS policy to remove admin rights.
            echo "<?xml version="1.0" encoding="UTF-8"?> 
            <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
            <plist version="1.0"> 
            </plist>" > /Library/LaunchDaemons/edu.adminremove.plist

            #set the permission on the file just made.
            chown root:wheel /Library/LaunchDaemons/edu.adminremove.plist
            chmod 644 /Library/LaunchDaemons/edu.adminremove.plist
            defaults write /Library/LaunchDaemons/edu.adminremove.plist disabled -bool false

            # load the removal plist timer.     
            launchctl load -w /Library/LaunchDaemons/edu.adminremove.plist

            # build log files in var/edu
            mkdir /var/edu
            TIME=`date "+Date:%m-%d-%Y TIME:%H:%M:%S"`
            echo $TIME " by " $USERNAME >> /var/edu/10mindmin.txt

            echo $USERNAME >> /var/edu/userToRemove

            # give current logged user admin rights
            /usr/sbin/dseditgroup -o edit -a $USER -t user admin
            exit 0


            echo "mismatched code"

            $CD ok-msgbox --no-cancel --text "Admin Access" --informative-text  "Codes did not match. Please contact 17000 for new code" --no-newline --float



Contributor II

@howie_isaacks Let me know if want to see the rest of it, there are two more scripts that go with it.

  1. this code which is a self service policy and confirms user is owner of computer and generates code
  2. Phone support guys run a similar code to generate a code - both codes match admin access granted
  3. policy is called by launchagent which runs the turn off for the admin access

Im sure there are nicer ways to achieve this and happy to have someone help me out to get it perfect.

New Contributor III

Hey all. Wanted to share my script for temporary admin access. The script takes an argument to remove the access after N seconds. The script has a signal termination trap, which will remove the user's access should the machine shut down or if the script is manually "killed" via the command line.

There isn't much else logic for looking to see if the user completely compromises the computer, because well, if you're giving them temporary admin access, you trust them enough to potentially compromise the whole machine, or else you wouldn't be doing this in the first place!

Use this at your own peril. I've tested this script for months and it runs pretty solid on macOS 10.12.

if [[ ! $(whoami) = "root" ]];then echo "Must be root.";exit 1;fi
curUser="$(ls -l /dev/console | awk '{ print $3 }')"
if ! [[ -z $arg ]];then
  if [[ $arg =~ $numtest ]];then 
isUserAnAdmin () {
  if [[ $(dscl . read /Groups/admin GroupMembership | grep -oq "${curUser}";echo $?) -eq 0 ]];then
grant_admin () {
  dscl . append /Groups/admin GroupMembership "${curUser}"
deny_admin () {
  dscl . delete /Groups/admin GroupMembership "${curUser}" >/dev/null 2>&1
exit_script () {
  if isUserAnAdmin;then
if isUserAnAdmin;then
 trap exit_script SIGINT SIGTERM
 sleep ${sleeptimer}
exit $?

Valued Contributor

Thanks for all of the suggestions!