*/
#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_private.h"
#include "ldb/ldb_ldap/ldb_ldap.h"
#if 0
/*
close/free the connection
*/
-static int lldb_close(struct ldb_context *ldb)
+static int lldb_close(struct ldb_module *module)
{
int i, ret = 0;
- struct lldb_private *lldb = ldb->private_data;
+ struct ldb_context *ldb = module->ldb;
+ struct lldb_private *lldb = module->private_data;
if (ldap_unbind(lldb->ldap) != LDAP_SUCCESS) {
ret = -1;
}
+ ldb_set_alloc(ldb, NULL, NULL);
+
if (lldb->options) {
for (i=0;lldb->options[i];i++) {
- 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;
}
+/*
+ rename a record
+*/
+static int lldb_rename(struct ldb_module *module, const char *olddn, const char *newdn)
+{
+ struct ldb_context *ldb = module->ldb;
+ struct lldb_private *lldb = module->private_data;
+ int ret = 0;
+ char *newrdn, *p;
+ const char *parentdn = "";
+
+ /* ignore ltdb specials */
+ if (olddn[0] == '@' ||newdn[0] == '@') {
+ return 0;
+ }
+
+ newrdn = ldb_strdup(ldb, newdn);
+ if (!newrdn) {
+ return -1;
+ }
+
+ p = strchr(newrdn, ',');
+ if (p) {
+ *p++ = '\0';
+ parentdn = p;
+ }
+
+ 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;
+ }
+
+ 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 */
*/
static int lldb_msg_free(struct ldb_context *ldb, struct ldb_message *msg)
{
- int i, j;
- free(msg->dn);
+ unsigned int i, j;
+ 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;
}
/*
free a search result
*/
-static int lldb_search_free(struct ldb_context *ldb, struct ldb_message **res)
+static int lldb_search_free(struct ldb_module *module, struct ldb_message **res)
{
+ struct ldb_context *ldb = module->ldb;
int i;
for (i=0;res[i];i++) {
if (lldb_msg_free(ldb, res[i]) != 0) {
return -1;
}
}
- free(res);
+ ldb_free(ldb, res);
return 0;
}
/*
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;
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;
el = &msg->elements[msg->num_elements];
- el->name = strdup(attr);
+ el->name = ldb_strdup(ldb, attr);
if (!el->name) {
errno = ENOMEM;
return -1;
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;
}
/*
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) = 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;
if (msg_count == count) {
/* hmm, got too many? */
- fprintf(stderr,"Too many messages?!\n");
+ ldb_debug(ldb, LDB_DEBUG_FATAL, "Fatal: ldap message count inconsistent\n");
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;
}
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;
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);
}
return msg_count;
failed:
- if (*res) lldb_search_free(ldb, *res);
+ if (*res) lldb_search_free(module, *res);
return -1;
}
/*
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;
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);
}
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;
+ unsigned int i, j;
+ int 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;
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;
}
}
}
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;
}
return mods;
failed:
- lldb_mods_free(mods);
+ lldb_mods_free(ldb, 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;
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;
}
/*
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;
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;
+}
+
+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 = {
+static const struct ldb_module_ops lldb_ops = {
+ "ldap",
lldb_close,
lldb_search,
lldb_search_free,
lldb_add,
lldb_modify,
lldb_delete,
+ lldb_rename,
+ lldb_lock,
+ lldb_unlock,
lldb_errstring
};
{
struct ldb_context *ldb = NULL;
struct lldb_private *lldb = NULL;
- int i;
+ int i, version = 3;
- 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;
}
goto failed;
}
- ldb->ops = &lldb_ops;
- ldb->private_data = lldb;
+ lldb->last_rc = ldap_set_option(lldb->ldap, LDAP_OPT_PROTOCOL_VERSION, &version);
+ if (lldb->last_rc != LDAP_SUCCESS) {
+ goto failed;
+ }
+
+ ldb->modules = ldb_malloc_p(ldb, struct ldb_module);
+ if (!ldb->modules) {
+ ldb_free(ldb, ldb);
+ 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 = 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;
}
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;
}