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 * (in the LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC we don't
330 * allocate the data). So with
331 * LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this ahead
332 * of time and use it for the single values where possible.
333 * (This is used the the normal search case, but not in the
334 * index case because of caller requirements).
336 if (flags
& LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC
) {
337 ldb_val_single_array
= talloc_array(message
->elements
, struct ldb_val
,
338 message
->num_elements
);
339 if (ldb_val_single_array
== NULL
) {
345 for (i
=0;i
<message
->num_elements
;i
++) {
346 const char *attr
= NULL
;
348 struct ldb_message_element
*element
= NULL
;
350 if (remaining
< 10) {
355 * With this check, we know that the attribute name at
356 * p is \0 terminated.
358 attr_len
= strnlen((char *)p
, remaining
-6);
359 if (attr_len
== remaining
-6) {
370 * The general idea is to reduce allocations by skipping over
371 * attributes that we do not actually care about.
373 * This is a bit expensive but normally the list is pretty small
374 * also the cost of freeing unused attributes is quite important
375 * and can dwarf the cost of looping.
377 if (list_size
!= 0) {
382 * We know that p has a \0 terminator before the
383 * end of the buffer due to the check above.
385 for (h
= 0; h
< list_size
&& found
< list_size
; h
++) {
386 if (ldb_attr_cmp(attr
, list
[h
]) == 0) {
394 if (remaining
< (attr_len
+ 1)) {
398 remaining
-= attr_len
+ 1;
400 if (!ldb_consume_element_data(&p
, &remaining
)) {
407 element
= &message
->elements
[nelem
];
408 if (flags
& LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
) {
409 element
->name
= attr
;
411 element
->name
= talloc_memdup(message
->elements
, attr
, attr_len
+1);
413 if (element
->name
== NULL
) {
420 if (remaining
< (attr_len
+ 1)) {
424 remaining
-= attr_len
+ 1;
426 element
->num_values
= pull_uint32(p
, 0);
427 element
->values
= NULL
;
428 if ((flags
& LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC
) && element
->num_values
== 1) {
429 element
->values
= &ldb_val_single_array
[nelem
];
430 } else if (element
->num_values
!= 0) {
431 element
->values
= talloc_array(message
->elements
,
433 element
->num_values
);
434 if (!element
->values
) {
445 for (j
= 0; j
< element
->num_values
; j
++) {
452 len
= pull_uint32(p
, 0);
453 if (remaining
< len
) {
462 element
->values
[j
].length
= len
;
463 if (flags
& LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC
) {
464 element
->values
[j
].data
= p
+ 4;
466 element
->values
[j
].data
= talloc_size(element
->values
, len
+1);
467 if (element
->values
[j
].data
== NULL
) {
471 memcpy(element
->values
[j
].data
, p
+ 4,
473 element
->values
[j
].data
[len
] = 0;
481 * Adapt the number of elements to the real number of unpacked elements,
482 * it means that we overallocated elements array.
484 message
->num_elements
= nelem
;
487 * Shrink the allocated size. On current talloc behaviour
488 * this will help if we skipped 32 or more attributes.
490 message
->elements
= talloc_realloc(message
, message
->elements
,
491 struct ldb_message_element
,
492 message
->num_elements
);
494 if (remaining
!= 0) {
495 ldb_debug(ldb
, LDB_DEBUG_ERROR
,
496 "Error: %zu bytes unread in ldb_unpack_data_only_attr_list",
503 talloc_free(message
->elements
);
508 * Unpack a ldb message from a linear buffer in ldb_val
510 * Providing a list of attributes to this function allows selective unpacking.
511 * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
513 * Free with ldb_unpack_data_free()
515 int ldb_unpack_data_only_attr_list(struct ldb_context
*ldb
,
516 const struct ldb_val
*data
,
517 struct ldb_message
*message
,
518 const char * const *list
,
519 unsigned int list_size
,
520 unsigned int *nb_elements_in_db
)
522 return ldb_unpack_data_only_attr_list_flags(ldb
,
531 int ldb_unpack_data(struct ldb_context
*ldb
,
532 const struct ldb_val
*data
,
533 struct ldb_message
*message
)
535 return ldb_unpack_data_only_attr_list(ldb
, data
, message
, NULL
, 0, NULL
);