LoginHook Bonjour

Want users to be able to use Bonjour at home without having their systems registering with Bonjour when they’re on your network? Many environments have taken to wholesale disabling Bonjour. This can be done by augmenting the LaunchDaemon that invokes Bonjour, com.apple.mDNSResponder.plist that is located at /System/Library/LaunchDaemons. You add a -NoMulticastAdvertisements to the ProgramArguments array. This can be done with the defaults command as so:
defaults write /System/Library/LaunchDaemons/com.apple.mDNSResponder ProgramArguments -array-add “-NoMulticastAdvertisements”
This can then be undone by writing the contents you want back into the array without the -NoMulticastAdvertisements:
defaults write /System/Library/LaunchDaemons/com.apple.mDNSResponder ProgramArguments -array /usr/sbin/mDNSResponder -launchd
This is somewhat well documented, initially appearing as an Apple kbase article. However, we should keep in mind that computers, especially laptops, have a tendency to go home with people. Therefore, you may very well want to fire Bonjour back up in the event that your users are not in your environment. Prior to Mac OS X 10.6 (aka 10.5 and below) you could edit the /System/Library/SystemConfiguration/Kicker.bundle/Contents/Resources/Kicker.xml file to add a shell script and upon network change it would fire off an event to run some script that you craft. In this case, the script you might run would be a simple look for some variable you decide to key off of and run one of the two above commands based on an if/then keyed off against whether the name mybigserver.mydomain.com has a valid hostname (we’re assuming it does in your network and it does not when not in your network):
if [ $(host mybigserver.mydomain.com | grep -ic “not found:”) > 0 ]; then defaults write /System/Library/LaunchDaemons/com.apple.mDNSResponder ProgramArguments -array /usr/sbin/mDNSResponder -launchd else defaults write /System/Library/LaunchDaemons/com.apple.mDNSResponder ProgramArguments -array-add “-NoMulticastAdvertisements” fi
You can also use this as a login hook or the if/then swapped out with one another as a logout hook; customize to your hearts content. You could even run it at boot time or on a scheduled interval, instead of as a login hook. Now, the simple fact is that since this is easy, it’s tempting. But luckily some really smart guys thought of a better way to do this kind of thing (not relying on a login or logout hook). They though that the old 10.5 Kicker was a much better solution and came up with the next best thing, crankd, which allows you to fire off a shell script (maybe one similar to the one here) when the network status changes. Thanks to all involved with this project.

Monitoring/Restarting Retrospect

As of version 8, Retrospect uses port 22024 when the Retrospect Console needs to communicate with the engine. It just so happens that this can become unresponsive when the engine itself decides to stop working. Therefore, if you’re using Retrospect 8, you can run a port scan against port 22024 ( i.e. stroke <IP_ADDRESS> 22024 22024 ) and then restart the engine if it goes unresponsive. To restart the engine, simply unload and then load com.retrospect.launchd.retroengine. For example: /bin/launchctl unload /Library/LaunchDaemons/com.retrospect.launchd.retroengine.plist; /bin/launchctl load /Library/LaunchDaemons/com.retrospect.launchd.retroengine.plist I have found that if you alter the nice value that the engine crashes less (not that I’m saying that it crashes a lot or is buggy btw, just seen it in a few cases now).  To do so, change the nice value in /Library/LaunchDaemons/com.retrospect.launchd.retroengine.plist from the default (0) to -10 (or -20 even). Historically, there have been intermittent issues with the client software running. To determine if it’s running or stopped from within the host that the client is running on you can use the following (for versions 6 and below): ps -cx | grep retroclient Or you can use the following for version 8: ps -cx | grep pitond Or you can port scan port 497 for the client: stroke <IP_ADDRESS> 497 497

Programatic Screen Sharing

You can remotely start ARD with kickstart, which I have previously covered at length. But Screen Sharing is a bit of a different little beast. To start up Screen Sharing, you can just use the following command:
echo -n enabled > /Library/Preferences/com.apple.ScreenSharing.launchd
I still prefer kickstart, but this method functions when you need something quick and easy. To then disable Screen Sharing, you can just toss the launchd item:
rm /Library/Preferences/com.apple.ScreenSharing.launchd
Once you have Screen Sharing started, you can then open the Screen Sharing application from a client by using the open command, followed by the protocol, which would be vnc and then the IP address. As with FTP you can also inject the user name and password into the open, following the //, by placing the user name followed by a colon (:) followed by the password and then the @ symbol (all before the IP address). For example, to connect to a computer with an IP address of using the username of krypted and the password of mypass you would use the following command.
open vnc://krypted:mypass@
You may encounter an encryption error, which if you are attempting to script can be annoying to click on. To suppress it, use defaults to set the dontWarnOnVNCEncryption key of the com.apple.ScreenSharing.plist to True:
defaults write com.apple.ScreenSharing dontWarnOnVNCEncryption -bool TRUE
Have fun!

Finishing RADIUS Kbase Article for AAPL

Troubleshooting radius is a crappy task. But crappy articles don’t help: http://support.apple.com/kb/HT3929 To be more specific, the debug mode flag is -X (not sure why that was so hard). In that case it’s doing single server mode and the process cannot fork. You can also do the lowercase, -x (which is part of -X), or -xx for further granularity. In order to set the launchd item to debug mode you would therefore find the /System/Library/LaunchDaemons/org.freeradius.radiusd.plist file (only created once you’ve fired up RADIUS btw). From here, locate the array for invoking the command:
<string>/usr/sbin/radiusd</string> <string>-sf</string>
Change the -sf to either a -X or add an x or two in there as needed. I’ve also had to enable core dumps for troubleshooting RADIUS as well, which means editing the /etc/raddb/radiusd.conf file, looking for allow_core_dumps and changing it to an = yes instead of an = no. Anyway, just finishing their article for them as my own little core dump to you.

Self Destructing Scripts

I have mentioned creating a self destructing script or launchd item a few times in articles on this site. But it was recently pointed out that I never actually showed how to go about doing so. Until recently I would actually use an out-of-band script to remove a script, a launchd agent or a launchd daemon. However, this would invariably leave elements somewhere on a file system of the script. For example, within a script I would echo out another script, fire off that script and then use it to delete (rm) the original script. When I planned out a deployment or a series of scripts I would always have one deploy the next, which would remove the first (I like being granular with my scripts rather than monolithic;).  On top of leaving trace elements this was terribly inefficient. Then I discovered that I could just put a line at the end of a script and it would erase itself when it was done running. So if I have a bind script with a password in the script and I want it to be removed when it is complete, I can just put the following line at the very end:
srm “$0”
The same logic can be applied to launchd items.  Let’s say I kick off a script called myscript using a launchd item called com.krypted.myscript with the following contents:
<?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>com.krypted.myscript</string> <key>ProgramArguments</key> <array> <string>sudo</string> <string>./Scripts/selfdestruct.sh</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist>
Now at the end of this script (assuming a payload above these lines with a bunch of stuff you actually want to accomplish) you can use the following commands to stop the LaunchAgent and finally delete the script itself (the first line is not always required):
launchctl stop com.krypted.myscript launchctl unload /Library/LaunchAgents/com.krypted.myscript.plist launchctl remove com.krypted.myscript srm “$0”
Now when I have a series of scripts that kicks off, I can either have each remove itself or have a cleanup script that removes all of my installation items and then, like a cartoon pencil, erases itself.

Mac OS X: Enable and Disable Spotlight

To Disable Spotlight for Mac OS X you can stop the Spotlight processes from being invoked by launchd.  To do so use the following commands: launchctl unload -w /System/Library/LaunchAgents/com.apple.Spotlight.plist launchctl unload -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist To re-enable it you would simply load up your launchd processes again like so: launchctl load -w /System/Library/LaunchAgents/com.apple.Spotlight.plist launchctl load -w /System/Library/LaunchDaemons/com.apple.metadata.mds.plist

Mac OS X: SystemStarter

Ever wonder why those things you put into /System/Library/StartupItems and /Library/StartupItems start automatically?  SystemStarter. System starter automatically starts up items stored in /Library/StartupItems and /System/Library/StartupItems.  As Mac OS X continues to transition much of the previous functionality of other facilities such as the cron daemon into launchd, development has also reduced the reliance on SystemStarter since Mac OS X 10.3.  However, many third-party applications do still use StartupItems, Apple development prefers the launchd facility and will continue to rely more heavily on it in 10.6 and beyond.


Mac OS X: launch daemons vs launch agents

There are two types of services that launchd manages:

launch daemons can run without a user logged in. Launch daemons cannot display information using the GUI. Launch daemon configuration plist files are stored in the /System/Library/LaunchDaemons folder (for those provided by Apple et al) and /Library/LaunchDaemons (for the rest).  Launch agents run on behalf of a user and therefore need the user to be logged in to run.  Launch agents can display information through the window server. As with launch daemons, launch agent configuration plist files are stored in the /System/Library/LaunchAgents and /Library/LaunchAgents. User launch agents are installed in the ~/Library/LaunchAgents folder.