mirror of
https://github.com/samba-team/samba.git
synced 2025-07-31 20:22:15 +03:00
r4474: - converted ldb to use talloc internally
- added gcov flags to Makefile.ldb - expanded ldb test suite to get more coverage
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
98b5f73c1b
commit
0ab98f50a7
@ -10,24 +10,33 @@ LDB_LDAP_OBJ=ldb_ldap/ldb_ldap.o
|
||||
endif
|
||||
|
||||
TDBDIR=../tdb
|
||||
TALLOCDIR=../talloc
|
||||
|
||||
CFLAGS=-Wall -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -g -Iinclude -I. -I.. -I$(TDBDIR)/include -DUSE_MMAP=1 $(LDAP_FLAGS)
|
||||
LIB_FLAGS=-Llib -lldb $(LDAP_LIBS)
|
||||
CFLAGS1=-Wall -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith \
|
||||
-Wcast-qual -Wcast-align -Wwrite-strings -g -Iinclude -I. -I.. \
|
||||
-I$(TDBDIR)/include -I$(TALLOCDIR) -DUSE_MMAP=1 $(LDAP_FLAGS)
|
||||
#GCOV_FLAGS = -ftest-coverage -fprofile-arcs
|
||||
#GCOV_LIBS = -lgcov
|
||||
|
||||
CFLAGS = $(CFLAGS1) $(GCOV_FLAGS)
|
||||
|
||||
LIB_FLAGS=-Llib -lldb $(LDAP_LIBS) $(GCOV_LIBS)
|
||||
|
||||
TDB_OBJ=$(TDBDIR)/common/tdb.o $(TDBDIR)/common/spinlock.o
|
||||
TALLOC_OBJ=$(TALLOCDIR)/talloc.o
|
||||
|
||||
LDB_TDB_OBJ=ldb_tdb/ldb_match.o ldb_tdb/ldb_tdb.o \
|
||||
ldb_tdb/ldb_pack.o ldb_tdb/ldb_search.o ldb_tdb/ldb_index.o \
|
||||
ldb_tdb/ldb_cache.o
|
||||
|
||||
|
||||
COMMON_OBJ=common/ldb.o common/ldb_ldif.o common/util.o common/talloc.o \
|
||||
COMMON_OBJ=common/ldb.o common/ldb_ldif.o common/util.o \
|
||||
common/ldb_parse.o common/ldb_msg.o common/ldb_utf8.o \
|
||||
common/ldb_alloc.o common/ldb_debug.o common/ldb_modules.o
|
||||
common/ldb_debug.o common/ldb_modules.o
|
||||
|
||||
MODULES_OBJ=modules/timestamps.o
|
||||
|
||||
OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(LDB_LDAP_OBJ)
|
||||
OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(TALLOC_OBJ) $(LDB_LDAP_OBJ)
|
||||
|
||||
LDB_LIB = lib/libldb.a
|
||||
|
||||
@ -72,7 +81,7 @@ manpages:
|
||||
-man/build_manpages.sh
|
||||
|
||||
clean:
|
||||
rm -f */*.o *~ */*~ $(BINS) $(LDB_LIB) man/man?/*.[13]
|
||||
rm -f */*.o *.gcov */*.gc?? *~ */*~ $(BINS) $(TDB_OBJ) $(TALLOC_OBJ) $(LDB_LIB) man/man?/*.[13]
|
||||
|
||||
etags:
|
||||
etags */*.[ch]
|
||||
@ -86,3 +95,10 @@ test-ldap:
|
||||
tests/test-ldap.sh
|
||||
|
||||
test: test-tdb test-ldap
|
||||
|
||||
gcov:
|
||||
gcov -po ldb_ldap ldb_ldap/*.c 2| tee ldb_ldap.report.gcov
|
||||
gcov -po ldb_tdb ldb_tdb/*.c 2| tee ldb_tdb.report.gcov
|
||||
gcov -po common common/*.c 2| tee ldb_common.report.gcov
|
||||
gcov -po modules modules/*.c 2| tee ldb_modules.report.gcov
|
||||
gcov -po tools tools/*.c 2| tee ldb_tools.report.gcov
|
||||
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
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 alloc
|
||||
*
|
||||
* Description: functions for memory allocation
|
||||
*
|
||||
* Author: Andrew Tridgell
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "ldb/include/ldb.h"
|
||||
#include "ldb/include/ldb_private.h"
|
||||
|
||||
|
||||
/*
|
||||
this allows the user to choose their own allocation function
|
||||
*/
|
||||
int ldb_set_alloc(struct ldb_context *ldb,
|
||||
void *(*alloc)(const void *context, void *ptr, size_t size),
|
||||
void *context)
|
||||
{
|
||||
ldb->alloc_ops.alloc = alloc;
|
||||
ldb->alloc_ops.context = context;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
this is the default memory allocation function
|
||||
*/
|
||||
static void *ldb_default_alloc(const void *context, void *ptr, size_t size)
|
||||
{
|
||||
/* by setting LDB_ALLOC_OFS to non-zero the test suite can
|
||||
catch any places where we incorrectly use the libc alloc
|
||||
funcitons directly */
|
||||
#define LDB_ALLOC_OFS 4
|
||||
/* we don't assume a modern realloc function */
|
||||
if (ptr == NULL) {
|
||||
ptr = malloc(size+LDB_ALLOC_OFS);
|
||||
if (ptr) return ((char *)ptr)+LDB_ALLOC_OFS;
|
||||
return NULL;
|
||||
}
|
||||
if (size == 0) {
|
||||
free(((char *)ptr)-LDB_ALLOC_OFS);
|
||||
return NULL;
|
||||
}
|
||||
ptr = realloc(((char *)ptr)-LDB_ALLOC_OFS, size+LDB_ALLOC_OFS);
|
||||
if (ptr) {
|
||||
return ((char *)ptr)+LDB_ALLOC_OFS;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
all memory allocation goes via this function
|
||||
*/
|
||||
void *ldb_realloc(struct ldb_context *ldb, void *ptr, size_t size)
|
||||
{
|
||||
if (!ldb->alloc_ops.alloc) {
|
||||
ldb_set_alloc(ldb, ldb_default_alloc, NULL);
|
||||
}
|
||||
return ldb->alloc_ops.alloc(ldb->alloc_ops.context, ptr, size);
|
||||
}
|
||||
|
||||
void *ldb_malloc(struct ldb_context *ldb, size_t size)
|
||||
{
|
||||
return ldb_realloc(ldb, NULL, size);
|
||||
}
|
||||
|
||||
void ldb_free(struct ldb_context *ldb, void *ptr)
|
||||
{
|
||||
if (ptr != NULL) {
|
||||
ldb_realloc(ldb, ptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void *ldb_strndup(struct ldb_context *ldb, const char *str, size_t maxlen)
|
||||
{
|
||||
size_t len = strnlen(str, maxlen);
|
||||
void *ret;
|
||||
ret = ldb_realloc(ldb, NULL, len+1);
|
||||
if (ret) {
|
||||
memcpy(ret, str, len);
|
||||
((char *)ret)[len] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *ldb_strdup(struct ldb_context *ldb, const char *str)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
void *ret;
|
||||
ret = ldb_realloc(ldb, NULL, len+1);
|
||||
if (ret) {
|
||||
memcpy(ret, str, len+1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
a ldb wrapper for asprintf(), using ldb_malloc()
|
||||
*/
|
||||
int ldb_asprintf(struct ldb_context *ldb, char **strp, const char *fmt, ...)
|
||||
{
|
||||
int len, len2;
|
||||
va_list ap;
|
||||
|
||||
*strp = NULL;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(NULL, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
if (len < 0) {
|
||||
return len;
|
||||
}
|
||||
|
||||
*strp = ldb_malloc(ldb, len+1);
|
||||
if (! *strp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
len2 = vsnprintf(*strp, len+1, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (len2 != len) {
|
||||
/* buggy (or non-C99) vsnprintf function */
|
||||
ldb_free(ldb, *strp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
realloc an array, checking for integer overflow in the array size
|
||||
*/
|
||||
void *ldb_realloc_array(struct ldb_context *ldb,
|
||||
void *ptr, size_t el_size, unsigned count)
|
||||
{
|
||||
#define MAX_MALLOC_SIZE 0x7fffffff
|
||||
|
||||
if (count == 0 ||
|
||||
count >= MAX_MALLOC_SIZE/el_size) {
|
||||
return NULL;
|
||||
}
|
||||
if (!ptr) {
|
||||
return ldb_malloc(ldb, el_size * count);
|
||||
}
|
||||
return ldb_realloc(ldb, ptr, el_size * count);
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ char *ldb_base64_encode(struct ldb_context *ldb, const char *buf, int len)
|
||||
int bytes = (len*8 + 5)/6;
|
||||
char *out;
|
||||
|
||||
out = ldb_malloc(ldb, bytes+2);
|
||||
out = talloc_array_p(ldb, char, bytes+2);
|
||||
if (!out) return NULL;
|
||||
|
||||
for (i=0;i<bytes;i++) {
|
||||
@ -185,7 +185,7 @@ static int base64_encode_f(struct ldb_context *ldb,
|
||||
|
||||
ret = fold_string(fprintf_fn, private_data, b, strlen(b), start_pos);
|
||||
|
||||
ldb_free(ldb, b);
|
||||
talloc_free(b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -212,7 +212,7 @@ int ldb_ldif_write(struct ldb_context *ldb,
|
||||
int total=0, ret;
|
||||
const struct ldb_message *msg;
|
||||
|
||||
msg = &ldif->msg;
|
||||
msg = ldif->msg;
|
||||
|
||||
ret = fprintf_fn(private_data, "dn: %s\n", msg->dn);
|
||||
CHECK_RET;
|
||||
@ -305,9 +305,9 @@ static char *next_chunk(struct ldb_context *ldb,
|
||||
if (chunk_size+1 >= alloc_size) {
|
||||
char *c2;
|
||||
alloc_size += 1024;
|
||||
c2 = ldb_realloc_p(ldb, chunk, char, alloc_size);
|
||||
c2 = talloc_realloc_p(ldb, chunk, char, alloc_size);
|
||||
if (!c2) {
|
||||
ldb_free(ldb, chunk);
|
||||
talloc_free(chunk);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
@ -416,15 +416,7 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value)
|
||||
*/
|
||||
void ldb_ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif)
|
||||
{
|
||||
struct ldb_message *msg = &ldif->msg;
|
||||
unsigned int i;
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
if (msg->elements[i].name) ldb_free(ldb, msg->elements[i].name);
|
||||
if (msg->elements[i].values) ldb_free(ldb, msg->elements[i].values);
|
||||
}
|
||||
if (msg->elements) ldb_free(ldb, msg->elements);
|
||||
if (msg->private_data) ldb_free(ldb, msg->private_data);
|
||||
ldb_free(ldb, ldif);
|
||||
talloc_free(ldif);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -435,8 +427,8 @@ static int msg_add_empty(struct ldb_context *ldb,
|
||||
{
|
||||
struct ldb_message_element *el2, *el;
|
||||
|
||||
el2 = ldb_realloc_p(ldb, msg->elements,
|
||||
struct ldb_message_element, msg->num_elements+1);
|
||||
el2 = talloc_realloc_p(msg, msg->elements,
|
||||
struct ldb_message_element, msg->num_elements+1);
|
||||
if (!el2) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -446,7 +438,7 @@ static int msg_add_empty(struct ldb_context *ldb,
|
||||
|
||||
el = &msg->elements[msg->num_elements];
|
||||
|
||||
el->name = ldb_strdup(ldb, name);
|
||||
el->name = talloc_strdup(msg->elements, name);
|
||||
el->num_values = 0;
|
||||
el->values = NULL;
|
||||
el->flags = flags;
|
||||
@ -476,11 +468,17 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
|
||||
|
||||
value.data = NULL;
|
||||
|
||||
ldif = ldb_malloc_p(ldb, struct ldb_ldif);
|
||||
ldif = talloc_p(ldb, struct ldb_ldif);
|
||||
if (!ldif) return NULL;
|
||||
|
||||
ldif->msg = talloc_p(ldif, struct ldb_message);
|
||||
if (ldif->msg == NULL) {
|
||||
talloc_free(ldif);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ldif->changetype = LDB_CHANGETYPE_NONE;
|
||||
msg = &ldif->msg;
|
||||
msg = ldif->msg;
|
||||
|
||||
msg->dn = NULL;
|
||||
msg->elements = NULL;
|
||||
@ -558,8 +556,8 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
|
||||
flags == el->flags) {
|
||||
/* its a continuation */
|
||||
el->values =
|
||||
ldb_realloc_p(ldb, el->values,
|
||||
struct ldb_val, el->num_values+1);
|
||||
talloc_realloc_p(msg->elements, el->values,
|
||||
struct ldb_val, el->num_values+1);
|
||||
if (!el->values) {
|
||||
goto failed;
|
||||
}
|
||||
@ -567,16 +565,16 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
|
||||
el->num_values++;
|
||||
} else {
|
||||
/* its a new attribute */
|
||||
msg->elements = ldb_realloc_p(ldb, msg->elements,
|
||||
struct ldb_message_element,
|
||||
msg->num_elements+1);
|
||||
msg->elements = talloc_realloc_p(ldif, msg->elements,
|
||||
struct ldb_message_element,
|
||||
msg->num_elements+1);
|
||||
if (!msg->elements) {
|
||||
goto failed;
|
||||
}
|
||||
el = &msg->elements[msg->num_elements];
|
||||
el->flags = flags;
|
||||
el->name = ldb_strdup(ldb, attr);
|
||||
el->values = ldb_malloc_p(ldb, struct ldb_val);
|
||||
el->name = talloc_strdup(msg->elements, attr);
|
||||
el->values = talloc_p(msg->elements, struct ldb_val);
|
||||
if (!el->values || !el->name) {
|
||||
goto failed;
|
||||
}
|
||||
@ -589,7 +587,7 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
|
||||
return ldif;
|
||||
|
||||
failed:
|
||||
if (ldif) ldb_ldif_read_free(ldb, ldif);
|
||||
talloc_free(ldif);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -57,21 +57,19 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
|
||||
pn = 0;
|
||||
|
||||
if (options) {
|
||||
|
||||
for (i = 0; options[i] != NULL; i++) {
|
||||
|
||||
if (strncmp(options[i], LDB_MODULE_PREFIX, LDB_MODULE_PREFIX_LEN) == 0) {
|
||||
|
||||
p = q = ldb_strdup(ldb, &options[i][LDB_MODULE_PREFIX_LEN]);
|
||||
if (strncmp(options[i], LDB_MODULE_PREFIX,
|
||||
LDB_MODULE_PREFIX_LEN) == 0) {
|
||||
p = q = talloc_strdup(ldb, &options[i][LDB_MODULE_PREFIX_LEN]);
|
||||
if (*q != ':') {
|
||||
ldb_free(ldb, q);
|
||||
talloc_free(q);
|
||||
return -1;
|
||||
}
|
||||
do {
|
||||
*p = '\0';
|
||||
q = p + 1;
|
||||
pn++;
|
||||
modules = ldb_realloc_array(ldb, modules, sizeof(char *), pn);
|
||||
modules = talloc_realloc_p(ldb, modules, char *, pn);
|
||||
if (!modules) {
|
||||
ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n");
|
||||
return -1;
|
||||
@ -82,10 +80,12 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
|
||||
}
|
||||
}
|
||||
|
||||
if (!modules && strcmp("ldap", ldb->modules->ops->name)) { /* no modules in the options, look for @MODULES in the db (not for ldap) */
|
||||
if (!modules && strcmp("ldap", ldb->modules->ops->name)) {
|
||||
/* no modules in the options, look for @MODULES in the
|
||||
db (not for ldap) */
|
||||
int ret, j, k;
|
||||
const char * const attrs[] = { "@MODULE" , NULL};
|
||||
struct ldb_message **msg;
|
||||
struct ldb_message **msg = NULL;
|
||||
|
||||
ret = ldb_search(ldb, "", LDB_SCOPE_BASE, "dn=@MODULES", attrs, &msg);
|
||||
if (ret == 0) {
|
||||
@ -103,12 +103,12 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
|
||||
for (j = 0; j < msg[0]->num_elements; j++) {
|
||||
for (k = 0; k < msg[0]->elements[j].num_values; k++) {
|
||||
pn++;
|
||||
modules = ldb_realloc_array(ldb, modules, sizeof(char *), pn);
|
||||
modules = talloc_realloc_p(ldb, modules, char *, pn);
|
||||
if (!modules) {
|
||||
ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n");
|
||||
return -1;
|
||||
}
|
||||
modules[pn - 1] = ldb_strndup(ldb, msg[0]->elements[j].values[k].data, msg[0]->elements[j].values[k].length);
|
||||
modules[pn - 1] = talloc_strndup(modules, msg[0]->elements[j].values[k].data, msg[0]->elements[j].values[k].length);
|
||||
if (!modules[pn - 1]) {
|
||||
ldb_debug(ldb, LDB_DEBUG_FATAL, "Out of Memory in register_modules()\n");
|
||||
return -1;
|
||||
@ -116,13 +116,11 @@ int ldb_load_modules(struct ldb_context *ldb, const char *options[])
|
||||
}
|
||||
}
|
||||
}
|
||||
ldb_search_free(ldb, msg);
|
||||
talloc_free(msg);
|
||||
}
|
||||
|
||||
if (modules) {
|
||||
|
||||
for (i = 0; i < pn; i++) {
|
||||
|
||||
if (strcmp(modules[i], "timestamps") == 0) {
|
||||
current = timestamps_module_init(ldb, options);
|
||||
if (!current) {
|
||||
@ -274,10 +272,3 @@ const char *ldb_next_errstring(struct ldb_module *module)
|
||||
return module->next->ops->errstring(module->next);
|
||||
}
|
||||
|
||||
void ldb_next_cache_free(struct ldb_module *module)
|
||||
{
|
||||
if (!module->next) {
|
||||
return;
|
||||
}
|
||||
module->next->ops->cache_free(module->next);
|
||||
}
|
||||
|
@ -36,6 +36,13 @@
|
||||
#include "ldb/include/ldb.h"
|
||||
#include "ldb/include/ldb_private.h"
|
||||
|
||||
/*
|
||||
create a new ldb_message in a given memory context (NULL for top level)
|
||||
*/
|
||||
struct ldb_message *ldb_msg_new(void *mem_ctx)
|
||||
{
|
||||
return talloc_zero_p(mem_ctx, struct ldb_message);
|
||||
}
|
||||
|
||||
/*
|
||||
find an element in a message by attribute name
|
||||
@ -88,7 +95,7 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el,
|
||||
/*
|
||||
duplicate a ldb_val structure
|
||||
*/
|
||||
struct ldb_val ldb_val_dup(struct ldb_context *ldb,
|
||||
struct ldb_val ldb_val_dup(TALLOC_CTX *mem_ctx,
|
||||
const struct ldb_val *v)
|
||||
{
|
||||
struct ldb_val v2;
|
||||
@ -100,7 +107,7 @@ struct ldb_val ldb_val_dup(struct ldb_context *ldb,
|
||||
|
||||
/* the +1 is to cope with buggy C library routines like strndup
|
||||
that look one byte beyond */
|
||||
v2.data = ldb_malloc(ldb, v->length+1);
|
||||
v2.data = talloc_array_p(mem_ctx, char, v->length+1);
|
||||
if (!v2.data) {
|
||||
v2.length = 0;
|
||||
return v2;
|
||||
@ -119,8 +126,8 @@ int ldb_msg_add_empty(struct ldb_context *ldb,
|
||||
{
|
||||
struct ldb_message_element *els;
|
||||
|
||||
els = ldb_realloc_p(ldb, msg->elements,
|
||||
struct ldb_message_element, msg->num_elements+1);
|
||||
els = talloc_realloc_p(msg, msg->elements,
|
||||
struct ldb_message_element, msg->num_elements+1);
|
||||
if (!els) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -129,7 +136,7 @@ int ldb_msg_add_empty(struct ldb_context *ldb,
|
||||
els[msg->num_elements].values = NULL;
|
||||
els[msg->num_elements].num_values = 0;
|
||||
els[msg->num_elements].flags = flags;
|
||||
els[msg->num_elements].name = ldb_strdup(ldb, attr_name);
|
||||
els[msg->num_elements].name = talloc_strdup(els, attr_name);
|
||||
if (!els[msg->num_elements].name) {
|
||||
return -1;
|
||||
}
|
||||
@ -178,7 +185,7 @@ int ldb_msg_add_value(struct ldb_context *ldb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
vals = ldb_realloc_p(ldb, el->values, struct ldb_val, el->num_values+1);
|
||||
vals = talloc_realloc_p(msg, el->values, struct ldb_val, el->num_values+1);
|
||||
if (!vals) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -332,19 +339,7 @@ void ldb_msg_sort_elements(struct ldb_message *msg)
|
||||
*/
|
||||
void ldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
struct ldb_message_element *el = &msg->elements[i];
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
ldb_free(ldb, el->values[j].data);
|
||||
}
|
||||
if (el->values) ldb_free(ldb, el->values);
|
||||
ldb_free(ldb, el->name);
|
||||
}
|
||||
if (msg->elements) ldb_free(ldb, msg->elements);
|
||||
ldb_free(ldb, msg->dn);
|
||||
ldb_free(ldb, msg);
|
||||
talloc_free(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -356,17 +351,17 @@ struct ldb_message *ldb_msg_copy(struct ldb_context *ldb,
|
||||
struct ldb_message *msg2;
|
||||
int i, j;
|
||||
|
||||
msg2 = ldb_malloc_p(ldb, struct ldb_message);
|
||||
msg2 = talloc_p(ldb, struct ldb_message);
|
||||
if (msg2 == NULL) return NULL;
|
||||
|
||||
msg2->elements = NULL;
|
||||
msg2->num_elements = 0;
|
||||
msg2->private_data = NULL;
|
||||
|
||||
msg2->dn = ldb_strdup(ldb, msg->dn);
|
||||
msg2->dn = talloc_strdup(msg2, msg->dn);
|
||||
if (msg2->dn == NULL) goto failed;
|
||||
|
||||
msg2->elements = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
|
||||
msg2->elements = talloc_array_p(msg2, struct ldb_message_element, msg->num_elements);
|
||||
if (msg2->elements == NULL) goto failed;
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
@ -376,15 +371,16 @@ struct ldb_message *ldb_msg_copy(struct ldb_context *ldb,
|
||||
el2->flags = el1->flags;
|
||||
el2->num_values = 0;
|
||||
el2->values = NULL;
|
||||
el2->name = ldb_strdup(ldb, el1->name);
|
||||
el2->name = talloc_strdup(msg2->elements, el1->name);
|
||||
if (el2->name == NULL) goto failed;
|
||||
el2->values = ldb_malloc_array_p(ldb, struct ldb_val, el1->num_values);
|
||||
el2->values = talloc_array_p(msg2->elements, struct ldb_val, el1->num_values);
|
||||
for (j=0;j<el1->num_values;j++) {
|
||||
el2->values[j] = ldb_val_dup(ldb, &el1->values[j]);
|
||||
if (el2->values[j].data == NULL &&
|
||||
el1->values[j].length != 0) {
|
||||
goto failed;
|
||||
}
|
||||
el2->values[j].data = talloc_steal(el2->values, el2->values[j].data);
|
||||
el2->num_values++;
|
||||
}
|
||||
|
||||
@ -394,7 +390,7 @@ struct ldb_message *ldb_msg_copy(struct ldb_context *ldb,
|
||||
return msg2;
|
||||
|
||||
failed:
|
||||
ldb_msg_free(ldb, msg2);
|
||||
talloc_free(msg2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -417,8 +413,8 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
|
||||
struct ldb_message_element *el1 = &msg2->elements[i-1];
|
||||
struct ldb_message_element *el2 = &msg2->elements[i];
|
||||
if (ldb_msg_element_compare_name(el1, el2) == 0) {
|
||||
el1->values = ldb_realloc_p(ldb, el1->values, struct ldb_val,
|
||||
el1->num_values + el2->num_values);
|
||||
el1->values = talloc_realloc_p(msg2->elements, el1->values, struct ldb_val,
|
||||
el1->num_values + el2->num_values);
|
||||
if (el1->values == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -426,8 +422,8 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
|
||||
el2->values,
|
||||
sizeof(struct ldb_val) * el2->num_values);
|
||||
el1->num_values += el2->num_values;
|
||||
ldb_free(ldb, el2->name);
|
||||
ldb_free(ldb, el2->values);
|
||||
talloc_free(el2->name);
|
||||
talloc_free(el2->values);
|
||||
if (i+1<msg2->num_elements) {
|
||||
memmove(el2, el2+1, sizeof(struct ldb_message_element) *
|
||||
(msg2->num_elements - (i+1)));
|
||||
|
@ -65,7 +65,7 @@ a filter is defined by:
|
||||
/*
|
||||
return next token element. Caller frees
|
||||
*/
|
||||
static char *ldb_parse_lex(struct ldb_context *ldb, const char **s, const char *sep)
|
||||
static char *ldb_parse_lex(TALLOC_CTX *ctx, const char **s, const char *sep)
|
||||
{
|
||||
const char *p = *s;
|
||||
char *ret;
|
||||
@ -81,7 +81,7 @@ static char *ldb_parse_lex(struct ldb_context *ldb, const char **s, const char *
|
||||
|
||||
if (strchr(sep, *p)) {
|
||||
(*s) = p+1;
|
||||
ret = ldb_strndup(ldb, p, 1);
|
||||
ret = talloc_strndup(ctx, p, 1);
|
||||
if (!ret) {
|
||||
errno = ENOMEM;
|
||||
}
|
||||
@ -96,7 +96,7 @@ static char *ldb_parse_lex(struct ldb_context *ldb, const char **s, const char *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = ldb_strndup(ldb, *s, p - *s);
|
||||
ret = talloc_strndup(ctx, *s, p - *s);
|
||||
if (!ret) {
|
||||
errno = ENOMEM;
|
||||
}
|
||||
@ -128,47 +128,46 @@ static const char *match_brace(const char *s)
|
||||
}
|
||||
|
||||
|
||||
static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s);
|
||||
static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s);
|
||||
|
||||
/*
|
||||
<simple> ::= <attributetype> <filtertype> <attributevalue>
|
||||
*/
|
||||
static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const char *s)
|
||||
static struct ldb_parse_tree *ldb_parse_simple(TALLOC_CTX *ctx, const char *s)
|
||||
{
|
||||
char *eq, *val, *l;
|
||||
struct ldb_parse_tree *ret;
|
||||
|
||||
l = ldb_parse_lex(ldb, &s, LDB_ALL_SEP);
|
||||
if (!l) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strchr("()&|=", *l)) {
|
||||
ldb_free(ldb, l);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eq = ldb_parse_lex(ldb, &s, LDB_ALL_SEP);
|
||||
if (!eq || strcmp(eq, "=") != 0) {
|
||||
ldb_free(ldb, l);
|
||||
if (eq) ldb_free(ldb, eq);
|
||||
return NULL;
|
||||
}
|
||||
ldb_free(ldb, eq);
|
||||
|
||||
val = ldb_parse_lex(ldb, &s, ")");
|
||||
if (val && strchr("()&|", *val)) {
|
||||
ldb_free(ldb, l);
|
||||
if (val) ldb_free(ldb, val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = ldb_malloc_p(ldb, struct ldb_parse_tree);
|
||||
ret = talloc_p(ctx, struct ldb_parse_tree);
|
||||
if (!ret) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
l = ldb_parse_lex(ret, &s, LDB_ALL_SEP);
|
||||
if (!l) {
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strchr("()&|=", *l)) {
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eq = ldb_parse_lex(ret, &s, LDB_ALL_SEP);
|
||||
if (!eq || strcmp(eq, "=") != 0) {
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
talloc_free(eq);
|
||||
|
||||
val = ldb_parse_lex(ret, &s, ")");
|
||||
if (val && strchr("()&|", *val)) {
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->operation = LDB_OP_SIMPLE;
|
||||
ret->u.simple.attr = l;
|
||||
ret->u.simple.value.data = val;
|
||||
@ -184,12 +183,12 @@ static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const ch
|
||||
<or> ::= '|' <filterlist>
|
||||
<filterlist> ::= <filter> | <filter> <filterlist>
|
||||
*/
|
||||
static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb,
|
||||
static struct ldb_parse_tree *ldb_parse_filterlist(TALLOC_CTX *ctx,
|
||||
enum ldb_parse_op op, const char *s)
|
||||
{
|
||||
struct ldb_parse_tree *ret, *next;
|
||||
|
||||
ret = ldb_malloc_p(ldb, struct ldb_parse_tree);
|
||||
ret = talloc_p(ctx, struct ldb_parse_tree);
|
||||
if (!ret) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
@ -197,31 +196,29 @@ static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb,
|
||||
|
||||
ret->operation = op;
|
||||
ret->u.list.num_elements = 1;
|
||||
ret->u.list.elements = ldb_malloc_p(ldb, struct ldb_parse_tree *);
|
||||
ret->u.list.elements = talloc_p(ret, struct ldb_parse_tree *);
|
||||
if (!ret->u.list.elements) {
|
||||
errno = ENOMEM;
|
||||
ldb_free(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->u.list.elements[0] = ldb_parse_filter(ldb, &s);
|
||||
ret->u.list.elements[0] = ldb_parse_filter(ret->u.list.elements, &s);
|
||||
if (!ret->u.list.elements[0]) {
|
||||
ldb_free(ldb, ret->u.list.elements);
|
||||
ldb_free(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (isspace(*s)) s++;
|
||||
|
||||
while (*s && (next = ldb_parse_filter(ldb, &s))) {
|
||||
while (*s && (next = ldb_parse_filter(ret->u.list.elements, &s))) {
|
||||
struct ldb_parse_tree **e;
|
||||
e = ldb_realloc_p(ldb, ret->u.list.elements,
|
||||
struct ldb_parse_tree *,
|
||||
ret->u.list.num_elements+1);
|
||||
e = talloc_realloc_p(ret, ret->u.list.elements,
|
||||
struct ldb_parse_tree *,
|
||||
ret->u.list.num_elements+1);
|
||||
if (!e) {
|
||||
errno = ENOMEM;
|
||||
ldb_parse_tree_free(ldb, next);
|
||||
ldb_parse_tree_free(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->u.list.elements = e;
|
||||
@ -237,20 +234,20 @@ static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb,
|
||||
/*
|
||||
<not> ::= '!' <filter>
|
||||
*/
|
||||
static struct ldb_parse_tree *ldb_parse_not(struct ldb_context *ldb, const char *s)
|
||||
static struct ldb_parse_tree *ldb_parse_not(TALLOC_CTX *ctx, const char *s)
|
||||
{
|
||||
struct ldb_parse_tree *ret;
|
||||
|
||||
ret = ldb_malloc_p(ldb, struct ldb_parse_tree);
|
||||
ret = talloc_p(ctx, struct ldb_parse_tree);
|
||||
if (!ret) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->operation = LDB_OP_NOT;
|
||||
ret->u.not.child = ldb_parse_filter(ldb, &s);
|
||||
ret->u.not.child = ldb_parse_filter(ret, &s);
|
||||
if (!ret->u.not.child) {
|
||||
ldb_free(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -261,49 +258,48 @@ static struct ldb_parse_tree *ldb_parse_not(struct ldb_context *ldb, const char
|
||||
parse a filtercomp
|
||||
<filtercomp> ::= <and> | <or> | <not> | <simple>
|
||||
*/
|
||||
static struct ldb_parse_tree *ldb_parse_filtercomp(struct ldb_context *ldb,
|
||||
const char *s)
|
||||
static struct ldb_parse_tree *ldb_parse_filtercomp(TALLOC_CTX *ctx, const char *s)
|
||||
{
|
||||
while (isspace(*s)) s++;
|
||||
|
||||
switch (*s) {
|
||||
case '&':
|
||||
return ldb_parse_filterlist(ldb, LDB_OP_AND, s+1);
|
||||
return ldb_parse_filterlist(ctx, LDB_OP_AND, s+1);
|
||||
|
||||
case '|':
|
||||
return ldb_parse_filterlist(ldb, LDB_OP_OR, s+1);
|
||||
return ldb_parse_filterlist(ctx, LDB_OP_OR, s+1);
|
||||
|
||||
case '!':
|
||||
return ldb_parse_not(ldb, s+1);
|
||||
return ldb_parse_not(ctx, s+1);
|
||||
|
||||
case '(':
|
||||
case ')':
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ldb_parse_simple(ldb, s);
|
||||
return ldb_parse_simple(ctx, s);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
<filter> ::= '(' <filtercomp> ')'
|
||||
*/
|
||||
static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s)
|
||||
static struct ldb_parse_tree *ldb_parse_filter(TALLOC_CTX *ctx, const char **s)
|
||||
{
|
||||
char *l, *s2;
|
||||
const char *p, *p2;
|
||||
struct ldb_parse_tree *ret;
|
||||
|
||||
l = ldb_parse_lex(ldb, s, LDB_ALL_SEP);
|
||||
l = ldb_parse_lex(ctx, s, LDB_ALL_SEP);
|
||||
if (!l) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strcmp(l, "(") != 0) {
|
||||
ldb_free(ldb, l);
|
||||
talloc_free(l);
|
||||
return NULL;
|
||||
}
|
||||
ldb_free(ldb, l);
|
||||
talloc_free(l);
|
||||
|
||||
p = match_brace(*s);
|
||||
if (!p) {
|
||||
@ -311,14 +307,14 @@ static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const ch
|
||||
}
|
||||
p2 = p + 1;
|
||||
|
||||
s2 = ldb_strndup(ldb, *s, p - *s);
|
||||
s2 = talloc_strndup(ctx, *s, p - *s);
|
||||
if (!s2) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = ldb_parse_filtercomp(ldb, s2);
|
||||
ldb_free(ldb, s2);
|
||||
ret = ldb_parse_filtercomp(ctx, s2);
|
||||
talloc_free(s2);
|
||||
|
||||
*s = p2;
|
||||
|
||||
@ -347,27 +343,6 @@ struct ldb_parse_tree *ldb_parse_tree(struct ldb_context *ldb, const char *s)
|
||||
*/
|
||||
void ldb_parse_tree_free(struct ldb_context *ldb, struct ldb_parse_tree *tree)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
switch (tree->operation) {
|
||||
case LDB_OP_SIMPLE:
|
||||
ldb_free(ldb, tree->u.simple.attr);
|
||||
if (tree->u.simple.value.data) ldb_free(ldb, tree->u.simple.value.data);
|
||||
break;
|
||||
|
||||
case LDB_OP_AND:
|
||||
case LDB_OP_OR:
|
||||
for (i=0;i<tree->u.list.num_elements;i++) {
|
||||
ldb_parse_tree_free(ldb, tree->u.list.elements[i]);
|
||||
}
|
||||
if (tree->u.list.elements) ldb_free(ldb, tree->u.list.elements);
|
||||
break;
|
||||
|
||||
case LDB_OP_NOT:
|
||||
ldb_parse_tree_free(ldb, tree->u.not.child);
|
||||
break;
|
||||
}
|
||||
|
||||
ldb_free(ldb, tree);
|
||||
talloc_free(tree);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
char *ldb_casefold(struct ldb_context *ldb, const char *s)
|
||||
{
|
||||
int i;
|
||||
char *ret = ldb_strdup(ldb, s);
|
||||
char *ret = talloc_strdup(ldb, s);
|
||||
if (!s) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
|
@ -48,11 +48,10 @@ ADD_OBJ_FILES = \
|
||||
lib/ldb/common/ldb_msg.o \
|
||||
lib/ldb/common/util.o \
|
||||
lib/ldb/common/ldb_utf8.o \
|
||||
lib/ldb/common/ldb_alloc.o \
|
||||
lib/ldb/common/ldb_debug.o \
|
||||
lib/ldb/common/ldb_modules.o
|
||||
REQUIRED_SUBSYSTEMS = \
|
||||
LIBREPLACE
|
||||
LIBREPLACE LIBTALLOC
|
||||
NOPROTO = YES
|
||||
#
|
||||
# End SUBSYSTEM LIBLDB
|
||||
|
@ -18,15 +18,15 @@
|
||||
#include <fnmatch.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ldb.h"
|
||||
#include "ldb_private.h"
|
||||
#include "talloc.h"
|
||||
|
||||
#ifdef HAVE_INTPTR_T
|
||||
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
|
||||
#define discard_const(ptr) ((void *)((intptr_t)(ptr)))
|
||||
#else
|
||||
#define discard_const(ptr) ((void *)(ptr))
|
||||
#endif
|
||||
#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
|
||||
|
||||
|
||||
|
@ -105,7 +105,7 @@ enum ldb_changetype {
|
||||
*/
|
||||
struct ldb_ldif {
|
||||
enum ldb_changetype changetype;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
};
|
||||
|
||||
enum ldb_scope {LDB_SCOPE_DEFAULT=-1,
|
||||
@ -123,16 +123,6 @@ typedef int (*ldb_traverse_fn)(struct ldb_context *, const struct ldb_message *)
|
||||
|
||||
struct ldb_module;
|
||||
|
||||
/*
|
||||
the user can optionally supply a allocator function. It is presumed
|
||||
it will act like a modern realloc(), with a context ptr to allow
|
||||
for pool allocators
|
||||
*/
|
||||
struct ldb_alloc_ops {
|
||||
void *(*alloc)(const void *context, void *ptr, size_t size);
|
||||
void *context;
|
||||
};
|
||||
|
||||
/* debugging uses one of the following levels */
|
||||
enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR,
|
||||
LDB_DEBUG_WARNING, LDB_DEBUG_TRACE};
|
||||
@ -240,6 +230,9 @@ int ldb_ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif
|
||||
int ldb_dn_cmp(const char *dn1, const char *dn2);
|
||||
int ldb_attr_cmp(const char *dn1, const char *dn2);
|
||||
|
||||
/* create an empty message */
|
||||
struct ldb_message *ldb_msg_new(void *mem_ctx);
|
||||
|
||||
/* find an element within an message */
|
||||
struct ldb_message_element *ldb_msg_find_element(const struct ldb_message *msg,
|
||||
const char *attr_name);
|
||||
@ -305,40 +298,11 @@ struct ldb_message *ldb_msg_canonicalize(struct ldb_context *ldb,
|
||||
const struct ldb_message *msg);
|
||||
|
||||
|
||||
struct ldb_val ldb_val_dup(struct ldb_context *ldb,
|
||||
const struct ldb_val *v);
|
||||
|
||||
/*
|
||||
this allows the user to choose their own allocation function
|
||||
the allocation function should behave like a modern realloc()
|
||||
function, which means that:
|
||||
malloc(size) == alloc(context, NULL, size)
|
||||
free(ptr) == alloc(context, ptr, 0)
|
||||
realloc(ptr, size) == alloc(context, ptr, size)
|
||||
The context argument is provided to allow for pool based allocators,
|
||||
which often take a context argument
|
||||
*/
|
||||
int ldb_set_alloc(struct ldb_context *ldb,
|
||||
void *(*alloc)(const void *context, void *ptr, size_t size),
|
||||
void *context);
|
||||
|
||||
/* these are used as type safe versions of the ldb allocation functions */
|
||||
#define ldb_malloc_p(ldb, type) (type *)ldb_malloc(ldb, sizeof(type))
|
||||
#define ldb_malloc_array_p(ldb, type, count) (type *)ldb_realloc_array(ldb, NULL, sizeof(type), count)
|
||||
#define ldb_realloc_p(ldb, p, type, count) (type *)ldb_realloc_array(ldb, p, sizeof(type), count)
|
||||
|
||||
void *ldb_realloc(struct ldb_context *ldb, void *ptr, size_t size);
|
||||
void *ldb_malloc(struct ldb_context *ldb, size_t size);
|
||||
void ldb_free(struct ldb_context *ldb, void *ptr);
|
||||
void *ldb_strndup(struct ldb_context *ldb, const char *str, size_t maxlen);
|
||||
void *ldb_strdup(struct ldb_context *ldb, const char *str);
|
||||
void *ldb_realloc_array(struct ldb_context *ldb,
|
||||
void *ptr, size_t el_size, unsigned count);
|
||||
struct ldb_val ldb_val_dup(void *mem_ctx, const struct ldb_val *v);
|
||||
|
||||
#ifndef PRINTF_ATTRIBUTE
|
||||
#define PRINTF_ATTRIBUTE(a,b)
|
||||
#endif
|
||||
int ldb_asprintf(struct ldb_context *ldb, char **strp, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
|
||||
|
||||
/*
|
||||
this allows the user to set a debug function for error reporting
|
||||
|
@ -66,10 +66,6 @@ struct ldb_module_ops {
|
||||
int (*named_lock)(struct ldb_module *, const char *);
|
||||
int (*named_unlock)(struct ldb_module *, const char *);
|
||||
const char * (*errstring)(struct ldb_module *);
|
||||
|
||||
/* this is called when the alloc ops changes to ensure we
|
||||
don't have any old allocated data in the context */
|
||||
void (*cache_free)(struct ldb_module *);
|
||||
};
|
||||
|
||||
/* the modules init function */
|
||||
@ -82,10 +78,7 @@ struct ldb_context {
|
||||
/* the operations provided by the backend */
|
||||
struct ldb_module *modules;
|
||||
|
||||
/* memory allocation info */
|
||||
struct ldb_alloc_ops alloc_ops;
|
||||
|
||||
/* memory allocation info */
|
||||
/* debugging operations */
|
||||
struct ldb_debug_ops debug_ops;
|
||||
};
|
||||
|
||||
@ -106,7 +99,6 @@ int ldb_next_rename_record(struct ldb_module *module, const char *olddn, const c
|
||||
int ldb_next_named_lock(struct ldb_module *module, const char *lockname);
|
||||
int ldb_next_named_unlock(struct ldb_module *module, const char *lockname);
|
||||
const char *ldb_next_errstring(struct ldb_module *module);
|
||||
void ldb_next_cache_free(struct ldb_module *module);
|
||||
|
||||
/* The following definitions come from lib/ldb/common/util.c */
|
||||
int ldb_list_find(const void *needle,
|
||||
|
@ -1,96 +0,0 @@
|
||||
#ifndef _TALLOC_H_
|
||||
#define _TALLOC_H_
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Samba temporary memory allocation functions
|
||||
|
||||
Copyright (C) Andrew Tridgell 2004
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* this is only needed for compatibility with the old talloc */
|
||||
typedef void TALLOC_CTX;
|
||||
|
||||
/*
|
||||
this uses a little trick to allow __LINE__ to be stringified
|
||||
*/
|
||||
#define _STRING_LINE_(s) #s
|
||||
#define _STRING_LINE2_(s) _STRING_LINE_(s)
|
||||
#define __LINESTR__ _STRING_LINE2_(__LINE__)
|
||||
#define __location__ __FILE__ ":" __LINESTR__
|
||||
|
||||
/* useful macros for creating type checked pointers */
|
||||
#define talloc(ctx, size) talloc_named_const(ctx, size, __location__)
|
||||
#define talloc_zero(ctx, size) _talloc_zero(ctx, size, __location__)
|
||||
#define talloc_realloc(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
|
||||
#define talloc_p(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
|
||||
#define talloc_zero_p(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
|
||||
#define talloc_zero_array_p(ctx, type, count) (type *)talloc_zero_array(ctx, sizeof(type), count, __location__)
|
||||
#define talloc_array_p(ctx, type, count) (type *)talloc_array(ctx, sizeof(type), count, __location__)
|
||||
#define talloc_realloc_p(ctx, p, type, count) (type *)talloc_realloc_array(ctx, p, sizeof(type), count, __location__)
|
||||
#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
|
||||
|
||||
#define talloc_destroy(ctx) talloc_free(ctx)
|
||||
|
||||
#define malloc_p(type) (type *)malloc(sizeof(type))
|
||||
#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count)
|
||||
#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count)
|
||||
|
||||
#define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB: "__location__)
|
||||
#define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, size, "DATA_BLOB: "__location__)
|
||||
|
||||
#ifndef PRINTF_ATTRIBUTE
|
||||
#define PRINTF_ATTRIBUTE(a1, a2)
|
||||
#endif
|
||||
|
||||
|
||||
/* The following definitions come from lib/talloc.c */
|
||||
void *_talloc(const void *context, size_t size);
|
||||
void talloc_set_destructor(const void *ptr, int (*destructor)(void *));
|
||||
void talloc_increase_ref_count(const void *ptr);
|
||||
void *talloc_reference(const void *context, const void *ptr);
|
||||
int talloc_unlink(const void *context, void *ptr);
|
||||
void talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
|
||||
void talloc_set_name_const(const void *ptr, const char *name);
|
||||
void *talloc_named(const void *context, size_t size,
|
||||
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
|
||||
void *talloc_named_const(const void *context, size_t size, const char *name);
|
||||
const char *talloc_get_name(const void *ptr);
|
||||
void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
|
||||
int talloc_free(void *ptr);
|
||||
void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
|
||||
void *talloc_steal(const void *new_ctx, const void *ptr);
|
||||
off_t talloc_total_size(const void *ptr);
|
||||
off_t talloc_total_blocks(const void *ptr);
|
||||
void talloc_report_full(const void *ptr, FILE *f);
|
||||
void talloc_report(const void *ptr, FILE *f);
|
||||
void talloc_enable_leak_report(void);
|
||||
void talloc_enable_leak_report_full(void);
|
||||
void *_talloc_zero(const void *ctx, size_t size, const char *name);
|
||||
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
|
||||
char *talloc_strdup(const void *t, const char *p);
|
||||
char *talloc_strndup(const void *t, const char *p, size_t n);
|
||||
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
|
||||
char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
|
||||
char *talloc_asprintf_append(char *s,
|
||||
const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
|
||||
void *talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
|
||||
void *talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
|
||||
void *talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
|
||||
void *talloc_ldb_alloc(void *context, void *ptr, size_t size);
|
||||
|
||||
#endif
|
||||
|
@ -72,26 +72,9 @@ static const char *lldb_option_find(const struct lldb_private *lldb, const char
|
||||
*/
|
||||
static int lldb_close(struct ldb_module *module)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct lldb_private *lldb = module->private_data;
|
||||
|
||||
if (ldap_unbind(lldb->ldap) != LDAP_SUCCESS) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
ldb_set_alloc(ldb, NULL, NULL);
|
||||
|
||||
if (lldb->options) {
|
||||
for (i=0;lldb->options[i];i++) {
|
||||
ldb_free(ldb, lldb->options[i]);
|
||||
}
|
||||
ldb_free(ldb, lldb->options);
|
||||
}
|
||||
ldb_free(ldb, lldb);
|
||||
free(ldb);
|
||||
|
||||
return ret;
|
||||
talloc_free(ldb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -99,18 +82,18 @@ static int lldb_close(struct ldb_module *module)
|
||||
*/
|
||||
static int lldb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct lldb_private *lldb = module->private_data;
|
||||
int ret = 0;
|
||||
char *newrdn, *p;
|
||||
const char *parentdn = "";
|
||||
TALLOC_CTX *mem_ctx = talloc(lldb, 0);
|
||||
|
||||
/* ignore ltdb specials */
|
||||
if (olddn[0] == '@' ||newdn[0] == '@') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
newrdn = ldb_strdup(ldb, newdn);
|
||||
newrdn = talloc_strdup(mem_ctx, newdn);
|
||||
if (!newrdn) {
|
||||
return -1;
|
||||
}
|
||||
@ -122,11 +105,12 @@ static int lldb_rename(struct ldb_module *module, const char *olddn, const char
|
||||
}
|
||||
|
||||
lldb->last_rc = ldap_rename_s(lldb->ldap, olddn, newrdn, parentdn, 1, NULL, NULL);
|
||||
ldb_free(ldb, newrdn);
|
||||
if (lldb->last_rc != LDAP_SUCCESS) {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -151,40 +135,12 @@ static int lldb_delete(struct ldb_module *module, const char *dn)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
free a search message
|
||||
*/
|
||||
static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
|
||||
{
|
||||
unsigned int i, j;
|
||||
ldb_free(ldb, msg->dn);
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
ldb_free(ldb, msg->elements[i].name);
|
||||
for (j=0;j<msg->elements[i].num_values;j++) {
|
||||
if (msg->elements[i].values[j].data) {
|
||||
ldb_free(ldb, msg->elements[i].values[j].data);
|
||||
}
|
||||
}
|
||||
ldb_free(ldb, msg->elements[i].values);
|
||||
}
|
||||
if (msg->elements) ldb_free(ldb, msg->elements);
|
||||
ldb_free(ldb, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
free a search result
|
||||
*/
|
||||
static int lldb_search_free(struct ldb_module *module, struct ldb_message **res)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
int i;
|
||||
for (i=0;res[i];i++) {
|
||||
if (lldb_msg_free(ldb, res[i]) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ldb_free(ldb, res);
|
||||
talloc_free(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -205,8 +161,8 @@ static int lldb_add_msg_attr(struct ldb_context *ldb,
|
||||
return -1;
|
||||
}
|
||||
|
||||
el = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
|
||||
msg->num_elements + 1);
|
||||
el = talloc_realloc_p(msg, msg->elements, struct ldb_message_element,
|
||||
msg->num_elements + 1);
|
||||
if (!el) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -216,7 +172,7 @@ static int lldb_add_msg_attr(struct ldb_context *ldb,
|
||||
|
||||
el = &msg->elements[msg->num_elements];
|
||||
|
||||
el->name = ldb_strdup(ldb, attr);
|
||||
el->name = talloc_strdup(msg->elements, attr);
|
||||
if (!el->name) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -224,18 +180,17 @@ static int lldb_add_msg_attr(struct ldb_context *ldb,
|
||||
el->flags = 0;
|
||||
|
||||
el->num_values = 0;
|
||||
el->values = ldb_malloc_array_p(ldb, struct ldb_val, count);
|
||||
el->values = talloc_array_p(msg->elements, struct ldb_val, count);
|
||||
if (!el->values) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
el->values[i].data = ldb_malloc(ldb, bval[i]->bv_len);
|
||||
el->values[i].data = talloc_memdup(el->values, bval[i]->bv_val, bval[i]->bv_len);
|
||||
if (!el->values[i].data) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(el->values[i].data, bval[i]->bv_val, bval[i]->bv_len);
|
||||
el->values[i].length = bval[i]->bv_len;
|
||||
el->num_values++;
|
||||
}
|
||||
@ -275,7 +230,7 @@ static int lldb_search(struct ldb_module *module, const char *base,
|
||||
return count;
|
||||
}
|
||||
|
||||
(*res) = ldb_malloc_array_p(ldb, struct ldb_message *, count+1);
|
||||
(*res) = talloc_array_p(lldb, struct ldb_message *, count+1);
|
||||
if (! *res) {
|
||||
ldap_msgfree(ldapres);
|
||||
errno = ENOMEM;
|
||||
@ -299,7 +254,7 @@ static int lldb_search(struct ldb_module *module, const char *base,
|
||||
break;
|
||||
}
|
||||
|
||||
(*res)[msg_count] = ldb_malloc_p(ldb, struct ldb_message);
|
||||
(*res)[msg_count] = talloc_p(*res, struct ldb_message);
|
||||
if (!(*res)[msg_count]) {
|
||||
goto failed;
|
||||
}
|
||||
@ -310,7 +265,7 @@ static int lldb_search(struct ldb_module *module, const char *base,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
(*res)[msg_count]->dn = ldb_strdup(ldb, dn);
|
||||
(*res)[msg_count]->dn = talloc_strdup((*res)[msg_count], dn);
|
||||
ldap_memfree(dn);
|
||||
if (!(*res)[msg_count]->dn) {
|
||||
goto failed;
|
||||
@ -350,28 +305,6 @@ failed:
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
free a set of mods from lldb_msg_to_mods()
|
||||
*/
|
||||
static void lldb_mods_free(struct ldb_context *ldb, LDAPMod **mods)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (!mods) return;
|
||||
|
||||
for (i=0;mods[i];i++) {
|
||||
if (mods[i]->mod_vals.modv_bvals) {
|
||||
for (j=0;mods[i]->mod_vals.modv_bvals[j];j++) {
|
||||
ldb_free(ldb, mods[i]->mod_vals.modv_bvals[j]);
|
||||
}
|
||||
ldb_free(ldb, mods[i]->mod_vals.modv_bvals);
|
||||
}
|
||||
ldb_free(ldb, mods[i]);
|
||||
}
|
||||
ldb_free(ldb, mods);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
convert a ldb_message structure to a list of LDAPMod structures
|
||||
ready for ldap_add() or ldap_modify()
|
||||
@ -384,7 +317,7 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
|
||||
int num_mods = 0;
|
||||
|
||||
/* allocate maximum number of elements needed */
|
||||
mods = ldb_malloc_array_p(ldb, LDAPMod *, msg->num_elements+1);
|
||||
mods = talloc_array_p(ldb, LDAPMod *, msg->num_elements+1);
|
||||
if (!mods) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
@ -394,7 +327,7 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
const struct ldb_message_element *el = &msg->elements[i];
|
||||
|
||||
mods[num_mods] = ldb_malloc_p(ldb, LDAPMod);
|
||||
mods[num_mods] = talloc_p(ldb, LDAPMod);
|
||||
if (!mods[num_mods]) {
|
||||
goto failed;
|
||||
}
|
||||
@ -414,15 +347,16 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
|
||||
}
|
||||
}
|
||||
mods[num_mods]->mod_type = el->name;
|
||||
mods[num_mods]->mod_vals.modv_bvals = ldb_malloc_array_p(ldb,
|
||||
struct berval *,
|
||||
1+el->num_values);
|
||||
mods[num_mods]->mod_vals.modv_bvals = talloc_array_p(mods[num_mods],
|
||||
struct berval *,
|
||||
1+el->num_values);
|
||||
if (!mods[num_mods]->mod_vals.modv_bvals) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
mods[num_mods]->mod_vals.modv_bvals[j] = ldb_malloc_p(ldb, struct berval);
|
||||
mods[num_mods]->mod_vals.modv_bvals[j] = talloc_p(mods[num_mods]->mod_vals.modv_bvals,
|
||||
struct berval);
|
||||
if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
|
||||
goto failed;
|
||||
}
|
||||
@ -436,7 +370,7 @@ static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
|
||||
return mods;
|
||||
|
||||
failed:
|
||||
lldb_mods_free(ldb, mods);
|
||||
talloc_free(mods);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -463,7 +397,7 @@ static int lldb_add(struct ldb_module *module, const struct ldb_message *msg)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
lldb_mods_free(ldb, mods);
|
||||
talloc_free(mods);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -491,7 +425,7 @@ static int lldb_modify(struct ldb_module *module, const struct ldb_message *msg)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
lldb_mods_free(ldb, mods);
|
||||
talloc_free(mods);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -547,6 +481,13 @@ static const struct ldb_module_ops lldb_ops = {
|
||||
};
|
||||
|
||||
|
||||
static int lldb_destructor(void *p)
|
||||
{
|
||||
struct lldb_private *lldb = p;
|
||||
ldap_unbind(lldb->ldap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
connect to the database
|
||||
*/
|
||||
@ -558,15 +499,14 @@ struct ldb_context *lldb_connect(const char *url,
|
||||
struct lldb_private *lldb = NULL;
|
||||
int i, version = 3;
|
||||
|
||||
ldb = calloc(1, sizeof(struct ldb_context));
|
||||
ldb = talloc_p(NULL, struct ldb_context);
|
||||
if (!ldb) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
lldb = ldb_malloc_p(ldb, struct lldb_private);
|
||||
lldb = talloc_p(ldb, struct lldb_private);
|
||||
if (!lldb) {
|
||||
ldb_free(ldb, ldb);
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
@ -579,14 +519,15 @@ struct ldb_context *lldb_connect(const char *url,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
talloc_set_destructor(lldb, lldb_destructor);
|
||||
|
||||
lldb->last_rc = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||
if (lldb->last_rc != LDAP_SUCCESS) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ldb->modules = ldb_malloc_p(ldb, struct ldb_module);
|
||||
ldb->modules = talloc_p(ldb, struct ldb_module);
|
||||
if (!ldb->modules) {
|
||||
ldb_free(ldb, ldb);
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
}
|
||||
@ -600,14 +541,14 @@ struct ldb_context *lldb_connect(const char *url,
|
||||
on the caller keeping it around (it might be dynamic) */
|
||||
for (i=0;options[i];i++) ;
|
||||
|
||||
lldb->options = ldb_malloc_array_p(ldb, char *, i+1);
|
||||
lldb->options = talloc_array_p(lldb, char *, i+1);
|
||||
if (!lldb->options) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (i=0;options[i];i++) {
|
||||
lldb->options[i+1] = NULL;
|
||||
lldb->options[i] = ldb_strdup(ldb, options[i]);
|
||||
lldb->options[i] = talloc_strdup(lldb->options, options[i]);
|
||||
if (!lldb->options[i]) {
|
||||
goto failed;
|
||||
}
|
||||
@ -617,17 +558,7 @@ struct ldb_context *lldb_connect(const char *url,
|
||||
return ldb;
|
||||
|
||||
failed:
|
||||
if (lldb && lldb->options) {
|
||||
for (i=0;lldb->options[i];i++) {
|
||||
ldb_free(ldb, lldb->options[i]);
|
||||
}
|
||||
ldb_free(ldb, lldb->options);
|
||||
}
|
||||
if (lldb && lldb->ldap) {
|
||||
ldap_unbind(lldb->ldap);
|
||||
}
|
||||
ldb_free(ldb, lldb);
|
||||
if (ldb) free(ldb);
|
||||
talloc_free(ldb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,8 @@
|
||||
*/
|
||||
static int ltdb_baseinfo_init(struct ldb_module *module)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
struct ldb_message_element el;
|
||||
struct ldb_val val;
|
||||
int ret;
|
||||
@ -55,60 +54,61 @@ static int ltdb_baseinfo_init(struct ldb_module *module)
|
||||
|
||||
ltdb->sequence_number = atof(initial_sequence_number);
|
||||
|
||||
msg.num_elements = 1;
|
||||
msg.elements = ⪙
|
||||
msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
|
||||
if (!msg.dn) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
msg = talloc_p(ltdb, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
|
||||
|
||||
msg->num_elements = 1;
|
||||
msg->elements = ⪙
|
||||
msg->dn = talloc_strdup(msg, LTDB_BASEINFO);
|
||||
if (!msg->dn) {
|
||||
goto failed;
|
||||
}
|
||||
el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
|
||||
if (!el.name) {
|
||||
ldb_free(ldb, msg.dn);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
goto failed;
|
||||
}
|
||||
el.values = &val;
|
||||
el.num_values = 1;
|
||||
el.flags = 0;
|
||||
val.data = ldb_strdup(ldb, initial_sequence_number);
|
||||
val.data = talloc_strdup(msg, initial_sequence_number);
|
||||
if (!val.data) {
|
||||
ldb_free(ldb, el.name);
|
||||
ldb_free(ldb, msg.dn);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
goto failed;
|
||||
}
|
||||
val.length = 1;
|
||||
|
||||
ret = ltdb_store(module, &msg, TDB_INSERT);
|
||||
ret = ltdb_store(module, msg, TDB_INSERT);
|
||||
|
||||
ldb_free(ldb, msg.dn);
|
||||
ldb_free(ldb, el.name);
|
||||
ldb_free(ldb, val.data);
|
||||
talloc_free(msg);
|
||||
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
talloc_free(msg);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
free any cache records
|
||||
*/
|
||||
void ltdb_cache_free(struct ldb_module *module)
|
||||
static void ltdb_cache_free(struct ldb_module *module)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
struct ldb_alloc_ops alloc = ldb->alloc_ops;
|
||||
ldb->alloc_ops.alloc = NULL;
|
||||
|
||||
ltdb->sequence_number = 0;
|
||||
ltdb_search_dn1_free(module, <db->cache.baseinfo);
|
||||
ltdb_search_dn1_free(module, <db->cache.indexlist);
|
||||
ltdb_search_dn1_free(module, <db->cache.subclasses);
|
||||
ltdb_search_dn1_free(module, <db->cache.attributes);
|
||||
talloc_free(ltdb->cache);
|
||||
ltdb->cache = NULL;
|
||||
}
|
||||
|
||||
ldb_free(ldb, ltdb->cache.last_attribute.name);
|
||||
memset(<db->cache, 0, sizeof(ltdb->cache));
|
||||
|
||||
ldb->alloc_ops = alloc;
|
||||
/*
|
||||
force a cache reload
|
||||
*/
|
||||
int ltdb_cache_reload(struct ldb_module *module)
|
||||
{
|
||||
ltdb_cache_free(module);
|
||||
return ltdb_cache_load(module);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -116,60 +116,78 @@ void ltdb_cache_free(struct ldb_module *module)
|
||||
*/
|
||||
int ltdb_cache_load(struct ldb_module *module)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
double seq;
|
||||
struct ldb_alloc_ops alloc = ldb->alloc_ops;
|
||||
|
||||
ldb->alloc_ops.alloc = NULL;
|
||||
if (ltdb->cache == NULL) {
|
||||
ltdb->cache = talloc_zero_p(ltdb, struct ltdb_cache);
|
||||
if (ltdb->cache == NULL) goto failed;
|
||||
ltdb->cache->indexlist = talloc_zero_p(ltdb->cache, struct ldb_message);
|
||||
ltdb->cache->subclasses = talloc_zero_p(ltdb->cache, struct ldb_message);
|
||||
ltdb->cache->attributes = talloc_zero_p(ltdb->cache, struct ldb_message);
|
||||
if (ltdb->cache->indexlist == NULL ||
|
||||
ltdb->cache->subclasses == NULL ||
|
||||
ltdb->cache->attributes == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
ltdb_search_dn1_free(module, <db->cache.baseinfo);
|
||||
talloc_free(ltdb->cache->baseinfo);
|
||||
ltdb->cache->baseinfo = talloc_p(ltdb->cache, struct ldb_message);
|
||||
if (ltdb->cache->baseinfo == NULL) goto failed;
|
||||
|
||||
if (ltdb_search_dn1(module, LTDB_BASEINFO, <db->cache.baseinfo) == -1) {
|
||||
if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) == -1) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* possibly initialise the baseinfo */
|
||||
if (!ltdb->cache.baseinfo.dn) {
|
||||
if (!ltdb->cache->baseinfo->dn) {
|
||||
if (ltdb_baseinfo_init(module) != 0) {
|
||||
goto failed;
|
||||
}
|
||||
if (ltdb_search_dn1(module, LTDB_BASEINFO, <db->cache.baseinfo) != 1) {
|
||||
if (ltdb_search_dn1(module, LTDB_BASEINFO, ltdb->cache->baseinfo) != 1) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the current internal sequence number is the same as the one
|
||||
in the database then assume the rest of the cache is OK */
|
||||
seq = ldb_msg_find_double(<db->cache.baseinfo, LTDB_SEQUENCE_NUMBER, 0);
|
||||
seq = ldb_msg_find_double(ltdb->cache->baseinfo, LTDB_SEQUENCE_NUMBER, 0);
|
||||
if (seq == ltdb->sequence_number) {
|
||||
goto done;
|
||||
}
|
||||
ltdb->sequence_number = seq;
|
||||
|
||||
ldb_free(ldb, ltdb->cache.last_attribute.name);
|
||||
memset(<db->cache.last_attribute, 0, sizeof(ltdb->cache.last_attribute));
|
||||
talloc_free(ltdb->cache->last_attribute.name);
|
||||
memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute));
|
||||
|
||||
ltdb_search_dn1_free(module, <db->cache.indexlist);
|
||||
ltdb_search_dn1_free(module, <db->cache.subclasses);
|
||||
ltdb_search_dn1_free(module, <db->cache.attributes);
|
||||
talloc_free(ltdb->cache->indexlist);
|
||||
talloc_free(ltdb->cache->subclasses);
|
||||
talloc_free(ltdb->cache->attributes);
|
||||
|
||||
if (ltdb_search_dn1(module, LTDB_INDEXLIST, <db->cache.indexlist) == -1) {
|
||||
ltdb->cache->indexlist = talloc_zero_p(ltdb->cache, struct ldb_message);
|
||||
ltdb->cache->subclasses = talloc_zero_p(ltdb->cache, struct ldb_message);
|
||||
ltdb->cache->attributes = talloc_zero_p(ltdb->cache, struct ldb_message);
|
||||
if (ltdb->cache->indexlist == NULL ||
|
||||
ltdb->cache->subclasses == NULL ||
|
||||
ltdb->cache->attributes == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
if (ltdb_search_dn1(module, LTDB_SUBCLASSES, <db->cache.subclasses) == -1) {
|
||||
|
||||
if (ltdb_search_dn1(module, LTDB_INDEXLIST, ltdb->cache->indexlist) == -1) {
|
||||
goto failed;
|
||||
}
|
||||
if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, <db->cache.attributes) == -1) {
|
||||
if (ltdb_search_dn1(module, LTDB_SUBCLASSES, ltdb->cache->subclasses) == -1) {
|
||||
goto failed;
|
||||
}
|
||||
if (ltdb_search_dn1(module, LTDB_ATTRIBUTES, ltdb->cache->attributes) == -1) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
done:
|
||||
ldb->alloc_ops = alloc;
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
ldb->alloc_ops = alloc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -181,33 +199,37 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
struct ldb_message_element el;
|
||||
struct ldb_val val;
|
||||
char *s = NULL;
|
||||
int ret;
|
||||
|
||||
ldb_asprintf(ldb, &s, "%.0f", ltdb->sequence_number+1);
|
||||
s = talloc_asprintf(ldb, "%.0f", ltdb->sequence_number+1);
|
||||
if (!s) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.num_elements = 1;
|
||||
msg.elements = ⪙
|
||||
msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
|
||||
el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
|
||||
msg = talloc_p(ltdb, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->num_elements = 1;
|
||||
msg->elements = ⪙
|
||||
msg->dn = talloc_strdup(msg, LTDB_BASEINFO);
|
||||
el.name = talloc_strdup(msg, LTDB_SEQUENCE_NUMBER);
|
||||
el.values = &val;
|
||||
el.num_values = 1;
|
||||
el.flags = LDB_FLAG_MOD_REPLACE;
|
||||
val.data = s;
|
||||
val.length = strlen(s);
|
||||
|
||||
ret = ltdb_modify_internal(module, &msg);
|
||||
ret = ltdb_modify_internal(module, msg);
|
||||
|
||||
ldb_free(ldb, s);
|
||||
ldb_free(ldb, msg.dn);
|
||||
ldb_free(ldb, el.name);
|
||||
talloc_free(msg);
|
||||
|
||||
if (ret == 0) {
|
||||
ltdb->sequence_number += 1;
|
||||
@ -223,7 +245,6 @@ int ltdb_increase_sequence_number(struct ldb_module *module)
|
||||
*/
|
||||
int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
const char *attrs;
|
||||
const struct {
|
||||
@ -238,11 +259,10 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
|
||||
};
|
||||
size_t len;
|
||||
int i, ret=0;
|
||||
struct ldb_alloc_ops alloc = ldb->alloc_ops;
|
||||
|
||||
if (ltdb->cache.last_attribute.name &&
|
||||
ldb_attr_cmp(ltdb->cache.last_attribute.name, attr_name) == 0) {
|
||||
return ltdb->cache.last_attribute.flags;
|
||||
if (ltdb->cache->last_attribute.name &&
|
||||
ldb_attr_cmp(ltdb->cache->last_attribute.name, attr_name) == 0) {
|
||||
return ltdb->cache->last_attribute.flags;
|
||||
}
|
||||
|
||||
/* objectclass is a special default case */
|
||||
@ -250,7 +270,7 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
|
||||
ret = LTDB_FLAG_OBJECTCLASS | LTDB_FLAG_CASE_INSENSITIVE;
|
||||
}
|
||||
|
||||
attrs = ldb_msg_find_string(<db->cache.attributes, attr_name, NULL);
|
||||
attrs = ldb_msg_find_string(ltdb->cache->attributes, attr_name, NULL);
|
||||
|
||||
if (!attrs) {
|
||||
return ret;
|
||||
@ -270,14 +290,10 @@ int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name)
|
||||
attrs += strspn(attrs, " ,");
|
||||
}
|
||||
|
||||
ldb->alloc_ops.alloc = NULL;
|
||||
talloc_free(ltdb->cache->last_attribute.name);
|
||||
|
||||
ldb_free(ldb, ltdb->cache.last_attribute.name);
|
||||
ltdb->cache->last_attribute.name = talloc_strdup(ltdb->cache, attr_name);
|
||||
ltdb->cache->last_attribute.flags = ret;
|
||||
|
||||
ltdb->cache.last_attribute.name = ldb_strdup(ldb, attr_name);
|
||||
ltdb->cache.last_attribute.flags = ret;
|
||||
|
||||
ldb->alloc_ops = alloc;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -43,18 +43,6 @@ struct dn_list {
|
||||
char **dn;
|
||||
};
|
||||
|
||||
/*
|
||||
free a struct dn_list
|
||||
*/
|
||||
static void dn_list_free(struct ldb_context *ldb, struct dn_list *list)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0;i<list->count;i++) {
|
||||
ldb_free(ldb, list->dn[i]);
|
||||
}
|
||||
ldb_free(ldb, list->dn);
|
||||
}
|
||||
|
||||
/*
|
||||
return the dn key to be used for an index
|
||||
caller frees
|
||||
@ -67,13 +55,13 @@ static char *ldb_dn_key(struct ldb_context *ldb,
|
||||
if (ldb_should_b64_encode(value)) {
|
||||
char *vstr = ldb_base64_encode(ldb, value->data, value->length);
|
||||
if (!vstr) return NULL;
|
||||
ldb_asprintf(ldb, &ret, "%s:%s::%s", LTDB_INDEX, attr, vstr);
|
||||
ldb_free(ldb, vstr);
|
||||
ret = talloc_asprintf(ldb, "%s:%s::%s", LTDB_INDEX, attr, vstr);
|
||||
talloc_free(vstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ldb_asprintf(ldb, &ret, "%s:%s:%.*s", LTDB_INDEX, attr, value->length, (char *)value->data);
|
||||
return ret;
|
||||
return talloc_asprintf(ldb, "%s:%s:%.*s",
|
||||
LTDB_INDEX, attr, value->length, (char *)value->data);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -118,7 +106,7 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
|
||||
char *dn = NULL;
|
||||
int ret;
|
||||
unsigned int i, j;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
|
||||
list->count = 0;
|
||||
list->dn = NULL;
|
||||
@ -141,39 +129,43 @@ static int ltdb_index_dn_simple(struct ldb_module *module,
|
||||
dn = ldb_dn_key(ldb, tree->u.simple.attr, &tree->u.simple.value);
|
||||
if (!dn) return -1;
|
||||
|
||||
ret = ltdb_search_dn1(module, dn, &msg);
|
||||
ldb_free(ldb, dn);
|
||||
msg = talloc_p(list, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_search_dn1(module, dn, msg);
|
||||
talloc_free(dn);
|
||||
if (ret == 0 || ret == -1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i=0;i<msg.num_elements;i++) {
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
struct ldb_message_element *el;
|
||||
|
||||
if (strcmp(msg.elements[i].name, LTDB_IDX) != 0) {
|
||||
if (strcmp(msg->elements[i].name, LTDB_IDX) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
el = &msg.elements[i];
|
||||
el = &msg->elements[i];
|
||||
|
||||
list->dn = ldb_malloc_array_p(ldb, char *, el->num_values);
|
||||
list->dn = talloc_array_p(list, char *, el->num_values);
|
||||
if (!list->dn) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
list->dn[list->count] =
|
||||
ldb_strdup(ldb, (char *)el->values[j].data);
|
||||
talloc_strdup(list->dn, (char *)el->values[j].data);
|
||||
if (!list->dn[list->count]) {
|
||||
dn_list_free(ldb, list);
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
talloc_free(list);
|
||||
return -1;
|
||||
}
|
||||
list->count++;
|
||||
}
|
||||
}
|
||||
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
talloc_free(msg);
|
||||
|
||||
qsort(list->dn, list->count, sizeof(char *), (comparison_fn_t) list_cmp);
|
||||
|
||||
@ -203,30 +195,34 @@ static int ltdb_index_dn_objectclass(struct ldb_module *module,
|
||||
|
||||
ret = ltdb_index_dn_simple(module, tree, index_list, list);
|
||||
|
||||
for (i=0;i<ltdb->cache.subclasses.num_elements;i++) {
|
||||
struct ldb_message_element *el = <db->cache.subclasses.elements[i];
|
||||
for (i=0;i<ltdb->cache->subclasses->num_elements;i++) {
|
||||
struct ldb_message_element *el = <db->cache->subclasses->elements[i];
|
||||
if (ldb_attr_cmp(el->name, target) == 0) {
|
||||
unsigned int j;
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
struct ldb_parse_tree tree2;
|
||||
struct dn_list list2;
|
||||
struct dn_list *list2;
|
||||
tree2.operation = LDB_OP_SIMPLE;
|
||||
tree2.u.simple.attr = ldb_strdup(ldb, LTDB_OBJECTCLASS);
|
||||
tree2.u.simple.attr = talloc_strdup(list, LTDB_OBJECTCLASS);
|
||||
if (!tree2.u.simple.attr) {
|
||||
return -1;
|
||||
}
|
||||
tree2.u.simple.value = el->values[j];
|
||||
list2 = talloc_p(list, struct dn_list);
|
||||
if (list2 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (ltdb_index_dn_objectclass(module, &tree2,
|
||||
index_list, &list2) == 1) {
|
||||
index_list, list2) == 1) {
|
||||
if (list->count == 0) {
|
||||
*list = list2;
|
||||
*list = *list2;
|
||||
ret = 1;
|
||||
} else {
|
||||
list_union(ldb, list, &list2);
|
||||
dn_list_free(ldb, &list2);
|
||||
list_union(ldb, list, list2);
|
||||
talloc_free(list2);
|
||||
}
|
||||
}
|
||||
ldb_free(ldb, tree2.u.simple.attr);
|
||||
talloc_free(tree2.u.simple.attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,35 +253,42 @@ static int ltdb_index_dn_leaf(struct ldb_module *module,
|
||||
static int list_intersect(struct ldb_context *ldb,
|
||||
struct dn_list *list, const struct dn_list *list2)
|
||||
{
|
||||
struct dn_list list3;
|
||||
struct dn_list *list3;
|
||||
unsigned int i;
|
||||
|
||||
if (list->count == 0 || list2->count == 0) {
|
||||
/* 0 & X == 0 */
|
||||
dn_list_free(ldb, list);
|
||||
talloc_free(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
list3.dn = ldb_malloc_array_p(ldb, char *, list->count);
|
||||
if (!list3.dn) {
|
||||
dn_list_free(ldb, list);
|
||||
list3 = talloc_p(ldb, struct dn_list);
|
||||
if (list3 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
list3.count = 0;
|
||||
|
||||
list3->dn = talloc_array_p(list3, char *, list->count);
|
||||
if (!list3->dn) {
|
||||
talloc_free(list);
|
||||
talloc_free(list3);
|
||||
return -1;
|
||||
}
|
||||
list3->count = 0;
|
||||
|
||||
for (i=0;i<list->count;i++) {
|
||||
if (ldb_list_find(list->dn[i], list2->dn, list2->count,
|
||||
sizeof(char *), (comparison_fn_t)strcmp) != -1) {
|
||||
list3.dn[list3.count] = list->dn[i];
|
||||
list3.count++;
|
||||
list3->dn[list3->count] = talloc_steal(list3->dn, list->dn[i]);
|
||||
list3->count++;
|
||||
} else {
|
||||
ldb_free(ldb, list->dn[i]);
|
||||
talloc_free(list->dn[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ldb_free(ldb, list->dn);
|
||||
list->dn = list3.dn;
|
||||
list->count = list3.count;
|
||||
talloc_free(list->dn);
|
||||
list->dn = talloc_steal(list, list3->dn);
|
||||
list->count = list3->count;
|
||||
talloc_free(list3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -305,13 +308,13 @@ static int list_union(struct ldb_context *ldb,
|
||||
|
||||
if (list->count == 0 && list2->count == 0) {
|
||||
/* 0 | 0 == 0 */
|
||||
dn_list_free(ldb, list);
|
||||
talloc_free(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
d = ldb_realloc_p(ldb, list->dn, char *, list->count + list2->count);
|
||||
d = talloc_realloc_p(list, list->dn, char *, list->count + list2->count);
|
||||
if (!d) {
|
||||
dn_list_free(ldb, list);
|
||||
talloc_free(list);
|
||||
return -1;
|
||||
}
|
||||
list->dn = d;
|
||||
@ -319,9 +322,9 @@ static int list_union(struct ldb_context *ldb,
|
||||
for (i=0;i<list2->count;i++) {
|
||||
if (ldb_list_find(list2->dn[i], list->dn, count,
|
||||
sizeof(char *), (comparison_fn_t)strcmp) == -1) {
|
||||
list->dn[list->count] = ldb_strdup(ldb, list2->dn[i]);
|
||||
list->dn[list->count] = talloc_strdup(list->dn, list2->dn[i]);
|
||||
if (!list->dn[list->count]) {
|
||||
dn_list_free(ldb, list);
|
||||
talloc_free(list);
|
||||
return -1;
|
||||
}
|
||||
list->count++;
|
||||
@ -358,39 +361,48 @@ static int ltdb_index_dn_or(struct ldb_module *module,
|
||||
list->count = 0;
|
||||
|
||||
for (i=0;i<tree->u.list.num_elements;i++) {
|
||||
struct dn_list list2;
|
||||
struct dn_list *list2;
|
||||
int v;
|
||||
v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, &list2);
|
||||
|
||||
list2 = talloc_p(module, struct dn_list);
|
||||
if (list2 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2);
|
||||
|
||||
if (v == 0) {
|
||||
/* 0 || X == X */
|
||||
if (ret == -1) {
|
||||
ret = 0;
|
||||
}
|
||||
talloc_free(list2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (v == -1) {
|
||||
/* 1 || X == 1 */
|
||||
dn_list_free(ldb, list);
|
||||
talloc_free(list->dn);
|
||||
talloc_free(list2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
ret = 1;
|
||||
*list = list2;
|
||||
list->dn = talloc_steal(list, list2->dn);
|
||||
list->count = list2->count;
|
||||
} else {
|
||||
if (list_union(ldb, list, &list2) == -1) {
|
||||
dn_list_free(ldb, &list2);
|
||||
if (list_union(ldb, list, list2) == -1) {
|
||||
talloc_free(list2);
|
||||
return -1;
|
||||
}
|
||||
dn_list_free(ldb, &list2);
|
||||
ret = 1;
|
||||
}
|
||||
talloc_free(list2);
|
||||
}
|
||||
|
||||
if (list->count == 0) {
|
||||
dn_list_free(ldb, list);
|
||||
talloc_free(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -434,33 +446,44 @@ static int ltdb_index_dn_and(struct ldb_module *module,
|
||||
list->count = 0;
|
||||
|
||||
for (i=0;i<tree->u.list.num_elements;i++) {
|
||||
struct dn_list list2;
|
||||
struct dn_list *list2;
|
||||
int v;
|
||||
v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, &list2);
|
||||
|
||||
list2 = talloc_p(module, struct dn_list);
|
||||
if (list2 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
v = ltdb_index_dn(module, tree->u.list.elements[i], index_list, list2);
|
||||
|
||||
if (v == 0) {
|
||||
/* 0 && X == 0 */
|
||||
dn_list_free(ldb, list);
|
||||
talloc_free(list->dn);
|
||||
talloc_free(list2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (v == -1) {
|
||||
talloc_free(list2);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
ret = 1;
|
||||
*list = list2;
|
||||
talloc_free(list->dn);
|
||||
list->dn = talloc_steal(list, list2->dn);
|
||||
list->count = list2->count;
|
||||
} else {
|
||||
if (list_intersect(ldb, list, &list2) == -1) {
|
||||
dn_list_free(ldb, &list2);
|
||||
if (list_intersect(ldb, list, list2) == -1) {
|
||||
talloc_free(list2);
|
||||
return -1;
|
||||
}
|
||||
dn_list_free(ldb, &list2);
|
||||
}
|
||||
|
||||
talloc_free(list2);
|
||||
|
||||
if (list->count == 0) {
|
||||
if (list->dn) ldb_free(ldb, list->dn);
|
||||
talloc_free(list->dn);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -514,24 +537,32 @@ static int ldb_index_filter(struct ldb_module *module, struct ldb_parse_tree *tr
|
||||
int count = 0;
|
||||
|
||||
for (i=0;i<dn_list->count;i++) {
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
int ret;
|
||||
ret = ltdb_search_dn1(module, dn_list->dn[i], &msg);
|
||||
|
||||
msg = talloc_p(module, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_search_dn1(module, dn_list->dn[i], msg);
|
||||
if (ret == 0) {
|
||||
/* the record has disappeared? yes, this can happen */
|
||||
talloc_free(msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
/* an internal error */
|
||||
talloc_free(msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
if (ltdb_message_match(module, &msg, tree, base, scope) == 1) {
|
||||
ret = ltdb_add_attr_results(module, &msg, attrs, &count, res);
|
||||
if (ltdb_message_match(module, msg, tree, base, scope) == 1) {
|
||||
ret = ltdb_add_attr_results(module, msg, attrs, &count, res);
|
||||
}
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
talloc_free(msg);
|
||||
if (ret != 0) {
|
||||
return -1;
|
||||
}
|
||||
@ -551,26 +582,31 @@ int ltdb_search_indexed(struct ldb_module *module,
|
||||
struct ldb_parse_tree *tree,
|
||||
const char * const attrs[], struct ldb_message ***res)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
struct dn_list dn_list;
|
||||
struct dn_list *dn_list;
|
||||
int ret;
|
||||
|
||||
if (ltdb->cache.indexlist.num_elements == 0) {
|
||||
if (ltdb->cache->indexlist->num_elements == 0) {
|
||||
/* no index list? must do full search */
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_index_dn(module, tree, <db->cache.indexlist, &dn_list);
|
||||
dn_list = talloc_p(module, struct dn_list);
|
||||
if (dn_list == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_index_dn(module, tree, ltdb->cache->indexlist, dn_list);
|
||||
|
||||
if (ret == 1) {
|
||||
/* we've got a candidate list - now filter by the full tree
|
||||
and extract the needed attributes */
|
||||
ret = ldb_index_filter(module, tree, base, scope, &dn_list,
|
||||
ret = ldb_index_filter(module, tree, base, scope, dn_list,
|
||||
attrs, res);
|
||||
dn_list_free(ldb, &dn_list);
|
||||
}
|
||||
|
||||
talloc_free(dn_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -585,19 +621,19 @@ static int ltdb_index_add1_new(struct ldb_context *ldb,
|
||||
struct ldb_message_element *el2;
|
||||
|
||||
/* add another entry */
|
||||
el2 = ldb_realloc_p(ldb, msg->elements,
|
||||
struct ldb_message_element, msg->num_elements+1);
|
||||
el2 = talloc_realloc_p(msg, msg->elements,
|
||||
struct ldb_message_element, msg->num_elements+1);
|
||||
if (!el2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg->elements = el2;
|
||||
msg->elements[msg->num_elements].name = ldb_strdup(ldb, LTDB_IDX);
|
||||
msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, LTDB_IDX);
|
||||
if (!msg->elements[msg->num_elements].name) {
|
||||
return -1;
|
||||
}
|
||||
msg->elements[msg->num_elements].num_values = 0;
|
||||
msg->elements[msg->num_elements].values = ldb_malloc_p(ldb, struct ldb_val);
|
||||
msg->elements[msg->num_elements].values = talloc_p(msg->elements, struct ldb_val);
|
||||
if (!msg->elements[msg->num_elements].values) {
|
||||
return -1;
|
||||
}
|
||||
@ -630,9 +666,9 @@ static int ltdb_index_add1_add(struct ldb_context *ldb,
|
||||
}
|
||||
}
|
||||
|
||||
v2 = ldb_realloc_p(ldb, msg->elements[idx].values,
|
||||
struct ldb_val,
|
||||
msg->elements[idx].num_values+1);
|
||||
v2 = talloc_realloc_p(msg->elements, msg->elements[idx].values,
|
||||
struct ldb_val,
|
||||
msg->elements[idx].num_values+1);
|
||||
if (!v2) {
|
||||
return -1;
|
||||
}
|
||||
@ -652,9 +688,9 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn,
|
||||
struct ldb_message_element *el, int v_idx)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
char *dn_key;
|
||||
int ret, added=0, added_dn=0;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
|
||||
dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]);
|
||||
@ -662,52 +698,45 @@ static int ltdb_index_add1(struct ldb_module *module, char *dn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_search_dn1(module, dn_key, &msg);
|
||||
msg = talloc_p(dn_key, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_search_dn1(module, dn_key, msg);
|
||||
if (ret == -1) {
|
||||
ldb_free(ldb, dn_key);
|
||||
talloc_free(dn_key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
added_dn = 1;
|
||||
msg.dn = ldb_strdup(ldb, dn_key);
|
||||
if (!msg.dn) {
|
||||
ldb_free(ldb, dn_key);
|
||||
msg->dn = talloc_strdup(msg, dn_key);
|
||||
if (!msg->dn) {
|
||||
talloc_free(dn_key);
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
msg.num_elements = 0;
|
||||
msg.elements = NULL;
|
||||
msg.private_data = NULL;
|
||||
msg->num_elements = 0;
|
||||
msg->elements = NULL;
|
||||
}
|
||||
|
||||
ldb_free(ldb, dn_key);
|
||||
|
||||
for (i=0;i<msg.num_elements;i++) {
|
||||
if (strcmp(LTDB_IDX, msg.elements[i].name) == 0) {
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
if (strcmp(LTDB_IDX, msg->elements[i].name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == msg.num_elements) {
|
||||
added = 1;
|
||||
ret = ltdb_index_add1_new(ldb, &msg, el, dn);
|
||||
if (i == msg->num_elements) {
|
||||
ret = ltdb_index_add1_new(ldb, msg, el, dn);
|
||||
} else {
|
||||
ret = ltdb_index_add1_add(ldb, &msg, el, i, dn);
|
||||
ret = ltdb_index_add1_add(ldb, msg, el, i, dn);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = ltdb_store(module, &msg, TDB_REPLACE);
|
||||
ret = ltdb_store(module, msg, TDB_REPLACE);
|
||||
}
|
||||
|
||||
if (added) {
|
||||
ldb_free(ldb, msg.elements[i].name);
|
||||
}
|
||||
if (added_dn) {
|
||||
ldb_free(ldb, msg.dn);
|
||||
}
|
||||
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
talloc_free(dn_key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -722,13 +751,13 @@ int ltdb_index_add(struct ldb_module *module, const struct ldb_message *msg)
|
||||
int ret;
|
||||
unsigned int i, j;
|
||||
|
||||
if (ltdb->cache.indexlist.num_elements == 0) {
|
||||
if (ltdb->cache->indexlist->num_elements == 0) {
|
||||
/* no indexed fields */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
ret = ldb_msg_find_idx(<db->cache.indexlist, msg->elements[i].name,
|
||||
ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name,
|
||||
NULL, LTDB_IDXATTR);
|
||||
if (ret == -1) {
|
||||
continue;
|
||||
@ -752,7 +781,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
|
||||
struct ldb_message_element *el, int v_idx)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
char *dn_key;
|
||||
int ret, i;
|
||||
unsigned int j;
|
||||
@ -762,44 +791,48 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_search_dn1(module, dn_key, &msg);
|
||||
msg = talloc_p(dn_key, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
talloc_free(dn_key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_search_dn1(module, dn_key, msg);
|
||||
if (ret == -1) {
|
||||
ldb_free(ldb, dn_key);
|
||||
talloc_free(dn_key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* it wasn't indexed. Did we have an earlier error? If we did then
|
||||
its gone now */
|
||||
ldb_free(ldb, dn_key);
|
||||
talloc_free(dn_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
i = ldb_msg_find_idx(&msg, dn, &j, LTDB_IDX);
|
||||
i = ldb_msg_find_idx(msg, dn, &j, LTDB_IDX);
|
||||
if (i == -1) {
|
||||
ldb_debug(ldb, LDB_DEBUG_ERROR, "ERROR: dn %s not found in %s\n", dn, dn_key);
|
||||
/* it ain't there. hmmm */
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
ldb_free(ldb, dn_key);
|
||||
talloc_free(dn_key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (j != msg.elements[i].num_values - 1) {
|
||||
memmove(&msg.elements[i].values[j],
|
||||
&msg.elements[i].values[j+1],
|
||||
(msg.elements[i].num_values-(j+1)) *
|
||||
sizeof(msg.elements[i].values[0]));
|
||||
if (j != msg->elements[i].num_values - 1) {
|
||||
memmove(&msg->elements[i].values[j],
|
||||
&msg->elements[i].values[j+1],
|
||||
(msg->elements[i].num_values-(j+1)) *
|
||||
sizeof(msg->elements[i].values[0]));
|
||||
}
|
||||
msg.elements[i].num_values--;
|
||||
msg->elements[i].num_values--;
|
||||
|
||||
if (msg.elements[i].num_values == 0) {
|
||||
if (msg->elements[i].num_values == 0) {
|
||||
ret = ltdb_delete_noindex(module, dn_key);
|
||||
} else {
|
||||
ret = ltdb_store(module, &msg, TDB_REPLACE);
|
||||
ret = ltdb_store(module, msg, TDB_REPLACE);
|
||||
}
|
||||
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
ldb_free(ldb, dn_key);
|
||||
talloc_free(dn_key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -815,13 +848,13 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg)
|
||||
unsigned int i, j;
|
||||
|
||||
/* find the list of indexed fields */
|
||||
if (ltdb->cache.indexlist.num_elements == 0) {
|
||||
if (ltdb->cache->indexlist->num_elements == 0) {
|
||||
/* no indexed fields */
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
ret = ldb_msg_find_idx(<db->cache.indexlist, msg->elements[i].name,
|
||||
ret = ldb_msg_find_idx(ltdb->cache->indexlist, msg->elements[i].name,
|
||||
NULL, LTDB_IDXATTR);
|
||||
if (ret == -1) {
|
||||
continue;
|
||||
@ -856,7 +889,7 @@ static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, vo
|
||||
static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
|
||||
{
|
||||
struct ldb_module *module = state;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
int ret;
|
||||
|
||||
if (strncmp(key.dptr, "DN=@", 4) == 0 ||
|
||||
@ -864,18 +897,24 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ltdb_unpack_data(module, &data, &msg);
|
||||
if (ret != 0) {
|
||||
msg = talloc_p(module, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!msg.dn) {
|
||||
msg.dn = key.dptr+3;
|
||||
ret = ltdb_unpack_data(module, &data, msg);
|
||||
if (ret != 0) {
|
||||
talloc_free(msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_index_add(module, &msg);
|
||||
if (!msg->dn) {
|
||||
msg->dn = key.dptr+3;
|
||||
}
|
||||
|
||||
ltdb_unpack_data_free(module, &msg);
|
||||
ret = ltdb_index_add(module, msg);
|
||||
|
||||
talloc_free(msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -888,9 +927,7 @@ int ltdb_reindex(struct ldb_module *module)
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
int ret;
|
||||
|
||||
ltdb_cache_free(module);
|
||||
|
||||
if (ltdb_cache_load(module) != 0) {
|
||||
if (ltdb_cache_reload(module) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -93,13 +93,14 @@ static int ltdb_val_equal_wildcard_ci(struct ldb_module *module,
|
||||
|
||||
s2 = ldb_casefold(ldb, v2->data);
|
||||
if (!s2) {
|
||||
talloc_free(s1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = fnmatch(s2, s1, 0);
|
||||
|
||||
ldb_free(ldb, s1);
|
||||
ldb_free(ldb, s2);
|
||||
talloc_free(s1);
|
||||
talloc_free(s2);
|
||||
|
||||
if (ret == 0) {
|
||||
return 1;
|
||||
@ -149,8 +150,8 @@ static int ltdb_val_equal_objectclass(struct ldb_module *module,
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i=0;i<ltdb->cache.subclasses.num_elements;i++) {
|
||||
struct ldb_message_element *el = <db->cache.subclasses.elements[i];
|
||||
for (i=0;i<ltdb->cache->subclasses->num_elements;i++) {
|
||||
struct ldb_message_element *el = <db->cache->subclasses->elements[i];
|
||||
if (ldb_attr_cmp(el->name, v2->data) == 0) {
|
||||
unsigned int j;
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
|
@ -99,7 +99,7 @@ int ltdb_pack_data(struct ldb_module *module,
|
||||
}
|
||||
|
||||
/* allocate it */
|
||||
data->dptr = ldb_malloc(ldb, size);
|
||||
data->dptr = talloc_array_p(ldb, char, size);
|
||||
if (!data->dptr) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -144,25 +144,14 @@ int ltdb_pack_data(struct ldb_module *module,
|
||||
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);
|
||||
talloc_free(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,
|
||||
@ -220,8 +209,7 @@ int ltdb_unpack_data(struct ldb_module *module,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
message->elements = ldb_malloc_array_p(ldb, struct ldb_message_element,
|
||||
message->num_elements);
|
||||
message->elements = talloc_array_p(ldb, struct ldb_message_element, message->num_elements);
|
||||
if (!message->elements) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
@ -247,9 +235,9 @@ int ltdb_unpack_data(struct ldb_module *module,
|
||||
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_p(message->elements,
|
||||
struct ldb_val,
|
||||
message->elements[i].num_values);
|
||||
if (!message->elements[i].values) {
|
||||
errno = ENOMEM;
|
||||
goto failed;
|
||||
|
@ -38,25 +38,6 @@
|
||||
#include "ldb/ldb_tdb/ldb_tdb.h"
|
||||
#include "ldb/include/ldb_parse.h"
|
||||
|
||||
/*
|
||||
free a message that has all parts separately allocated
|
||||
*/
|
||||
static void msg_free_all_parts(struct ldb_context *ldb, struct ldb_message *msg)
|
||||
{
|
||||
unsigned int i, j;
|
||||
ldb_free(ldb, msg->dn);
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
ldb_free(ldb, msg->elements[i].name);
|
||||
for (j=0;j<msg->elements[i].num_values;j++) {
|
||||
ldb_free(ldb, msg->elements[i].values[j].data);
|
||||
}
|
||||
ldb_free(ldb, msg->elements[i].values);
|
||||
}
|
||||
ldb_free(ldb, msg->elements);
|
||||
ldb_free(ldb, msg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
add one element to a message
|
||||
*/
|
||||
@ -66,7 +47,7 @@ static int msg_add_element(struct ldb_context *ldb,
|
||||
unsigned int i;
|
||||
struct ldb_message_element *e2, *elnew;
|
||||
|
||||
e2 = ldb_realloc_p(ldb, ret->elements, struct ldb_message_element, ret->num_elements+1);
|
||||
e2 = talloc_realloc_p(ret, ret->elements, struct ldb_message_element, ret->num_elements+1);
|
||||
if (!e2) {
|
||||
return -1;
|
||||
}
|
||||
@ -74,13 +55,13 @@ static int msg_add_element(struct ldb_context *ldb,
|
||||
|
||||
elnew = &e2[ret->num_elements];
|
||||
|
||||
elnew->name = ldb_strdup(ldb, el->name);
|
||||
elnew->name = talloc_strdup(ret->elements, el->name);
|
||||
if (!elnew->name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (el->num_values) {
|
||||
elnew->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
|
||||
elnew->values = talloc_array_p(ret->elements, struct ldb_val, el->num_values);
|
||||
if (!elnew->values) {
|
||||
return -1;
|
||||
}
|
||||
@ -89,7 +70,7 @@ static int msg_add_element(struct ldb_context *ldb,
|
||||
}
|
||||
|
||||
for (i=0;i<el->num_values;i++) {
|
||||
elnew->values[i] = ldb_val_dup(ldb, &el->values[i]);
|
||||
elnew->values[i] = ldb_val_dup(elnew->values, &el->values[i]);
|
||||
if (elnew->values[i].length != el->values[i].length) {
|
||||
return -1;
|
||||
}
|
||||
@ -136,24 +117,23 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
|
||||
struct ldb_message *ret;
|
||||
int i;
|
||||
|
||||
ret = ldb_malloc_p(ldb, struct ldb_message);
|
||||
ret = talloc_p(ldb, struct ldb_message);
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->dn = ldb_strdup(ldb, msg->dn);
|
||||
ret->dn = talloc_strdup(ret, msg->dn);
|
||||
if (!ret->dn) {
|
||||
ldb_free(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->num_elements = 0;
|
||||
ret->elements = NULL;
|
||||
ret->private_data = NULL;
|
||||
|
||||
if (!attrs) {
|
||||
if (msg_add_all_elements(module, ret, msg) != 0) {
|
||||
msg_free_all_parts(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
@ -164,7 +144,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
|
||||
|
||||
if (strcmp(attrs[i], "*") == 0) {
|
||||
if (msg_add_all_elements(module, ret, msg) != 0) {
|
||||
msg_free_all_parts(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
continue;
|
||||
@ -175,10 +155,9 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
|
||||
struct ldb_val val;
|
||||
|
||||
el2.flags = 0;
|
||||
el2.name = ldb_strdup(ldb, "dn");
|
||||
el2.name = talloc_strdup(ret, "dn");
|
||||
if (!el2.name) {
|
||||
msg_free_all_parts(ldb, ret);
|
||||
ldb_free(ldb, el2.name);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
el2.num_values = 1;
|
||||
@ -187,11 +166,10 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
|
||||
val.length = strlen(ret->dn);
|
||||
|
||||
if (msg_add_element(ldb, ret, &el2) != 0) {
|
||||
msg_free_all_parts(ldb, ret);
|
||||
ldb_free(ldb, el2.name);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ldb_free(ldb, el2.name);
|
||||
talloc_free(el2.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -200,7 +178,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module,
|
||||
continue;
|
||||
}
|
||||
if (msg_add_element(ldb, ret, el) != 0) {
|
||||
msg_free_all_parts(ldb, ret);
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -237,22 +215,6 @@ int ltdb_has_wildcard(struct ldb_module *module, const char *attr_name,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
free the results of a ltdb_search_dn1 search
|
||||
*/
|
||||
void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
unsigned int i;
|
||||
ldb_free(ldb, msg->private_data);
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
ldb_free(ldb, msg->elements[i].values);
|
||||
}
|
||||
ldb_free(ldb, msg->elements);
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
search the database for a single simple dn, returning all attributes
|
||||
in a single message
|
||||
@ -261,7 +223,6 @@ void ltdb_search_dn1_free(struct ldb_module *module, struct ldb_message *msg)
|
||||
*/
|
||||
int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_message *msg)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
int ret;
|
||||
TDB_DATA tdb_key, tdb_data, tdb_data2;
|
||||
@ -275,35 +236,32 @@ int ltdb_search_dn1(struct ldb_module *module, const char *dn, struct ldb_messag
|
||||
}
|
||||
|
||||
tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
if (!tdb_data.dptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tdb_data2.dptr = ldb_malloc(ldb, tdb_data.dsize);
|
||||
tdb_data2.dptr = talloc_memdup(msg, tdb_data.dptr, tdb_data.dsize);
|
||||
free(tdb_data.dptr);
|
||||
if (!tdb_data2.dptr) {
|
||||
free(tdb_data.dptr);
|
||||
return -1;
|
||||
}
|
||||
memcpy(tdb_data2.dptr, tdb_data.dptr, tdb_data.dsize);
|
||||
free(tdb_data.dptr);
|
||||
tdb_data2.dsize = tdb_data.dsize;
|
||||
|
||||
msg->private_data = tdb_data2.dptr;
|
||||
msg->num_elements = 0;
|
||||
msg->elements = NULL;
|
||||
|
||||
ret = ltdb_unpack_data(module, &tdb_data2, msg);
|
||||
if (ret == -1) {
|
||||
ldb_free(ldb, tdb_data2.dptr);
|
||||
talloc_free(tdb_data2.dptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!msg->dn) {
|
||||
msg->dn = ldb_strdup(ldb, dn);
|
||||
msg->dn = talloc_strdup(tdb_data2.dptr, dn);
|
||||
}
|
||||
if (!msg->dn) {
|
||||
ldb_free(ldb, tdb_data2.dptr);
|
||||
talloc_free(tdb_data2.dptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -319,24 +277,32 @@ int ltdb_search_dn(struct ldb_module *module, char *dn,
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
int ret;
|
||||
struct ldb_message msg, *msg2;
|
||||
struct ldb_message *msg, *msg2;
|
||||
|
||||
ret = ltdb_search_dn1(module, dn, &msg);
|
||||
if (ret != 1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
msg2 = ltdb_pull_attrs(module, &msg, attrs);
|
||||
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
|
||||
if (!msg2) {
|
||||
*res = talloc_array_p(ldb, struct ldb_message *, 2);
|
||||
if (! *res) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*res = ldb_malloc_array_p(ldb, struct ldb_message *, 2);
|
||||
if (! *res) {
|
||||
msg_free_all_parts(ldb, msg2);
|
||||
msg = talloc_p(*res, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
talloc_free(*res);
|
||||
*res = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_search_dn1(module, dn, msg);
|
||||
if (ret != 1) {
|
||||
talloc_free(*res);
|
||||
*res = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
msg2 = ltdb_pull_attrs(module, msg, attrs);
|
||||
|
||||
talloc_free(msg);
|
||||
|
||||
if (!msg2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -367,9 +333,9 @@ int ltdb_add_attr_results(struct ldb_module *module, struct ldb_message *msg,
|
||||
}
|
||||
|
||||
/* add to the results list */
|
||||
res2 = ldb_realloc_p(ldb, *res, struct ldb_message *, (*count)+2);
|
||||
res2 = talloc_realloc_p(ldb, *res, struct ldb_message *, (*count)+2);
|
||||
if (!res2) {
|
||||
msg_free_all_parts(ldb, msg2);
|
||||
talloc_free(msg2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -404,7 +370,7 @@ struct ltdb_search_info {
|
||||
static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state)
|
||||
{
|
||||
struct ltdb_search_info *sinfo = state;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
int ret;
|
||||
|
||||
if (key.dsize < 4 ||
|
||||
@ -412,31 +378,37 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
|
||||
return 0;
|
||||
}
|
||||
|
||||
msg = talloc_p(sinfo, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* unpack the record */
|
||||
ret = ltdb_unpack_data(sinfo->module, &data, &msg);
|
||||
ret = ltdb_unpack_data(sinfo->module, &data, msg);
|
||||
if (ret == -1) {
|
||||
sinfo->failures++;
|
||||
talloc_free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!msg.dn) {
|
||||
msg.dn = key.dptr + 3;
|
||||
if (!msg->dn) {
|
||||
msg->dn = key.dptr + 3;
|
||||
}
|
||||
|
||||
/* see if it matches the given expression */
|
||||
if (!ltdb_message_match(sinfo->module, &msg, sinfo->tree,
|
||||
sinfo->base, sinfo->scope)) {
|
||||
ltdb_unpack_data_free(sinfo->module, &msg);
|
||||
if (!ltdb_message_match(sinfo->module, msg, sinfo->tree,
|
||||
sinfo->base, sinfo->scope)) {
|
||||
talloc_free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ltdb_add_attr_results(sinfo->module, &msg, sinfo->attrs, &sinfo->count, &sinfo->msgs);
|
||||
ret = ltdb_add_attr_results(sinfo->module, msg, sinfo->attrs, &sinfo->count, &sinfo->msgs);
|
||||
|
||||
if (ret == -1) {
|
||||
sinfo->failures++;
|
||||
}
|
||||
|
||||
ltdb_unpack_data_free(sinfo->module, &msg);
|
||||
talloc_free(msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -447,19 +419,11 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
|
||||
*/
|
||||
int ltdb_search_free(struct ldb_module *module, struct ldb_message **msgs)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
int i;
|
||||
|
||||
ltdb->last_err_string = NULL;
|
||||
|
||||
if (!msgs) return 0;
|
||||
|
||||
for (i=0;msgs[i];i++) {
|
||||
msg_free_all_parts(ldb, msgs[i]);
|
||||
}
|
||||
|
||||
ldb_free(ldb, msgs);
|
||||
talloc_free(msgs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -475,27 +439,36 @@ static int ltdb_search_full(struct ldb_module *module,
|
||||
const char * const attrs[], struct ldb_message ***res)
|
||||
{
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
int ret;
|
||||
struct ltdb_search_info sinfo;
|
||||
int ret, count;
|
||||
struct ltdb_search_info *sinfo;
|
||||
|
||||
sinfo.tree = tree;
|
||||
sinfo.module = module;
|
||||
sinfo.scope = scope;
|
||||
sinfo.base = base;
|
||||
sinfo.attrs = attrs;
|
||||
sinfo.msgs = NULL;
|
||||
sinfo.count = 0;
|
||||
sinfo.failures = 0;
|
||||
|
||||
ret = tdb_traverse(ltdb->tdb, search_func, &sinfo);
|
||||
|
||||
if (ret == -1) {
|
||||
ltdb_search_free(module, sinfo.msgs);
|
||||
sinfo = talloc_p(ltdb, struct ltdb_search_info);
|
||||
if (sinfo == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*res = sinfo.msgs;
|
||||
return sinfo.count;
|
||||
sinfo->tree = tree;
|
||||
sinfo->module = module;
|
||||
sinfo->scope = scope;
|
||||
sinfo->base = base;
|
||||
sinfo->attrs = attrs;
|
||||
sinfo->msgs = NULL;
|
||||
sinfo->count = 0;
|
||||
sinfo->failures = 0;
|
||||
|
||||
ret = tdb_traverse(ltdb->tdb, search_func, sinfo);
|
||||
|
||||
if (ret == -1) {
|
||||
talloc_free(sinfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*res = talloc_steal(ltdb, sinfo->msgs);
|
||||
count = sinfo->count;
|
||||
|
||||
talloc_free(sinfo);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -75,7 +75,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
|
||||
if (strncmp(dn, prefix, strlen(prefix)) == 0 &&
|
||||
(s = strchr(dn+strlen(prefix), ':'))) {
|
||||
char *attr_name, *attr_name_folded;
|
||||
attr_name = ldb_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix))));
|
||||
attr_name = talloc_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix))));
|
||||
if (!attr_name) {
|
||||
goto failed;
|
||||
}
|
||||
@ -88,12 +88,12 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
|
||||
if (!attr_name_folded) {
|
||||
goto failed;
|
||||
}
|
||||
ldb_asprintf(ldb, &dn_folded, "%s:%s:%s",
|
||||
prefix, attr_name_folded,
|
||||
s+1);
|
||||
ldb_free(ldb, attr_name_folded);
|
||||
dn_folded = talloc_asprintf(ldb, "%s:%s:%s",
|
||||
prefix, attr_name_folded,
|
||||
s+1);
|
||||
talloc_free(attr_name_folded);
|
||||
}
|
||||
ldb_free(ldb, attr_name);
|
||||
talloc_free(attr_name);
|
||||
} else {
|
||||
dn_folded = ldb_casefold(ldb, dn);
|
||||
}
|
||||
@ -102,8 +102,8 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, const char *dn)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded);
|
||||
ldb_free(ldb, dn_folded);
|
||||
key_str = talloc_asprintf(ldb, "DN=%s", dn_folded);
|
||||
talloc_free(dn_folded);
|
||||
|
||||
if (!key_str) {
|
||||
goto failed;
|
||||
@ -126,7 +126,6 @@ failed:
|
||||
*/
|
||||
static int ltdb_lock(struct ldb_module *module, const char *lockname)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
TDB_DATA key;
|
||||
int ret;
|
||||
@ -142,7 +141,7 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname)
|
||||
|
||||
ret = tdb_chainlock(ltdb->tdb, key);
|
||||
|
||||
ldb_free(ldb, key.dptr);
|
||||
talloc_free(key.dptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -152,7 +151,6 @@ static int ltdb_lock(struct ldb_module *module, const char *lockname)
|
||||
*/
|
||||
static int ltdb_unlock(struct ldb_module *module, const char *lockname)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
TDB_DATA key;
|
||||
|
||||
@ -167,7 +165,7 @@ static int ltdb_unlock(struct ldb_module *module, const char *lockname)
|
||||
|
||||
tdb_chainunlock(ltdb->tdb, key);
|
||||
|
||||
ldb_free(ldb, key.dptr);
|
||||
talloc_free(key.dptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -199,7 +197,6 @@ static int ltdb_modified(struct ldb_module *module, const char *dn)
|
||||
*/
|
||||
int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flgs)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
TDB_DATA tdb_key, tdb_data;
|
||||
int ret;
|
||||
@ -211,7 +208,7 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
|
||||
|
||||
ret = ltdb_pack_data(module, msg, &tdb_data);
|
||||
if (ret == -1) {
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -226,8 +223,8 @@ int ltdb_store(struct ldb_module *module, const struct ldb_message *msg, int flg
|
||||
}
|
||||
|
||||
done:
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
ldb_free(ldb, tdb_data.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
talloc_free(tdb_data.dptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -269,7 +266,6 @@ static int ltdb_add(struct ldb_module *module, const struct ldb_message *msg)
|
||||
*/
|
||||
int ltdb_delete_noindex(struct ldb_module *module, const char *dn)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
TDB_DATA tdb_key;
|
||||
int ret;
|
||||
@ -280,7 +276,7 @@ int ltdb_delete_noindex(struct ldb_module *module, const char *dn)
|
||||
}
|
||||
|
||||
ret = tdb_delete(ltdb->tdb, tdb_key);
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -292,7 +288,7 @@ static int ltdb_delete(struct ldb_module *module, const char *dn)
|
||||
{
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
int ret;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg = NULL;
|
||||
|
||||
ltdb->last_err_string = NULL;
|
||||
|
||||
@ -301,13 +297,17 @@ static int ltdb_delete(struct ldb_module *module, const char *dn)
|
||||
}
|
||||
|
||||
if (ltdb_cache_load(module) != 0) {
|
||||
ltdb_unlock(module, LDBLOCK);
|
||||
return -1;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
msg = talloc_p(module, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* in case any attribute of the message was indexed, we need
|
||||
to fetch the old record */
|
||||
ret = ltdb_search_dn1(module, dn, &msg);
|
||||
ret = ltdb_search_dn1(module, dn, msg);
|
||||
if (ret != 1) {
|
||||
/* not finding the old record is an error */
|
||||
goto failed;
|
||||
@ -315,23 +315,22 @@ static int ltdb_delete(struct ldb_module *module, const char *dn)
|
||||
|
||||
ret = ltdb_delete_noindex(module, dn);
|
||||
if (ret == -1) {
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* remove any indexed attributes */
|
||||
ret = ltdb_index_del(module, &msg);
|
||||
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
ret = ltdb_index_del(module, msg);
|
||||
|
||||
if (ret == 0) {
|
||||
ltdb_modified(module, dn);
|
||||
}
|
||||
|
||||
talloc_free(msg);
|
||||
ltdb_unlock(module, LDBLOCK);
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
talloc_free(msg);
|
||||
ltdb_unlock(module, LDBLOCK);
|
||||
return -1;
|
||||
}
|
||||
@ -369,8 +368,8 @@ static int msg_add_element(struct ldb_context *ldb,
|
||||
struct ldb_message_element *e2;
|
||||
unsigned int i;
|
||||
|
||||
e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
|
||||
msg->num_elements+1);
|
||||
e2 = talloc_realloc_p(msg, msg->elements, struct ldb_message_element,
|
||||
msg->num_elements+1);
|
||||
if (!e2) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -384,7 +383,7 @@ static int msg_add_element(struct ldb_context *ldb,
|
||||
e2->flags = el->flags;
|
||||
e2->values = NULL;
|
||||
if (el->num_values != 0) {
|
||||
e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
|
||||
e2->values = talloc_array_p(msg->elements, struct ldb_val, el->num_values);
|
||||
if (!e2->values) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
@ -407,30 +406,28 @@ static int msg_delete_attribute(struct ldb_module *module,
|
||||
struct ldb_context *ldb,
|
||||
struct ldb_message *msg, const char *name)
|
||||
{
|
||||
unsigned int i, j, count=0;
|
||||
struct ldb_message_element *el2;
|
||||
|
||||
el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
|
||||
if (!el2) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
unsigned int i, j;
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
|
||||
el2[count++] = msg->elements[i];
|
||||
} else {
|
||||
if (ldb_attr_cmp(msg->elements[i].name, name) == 0) {
|
||||
for (j=0;j<msg->elements[i].num_values;j++) {
|
||||
ltdb_index_del_value(module, msg->dn, &msg->elements[i], j);
|
||||
}
|
||||
ldb_free(ldb, msg->elements[i].values);
|
||||
talloc_free(msg->elements[i].values);
|
||||
if (msg->num_elements > (i+1)) {
|
||||
memmove(&msg->elements[i],
|
||||
&msg->elements[i+1],
|
||||
sizeof(struct ldb_message_element)*
|
||||
(msg->num_elements - (i+1)));
|
||||
}
|
||||
msg->num_elements--;
|
||||
i--;
|
||||
msg->elements = talloc_realloc_p(msg, msg->elements,
|
||||
struct ldb_message_element,
|
||||
msg->num_elements);
|
||||
}
|
||||
}
|
||||
|
||||
msg->num_elements = count;
|
||||
ldb_free(ldb, msg->elements);
|
||||
msg->elements = el2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -486,7 +483,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
TDB_DATA tdb_key, tdb_data;
|
||||
struct ldb_message msg2;
|
||||
struct ldb_message *msg2;
|
||||
unsigned i, j;
|
||||
int ret;
|
||||
|
||||
@ -497,19 +494,25 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
|
||||
tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
|
||||
if (!tdb_data.dptr) {
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_unpack_data(module, &tdb_data, &msg2);
|
||||
msg2 = talloc_p(tdb_key.dptr, struct ldb_message);
|
||||
if (msg2 == NULL) {
|
||||
talloc_free(tdb_key.dptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ltdb_unpack_data(module, &tdb_data, msg2);
|
||||
if (ret == -1) {
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
free(tdb_data.dptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!msg2.dn) {
|
||||
msg2.dn = msg->dn;
|
||||
if (!msg2->dn) {
|
||||
msg2->dn = msg->dn;
|
||||
}
|
||||
|
||||
for (i=0;i<msg->num_elements;i++) {
|
||||
@ -522,16 +525,16 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
case LDB_FLAG_MOD_ADD:
|
||||
/* add this element to the message. fail if it
|
||||
already exists */
|
||||
ret = find_element(&msg2, el->name);
|
||||
ret = find_element(msg2, el->name);
|
||||
|
||||
if (ret == -1) {
|
||||
if (msg_add_element(ldb, &msg2, el) != 0) {
|
||||
if (msg_add_element(ldb, msg2, el) != 0) {
|
||||
goto failed;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
el2 = &msg2.elements[ret];
|
||||
el2 = &msg2->elements[ret];
|
||||
|
||||
/* An attribute with this name already exists, add all
|
||||
* values if they don't already exist. */
|
||||
@ -544,15 +547,15 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
}
|
||||
}
|
||||
|
||||
vals = ldb_realloc_p(ldb, el2->values, struct ldb_val,
|
||||
el2->num_values + el->num_values);
|
||||
vals = talloc_realloc_p(msg2->elements, el2->values, struct ldb_val,
|
||||
el2->num_values + el->num_values);
|
||||
|
||||
if (vals == NULL)
|
||||
goto failed;
|
||||
|
||||
for (j=0;j<el->num_values;j++) {
|
||||
vals[el2->num_values + j] =
|
||||
ldb_val_dup(ldb, &el->values[j]);
|
||||
ldb_val_dup(vals, &el->values[j]);
|
||||
}
|
||||
|
||||
el2->values = vals;
|
||||
@ -563,11 +566,11 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
case LDB_FLAG_MOD_REPLACE:
|
||||
/* replace all elements of this attribute name with the elements
|
||||
listed. The attribute not existing is not an error */
|
||||
msg_delete_attribute(module, ldb, &msg2, msg->elements[i].name);
|
||||
msg_delete_attribute(module, ldb, msg2, msg->elements[i].name);
|
||||
|
||||
/* add the replacement element, if not empty */
|
||||
if (msg->elements[i].num_values != 0 &&
|
||||
msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
|
||||
msg_add_element(ldb, msg2, &msg->elements[i]) != 0) {
|
||||
goto failed;
|
||||
}
|
||||
break;
|
||||
@ -576,7 +579,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
/* we could be being asked to delete all
|
||||
values or just some values */
|
||||
if (msg->elements[i].num_values == 0) {
|
||||
if (msg_delete_attribute(module, ldb, &msg2,
|
||||
if (msg_delete_attribute(module, ldb, msg2,
|
||||
msg->elements[i].name) != 0) {
|
||||
ltdb->last_err_string = "No such attribute";
|
||||
goto failed;
|
||||
@ -585,7 +588,7 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
}
|
||||
for (j=0;j<msg->elements[i].num_values;j++) {
|
||||
if (msg_delete_element(module,
|
||||
&msg2,
|
||||
msg2,
|
||||
msg->elements[i].name,
|
||||
&msg->elements[i].values[j]) != 0) {
|
||||
ltdb->last_err_string = "No such attribute";
|
||||
@ -600,17 +603,15 @@ int ltdb_modify_internal(struct ldb_module *module, const struct ldb_message *ms
|
||||
}
|
||||
|
||||
/* we've made all the mods - save the modified record back into the database */
|
||||
ret = ltdb_store(module, &msg2, TDB_MODIFY);
|
||||
ret = ltdb_store(module, msg2, TDB_MODIFY);
|
||||
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
free(tdb_data.dptr);
|
||||
ltdb_unpack_data_free(module, &msg2);
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
ldb_free(ldb, tdb_key.dptr);
|
||||
talloc_free(tdb_key.dptr);
|
||||
free(tdb_data.dptr);
|
||||
ltdb_unpack_data_free(module, &msg2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -649,10 +650,9 @@ static int ltdb_modify(struct ldb_module *module, const struct ldb_message *msg)
|
||||
*/
|
||||
static int ltdb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
int ret;
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
const char *error_str;
|
||||
|
||||
ltdb->last_err_string = NULL;
|
||||
@ -661,28 +661,28 @@ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg = talloc_p(module, struct ldb_message);
|
||||
if (msg == NULL) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* in case any attribute of the message was indexed, we need
|
||||
to fetch the old record */
|
||||
ret = ltdb_search_dn1(module, olddn, &msg);
|
||||
ret = ltdb_search_dn1(module, olddn, msg);
|
||||
if (ret != 1) {
|
||||
/* not finding the old record is an error */
|
||||
goto failed;
|
||||
}
|
||||
|
||||
msg.dn = ldb_strdup(ldb,newdn);
|
||||
if (!msg.dn) {
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
msg->dn = talloc_strdup(msg, newdn);
|
||||
if (!msg->dn) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ret = ltdb_add(module, &msg);
|
||||
ret = ltdb_add(module, msg);
|
||||
if (ret == -1) {
|
||||
ldb_free(ldb, msg.dn);
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
goto failed;
|
||||
}
|
||||
ldb_free(ldb, msg.dn);
|
||||
ltdb_search_dn1_free(module, &msg);
|
||||
|
||||
ret = ltdb_delete(module, olddn);
|
||||
error_str = ltdb->last_err_string;
|
||||
@ -692,10 +692,13 @@ static int ltdb_rename(struct ldb_module *module, const char *olddn, const char
|
||||
|
||||
ltdb->last_err_string = error_str;
|
||||
|
||||
talloc_free(msg);
|
||||
ltdb_unlock(module, LDBLOCK);
|
||||
|
||||
return ret;
|
||||
|
||||
failed:
|
||||
talloc_free(msg);
|
||||
ltdb_unlock(module, LDBLOCK);
|
||||
return -1;
|
||||
}
|
||||
@ -706,18 +709,8 @@ failed:
|
||||
static int ltdb_close(struct ldb_module *module)
|
||||
{
|
||||
struct ldb_context *ldb = module->ldb;
|
||||
struct ltdb_private *ltdb = module->private_data;
|
||||
int ret;
|
||||
|
||||
ltdb->last_err_string = NULL;
|
||||
|
||||
ltdb_cache_free(module);
|
||||
ldb_set_alloc(ldb, NULL, NULL);
|
||||
|
||||
ret = tdb_close(ltdb->tdb);
|
||||
ldb_free(ldb, ltdb);
|
||||
free(ldb);
|
||||
return ret;
|
||||
talloc_free(ldb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -745,11 +738,20 @@ static const struct ldb_module_ops ltdb_ops = {
|
||||
ltdb_rename,
|
||||
ltdb_lock,
|
||||
ltdb_unlock,
|
||||
ltdb_errstring,
|
||||
ltdb_cache_free
|
||||
ltdb_errstring
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
destroy the ltdb context
|
||||
*/
|
||||
static int ltdb_destructor(void *p)
|
||||
{
|
||||
struct ltdb_private *ltdb = p;
|
||||
tdb_close(ltdb->tdb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
connect to the database
|
||||
*/
|
||||
@ -763,7 +765,7 @@ struct ldb_context *ltdb_connect(const char *url,
|
||||
TDB_CONTEXT *tdb;
|
||||
struct ldb_context *ldb;
|
||||
|
||||
ldb = calloc(1, sizeof(struct ldb_context));
|
||||
ldb = talloc_zero_p(NULL, struct ldb_context);
|
||||
if (!ldb) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
@ -773,6 +775,7 @@ struct ldb_context *ltdb_connect(const char *url,
|
||||
if (strchr(url, ':')) {
|
||||
if (strncmp(url, "tdb://", 6) != 0) {
|
||||
errno = EINVAL;
|
||||
talloc_free(ldb);
|
||||
return NULL;
|
||||
}
|
||||
path = url+6;
|
||||
@ -791,14 +794,14 @@ struct ldb_context *ltdb_connect(const char *url,
|
||||
/* note that we use quite a large default hash size */
|
||||
tdb = tdb_open(path, 10000, tdb_flags, open_flags, 0666);
|
||||
if (!tdb) {
|
||||
free(ldb);
|
||||
talloc_free(ldb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ltdb = ldb_malloc_p(ldb, struct ltdb_private);
|
||||
ltdb = talloc_zero_p(ldb, struct ltdb_private);
|
||||
if (!ltdb) {
|
||||
tdb_close(tdb);
|
||||
free(ldb);
|
||||
talloc_free(ldb);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
@ -806,12 +809,11 @@ struct ldb_context *ltdb_connect(const char *url,
|
||||
ltdb->tdb = tdb;
|
||||
ltdb->sequence_number = 0;
|
||||
|
||||
memset(<db->cache, 0, sizeof(ltdb->cache));
|
||||
talloc_set_destructor(ltdb, ltdb_destructor);
|
||||
|
||||
ldb->modules = ldb_malloc_p(ldb, struct ldb_module);
|
||||
ldb->modules = talloc_p(ldb, struct ldb_module);
|
||||
if (!ldb->modules) {
|
||||
tdb_close(tdb);
|
||||
free(ldb);
|
||||
talloc_free(ldb);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -13,17 +13,17 @@ struct ltdb_private {
|
||||
handling. It has plenty of digits of precision */
|
||||
double sequence_number;
|
||||
|
||||
struct {
|
||||
struct ldb_message baseinfo;
|
||||
struct ldb_message indexlist;
|
||||
struct ldb_message attributes;
|
||||
struct ldb_message subclasses;
|
||||
struct ltdb_cache {
|
||||
struct ldb_message *baseinfo;
|
||||
struct ldb_message *indexlist;
|
||||
struct ldb_message *attributes;
|
||||
struct ldb_message *subclasses;
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
int flags;
|
||||
} last_attribute;
|
||||
} cache;
|
||||
} *cache;
|
||||
|
||||
/* error if an internal ldb+tdb error */
|
||||
const char *last_err_string;
|
||||
@ -51,7 +51,7 @@ struct ltdb_private {
|
||||
|
||||
/* The following definitions come from lib/ldb/ldb_tdb/ldb_cache.c */
|
||||
|
||||
void ltdb_cache_free(struct ldb_module *module);
|
||||
int ltdb_cache_reload(struct ldb_module *module);
|
||||
int ltdb_cache_load(struct ldb_module *module);
|
||||
int ltdb_increase_sequence_number(struct ldb_module *module);
|
||||
int ltdb_attribute_flags(struct ldb_module *module, const char *attr_name);
|
||||
|
@ -98,11 +98,6 @@ static const char *skel_errstring(struct ldb_module *module)
|
||||
return ldb_next_errstring(module);
|
||||
}
|
||||
|
||||
static void skel_cache_free(struct ldb_module *module)
|
||||
{
|
||||
ldb_next_cache_free(module);
|
||||
}
|
||||
|
||||
static const struct ldb_module_ops skel_ops = {
|
||||
"skel",
|
||||
skel_close,
|
||||
@ -114,8 +109,7 @@ static const struct ldb_module_ops skel_ops = {
|
||||
skel_rename_record,
|
||||
skel_named_lock,
|
||||
skel_named_unlock,
|
||||
skel_errstring,
|
||||
skel_cache_free
|
||||
skel_errstring
|
||||
};
|
||||
|
||||
#ifdef HAVE_DLOPEN
|
||||
|
@ -57,7 +57,8 @@ static int timestamps_search_free(struct ldb_module *module, struct ldb_message
|
||||
return ldb_next_search_free(module, res);
|
||||
}
|
||||
|
||||
static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg, const char *attr_name, const char *time_string, unsigned int flags)
|
||||
static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg,
|
||||
const char *attr_name, const char *time_string, unsigned int flags)
|
||||
{
|
||||
struct ldb_val *values;
|
||||
char *name, *timestr;
|
||||
@ -69,10 +70,11 @@ static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg, co
|
||||
}
|
||||
}
|
||||
|
||||
msg->elements = ldb_realloc_array(ldb, msg->elements, sizeof(struct ldb_message_element), msg->num_elements + 1);
|
||||
name = ldb_strdup(ldb, attr_name);
|
||||
timestr = ldb_strdup(ldb, time_string);
|
||||
values = ldb_malloc(ldb, sizeof(struct ldb_val));
|
||||
msg->elements = talloc_realloc_p(msg, msg->elements,
|
||||
struct ldb_message_element, msg->num_elements + 1);
|
||||
name = talloc_strdup(msg->elements, attr_name);
|
||||
timestr = talloc_strdup(msg->elements, time_string);
|
||||
values = talloc_p(msg->elements, struct ldb_val);
|
||||
if (!msg->elements || !name || !timestr || !values) {
|
||||
return -1;
|
||||
}
|
||||
@ -89,19 +91,6 @@ static int add_time_element(struct ldb_context *ldb, struct ldb_message *msg, co
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_elements(struct ldb_context *ldb, struct ldb_message *msg, int real_el_num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = real_el_num; i < msg->num_elements; i++) {
|
||||
ldb_free(ldb, msg->elements[i].name);
|
||||
ldb_free(ldb, msg->elements[i].values[0].data);
|
||||
ldb_free(ldb, msg->elements[i].values);
|
||||
}
|
||||
ldb_free(ldb, msg->elements);
|
||||
ldb_free(ldb, msg);
|
||||
}
|
||||
|
||||
/* add_record: add crateTimestamp/modifyTimestamp attributes */
|
||||
static int timestamps_add_record(struct ldb_module *module, const struct ldb_message *msg)
|
||||
{
|
||||
@ -120,25 +109,24 @@ static int timestamps_add_record(struct ldb_module *module, const struct ldb_mes
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* formatted like: 20040408072012.0Z */
|
||||
ldb_asprintf(module->ldb, ×tr,
|
||||
"%04u%02u%02u%02u%02u%02u.0Z",
|
||||
tm->tm_year+1900, tm->tm_mon+1,
|
||||
tm->tm_mday, tm->tm_hour, tm->tm_min,
|
||||
tm->tm_sec);
|
||||
msg2 = talloc_p(module, struct ldb_message);
|
||||
if (!msg2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* formatted like: 20040408072012.0Z */
|
||||
timestr = talloc_asprintf(msg2, "%04u%02u%02u%02u%02u%02u.0Z",
|
||||
tm->tm_year+1900, tm->tm_mon+1,
|
||||
tm->tm_mday, tm->tm_hour, tm->tm_min,
|
||||
tm->tm_sec);
|
||||
if (!timestr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg2 = ldb_malloc_p(module->ldb, struct ldb_message);
|
||||
if (!msg2) {
|
||||
return -1;
|
||||
}
|
||||
msg2->dn = msg->dn;
|
||||
msg2->num_elements = msg->num_elements;
|
||||
msg2->private_data = msg->private_data;
|
||||
msg2->elements = ldb_malloc_array_p(module->ldb, struct ldb_message_element, msg2->num_elements);
|
||||
msg2->elements = talloc_array_p(msg2, struct ldb_message_element, msg2->num_elements);
|
||||
for (i = 0; i < msg2->num_elements; i++) {
|
||||
msg2->elements[i] = msg->elements[i];
|
||||
}
|
||||
@ -147,13 +135,11 @@ static int timestamps_add_record(struct ldb_module *module, const struct ldb_mes
|
||||
add_time_element(module->ldb, msg2, "modifyTimestamp", timestr, LDB_FLAG_MOD_ADD);
|
||||
add_time_element(module->ldb, msg2, "whenCreated", timestr, LDB_FLAG_MOD_ADD);
|
||||
add_time_element(module->ldb, msg2, "whenChanged", timestr, LDB_FLAG_MOD_ADD);
|
||||
|
||||
ldb_free(module->ldb, timestr);
|
||||
}
|
||||
|
||||
if (msg2) {
|
||||
ret = ldb_next_add_record(module, msg2);
|
||||
free_elements(module->ldb, msg2, msg->num_elements);
|
||||
talloc_free(msg2);
|
||||
} else {
|
||||
ret = ldb_next_add_record(module, msg);
|
||||
}
|
||||
@ -179,38 +165,36 @@ static int timestamps_modify_record(struct ldb_module *module, const struct ldb_
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg2 = talloc_p(module, struct ldb_message);
|
||||
if (!msg2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* formatted like: 20040408072012.0Z */
|
||||
ldb_asprintf(module->ldb, ×tr,
|
||||
timestr = talloc_asprintf(msg2,
|
||||
"%04u%02u%02u%02u%02u%02u.0Z",
|
||||
tm->tm_year+1900, tm->tm_mon+1,
|
||||
tm->tm_mday, tm->tm_hour, tm->tm_min,
|
||||
tm->tm_sec);
|
||||
|
||||
if (!timestr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg2 = ldb_malloc_p(module->ldb, struct ldb_message);
|
||||
if (!msg2) {
|
||||
return -1;
|
||||
}
|
||||
msg2->dn = msg->dn;
|
||||
msg2->num_elements = msg->num_elements;
|
||||
msg2->private_data = msg->private_data;
|
||||
msg2->elements = ldb_malloc_array_p(module->ldb, struct ldb_message_element, msg2->num_elements);
|
||||
msg2->elements = talloc_array_p(msg2, struct ldb_message_element, msg2->num_elements);
|
||||
for (i = 0; i < msg2->num_elements; i++) {
|
||||
msg2->elements[i] = msg->elements[i];
|
||||
}
|
||||
|
||||
add_time_element(module->ldb, msg2, "modifyTimestamp", timestr, LDB_FLAG_MOD_REPLACE);
|
||||
add_time_element(module->ldb, msg2, "whenChanged", timestr, LDB_FLAG_MOD_REPLACE);
|
||||
|
||||
ldb_free(module->ldb, timestr);
|
||||
}
|
||||
|
||||
if (msg2) {
|
||||
ret = ldb_next_modify_record(module, msg2);
|
||||
free_elements(module->ldb, msg2, msg->num_elements);
|
||||
talloc_free(msg2);
|
||||
} else {
|
||||
ret = ldb_next_modify_record(module, msg);
|
||||
}
|
||||
@ -249,12 +233,6 @@ static const char *timestamps_errstring(struct ldb_module *module)
|
||||
return ldb_next_errstring(module);
|
||||
}
|
||||
|
||||
static void timestamps_cache_free(struct ldb_module *module)
|
||||
{
|
||||
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "timestamps_cache_free\n");
|
||||
ldb_next_cache_free(module);
|
||||
}
|
||||
|
||||
static const struct ldb_module_ops timestamps_ops = {
|
||||
"timestamps",
|
||||
timestamps_close,
|
||||
@ -266,8 +244,7 @@ static const struct ldb_module_ops timestamps_ops = {
|
||||
timestamps_rename_record,
|
||||
timestamps_lock,
|
||||
timestamps_unlock,
|
||||
timestamps_errstring,
|
||||
timestamps_cache_free
|
||||
timestamps_errstring
|
||||
};
|
||||
|
||||
|
||||
@ -280,7 +257,7 @@ struct ldb_module *timestamps_module_init(struct ldb_context *ldb, const char *o
|
||||
{
|
||||
struct ldb_module *ctx;
|
||||
|
||||
ctx = (struct ldb_module *)malloc(sizeof(struct ldb_module));
|
||||
ctx = talloc_p(ldb, struct ldb_module);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
|
@ -25,6 +25,14 @@ time $VALGRIND bin/ldbtest -r 1000 -s 10 || exit 1
|
||||
echo "Adding index"
|
||||
$VALGRIND bin/ldbadd tests/test-index.ldif || exit 1
|
||||
|
||||
echo "testing indexed search"
|
||||
$VALGRIND bin/ldbsearch '(uid=uham)' || exit 1
|
||||
$VALGRIND bin/ldbsearch '(&(uid=uham)(uid=uham))' || exit 1
|
||||
$VALGRIND bin/ldbsearch '(|(uid=uham)(uid=uham))' || exit 1
|
||||
$VALGRIND bin/ldbsearch '(|(uid=uham)(uid=uham)(objectclass=OpenLDAPperson))' || exit 1
|
||||
$VALGRIND bin/ldbsearch '(&(uid=uham)(uid=uham)(!(objectclass=xxx)))' || exit 1
|
||||
$VALGRIND bin/ldbsearch '(&(uid=uham)(!(uid=uhamxx)))' || exit 1
|
||||
|
||||
echo "Starting ldbtest indexed"
|
||||
time $VALGRIND bin/ldbtest -r 1000 -s 5000 || exit 1
|
||||
|
||||
|
@ -66,10 +66,10 @@ static int process_file(struct ldb_context *ldb, FILE *f)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ldb_add(ldb, &ldif->msg);
|
||||
ret = ldb_add(ldb, ldif->msg);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "ERR: \"%s\" on DN %s\n",
|
||||
ldb_errstring(ldb), ldif->msg.dn);
|
||||
ldb_errstring(ldb), ldif->msg->dn);
|
||||
failures++;
|
||||
} else {
|
||||
count++;
|
||||
|
@ -48,7 +48,7 @@ static void ldif_write_msg(struct ldb_context *ldb,
|
||||
{
|
||||
struct ldb_ldif ldif;
|
||||
ldif.changetype = changetype;
|
||||
ldif.msg = *msg;
|
||||
ldif.msg = msg;
|
||||
ldb_ldif_write_file(ldb, f, &ldif);
|
||||
}
|
||||
|
||||
@ -60,14 +60,16 @@ static int modify_record(struct ldb_context *ldb,
|
||||
struct ldb_message *msg1,
|
||||
struct ldb_message *msg2)
|
||||
{
|
||||
struct ldb_message mod;
|
||||
struct ldb_message *mod;
|
||||
struct ldb_message_element *el;
|
||||
unsigned int i;
|
||||
int count = 0;
|
||||
|
||||
mod.dn = msg1->dn;
|
||||
mod.num_elements = 0;
|
||||
mod.elements = NULL;
|
||||
mod = ldb_msg_new(ldb);
|
||||
|
||||
mod->dn = msg1->dn;
|
||||
mod->num_elements = 0;
|
||||
mod->elements = NULL;
|
||||
|
||||
msg2 = ldb_msg_canonicalize(ldb, msg2);
|
||||
if (msg2 == NULL) {
|
||||
@ -84,7 +86,7 @@ static int modify_record(struct ldb_context *ldb,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ldb_msg_add(ldb, &mod,
|
||||
if (ldb_msg_add(ldb, mod,
|
||||
&msg2->elements[i],
|
||||
el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) {
|
||||
return -1;
|
||||
@ -96,7 +98,7 @@ static int modify_record(struct ldb_context *ldb,
|
||||
for (i=0;i<msg1->num_elements;i++) {
|
||||
el = ldb_msg_find_element(msg2, msg1->elements[i].name);
|
||||
if (!el) {
|
||||
if (ldb_msg_add_empty(ldb, &mod,
|
||||
if (ldb_msg_add_empty(ldb, mod,
|
||||
msg1->elements[i].name,
|
||||
LDB_FLAG_MOD_DELETE) != 0) {
|
||||
return -1;
|
||||
@ -105,18 +107,18 @@ static int modify_record(struct ldb_context *ldb,
|
||||
}
|
||||
}
|
||||
|
||||
if (mod.num_elements == 0) {
|
||||
if (mod->num_elements == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ldb_modify(ldb, &mod) != 0) {
|
||||
if (ldb_modify(ldb, mod) != 0) {
|
||||
fprintf(stderr, "failed to modify %s - %s\n",
|
||||
msg1->dn, ldb_errstring(ldb));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (verbose > 0) {
|
||||
ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, &mod);
|
||||
ldif_write_msg(ldb, stdout, LDB_CHANGETYPE_MODIFY, mod);
|
||||
}
|
||||
|
||||
return count;
|
||||
@ -205,7 +207,7 @@ static int save_ldif(struct ldb_context *ldb,
|
||||
fprintf(f, "# record %d\n", i+1);
|
||||
|
||||
ldif.changetype = LDB_CHANGETYPE_NONE;
|
||||
ldif.msg = *msgs[i];
|
||||
ldif.msg = msgs[i];
|
||||
|
||||
ldb_ldif_write_file(ldb, f, &ldif);
|
||||
}
|
||||
@ -278,12 +280,12 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun
|
||||
}
|
||||
|
||||
while ((ldif = ldb_ldif_read_file(ldb, f))) {
|
||||
msgs2 = ldb_realloc_p(ldb, msgs2, struct ldb_message *, count2+1);
|
||||
msgs2 = talloc_realloc_p(ldb, msgs2, struct ldb_message *, count2+1);
|
||||
if (!msgs2) {
|
||||
fprintf(stderr, "out of memory");
|
||||
return -1;
|
||||
}
|
||||
msgs2[count2++] = &ldif->msg;
|
||||
msgs2[count2++] = ldif->msg;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
@ -62,18 +62,18 @@ static int process_file(struct ldb_context *ldb, FILE *f)
|
||||
switch (ldif->changetype) {
|
||||
case LDB_CHANGETYPE_NONE:
|
||||
case LDB_CHANGETYPE_ADD:
|
||||
ret = ldb_add(ldb, &ldif->msg);
|
||||
ret = ldb_add(ldb, ldif->msg);
|
||||
break;
|
||||
case LDB_CHANGETYPE_DELETE:
|
||||
ret = ldb_delete(ldb, ldif->msg.dn);
|
||||
ret = ldb_delete(ldb, ldif->msg->dn);
|
||||
break;
|
||||
case LDB_CHANGETYPE_MODIFY:
|
||||
ret = ldb_modify(ldb, &ldif->msg);
|
||||
ret = ldb_modify(ldb, ldif->msg);
|
||||
break;
|
||||
}
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "ERR: \"%s\" on DN %s\n",
|
||||
ldb_errstring(ldb), ldif->msg.dn);
|
||||
ldb_errstring(ldb), ldif->msg->dn);
|
||||
failures++;
|
||||
} else {
|
||||
count++;
|
||||
|
@ -71,7 +71,7 @@ static int do_search(struct ldb_context *ldb,
|
||||
printf("# record %d\n", i+1);
|
||||
|
||||
ldif.changetype = LDB_CHANGETYPE_NONE;
|
||||
ldif.msg = *msgs[i];
|
||||
ldif.msg = msgs[i];
|
||||
|
||||
ldb_ldif_write_file(ldb, stdout, &ldif);
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ static void add_records(struct ldb_context *ldb,
|
||||
free(name);
|
||||
free(msg.dn);
|
||||
free(vals[1][0].data);
|
||||
ldb_free(ldb, vals[2][0].data);
|
||||
talloc_free(vals[2][0].data);
|
||||
free(vals[3][0].data);
|
||||
free(vals[4][0].data);
|
||||
}
|
||||
@ -288,7 +288,7 @@ be indexed
|
||||
*/
|
||||
static void start_test_index(struct ldb_context **ldb)
|
||||
{
|
||||
struct ldb_message msg;
|
||||
struct ldb_message *msg;
|
||||
struct ldb_message **res;
|
||||
int ret;
|
||||
|
||||
@ -296,24 +296,25 @@ static void start_test_index(struct ldb_context **ldb)
|
||||
|
||||
ldb_delete(*ldb, "@INDEXLIST");
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.dn = strdup("@INDEXLIST");
|
||||
ldb_msg_add_string(*ldb, &msg, "@IDXATTR", strdup("uid"));
|
||||
msg = ldb_msg_new(NULL);
|
||||
|
||||
if (ldb_add(*ldb, &msg) != 0) {
|
||||
printf("Add of %s failed - %s\n", msg.dn, ldb_errstring(*ldb));
|
||||
msg->dn = strdup("@INDEXLIST");
|
||||
ldb_msg_add_string(*ldb, msg, "@IDXATTR", strdup("uid"));
|
||||
|
||||
if (ldb_add(*ldb, msg) != 0) {
|
||||
printf("Add of %s failed - %s\n", msg->dn, ldb_errstring(*ldb));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
asprintf(&msg.dn, "cn=%s,%s", "test", base_dn);
|
||||
ldb_msg_add_string(*ldb, &msg, "cn", strdup("test"));
|
||||
ldb_msg_add_string(*ldb, &msg, "sn", strdup("test"));
|
||||
ldb_msg_add_string(*ldb, &msg, "uid", strdup("test"));
|
||||
ldb_msg_add_string(*ldb, &msg, "objectClass", strdup("OpenLDAPperson"));
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
asprintf(&msg->dn, "cn=%s,%s", "test", base_dn);
|
||||
ldb_msg_add_string(*ldb, msg, "cn", strdup("test"));
|
||||
ldb_msg_add_string(*ldb, msg, "sn", strdup("test"));
|
||||
ldb_msg_add_string(*ldb, msg, "uid", strdup("test"));
|
||||
ldb_msg_add_string(*ldb, msg, "objectClass", strdup("OpenLDAPperson"));
|
||||
|
||||
if (ldb_add(*ldb, &msg) != 0) {
|
||||
printf("Add of %s failed - %s\n", msg.dn, ldb_errstring(*ldb));
|
||||
if (ldb_add(*ldb, msg) != 0) {
|
||||
printf("Add of %s failed - %s\n", msg->dn, ldb_errstring(*ldb));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -335,7 +336,7 @@ static void start_test_index(struct ldb_context **ldb)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ldb_delete(*ldb, msg.dn) != 0 ||
|
||||
if (ldb_delete(*ldb, msg->dn) != 0 ||
|
||||
ldb_delete(*ldb, "@INDEXLIST") != 0) {
|
||||
printf("cleanup failed - %s\n", ldb_errstring(*ldb));
|
||||
exit(1);
|
||||
|
Reference in New Issue
Block a user