I came across an interesting “problem” with Active Directory binding on Mac OS X Leopard. The symptoms were:
Since I’ve written (what seems like a) a book about Active Directory troubleshooting, I threw the book at this problem. It ended up taking quite some time to troubleshoot, and the answer ended up being very simple. However, it wasn’t on my normal list of culprits.
The biggest clue I found, besides the symptoms above, was that the DirectoryService debug logs yielded this during Active Directory logins from loginwindow:
It didn’t seem like a smoking gun, but I’d never come across this “false” response on a bound system before. So, what group was so important to the login process that the DirectoryService debug logs cared enough to note the failure? I was darned if I knew, and I had no other promising clues at that point.
So, I investigated that group further, and found it by its UUID using dsmemberutil:
Well, that helped a little, but the name would have helped a lot more. I had to find which group corresponded to the GID of 200. That GID was not at all familiar to me, but it was under 500, so there was a pretty good chance it came from Mac OS X.
This was my eureka! moment. I wasn’t entirely sure, but I was pretty confident that the “com.apple.access_loginwindow” group was the access control list group for the loginwindow process. Loginwindow controls all graphical logins to Mac OS X, and is the parent process of each GUI login session.
Looking up the group’s description confirmed that it was the ACL group. I did the lookup in Workgroup Manager, which was set to view the DSLocal directory service. While I was there, I also checked the membership: it listed only the computational group “localaccounts.” The “localaccounts” group is essentially a query that returns all accounts in the local directory service.
Well, that would certainly prevent Active Directory users from logging in with loginwindow. The ACL consulted the membership of the “com.apple.access_loginwindow” group to determine who was allowed to log in via the GUI. Because it contained only the “localaccounts” group, the ACL was preventing all non-local users from logging in.

Not knowing how this group was handled or even what had last edited it, I compared the affected system to a different AD-bound Leopard computer, which also had Workgroup Manager. (It’s handy to have the Mac OS X Server Admin Tools deployed out to your computers even if you don’t have a server to maintain.) The second computer didn’t have the group at all, which perplexed me a bit.
However, that made me reasonably sure I could simply delete that group. I backed it up from the filesystem at the command line, just to make sure, and then deleted it with Workgroup Manager on the affected computer.
After that, logins for all Active Directory accounts I tried proceeded normally at the loginwindow on that system.
With the problem solved, I sought more information about the workings of the “com.apple.access_loginwindow” group. I confirmed that it is created when the “Allow network users to login in at login window”
option is turned on in System Preferences > Accounts > Login Options. This should be turned on by default, and that initial state results in no “com.apple.access_loginwindow” group at all.

Since the option is on by default, the really simple solutions to this kind of problem are:

Deleting the “com.apple.access_loginwindow” group removes it completely and reinstates login capability for both local and network user accounts.
Toggling the System Preferences option back on, adds the “netaccounts” group to the “com.apple.access_loginwindow” group, reenabling login for both local and network users. It does not, however, remove the group “com.apple.access_loginwindow,” which remains on the system afterwards.
Here's what that looks like in Workgroup Manager:

To prevent this on managed clients, I could see a system administrator proactively creating and managing the membership of the “com.apple.access_loginwindow” group. To ensure that managed clients bound to an Active Directory allow both local and network users to log in, make sure the group is populated with the appropriate nested groups: “localaccounts” and “netaccounts.”
In this MacEnterprise list thread about printing authentication, Greg Neagle mentions that:
Under Leopard, all local users are members of lpadmin, but I think network users are not. So this method won't grant network users CUPS rights.
To confirm Greg's suspicions, I ran the following shell snippet.
This loops through the fictional accounts, "mobile_account_user," "network_account_user," and "local_account_user." These accounts are, as you might expect, as a locally-cached mobile account from a network directory, a wholly network directory-based account, and a simple local admin account. While the accounts presented here are fictional, the results were confirmed on a live system bound to a directory service.
The rest of the snippet determines if the accounts are members of any of the specified computational groups that debuted in Leopard. The last group checked is the "lpadmin" group. By looking at these group memberships, we can determine whether Leopard thinks that the account being tested is a local or network account.
Running the snippet above, with the right accounts available, produces the following output:
So, it appears mobile and local users get added to the lpadmin group automatically in Leopard, but network accounts do not.
Note that I didn’t check whether membership in the “admin” group made a difference or not. I also didn’t isolate for that factor.
I found it interesting that the mobile account is a member of “netaccounts” but not “localaccounts.” (By group membership alone, I’m not sure you could identify whether an account was a mobile account or not. Yet, that kind of test is part of the point of having these computational groups in the first place.)
When you have the print queue window open for a printer in Mac OS X Leopard, the Printer menu > Print Test Page command is active. That command sends the CUPS test page to the selected print queue.
The test page file itself is a PostScript document located at this path:
/usr/share/cups/data/testprint.ps
Since Leopard — like Mac OS X versions since Panther, has a built-in PostScript interpreter — you can open up this PostScript document and have it rendered as a PDF. By default, it will be sent to the Preview application.
It’s helpful to be able to view this document on-screen, so you can see what it is supposed to look like, in case your printer is not working as intended. You can compare the on-screen results with the printed output to verify how well your printer is working.
There are occasionally times in system administration where I feel as if I’m on the bleeding edge. They are not frequent … which probably puts me somewhere much closer to the lunatic fringe. These are also the times when no one else probably cares about the same things — but no matter, I generally have my own pragmatic reasons for them. This is one of those times, and I have waited for this particular feature for a while. I'm happy to have discovered it.
Let’s set up a scenario: you have a Mac OS X Tiger system bound to an Active Directory. All of the thousands of Active Directory users are available on that Tiger system; any one of them could log in to that computer. This isn’t bad if you only allow logins at the login window. However, if you enable any sharing services, the game changes and your exposure widens.
What if you don’t want everyone in your enterprise directory to log in? This gets a little scary to think about. What if you want to limit those who can log in, particularly for services like SSH? How do you let some users in but keep others out — even going to the point of denying access to whole classes of users?
There are a number of things you can do, some at the client and some in the directory. Unfortunately, some kinds of configuration must be done at the client. There isn’t a great way I’m aware of to distinguish between local and network accounts, complicates the situation for the administrator. With Open Directory in Tiger, any user from any directory service was as valid as any other. There will probably be some manual effort — ongoing effort at that — required to restrict access.
Enter Mac OS X Leopard. It now has “computational groups” in its Open Directory client. They are like smart groups in your local node. The memberships of these groups are calculated, rather than static. They are more like query-based groups.
For the scenario above, the two computational groups that provide the most utility are probably “localaccounts” and “netaccounts.” They allow you to distinguish users who are in the DSLocal database from those in Active Directory. This magic gives the glue we need to maintain finer-grained access controls automatically over time; you could use these groups for the sshd server configuration or in the authorization database at /private/etc/authorization, as examples.
Let’s try the groups out with dsmemberutil, with which we can determine whether or not a user is a member of a specific group. What about the first local user, typically created by the Mac OS X Setup Assistant?
$ dsmemberutil checkmembership -u 501 -G localaccounts
user is a member of the group
$ dsmemberutil checkmembership -u 501 -G netaccounts
user is not a member of the group
Digging further, all of the computational groups I’ve found had the same comment. We can search for that to find the rest, to find all of the computational groups that ship with a Leopard client.
$ dscl . -search /Groups Comment "Group membership calculated by system" | awk '/user|account/ { print $1 }'
authedusers
consoleusers
interactusers
localaccounts
netaccounts
netusers
From that list, we can determine more information about the groups:
| Short name | Real name | GID | Notes |
|---|---|---|---|
| authedusers | Authenticated Users | 50 | |
| consoleusers | Terminal Server User | 53 | |
| interactusers | Interactive | 51 | |
| netaccounts | Network Accounts | 61 | Accounts from a non-local database |
| localaccounts | Local Accounts | 62 | Accounts residing only in one of the local databases |
| netusers | Network | 52 |
Unfortunately, I couldn’t find any other documentation about the computational groups. If you do find some, I’d love to hear about it.
Aaron Hall noted on the MacEnterprise list that the font caches in Leopard “seem to be under /var/folders now, but you can manipulate them with the cool new atsutil in Leopard.”
The atsutil command is quite an interesting find to me, so I wanted to point it out.
I picked up a neat tip on the MacEnterprise.org mailing list today: put ~/Library/Printers in the Dock (on its right side) in Leopard. This gives you a stack which will pop out and show you your desktop printer icons, giving fast visual access to those print queues.
Update: This may only list the printers already used by that user account.
One stumbling block with using launchd’s WatchPath key in Tiger was that the watched path had to exist. In my quick launchd trials today, I found that Leopard does now execute the job as I would expect, even if the path did not exist yet when the job was loaded.
Simply using `touch` to create the watched path, where it was previously missing, is enough to trigger the job to run.
This makes the WatchPath key much more useful, especially if you’re using SSH or Apple Remote Desktop or some other means to connect to a client system. Through those means, if you can somehow create the path, any job that is waiting for its modification will run.
One drawback I found is that deleting the object at that path will also trigger the job — any modification of the path, then, counts. So the target script of your WatchPath-using launchd job should not remove the path. Just leave it in place.
After a tiny bit of experimentation with Leopard launchd jobs that have multiple triggers, I found that they can in fact run as expected when either trigger is hit.
I had a working launchd job that used the StartCalendarInterval key. I then added a WatchPath key and rebooted for good measure. When I used `touch` to modify the watched path, the job executed.
Good to know, even though I’d never tried this in Tiger. I don't yet know if there is a limitation on how many triggers can be added successfully, or if there are triggers which cannot be combined.
One immediate benefit of this, however, is that you can have one job that will definitely be coalesced into a single execution whenever it is missed (as with system sleep). If they don't coalesce into a single execution, it sounds as if the developers at Apple would consider that a bug. Multiple individual jobs do not coalesce if they are defined in separate plists, even if they call the same script or command line tool.
I've come across some fonts which worked in Mac OS X Tiger but don't work in Leopard. They won't load for me, even though the suitcase files — these are some old fonts — look good. The ones I've been able to run through verification in Font Book have passed. The suitcases themselves contain resource fork PostScript Type 1 fonts that I've carried with me like the uncertain digital baggage of youth, for many years.
I get a Font Book error -984 in my console log, when I examine the log, trying to load these fonts from my home directory. For example:
11/27/07 6:06:39 PM Font Book[5243] Could not create face from /Users/jaharmi/Library/Fonts/Officina Serif. Error -984.
I haven't been able to find any useful reference to this error code yet, so my troubleshooting has been slowed.
I’m not sure if it is the first signed third-party application to take advantage of Mac OS X Leopard’s new code signing feature. However, it’s at least the first one I’ve seen publicly.
The release notes for Fetch 5.3 show a raft of updates for the little niceties of Leopard. Put Automator actions under the “Internet” category? Check. Prevent Time Machine backups of Fetch’s cache? Check. Support the new application level firewall (ALF)? Check. Make the appearance match Leopard’s unified style? Check. And so on.