#79 Rework the hybrid domain design page to reflect the changed requirements
Merged 5 years ago by jhrozek. Opened 5 years ago by jhrozek.
SSSD/ jhrozek/docs hybrid  into  master

@@ -10,63 +10,66 @@ 

  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.

+ is a boolean option with a third mode that would, for users whose ``uidNumber``

+ has the same value as the ``gidNumber`` attribute and no group exists in

+ LDAP that has the same value of gidNumber, to 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.

+ This change is mostly useful for backwards compatibility in environments

+ that used to manually create a corresponding group for every user's

+ ``gidNumber`` and need to retain the same primary groups, but for newly

+ added user, autogenerate the user private group from the ``gidNumber.``

+ 

+ To keep backwards compatibility, if a group exists with the same

+ ``gidNumber`` as set a user entry, this "real" group must not be shadowed

+ by the autogenerated group even if the autogenerated group comes from a

+ different domain than the user.

+ 

+ Please see the "How to test" section for a complete 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.

+ Internally, a hybrid domain would work as a usual non-MPG domain. All

+ logic will be implemented in the NSS responder, to account for the

+ case where the primary group comes from a different domain than

+ the user, because in that case, SSSD must iterate over the domains,

+ which means calling into the ``cache_req`` code.

  

- 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.

+ Care must be taken in the ``getgrnam`` and ``getgrgid`` calls to not

+ return the autogenerated group if requested for a user whose ``gidNumber``

+ is also represented in LDAP with a real group.

  

  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 supplementary 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.

+ As said above, the logic will be contained in the NSS responder. If a request

+ for a group arrives, either by ID or by name, the NSS responder first

+ issues a request for a group. If that group is not resolvable and the

+ domain is configured in this special mode, the SSSD retries the same

+ search in the user ID space or name space.

+ 

+ If a result is found with this fallback search, the resulting object

+ would be transformed from a user object to a group object so that the

+ NSS protocol can create a reply.

+ 

+ As a last step, if a group is requested by name, the NSS responder must,

+ in case of returning the user group, verify that this user group is

+ not shadowed by an entry in another domain. This is important because

+ if the autogenerated group was returned even as an alias, the result

+ would have been stored in the memory cache and subsequent ``getgrgid()``

+ requests would return this autogenerated group from the memory cache

+ until it expires, but then return the real group entry from the on-disk

+ cache. To avoid this confusing state, the NSS responder would also run

+ a by-GID search and only return the result if the by-GID search returns

+ nothing. For example, consider that there is a user ``hybrid_with_group``

+ whose uid and gid are the same, but there exists a group ``real_group``

+ with the same gid as the primary gid of the user entry. A ``getgrnam``

+ request arrives for the ``hybrid_with_group`` group, does not match a real

+ group entry, falls back to the user space. In order to avoid returning the

+ ``hybrid_with_group`` group, the NSS responder would search the group space

+ again for ``hybrid_with_group``'s primary GID, find out that the group

+ ``real_group`` exists and return ``ENOENT.``

  

  Configuration changes

  ---------------------
@@ -78,9 +81,10 @@ 

  

  How To Test

  -----------

- Considering these two partial LDIFs::

+ Considering these partial LDIFs::

  

-     cn=posixuser,dc=example,dc=com

+     cn=posixuser,ou=Users,dc=example,dc=com

+     objectclass: posixUser

      uidNumber: 1234

      gidNumber: 5678

      cn: posixuser
@@ -88,20 +92,66 @@ 

      homeDirectory: /home/posixuser

      loginShell: /bin/sh

  

-     cn=hybriduser,dc=example,dc=com

+     cn=posixgroup,ou=Groups,dc=example,dc=com

+     objectclass: posixGroup

+     gidNumber: 5678

+     cn: real_group

+ 

+     cn=hybriduser,ou=Users,dc=example,dc=com

+     objectclass: posixUser

      uidNumber: 2345

+     gidNumber: 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::

+     cn=hybrid_with_group,ou=Users,dc=example,dc=com

+     objectclass: posixUser

+     uidNumber: 3456

+     gidNumber: 3456

+     cn: hybrid_with_group

+     gecos: hybrid with group

+     homeDirectory: /home/hybrid_with_group

+     loginShell: /bin/sh

+ 

+     cn=real_group,ou=Groups,dc=example,dc=com

+     objectclass: posixGroup

+     gidNumber: 3456

+     cn: real_group

+ 

+ The ``posixuser`` behaves as usual::

  

      $ getent passwd posixuser

      posixuser:*:1234:5678:posix user:/home/posixuser:/bin/sh

+     $ getent group 5678

+     posixgroup:*:5678:

+     $ getent group posixuser

+     returns nothing

+     $ id posixuser

+     uid=1234(posixuser) gid=5678(posixgroup) groups=5678(posixgroup)

+ 

+ The ``hybriduser``'s primary group is autogenerated::

+ 

      $ getent passwd hybriduser

-     hybriduser:*:2345:2345:hybrid user:/home/hybriduser:/bin/sh

+     hybriduser:*:2345:2345:posix user:/home/hybriduser:/bin/sh

+     $ getent group 2345

+     hybriduser:*:2345:

+     $ getent group hybriduser

+     hybriduser:*:2345:

+     $ id hybriduser

+     uid=2345(hybriduser) gid=2345(hybriduser) groups=2345(hybriduser)

+ 

+ The primary group of ``hybrid_with_group`` is still the one stored in LDAP, not autogenerated::

+ 

+     $ getent passwd hybrid_with_group

+     hybrid_with_group:*:3456:3456:posix user:/home/hybrid_with_group:/bin/sh

+     $ getent group 3456

+     real_group:*:3456:

+     $ getent group hybrid_with_group

+     returns nothing

+     $ id hybrid_with_group

+     uid=3456(hybrid_with_group) gid=3456(real_group) groups=3456(hybrid_with_group)

  

  Authors

  -------

This change reworks the design page to reflect the current state of https://github.com/SSSD/sssd/pull/650

Pull-Request has been merged by jhrozek

5 years ago
Metadata