* Author: Derrell Lipman (based on Andrew Tridgell's LDAP backend)
*/
-#include <stdarg.h>
#include "includes.h"
-#include "ldb/include/ldb.h"
-#include "ldb/include/ldb_private.h"
+#include "ldb/include/includes.h"
+
#include "ldb/ldb_sqlite3/ldb_sqlite3.h"
/*
* For simple searches, we want to retrieve the list of EIDs that
* match the criteria.
*/
- attr = ldb_casefold(mem_ctx, t->u.equality.attr);
+ attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr);
if (attr == NULL) return NULL;
h = ldb_attrib_handler(module->ldb, attr);
wild_card_string[strlen(wild_card_string) - 1] = '\0';
}
- attr = ldb_casefold(mem_ctx, t->u.substring.attr);
+ attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.substring.attr);
if (attr == NULL) return NULL;
h = ldb_attrib_handler(module->ldb, attr);
value.data);
case LDB_OP_GREATER:
- attr = ldb_casefold(mem_ctx, t->u.equality.attr);
+ attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr);
if (attr == NULL) return NULL;
h = ldb_attrib_handler(module->ldb, attr);
return lsqlite3_tprintf(mem_ctx,
"SELECT eid FROM ldb_attribute_values "
"WHERE norm_attr_name = '%q' "
- "AND norm_attr_value LIKE '>=%q' ESCAPE '%q' ",
+ "AND ldap_compare(norm_attr_value, '>=', '%q', '%q') ",
attr,
value.data,
attr);
case LDB_OP_LESS:
- attr = ldb_casefold(mem_ctx, t->u.equality.attr);
+ attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr);
if (attr == NULL) return NULL;
h = ldb_attrib_handler(module->ldb, attr);
return lsqlite3_tprintf(mem_ctx,
"SELECT eid FROM ldb_attribute_values "
"WHERE norm_attr_name = '%q' "
- "AND norm_attr_value LIKE '<=%q' ESCAPE '%q' ",
+ "AND ldap_compare(norm_attr_value, '<=', '%q', '%q') ",
attr,
value.data,
attr);
return talloc_strdup(mem_ctx, "SELECT eid FROM ldb_entry");
}
- attr = ldb_casefold(mem_ctx, t->u.present.attr);
+ attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.present.attr);
if (attr == NULL) return NULL;
return lsqlite3_tprintf(mem_ctx,
attr);
case LDB_OP_APPROX:
- attr = ldb_casefold(mem_ctx, t->u.equality.attr);
+ attr = ldb_attr_casefold(module->ldb, mem_ctx, t->u.equality.attr);
if (attr == NULL) return NULL;
h = ldb_attrib_handler(module->ldb, attr);
return lsqlite3_tprintf(mem_ctx,
"SELECT eid FROM ldb_attribute_values "
"WHERE norm_attr_name = '%q' "
- "AND norm_attr_value LIKE '~%q' ESCAPE '%q' ",
+ "AND ldap_compare(norm_attr_value, '~%', 'q', '%q') ",
attr,
value.data,
attr);
return NULL;
}
-/* obtain a named lock */
-static int
-lsqlite3_lock(struct ldb_module * module,
- const char * lockname)
-{
- struct lsqlite3_private * lsqlite3 = module->private_data;
-
-/* FIXME
- if (lockname == NULL) {
- return -1;
- }
-
- if (strcmp(lockname, "transaction") == 0) {
- if (lsqlite3->lock_count == 0) {
- if (query_norows(lsqlite3, "BEGIN EXCLUSIVE;") != 0) {
- return -1;
- }
- }
- ++lsqlite3->lock_count;
- }
-*/
- return 0;
-}
-
-/* release a named lock */
-static int
-lsqlite3_unlock(struct ldb_module *module,
- const char *lockname)
-{
- struct lsqlite3_private * lsqlite3 = module->private_data;
-
-/* FIXME
- if (lockname == NULL) {
- return -1;
- }
-
- if (strcmp(lockname, "transaction") == 0) {
- if (lsqlite3->lock_count == 1) {
- if (query_norows(lsqlite3, "COMMIT;") != 0) {
- query_norows(lsqlite3, "ROLLBACK;");
- }
- } else if (lsqlite3->lock_count > 0) {
- --lsqlite3->lock_count;
- }
- } else if (strcmp(lockname, "rollback") == 0) {
- query_norows(lsqlite3, "ROLLBACK;");
- }
-*/
- return 0;
-}
-
/*
* query_int()
*
/*
* This is a bad hack to support ldap style comparisons whithin sqlite.
- * This function substitues the X LIKE Y ESCAPE Z expression
- * X is an expression + value to compare against (eg: ">=test")
- * Y is the attribute in the row currently under test
- * Z is the attribute name the value of which we want to test
+ * val is the attribute in the row currently under test
+ * func is the desired test "<=" ">=" "~" ":"
+ * cmp is the value to compare against (eg: "test")
+ * attr is the attribute name the value of which we want to test
*/
static void lsqlite3_compare(sqlite3_context *ctx, int argc,
sqlite3_value **argv)
{
struct ldb_context *ldb = (struct ldb_context *)sqlite3_user_data(ctx);
- const unsigned char *X = sqlite3_value_text(argv[0]);
- const unsigned char *Y = sqlite3_value_text(argv[1]);
- const unsigned char *Z = sqlite3_value_text(argv[2]);
- const unsigned char *p;
+ const unsigned char *val = sqlite3_value_text(argv[0]);
+ const unsigned char *func = sqlite3_value_text(argv[1]);
+ const unsigned char *cmp = sqlite3_value_text(argv[2]);
+ const unsigned char *attr = sqlite3_value_text(argv[3]);
const struct ldb_attrib_handler *h;
struct ldb_val valX;
struct ldb_val valY;
int ret;
- switch (X[0]) {
+ switch (func[0]) {
/* greater */
case '>': /* >= */
- p = &(X[2]);
- h = ldb_attrib_handler(ldb, Z);
- valX.data = p;
- valX.length = strlen(p);
- valY.data = Y;
- valY.length = strlen(Y);
+ h = ldb_attrib_handler(ldb, attr);
+ valX.data = cmp;
+ valX.length = strlen(cmp);
+ valY.data = val;
+ valY.length = strlen(val);
ret = h->comparison_fn(ldb, ldb, &valY, &valX);
if (ret >= 0)
sqlite3_result_int(ctx, 1);
/* lesser */
case '<': /* <= */
- p = &(X[2]);
- h = ldb_attrib_handler(ldb, Z);
- valX.data = p;
- valX.length = strlen(p);
- valY.data = Y;
- valY.length = strlen(Y);
+ h = ldb_attrib_handler(ldb, attr);
+ valX.data = cmp;
+ valX.length = strlen(cmp);
+ valY.data = val;
+ valY.length = strlen(val);
ret = h->comparison_fn(ldb, ldb, &valY, &valX);
if (ret <= 0)
sqlite3_result_int(ctx, 1);
ret = sqlite3_exec(sqlite, "ROLLBACK;", NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_safe_rollback: Serious Error: %s\n", errmsg);
+ printf("lsqlite3_safe_rollback: Error: %s\n", errmsg);
free(errmsg);
}
return -1;
if (!found) return 0;
}
- msg->elements = talloc_realloc(msg,
- msg->elements,
- struct ldb_message_element,
- msg->num_elements + 1);
- if (msg->elements == NULL) return SQLITE_ABORT;
-
- msg->elements[msg->num_elements].flags = 0;
- msg->elements[msg->num_elements].name = talloc_strdup(msg->elements, cols[2]);
- if (msg->elements[msg->num_elements].name == NULL) return SQLITE_ABORT;
-
- msg->elements[msg->num_elements].num_values = 1;
- msg->elements[msg->num_elements].values = talloc_array(msg->elements,
- struct ldb_val, 1);
- if (msg->elements[msg->num_elements].values == NULL) return SQLITE_ABORT;
-
- msg->elements[msg->num_elements].values[0].length = strlen(cols[3]);
- msg->elements[msg->num_elements].values[0].data = talloc_strdup(msg->elements, cols[3]);
- if (msg->elements[msg->num_elements].values[0].data == NULL) return SQLITE_ABORT;
-
- msg->num_elements++;
+ if (ldb_msg_add_string(msg, cols[2], cols[3]) != 0)
+ return SQLITE_ABORT;
return SQLITE_OK;
}
/* search for matching records, by tree */
static int lsqlite3_search_bytree(struct ldb_module * module, const struct ldb_dn* basedn,
enum ldb_scope scope, struct ldb_parse_tree * tree,
- const char * const * attrs, struct ldb_message *** res)
+ const char * const * attrs, struct ldb_result ** res)
{
TALLOC_CTX *local_ctx;
struct lsqlite3_private *lsqlite3 = module->private_data;
char *norm_basedn;
char *sqlfilter;
char *errmsg;
- char *query;
+ char *query = NULL;
int ret, i;
/* create a local ctx */
- local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_search_by_tree local context");
+ local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_search_bytree local context");
if (local_ctx == NULL) {
return -1;
}
if (basedn) {
norm_basedn = ldb_dn_linearize(local_ctx, ldb_dn_casefold(module->ldb, basedn));
- if (norm_basedn == NULL) goto failed;
+ if (norm_basedn == NULL) {
+ ret = LDB_ERR_INVALID_DN_SYNTAX;
+ goto failed;
+ }
} else norm_basedn = talloc_strdup(local_ctx, "");
if (*norm_basedn == '\0' &&
- (scope == LDB_SCOPE_BASE || scope == LDB_SCOPE_ONELEVEL))
+ (scope == LDB_SCOPE_BASE || scope == LDB_SCOPE_ONELEVEL)) {
+ ret = LDB_ERR_UNWILLING_TO_PERFORM;
goto failed;
+ }
/* Convert filter into a series of SQL conditions (constraints) */
sqlfilter = parsetree_to_sql(module, local_ctx, tree);
}
if (query == NULL) {
- ret = -1;
+ ret = LDB_ERR_OTHER;
goto failed;
}
ret = sqlite3_exec(lsqlite3->sqlite, query, lsqlite3_search_callback, &msgs, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_search_bytree: Fatal Error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
+ ret = LDB_ERR_OTHER;
goto failed;
}
for (i = 0; i < msgs.count; i++) {
msgs.msgs[i] = ldb_msg_canonicalize(module->ldb, msgs.msgs[i]);
- if (msgs.msgs[i] == NULL) goto failed;
+ if (msgs.msgs[i] == NULL) {
+ goto failed;
+ }
}
- *res = talloc_steal(module, msgs.msgs);
- ret = msgs.count;
+ *res = talloc(module, struct ldb_result);
+ if (! *res) {
+ goto failed;
+ }
+
+ (*res)->msgs = talloc_steal(*res, msgs.msgs);
+ (*res)->count = msgs.count;
+ (*res)->refs = NULL;
+ (*res)->controls = NULL;
talloc_free(local_ctx);
- return ret;
+ return LDB_SUCCESS;
/* If error, return error code; otherwise return number of results */
failed:
talloc_free(local_ctx);
- return -1;
-}
-
-/* search for matching records, by expression */
-static int lsqlite3_search(struct ldb_module * module, const struct ldb_dn *basedn,
- enum ldb_scope scope, const char * expression,
- const char * const *attrs, struct ldb_message *** res)
-{
- struct ldb_parse_tree * tree;
- int ret;
-
- /* Handle tdb specials */
- if (ldb_dn_is_special(basedn)) {
-#warning "handle tdb specials"
- return 0;
- }
-
-#if 0
-/* (|(objectclass=*)(dn=*)) is passed by the command line tool now instead */
- /* Handle the special case of requesting all */
- if (pExpression != NULL && *pExpression == '\0') {
- pExpression = "dn=*";
- }
-#endif
-
- /* Parse the filter expression into a tree we can work with */
- if ((tree = ldb_parse_tree(module->ldb, expression)) == NULL) {
- return -1;
- }
-
- /* Now use the bytree function for the remainder of processing */
- ret = lsqlite3_search_bytree(module, basedn, scope, tree, attrs, res);
-
- /* Free the parse tree */
- talloc_free(tree);
-
- /* All done. */
- return ret;
+ return LDB_ERR_OTHER;
}
char *dn, *ndn;
char *errmsg;
char *query;
- int rollback = 0;
int ret;
int i;
/* create a local ctx */
local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_add local context");
if (local_ctx == NULL) {
- return -1;
+ return LDB_ERR_OTHER;
}
/* See if this is an ltdb special */
c = ldb_dn_explode(local_ctx, "@SUBCLASSES");
if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
#warning "insert subclasses into object class tree"
+ ret = LDB_ERR_UNWILLING_TO_PERFORM;
goto failed;
}
}
*/
/* Others are implicitly ignored */
- return 0;
+ return LDB_SUCCESS;
}
/* create linearized and normalized dns */
dn = ldb_dn_linearize(local_ctx, msg->dn);
ndn = ldb_dn_linearize(local_ctx, ldb_dn_casefold(module->ldb, msg->dn));
- if (dn == NULL || ndn == NULL) goto failed;
+ if (dn == NULL || ndn == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
query = lsqlite3_tprintf(local_ctx,
- /* Begin the transaction */
- "BEGIN EXCLUSIVE; "
/* Add new entry */
"INSERT OR ABORT INTO ldb_entry "
"('dn', 'norm_dn') "
"VALUES ('%q', '%q');",
dn, ndn);
- if (query == NULL) goto failed;
+ if (query == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_add: exec error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
- lsqlite3_safe_rollback(lsqlite3->sqlite);
+ ret = LDB_ERR_OTHER;
goto failed;
}
- rollback = 1;
eid = lsqlite3_get_eid_ndn(lsqlite3->sqlite, local_ctx, ndn);
- if (eid == -1) goto failed;
+ if (eid == -1) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
for (i = 0; i < msg->num_elements; i++) {
const struct ldb_message_element *el = &msg->elements[i];
int j;
/* Get a case-folded copy of the attribute name */
- attr = ldb_casefold(local_ctx, el->name);
- if (attr == NULL) goto failed;
+ attr = ldb_attr_casefold(module->ldb, local_ctx, el->name);
+ if (attr == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
h = ldb_attrib_handler(module->ldb, el->name);
/* Get a canonicalised copy of the data */
h->canonicalise_fn(module->ldb, local_ctx, &(el->values[j]), &value);
- if (value.data == NULL) goto failed;
+ if (value.data == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
insert = lsqlite3_tprintf(local_ctx,
"INSERT OR ROLLBACK INTO ldb_attribute_values "
"VALUES ('%lld', '%q', '%q', '%q', '%q');",
eid, el->name, attr,
el->values[j].data, value.data);
- if (insert == NULL) goto failed;
+ if (insert == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
ret = sqlite3_exec(lsqlite3->sqlite, insert, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_add: insert error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
+ ret = LDB_ERR_OTHER;
goto failed;
}
}
}
- ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg);
- if (ret != SQLITE_OK) {
- if (errmsg) {
- printf("lsqlite3_add: commit error: %s\n", errmsg);
- free(errmsg);
- }
- goto failed;
- }
-
talloc_free(local_ctx);
- return 0;
+ return LDB_SUCCESS;
failed:
- if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite);
talloc_free(local_ctx);
- return -1;
+ return ret;
}
struct lsqlite3_private *lsqlite3 = module->private_data;
long long eid;
char *errmsg;
- int rollback = 0;
int ret;
int i;
/* create a local ctx */
local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_modify local context");
if (local_ctx == NULL) {
- return -1;
+ return LDB_ERR_OTHER;
}
/* See if this is an ltdb special */
c = ldb_dn_explode(local_ctx, "@SUBCLASSES");
if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
#warning "modify subclasses into object class tree"
- goto failed;
- }
-
- c = ldb_dn_explode(local_ctx, "@INDEXLIST");
- if (ldb_dn_compare(module->ldb, msg->dn, c) == 0) {
-#warning "should we handle indexes somehow ?"
+ ret = LDB_ERR_UNWILLING_TO_PERFORM;
goto failed;
}
/* Others are implicitly ignored */
- return 0;
- }
-
- ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN EXCLUSIVE;", NULL, NULL, &errmsg);
- if (ret != SQLITE_OK) {
- if (errmsg) {
- printf("lsqlite3_modify: error: %s\n", errmsg);
- free(errmsg);
- }
- goto failed;
+ return LDB_SUCCESS;
}
- rollback = 1;
eid = lsqlite3_get_eid(module, msg->dn);
if (eid == -1) {
+ ret = LDB_ERR_OTHER;
goto failed;
}
int j;
/* Get a case-folded copy of the attribute name */
- attr = ldb_casefold(local_ctx, el->name);
+ attr = ldb_attr_casefold(module->ldb, local_ctx, el->name);
if (attr == NULL) {
+ ret = LDB_ERR_OTHER;
goto failed;
}
"WHERE eid = '%lld' "
"AND norm_attr_name = '%q';",
eid, attr);
- if (mod == NULL) goto failed;
+ if (mod == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_modify: error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
+ ret = LDB_ERR_OTHER;
goto failed;
}
/* Get a canonicalised copy of the data */
h->canonicalise_fn(module->ldb, local_ctx, &(el->values[j]), &value);
if (value.data == NULL) {
+ ret = LDB_ERR_OTHER;
goto failed;
}
eid, el->name, attr,
el->values[j].data, value.data);
- if (mod == NULL) goto failed;
+ if (mod == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_modify: error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
+ ret = LDB_ERR_OTHER;
goto failed;
}
}
"WHERE eid = '%lld' "
"AND norm_attr_name = '%q';",
eid, attr);
- if (mod == NULL) goto failed;
+ if (mod == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_modify: error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
+ ret = LDB_ERR_OTHER;
goto failed;
}
}
/* Get a canonicalised copy of the data */
h->canonicalise_fn(module->ldb, local_ctx, &(el->values[j]), &value);
if (value.data == NULL) {
+ ret = LDB_ERR_OTHER;
goto failed;
}
"AND norm_attr_value = '%q';",
eid, attr, value.data);
- if (mod == NULL) goto failed;
+ if (mod == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
ret = sqlite3_exec(lsqlite3->sqlite, mod, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_modify: error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
+ ret = LDB_ERR_OTHER;
goto failed;
}
}
}
}
- ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg);
- if (ret != SQLITE_OK) {
- if (errmsg) {
- printf("lsqlite3_modify: error: %s\n", errmsg);
- free(errmsg);
- }
- goto failed;
- }
-
talloc_free(local_ctx);
- return 0;
+ return LDB_SUCCESS;
failed:
- if (rollback) lsqlite3_safe_rollback(lsqlite3->sqlite);
talloc_free(local_ctx);
- return -1;
+ return ret;
}
/* delete a record */
/* ignore ltdb specials */
if (ldb_dn_is_special(dn)) {
- return 0;
+ return LDB_SUCCESS;
}
/* create a local ctx */
local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_delete local context");
if (local_ctx == NULL) {
- return -1;
+ return LDB_ERR_OTHER;
}
eid = lsqlite3_get_eid(module, dn);
- if (eid == -1) goto failed;
+ if (eid == -1) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
query = lsqlite3_tprintf(local_ctx,
- /* Begin the transaction */
- "BEGIN EXCLUSIVE; "
/* Delete entry */
"DELETE FROM ldb_entry WHERE eid = %lld; "
/* Delete attributes */
- "DELETE FROM ldb_attribute_values WHERE eid = %lld; "
- /* Commit */
- "COMMIT;",
+ "DELETE FROM ldb_attribute_values WHERE eid = %lld; ",
eid, eid);
- if (query == NULL) goto failed;
+ if (query == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_delete: error getting eid: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
- lsqlite3_safe_rollback(lsqlite3->sqlite);
+ ret = LDB_ERR_OTHER;
goto failed;
}
talloc_free(local_ctx);
- return 0;
+ return LDB_SUCCESS;
failed:
talloc_free(local_ctx);
- return -1;
+ return ret;
}
/* rename a record */
/* ignore ltdb specials */
if (ldb_dn_is_special(olddn) || ldb_dn_is_special(newdn)) {
- return 0;
+ return LDB_SUCCESS;
}
/* create a local ctx */
local_ctx = talloc_named(lsqlite3, 0, "lsqlite3_rename local context");
if (local_ctx == NULL) {
- return -1;
+ return LDB_ERR_OTHER;
}
/* create linearized and normalized dns */
old_cdn = ldb_dn_linearize(local_ctx, ldb_dn_casefold(module->ldb, olddn));
new_cdn = ldb_dn_linearize(local_ctx, ldb_dn_casefold(module->ldb, newdn));
new_dn = ldb_dn_linearize(local_ctx, newdn);
- if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) goto failed;
+ if (old_cdn == NULL || new_cdn == NULL || new_dn == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
/* build the SQL query */
query = lsqlite3_tprintf(local_ctx,
"UPDATE ldb_entry SET dn = '%q', norm_dn = '%q' "
"WHERE norm_dn = '%q';",
new_dn, new_cdn, old_cdn);
- if (query == NULL) goto failed;
+ if (query == NULL) {
+ ret = LDB_ERR_OTHER;
+ goto failed;
+ }
/* execute */
ret = sqlite3_exec(lsqlite3->sqlite, query, NULL, NULL, &errmsg);
if (ret != SQLITE_OK) {
if (errmsg) {
- printf("lsqlite3_rename: sqlite3_exec error: %s\n", errmsg);
+ ldb_set_errstring(module, talloc_strdup(module, errmsg));
free(errmsg);
}
+ ret = LDB_ERR_OTHER;
goto failed;
}
/* clean up and exit */
talloc_free(local_ctx);
- return 0;
+ return LDB_SUCCESS;
failed:
talloc_free(local_ctx);
- return -1;
+ return ret;
}
-/* return extended error information */
-static const char *
-lsqlite3_errstring(struct ldb_module *module)
+
+static int lsqlite3_start_trans(struct ldb_module * module)
{
+ int ret;
+ char *errmsg;
struct lsqlite3_private * lsqlite3 = module->private_data;
-
- return sqlite3_errmsg(lsqlite3->sqlite);
+
+ if (lsqlite3->trans_count == 0) {
+ ret = sqlite3_exec(lsqlite3->sqlite, "BEGIN IMMEDIATE;", NULL, NULL, &errmsg);
+ if (ret != SQLITE_OK) {
+ if (errmsg) {
+ printf("lsqlite3_start_trans: error: %s\n", errmsg);
+ free(errmsg);
+ }
+ return -1;
+ }
+ };
+
+ lsqlite3->trans_count++;
+
+ return 0;
+}
+
+static int lsqlite3_end_trans(struct ldb_module *module)
+{
+ int ret;
+ char *errmsg;
+ struct lsqlite3_private *lsqlite3 = module->private_data;
+
+ if (lsqlite3->trans_count > 0) {
+ lsqlite3->trans_count--;
+ } else return -1;
+
+ if (lsqlite3->trans_count == 0) {
+ ret = sqlite3_exec(lsqlite3->sqlite, "COMMIT;", NULL, NULL, &errmsg);
+ if (ret != SQLITE_OK) {
+ if (errmsg) {
+ printf("lsqlite3_end_trans: error: %s\n", errmsg);
+ free(errmsg);
+ }
+ return -1;
+ }
+ }
+
+ return 0;
}
+static int lsqlite3_del_trans(struct ldb_module *module)
+{
+ struct lsqlite3_private *lsqlite3 = module->private_data;
+
+ if (lsqlite3->trans_count > 0) {
+ lsqlite3->trans_count--;
+ } else return -1;
+ if (lsqlite3->trans_count == 0) {
+ return lsqlite3_safe_rollback(lsqlite3->sqlite);
+ }
+ return -1;
+}
/*
* Static functions
*/
static int initialize(struct lsqlite3_private *lsqlite3,
- struct ldb_context *ldb, const char *url)
+ struct ldb_context *ldb, const char *url, int flags)
{
TALLOC_CTX *local_ctx;
long long queryInt;
goto failed;
}
- /* DANGEROUS */
- ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg);
- if (ret != SQLITE_OK) {
- if (errmsg) {
- printf("lsqlite3 initializaion error: %s\n", errmsg);
- free(errmsg);
+ if (flags & LDB_FLG_NOSYNC) {
+ /* DANGEROUS */
+ ret = sqlite3_exec(lsqlite3->sqlite, "PRAGMA synchronous = OFF;", NULL, NULL, &errmsg);
+ if (ret != SQLITE_OK) {
+ if (errmsg) {
+ printf("lsqlite3 initializaion error: %s\n", errmsg);
+ free(errmsg);
+ }
+ goto failed;
}
- goto failed;
}
/* */
/* Create a function, callable from sql, to perform various comparisons */
if ((ret =
sqlite3_create_function(lsqlite3->sqlite, /* handle */
- "like", /* function name */
- 3, /* number of args */
+ "ldap_compare", /* function name */
+ 4, /* number of args */
SQLITE_ANY, /* preferred text type */
ldb , /* user data */
lsqlite3_compare, /* called func */
}
+static int lsqlite3_request(struct ldb_module *module, struct ldb_request *req)
+{
+ /* check for oustanding critical controls and return an error if found */
+ if (check_critical_controls(req->controls)) {
+ return LDB_ERR_UNSUPPORTED_CRITICAL_EXTENSION;
+ }
+
+ switch (req->operation) {
+
+ case LDB_REQ_SEARCH:
+ return lsqlite3_search_bytree(module,
+ req->op.search.base,
+ req->op.search.scope,
+ req->op.search.tree,
+ req->op.search.attrs,
+ &req->op.search.res);
+
+ case LDB_REQ_ADD:
+ return lsqlite3_add(module, req->op.add.message);
+
+ case LDB_REQ_MODIFY:
+ return lsqlite3_modify(module, req->op.mod.message);
+
+ case LDB_REQ_DELETE:
+ return lsqlite3_delete(module, req->op.del.dn);
+
+ case LDB_REQ_RENAME:
+ return lsqlite3_rename(module,
+ req->op.rename.olddn,
+ req->op.rename.newdn);
+
+ default:
+ return LDB_ERR_OPERATIONS_ERROR;
+
+ }
+}
+
+static int lsqlite3_init_2(struct ldb_module *module)
+{
+ return LDB_SUCCESS;
+}
/*
* Table of operations for the sqlite3 backend
*/
static const struct ldb_module_ops lsqlite3_ops = {
- .name = "sqlite",
- .search = lsqlite3_search,
- .search_bytree = lsqlite3_search_bytree,
- .add_record = lsqlite3_add,
- .modify_record = lsqlite3_modify,
- .delete_record = lsqlite3_delete,
- .rename_record = lsqlite3_rename,
- .named_lock = lsqlite3_lock,
- .named_unlock = lsqlite3_unlock,
- .errstring = lsqlite3_errstring
+ .name = "sqlite",
+ .request = lsqlite3_request,
+ .start_transaction = lsqlite3_start_trans,
+ .end_transaction = lsqlite3_end_trans,
+ .del_transaction = lsqlite3_del_trans,
+ .second_stage_init = lsqlite3_init_2
};
/*
lsqlite3->sqlite = NULL;
lsqlite3->options = NULL;
+ lsqlite3->trans_count = 0;
- ret = initialize(lsqlite3, ldb, url);
+ ret = initialize(lsqlite3, ldb, url, flags);
if (ret != SQLITE_OK) {
goto failed;
}