From d6e73651a6b196cdf9ec28e1955175c033049f65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 10 Nov 2015 11:34:14 +0100
Subject: [PATCH 11/34] SUDO: do not imitate full refresh if usn is unknown in
 smart refresh

USN value should be always known now if at least one full refresh
was successful.
---
 src/providers/ldap/sdap.h              |  2 +-
 src/providers/ldap/sdap_async_sudo.c   | 22 ++++++++++++++--------
 src/providers/ldap/sdap_sudo_refresh.c | 20 +++++++-------------
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index edfbf229b4c4396592020de931eba5f83a8f06ed..85adad9a23d6c71da3ceb3968cc155a5c245594a 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -460,7 +460,7 @@ struct sdap_server_opts {
     char *max_user_value;
     char *max_group_value;
     char *max_service_value;
-    char *max_sudo_value;
+    const char *max_sudo_value;
     bool posix_checked;
 };
 
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index 84eff3b2a99e9f7c38e49c870cd301f4f88b4d02..1f4ab8590c1b89666b91566e45c88a5318cfe64d 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -305,16 +305,24 @@ static void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
     unsigned int usn_number;
     char *endptr = NULL;
 
-    if (usn == NULL) {
-        DEBUG(SSSDBG_TRACE_FUNC, "Empty USN, ignoring\n");
-        return;
-    }
-
     if (srv_opts == NULL) {
         DEBUG(SSSDBG_TRACE_FUNC, "Bug: srv_opts is NULL\n");
         return;
     }
 
+    if (usn == NULL) {
+        /* If the USN value is unknown and we don't have max_sudo_value set
+         * (possibly first full refresh which did not find any rule) we will
+         * set zero so smart refresh can pick up. */
+        if (srv_opts->max_sudo_value == NULL) {
+            srv_opts->max_sudo_value = "0";
+            return;
+        }
+
+        DEBUG(SSSDBG_TRACE_FUNC, "Empty USN, ignoring\n");
+        return;
+    }
+
     talloc_zfree(srv_opts->max_sudo_value);
     srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
 
@@ -689,9 +697,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
     DEBUG(SSSDBG_TRACE_FUNC, "Sudoers is successfuly stored in cache\n");
 
     /* remember new usn */
-    if (usn != NULL) {
-        sdap_sudo_set_usn(state->srv_opts, usn);
-    }
+    sdap_sudo_set_usn(state->srv_opts, usn);
 
     ret = EOK;
     state->num_rules = rules_count;
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index 80627f1c84cf6ef0d5b41a1368c9e0a0b7e5ed32..1a7b01c36068dd03a0a077497b980d1afb0a3fba 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -182,7 +182,7 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
     }
 
     if (!sudo_ctx->full_refresh_done
-            && (srv_opts == NULL || srv_opts->max_sudo_value == 0)) {
+            || srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
         /* Perform full refresh first */
         DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, "
                                   "waiting for full refresh!\n");
@@ -195,17 +195,11 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
 
     /* Download all rules from LDAP that are newer than usn */
     usn = srv_opts->max_sudo_value;
-    if (usn != NULL) {
-        search_filter = talloc_asprintf(state,
-                                        "(&(objectclass=%s)(%s>=%s)(!(%s=%s)))",
-                                        map[SDAP_OC_SUDORULE].name,
-                                        map[SDAP_AT_SUDO_USN].name, usn,
-                                        map[SDAP_AT_SUDO_USN].name, usn);
-    } else {
-        /* no valid USN value known */
-        search_filter = talloc_asprintf(state, SDAP_SUDO_FILTER_CLASS,
-                                      map[SDAP_OC_SUDORULE].name);
-    }
+    search_filter = talloc_asprintf(state,
+                                    "(&(objectclass=%s)(%s>=%s)(!(%s=%s)))",
+                                    map[SDAP_OC_SUDORULE].name,
+                                    map[SDAP_AT_SUDO_USN].name, usn,
+                                    map[SDAP_AT_SUDO_USN].name, usn);
     if (search_filter == NULL) {
         ret = ENOMEM;
         goto immediately;
@@ -215,7 +209,7 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
      * sysdb_filter = NULL; */
 
     DEBUG(SSSDBG_TRACE_FUNC, "Issuing a smart refresh of sudo rules "
-                              "(USN > %s)\n", (usn == NULL ? "0" : usn));
+                              "(USN > %s)\n", usn);
 
     subreq = sdap_sudo_refresh_send(state, sudo_ctx, search_filter, NULL);
     if (subreq == NULL) {
-- 
2.1.0

