Blame SOURCES/0063-sudo-do-not-search-by-low-usn-value-to-improve-perfo.patch

44f86b
From 73f35e5e6836c3d63cfdc4d85dfbfed99f0bcf5a Mon Sep 17 00:00:00 2001
44f86b
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
44f86b
Date: Fri, 29 Jan 2021 12:41:28 +0100
44f86b
Subject: [PATCH] sudo: do not search by low usn value to improve performance
44f86b
44f86b
This is a follow up on these two commits.
44f86b
44f86b
- 819d70ef6e6fa0e736ebd60a7f8a26f672927d57
44f86b
- 6815844daa7701c76e31addbbdff74656cd30bea
44f86b
44f86b
The first one improved the search filter little bit to achieve better
44f86b
performance, however it also changed the behavior: we started to search
44f86b
for `usn >= 1` in the filter if no usn number was known.
44f86b
44f86b
This caused issues on OpenLDAP server which was fixed by the second patch.
44f86b
However, the fix was wrong and searching by this meaningfully low number
44f86b
can cause performance issues depending on how the filter is optimized and
44f86b
evaluated on the server.
44f86b
44f86b
Now we omit the usn attribute from the filter if there is no meaningful value.
44f86b
44f86b
How to test:
44f86b
1. Setup LDAP with no sudo rules defined
44f86b
2. Make sure that the LDAP server does not support USN or use the following diff
44f86b
   to enforce modifyTimestamp (last USN is always available from rootDSE)
44f86b
```diff
44f86b
44f86b
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
44f86b
(cherry picked from commit b100efbfabd96dcfb2825777b75b9a9dfaacb937)
44f86b
---
44f86b
 src/providers/ldap/sdap.c              |  4 ++--
44f86b
 src/providers/ldap/sdap_sudo_refresh.c |  6 ++++--
44f86b
 src/providers/ldap/sdap_sudo_shared.c  | 21 ++++++---------------
44f86b
 3 files changed, 12 insertions(+), 19 deletions(-)
44f86b
44f86b
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
44f86b
index a1a00df56..0413930bc 100644
44f86b
--- a/src/providers/ldap/sdap.c
44f86b
+++ b/src/providers/ldap/sdap.c
44f86b
@@ -1322,7 +1322,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
44f86b
     last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name;
44f86b
     entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name;
44f86b
     if (rootdse) {
44f86b
-        if (last_usn_name) {
44f86b
+        if (false) {
44f86b
             ret = sysdb_attrs_get_string(rootdse,
44f86b
                                           last_usn_name, &last_usn_value);
44f86b
             if (ret != EOK) {
44f86b
@@ -1431,7 +1431,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
44f86b
         }
44f86b
     }
44f86b
 
44f86b
-    if (!last_usn_name) {
44f86b
+    if (true) {
44f86b
         DEBUG(SSSDBG_FUNC_DATA,
44f86b
               "No known USN scheme is supported by this server!\n");
44f86b
         if (!entry_usn_name) {
44f86b
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
44f86b
index 5c72c6ec5..fd5deeb7a 100644
44f86b
--- a/src/providers/ldap/sdap_sudo_refresh.c
44f86b
+++ b/src/providers/ldap/sdap_sudo_refresh.c
44f86b
@@ -181,8 +181,10 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
44f86b
     state->sysdb = id_ctx->be->domain->sysdb;
44f86b
 
44f86b
     /* Download all rules from LDAP that are newer than usn */
44f86b
-    if (srv_opts == NULL || srv_opts->max_sudo_value == 0) {
44f86b
-        DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
44f86b
+    if (srv_opts == NULL || srv_opts->max_sudo_value == NULL
44f86b
+         || strcmp(srv_opts->max_sudo_value, "0") == 0) {
44f86b
+        DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero and "
44f86b
+              "omitting it from the filter.\n");
44f86b
         usn = "0";
44f86b
         search_filter = talloc_asprintf(state, "(%s=%s)",
44f86b
                                         map[SDAP_AT_SUDO_OC].name,
44f86b
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
44f86b
index bd3a24da0..5f6afb1ac 100644
44f86b
--- a/src/providers/ldap/sdap_sudo_shared.c
44f86b
+++ b/src/providers/ldap/sdap_sudo_shared.c
44f86b
@@ -127,25 +127,17 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
44f86b
 static char *
44f86b
 sdap_sudo_new_usn(TALLOC_CTX *mem_ctx,
44f86b
                   unsigned long usn,
44f86b
-                  const char *leftover,
44f86b
-                  bool supports_usn)
44f86b
+                  const char *leftover)
44f86b
 {
44f86b
     const char *str = leftover == NULL ? "" : leftover;
44f86b
     char *newusn;
44f86b
 
44f86b
-    /* This is a fresh start and server uses modifyTimestamp. We need to
44f86b
-     * provide proper datetime value. */
44f86b
-    if (!supports_usn && usn == 0) {
44f86b
-        newusn = talloc_strdup(mem_ctx, "00000101000000Z");
44f86b
-        if (newusn == NULL) {
44f86b
-            DEBUG(SSSDBG_MINOR_FAILURE, "Unable to change USN value (OOM)!\n");
44f86b
-            return NULL;
44f86b
-        }
44f86b
-
44f86b
-        return newusn;
44f86b
+    /* Current largest USN is unknown so we keep "0" to indicate it. */
44f86b
+    if (usn == 0) {
44f86b
+        return talloc_strdup(mem_ctx, "0");
44f86b
     }
44f86b
 
44f86b
-    /* We increment USN number so that we can later use simplify filter
44f86b
+    /* We increment USN number so that we can later use simplified filter
44f86b
      * (just usn >= last+1 instead of usn >= last && usn != last).
44f86b
      */
44f86b
     usn++;
44f86b
@@ -217,8 +209,7 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
44f86b
         srv_opts->last_usn = usn_number;
44f86b
     }
44f86b
 
44f86b
-    newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, timezone,
44f86b
-                               srv_opts->supports_usn);
44f86b
+    newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, timezone);
44f86b
     if (newusn == NULL) {
44f86b
         return;
44f86b
     }
44f86b
-- 
44f86b
2.26.3
44f86b