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