#8361 Add support for managing subuids and subgids in FreeIPA
Closed: fixed by rcritten. Opened by abbra.

For containerized environments it is helpful to enable centrally-managed allocation and distribution of ID sub-ranges for users/groups to use in podman and runc.

As discussed in https://github.com/shadow-maint/shadow/issues/154, https://github.com/shadow-maint/shadow/commit/0a7888b1fad613a052b988b01a71933b67296e68 adds a new interface, libsubid. This interface will be extended to allow pluggable backends.

The purpose of this ticket is to track two tasks:
- add support for storing per-user/group subid ranges in FreeIPA
- track retrieval and distribution of per-user/group subid ranges in SSSD

For the latter a new ticket needs to be added.


SSSD ticket: https://github.com/SSSD/sssd/issues/5197

Metadata Update from @cheimes:
- Issue assigned to cheimes

Metadata Update from @cheimes:
- Issue priority set to: important
- Issue set to the milestone: FreeIPA 4.9
- Issue tagged with: rfe

Each entry of /etc/subuid and /etc/subgid has three fields:

  • login / uid
  • numerical subordinate user or group ID
  • numerical subordinate user or group ID count

The numerical id is the start value of an invertal. The count specifies to size of the interval. A typical value for a count is 65536. An implementation should ensure that intervals don't overlap or conflict with reserved ranges for standard uidNumber and gidNumber. 389-DS LDAP server has a distributed numeric assignment plugin (DNA) that takes care of assigning numbers in a master-master replication. The DNA plugin does not support intervals, the feature is disabled.

subuid and subgid have a 1:1 relationship to users. Therefore it makes sense to store both mappings directly in user entries. The feature requires one auxiliar object classes with four mandatory integer field for start number and count: subuidNumber, subuidCount, subgidNumber, subgidCount. IMHO it does not make much sense to have subuid without subgid.

The maximum value for user and group ids are restricted. uid_t and gid_t are aliases for unsigned int (uint32_t). I assume that subuid and subgid are restricted to 32 bit unsigned ints as well. With idstart = random.randint(1, 10000) * 200000 and count = 65536 IPA would support about 35,000 users with subuid/subgid ranges. It looks like 65536 is actually required to properly map nobody to uid=65534.

>>> subuid_count = 65536
>>> uid_max = 1 << 32
>>> ipa_idstart_max = 10000 * 200000
>>> ipa_idmax = ipa_idstart_max + 200000 - 1
>>> (uid_max - ipa_idmax) // subuid_count
35015

To simplify the implementation it may make sense to hardcode the count value and set subuidNumber == subgidNumber. I think we could even go so far and derive the subuidNumber from uidNumber so we don't have to worry about overlapping ranges.

subuidnumber = subuid_start + (uidnumber - idstart) * subuid_count

The assignment could be handled by a 389-DS plugin.

Question: Is the range a 32bit, 64bit, or machine dependent integer? shadowutils defines the range values as unsigned long, see idmapping.h, but have_sub_uids() uses uid_t as start value.

Metadata Update from @cheimes:
- Custom field on_review adjusted to https://github.com/freeipa/freeipa/pull/5438

Hi @cheimes ,

do I understand your proposal correctly that subuid_start == (ipa_idmax + 1)?

While I like the simplicity of the approach, I have a few questions:

1) what would be subuidnumber for users with (uidnumber - idstart) > 35015? Will we disallow/disable sub-id ranges for those users?
IIUC, this should be very common case for example when replica requests own range and 200k are split.

2) I'm not sure I understand Adding New Ranges correctly, but looks like initial 200k range can be extended manually?
I guess, this operation at least changes idstart and thus either invalidates existing assignments or creates potential for conflicts?

3) The same doc mentions: "if two separate FreeIPA domains are ever merged in the future".
In this case we will get overlapping sub-id ranges?

4) Is it required to take into account AD trust ranges when IPA generates IDs for AD users?
(I don't know what ID space is used for this...)

5) In case of trust with AD that defines and populates own attrs for sub-id ranges, will we ignore those?

do I understand your proposal correctly that subuid_start == (ipa_idmax + 1)?

After further investigation I came to the conclusion that this approach is not going to work:

  • IPA users can have uidNumber and gidNumber outside the range of [idstart, idmax].
  • 389-DS DNA plugin assigns uidNumber anywhere in the interval of [idstart, idmax]. For example the second replica owns the top half of the range. ipa user-add will use uidNumber=idstart + 100000 as auto-assigned uidNumber. The 32bit int restriction doesn't permit mapping of 200,000 uids with 65,536 count.
  • AD trust makes things even more complicated.

Back to the drawing board!

Hi @cheimes ,

It looks like 65536 is actually required to properly map nobody to uid=65534.

If I read man newuidmap correctly (please correct me if I'm wrong),
nothing prevents calling newuidmap $pid 65534 anything_in_the_allowed_interval 1
and thus mapping of 65534 doesn't necessary require interval size >= 65536, right?

Hi @cheimes ,

It looks like 65536 is actually required to properly map nobody to uid=65534.

If I read man newuidmap correctly (please correct me if I'm wrong),
nothing prevents calling newuidmap $pid 65534 anything_in_the_allowed_interval 1
and thus mapping of 65534 doesn't necessary require interval size >= 65536, right?

No, despite this is technically possible, this is not what Podman uses...

Metadata Update from @cheimes:
- Custom field on_review adjusted to https://github.com/freeipa/freeipa/pull/5652 (was: https://github.com/freeipa/freeipa/pull/5438)

master:

  • a297ebbb8a277c7c3fcb44f6da182dde71447442 Add max/min safe integer

ipa-4-9:

  • 0c3a2dbfeaa73db868bacd4042de02a20b714d05 Add max/min safe integer

master:

  • 1c4ae37293c31c5030556e8464099cad22d49db8 Add basic support for subordinate user/group ids
  • c78d1341ad54a1837f64ee6a332f534ecd534046 Redesign subid feature
  • 51035d9354e0f7497bbdd5486b4717b385ee5a62 Use 389-DS' dnaInterval setting to assign intervals
  • 1e00748f1833a79488aeaa9ba798ba6538905fa7 Fix ipa-server-upgrade
  • 110940b998b0d7adb68fa097dd973b67bbdbd644 Fix oid of ipaUserDefaultSubordinateId
  • 30eceb504adcfd7e223430753fb45bf47fb9673b WebUI: Improve subordinate ids user workflow
  • aae6c029dac285c1704fea3d97e576f81d0bc357 Test DNA plugin configuration

ipa-4-9:

  • 3540986a11d4f3401ba4918f25229a79283d9dbd Add basic support for subordinate user/group ids
  • 5d4fe06663c3e66b1da73c01ce022790634a3e3b Redesign subid feature
  • ef115b04182d572bf61e32e2405bbb68ff65e928 Use 389-DS' dnaInterval setting to assign intervals
  • e6e3fb606d08b0dc57bfa360a0f0082052441db6 Fix ipa-server-upgrade
  • 44ccc0f64bac9fc2e7e3264984af26635bb34742 Fix oid of ipaUserDefaultSubordinateId
  • 9f4b8982cd06011df8daac480a726637fc52649e WebUI: Improve subordinate ids user workflow
  • b53a52a1fafa94e0129e6e3e55fddd59909f0f0a Test DNA plugin configuration

Metadata Update from @rcritten:
- Issue close_status updated to: fixed
- Issue status updated to: Closed (was: Open)

master:

  • 4616c125b6656f15d51718d651d586a8c98d7f2e pr-ci definitions: add subid-related jobs

ipa-4-9:

  • d456649feb40d462f73321a4a220b4aff7adb443 pr-ci definitions: add subid-related jobs

master:

  • c2f2597b6d3ff3a605b2167f33313155e9a86d4e ipatests: webui: Tests for subordinate ids.
  • 56df1fd95cd277e9e60e8dc6f57a6663a716ac39 pr-ci definitions: add web-ui subid-related jobs

ipa-4-9:

  • edbd8f692a28fc999b92e9032614d366511db323 ipatests: webui: Tests for subordinate ids.
  • 878859f4a27aa03c905b82f68327815825ceb1fa pr-ci definitions: add web-ui subid-related jobs

Metadata Update from @frenaud:
- Custom field changelog adjusted to IPA is now able to centrally store ID sub-ranges for users/groups. More details can be found in the design document: https://freeipa.readthedocs.io/en/latest/designs/subordinate-ids.html

Metadata