r9391: Convert all the code to use struct ldb_dn to ohandle ldap like distinguished...
[kamenim/samba.git] / source4 / lib / ldb / common / ldb.c
index 86d0dd9e9bf1752bc82a72815e4afb9e71b20393..25e7bee66b749a4135037d571a012b1e87d5e6e7 100644 (file)
  */
 
 #include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_private.h"
+
+/* 
+   initialise a ldb context
+   The mem_ctx is optional
+*/
+struct ldb_context *ldb_init(void *mem_ctx)
+{
+       struct ldb_context *ldb = talloc_zero(mem_ctx, struct ldb_context);
+       int ret;
+
+       ret = ldb_setup_wellknown_attributes(ldb);
+       if (ret != 0) {
+               talloc_free(ldb);
+               return NULL;
+       }
+
+       return ldb;
+}
 
 /* 
  connect to a database. The URL can either be one of the following forms
    the options are passed uninterpreted to the backend, and are
    backend specific
 */
-struct ldb_context *ldb_connect(const char *url, unsigned int flags,
-                               const char *options[])
+int ldb_connect(struct ldb_context *ldb, const char *url, unsigned int flags, const char *options[])
 {
+       int ret;
 
        if (strncmp(url, "tdb:", 4) == 0 ||
            strchr(url, ':') == NULL) {
-               return ltdb_connect(url, flags, options);
+               ret = ltdb_connect(ldb, url, flags, options);
        }
 
-#if HAVE_LDAP
-       if (strncmp(url, "ldap", 4) == 0) {
-               return lldb_connect(url, flags, options);
+#if HAVE_ILDAP
+       else if (strncmp(url, "ldap", 4) == 0) {
+               ret = ildb_connect(ldb, url, flags, options);
+       }
+#elif HAVE_LDAP
+       else if (strncmp(url, "ldap", 4) == 0) {
+               ret = lldb_connect(ldb, url, flags, options);
+       }
+#endif
+#if HAVE_SQLITE3
+       else if (strncmp(url, "sqlite:", 7) == 0) {
+                ret = lsqlite3_connect(ldb, url, flags, options);
        }
 #endif
+       else {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to find backend for '%s'\n", url);
+               return -1;
+       }
 
-       errno = EINVAL;
-       return NULL;
-}
+       if (ret != 0) {
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to '%s'\n", url);
+               return ret;
+       }
 
-/*
-  close the connection to the database
-*/
-int ldb_close(struct ldb_context *ldb)
-{
-       return ldb->ops->close(ldb);
-}
+       if (ldb_load_modules(ldb, options) != 0) {
+               ldb_debug(ldb, LDB_DEBUG_FATAL, "Unable to load modules for '%s'\n", url);
+               return -1;
+       }
 
+       return 0;
+}
 
 /*
   search the database given a LDAP-like search expression
 
   return the number of records found, or -1 on error
+
+  Use talloc_free to free the ldb_message returned in 'res'
+
 */
 int ldb_search(struct ldb_context *ldb, 
-              const char *base,
+              const struct ldb_dn *base,
               enum ldb_scope scope,
               const char *expression,
-              char * const *attrs, struct ldb_message ***res)
+              const char * const *attrs, struct ldb_message ***res)
 {
-       return ldb->ops->search(ldb, base, scope, expression, attrs, res);
+       return ldb->modules->ops->search(ldb->modules, base, scope, expression, attrs, res);
 }
 
-/* 
-   free a set of messages returned by ldb_search
+/*
+  search the database given a LDAP-like search expression
+
+  return the number of records found, or -1 on error
+
+  Use talloc_free to free the ldb_message returned in 'res'
+
 */
-int ldb_search_free(struct ldb_context *ldb, struct ldb_message **msgs)
+int ldb_search_bytree(struct ldb_context *ldb, 
+                     const struct ldb_dn *base,
+                     enum ldb_scope scope,
+                     struct ldb_parse_tree *tree,
+                     const char * const *attrs, struct ldb_message ***res)
 {
-       return ldb->ops->search_free(ldb, msgs);
+       return ldb->modules->ops->search_bytree(ldb->modules, base, scope, tree, attrs, res);
 }
 
-
 /*
   add a record to the database. Will fail if a record with the given class and key
   already exists
@@ -102,7 +146,7 @@ int ldb_search_free(struct ldb_context *ldb, struct ldb_message **msgs)
 int ldb_add(struct ldb_context *ldb, 
            const struct ldb_message *message)
 {
-       return ldb->ops->add_record(ldb, message);
+       return ldb->modules->ops->add_record(ldb->modules, message);
 }
 
 /*
@@ -111,16 +155,40 @@ int ldb_add(struct ldb_context *ldb,
 int ldb_modify(struct ldb_context *ldb, 
               const struct ldb_message *message)
 {
-       return ldb->ops->modify_record(ldb, message);
+       return ldb->modules->ops->modify_record(ldb->modules, message);
 }
 
 
 /*
   delete a record from the database
 */
-int ldb_delete(struct ldb_context *ldb, const char *dn)
+int ldb_delete(struct ldb_context *ldb, const struct ldb_dn *dn)
 {
-       return ldb->ops->delete_record(ldb, dn);
+       return ldb->modules->ops->delete_record(ldb->modules, dn);
+}
+
+/*
+  rename a record in the database
+*/
+int ldb_rename(struct ldb_context *ldb, const struct ldb_dn *olddn, const struct ldb_dn *newdn)
+{
+       return ldb->modules->ops->rename_record(ldb->modules, olddn, newdn);
+}
+
+/*
+  create a named lock
+*/
+int ldb_lock(struct ldb_context *ldb, const char *lockname)
+{
+        return ldb->modules->ops->named_lock(ldb->modules, lockname);
+}
+
+/*
+  release a named lock
+*/
+int ldb_unlock(struct ldb_context *ldb, const char *lockname)
+{
+        return ldb->modules->ops->named_unlock(ldb->modules, lockname);
 }
 
 /*
@@ -128,5 +196,40 @@ int ldb_delete(struct ldb_context *ldb, const char *dn)
 */
 const char *ldb_errstring(struct ldb_context *ldb)
 {
-       return ldb->ops->errstring(ldb);
+       if (ldb->modules == NULL) {
+               return "ldb not connected";
+       }
+       return ldb->modules->ops->errstring(ldb->modules);
+}
+
+
+/*
+  set backend specific opaque parameters
+*/
+int ldb_set_opaque(struct ldb_context *ldb, const char *name, void *value)
+{
+       struct ldb_opaque *o = talloc(ldb, struct ldb_opaque);
+       if (o == NULL) {
+               ldb_oom(ldb);
+               return -1;
+       }
+       o->next = ldb->opaque;
+       o->name = name;
+       o->value = value;
+       ldb->opaque = o;
+       return 0;
+}
+
+/*
+  get a previously set opaque value
+*/
+void *ldb_get_opaque(struct ldb_context *ldb, const char *name)
+{
+       struct ldb_opaque *o;
+       for (o=ldb->opaque;o;o=o->next) {
+               if (strcmp(o->name, name) == 0) {
+                       return o->value;
+               }
+       }
+       return NULL;
 }