summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ldb/common/ldb_pack.c41
-rw-r--r--lib/ldb/include/ldb_module.h4
2 files changed, 45 insertions, 0 deletions
diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c
index e7dd364008a..028d96a619a 100644
--- a/lib/ldb/common/ldb_pack.c
+++ b/lib/ldb/common/ldb_pack.c
@@ -690,6 +690,7 @@ static int ldb_unpack_data_flags_v1(struct ldb_context *ldb,
element->values = NULL;
if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) {
element->values = &ldb_val_single_array[nelem];
+ element->flags |= LDB_FLAG_INTERNAL_SHARED_VALUES;
} else if (element->num_values != 0) {
element->values = talloc_array(message->elements,
struct ldb_val,
@@ -932,6 +933,7 @@ static int ldb_unpack_data_flags_v2(struct ldb_context *ldb,
if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) &&
element->num_values == 1) {
element->values = &ldb_val_single_array[nelem];
+ element->flags |= LDB_FLAG_INTERNAL_SHARED_VALUES;
} else if (element->num_values != 0) {
element->values = talloc_array(message->elements,
struct ldb_val,
@@ -1259,3 +1261,42 @@ failed:
TALLOC_FREE(filtered_msg->elements);
return -1;
}
+
+/* Have an unpacked ldb message take talloc ownership of its elements. */
+int ldb_msg_elements_take_ownership(struct ldb_message *msg)
+{
+ unsigned int i = 0;
+
+ for (i = 0; i < msg->num_elements; i++) {
+ struct ldb_message_element *el = &msg->elements[i];
+ const char *name;
+ unsigned int j;
+
+ name = talloc_strdup(msg->elements,
+ el->name);
+ if (name == NULL) {
+ return -1;
+ }
+ el->name = name;
+
+ if (el->flags & LDB_FLAG_INTERNAL_SHARED_VALUES) {
+ struct ldb_val *values = talloc_memdup(msg->elements, el->values,
+ sizeof(struct ldb_val) * el->num_values);
+ if (values == NULL) {
+ return -1;
+ }
+ el->values = values;
+ el->flags &= ~LDB_FLAG_INTERNAL_SHARED_VALUES;
+ }
+
+ for (j = 0; j < el->num_values; j++) {
+ struct ldb_val val = ldb_val_dup(el->values, &el->values[j]);
+ if (val.data == NULL && el->values[j].length != 0) {
+ return -1;
+ }
+ el->values[j] = val;
+ }
+ }
+
+ return LDB_SUCCESS;
+}
diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h
index 8481fd3991a..8c7f33496fb 100644
--- a/lib/ldb/include/ldb_module.h
+++ b/lib/ldb/include/ldb_module.h
@@ -542,6 +542,10 @@ int ldb_filter_attrs(struct ldb_context *ldb,
const struct ldb_message *msg,
const char *const *attrs,
struct ldb_message *filtered_msg);
+
+/* Have an unpacked ldb message take talloc ownership of its elements. */
+int ldb_msg_elements_take_ownership(struct ldb_message *msg);
+
/*
* Unpack a ldb message from a linear buffer in ldb_val
*