fix mem leak in ltdb_index_dn_base_dn and ltdb_search_indexed
[amitay/samba.git] / lib / ldb / ldb_key_value / ldb_kv_index.c
index 96ebd6b86ccec069a099baee0f6f3c8b34a8bae3..6c21c19d65473dc2356c3e846420af9b18eb3ab9 100644 (file)
@@ -483,7 +483,7 @@ int ldb_kv_key_dn_from_idx(struct ldb_module *module,
                           struct ldb_kv_private *ldb_kv,
                           TALLOC_CTX *mem_ctx,
                           struct ldb_dn *dn,
-                          TDB_DATA *tdb_key)
+                          struct ldb_val *ldb_key)
 {
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        int ret;
@@ -529,9 +529,9 @@ int ldb_kv_key_dn_from_idx(struct ldb_module *module,
                index = -1;
                for (i=0; i < list->count; i++) {
                        uint8_t guid_key[LDB_KV_GUID_KEY_SIZE];
-                       TDB_DATA key = {
-                               .dptr = guid_key,
-                               .dsize = sizeof(guid_key)
+                       struct ldb_val key = {
+                               .data = guid_key,
+                               .length = sizeof(guid_key)
                        };
                        const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS;
                        struct ldb_message *rec = ldb_msg_new(ldb);
@@ -550,8 +550,8 @@ int ldb_kv_key_dn_from_idx(struct ldb_module *module,
 
                        ret =
                            ldb_kv_search_key(module, ldb_kv, key, rec, flags);
-                       if (key.dptr != guid_key) {
-                               TALLOC_FREE(key.dptr);
+                       if (key.data != guid_key) {
+                               TALLOC_FREE(key.data);
                        }
                        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                                /*
@@ -592,8 +592,8 @@ int ldb_kv_key_dn_from_idx(struct ldb_module *module,
                }
        }
 
-       /* The tdb_key memory is allocated by the caller */
-       ret = ldb_kv_guid_to_key(module, ldb_kv, &list->dn[index], tdb_key);
+       /* The ldb_key memory is allocated by the caller */
+       ret = ldb_kv_guid_to_key(module, ldb_kv, &list->dn[index], ldb_key);
        TALLOC_FREE(list);
 
        if (ret != LDB_SUCCESS) {
@@ -1172,6 +1172,7 @@ static int ldb_kv_index_dn_leaf(struct ldb_module *module,
        }
        if (ldb_attr_dn(tree->u.equality.attr) == 0) {
                enum key_truncation truncation = KEY_NOT_TRUNCATED;
+               bool valid_dn = false;
                struct ldb_dn *dn
                        = ldb_dn_from_ldb_val(list,
                                              ldb_module_get_ctx(module),
@@ -1183,6 +1184,14 @@ static int ldb_kv_index_dn_leaf(struct ldb_module *module,
                        return LDB_SUCCESS;
                }
 
+               valid_dn = ldb_dn_validate(dn);
+               if (valid_dn == false) {
+                       /* If we can't parse it, no match */
+                       list->dn = NULL;
+                       list->count = 0;
+                       return LDB_SUCCESS;
+               }
+
                /*
                 * Re-use the same code we use for a SCOPE_BASE
                 * search
@@ -1613,6 +1622,15 @@ static int ldb_kv_index_dn_attr(struct ldb_module *module,
 
        /* work out the index key from the parent DN */
        val.data = (uint8_t *)((uintptr_t)ldb_dn_get_casefold(dn));
+       if (val.data == NULL) {
+               const char *dn_str = ldb_dn_get_linearized(dn);
+               ldb_asprintf_errstring(ldb_module_get_ctx(module),
+                                      __location__
+                                      ": Failed to get casefold DN "
+                                      "from: %s",
+                                      dn_str);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
        val.length = strlen((char *)val.data);
        key = ldb_kv_index_key(ldb, ldb_kv, attr, &val, NULL, truncation);
        if (!key) {
@@ -1666,6 +1684,7 @@ static int ldb_kv_index_dn_base_dn(struct ldb_module *module,
                dn_list->dn[0].data = discard_const_p(unsigned char,
                                                      ldb_dn_get_linearized(base_dn));
                if (dn_list->dn[0].data == NULL) {
+                       talloc_free(dn_list->dn);
                        return ldb_module_oom(module);
                }
                dn_list->dn[0].length = strlen((char *)dn_list->dn[0].data);
@@ -1753,7 +1772,7 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv,
        unsigned int i;
        unsigned int num_keys = 0;
        uint8_t previous_guid_key[LDB_KV_GUID_KEY_SIZE] = {};
-       TDB_DATA *keys = NULL;
+       struct ldb_val *keys = NULL;
 
        /*
         * We have to allocate the key list (rather than just walk the
@@ -1761,7 +1780,7 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv,
         * (by modifying an indexed attribute hosted in the in-memory
         * index cache!)
         */
-       keys = talloc_array(ac, TDB_DATA, dn_list->count);
+       keys = talloc_array(ac, struct ldb_val, dn_list->count);
        if (keys == NULL) {
                return ldb_module_oom(ac->module);
        }
@@ -1785,13 +1804,13 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv,
                        return ldb_module_oom(ac->module);
                }
                for (i = 0; i < dn_list->count; i++) {
-                       keys[i].dptr = key_values[i].guid_key;
-                       keys[i].dsize = sizeof(key_values[i].guid_key);
+                       keys[i].data = key_values[i].guid_key;
+                       keys[i].length = sizeof(key_values[i].guid_key);
                }
        } else {
                for (i = 0; i < dn_list->count; i++) {
-                       keys[i].dptr = NULL;
-                       keys[i].dsize = 0;
+                       keys[i].data = NULL;
+                       keys[i].length = 0;
                }
        }
 
@@ -1818,13 +1837,13 @@ static int ldb_kv_index_filter(struct ldb_kv_private *ldb_kv,
                         */
 
                        if (memcmp(previous_guid_key,
-                                  keys[num_keys].dptr,
+                                  keys[num_keys].data,
                                   sizeof(previous_guid_key)) == 0) {
                                continue;
                        }
 
                        memcpy(previous_guid_key,
-                              keys[num_keys].dptr,
+                              keys[num_keys].data,
                               sizeof(previous_guid_key));
                }
                num_keys++;
@@ -2021,6 +2040,7 @@ int ldb_kv_search_indexed(struct ldb_kv_context *ac, uint32_t *match_count)
                        struct dn_list *idx_one_tree_list
                                = talloc_zero(ac, struct dn_list);
                        if (idx_one_tree_list == NULL) {
+                               talloc_free(dn_list);
                                return ldb_module_oom(ac->module);
                        }
 
@@ -2187,9 +2207,9 @@ static int ldb_kv_index_add1(struct ldb_module *module,
                int i;
                for (i=0; i < list->count; i++) {
                        uint8_t guid_key[LDB_KV_GUID_KEY_SIZE];
-                       TDB_DATA key = {
-                               .dptr = guid_key,
-                               .dsize = sizeof(guid_key)
+                       struct ldb_val key = {
+                               .data = guid_key,
+                               .length = sizeof(guid_key)
                        };
                        const int flags = LDB_UNPACK_DATA_FLAG_NO_ATTRS;
                        struct ldb_message *rec = ldb_msg_new(ldb);
@@ -2207,8 +2227,8 @@ static int ldb_kv_index_add1(struct ldb_module *module,
 
                        ret =
                            ldb_kv_search_key(module, ldb_kv, key, rec, flags);
-                       if (key.dptr != guid_key) {
-                               TALLOC_FREE(key.dptr);
+                       if (key.data != guid_key) {
+                               TALLOC_FREE(key.data);
                        }
                        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
                                /*
@@ -2849,7 +2869,7 @@ static int delete_index(struct ldb_kv_private *ldb_kv,
   traversal function that adds @INDEX records during a re index TODO wrong comment
 */
 static int re_key(struct ldb_kv_private *ldb_kv,
-                 struct ldb_val ldb_key,
+                 struct ldb_val key,
                  struct ldb_val val,
                  void *state)
 {
@@ -2860,17 +2880,13 @@ static int re_key(struct ldb_kv_private *ldb_kv,
        struct ldb_message *msg;
        unsigned int nb_elements_in_db;
        int ret;
-       TDB_DATA key2;
+       struct ldb_val key2;
        bool is_record;
-       TDB_DATA key = {
-               .dptr = ldb_key.data,
-               .dsize = ldb_key.length
-       };
 
        ldb = ldb_module_get_ctx(module);
 
-       if (key.dsize > 4 &&
-           memcmp(key.dptr, "DN=@", 4) == 0) {
+       if (key.length > 4 &&
+           memcmp(key.data, "DN=@", 4) == 0) {
                return 0;
        }
 
@@ -2901,8 +2917,8 @@ static int re_key(struct ldb_kv_private *ldb_kv,
                ldb_debug(ldb, LDB_DEBUG_ERROR,
                          "Refusing to re-index as GUID "
                          "key %*.*s with no DN\n",
-                         (int)key.dsize, (int)key.dsize,
-                         (char *)key.dptr);
+                         (int)key.length, (int)key.length,
+                         (char *)key.data);
                talloc_free(msg);
                return -1;
        }
@@ -2911,23 +2927,19 @@ static int re_key(struct ldb_kv_private *ldb_kv,
           insensitivity of an element changing, or a change from DN
           to GUID keys */
        key2 = ldb_kv_key_msg(module, msg, msg);
-       if (key2.dptr == NULL) {
+       if (key2.data == NULL) {
                /* probably a corrupt record ... darn */
                ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid DN in re_index: %s",
                                                ldb_dn_get_linearized(msg->dn));
                talloc_free(msg);
                return 0;
        }
-       if (key.dsize != key2.dsize ||
-           (memcmp(key.dptr, key2.dptr, key.dsize) != 0)) {
-               struct ldb_val ldb_key2 = {
-                       .data = key2.dptr,
-                       .length = key2.dsize
-               };
+       if (key.length != key2.length ||
+           (memcmp(key.data, key2.data, key.length) != 0)) {
                ldb_kv->kv_ops->update_in_iterate(
-                   ldb_kv, ldb_key, ldb_key2, val, ctx);
+                   ldb_kv, key, key2, val, ctx);
        }
-       talloc_free(key2.dptr);
+       talloc_free(key2.data);
 
        talloc_free(msg);
 
@@ -2945,7 +2957,7 @@ static int re_key(struct ldb_kv_private *ldb_kv,
   traversal function that adds @INDEX records during a re index
 */
 static int re_index(struct ldb_kv_private *ldb_kv,
-                   struct ldb_val ldb_key,
+                   struct ldb_val key,
                    struct ldb_val val,
                    void *state)
 {
@@ -2955,17 +2967,13 @@ static int re_index(struct ldb_kv_private *ldb_kv,
        struct ldb_module *module = ctx->module;
        struct ldb_message *msg;
        unsigned int nb_elements_in_db;
-       TDB_DATA key = {
-               .dptr = ldb_key.data,
-               .dsize = ldb_key.length
-       };
        int ret;
        bool is_record;
 
        ldb = ldb_module_get_ctx(module);
 
-       if (key.dsize > 4 &&
-           memcmp(key.dptr, "DN=@", 4) == 0) {
+       if (key.length > 4 &&
+           memcmp(key.data, "DN=@", 4) == 0) {
                return 0;
        }
 
@@ -2996,8 +3004,8 @@ static int re_index(struct ldb_kv_private *ldb_kv,
                ldb_debug(ldb, LDB_DEBUG_ERROR,
                          "Refusing to re-index as GUID "
                          "key %*.*s with no DN\n",
-                         (int)key.dsize, (int)key.dsize,
-                         (char *)key.dptr);
+                         (int)key.length, (int)key.length,
+                         (char *)key.data);
                talloc_free(msg);
                return -1;
        }