*/
#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_private.h"
#include "ldb/ldb_ldap/ldb_ldap.h"
#if 0
}
#endif
-/*
- close/free the connection
-*/
-static int lldb_close(struct ldb_context *ldb)
-{
- int i, ret = 0;
- struct lldb_private *lldb = ldb->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;
-}
-
/*
rename a record
*/
-static int lldb_rename(struct ldb_context *ldb, const char *olddn, const char *newdn)
+static int lldb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
{
- struct lldb_private *lldb = ldb->private_data;
+ struct lldb_private *lldb = module->private_data;
int ret = 0;
char *newrdn, *p;
const char *parentdn = "";
+ TALLOC_CTX *mem_ctx = talloc_new(lldb);
/* 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;
}
}
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;
}
/*
delete a record
*/
-static int lldb_delete(struct ldb_context *ldb, const char *dn)
+static int lldb_delete(struct ldb_module *module, const char *dn)
{
- struct lldb_private *lldb = ldb->private_data;
+ struct lldb_private *lldb = module->private_data;
int ret = 0;
/* ignore ltdb specials */
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_context *ldb, struct ldb_message **res)
-{
- int i;
- for (i=0;res[i];i++) {
- if (lldb_msg_free(ldb, res[i]) != 0) {
- return -1;
- }
- }
- ldb_free(ldb, res);
- return 0;
-}
-
-
/*
add a single set of ldap message values to a ldb_message
*/
return -1;
}
- el = ldb_realloc_p(ldb, msg->elements, struct ldb_message_element,
- msg->num_elements + 1);
+ el = talloc_realloc(msg, msg->elements, struct ldb_message_element,
+ msg->num_elements + 1);
if (!el) {
errno = ENOMEM;
return -1;
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;
el->flags = 0;
el->num_values = 0;
- el->values = ldb_malloc_array_p(ldb, struct ldb_val, count);
+ el->values = talloc_array(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++;
}
/*
search for matching records
*/
-static int lldb_search(struct ldb_context *ldb, const char *base,
+static int lldb_search(struct ldb_module *module, const char *base,
enum ldb_scope scope, const char *expression,
const char * const *attrs, struct ldb_message ***res)
{
- struct lldb_private *lldb = ldb->private_data;
+ struct ldb_context *ldb = module->ldb;
+ struct lldb_private *lldb = module->private_data;
int count, msg_count;
LDAPMessage *ldapres, *msg;
+ if (base == NULL) {
+ base = "";
+ }
+
lldb->last_rc = ldap_search_s(lldb->ldap, base, (int)scope,
- expression, attrs, 0, &ldapres);
+ expression,
+ discard_const_p(char *, attrs),
+ 0, &ldapres);
if (lldb->last_rc != LDAP_SUCCESS) {
return -1;
}
return count;
}
- (*res) = ldb_malloc_array_p(ldb, struct ldb_message *, count+1);
+ (*res) = talloc_array(lldb, struct ldb_message *, count+1);
if (! *res) {
ldap_msgfree(ldapres);
errno = ENOMEM;
break;
}
- (*res)[msg_count] = ldb_malloc_p(ldb, struct ldb_message);
+ (*res)[msg_count] = talloc(*res, struct ldb_message);
if (!(*res)[msg_count]) {
goto failed;
}
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;
return msg_count;
failed:
- if (*res) lldb_search_free(ldb, *res);
+ if (*res) talloc_free(*res);
return -1;
}
/*
- free a set of mods from lldb_msg_to_mods()
+ search for matching records using a ldb_parse_tree
*/
-static void lldb_mods_free(struct ldb_context *ldb, LDAPMod **mods)
+static int lldb_search_bytree(struct ldb_module *module, const char *base,
+ enum ldb_scope scope, struct ldb_parse_tree *tree,
+ const char * const *attrs, struct ldb_message ***res)
{
- int i, j;
-
- if (!mods) return;
+ struct lldb_private *lldb = module->private_data;
+ char *expression;
+ int ret;
- 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]);
+ expression = ldb_filter_from_tree(lldb, tree);
+ if (expression == NULL) {
+ return -1;
}
- ldb_free(ldb, mods);
+ ret = lldb_search(module, base, scope, expression, attrs, res);
+ talloc_free(expression);
+ return ret;
}
int num_mods = 0;
/* allocate maximum number of elements needed */
- mods = ldb_malloc_array_p(ldb, LDAPMod *, msg->num_elements+1);
+ mods = talloc_array(ldb, LDAPMod *, msg->num_elements+1);
if (!mods) {
errno = ENOMEM;
return NULL;
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(ldb, LDAPMod);
if (!mods[num_mods]) {
goto failed;
}
}
}
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(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(mods[num_mods]->mod_vals.modv_bvals,
+ struct berval);
if (!mods[num_mods]->mod_vals.modv_bvals[j]) {
goto failed;
}
return mods;
failed:
- lldb_mods_free(ldb, mods);
+ talloc_free(mods);
return NULL;
}
/*
add a record
*/
-static int lldb_add(struct ldb_context *ldb, const struct ldb_message *msg)
+static int lldb_add(struct ldb_module *module, const struct ldb_message *msg)
{
- struct lldb_private *lldb = ldb->private_data;
+ struct ldb_context *ldb = module->ldb;
+ struct lldb_private *lldb = module->private_data;
LDAPMod **mods;
int ret = 0;
ret = -1;
}
- lldb_mods_free(ldb, mods);
+ talloc_free(mods);
return ret;
}
/*
modify a record
*/
-static int lldb_modify(struct ldb_context *ldb, const struct ldb_message *msg)
+static int lldb_modify(struct ldb_module *module, const struct ldb_message *msg)
{
- struct lldb_private *lldb = ldb->private_data;
+ struct ldb_context *ldb = module->ldb;
+ struct lldb_private *lldb = module->private_data;
LDAPMod **mods;
int ret = 0;
ret = -1;
}
- lldb_mods_free(ldb, mods);
+ talloc_free(mods);
return ret;
}
+static int lldb_lock(struct ldb_module *module, const char *lockname)
+{
+ int ret = 0;
+
+ if (lockname == NULL) {
+ return -1;
+ }
+
+ /* TODO implement a local locking mechanism here */
+
+ return ret;
+}
+
+static int lldb_unlock(struct ldb_module *module, const char *lockname)
+{
+ int ret = 0;
+
+ if (lockname == NULL) {
+ return -1;
+ }
+
+ /* TODO implement a local unlocking mechanism here */
+
+ return ret;
+}
/*
return extended error information
*/
-static const char *lldb_errstring(struct ldb_context *ldb)
+static const char *lldb_errstring(struct ldb_module *module)
{
- struct lldb_private *lldb = ldb->private_data;
+ struct lldb_private *lldb = module->private_data;
return ldap_err2string(lldb->last_rc);
}
-static const struct ldb_backend_ops lldb_ops = {
- lldb_close,
- lldb_search,
- lldb_search_free,
- lldb_add,
- lldb_modify,
- lldb_delete,
- lldb_rename,
- lldb_errstring
+static const struct ldb_module_ops lldb_ops = {
+ .name = "ldap",
+ .search = lldb_search,
+ .search_bytree = lldb_search_bytree,
+ .add_record = lldb_add,
+ .modify_record = lldb_modify,
+ .delete_record = lldb_delete,
+ .rename_record = lldb_rename,
+ .named_lock = lldb_lock,
+ .named_unlock = lldb_unlock,
+ .errstring = lldb_errstring
};
+static int lldb_destructor(void *p)
+{
+ struct lldb_private *lldb = p;
+ ldap_unbind(lldb->ldap);
+ return 0;
+}
+
/*
connect to the database
*/
struct lldb_private *lldb = NULL;
int i, version = 3;
- ldb = calloc(1, sizeof(struct ldb_context));
+ ldb = talloc(NULL, struct ldb_context);
if (!ldb) {
errno = ENOMEM;
goto failed;
}
- lldb = ldb_malloc_p(ldb, struct lldb_private);
+ ldb->debug_ops.debug = NULL;
+
+ lldb = talloc(ldb, struct lldb_private);
if (!lldb) {
- ldb_free(ldb, ldb);
errno = ENOMEM;
goto failed;
}
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->ops = &lldb_ops;
- ldb->private_data = lldb;
+ ldb->modules = talloc(ldb, struct ldb_module);
+ if (!ldb->modules) {
+ errno = ENOMEM;
+ goto failed;
+ }
+ ldb->modules->ldb = ldb;
+ ldb->modules->prev = ldb->modules->next = NULL;
+ ldb->modules->private_data = lldb;
+ ldb->modules->ops = &lldb_ops;
if (options) {
/* take a copy of the options array, so we don't have to rely
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(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;
}
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;
}