0

I'm trying to block some websites via /etc/hosts
I can't seem to figure out how to run the LaunchAgent with the correct permissions.

$ ls -la ~/Library/LaunchAgents/hosts_Blocksites_AM.plist     
-rw-r--r--@ 1 root  staff  1854 Aug 25 11:55 /Users/bryanwheelock/Library/LaunchAgents/hosts_Blocksites_AM.plist    

I set a UserName key:

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

Here is the hosts_Blocksites_AM.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>Label</key>  
    <string>local.job</string>  
    <key>ProgramArguments</key>  
    <array>  
        <string>cp</string>  
        <string>/etc/hosts_BLOCKED_sites.txt</string>  
        <string>/etc/hosts</string>  
    </array>  
    <key>RunAtLoad</key>  
    <true/>  
    <key>UserName</key>  
    <string>root</string>  
    <key>StartCalendarInterval</key>  
    <array>  
        <dict>  
            <key>Hour</key>  
            <integer>8</integer>  
            <key>Minute</key>  
            <integer>15</integer>  
            <key>Weekday</key>  
            <integer>1</integer>  
        </dict>  
        <dict>  
            <key>Hour</key>  
            <integer>8</integer>  
            <key>Minute</key>  
            <integer>15</integer>  
            <key>Weekday</key>  
            <integer>2</integer>  
        </dict>  
        <dict>  
            <key>Hour</key>  
            <integer>8</integer>  
            <key>Minute</key>  
            <integer>15</integer>  
            <key>Weekday</key>  
            <integer>3</integer>  
        </dict>  
        <dict>  
            <key>Hour</key>  
            <integer>8</integer>  
            <key>Minute</key>  
            <integer>15</integer>  
            <key>Weekday</key>  
            <integer>4</integer>  
        </dict>  
        <dict>  
            <key>Hour</key>  
            <integer>8</integer>  
            <key>Minute</key>  
            <integer>15</integer>  
            <key>Weekday</key>  
            <integer>5</integer>  
        </dict>  
    </array>  
    <key>StandardErrorPath</key>                                                                                                                                                          
    <string>/tmp/mycommand.err</string>                                                                                                                                       
    <key>StandardOutPath</key>                                                                                                                                                                <string>/tmp/mycommand.out</string>  
</dict>  
</plist>  

Here are the errors:

$ cat /tmp/mycommand.err   
sudo: no tty present and no askpass program specified  
cp: /etc/hosts: Permission denied  

I had tried to add the sudo command to the program arguments, but I don't think that was correct.

EDITED:

Changed Label key:

<key>Label</key>  
<string>local.hosts.blockingAM</string>  

Removed UserName key.

Moved the plist and changed name:

$ ls -la /Library/LaunchDaemons/
-rw-r--r--@  1 root  wheel  1474 Aug 29 13:19 local.hosts.blockingAM.plist  

I was still getting permission errors until I ran launchctl with sudo:

sudo launchctl load /Library/LaunchDaemons/local.hosts.blocking.plist 
1
  • 1
    Start by changing the label to the name of the plist- hosts_Blocksites_AM
    – fd0
    Commented Aug 26, 2016 at 15:56

2 Answers 2

4

Launch agents are run when a user logs in. So adding a plist in ~/Library/LaunchAgents and loading/starting it, will run a task in behalf of the user logged in - and only this one, because no other user has access to this folder. You can't run a launch agent with the rights of another user and the key UserName is no valid option in there.

A launch agent in /Library/LaunchAgents will also run in the realm of the logged in user. But every user logging in will initiate it. So two users logged in at the same time will each start an arbitrary agent task with the respective rights/permissions.

The system's LaunchAgents and LaunchDaemons folders are forbidden area, so you are left creating a launch daemon in /Library/LaunchDaemons.

Since launch daemons already run with root permissions use the following plist local.hosts.blocking.plist in /Library/LaunchDaemons/ (naming conventions regarding label/error file and standard output file already included):

<?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>Label</key>  
    <string>local.hosts.blocking</string>  
    <key>ProgramArguments</key>  
    <array>  
        <string>cp</string>  
        <string>/etc/hosts_BLOCKED_sites.txt</string>  
        <string>/etc/hosts</string>  
    </array>  
    <key>StartCalendarInterval</key>  
    <array>  
        <dict>  
        ....
        </dict>  
    </array>  
    <key>StandardErrorPath</key>                                                                                                                                                          
    <string>/tmp/local.hosts.blocking.err</string>
    <key>StandardOutPath</key> 
    <string>/tmp/local.hosts.blocking.out</string>  
</dict>  
</plist>

Apply standard permissions to the plist: root:wheel/644 and load/start it with:

sudo launchctl load /Library/LaunchDaemons/local.hosts.blocking.plist
6
  • Thanks for the response. I made the changes suggested and still get a permission error. I posted the changes in OP. Commented Aug 29, 2016 at 19:58
  • I copied your plist exactly and I got the exact same permission error: Commented Aug 29, 2016 at 20:46
  • $ ls /Library/LaunchDaemons/local.hosts.blocking.plist -rw-r--r-- 1 root wheel 1002 Aug 29 16:43 /Library/LaunchDaemons/local.hosts.blocking.plist Commented Aug 29, 2016 at 20:46
  • launchctl load /Library/LaunchDaemons/local.hosts.blocking.plist Commented Aug 29, 2016 at 21:02
  • @BryanWheelock After unloading it first, please use sudo launchctl ...
    – klanomath
    Commented Aug 29, 2016 at 21:05
1

The asker mentions LaunchAgents a couple of times and @klanomath's answer is correct: in this case a LaunchDaemon is probably the appropriate approach.

However for Googlers that are trying to give a LaunchAgent elevated sudo/root privileges, I recommend checking out or this answer on this question about LaunchAgents.

It describes a method of having selectively elevated privileges for the user and command you're running, allowing launchctl to run sudo without an interactive password prompt.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .