ldif = talloc(ldb, struct ldb_ldif);
if (!ldif) return NULL;
- ldif->msg = talloc(ldif, struct ldb_message);
+ ldif->msg = talloc_zero(ldif, struct ldb_message);
if (ldif->msg == NULL) {
talloc_free(ldif);
return NULL;
ldif->changetype = LDB_CHANGETYPE_NONE;
msg = ldif->msg;
- msg->dn = NULL;
- msg->elements = NULL;
- msg->num_elements = 0;
-
chunk = next_chunk(ldb, fgetc_fn, private_data);
if (!chunk) {
goto failed;
*/
#include "ldb_private.h"
+#include "lib/util/binsearch.h"
/*
create a new ldb_message in a given memory context (NULL for top level)
const char *attr_name)
{
unsigned int i;
+ if (msg->flags & LDB_FLAG_SORTED_ATTRIBUTES) {
+ struct ldb_message_element *e;
+ if (msg->num_elements == 0) {
+ return NULL;
+ }
+ BINARY_ARRAY_SEARCH(msg->elements, msg->num_elements, name,
+ attr_name, strcasecmp, e);
+ /* distinguishedname if present on sorted message is always at the end */
+ if (e == NULL &&
+ strcasecmp(attr_name, "distinguishedname") == 0 &&
+ strcasecmp(msg->elements[msg->num_elements - 1].name, attr_name) == 0)
+ {
+ return &msg->elements[msg->num_elements - 1];
+ }
+ return e;
+ }
for (i=0;i<msg->num_elements;i++) {
if (ldb_attr_cmp(msg->elements[i].name, attr_name) == 0) {
return &msg->elements[i];
{
struct ldb_message_element *els;
+ /* do not concidere attributes to be sorted */
+ msg->flags = 0;
/*
* TODO: Find out a way to assert on input parameters.
* msg and return_el must be valid
{
int ret;
struct ldb_message_element *el;
+ int msgflags = msg->flags;
ret = _ldb_msg_add_el(msg, &el);
if (ret != LDB_SUCCESS) {
if (!el->name) {
return LDB_ERR_OPERATIONS_ERROR;
}
+ /* Restore flags as distinguisedName is always at the end in sorted
+ * message */
+ if (strcasecmp(attr_name, "distinguishedName") == 0) {
+ msg->flags = msgflags;
+ }
if (return_el) {
*return_el = el;
struct ldb_message *msg2;
msg2 = ldb_msg_copy(mem_ctx, msg);
+ msg2->flags = 0;
if (msg2 == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
int ldb_msg_rename_attr(struct ldb_message *msg, const char *attr, const char *replace)
{
struct ldb_message_element *el = ldb_msg_find_element(msg, attr);
+ msg->flags = 0;
if (el == NULL) {
return LDB_SUCCESS;
}
/* change this if the data format ever changes */
#define LDB_PACKING_FORMAT 0x26011967
+#define LDB_PACKING_FORMAT_SORTED 0x26011968
/* old packing formats */
#define LDB_PACKING_FORMAT_NODN 0x26011966
return el->num_values;
}
+static int message_element_cmp(const struct ldb_message_element *v1,
+ const struct ldb_message_element *v2)
+{
+ return strcasecmp(v1->name, v2->name);
+}
/*
pack a ldb message into a linear buffer in a ldb_val
const char *dn;
uint8_t *p;
size_t len;
+ int format;
dn = ldb_dn_get_linearized(message->dn);
if (dn == NULL) {
}
data->length = size;
+ format = LDB_PACKING_FORMAT_SORTED;
p = data->data;
- put_uint32(p, 0, LDB_PACKING_FORMAT);
+
+ /* FIXME this needs to be made a bit more configurable */
+ put_uint32(p, 0, format);
put_uint32(p, 4, real_elements);
p += 8;
memcpy(p, dn, len+1);
p += len + 1;
+ if (format == LDB_PACKING_FORMAT_SORTED) {
+ TYPESAFE_QSORT(message->elements, message->num_elements, message_element_cmp);
+ }
+
for (i=0;i<message->num_elements;i++) {
if (attribute_storable_values(&message->elements[i]) == 0) {
continue;
message->dn = NULL;
break;
+ case LDB_PACKING_FORMAT_SORTED:
case LDB_PACKING_FORMAT:
len = strnlen((char *)p, remaining);
if (len == remaining) {
* bad.
*/
message->num_elements = nelem;
+ if (format == LDB_PACKING_FORMAT_SORTED) {
+ message->flags |= LDB_FLAG_SORTED_ATTRIBUTES;
+ }
if (remaining != 0) {
ldb_debug(ldb, LDB_DEBUG_ERROR,
struct ldb_dn *dn;
unsigned int num_elements;
struct ldb_message_element *elements;
+ int flags;
};
enum ldb_changetype {
/* call is from an untrusted source - eg. over ldap:// */
#define LDB_HANDLE_FLAG_UNTRUSTED 2
+/* Bitfield in the flag member */
+#define LDB_FLAG_SORTED_ATTRIBUTES 1
+
struct ldb_handle {
int status;
enum ldb_state state;
ret->num_elements = 0;
ret->elements = NULL;
+ ret->flags = msg->flags;
if (!attrs) {
if (msg_add_all_elements(module, ret, msg) != 0) {
if (!msg2->dn) {
msg2->dn = msg->dn;
}
+ msg2->flags = 0;
for (i=0; i<msg->num_elements; i++) {
struct ldb_message_element *el = &msg->elements[i], *el2;
DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn));
- msg = talloc(local_ctx, struct ldb_message);
+ msg = talloc_zero(local_ctx, struct ldb_message);
NT_STATUS_HAVE_NO_MEMORY(msg);
msg->dn = dn;
- msg->num_elements = 0;
- msg->elements = NULL;
if (req->num_mods > 0) {
msg->num_elements = req->num_mods;
DEBUG(10, ("AddRequest: dn: [%s]\n", req->dn));
- msg = talloc(local_ctx, struct ldb_message);
+ msg = talloc_zero(local_ctx, struct ldb_message);
NT_STATUS_HAVE_NO_MEMORY(msg);
msg->dn = dn;
- msg->num_elements = 0;
- msg->elements = NULL;
if (req->num_attributes > 0) {
msg->num_elements = req->num_attributes;