MacOS – How to get the LaunchAgent to run as root

launchdmacosroot

I want to run a process as root at user login.

I created /System/Library/LaunchAgents/eXist.plist with rx—r—r— permissions:

<?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">
    <dict>
        <key>Disabled</key>
        <false/>
        <key>GroupName</key>
        <string>wheel</string>
        <key>Label</key>
        <string>eXist DB</string>
        <key>Program</key>
        <string>/Applications/eXist-db/bin/startup.sh</string>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/tmp/eXist DB.err</string>
        <key>StandardOutPath</key>
        <string>/tmp/eXist DB.out</string>
        <key>UserName</key>
        <string>root</string>
    </dict>
</plist>

However, my process continues to run as my user davea instead of root. Any ideas what else I need to do?

I’m using Mac 10.9.1.

Best Answer

To get a user LaunchAgent executing a script to run as root you have to do the following:

Modify the permissions of the script. Add the script (or command) to the sudoers file in the context of the user and finally add and load a proper launch agent plist.

This approach might create severe security holes!


In the example below I use the startup.sh of eXit-db 2.2:

  • Create a plist:

    <?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">
    <dict>
        <key>Disabled</key>
        <false/>
        <key>Label</key>
        <string>org.eXist_DB</string>
        <key>ProgramArguments</key>
        <array>
            <string>/usr/bin/sudo</string>
            <string>/Applications/eXist-db.app/Contents/Resources/eXist-db/bin/startup.sh</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>StandardErrorPath</key>
        <string>/tmp/eXist_DB.err</string>
        <key>StandardOutPath</key>
        <string>/tmp/eXist_DB.out</string>
        <key>ThrottleInterval</key>
        <integer>10</integer>
    </dict>
    </plist>
    

    and save it as org.eXist_DB.plist in ~/Library/LaunchAgents

    The last key:

        <key>ThrottleInterval</key>
        <integer>10</integer>
    

    might not be necessary. In my VM it was - for unknown reasons.

  • Modify the permissions of startup.sh:

    sudo chown root /Applications/eXist-db.app/Contents/Resources/eXist-db/bin/startup.sh
    sudo chmod 4755 /Applications/eXist-db.app/Contents/Resources/eXist-db/bin/startup.sh
    
  • Modify the sudoers file:

    sudo visudo
    
  • add a line to enable executing a command without the need to enter the sudo password

    # User privilege specification
    root    ALL=(ALL) ALL
    %admin  ALL=(ALL) ALL
    

    ->

    # User privilege specification
    root    ALL=(ALL) ALL
    %admin  ALL=(ALL) ALL
    your_user_name ALL=(ALL) NOPASSWD: /Applications/eXist-db.app/Contents/Resources/eXist-db/bin/startup.sh
    
  • Finally enter:

    launchctl load -w ~/Library/LaunchAgents/org.eXist_DB.plist
    

    to load and start the launch agent