• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: How to execute script as root, and then an another script on behalf of an ordinary user
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to execute script as root, and then an another script on behalf of an ordinary user


  • Subject: Re: How to execute script as root, and then an another script on behalf of an ordinary user
  • From: Xochitl Lunde <email@hidden>
  • Date: Wed, 5 Jan 2011 14:20:30 -0600



> > Yes, there are lots. As a simple example: why are you assuming that there is
> > only one person logged in, or that there is even one person loggedin to the
> > computer. Both cases are valid.
>
> I guess i will have to ps -x | grep loginwindow and execute "launchctl
> bsexec" for every instance of loginwindow? if there's no users logged
> in, the loop will never be executed. Otherwise, it'll execute for
> every user who's logged in (well, just like in that example on that
> link).
>
> > We don't know exactly what you are trying to do, backing out a step or two
> > might be a really good idea. There are a lot of people on this list that can
> > probably better help you out if you give them the information they need to
> > help you.
>
> It's an NKE Kext , which is autoloaded by a "starter"-daemon and whose
> status is displayed by an agent in a status bar. After installing, i
> want these daemon and agent to be launched immediately, without
> reboot.

FYI: Everything I'm going to say is only based on my experience working with my program's installation, NOT anything definitive on how launchctl *ought to* behave.   My program starts a daemon and a GUI-user-only launch agent that displays any bad news from the daemon (i.e. "computer shutting down in 60 seconds, do you want to log out?").

An example of when there could be 0 users logged in is when you are installing with ARD.

When working with launchctl from a script in a package, it's important to know who you are.  The package can be installed through ARD, command line, or GUI and each scenario affects who you are when the script runs.  You only get a $SUDO_USER environment variable in the IntallationCheck script (maybe VolumeCheck), you won't get it in preflight/postflight/etc.

If you are installing a daemon, you will require authentication on your package.  This should make the $USER in your scripts root.  Good for starting / stopping a daemon, not good for starting an agent.  I ended up guessing who was installing the package based on the contents of $HOME and the output of 'who'.

# this is some of my unload code from preinstall/preupgrade, but the load code is about the same - i had to retype it so it might not be perfectly typed.
# In the postinstall, I check if the plist file got installed before even trying to load the daemons and agents.

if [ ! $USER = "root" ] ; then
        su $USER -c 'launchctl unload -w /Library/LaunchAgents/com.tripplite.myproject.myagent.plist ||: #don't hang
else
home_user="";
for user in `who | grep console | awk {'print $1'}`
do
        user_in_home="`echo "${HOME}" | grep $user`"
        if [ -n "${user_in_home}" ] ; then
                home_user=$user
        fi
done

if [ -n "${home_user}" ] ; then
        echo "Stopping MyAgent for $home_user."
        su $home_user -c 'launchctl unload -w /Library/LaunchAgents/com.tripplite.myproject.myagent.plist ||: #don't hang
fi
fi

By my experience, launchctl isn't going to let you switch user and load something for any user other than $USER or the user who started the package.  It always errored out for me if I tried to launch an agent for a user that was fast user switched or any user that hadn't run the package.  Granted, it's been since 10.6.3 since I've tried it.

I get around this by not installing the package if too many GUI users are logged in, which might or might not be appropriate for you.  Depends on how important it is for your agent to be running.  It's not perfect, but it does increase the likelihood that I will not have some GUI users with agents running and some who did not get to launch the agent.  There's a race condition because I can't prevent anyone from logging in from the time that I do the check to the time that I start the agent.

# I do this in InstallationCheck so that I can present an error message from InstallationCheck.strings

for name in `who | grep console | awk {'print $1'}`
do
if [ ! $name = $USER ] ; then
if [ ! $name = $SUDO_USER ] ; then
exit 112 ; # Return String 16
fi
fi
done

What I can say about the correctness of this solution is that:
1.  It works.  It has been working fine for ARD, command line, and GUI installs, tested on 10.5.8 & 10.6.3
2.  Nobody ever told me it was an unacceptable solution when I was discussing it on the list back around March.

Hope this helps or was interesting.
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Installer-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >Re: How to execute script as root, and then an another script on behalf of an ordinary user (From: eveningnick eveningnick <email@hidden>)

  • Prev by Date: Re: How to execute script as root, and then an another script on behalf of an ordinary user
  • Next by Date: Re: How to execute script as root, and then an another script on behalf of an ordinary user
  • Previous by thread: Re: How to execute script as root, and then an another script on behalf of an ordinary user
  • Next by thread: Re: How to execute script as root, and then an another script on behalf of an ordinary user
  • Index(es):
    • Date
    • Thread