Warning
This is a design page. It was used to design and discuss the initial implementation of the change. However, the state of this document does not necessarily correspond to the current state of the implementation since we do not keep this document up to date with further changes and bug fixes.
Adding the ad_access_filter option
Related ticket(s):
Somewhat related:
Problem Statement
The recommended way of connecting a GNU/Linux client to an Active Directory domain is using the AD provider. However, in the default configuration of the Active Directory provider, only account expiration is checked. Very often, the administrator needs to restrict the access to the client machine further, limiting the access to a certain user, group of users, or using some other custom filtering mechanism. In order to do so, the administrator is required to use an alternative access control provider. However, none of the alternatives provide the full required functionality for all users resolvable by the AD provider, moreover they are hard to configure. This design page proposes extension of the AD access provider to address these concerns.
Current access control options
With the existing SSSD, the administrator has two basic means to restrict access control to the GNU/Linux client - using the simple access control provider or configuring the LDAP access control provider. Each approach has its pros and cons.
Using the simple access provider
The simple access provider grants or denies access based on the contents of allow and deny lists. There are separate lists for user and group names as well as allowed and denied objects.
The following example shows configuration that grants access to user
named tux
and group called linuxadmins
.
access_provider = simple
simple_allow_users = tux
simple_allow_groups = linuxadmins
Pros:
Easy to configure
Realmd provides an interface to configure the simple access provider using its CLI
Cons:
Account expiration is not checked
Limited expressiveness. No way to combine several clauses
Does not align with the LDAP structure the Active Directory uses
Using the LDAP access provider
The LDAP access provider offers a way to configure the access control decision based on whether the user matches a preconfigured filter. Moreover, the LDAP access provider also offers chaining other LDAP based checks. For the vanilla AD environment, only account expiration check applies.
The following example illustrates configuration that allows access to
those users, who are members of group named linuxadmins
AND have a
valid home directory set using the ldap_access_filter
directive. The
users who match the configured filter are also checked whether they are
expired (ldap_access_order
contains expire
).
access_provider = ldap
ldap_access_order = filter, expire
ldap_account_expire_policy = ad
ldap_access_filter = (&(memberOf=cn=admins,ou=groups,dc=example,dc=com)(unixHomeDirectory=*))
ldap_sasl_mech = GSSAPI
ldap_sasl_authid = CLIENT_SHORTNAME$@EXAMPLE.COM
ldap_schema = ad
Pros:
Allows the administrator to base access control on a custom LDAP filter, making it possible to combine several conditions
Conditions are not limited to user names or group membership
Cons:
Nontrivial and clumsy configuration that must include several low level LDAP settings, otherwise set automatically by the AD provider. Defeats the whole purpose of the AD provider
The admin needs to combine AD and LDAP providers. Judging by experience from triaging support cases with Red Hat support, this is a problem for many admins.
Account expiration check must be configured separately, which is not obvious
No support for users from trusted AD domains
No realmd integration
Proposed solution
The proposal is to add a new access filter configuration option to the
existing AD access provider. Adding the option to the AD provider would
greatly simplify the configuration when compared to the LDAP access
control, while maintaining the full expressiveness of
ldap_access_filter
. The new option would be called
ad_access_filter
. If the new option was set, then the AD access
provider would first match the entry against the filter in that option.
If the entry matched, then the account would be checked for expiration.
The following example illustrates an example similar to the one above, using the proposed AD options:
access_provider = ad
ad_access_filter = (&(memberOf=cn=admins,ou=groups,dc=example,dc=com)(unixHomeDirectory=*))
The main advantage is simplified configuration. The admin doesn’t have to know or understand what “SASL ID” is.
In comparison with the two legacy solutions explained above:
Pros
Easy and intuitive configuration. Only one provider type is configured
Sane defaults - always checks for expiration, also checks access filter if configured that way
Would support users and groups from trusted domains by leveraging the existing AD provider infrastructure
Cons
No realmd integration
Realmd integration
After a short discussion with the realmd upstream maintainer, it was decided that these options do not fit the realmd use-cases well. If the user needs to use such advanced techniques as LDAP filters, chances are that he doesn’t need a tool like realmd to set them up in the config file.
Implementation details
The default value of what AD access_provider is set to should be changed
Currently, if
access_provider
is not set explicitly, the default ispermit
, thus allowing even expired accountsThe new default would be
ad
, checking account expiration even with a minimal configuration
A new option would be added. The new option would be called
ad_access_filter
The LDAP access provider must be extended to allow connecting to a GC and support subdomains in general
Pass in
struct sdap_domain
andid_conn
instead of using the connection fromsdap_id_ctx
directlyThe code must not read the
sss_domain_info
frombe_ctx
but only fromsdap_domain
in order to support subdomain users
The AD access provider must call the improved LDAP access provider internally with the right connection
The default should be GC
If POSIX attributes are in use and GC lookup wouldn’t match, optionally fall back to LDAP. This fallback could be tried just once to speed up subsequent access control
The default chain of LDAP access filter the AD provider sets internally must be changed.
Currently AD provider sets
ldap_access_order=expire
. If (and only if)ad_access_filter
was set, the LDAP chain would becomeldap_access_order=filter,expire
None
The
ad_access_filter
option is a comma-separated list of filters that apply globally, per-domain or per-forest. The most specific match is usedIf the
ad_access_filter
value starts with an opening bracket(
, it is used as a filter for all entries from all domains and forestsexample:
(&(memberOf=cn=admins,ou=groups,dc=example,dc=com)(unixHomeDirectory=*))
More advanced format can be used to restrict the filter to a specific domain or a specific forest. This format is
KEYWORD:NAME:FILTER
KEYWORD can be one of
DOM
orFOREST
KEYWORD can be missing
NAME is a label.
if KEYWORD equals
DOM
or missing completely, the filter is applied for users from domain named NAME onlyif KEYWORD equals
FOREST
, the filter is applied on users from forest named NAME only
examples of valid filters are:
apply filter on domain called dom1 only:
dom1:(memberOf=cn=admins,ou=groups,dc=dom1,dc=com)
apply filter on domain called dom2 only:
DOM:dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com)
apply filter on forest called EXAMPLE.COM only:
FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com)
If no filter matches the user’s domain, access is denied
example
ad_access_filter = dom1:(memberOf=cn=admins,ou=groups,dc=dom1,dc=com), dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com)
, user logs in from dom3
Contingency plan
None needed. The existing options would still exist and function as they do now.
How to test
Check that
access_provider=ad
without any other options allows non-expired usersCheck that
access_provider=ad
without any other options denies expired usersTest that setting
ad_access_filter
restricts access to users who match the filtertest that an expired user, even though he matches the filter, is denied access
this test must include users from the primary domain as well as a sub domain
Different filters should be tested to make sure the most specific filter applies
example: add a restrictive filter for dom1 and permissive filter without specifying the domain. A user from dom1 must be denied access, while a user from other domain must be allowed access
When access is denied, the SSSD PAM responder must return a reasonable return code (6)
Future and optional enhancements
In the future, we should extend the access_provider
option itself
and allow chaining access providers. This enhancement would allow even
more flexibility and would allow the administrator to combine different
access providers, but is outside the scope of the change described by
this design page.
Author(s)
Jakub Hrozek <jhrozek@redhat.com>
Sumit Bose <sbose@redhat.com>