1 /*
2 ldb database library
3
4 Copyright (C) Andrew Tridgell 2004
5
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
9
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.
14
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.
19
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/>.
22 */
23
24 /*
25 * Name: ldb
26 *
27 * Component: ldb pack/unpack
28 *
29 * Description: pack/unpack routines for ldb messages as key/value blobs
30 *
31 * Author: Andrew Tridgell
32 */
33
34 #include "ldb_private.h"
35
36 /* use a portable integer format */
put_uint32(uint8_t * p,int ofs,unsigned int val)37 static void put_uint32(uint8_t *p, int ofs, unsigned int val)
38 {
39 p += ofs;
40 p[0] = val&0xFF;
41 p[1] = (val>>8) & 0xFF;
42 p[2] = (val>>16) & 0xFF;
43 p[3] = (val>>24) & 0xFF;
44 }
45
pull_uint32(uint8_t * p,int ofs)46 static unsigned int pull_uint32(uint8_t *p, int ofs)
47 {
48 p += ofs;
49 return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
50 }
51
attribute_storable_values(const struct ldb_message_element * el)52 static int attribute_storable_values(const struct ldb_message_element *el)
53 {
54 if (el->num_values == 0) return 0;
55
56 if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0;
57
58 return el->num_values;
59 }
60
61 /*
62 pack a ldb message into a linear buffer in a ldb_val
63
64 note that this routine avoids saving elements with zero values,
65 as these are equivalent to having no element
66
67 caller frees the data buffer after use
68 */
ldb_pack_data(struct ldb_context * ldb,const struct ldb_message * message,struct ldb_val * data)69 int ldb_pack_data(struct ldb_context *ldb,
70 const struct ldb_message *message,
71 struct ldb_val *data)
72 {
73 unsigned int i, j, real_elements=0;
74 size_t size, dn_len, attr_len, value_len;
75 const char *dn;
76 uint8_t *p;
77 size_t len;
78
79 dn = ldb_dn_get_linearized(message->dn);
80 if (dn == NULL) {
81 errno = ENOMEM;
82 return -1;
83 }
84
85 /* work out how big it needs to be */
86 size = 8;
87
88 size += 1;
89
90 dn_len = strlen(dn);
91 if (size + dn_len < size) {
92 errno = ENOMEM;
93 return -1;
94 }
95 size += dn_len;
96
97 /*
98 * First calcuate the buffer size we need, and check for
99 * overflows
100 */
101 for (i=0;i<message->num_elements;i++) {
102 if (attribute_storable_values(&message->elements[i]) == 0) {
103 continue;
104 }
105
106 real_elements++;
107
108 if (size + 5 < size) {
109 errno = ENOMEM;
110 return -1;
111 }
112 size += 5;
113
114 attr_len = strlen(message->elements[i].name);
115 if (size + attr_len < size) {
116 errno = ENOMEM;
117 return -1;
118 }
119 size += attr_len;
120
121 for (j=0;j<message->elements[i].num_values;j++) {
122 if (size + 5 < size) {
123 errno = ENOMEM;
124 return -1;
125 }
126 size += 5;
127
128 value_len = message->elements[i].values[j].length;
129 if (size + value_len < size) {
130 errno = ENOMEM;
131 return -1;
132 }
133 size += value_len;
134 }
135 }
136
137 /* allocate it */
138 data->data = talloc_array(ldb, uint8_t, size);
139 if (!data->data) {
140 errno = ENOMEM;
141 return -1;
142 }
143 data->length = size;
144
145 p = data->data;
146 put_uint32(p, 0, LDB_PACKING_FORMAT);
147 put_uint32(p, 4, real_elements);
148 p += 8;
149
150 /* the dn needs to be packed so we can be case preserving
151 while hashing on a case folded dn */
152 len = dn_len;
153 memcpy(p, dn, len+1);
154 p += len + 1;
155
156 for (i=0;i<message->num_elements;i++) {
157 if (attribute_storable_values(&message->elements[i]) == 0) {
158 continue;
159 }
160 len = strlen(message->elements[i].name);
161 memcpy(p, message->elements[i].name, len+1);
162 p += len + 1;
163 put_uint32(p, 0, message->elements[i].num_values);
164 p += 4;
165 for (j=0;j<message->elements[i].num_values;j++) {
166 put_uint32(p, 0, message->elements[i].values[j].length);
167 memcpy(p+4, message->elements[i].values[j].data,
168 message->elements[i].values[j].length);
169 p[4+message->elements[i].values[j].length] = 0;
170 p += 4 + message->elements[i].values[j].length + 1;
171 }
172 }
173
174 return 0;
175 }
176
ldb_consume_element_data(uint8_t ** pp,size_t * premaining)177 static bool ldb_consume_element_data(uint8_t **pp, size_t *premaining)
178 {
179 unsigned int remaining = *premaining;
180 uint8_t *p = *pp;
181 uint32_t num_values = pull_uint32(p, 0);
182 uint32_t j, len;
183
184 p += 4;
185 if (remaining < 4) {
186 return false;
187 }
188 remaining -= 4;
189 for (j = 0; j < num_values; j++) {
190 len = pull_uint32(p, 0);
191 if (remaining < 5) {
192 return false;
193 }
194 remaining -= 5;
195 if (len > remaining) {
196 return false;
197 }
198 remaining -= len;
199 p += len + 4 + 1;
200 }
201
202 *premaining = remaining;
203 *pp = p;
204 return true;
205 }
206
207
208 /*
209 * Unpack a ldb message from a linear buffer in ldb_val
210 *
211 * Providing a list of attributes to this function allows selective unpacking.
212 * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
213 */
ldb_unpack_data_only_attr_list_flags(struct ldb_context * ldb,const struct ldb_val * data,struct ldb_message * message,const char * const * list,unsigned int list_size,unsigned int flags,unsigned int * nb_elements_in_db)214 int ldb_unpack_data_only_attr_list_flags(struct ldb_context *ldb,
215 const struct ldb_val *data,
216 struct ldb_message *message,
217 const char * const *list,
218 unsigned int list_size,
219 unsigned int flags,
220 unsigned int *nb_elements_in_db)
221 {
222 uint8_t *p;
223 size_t remaining;
224 size_t dn_len;
225 unsigned int i, j;
226 uint32_t format;
227 unsigned int nelem = 0;
228 size_t len;
229 unsigned int found = 0;
230 struct ldb_val *ldb_val_single_array = NULL;
231
232 if (list == NULL) {
233 list_size = 0;
234 }
235
236 message->elements = NULL;
237
238 p = data->data;
239 if (data->length < 8) {
240 errno = EIO;
241 goto failed;
242 }
243
244 if (ldb_unpack_get_format(data, &format) != LDB_SUCCESS) {
245 errno = EIO;
246 goto failed;
247 }
248 message->num_elements = pull_uint32(p, 4);
249 p += 8;
250 if (nb_elements_in_db) {
251 *nb_elements_in_db = message->num_elements;
252 }
253
254 remaining = data->length - 8;
255
256 switch (format) {
257 case LDB_PACKING_FORMAT_NODN:
258 message->dn = NULL;
259 break;
260
261 case LDB_PACKING_FORMAT:
262 /*
263 * With this check, we know that the DN at p is \0
264 * terminated.
265 */
266 dn_len = strnlen((char *)p, remaining);
267 if (dn_len == remaining) {
268 errno = EIO;
269 goto failed;
270 }
271 if (flags & LDB_UNPACK_DATA_FLAG_NO_DN) {
272 message->dn = NULL;
273 } else {
274 struct ldb_val blob;
275 blob.data = discard_const_p(uint8_t, p);
276 blob.length = dn_len;
277 message->dn = ldb_dn_from_ldb_val(message, ldb, &blob);
278 if (message->dn == NULL) {
279 errno = ENOMEM;
280 goto failed;
281 }
282 }
283 /*
284 * Redundant: by definition, remaining must be more
285 * than one less than dn_len, as otherwise it would be
286 * == dn_len
287 */
288 if (remaining < dn_len + 1) {
289 errno = EIO;
290 goto failed;
291 }
292 remaining -= dn_len + 1;
293 p += dn_len + 1;
294 break;
295
296 default:
297 errno = EIO;
298 goto failed;
299 }
300
301
302 if (flags & LDB_UNPACK_DATA_FLAG_NO_ATTRS) {
303 return 0;
304 }
305
306 if (message->num_elements == 0) {
307 return 0;
308 }
309
310 if (message->num_elements > remaining / 6) {
311 errno = EIO;
312 goto failed;
313 }
314
315 message->elements = talloc_zero_array(message, struct ldb_message_element,
316 message->num_elements);
317 if (!message->elements) {
318 errno = ENOMEM;
319 goto failed;
320 }
321
322 /*
323 * In typical use, most values are single-valued. This makes
324 * it quite expensive to allocate an array of ldb_val for each
325 * of these, just to then hold the pointer to the data buffer
326 * (in the LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC we don't
327 * allocate the data). So with
328 * LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC we allocate this ahead
329 * of time and use it for the single values where possible.
330 * (This is used the the normal search case, but not in the
331 * index case because of caller requirements).
332 */
333 if (flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) {
334 ldb_val_single_array = talloc_array(message->elements, struct ldb_val,
335 message->num_elements);
336 if (ldb_val_single_array == NULL) {
337 errno = ENOMEM;
338 goto failed;
339 }
340 }
341
342 for (i=0;i<message->num_elements;i++) {
343 const char *attr = NULL;
344 size_t attr_len;
345 struct ldb_message_element *element = NULL;
346
347 if (remaining < 10) {
348 errno = EIO;
349 goto failed;
350 }
351 /*
352 * With this check, we know that the attribute name at
353 * p is \0 terminated.
354 */
355 attr_len = strnlen((char *)p, remaining-6);
356 if (attr_len == remaining-6) {
357 errno = EIO;
358 goto failed;
359 }
360 if (attr_len == 0) {
361 errno = EIO;
362 goto failed;
363 }
364 attr = (char *)p;
365
366 /*
367 * The general idea is to reduce allocations by skipping over
368 * attributes that we do not actually care about.
369 *
370 * This is a bit expensive but normally the list is pretty small
371 * also the cost of freeing unused attributes is quite important
372 * and can dwarf the cost of looping.
373 */
374 if (list_size != 0) {
375 bool keep = false;
376 unsigned int h;
377
378 /*
379 * We know that p has a \0 terminator before the
380 * end of the buffer due to the check above.
381 */
382 for (h = 0; h < list_size && found < list_size; h++) {
383 if (ldb_attr_cmp(attr, list[h]) == 0) {
384 keep = true;
385 found++;
386 break;
387 }
388 }
389
390 if (!keep) {
391 if (remaining < (attr_len + 1)) {
392 errno = EIO;
393 goto failed;
394 }
395 remaining -= attr_len + 1;
396 p += attr_len + 1;
397 if (!ldb_consume_element_data(&p, &remaining)) {
398 errno = EIO;
399 goto failed;
400 }
401 continue;
402 }
403 }
404 element = &message->elements[nelem];
405 if (flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
406 element->name = attr;
407 } else {
408 element->name = talloc_memdup(message->elements, attr, attr_len+1);
409
410 if (element->name == NULL) {
411 errno = ENOMEM;
412 goto failed;
413 }
414 }
415 element->flags = 0;
416
417 if (remaining < (attr_len + 1)) {
418 errno = EIO;
419 goto failed;
420 }
421 remaining -= attr_len + 1;
422 p += attr_len + 1;
423 element->num_values = pull_uint32(p, 0);
424 element->values = NULL;
425 if ((flags & LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC) && element->num_values == 1) {
426 element->values = &ldb_val_single_array[nelem];
427 } else if (element->num_values != 0) {
428 element->values = talloc_array(message->elements,
429 struct ldb_val,
430 element->num_values);
431 if (!element->values) {
432 errno = ENOMEM;
433 goto failed;
434 }
435 }
436 p += 4;
437 if (remaining < 4) {
438 errno = EIO;
439 goto failed;
440 }
441 remaining -= 4;
442 for (j = 0; j < element->num_values; j++) {
443 if (remaining < 5) {
444 errno = EIO;
445 goto failed;
446 }
447 remaining -= 5;
448
449 len = pull_uint32(p, 0);
450 if (remaining < len) {
451 errno = EIO;
452 goto failed;
453 }
454 if (len + 1 < len) {
455 errno = EIO;
456 goto failed;
457 }
458
459 element->values[j].length = len;
460 if (flags & LDB_UNPACK_DATA_FLAG_NO_DATA_ALLOC) {
461 element->values[j].data = p + 4;
462 } else {
463 element->values[j].data = talloc_size(element->values, len+1);
464 if (element->values[j].data == NULL) {
465 errno = ENOMEM;
466 goto failed;
467 }
468 memcpy(element->values[j].data, p + 4,
469 len);
470 element->values[j].data[len] = 0;
471 }
472 remaining -= len;
473 p += len+4+1;
474 }
475 nelem++;
476 }
477 /*
478 * Adapt the number of elements to the real number of unpacked elements,
479 * it means that we overallocated elements array.
480 */
481 message->num_elements = nelem;
482
483 /*
484 * Shrink the allocated size. On current talloc behaviour
485 * this will help if we skipped 32 or more attributes.
486 */
487 message->elements = talloc_realloc(message, message->elements,
488 struct ldb_message_element,
489 message->num_elements);
490
491 if (remaining != 0) {
492 ldb_debug(ldb, LDB_DEBUG_ERROR,
493 "Error: %zu bytes unread in ldb_unpack_data_only_attr_list",
494 remaining);
495 }
496
497 return 0;
498
499 failed:
500 talloc_free(message->elements);
501 return -1;
502 }
503
ldb_unpack_get_format(const struct ldb_val * data,uint32_t * pack_format_version)504 int ldb_unpack_get_format(const struct ldb_val *data,
505 uint32_t *pack_format_version)
506 {
507 if (data->length < 4) {
508 return LDB_ERR_OPERATIONS_ERROR;
509 }
510 *pack_format_version = pull_uint32(data->data, 0);
511 return LDB_SUCCESS;
512 }
513
514 /*
515 * Unpack a ldb message from a linear buffer in ldb_val
516 *
517 * Providing a list of attributes to this function allows selective unpacking.
518 * Giving a NULL list (or a list_size of 0) unpacks all the attributes.
519 *
520 * Free with ldb_unpack_data_free()
521 */
ldb_unpack_data_only_attr_list(struct ldb_context * ldb,const struct ldb_val * data,struct ldb_message * message,const char * const * list,unsigned int list_size,unsigned int * nb_elements_in_db)522 int ldb_unpack_data_only_attr_list(struct ldb_context *ldb,
523 const struct ldb_val *data,
524 struct ldb_message *message,
525 const char * const *list,
526 unsigned int list_size,
527 unsigned int *nb_elements_in_db)
528 {
529 return ldb_unpack_data_only_attr_list_flags(ldb,
530 data,
531 message,
532 list,
533 list_size,
534 0,
535 nb_elements_in_db);
536 }
537
ldb_unpack_data(struct ldb_context * ldb,const struct ldb_val * data,struct ldb_message * message)538 int ldb_unpack_data(struct ldb_context *ldb,
539 const struct ldb_val *data,
540 struct ldb_message *message)
541 {
542 return ldb_unpack_data_only_attr_list(ldb, data, message, NULL, 0, NULL);
543 }
544