4 Copyright (C) Andrew Tridgell 2004
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 3 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 * Component: ldb pack/unpack
29 * Description: pack/unpack routines for ldb messages as key/value blobs
31 * Author: Andrew Tridgell
34 #include "ldb_private.h"
36 /* change this if the data format ever changes */
37 #define LDB_PACKING_FORMAT 0x26011967
39 /* old packing formats */
40 #define LDB_PACKING_FORMAT_NODN 0x26011966
42 /* use a portable integer format */
43 static void put_uint32(uint8_t *p, int ofs, unsigned int val)
47 p[1] = (val>>8) & 0xFF;
48 p[2] = (val>>16) & 0xFF;
49 p[3] = (val>>24) & 0xFF;
52 static unsigned int pull_uint32(uint8_t *p, int ofs)
55 return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
58 static int attribute_storable_values(const struct ldb_message_element *el)
60 if (el->num_values == 0) return 0;
62 if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0;
64 return el->num_values;
68 pack a ldb message into a linear buffer in a ldb_val
70 note that this routine avoids saving elements with zero values,
71 as these are equivalent to having no element
73 caller frees the data buffer after use
75 int ldb_pack_data(struct ldb_context *ldb,
76 const struct ldb_message *message,
79 unsigned int i, j, real_elements=0;
80 size_t size, dn_len, attr_len, value_len;
85 dn = ldb_dn_get_linearized(message->dn);
91 /* work out how big it needs to be */
97 if (size + dn_len < size) {
104 * First calcuate the buffer size we need, and check for
107 for (i=0;i<message->num_elements;i++) {
108 if (attribute_storable_values(&message->elements[i]) == 0) {
114 if (size + 5 < size) {
120 attr_len = strlen(message->elements[i].name);
121 if (size + attr_len < size) {
127 for (j=0;j<message->elements[i].num_values;j++) {
128 if (size + 5 < size) {
134 value_len = message->elements[i].values[j].length;
135 if (size + value_len < size) {
144 data->data = talloc_array(ldb, uint8_t, size);
152 put_uint32(p, 0, LDB_PACKING_FORMAT);
153 put_uint32(p, 4, real_elements);
156 /* the dn needs to be packed so we can be case preserving
157 while hashing on a case folded dn */
159 memcpy(p, dn, len+1);
162 for (i=0;i<message->num_elements;i++) {
163 if (attribute_storable_values(&message->elements[i]) == 0) {
166 len = strlen(message->elements[i].name);
167 memcpy(p, message->elements[i].name, len+1);
169 put_uint32(p, 0, message->elements[i].num_values);
171 for (j=0;j<message->elements[i].num_values;j++) {
172 put_uint32(p, 0, message->elements[i].values[j].length);
173 memcpy(p+4, message->elements[i].values[j].data,
174 message->elements[i].values[j].length);
175 p[4+message->elements[i].values[j].length] = 0;
176 p += 4 + message->elements[i].values[j].length + 1;
183 static bool ldb_consume_element_data(uint8_t **pp, size_t *premaining)
185 unsigned int remaining = *premaining;
187 uint32_t num_values = pull_uint32(p, 0);
195 for (j = 0; j < num_values; j++) {
196 len = pull_uint32(p, 0);
201 if (len > remaining) {
208 *premaining = remaining;
215 * Unpack a ldb message from a linear buffer in ldb_val
217 * Providing a list of attributes to this function allows selective unpacking.
218 * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
220 int ldb_unpack_data_only_attr_list_flags(struct ldb_context *ldb,
221 const struct ldb_val *data,
222 struct ldb_message *message,
223 const char * const *list,
224 unsigned int list_size,
226 unsigned int *nb_elements_in_db)
233 unsigned int nelem = 0;
235 unsigned int found = 0;
236 struct ldb_val *ldb_val_single_array = NULL;
242 message->elements = NULL;
245 if (data->length < 8) {
250 format = pull_uint32(p, 0);
251 message->num_elements = pull_uint32(p, 4);
253 if (nb_elements_in_db) {
254 *nb_elements_in_db = message->num_elements;
257 remaining = data->length - 8;
260 case LDB_PACKING_FORMAT_NODN:
264 case LDB_PACKING_FORMAT:
266 * With this check, we know that the DN at p is \0
269 dn_len = strnlen((char *)p, remaining);
270 if (dn_len == remaining) {
274 if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) {
278 blob.data = discard_const_p(uint8_t, p);
279 blob.length = dn_len;
280 message->dn = ldb_dn_from_ldb_val(message, ldb, &blob);
281 if (message->dn == NULL) {
287 * Redundant: by definition, remaining must be more
288 * than one less than dn_len, as otherwise it would be
291 if (remaining < dn_len + 1) {
295 remaining -= dn_len + 1;
305 if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) {
309 if (message->num_elements == 0) {
313 if (message->num_elements > remaining / 6) {
318 message->elements = talloc_zero_array(message, struct ldb_message_element,
319 message->num_elements);
320 if (!message->elements) {
326 * In typical use, most values are single-valued. This makes
327 * it quite expensive to allocate an array of ldb_val for each
328 * of these, just to then hold the pointer to the data buffer
329 * So with LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this
330 * ahead of time and use it for the single values where possible.
331 * (This is used the the normal search case, but not in the
332 * index case because of caller requirements).
334 if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) {
335 ldb_val_single_array = talloc_array(message->elements, struct ldb_val,
336 message->num_elements);
337 if (ldb_val_single_array == NULL) {
343 for (i=0;i<message->num_elements;i++) {
344 const char *attr = NULL;
346 struct ldb_message_element *element = NULL;
348 if (remaining < 10) {
353 * With this check, we know that the attribute name at
354 * p is \0 terminated.
356 attr_len = strnlen((char *)p, remaining-6);
357 if (attr_len == remaining-6) {
368 * The general idea is to reduce allocations by skipping over
369 * attributes that we do not actually care about.
371 * This is a bit expensive but normally the list is pretty small
372 * also the cost of freeing unused attributes is quite important
373 * and can dwarf the cost of looping.
375 if (list_size != 0) {
380 * We know that p has a \0 terminator before the
381 * end of the buffer due to the check above.
383 for (h = 0; h < list_size && found < list_size; h++) {
384 if (ldb_attr_cmp(attr, list[h]) == 0) {
392 if (remaining < (attr_len + 1)) {
396 remaining -= attr_len + 1;
398 if (!ldb_consume_element_data(&p, &remaining)) {
405 element = &message->elements[nelem];
406 element->name = attr;
409 if (remaining < (attr_len + 1)) {
413 remaining -= attr_len + 1;
415 element->num_values = pull_uint32(p, 0);
416 element->values = NULL;
417 if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) {
418 element->values = &ldb_val_single_array[nelem];
419 } else if (element->num_values != 0) {
420 element->values = talloc_array(message->elements,
422 element->num_values);
423 if (!element->values) {
434 for (j = 0; j < element->num_values; j++) {
441 len = pull_uint32(p, 0);
442 if (remaining < len) {
451 element->values[j].length = len;
452 element->values[j].data = p + 4;
459 * Adapt the number of elements to the real number of unpacked elements,
460 * it means that we overallocated elements array.
462 message->num_elements = nelem;
465 * Shrink the allocated size. On current talloc behaviour
466 * this will help if we skipped 32 or more attributes.
468 message->elements = talloc_realloc(message, message->elements,
469 struct ldb_message_element,
470 message->num_elements);
472 if (remaining != 0) {
473 ldb_debug(ldb, LDB_DEBUG_ERROR,
474 "Error: %zu bytes unread in ldb_unpack_data_only_attr_list",
481 talloc_free(message->elements);
486 * Unpack a ldb message from a linear buffer in ldb_val
488 * Providing a list of attributes to this function allows selective unpacking.
489 * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
491 * Free with ldb_unpack_data_free()
493 int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
494 const struct ldb_val *data,
495 struct ldb_message *message,
496 const char * const *list,
497 unsigned int list_size,
498 unsigned int *nb_elements_in_db)
500 return ldb_unpack_data_only_attr_list_flags(ldb,
509 int ldb_unpack_data(struct ldb_context *ldb,
510 const struct ldb_val *data,
511 struct ldb_message *message)
513 return ldb_unpack_data_only_attr_list(ldb, data, message, NULL, 0, NULL);
517 add the special distinguishedName element
519 static int msg_add_distinguished_name(struct ldb_message *msg)
521 const char *dn_attr = "distinguishedName";
524 if (ldb_msg_find_element(msg, dn_attr)) {
526 * This should not happen, but this is
527 * existing behaviour...
532 dn = ldb_dn_alloc_linearized(msg, msg->dn);
534 return LDB_ERR_OPERATIONS_ERROR;
537 return ldb_msg_add_steal_string(msg, dn_attr, dn);
541 * filter the specified list of attributes from msg,
542 * adding requested attributes, and perhaps all for *,
543 * but not the DN to filtered_msg.
545 int ldb_filter_attrs(struct ldb_context *ldb,
546 const struct ldb_message *msg,
547 const char *const *attrs,
548 struct ldb_message *filtered_msg)
551 bool keep_all = false;
553 uint32_t num_elements;
554 uint32_t elements_size;
557 /* check for special attrs */
558 for (i = 0; attrs[i]; i++) {
559 int cmp = strcmp(attrs[i], "*");
564 cmp = ldb_attr_cmp(attrs[i], "distinguishedName");
575 elements_size = msg->num_elements + 1;
577 /* Shortcuts for the simple cases */
578 } else if (add_dn && i == 1) {
579 if (msg_add_distinguished_name(filtered_msg) != 0) {
586 /* Otherwise we are copying at most as many element as we have attributes */
591 filtered_msg->elements = talloc_array(filtered_msg,
592 struct ldb_message_element,
594 if (filtered_msg->elements == NULL) goto failed;
598 for (i = 0; i < msg->num_elements; i++) {
599 struct ldb_message_element *el = &msg->elements[i];
600 struct ldb_message_element *el2 = &filtered_msg->elements[num_elements];
603 if (keep_all == false) {
605 for (j = 0; attrs[j]; j++) {
606 int cmp = ldb_attr_cmp(el->name, attrs[j]);
612 if (found == false) {
617 el2->name = talloc_strdup(filtered_msg->elements,
619 if (el2->name == NULL) {
622 el2->values = talloc_array(filtered_msg->elements,
623 struct ldb_val, el->num_values);
624 if (el2->values == NULL) {
627 for (j=0;j<el->num_values;j++) {
628 el2->values[j] = ldb_val_dup(el2->values, &el->values[j]);
629 if (el2->values[j].data == NULL && el->values[j].length != 0) {
635 /* Pidginhole principle: we can't have more elements
636 * than the number of attributes if they are unique in
638 if (num_elements > elements_size) {
643 filtered_msg->num_elements = num_elements;
646 if (msg_add_distinguished_name(filtered_msg) != 0) {
651 if (filtered_msg->num_elements > 0) {
652 filtered_msg->elements
653 = talloc_realloc(filtered_msg,
654 filtered_msg->elements,
655 struct ldb_message_element,
656 filtered_msg->num_elements);
657 if (filtered_msg->elements == NULL) {
661 talloc_free(filtered_msg->elements);
662 filtered_msg->elements = NULL;