How do I get my LaunchAgent to run as root?

Solution 1:

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

Solution 2:

Add the key value pair for UserName:

<key>UserName</key>
<string>root</string>

Place the launchd job ticket in /Library/LaunchDaemons/; the /System folder is reserved exclusively for Apple's use.

To run as the specified user, be sure to place the job ticket in LaunchDaemons. As @Manu mentions in the comment below, the UserName key is ignored for jobs in LaunchAgents.