-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 10/18/2010 07:42 PM, Petr Baudis wrote:
This RFC patch adds support for new interfaces: getgrgid2(), getgrnam2() and their *_r() variants. These interfaces allow the user to specify whether the group.gr_mem field shall be filled in.
The issue we are trying to solve is that needlessly high load is generated in large deployments with NIS/LDAP user groups with possibly thousands of members. Even when nscd is used, the information is requested and transferred frequently even when there never arises any real use for the huge lists of members at the node at all.
We have looked at some commonly used applications and e.g. for a normal desktop, if some basic utilities and file managers would be trivially modified to use the new interface, the full lists of users in a group would never have to be downloaded. Right now, even ls will trigger getting full lists of users in all groups it encounters. Moreover, e.g. the sssd guys are reportedly trying to solve this problem by evil hacks like randomly not filling or only partially filling the gr_mem field.
Actually, your information is a little bit incorrect. We recently discovered that we had a few bugs in SSSD that were causing us to only present a subset of the gr_mem field. This was entirely incorrect, and as of SSSD 1.2.4 and 1.4.0 we have rectified this problem.
The way we do things in SSSD is, however, designed to significantly reduce the load on LDAP servers. When we perform a group lookup with getgrnam() or getgrgid(), we request ONLY this group from the LDAP server. What we then do on our client-side is to create in our cache mechanism a series of "fake" users in our data store. These users will be reported back to getgrnam(), but they are not separately looked up and populated with their complete user information unless they are directly requested by a getpwnam() or getpwid() request.
The net result is that we will report all of the users that belong in a group, but we will not make additional requests to populate those users unless they are directly requested.
Yes, for groups that have many thousands of users, we may make a single request that transfers a couple hundred kilobytes, but we do not make subsequent requests for each of those users in turn.
RFC2307bis servers require slightly more processing, as we need to make multiple requests to LDAP if there are nested groups in play. But we never make more requests than the configured nesting limit.
Any comments on the API are welcome, including thoughts on how to make it more elegant. Originally, I wanted to implement it as gid_t getgidbyname(const char *name) etc., but I would have to redo some parts of the NSS infrastructure to easily allow returning gid_t instead of a struct.
If there is a consensus that this is a good idea and Ulrich gives his blessing, I will of course extend the patch to be compatible with older NSS modules and add NIS support and nscd support.
I'm really not sure what the value of this approach is. Realistically, you're talking about creating an interface whose sole purpose is to map GID<->groupname and nothing else?
I'm not sure there's sufficient value in this approach, given that it's possible as described above to limit the network requests. I think it makes much more sense to guide the respective name-service providers along the path of handling these requests more efficiently.
I'm expanding this mailing to include the sssd-devel list for broader discussion.
- -- Stephen Gallagher RHCE 804006346421761
Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/
Am Dienstag 19 Oktober 2010, 14:04:06 schrieb Stephen Gallagher:
On 10/18/2010 07:42 PM, Petr Baudis wrote:
This RFC patch adds support for new interfaces: getgrgid2(), getgrnam2() and their *_r() variants. These interfaces allow the user to specify whether the group.gr_mem field shall be filled in.
The issue we are trying to solve is that needlessly high load is generated in large deployments with NIS/LDAP user groups with possibly thousands of members. Even when nscd is used, the information is requested and transferred frequently even when there never arises any real use for the huge lists of members at the node at all.
We have looked at some commonly used applications and e.g. for a normal desktop, if some basic utilities and file managers would be trivially modified to use the new interface, the full lists of users in a group would never have to be downloaded. Right now, even ls will trigger getting full lists of users in all groups it encounters. Moreover, e.g. the sssd guys are reportedly trying to solve this problem by evil hacks like randomly not filling or only partially filling the gr_mem field.
Actually, your information is a little bit incorrect. We recently discovered that we had a few bugs in SSSD that were causing us to only present a subset of the gr_mem field. This was entirely incorrect, and as of SSSD 1.2.4 and 1.4.0 we have rectified this problem.
From the recent discussion on sssd-devel it seemed to have been done as an "optimization" initially. But in the end that doesn't really matter.
The way we do things in SSSD is, however, designed to significantly reduce the load on LDAP servers. When we perform a group lookup with getgrnam() or getgrgid(), we request ONLY this group from the LDAP server. What we then do on our client-side is to create in our cache mechanism a series of "fake" users in our data store. These users will be reported back to getgrnam(), but they are not separately looked up and populated with their complete user information unless they are directly requested by a getpwnam() or getpwid() request.
This is not correct. See below.
The net result is that we will report all of the users that belong in a group, but we will not make additional requests to populate those users unless they are directly requested.
Yes, for groups that have many thousands of users, we may make a single request that transfers a couple hundred kilobytes, but we do not make subsequent requests for each of those users in turn.
RFC2307bis servers require slightly more processing, as we need to make multiple requests to LDAP if there are nested groups in play. But we never make more requests than the configured nesting limit.
I think your are mixing things up a bit. For RFC2307bis, even if nested groups are not used (IIRC nested groups were never really part of RFC2307bis), sssd still needs to make an LDAP lookup for every single member to correctly populate the gr_mem attribute of the struct group, you can't create any fake entries in the sssd cache for that (the fake user approach only works with plain old RFC2307 groups).
Any comments on the API are welcome, including thoughts on how to make it more elegant. Originally, I wanted to implement it as gid_t getgidbyname(const char *name) etc., but I would have to redo some parts of the NSS infrastructure to easily allow returning gid_t instead of a struct.
If there is a consensus that this is a good idea and Ulrich gives his blessing, I will of course extend the patch to be compatible with older NSS modules and add NIS support and nscd support.
I'm really not sure what the value of this approach is. Realistically, you're talking about creating an interface whose sole purpose is to map GID<->groupname and nothing else?
Yes.
I'm not sure there's sufficient value in this approach, given that it's possible as described above to limit the network requests. I think it makes much more sense to guide the respective name-service providers along the path of handling these requests more efficiently.
That's the problem, for e.g. RFC2307bis this can't be done more efficiently in a reliable manner (see the recent discussion around getgrgid/getgrnam() on the sssd-devel list). So as most callers of getgrnam/getgrgid don't use the member information anyways I think such gid<->groupname mapping function could be quite useful.
I'm expanding this mailing to include the sssd-devel list for broader discussion.
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 10/19/2010 09:09 AM, Ralf Haferkamp wrote:
The net result is that we will report all of the users that belong in a group, but we will not make additional requests to populate those users unless they are directly requested.
Yes, for groups that have many thousands of users, we may make a single request that transfers a couple hundred kilobytes, but we do not make subsequent requests for each of those users in turn.
RFC2307bis servers require slightly more processing, as we need to make multiple requests to LDAP if there are nested groups in play. But we never make more requests than the configured nesting limit.
I think your are mixing things up a bit. For RFC2307bis, even if nested groups are not used (IIRC nested groups were never really part of RFC2307bis), sssd still needs to make an LDAP lookup for every single member to correctly populate the gr_mem attribute of the struct group, you can't create any fake entries in the sssd cache for that (the fake user approach only works with plain old RFC2307 groups).
Sorry, you are correct. I forgot that we have to validate the DNs for the RFC2307bis users. So for RFC2307bis, I suppose I can see some value in this approach.
Any comments on the API are welcome, including thoughts on how to make it more elegant. Originally, I wanted to implement it as gid_t getgidbyname(const char *name) etc., but I would have to redo some parts of the NSS infrastructure to easily allow returning gid_t instead of a struct.
If there is a consensus that this is a good idea and Ulrich gives his blessing, I will of course extend the patch to be compatible with older NSS modules and add NIS support and nscd support.
I'm really not sure what the value of this approach is. Realistically, you're talking about creating an interface whose sole purpose is to map GID<->groupname and nothing else?
Yes.
I'm not sure there's sufficient value in this approach, given that it's possible as described above to limit the network requests. I think it makes much more sense to guide the respective name-service providers along the path of handling these requests more efficiently.
That's the problem, for e.g. RFC2307bis this can't be done more efficiently in a reliable manner (see the recent discussion around getgrgid/getgrnam() on the sssd-devel list). So as most callers of getgrnam/getgrgid don't use the member information anyways I think such gid<->groupname mapping function could be quite useful.
My main concern with adding a new interface would be buy-in from all of the assorted name-service providers (nss_nis, nss_ldap, etc.). Lets be honest: even if we created this new interface, the most likely outcome is that the libraries are just going to continue processing the way that they do already, and then just reply with a limited subset of the results.
Creating the groups in our SSSD cache without including membership information introduces integrity issues when we're dealing with offline operation, for example. If access control for some application relies on group membership, but our cache only has reference to the group and its GID, without a list of members, then when we're offline and can't request further information, we'll improperly deny access.
- -- Stephen Gallagher RHCE 804006346421761
Delivering value year after year. Red Hat ranks #1 in value among software vendors. http://www.redhat.com/promo/vendor/
On Tue, 19 Oct 2010 09:59:21 -0400 Stephen Gallagher sgallagh@redhat.com wrote:
My main concern with adding a new interface would be buy-in from all of the assorted name-service providers (nss_nis, nss_ldap, etc.). Lets be honest: even if we created this new interface, the most likely outcome is that the libraries are just going to continue processing the way that they do already, and then just reply with a limited subset of the results.
The main concern here I think is that of making a substantial effort to change a lot of applications to use an interface that is only marginally better for just one use case. I am not sure it is worth the effort given the very meager gains you get.
Creating the groups in our SSSD cache without including membership information introduces integrity issues when we're dealing with offline operation, for example. If access control for some application relies on group membership, but our cache only has reference to the group and its GID, without a list of members, then when we're offline and can't request further information, we'll improperly deny access.
This shouldn't be a real problem, as all group memberships relevant to logged in users must be fetched at login time. And only users that previously logged in are allowed to login again or keep stay logged when offline.
Simo.
On Tue, 19 Oct 2010 15:09:48 +0200 Ralf Haferkamp rhafer@suse.de wrote:
That's the problem, for e.g. RFC2307bis this can't be done more efficiently in a reliable manner (see the recent discussion around getgrgid/getgrnam() on the sssd-devel list). So as most callers of getgrnam/getgrgid don't use the member information anyways I think such gid<->groupname mapping function could be quite useful.
I agree on this point. I think such interfaces may have some merit. Although it is clear that they would have a very limited impact on performance until most applications are switched to use these interfaces. And that could take a very long time.
I wonder if it wouldn't be better to start thinking of a completely new approach instead. something that takes in account the need to deal with multiple domains, that ditches enumeration in favor of targeted searches (filter based). Something that can get us out of the dark ages of POSIX where the user database is only local to the machine and there is no concept of local vs network/domain/ldap/makeyourown users that come from an external source.
Simo.
sssd-devel@lists.fedorahosted.org