(skip to "** QUICKQUICK **" if you don't have much time)
So I cancelled sleep last night after having lost administrator access as well. Basically what happened is that Azureus went apeshit and started filling up my whole hard disk whilst being unkillable. In the end I just held down the power button to shut the machine down. A reboot later all administrator users were gone.
I went into single user mode to enable the root user, logged into it and tried to give administrator rights back through System Preferences. To no avail! Exact same problem as unry described in his initial post.
I played around with dscl a while and when trying to add my user to the admin group I got the eDSUnknownNodeName as well. My hatred for Mac OS X grew a lot in these hours but I'm proud to say that human > machine. In my case what happened is that OS X fu**ed up big time and got itself into a position from which it couldn't recover on its own.
Bit of background regarding dscl: Information about e.g. user groups and user accounts are stored in directories by OS X as opposed to e.g. /etc/passwd and /etc/groups on standard Linux systems. Now I'm certainly no guru in this area but OS X can interface with various "providers" for these directories. Typically this would be a LDAP or AD server. If you find yourself in such a setup the following might not necessarily help you, sorry 🙂 In my case however I simply had a stand alone macbook meaning that my directory information is stored in /var/db/dslocal. In there are the XML files the command line utilities such as dscl interact with.
** QUICKQUICK **
Armoured with that knowledge let's venture into single user mode once more:
- Reboot
- Hold Apple+S
$ /sbin/fsck -fy
$ /sbin/mount -uw /
$ launchctl load /System/Library/LaunchDaemons/com.apple.DirectoryServices.plist
$ dscl . append /groups/admin GroupMembership myuser
=> <dscl_cmd> DS Error: -14009 (eDSUnknownNodeName)
- huh?
$ dscl . ls /groups
=> long list with groups like "wheel" and "staff" but NO "admin"
- Apparently this group got lost somehwo. ***** but shouldn't be a big problem, we'll just recreate it with its standard id 80. For this we use a convenient utility built on top of dscl
$ dseditgroup -o create -i 80 admin
=> ERROR: A Directory Service error occured.
14135: eDSRecordAlreadyExists
- ***? It's there after all? Probably corrupted though? Let's delete and recreate it..
$ dseditgroup -o delete admin
=> ERROR: A Directory Service error occured.
14136: eDSRecordNotFound
- Oh, COME ON! create command complains that this group already exists, delete command complains that it does infact not exist? We have to step down a level and dig into the actual storage for this stuff:
$ cat /var/db/dslocal/nodes/Default/groups/admin.plist
=>
- empty output? Aaaahh! This is the key to the whole ordeal: the group definition file exists but is empty! So on the one hand directory service thinks the group exists and thus refuses to create it but on the other hand there is no information in this file, thus users can't be added, the group is not listed when using dscl etc.
$ rm /var/db/dslocal/nodes/Default/groups/admin.plist
$ dseditgroup -o create -i 80 admin
$ dscl . append /groups/admin GroupMembership myuser
- While you are in there take a quick peek into the other group definition files, if one is corrupted others might as well be..
$ reboot
Done.
It might have been an edge case with me but I'm willing to bet that this fix, or a variation of it, can help several people out who reported similar problems. Personally I am very taken aback by this. Yes, Leopard is shiny but if an essential service such as Directory Service gets corrupted so quickly (unorderly shutdown) and can't automatically revocer from something as trivial as an empty group definition file, then I don't even dare to think about how much trouble a similarly poorly implemented FileVault might cause me..
(e.g. IMHO the group.plist should never be just opened and written to. A copy should be created, this can then be edited and upon successfully writing this copy the group.plist and group.plist.tmp can then be switched to avoid ending up with an empty file..)
In any case, hope it helps. Sorry for this rather long post I just was too proud.. 😉
Cheers,
Niels