dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

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

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