From 0f907d8501387ec32dbb00e1c38d5da25e698f90 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 14 Nov 2017 13:14:14 +0100
Subject: [PATCH 57/57] sysdb: remove IDXONE and objectClass from users and
groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch does the needed sysdb update for the previous to patches. It
removes the one-level search index IDXONE and replaces objectClass with
objectCategory in the user and group objects.
Related to https://pagure.io/SSSD/sssd/issue/3503
Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 2927da49dd8a16fff6312d89ad43cc355655800c)
---
src/db/sysdb_init.c | 52 +++++++++++-
src/db/sysdb_private.h | 11 ++-
src/db/sysdb_upgrade.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 274 insertions(+), 6 deletions(-)
diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c
index 44a7918f603fe1368b7d81738666de6bb47b83d0..74ad23f3050da0ae14fa495d2302f4a858fcd3c5 100644
--- a/src/db/sysdb_init.c
+++ b/src/db/sysdb_init.c
@@ -359,8 +359,48 @@ static errno_t sysdb_ts_cache_upgrade(TALLOC_CTX *mem_ctx,
const char *cur_version,
const char **_new_version)
{
- /* Currently the sysdb cache only has one version */
- return EFAULT;
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+ const char *version;
+ struct ldb_context *save_ldb;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ /* The upgrade process depends on having ldb around, yet the upgrade
+ * function shouldn't set the ldb pointer, only the connect function
+ * should after it's successful. To avoid hard refactoring, save the
+ * ldb pointer here and restore in the 'done' handler
+ */
+ save_ldb = sysdb->ldb;
+ sysdb->ldb = ldb;
+
+ version = talloc_strdup(tmp_ctx, cur_version);
+ if (version == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "Upgrading timstamp cache of DB [%s] from version: %s\n",
+ domain->name, version);
+
+ if (strcmp(version, SYSDB_TS_VERSION_0_1) == 0) {
+ ret = sysdb_ts_upgrade_01(sysdb, &version);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ ret = EOK;
+
+done:
+ sysdb->ldb = save_ldb;
+ *_new_version = version;
+ talloc_free(tmp_ctx);
+ return ret;
}
static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx,
@@ -511,6 +551,14 @@ static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx,
}
}
+ if (strcmp(version, SYSDB_VERSION_0_19) == 0) {
+ ret = sysdb_upgrade_19(sysdb, &version);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+
ret = EOK;
done:
sysdb->ldb = save_ldb;
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index dbd75615bc212e73c4338a76dceaa68a5889ed1d..cac06ba46da23080d1ab661502d0792bd37b9291 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -23,6 +23,7 @@
#ifndef __INT_SYS_DB_H__
#define __INT_SYS_DB_H__
+#define SYSDB_VERSION_0_20 "0.20"
#define SYSDB_VERSION_0_19 "0.19"
#define SYSDB_VERSION_0_18 "0.18"
#define SYSDB_VERSION_0_17 "0.17"
@@ -43,7 +44,7 @@
#define SYSDB_VERSION_0_2 "0.2"
#define SYSDB_VERSION_0_1 "0.1"
-#define SYSDB_VERSION SYSDB_VERSION_0_19
+#define SYSDB_VERSION SYSDB_VERSION_0_20
#define SYSDB_BASE_LDIF \
"dn: @ATTRIBUTES\n" \
@@ -72,7 +73,6 @@
"@IDXATTR: sudoUser\n" \
"@IDXATTR: sshKnownHostsExpire\n" \
"@IDXATTR: objectSIDString\n" \
- "@IDXONE: 1\n" \
"@IDXATTR: ghost\n" \
"@IDXATTR: userPrincipalName\n" \
"@IDXATTR: canonicalUserPrincipalName\n" \
@@ -92,9 +92,10 @@
"\n"
/* The timestamp cache has its own versioning */
+#define SYSDB_TS_VERSION_0_2 "0.2"
#define SYSDB_TS_VERSION_0_1 "0.1"
-#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_1
+#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_2
#define SYSDB_TS_BASE_LDIF \
"dn: @ATTRIBUTES\n" \
@@ -103,7 +104,6 @@
"dn: @INDEXLIST\n" \
"@IDXATTR: lastUpdate\n" \
"@IDXATTR: dataExpireTimestamp\n" \
- "@IDXONE: 1\n" \
"\n" \
"dn: cn=sysdb\n" \
"cn: sysdb\n" \
@@ -169,6 +169,9 @@ int sysdb_upgrade_17(struct sysdb_ctx *sysdb,
struct sysdb_dom_upgrade_ctx *upgrade_ctx,
const char **ver);
int sysdb_upgrade_18(struct sysdb_ctx *sysdb, const char **ver);
+int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver);
+
+int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver);
int sysdb_add_string(struct ldb_message *msg,
const char *attr, const char *value);
diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c
index 365d45f7ebd78523ca9ec4b9c2158cc09acb5489..bc157a24664239bc1255e49a1825243a07acc90f 100644
--- a/src/db/sysdb_upgrade.c
+++ b/src/db/sysdb_upgrade.c
@@ -2317,6 +2317,223 @@ done:
return ret;
}
+static errno_t add_object_category(struct ldb_context *ldb,
+ struct upgrade_ctx *ctx)
+{
+ errno_t ret;
+ struct ldb_result *objects = NULL;
+ const char *attrs[] = { SYSDB_OBJECTCLASS, NULL };
+ struct ldb_dn *base_dn;
+ size_t c;
+ const char *class_name;
+ struct ldb_message *msg = NULL;
+ struct ldb_message *del_msg = NULL;
+
+ base_dn = ldb_dn_new(ctx, ldb, SYSDB_BASE);
+ if (base_dn == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed create base dn.\n");
+ return ENOMEM;
+ }
+
+ ret = ldb_search(ldb, ctx, &objects, base_dn,
+ LDB_SCOPE_SUBTREE, attrs,
+ "(|("SYSDB_OBJECTCLASS"="SYSDB_USER_CLASS")"
+ "("SYSDB_OBJECTCLASS"="SYSDB_GROUP_CLASS"))");
+ talloc_free(base_dn);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to search objects: %d\n", ret);
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ if (objects == NULL || objects->count == 0) {
+ DEBUG(SSSDBG_TRACE_LIBS, "No objects found, nothing to do.");
+ ret = EOK;
+ goto done;
+ }
+
+ del_msg = ldb_msg_new(ctx);
+ if (del_msg == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_empty(del_msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_DELETE,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL, "Found [%d] objects.\n", objects->count);
+ for (c = 0; c < objects->count; c++) {
+ DEBUG(SSSDBG_TRACE_ALL, "Updating [%s].\n",
+ ldb_dn_get_linearized(objects->msgs[c]->dn));
+
+ class_name = ldb_msg_find_attr_as_string(objects->msgs[c],
+ SYSDB_OBJECTCLASS, NULL);
+ if (class_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Searched objects by objectClass, "
+ "but result does not have one.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ talloc_free(msg);
+ msg = ldb_msg_new(ctx);
+ if (msg == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ msg->dn = objects->msgs[c]->dn;
+ del_msg->dn = objects->msgs[c]->dn;
+
+ ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCATEGORY, LDB_FLAG_MOD_ADD,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ ret = ldb_msg_add_string(msg, SYSDB_OBJECTCATEGORY, class_name);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n");
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL, "Adding [%s] to [%s].\n", class_name,
+ ldb_dn_get_linearized(objects->msgs[c]->dn));
+ ret = ldb_modify(ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to add objectCategory to %s: %d.\n",
+ ldb_dn_get_linearized(objects->msgs[c]->dn),
+ sysdb_error_to_errno(ret));
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ ret = ldb_modify(ldb, del_msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to remove objectClass from %s: %d.\n",
+ ldb_dn_get_linearized(objects->msgs[c]->dn),
+ sysdb_error_to_errno(ret));
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(msg);
+ talloc_free(del_msg);
+ talloc_free(objects);
+
+ return ret;
+}
+
+int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver)
+{
+ struct upgrade_ctx *ctx;
+ errno_t ret;
+ struct ldb_message *msg = NULL;
+
+ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_20, &ctx);
+ if (ret) {
+ return ret;
+ }
+
+ ret = add_object_category(sysdb->ldb, ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "add_object_category failed.\n");
+ goto done;
+ }
+
+ /* Remove @IDXONE from index */
+ msg = ldb_msg_new(ctx);
+ if (msg == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST");
+ if (msg->dn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_DELETE, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_modify(sysdb->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ /* conversion done, update version number */
+ ret = update_version(ctx);
+
+done:
+ ret = finish_upgrade(ret, &ctx, ver);
+ return ret;
+}
+
+int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver)
+{
+ struct upgrade_ctx *ctx;
+ errno_t ret;
+ struct ldb_message *msg = NULL;
+
+ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_TS_VERSION_0_2, &ctx);
+ if (ret) {
+ return ret;
+ }
+
+ /* Remove @IDXONE from index */
+ talloc_free(msg);
+ msg = ldb_msg_new(ctx);
+ if (msg == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST");
+ if (msg->dn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_DELETE, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_modify(sysdb->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ /* conversion done, update version number */
+ ret = update_version(ctx);
+
+done:
+ ret = finish_upgrade(ret, &ctx, ver);
+ return ret;
+}
+
/*
* Example template for future upgrades.
* Copy and change version numbers as appropriate.
--
2.14.3