From 69e1f5fe79806a530e90c8af09bedd3b9e6b4dac Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 10 Jul 2020 15:30:29 +0200
Subject: [PATCH] GPO: respect ad_gpo_implicit_deny when evaluation rules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently if setting ad_gpo_implicit_deny to 'True' is rejected access
if no GPOs applied to the host since in this case there are obvious not
allow rules available.
But according to the man page we have to be more strict "When this
option is set to True users will be allowed access only when explicitly
allowed by a GPO rule". So if GPOs apply and no allow rules are present
we have to reject access as well.
Resolves: https://github.com/SSSD/sssd/issues/5061
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/man/sssd-ad.5.xml | 59 +++++++++++++++++++++++++++++++++++++++
src/providers/ad/ad_gpo.c | 13 +++++++--
2 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 5c2f46546..fbd4985d7 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -477,9 +477,68 @@ DOM:dom1:(memberOf:1.2.840.113556.1.4.1941:=cn=nestedgroup,ou=groups,dc=example,
built-in Administrators group if no GPO rules
apply to them.
</para>
+
<para>
Default: False
</para>
+
+ <para>
+ The following 2 tables should illustrate when a user
+ is allowed or rejected based on the allow and deny
+ login rights defined on the server-side and the
+ setting of ad_gpo_implicit_deny.
+ </para>
+ <informaltable frame='all'>
+ <tgroup cols='3'>
+ <colspec colname='c1' align='center'/>
+ <colspec colname='c2' align='center'/>
+ <colspec colname='c3' align='center'/>
+ <thead>
+ <row><entry namest='c1' nameend='c3' align='center'>
+ ad_gpo_implicit_deny = False (default)</entry></row>
+ <row><entry>allow-rules</entry><entry>deny-rules</entry>
+ <entry>results</entry></row>
+ </thead>
+ <tbody>
+ <row><entry>missing</entry><entry>missing</entry>
+ <entry><para>all users are allowed</para>
+ </entry></row>
+ <row><entry>missing</entry><entry>present</entry>
+ <entry><para>only users not in deny-rules are
+ allowed</para></entry></row>
+ <row><entry>present</entry><entry>missing</entry>
+ <entry><para>only users in allow-rules are
+ allowed</para></entry></row>
+ <row><entry>present</entry><entry>present</entry>
+ <entry><para>only users in allow-rules and not in
+ deny-rules are allowed</para></entry></row>
+ </tbody></tgroup></informaltable>
+
+ <informaltable frame='all'>
+ <tgroup cols='3'>
+ <colspec colname='c1' align='center'/>
+ <colspec colname='c2' align='center'/>
+ <colspec colname='c3' align='center'/>
+ <thead>
+ <row><entry namest='c1' nameend='c3' align='center'>
+ ad_gpo_implicit_deny = True</entry></row>
+ <row><entry>allow-rules</entry><entry>deny-rules</entry>
+ <entry>results</entry></row>
+ </thead>
+ <tbody>
+ <row><entry>missing</entry><entry>missing</entry>
+ <entry><para>no users are allowed</para>
+ </entry></row>
+ <row><entry>missing</entry><entry>present</entry>
+ <entry><para>no users are allowed</para>
+ </entry></row>
+ <row><entry>present</entry><entry>missing</entry>
+ <entry><para>only users in allow-rules are
+ allowed</para></entry></row>
+ <row><entry>present</entry><entry>present</entry>
+ <entry><para>only users in allow-rules and not in
+ deny-rules are allowed</para></entry></row>
+ </tbody></tgroup></informaltable>
</listitem>
</varlistentry>
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 2c6aa7fa6..0cf5da2a1 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -1531,6 +1531,7 @@ ad_gpo_access_check(TALLOC_CTX *mem_ctx,
enum gpo_access_control_mode gpo_mode,
enum gpo_map_type gpo_map_type,
const char *user,
+ bool gpo_implicit_deny,
struct sss_domain_info *domain,
char **allowed_sids,
int allowed_size,
@@ -1575,7 +1576,7 @@ ad_gpo_access_check(TALLOC_CTX *mem_ctx,
group_sids[j]);
}
- if (allowed_size == 0) {
+ if (allowed_size == 0 && !gpo_implicit_deny) {
access_granted = true;
} else {
access_granted = check_rights(allowed_sids, allowed_size, user_sid,
@@ -1694,6 +1695,7 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx,
enum gpo_access_control_mode gpo_mode,
enum gpo_map_type gpo_map_type,
const char *user,
+ bool gpo_implicit_deny,
struct sss_domain_info *user_domain,
struct sss_domain_info *host_domain)
{
@@ -1732,8 +1734,8 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx,
/* perform access check with the final resultant allow_sids and deny_sids */
ret = ad_gpo_access_check(mem_ctx, gpo_mode, gpo_map_type, user,
- user_domain, allow_sids, allow_size, deny_sids,
- deny_size);
+ gpo_implicit_deny, user_domain,
+ allow_sids, allow_size, deny_sids, deny_size);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
@@ -1918,6 +1920,7 @@ immediately:
static errno_t
process_offline_gpos(TALLOC_CTX *mem_ctx,
const char *user,
+ bool gpo_implicit_deny,
enum gpo_access_control_mode gpo_mode,
struct sss_domain_info *user_domain,
struct sss_domain_info *host_domain,
@@ -1930,6 +1933,7 @@ process_offline_gpos(TALLOC_CTX *mem_ctx,
gpo_mode,
gpo_map_type,
user,
+ gpo_implicit_deny,
user_domain,
host_domain);
if (ret != EOK) {
@@ -1976,6 +1980,7 @@ ad_gpo_connect_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n");
ret = process_offline_gpos(state,
state->user,
+ state->gpo_implicit_deny,
state->gpo_mode,
state->user_domain,
state->host_domain,
@@ -2102,6 +2107,7 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n");
ret = process_offline_gpos(state,
state->user,
+ state->gpo_implicit_deny,
state->gpo_mode,
state->user_domain,
state->host_domain,
@@ -2766,6 +2772,7 @@ ad_gpo_cse_done(struct tevent_req *subreq)
state->gpo_mode,
state->gpo_map_type,
state->user,
+ state->gpo_implicit_deny,
state->user_domain,
state->host_domain);
if (ret != EOK) {
--
2.21.3