dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0063-SSSD-Allow-refreshing-only-certain-section-with-genc.patch

71e593
From 92b8f8d404bfe72abe8cd324f5569be5ba2c6db1 Mon Sep 17 00:00:00 2001
71e593
From: Jakub Hrozek <jhrozek@redhat.com>
71e593
Date: Tue, 9 Oct 2018 15:32:12 +0200
71e593
Subject: [PATCH 63/66] SSSD: Allow refreshing only certain section with
71e593
 --genconf
71e593
MIME-Version: 1.0
71e593
Content-Type: text/plain; charset=UTF-8
71e593
Content-Transfer-Encoding: 8bit
71e593
71e593
Related:
71e593
https://pagure.io/SSSD/sssd/issue/3862
71e593
71e593
Adds a new option --genconf-section for the sssd binary.  If this new
71e593
option --genconf-section is used, then only the section passed as this
71e593
option's value is refreshed.
71e593
71e593
Conversely, if this section no longer exists in the config file, then it
71e593
is removed from the confdb
71e593
71e593
Reviewed-by: Michal Židek <mzidek@redhat.com>
71e593
---
71e593
 src/confdb/confdb_setup.c    | 80 +++++++++++++++++++++++++++---------
71e593
 src/confdb/confdb_setup.h    |  1 +
71e593
 src/man/sssd.8.xml           | 27 ++++++++++++
71e593
 src/monitor/monitor.c        | 17 +++++++-
71e593
 src/tools/common/sss_tools.c |  1 +
71e593
 src/util/sss_ini.c           | 54 ++++++++++++++++++++++++
71e593
 src/util/sss_ini.h           |  1 +
71e593
 7 files changed, 160 insertions(+), 21 deletions(-)
71e593
71e593
diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c
71e593
index c2b7f9f73..7acefbe6b 100644
71e593
--- a/src/confdb/confdb_setup.c
71e593
+++ b/src/confdb/confdb_setup.c
71e593
@@ -138,6 +138,7 @@ static int confdb_create_base(struct confdb_ctx *cdb)
71e593
 static int confdb_ldif_from_ini_file(TALLOC_CTX *mem_ctx,
71e593
                                      const char *config_file,
71e593
                                      const char *config_dir,
71e593
+                                     const char *only_section,
71e593
                                      struct sss_ini_initdata *init_data,
71e593
                                      const char **_timestr,
71e593
                                      const char **_ldif)
71e593
@@ -222,7 +223,7 @@ static int confdb_ldif_from_ini_file(TALLOC_CTX *mem_ctx,
71e593
         }
71e593
     }
71e593
 
71e593
-    ret = sss_confdb_create_ldif(mem_ctx, init_data, _ldif);
71e593
+    ret = sss_confdb_create_ldif(mem_ctx, init_data, only_section, _ldif);
71e593
     if (ret != EOK) {
71e593
         DEBUG(SSSDBG_FATAL_FAILURE, "Could not create LDIF for confdb\n");
71e593
         return ret;
71e593
@@ -249,7 +250,50 @@ static int confdb_fallback_ldif(TALLOC_CTX *mem_ctx,
71e593
     return EOK;
71e593
 }
71e593
 
71e593
-static int confdb_init_db(const char *config_file, const char *config_dir,
71e593
+static int confdb_write_ldif(struct confdb_ctx *cdb,
71e593
+                             const char *config_ldif,
71e593
+                             bool replace_whole_db)
71e593
+{
71e593
+    int ret;
71e593
+    struct ldb_ldif *ldif;
71e593
+
71e593
+    while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) {
71e593
+        if (ldif->changetype == LDB_CHANGETYPE_DELETE) {
71e593
+            /* We should remove this section */
71e593
+            ret = ldb_delete(cdb->ldb, ldif->msg->dn);
71e593
+            if (ret == LDB_ERR_NO_SUCH_OBJECT) {
71e593
+                /* Removing a non-existing section is not an error */
71e593
+                ret = LDB_SUCCESS;
71e593
+            }
71e593
+        } else {
71e593
+            ret = ldb_add(cdb->ldb, ldif->msg);
71e593
+            if (ret != LDB_SUCCESS && replace_whole_db == false) {
71e593
+                /* This section already existed, remove and re-add it. We
71e593
+                * really want to replace the whole thing instead of messing
71e593
+                * around with changetypes and flags on individual elements
71e593
+                */
71e593
+                ret = ldb_delete(cdb->ldb, ldif->msg->dn);
71e593
+                if (ret == LDB_SUCCESS) {
71e593
+                    ret = ldb_add(cdb->ldb, ldif->msg);
71e593
+                }
71e593
+            }
71e593
+        }
71e593
+
71e593
+        if (ret != LDB_SUCCESS) {
71e593
+            DEBUG(SSSDBG_FATAL_FAILURE,
71e593
+                "Failed to initialize DB (%d,[%s]), aborting!\n",
71e593
+                ret, ldb_errstring(cdb->ldb));
71e593
+            return EIO;
71e593
+        }
71e593
+        ldb_ldif_read_free(cdb->ldb, ldif);
71e593
+    }
71e593
+
71e593
+    return EOK;
71e593
+}
71e593
+
71e593
+static int confdb_init_db(const char *config_file,
71e593
+                          const char *config_dir,
71e593
+                          const char *only_section,
71e593
                           struct confdb_ctx *cdb)
71e593
 {
71e593
     TALLOC_CTX *tmp_ctx;
71e593
@@ -259,7 +303,6 @@ static int confdb_init_db(const char *config_file, const char *config_dir,
71e593
     const char *timestr = NULL;
71e593
     const char *config_ldif;
71e593
     const char *vals[2] = { NULL, NULL };
71e593
-    struct ldb_ldif *ldif;
71e593
     struct sss_ini_initdata *init_data;
71e593
 
71e593
     tmp_ctx = talloc_new(cdb);
71e593
@@ -281,6 +324,7 @@ static int confdb_init_db(const char *config_file, const char *config_dir,
71e593
         ret = confdb_ldif_from_ini_file(tmp_ctx,
71e593
                                         config_file,
71e593
                                         config_dir,
71e593
+                                        only_section,
71e593
                                         init_data,
71e593
                                         &timestr,
71e593
                                         &config_ldif);
71e593
@@ -318,24 +362,21 @@ static int confdb_init_db(const char *config_file, const char *config_dir,
71e593
     }
71e593
     in_transaction = true;
71e593
 
71e593
-    /* Purge existing database */
71e593
-    ret = confdb_purge(cdb);
71e593
-    if (ret != EOK) {
71e593
-        DEBUG(SSSDBG_FATAL_FAILURE,
71e593
-              "Could not purge existing configuration\n");
71e593
-        goto done;
71e593
-    }
71e593
-
71e593
-    while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) {
71e593
-        ret = ldb_add(cdb->ldb, ldif->msg);
71e593
-        if (ret != LDB_SUCCESS) {
71e593
+    /* Purge existing database, if we are reinitializing the confdb completely */
71e593
+    if (only_section == NULL) {
71e593
+        ret = confdb_purge(cdb);
71e593
+        if (ret != EOK) {
71e593
             DEBUG(SSSDBG_FATAL_FAILURE,
71e593
-                  "Failed to initialize DB (%d,[%s]), aborting!\n",
71e593
-                  ret, ldb_errstring(cdb->ldb));
71e593
-            ret = EIO;
71e593
+                "Could not purge existing configuration\n");
71e593
             goto done;
71e593
         }
71e593
-        ldb_ldif_read_free(cdb->ldb, ldif);
71e593
+    }
71e593
+
71e593
+    ret = confdb_write_ldif(cdb,
71e593
+                            config_ldif,
71e593
+                            only_section == NULL ? true : false);
71e593
+    if (ret != EOK) {
71e593
+        goto done;
71e593
     }
71e593
 
71e593
     /* now store the lastUpdate time so that we do not re-init if nothing
71e593
@@ -377,6 +418,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx,
71e593
                      const char *cdb_file,
71e593
                      const char *config_file,
71e593
                      const char *config_dir,
71e593
+                     const char *only_section,
71e593
                      struct confdb_ctx **_cdb)
71e593
 {
71e593
     TALLOC_CTX *tmp_ctx;
71e593
@@ -432,7 +474,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx,
71e593
         goto done;
71e593
     }
71e593
 
71e593
-    ret = confdb_init_db(config_file, config_dir, cdb);
71e593
+    ret = confdb_init_db(config_file, config_dir, only_section, cdb);
71e593
     if (ret != EOK) {
71e593
         DEBUG(SSSDBG_FATAL_FAILURE, "ConfDB initialization has failed "
71e593
               "[%d]: %s\n", ret, sss_strerror(ret));
71e593
diff --git a/src/confdb/confdb_setup.h b/src/confdb/confdb_setup.h
71e593
index 9f647ec16..c7fe59541 100644
71e593
--- a/src/confdb/confdb_setup.h
71e593
+++ b/src/confdb/confdb_setup.h
71e593
@@ -49,6 +49,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx,
71e593
                      const char *cdb_file,
71e593
                      const char *config_file,
71e593
                      const char *config_dir,
71e593
+                     const char *only_section,
71e593
                      struct confdb_ctx **_cdb);
71e593
 
71e593
 #endif /* CONFDB_SETUP_H_ */
71e593
diff --git a/src/man/sssd.8.xml b/src/man/sssd.8.xml
71e593
index f2cbe015b..ff3d8825d 100644
71e593
--- a/src/man/sssd.8.xml
71e593
+++ b/src/man/sssd.8.xml
71e593
@@ -164,6 +164,33 @@
71e593
                     </para>
71e593
                 </listitem>
71e593
             </varlistentry>
71e593
+            <varlistentry>
71e593
+                <term>
71e593
+                    <option>-g</option>,<option>--genconf</option>
71e593
+                </term>
71e593
+                <listitem>
71e593
+                    <para>
71e593
+                        Do not start the SSSD, but refresh the configuration
71e593
+                        database from the contents of
71e593
+                        <filename>/etc/sssd/sssd.conf</filename> and exit.
71e593
+                    </para>
71e593
+                </listitem>
71e593
+            </varlistentry>
71e593
+            <varlistentry>
71e593
+                <term>
71e593
+                    <option>-s</option>,<option>--genconf-section</option>
71e593
+                </term>
71e593
+                <listitem>
71e593
+                    <para>
71e593
+                        Similar to <quote>--genconf</quote>, but only refresh
71e593
+                        a single section from the configuration file.  This
71e593
+                        option is useful mainly to be called from systemd
71e593
+                        unit files to allow socket-activated responders
71e593
+                        to refresh their configuration without requiring
71e593
+                        the administrator to restart the whole SSSD.
71e593
+                    </para>
71e593
+                </listitem>
71e593
+            </varlistentry>
71e593
             <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/param_help.xml" />
71e593
             <varlistentry>
71e593
                 <term>
71e593
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
71e593
index ea689c604..136cf8f27 100644
71e593
--- a/src/monitor/monitor.c
71e593
+++ b/src/monitor/monitor.c
71e593
@@ -1579,6 +1579,7 @@ static int monitor_ctx_destructor(void *mem)
71e593
 errno_t load_configuration(TALLOC_CTX *mem_ctx,
71e593
                            const char *config_file,
71e593
                            const char *config_dir,
71e593
+                           const char *only_section,
71e593
                            struct mt_ctx **monitor)
71e593
 {
71e593
     errno_t ret;
71e593
@@ -1600,7 +1601,8 @@ errno_t load_configuration(TALLOC_CTX *mem_ctx,
71e593
         goto done;
71e593
     }
71e593
 
71e593
-    ret = confdb_setup(ctx, cdb_file, config_file, config_dir, &ctx->cdb);
71e593
+    ret = confdb_setup(ctx, cdb_file, config_file, config_dir, only_section,
71e593
+                       &ctx->cdb);
71e593
     if (ret != EOK) {
71e593
         DEBUG(SSSDBG_FATAL_FAILURE, "Unable to setup ConfDB [%d]: %s\n",
71e593
              ret, sss_strerror(ret));
71e593
@@ -2329,6 +2331,7 @@ int main(int argc, const char *argv[])
71e593
     char *opt_config_file = NULL;
71e593
     char *opt_logger = NULL;
71e593
     char *config_file = NULL;
71e593
+    char *opt_genconf_section = NULL;
71e593
     int flags = 0;
71e593
     struct main_context *main_ctx;
71e593
     TALLOC_CTX *tmp_ctx;
71e593
@@ -2352,6 +2355,9 @@ int main(int argc, const char *argv[])
71e593
         {"genconf", 'g', POPT_ARG_NONE, &opt_genconf, 0, \
71e593
          _("Refresh the configuration database, then exit"), \
71e593
          NULL}, \
71e593
+        {"genconf-section", 's', POPT_ARG_STRING, &opt_genconf_section, 0, \
71e593
+         _("Similar to --genconf, but only refreshes the given section"), \
71e593
+         NULL}, \
71e593
         {"version", '\0', POPT_ARG_NONE, &opt_version, 0, \
71e593
          _("Print version number and exit"), NULL }, \
71e593
         POPT_TABLEEND
71e593
@@ -2378,6 +2384,13 @@ int main(int argc, const char *argv[])
71e593
         return EXIT_SUCCESS;
71e593
     }
71e593
 
71e593
+    if (opt_genconf_section) {
71e593
+        /* --genconf-section implies genconf, just restricted to a single
71e593
+         * section
71e593
+         */
71e593
+        opt_genconf = 1;
71e593
+    }
71e593
+
71e593
     /* If the level or timestamps was passed at the command-line, we want
71e593
      * to save it and pass it to the children later.
71e593
      */
71e593
@@ -2529,7 +2542,7 @@ int main(int argc, const char *argv[])
71e593
 
71e593
     /* Parse config file, fail if cannot be done */
71e593
     ret = load_configuration(tmp_ctx, config_file, CONFDB_DEFAULT_CONFIG_DIR,
71e593
-                             &monitor);
71e593
+                             opt_genconf_section, &monitor);
71e593
     if (ret != EOK) {
71e593
         switch (ret) {
71e593
         case EPERM:
71e593
diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c
71e593
index 701db2d93..0d918f164 100644
71e593
--- a/src/tools/common/sss_tools.c
71e593
+++ b/src/tools/common/sss_tools.c
71e593
@@ -98,6 +98,7 @@ static errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx,
71e593
 
71e593
     ret = confdb_setup(mem_ctx, path,
71e593
                        SSSD_CONFIG_FILE, CONFDB_DEFAULT_CONFIG_DIR,
71e593
+                       NULL,
71e593
                        &confdb);
71e593
     talloc_zfree(path);
71e593
     if (ret != EOK) {
71e593
diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c
71e593
index 9a059fc00..3c15b2809 100644
71e593
--- a/src/util/sss_ini.c
71e593
+++ b/src/util/sss_ini.c
71e593
@@ -414,6 +414,7 @@ void sss_ini_config_destroy(struct sss_ini_initdata *init_data)
71e593
 
71e593
 int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx,
71e593
                            struct sss_ini_initdata *init_data,
71e593
+                           const char *only_section,
71e593
                            const char **config_ldif)
71e593
 {
71e593
     int ret, i, j;
71e593
@@ -436,6 +437,14 @@ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx,
71e593
 #else
71e593
     struct collection_item *obj = NULL;
71e593
 #endif
71e593
+    bool section_handled = true;
71e593
+
71e593
+    if (only_section != NULL) {
71e593
+        /* If the section is specified, we must handle it, either by adding
71e593
+         * its contents or by deleting the section if it doesn't exist
71e593
+         */
71e593
+        section_handled = false;
71e593
+    }
71e593
 
71e593
     ldif_len = strlen(CONFDB_INTERNAL_LDIF);
71e593
     ldif = talloc_array(mem_ctx, char, ldif_len+1);
71e593
@@ -466,6 +475,18 @@ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx,
71e593
             goto error;
71e593
         }
71e593
 
71e593
+        if (only_section != NULL) {
71e593
+            if (strcasecmp(only_section, sections[i])) {
71e593
+                DEBUG(SSSDBG_TRACE_FUNC, "Skipping section %s\n", sections[i]);
71e593
+                continue;
71e593
+            } else {
71e593
+                /* Mark the requested section as handled so that we don't
71e593
+                 * try to re-add it later
71e593
+                 */
71e593
+                section_handled = true;
71e593
+            }
71e593
+        }
71e593
+
71e593
         dn = talloc_asprintf(tmp_ctx,
71e593
                              "dn: %s,cn=config\n"
71e593
                              "cn: %s\n",
71e593
@@ -552,6 +573,39 @@ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx,
71e593
         talloc_free(dn);
71e593
     }
71e593
 
71e593
+
71e593
+    if (only_section != NULL && section_handled == false) {
71e593
+        /* If only a single section was supposed to be
71e593
+         * handled, but it wasn't found in the INI file,
71e593
+         * create an LDIF that would remove the section
71e593
+         */
71e593
+        ret = parse_section(tmp_ctx, only_section, &sec_dn, NULL);
71e593
+        if (ret != EOK) {
71e593
+            goto error;
71e593
+        }
71e593
+
71e593
+        dn = talloc_asprintf(tmp_ctx,
71e593
+                             "dn: %s,cn=config\n"
71e593
+                             "changetype: delete\n\n",
71e593
+                             sec_dn);
71e593
+        if (dn == NULL) {
71e593
+            ret = ENOMEM;
71e593
+            goto error;
71e593
+        }
71e593
+        dn_size = strlen(dn);
71e593
+
71e593
+        tmp_ldif = talloc_realloc(mem_ctx, ldif, char,
71e593
+                                  ldif_len+dn_size+1);
71e593
+        if (!tmp_ldif) {
71e593
+            ret = ENOMEM;
71e593
+            goto error;
71e593
+        }
71e593
+
71e593
+        ldif = tmp_ldif;
71e593
+        memcpy(ldif+ldif_len, dn, dn_size);
71e593
+        ldif_len += dn_size;
71e593
+    }
71e593
+
71e593
     ldif[ldif_len] = '\0';
71e593
 
71e593
     free_section_list(sections);
71e593
diff --git a/src/util/sss_ini.h b/src/util/sss_ini.h
71e593
index 0b173831d..470b88f99 100644
71e593
--- a/src/util/sss_ini.h
71e593
+++ b/src/util/sss_ini.h
71e593
@@ -77,6 +77,7 @@ void sss_ini_config_destroy(struct sss_ini_initdata *init_data);
71e593
 /* Create LDIF */
71e593
 int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx,
71e593
                            struct sss_ini_initdata *init_data,
71e593
+                           const char *only_section,
71e593
                            const char **config_ldif);
71e593
 
71e593
 /* Validate sssd.conf if libini_config support it */
71e593
-- 
71e593
2.19.1
71e593