*/
#include "includes.h"
-#include "ldb_tdb.h"
+#include "ldb/ldb_tdb/ldb_tdb.h"
/*
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);
}
-/*
- TODO: this should take advantage of the sorted nature of the message
-
- return index of the attribute, or -1 if not found
-*/
-int ldb_msg_find_attr(const struct ldb_message *msg, const char *attr)
-{
- int i;
- for (i=0;i<msg->num_elements;i++) {
- if (strcmp(msg->elements[i].name, attr) == 0) {
- return i;
- }
- }
- return -1;
-}
-
/*
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;
/* 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;
/*
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;
}
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;
}
}
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;
}
/*
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) {
+ int flags = ltdb_attribute_flags(ldb, msg->elements[i].name);
+ if ((msg->dn[0] != '@') && (flags & LTDB_FLAG_HIDDEN)) {
+ continue;
+ }
+ if (msg_add_element(ldb, ret, &msg->elements[i]) != 0) {
return -1;
}
}
*/
static struct ldb_message *ltdb_pull_attrs(struct ldb_context *ldb,
const struct ldb_message *msg,
- const char **attrs)
+ const char * const *attrs)
{
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;
}
ret->num_elements = 0;
ret->elements = NULL;
- ret->private = NULL;
+ 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;
}
for (i=0;attrs[i];i++) {
- int j;
+ 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;
}
- j = ldb_msg_find_attr(msg, attrs[i]);
- if (j == -1) {
+
+ el = ldb_msg_find_element(msg, attrs[i]);
+ if (!el) {
continue;
}
- do {
- if (msg_add_element(ret, &msg->elements[j]) != 0) {
- msg_free_all_parts(ret);
- return NULL;
- }
- } while (++j < msg->num_elements &&
- strcmp(attrs[i], msg->elements[j].name) == 0);
+ if (msg_add_element(ldb, ret, el) != 0) {
+ msg_free_all_parts(ldb, ret);
+ return NULL;
+ }
}
return ret;
/*
see if a ldb_val is a wildcard
+ return 1 if yes, 0 if no
*/
-int ltdb_has_wildcard(const struct ldb_val *val)
+int ltdb_has_wildcard(struct ldb_context *ldb, const char *attr_name,
+ const struct ldb_val *val)
{
- if (val->length == 1 && ((char *)val->data)[0] == '*') {
+ int flags;
+
+ /* all attribute types recognise the "*" wildcard */
+ if (val->length == 1 && strncmp((char *)val->data, "*", 1) == 0) {
return 1;
}
+
+ if (strpbrk(val->data, "*?") == NULL) {
+ return 0;
+ }
+
+ flags = ltdb_attribute_flags(ldb, attr_name);
+ if (flags & LTDB_FLAG_WILDCARD) {
+ return 1;
+ }
+
return 0;
}
void ltdb_search_dn1_free(struct ldb_context *ldb, struct ldb_message *msg)
{
int i;
- if (msg->dn) free(msg->dn);
- if (msg->private) free(msg->private);
+ 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));
}
*/
int ltdb_search_dn1(struct ldb_context *ldb, const char *dn, struct ldb_message *msg)
{
- struct ltdb_private *ltdb = ldb->private;
+ struct ltdb_private *ltdb = ldb->private_data;
int ret;
- TDB_DATA tdb_key, tdb_data;
+ TDB_DATA tdb_key, tdb_data, tdb_data2;
+
+ memset(msg, 0, sizeof(*msg));
/* form the key */
- tdb_key = ltdb_key(dn);
+ tdb_key = ltdb_key(ldb, dn);
if (!tdb_key.dptr) {
return -1;
}
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->dn = strdup(dn);
- if (!msg->dn) {
+ tdb_data2.dptr = ldb_malloc(ldb, tdb_data.dsize);
+ if (!tdb_data2.dptr) {
free(tdb_data.dptr);
return -1;
}
- msg->private = tdb_data.dptr;
+ 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 = ldb_strdup(ldb, dn);
+ }
+ if (!msg->dn) {
+ ldb_free(ldb, tdb_data2.dptr);
+ return -1;
+ }
+
return 1;
}
search the database for a single simple dn
*/
int ltdb_search_dn(struct ldb_context *ldb, char *dn,
- const char *attrs[], struct ldb_message ***res)
+ const char * const attrs[], struct ldb_message ***res)
{
int ret;
struct ldb_message msg, *msg2;
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;
}
return 0 on success, -1 on failure
*/
int ltdb_add_attr_results(struct ldb_context *ldb, struct ldb_message *msg,
- const char *attrs[],
+ const char * const attrs[],
unsigned int *count,
struct ldb_message ***res)
{
}
/* 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;
}
struct ldb_parse_tree *tree;
const char *base;
enum ldb_scope scope;
- const char **attrs;
+ const char * const *attrs;
struct ldb_message **msgs;
int failures;
int count;
return 0;
}
- msg.dn = key.dptr + 3;
-
/* unpack the record */
ret = ltdb_unpack_data(sinfo->ldb, &data, &msg);
if (ret == -1) {
return 0;
}
+ if (!msg.dn) {
+ msg.dn = key.dptr + 3;
+ }
+
/* 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;
}
sinfo->failures++;
}
- ltdb_unpack_data_free(&msg);
+ ltdb_unpack_data_free(sinfo->ldb, &msg);
return ret;
}
*/
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;
}
const char *base,
enum ldb_scope scope,
struct ldb_parse_tree *tree,
- const char *attrs[], struct ldb_message ***res)
+ const char * const attrs[], struct ldb_message ***res)
{
- struct ltdb_private *ltdb = ldb->private;
+ struct ltdb_private *ltdb = ldb->private_data;
int ret;
struct ltdb_search_info sinfo;
*/
int ltdb_search(struct ldb_context *ldb, const char *base,
enum ldb_scope scope, const char *expression,
- const char *attrs[], struct ldb_message ***res)
+ const 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;
+ }
+
*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;
}
if (tree->operation == LDB_OP_SIMPLE &&
- strcmp(tree->u.simple.attr, "dn") == 0 &&
- !ltdb_has_wildcard(&tree->u.simple.value)) {
+ ldb_attr_cmp(tree->u.simple.attr, "dn") == 0 &&
+ !ltdb_has_wildcard(ldb, tree->u.simple.attr, &tree->u.simple.value)) {
/* yay! its a nice simple one */
ret = ltdb_search_dn(ldb, tree->u.simple.value.data, attrs, res);
} else {
}
}
- ldb_parse_tree_free(tree);
+ ldb_parse_tree_free(ldb, tree);
return ret;
}