From 3e2c696e45b24b0192ab7b1ddaf1dd4d79571609 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Sep 2006 02:49:04 +0000 Subject: r18866: Jeremy and Volker have given the go-ahead on the group mapping ldb code. Yay! This first commit copies lib/ldb/ from Samba4. A huge congratulations should go to Simo on this - he has put an enormous amount of work into ldb, and it's great to see it go into the Samba3 tree. (This used to be commit bbedf2e34315f5c420a3a05dfe22b1d5cf79f042) --- source3/lib/ldb/ldb_tdb/ldb_pack.c | 294 +++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 source3/lib/ldb/ldb_tdb/ldb_pack.c (limited to 'source3/lib/ldb/ldb_tdb/ldb_pack.c') diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c new file mode 100644 index 0000000000..c6edf663ae --- /dev/null +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -0,0 +1,294 @@ +/* + ldb database library + + Copyright (C) Andrew Tridgell 2004 + + ** NOTE! The following LGPL license applies to the ldb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* + * Name: ldb + * + * Component: ldb pack/unpack + * + * Description: pack/unpack routines for ldb messages as key/value blobs + * + * Author: Andrew Tridgell + */ + +#include "includes.h" +#include "ldb/include/includes.h" + +#include "ldb/ldb_tdb/ldb_tdb.h" + +/* change this if the data format ever changes */ +#define LTDB_PACKING_FORMAT 0x26011967 + +/* old packing formats */ +#define LTDB_PACKING_FORMAT_NODN 0x26011966 + +/* use a portable integer format */ +static void put_uint32(uint8_t *p, int ofs, unsigned int val) +{ + p += ofs; + p[0] = val&0xFF; + p[1] = (val>>8) & 0xFF; + p[2] = (val>>16) & 0xFF; + p[3] = (val>>24) & 0xFF; +} + +static unsigned int pull_uint32(uint8_t *p, int ofs) +{ + p += ofs; + return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24); +} + +static int attribute_storable_values(const struct ldb_message_element *el) +{ + if (el->num_values == 0) return 0; + + if (ldb_attr_cmp(el->name, "dn") == 0) return 0; + + if (ldb_attr_cmp(el->name, "distinguishedName") == 0) return 0; + + return el->num_values; +} + +/* + pack a ldb message into a linear buffer in a TDB_DATA + + note that this routine avoids saving elements with zero values, + as these are equivalent to having no element + + caller frees the data buffer after use +*/ +int ltdb_pack_data(struct ldb_module *module, + const struct ldb_message *message, + struct TDB_DATA *data) +{ + struct ldb_context *ldb = module->ldb; + unsigned int i, j, real_elements=0; + size_t size; + char *dn; + uint8_t *p; + size_t len; + + dn = ldb_dn_linearize(ldb, message->dn); + if (dn == NULL) { + errno = ENOMEM; + return -1; + } + + /* work out how big it needs to be */ + size = 8; + + size += 1 + strlen(dn); + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + + real_elements++; + + size += 1 + strlen(message->elements[i].name) + 4; + for (j=0;jelements[i].num_values;j++) { + size += 4 + message->elements[i].values[j].length + 1; + } + } + + /* allocate it */ + data->dptr = talloc_array(ldb, uint8_t, size); + if (!data->dptr) { + talloc_free(dn); + errno = ENOMEM; + return -1; + } + data->dsize = size; + + p = data->dptr; + put_uint32(p, 0, LTDB_PACKING_FORMAT); + put_uint32(p, 4, real_elements); + p += 8; + + /* the dn needs to be packed so we can be case preserving + while hashing on a case folded dn */ + len = strlen(dn); + memcpy(p, dn, len+1); + p += len + 1; + + for (i=0;inum_elements;i++) { + if (attribute_storable_values(&message->elements[i]) == 0) { + continue; + } + len = strlen(message->elements[i].name); + memcpy(p, message->elements[i].name, len+1); + p += len + 1; + put_uint32(p, 0, message->elements[i].num_values); + p += 4; + for (j=0;jelements[i].num_values;j++) { + put_uint32(p, 0, message->elements[i].values[j].length); + memcpy(p+4, message->elements[i].values[j].data, + message->elements[i].values[j].length); + p[4+message->elements[i].values[j].length] = 0; + p += 4 + message->elements[i].values[j].length + 1; + } + } + + talloc_free(dn); + return 0; +} + +/* + unpack a ldb message from a linear buffer in TDB_DATA + + Free with ltdb_unpack_data_free() +*/ +int ltdb_unpack_data(struct ldb_module *module, + const struct TDB_DATA *data, + struct ldb_message *message) +{ + struct ldb_context *ldb = module->ldb; + uint8_t *p; + unsigned int remaining; + unsigned int i, j; + unsigned format; + size_t len; + + message->elements = NULL; + + p = data->dptr; + if (data->dsize < 8) { + errno = EIO; + goto failed; + } + + format = pull_uint32(p, 0); + message->num_elements = pull_uint32(p, 4); + p += 8; + + remaining = data->dsize - 8; + + switch (format) { + case LTDB_PACKING_FORMAT_NODN: + message->dn = NULL; + break; + + case LTDB_PACKING_FORMAT: + len = strnlen((char *)p, remaining); + if (len == remaining) { + errno = EIO; + goto failed; + } + message->dn = ldb_dn_explode(message, (char *)p); + if (message->dn == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + break; + + default: + errno = EIO; + goto failed; + } + + if (message->num_elements == 0) { + message->elements = NULL; + return 0; + } + + if (message->num_elements > remaining / 6) { + errno = EIO; + goto failed; + } + + message->elements = talloc_array(message, struct ldb_message_element, message->num_elements); + if (!message->elements) { + errno = ENOMEM; + goto failed; + } + + memset(message->elements, 0, + message->num_elements * sizeof(struct ldb_message_element)); + + for (i=0;inum_elements;i++) { + if (remaining < 10) { + errno = EIO; + goto failed; + } + len = strnlen((char *)p, remaining-6); + if (len == remaining-6) { + errno = EIO; + goto failed; + } + message->elements[i].flags = 0; + message->elements[i].name = talloc_strndup(message->elements, (char *)p, len); + if (message->elements[i].name == NULL) { + errno = ENOMEM; + goto failed; + } + remaining -= len + 1; + p += len + 1; + message->elements[i].num_values = pull_uint32(p, 0); + message->elements[i].values = NULL; + if (message->elements[i].num_values != 0) { + message->elements[i].values = talloc_array(message->elements, + struct ldb_val, + message->elements[i].num_values); + if (!message->elements[i].values) { + errno = ENOMEM; + goto failed; + } + } + p += 4; + remaining -= 4; + for (j=0;jelements[i].num_values;j++) { + len = pull_uint32(p, 0); + if (len > remaining-5) { + errno = EIO; + goto failed; + } + + message->elements[i].values[j].length = len; + message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); + if (message->elements[i].values[j].data == NULL) { + errno = ENOMEM; + goto failed; + } + memcpy(message->elements[i].values[j].data, p+4, len); + message->elements[i].values[j].data[len] = 0; + + remaining -= len+4+1; + p += len+4+1; + } + } + + if (remaining != 0) { + ldb_debug(ldb, LDB_DEBUG_ERROR, + "Error: %d bytes unread in ltdb_unpack_data\n", remaining); + } + + return 0; + +failed: + talloc_free(message->elements); + return -1; +} -- cgit From 847644bdac520a3cca7f30ffa50c0de3eeedf6d9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 27 Nov 2006 08:41:41 +0000 Subject: r19917: Fix warnings (This used to be commit cf4309b9048a8417104cac660421a3dcd2e96ffe) --- source3/lib/ldb/ldb_tdb/ldb_pack.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb/ldb_pack.c') diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index c6edf663ae..50dc20524f 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -114,7 +114,7 @@ int ltdb_pack_data(struct ldb_module *module, } /* allocate it */ - data->dptr = talloc_array(ldb, uint8_t, size); + data->dptr = talloc_array(ldb, char, size); if (!data->dptr) { talloc_free(dn); errno = ENOMEM; @@ -122,7 +122,7 @@ int ltdb_pack_data(struct ldb_module *module, } data->dsize = size; - p = data->dptr; + p = (uint8_t *)data->dptr; put_uint32(p, 0, LTDB_PACKING_FORMAT); put_uint32(p, 4, real_elements); p += 8; @@ -173,7 +173,7 @@ int ltdb_unpack_data(struct ldb_module *module, message->elements = NULL; - p = data->dptr; + p = (uint8_t *)data->dptr; if (data->dsize < 8) { errno = EIO; goto failed; @@ -268,7 +268,7 @@ int ltdb_unpack_data(struct ldb_module *module, } message->elements[i].values[j].length = len; - message->elements[i].values[j].data = talloc_size(message->elements[i].values, len+1); + message->elements[i].values[j].data = (uint8_t *)talloc_size(message->elements[i].values, len+1); if (message->elements[i].values[j].data == NULL) { errno = ENOMEM; goto failed; -- cgit From bc2b6436d0f5f3e9ffdfaeb7f1b32996a83d5478 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Mar 2007 09:35:51 +0000 Subject: r22009: change TDB_DATA from char * to unsigned char * and fix all compiler warnings in the users metze (This used to be commit 3a28443079c141a6ce8182c65b56ca210e34f37f) --- source3/lib/ldb/ldb_tdb/ldb_pack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb/ldb_pack.c') diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index 50dc20524f..45fcf354a5 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -114,7 +114,7 @@ int ltdb_pack_data(struct ldb_module *module, } /* allocate it */ - data->dptr = talloc_array(ldb, char, size); + data->dptr = talloc_array(ldb, uint8_t, size); if (!data->dptr) { talloc_free(dn); errno = ENOMEM; -- cgit From 2c09988e46d4e917b1c53c9bda3f81a48bba4952 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 01:44:42 +0000 Subject: r23790: LGPLv3+ conversion for our LGPLv2+ library code (This used to be commit 1b78cace504f60c0f525765fbf59d9cc6506cd4d) --- source3/lib/ldb/ldb_tdb/ldb_pack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/lib/ldb/ldb_tdb/ldb_pack.c') diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index 45fcf354a5..df01dfb438 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -10,7 +10,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- cgit From 9fa1c63578733077c0aaaeeb2fc97c3b191089cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 03:42:26 +0000 Subject: r23798: updated old Temple Place FSF addresses to new URL (This used to be commit c676a971142d7176fd5dbf21405fca14515a0a76) --- source3/lib/ldb/ldb_tdb/ldb_pack.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/lib/ldb/ldb_tdb/ldb_pack.c') diff --git a/source3/lib/ldb/ldb_tdb/ldb_pack.c b/source3/lib/ldb/ldb_tdb/ldb_pack.c index df01dfb438..3f3d1ccca7 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_pack.c +++ b/source3/lib/ldb/ldb_tdb/ldb_pack.c @@ -18,8 +18,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ /* -- cgit