POSIX IDs, SIDs and IDRanges in IPA

Updated

Terminology

POSIX UID\GIDs

UNIX-like systems, RHEL in particular, use POSIX attributes to work with users and groups - User IDs or UIDs and Group IDs or GIDs respectively. UIDs, like GIDs, are represented via 32bit numeric value, which translates to 4,294,967,296 unique IDs for each.

In RHEL, ID's below 500 are regarded as system ID's and are reserved for system users and groups, and IDs in the 501-1000 range are traditionally used for service users and groups. If nothing is specified, a RHEL system will assign IDs starting from 1001 upwards for locally created users. By default, when a new user is created, the system will create a private group with a GID equal to the UID of the created user. Users that are local to the system are stored in the /etc/passwd file, and groups in /etc/group.

SID

Windows systems, however, are designed in a different way. In order to uniquely identify domain entities like users, groups or hosts they use Security Identifiers or, more commonly, SIDs.

The structure of the SID looks like this:

S-[Revision]-[IdentifierAuthority]-[SubAuthority0]-...-[SubAuthorityN](-RID).

A standard SID looks like this:

S-1-5-21-1376517128-3415768394-3708681247-1029

The individual parts of the SID represent the following:

Windows SID structure
Windows SID structure

Each entity in a Windows domain receives a unique SID which consists of domain SID and Relative ID or RID, which represents entity ID inside the domain. Each SID represents only one entity, and, once used, cannot be reused again during the lifecycle of the Windows domain - even if the entity is deleted.

For more detailed information about the topic, and for a list of well-known SIDs, refer to Content from learn.microsoft.com is not included.Microsoft article about Security identifiers.

RID

As indicated above, Relative ID, or RID, is the ID of an entity inside the domain, the last bit of an SID. RIDs in Windows systems are allocated by Security Accounts Manager (SAM). It is responsible for giving the next entity the next RID, and never using the same RID for one domain again.

RID size limit is 30 bits, or 1,073,741,823 entries. Inside a Windows domain, the first 1000 RIDs are reserved for Windows default entities, such as the Administator user and builtin groups.

SubID

Subordinate IDs, or SubIDs, are a Linux Kernel feature to grant a user additional user and group ID ranges. Usually this is used by container runtime engines to implement rootless containers. Traditionally SubID ranges are configured in /etc/subuid and /etc/subgid respectively.

For more information, see this Content from freeipa.readthedocs.io is not included.design page.

IPA ID ranges

There are different types of ID ranges in IPA. You can list current ranges set up for your IPA with (--all is used to show all the attributes assigned):

# ipa idrange-find --all

Default IPA Local ID range

During the initial installation of IPA and creation of IPA domain, a default POSIX ID range is created in order to accommodate its users and groups with name $REALM_id_range and of the ipa-local type. While the first POSIX ID is random, by default this range will have the size of 200,000 IDs. For new installations, this range will also get ipabaserid and ipasecondarybaserid attributes that will map primary and secondary RID ranges for this ID range. It looks like this:

  dn: cn=$REALM_id_range,cn=ranges,cn=etc,$SUFFIX
  Range name: $REALM.LOCAL_id_range
  First Posix ID of the range: 1862000000
  Number of IDs in the range: 200000
  First RID of the corresponding RID range: 1000
  First RID of the secondary RID range: 100000000
  Range type: local domain range
  iparangetyperaw: ipa-local
  objectclass: top, ipaIDrange, ipaDomainIDRange

Additional IPA Local ID ranges

You can expand the default IPA ID range with additional ones. You can use # ipa idrange-add command for that. For more info on manual management of ID ranges, refer to the documentation. Note that at the moment of writing this article, IPA can't assign primary and secondary RID ranges for the new range automatically, and it will expect --rid-base=INT and --secondary-rid-base=INT attributes or will ask about them interactively.

IPA SubID range

During initial deployment, IPA creates a default SubID range of the ipa-ad-trust type, with name $REALM_subid_range, which is not to be confused with the default IPA local ID range. It looks like this:

  dn: cn=$REALM_subid_range,cn=ranges,cn=etc,$SUFFIX
  Range name: $REALM_subid_range
  First Posix ID of the range: 2147483648
  Number of IDs in the range: 2147352576
  First RID of the corresponding RID range: 2147283648
  Domain SID of the trusted domain: S-1-5-21-738065-838566-4207669186
  Range type: Active Directory domain range
  iparangetyperaw: ipa-ad-trust
  objectclass: top, ipaIDrange, ipaTrustedADDomainRange

This range doesn't need a secondary RID range, and primary is created by default. You can read more about managing SubID ranges here.

IPA ADTrust range

During trust creation, a special ipa-ad-trust ID range is created in IPA. It's designed to accommodate trusted users that come from AD.

It looks like this:

  dn: cn=$AD.REALM_id_range,cn=ranges,cn=etc,$SUFFIX
  Range name: cn=$AD.REALM_id_range
  First Posix ID of the range: 1001600000
  Number of IDs in the range: 200000
  First RID of the corresponding RID range: 0
  Domain SID of the trusted domain: S-1-5-21-3014607317-3340640230-4186965532
  Range type: Active Directory domain range
  Auto private groups: true
  iparangetyperaw: ipa-ad-trust
  objectclass: ipaIDrange, ipatrustedaddomainrange

As you can see, RID range here starts from 0, not 1000, as we actually want to see and map special Windows users and groups as well.

Replica DNA range

The ID ranges discussed above are not to be confused with the Distributed Numeric Assignment range, or DNA range. A DNA range is a small subset of the main IPA local ID range, assigned to a specific replica, which it uses to create new users and groups. If a new replica doesn't have a DNA range set up, it will be assigned one automatically when it first tries to create a user or a group. The same will happen if the existing DNA range gets depleted.

This approach guarantees that, even if two users were created on two different replicas simultaneously, they'd get different UIDs. You can read more about DNA ranges in this article.

You can list your current DNA ranges via

# ipa-replica-manage dnarange-show

Translation of POSIX IDs and SIDs

Translation of SID to POSIX IDs for trusted domains

If IPA has established trust with AD, it can authenticate AD users. But how to map SIDs of AD users into POSIX IDs? In some cases, AD has POSIX attributes populated, but by default it's not the case. So IPA has a built-in mechanism of translating SIDs into POSIX IDs. The process is pretty straight-forward:

Translation of SID to IPA POSIX IDs
Translation of SID to IPA POSIX IDs

As you can see, the resulting POSIX ID is equal to trusted_range_first_ID + RID of the entity in AD.

Translation of POSIX IDs to IPA SIDs

On the other hand, translating POSIX IPA's IDs into SIDs is not that trivial. The problem is that nothing prevents us from creating, let's say, user John with uid=1001 without a private group and user group Doe with gid=1001. This is a valid configuration for a Linux system - both users and groups all have unique IDs. For example, by default, RHEL system has user operator:x:11:0:operator:/root:/sbin/nologin and group cdrom:x:11:, and the ID number is the same, 11 - it's just UID and GID respectively.

How do we solve this problem? In order to do that, IPA introduces two virtual ranges for each ipa-local ID range - primary and secondary RID ranges. They both have the same length as the parent range itself, and do not overlap between themselves and other RID ranges. It looks like this:

Translation of IPA POSIX IDs to IPA SIDs
Translation of IPA POSIX IDs to IPA SIDs

If in this example we have simultaneously a user with UID=1862000006 and a group with GID=1862000006, the user will get RID of 1006, but the group will get RID from the secondary range - 300006. This way, we make sure that all IPA users and groups will get unique SID and won't conflict for the same RID. As in Windows environments users don't have private groups, they are being ignored and not translated to SIDs.

Why do we need to translate IPA POSIX accounts into Windows-like SIDs at all? There are multitude of reasons, starting with bi-directional trust between IPA and AD domains, but starting with RHEL 9.2 all IPA installations will force creating SIDs for MS-PAC compatibility sake. For more information, you can refer to this article.

Handling multiple IDRanges for IPA

While the default IPA ID range gets its primary and secondary RID ranges during the creation of the domain, what happens if we add a second, third ID range to accommodate growing number of our users? Or what happens if the default ID range was created in earlier versions of IPA and didn't get correct attributes? Well, we'll have to fall back to manual ways.

In general, RID ranges are defined by two attributes: base RID and parent range size. While setting up those, there are two main rules:

  1. The range should be starting at least from 1000, in order to not interfere with built-in Windows SIDs;
  2. The range shouldn't overlap with any existing RID range.

Other than that, there are no limitations, but usually it's convenient to keep ranges close together and start the secondary RID range with the next ID from the end of the primary one. Formula for that would be ipasecondarybaserid = ipabaserid + ipaidrangesize + 1. It should look like this:

Multiple ID Ranges to RID ranges
Multiple ID Ranges to RID ranges

Setting it up usually requires direct intervention in LDAP, so be careful to set correct attributes:

ldapmodify -D "cn=Directory Manager" -W -x << EOF
dn: cn=<IDRANGENAME>,cn=ranges,cn=etc,$SUFFIX
changetype: modify
add: ipabaserid
ipabaserid: 2000
-
add: ipasecondarybaserid
ipasecondarybaserid: 5001
EOF

After the correct attributes are set, double-check the result via

# ipa idrange-find --all --raw

You can trigger SID generation task for all users/groups without SID with

# ipa config-mod --enable-sid --add-sids

It's worth mentioning that the above task will fail if some of your IPA users or groups are out of IPA-managed ranges - they will not get into any RID range. The task will also fail if you have duplicated UIDs or GIDs in your IPA, for an obvious reason - users or groups will get the same RID, and this is not allowed. On a general note, duplicated IDs are not supported and are a very bad practice in Linux environments.

Category
Components
Article Type