rpms/sssd/devel 0001-Add-reconnection-code-between-the-NSS-responder-and.patch, NONE, 1.1 0003-Make-reconnection-to-the-Data-Provider-a-global-sett.patch, NONE, 1.1 0004-Add-common-function-to-retrieve-comma-sep.-lists.patch, NONE, 1.1 0005-Fixing-memory-issues-in-ini-and-collection.patch, NONE, 1.1 sssd.conf.default, 1.2, 1.3 sssd.spec, 1.8, 1.9

Simo Sorce simo at fedoraproject.org
Tue Apr 14 21:25:07 UTC 2009


Author: simo

Update of /cvs/pkgs/rpms/sssd/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv1532

Modified Files:
	sssd.conf.default sssd.spec 
Added Files:
	0001-Add-reconnection-code-between-the-NSS-responder-and.patch 
	0003-Make-reconnection-to-the-Data-Provider-a-global-sett.patch 
	0004-Add-common-function-to-retrieve-comma-sep.-lists.patch 
	0005-Fixing-memory-issues-in-ini-and-collection.patch 
Log Message:
* Tue Apr 14 2009 Simo Sorce <ssorce at redhat.com> - 0.3.1-2
- Add last minute bug fixes, found in testing the package


0001-Add-reconnection-code-between-the-NSS-responder-and.patch:

--- NEW FILE 0001-Add-reconnection-code-between-the-NSS-responder-and.patch ---
>From ecd411426a6c37d842b6d390c4895f34538130cf Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh at redhat.com>
Date: Tue, 14 Apr 2009 09:24:27 -0400
Subject: [PATCH] Add reconnection code between the NSS responder and the Data provider

---
 server/responder/nss/nsssrv.c |   53 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 1 deletions(-)

diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 58b09fb..8e72a95 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -219,6 +219,41 @@ done:
     return ret;
 }
 
+static void nss_shutdown(struct resp_ctx *rctx)
+{
+    /* TODO: Do clean-up here */
+
+    /* Nothing left to do but exit() */
+    exit(0);
+}
+
+
+static void nss_dp_reconnect_init(struct sbus_conn_ctx *sconn, int status, void *pvt)
+{
+    int ret;
+    struct resp_ctx *rctx = talloc_get_type(pvt, struct resp_ctx);
+
+    /* Did we reconnect successfully? */
+    if (status == SBUS_RECONNECT_SUCCESS) {
+        /* Add the methods back to the new connection */
+        ret = sbus_conn_add_method_ctx(rctx->dp_ctx->scon_ctx,
+                                       rctx->dp_ctx->sm_ctx);
+        if (ret != EOK) {
+            DEBUG(0, ("Could not re-add methods on reconnection.\n"));
+            nss_shutdown(rctx);
+        }
+
+        DEBUG(1, ("Reconnected to the Data Provider.\n"));
+        return;
+    }
+
+    /* Handle failure */
+    DEBUG(0, ("Could not reconnect to data provider.\n"));
+    /* Kill the backend and let the monitor restart it */
+    nss_shutdown(rctx);
+}
+
+
 int nss_process_init(TALLOC_CTX *mem_ctx,
                      struct tevent_context *ev,
                      struct confdb_ctx *cdb)
@@ -226,7 +261,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     struct sbus_method *nss_dp_methods;
     struct sss_cmd_table *nss_cmds;
     struct nss_ctx *nctx;
-    int ret;
+    int ret, max_retries;
 
     nctx = talloc_zero(mem_ctx, struct nss_ctx);
     if (!nctx) {
@@ -261,6 +296,22 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
         return ret;
     }
 
+    /* Enable automatic reconnection to the Data Provider */
+
+    /* FIXME: "retries" is too generic, either get it from a global config
+     * or specify these retries are about the sbus connections to DP */
+    ret = confdb_get_int(nctx->rctx->cdb, nctx->rctx,
+                         nctx->rctx->confdb_service_path,
+                         "retries", 3, &max_retries);
+    if (ret != EOK) {
+        DEBUG(0, ("Failed to set up automatic reconnection\n"));
+        return ret;
+    }
+
+    sbus_reconnect_init(nctx->rctx->dp_ctx->scon_ctx,
+                        max_retries,
+                        nss_dp_reconnect_init, nctx->rctx);
+
     DEBUG(1, ("NSS Initialization complete\n"));
 
     return EOK;
-- 
1.6.0.6


0003-Make-reconnection-to-the-Data-Provider-a-global-sett.patch:

--- NEW FILE 0003-Make-reconnection-to-the-Data-Provider-a-global-sett.patch ---
>From ac5a54e24ac79a33ddf8320811d981b950e21e8e Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh at redhat.com>
Date: Tue, 14 Apr 2009 10:22:20 -0400
Subject: [PATCH] Make reconnection to the Data Provider a global setting

Previously, every DP client was allowed to set its own "retries"
option. This option was ambiguous, and useless. All DP clients
will now use a global option set in the services config called
"reconnection_retries"
---
 server/confdb/confdb.h              |    2 ++
 server/examples/sssd.conf           |    3 +++
 server/monitor/monitor.c            |    2 +-
 server/providers/data_provider_be.c |    4 ++--
 server/responder/nss/nsssrv.c       |    7 ++-----
 server/responder/pam/pamsrv.c       |    4 ++--
 6 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index fda584c..19614fc 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -32,6 +32,8 @@
 #define CONFDB_DEFAULT_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf"
 #define SSSD_MIN_ID 1000
 
+#define SERVICE_CONF_ENTRY "config/services"
+
 struct confdb_ctx;
 
 typedef int (*confdb_reconf_fn) (struct confdb_ctx *cdb, void *pvt);
diff --git a/server/examples/sssd.conf b/server/examples/sssd.conf
index b9a421e..a480b54 100644
--- a/server/examples/sssd.conf
+++ b/server/examples/sssd.conf
@@ -1,6 +1,9 @@
 [services]
 description = Local Service Configuration
 activeServices = nss, dp, pam
+# Number of times services should attempt to reconnect in the
+# event of a Data Provider crash or restart before they give up
+reconnection_retries = 3
 
 [services/nss]
 description = NSS Responder Configuration
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index 69640b9..dd80830 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -558,7 +558,7 @@ int get_monitor_config(struct mt_ctx *ctx)
     }
 
     ret = confdb_get_string(ctx->cdb, ctx,
-                            "config/services", "activeServices",
+                            SERVICE_CONF_ENTRY, "activeServices",
                             NULL, &svcs);
 
     if (ret != EOK || svcs == NULL) {
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 3d824c3..6cd86e8 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -681,8 +681,8 @@ static int be_cli_init(struct be_ctx *ctx)
     }
 
     /* Enable automatic reconnection to the Data Provider */
-    ret = confdb_get_int(ctx->cdb, ctx, ctx->conf_path,
-                         "retries", 3, &max_retries);
+    ret = confdb_get_int(ctx->cdb, ctx, SERVICE_CONF_ENTRY,
+                         "reconnection_retries", 3, &max_retries);
     if (ret != EOK) {
         DEBUG(0, ("Failed to set up automatic reconnection\n"));
         return ret;
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 8e72a95..e85e56b 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -297,12 +297,9 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     }
 
     /* Enable automatic reconnection to the Data Provider */
-
-    /* FIXME: "retries" is too generic, either get it from a global config
-     * or specify these retries are about the sbus connections to DP */
     ret = confdb_get_int(nctx->rctx->cdb, nctx->rctx,
-                         nctx->rctx->confdb_service_path,
-                         "retries", 3, &max_retries);
+                         SERVICE_CONF_ENTRY,
+                         "reconnection_retries", 3, &max_retries);
     if (ret != EOK) {
         DEBUG(0, ("Failed to set up automatic reconnection\n"));
         return ret;
diff --git a/server/responder/pam/pamsrv.c b/server/responder/pam/pamsrv.c
index 1adbb14..e4ddc43 100644
--- a/server/responder/pam/pamsrv.c
+++ b/server/responder/pam/pamsrv.c
@@ -163,8 +163,8 @@ static int pam_process_init(struct main_context *main_ctx,
 
     /* FIXME: "retries" is too generic, either get it from a global config
      * or specify these retries are about the sbus connections to DP */
-    ret = confdb_get_int(rctx->cdb, rctx, rctx->confdb_service_path,
-                         "retries", 3, &max_retries);
+    ret = confdb_get_int(rctx->cdb, rctx, SERVICE_CONF_ENTRY,
+                         "reconnection_retries", 3, &max_retries);
     if (ret != EOK) {
         DEBUG(0, ("Failed to set up automatic reconnection\n"));
         return ret;
-- 
1.6.0.6


0004-Add-common-function-to-retrieve-comma-sep.-lists.patch:

--- NEW FILE 0004-Add-common-function-to-retrieve-comma-sep.-lists.patch ---
>From 4ad7fe5e6acc87140fc29b635605af8445d2d32f Mon Sep 17 00:00:00 2001
From: Simo Sorce <ssorce at redhat.com>
Date: Tue, 14 Apr 2009 11:20:30 -0400
Subject: [PATCH] Add common function to retrieve comma sep. lists

Also convert all places where we were using custom code to parse
config arguments.
And fix a copy&paste error in nss_get_config
---
 server/confdb/confdb.c        |  203 ++++++++++++++++++++++++++++++++---------
 server/confdb/confdb.h        |    4 +
 server/monitor/monitor.c      |   54 +----------
 server/responder/nss/nsssrv.c |   24 +++--
 4 files changed, 179 insertions(+), 106 deletions(-)

diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c
index d3a2a08..1f642ca 100644
--- a/server/confdb/confdb.c
+++ b/server/confdb/confdb.c
@@ -36,8 +36,8 @@
 #include "ini_config.h"
 
 #define CONFDB_VERSION "1"
-#define CONFDB_BASEDN "cn=config"
-#define CONFDB_DOMAIN_BASEDN "cn=domains,"CONFDB_BASEDN
+#define CONFDB_DOMAINS_PATH "config/domains"
+#define CONFDB_DOMAIN_BASEDN "cn=domains,cn=config"
 #define CONFDB_DOMAIN_ATTR "cn"
 #define CONFDB_MPG "magicPrivateGroups"
 #define CONFDB_FQ "useFullyQualifiedNames"
@@ -121,6 +121,110 @@ done:
     return ret;
 }
 
+/* split a string into an allocated array of strings.
+ * the separator is a string, and is case-sensitive.
+ * optionally single values can be trimmed of of spaces and tabs */
+static int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
+                              char *sep, bool trim, char ***_list, int *size)
+{
+    const char *t, *p, *n;
+    size_t l, s, len;
+    char **list, **r;
+
+    if (!str || !*str || !sep || !*sep || !_list) return EINVAL;
+
+    s = strlen(sep);
+    t = str;
+
+    list = NULL;
+    l = 0;
+
+    if (trim)
+        while (*t == ' ' || *t == '\t') t++;
+
+    while (t && (p = strstr(t, sep))) {
+        len = p - t;
+        n = p + s; /* save next string starting point */
+        if (trim) {
+            while (*t == ' ' || *t == '\t') {
+                t++;
+                len--;
+                if (len == 0) break;
+            }
+            p--;
+            while (len > 0 && (*p == ' ' || *p == '\t')) {
+                len--;
+                p--;
+            }
+        }
+
+        r = talloc_realloc(mem_ctx, list, char *, l + 2);
+        if (!r) {
+            talloc_free(list);
+            return ENOMEM;
+        } else {
+            list = r;
+        }
+
+        if (len == 0) {
+            list[l] = talloc_strdup(list, "");
+        } else {
+            list[l] = talloc_strndup(list, t, len);
+        }
+        if (!list[l]) {
+            talloc_free(list);
+            return ENOMEM;
+        }
+        l++;
+
+        t = n; /* move to next string */
+    }
+
+    if (t) {
+        r = talloc_realloc(mem_ctx, list, char *, l + 2);
+        if (!r) {
+            talloc_free(list);
+            return ENOMEM;
+        } else {
+            list = r;
+        }
+
+        if (trim) {
+            len = strlen(t);
+            while (*t == ' ' || *t == '\t') {
+                t++;
+                len--;
+                if (len == 0) break;
+            }
+            p = t + len - 1;
+            while (len > 0 && (*p == ' ' || *p == '\t')) {
+                len--;
+                p--;
+            }
+
+            if (len == 0) {
+                list[l] = talloc_strdup(list, "");
+            } else {
+                list[l] = talloc_strndup(list, t, len);
+            }
+        } else {
+            list[l] = talloc_strdup(list, t);
+        }
+        if (!list[l]) {
+            talloc_free(list);
+            return ENOMEM;
+        }
+        l++;
+    }
+
+    list[l] = NULL; /* terminate list */
+
+    if (size) *size = l + 1;
+    *_list = list;
+
+    return EOK;
+}
+
 int confdb_add_param(struct confdb_ctx *cdb,
                      bool replace,
                      const char *section,
@@ -496,6 +600,43 @@ failed:
     return ret;
 }
 
+/* WARNING: Unlike other similar functions, this one does NOT take a default,
+ * and returns ENOENT if the attribute was not found ! */
+int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
+                              const char *section, const char *attribute,
+                              char ***result)
+{
+    char **values = NULL;
+    int ret;
+
+    ret = confdb_get_param(cdb, ctx, section, attribute, &values);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    if (values && values[0]) {
+        if (values[1] != NULL) {
+            /* too many values */
+            ret = EINVAL;
+            goto done;
+        }
+    } else {
+        /* Did not return a value */
+        ret = ENOENT;
+        goto done;
+    }
+
+    ret = split_on_separator(ctx, values[0], ",", true, result, NULL);
+
+done:
+    talloc_free(values);
+    if (ret != EOK && ret != ENOENT) {
+        DEBUG(2, ("Failed to get [%s] from [%s], error [%d] (%s)",
+                  attribute, section, ret, strerror(ret)));
+    }
+    return ret;
+}
+
 int confdb_test(struct confdb_ctx *cdb)
 {
     char **values;
@@ -948,61 +1089,33 @@ int confdb_get_domains(struct confdb_ctx *cdb,
                        struct sss_domain_info **domains)
 {
     TALLOC_CTX *tmp_ctx;
-    struct ldb_dn *dn;
-    struct ldb_result *res;
     struct sss_domain_info *domain, *prevdom;
     struct sss_domain_info *first = NULL;
-    const char *attrs[] = { "domains", NULL };
-    const char *tmp;
-    char *cur, *p, *t;
-    int ret;
+    char **domlist;
+    int ret, i;
 
     tmp_ctx = talloc_new(mem_ctx);
     if (!tmp_ctx) return ENOMEM;
 
-    dn = ldb_dn_new(tmp_ctx, cdb->ldb, CONFDB_DOMAIN_BASEDN);
-    if (!dn) {
-        ret = EIO;
-        goto done;
-    }
-
-    ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
-                     LDB_SCOPE_BASE, attrs, NULL);
-    if (ret != LDB_SUCCESS) {
-        ret = EIO;
-        goto done;
-    }
-
-    if (res->count != 1) {
-        ret = EFAULT;
+    ret = confdb_get_string_as_list(cdb, tmp_ctx,
+                                    CONFDB_DOMAINS_PATH, "domains", &domlist);
+    if (ret == ENOENT) {
+        DEBUG(0, ("No domains configured, fatal error!\n"));
         goto done;
     }
-
-    tmp = ldb_msg_find_attr_as_string(res->msgs[0], "domains",  NULL);
-    if (!tmp) {
-        DEBUG(0, ("No domains configured, fatal error!\n"));
-        ret = EINVAL;
+    if (ret != EOK ) {
+        DEBUG(0, ("Fatal error retrieving domains list!\n"));
         goto done;
     }
-    cur = p = talloc_strdup(tmp_ctx, tmp);
 
-    while (p && *p) {
-
-        for (cur = p; (*cur == ' ' || *cur == '\t'); cur++) /* trim */ ;
-        if (!*cur) break;
-
-        p = strchr(cur, ',');
-        if (p) {
-            /* terminate element */
-            *p = '\0';
-            /* trim spaces */
-            for (t = p-1; (*t == ' ' || *t == '\t'); t--) *t = '\0';
-            p++;
+    for (i = 0; domlist[i]; i++) {
+        ret = confdb_get_domain(cdb, mem_ctx, domlist[i], &domain);
+        if (ret) {
+            DEBUG(0, ("Error (%d [%s]) retrieving domain %s, skipping!\n",
+                      ret, strerror(ret), domains[i]));
+            continue;
         }
 
-        ret = confdb_get_domain(cdb, mem_ctx, cur, &domain);
-        if (ret) goto done;
-
         if (first == NULL) {
             first = domain;
             prevdom = first;
@@ -1014,7 +1127,7 @@ int confdb_get_domains(struct confdb_ctx *cdb,
 
     if (first == NULL) {
         DEBUG(0, ("No domains configured, fatal error!\n"));
-        ret = EINVAL;
+        ret = ENOENT;
     }
 
     *domains = first;
diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index 19614fc..76e4482 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -80,6 +80,10 @@ int confdb_get_bool(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
                     const char *section, const char *attribute,
                     bool defval, bool *result);
 
+int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
+                              const char *section, const char *attribute,
+                              char ***result);
+
 int confdb_init(TALLOC_CTX *mem_ctx,
                 struct tevent_context *ev,
                 struct confdb_ctx **cdb_ctx,
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index dd80830..20734d1 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -544,11 +544,6 @@ static int service_signal_reload(struct mt_svc *svc)
 int get_monitor_config(struct mt_ctx *ctx)
 {
     int ret;
-    size_t svc_count = 0;
-    char *svcs;
-    char *cur, *p, *t;
-    char **svc_list = NULL;
-    char **tmp_list = NULL;
 
     ret = confdb_get_int(ctx->cdb, ctx,
                          MONITOR_CONF_ENTRY, "sbusTimeout",
@@ -557,61 +552,20 @@ int get_monitor_config(struct mt_ctx *ctx)
         return ret;
     }
 
-    ret = confdb_get_string(ctx->cdb, ctx,
-                            SERVICE_CONF_ENTRY, "activeServices",
-                            NULL, &svcs);
-
-    if (ret != EOK || svcs == NULL) {
+    ret = confdb_get_string_as_list(ctx->cdb, ctx, SERVICE_CONF_ENTRY,
+                                    "activeServices", &ctx->services);
+    if (ret != EOK) {
         DEBUG(0, ("No services configured!\n"));
         return EINVAL;
     }
 
-    cur = p = talloc_strdup(svcs, svcs);
-    while (p && *p) {
-        for (cur = p; (*cur == ' ' || *cur == '\t'); cur++) /* trim */ ;
-        if (!*cur) break;
-
-        p = strchr(cur, ',');
-        if (p) {
-            /* terminate element */
-            *p = '\0';
-            /* trim spaces */
-            for (t = p-1; (*t == ' ' || *t == '\t'); t--) *t = '\0';
-            p++;
-        }
-
-        svc_count++;
-        tmp_list = talloc_realloc(svcs, svc_list, char *, svc_count);
-        if (!tmp_list) {
-            ret = ENOMEM;
-            goto done;
-        }
-        svc_list = tmp_list;
-        svc_list[svc_count-1] = talloc_strdup(svc_list, cur);
-    }
-
-    svc_count++;
-    tmp_list = talloc_realloc(svcs, svc_list, char *, svc_count);
-    if (!tmp_list) {
-        ret = ENOMEM;
-        goto done;
-    }
-    svc_list = tmp_list;
-    svc_list[svc_count-1] = NULL;
-
-    ctx->services = talloc_steal(ctx, svc_list);
-
     ret = confdb_get_domains(ctx->cdb, ctx, &ctx->domains);
     if (ret != EOK) {
         DEBUG(2, ("No domains configured. LOCAL should always exist!\n"));
         return ret;
     }
 
-    ret = EOK;
-
-done:
-    talloc_free(svcs);
-    return ret;
+    return EOK;
 }
 
 static int get_service_config(struct mt_ctx *ctx, const char *name,
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index e85e56b..e04a8c8 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -138,18 +138,20 @@ static int nss_get_config(struct nss_ctx *nctx,
 
     ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG,
                          "EntryCacheTimeout", 600,
-                         &nctx->enum_cache_timeout);
+                         &nctx->cache_timeout);
     if (ret != EOK) goto done;
 
     ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG,
                          "EntryNegativeTimeout", 15,
-                         &nctx->enum_cache_timeout);
+                         &nctx->neg_timeout);
     if (ret != EOK) goto done;
 
-    ret = confdb_get_param(cdb, nctx, NSS_SRV_CONFIG,
-                           "filterUsers", &filter_list);
-    if (ret != EOK) goto done;
-    for (i = 0; filter_list[i]; i++) {
+    ret = confdb_get_string_as_list(cdb, tmpctx, NSS_SRV_CONFIG,
+                                    "filterUsers", &filter_list);
+    if (ret == ENOENT) filter_list = NULL;
+    else if (ret != EOK) goto done;
+
+    for (i = 0; (filter_list && filter_list[i]); i++) {
         ret = sss_parse_name(tmpctx, nctx->rctx->names,
                              filter_list[i], &domain, &name);
         if (ret != EOK) {
@@ -178,11 +180,12 @@ static int nss_get_config(struct nss_ctx *nctx,
             }
         }
     }
-    talloc_free(filter_list);
 
-    ret = confdb_get_param(cdb, nctx, NSS_SRV_CONFIG,
-                           "filterGroups", &filter_list);
-    if (ret != EOK) goto done;
+    ret = confdb_get_string_as_list(cdb, tmpctx, NSS_SRV_CONFIG,
+                                    "filterGroups", &filter_list);
+    if (ret == ENOENT) filter_list = NULL;
+    else if (ret != EOK) goto done;
+
     for (i = 0; filter_list[i]; i++) {
         ret = sss_parse_name(tmpctx, nctx->rctx->names,
                              filter_list[i], &domain, &name);
@@ -212,7 +215,6 @@ static int nss_get_config(struct nss_ctx *nctx,
             }
         }
     }
-    talloc_free(filter_list);
 
 done:
     talloc_free(tmpctx);
-- 
1.6.0.6


0005-Fixing-memory-issues-in-ini-and-collection.patch:

--- NEW FILE 0005-Fixing-memory-issues-in-ini-and-collection.patch ---
>From 9fc454c84d539cd90aed3a74a350bdc792455407 Mon Sep 17 00:00:00 2001
From: Dmitri Pal <dpal at redhat.com>
Date: Tue, 14 Apr 2009 14:55:42 -0400
Subject: [PATCH] Fixing memory issues in ini and collection

The read_line() function used an internal buffer allocated on stack
as temporary storage for a line read from file, then returned it.
read_line() now gets a buffer from the caller.
Fixed memory leaks in INI and Collection found by valgrind.
---
 common/collection/collection_ut.c |   15 +++++++++------
 common/ini/ini_config.c           |   36 +++++++++++++++++++++++++++++-------
 common/ini/ini_config_ut.c        |    4 ++--
 3 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/common/collection/collection_ut.c b/common/collection/collection_ut.c
index 6d27db6..eabf522 100644
--- a/common/collection/collection_ut.c
+++ b/common/collection/collection_ut.c
@@ -480,6 +480,7 @@ int mixed_collection_test()
     /* Traverse collection again - peer should still be there */
     error = print_collection(event);
     if(error) {
+        destroy_collection(event);
         printf("Error printing collection %d\n",error);
         return error;
     }
@@ -488,18 +489,17 @@ int mixed_collection_test()
 
     error = debug_collection(event,COL_TRAVERSE_DEFAULT);
     if(error) {
+        destroy_collection(event);
         printf("Error printing collection %d\n",error);
         return error;
     }
 
     printf("Attempt to add property to a referenced collection.\n");
 
-    /* Some negative tests */
-    /* Can't add attributes to the referenced collection */
     error = add_int_property(event,"host","session",500);
-    if(error != 0) printf("Error was NOT able to add property to a referenced collection.\n");
-    else {
-        printf("Unexpected success which is an implementation error.\n");
+    if(error) {
+        destroy_collection(event);
+        printf("Error was NOT able to add property to a referenced collection %d.\n", error);
         return error;
     }
 
@@ -508,6 +508,7 @@ int mixed_collection_test()
     /* Can't delete non exitent property */
     error = delete_property(event,"host.host",COL_TYPE_ANY, COL_TRAVERSE_DEFAULT);
     if(error == 0) {
+        destroy_collection(event);
         printf("Error was able to delete property that does not exist.\n");
         return -1;
     }
@@ -516,12 +517,14 @@ int mixed_collection_test()
     /* Set collection class */
     error = set_collection_class(event,2);
     if(error != 0) {
+        destroy_collection(event);
         printf("Error was NOT able to set class.\n");
         return error;
     }
 
     error = get_collection_class(event,&class);
     if(error != 0) {
+        destroy_collection(event);
         printf("Error was NOT able to get class.\n");
         return error;
     }
@@ -529,6 +532,7 @@ int mixed_collection_test()
 
     if(is_of_class(event,2)) printf("Class mathced!\n");
     else {
+        destroy_collection(event);
         printf("Error - bad class.\n");
         return -1;
     }
@@ -706,4 +710,3 @@ int main()
     /* Add other tests here ... */
     return error;
 }
-
diff --git a/common/ini/ini_config.c b/common/ini/ini_config.c
index 4112049..fd1efb0 100644
--- a/common/ini/ini_config.c
+++ b/common/ini/ini_config.c
@@ -83,8 +83,14 @@ inline const char *parsing_error_str(int parsing_error)
             return str_error[parsing_error-1];
 }
 
-
-int read_line(FILE *file,char **key,char **value, int *length, int *ext_error);
+/* Internal function to read line from INI file */
+int read_line(FILE *file,
+              char *buf,
+              int read_size,
+              char **key,
+              char **value,
+              int *length,
+              int *ext_error);
 
 /* Add to collection or update - CONSIDER moving to the collection.c */
 static int add_or_update(struct collection_item *current_section,
@@ -137,6 +143,8 @@ static int ini_to_collection(const char *filename,
     struct parse_error pe;
     int line = 0;
     int created = 0;
+    char buf[BUFFER_SIZE+1];
+
 
     TRACE_FLOW_STRING("ini_to_collection", "Entry");
 
@@ -162,7 +170,8 @@ static int ini_to_collection(const char *filename,
 
     /* Read file lines */
     while (1) {
-        status = read_line(file, &key, &value, &length, &ext_err);
+        /* Always read one less than the buffer */
+        status = read_line(file, buf, BUFFER_SIZE+1, &key, &value, &length, &ext_err);
         if (status == RET_EOF) break;
 
         line++;
@@ -505,11 +514,15 @@ int config_for_app(const char *application,
 }
 
 /* Reads a line from the file */
-int read_line(FILE *file, char **key,char **value, int *length, int *ext_error)
+int read_line(FILE *file,
+              char *buf,
+              int read_size,
+              char **key, char **value,
+              int *length,
+              int *ext_error)
 {
 
     char *res;
-    char buf[BUFFER_SIZE+1];
     int len;
     char *buffer;
     int i;
@@ -522,12 +535,15 @@ int read_line(FILE *file, char **key,char **value, int *length, int *ext_error)
     buffer = buf;
 
     /* Get data from file */
-    res = fgets(buffer, BUFFER_SIZE, file);
+    res = fgets(buffer, read_size - 1, file);
     if (res == NULL) {
         TRACE_ERROR_STRING("Read nothing", "");
         return RET_EOF;
     }
 
+    /* Make sure the buffer is NULL terminated */
+    buffer[read_size - 1] = '\0';
+
     len = strlen(buffer);
     if (len == 0) {
         TRACE_ERROR_STRING("Nothing was read.", "");
@@ -550,7 +566,8 @@ int read_line(FILE *file, char **key,char **value, int *length, int *ext_error)
     TRACE_INFO_STRING("BUFFER before trimming:", buffer);
 
     /* Trucate trailing spaces and CRs */
-    while (isspace(buffer[len - 1])) {
+    /* Make sure not to step before the beginning */
+    while (len && isspace(buffer[len - 1])) {
         buffer[len - 1] = '\0';
         len--;
     }
@@ -847,6 +864,9 @@ int get_config_item(const char *section,
     error = get_item(section_handle, name,
                      COL_TYPE_STRING, COL_TRAVERSE_ONELEVEL, item);
 
+    /* Make sure we free the section we found */
+    destroy_collection(section_handle);
+
     TRACE_FLOW_NUMBER("get_config_item returning", error);
     return error;
 }
@@ -1521,6 +1541,8 @@ char **get_attribute_list(struct collection_item *ini_config, const char *sectio
     /* Pass it to the function from collection API */
     list = collection_to_list(subcollection, size, error);
 
+    destroy_collection(subcollection);
+
     TRACE_FLOW_STRING("get_attribute_list returning", list == NULL ? "NULL" : list[0]);
     return list;
 }
diff --git a/common/ini/ini_config_ut.c b/common/ini/ini_config_ut.c
index 6787c36..5441e02 100644
--- a/common/ini/ini_config_ut.c
+++ b/common/ini/ini_config_ut.c
@@ -303,7 +303,6 @@ int get_test()
 
     debug_item(item);
 
-
     printf("Get item as string without duplication from NULL item.\n");
 
     /* Get a string without duplicication */
@@ -759,9 +758,10 @@ int get_test()
         return -1;
     }
 
-    for (i=0;i<size;i++) printf("Section: [%s]\n", prop_array[i]);
+    for (i=0;i<size;i++) printf("Attribute: [%s]\n", prop_array[i]);
     free_attribute_list(prop_array);
 
+    destroy_collection(ini_config);
     printf("Done with get test!\n");
     return EOK;
 }
-- 
1.6.0.6



Index: sssd.conf.default
===================================================================
RCS file: /cvs/pkgs/rpms/sssd/devel/sssd.conf.default,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- sssd.conf.default	13 Apr 2009 22:37:11 -0000	1.2
+++ sssd.conf.default	14 Apr 2009 21:24:36 -0000	1.3
@@ -16,9 +16,6 @@
 [services/pam]
 description = PAM Responder Configuration
 
-[services/info]
-description = InfoPipe Configuration
-
 [services/monitor]
 description = Service Monitor Configuration
 #if a backend is particularly slow you can raise this timeout here


Index: sssd.spec
===================================================================
RCS file: /cvs/pkgs/rpms/sssd/devel/sssd.spec,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- sssd.spec	13 Apr 2009 22:37:11 -0000	1.8
+++ sssd.spec	14 Apr 2009 21:24:36 -0000	1.9
@@ -1,6 +1,6 @@
 Name: sssd
 Version: 0.3.1
-Release: 1%{?dist}
+Release: 2%{?dist}
 Group: Applications/System
 Summary: System Security Services Daemon
 
@@ -13,6 +13,10 @@
 BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
 
 ### Patches ###
+Patch101: 0001-Add-reconnection-code-between-the-NSS-responder-and.patch
+Patch103: 0003-Make-reconnection-to-the-Data-Provider-a-global-sett.patch
+Patch104: 0004-Add-common-function-to-retrieve-comma-sep.-lists.patch
+Patch105: 0005-Fixing-memory-issues-in-ini-and-collection.patch
 
 ### Dependencies ###
 
@@ -51,6 +55,11 @@
 %prep
 %setup -q
 
+%patch101 -p1 -b .reconnect
+%patch103 -p1 -b .global_reconnect_option
+%patch104 -p1 -b .fix_filters
+%patch105 -p1 -b .fix_mem_issues
+
 %build
 
 # common
@@ -138,6 +147,9 @@
 fi
 
 %changelog
+* Tue Apr 14 2009 Simo Sorce <ssorce at redhat.com> - 0.3.1-2
+- Add last minute bug fixes, found in testing the package
+
 * Mon Apr 13 2009 Simo Sorce <ssorce at redhat.com> - 0.3.1-1
 - Version 0.3.1
 - includes previous release patches




More information about the fedora-extras-commits mailing list