From 04c704fb767e10c19b8c1b3a02eb32b7767de2fb Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Sep 10 2018 13:12:33 +0000 Subject: A design document for the auto_private_groups=hybrid feature --- diff --git a/design_pages/hybrid_private_groups.rst b/design_pages/hybrid_private_groups.rst new file mode 100644 index 0000000..c489542 --- /dev/null +++ b/design_pages/hybrid_private_groups.rst @@ -0,0 +1,108 @@ +.. highlight:: none + +Hybrid Private Groups for LDAP and AD domains +============================================= + +Related ticket(s): +------------------ + https://pagure.io/SSSD/sssd/issue/3822 + +Problem statement +----------------- +This change will augment the ``auto_private_groups`` option which currently +is a boolean option with a third mode that would, for users who do have +the ``gidNumber`` attribute set return the original group, but for users who +have no ``gidNumber,`` autogenerate a user-private group. + +Use cases +--------- +This change is mostly useful for backwards compatibility in environments that +used to manually set a ``gidNumber`` and need to retain the same primary +GID number, but for newly added user, autogenerate the user private group +from the ``uidNumber.`` Please see the "How to test" section for an example. + +Overview of the solution +------------------------ +Internally, this hybrid domain would work as a MPG domain, so as if +``auto_private_groups`` was set true. The difference would be when +returning the entries. In the hybrid model, if the user being returned +had an original GID, this original GID would be used. Otherwise, a primary +group generated from the UID would be returned. + +Care must be taken in the getgrnam and getgrgid calls to not return the +autogenerated group if requested for a user who also has the originalGID set. + +Implementation details +---------------------- +As said above, for the most part, the hybrid domain would work in a similar +manner as a domain that had ``auto_private_groups=true`` set in the config +file. This means, that the ``uidNumber`` and ``gidNumber`` attributes in +the sysdb cache are always set to the same value, but in case the original +entry in LDAP did have a gidNumber stored, that original value is also +stored in the cache using the ``origPrimaryGroupGidNumber`` attribute. +The purpose of this attribute is to be able to return the original +primary GID as a supplemetary group so that any resources owned by this +ID are still accessible to the user. + +We will take advantage of this attribute when returning the user object +during ``getpwnam`` (keep in mind that ``struct passwd`` that the +``getpwnam`` call returns also contains the primary GID number), initgroups +and also for a special case during the ``getgrgid`` and ``getgrnam`` calls. + +During the getpwnam call, the code will check whether the user being returned +has the ``origPrimaryGroupGidNumber`` or not. If it does, its value would +be returned as the GID number, otherwise the ``gidNumber`` attribute would +be used. A similar logic will be implemented in the initgroups call, with +the additional caveat that if the ``origPrimaryGroupGidNumber`` exists, +it wouldn't be returned as another secondary group. + +For group requests in a domain where the user private groups are completely +managed, SSSD would search the whole combined user and group space and +return group objects based on user objects in the cache. The hybrid domain +must behave a little differently here. When a request for a user-private +group comes, the ``getgr*`` call in a hybrid domain should first try +to search group objects only. If there is no match, then also the user +objects need to be searched, but only those user objects that have no +``origPrimaryGroupGidNumber`` set can be returned as a private groups. +Reusing the example above, ``getgrnam("hybriduser")`` would return a group +object inferred from the user object, but ``getgrnam("posixuser")`` would +not return anything. + +Configuration changes +--------------------- +Since we are adding a new option value to the existing +``auto_private_groups`` call, the option must internally be converted from +boolean to a string with three possible values. We would retain ``true`` +and ``false`` for backwards compatibility but add a third option value +``hybrid.`` + +How To Test +----------- +Considering these two partial LDIFs:: + + cn=posixuser,dc=example,dc=com + uidNumber: 1234 + gidNumber: 5678 + cn: posixuser + gecos: posix user + homeDirectory: /home/posixuser + loginShell: /bin/sh + + cn=hybriduser,dc=example,dc=com + uidNumber: 2345 + cn: hybriduser + # note: no gidNumber attribute + gecos: hybrid user + homeDirectory: /home/hybriduser + loginShell: /bin/sh + +The getpwnam output for these two users would be:: + + $ getent passwd posixuser + posixuser:*:1234:5678:posix user:/home/posixuser:/bin/sh + $ getent passwd hybriduser + hybriduser:*:2345:2345:hybrid user:/home/hybriduser:/bin/sh + +Authors +------- + * Jakub Hrozek diff --git a/design_pages/index.rst b/design_pages/index.rst index 32335c0..d41c140 100644 --- a/design_pages/index.rst +++ b/design_pages/index.rst @@ -22,6 +22,7 @@ Implemented in 1.16.x :maxdepth: 1 auto_private_groups + hybrid_private_groups uid_negative_global_catalog smartcard_multiple_certificates enhanced_nss_api