diff options
author | Yassir Elley <yelley@redhat.com> | 2014-09-07 23:23:26 -0400 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-09-08 20:49:06 +0200 |
commit | eb0cde4e6dfdbda08588860534f7ece5776ec3af (patch) | |
tree | 78fbcff93cf8a9edcce7473fd6c4df4e6071e85b | |
parent | 53b6d6e82dbe52aa655f910e87eb3595584aa9c9 (diff) | |
download | sssd-eb0cde4e6dfdbda08588860534f7ece5776ec3af.tar.gz sssd-eb0cde4e6dfdbda08588860534f7ece5776ec3af.tar.xz sssd-eb0cde4e6dfdbda08588860534f7ece5776ec3af.zip |
AD-GPO: delete stale GPOs
https://fedorahosted.org/sssd/ticket/2431
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r-- | src/db/sysdb.h | 5 | ||||
-rw-r--r-- | src/db/sysdb_gpo.c | 93 | ||||
-rw-r--r-- | src/providers/ad/ad_gpo.c | 36 |
3 files changed, 134 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 295949cf4..901b6129b 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -908,4 +908,9 @@ errno_t sysdb_gpo_get_gpos(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result); +errno_t sysdb_gpo_delete_stale_gpos(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char **gpo_guid_list, + int num_gpos); + #endif /* __SYS_DB_H__ */ diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c index 7dd31d81a..e0b9bb9f0 100644 --- a/src/db/sysdb_gpo.c +++ b/src/db/sysdb_gpo.c @@ -352,3 +352,96 @@ done: talloc_free(tmp_ctx); return ret; } + +static inline bool +sysdb_gpo_guid_in_list(const char **gpo_guid_list, int num_gpos, const char *gpo_guid) +{ + size_t i; + + for (i = 0; i < num_gpos; i++) { + if (strcasecmp(gpo_guid_list[i], gpo_guid) == 0) { + break; + } + } + + return (i < num_gpos) ? true : false; +} + +errno_t +sysdb_gpo_delete_stale_gpos(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char **gpo_guid_list, + int num_gpos) +{ + struct ldb_result *res; + errno_t ret, sret; + int i; + bool in_transaction = false; + const char *cached_gpo_guid; + bool stale_gpo_found = false; + + ret = sysdb_transaction_start(domain->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); + goto done; + } + + in_transaction = true; + + ret = sysdb_gpo_get_gpos(mem_ctx, domain, &res); + if (ret != EOK && ret != ENOENT) { + goto done; + } else if (ret != ENOENT) { + for (i = 0; i < res->count; i++) { + cached_gpo_guid = ldb_msg_find_attr_as_string(res->msgs[i], + SYSDB_GPO_GUID_ATTR, + NULL); + if (cached_gpo_guid == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "No gpo_guid attribute found in gpo cache entry\n"); + ret = EFAULT; + goto done; + } + + if (sysdb_gpo_guid_in_list(gpo_guid_list, num_gpos, cached_gpo_guid)) { + /* the cached_gpo_guid is still applicable, skip it */ + continue; + } else { + stale_gpo_found = true; + /* the cached_gpo_guid is no longer applicable, delete it */ + DEBUG(SSSDBG_TRACE_FUNC, "Deleting stale GPO [gpo_guid:%s]\n", + cached_gpo_guid); + + ret = sysdb_delete_entry(domain->sysdb, res->msgs[i]->dn, true); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Could not delete GPO cache entry [gpo_guid:%s]\n", + cached_gpo_guid); + goto done; + } + } + } + } + + if (!stale_gpo_found) { + DEBUG(SSSDBG_TRACE_FUNC, "No stale GPOs found\n"); + } + + ret = sysdb_transaction_commit(domain->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not commit transaction: [%s]\n", strerror(ret)); + goto done; + } + in_transaction = false; + +done: + if (in_transaction) { + sret = sysdb_transaction_cancel(domain->sysdb); + if (sret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); + } + } + return ret; + +} diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index 9afb9ff89..de4d44166 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -1733,6 +1733,7 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) struct gp_gpo **candidate_gpos = NULL; int num_candidate_gpos = 0; int i = 0; + const char **cse_filtered_gpo_guids; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_access_state); @@ -1798,14 +1799,49 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) goto done; } + /* we create and populate an array of applicable gpo-guids */ + cse_filtered_gpo_guids = + talloc_array(state, const char *, state->num_cse_filtered_gpos); + if (cse_filtered_gpo_guids == NULL) { + ret = ENOMEM; + goto done; + } + for (i = 0; i < state->num_cse_filtered_gpos; i++) { DEBUG(SSSDBG_TRACE_FUNC, "cse_filtered_gpos[%d]->gpo_guid is %s\n", i, state->cse_filtered_gpos[i]->gpo_guid); + cse_filtered_gpo_guids[i] = talloc_steal(cse_filtered_gpo_guids, + state->cse_filtered_gpos[i]->gpo_guid); + if (cse_filtered_gpo_guids[i] == NULL) { + ret = ENOMEM; + goto done; + } } DEBUG(SSSDBG_TRACE_FUNC, "num_cse_filtered_gpos: %d\n", state->num_cse_filtered_gpos); + /* + * we now have the array of applicable gpos in hand; however, since we + * may have cached a larger set of gpo-guids previously, we delete + * all stale gpo cache entries (i.e. entries that have a gpo-guid that + * doesn't match any of the gpo-guids in the cse_filtered_gpo_guids list) + */ + ret = sysdb_gpo_delete_stale_gpos(state, state->domain, + cse_filtered_gpo_guids, + state->num_cse_filtered_gpos); + if (ret != EOK) { + switch (ret) { + case ENOENT: + DEBUG(SSSDBG_OP_FAILURE, "No GPOs available in cache\n"); + default: + DEBUG(SSSDBG_FATAL_FAILURE, + "Could not delete stale GPOs from cache: [%s]\n", + strerror(ret)); + goto done; + } + } + ret = ad_gpo_cse_step(req); done: |