From f60af3b7bfece6e371ab7582cc23cf01d483d434 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 10 Nov 2015 10:34:41 +0100
Subject: [PATCH 09/28] SUDO: set USN inside sdap_sudo_refresh request

Reduce code duplication.
---
 src/providers/ldap/sdap_async_sudo.c   | 48 +++++++++++++++++++++------
 src/providers/ldap/sdap_sudo.h         |  2 +-
 src/providers/ldap/sdap_sudo_refresh.c | 59 ++++++----------------------------
 3 files changed, 49 insertions(+), 60 deletions(-)

diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index 71e1b3322a557beaf82b51316967b3147fb61f76..7a90ccde9cbd2efc0d0509f21e072cd745c57844 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -283,6 +283,7 @@ static int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx,
 
     /* Empty sudoers? Done. */
     if (rules_count == 0 || rules == NULL) {
+        *_usn = NULL;
         return EOK;
     }
 
@@ -299,8 +300,37 @@ static int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx,
     return EOK;
 }
 
+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;
+    }
+
+    talloc_zfree(srv_opts->max_sudo_value);
+    srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
+
+    usn_number = strtoul(usn, &endptr, 10);
+    if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
+         && (usn_number > srv_opts->last_usn)) {
+         srv_opts->last_usn = usn_number;
+    }
+
+    DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%s]\n",
+                             srv_opts->max_sudo_value);
+}
+
 struct sdap_sudo_refresh_state {
     struct tevent_context *ev;
+    struct sdap_server_opts *srv_opts;
     struct sdap_options *opts;
     struct sdap_id_op *sdap_op;
     struct sysdb_ctx *sysdb;
@@ -310,7 +340,6 @@ struct sdap_sudo_refresh_state {
     const char *sysdb_filter;   /* delete */
 
     int dp_error;
-    char *highest_usn;
     size_t num_rules;
 };
 
@@ -321,6 +350,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq);
 struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
                                           struct tevent_context *ev,
                                           struct sss_domain_info *domain,
+                                          struct sdap_server_opts *srv_opts,
                                           struct sdap_options *opts,
                                           struct sdap_id_conn_ctx *conn,
                                           const char *ldap_filter,
@@ -342,11 +372,11 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
     }
 
     state->ev = ev;
+    state->srv_opts = srv_opts;
     state->opts = opts;
     state->domain = domain;
     state->sysdb = domain->sysdb;
     state->dp_error = DP_ERR_FATAL;
-    state->highest_usn = NULL;
 
     state->sdap_op = sdap_id_op_create(state, conn->conn_cache);
     if (!state->sdap_op) {
@@ -448,6 +478,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
     struct sdap_sudo_refresh_state *state;
     struct sysdb_attrs **rules = NULL;
     size_t rules_count = 0;
+    char *usn = NULL;
     int dp_error;
     int ret;
     errno_t sret;
@@ -491,8 +522,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
     now = time(NULL);
     ret = sdap_sudo_store_sudoers(state, state->domain,
                                   state->opts, rules_count, rules,
-                                  state->domain->sudo_timeout, now,
-                                  &state->highest_usn);
+                                  state->domain->sudo_timeout, now, &usn);
     if (ret != EOK) {
         goto done;
     }
@@ -507,6 +537,11 @@ 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);
+    }
+
     ret = EOK;
     state->num_rules = rules_count;
 
@@ -529,7 +564,6 @@ done:
 int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx,
                            struct tevent_req *req,
                            int *dp_error,
-                           char **usn,
                            size_t *num_rules)
 {
     struct sdap_sudo_refresh_state *state;
@@ -540,10 +574,6 @@ int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx,
 
     *dp_error = state->dp_error;
 
-    if (usn != NULL && state->highest_usn != NULL) {
-        *usn = talloc_steal(mem_ctx, state->highest_usn);
-    }
-
     if (num_rules != NULL) {
         *num_rules = state->num_rules;
     }
diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h
index 7b47a297a65cce07c41fb9ceb8ce07a680783d53..2f971616edc22837091b0263987088019f803225 100644
--- a/src/providers/ldap/sdap_sudo.h
+++ b/src/providers/ldap/sdap_sudo.h
@@ -48,6 +48,7 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
 struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
                                           struct tevent_context *ev,
                                           struct sss_domain_info *domain,
+                                          struct sdap_server_opts *srv_opts,
                                           struct sdap_options *opts,
                                           struct sdap_id_conn_ctx *conn,
                                           const char *ldap_filter,
@@ -56,7 +57,6 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
 int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx,
                            struct tevent_req *req,
                            int *dp_error,
-                           char **usn,
                            size_t *num_rules);
 
 struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index 998a823807b4d39500a1cc540dd22972a32d8193..702fced7153118ee53d9742a7197ddbd0352c0f8 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -27,28 +27,6 @@
 #include "providers/ldap/sdap_sudo.h"
 #include "db/sysdb_sudo.h"
 
-static void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
-{
-    unsigned int usn_number;
-    char *endptr = NULL;
-
-    if (srv_opts != NULL && usn != NULL) {
-        talloc_zfree(srv_opts->max_sudo_value);
-        srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
-
-        usn_number = strtoul(usn, &endptr, 10);
-        if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
-             && (usn_number > srv_opts->last_usn)) {
-             srv_opts->last_usn = usn_number;
-        }
-
-        DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%s]\n",
-                                 srv_opts->max_sudo_value);
-    } else {
-        DEBUG(SSSDBG_TRACE_FUNC, "srv_opts is NULL\n");
-    }
-}
-
 static char *sdap_sudo_build_host_filter(TALLOC_CTX *mem_ctx,
                                          struct sdap_attr_map *map,
                                          char **hostnames,
@@ -250,8 +228,9 @@ struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
     DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n");
 
     subreq = sdap_sudo_refresh_send(state, id_ctx->be->ev, id_ctx->be->domain,
-                                    id_ctx->opts, id_ctx->conn,
-                                    ldap_full_filter, sysdb_filter);
+                                    id_ctx->srv_opts, id_ctx->opts,
+                                    id_ctx->conn, ldap_full_filter,
+                                    sysdb_filter);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto immediately;
@@ -281,14 +260,12 @@ static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
 {
     struct tevent_req *req = NULL;
     struct sdap_sudo_full_refresh_state *state = NULL;
-    char *highest_usn = NULL;
     int ret;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct sdap_sudo_full_refresh_state);
 
-    ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error,
-                                 &highest_usn, NULL);
+    ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, NULL);
     talloc_zfree(subreq);
     if (ret != EOK || state->dp_error != DP_ERR_OK) {
         goto done;
@@ -308,11 +285,6 @@ static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
 
     DEBUG(SSSDBG_TRACE_FUNC, "Successful full refresh of sudo rules\n");
 
-    /* set highest usn */
-    if (highest_usn != NULL) {
-        sdap_sudo_set_usn(state->id_ctx->srv_opts, highest_usn);
-    }
-
 done:
     state->sudo_ctx->full_refresh_in_progress = false;
 
@@ -408,8 +380,8 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
                               "(USN > %s)\n", (usn == NULL ? "0" : usn));
 
     subreq = sdap_sudo_refresh_send(state, id_ctx->be->ev, id_ctx->be->domain,
-                                    id_ctx->opts, id_ctx->conn,
-                                    ldap_full_filter, NULL);
+                                    id_ctx->srv_opts, id_ctx->opts,
+                                    id_ctx->conn, ldap_full_filter, NULL);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto immediately;
@@ -438,14 +410,12 @@ static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq)
 {
     struct tevent_req *req = NULL;
     struct sdap_sudo_smart_refresh_state *state = NULL;
-    char *highest_usn = NULL;
     int ret;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state);
 
-    ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error,
-                                 &highest_usn, NULL);
+    ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, NULL);
     talloc_zfree(subreq);
     if (ret != EOK || state->dp_error != DP_ERR_OK) {
         goto done;
@@ -453,11 +423,6 @@ static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq)
 
     DEBUG(SSSDBG_TRACE_FUNC, "Successful smart refresh of sudo rules\n");
 
-    /* set highest usn */
-    if (highest_usn != NULL) {
-        sdap_sudo_set_usn(state->id_ctx->srv_opts, highest_usn);
-    }
-
 done:
     if (ret != EOK) {
         tevent_req_error(req, ret);
@@ -578,7 +543,7 @@ struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
     }
 
     subreq = sdap_sudo_refresh_send(req, id_ctx->be->ev, id_ctx->be->domain,
-                                    opts, id_ctx->conn,
+                                    id_ctx->srv_opts, opts, id_ctx->conn,
                                     ldap_full_filter, sysdb_filter);
     if (subreq == NULL) {
         ret = ENOMEM;
@@ -603,7 +568,6 @@ static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq)
 {
     struct tevent_req *req = NULL;
     struct sdap_sudo_rules_refresh_state *state = NULL;
-    char *highest_usn = NULL;
     size_t downloaded_rules_num;
     int ret;
 
@@ -611,17 +575,12 @@ static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq)
     state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state);
 
     ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error,
-                                 &highest_usn, &downloaded_rules_num);
+                                 &downloaded_rules_num);
     talloc_zfree(subreq);
     if (ret != EOK || state->dp_error != DP_ERR_OK) {
         goto done;
     }
 
-    /* set highest usn */
-    if (highest_usn != NULL) {
-        sdap_sudo_set_usn(state->id_ctx->srv_opts, highest_usn);
-    }
-
     state->deleted = downloaded_rules_num != state->num_rules ? true : false;
 
 done:
-- 
2.1.0

