On Tue, May 28, 2013 at 01:20:15PM +0200, Sumit Bose wrote:
I have created a design page for one of the next major features of SSSD
basic idea is that if SSSD is running on a FreeIPA server it should help
the FreeIPA server to look up users and groups from trusted domains.
For your convenience the content can be found below as well.
Comments are suggestions are welcome.
== IPA Server Mode ==
RFE Allow using UIDs and GIDs from AD in
RFE Determine how to map SID to UID/GID
based on IdM server configuration]
* more to come
I like the design page, I think it sums up everything we talked about
=== Problem Statement ===
FreeIPA is planning to make users and groups from trusted domains available to legacy
systems, e.g. systems where only nss_ldap and pam_ldap are available. For this a new
directory server plugin ([https://fedorahosted.org/freeipa/ticket/3567
]) will accept the
LDAP search request from the legacy systems for the trusted users and groups, resolve the
requested objects and send the result back to the legacy client.
Since all trusted users and groups are resolvable on the IPA server via the SSSD IPA
provider the idea is that the new plugin will just run getpwnam_r(), getgrnam_r() and
related calls. The SSSD disk and memory cache will help to answer those request fast
without the need of additional caching inside the directory server.
To offer reliable group lookups to legacy systems it must be possible to lookup all the
members of a group from a trusted domain and not only show members which already logged in
once on the FreeIPA server, which is the current status on IPA clients with a recent
version of SSSD. Additionally legacy systems tend to rely on user and group enumerations.
Both requirements force an enumeration and caching of all trusted users and groups on the
If the legacy systems used an algorithmic mapping scheme based on the RID of the AD
object and an offset to find a POSIX ID for the trusted user or group the
''--base-id'' of the ''ipa trust-add'' command can be used
to get the same ID mapping. For legacy systems which read the POSIX IDs directly from AD a
new idrange type must be introduced on the FreeIPA server
]) to indicate that for those trusted users
an groups the POSIX ID must be read from AD.
All of the above can basically be solved with the current layout of the FreeIPA server
where winbind is doing the lookups against AD and SSSD is using the extdom LDAP plugin to
read this data via the directory server. But it was decided to enhance SSSD to do the
lookup. Some of the reasons are:
* resources, since SSSD has to run anyway on the FreeIPA server and is capable of the AD
user and group lookups, winbind does not have to run anymore
* avoid double caching, to work efficiently winbind has to do some caching on its own and
as a result users and groups are cached twice on the FreeIPA server
* configuration, winbind uses a separate configuration file while the IPA provider of
SSSD can read e.g. the idranges directly from the FreeIPA server, this minimized to
configuration effort and avoids conflicting configuration of different components
=== Overview of the solution ===
First sssd needs to know that it is running on an IPA server and should not look up
trusted users and groups with the help of the extdom plugin but do the lookups on its own.
For this a new boolean configuration option, e.g. ipa_server_mode, should be introduced
('''SSSD ticket#''') which defaults to ''false''
but is set to ''true'' during ipa-server-install or during updates of the
FreeIPA server ([https://fedorahosted.org/freeipa/ticket/3652
]) if it is not already set.
Since AD by default requires an authenticate LDAP bind to do searches SSSD needs
credentials which are accepted by a trusted AD server. Because if the trust relationship
this can even be credentials from the FreeIPA domain if Kerberos is user for
authentication. So the easiest way is just to use the local keytab which requires no
changes on the SSSD side, because the generic LDAP provider already knows how to handle
SASL bind with the local keytab.
But currently AD LDAP server does not accept the Kerberos ticket from a FreeIPA host,
because the FreeIPA KDC does not attach a PAC to the TGTs of host/ principals
], until this is fixed some dummy
credentials, e.g. a keytab for a dummy user, can be used).
Now the AD provider code can be used to lookup up the users and group of the trusted AD
domain. Only the ID-mapping logic should be refactored so that the same code can be used
in the standalone AD provider where the configuration is read form ssd.conf and as part of
the IPA provider where the idrange objects read from the IPA server dictates the mapping.
Maybe libsss_idmap can be extended to handle idranges for mappings in AD as well, e.g. a
specific error code can be used to indicate to the caller that for this domain no
algorithmic mapping is available and the value from the corresponding AD attribute should
be use ('''SSSD ticket?''').
A task (or a separate process) must be created to handle enumerations efficiently without
having to much impact on parallel running requests ('''SSSD
ticket#'''). Maybe we can find a scheme which allows to read only a limited
(configurable) number of users with their group memberships at a time. This way the cache
might not be complete at once but always consistent with respect to group memberships of
the caches users. If eventually all users are read, the task will periodically look for
new users and update old entries.
=== Implementation details ===
==== Add ipa_server_mode option ====
A new boolean option ipa_server_mode which defaults to false should
be added to the IPA provider. ipa_get_subdom_acct_send() should only
be called if ipa_server_mode is false. If ipa_server_mode is true
ipa_account_info_handler() should return ENOSYS for subdomain requests. A
suitable tevent request will be handled in a different ticket.
Ack, this one sounds easy. The next ticket that handles the suitable
tevent request is described in integrating the AD provider lookup code,
==== Enhance libsss_idmap ====
1. Allow algorithmic mapping where the first RID is not 0
Currently it is implicitly assumed that the first POSIX ID of a range
is mapped to the RID 0. To support multiple ranges for a single domain a
different first RID must handled as well.[[BR]]
2. Add a range type to handle mappings in AD
Sorry, it's not quite clear to me what 2. is ? Does it talk about the
plugin interface described also in the next paragraph?
==== Add plugin to LDAP provider to find new ranges ====
Currently the range management code is in the generic LDAP provider and
can be used by the LDAP and AD provider. New ranges are allocated with
the help of a hash value of the domain SID.
If the IPA provider cannot find a range for a given domain it cannot
allocate a new range on its own but has to look up the idrange objects
on the FreeIPA server and use them accordingly. To allow the LDAP, AD
and IPA provider to use as much common code as possible I think a plugin
interface, similar to the one used to find the DNS site, to find a missing
range would be useful. The default plugin will be used by the LDAP and the
AD provider and the IPA provider will implement a plugin to read the data
from the server.
I like this design.
==== Integrate AD provider lookup code into IPA subdomain user lookup
If the ipa_server_mode is selected IPA subdomain user and group lookups
should not be done with the help of the extdom plugin but directly against
AD with the help of LDAP of GC lookups. For this the IPA provider must
be able to call the related functions from the AD provider. Since by
default the POSIX attributes are not replicated to the global catalog
and supporting them is a requirement, I think it would be sufficient make
sure LDAP lookups are working as expected. Additionally FreeIPA currently
supports only one trusted domain global catalog lookups for users and
groups from the forest or different forests can be added later.
How would the IPA provider know which servers to contact? Does IPA
export this info in some kind of trust config object since the AD site
lookups integration is optional feature?
Since the Kerberos hosts keys from the host keytab should be used as
credentials to access AD no changes are expected here.
It should be taken care that not accidentally the the AD SRV plugin is
loaded, see next section as well.
==== Enhance IPA SRV plugin to do AD site lookups as well ====
From the AD point of view trusted domains do not belong to a specific
site. But recent version of AD return the next_closest_site for host which
do not belong to a site. To make sure that SSSD is communication with an
AD server which is network-wise reasonably near it would be useful if the
IPA SRV plugin can be enhanced to do CLDAP pings and AD site lookups as
well. Additionally the plugin must know when to use IPA style and when AD
Maybe we could chain the existing plugins? I think the plugin
architecture would allow mixing different lookup types.
This is a nice to have feature.
Yes, I agree, I think we could do the design now to see if implementing
this feature would require other changes in the failover code.
==== Implement or Improve enumeration ====
If enumeration is enable SSSD tries to update all users and groups at
startup. As a result the startup time where SSSD is basically blocked and
cannot serve requests even for data in the cache can be quite long. A new
tevent_req task should be created which can read users and groups from the
AD domain in smaller chunks so that other request can always slip in between.
Maybe we could reuse existing ticket
for this feature?
The task should make sure all users and groups are read after a
without reading objects twice in a single run. Maybe it is possible to
add a special paged-search tevent request which returns after the first
page is read to the caller (instead of doing the paging behind the scenes)
which the results and a handle which would allow to continue the the search
with the next page? If this is a way to go creating this new request would
be another development subtask.
Yes, I was considering about similar design when I was thinking about #1829.
Maybe we could do the enumeration only for the trusted domains so that
it would run on the background only. Then we wouldn't have to worry
about how to handle getpwent/getgrent requests towards the frontend.
Additionally it has to be considered how to handle large groups. But
since we have to read all user as well it might be possible to just read
the group memberships of the user and build up the groups in the SSSD
cache and let the getgrp*() calls only return entries from the cache and
never go to the server directly.
As seen in how to test, this would make the SSSD return incomplete group
memberships, isn't that a potential issue for access control?
=== How to test ===
If the ipa_server_mode is enable on a FreeIPA server which trusts an AD server,
''getent passwd AD\username'' or ''id AD\username'' should
return the expected results for users and groups.
''getent group AD\groupname'' should return results depending the state
of enumeration. Immediately after startup with an empty cache e.g. the 'Domain
User' group should only have a few members if any. After some time more and more
members should be displayed until the enumeration is complete and all users and groups are
in the SSSD cache.
=== Author(s) ===
Sumit Bose <sbose(a)redhat.com>
sssd-devel mailing list