[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sssd-devel
Subject:    [SSSD]  [PATCH] AD: add entry_cache_gpo_timeout option
From:       Yassir Elley <yelley () redhat ! com>
Date:       2014-07-24 10:53:24
Message-ID: 1838605117.1033720.1406199204510.JavaMail.zimbra () redhat ! com
[Download RAW message or body]

Hi,

The attached patch adds support for an "entry_cache_gpo_timeout" option, which allows \
an admin to specify how many seconds the backend should consider locally stored gpo \
policy files to be valid before asking the backend again. This is an additional \
performance enhancement (along with comparing gpo versions to avoid unnecessary \
downloads). The timeout is set when a gpo entry is stored in the cache (which only \
happens after policy files have been downloaded). 

During the processing of a gpo, if the gpo's cache timeout has not elapsed, the \
backend does not interact with the gpo_child at all (and therefore doesn't download \
any files from the smb server). Rather, it re-uses the policy files that are already \
stored locally. Obviously, no gpo version comparisons need to be made in this case. \
If the timeout has elapsed (or there is no gpo entry in the cache), then the backend \
does interact with the gpo child in the usual manner (including comparing gpo \
versions to avoid unnecessary downloads). Note that the entry_cache_gpo_timeout \
option is *not* an expiration for the data in the gpo cache entry (which includes the \
cached_gpt_version). Indeed, the cached_gpt_version is never considered to be \
"expired".

Note that this patch does not add support for offline mode, which will be implemented \
in a subsequent patch.

Regards,
Yassir.


["0001-AD-GPO-add-entry_cache_gpo_timeout-option.patch" (text/x-patch)]

From 8aff4445df5cf42e09cd8b521cbd5ff4d6e1a666 Mon Sep 17 00:00:00 2001
From: Yassir Elley <yelley@redhat.com>
Date: Tue, 22 Jul 2014 14:19:35 -0400
Subject: [PATCH] AD-GPO: add entry_cache_gpo_timeout option

---
 src/confdb/confdb.c                  |  11 ++
 src/confdb/confdb.h                  |   2 +
 src/config/SSSDConfig/__init__.py.in |   1 +
 src/config/SSSDConfigTest.py         |   2 +
 src/config/etc/sssd.api.conf         |   1 +
 src/db/sysdb.h                       |  14 +-
 src/db/sysdb_gpo.c                   |  46 +++++-
 src/man/sssd.conf.5.xml              |  13 ++
 src/providers/ad/ad_gpo.c            | 292 +++++++++++++++++++++++------------
 9 files changed, 271 insertions(+), 111 deletions(-)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 15de9616ffdddf640f29e6b816c246ee05da48c7..5fbf31b822bc100f4e266212c0ab3e52bbc247bd 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1040,6 +1040,17 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
         goto done;
     }
 
+    /* Override the gpo cache timeout, if specified */
+    ret = get_entry_as_uint32(res->msgs[0], &domain->gpo_timeout,
+                              CONFDB_DOMAIN_GPO_CACHE_TIMEOUT,
+                              entry_cache_timeout);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Invalid value for [%s]\n",
+               CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT);
+        goto done;
+    }
+
     /* Set refresh_expired_interval, if specified */
     ret = get_entry_as_uint32(res->msgs[0], &domain->refresh_expired_interval,
                               CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL,
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index ba33ea5d7123c6e799f13529b60c5938ad20e411..52063dd56fcc2d24d106b380d41b394b44187a8e 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -175,6 +175,7 @@
 #define CONFDB_DOMAIN_SERVICE_CACHE_TIMEOUT "entry_cache_service_timeout"
 #define CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT "entry_cache_autofs_timeout"
 #define CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT "entry_cache_sudo_timeout"
+#define CONFDB_DOMAIN_GPO_CACHE_TIMEOUT "entry_cache_gpo_timeout"
 #define CONFDB_DOMAIN_PWD_EXPIRATION_WARNING "pwd_expiration_warning"
 #define CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL "refresh_expired_interval"
 #define CONFDB_DOMAIN_OFFLINE_TIMEOUT "offline_timeout"
@@ -232,6 +233,7 @@ struct sss_domain_info {
     uint32_t service_timeout;
     uint32_t autofsmap_timeout;
     uint32_t sudo_timeout;
+    uint32_t gpo_timeout;
 
     uint32_t refresh_expired_interval;
     uint32_t subdomain_refresh_interval;
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 439378ff86d07311f67d51ed775e2d973cd93869..b027e2ba60b09912d076c1727960413e9f297af8 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -130,6 +130,7 @@ option_strings = {
     'entry_cache_service_timeout' : _('Entry cache timeout length (seconds)'),
     'entry_cache_autofs_timeout' : _('Entry cache timeout length (seconds)'),
     'entry_cache_sudo_timeout' : _('Entry cache timeout length (seconds)'),
+    'entry_cache_gpo_timeout' : _('Entry cache timeout length (seconds)'),
     'refresh_expired_interval' : _('How often should expired entries be refreshed in background'),
     'dyndns_update' : _("Whether to automatically update the client's DNS entry"),
     'dyndns_ttl' : _("The TTL to apply to the client's DNS entry after updating it"),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 14500031beca7b621eb6a77011e1a48fa22c2f9a..b8dd56b94fee9ada3d86c1cb649aed9122f39820 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -505,6 +505,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'entry_cache_service_timeout',
             'entry_cache_autofs_timeout',
             'entry_cache_sudo_timeout',
+            'entry_cache_gpo_timeout',
             'refresh_expired_interval',
             'lookup_family_order',
             'account_cache_expiration',
@@ -863,6 +864,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
             'entry_cache_service_timeout',
             'entry_cache_autofs_timeout',
             'entry_cache_sudo_timeout',
+            'entry_cache_gpo_timeout',
             'refresh_expired_interval',
             'account_cache_expiration',
             'lookup_family_order',
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 5e5a9284e9ad80d822fe1db4269353aeb7925682..14863b90bae5a8bdb0246960d26ed0f370ea8f8e 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -133,6 +133,7 @@ entry_cache_netgroup_timeout = int, None, false
 entry_cache_service_timeout = int, None, false
 entry_cache_autofs_timeout = int, None, false
 entry_cache_sudo_timeout = int, None, false
+entry_cache_gpo_timeout = int, None, false
 refresh_expired_interval = int, None, false
 
 # Dynamic DNS updates
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 63f596007cdf53c5ebbdccf37f3c4bcc7830a205..addf13196352825009a4a4a0ebaed7e343c72a14 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -873,6 +873,7 @@ errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx,
 #define SYSDB_GPO_FILTER "(&(objectClass="SYSDB_GPO_OC")("SYSDB_GPO_GUID_ATTR"=%s))"
 #define SYSDB_GPO_GUID_ATTR "gpoGUID"
 #define SYSDB_GPO_VERSION_ATTR "gpoVersion"
+#define SYSDB_GPO_TIMEOUT_ATTR "gpoPolicyFileTimeout"
 
 #define SYSDB_TMPL_GPO_BASE SYSDB_GPO_CONTAINER","SYSDB_DOM_BASE
 #define SYSDB_TMPL_GPO SYSDB_GPO_GUID_ATTR"=%s,"SYSDB_TMPL_GPO_BASE
@@ -881,15 +882,18 @@ errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx,
         SYSDB_NAME, \
         SYSDB_GPO_GUID_ATTR, \
         SYSDB_GPO_VERSION_ATTR, \
+        SYSDB_GPO_TIMEOUT_ATTR, \
         NULL }
 
 errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain,
                             const char *gpo_guid,
-                            int gpo_version);
+                            int gpo_version,
+                            int cache_timeout,
+                            time_t now);
 
-errno_t sysdb_gpo_get_gpo(TALLOC_CTX *mem_ctx,
-                          struct sss_domain_info *domain,
-                          const char *gpo_guid,
-                          struct ldb_result **_result);
+errno_t sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx,
+                                  struct sss_domain_info *domain,
+                                  const char *gpo_guid,
+                                  struct ldb_result **_result);
 
 #endif /* __SYS_DB_H__ */
diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c
index 3c23c5b8fae6aaa41168b1466f4b3e520231e7e2..228f131ace761909c98e0c02fffc889599f86c07 100644
--- a/src/db/sysdb_gpo.c
+++ b/src/db/sysdb_gpo.c
@@ -49,7 +49,9 @@ sysdb_gpo_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain,
 errno_t
 sysdb_gpo_store_gpo(struct sss_domain_info *domain,
                     const char *gpo_guid,
-                    int gpo_version)
+                    int gpo_version,
+                    int cache_timeout,
+                    time_t now)
 {
     errno_t ret, sret;
     int lret;
@@ -81,6 +83,10 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain,
         goto done;
     }
 
+    if (!now) {
+        now = time(NULL);
+    }
+
     in_transaction = true;
 
     /* Check for an existing gpo_guid entry */
@@ -140,6 +146,21 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain,
             goto done;
         }
 
+        /* Add the Policy File Timeout */
+        lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_TIMEOUT_ATTR,
+                                 LDB_FLAG_MOD_ADD, NULL);
+        if (lret != LDB_SUCCESS) {
+            ret = sysdb_error_to_errno(lret);
+            goto done;
+        }
+
+        lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_TIMEOUT_ATTR, "%lu",
+                               ((cache_timeout) ? (now + cache_timeout) : 0));
+        if (lret != LDB_SUCCESS) {
+            ret = sysdb_error_to_errno(lret);
+            goto done;
+        }
+
         lret = ldb_add(domain->sysdb->ldb, update_msg);
         if (lret != LDB_SUCCESS) {
             DEBUG(SSSDBG_MINOR_FAILURE,
@@ -170,6 +191,21 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain,
             goto done;
         }
 
+        /* Add the Policy File Timeout */
+        lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_TIMEOUT_ATTR,
+                                 LDB_FLAG_MOD_REPLACE, NULL);
+        if (lret != LDB_SUCCESS) {
+            ret = sysdb_error_to_errno(lret);
+            goto done;
+        }
+
+        lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_TIMEOUT_ATTR, "%lu",
+                               ((cache_timeout) ? (now + cache_timeout) : 0));
+        if (lret != LDB_SUCCESS) {
+            ret = sysdb_error_to_errno(lret);
+            goto done;
+        }
+
         lret = ldb_modify(domain->sysdb->ldb, update_msg);
         if (lret != LDB_SUCCESS) {
             DEBUG(SSSDBG_MINOR_FAILURE,
@@ -202,10 +238,10 @@ done:
 }
 
 errno_t
-sysdb_gpo_get_gpo(TALLOC_CTX *mem_ctx,
-                  struct sss_domain_info *domain,
-                  const char *gpo_guid,
-                  struct ldb_result **_result)
+sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx,
+                          struct sss_domain_info *domain,
+                          const char *gpo_guid,
+                          struct ldb_result **_result)
 {
     errno_t ret;
     int lret;
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 27d22f44ef4449ef9cad026757ff54dd5083672b..9c7a33dab2469a488d5a2b54d7f69e18bac23a15 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1176,6 +1176,19 @@ fallback_homedir = /home/%u
                 </varlistentry>
 
                 <varlistentry>
+                    <term>entry_cache_gpo_timeout (integer)</term>
+                    <listitem>
+                        <para>
+                            How many seconds should gpo consider
+                            policy files valid before asking the backend again
+                        </para>
+                        <para>
+                            Default: entry_cache_timeout
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+                <varlistentry>
                     <term>refresh_expired_interval (integer)</term>
                     <listitem>
                         <para>
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index a1cce057ef874ea84c8a0312ce32f8b437ff5c78..31d820fbda79d3ea1d464c76cfaae85815194826 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -123,6 +123,7 @@ struct gp_gpo {
     int num_gpo_cse_guids;
     int gpo_func_version;
     int gpo_flags;
+    bool send_to_child;
 };
 
 enum ace_eval_status {
@@ -157,19 +158,18 @@ int ad_gpo_process_gpo_recv(struct tevent_req *req,
                             int *num_candidate_gpos);
 struct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
                                            struct tevent_context *ev,
-                                           struct sss_domain_info *domain,
+                                           bool send_to_child,
+                                           const char *domain_name,
+                                           const char *gpo_guid,
                                            const char *smb_server,
                                            const char *smb_share,
                                            const char *smb_path,
                                            const char *smb_cse_suffix,
-                                           const char *gpo_guid);
+                                           int cached_gpt_version);
 int ad_gpo_process_cse_recv(struct tevent_req *req,
                             TALLOC_CTX *mem_ctx,
                             int *_sysvol_gpt_version,
-                            int *_allowed_size,
-                            char ***_allowed_sids,
-                            int *_denied_size,
-                            char ***_denied_sids);
+                            const char **_policy_filename);
 
 /* == ad_gpo_access_send/recv helpers =======================================*/
 
@@ -881,6 +881,12 @@ static void ad_gpo_process_som_done(struct tevent_req *subreq);
 static void ad_gpo_process_gpo_done(struct tevent_req *subreq);
 
 static errno_t ad_gpo_cse_step(struct tevent_req *req);
+static errno_t ad_gpo_parse_policy_file(TALLOC_CTX *mem_ctx,
+                                        const char *filename,
+                                        char ***allowed_sids,
+                                        int *allowed_size,
+                                        char ***denied_sids,
+                                        int *denied_size);
 static void ad_gpo_cse_done(struct tevent_req *subreq);
 
 struct tevent_req *
@@ -1305,6 +1311,12 @@ ad_gpo_cse_step(struct tevent_req *req)
     struct tevent_req *subreq;
     struct ad_gpo_access_state *state;
     int i = 0;
+    struct ldb_result *res;
+    errno_t ret;
+    bool found_in_cache = false;
+    bool send_to_child = true;
+    int cached_gpt_version = 0;
+    time_t policy_file_timeout = 0;
 
     state = tevent_req_data(req, struct ad_gpo_access_state);
 
@@ -1327,14 +1339,69 @@ ad_gpo_cse_step(struct tevent_req *req)
     DEBUG(SSSDBG_TRACE_FUNC, "smb_path: %s\n", cse_filtered_gpo->smb_path);
     DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s\n", cse_filtered_gpo->gpo_guid);
 
+    /* retrieve gpo cache entry; set cached_gpt_version to -1 if unavailable */
+    DEBUG(SSSDBG_TRACE_FUNC, "retrieving GPO from cache [%s]\n",
+          cse_filtered_gpo->gpo_guid);
+    ret = sysdb_gpo_get_gpo_by_guid(state,
+                                    state->domain,
+                                    cse_filtered_gpo->gpo_guid,
+                                    &res);
+    if (ret == EOK) {
+        found_in_cache = true;
+    } else {
+        switch (ret) {
+        case ENOENT:
+            DEBUG(SSSDBG_TRACE_FUNC, "ENOENT\n");
+            cached_gpt_version = -1;
+            break;
+        default:
+            DEBUG(SSSDBG_FATAL_FAILURE, "Could not read GPO from cache: [%s]\n",
+                  strerror(ret));
+            return ret;
+        }
+    }
+
+    DEBUG(SSSDBG_TRACE_FUNC, "found_in_cache: %d\n", found_in_cache);
+    if (found_in_cache) {
+
+        /*
+         * Note: if the timeout is valid, then we can later avoid downloading
+         * the GPT.INI file, as well as any policy files (i.e. we don't need
+         * to interact with the gpo_child at all). However, even if the timeout
+         * is not valid, while we will have to interact with the gpo child to
+         * download the GPT.INI file, we may still be able to avoid downloading
+         * the policy files (if the cached_gpt_version is the same as the
+         * GPT.INI version). In other words, the timeout is *not* an expiration
+         * for the entire cache entry; the cached_gpt_version never expires.
+         */
+
+        cached_gpt_version = ldb_msg_find_attr_as_int(res->msgs[0],
+                                                      SYSDB_GPO_VERSION_ATTR,
+                                                      0);
+
+        policy_file_timeout = ldb_msg_find_attr_as_uint64
+            (res->msgs[0], SYSDB_GPO_TIMEOUT_ATTR, 0);
+
+        if (policy_file_timeout >= time(NULL)) {
+            send_to_child = false;
+        }
+    }
+
+    DEBUG(SSSDBG_TRACE_FUNC, "send_to_child: %d\n", send_to_child);
+    DEBUG(SSSDBG_TRACE_FUNC, "cached_gpt_version: %d\n", cached_gpt_version);
+
+    cse_filtered_gpo->send_to_child = send_to_child;
+
     subreq = ad_gpo_process_cse_send(state,
                                      state->ev,
-                                     state->domain,
+                                     send_to_child,
+                                     state->domain->name,
+                                     cse_filtered_gpo->gpo_guid,
                                      cse_filtered_gpo->smb_server,
                                      cse_filtered_gpo->smb_share,
                                      cse_filtered_gpo->smb_path,
                                      GP_EXT_GUID_SECURITY_SUFFIX,
-                                     cse_filtered_gpo->gpo_guid);
+                                     cached_gpt_version);
 
     tevent_req_set_callback(subreq, ad_gpo_cse_done, req);
     return EAGAIN;
@@ -1356,10 +1423,12 @@ ad_gpo_cse_done(struct tevent_req *subreq)
     struct ad_gpo_access_state *state;
     int ret;
     int sysvol_gpt_version;
+    const char *policy_filename = NULL;
     char **allowed_sids;
     int allowed_size;
     char **denied_sids;
     int denied_size;
+    time_t now;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct ad_gpo_access_state);
@@ -1372,8 +1441,7 @@ ad_gpo_cse_done(struct tevent_req *subreq)
     DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s\n", gpo_guid);
 
     ret = ad_gpo_process_cse_recv(subreq, state, &sysvol_gpt_version,
-                                  &allowed_size, &allowed_sids,
-                                  &denied_size, &denied_sids);
+                                  &policy_filename);
 
     talloc_zfree(subreq);
 
@@ -1383,17 +1451,35 @@ ad_gpo_cse_done(struct tevent_req *subreq)
         goto done;
     }
 
-    DEBUG(SSSDBG_TRACE_FUNC, "sysvol_gpt_version: %d\n", sysvol_gpt_version);
+    /* only store to cache (and refresh timeout) if we interacted with child */
+    if (cse_filtered_gpo->send_to_child) {
 
-    ret = sysdb_gpo_store_gpo(state->domain, gpo_guid, sysvol_gpt_version);
+        DEBUG(SSSDBG_TRACE_FUNC, "sysvol_gpt_version: %d\n", sysvol_gpt_version);
+
+        now = time(NULL);
+        ret = sysdb_gpo_store_gpo(state->domain, gpo_guid, sysvol_gpt_version,
+                                  state->domain->gpo_timeout, now);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE, "Unable to store gpo cache entry: [%d](%s}\n",
+                  ret, sss_strerror(ret));
+            goto done;
+        }
+    }
+
+    ret = ad_gpo_parse_policy_file(state,
+                                   policy_filename,
+                                   &allowed_sids,
+                                   &allowed_size,
+                                   &denied_sids,
+                                   &denied_size);
 
     if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE, "Unable to store gpo cache entry: [%d](%s}\n",
-              ret, sss_strerror(ret));
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "Cannot parse policy file: [%s][%d][%s]\n",
+              policy_filename, ret, strerror(ret));
         goto done;
     }
 
-    /* TBD: allowed/denied_sids/size, should be retrieved from cache */
     ret = ad_gpo_access_check
         (state, state->gpo_mode, state->user, state->domain,
          allowed_sids, allowed_size, denied_sids, denied_size);
@@ -2380,8 +2466,22 @@ ad_gpo_extract_smb_components(TALLOC_CTX *mem_ctx,
     *_smb_server = talloc_asprintf(mem_ctx, "%s%s",
                                    SMB_STANDARD_URI,
                                    server_hostname);
+    if (*_smb_server == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
     *_smb_share = talloc_asprintf(mem_ctx, "/%s", smb_share);
+    if (*_smb_share == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
     *_smb_path = talloc_asprintf(mem_ctx, "/%s", smb_path);
+    if (*_smb_path == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
 
     ret = EOK;
 
@@ -3136,6 +3236,8 @@ struct ad_gpo_process_cse_state {
     struct tevent_context *ev;
     const char *smb_path;
     const char *smb_cse_suffix;
+    int sysvol_gpt_version;
+    const char *policy_filename;
     pid_t child_pid;
     uint8_t *buf;
     ssize_t len;
@@ -3191,19 +3293,19 @@ static void gpo_cse_done(struct tevent_req *subreq);
 struct tevent_req *
 ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
                         struct tevent_context *ev,
-                        struct sss_domain_info *domain,
+                        bool send_to_child,
+                        const char *domain_name,
+                        const char *gpo_guid,
                         const char *smb_server,
                         const char *smb_share,
                         const char *smb_path,
                         const char *smb_cse_suffix,
-                        const char *gpo_guid)
+                        int cached_gpt_version)
 {
     struct tevent_req *req;
     struct tevent_req *subreq;
     struct ad_gpo_process_cse_state *state;
-    struct ldb_result *res;
     struct io_buffer *buf = NULL;
-    int cached_gpt_version = 0;
     errno_t ret;
 
     req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_cse_state);
@@ -3212,6 +3314,29 @@ ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
         return NULL;
     }
 
+    state->sysvol_gpt_version = -1;
+
+    if (!send_to_child) {
+        /*
+         * if we don't need to talk to child (b/c cache timeout is valid),
+         * we simply set the policy_filename and complete the request
+         */
+        state->policy_filename =
+            talloc_asprintf(state,
+                            GPO_CACHE_PATH"/%s/Policies/%s%s",
+                            domain_name,
+                            gpo_guid,
+                            GP_EXT_GUID_SECURITY_SUFFIX);
+        if (state->policy_filename == NULL) {
+            ret = ENOMEM;
+            goto immediately;
+        }
+
+        DEBUG(SSSDBG_TRACE_FUNC, "policy_filename:%s\n", state->policy_filename);
+        ret = EOK;
+        goto immediately;
+    }
+
     state->ev = ev;
     state->buf = NULL;
     state->len = 0;
@@ -3221,64 +3346,47 @@ ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
     if (state->io == NULL) {
         DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
         ret = ENOMEM;
-        goto fail;
+        goto immediately;
     }
 
     state->io->write_to_child_fd = -1;
     state->io->read_from_child_fd = -1;
     talloc_set_destructor((void *) state->io, gpo_child_io_destructor);
 
-    /* retrieve cached gpt version (or set it to -1 if unavailable) */
-    DEBUG(SSSDBG_TRACE_FUNC, "retrieving GPO from cache [%s]\n", gpo_guid);
-    ret = sysdb_gpo_get_gpo(state, domain, gpo_guid, &res);
-    if (ret != EOK) {
-        switch (ret) {
-        case ENOENT:
-            DEBUG(SSSDBG_TRACE_FUNC, "ENOENT\n");
-            cached_gpt_version = -1;
-            break;
-        default:
-            DEBUG(SSSDBG_FATAL_FAILURE, "Could not read GPO from cache: [%s]\n",
-                  strerror(ret));
-            goto fail;
-        }
-    }
-
-    if (cached_gpt_version != -1) {
-        /* cached_gpt_version is in cache, so retrieve it from cache */
-        cached_gpt_version = ldb_msg_find_attr_as_int(res->msgs[0],
-                                                      SYSDB_GPO_VERSION_ATTR,
-                                                      0);
-    }
-    DEBUG(SSSDBG_TRACE_FUNC, "cached_gpt_version: %d\n", cached_gpt_version);
-
     /* prepare the data to pass to child */
     ret = create_cse_send_buffer(state, smb_server, smb_share, smb_path,
                                  smb_cse_suffix, cached_gpt_version, &buf);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "create_cse_send_buffer failed.\n");
-        goto fail;
+        goto immediately;
     }
 
     ret = gpo_fork_child(req);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "gpo_fork_child failed.\n");
-        goto fail;
+        goto immediately;
     }
 
     subreq = write_pipe_send(state, ev, buf->data, buf->size,
                              state->io->write_to_child_fd);
     if (subreq == NULL) {
         ret = ENOMEM;
-        goto fail;
+        goto immediately;
     }
     tevent_req_set_callback(subreq, gpo_cse_step, req);
 
     return req;
 
-fail:
-    tevent_req_error(req, ret);
-    tevent_req_post(req, ev);
+immediately:
+
+    if (ret == EOK) {
+        tevent_req_done(req);
+        tevent_req_post(req, ev);
+    } else {
+        tevent_req_error(req, ret);
+        tevent_req_post(req, ev);
+    }
+
     return req;
 }
 
@@ -3314,6 +3422,8 @@ static void gpo_cse_done(struct tevent_req *subreq)
 {
     struct tevent_req *req;
     struct ad_gpo_process_cse_state *state;
+    uint32_t sysvol_gpt_version = -1;
+    uint32_t child_result;
 
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct ad_gpo_process_cse_state);
@@ -3329,69 +3439,49 @@ static void gpo_cse_done(struct tevent_req *subreq)
     close(state->io->read_from_child_fd);
     state->io->read_from_child_fd = -1;
 
-    tevent_req_done(req);
-    return;
-}
-
-int ad_gpo_process_cse_recv(struct tevent_req *req,
-                            TALLOC_CTX *mem_ctx,
-                            int *_sysvol_gpt_version,
-                            int *_allowed_size,
-                            char ***_allowed_sids,
-                            int *_denied_size,
-                            char ***_denied_sids)
-{
-    int ret;
-    uint32_t sysvol_gpt_version;
-    uint32_t result;
-    char **allowed_sids;
-    int allowed_size;
-    char **denied_sids;
-    int denied_size;
-    struct ad_gpo_process_cse_state *state;
-    const char *policy_filename = NULL;
-
-    state = tevent_req_data(req, struct ad_gpo_process_cse_state);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
     ret = ad_gpo_parse_gpo_child_response(state, state->buf, state->len,
-                                          &sysvol_gpt_version, &result);
+                                          &sysvol_gpt_version, &child_result);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "ad_gpo_parse_gpo_child_response failed: [%d][%s]\n",
               ret, strerror(ret));
-        return ret;
-    } else if (result != 0){
+        tevent_req_error(req, ret);
+    } else if (child_result != 0){
         DEBUG(SSSDBG_CRIT_FAILURE,
-              "Error in gpo_child: [%d][%s]\n", result, strerror(result));
-        return result;
+              "Error in gpo_child: [%d][%s]\n",
+              child_result, strerror(child_result));
+        tevent_req_error(req, child_result);
     }
 
-    policy_filename = talloc_asprintf(mem_ctx, GPO_CACHE_PATH"%s%s",
-                               state->smb_path, state->smb_cse_suffix);
+    state->sysvol_gpt_version = sysvol_gpt_version;
+    state->policy_filename = talloc_asprintf(state,
+                                             GPO_CACHE_PATH"%s%s",
+                                             state->smb_path,
+                                             state->smb_cse_suffix);
+    if (state->policy_filename == NULL) {
+        tevent_req_error(req, ENOMEM);
+    }
 
-    DEBUG(SSSDBG_TRACE_FUNC, "policy_filename:%s\n", policy_filename);
 
-    ret = ad_gpo_parse_policy_file(state,
-                                   policy_filename,
-                                   &allowed_sids,
-                                   &allowed_size,
-                                   &denied_sids,
-                                   &denied_size);
+    DEBUG(SSSDBG_TRACE_FUNC, "policy_filename:%s\n", state->policy_filename);
 
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "Cannot parse policy file: [%s][%d][%s]\n",
-              policy_filename, ret, strerror(ret));
-        return ret;
-    }
+    tevent_req_done(req);
+    return;
+}
+
+int ad_gpo_process_cse_recv(struct tevent_req *req,
+                            TALLOC_CTX *mem_ctx,
+                            int *_sysvol_gpt_version,
+                            const char **_policy_filename)
+{
+    struct ad_gpo_process_cse_state *state;
+
+    state = tevent_req_data(req, struct ad_gpo_process_cse_state);
+
+    TEVENT_REQ_RETURN_ON_ERROR(req);
 
-    *_sysvol_gpt_version = sysvol_gpt_version;
-    *_allowed_size = allowed_size;
-    *_allowed_sids = talloc_steal(mem_ctx, allowed_sids);
-    *_denied_size = denied_size;
-    *_denied_sids = talloc_steal(mem_ctx, denied_sids);
+    *_sysvol_gpt_version = state->sysvol_gpt_version;
+    *_policy_filename = talloc_steal(mem_ctx, state->policy_filename);
 
     return EOK;
 }
-- 
1.8.5.3


[Attachment #4 (text/plain)]

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic