Posted on 03-13-2017 09:58 AM
I'm trying to figure out how I can run a script from Self Service as the user who is triggering it. By default, the scripts are being run as root (or the service account, I think).
For background, it's a script to re-direct screenshots from being saved to the Desktop to another folder. I'd like this script to run as the user who is logged into Self Service so they have ownership of the folder created. Here's an example of what I got so far:
#!/bin/bash
mkdir -p $HOME/New_SCREEN_SHOTS_Folder
defaults write com.apple.screencapture location $HOME/New_SCREEN_SHOTS_Folder
killall SystemUIServer
exit 0
Posted on 03-13-2017 10:16 AM
There isn't an easy way to run the entire script as the user, unless you deployed it as a local script and called it via a LaunchAgent, but you can run portions of the script as the logged in user, or, in your case, simply determine who the logged in user is and make sure to direct the command at their files and preferences.
So using what you have above, the following should work to ensure the logged in user's plist is being written to.
#!/bin/bash
loggedInUser=$(stat -f%Su /dev/console)
mkdir -p /Users/$loggedInUser/New_SCREEN_SHOTS_Folder
/usr/bin/defaults write /Users/$loggedInUser/Library/Preferences/com.apple.screencapture.plist location /Users/$loggedInUser/New_SCREEN_SHOTS_Folder
## Make sure the plist we just wrote to as root is owned by the user and not root
/usr/sbin/chown $loggedInUser /Users/$loggedInUser/Library/Preferences/com.apple.screencapture.plist
killall SystemUIServer
EDIT: Looking at it again, you may also want to throw in an extra chown -R
command against the new folder the script creates, just to ensure the user also owns that directory and not root.
Posted on 03-13-2017 10:24 AM
If running via Self Service, $3 works to get the username.
No idea why I didn't do it, here but seems a similar script.
Posted on 03-13-2017 12:39 PM
@bentoms @mm2270 Thanks for you guidance. I remembered that $3 outputs the current user logged in. So, do you think adding an "su -c $3" line at the beginning should work?
#!/bin/bash
su -c $3
mkdir -p $HOME/New_SCREEN_SHOTS_Folder
defaults write com.apple.screencapture location $HOME/New_SCREEN_SHOTS_Folder
killall SystemUIServer
exit 0
Otherwise, more like your suggestions:
#!/bin/bash
mkdir -p $HOME/New_SCREEN_SHOTS_Folder
defaults write $HOME/Library/Preferences/com.apple.screencapture location $HOME/New_SCREEN_SHOTS_Folder
chown $3 /Users/$HOME/Library/Preferences/com.apple.screencapture.plist
chown -R $3 /Users/$HOME/New_SCREEN_SHOTS_Folder
killall SystemUIServer
exit 0
I know you both defined the home folder path more specifically as "/Users/$loggedInUser/folderpath," but $HOME does the same, correct? Do you think I would also have to include a couple of "chmod" lines for the plist and folder being created?
I'm just trying to use as few lines as possible.
Posted on 03-13-2017 12:51 PM
You can use launchctl
to run commands using the logged-in user's privileges. I discuss how to do that as part of the post linked below:
For a practical example of how I've used it, please see the link below:
[https://derflounder.wordpress.com/2016/11/10/providing-website-links-via-casper-self-service-policies/](lhttps://derflounder.wordpress.com/2016/11/10/providing-website-links-via-casper-self-service-policies/)
Posted on 03-13-2017 01:10 PM
I don't believe the $HOME variable will work in a case of the script being run by another account, like the service account or root. For example, if you simply switch to another account on the Mac in Terminal, like su administrator
and then run echo $HOME
you'll see the path it prints is of the account you just logged into, not your home path. Because it doesn't work in that context, you would need to use something like /Users/$3/
or /Users/$loggedInUser/
, meaning the full path to the home directory.
As for whether to use $3 or a separate logged in user variable, that is entirely up to you. $3 certainly works for your case scenario, but I tend to write scripts to be as portable as possible (at least most times). I never know if I'll end up running the script in a different context, like not from Self Service. In that case, a separate variable that would always get the logged in user would work in those extras cases, not just from Self Service or the login/logout trigger. But its really up to you. If you're pretty confident you'll only be running this from Self Service, then $3 should be fine to use.
Posted on 03-13-2017 02:54 PM
Are the users always going to run it from Self Service?
I've had to run package installers before as the user and ended putting the package within a package using Composer to copy the file locally then ran a script using the su command to run the pkg as the user. This was all being done silently/in the background using a checkin as a trigger (vs. initiation from Self Service). I noticed differences in launching via Self Service and launching via recurring checkin when using sudo vs. su -c, just a heads up. That was mostly related to running the pkg installation, though.
Snippet:
current_user=$( ls -la /dev/console | cut -d " " -f 4 )
su -l $current_user -c "/usr/sbin/installer -verboseR -dumplog -pkg /path/to/packag/installer.pgk -target CurrentUserHomeDirectory"
I don't think your use case would warrant copying a separate script down, just run the commands requiring user privileges with su. Sudo -u $current_user can also work as a prefix to the command you're trying to run but like I said, I saw odd behaviors with that so just something to keep in mind. Hope this helps.
Posted on 12-27-2018 06:11 AM
**@mm2270 "There isn't an easy way to run the entire script as the user, unless you deployed it as a local script and called it via a LaunchAgent"
Could you please elaborate on that or maybe some step-by-step guide? I have a script that has to be run completely by the user and your way seems to be the only one.
Thanks