1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

r502: modified ldb to allow the use of an external pool memory

allocator. The way to use this is to call ldb_set_alloc() with a
function pointer to whatever memory allocator you like. It includes a
context pointer to allow for pool based allocators.
This commit is contained in:
Andrew Tridgell 2004-05-06 04:40:15 +00:00 committed by Gerald (Jerry) Carter
parent ace939a588
commit 3955c482e6
25 changed files with 693 additions and 492 deletions

View File

@ -22,7 +22,8 @@ LDB_TDB_OBJ=ldb_tdb/ldb_match.o ldb_tdb/ldb_tdb.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_parse.o common/ldb_msg.o common/ldb_utf8.o \
common/ldb_alloc.o
OBJS = $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(LDB_LDAP_OBJ)

View File

@ -0,0 +1,174 @@
/*
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"
/*
this allows the user to choose their own allocation function
*/
int ldb_set_alloc(struct ldb_context *ldb,
void *(*alloc)(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(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);
}

View File

@ -86,7 +86,7 @@ static int base64_decode(char *s)
encode as base64
caller frees
*/
char *ldb_base64_encode(const char *buf, int len)
char *ldb_base64_encode(struct ldb_context *ldb, const char *buf, int len)
{
const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int bit_offset, byte_offset, idx, i;
@ -94,7 +94,7 @@ char *ldb_base64_encode(const char *buf, int len)
int bytes = (len*8 + 5)/6;
char *out;
out = malloc(bytes+2);
out = ldb_malloc(ldb, bytes+2);
if (!out) return NULL;
for (i=0;i<bytes;i++) {
@ -164,10 +164,12 @@ static int fold_string(int (*fprintf_fn)(void *, const char *, ...), void *priva
/*
encode as base64 to a file
*/
static int base64_encode_f(int (*fprintf_fn)(void *, const char *, ...), void *private_data,
static int base64_encode_f(struct ldb_context *ldb,
int (*fprintf_fn)(void *, const char *, ...),
void *private_data,
const char *buf, int len, int start_pos)
{
char *b = ldb_base64_encode(buf, len);
char *b = ldb_base64_encode(ldb, buf, len);
int ret;
if (!b) {
@ -176,7 +178,7 @@ static int base64_encode_f(int (*fprintf_fn)(void *, const char *, ...), void *p
ret = fold_string(fprintf_fn, private_data, b, strlen(b), start_pos);
free(b);
ldb_free(ldb, b);
return ret;
}
@ -194,7 +196,8 @@ static const struct {
/*
write to ldif, using a caller supplied write method
*/
int ldif_write(int (*fprintf_fn)(void *, const char *, ...),
int ldif_write(struct ldb_context *ldb,
int (*fprintf_fn)(void *, const char *, ...),
void *private_data,
const struct ldb_ldif *ldif)
{
@ -244,7 +247,7 @@ int ldif_write(int (*fprintf_fn)(void *, const char *, ...),
ret = fprintf_fn(private_data, "%s:: ",
msg->elements[i].name);
CHECK_RET;
ret = base64_encode_f(fprintf_fn, private_data,
ret = base64_encode_f(ldb, fprintf_fn, private_data,
msg->elements[i].values[j].data,
msg->elements[i].values[j].length,
strlen(msg->elements[i].name)+3);
@ -282,7 +285,8 @@ int ldif_write(int (*fprintf_fn)(void *, const char *, ...),
caller frees
*/
static char *next_chunk(int (*fgetc_fn)(void *), void *private_data)
static char *next_chunk(struct ldb_context *ldb,
int (*fgetc_fn)(void *), void *private_data)
{
size_t alloc_size=0, chunk_size = 0;
char *chunk = NULL;
@ -293,9 +297,9 @@ static char *next_chunk(int (*fgetc_fn)(void *), void *private_data)
if (chunk_size+1 >= alloc_size) {
char *c2;
alloc_size += 1024;
c2 = realloc_p(chunk, char, alloc_size);
c2 = ldb_realloc_p(ldb, chunk, char, alloc_size);
if (!c2) {
free(chunk);
ldb_free(ldb, chunk);
errno = ENOMEM;
return NULL;
}
@ -402,27 +406,29 @@ static int next_attr(char **s, const char **attr, struct ldb_val *value)
/*
free a message from a ldif_read
*/
void ldif_read_free(struct ldb_ldif *ldif)
void ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *ldif)
{
struct ldb_message *msg = &ldif->msg;
int i;
for (i=0;i<msg->num_elements;i++) {
if (msg->elements[i].name) free(msg->elements[i].name);
if (msg->elements[i].values) free(msg->elements[i].values);
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) free(msg->elements);
if (msg->private_data) free(msg->private_data);
free(ldif);
if (msg->elements) ldb_free(ldb, msg->elements);
if (msg->private_data) ldb_free(ldb, msg->private_data);
ldb_free(ldb, ldif);
}
/*
add an empty element
*/
static int msg_add_empty(struct ldb_message *msg, const char *name, unsigned flags)
static int msg_add_empty(struct ldb_context *ldb,
struct ldb_message *msg, const char *name, unsigned flags)
{
struct ldb_message_element *el2, *el;
el2 = realloc_p(msg->elements, struct ldb_message_element, msg->num_elements+1);
el2 = ldb_realloc_p(ldb, msg->elements,
struct ldb_message_element, msg->num_elements+1);
if (!el2) {
errno = ENOMEM;
return -1;
@ -432,7 +438,7 @@ static int msg_add_empty(struct ldb_message *msg, const char *name, unsigned fla
el = &msg->elements[msg->num_elements];
el->name = strdup(name);
el->name = ldb_strdup(ldb, name);
el->num_values = 0;
el->values = NULL;
el->flags = flags;
@ -450,7 +456,8 @@ static int msg_add_empty(struct ldb_message *msg, const char *name, unsigned fla
/*
read from a LDIF source, creating a ldb_message
*/
struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
struct ldb_ldif *ldif_read(struct ldb_context *ldb,
int (*fgetc_fn)(void *), void *private_data)
{
struct ldb_ldif *ldif;
struct ldb_message *msg;
@ -461,7 +468,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
value.data = NULL;
ldif = malloc_p(struct ldb_ldif);
ldif = ldb_malloc_p(ldb, struct ldb_ldif);
if (!ldif) return NULL;
ldif->changetype = LDB_CHANGETYPE_NONE;
@ -472,7 +479,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
msg->num_elements = 0;
msg->private_data = NULL;
chunk = next_chunk(fgetc_fn, private_data);
chunk = next_chunk(ldb, fgetc_fn, private_data);
if (!chunk) {
goto failed;
}
@ -530,7 +537,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
}
if (empty) {
if (msg_add_empty(msg, (char *)value.data, flags) != 0) {
if (msg_add_empty(ldb, msg, (char *)value.data, flags) != 0) {
goto failed;
}
continue;
@ -542,7 +549,8 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
flags == el->flags) {
/* its a continuation */
el->values =
realloc_p(el->values, struct ldb_val, el->num_values+1);
ldb_realloc_p(ldb, el->values,
struct ldb_val, el->num_values+1);
if (!el->values) {
goto failed;
}
@ -550,16 +558,16 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
el->num_values++;
} else {
/* its a new attribute */
msg->elements = realloc_p(msg->elements,
struct ldb_message_element,
msg->num_elements+1);
msg->elements = ldb_realloc_p(ldb, 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 = strdup(attr);
el->values = malloc_p(struct ldb_val);
el->name = ldb_strdup(ldb, attr);
el->values = ldb_malloc_p(ldb, struct ldb_val);
if (!el->values || !el->name) {
goto failed;
}
@ -572,7 +580,7 @@ struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data)
return ldif;
failed:
if (ldif) ldif_read_free(ldif);
if (ldif) ldif_read_free(ldb, ldif);
return NULL;
}
@ -591,11 +599,11 @@ static int fgetc_file(void *private_data)
return fgetc(state->f);
}
struct ldb_ldif *ldif_read_file(FILE *f)
struct ldb_ldif *ldif_read_file(struct ldb_context *ldb, FILE *f)
{
struct ldif_read_file_state state;
state.f = f;
return ldif_read(fgetc_file, &state);
return ldif_read(ldb, fgetc_file, &state);
}
@ -615,11 +623,11 @@ static int fgetc_string(void *private_data)
return EOF;
}
struct ldb_ldif *ldif_read_string(const char *s)
struct ldb_ldif *ldif_read_string(struct ldb_context *ldb, const char *s)
{
struct ldif_read_string_state state;
state.s = s;
return ldif_read(fgetc_string, &state);
return ldif_read(ldb, fgetc_string, &state);
}
@ -642,9 +650,9 @@ static int fprintf_file(void *private_data, const char *fmt, ...)
return ret;
}
int ldif_write_file(FILE *f, const struct ldb_ldif *ldif)
int ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *ldif)
{
struct ldif_write_file_state state;
state.f = f;
return ldif_write(fprintf_file, &state, ldif);
return ldif_write(ldb, fprintf_file, &state, ldif);
}

View File

@ -87,11 +87,13 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el,
/*
add an empty element to a message
*/
int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags)
int ldb_msg_add_empty(struct ldb_context *ldb,
struct ldb_message *msg, const char *attr_name, int flags)
{
struct ldb_message_element *els;
els = realloc_p(msg->elements, struct ldb_message_element, msg->num_elements+1);
els = ldb_realloc_p(ldb, msg->elements,
struct ldb_message_element, msg->num_elements+1);
if (!els) {
errno = ENOMEM;
return -1;
@ -100,7 +102,7 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags)
els[msg->num_elements].values = NULL;
els[msg->num_elements].num_values = 0;
els[msg->num_elements].flags = flags;
els[msg->num_elements].name = strdup(attr_name);
els[msg->num_elements].name = ldb_strdup(ldb, attr_name);
if (!els[msg->num_elements].name) {
return -1;
}
@ -114,11 +116,12 @@ int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags)
/*
add an empty element to a message
*/
int ldb_msg_add(struct ldb_message *msg,
int ldb_msg_add(struct ldb_context *ldb,
struct ldb_message *msg,
const struct ldb_message_element *el,
int flags)
{
if (ldb_msg_add_empty(msg, el->name, flags) != 0) {
if (ldb_msg_add_empty(ldb, msg, el->name, flags) != 0) {
return -1;
}

View File

@ -59,7 +59,7 @@ a filter is defined by:
/*
return next token element. Caller frees
*/
static char *ldb_parse_lex(const char **s)
static char *ldb_parse_lex(struct ldb_context *ldb, const char **s)
{
const char *p = *s;
char *ret;
@ -75,7 +75,7 @@ static char *ldb_parse_lex(const char **s)
if (strchr("()&|=!", *p)) {
(*s) = p+1;
ret = strndup(p, 1);
ret = ldb_strndup(ldb, p, 1);
if (!ret) {
errno = ENOMEM;
}
@ -90,7 +90,7 @@ static char *ldb_parse_lex(const char **s)
return NULL;
}
ret = strndup(*s, p - *s);
ret = ldb_strndup(ldb, *s, p - *s);
if (!ret) {
errno = ENOMEM;
}
@ -122,46 +122,42 @@ static const char *match_brace(const char *s)
}
static struct ldb_parse_tree *ldb_parse_filter(const char **s);
static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s);
/*
<simple> ::= <attributetype> <filtertype> <attributevalue>
*/
static struct ldb_parse_tree *ldb_parse_simple(const char *s)
static struct ldb_parse_tree *ldb_parse_simple(struct ldb_context *ldb, const char *s)
{
char *eq, *val, *l;
struct ldb_parse_tree *ret;
l = ldb_parse_lex(&s);
l = ldb_parse_lex(ldb, &s);
if (!l) {
fprintf(stderr, "Unexpected end of expression\n");
return NULL;
}
if (strchr("()&|=", *l)) {
fprintf(stderr, "Unexpected token '%s'\n", l);
free(l);
ldb_free(ldb, l);
return NULL;
}
eq = ldb_parse_lex(&s);
eq = ldb_parse_lex(ldb, &s);
if (!eq || strcmp(eq, "=") != 0) {
fprintf(stderr, "Expected '='\n");
free(l);
if (eq) free(eq);
ldb_free(ldb, l);
if (eq) ldb_free(ldb, eq);
return NULL;
}
free(eq);
ldb_free(ldb, eq);
val = ldb_parse_lex(&s);
val = ldb_parse_lex(ldb, &s);
if (val && strchr("()&|=", *val)) {
fprintf(stderr, "Unexpected token '%s'\n", val);
free(l);
if (val) free(val);
ldb_free(ldb, l);
if (val) ldb_free(ldb, val);
return NULL;
}
ret = malloc_p(struct ldb_parse_tree);
ret = ldb_malloc_p(ldb, struct ldb_parse_tree);
if (!ret) {
errno = ENOMEM;
return NULL;
@ -182,11 +178,12 @@ static struct ldb_parse_tree *ldb_parse_simple(const char *s)
<or> ::= '|' <filterlist>
<filterlist> ::= <filter> | <filter> <filterlist>
*/
static struct ldb_parse_tree *ldb_parse_filterlist(enum ldb_parse_op op, const char *s)
static struct ldb_parse_tree *ldb_parse_filterlist(struct ldb_context *ldb,
enum ldb_parse_op op, const char *s)
{
struct ldb_parse_tree *ret, *next;
ret = malloc_p(struct ldb_parse_tree);
ret = ldb_malloc_p(ldb, struct ldb_parse_tree);
if (!ret) {
errno = ENOMEM;
return NULL;
@ -194,31 +191,31 @@ static struct ldb_parse_tree *ldb_parse_filterlist(enum ldb_parse_op op, const c
ret->operation = op;
ret->u.list.num_elements = 1;
ret->u.list.elements = malloc_p(struct ldb_parse_tree *);
ret->u.list.elements = ldb_malloc_p(ldb, struct ldb_parse_tree *);
if (!ret->u.list.elements) {
errno = ENOMEM;
free(ret);
ldb_free(ldb, ret);
return NULL;
}
ret->u.list.elements[0] = ldb_parse_filter(&s);
ret->u.list.elements[0] = ldb_parse_filter(ldb, &s);
if (!ret->u.list.elements[0]) {
free(ret->u.list.elements);
free(ret);
ldb_free(ldb, ret->u.list.elements);
ldb_free(ldb, ret);
return NULL;
}
while (isspace(*s)) s++;
while (*s && (next = ldb_parse_filter(&s))) {
while (*s && (next = ldb_parse_filter(ldb, &s))) {
struct ldb_parse_tree **e;
e = realloc_p(ret->u.list.elements,
struct ldb_parse_tree *,
ret->u.list.num_elements+1);
e = ldb_realloc_p(ldb, ret->u.list.elements,
struct ldb_parse_tree *,
ret->u.list.num_elements+1);
if (!e) {
errno = ENOMEM;
ldb_parse_tree_free(next);
ldb_parse_tree_free(ret);
ldb_parse_tree_free(ldb, next);
ldb_parse_tree_free(ldb, ret);
return NULL;
}
ret->u.list.elements = e;
@ -234,20 +231,20 @@ static struct ldb_parse_tree *ldb_parse_filterlist(enum ldb_parse_op op, const c
/*
<not> ::= '!' <filter>
*/
static struct ldb_parse_tree *ldb_parse_not(const char *s)
static struct ldb_parse_tree *ldb_parse_not(struct ldb_context *ldb, const char *s)
{
struct ldb_parse_tree *ret;
ret = malloc_p(struct ldb_parse_tree);
ret = ldb_malloc_p(ldb, struct ldb_parse_tree);
if (!ret) {
errno = ENOMEM;
return NULL;
}
ret->operation = LDB_OP_NOT;
ret->u.not.child = ldb_parse_filter(&s);
ret->u.not.child = ldb_parse_filter(ldb, &s);
if (!ret->u.not.child) {
free(ret);
ldb_free(ldb, ret);
return NULL;
}
@ -258,67 +255,64 @@ static struct ldb_parse_tree *ldb_parse_not(const char *s)
parse a filtercomp
<filtercomp> ::= <and> | <or> | <not> | <simple>
*/
static struct ldb_parse_tree *ldb_parse_filtercomp(const char *s)
static struct ldb_parse_tree *ldb_parse_filtercomp(struct ldb_context *ldb,
const char *s)
{
while (isspace(*s)) s++;
switch (*s) {
case '&':
return ldb_parse_filterlist(LDB_OP_AND, s+1);
return ldb_parse_filterlist(ldb, LDB_OP_AND, s+1);
case '|':
return ldb_parse_filterlist(LDB_OP_OR, s+1);
return ldb_parse_filterlist(ldb, LDB_OP_OR, s+1);
case '!':
return ldb_parse_not(s+1);
return ldb_parse_not(ldb, s+1);
case '(':
case ')':
fprintf(stderr, "Unexpected token '%c'\n", *s);
return NULL;
}
return ldb_parse_simple(s);
return ldb_parse_simple(ldb, s);
}
/*
<filter> ::= '(' <filtercomp> ')'
*/
static struct ldb_parse_tree *ldb_parse_filter(const char **s)
static struct ldb_parse_tree *ldb_parse_filter(struct ldb_context *ldb, const char **s)
{
char *l, *s2;
const char *p, *p2;
struct ldb_parse_tree *ret;
l = ldb_parse_lex(s);
l = ldb_parse_lex(ldb, s);
if (!l) {
fprintf(stderr, "Unexpected end of expression\n");
return NULL;
}
if (strcmp(l, "(") != 0) {
free(l);
fprintf(stderr, "Expected '('\n");
ldb_free(ldb, l);
return NULL;
}
free(l);
ldb_free(ldb, l);
p = match_brace(*s);
if (!p) {
fprintf(stderr, "Parse error - mismatched braces\n");
return NULL;
}
p2 = p + 1;
s2 = strndup(*s, p - *s);
s2 = ldb_strndup(ldb, *s, p - *s);
if (!s2) {
errno = ENOMEM;
return NULL;
}
ret = ldb_parse_filtercomp(s2);
free(s2);
ret = ldb_parse_filtercomp(ldb, s2);
ldb_free(ldb, s2);
*s = p2;
@ -331,130 +325,43 @@ static struct ldb_parse_tree *ldb_parse_filter(const char **s)
expression ::= <simple> | <filter>
*/
struct ldb_parse_tree *ldb_parse_tree(const char *s)
struct ldb_parse_tree *ldb_parse_tree(struct ldb_context *ldb, const char *s)
{
while (isspace(*s)) s++;
if (*s == '(') {
return ldb_parse_filter(&s);
return ldb_parse_filter(ldb, &s);
}
return ldb_parse_simple(s);
return ldb_parse_simple(ldb, s);
}
/*
free a parse tree returned from ldb_parse_tree()
*/
void ldb_parse_tree_free(struct ldb_parse_tree *tree)
void ldb_parse_tree_free(struct ldb_context *ldb, struct ldb_parse_tree *tree)
{
int i;
switch (tree->operation) {
case LDB_OP_SIMPLE:
free(tree->u.simple.attr);
if (tree->u.simple.value.data) free(tree->u.simple.value.data);
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(tree->u.list.elements[i]);
ldb_parse_tree_free(ldb, tree->u.list.elements[i]);
}
if (tree->u.list.elements) free(tree->u.list.elements);
if (tree->u.list.elements) ldb_free(ldb, tree->u.list.elements);
break;
case LDB_OP_NOT:
ldb_parse_tree_free(tree->u.not.child);
ldb_parse_tree_free(ldb, tree->u.not.child);
break;
}
free(tree);
ldb_free(ldb, tree);
}
#if TEST_PROGRAM
/*
return a string representation of a parse tree
used for debugging
*/
static char *tree_string(struct ldb_parse_tree *tree)
{
char *s = NULL;
char *s1, *s2;
int i;
switch (tree->operation) {
case LDB_OP_SIMPLE:
asprintf(&s, "( %s = \"%s\" )", tree->u.simple.attr,
(char *)tree->u.simple.value.data);
break;
case LDB_OP_AND:
case LDB_OP_OR:
asprintf(&s, "( %c", tree->operation==LDB_OP_AND?'&':'|');
if (!s) return NULL;
for (i=0;i<tree->u.list.num_elements;i++) {
s1 = tree_string(tree->u.list.elements[i]);
if (!s1) {
free(s);
return NULL;
}
asprintf(&s2, "%s %s", s, s1);
free(s);
free(s1);
s = s2;
}
if (!s) {
return NULL;
}
asprintf(&s2, "%s )", s);
free(s);
s = s2;
break;
case LDB_OP_NOT:
s1 = tree_string(tree->u.not.child);
asprintf(&s, "( ! %s )", s1);
free(s1);
break;
}
return s;
}
/*
print a tree
*/
static void print_tree(struct ldb_parse_tree *tree)
{
char *s = tree_string(tree);
printf("%s\n", s);
free(s);
}
int main(void)
{
char line[1000];
int ret = 0;
while (fgets(line, sizeof(line)-1, stdin)) {
struct ldb_parse_tree *tree;
if (line[strlen(line)-1] == '\n') {
line[strlen(line)-1] = 0;
}
tree = ldb_parse_tree(line);
if (!tree) {
fprintf(stderr, "Failed to parse\n");
ret = 1;
continue;
}
print_tree(tree);
ldb_parse_tree_free(tree);
}
return ret;
}
#endif /* TEST_PROGRAM */

View File

@ -38,10 +38,10 @@
TODO:
a simple case folding function - will be replaced by a UTF8 aware function later
*/
char *ldb_casefold(const char *s)
char *ldb_casefold(struct ldb_context *ldb, const char *s)
{
int i;
char *ret = strdup(s);
char *ret = ldb_strdup(ldb, s);
if (!s) {
errno = ENOMEM;
return NULL;

View File

@ -35,24 +35,6 @@
#include "includes.h"
#define MAX_MALLOC_SIZE 0x7fffffff
/*
realloc an array, checking for integer overflow in the array size
*/
void *realloc_array(void *ptr, size_t el_size, unsigned count)
{
if (count == 0 ||
count >= MAX_MALLOC_SIZE/el_size) {
return NULL;
}
if (!ptr) {
return malloc(el_size * count);
}
return realloc(ptr, el_size * count);
}
/*
find an element in a list, using the given comparison function and
assuming that the list is already sorted using comp_fn

View File

@ -8,6 +8,7 @@ SMB_SUBSYSTEM(LIBLDB,[lib/ldb/common/ldb.o],
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/ldb_tdb/ldb_search.o \
lib/ldb/ldb_tdb/ldb_tdb.o \
lib/ldb/ldb_tdb/ldb_pack.o \

View File

@ -18,11 +18,5 @@
#include <sys/time.h>
#include <time.h>
#include "ldb.h"
#include "ldb_parse.h"
#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)
#include "tdb/tdb.h"
#include "proto.h"

View File

@ -32,6 +32,9 @@
* Author: Andrew Tridgell
*/
#ifndef _LDB_H_
#define _LDB_H_ 1
/*
major restrictions as compared to normal LDAP:
@ -46,7 +49,6 @@
*/
/*
an individual lump of data in a result comes in this format. The
pointer will usually be to a UTF-8 string if the application is
@ -58,6 +60,9 @@ struct ldb_val {
void *data;
};
#include "ldb_parse.h"
/* these flags are used in ldd_message_element.flags fields. The
LDA_FLAGS_MOD_* flags are used in ldap_modify() calls to specify
whether attributes are being added, deleted or modified */
@ -130,8 +135,24 @@ struct ldb_backend_ops {
int (*modify_record)(struct ldb_context *, const struct ldb_message *);
int (*delete_record)(struct ldb_context *, const char *);
const char * (*errstring)(struct ldb_context *);
/* 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_context *);
};
/*
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)(void *context, void *ptr, size_t size);
void *context;
};
/*
every ldb connection is started by establishing a ldb_context
*/
@ -141,6 +162,9 @@ struct ldb_context {
/* the operations provided by the backend */
const struct ldb_backend_ops *ops;
/* memory allocation info */
struct ldb_alloc_ops alloc_ops;
};
@ -209,19 +233,21 @@ const char *ldb_errstring(struct ldb_context *ldb);
/*
casefold a string (should be UTF8, but at the moment it isn't)
*/
char *ldb_casefold(const char *s);
char *ldb_casefold(struct ldb_context *ldb, const char *s);
/*
ldif manipulation functions
*/
int ldif_write(int (*fprintf_fn)(void *, const char *, ...),
int ldif_write(struct ldb_context *ldb,
int (*fprintf_fn)(void *, const char *, ...),
void *private_data,
const struct ldb_ldif *ldif);
void ldif_read_free(struct ldb_ldif *);
struct ldb_ldif *ldif_read(int (*fgetc_fn)(void *), void *private_data);
struct ldb_ldif *ldif_read_file(FILE *f);
struct ldb_ldif *ldif_read_string(const char *s);
int ldif_write_file(FILE *f, const struct ldb_ldif *msg);
void ldif_read_free(struct ldb_context *ldb, struct ldb_ldif *);
struct ldb_ldif *ldif_read(struct ldb_context *ldb,
int (*fgetc_fn)(void *), void *private_data);
struct ldb_ldif *ldif_read_file(struct ldb_context *ldb, FILE *f);
struct ldb_ldif *ldif_read_string(struct ldb_context *ldb, const char *s);
int ldif_write_file(struct ldb_context *ldb, FILE *f, const struct ldb_ldif *msg);
/* useful functions for ldb_message structure manipulation */
@ -238,10 +264,12 @@ struct ldb_val *ldb_msg_find_val(const struct ldb_message_element *el,
struct ldb_val *val);
/* add a new empty element to a ldb_message */
int ldb_msg_add_empty(struct ldb_message *msg, const char *attr_name, int flags);
int ldb_msg_add_empty(struct ldb_context *ldb,
struct ldb_message *msg, const char *attr_name, int flags);
/* add a element to a ldb_message */
int ldb_msg_add(struct ldb_message *msg,
int ldb_msg_add(struct ldb_context *ldb,
struct ldb_message *msg,
const struct ldb_message_element *el,
int flags);
@ -264,3 +292,26 @@ double ldb_msg_find_double(const struct ldb_message *msg,
const char *ldb_msg_find_string(const struct ldb_message *msg,
const char *attr_name,
const char *default_value);
/*
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)(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)
#endif

View File

@ -32,6 +32,8 @@
* Author: Andrew Tridgell
*/
#ifndef _LDB_PARSE_H
#define _LDB_PARSE_H 1
enum ldb_parse_op {LDB_OP_SIMPLE, LDB_OP_AND, LDB_OP_OR, LDB_OP_NOT};
@ -51,3 +53,5 @@ struct ldb_parse_tree {
} not;
} u;
};
#endif

View File

@ -77,13 +77,15 @@ static int lldb_close(struct ldb_context *ldb)
ret = -1;
}
ldb_set_alloc(ldb, NULL, NULL);
if (lldb->options) {
for (i=0;lldb->options[i];i++) {
free(lldb->options[i]);
ldb_free(ldb, lldb->options[i]);
}
free(lldb->options);
ldb_free(ldb, lldb->options);
}
free(lldb);
ldb_free(ldb, lldb);
free(ldb);
return ret;
@ -116,18 +118,18 @@ static int lldb_delete(struct ldb_context *ldb, const char *dn)
static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
{
int i, j;
free(msg->dn);
ldb_free(ldb, msg->dn);
for (i=0;i<msg->num_elements;i++) {
free(msg->elements[i].name);
ldb_free(ldb, msg->elements[i].name);
for (j=0;j<msg->elements[i].num_values;j++) {
if (msg->elements[i].values[j].data) {
free(msg->elements[i].values[j].data);
ldb_free(ldb, msg->elements[i].values[j].data);
}
}
free(msg->elements[i].values);
ldb_free(ldb, msg->elements[i].values);
}
if (msg->elements) free(msg->elements);
free(msg);
if (msg->elements) ldb_free(ldb, msg->elements);
ldb_free(ldb, msg);
return 0;
}
@ -142,7 +144,7 @@ static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res)
return -1;
}
}
free(res);
ldb_free(ldb, res);
return 0;
}
@ -150,7 +152,8 @@ static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res)
/*
add a single set of ldap message values to a ldb_message
*/
static int lldb_add_msg_attr(struct ldb_message *msg,
static int lldb_add_msg_attr(struct ldb_context *ldb,
struct ldb_message *msg,
const char *attr, struct berval **bval)
{
int count, i;
@ -162,8 +165,8 @@ static int lldb_add_msg_attr(struct ldb_message *msg,
return -1;
}
el = realloc_p(msg->elements, struct ldb_message_element,
msg->num_elements + 1);
el = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
msg->num_elements + 1);
if (!el) {
errno = ENOMEM;
return -1;
@ -173,7 +176,7 @@ static int lldb_add_msg_attr(struct ldb_message *msg,
el = &msg->elements[msg->num_elements];
el->name = strdup(attr);
el->name = ldb_strdup(ldb, attr);
if (!el->name) {
errno = ENOMEM;
return -1;
@ -181,14 +184,14 @@ static int lldb_add_msg_attr(struct ldb_message *msg,
el->flags = 0;
el->num_values = 0;
el->values = malloc_array_p(struct ldb_val, count);
el->values = ldb_malloc_array_p(ldb, struct ldb_val, count);
if (!el->values) {
errno = ENOMEM;
return -1;
}
for (i=0;i<count;i++) {
el->values[i].data = malloc(bval[i]->bv_len);
el->values[i].data = ldb_malloc(ldb, bval[i]->bv_len);
if (!el->values[i].data) {
return -1;
}
@ -225,7 +228,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
return count;
}
(*res) = malloc_array_p(struct ldb_message *, count+1);
(*res) = ldb_malloc_array_p(ldb, struct ldb_message *, count+1);
if (! *res) {
ldap_msgfree(ldapres);
errno = ENOMEM;
@ -249,7 +252,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
break;
}
(*res)[msg_count] = malloc_p(struct ldb_message);
(*res)[msg_count] = ldb_malloc_p(ldb, struct ldb_message);
if (!(*res)[msg_count]) {
goto failed;
}
@ -260,7 +263,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
goto failed;
}
(*res)[msg_count]->dn = strdup(dn);
(*res)[msg_count]->dn = ldb_strdup(ldb, dn);
ldap_memfree(dn);
if (!(*res)[msg_count]->dn) {
goto failed;
@ -279,7 +282,7 @@ static int lldb_search(struct ldb_context *ldb, const char *base,
bval = ldap_get_values_len(lldb->ldap, msg, attr);
if (bval) {
lldb_add_msg_attr((*res)[msg_count], attr, bval);
lldb_add_msg_attr(ldb, (*res)[msg_count], attr, bval);
ldap_value_free_len(bval);
}
@ -303,7 +306,7 @@ failed:
/*
free a set of mods from lldb_msg_to_mods()
*/
static void lldb_mods_free(LDAPMod **mods)
static void lldb_mods_free(struct ldb_context *ldb, LDAPMod **mods)
{
int i, j;
@ -312,13 +315,13 @@ static void lldb_mods_free(LDAPMod **mods)
for (i=0;mods[i];i++) {
if (mods[i]->mod_vals.modv_bvals) {
for (j=0;mods[i]->mod_vals.modv_bvals[j];j++) {
free(mods[i]->mod_vals.modv_bvals[j]);
ldb_free(ldb, mods[i]->mod_vals.modv_bvals[j]);
}
free(mods[i]->mod_vals.modv_bvals);
ldb_free(ldb, mods[i]->mod_vals.modv_bvals);
}
free(mods[i]);
ldb_free(ldb, mods[i]);
}
free(mods);
ldb_free(ldb, mods);
}
@ -326,13 +329,14 @@ static void lldb_mods_free(LDAPMod **mods)
convert a ldb_message structure to a list of LDAPMod structures
ready for ldap_add() or ldap_modify()
*/
static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
static LDAPMod **lldb_msg_to_mods(struct ldb_context *ldb,
const struct ldb_message *msg, int use_flags)
{
LDAPMod **mods;
int i, j, num_mods = 0;
/* allocate maximum number of elements needed */
mods = malloc_array_p(LDAPMod *, msg->num_elements+1);
mods = ldb_malloc_array_p(ldb, LDAPMod *, msg->num_elements+1);
if (!mods) {
errno = ENOMEM;
return NULL;
@ -342,7 +346,7 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
for (i=0;i<msg->num_elements;i++) {
const struct ldb_message_element *el = &msg->elements[i];
mods[num_mods] = malloc_p(LDAPMod);
mods[num_mods] = ldb_malloc_p(ldb, LDAPMod);
if (!mods[num_mods]) {
goto failed;
}
@ -362,14 +366,15 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
}
}
mods[num_mods]->mod_type = el->name;
mods[num_mods]->mod_vals.modv_bvals = malloc_array_p(struct berval *,
1+el->num_values);
mods[num_mods]->mod_vals.modv_bvals = ldb_malloc_array_p(ldb,
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] = malloc_p(struct berval);
mods[num_mods]->mod_vals.modv_bvals[j] = ldb_malloc_p(ldb, struct berval);
if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
goto failed;
}
@ -383,7 +388,7 @@ static LDAPMod **lldb_msg_to_mods(const struct ldb_message *msg, int use_flags)
return mods;
failed:
lldb_mods_free(mods);
lldb_mods_free(ldb, mods);
return NULL;
}
@ -402,14 +407,14 @@ static int lldb_add(struct ldb_context *ldb, const struct ldb_message *msg)
return 0;
}
mods = lldb_msg_to_mods(msg, 0);
mods = lldb_msg_to_mods(ldb, msg, 0);
lldb->last_rc = ldap_add_s(lldb->ldap, msg->dn, mods);
if (lldb->last_rc != LDAP_SUCCESS) {
ret = -1;
}
lldb_mods_free(mods);
lldb_mods_free(ldb, mods);
return ret;
}
@ -429,14 +434,14 @@ static int lldb_modify(struct ldb_context *ldb, const struct ldb_message *msg)
return 0;
}
mods = lldb_msg_to_mods(msg, 1);
mods = lldb_msg_to_mods(ldb, msg, 1);
lldb->last_rc = ldap_modify_s(lldb->ldap, msg->dn, mods);
if (lldb->last_rc != LDAP_SUCCESS) {
ret = -1;
}
lldb_mods_free(mods);
lldb_mods_free(ldb, mods);
return ret;
}
@ -474,15 +479,15 @@ struct ldb_context *lldb_connect(const char *url,
struct lldb_private *lldb = NULL;
int i;
ldb = malloc_p(struct ldb_context);
ldb = calloc(1, sizeof(struct ldb_context));
if (!ldb) {
errno = ENOMEM;
goto failed;
}
lldb = malloc_p(struct lldb_private);
lldb = ldb_malloc_p(ldb, struct lldb_private);
if (!lldb) {
free(ldb);
ldb_free(ldb, ldb);
errno = ENOMEM;
goto failed;
}
@ -503,14 +508,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 = malloc_array_p(char *, i+1);
lldb->options = ldb_malloc_array_p(ldb, char *, i+1);
if (!lldb->options) {
goto failed;
}
for (i=0;options[i];i++) {
lldb->options[i+1] = NULL;
lldb->options[i] = strdup(options[i]);
lldb->options[i] = ldb_strdup(ldb, options[i]);
if (!lldb->options[i]) {
goto failed;
}
@ -522,14 +527,14 @@ struct ldb_context *lldb_connect(const char *url,
failed:
if (lldb && lldb->options) {
for (i=0;lldb->options[i];i++) {
free(lldb->options[i]);
ldb_free(ldb, lldb->options[i]);
}
free(lldb->options);
ldb_free(ldb, lldb->options);
}
if (lldb && lldb->ldap) {
ldap_unbind(lldb->ldap);
}
if (lldb) free(lldb);
ldb_free(ldb, lldb);
if (ldb) free(ldb);
return NULL;
}

View File

@ -50,24 +50,24 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb)
msg.num_elements = 1;
msg.elements = &el;
msg.dn = strdup(LTDB_BASEINFO);
msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
if (!msg.dn) {
errno = ENOMEM;
return -1;
}
el.name = strdup(LTDB_SEQUENCE_NUMBER);
el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
if (!el.name) {
free(msg.dn);
ldb_free(ldb, msg.dn);
errno = ENOMEM;
return -1;
}
el.values = &val;
el.num_values = 1;
el.flags = 0;
val.data = strdup("0");
val.data = ldb_strdup(ldb, "0");
if (!val.data) {
free(el.name);
free(msg.dn);
ldb_free(ldb, el.name);
ldb_free(ldb, msg.dn);
errno = ENOMEM;
return -1;
}
@ -75,9 +75,9 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb)
ret = ltdb_store(ldb, &msg, TDB_INSERT);
free(msg.dn);
free(el.name);
free(val.data);
ldb_free(ldb, msg.dn);
ldb_free(ldb, el.name);
ldb_free(ldb, val.data);
return ret;
}
@ -88,6 +88,8 @@ static int ltdb_baseinfo_init(struct ldb_context *ldb)
void ltdb_cache_free(struct ldb_context *ldb)
{
struct ltdb_private *ltdb = ldb->private_data;
struct ldb_alloc_ops alloc = ldb->alloc_ops;
ldb->alloc_ops.alloc = NULL;
ltdb->sequence_number = 0;
ltdb_search_dn1_free(ldb, &ltdb->cache.baseinfo);
@ -95,8 +97,10 @@ void ltdb_cache_free(struct ldb_context *ldb)
ltdb_search_dn1_free(ldb, &ltdb->cache.subclasses);
ltdb_search_dn1_free(ldb, &ltdb->cache.attributes);
if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name);
ldb_free(ldb, ltdb->cache.last_attribute.name);
memset(&ltdb->cache, 0, sizeof(ltdb->cache));
ldb->alloc_ops = alloc;
}
/*
@ -106,20 +110,23 @@ int ltdb_cache_load(struct ldb_context *ldb)
{
struct ltdb_private *ltdb = ldb->private_data;
double seq;
struct ldb_alloc_ops alloc = ldb->alloc_ops;
ldb->alloc_ops.alloc = NULL;
ltdb_search_dn1_free(ldb, &ltdb->cache.baseinfo);
if (ltdb_search_dn1(ldb, LTDB_BASEINFO, &ltdb->cache.baseinfo) == -1) {
return -1;
goto failed;
}
/* possibly initialise the baseinfo */
if (!ltdb->cache.baseinfo.dn) {
if (ltdb_baseinfo_init(ldb) != 0) {
return -1;
goto failed;
}
if (ltdb_search_dn1(ldb, LTDB_BASEINFO, &ltdb->cache.baseinfo) != 1) {
return -1;
goto failed;
}
}
@ -127,11 +134,11 @@ int ltdb_cache_load(struct ldb_context *ldb)
in the database then assume the rest of the cache is OK */
seq = ldb_msg_find_double(&ltdb->cache.baseinfo, LTDB_SEQUENCE_NUMBER, 0);
if (seq == ltdb->sequence_number) {
return 0;
goto done;
}
ltdb->sequence_number = seq;
if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name);
ldb_free(ldb, ltdb->cache.last_attribute.name);
memset(&ltdb->cache.last_attribute, 0, sizeof(ltdb->cache.last_attribute));
ltdb_search_dn1_free(ldb, &ltdb->cache.indexlist);
@ -139,16 +146,22 @@ int ltdb_cache_load(struct ldb_context *ldb)
ltdb_search_dn1_free(ldb, &ltdb->cache.attributes);
if (ltdb_search_dn1(ldb, LTDB_INDEXLIST, &ltdb->cache.indexlist) == -1) {
return -1;
goto failed;
}
if (ltdb_search_dn1(ldb, LTDB_SUBCLASSES, &ltdb->cache.subclasses) == -1) {
return -1;
goto failed;
}
if (ltdb_search_dn1(ldb, LTDB_ATTRIBUTES, &ltdb->cache.attributes) == -1) {
return -1;
goto failed;
}
done:
ldb->alloc_ops = alloc;
return 0;
failed:
ldb->alloc_ops = alloc;
return -1;
}
@ -164,7 +177,7 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb)
char *s = NULL;
int ret;
asprintf(&s, "%.0f", ltdb->sequence_number+1);
ldb_asprintf(ldb, &s, "%.0f", ltdb->sequence_number+1);
if (!s) {
errno = ENOMEM;
return -1;
@ -172,8 +185,8 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb)
msg.num_elements = 1;
msg.elements = &el;
msg.dn = strdup(LTDB_BASEINFO);
el.name = strdup(LTDB_SEQUENCE_NUMBER);
msg.dn = ldb_strdup(ldb, LTDB_BASEINFO);
el.name = ldb_strdup(ldb, LTDB_SEQUENCE_NUMBER);
el.values = &val;
el.num_values = 1;
el.flags = LDB_FLAG_MOD_REPLACE;
@ -182,9 +195,9 @@ int ltdb_increase_sequence_number(struct ldb_context *ldb)
ret = ltdb_modify_internal(ldb, &msg);
free(s);
free(msg.dn);
free(el.name);
ldb_free(ldb, s);
ldb_free(ldb, msg.dn);
ldb_free(ldb, el.name);
if (ret == 0) {
ltdb->sequence_number += 1;
@ -244,9 +257,9 @@ int ltdb_attribute_flags(struct ldb_context *ldb, const char *attr_name)
attrs += strspn(attrs, " ,");
}
if (ltdb->cache.last_attribute.name) free(ltdb->cache.last_attribute.name);
if (ltdb->cache.last_attribute.name) ldb_free(ldb, ltdb->cache.last_attribute.name);
ltdb->cache.last_attribute.name = strdup(attr_name);
ltdb->cache.last_attribute.name = ldb_strdup(ldb, attr_name);
ltdb->cache.last_attribute.flags = ret;
return ret;

View File

@ -43,32 +43,33 @@ struct dn_list {
/*
free a struct dn_list
*/
static void dn_list_free(struct dn_list *list)
static void dn_list_free(struct ldb_context *ldb, struct dn_list *list)
{
int i;
for (i=0;i<list->count;i++) {
free(list->dn[i]);
ldb_free(ldb, list->dn[i]);
}
if (list->dn) free(list->dn);
ldb_free(ldb, list->dn);
}
/*
return the dn key to be used for an index
caller frees
*/
static char *ldb_dn_key(const char *attr, const struct ldb_val *value)
static char *ldb_dn_key(struct ldb_context *ldb,
const char *attr, const struct ldb_val *value)
{
char *ret = NULL;
if (ldb_should_b64_encode(value)) {
char *vstr = ldb_base64_encode(value->data, value->length);
char *vstr = ldb_base64_encode(ldb, value->data, value->length);
if (!vstr) return NULL;
asprintf(&ret, "%s:%s::%s", LTDB_INDEX, attr, vstr);
free(vstr);
ldb_asprintf(ldb, &ret, "%s:%s::%s", LTDB_INDEX, attr, vstr);
ldb_free(ldb, vstr);
return ret;
}
asprintf(&ret, "%s:%s:%s", LTDB_INDEX, attr, (char *)value->data);
ldb_asprintf(ldb, &ret, "%s:%s:%s", LTDB_INDEX, attr, (char *)value->data);
return ret;
}
@ -132,11 +133,11 @@ static int ltdb_index_dn_simple(struct ldb_context *ldb,
/* the attribute is indexed. Pull the list of DNs that match the
search criterion */
dn = ldb_dn_key(tree->u.simple.attr, &tree->u.simple.value);
dn = ldb_dn_key(ldb, tree->u.simple.attr, &tree->u.simple.value);
if (!dn) return -1;
ret = ltdb_search_dn1(ldb, dn, &msg);
free(dn);
ldb_free(ldb, dn);
if (ret == 0 || ret == -1) {
return ret;
}
@ -150,16 +151,16 @@ static int ltdb_index_dn_simple(struct ldb_context *ldb,
el = &msg.elements[i];
list->dn = malloc_array_p(char *, el->num_values);
list->dn = ldb_malloc_array_p(ldb, char *, el->num_values);
if (!list->dn) {
break;
}
for (j=0;j<el->num_values;j++) {
list->dn[list->count] =
strdup((char *)el->values[j].data);
ldb_strdup(ldb, (char *)el->values[j].data);
if (!list->dn[list->count]) {
dn_list_free(list);
dn_list_free(ldb, list);
ltdb_search_dn1_free(ldb, &msg);
return -1;
}
@ -202,7 +203,7 @@ static int ltdb_index_dn_objectclass(struct ldb_context *ldb,
struct ldb_parse_tree tree2;
struct dn_list list2;
tree2.operation = LDB_OP_SIMPLE;
tree2.u.simple.attr = strdup(LTDB_OBJECTCLASS);
tree2.u.simple.attr = ldb_strdup(ldb, LTDB_OBJECTCLASS);
if (!tree2.u.simple.attr) {
return -1;
}
@ -214,10 +215,10 @@ static int ltdb_index_dn_objectclass(struct ldb_context *ldb,
ret = 1;
} else {
list_union(list, &list2);
dn_list_free(&list2);
dn_list_free(ldb, &list2);
}
}
free(tree2.u.simple.attr);
ldb_free(ldb, tree2.u.simple.attr);
}
}
}
@ -245,20 +246,21 @@ static int ltdb_index_dn_leaf(struct ldb_context *ldb,
list = list & list2
relies on the lists being sorted
*/
static int list_intersect(struct dn_list *list, const struct dn_list *list2)
static int list_intersect(struct ldb_context *ldb,
struct dn_list *list, const struct dn_list *list2)
{
struct dn_list list3;
int i;
if (list->count == 0 || list2->count == 0) {
/* 0 & X == 0 */
dn_list_free(list);
dn_list_free(ldb, list);
return 0;
}
list3.dn = malloc_array_p(char *, list->count);
list3.dn = ldb_malloc_array_p(ldb, char *, list->count);
if (!list3.dn) {
dn_list_free(list);
dn_list_free(ldb, list);
return -1;
}
list3.count = 0;
@ -269,11 +271,11 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2)
list3.dn[list3.count] = list->dn[i];
list3.count++;
} else {
free(list->dn[i]);
ldb_free(ldb, list->dn[i]);
}
}
free(list->dn);
ldb_free(ldb, list->dn);
list->dn = list3.dn;
list->count = list3.count;
@ -286,7 +288,8 @@ static int list_intersect(struct dn_list *list, const struct dn_list *list2)
list = list | list2
relies on the lists being sorted
*/
static int list_union(struct dn_list *list, const struct dn_list *list2)
static int list_union(struct ldb_context *ldb,
struct dn_list *list, const struct dn_list *list2)
{
int i;
char **d;
@ -294,13 +297,13 @@ static int list_union(struct dn_list *list, const struct dn_list *list2)
if (list->count == 0 && list2->count == 0) {
/* 0 | 0 == 0 */
dn_list_free(list);
dn_list_free(ldb, list);
return 0;
}
d = realloc_p(list->dn, char *, list->count + list2->count);
d = ldb_realloc_p(ldb, list->dn, char *, list->count + list2->count);
if (!d) {
dn_list_free(list);
dn_list_free(ldb, list);
return -1;
}
list->dn = d;
@ -308,9 +311,9 @@ static int list_union(struct dn_list *list, const struct dn_list *list2)
for (i=0;i<list2->count;i++) {
if (list_find(list2->dn[i], list->dn, count,
sizeof(char *), (comparison_fn_t)strcmp) == -1) {
list->dn[list->count] = strdup(list2->dn[i]);
list->dn[list->count] = ldb_strdup(ldb, list2->dn[i]);
if (!list->dn[list->count]) {
dn_list_free(list);
dn_list_free(ldb, list);
return -1;
}
list->count++;
@ -359,7 +362,7 @@ static int ltdb_index_dn_or(struct ldb_context *ldb,
if (v == -1) {
/* 1 || X == 1 */
dn_list_free(list);
dn_list_free(ldb, list);
return -1;
}
@ -367,16 +370,16 @@ static int ltdb_index_dn_or(struct ldb_context *ldb,
ret = 1;
*list = list2;
} else {
if (list_union(list, &list2) == -1) {
dn_list_free(&list2);
if (list_union(ldb, list, &list2) == -1) {
dn_list_free(ldb, &list2);
return -1;
}
dn_list_free(&list2);
dn_list_free(ldb, &list2);
}
}
if (list->count == 0) {
dn_list_free(list);
dn_list_free(ldb, list);
return 0;
}
@ -424,7 +427,7 @@ static int ltdb_index_dn_and(struct ldb_context *ldb,
if (v == 0) {
/* 0 && X == 0 */
dn_list_free(list);
dn_list_free(ldb, list);
return 0;
}
@ -436,15 +439,15 @@ static int ltdb_index_dn_and(struct ldb_context *ldb,
ret = 1;
*list = list2;
} else {
if (list_intersect(list, &list2) == -1) {
dn_list_free(&list2);
if (list_intersect(ldb, list, &list2) == -1) {
dn_list_free(ldb, &list2);
return -1;
}
dn_list_free(&list2);
dn_list_free(ldb, &list2);
}
if (list->count == 0) {
if (list->dn) free(list->dn);
if (list->dn) ldb_free(ldb, list->dn);
return 0;
}
}
@ -550,7 +553,7 @@ int ltdb_search_indexed(struct ldb_context *ldb,
and extract the needed attributes */
ret = ldb_index_filter(ldb, tree, base, scope, &dn_list,
attrs, res);
dn_list_free(&dn_list);
dn_list_free(ldb, &dn_list);
}
return ret;
@ -567,18 +570,19 @@ static int ltdb_index_add1_new(struct ldb_context *ldb,
struct ldb_message_element *el2;
/* add another entry */
el2 = realloc_p(msg->elements, struct ldb_message_element, msg->num_elements+1);
el2 = ldb_realloc_p(ldb, msg->elements,
struct ldb_message_element, msg->num_elements+1);
if (!el2) {
return -1;
}
msg->elements = el2;
msg->elements[msg->num_elements].name = strdup(LTDB_IDX);
msg->elements[msg->num_elements].name = ldb_strdup(ldb, 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 = malloc_p(struct ldb_val);
msg->elements[msg->num_elements].values = ldb_malloc_p(ldb, struct ldb_val);
if (!msg->elements[msg->num_elements].values) {
return -1;
}
@ -611,9 +615,9 @@ static int ltdb_index_add1_add(struct ldb_context *ldb,
}
}
v2 = realloc_p(msg->elements[idx].values,
struct ldb_val,
msg->elements[idx].num_values+1);
v2 = ldb_realloc_p(ldb, msg->elements[idx].values,
struct ldb_val,
msg->elements[idx].num_values+1);
if (!v2) {
return -1;
}
@ -634,23 +638,24 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn,
{
struct ldb_message msg;
char *dn_key;
int ret, i, added=0;
int ret, i, added=0, added_dn=0;
dn_key = ldb_dn_key(el->name, &el->values[v_idx]);
dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]);
if (!dn_key) {
return -1;
}
ret = ltdb_search_dn1(ldb, dn_key, &msg);
if (ret == -1) {
free(dn_key);
ldb_free(ldb, dn_key);
return -1;
}
if (ret == 0) {
msg.dn = strdup(dn_key);
added_dn = 1;
msg.dn = ldb_strdup(ldb, dn_key);
if (!msg.dn) {
free(dn_key);
ldb_free(ldb, dn_key);
errno = ENOMEM;
return -1;
}
@ -659,7 +664,7 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn,
msg.private_data = NULL;
}
free(dn_key);
ldb_free(ldb, dn_key);
for (i=0;i<msg.num_elements;i++) {
if (strcmp(LTDB_IDX, msg.elements[i].name) == 0) {
@ -679,7 +684,10 @@ static int ltdb_index_add1(struct ldb_context *ldb, char *dn,
}
if (added) {
free(msg.elements[i].name);
ldb_free(ldb, msg.elements[i].name);
}
if (added_dn) {
ldb_free(ldb, msg.dn);
}
ltdb_search_dn1_free(ldb, &msg);
@ -728,14 +736,14 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
char *dn_key;
int ret, i, j;
dn_key = ldb_dn_key(el->name, &el->values[v_idx]);
dn_key = ldb_dn_key(ldb, el->name, &el->values[v_idx]);
if (!dn_key) {
return -1;
}
ret = ltdb_search_dn1(ldb, dn_key, &msg);
if (ret == -1) {
free(dn_key);
ldb_free(ldb, dn_key);
return -1;
}
@ -743,6 +751,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
/* it wasn't indexed. Did we have an earlier error? If we did then
its gone now */
ltdb_search_dn1_free(ldb, &msg);
ldb_free(ldb, dn_key);
return 0;
}
@ -750,6 +759,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
if (i == -1) {
/* it ain't there. hmmm */
ltdb_search_dn1_free(ldb, &msg);
ldb_free(ldb, dn_key);
return 0;
}
@ -768,6 +778,7 @@ static int ltdb_index_del1(struct ldb_context *ldb, const char *dn,
}
ltdb_search_dn1_free(ldb, &msg);
ldb_free(ldb, dn_key);
return ret;
}
@ -841,7 +852,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *
ret = ltdb_index_add(ldb, &msg);
ltdb_unpack_data_free(&msg);
ltdb_unpack_data_free(ldb, &msg);
return ret;
}

View File

@ -71,7 +71,8 @@ static int ldb_val_equal_case_insensitive(const struct ldb_val *v1,
and case insensitive
return 1 for a match, 0 for a mis-match
*/
static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1,
static int ldb_val_equal_wildcard_ci(struct ldb_context *ldb,
const struct ldb_val *v1,
const struct ldb_val *v2)
{
char *s1, *s2;
@ -81,20 +82,20 @@ static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1,
return v1->data == v2->data;
}
s1 = ldb_casefold(v1->data);
s1 = ldb_casefold(ldb, v1->data);
if (!s1) {
return -1;
}
s2 = ldb_casefold(v2->data);
s2 = ldb_casefold(ldb, v2->data);
if (!s2) {
return -1;
}
ret = fnmatch(s2, s1, 0);
free(s1);
free(s2);
ldb_free(ldb, s1);
ldb_free(ldb, s2);
if (ret == 0) {
return 1;
@ -107,12 +108,13 @@ static int ldb_val_equal_wildcard_ci(const struct ldb_val *v1,
see if two ldb_val structures contain the same data with wildcards
return 1 for a match, 0 for a mis-match
*/
static int ldb_val_equal_wildcard(const struct ldb_val *v1,
static int ldb_val_equal_wildcard(struct ldb_context *ldb,
const struct ldb_val *v1,
const struct ldb_val *v2,
int flags)
{
if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
return ldb_val_equal_wildcard_ci(v1, v2);
return ldb_val_equal_wildcard_ci(ldb, v1, v2);
}
if (!v1->data || !v2->data) {
return v1->data == v2->data;
@ -182,7 +184,7 @@ int ldb_val_equal(struct ldb_context *ldb,
}
if (flags & LTDB_FLAG_WILDCARD) {
return ldb_val_equal_wildcard(v1, v2, flags);
return ldb_val_equal_wildcard(ldb, v1, v2, flags);
}
if (flags & LTDB_FLAG_CASE_INSENSITIVE) {

View File

@ -49,7 +49,7 @@
caller frees the data buffer after use
*/
int ltdb_pack_data(struct ldb_context *ctx,
int ltdb_pack_data(struct ldb_context *ldb,
const struct ldb_message *message,
struct TDB_DATA *data)
{
@ -74,7 +74,7 @@ int ltdb_pack_data(struct ldb_context *ctx,
}
/* allocate it */
data->dptr = malloc(size);
data->dptr = ldb_malloc(ldb, size);
if (!data->dptr) {
errno = ENOMEM;
return -1;
@ -116,14 +116,15 @@ int ltdb_pack_data(struct ldb_context *ctx,
/*
free the memory allocated from a ltdb_unpack_data()
*/
void ltdb_unpack_data_free(struct ldb_message *message)
void ltdb_unpack_data_free(struct ldb_context *ldb,
struct ldb_message *message)
{
int i;
for (i=0;i<message->num_elements;i++) {
if (message->elements[i].values) free(message->elements[i].values);
if (message->elements[i].values) ldb_free(ldb, message->elements[i].values);
}
if (message->elements) free(message->elements);
if (message->elements) ldb_free(ldb, message->elements);
}
@ -137,7 +138,7 @@ void ltdb_unpack_data_free(struct ldb_message *message)
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()
*/
int ltdb_unpack_data(struct ldb_context *ctx,
int ltdb_unpack_data(struct ldb_context *ldb,
const struct TDB_DATA *data,
struct ldb_message *message)
{
@ -192,8 +193,8 @@ int ltdb_unpack_data(struct ldb_context *ctx,
goto failed;
}
message->elements = malloc_array_p(struct ldb_message_element,
message->num_elements);
message->elements = ldb_malloc_array_p(ldb, struct ldb_message_element,
message->num_elements);
if (!message->elements) {
errno = ENOMEM;
@ -217,8 +218,9 @@ int ltdb_unpack_data(struct ldb_context *ctx,
message->elements[i].num_values = IVAL(p, 0);
message->elements[i].values = NULL;
if (message->elements[i].num_values != 0) {
message->elements[i].values = malloc_array_p(struct ldb_val,
message->elements[i].num_values);
message->elements[i].values = ldb_malloc_array_p(ldb,
struct ldb_val,
message->elements[i].num_values);
if (!message->elements[i].values) {
errno = ENOMEM;
goto failed;
@ -242,7 +244,7 @@ int ltdb_unpack_data(struct ldb_context *ctx,
return 0;
failed:
ltdb_unpack_data_free(message);
ltdb_unpack_data_free(ldb, message);
return -1;
}

View File

@ -38,27 +38,27 @@
/*
free a message that has all parts separately allocated
*/
static void msg_free_all_parts(struct ldb_message *msg)
static void msg_free_all_parts(struct ldb_context *ldb, struct ldb_message *msg)
{
int i, j;
if (msg->dn) free(msg->dn);
ldb_free(ldb, msg->dn);
for (i=0;i<msg->num_elements;i++) {
if (msg->elements[i].name) free(msg->elements[i].name);
ldb_free(ldb, msg->elements[i].name);
for (j=0;j<msg->elements[i].num_values;j++) {
if (msg->elements[i].values[j].data)
free(msg->elements[i].values[j].data);
ldb_free(ldb, msg->elements[i].values[j].data);
}
if (msg->elements[i].values) free(msg->elements[i].values);
ldb_free(ldb, msg->elements[i].values);
}
free(msg->elements);
free(msg);
ldb_free(ldb, msg->elements);
ldb_free(ldb, msg);
}
/*
duplicate a ldb_val structure
*/
struct ldb_val ldb_val_dup(const struct ldb_val *v)
struct ldb_val ldb_val_dup(struct ldb_context *ldb,
const struct ldb_val *v)
{
struct ldb_val v2;
v2.length = v->length;
@ -69,7 +69,7 @@ struct ldb_val ldb_val_dup(const struct ldb_val *v)
/* the +1 is to cope with buggy C library routines like strndup
that look one byte beyond */
v2.data = malloc(v->length+1);
v2.data = ldb_malloc(ldb, v->length+1);
if (!v2.data) {
v2.length = 0;
return v2;
@ -85,12 +85,13 @@ struct ldb_val ldb_val_dup(const struct ldb_val *v)
/*
add one element to a message
*/
static int msg_add_element(struct ldb_message *ret, const struct ldb_message_element *el)
static int msg_add_element(struct ldb_context *ldb,
struct ldb_message *ret, const struct ldb_message_element *el)
{
int i;
struct ldb_message_element *e2, *elnew;
e2 = realloc_p(ret->elements, struct ldb_message_element, ret->num_elements+1);
e2 = ldb_realloc_p(ldb, ret->elements, struct ldb_message_element, ret->num_elements+1);
if (!e2) {
return -1;
}
@ -98,13 +99,13 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele
elnew = &e2[ret->num_elements];
elnew->name = strdup(el->name);
elnew->name = ldb_strdup(ldb, el->name);
if (!elnew->name) {
return -1;
}
if (el->num_values) {
elnew->values = malloc_array_p(struct ldb_val, el->num_values);
elnew->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
if (!elnew->values) {
return -1;
}
@ -113,7 +114,7 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele
}
for (i=0;i<el->num_values;i++) {
elnew->values[i] = ldb_val_dup(&el->values[i]);
elnew->values[i] = ldb_val_dup(ldb, &el->values[i]);
if (elnew->values[i].length != el->values[i].length) {
return -1;
}
@ -129,12 +130,12 @@ static int msg_add_element(struct ldb_message *ret, const struct ldb_message_ele
/*
add all elements from one message into another
*/
static int msg_add_all_elements(struct ldb_message *ret,
static int msg_add_all_elements(struct ldb_context *ldb, struct ldb_message *ret,
const struct ldb_message *msg)
{
int i;
for (i=0;i<msg->num_elements;i++) {
if (msg_add_element(ret, &msg->elements[i]) != 0) {
if (msg_add_element(ldb, ret, &msg->elements[i]) != 0) {
return -1;
}
}
@ -153,14 +154,14 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
struct ldb_message *ret;
int i;
ret = malloc_p(struct ldb_message);
ret = ldb_malloc_p(ldb, struct ldb_message);
if (!ret) {
return NULL;
}
ret->dn = strdup(msg->dn);
ret->dn = ldb_strdup(ldb, msg->dn);
if (!ret->dn) {
free(ret);
ldb_free(ldb, ret);
return NULL;
}
@ -169,8 +170,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
ret->private_data = NULL;
if (!attrs) {
if (msg_add_all_elements(ret, msg) != 0) {
msg_free_all_parts(ret);
if (msg_add_all_elements(ldb, ret, msg) != 0) {
msg_free_all_parts(ldb, ret);
return NULL;
}
return ret;
@ -180,8 +181,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
struct ldb_message_element *el;
if (strcmp(attrs[i], "*") == 0) {
if (msg_add_all_elements(ret, msg) != 0) {
msg_free_all_parts(ret);
if (msg_add_all_elements(ldb, ret, msg) != 0) {
msg_free_all_parts(ldb, ret);
return NULL;
}
continue;
@ -191,8 +192,8 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
if (!el) {
continue;
}
if (msg_add_element(ret, el) != 0) {
msg_free_all_parts(ret);
if (msg_add_element(ldb, ret, el) != 0) {
msg_free_all_parts(ldb, ret);
return NULL;
}
}
@ -235,11 +236,11 @@ int ltdb_has_wildcard(struct ldb_context *ldb, const char *attr_name,
void ltdb_search_dn1_free(struct ldb_context *ldb, struct ldb_message *msg)
{
int i;
if (msg->private_data) free(msg->private_data);
ldb_free(ldb, msg->private_data);
for (i=0;i<msg->num_elements;i++) {
if (msg->elements[i].values) free(msg->elements[i].values);
ldb_free(ldb, msg->elements[i].values);
}
if (msg->elements) free(msg->elements);
ldb_free(ldb, msg->elements);
memset(msg, 0, sizeof(*msg));
}
@ -254,7 +255,7 @@ int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message
{
struct ltdb_private *ltdb = ldb->private_data;
int ret;
TDB_DATA tdb_key, tdb_data;
TDB_DATA tdb_key, tdb_data, tdb_data2;
/* form the key */
tdb_key = ltdb_key(ldb, dn);
@ -263,26 +264,35 @@ int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message
}
tdb_data = tdb_fetch(ltdb->tdb, tdb_key);
free(tdb_key.dptr);
ldb_free(ldb, tdb_key.dptr);
if (!tdb_data.dptr) {
return 0;
}
msg->private_data = tdb_data.dptr;
tdb_data2.dptr = ldb_malloc(ldb, tdb_data.dsize);
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(ldb, &tdb_data, msg);
ret = ltdb_unpack_data(ldb, &tdb_data2, msg);
if (ret == -1) {
free(tdb_data.dptr);
free(tdb_data2.dptr);
return -1;
}
if (!msg->dn) {
msg->dn = strdup(dn);
msg->dn = ldb_strdup(ldb, dn);
}
if (!msg->dn) {
free(tdb_data.dptr);
ldb_free(ldb, tdb_data2.dptr);
return -1;
}
@ -312,9 +322,9 @@ int ltdb_search_dn(struct ldb_context *ldb, char *dn,
return -1;
}
*res = malloc_array_p(struct ldb_message *, 2);
*res = ldb_malloc_array_p(ldb, struct ldb_message *, 2);
if (! *res) {
msg_free_all_parts(msg2);
msg_free_all_parts(ldb, msg2);
return -1;
}
@ -344,9 +354,9 @@ int ltdb_add_attr_results(struct ldb_context *ldb, struct ldb_message *msg,
}
/* add to the results list */
res2 = realloc_p(*res, struct ldb_message *, (*count)+2);
res2 = ldb_realloc_p(ldb, *res, struct ldb_message *, (*count)+2);
if (!res2) {
msg_free_all_parts(msg2);
msg_free_all_parts(ldb, msg2);
return -1;
}
@ -403,7 +413,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
/* see if it matches the given expression */
if (!ldb_message_match(sinfo->ldb, &msg, sinfo->tree,
sinfo->base, sinfo->scope)) {
ltdb_unpack_data_free(&msg);
ltdb_unpack_data_free(sinfo->ldb, &msg);
return 0;
}
@ -413,7 +423,7 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
sinfo->failures++;
}
ltdb_unpack_data_free(&msg);
ltdb_unpack_data_free(sinfo->ldb, &msg);
return ret;
}
@ -424,15 +434,18 @@ static int search_func(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, voi
*/
int ltdb_search_free(struct ldb_context *ldb, struct ldb_message **msgs)
{
struct ltdb_private *ltdb = ldb->private_data;
int i;
ltdb->last_err_string = NULL;
if (!msgs) return 0;
for (i=0;msgs[i];i++) {
msg_free_all_parts(msgs[i]);
msg_free_all_parts(ldb, msgs[i]);
}
free(msgs);
ldb_free(ldb, msgs);
return 0;
}
@ -480,9 +493,12 @@ int ltdb_search(struct ldb_context *ldb, const char *base,
enum ldb_scope scope, const char *expression,
char * const attrs[], struct ldb_message ***res)
{
struct ltdb_private *ltdb = ldb->private_data;
struct ldb_parse_tree *tree;
int ret;
ltdb->last_err_string = NULL;
if (ltdb_cache_load(ldb) != 0) {
return -1;
}
@ -490,8 +506,9 @@ int ltdb_search(struct ldb_context *ldb, const char *base,
*res = NULL;
/* form a parse tree for the expression */
tree = ldb_parse_tree(expression);
tree = ldb_parse_tree(ldb, expression);
if (!tree) {
ltdb->last_err_string = "expression parse failed";
return -1;
}
@ -507,7 +524,7 @@ int ltdb_search(struct ldb_context *ldb, const char *base,
}
}
ldb_parse_tree_free(tree);
ldb_parse_tree_free(ldb, tree);
return ret;
}

View File

@ -67,35 +67,35 @@ struct TDB_DATA ltdb_key(struct ldb_context *ldb, const char *dn)
if (strncmp(dn, prefix, strlen(prefix)) == 0 &&
(s = strchr(dn+strlen(prefix), ':'))) {
char *attr_name, *attr_name_folded;
attr_name = strndup(dn+strlen(prefix), (s-(dn+strlen(prefix))));
attr_name = ldb_strndup(ldb, dn+strlen(prefix), (s-(dn+strlen(prefix))));
if (!attr_name) {
goto failed;
}
flags = ltdb_attribute_flags(ldb, attr_name);
if (flags & LTDB_FLAG_CASE_INSENSITIVE) {
dn_folded = ldb_casefold(dn);
dn_folded = ldb_casefold(ldb, dn);
} else {
attr_name_folded = ldb_casefold(attr_name);
attr_name_folded = ldb_casefold(ldb, attr_name);
if (!attr_name_folded) {
goto failed;
}
asprintf(&dn_folded, "%s:%s:%s",
ldb_asprintf(ldb, &dn_folded, "%s:%s:%s",
prefix, attr_name_folded,
s+1);
free(attr_name_folded);
ldb_free(ldb, attr_name_folded);
}
free(attr_name);
ldb_free(ldb, attr_name);
} else {
dn_folded = ldb_casefold(dn);
dn_folded = ldb_casefold(ldb, dn);
}
if (!dn_folded) {
goto failed;
}
asprintf(&key_str, "DN=%s", dn_folded);
free(dn_folded);
ldb_asprintf(ldb, &key_str, "DN=%s", dn_folded);
ldb_free(ldb, dn_folded);
if (!key_str) {
goto failed;
@ -129,7 +129,7 @@ static int ltdb_lock(struct ldb_context *ldb)
ret = tdb_chainlock(ltdb->tdb, key);
free(key.dptr);
ldb_free(ldb, key.dptr);
return ret;
}
@ -149,7 +149,7 @@ static void ltdb_unlock(struct ldb_context *ldb)
tdb_chainunlock(ltdb->tdb, key);
free(key.dptr);
ldb_free(ldb, key.dptr);
}
@ -190,7 +190,7 @@ int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs)
ret = ltdb_pack_data(ldb, msg, &tdb_data);
if (ret == -1) {
free(tdb_key.dptr);
ldb_free(ldb, tdb_key.dptr);
return -1;
}
@ -205,8 +205,8 @@ int ltdb_store(struct ldb_context *ldb, const struct ldb_message *msg, int flgs)
}
done:
free(tdb_key.dptr);
free(tdb_data.dptr);
ldb_free(ldb, tdb_key.dptr);
ldb_free(ldb, tdb_data.dptr);
return ret;
}
@ -217,8 +217,11 @@ done:
*/
static int ltdb_add(struct ldb_context *ldb, const struct ldb_message *msg)
{
struct ltdb_private *ltdb = ldb->private_data;
int ret;
ltdb->last_err_string = NULL;
if (ltdb_lock(ldb) != 0) {
return -1;
}
@ -255,7 +258,7 @@ int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn)
}
ret = tdb_delete(ltdb->tdb, tdb_key);
free(tdb_key.dptr);
ldb_free(ldb, tdb_key.dptr);
return ret;
}
@ -265,9 +268,12 @@ int ltdb_delete_noindex(struct ldb_context *ldb, const char *dn)
*/
static int ltdb_delete(struct ldb_context *ldb, const char *dn)
{
struct ltdb_private *ltdb = ldb->private_data;
int ret;
struct ldb_message msg;
ltdb->last_err_string = NULL;
if (ltdb_lock(ldb) != 0) {
return -1;
}
@ -335,12 +341,13 @@ static int find_element(const struct ldb_message *msg, const char *name)
returns 0 on success, -1 on failure (and sets errno)
*/
static int msg_add_element(struct ldb_message *msg, struct ldb_message_element *el)
static int msg_add_element(struct ldb_context *ldb,
struct ldb_message *msg, struct ldb_message_element *el)
{
struct ldb_message_element *e2;
int i;
e2 = realloc_p(msg->elements, struct ldb_message_element,
e2 = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
msg->num_elements+1);
if (!e2) {
errno = ENOMEM;
@ -355,7 +362,7 @@ static int msg_add_element(struct ldb_message *msg, struct ldb_message_element *
e2->flags = el->flags;
e2->values = NULL;
if (el->num_values != 0) {
e2->values = malloc_array_p(struct ldb_val, el->num_values);
e2->values = ldb_malloc_array_p(ldb, struct ldb_val, el->num_values);
if (!e2->values) {
free(e2->name);
errno = ENOMEM;
@ -375,12 +382,13 @@ static int msg_add_element(struct ldb_message *msg, struct ldb_message_element *
/*
delete all elements having a specified attribute name
*/
static int msg_delete_attribute(struct ldb_message *msg, const char *name)
static int msg_delete_attribute(struct ldb_context *ldb,
struct ldb_message *msg, const char *name)
{
int i, count=0;
struct ldb_message_element *el2;
el2 = malloc_array_p(struct ldb_message_element, msg->num_elements);
el2 = ldb_malloc_array_p(ldb, struct ldb_message_element, msg->num_elements);
if (!el2) {
errno = ENOMEM;
return -1;
@ -390,12 +398,12 @@ static int msg_delete_attribute(struct ldb_message *msg, const char *name)
if (ldb_attr_cmp(msg->elements[i].name, name) != 0) {
el2[count++] = msg->elements[i];
} else {
if (msg->elements[i].values) free(msg->elements[i].values);
ldb_free(ldb, msg->elements[i].values);
}
}
msg->num_elements = count;
if (msg->elements) free(msg->elements);
ldb_free(ldb, msg->elements);
msg->elements = el2;
return 0;
@ -425,7 +433,7 @@ static int msg_delete_element(struct ldb_context *ldb,
if (ldb_val_equal(ldb, msg->elements[i].name, &el->values[i], val)) {
if (i<el->num_values-1) {
memmove(&el->values[i], &el->values[i+1],
sizeof(el->values[i])*el->num_values-(i+1));
sizeof(el->values[i])*(el->num_values-(i+1)));
}
el->num_values--;
return 0;
@ -463,7 +471,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
ret = ltdb_unpack_data(ldb, &tdb_data, &msg2);
if (ret == -1) {
free(tdb_key.dptr);
ldb_free(ldb, tdb_key.dptr);
free(tdb_data.dptr);
return -1;
}
@ -483,7 +491,7 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
errno = EEXIST;
goto failed;
}
if (msg_add_element(&msg2, &msg->elements[i]) != 0) {
if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
goto failed;
}
break;
@ -491,11 +499,11 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
case LDB_FLAG_MOD_REPLACE:
/* replace all elements of this attribute name with the elements
listed */
if (msg_delete_attribute(&msg2, msg->elements[i].name) != 0) {
if (msg_delete_attribute(ldb, &msg2, msg->elements[i].name) != 0) {
goto failed;
}
/* add the replacement element */
if (msg_add_element(&msg2, &msg->elements[i]) != 0) {
if (msg_add_element(ldb, &msg2, &msg->elements[i]) != 0) {
goto failed;
}
break;
@ -504,8 +512,8 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
/* we could be being asked to delete all
values or just some values */
if (msg->elements[i].num_values == 0) {
if (msg_delete_attribute(&msg2,
msg->elements[i].name) != 0) {
if (msg_delete_attribute(ldb, &msg2,
msg->elements[i].name) != 0) {
goto failed;
}
break;
@ -525,15 +533,15 @@ int ltdb_modify_internal(struct ldb_context *ldb, const struct ldb_message *msg)
/* we've made all the mods - save the modified record back into the database */
ret = ltdb_store(ldb, &msg2, TDB_MODIFY);
free(tdb_key.dptr);
ldb_free(ldb, tdb_key.dptr);
free(tdb_data.dptr);
ltdb_unpack_data_free(&msg2);
ltdb_unpack_data_free(ldb, &msg2);
return ret;
failed:
free(tdb_key.dptr);
ldb_free(ldb, tdb_key.dptr);
free(tdb_data.dptr);
ltdb_unpack_data_free(&msg2);
ltdb_unpack_data_free(ldb, &msg2);
return -1;
}
@ -542,8 +550,11 @@ failed:
*/
static int ltdb_modify(struct ldb_context *ldb, const struct ldb_message *msg)
{
struct ltdb_private *ltdb = ldb->private_data;
int ret;
ltdb->last_err_string = NULL;
if (ltdb_lock(ldb) != 0) {
return -1;
}
@ -572,10 +583,13 @@ static int ltdb_close(struct ldb_context *ldb)
struct ltdb_private *ltdb = ldb->private_data;
int ret;
ltdb->last_err_string = NULL;
ltdb_cache_free(ldb);
ldb_set_alloc(ldb, NULL, NULL);
ret = tdb_close(ltdb->tdb);
free(ltdb);
ldb_free(ldb, ltdb);
free(ldb);
return ret;
}
@ -587,6 +601,9 @@ static int ltdb_close(struct ldb_context *ldb)
static const char *ltdb_errstring(struct ldb_context *ldb)
{
struct ltdb_private *ltdb = ldb->private_data;
if (ltdb->last_err_string) {
return ltdb->last_err_string;
}
return tdb_errorstr(ltdb->tdb);
}
@ -598,7 +615,8 @@ static const struct ldb_backend_ops ltdb_ops = {
ltdb_add,
ltdb_modify,
ltdb_delete,
ltdb_errstring
ltdb_errstring,
ltdb_cache_free
};
@ -615,6 +633,12 @@ struct ldb_context *ltdb_connect(const char *url,
TDB_CONTEXT *tdb;
struct ldb_context *ldb;
ldb = calloc(1, sizeof(struct ldb_context));
if (!ldb) {
errno = ENOMEM;
return NULL;
}
/* parse the url */
if (strchr(url, ':')) {
if (strncmp(url, "tdb://", 6) != 0) {
@ -637,12 +661,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);
return NULL;
}
ltdb = malloc_p(struct ltdb_private);
ltdb = ldb_malloc_p(ldb, struct ltdb_private);
if (!ltdb) {
tdb_close(tdb);
free(ldb);
errno = ENOMEM;
return NULL;
}
@ -652,14 +678,6 @@ struct ldb_context *ltdb_connect(const char *url,
memset(&ltdb->cache, 0, sizeof(ltdb->cache));
ldb = malloc_p(struct ldb_context);
if (!ldb) {
tdb_close(tdb);
free(ltdb);
errno = ENOMEM;
return NULL;
}
ldb->private_data = ltdb;
ldb->ops = &ltdb_ops;

View File

@ -19,6 +19,9 @@ struct ltdb_private {
int flags;
} last_attribute;
} cache;
/* error if an internal ldb+tdb error */
const char *last_err_string;
};
/* special record types */

View File

@ -1,17 +1,17 @@
echo "Adding base elements"
bin/ldbadd tests/test.ldif || exit 1
$VALGRIND bin/ldbadd tests/test.ldif || exit 1
echo "Modifying elements"
bin/ldbmodify tests/test-modify.ldif || exit 1
$VALGRIND bin/ldbmodify tests/test-modify.ldif || exit 1
echo "Showing modified record"
bin/ldbsearch '(uid=uham)' || exit 1
$VALGRIND bin/ldbsearch '(uid=uham)' || exit 1
echo "Starting ldbtest"
time bin/ldbtest -r 1000 -s 100 || exit 1
time $VALGRIND bin/ldbtest -r 1000 -s 10 || exit 1
echo "Adding index"
bin/ldbadd tests/test-index.ldif || exit 1
$VALGRIND bin/ldbadd tests/test-index.ldif || exit 1
echo "Starting ldbtest indexed"
time bin/ldbtest -r 1000 -s 5000 || exit 1
time $VALGRIND bin/ldbtest -r 1000 -s 5000 || exit 1

View File

@ -55,7 +55,7 @@ static int process_file(struct ldb_context *ldb, FILE *f)
struct ldb_ldif *ldif;
int ret, count=0;
while ((ldif = ldif_read_file(f))) {
while ((ldif = ldif_read_file(ldb, f))) {
if (ldif->changetype != LDB_CHANGETYPE_ADD &&
ldif->changetype != LDB_CHANGETYPE_NONE) {
fprintf(stderr, "Only CHANGETYPE_ADD records allowed\n");
@ -70,7 +70,7 @@ static int process_file(struct ldb_context *ldb, FILE *f)
} else {
count++;
}
ldif_read_free(ldif);
ldif_read_free(ldb, ldif);
}
return count;

View File

@ -60,7 +60,7 @@ static int modify_record(struct ldb_context *ldb,
continue;
}
if (ldb_msg_add(&mod,
if (ldb_msg_add(ldb, &mod,
&msg2->elements[i],
el?LDB_FLAG_MOD_REPLACE:LDB_FLAG_MOD_ADD) != 0) {
return -1;
@ -72,7 +72,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(&mod,
if (ldb_msg_add_empty(ldb, &mod,
msg1->elements[i].name,
LDB_FLAG_MOD_DELETE) != 0) {
return -1;
@ -159,7 +159,8 @@ static int merge_edits(struct ldb_context *ldb,
/*
save a set of messages as ldif to a file
*/
static int save_ldif(FILE *f, struct ldb_message **msgs, int count)
static int save_ldif(struct ldb_context *ldb,
FILE *f, struct ldb_message **msgs, int count)
{
int i;
@ -172,7 +173,7 @@ static int save_ldif(FILE *f, struct ldb_message **msgs, int count)
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = *msgs[i];
ldif_write_file(f, &ldif);
ldif_write_file(ldb, f, &ldif);
}
return 0;
@ -211,13 +212,13 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun
return -1;
}
if (save_ldif(f, msgs1, count1) != 0) {
if (save_ldif(ldb, f, msgs1, count1) != 0) {
return -1;
}
fclose(f);
asprintf(&cmd, "%s %s", editor, template);
ldb_asprintf(ldb, &cmd, "%s %s", editor, template);
if (!cmd) {
unlink(template);
@ -242,8 +243,8 @@ static int do_edit(struct ldb_context *ldb, struct ldb_message **msgs1, int coun
return -1;
}
while ((ldif = ldif_read_file(f))) {
msgs2 = realloc_p(msgs2, struct ldb_message *, count2+1);
while ((ldif = ldif_read_file(ldb, f))) {
msgs2 = ldb_realloc_p(ldb, msgs2, struct ldb_message *, count2+1);
if (!msgs2) {
fprintf(stderr, "out of memory");
return -1;

View File

@ -54,7 +54,7 @@ static int process_file(struct ldb_context *ldb, FILE *f)
struct ldb_ldif *ldif;
int ret = -1, count = 0;
while ((ldif = ldif_read_file(f))) {
while ((ldif = ldif_read_file(ldb, f))) {
switch (ldif->changetype) {
case LDB_CHANGETYPE_NONE:
case LDB_CHANGETYPE_ADD:
@ -74,7 +74,7 @@ static int process_file(struct ldb_context *ldb, FILE *f)
} else {
count++;
}
ldif_read_free(ldif);
ldif_read_free(ldb, ldif);
}
return count;

View File

@ -45,11 +45,11 @@ static void usage(void)
exit(1);
}
static void do_search(struct ldb_context *ldb,
const char *basedn,
int scope,
const char *expression,
char * const *attrs)
static int do_search(struct ldb_context *ldb,
const char *basedn,
int scope,
const char *expression,
char * const *attrs)
{
int ret, i;
struct ldb_message **msgs;
@ -57,7 +57,7 @@ static void do_search(struct ldb_context *ldb,
ret = ldb_search(ldb, basedn, scope, expression, attrs, &msgs);
if (ret == -1) {
printf("search failed - %s\n", ldb_errstring(ldb));
return;
return -1;
}
printf("# returned %d records\n", ret);
@ -69,7 +69,7 @@ static void do_search(struct ldb_context *ldb,
ldif.changetype = LDB_CHANGETYPE_NONE;
ldif.msg = *msgs[i];
ldif_write_file(stdout, &ldif);
ldif_write_file(ldb, stdout, &ldif);
}
if (ret > 0) {
@ -79,6 +79,8 @@ static void do_search(struct ldb_context *ldb,
exit(1);
}
}
return 0;
}
int main(int argc, char * const argv[])
@ -89,7 +91,7 @@ static void do_search(struct ldb_context *ldb,
const char *basedn = NULL;
int opt;
enum ldb_scope scope = LDB_SCOPE_SUBTREE;
int interactive = 0;
int interactive = 0, ret=0;
ldb_url = getenv("LDB_URL");
@ -150,12 +152,14 @@ static void do_search(struct ldb_context *ldb,
if (interactive) {
char line[1024];
while (fgets(line, sizeof(line), stdin)) {
do_search(ldb, basedn, scope, line, attrs);
if (do_search(ldb, basedn, scope, line, attrs) == -1) {
ret = -1;
}
}
} else {
do_search(ldb, basedn, scope, argv[0], attrs);
ret = do_search(ldb, basedn, scope, argv[0], attrs);
}
ldb_close(ldb);
return 0;
return ret;
}

View File

@ -84,7 +84,7 @@ static void add_records(struct ldb_context *ldb,
el[2].name = "uid";
el[2].num_values = 1;
el[2].values = vals[2];
vals[2][0].data = ldb_casefold(name);
vals[2][0].data = ldb_casefold(ldb, name);
vals[2][0].length = strlen(vals[2][0].data);
el[3].flags = 0;
@ -121,7 +121,7 @@ static void add_records(struct ldb_context *ldb,
free(name);
free(msg.dn);
free(vals[1][0].data);
free(vals[2][0].data);
ldb_free(ldb, vals[2][0].data);
free(vals[3][0].data);
}