summaryrefslogtreecommitdiffstats
path: root/src/db
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-09-16 15:18:53 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-16 17:54:54 +0200
commit2ef62c64e7f07c8aced3f72850008ecb72860162 (patch)
treee6dc7e1e44c5153ecc91447fd051f5e0951a47ce /src/db
parent0d01e4f6cc21d8ca0e4fafe59c7cbfa1459fa47e (diff)
downloadsssd-2ef62c64e7f07c8aced3f72850008ecb72860162.tar.gz
sssd-2ef62c64e7f07c8aced3f72850008ecb72860162.tar.xz
sssd-2ef62c64e7f07c8aced3f72850008ecb72860162.zip
sysdb: add sysdb_update_view_name()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Diffstat (limited to 'src/db')
-rw-r--r--src/db/sysdb.h11
-rw-r--r--src/db/sysdb_views.c181
2 files changed, 192 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index c93119cf1..b87b956c9 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -36,11 +36,13 @@
#define SYSDB_CUSTOM_CONTAINER "cn=custom"
#define SYSDB_NETGROUP_CONTAINER "cn=Netgroups"
#define SYSDB_RANGE_CONTAINER "cn=ranges"
+#define SYSDB_VIEW_CONTAINER "cn=views"
#define SYSDB_TMPL_USER_BASE SYSDB_USERS_CONTAINER","SYSDB_DOM_BASE
#define SYSDB_TMPL_GROUP_BASE SYSDB_GROUPS_CONTAINER","SYSDB_DOM_BASE
#define SYSDB_TMPL_CUSTOM_BASE SYSDB_CUSTOM_CONTAINER","SYSDB_DOM_BASE
#define SYSDB_TMPL_NETGROUP_BASE SYSDB_NETGROUP_CONTAINER","SYSDB_DOM_BASE
#define SYSDB_TMPL_RANGE_BASE SYSDB_RANGE_CONTAINER","SYSDB_BASE
+#define SYSDB_TMPL_VIEW_BASE SYSDB_VIEW_CONTAINER","SYSDB_BASE
#define SYSDB_SUBDOMAIN_CLASS "subdomain"
#define SYSDB_USER_CLASS "user"
@@ -145,6 +147,10 @@
#define SYSDB_AD_ACCOUNT_EXPIRES "adAccountExpires"
#define SYSDB_AD_USER_ACCOUNT_CONTROL "adUserAccountControl"
+#define SYSDB_VIEW_CLASS "view"
+#define SYSDB_VIEW_NAME "viewName"
+#define SYSDB_DEFAULT_VIEW_NAME "default"
+
#define SYSDB_NEXTID_FILTER "("SYSDB_NEXTID"=*)"
#define SYSDB_UC "objectclass="SYSDB_USER_CLASS
@@ -412,6 +418,11 @@ errno_t sysdb_range_create(struct sysdb_ctx *sysdb, struct range_info *range);
errno_t sysdb_update_ranges(struct sysdb_ctx *sysdb,
struct range_info **ranges);
+errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, const char *view_name);
+
+errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
+ char **view_name);
+
/* Sysdb initialization.
* call this function *only* once to initialize the database and get
* the sysdb ctx */
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
new file mode 100644
index 000000000..c0ca269aa
--- /dev/null
+++ b/src/db/sysdb_views.c
@@ -0,0 +1,181 @@
+/*
+ SSSD
+
+ System Database - View and Override related calls
+
+ Copyright (C) 2014 Sumit Bose <sbose@redhat.com>
+
+ 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 "util/util.h"
+#include "db/sysdb_private.h"
+
+/* In general is should not be possible that there is a view container without
+ * a view name set. But to be on the safe side we return both information
+ * separately. */
+static errno_t sysdb_get_view_name_ex(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ char **_view_name,
+ bool *view_container_exists)
+{
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+ const char *tmp_str;
+ struct ldb_dn *view_base_dn;
+ struct ldb_result *res;
+ const char *attrs[] = {SYSDB_VIEW_NAME,
+ NULL};
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ view_base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_BASE);
+ if (view_base_dn == NULL) {
+ ret = EIO;
+ goto done;
+ }
+ ret = ldb_search(sysdb->ldb, tmp_ctx, &res, view_base_dn, LDB_SCOPE_BASE,
+ attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+
+ if (res->count > 1) {
+ DEBUG(SSSDBG_OP_FAILURE, "Base search returned [%d] results, "
+ "expected 1.\n", res->count);
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (res->count == 0) {
+ *view_container_exists = false;
+ ret = ENOENT;
+ goto done;
+ } else {
+ *view_container_exists = true;
+ tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_VIEW_NAME,
+ NULL);
+ if (tmp_str == NULL) {
+ ret = ENOENT;
+ goto done;
+ }
+ }
+
+ *_view_name = talloc_steal(mem_ctx, discard_const(tmp_str));
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
+ char **view_name)
+{
+ bool view_container_exists;
+
+ return sysdb_get_view_name_ex(mem_ctx, sysdb, view_name,
+ &view_container_exists);
+}
+
+errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb,
+ const char *view_name)
+{
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+ char *tmp_str;
+ bool view_container_exists = false;
+ bool add_view_name = false;
+ struct ldb_message *msg;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_get_view_name_ex(tmp_ctx, sysdb, &tmp_str,
+ &view_container_exists);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name_ex failed.\n");
+ goto done;
+ }
+
+ if (ret == EOK) {
+ if (strcmp(tmp_str, view_name) == 0) {
+ /* view name already known, nothing to do */
+ DEBUG(SSSDBG_TRACE_ALL, "View name already in place.\n");
+ ret = EOK;
+ goto done;
+ } else {
+ /* view name changed */
+ /* not supported atm */
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "View name changed from [%s] to [%s]. NOT SUPPORTED.\n",
+ tmp_str, view_name);
+ ret = ENOTSUP;
+ goto done;
+ }
+ }
+
+ add_view_name = true;
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (msg == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_BASE);
+ if (msg->dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ ret = ldb_msg_add_empty(msg, SYSDB_VIEW_NAME,
+ add_view_name ? LDB_FLAG_MOD_ADD
+ : LDB_FLAG_MOD_REPLACE,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ ret = ldb_msg_add_string(msg, SYSDB_VIEW_NAME, view_name);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ if (view_container_exists) {
+ ret = ldb_modify(sysdb->ldb, msg);
+ } else {
+ ret = ldb_add(sysdb->ldb, msg);
+ }
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to %s view container",
+ view_container_exists ? "modify" : "add");
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}