#647 Add user and group search LDAP filter options
Closed: Fixed None Opened 8 years ago by nixfu.

A filter is needed to the default searches for users and groups.

The existing ldap_auth_filter does not serve this purpose.

A filter is needed to also filter the results returned on searching and enumberating the user and group lists such as the ones that nss_ldap has.

This will also limit the amount of data that sssd client requests from the LDAP server and that is returned to nss and pam.

Example: I want a system to restrict itself to only users that have gid=1001 or gid=1002.

ldap_user_search_filter = |(gidNumber=1001)(gidNumber=9002)

ldap_group_search_filter = [also combined with ldap_group_search_base to all group queries]

This would be combined with ldap_user_search_base to perform all queries. Right now sssd does all queries with ldap_user_search_base + objectClass=posixAccount.

By adding these filters the searches will be much more efficient and there will be no reason to query the ldap for all users in the directory or for users that are outside of the desired auth_filter scope.


Fields changed

type: defect => enhancement

I recently answered this question elsewhere, so I'm including that summary below.

1) Even if users aren't eligible to log into a particular system, it
still often makes sense for them to be able to identify the owner of
files on a shared filesystem. By allowing user lookups of all users, we
allow this information to be presentable to the user.
2) Client-side filtering of which user accounts are or are not visible
provides a false sense of security. Sure, the users won't appear in a
simple getent call, but there's nothing preventing a user from asking
LDAP directly.

If filtering of users out of identity lookups IS necessary for one
reason or another, then there are two correct ways to do this.

1) Configure it so that users visible by anonymous bind exist in one
LDAP subtree, while restricted users live in a higher level of the tree.
e.g. you might have:
ou=Accounts,dc=example,dc=com
and then a subset:
ou=public_users,ou=Accounts,dc=example,dc=com

In this case, you would configure SSSD with
ldap_search_base = dc=example,dc=com
ldap_user_search_base = ou=public_users,ou=Accounts,dc=example,dc=com

on the systems that need to have the restricted users. Note that this
approach does not address the issue of users querying LDAP directly.

2) The more-complicated-but-more-secure-approach would be to set up ACIs
on the LDAP server specifying which LDAP bind accounts have access to
read which entries. This approach also does not necessarily require
reorganizing the tree structure, as ACIs can be set at any level.

In this case, you would configure SSSD with
ldap_search_base = dc=example,dc=com
ldap_default_bind_dn = cn=restricted_hosts,ou=Hosts,dc=example,dc=com
ldap_default_authtok = supersecretpassword

Thus the SSSD would bind as an LDAP account with privileges limited by
the ACIs.

In most cases, 2) is the preferred approach, as it is the most secure.
Because the user accounts are controlled by ACIs, it also protects
against direct access of LDAP.

Can you provide an example why you would need to limit the information available to NSS? If you're not running with {{{enumerate = true}}} in your sssd.conf, then there would be no performance increase in any case.

Sorry, better formatted:

I recently answered this question elsewhere, so I'm including that summary below.

  1. Even if users aren't eligible to log into a particular system, it still often makes sense for them to be able to identify the owner of files on a shared filesystem. By allowing user lookups of all users, we allow this information to be presentable to the user.
  2. Client-side filtering of which user accounts are or are not visible provides a false sense of security. Sure, the users won't appear in a simple getent call, but there's nothing preventing a user from asking LDAP directly.

If filtering of users out of identity lookups IS necessary for one
reason or another, then there are two correct ways to do this.

1) Configure it so that users visible by anonymous bind exist in one LDAP subtree, while restricted users live in a higher level of the tree. e.g. you might have:

ou=Accounts,dc=example,dc=com

and then a subset:

ou=public_users,ou=Accounts,dc=example,dc=com

In this case, you would configure SSSD with

ldap_search_base = dc=example,dc=com
ldap_user_search_base = ou=public_users,ou=Accounts,dc=example,dc=com

on the systems that need to have the restricted users. Note that this approach does not address the issue of users querying LDAP directly.

2) The more-complicated-but-more-secure-approach would be to set up ACIs on the LDAP server specifying which LDAP bind accounts have access to read which entries. This approach also does not necessarily require reorganizing the tree structure, as ACIs can be set at any level.
In this case, you would configure SSSD with

ldap_search_base = dc=example,dc=com
ldap_default_bind_dn = cn=restricted_hosts,ou=Hosts,dc=example,dc=com
ldap_default_authtok = supersecretpassword

Thus the SSSD would bind as an LDAP account with privileges limited by
the ACIs.

In most cases, 2) is the preferred approach, as it is the most secure.
Because the user accounts are controlled by ACIs, it also protects
against direct access of LDAP.

Can you provide an example why you would need to limit the information available to NSS? If you're not running with {{{enumerate = true}}} in your sssd.conf, then there would be no performance increase in any case.

Ok. Well, after reading and re-reading your response I think I understand a little better.

The old nss_ldap philosophy was that you could only see the users that could login to the system via getent.

Your philosophy is that enumerate should always be disabled so you could never get a full list of users via getent, and all LDAP calls should be for one user at a time(via getpwnam, or getent, etc.

I think I can see some validity in that approach, in that like you said files will always show ownership, never numberic ids etc.

I guess the one concern I would have is that there IS a bit of an extra load generated on the LDAP servers by having every client have access to the entire directory, because in my testing it seems that sssd on every box will potentially cache every user in the LDAP. Maybe that will not happen if enumerate was not on, I don't know for sure I will test. It's possible that ldap_auth_filter may work properly to then limit who can login and try your philosophy out.

The way that we do LDAP access is we attach an ou to every users People entry such as ou=appxdev, ou=mqserver, ou=oraclesvrs and then users get access to any servers that have those ou's configured in their search filters for nss. like |(ou=oraclesvrs)(ou=appxdeev), and that would allow both users who are developers for Appx(who have ou=appxdev attached to their People entry, and the oracle DBA's(who have ou=oraclesvrs on their People entry) access to the system.

This is much much more efficient than the old host= People thing to limit people by hostname. That breaks down in a Fortune50 size environment like I work in.

I did think of one other way that might be possible for sssd to handle both philosophy and allow people who wanted to have enumerate on to function.

If the ldap_user_search_base and ldap_group_search_base would accept full LDAP search strings including optional limits such as: "ou=People,o=ourcompany?one?|(gidNumber=1001)(ou=allsystems)" instead of "ou=People,o=ourcompany" it would be intuitive.

This is exactly how you limited queries on the old NSS_LDAP by setting user and group search bases that included filters.

That would eliminate any need for an additional parameter in the design.

Replying to [comment:4 nixfu]:

Ok. Well, after reading and re-reading your response I think I understand a little better.

The old nss_ldap philosophy was that you could only see the users that could login to the system via getent.

Your philosophy is that enumerate should always be disabled so you could never get a full list of users via getent, and all LDAP calls should be for one user at a time(via getpwnam, or getent, etc.

I think I can see some validity in that approach, in that like you said files will always show ownership, never numberic ids etc.

I guess the one concern I would have is that there IS a bit of an extra load generated on the LDAP servers by having every client have access to the entire directory, because in my testing it seems that sssd on every box will potentially cache every user in the LDAP. Maybe that will not happen if enumerate was not on, I don't know for sure I will test. It's possible that ldap_auth_filter may work properly to then limit who can login and try your philosophy out.

The way that we do LDAP access is we attach an ou to every users People entry such as ou=appxdev, ou=mqserver, ou=oraclesvrs and then users get access to any servers that have those ou's configured in their search filters for nss. like |(ou=oraclesvrs)(ou=appxdeev), and that would allow both users who are developers for Appx(who have ou=appxdev attached to their People entry, and the oracle DBA's(who have ou=oraclesvrs on their People entry) access to the system.

This is much much more efficient than the old host= People thing to limit people by hostname. That breaks down in a Fortune50 size environment like I work in.

I did think of one other way that might be possible for sssd to handle both philosophy and allow people who wanted to have enumerate on to function.

If the ldap_user_search_base and ldap_group_search_base would accept full LDAP search strings including optional limits such as: "ou=People,o=ourcompany?one?|(gidNumber=1001)(ou=allsystems)" instead of "ou=People,o=ourcompany" it would be intuitive.

This is exactly how you limited queries on the old NSS_LDAP by setting user and group search bases that included filters.

That would eliminate any need for an additional parameter in the design.

Do we understand it correctly that this is an enhancement that we can look at a bit later and put into the 1.6 bucket or so? Current set for the 1.5 release is pretty bug and we are a bit swamped with the amount of work we need to do in several upcoming months.

Fields changed

milestone: NEEDS_TRIAGE => SSSD Deferred

I'm moving this back into NEEDS_TRIAGE so we can discuss where it belongs in the schedule.

Something that was recently discussed elsewhere was the topic of sharing a single user database among users with multiple possible authentication mechanisms.

For example, users whose LDAP entry contains an attribute for OTPTokenID (for example) should be authenticated using an OTP authentication mechanism, while other users should default to password authentication.

We could do this by including these filters in the ID provider, thereby making it so that only users with certain attributes would be recognized in a particular SSSD domain.

For example:

[sssd]
domains = example.com-OTP, example.com

[domain/example.com-OTP]
id_provider = ldap
ldap_uri = ldap://ldap.example.com
ldap_user_filter = (OTPToken=*)
auth_provider = otp

[domain/example.com]
ldap_uri = ldap://ldap.example.com
ldap_user_filter = (OTPToken=*)
auth_provider = ldap

In this case, all users would still be caught by the {{{example.com}}} domain, but by specifying {{{example.com-OTP}}} first in the {{{domains =}}} line, we would make it so that users who matched that filter would be authenticated with the {{{otp}}} provider.

milestone: SSSD Deferred => NEEDS_TRIAGE

My apologies, my example above was incorrect.

[sssd]
domains = example.com-OTP, example.com

[domain/example.com-OTP]
id_provider = ldap
ldap_uri = ldap://ldap.example.com
ldap_user_filter = (OTPToken=*)
auth_provider = otp

[domain/example.com]
id_provider = ldap
ldap_uri = ldap://ldap.example.com
auth_provider = ldap

Fields changed

milestone: NEEDS_TRIAGE => SSSD 1.6.0

Fields changed

coverity: =>
owner: somebody => jhrozek
priority: major => critical
upgrade: => 0

master: 361b29f

patch: => 0
resolution: => fixed
status: new => closed

This ticket was obsoleted by #868

blockedby: =>
blocking: => 868
rhbz: => 0

Metadata Update from @nixfu:
- Issue assigned to jhrozek
- Issue marked as blocked by: #868
- Issue set to the milestone: SSSD 1.6.0

2 years ago

Login to comment on this ticket.

Metadata