Lion’s grey sidebar is a Jedi mind trick

These aren't the files you're looking for...

And a poor attempt at a Jedi mind trick at that. With the now grey and lifeless sidbar in Lion Apple is trying to visually say: “these aren’t the files or folders you’re looking for”. It’s as if they want us to become so turned-off to this grey apocalyptic version of the sidebar that we yearn for iCloud where our data lives in the apps and those pesky file and folder structures cease to have any relevance in our workflow.

Reality check Apple, you won’t change our habits overnight, nor overturn what is a completely valid way of working with your computers.  You will not endear us to the iCloud experience by also crippling the Finder’s look and feel. Although I do thank you for returning the ability to have large icons in the sidebar, which you took away in 10.5, the grey-ification of the icons and the exile of Devices to the bottom of the list has truly hobbled any usefulness the Finder had. Oh, add the fact that mounted volumes no longer show as a Device, but rather you have to add them manually to favorites has also irked me. Why should I have to open up Shared, click the server then find the volume I want. It’s ridiculous when you couple that with having the default Finder behavior to not show mounted volumes on the desktop. Fine you hate files, folders and drives, we get it, but not all of us agree… “the rest of us”, as it were.

Here’s a compromise I could live with Apple:

At least give us a choice Apple!

Thankfully, a very bright Mac developer has made a plugin to return color to the Finder sidebar. Now I normally do not like using SIMBL plugins because code injection and method swizzling makes me nervous. But having color on the sidebar is worth it. You can find all the info for doing this at OS X Daily along with installation tips.

Colorful Sidebar by CVZ

So, file those Bug Reports with Apple and let them know their Jedi mind trick isn’t going to work. These are the files and folders we’re looking for and color would greatly help us find them. (I’d consider this a regression fix rather than a feature request.)

Postscript on (not) using Finder:
A quick note for the purists out there who don’t even run Finder. You intrepid folks take a road less travelled but not one that not everyone wants to embark down. Now, Rick of Rixstep will argue that Finder is an and abhorrent holdover from OS 9 that should have gotten the axe or at the least been completely recoded into 100% Cocoa, all of its Carbon cruft put out to pasture, its very existence is retarding OS X, and to run Finder on your system is akin to self-trepanation. OK — fair enough actually on most points! :D However, until someone else comes along with a Finder replacement that is 100% Cocoa and has full feature parity, then we put up with the Finder. (And most businesses would be loathe to spend money on licenses for Finder replacements like XFile or PathFinder, it’s hard enough to get them to spend the extra dough up-front for a Mac!) Wah wah :/ So we commiserate with others on the discussion boards and plead our case to the Designers Gone Wild at Apple.

Make Safari find substring matches by default

So, I thought I’d tip ol’ Pierre at betalogue to an apparent bug that Safari doesn’t find substrings, only words that begin with the search string! But then his astute readers pointed out that Safari 5.1 has changed the behaviour of the Find window, if you just look close enough *blush*

Now by default in Safari 5.1, when you hit Command-F and type in a word, Safari will match words that “Start with” your search item, clicking the magnifying glass, presents you with the option to search for words that “Contain” your search phrase (this was the default search behaviour in Safari pre-5.1), and in fact clicking the magnifying glass used to step through matches. Who knew!? I’m a (Shift)/Command-G man myself.

Now how could we change this behaviour back for a few hundred users who are used to the way Safari has been functioning before Apple so elegantly altered it? Here we go!

Preference domain: com.apple.Safari
Key Name: FindOnPageMatchesWordStartsOnly
Values: Boolean, TRUE equals “Start With” and FALSE equals “Contains”.

It is a per-user preference, if the key is not present Safari defaults to “Start With” in a search. Writing the pref to the higher level /Library/Preferences/com.apple.Safari.plist will affect all users who don’t already have the key set, otherwise Safari will defer to the user’s prefs (and it can then be assumed the user is aware of the change since they clicked on the magnifying glass and altered the setting).

Here’s the defaults commands for Terminal to set Safari’s Find back to “Contains”:
All Users (who don’t have it set in their prefs)
defaults write /Library/Preferences/com.apple.Safari FindOnPageMatchesWordStartsOnly -bool FALSE
Current User
defaults write com.apple.Safari FindOnPageMatchesWordStartsOnly -bool FALSE

There you go that’ll get things back the way they were, make sure it’s all on one line, the theme seems to like to wrap code, but a copy/paste does not include the newline.

Restore previous Safari version from .SafariArchive.tar.gz

Did that new Safari update break something? Want your old version back?
Simple. Thanks to Apple’s prescient yet secretive engineers, there’s a way.
Let me show you.

When Safari does an upgrade it saves the previous version in this location:
/Library/Application\ Support/Apple/.SafariArchive.tar.gz

To restore we just need to tell tar to expand the archive to the root folder:
sudo tar -xvf /Library/Application\ Support/Apple/.SafariArchive.tar.gz -C /

To be complete, delete the receipt from /var/db/receipts, in this case it is Safari 5.1
sudo rm -rf /private/var/db/receipts/com.apple.pkg.Safari51SnowLeopard.*

Reboot. (since we’ve just replaced a whole bunch of public and private frameworks the OS uses)

Done.
(Whew. This will fix the early Safari 5.1 adopters at work who now can’t use our Java based timesheet app since upgrading!)

myXProtectStatus

myXProtectStatus – A drop down status menulet for XProtect, showing date, version, and threats protected against. Written in bash, and wrapped with Platypus, it is informational only, so don’t ask me to add some menu item to do something, it just reports. However I did add the Command Line and GUI ways to update XProtect in the output, so it’s of some use for that. When run, it’ll reside in your menu bar and call a script inside itself each time it runs. Tuck it away somewhere, add it to your loginitems. Check it every once and a while…

Screenshot of myXProtectStatus:

Other notes: I pipe the output of the threat list though /usr/bin/uniq, because while Hell.RTS has three different signatures it retains the same name in each and it seemed redundant to list all of them out! So all recurring names will be reduced to one entry.

The menu bar icon: it’s an X with a grey picket fence around it, I made it tiny… then realized I need an icon for the App too rather than Platypus’ so I sized it up, it’s fugly, but you’ll never see it! :)

Bonus: When run as root, it will show the auto-update on/off status, which can only be determined on the command line by root.

 

WWDC 2011

Going to WWDC 2011! See you all there! (although, I got a haircut so it’s all short now and not the curls you see on the site :)) and whatever is not NDA I’ll tweet via brunerd

Advanced Safe Downloads List Tips and Tricks

So I submitted a hint for getting info about the Safe Downloads protection list, then I made a widget, now delving deeper into Safe Downloads list and the command line

Let’s look at the BOM for the update:

/Library/Preferences/com.apple.ReportMessages.domains
/Library/Preferences/com.apple.ReportMessages.v2.domains
/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.plist
/System/Library/CoreServices/MRTAgent.app
/System/Library/LaunchAgents/com.apple.mrt.uiagent.plist
/System/Library/LaunchDaemons/com.apple.mrt.plist
/System/Library/LaunchDaemons/com.apple.xprotectupdater.plist
/System/Library/PreferencePanes/Security.prefPane
/usr/libexec/MRT
/usr/libexec/XProtectUpdater

What’s interesting is after installation /usr/libexec/MRT, com.apple.mrt.plist, and com.apple.mrt.uiagent.plist delete themselves after they run?! This is odd, yes? From what it looks like MRT has a lot of pattern matching  code in it… Also notable is that in the postflight action loadMRT, the launchagent and daemon are unloaded and reloaded in the postflight actions, however the loadXProtectUpdater script does not do this. So the XProtectUpdater does not run again if you rerun the installer since launchctl will report it’s already loaded, so you’ll have to wait a day for it to check again and update as seen in com.apple.xprotectupdater.plist (86400 seconds = 1 day).

If you want to manually force an update, you can run this command:
sudo /usr/libexec/XprotectUpdater
You must run as root or else it informs you:
XprotectUpdater[pids] Unable to write new signature meta plist

You can also just toggle the preference in the Security prefpane, this causes the launchd job to be unloaded an reloaded, however from an admin POV it’s nice to have a non-GUI way to do this. Also there seems to be a bug in the prefpane so values are not written after it is open for more than 30 seconds! Come on 10.6.8! (It feels like this was Lion stuff that’s getting shoe-horned into Snow Leopard a bit earlier than they expected )

Another interesting tidbit is the actual malware list that is squirreled away here:
/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.plist

If you attempt to use the defaults command to read it you are given this:
defaults[pids] Preference plist was NOT a dictionary.
defaults[pids] Domain /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect does not exist

It seems the Apple folks have done some creative things so while this is still valid XML it is not a defaults compatible plist. The values are dictionaries stored in an array at the top level. Is this protection against script-kiddies who’d use defaults to change values in the list? While the file is root owned, one must wonder if there are safeguards to check its checksum against a server to detect unauthorized changes to it? Since admin status is enough to escalate to root using sudo (and every initial user in OS X is an admin), combine this with the fact that installer runs as root when installing a pkg, and this is something to keep an eye on… (oh right my point being this thwarts a script to list detected threats, at least easily using defaults)

And some parting advice: Turn off Open Safe Downloads in Safari! It’s an oddly bad decision by Apple, its paralells to Windows’ AutoPlay/AutoRun give me goose bumps! I don’t want a dmg opening itself up and copying out it’s pkg payload into Downloads, then auto launching it! CRAZY BAD! Malware on a platinum platter, Apple couldn’t have made it easier!

Here’s the code for turning this off in Safari, it is a per user preference:
defaults write com.apple.Safari AutoOpenSafeDownloads -bool FALSE

And so concludes this expedition, hope you learned something, and can teach me something back in the process, thanks!

Safe Downloads List Info Widget

UPDATE: The AUTOUPDATE code only works as root and so is not useful in the Dashboard environment! This has been removed from the widget.

So I slapped together a widget for the Safe Downloads commands I post at OSXHints:

Safe Downloads Info Widget

Nothing glamorous just the facts and the following code is how it gets it’s values:

defaults read /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta LastModification
defaults read /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta Version

The auto updates status took a bit more massaging:

eval $(sudo defaults read /private/var/db/launchd.db/com.apple.launchd/overrides com.apple.xprotectupdater | sed 's/ //g')
if [ ${Disabled:=0} -eq 0 ]; then
echo ON
else
echo OFF
fi

All apologies to Dashboard coding perfectionists but the calls for the widget are synchronous, and reading up on Dashboard coding best practices, Apple says a shipping widget should only use asynchronous calls for info… oh well it works well enough for me! :) Perhaps I’ll go back and throw in extra lines of code for asynchronous handlers when I can, if my widget freezes up any other widgets you can simply restart Dashboard by killing to Dock process from Activity Monitor.

Related:
myXprotect Status – a drop down list of threats protected against for the menu bar

Finder’s Nasty Inherited ACL Bug (aka Error -41)

Finder’s Inherited ACL handling is broken

Support for inherited ACLs on folders is still in disarray in 10.6.7 (and has been since 10.6.5), there have been a few reports here and there, some mentioning Error -41, other saying it was AFP, but I’ve whittled it down and it’s a Finder flaw handling inherited ACLs that was introduced in 10.6.3!

Hands On Demo

Let’s create a folder in your home directory using Terminal to make a nice little nested folder set to play with :
mkdir -p ~/ACLShackles/1/2/3/4/5/6/7/8/9/10/11

Now let’s add an entry to the folder’s ACL, in this case  inherited folder and file Read & Write permissions, a common setup for workgroups that share a folder. OS X’s Server Admin sets inheritance by default when adding a user to an ACL, to do this with OS X Client you must use chmod:

chmod +a "$(whoami) allow list,add_file,search,add_subdirectory,delete_child,readattr,writeattr,readextattr,writeextattr,readsecurity,file_inherit,directory_inherit" ~/ACLShackles/

Make sure the above is all on one line and paste into Terminal.
Now, that the permissions are set double check with: ls -led ~/ACLShackles

Now duplicate folder structure we made called “1” with Command-D, now try and duplicate “1 copy”  — it fails. Finder Error -41.

Looking at the ACL in Terminal isn’t pretty:
ls -leR /Users/brunerj/ACLShackles/1\ copy\ 2

It goes on to 108…

If you don’t like Terminal, I’ve got an Applescript for you: Error41.zip

Just download and, open the resulting Error41.dmg, open and run Error41.scpt to get this result:

Step-by-step illustrated Demo

Let’s try another example and illustrate.

Now, let’s copy in Chess.app, take a look at the permissions with the Inspector (Command-Option-I), notice the Permissions (for this example I added a different user in the ACL to avoid confusion between the Unix permission and the ACL when looking at Finder’s Get Info, it’s the same silhouette):

Looks good, and how it should. Now duplicate Chess.app within this folder with a Command-D:

Uh-oh. Something’s not right. It’s duplicated the original ACE (Access Control Entry) and added one for me the duplicator that seems to mimic my Unix permissions.

Copy the copy.

Much worse. It’s now duplicating my erroneous ACE and the ACE of the test user as well.

Copy the copy.

Oh dear. Fail. Error -41. Checkmate.

Let’s look at that third failed and truncated copy in Finder

Care to see how long an ACL is inside the app?

Yes. 110 ACEs are on “Chess copy 3.app/Contents”!

Comparing other file manager’s behavior

cp doesn’t suffer the same fate as Finder when making copies of copies.

This simulates Finder’s copy of a copy, delete any existing duplicate folders and try this:

cp -Rp 1 1\ copy; cp -Rp 1\ copy 1\ copy\ 2; cp -Rp 1\ copy\ 2 1\ copy\ 3; cp -Rp 1\ copy\ 3 1\ copy\ 4

Take a look inside with ls -leR ~/ACLShackles, nice and clean, one ACE per ACL on each folder the way it should be.

Rixstep’s XFile – doesn’t exhibit this behavior when copying or duplicating either, Rixstep software is quite conscientious about doing the Right Thing™

Path Finder however duplicates ACLs just like Finder, but instead of Error -41 when an ACL gets too long and deep it just hangs instead. What’s interesting is what calls is PathFinder using? They have an SDK but have only taken a cursory look, regardless it’s the same result as Finder.

In conclusion…

For OS X Server environments, this affects crucial workflow behavior where multiple people act upon the same files and folders. ACLs quickly stack up and render Finder unusable. Currently the last known proper behavior for Finder was 10.6.2. Then 10.6.3 and 10.6.4, added the quirk of  adding an ACL entry that mimicked the UNIX permissions of the user doing the copy operation, but at least the ACEs weren’t duplicated ad nauseum. But taking the insanity to new heights was 10.6.5, 10.6.6, and now 10.6.7 with the duplication bug that makes working with inherited permissions unbearable. Luckily for OS X Client, this is minimized since Finder does not enable Inheritance for files or folders, but then you lose out on what inherited ACLs could do for you and your workgroup!

Since 10.6.7 is out now, 10.6.8 might be your last chance to have Snow Leopard’s Finder ACL behavior put back in working order. Let Apple know this is important to you, file a bug report at Apple’s Bug Reporter site, you can reference my bug number: 9160099 (you can view it at OpenRadar )

P.S. If you are wondering why I didn’t file this earlier since I am so detailed in the earlier 10.6 behavior? I actually became aware of something wrong in 10.6.5 but I also wasn’t sure what the cause was, Client, Server, AFP, Active Direcroty? Our UIDs are 10 digits long! During that time I hoped the soon to be released 10.6.6 would fix it, but when it didn’t I spent a lot of time just trying to fix it and clean the ACLs, it wasn’t until last week during the final seed of 10.6.7 that I found time to set up a new server and incrementally test 10.6, 10.6.2, 10.6.3, 10.6.4, 10.6.5, 10.6.6, and 10.6.7, recording QT Screen captures for each one and that took some time! My bug report only got in this Sunday. Oh well better late than never! :/

Remedies

It’s easy to nuke all the ACLs in a given folder, but then you’ll probably want them set back up again to be of any use! Anyway this will recursively wipe the ACLs from everything in the folder you’re in, be careful, you could wipe your own access! So it’s best for the server admin to to run from the server itself, then re-propagate the ACLs for the Share (actually you may not be able to delete ACLs from client anyway):

chmod -RN *

Update (3/23/11):

So I left my ACLShackles folder in my home foder and Time Machine failed to backup (backupd error -41, surprise.) so to avoid that, delete ACLShackles and/or turn off Time Machine while you play around with this…

Update (Sep 2011):
Just posting my comment down at the bottom so you don’t have to scroll all the way down there to read it…

10.6.8 has addressed it for the most part. You’ll still get weirdness when duplicating folders with inherited folders inside a folder with inherited permissions, but it’s a linear rather than geometric and that’s bearable.

More App Store tips for admins

Continuing the tech ramble about how to keep the App Store from your users…

So, I figured out the two ways the App Store icon is added to the dock:

1. Existing users on an upgraded system are affected by this file: /Library/Preferences/com.apple.dockfixup

Looking at the add-app key inside contains the answer:

<key>add-app</key>
<array>
<dict>
<key>path</key>
<string>/Applications/App Store.app</string>
<key>after</key>
<string>begin</string>
</dict>
</array>

We can rid ourselves of  this behavior with defaults:

defaults delete /Library/Preferences/com.apple.dockfixup add-app

However, if you try to use a loginhook to remove the icon, it will not take effect unitl the second login, sine the loginhook runs before Apple’s dockfixup is applied.

The solution to a user never seeing it (and avoiding calls about it) is to use a daemon that runs at system startup and deletes the entry in the plist before it is ever used.

Save as /Library/LaunchDaemon/com.brunerd.dockfixer.plist (or whatever you wish):

<?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>com.sts.dockfixup</string>
<key>ProgramArguments</key>
<array>
<string>defaults</string>
<string>delete</string>
<string>/Library/Preferences/com.apple.dockfixup</string>
<string>add-app</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

You could call another script, check for add-app’s presence, but having this run everytime, insures that despite OS updates and reversions of files your user will never have App Store added to their Docks.

2. Suppressing App Store in new user accounts is affected by Dock.app’s default.plist:
/System/Library/CoreServices/Dock.app/Contents/Resources/English.lproj/default.plist

But just deleting this and not com.apple.fixup.plist will not do what you want since fixup will still run, you must delete both. Altering that is the perfect job for removeitemfromdock… if only it worked with a supplied path… now it does! So after installing and downloading you can run this command to alter the default dock:

sudo /sbin/removeitemfromdock -f /System/Library/CoreServices/Dock.app/Contents/Resources/English.lproj/default.plist /Applications/App\ Store.app/

You could make this another Daemon or just have the daemon call an external script, your choice, I can’t do all the work for you :)

App Store tips and tricks for sysadmins

App Store Tips, Tricks, and Hacks for the SysAdmin

App Store, oh, App Store, like all Apple products you are made first for consumers and in time maybe you will be ready for corporate deployment, but for now, here’s some tips for the Mac IT worker needs to wrangle this beast.

Firstly, the App Store, if you’ve noticed, requires admin rights to download and install apps. Not just because it installs to /Applications (it could be ~/Applications if it wanted to…) But most likely due to the new location of the receipts folder in /var/db/receipts. Up until version 10.6 it was /Library/Receipts and this would have made it possible to use the domain system that was the simple genius of OS X, where things can live in /System/Library, /Library, or ~/Library and when the system couldn’t find a pref or support file in one domain it would look in the next. Fonts are a great example of this in action, why didn’t they think it was a good idea for receipts is anyone’s guess. But since there is no way to make an analogous folder structure of /var/db/receipts in a user’s home folder, much less have the system recognize there are receipts there, the App store is not “Standard User” compatible.

Disabling Execution and hiding the App Store with Unix Permissions:

#hide it
sudo chflags hidden /Applications/App\ Store.app/

#keep it from executing for anyone other than root (since it is ownership is root:wheel)
sudo chmod o-x /Applications/App\ Store.app/Contents/MacOS/App\ Store

#to let admin users execute, next change group ownership of executable
sudo chgrp admin /Applications/App\ Store.app/Contents/MacOS/App\ Store

#OR keep anyone from executing it
sudo chmod ugo-x /Applications/App\ Store.app/Contents/MacOS/App\ Store

Keeping the icon from populating the Dock is more troublesome, since Apple has changed this from 10.5, previous versions, it was a matter of altering /System/Library/User\ Template/English.lproj/Library/Preferences/com.apple.dock.plist but this no longer exists. I am searching for where this information is pulled… but in the meantime you could use a utility like RemoveItemFromDock to run for a user when they log in (note: a new user will not have a com.apple.dock.plist file until their first login, this makes it tricky for login scripts on first login…) I had a good lead in /Library/Preferences/com.apple.dockfixup.plist but removing the add-app entry that contains the path to the App Store did not help… wah wah.

Well, so you hidden the App Store, restricted it running, but what can your sneaky users do?

They can buy an App Store app on their home computer and then simply copy it to their work laptop. The app will prompt them to authorize it with their AppleID, boom, done, no problem for a Standard User. However, they will not get updates on the computer, since there is no receipt of its installation, this would need to be done manually. User bringing in paid apps to a work computer creates a quandary for admins who run app inventory on computers (especially if it’s for license compliance)! From my attempts at pruning and tinkering with the Parental controls MCX values in the user’s records there didn’t  seem to be a way to wildcard the white or blacklist, however it is promising that there is a boolean key call appStore that shows up. But for now enabling “Limit Applications” setting involves explicit approval for EVERY app they want to run that’s not on the whitelist, and personally I don’t care if you want to run Primate Plunge to waste time during conference calls – you and I will probably be saner for it. :)

Bottomline MCX doesn’t seem to have a straightforward way to deal with this now that doesn’t involve more admin overhead using Parental Controls.

Perhaps though, you don’t care what your user intalls from the App Store but you care enough that they are still Standard Users, well here’s the hack and slash way to enable them to use the app store…

How to Allow Standard Users to Run the App Store*

*Disclaimer: !!!WARNING!!! Security settings are changed with this action!!!! HACK AT YOUR OWN RISK !!!!!

#Make the App store an SUID binary so it runs as root *

sudo chmod +s /Applications/App\ Store.app/Contents/MacOS/App\ Store

#Change rights in /etc/authorization to allow system.privilege.setugid_appkit right by anyone* **

sudo cp /etc/authorization /etc/authorization.saved
sudo cp /etc/authorization /etc/authorization.plist
sudo defaults write /etc/authorization rights -dict-add system.privilege.setugid_appkit '<dict><key>rule</key><string>allow</string></dict>'
sudo plutil -convert xml1 /etc/authorization.plist
sudo sudo chmod go+r /etc/authorization.plist
sudo mv /etc/authorization.plist /etc/authorization

There you go, your standard users can now install App Store apps.

*Disclaimer: !!!WARNING!!! Security settings are changed with this action!!!! HACK AT YOUR OWN RISK !!!!!

** When you Google this, you’ll find this is the same solution I found for using Flip4Mac with Compressor as a standard user. I just love reusable code ;)

I hope you learned something and even better I hope you might have some insight to add that I’ve missed, please send in your comments, thanks!

Putting it all back the way it was before we started messing around

sudo chmod u=rwx,go=rx /Applications/App\ Store.app/Contents/MacOS/App\ Store
sudo chown root:wheel  /Applications/App\ Store.app/Contents/MacOS/App\ Store
sudo chflags nohidden /Applications/App\ Store.app/
mv /etc/authorization.saved /etc/authorization

Update: My removeitemfromdock script seems to have been thrown by a loop by changes to the dock plist, just like I had to work around Dashboard when it was itroduced to the Dock in a new way. Update to come…

Update-2: removeitemfromdock now works like a charm, my Dashboard hack was taking for granted that Dashboard is not always at position 0 after the Finder, so when App Store snuck in behind, it was getting skipped, now there are some robust kludges to deal with Dashboard’s non standard dock entry