return ldb_next_start_trans(module);
}
-static int objectguid_end_trans(struct ldb_module *module, int status)
+static int objectguid_end_trans(struct ldb_module *module)
{
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "objectguid_end_trans\n");
- return ldb_next_end_trans(module, status);
+ return ldb_next_end_trans(module);
+}
+
+static int objectguid_del_trans(struct ldb_module *module)
+{
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "objectguid_del_trans\n");
+ return ldb_next_del_trans(module);
}
static int objectguid_destructor(void *module_ctx)
.delete_record = objectguid_delete_record,
.rename_record = objectguid_rename_record,
.start_transaction = objectguid_start_trans,
- .end_transaction = objectguid_end_trans
+ .end_transaction = objectguid_end_trans,
+ .del_transaction = objectguid_del_trans
};
return ldb_next_start_trans(module);
}
-static int samldb_end_trans(struct ldb_module *module, int status)
+static int samldb_end_trans(struct ldb_module *module)
{
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_end_trans\n");
- return ldb_next_end_trans(module, status);
+ return ldb_next_end_trans(module);
+}
+
+static int samldb_del_trans(struct ldb_module *module)
+{
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "samldb_del_trans\n");
+ return ldb_next_del_trans(module);
}
static int samldb_destructor(void *module_ctx)
.delete_record = samldb_delete_record,
.rename_record = samldb_rename_record,
.start_transaction = samldb_start_trans,
- .end_transaction = samldb_end_trans
+ .end_transaction = samldb_end_trans,
+ .del_transaction = samldb_del_trans
};
return LDB_ERR_OTHER;
}
- if (ret != LDB_ERR_SUCCESS) {
+ if (ret != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
return ret;
}
- if (ldb_load_modules(ldb, options) != LDB_ERR_SUCCESS) {
+ if (ldb_load_modules(ldb, options) != LDB_SUCCESS) {
ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for '%s'\n", url);
return LDB_ERR_OTHER;
}
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
static void ldb_reset_err_string(struct ldb_context *ldb)
/*
start a transaction
*/
-static int ldb_start_trans(struct ldb_context *ldb)
+int ldb_transaction_start(struct ldb_context *ldb)
{
- return ldb->modules->ops->start_transaction(ldb->modules);
+ ldb->transaction_active++;
+
+ ldb_reset_err_string(ldb);
+
+ return ldb->modules->ops->start_transaction(ldb->modules);
}
/*
- end a transaction
+ commit a transaction
*/
-static int ldb_end_trans(struct ldb_context *ldb, int status)
+int ldb_transaction_commit(struct ldb_context *ldb)
{
- return ldb->modules->ops->end_transaction(ldb->modules, status);
+ if (ldb->transaction_active > 0) {
+ ldb->transaction_active--;
+ } else {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ldb_reset_err_string(ldb);
+
+ return ldb->modules->ops->end_transaction(ldb->modules);
+}
+
+/*
+ cancel a transaction
+*/
+int ldb_transaction_cancel(struct ldb_context *ldb)
+{
+ if (ldb->transaction_active > 0) {
+ ldb->transaction_active--;
+ } else {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ldb_reset_err_string(ldb);
+
+ return ldb->modules->ops->del_transaction(ldb->modules);
}
/*
ldb_reset_err_string(ldb);
status = ldb_msg_sanity_check(message);
- if (status != LDB_ERR_SUCCESS) return status;
+ if (status != LDB_SUCCESS) return status;
- status = ldb_start_trans(ldb);
- if (status != LDB_ERR_SUCCESS) return status;
+ if (! ldb->transaction_active) {
+ status = ldb_transaction_start(ldb);
+ if (status != LDB_SUCCESS) return status;
- status = ldb->modules->ops->add_record(ldb->modules, message);
- return ldb_end_trans(ldb, status);
+ status = ldb->modules->ops->add_record(ldb->modules, message);
+ if (status != LDB_SUCCESS) return ldb_transaction_cancel(ldb);
+ return ldb_transaction_commit(ldb);
+ }
+
+ return ldb->modules->ops->add_record(ldb->modules, message);
}
/*
ldb_reset_err_string(ldb);
status = ldb_msg_sanity_check(message);
- if (status != LDB_ERR_SUCCESS) return status;
+ if (status != LDB_SUCCESS) return status;
+
+ if (! ldb->transaction_active) {
+ status = ldb_transaction_start(ldb);
+ if (status != LDB_SUCCESS) return status;
- status = ldb_start_trans(ldb);
- if (status != LDB_ERR_SUCCESS) return status;
+ status = ldb->modules->ops->modify_record(ldb->modules, message);
+ if (status != LDB_SUCCESS) return ldb_transaction_cancel(ldb);
+ return ldb_transaction_commit(ldb);
+ }
- status = ldb->modules->ops->modify_record(ldb->modules, message);
- return ldb_end_trans(ldb, status);
+ return ldb->modules->ops->modify_record(ldb->modules, message);
}
ldb_reset_err_string(ldb);
- status = ldb_start_trans(ldb);
- if (status != LDB_ERR_SUCCESS) return status;
+ if (! ldb->transaction_active) {
+ status = ldb_transaction_start(ldb);
+ if (status != LDB_SUCCESS) return status;
- status = ldb->modules->ops->delete_record(ldb->modules, dn);
- return ldb_end_trans(ldb, status);
+ status = ldb->modules->ops->delete_record(ldb->modules, dn);
+ if (status != LDB_SUCCESS) return ldb_transaction_cancel(ldb);
+ return ldb_transaction_commit(ldb);
+ }
+
+ return ldb->modules->ops->delete_record(ldb->modules, dn);
}
/*
ldb_reset_err_string(ldb);
- status = ldb_start_trans(ldb);
- if (status != LDB_ERR_SUCCESS) return status;
+ if (! ldb->transaction_active) {
+ status = ldb_transaction_start(ldb);
+ if (status != LDB_SUCCESS) return status;
+
+ status = ldb->modules->ops->rename_record(ldb->modules, olddn, newdn);
+ if (status != LDB_SUCCESS) return ldb_transaction_cancel(ldb);
+ return ldb_transaction_commit(ldb);
+ }
- status = ldb->modules->ops->rename_record(ldb->modules, olddn, newdn);
- return ldb_end_trans(ldb, status);
+ return ldb->modules->ops->rename_record(ldb->modules, olddn, newdn);
}
+
+
/*
return extended error information
*/
o->name = name;
o->value = value;
ldb->opaque = o;
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
/*
return module->next->ops->start_transaction(module->next);
}
-int ldb_next_end_trans(struct ldb_module *module, int status)
+int ldb_next_end_trans(struct ldb_module *module)
{
if (!module->next) {
return -1;
}
- return module->next->ops->end_transaction(module->next, status);
+ return module->next->ops->end_transaction(module->next);
+}
+
+int ldb_next_del_trans(struct ldb_module *module)
+{
+ if (!module->next) {
+ return -1;
+ }
+ return module->next->ops->del_transaction(module->next);
}
void ldb_set_errstring(struct ldb_module *module, char *err_string)
}
}
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
*/
int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn);
+/*
+ start a transaction
+*/
+int ldb_transaction_start(struct ldb_context *ldb);
+
+/*
+ commit a transaction
+*/
+int ldb_transaction_commit(struct ldb_context *ldb);
+
+/*
+ cancel a transaction
+*/
+int ldb_transaction_cancel(struct ldb_context *ldb);
+
/*
return extended error information from the last call
* but they are keept here for reference anyway
*/
-#define LDB_ERR_SUCCESS 0
+#define LDB_SUCCESS 0
#define LDB_ERR_OPERATIONS_ERROR 1
#define LDB_ERR_PROTOCOL_ERROR 2
#define LDB_ERR_TIME_LIMIT_EXCEEDED 3
int (*delete_record)(struct ldb_module *, const struct ldb_dn *);
int (*rename_record)(struct ldb_module *, const struct ldb_dn *, const struct ldb_dn *);
int (*start_transaction)(struct ldb_module *);
- int (*end_transaction)(struct ldb_module *, int);
+ int (*end_transaction)(struct ldb_module *);
+ int (*del_transaction)(struct ldb_module *);
};
struct ldb_schema schema;
char *err_string;
+
+ int transaction_active;
};
/* the modules init function */
int ldb_next_delete_record(struct ldb_module *module, const struct ldb_dn *dn);
int ldb_next_rename_record(struct ldb_module *module, const struct ldb_dn *olddn, const struct ldb_dn *newdn);
int ldb_next_start_trans(struct ldb_module *module);
-int ldb_next_end_trans(struct ldb_module *module, int status);
+int ldb_next_end_trans(struct ldb_module *module);
+int ldb_next_del_trans(struct ldb_module *module);
void ldb_set_errstring(struct ldb_module *module, char *err_string);
return 0;
}
-static int ildb_end_trans(struct ldb_module *module, int status)
+static int ildb_end_trans(struct ldb_module *module)
{
/* TODO implement a local transaction mechanism here */
- return status;
+ return 0;
+}
+
+static int ildb_del_trans(struct ldb_module *module)
+{
+ /* TODO implement a local locking mechanism here */
+
+ return 0;
}
static const struct ldb_module_ops ildb_ops = {
.delete_record = ildb_delete,
.rename_record = ildb_rename,
.start_transaction = ildb_start_trans,
- .end_transaction = ildb_end_trans
+ .end_transaction = ildb_end_trans,
+ .del_transaction = ildb_del_trans
};
return 0;
}
-static int lldb_end_trans(struct ldb_module *module, int status)
+static int lldb_end_trans(struct ldb_module *module)
{
/* TODO implement a local transaction mechanism here */
- return status;
+ return 0;
+}
+
+static int lldb_del_trans(struct ldb_module *module)
+{
+ /* TODO implement a local transaction mechanism here */
+
+ return 0;
}
static const struct ldb_module_ops lldb_ops = {
.delete_record = lldb_delete,
.rename_record = lldb_rename,
.start_transaction = lldb_start_trans,
- .end_transaction = lldb_end_trans
+ .end_transaction = lldb_end_trans,
+ .del_transaction = lldb_del_trans
};
}
*/
/* Others are implicitly ignored */
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
/* create linearized and normalized dns */
}
talloc_free(local_ctx);
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
failed:
talloc_free(local_ctx);
}
/* Others are implicitly ignored */
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
eid = lsqlite3_get_eid(module, msg->dn);
}
talloc_free(local_ctx);
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
failed:
talloc_free(local_ctx);
/* ignore ltdb specials */
if (ldb_dn_is_special(dn)) {
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
/* create a local ctx */
}
talloc_free(local_ctx);
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
failed:
talloc_free(local_ctx);
/* ignore ltdb specials */
if (ldb_dn_is_special(olddn) || ldb_dn_is_special(newdn)) {
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
/* create a local ctx */
/* clean up and exit */
talloc_free(local_ctx);
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
failed:
talloc_free(local_ctx);
return 0;
}
-static int lsqlite3_end_trans(struct ldb_module *module, int status)
+static int lsqlite3_end_trans(struct ldb_module *module)
{
int ret;
char *errmsg;
struct lsqlite3_private *lsqlite3 = module->private_data;
- lsqlite3->trans_count--;
+ if (lsqlite3->trans_count > 0) {
+ lsqlite3->trans_count--;
+ } else return -1;
if (lsqlite3->trans_count == 0) {
- if (status == 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;
+ 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);
}
- } else {
- return lsqlite3_safe_rollback(lsqlite3->sqlite);
+ 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
*/
.delete_record = lsqlite3_delete,
.rename_record = lsqlite3_rename,
.start_transaction = lsqlite3_start_trans,
- .end_transaction = lsqlite3_end_trans
+ .end_transaction = lsqlite3_end_trans,
+ .del_transaction = lsqlite3_del_trans
};
/*
int ret;
ret = ltdb_check_special_dn(module, msg);
- if (ret != LDB_ERR_SUCCESS) {
+ if (ret != LDB_SUCCESS) {
return ret;
}
ret = ltdb_store(module, msg, TDB_INSERT);
- if (ret == LDB_ERR_SUCCESS) {
+ if (ret == LDB_SUCCESS) {
ltdb_modified(module, msg->dn);
}
}
ret = ltdb_delete_noindex(module, dn);
- if (ret != LDB_ERR_SUCCESS) {
+ if (ret != LDB_SUCCESS) {
goto failed;
}
/* remove any indexed attributes */
ret = ltdb_index_del(module, msg);
- if (ret == LDB_ERR_SUCCESS) {
+ if (ret == LDB_SUCCESS) {
ltdb_modified(module, dn);
} else
ret = LDB_ERR_OTHER;
ret = ltdb_modify_internal(module, msg);
- if (ret == LDB_ERR_SUCCESS) {
+ if (ret == LDB_SUCCESS) {
ltdb_modified(module, msg->dn);
}
}
ret = ltdb_add(module, msg);
- if (ret != LDB_ERR_SUCCESS) {
+ if (ret != LDB_SUCCESS) {
goto failed;
}
ret = ltdb_delete(module, olddn);
error_str = talloc_strdup(module, ldb_errstring(module->ldb));
- if (ret != LDB_ERR_SUCCESS) {
+ if (ret != LDB_SUCCESS) {
ltdb_delete(module, newdn);
}
return LDB_ERR_OPERATIONS_ERROR;
}
- return LDB_ERR_SUCCESS;
+ return LDB_SUCCESS;
}
-static int ltdb_end_trans(struct ldb_module *module, int status)
+static int ltdb_end_trans(struct ldb_module *module)
{
struct ltdb_private *ltdb = module->private_data;
- if (status != LDB_ERR_SUCCESS) {
- if (tdb_transaction_cancel(ltdb->tdb) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
- } else {
- if (tdb_transaction_commit(ltdb->tdb) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
+ if (tdb_transaction_commit(ltdb->tdb) != 0) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int ltdb_del_trans(struct ldb_module *module)
+{
+ struct ltdb_private *ltdb = module->private_data;
+
+ if (tdb_transaction_cancel(ltdb->tdb) != 0) {
+ return LDB_ERR_OPERATIONS_ERROR;
}
- return status;
+ return LDB_SUCCESS;
}
static const struct ldb_module_ops ltdb_ops = {
.delete_record = ltdb_delete,
.rename_record = ltdb_rename,
.start_transaction = ltdb_start_trans,
- .end_transaction = ltdb_end_trans
+ .end_transaction = ltdb_end_trans,
+ .del_transaction = ltdb_del_trans
};
return ldb_next_start_trans(module);
}
-static int map_end_trans(struct ldb_module *module, int status)
+static int map_end_trans(struct ldb_module *module)
{
- return ldb_next_end_trans(module, status);
+ return ldb_next_end_trans(module);
+}
+
+static int map_del_trans(struct ldb_module *module)
+{
+ return ldb_next_del_trans(module);
}
static const struct ldb_module_ops map_ops = {
.delete_record = map_delete,
.rename_record = map_rename,
.start_transaction = map_start_trans,
- .end_transaction = map_end_trans
+ .end_transaction = map_end_trans,
+ .del_transaction = map_del_trans
};
static char *map_find_url(struct ldb_context *ldb, const char *name)
return ldb_next_start_trans(module);
}
-static int rdn_end_trans(struct ldb_module *module, int status)
+static int rdn_end_trans(struct ldb_module *module)
{
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_end_trans\n");
- return ldb_next_end_trans(module, status);
+ return ldb_next_end_trans(module);
+}
+
+static int rdn_del_trans(struct ldb_module *module)
+{
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_del_trans\n");
+ return ldb_next_del_trans(module);
}
static int rdn_name_destructor(void *module_ctx)
.delete_record = rdn_name_delete_record,
.rename_record = rdn_name_rename_record,
.start_transaction = rdn_start_trans,
- .end_transaction = rdn_end_trans
+ .end_transaction = rdn_end_trans,
+ .del_transaction = rdn_del_trans
};
return ldb_next_start_trans(module);
}
-static int schema_end_trans(struct ldb_module *module, int status) {
- return ldb_next_end_trans(module, status);
+static int schema_end_trans(struct ldb_module *module) {
+ return ldb_next_end_trans(module);
+}
+
+static int schema_del_trans(struct ldb_module *module) {
+ return ldb_next_del_trans(module);
}
static int schema_destructor(void *module_ctx)
.delete_record = schema_delete_record,
.rename_record = schema_rename_record,
.start_transaction = schema_start_trans,
- .end_transaction = schema_end_trans
+ .end_transaction = schema_end_trans,
+ .del_transaction = schema_del_trans
};
#ifdef HAVE_DLOPEN_DISABLED
}
/* end a transaction */
-static int skel_end_trans(struct ldb_module *module, int status)
+static int skel_end_trans(struct ldb_module *module)
{
- return ldb_next_end_trans(module, status);
+ return ldb_next_end_trans(module);
+}
+
+/* delete a transaction */
+static int skel_del_trans(struct ldb_module *module)
+{
+ return ldb_next_del_trans(module);
}
static int skel_destructor(void *module_ctx)
.rename_record = skel_rename_record,
.start_transaction = skel_start_trans,
.end_transaction = skel_end_trans,
+ .del_transaction = skel_del_trans,
};
#ifdef HAVE_DLOPEN_DISABLED
return ldb_next_start_trans(module);
}
-static int timestamps_end_trans(struct ldb_module *module, int status)
+static int timestamps_end_trans(struct ldb_module *module)
{
ldb_debug(module->ldb, LDB_DEBUG_TRACE, "timestamps_end_trans\n");
- return ldb_next_end_trans(module, status);
+ return ldb_next_end_trans(module);
+}
+
+static int timestamps_del_trans(struct ldb_module *module)
+{
+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "timestamps_del_trans\n");
+ return ldb_next_del_trans(module);
}
static int timestamps_destructor(void *module_ctx)
.delete_record = timestamps_delete_record,
.rename_record = timestamps_rename_record,
.start_transaction = timestamps_start_trans,
- .end_transaction = timestamps_end_trans
+ .end_transaction = timestamps_end_trans,
+ .del_transaction = timestamps_del_trans
};
ldif->msg = ldb_msg_canonicalize(ldb, ldif->msg);
ret = ldb_add(ldb, ldif->msg);
- if (ret != LDB_ERR_SUCCESS) {
+ if (ret != LDB_SUCCESS) {
fprintf(stderr, "ERR: \"%s\" on DN %s\n",
ldb_errstring(ldb), ldb_dn_linearize(ldb, ldif->msg->dn));
failures++;
#include "nbt_server/nbt_server.h"
#include "nbt_server/wins/winsdb.h"
#include "lib/ldb/include/ldb.h"
+#include "lib/ldb/include/ldb_errors.h"
#include "db_wrap.h"
#include "system/time.h"
/*
remove a version id
*/
-static void winsdb_remove_version(struct wins_server *winssrv, uint64_t version)
+static BOOL winsdb_remove_version(struct wins_server *winssrv, uint64_t version)
{
if (version == winssrv->min_version) {
winssrv->min_version++;
- winsdb_save_version(winssrv);
+ return winsdb_save_version(winssrv);
}
+
+ return True;
}
struct ldb_context *ldb = winssrv->wins_db;
struct ldb_message *msg;
TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
- int ret;
+ int trans = -1;
+ int ret = 0;
+
+
+ trans = ldb_transaction_start(ldb);
+ if (trans != LDB_SUCCESS) goto failed;
rec->version = winsdb_allocate_version(winssrv);
if (rec->version == 0) goto failed;
ret = ldb_add(ldb, msg);
if (ret != 0) goto failed;
+ trans = ldb_transaction_commit(ldb);
+ if (trans != LDB_SUCCESS) goto failed;
+
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
failed:
+ if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
talloc_free(tmp_ctx);
return NBT_RCODE_SVR;
}
struct ldb_context *ldb = winssrv->wins_db;
struct ldb_message *msg;
TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
+ int trans;
int ret;
int i;
+ trans = ldb_transaction_start(ldb);
+ if (trans != LDB_SUCCESS) goto failed;
+
rec->version = winsdb_allocate_version(winssrv);
if (rec->version == 0) goto failed;
ret = ldb_modify(ldb, msg);
if (ret != 0) goto failed;
+ trans = ldb_transaction_commit(ldb);
+ if (trans != LDB_SUCCESS) goto failed;
+
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
failed:
+ if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
talloc_free(tmp_ctx);
return NBT_RCODE_SVR;
}
{
struct ldb_context *ldb = winssrv->wins_db;
TALLOC_CTX *tmp_ctx = talloc_new(winssrv);
- int ret;
const struct ldb_dn *dn;
+ int trans;
+ int ret;
+
+ trans = ldb_transaction_start(ldb);
+ if (trans != LDB_SUCCESS) goto failed;
- winsdb_remove_version(winssrv, rec->version);
+ if(!winsdb_remove_version(winssrv, rec->version))
+ goto failed;
dn = winsdb_dn(tmp_ctx, rec->name);
if (dn == NULL) goto failed;
ret = ldb_delete(ldb, dn);
if (ret != 0) goto failed;
+ trans = ldb_transaction_commit(ldb);
+ if (trans != LDB_SUCCESS) goto failed;
+
talloc_free(tmp_ctx);
return NBT_RCODE_OK;
failed:
+ if (trans == LDB_SUCCESS) ldb_transaction_cancel(ldb);
talloc_free(tmp_ctx);
return NBT_RCODE_SVR;
}