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
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 <http://www.gnu.org/licenses/>.
*/
/*
* Author: Andrew Tridgell
*/
-#include "includes.h"
-#include "ldb/include/ldb.h"
-#include "ldb/include/ldb_private.h"
-#include "ldb/ldb_tdb/ldb_tdb.h"
+#include "ldb_tdb.h"
/* change this if the data format ever changes */
#define LTDB_PACKING_FORMAT 0x26011967
#define LTDB_PACKING_FORMAT_NODN 0x26011966
/* use a portable integer format */
-static void put_uint32(uint32 *p, int ofs, unsigned int val)
+static void put_uint32(uint8_t *p, int ofs, unsigned int val)
{
p += ofs;
p[0] = val&0xFF;
p[3] = (val>>24) & 0xFF;
}
-static unsigned int pull_uint32(uint32 *p, int ofs)
+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
const struct ldb_message *message,
struct TDB_DATA *data)
{
- struct ldb_context *ldb = module->ldb;
+ struct ldb_context *ldb;
unsigned int i, j, real_elements=0;
size_t size;
- char *p;
+ const char *dn;
+ uint8_t *p;
size_t len;
- for (i=0;i<message->num_elements;i++) {
- if (message->elements[i].num_values != 0) {
- real_elements++;
- }
+ ldb = ldb_module_get_ctx(module);
+
+ dn = ldb_dn_get_linearized(message->dn);
+ if (dn == NULL) {
+ errno = ENOMEM;
+ return -1;
}
/* work out how big it needs to be */
size = 8;
- size += 1 + strlen(message->dn);
+ size += 1 + strlen(dn);
for (i=0;i<message->num_elements;i++) {
- if (message->elements[i].num_values == 0) {
+ if (attribute_storable_values(&message->elements[i]) == 0) {
continue;
}
+
+ real_elements++;
+
size += 1 + strlen(message->elements[i].name) + 4;
for (j=0;j<message->elements[i].num_values;j++) {
size += 4 + message->elements[i].values[j].length + 1;
}
/* allocate it */
- data->dptr = ldb_malloc(ldb, size);
+ data->dptr = talloc_array(ldb, uint8_t, size);
if (!data->dptr) {
errno = ENOMEM;
return -1;
/* the dn needs to be packed so we can be case preserving
while hashing on a case folded dn */
- len = strlen(message->dn);
- memcpy(p, message->dn, len+1);
+ len = strlen(dn);
+ memcpy(p, dn, len+1);
p += len + 1;
for (i=0;i<message->num_elements;i++) {
- if (message->elements[i].num_values == 0) {
+ if (attribute_storable_values(&message->elements[i]) == 0) {
continue;
}
len = strlen(message->elements[i].name);
return 0;
}
-/*
- free the memory allocated from a ltdb_unpack_data()
-*/
-void ltdb_unpack_data_free(struct ldb_module *module,
- struct ldb_message *message)
-{
- struct ldb_context *ldb = module->ldb;
- unsigned int i;
-
- for (i=0;i<message->num_elements;i++) {
- if (message->elements[i].values) ldb_free(ldb, message->elements[i].values);
- }
- if (message->elements) ldb_free(ldb, message->elements);
-}
-
-
/*
unpack a ldb message from a linear buffer in TDB_DATA
- note that this does not fill in the class and key elements
-
- caller frees. Memory for the elements[] and values[] arrays are
- malloced, but the memory for the elements is re-used from the
- TDB_DATA data. This means the caller only has to free the elements
- and values arrays. This can be done with ltdb_unpack_data_free()
+ 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;
- char *p;
+ struct ldb_context *ldb;
+ uint8_t *p;
unsigned int remaining;
unsigned int i, j;
unsigned format;
size_t len;
+ ldb = ldb_module_get_ctx(module);
message->elements = NULL;
p = data->dptr;
break;
case LTDB_PACKING_FORMAT:
- len = strnlen(p, remaining);
+ len = strnlen((char *)p, remaining);
if (len == remaining) {
errno = EIO;
goto failed;
}
- message->dn = p;
+ message->dn = ldb_dn_new(message, ldb, (char *)p);
+ if (message->dn == NULL) {
+ errno = ENOMEM;
+ goto failed;
+ }
remaining -= len + 1;
p += len + 1;
break;
}
if (message->num_elements == 0) {
- message->elements = NULL;
return 0;
}
goto failed;
}
- message->elements = ldb_malloc_array_p(ldb, struct ldb_message_element,
- message->num_elements);
+ message->elements = talloc_array(message, struct ldb_message_element, message->num_elements);
if (!message->elements) {
errno = ENOMEM;
goto failed;
errno = EIO;
goto failed;
}
- len = strnlen(p, remaining-6);
+ len = strnlen((char *)p, remaining-6);
if (len == remaining-6) {
errno = EIO;
goto failed;
}
+ if (len == 0) {
+ errno = EIO;
+ goto failed;
+ }
message->elements[i].flags = 0;
- message->elements[i].name = p;
+ 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 = ldb_malloc_array_p(ldb,
- struct ldb_val,
- message->elements[i].num_values);
+ 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;
}
message->elements[i].values[j].length = len;
- message->elements[i].values[j].data = p+4;
+ 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);
+ "Error: %d bytes unread in ltdb_unpack_data", remaining);
}
return 0;
failed:
- ltdb_unpack_data_free(module, message);
-
+ talloc_free(message->elements);
return -1;
}