From 3f1895a6d7e1b1b25daced255eb85cb3d60f14e8 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Tue, 16 Sep 2014 15:18:53 +0200 Subject: [PATCH 01/10] sysdb: add sysdb_update_view_name() --- Makefile.am | 1 + src/db/sysdb.h | 11 ++++ src/db/sysdb_views.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 src/db/sysdb_views.c diff --git a/Makefile.am b/Makefile.am index 4ee7eb9..6b06e7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -668,6 +668,7 @@ libsss_util_la_SOURCES = \ src/db/sysdb_services.c \ src/db/sysdb_autofs.c \ src/db/sysdb_subdomains.c \ + src/db/sysdb_views.c \ src/db/sysdb_ranges.c \ src/db/sysdb_idmap.c \ src/db/sysdb_gpo.c \ diff --git a/src/db/sysdb.h b/src/db/sysdb.h index c93119c..b87b956 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 0000000..f183525 --- /dev/null +++ b/src/db/sysdb_views.c @@ -0,0 +1,182 @@ +/* + SSSD + + System Database - View and Override related calls + + Copyright (C) 2014 Sumit Bose + + 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 . +*/ + +#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; +} + -- 1.8.3.1