summaryrefslogtreecommitdiffstats
path: root/src/db
diff options
context:
space:
mode:
authorYassir Elley <yelley@redhat.com>2014-07-22 03:02:30 -0400
committerJakub Hrozek <jhrozek@redhat.com>2014-07-30 10:38:16 +0200
commit64074e584a56611d7563667e0fcdadd215b0c922 (patch)
tree5238707fad620849debccd57eb0af45e6c3d5113 /src/db
parent7a719ffa79161694a354c8d18a28d33377d87db8 (diff)
downloadsssd-64074e584a56611d7563667e0fcdadd215b0c922.tar.gz
sssd-64074e584a56611d7563667e0fcdadd215b0c922.tar.xz
sssd-64074e584a56611d7563667e0fcdadd215b0c922.zip
AD-GPO: add sysdb_gpo support for caching gpo version
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Diffstat (limited to 'src/db')
-rw-r--r--src/db/sysdb.h28
-rw-r--r--src/db/sysdb_gpo.c262
2 files changed, 290 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 17cd5110c..63f596007 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -864,4 +864,32 @@ errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx,
const char *sid_str,
const char **attrs,
struct ldb_result **msg);
+
+/* === Functions related to GPOs === */
+
+#define SYSDB_GPO_CONTAINER "cn=gpos,cn=ad,cn=custom"
+
+#define SYSDB_GPO_OC "gpo"
+#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_TMPL_GPO_BASE SYSDB_GPO_CONTAINER","SYSDB_DOM_BASE
+#define SYSDB_TMPL_GPO SYSDB_GPO_GUID_ATTR"=%s,"SYSDB_TMPL_GPO_BASE
+
+#define SYSDB_GPO_ATTRS { \
+ SYSDB_NAME, \
+ SYSDB_GPO_GUID_ATTR, \
+ SYSDB_GPO_VERSION_ATTR, \
+ NULL }
+
+errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain,
+ const char *gpo_guid,
+ int gpo_version);
+
+errno_t sysdb_gpo_get_gpo(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
new file mode 100644
index 000000000..3c23c5b8f
--- /dev/null
+++ b/src/db/sysdb_gpo.c
@@ -0,0 +1,262 @@
+/*
+ SSSD
+
+ Authors:
+ Yassir Elley <yelley@redhat.com>
+
+ Copyright (C) 2014 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "db/sysdb.h"
+#include "db/sysdb_private.h"
+
+static struct ldb_dn *
+sysdb_gpo_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain,
+ const char *gpo_guid)
+{
+ errno_t ret;
+ char *clean_gpo_guid;
+ struct ldb_dn *dn;
+
+ ret = sysdb_dn_sanitize(NULL, gpo_guid, &clean_gpo_guid);
+ if (ret != EOK) {
+ return NULL;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, 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);
+ talloc_free(clean_gpo_guid);
+
+ return dn;
+}
+
+errno_t
+sysdb_gpo_store_gpo(struct sss_domain_info *domain,
+ const char *gpo_guid,
+ int gpo_version)
+{
+ errno_t ret, sret;
+ int lret;
+ struct ldb_message *update_msg;
+ struct ldb_message **msgs;
+ static const char *attrs[] = SYSDB_GPO_ATTRS;
+ size_t count;
+ bool in_transaction = 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_dn(update_msg, domain, gpo_guid);
+ if (!update_msg->dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_transaction_start(domain->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
+ goto done;
+ }
+
+ in_transaction = true;
+
+ /* Check for an existing gpo_guid entry */
+ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, update_msg->dn,
+ LDB_SCOPE_BASE, NULL, attrs, &count, &msgs);
+
+ if (ret == ENOENT) {
+ /* Create new GPO */
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Adding new GPO [gpo_guid:%s][gpo_version:%d]\n",
+ gpo_guid, gpo_version);
+
+ /* 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_OC);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ /* Add the GPO GUID */
+ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_GUID_ATTR,
+ 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_GPO_GUID_ATTR, gpo_guid);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ /* Add the Version */
+ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_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_VERSION_ATTR,
+ "%d", gpo_version);
+ 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: [%s]\n",
+ ldb_strerror(lret));
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+ } else if (ret == EOK && count == 1) {
+ /* Update the existing GPO */
+
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Updating new GPO [%s][%s]\n", domain->name, gpo_guid);
+
+ /* Add the Version */
+ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_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_VERSION_ATTR,
+ "%d", gpo_version);
+ 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: [%s]\n", ldb_strerror(lret));
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+ } else {
+ ret = EIO;
+ goto done;
+ }
+
+ 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(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *gpo_guid,
+ struct ldb_result **_result)
+{
+ errno_t ret;
+ int lret;
+ struct ldb_dn *base_dn;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+
+ const char *attrs[] = SYSDB_GPO_ATTRS;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) return ENOMEM;
+
+ DEBUG(SSSDBG_TRACE_FUNC, SYSDB_TMPL_GPO_BASE"\n", domain->name);
+
+ base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
+ SYSDB_TMPL_GPO_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_FILTER, gpo_guid);
+ if (lret) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Could not locate GPO: [%s]\n",
+ ldb_strerror(lret));
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ if (res->count > 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Search for GUID [%s] returned more than " \
+ "one object.\n", gpo_guid);
+ ret = EINVAL;
+ goto done;
+ } else 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 such entry.\n");
+ } else if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret));
+ }
+
+ talloc_free(tmp_ctx);
+ return ret;
+}