This change will augment the
auto_private_groups option which currently 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.
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
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.
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
Care must be taken in the
getgrgid calls to not return the autogenerated group if requested for a user whose
gidNumber is also represented in LDAP with a real group.
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
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
false for backwards compatibility but add a third option value
Considering these partial LDIFs:
cn=posixuser,ou=Users,dc=example,dc=com objectclass: posixUser uidNumber: 1234 gidNumber: 5678 cn: posixuser gecos: posix user homeDirectory: /home/posixuser loginShell: /bin/sh 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 gecos: hybrid user homeDirectory: /home/hybriduser loginShell: /bin/sh 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
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)
hybriduser’s primary group is autogenerated:
$ getent passwd hybriduser 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)
- Jakub Hrozek <firstname.lastname@example.org>