*/
#include "includes.h"
-#include "dlinklist.h"
+#include "lib/util/dlinklist.h"
+#include "lib/events/events.h"
#include "lib/tdb/include/tdb.h"
#include "lib/ldb/include/ldb.h"
+#include "lib/ldb/include/ldb_errors.h"
+#include "lib/ldb/samba/ldif_handlers.h"
#include "db_wrap.h"
-struct ldb_wrap {
- struct ldb_context *ldb;
-
- const char *url;
- struct ldb_wrap *next, *prev;
-};
-
-static struct ldb_wrap *ldb_list;
static struct tdb_wrap *tdb_list;
/*
if (DEBUGLEVEL < 4 && level > LDB_DEBUG_WARNING) {
return;
}
+ if (DEBUGLEVEL < 2 && level > LDB_DEBUG_ERROR) {
+ return;
+ }
vasprintf(&s, fmt, ap);
if (!s) return;
DEBUG(level, ("ldb: %s\n", s));
free(s);
}
-/* destroy the last connection to a ldb */
-static int ldb_wrap_destructor(void *ctx)
+char *wrap_casefold(void *context, void *mem_ctx, const char *s)
{
- struct ldb_wrap *w = ctx;
- DLIST_REMOVE(ldb_list, w);
- return 0;
-}
+ return strupper_talloc(mem_ctx, s);
+}
/*
wrapped connection to a ldb database
to close just talloc_free() the returned ldb_context
+
+ TODO: We need an error_string parameter
*/
struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx,
const char *url,
+ struct auth_session_info *session_info,
+ struct cli_credentials *credentials,
unsigned int flags,
const char *options[])
{
struct ldb_context *ldb;
- struct ldb_wrap *w;
int ret;
struct event_context *ev;
char *real_url = NULL;
- for (w = ldb_list; w; w = w->next) {
- if (strcmp(url, w->url) == 0) {
- return talloc_reference(mem_ctx, w->ldb);
- }
- }
-
- ldb = ldb_init(talloc_autofree_context());
+ ldb = ldb_init(mem_ctx);
if (ldb == NULL) {
return NULL;
}
/* we want to use the existing event context if possible. This
relies on the fact that in smbd, everything is a child of
the main event_context */
- ev = talloc_find_parent_bytype(mem_ctx, struct event_context);
- if (ev) {
- ldb_set_opaque(ldb, "EventContext", ev);
- } else {
- DEBUG(5,("WARNING: event_context not found\n"));
+ ev = event_context_find(ldb);
+
+ if (ldb_set_opaque(ldb, "EventContext", ev)) {
+ talloc_free(ldb);
+ return NULL;
+ }
+
+ if (ldb_set_opaque(ldb, "sessionInfo", session_info)) {
+ talloc_free(ldb);
+ return NULL;
+ }
+
+ if (ldb_set_opaque(ldb, "credentials", credentials)) {
+ talloc_free(ldb);
+ return NULL;
}
ret = ldb_register_samba_handlers(ldb);
talloc_free(ldb);
return NULL;
}
+
+ /* allow admins to force non-sync ldb for all databases */
+ if (lp_parm_bool(-1, "ldb", "nosync", False)) {
+ flags |= LDB_FLG_NOSYNC;
+ }
ret = ldb_connect(ldb, real_url, flags, options);
- if (ret == -1) {
+ if (ret != LDB_SUCCESS) {
talloc_free(ldb);
return NULL;
}
talloc_free(real_url);
- w = talloc(ldb, struct ldb_wrap);
- if (w == NULL) {
- talloc_free(ldb);
- return NULL;
- }
-
- w->ldb = ldb;
- w->url = talloc_strdup(w, url);
-
- talloc_set_destructor(w, ldb_wrap_destructor);
ldb_set_debug(ldb, ldb_wrap_debug, NULL);
- DLIST_ADD(ldb_list, w);
+ ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
return ldb;
}
/*
Log tdb messages via DEBUG().
*/
-static void tdb_wrap_log(TDB_CONTEXT *tdb, int level,
+static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,
const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static void tdb_wrap_log(TDB_CONTEXT *tdb, int level,
+static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level,
const char *format, ...)
{
va_list ap;
char *ptr = NULL;
+ int debug_level;
va_start(ap, format);
vasprintf(&ptr, format, ap);
va_end(ap);
+ switch (level) {
+ case TDB_DEBUG_FATAL:
+ debug_level = 0;
+ break;
+ case TDB_DEBUG_ERROR:
+ debug_level = 1;
+ break;
+ case TDB_DEBUG_WARNING:
+ debug_level = 2;
+ break;
+ case TDB_DEBUG_TRACE:
+ debug_level = 5;
+ break;
+ default:
+ debug_level = 0;
+ }
+
if (ptr != NULL) {
- DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unnamed", ptr));
+ const char *name = tdb_name(tdb);
+ DEBUG(debug_level, ("tdb(%s): %s", name ? name : "unnamed", ptr));
free(ptr);
}
}
/* destroy the last connection to a tdb */
-static int tdb_wrap_destructor(void *ctx)
+static int tdb_wrap_destructor(struct tdb_wrap *w)
{
- struct tdb_wrap *w = ctx;
tdb_close(w->tdb);
DLIST_REMOVE(tdb_list, w);
return 0;
int open_flags, mode_t mode)
{
struct tdb_wrap *w;
+ struct tdb_logging_context log_ctx;
+ log_ctx.log_fn = tdb_wrap_log;
for (w=tdb_list;w;w=w->next) {
if (strcmp(name, w->name) == 0) {
w->name = talloc_strdup(w, name);
w->tdb = tdb_open_ex(name, hash_size, tdb_flags,
- open_flags, mode, tdb_wrap_log, NULL);
+ open_flags, mode, &log_ctx, NULL);
if (w->tdb == NULL) {
talloc_free(w);
return NULL;