Unexpected behavior in script running on auto checkin versus via 'sudo jamf policy'

sdagley
Esteemed Contributor II

I want to display a message to users, and I want it to stay on the screen until they click a button to acknowledge the message at which point a URL will be opened with further information. I wrote a simple script to call jamfHelper to display the message and wait for the user to click a button at which point the script uses the open command so whatever app is configured as the handler for https will load the web page.

Since I don't want the policy running this script to hang until the user acknowledges the message my script writes out a secondary script which calls jamfHelper, waits for the user to click, calls open, and then deletes itself. The primary script calls the secondary script with a & at the end to spawn it as another process. That works fine when the Policy running my script is triggered via sudo jamf policy - the message is displayed, the jamf process completes, and when I click the button in the message the web page opens and the secondary script is deleted.

The behavior when the Policy executes during a Mac's scheduled check-in with Jamf Pro is different. The secondary script is spawned, the message is displayed, and then immediately goes away. The Policy log shows successful completion. It looks like the spawned process is being terminated as the call to open never happens and the script doesn't delete itself. I've tried several different methods of spawning the secondary script, and they all exhibit the same unexpected behavior when the Policy runs on periodic checkin as opposed to the desired behavior when using sudo jamf policy. If I have the output of the secondary script directed to a log nothing is written for the failure case.

So my question to those of you who have read this far is have you run into this problem before, and if so, what was your solution?

Here's a test script to demonstrate the problem (the other methods I've tried to spawn the secondary script are shown as comments):

#!/bin/bash

# jamfHelper Problem Example.bash
#
# Spawns a script to display a message via jamfHelper that will remain displayed until the user click Show Me.
# Once the user clicks a URL will be opened and the spawned script will be deleted.

currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }' )
currentUserID=$(id -u "$currentUser")

# convenience function to run a command as the current user
# usage:
#   runAsUser command arguments...
runAsUser() {  
  if [ "$currentUser" != "loginwindow" ]; then
    launchctl asuser "$currentUserID" sudo -u "$currentUser" "$@"
  else
    echo "no user logged in"
    # uncomment the exit command
    # to make the function exit with an error when no user is logged in
    # exit 1
  fi
}

JHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
NoteIconPath="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertNoteIcon.icns"

scriptPath="/Library/SomeOrg/SomeFolder"
scriptName="SomeScript"

## Because the parent bash script creates a new bash script using HEREDOC ( this <<EOF >that ),
## use a backslash before the dollar sign to avoid evaluating the variable (or command) as part of creating the script.

/bin/mkdir -p "$scriptPath"

/bin/cat << EOF > "$scriptPath/$scriptName"
#!/bin/bash

"$JHelper" -windowType hud -lockHUD -windowPosition ul -alignHeading center -alignDescription left 
        -title "Message Title" 
        -heading "Message Heading" 
        -description "Message text here" 
        -icon "$NoteIconPath" 
        -iconSize 100 
        -button1 "Show Me"

# Open URL
open "https://somesite.com/somepage.html"

rm -rf "$scriptPath"

exit 0

EOF

/usr/sbin/chown root:admin "$scriptPath/$scriptName"
/bin/chmod 755 "$scriptPath/$scriptName"

# Different ways of calling the secondary script - all exhibit the problem
# runAsUser "$scriptPath/$scriptName" &
# eval /usr/bin/nohup "$scriptPath/$scriptName" &
# /usr/local/jamf/bin/jamf runScript -script "$scriptName" -path "$scriptPath" &
eval /usr/bin/nohup /usr/local/jamf/bin/jamf runScript -script "$scriptName" -path "$scriptPath" >> "$scriptPath/../$scriptName.log" &

exit 0
1 ACCEPTED SOLUTION

sdagley
Esteemed Contributor II

Found a working method to spawn a script that works when a Policy is being called at regular checkin time - use jamf scheduledTask (aka the lazy Jamf admins way of creating a LaunchDaemon). Here's the working script for the curious:

#!/bin/bash

# jamfHelper Problem Example.bash
#
# Spawns a script to display a message via jamfHelper that will remain displayed until the user click Show Me.
# Once the user clicks a URL will be opened and the spawned script will be deleted.

JHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
NoteIconPath="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertNoteIcon.icns"

scriptPath="/Library/SomeOrg/SomeFolder"
scriptName="SomeScript"

## Because the parent bash script creates a new bash script using HEREDOC ( this <<EOF >that ),
## use a backslash before the dollar sign to avoid evaluating the variable (or command) as part of creating the script.

/bin/mkdir -p "$scriptPath"

/bin/cat << EOF > "$scriptPath/$scriptName"
#!/bin/bash

currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }' )
currentUserID=$(id -u "$currentUser")

runAsUser() {  
  if [ "$currentUser" != "loginwindow" ]; then
    launchctl asuser "$currentUserID" sudo -u "$currentUser" "$@"
  fi
}

"$JHelper" -windowType hud -lockHUD -windowPosition ul -alignHeading center -alignDescription left 
        -title "Message Title" 
        -heading "Message Heading" 
        -description "Message text here" 
        -icon "$NoteIconPath" 
        -iconSize 100 
        -button1 "Show Me"

# Open URL as logged in user
runAsUser open "https://somesite.com/somepage.html"

# Clean up
rm -rf "$scriptPath"
/bin/launchctl bootout system /Library/LaunchDaemons/com.jamfsoftware.task.$scriptName.plist

exit 0
EOF

/usr/sbin/chown root:admin "$scriptPath/$scriptName"
/bin/chmod 755 "$scriptPath/$scriptName"

/usr/local/jamf/bin/jamf scheduledTask -command "$scriptPath/$scriptName" -runAtLoad true -name "$scriptName"

exit 0

View solution in original post

2 REPLIES 2

sdagley
Esteemed Contributor II

Found a working method to spawn a script that works when a Policy is being called at regular checkin time - use jamf scheduledTask (aka the lazy Jamf admins way of creating a LaunchDaemon). Here's the working script for the curious:

#!/bin/bash

# jamfHelper Problem Example.bash
#
# Spawns a script to display a message via jamfHelper that will remain displayed until the user click Show Me.
# Once the user clicks a URL will be opened and the spawned script will be deleted.

JHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
NoteIconPath="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertNoteIcon.icns"

scriptPath="/Library/SomeOrg/SomeFolder"
scriptName="SomeScript"

## Because the parent bash script creates a new bash script using HEREDOC ( this <<EOF >that ),
## use a backslash before the dollar sign to avoid evaluating the variable (or command) as part of creating the script.

/bin/mkdir -p "$scriptPath"

/bin/cat << EOF > "$scriptPath/$scriptName"
#!/bin/bash

currentUser=$( echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ { print $3 }' )
currentUserID=$(id -u "$currentUser")

runAsUser() {  
  if [ "$currentUser" != "loginwindow" ]; then
    launchctl asuser "$currentUserID" sudo -u "$currentUser" "$@"
  fi
}

"$JHelper" -windowType hud -lockHUD -windowPosition ul -alignHeading center -alignDescription left 
        -title "Message Title" 
        -heading "Message Heading" 
        -description "Message text here" 
        -icon "$NoteIconPath" 
        -iconSize 100 
        -button1 "Show Me"

# Open URL as logged in user
runAsUser open "https://somesite.com/somepage.html"

# Clean up
rm -rf "$scriptPath"
/bin/launchctl bootout system /Library/LaunchDaemons/com.jamfsoftware.task.$scriptName.plist

exit 0
EOF

/usr/sbin/chown root:admin "$scriptPath/$scriptName"
/bin/chmod 755 "$scriptPath/$scriptName"

/usr/local/jamf/bin/jamf scheduledTask -command "$scriptPath/$scriptName" -runAtLoad true -name "$scriptName"

exit 0

gabester
Contributor III

@sdagley I to have had problems with nohup... sometimes it works, like when run from Self Service. Other times particularly when initiated by an automated checkin it throws up an error like:

nohup: can't detach from console: Inappropriate ioctl for device
executing /usr/bin/nohup /usr/bin/sudo -u USERNAME -i /Applications/TextEdit.app/Contents/MacOS/TextEdit &

Your lazy jamf admin's launchdaemon workaround may be a fix... I'll have to try it.