CVE-2019-3824 ldb: Add tests for ldb_wildcard_match
[Samba.git] / lib / ldb / common / ldb_pack.c
blob448c577ae1b9a69bf8489a9a701153f900a6df4f
1 /*
2 ldb database library
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
8 ** under the LGPL
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/>.
25 * Name: ldb
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)
45 p += ofs;
46 p[0] = val&0xFF;
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)
54 p += 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,
77 struct ldb_val *data)
79 unsigned int i, j, real_elements=0;
80 size_t size, dn_len, attr_len, value_len;
81 const char *dn;
82 uint8_t *p;
83 size_t len;
85 dn = ldb_dn_get_linearized(message->dn);
86 if (dn == NULL) {
87 errno = ENOMEM;
88 return -1;
91 /* work out how big it needs to be */
92 size = 8;
94 size += 1;
96 dn_len = strlen(dn);
97 if (size + dn_len < size) {
98 errno = ENOMEM;
99 return -1;
101 size += dn_len;
104 * First calcuate the buffer size we need, and check for
105 * overflows
107 for (i=0;i<message->num_elements;i++) {
108 if (attribute_storable_values(&message->elements[i]) == 0) {
109 continue;
112 real_elements++;
114 if (size + 5 < size) {
115 errno = ENOMEM;
116 return -1;
118 size += 5;
120 attr_len = strlen(message->elements[i].name);
121 if (size + attr_len < size) {
122 errno = ENOMEM;
123 return -1;
125 size += attr_len;
127 for (j=0;j<message->elements[i].num_values;j++) {
128 if (size + 5 < size) {
129 errno = ENOMEM;
130 return -1;
132 size += 5;
134 value_len = message->elements[i].values[j].length;
135 if (size + value_len < size) {
136 errno = ENOMEM;
137 return -1;
139 size += value_len;
143 /* allocate it */
144 data->data = talloc_array(ldb, uint8_t, size);
145 if (!data->data) {
146 errno = ENOMEM;
147 return -1;
149 data->length = size;
151 p = data->data;
152 put_uint32(p, 0, LDB_PACKING_FORMAT);
153 put_uint32(p, 4, real_elements);
154 p += 8;
156 /* the dn needs to be packed so we can be case preserving
157 while hashing on a case folded dn */
158 len = dn_len;
159 memcpy(p, dn, len+1);
160 p += len + 1;
162 for (i=0;i<message->num_elements;i++) {
163 if (attribute_storable_values(&message->elements[i]) == 0) {
164 continue;
166 len = strlen(message->elements[i].name);
167 memcpy(p, message->elements[i].name, len+1);
168 p += len + 1;
169 put_uint32(p, 0, message->elements[i].num_values);
170 p += 4;
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;
180 return 0;
183 static bool ldb_consume_element_data(uint8_t **pp, size_t *premaining)
185 unsigned int remaining = *premaining;
186 uint8_t *p = *pp;
187 uint32_t num_values = pull_uint32(p, 0);
188 uint32_t j, len;
190 p += 4;
191 if (remaining < 4) {
192 return false;
194 remaining -= 4;
195 for (j = 0; j < num_values; j++) {
196 len = pull_uint32(p, 0);
197 if (remaining < 5) {
198 return false;
200 remaining -= 5;
201 if (len > remaining) {
202 return false;
204 remaining -= len;
205 p += len + 4 + 1;
208 *premaining = remaining;
209 *pp = p;
210 return true;
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,
225 unsigned int flags,
226 unsigned int *nb_elements_in_db)
228 uint8_t *p;
229 size_t remaining;
230 size_t dn_len;
231 unsigned int i, j;
232 unsigned format;
233 unsigned int nelem = 0;
234 size_t len;
235 unsigned int found = 0;
236 struct ldb_val *ldb_val_single_array = NULL;
238 if (list == NULL) {
239 list_size = 0;
242 message->elements = NULL;
244 p = data->data;
245 if (data->length < 8) {
246 errno = EIO;
247 goto failed;
250 format = pull_uint32(p, 0);
251 message->num_elements = pull_uint32(p, 4);
252 p += 8;
253 if (nb_elements_in_db) {
254 *nb_elements_in_db = message->num_elements;
257 remaining = data->length - 8;
259 switch (format) {
260 case LDB_PACKING_FORMAT_NODN:
261 message->dn = NULL;
262 break;
264 case LDB_PACKING_FORMAT:
266 * With this check, we know that the DN at p is \0
267 * terminated.
269 dn_len = strnlen((char *)p, remaining);
270 if (dn_len == remaining) {
271 errno = EIO;
272 goto failed;
274 if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) {
275 message->dn = NULL;
276 } else {
277 struct ldb_val blob;
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) {
282 errno = ENOMEM;
283 goto failed;
287 * Redundant: by definition, remaining must be more
288 * than one less than dn_len, as otherwise it would be
289 * == dn_len
291 if (remaining < dn_len + 1) {
292 errno = EIO;
293 goto failed;
295 remaining -= dn_len + 1;
296 p += dn_len + 1;
297 break;
299 default:
300 errno = EIO;
301 goto failed;
305 if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) {
306 return 0;
309 if (message->num_elements == 0) {
310 return 0;
313 if (message->num_elements > remaining / 6) {
314 errno = EIO;
315 goto failed;
318 message->elements = talloc_zero_array(message, struct ldb_message_element,
319 message->num_elements);
320 if (!message->elements) {
321 errno = ENOMEM;
322 goto failed;
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) {
340 errno = ENOMEM;
341 goto failed;
345 for (i=0;i<message->num_elements;i++) {
346 const char *attr = NULL;
347 size_t attr_len;
348 struct ldb_message_element *element = NULL;
350 if (remaining < 10) {
351 errno = EIO;
352 goto failed;
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) {
360 errno = EIO;
361 goto failed;
363 if (attr_len == 0) {
364 errno = EIO;
365 goto failed;
367 attr = (char *)p;
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) {
378 bool keep = false;
379 unsigned int h;
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) {
387 keep = true;
388 found++;
389 break;
393 if (!keep) {
394 if (remaining < (attr_len + 1)) {
395 errno = EIO;
396 goto failed;
398 remaining -= attr_len + 1;
399 p += attr_len + 1;
400 if (!ldb_consume_element_data(&p, &remaining)) {
401 errno = EIO;
402 goto failed;
404 continue;
407 element = &message->elements[nelem];
408 if (flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
409 element->name = attr;
410 } else {
411 element->name = talloc_memdup(message->elements, attr, attr_len+1);
413 if (element->name == NULL) {
414 errno = ENOMEM;
415 goto failed;
418 element->flags = 0;
420 if (remaining < (attr_len + 1)) {
421 errno = EIO;
422 goto failed;
424 remaining -= attr_len + 1;
425 p += 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,
432 struct ldb_val,
433 element->num_values);
434 if (!element->values) {
435 errno = ENOMEM;
436 goto failed;
439 p += 4;
440 if (remaining < 4) {
441 errno = EIO;
442 goto failed;
444 remaining -= 4;
445 for (j = 0; j < element->num_values; j++) {
446 if (remaining < 5) {
447 errno = EIO;
448 goto failed;
450 remaining -= 5;
452 len = pull_uint32(p, 0);
453 if (remaining < len) {
454 errno = EIO;
455 goto failed;
457 if (len + 1 < len) {
458 errno = EIO;
459 goto failed;
462 element->values[j].length = len;
463 if (flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
464 element->values[j].data = p + 4;
465 } else {
466 element->values[j].data = talloc_size(element->values, len+1);
467 if (element->values[j].data == NULL) {
468 errno = ENOMEM;
469 goto failed;
471 memcpy(element->values[j].data, p + 4,
472 len);
473 element->values[j].data[len] = 0;
475 remaining -= len;
476 p += len+4+1;
478 nelem++;
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",
497 remaining);
500 return 0;
502 failed:
503 talloc_free(message->elements);
504 return -1;
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,
523 data,
524 message,
525 list,
526 list_size,
528 nb_elements_in_db);
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);