Author Archives: Michael Kuron

Fixing Microsoft Office 2011 SP2 Volume licensing

UPDATE 2012-11-15: The 14.2.5 installer no longer has this weird behavior (it does not include removables.txt files at all, however the postinstall script would still process them if they were there). Since it requires 14.2.3 as a prerequisite, you’ll still need to apply the fix mentioned below to 14.2.3 when chaining updates.

UPDATE 2012-11-30: I just obtained a copy of the 14.2.3 installer ISO from Microsoft VLSC. Copies of Office installed from it (or probably any 14.2.0+ installer ISO) do not exhibit the behavior explained here. The newer installer ships with flat-file Main.nib files that do not get removed by the removables.txt script.

UPDATE 2013-03-13: The 14.3.2 updater again contains a removables.txt which breaks Microsoft Office Setup Assistant.app. If you didn’t replace your installer ISO with a newer version, you will again need to apply the fix mentioned below when installing this update.

When you run Word, Excel, PowerPoint or Outlook 2011, it checks /Library/Preferences/com.microsoft.office.licensing.plist . If that file is not valid (such as after doing a fresh install of Microsoft Office 2011), it launches /Applications/Microsoft Office 2011/Office/Microsoft Office Setup Assistant.app. Microsoft Office Setup Assistant checks whether the DVD from which you installed is a volume licensed copy; if it is, it silently populates that plist and quits (allowing the app you initially started to start up); if it is not, it prompts you for a product key and activation.

If you install from the DVD, launch one of the Office apps to activate the license, quit it and then install all the available updates from Microsoft, everything is fine.

If you update to version 14.2.0, 14.2.1, 14.2.2, 14.2.3, 14.2.4 (or possibly future versions) right after installing from the DVD however, Microsoft Office Setup Assistant.app gets corrupted. This is due to ./Office 2011 14.2.X Update.mpkg/Contents/Packages/Office2011_all_core_14.2.X.combo.pkg/Contents/Resources/removables.txt, which gets run by ./Office 2011 14.2.X Update.mpkg/Contents/Packages/Office2011_all_core_14.2.X.combo.pkg/Contents/Resources/postflight. It deletes the contents of /Applications/Microsoft Office 2011/Office/Microsoft Office Setup Assistant.app/Contents/Resources/XX.lproj/Main.nib (which is a bundle-style NIB), however (unlike probably everything else listed in removables.txt) the update does not contain updated versions of them.

If you’re running an individually-licensed copy of Office 2011, that is no big deal: the Office apps themselves are able to prompt for a license key and activation.

If you’re running a volume licensed copy of Office 2011, you’re in trouble: You now get prompted for a product key by every Office app, which you obviously don’t have.

To fix this situation, you have two options:

1. Copying /Library/Preferences/com.microsoft.office.licensing.plist from a working install. You can do this using your favorite software depolyment tool, such as Munki. Please note that importing it as a Managed Preference (MCX) into Workgroup Manager (and probably Profile Manager) does not help. The file needs to be physically present on the client machine.

2. Move Microsoft Office Setup Assistant.app out of the way before updating. You can do this if your software deployment tool supports adding custom pre- and post-install scripts (Munki allows you to do that).

Here’s my pre-install script:

#!/bin/bash
cd "/Applications/Microsoft Office 2011/Office"
mv "Microsoft Office Setup Assistant.app" "SetupAssistantBackup.app"
exit 0

And my post-install script:

#!/bin/bash
cd "/Applications/Microsoft Office 2011/Office"
mv "SetupAssistantBackup.app" "Microsoft Office Setup Assistant.app"
exit 0

To find out whether you still need to do this on future updates (such as 14.2.5), open the installer package in a tool like Pacifist and check the following: a) Did they remove the  Microsoft Office Setup Assistant.app lines from removables.txt (go to the Resources tab and enter removables.txt into the search box to locate the file)? b) Does the update contain a new version of Microsoft Office Setup Assistant.app (go to the Package Contents tab and enter setup assistant into the search box to check for its existence)? If either one is true, Microsoft decided to fix the problem and you no longer need to use my pre-/post-install scripts.

Converting Xen Linux VMs to VMWare

A year ago I wrote about how to convert from Xen to VMWare (which is a similar process to a Xen virtual-to-physical or V2P conversion). Now I found a much simpler solution, thanks to http://www.zomo.co.uk/2012/04/moving-disks-from-xen-to-kvm/ .

In this example, I’m using LVM disks, but the process is no different from using Xen disk images.

  1. Install Debian Wheezy into a VMWare virtual machine. Attach a secondary virtual disk (it will be called /dev/sdc from now on) that’s sized about 500 MB larger than your Xen DomU (just to be safe). Fire up the VM. All subsequent commands will be run from inside that VM.
  2. Check whether your DomU disk has a partition table: ssh root@xen fdisk -l /dev/xenvg/4f89402b-8587-4139-8447-1da6d0571733.disk0. If it does, proceed to step 3. If it does not, proceed to step 4.
  3. Clone the Xen DomU onto the secondary virtual disk via SSH: ssh root@xen dd bs=1048576 if=/dev/xenvg/4f89402b-8587-4139-8447-1da6d0571733.disk0 | dd bs=1048576 of=/dev/sdc. Proceed to step 7.
  4. Zero out the beginning of the target disk: dd if=/dev/zero of=/dev/sdc bs=1048576 count=16
  5. Partition it and add a primary partition 8 MB into the disk: fdisk /dev/sdc, o Enter w Enter, fdisk /dev/sdc, n Enter p Enter 1 Enter 16384 Enter Enter, w Enter
  6. Clone the Xen DomU onto the secondary virtual disk’s first partition via SSH: ssh root@lara dd bs=1048576 if=/dev/xenvg/4f89402b-8587-4139-8447-1da6d0571733.disk0 | dd bs=1048576 of=/dev/sdc1
  7. reboot
  8. Mount the disk: mount -t ext3 /dev/sdc1 /mnt; cd /mnt
  9. Fix fstab: nano etc/fstab: change root disk from to /dev/sda1
  10. Fix the virtual console: nano etc/inittab: replace hvc0 with tty1
  11. Chroot into the disk: mount -t proc none /mnt/proc; mount -t sysfs none /mnt/sys; mount -o bind /dev /mnt/dev; chroot /mnt /bin/bash
  12. Fix mtab so the Grub installer works: grep -v rootfs /proc/mounts > /etc/mtab
  13. Install Grub: apt-get install grub2. When the installer asks to which disks to install, deselect all disks.
  14. Install Grub to MBR: grub-install –force /dev/sdc
  15. Update Grub configuration: update-grub
  16. Leave the chroot: exit; umount /mnt/* /mnt
  17. shutdown

Now you can detach the secondary virtual disk and create a new VM with it. If everything worked correctly, it will boot up.

Mac OS X 10.8 Mountain Lion Review

So I finally upgraded to Mountain Lion. I completely skipped over Lion because I didn’t like how Apple was iOS-ifying everything and had just stayed on Snow Leopard until a few days ago. Personally, I think Snow Leopard was the best operating system ever released. It was super stable and had everything you could ask of an operating system. I never really liked Leopard because it never worked 100% stable for me (though it did bring Time Machine and QuickLook, both of which are features I use every day). Tiger was great too back in the days, but if you look at it now, the GUI looks totally inconsistent.

Now that Apple is discontinuing security updates for Snow Leopard and an increasing number of apps requires Lion or newer, I had not much of a choice but upgrade.

This isn’t a full review of Mountain Lion. If you want to read one, check out John Siracusa’s epic review at Ars Technica. So far my impressions are:

Stability and speed: Mountain Lion is just as stable as Snow Leopard. It is also noticeably more responsive than Snow Leopard. I don’t think this has anything to do with actual speed, but more of a psychological thing: Safari now renders progressively, and many apps already let you interact with them while they’re still starting up (previously they would have been frozen for another second or two while they finished their startup prcedure).

iOS-ification: Launchpad is completely useless, but luckily Spotlight and the Dock still work exactly as they always have and will continue to be my preferred way of launching applications.

Auto Save however is outright obnoxious. You can no longer Command-D to hit the “Don’t Save” button when you want to close a window discarding changes. [UPDATE: Can’t believe it took me half a year to figure out that Command-Backspace can be used instead as an alternative to the old Command-D.] That window doesn’t even respect NSNavPanelExpandedStateForSaveMode (i.e. clicking the disclosure triangle is not persistent). “Save as” is now a secondary menu option behind “Duplicate”. iWork and TextEdit now show a file browser upon launch instead of opening a blank document. Save as defaults to iCloud instead of the local hard drive. And there are probably dozens of other things.

Here are some useful defaults commands to make it slightly less painful, but you still can’t completely disable Auto Save. Luckily I spend most of my time in apps that don’t use Auto Save (e.g. Microsoft Office, TextWrangler, TextMate, TeXShop).

defaults write -g NSNavPanelExpandedStateForSaveMode -bool TRUE # always expand open/save dialog
defaults write -g NSDocumentSaveNewDocumentsToCloud -bool FALSE # save locally instead of to iCloud by default

Also, check “Ask to keep changes when closing document” in the General pane in System Preferences.

Hold-to-umlaut is annoying on a full-size keyboard. Luckily you can re-enable key repeat:

defaults write -g ApplePressAndHoldEnabled -bool false # enable key-repeat

FileVault 2 is simple to enable, as secure as software-based full-disk encryption can be (according to several researchers) and has no noticeable performance hit. If you’re using it, you should enable deep sleep, otherwise the disk remains unlocked during sleep:

sudo pmset -a destroyfvkeyonstandby 1 hibernatemode 25

One thing that Apple could improve: after waking from deep sleep and entering your password at the EFI screen, that password should also be passed to the screensaver unlock screen (similar to how it’s passed to the loginwindow when booting). (this might be worth filing a bug report)

All of my favorite hidden Dock settings still work:

defaults write com.apple.Dock showhidden -bool YES # make hidden apps transparent
defaults write com.apple.dock no-glass -boolean YES # disable 3D dock
killall Dock

The one thing that doesn’t really work anymore is dragging widgets out of Dashboard after enabling developer mode:

defaults write com.apple.dashboard devmode -bool YES # enable dashboard dev mode
killall Dock

If you uncheck “Show Dashboard as a space” in the Mission Control pane in System Preferences, you can actually drag out the widget, but more often than not, it will just vanish along the way and won’t reappear until you kill the Dock.

Messages: I find it slightly annoying that Messages lists every single phone number and email address in the Show Info screen for every buddy, even if they don’t have iMessage activated. In fact, it even shows them after you disable iMessage in Messages’ preferences. Also, I miss the new message popup in the top right corner of my screen. Now, the only indication of a message received while you were away from your computer is a small number badge on the messages icon and a notification in Notification Center (which you don’t see until you open Notification Center). In fact, it doesn’t even show the message window until you click the icon (which may actually be a bug).

Notification Center is a very nice Growl replacement. I mainly need it for Mail and iChat, so I didn’t even bother installing something like Bark to forward Growl messages to Notification Center.

Full Screen is useless on a multi-screen setup, but running apps in full screen is pointless anyway on all but the smallest screens. Spaces used to be a pretty neat feature to switch between multiple sets of apps. Unfortunately, the old spaces (which you could access using Ctrl plus a number key or Ctrl plus the arrow keys) are gone and the new spaces can only be used to switch between multiple full-screen apps.

Most of my complaints are a matter of getting used to. When upgrading to a new OS, you always gain some things and you lose some things The only major issue I have is Auto Save. As long as my everyday apps don’t support it, I’ll be happy. Once they do (in Microsoft Office 2015 perhaps), I’ll need to find some way to get around it or get used to it.

Everything else is a reasonable tradeoff for being on the most recent OS version again.

I do remember how much my Windows friends complained six years ago when Vista changed everything they were used to after a decade of Windows 95 thru Windows XP. Or how some of my Linux friends complain about how Gnome 3 is so much worse than Gnome 2.

Installing Apple Remote Desktop 3.6.1 without first installing the boxed version

Apple Remote Desktop 3.0 was released in 2006. The current version is 3.6.1, and as such your six year old boxed copy license still entitles you to run it.

ARD has undergone some major changes during that time: most notably, Apple switched it from a Postgres database to an SQLite database, which greatly reduced its memory footprint and made it much more self-contained.

After reinstalling Mac OS X on my computer, I didn’t want to first install my boxed copy (version 3.2) because I didn’t want it to bloat my system with a copy of Postgresql that would get replaced by the update anyway.

After six years, it’s a safe bet that the downloadable Admin Update 3.6.1 does not require any previous version’s files. However, the installer checks for the existence of a previous version before allowing you to select the destination drive. This check can be satisfied by first running

defaults write /Applications/Remote\ Desktop.app/Contents/Info CFBundleShortVersionString -float 3.0

I’d like to point out that it still requires the license key that came in the box when you first run ARD.

Hashing and verifying LDAP passwords in PHP

I recently migrated a PHP web application that used LDAP for authentication and MySQL for data to something entirely MySQL based. I needed the users to be able to continue using their old LDAP passwords, so I dumped the LDAP database and grabbed the userPassword field for each user, base64_decode()d it and wrote that to a MySQL table. These password hashes start with something like {crypt}, {MD5}, {SHA1} or {SSHA1}, or in very rare cases, are plain-text.

Here’s a PHP function I wrote that, given a plain-text $password, verifies it against such a $hash. This is what you’ll be calling from your authentication script to verify a given password against the hash.

function check_password($password, $hash)
 {
 if ($hash == '') // no password
 {
 //echo "No password";
 return FALSE;
 }
 
 if ($hash{0} != '{') // plaintext password
 {
 if ($password == $hash)
 return TRUE;
 return FALSE;
 }
 
 if (substr($hash,0,7) == '{crypt}')
 {
 if (crypt($password, substr($hash,7)) == substr($hash,7))
 return TRUE;
 return FALSE;
 }
 elseif (substr($hash,0,5) == '{MD5}')
 {
 $encrypted_password = '{MD5}' . base64_encode(md5( $password,TRUE));
 }
 elseif (substr($hash,0,6) == '{SHA1}')
 {
 $encrypted_password = '{SHA}' . base64_encode(sha1( $password, TRUE ));
 }
 elseif (substr($hash,0,6) == '{SSHA}')
 {
 $salt = substr(base64_decode(substr($hash,6)),20);
 $encrypted_password = '{SSHA}' . base64_encode(sha1( $password.$salt, TRUE ). $salt);
 }
 else
 {
 echo "Unsupported password hash format";
 return FALSE;
 }
 
 if ($hash == $encrypted_password)
 return TRUE;
 
 return FALSE;
 }

And here’s one that make a {SSHA} hash from a password (I did not implement all the other algorithms as by today’s standards, they are no longer secure). This is what you’ll be calling from your change password script to hash the password for storing in the database.

function hash_password($password) // SSHA with random 4-character salt
 {
 $salt = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',4)),0,4);
 return '{SSHA}' . base64_encode(sha1( $password.$salt, TRUE ). $salt);
 }

Troubleshooting Apple Software Update Server

We are currently in the process of migrating towards a thin imaging approach for the Macs I manage at my university. One of the things we needed was an Apple Software Update Server, which is pretty straight forward to set up using Server Admin. I used Snow Leopard Server 10.6.8 with Lion updates enabled as described in Apple’s KB article.

A command I found extremely useful:

sudo serveradmin settings swupdate | grep "enable = no" | awk -F '=' '{print $1"= yes"}' | sudo serveradmin settings

This command enables all available updates. If you have set SUS to automatically mirror, but not automatically enable, this command saves you from having to click on every single one of the 600 updates to enable it.

A few days after I set up my SUS I was starting to see a bunch of error messages in /var/log/swupd/swupd_syncd_log after starting a sync run using the refresh button below the updates list in Server Admin. I’ll go over them here and explain my fixes:

“Product file URL contains possible security violation.” in log

*** Product file URL contains possible security violation.
*** Product ID: "11D2515_ServerEssentials"; file URL: "http://swcdn.apple.com/content/downloads/10/59/11D2515_ServerEssentials/xajda1v3ycqbtv75fiw5hvosaovu9to9hc/ServerEssentials.dst/041-5774.Italian.dist"
*** Reason: file download path cannot be reached / does not exist.
*** The suspect product file will not be downloaded.

A few Lion updates contain subfolders, which SUS does not create. Simply create those subfolders (mkdir /var/db/swupd/content/downloads/10/59/11D2515_ServerEssentials/xajda1v3ycqbtv75fiw5hvosaovu9to9hc/ServerEssentials.dst; chown _softwareupdate /var/db/swupd/content/downloads/10/59/11D2515_ServerEssentials/xajda1v3ycqbtv75fiw5hvosaovu9to9hc/ServerEssentials.dst) and have SUS recheck for available updates.

[EDIT: The original version of this blog post used curl to download the file, but forgot to chown the folder. Letting SUS download the file itself is the cleaner solution.]

[EDIT 2: This issue is really widespread with the ARD Client 3.6 update, where http://swcdn.apple.com/content/downloads/31/58/041-5433/xt9k9paj5zu8rx258rdccohk236ee77clh/RemoteDesktopClient.dst/041-5433.*.dist fails. This does solve this issue.]

“Product XXX-YYYY is no longer available and has no replacement” in log or “*** Missing version string for product XXX-YYYY” in log or “_productId Update” showing up in Server Admin

Your catalog is corrupted. Delete it to have it rebuilt automatically. The following commands help:

sudo serveradmin stop swupdate
cd $(sudo serveradmin settings swupdate:updatesDocRoot | awk -F '"' '{print $2}')/html/content
mv catalogs catalogs.old
sudo serveradmin start swupdate

Create a bootable Mac OS X Lion Server USB drive

  1. Download Lion from the Mac App Store.
  2. Use Disk Utility to restore /Applications/Install Mac OS X Lion.app/Contents/SharedSupport to a USB flash drive.
  3. Download Lion Server from the Mac App Store.
  4. Grab the correct version of ServerEssentials.pkg by running curl “http://swscan.apple.com/content/catalogs/others/index-lion-snowleopard-leopard.merged-1.sucatalog” | grep ServerEssentials in a Terminal, searching for the line that corresponds to your version of Lion (it can be identified by looking at ./System/Library/CoreServices/SystemVersion.plist on the flash drive), and downloading the file from the link referenced by that line (it will look like http://swcdn.apple.com/content/downloads/21/09/11E53_ServerEssentials/yfLkxRYr8GczRPHKBSpStgMYT3kjRnKQRf/ServerEssentials.pkg).
  5. Drop the downloaded ServerEssentials.pkg into ./Packages on the flash drive.
  6. If after installing from the Flash drive, you are missing /Applications/Server.app, that can easily be extracted from the Lion Server Combo Updater (use the version that corresponds to your Lion version) using Pacifist.

More details here.

Active PA speaker systems

During my high school time, I did a lot of work as a sound technician and lighting designer at all kinds of events, both as a volunteer at school and outside of school. Recently someone from the school told me that they were looking at buying a new portable speaker system, both to replace their old/broken/underpowered one and because they were paying more than a thousand euros in rental fees for additional speakers every year. They asked me if I could help them choose one. We quickly reached the conclusion that active speakers were the way to go because of their flexibility and because they would often be operated by people who didn’t know a lot about all the technical stuff.

We ended up narrowing it down to three candidates: the Yamaha DSR series, the JBL PRX600 series, and the QSC KW series. These are the top-of-the-line active systems the largest and most reputable speaker manufacturers have to offer, as of early 2012. The next step was to find a place where we could listen to all three and compare them. Thomann, the largest online shop for musical instruments and PA equipment in Europe, where we have been buying sound equipment for years, has a huge store and showroom in a small town in northern Bavaria. They ordered and set up all these speakers for us and let us listen to them for more than an hour. If the friendly sales guy ever grew tired of listening to our test songs like “He’s A Pirate” by Klaus Badelt or “Man in the Mirror” by Michael Jackson over and over again, he certainly didn’t show it.

We almost immediately ruled out the QSC: We had the QSC KW 153 three-way 15″ top coupled with a QSC KW 181 18″ subwoofer set up, but the mids and highs just sounded muddy.

Some other speakers we temporarily had in the test were some JBL Eon (by accident), which just sounded cheap compared to the others, and some RCF Art, which had crisp and powerful base, but not exactly outstanding highs.

Now we only had the JBL PRX 615 two-way 15″ top coupled with the JBL PRX618-XLF 18″ subwoofer and the Yamaha DSR 115 two-way 15″ top coupled with the Yamaha DSR 118W 18″ subwoofer left over. We tested and compared them for almost an hour: sometimes we tended towards the JBLs, other times we liked the Yamahas more.

The JBLs sounded very smooth (if you want to be mean, you could call them a tiny bit muddy) and their base stretched down to 30 Hz. On the other hand, the Yamahas had super-clear mids and highs and very precise and crisp base. After quite some discussion, we decided to go with the Yamahas. Another advantage was their significantly lower price and their more advanced DSP circuitry to protect the speakers.

They got delivered a few days ago and so far we’re really happy with them. They sound amazing: Perfect for the school’s numerous music performances. And they are powerful: Perfect for events like dances and parties.

If you’re looking for a set of high-quality portable speakers for a school, church, band or DJ, the Yamaha DSR series is most likely your best choice. They sound great, have lots of power and are well worth their money.

If you just use them for speech, a set of Yamaha DSR 112 would probably be a fine choice (I didn’t test the DSR 112, but assume they’re as good as the DSR 115 with a little less low-mids). If you’re using them for a band, go for a set of DSR 115, and if you have drums, base or anything else below 120 Hz, definitely get a pair of DSR 118W subwoofers along with them. Same goes for DJ and party use: a pair each of DSR 115 and DSR 118W should suffice to bring high-decibel, high-quality sound to a few hundred audience members.

If you have experiences with the Yamaha DSR (or the recently-released smaller DXR and DSW series), or have found other speakers in the same price range that sound better, please feel free to share them in the comments.

Integrating BIND with AD-integrated Microsoft DNS

I recently set up BIND9 to run secondary zones for an ActiveDirectory-integrated DNS server (the reason being that I hated effectively losing internet access when I rebooted my W2k8R2 server). While that was really easy (add the Linux server to the nameservers tab in DNS Admin, allow zone transfers and notifications, add slave zones in the named.conf), I thought that it shouldn’t be too difficult to also automatically replicate AD-integrated Conditional Forwarders.

While they are easily found in the DC=DomainDnsZones and DC=ForestDnsZones branch inside the AD, it turns out that the server information is stored in dnsproperty attributes containing binary data. However, Microsoft actually provides a specification for their DNS data structures, which is certainly very commendable. But as it turns out, it appears to have been written by someone who had no clue about Endianness or how many bits are in a byte (*).
The essence is: everything is Big Endian, except for IP addresses (the spec claims they are Network Byte Order, but in reality they are Little Endian), and every occurence of “1 byte” in section 2.3.1.1 dnsProperty should be replaced with “4 byte”.

So after taking about two hours for something that I expected would only take a couple minutes to hack together, I ended up with 400 lines of code that generate a file you can include in your named.conf that will look something like this:
zone "google.com" {
type forward;
forward first;
forwarders { 74.82.42.42; 2001:470:20:0:0:0:0:2; };
};

zone “youtube.com” {
type forward;
forward first;
forwarders { 74.82.42.42; 2001:470:20:0:0:0:0:2; };
};
(For those curious, this sample configuration would point google.com and youtube.com at Hurricane Electric’s DNS server so that you get AAAA records, a.k.a. Google over IPv6)

After this worked, I decided to also pull my slave zone definitions through the same mechanism. It only took me a minute to do that.
zone "example.com" {
type slave;
file "slave_example.com";
masters { 10.0.0.1; };
allow-notify { 10.0.0.1; };
};

So here we are: BIND9 as a fully-blown sync partner for AD-integrated DNS zones. To add a zone or conditional forwarder to BIND, add it to AD, set it to replicate to all DNS/domain controllers in this domain or forest, add the BIND server to the nameservers tab and allow zone transfers and notifications, and wait for the cron job to kick in.

I ended up having to write this script in PHP because Python’s LDAP module appears to have a broken SASL implementation, and you need SASL to use Kerberos for an LDAP connection.

The PHP script takes two parameters (1. the AD server’s address or the AD DNS domain name; 2. the AD base DN) and requires a valid Kerberos ticket.
The shell script (which you will most likely want to run from a cron job), which shares much of its code with my script from ISC DHCPd: Dynamic DNS updates against secure Microsoft DNS, needs to be configured with your realm, domain, base DN, user name (principal) and path to a keytab for that user (instruction on how to generate the keytab using ktutil are in the script’s comments).

(*) After doing all this, I figured that people from projects like Samba that write open source software to re-implement or interface with Microsoft products are doing an absolutely amazing job. They most likely aren’t getting any better specs than the one I found on MS DNS (if they get specs at all), and yet still somehow create almost perfect software that is a lot more complex than the simple stuff I did here.

UPDATE 2011-10-30: Apparently, AD refuses all requests from Linux clients that come in via IPv6. To force IPv4, line 7 of the PHP script needs to be changed to $conn = ldap_connect(gethostbyname($adserver), 389);, which is also fixed in the downloadable script.

Mount ext3 VMDK in VMWare Fusion using VMDKMounter

VMWare Fusion 3 comes with a tool called VMDKMounter.app. It allowed you to simply double-click NTFS or FAT32 VMDKs and they would be mounted on your desktop.

VMWare Fusion 4 dropped this tool, but you can download version 3.1.3 and extract /Library/Application Support/VMware Fusion/VMDKMounter.app from the package using Pacifist (just make sure that VMDKMounter.app/Contents/MacOS/vmware-vmdkMounterTool has the sticky bit set and is owned by root:wheel after you extract it).

Next, install OSXFUSE (the successor to MacFUSE) and fuse-ext2 if you don’t already have them installed.

VMDKMounter attempts to mount EXT2 using /System/Library/Filesystems/ext2.fs/Contents/Resources/mount_ext2, so we need to create two symlinks:

cd /System/Library/Filesystems
sudo ln -s fuse-ext2.fs ext2.fs
cd ext2.fs/Contents/Resources
sudo ln -s ../../mount_fuse-ext2 mount_ext2

Now we’re all set, you can simply open a VMDK by double-clicking it, or you can right-click a VMWare VM and open it with VMDKMounter.app and automatically have all its VMDKs mounted.

If you are receiving an NTFS-3G error message when mounting a non-NTFS VMDK: that’s perfectly normal, so you can just click OK. The error message is due to VMDKMounter simply trying a bunch of file system mounters until it finds one that doesn’t fail. As far as I can tell, it tries (in that order) ntfs, msdos, ntfs-3g, hfs, ext2, ext3.