summaryrefslogtreecommitdiffstats
path: root/src/db
diff options
context:
space:
mode:
authorYassir Elley <yelley@redhat.com>2014-09-09 15:37:05 -0400
committerJakub Hrozek <jhrozek@redhat.com>2014-10-02 14:13:39 +0200
commit4611802d41d8954a3040f39403590adb920ca521 (patch)
tree57277a84018e0a3796c1dc6cc56767372beed87b /src/db
parent7f4270ee333c1128a87fce6e6a3de64d263733e1 (diff)
downloadsssd-4611802d41d8954a3040f39403590adb920ca521.tar.gz
sssd-4611802d41d8954a3040f39403590adb920ca521.tar.xz
sssd-4611802d41d8954a3040f39403590adb920ca521.zip
AD-GPO resolve conflicting policy settings correctly
Resolves: https://fedorahosted.org/sssd/ticket/2437 Reviewed-by: Stephen Gallagher <sgallagh@redhat.com>
Diffstat (limited to 'src/db')
-rw-r--r--src/db/sysdb.h29
-rw-r--r--src/db/sysdb_gpo.c357
2 files changed, 331 insertions, 55 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 901b6129b..81b39252c 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -876,6 +876,8 @@ errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx,
#define SYSDB_GPO_CONTAINER "cn=gpos,cn=ad,cn=custom"
+/* === Functions related to GPO entries === */
+
#define SYSDB_GPO_OC "gpo"
#define SYSDB_GPO_FILTER "(objectClass="SYSDB_GPO_OC")"
#define SYSDB_GPO_GUID_FILTER "(&(objectClass="SYSDB_GPO_OC")("SYSDB_GPO_GUID_ATTR"=%s))"
@@ -908,9 +910,28 @@ 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);
+/* === Functions related to GPO Result object === */
+
+#define SYSDB_GPO_RESULT_OC "gpo_result"
+#define SYSDB_GPO_RESULT_FILTER "(objectClass="SYSDB_GPO_RESULT_OC")"
+
+#define SYSDB_TMPL_GPO_RESULT_BASE SYSDB_GPO_CONTAINER","SYSDB_DOM_BASE
+#define SYSDB_TMPL_GPO_RESULT "cn=%s,"SYSDB_TMPL_GPO_RESULT_BASE
+
+errno_t sysdb_gpo_get_gpo_result_object(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct ldb_result **_result);
+
+errno_t sysdb_gpo_delete_gpo_result_object(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain);
+
+errno_t sysdb_gpo_store_gpo_result_setting(struct sss_domain_info *domain,
+ const char *policy_setting_key,
+ const char *policy_setting_value);
+
+errno_t sysdb_gpo_get_gpo_result_setting(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *policy_setting_key,
+ const char **policy_setting_value);
#endif /* __SYS_DB_H__ */
diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c
index e0b9bb9f0..92559d41e 100644
--- a/src/db/sysdb_gpo.c
+++ b/src/db/sysdb_gpo.c
@@ -37,7 +37,7 @@ sysdb_gpo_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain,
return NULL;
}
- DEBUG(SSSDBG_TRACE_FUNC, SYSDB_TMPL_GPO"\n", clean_gpo_guid, domain->name);
+ DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO"\n", clean_gpo_guid, domain->name);
dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO,
clean_gpo_guid, domain->name);
@@ -172,8 +172,7 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain,
} else if (ret == EOK && count == 1) {
/* Update the existing GPO */
- DEBUG(SSSDBG_TRACE_FUNC,
- "Updating new GPO [%s][%s]\n", domain->name, gpo_guid);
+ DEBUG(SSSDBG_TRACE_ALL, "Updating new GPO [%s][%s]\n", domain->name, gpo_guid);
/* Add the Version */
lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_ATTR,
@@ -254,7 +253,7 @@ sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx,
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
- DEBUG(SSSDBG_TRACE_FUNC, SYSDB_TMPL_GPO_BASE"\n", domain->name);
+ DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_BASE"\n", domain->name);
base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
SYSDB_TMPL_GPO_BASE,
@@ -313,7 +312,7 @@ sysdb_gpo_get_gpos(TALLOC_CTX *mem_ctx,
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
- DEBUG(SSSDBG_TRACE_FUNC, SYSDB_TMPL_GPO_BASE"\n", domain->name);
+ DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_BASE"\n", domain->name);
base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
SYSDB_TMPL_GPO_BASE,
@@ -353,32 +352,59 @@ done:
return ret;
}
-static inline bool
-sysdb_gpo_guid_in_list(const char **gpo_guid_list, int num_gpos, const char *gpo_guid)
+/* GPO Result */
+
+static struct ldb_dn *
+sysdb_gpo_result_dn(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *result_name)
{
- size_t i;
+ errno_t ret;
+ char *clean_result_name;
+ struct ldb_dn *dn;
- for (i = 0; i < num_gpos; i++) {
- if (strcasecmp(gpo_guid_list[i], gpo_guid) == 0) {
- break;
- }
+ ret = sysdb_dn_sanitize(NULL, result_name, &clean_result_name);
+ if (ret != EOK) {
+ return NULL;
}
- return (i < num_gpos) ? true : false;
+ DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_RESULT"\n",
+ clean_result_name, domain->name);
+
+ dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO_RESULT,
+ clean_result_name, domain->name);
+ talloc_free(clean_result_name);
+
+ return dn;
}
errno_t
-sysdb_gpo_delete_stale_gpos(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- const char **gpo_guid_list,
- int num_gpos)
+sysdb_gpo_store_gpo_result_setting(struct sss_domain_info *domain,
+ const char *ini_key,
+ const char *ini_value)
{
- struct ldb_result *res;
errno_t ret, sret;
- int i;
+ int lret;
+ struct ldb_message *update_msg;
+ struct ldb_message **msgs;
+ size_t count;
bool in_transaction = false;
- const char *cached_gpo_guid;
- bool stale_gpo_found = false;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) return ENOMEM;
+
+ update_msg = ldb_msg_new(tmp_ctx);
+ if (!update_msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ update_msg->dn = sysdb_gpo_result_dn(update_msg, domain, "gpo_result");
+ if (!update_msg->dn) {
+ ret = ENOMEM;
+ goto done;
+ }
ret = sysdb_transaction_start(domain->sysdb);
if (ret != EOK) {
@@ -388,43 +414,272 @@ sysdb_gpo_delete_stale_gpos(TALLOC_CTX *mem_ctx,
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;
+ /* Check for an existing GPO Result object */
+ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, update_msg->dn,
+ LDB_SCOPE_BASE, NULL, NULL, &count, &msgs);
+
+ if (ret == ENOENT) {
+ /* Create new GPO Result object */
+ DEBUG(SSSDBG_TRACE_FUNC, "Storing setting: key [%s] value [%s]\n",
+ ini_key, ini_value);
+
+ /* Add the objectClass */
+ lret = ldb_msg_add_empty(update_msg, SYSDB_OBJECTCLASS,
+ LDB_FLAG_MOD_ADD,
+ NULL);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ lret = ldb_msg_add_string(update_msg, SYSDB_OBJECTCLASS,
+ SYSDB_GPO_RESULT_OC);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ /* Store the policy_setting if it is non-NULL */
+ if (ini_value) {
+ lret = ldb_msg_add_empty(update_msg, ini_key,
+ LDB_FLAG_MOD_ADD,
+ NULL);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ lret = ldb_msg_add_string(update_msg, ini_key, ini_value);
+ 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,
+ "Failed to add GPO Result: [%s]\n",
+ ldb_strerror(lret));
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+ } else if (ret == EOK && count == 1) {
+ /* Update existing GPO Result object*/
+ if (ini_value) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Updating setting: key [%s] value [%s]\n",
+ ini_key, ini_value);
+ /* Update the policy setting */
+ lret = ldb_msg_add_empty(update_msg, ini_key,
+ LDB_FLAG_MOD_REPLACE,
+ NULL);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
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;
- }
+ lret = ldb_msg_add_fmt(update_msg, ini_key, "%s", ini_value);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
}
+ } else {
+ /* If the value is NULL, we need to remove it from the cache */
+ DEBUG(SSSDBG_TRACE_FUNC, "Removing setting: key [%s]\n", ini_key);
+
+ /* Update the policy setting */
+ lret = ldb_msg_add_empty(update_msg, ini_key,
+ LDB_FLAG_MOD_DELETE,
+ NULL);
+ 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,
+ "Failed to modify GPO Result: [%s]\n", ldb_strerror(lret));
+ ret = sysdb_error_to_errno(lret);
+ goto done;
}
+ } else {
+ ret = EIO;
+ 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");
+ }
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+errno_t
+sysdb_gpo_get_gpo_result_setting(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *ini_key,
+ const char **_ini_value)
+{
+ errno_t ret;
+ int lret;
+ struct ldb_dn *base_dn;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+ const char *ini_value;
+
+ const char *attrs[] = {ini_key, NULL};
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) return ENOMEM;
+
+ DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_RESULT_BASE"\n", domain->name);
+
+ base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
+ SYSDB_TMPL_GPO_RESULT_BASE,
+ domain->name);
+ if (!base_dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
+ LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_RESULT_FILTER);
+ if (lret) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not locate GPO Result: [%s]\n",
+ ldb_strerror(lret));
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ if (res->count == 0) {
+ ret = ENOENT;
+ goto done;
+ }
+
+ ini_value = ldb_msg_find_attr_as_string(res->msgs[0],
+ ini_key,
+ NULL);
+ DEBUG(SSSDBG_TRACE_FUNC, "key [%s] value [%s]\n", ini_key, ini_value);
+
+ *_ini_value = talloc_strdup(mem_ctx, ini_value);
+ if (!*_ini_value && ini_value) {
+ /* If ini_value was NULL, this is expected to also be NULL */
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_ALL, "No setting for key [%s].\n", ini_key);
+ } else if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+
+errno_t
+sysdb_gpo_get_gpo_result_object(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct ldb_result **_result)
+{
+ errno_t ret;
+ int lret;
+ struct ldb_dn *base_dn;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) return ENOMEM;
+
+ DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_RESULT_BASE"\n", domain->name);
+
+ base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
+ SYSDB_TMPL_GPO_RESULT_BASE,
+ domain->name);
+ if (!base_dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
+ LDB_SCOPE_SUBTREE, NULL, SYSDB_GPO_RESULT_FILTER);
+ if (lret) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not locate GPO Result object: [%s]\n",
+ ldb_strerror(lret));
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ if (res->count == 0) {
+ ret = ENOENT;
+ goto done;
+ }
+
+ *_result = talloc_steal(mem_ctx, res);
+ ret = EOK;
+
+done:
+
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_ALL, "No GPO Result object.\n");
+ } else if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+
+errno_t sysdb_gpo_delete_gpo_result_object(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain)
+{
+ struct ldb_result *res;
+ errno_t ret, sret;
+ bool in_transaction = 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_gpo_result_object(mem_ctx, domain, &res);
+ if (ret != EOK && ret != ENOENT) {
+ goto done;
+ } else if (ret != ENOENT) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Deleting GPO Result object\n");
+
+ ret = sysdb_delete_entry(domain->sysdb, res->msgs[0]->dn, true);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not delete GPO Result cache entry\n");
+ goto done;
+ }
}
ret = sysdb_transaction_commit(domain->sysdb);