URL: https://github.com/SSSD/sssd/pull/5485
Author: pbrezina
 Title: #5485: sudo: do not search by low usn value to improve performance
Action: opened

PR body:
"""
This is a follow up on these two commits.

- 819d70ef6e6fa0e736ebd60a7f8a26f672927d57
- 6815844daa7701c76e31addbbdff74656cd30bea

The first one improved the search filter little bit to achieve better
performance, however it also changed the behavior: we started to search
for `usn >= 1` in the filter if no usn number was known.

This caused issues on OpenLDAP server which was fixed by the second patch.
However, the fix was wrong and searching by this meaningfully low number
can cause performance issues depending on how the filter is optimized and
evaluated on the server.

Now we omit the usn attribute from the filter if there is no meaningful value.

How to test:
1. Setup LDAP with no sudo rules defined
2. Make sure that the LDAP server does not support USN or use the following diff
   to enforce modifyTimestamp (last USN is always available from rootDSE)
```diff
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index 32c0144b9..c853e4dc1 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1391,7 +1391,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
     last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name;
     entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;
     if (rootdse) {
-        if (last_usn_name) {
+        if (false) {
             ret = sysdb_attrs_get_string(rootdse,
                                           last_usn_name, &last_usn_value);
             if (ret != EOK) {
@@ -1500,7 +1500,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
         }
     }

-    if (!last_usn_name) {
+    if (true) {
         DEBUG(SSSDBG_FUNC_DATA,
               "No known USN scheme is supported by this server!\n");
         if (!entry_usn_name) {
```
3. Run SSSD with sudo and check that smart refresh filter does not contain 
modifyTimestamp
4. Add new sudo rule, check that the filter does contain it after the rules is 
cached

Resolves: https://github.com/SSSD/sssd/issues/5483
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5485/head:pr5485
git checkout pr5485
From b40ae0469ea2c83c97b89da1326bd8792f34d713 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Fri, 29 Jan 2021 12:41:28 +0100
Subject: [PATCH] sudo: do not search by low usn value to improve performance

This is a follow up on these two commits.

- 819d70ef6e6fa0e736ebd60a7f8a26f672927d57
- 6815844daa7701c76e31addbbdff74656cd30bea

The first one improved the search filter little bit to achieve better
performance, however it also changed the behavior: we started to search
for `usn >= 1` in the filter if no usn number was known.

This caused issues on OpenLDAP server which was fixed by the second patch.
However, the fix was wrong and searching by this meaningfully low number
can cause performance issues depending on how the filter is optimized and
evaluated on the server.

Now we omit the usn attribute from the filter if there is no meaningful value.

How to test:
1. Setup LDAP with no sudo rules defined
2. Make sure that the LDAP server does not support USN or use the following diff
   to enforce modifyTimestamp (last USN is always available from rootDSE)
```diff
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index 32c0144b9..c853e4dc1 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1391,7 +1391,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
     last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name;
     entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;
     if (rootdse) {
-        if (last_usn_name) {
+        if (false) {
             ret = sysdb_attrs_get_string(rootdse,
                                           last_usn_name, &last_usn_value);
             if (ret != EOK) {
@@ -1500,7 +1500,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
         }
     }

-    if (!last_usn_name) {
+    if (true) {
         DEBUG(SSSDBG_FUNC_DATA,
               "No known USN scheme is supported by this server!\n");
         if (!entry_usn_name) {
```
3. Run SSSD with sudo and check that smart refresh filter does not contain modifyTimestamp
4. Add new sudo rule, check that the filter does contain it after the rules is cached

Resolves: https://github.com/SSSD/sssd/issues/5483
---
 src/providers/ldap/sdap_sudo_refresh.c |  3 ++-
 src/providers/ldap/sdap_sudo_shared.c  | 21 ++++++---------------
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index ddcb237811..3441dd8fd6 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -181,7 +181,8 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
     state->sysdb = id_ctx->be->domain->sysdb;
 
     /* Download all rules from LDAP that are newer than usn */
-    if (srv_opts == NULL || srv_opts->max_sudo_value == 0) {
+    if (srv_opts == NULL || srv_opts->max_sudo_value == NULL
+         || strcmp(srv_opts->max_sudo_value, "0") == 0) {
         DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
         usn = "0";
         search_filter = talloc_asprintf(state, "(%s=%s)",
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
index 4f09957ea4..75d1bc3d85 100644
--- a/src/providers/ldap/sdap_sudo_shared.c
+++ b/src/providers/ldap/sdap_sudo_shared.c
@@ -129,25 +129,17 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
 static char *
 sdap_sudo_new_usn(TALLOC_CTX *mem_ctx,
                   unsigned long usn,
-                  const char *leftover,
-                  bool supports_usn)
+                  const char *leftover)
 {
     const char *str = leftover == NULL ? "" : leftover;
     char *newusn;
 
-    /* This is a fresh start and server uses modifyTimestamp. We need to
-     * provide proper datetime value. */
-    if (!supports_usn && usn == 0) {
-        newusn = talloc_strdup(mem_ctx, "00000101000000Z");
-        if (newusn == NULL) {
-            DEBUG(SSSDBG_MINOR_FAILURE, "Unable to change USN value (OOM)!\n");
-            return NULL;
-        }
-
-        return newusn;
+    /* Current largest USN is unknown so we keep "0" to indicate it. */
+    if (usn == 0) {
+        return talloc_strdup(mem_ctx, "0");
     }
 
-    /* We increment USN number so that we can later use simplify filter
+    /* We increment USN number so that we can later use simplified filter
      * (just usn >= last+1 instead of usn >= last && usn != last).
      */
     usn++;
@@ -219,8 +211,7 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
         srv_opts->last_usn = usn_number;
     }
 
-    newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, timezone,
-                               srv_opts->supports_usn);
+    newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, timezone);
     if (newusn == NULL) {
         return;
     }
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org

Reply via email to