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

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