return LDB_SUCCESS;
}
-/*
- add an empty element to a message
-*/
-int ldb_msg_add_empty( struct ldb_message *msg,
- const char *attr_name,
- int flags,
- struct ldb_message_element **return_el)
+/**
+ * Add an empty element with a given name to a message
+ */
+int ldb_msg_add_empty(struct ldb_message *msg,
+ const char *attr_name,
+ int flags,
+ struct ldb_message_element **return_el)
{
- struct ldb_message_element *els;
+ int ret;
+ struct ldb_message_element *el;
- els = talloc_realloc(msg, msg->elements,
- struct ldb_message_element, msg->num_elements+1);
- if (!els) {
- errno = ENOMEM;
- return LDB_ERR_OPERATIONS_ERROR;
+ ret = _ldb_msg_add_el(msg, &el);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
- els[msg->num_elements].values = NULL;
- els[msg->num_elements].num_values = 0;
- els[msg->num_elements].flags = flags;
- els[msg->num_elements].name = talloc_strdup(els, attr_name);
- if (!els[msg->num_elements].name) {
+ /* initialize newly added element */
+ el->flags = flags;
+ el->name = talloc_strdup(msg->elements, attr_name);
+ if (!el->name) {
errno = ENOMEM;
return LDB_ERR_OPERATIONS_ERROR;
}
- msg->elements = els;
- msg->num_elements++;
-
if (return_el) {
- *return_el = &els[msg->num_elements-1];
+ *return_el = el;
}
return LDB_SUCCESS;
const struct ldb_message_element *el,
int flags)
{
+ int ret;
+ struct ldb_message_element *el_new;
/* We have to copy this, just in case *el is a pointer into
* what ldb_msg_add_empty() is about to realloc() */
struct ldb_message_element el_copy = *el;
- if (ldb_msg_add_empty(msg, el->name, flags, NULL) != LDB_SUCCESS) {
- return LDB_ERR_OPERATIONS_ERROR;
+
+ ret = _ldb_msg_add_el(msg, &el_new);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
- msg->elements[msg->num_elements-1] = el_copy;
- msg->elements[msg->num_elements-1].flags = flags;
+ el_new->flags = flags;
+ el_new->name = el_copy.name;
+ el_new->num_values = el_copy.num_values;
+ el_new->values = el_copy.values;
return LDB_SUCCESS;
}
return msg2;
}
+/**
+ * Canonicalize a message, merging elements of the same name
+ */
+int ldb_msg_canonicalize_ex(struct ldb_context *ldb,
+ const struct ldb_message *msg,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_message **_msg_out)
+{
+ unsigned int i;
+ struct ldb_message *msg2;
+
+ msg2 = ldb_msg_copy(mem_ctx, msg);
+ if (msg2 == NULL) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ldb_msg_sort_elements(msg2);
+
+ for (i=1; i < msg2->num_elements; i++) {
+ struct ldb_message_element *el1 = &msg2->elements[i-1];
+ struct ldb_message_element *el2 = &msg2->elements[i];
+
+ if (ldb_msg_element_compare_name(el1, el2) == 0) {
+ el1->values = talloc_realloc(msg2->elements,
+ el1->values, struct ldb_val,
+ el1->num_values + el2->num_values);
+ if (el1->num_values + el2->num_values > 0 && el1->values == NULL) {
+ talloc_free(msg2);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ memcpy(el1->values + el1->num_values,
+ el2->values,
+ sizeof(struct ldb_val) * el2->num_values);
+ el1->num_values += el2->num_values;
+ talloc_free(discard_const_p(char, el2->name));
+ if ((i+1) < msg2->num_elements) {
+ memmove(el2, el2+1, sizeof(struct ldb_message_element) *
+ (msg2->num_elements - (i+1)));
+ }
+ msg2->num_elements--;
+ i--;
+ }
+ }
+
+ *_msg_out = msg2;
+ return LDB_SUCCESS;
+}
+
/*
return a ldb_message representing the differences between msg1 and msg2. If you