r19365: fixed a memory leak in the ldb attribute handling
authorAndrew Tridgell <tridge@samba.org>
Tue, 17 Oct 2006 05:50:01 +0000 (05:50 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:21:17 +0000 (14:21 -0500)
(This used to be commit d7e07685164141f8fb2c2a6258e1fcb46ff9d06c)

source4/lib/ldb/common/ldb_attributes.c
source4/lib/ldb/include/ldb.h
source4/lib/ldb/ldb_tdb/ldb_cache.c

index c8a7909b4c5c7f6f27821086e9a0cd48cd360e64..2d9f0e6cf88d22b67f0f1cf6acd9936d46f37a37 100644 (file)
@@ -39,6 +39,7 @@ int ldb_set_attrib_handlers(struct ldb_context *ldb,
                            const struct ldb_attrib_handler *handlers, 
                            unsigned num_handlers)
 {
+       int i;
        struct ldb_attrib_handler *h;
        h = talloc_realloc(ldb, ldb->schema.attrib_handlers,
                           struct ldb_attrib_handler,
@@ -50,6 +51,16 @@ int ldb_set_attrib_handlers(struct ldb_context *ldb,
        ldb->schema.attrib_handlers = h;
        memcpy(h + ldb->schema.num_attrib_handlers, 
               handlers, sizeof(*h) * num_handlers);
+       for (i=0;i<num_handlers;i++) {
+               if (h[ldb->schema.num_attrib_handlers+i].flags & LDB_ATTR_FLAG_ALLOCATED) {
+                       h[ldb->schema.num_attrib_handlers+i].attr = talloc_strdup(ldb->schema.attrib_handlers,
+                                                                                 h[ldb->schema.num_attrib_handlers+i].attr);
+                       if (h[ldb->schema.num_attrib_handlers+i].attr == NULL) {
+                               ldb_oom(ldb);
+                               return -1;
+                       }
+               }
+       }
        ldb->schema.num_attrib_handlers += num_handlers;
        return 0;
 }
@@ -129,6 +140,9 @@ void ldb_remove_attrib_handler(struct ldb_context *ldb, const char *attrib)
        if (h == &ldb_default_attrib_handler) {
                return;
        }
+       if (h->flags & LDB_ATTR_FLAG_ALLOCATED) {
+               talloc_free(h->attr);
+       }
        i = h - ldb->schema.attrib_handlers;
        if (i < ldb->schema.num_attrib_handlers - 1) {
                memmove(&ldb->schema.attrib_handlers[i], 
index d2f3bd53d3fff4b732cdf894ed273f29a1839a4d..0af734eb13d80d3ed5411fa1d348305744b0baa1 100644 (file)
@@ -357,6 +357,9 @@ struct ldb_attrib_handler {
 */
 #define LDB_ATTR_FLAG_HIDDEN       (1<<0) 
 
+/* the attribute handler name should be freed when released */
+#define LDB_ATTR_FLAG_ALLOCATED    (1<<1) 
+
 /**
    The attribute is constructed from other attributes
 */
index a903ceb4cdf184843566a6b736b9eddafc1c552d..84932ac47f3bcf7458417a23a849fc55828dba1e 100644 (file)
@@ -71,13 +71,7 @@ static void ltdb_attributes_unload(struct ldb_module *module)
 
        msg = ltdb->cache->attributes;
        for (i=0;i<msg->num_elements;i++) {
-               const struct ldb_attrib_handler *h;
-               /* this is rather ugly - a consequence of const handling */
-               h = ldb_attrib_handler(module->ldb, msg->elements[i].name);
                ldb_remove_attrib_handler(module->ldb, msg->elements[i].name);
-               if (strcmp(h->attr, msg->elements[i].name) == 0) {
-                       talloc_steal(msg, h->attr);
-               }
        }
 
        talloc_free(ltdb->cache->attributes);
@@ -163,11 +157,11 @@ static int ltdb_attributes_load(struct ldb_module *module)
                        goto failed;
                }
                h2 = *h;
-               h2.attr = talloc_strdup(module, msg->elements[i].name);
+               h2.attr = msg->elements[i].name;
+               h2.flags |= LDB_ATTR_FLAG_ALLOCATED;
                if (ldb_set_attrib_handlers(module->ldb, &h2, 1) != 0) {
                        goto failed;
                }
-               talloc_steal(module->ldb->schema.attrib_handlers, h2.attr);
        }
 
        return 0;