Dealing with Windows SIDs in Solaris, part 2

As described in my first post on this subject, Solaris can now map SIDs to POSIX UIDs/GIDs and back, and it can store SIDs in ZFS. The identity models of Windows and Solaris are now unified, and the ACL model of ZFS has been extended. And we have a unified administration of SMB and NFS shares. Wow. I find this exciting, and not just because I’ve worked on parts of this story.

In this post I want to walk through the identity mapping facility’s design. Next I’ll talk about implementation, and then about how to use the facility.

Design of the Solaris ID mapping facility

The salient points of the design of the ID mapping facility are:

  • A door server daemon provides the ID mapping service (idmapd, svc:/system/idmap:default)
  • The service can be called via libidmap and the idmap kernel module
  • Given the need to map many SIDs at logon time and when dealing with ACLs, the idmap door protocol (an ONC RPC protocol), the kernel and user-land APIs, and the idmap service are designed to batch operations, to reduce latency by taking advantage of parallelism in the directory server and the network
  • There are two SQLite 2.x databases:
    • /var/idmap/idmap.db — contains persistent name-based ID mapping rules
    • /var/run/idmap/idmap.db — caches Windows name<->SID lookups, ID mappings and ephemeral ID allocations
  • There are two types of ID mapping today:
    • ephemeral ID mapping, where we dynamically allocate the next available UID or GID from the erstwhile negative uid_t/gid_t namespace (uid_t and gid_t are now unsigned), but we forget these mappings on reboot (see part 1 for more)
    • name-based ID mapping, where the sysadmin provides rules for mapping Windows users and groups to Solaris users and groups; these rules use names and wildcards, not SIDs and UIDs/GIDs.
  • There are three private system calls for idmapd:
    • idmap_reg() to register idmapd’s door; besides a door fd argument there’s a boolean that tells the kernel whether idmapd was unable to open/recover /var/run/idmap/idmap.db (see below)
    • idmap_unreg(), which is called when idmapd exits cleanly
    • allocids(), which allocates a number of ephemeral UIDs and GIDs for idmapd to use for dynamic ID allocation
  • The kernel tracks what ranges of ephemeral IDs are valid. Initially there are no (or very few) valid ephemeral IDs, and the kernel begins allocation of IDs at 2^31. When idmapd crashes in a way such that the ephemeral DB is unrecoverable then idmapd tells the kernel about this when it registers, and the kernel moves the low end of the valid ephemeral ID range to match the top end.
  • idmapd uses asynchronous LDAP searches of the Active Directory Global Catalog to do name<->SID resolution
  • idmapd uses DNS SRV RR lookups and LDAP searches of the Active Directory configuration partition to auto-discover Active Directory domain, forest and site names, and domain controller and global catalog directory server names

  • I’ve run out of time. I’ll cover implementation details next.

    ~ by nico on November 7, 2007.

    Leave a Reply

    Your email address will not be published. Required fields are marked *