Now that we pass down the event context, start removing calls to
[metze/samba/wip.git] / source / lib / ldb / ldb_ildap / ldb_ildap.c
index 7285bad00b7cb22fa9e650458077c186fc095f9b..d1677032f0b98bb75e7a9d5e36850b8c4a4d5473 100644 (file)
@@ -11,7 +11,7 @@
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
+   version 3 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,8 +19,7 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
 /*
 
 
 #include "includes.h"
-#include "ldb/include/includes.h"
+#include "ldb_includes.h"
 
 #include "lib/events/events.h"
 #include "libcli/ldap/ldap.h"
 #include "libcli/ldap/ldap_client.h"
 #include "auth/auth.h"
 #include "auth/credentials/credentials.h"
+#include "param/param.h"
 
 struct ildb_private {
        struct ldap_connection *ldap;
-       struct ldb_context *ldb;
        struct ldb_module *module;
 };
 
 struct ildb_context {
-       struct ldb_module *module;
+       struct ildb_private *ildb;
+       struct ldb_handle *handle;
        struct ldap_request *req;
        void *context;
        int (*callback)(struct ldb_context *, void *, struct ldb_reply *);
@@ -123,10 +123,16 @@ failed:
 */
 static int ildb_map_error(struct ildb_private *ildb, NTSTATUS status)
 {
+       TALLOC_CTX *mem_ctx = talloc_new(ildb);
        if (NT_STATUS_IS_OK(status)) {
                return LDB_SUCCESS;
        }
-       ldb_set_errstring(ildb->ldb, ldap_errstr(ildb->ldap, status));
+       if (!mem_ctx) {
+               ldb_oom(ildb->module->ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+       ldb_set_errstring(ildb->module->ldb, ldap_errstr(ildb->ldap, mem_ctx, status));
+       talloc_free(mem_ctx);
        if (NT_STATUS_IS_LDAP(status)) {
                return NT_STATUS_LDAP_CODE(status);
        }
@@ -136,8 +142,8 @@ static int ildb_map_error(struct ildb_private *ildb, NTSTATUS status)
 static void ildb_request_timeout(struct event_context *ev, struct timed_event *te,
                                 struct timeval t, void *private_data)
 {
-       struct ldb_handle *handle = talloc_get_type(private_data, struct ldb_handle);
-       struct ildb_context *ac = talloc_get_type(handle->private_data, struct ildb_context);
+       struct ildb_context *ac = talloc_get_type(private_data, struct ildb_context);
+       struct ldb_handle *handle = ac->handle;
 
        if (ac->req->state == LDAP_REQUEST_PENDING) {
                DLIST_REMOVE(ac->req->conn->pending, ac->req);
@@ -150,9 +156,9 @@ static void ildb_request_timeout(struct event_context *ev, struct timed_event *t
 
 static void ildb_callback(struct ldap_request *req)
 {
-       struct ldb_handle *handle = talloc_get_type(req->async.private_data, struct ldb_handle);
-       struct ildb_context *ac = talloc_get_type(handle->private_data, struct ildb_context);
-       struct ildb_private *ildb = talloc_get_type(ac->module->private_data, struct ildb_private);
+       struct ildb_context *ac = talloc_get_type(req->async.private_data, struct ildb_context);
+       struct ldb_handle *handle = ac->handle;
+       struct ildb_private *ildb = ac->ildb;
        NTSTATUS status;
        int i;
 
@@ -179,7 +185,7 @@ static void ildb_callback(struct ldap_request *req)
                handle->status = ildb_map_error(ildb, status);
                if (ac->callback && handle->status == LDB_SUCCESS) {
                        /* FIXME: build a corresponding ares to pass on */
-                       handle->status = ac->callback(ac->module->ldb, ac->context, NULL);
+                       handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);
                }
                handle->state = LDB_ASYNC_DONE;
                break;
@@ -193,7 +199,7 @@ static void ildb_callback(struct ldap_request *req)
                handle->status = ildb_map_error(ildb, status);
                if (ac->callback && handle->status == LDB_SUCCESS) {
                        /* FIXME: build a corresponding ares to pass on */
-                       handle->status = ac->callback(ac->module->ldb, ac->context, NULL);
+                       handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);
                }
                handle->state = LDB_ASYNC_DONE;
                break;
@@ -207,7 +213,7 @@ static void ildb_callback(struct ldap_request *req)
                handle->status = ildb_map_error(ildb, status);
                if (ac->callback && handle->status == LDB_SUCCESS) {
                        /* FIXME: build a corresponding ares to pass on */
-                       handle->status = ac->callback(ac->module->ldb, ac->context, NULL);
+                       handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);
                }
                handle->state = LDB_ASYNC_DONE;
                break;
@@ -221,7 +227,7 @@ static void ildb_callback(struct ldap_request *req)
                handle->status = ildb_map_error(ildb, status);
                if (ac->callback && handle->status == LDB_SUCCESS) {
                        /* FIXME: build a corresponding ares to pass on */
-                       handle->status = ac->callback(ac->module->ldb, ac->context, NULL);
+                       handle->status = ac->callback(ac->ildb->module->ldb, ac->context, NULL);
                }
                handle->state = LDB_ASYNC_DONE;
                break;
@@ -254,7 +260,7 @@ static void ildb_callback(struct ldap_request *req)
                                ares->controls = talloc_move(ares, &msg->controls);
                                if (msg->r.SearchResultDone.resultcode) {
                                        if (msg->r.SearchResultDone.errormessage) {
-                                               ldb_set_errstring(ac->module->ldb, msg->r.SearchResultDone.errormessage);
+                                               ldb_set_errstring(ac->ildb->module->ldb, msg->r.SearchResultDone.errormessage);
                                        }
                                }
 
@@ -274,7 +280,7 @@ static void ildb_callback(struct ldap_request *req)
 
                                search = &(msg->r.SearchResultEntry);
                
-                               ares->message->dn = ldb_dn_new(ares->message, ac->module->ldb, search->dn);
+                               ares->message->dn = ldb_dn_new(ares->message, ac->ildb->module->ldb, search->dn);
                                if ( ! ldb_dn_validate(ares->message->dn)) {
                                        handle->status = LDB_ERR_OPERATIONS_ERROR;
                                        return;
@@ -303,7 +309,7 @@ static void ildb_callback(struct ldap_request *req)
                                return;
                        }
 
-                       ret = ac->callback(ac->module->ldb, ac->context, ares);
+                       ret = ac->callback(ac->ildb->module->ldb, ac->context, ares);
                        if (ret) {
                                handle->status = ret;
                        }
@@ -321,58 +327,56 @@ static void ildb_callback(struct ldap_request *req)
        }
 }
 
-static struct ldb_handle *init_ildb_handle(struct ldb_module *module, 
-                                          void *context,
-                                          int (*callback)(struct ldb_context *, void *, struct ldb_reply *))
+static struct ildb_context *init_ildb_handle(struct ildb_private *ildb,
+                                            struct ldb_request *req)
 {
-       struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private);
        struct ildb_context *ildb_ac;
        struct ldb_handle *h;
 
-       h = talloc_zero(ildb->ldap, struct ldb_handle);
+       h = talloc_zero(req, struct ldb_handle);
        if (h == NULL) {
-               ldb_set_errstring(module->ldb, "Out of Memory");
+               ldb_set_errstring(ildb->module->ldb, "Out of Memory");
                return NULL;
        }
 
-       h->module = module;
+       h->module = ildb->module;
 
        ildb_ac = talloc(h, struct ildb_context);
        if (ildb_ac == NULL) {
-               ldb_set_errstring(module->ldb, "Out of Memory");
+               ldb_set_errstring(ildb->module->ldb, "Out of Memory");
                talloc_free(h);
                return NULL;
        }
 
-       h->private_data = (void *)ildb_ac;
+       h->private_data = ildb_ac;
 
        h->state = LDB_ASYNC_INIT;
        h->status = LDB_SUCCESS;
 
-       ildb_ac->module = module;
-       ildb_ac->context = context;
-       ildb_ac->callback = callback;
+       ildb_ac->ildb = ildb;
+       ildb_ac->handle = h;
+       ildb_ac->context = req->context;
+       ildb_ac->callback = req->callback;
 
-       return h;
+       req->handle = h;
+       return ildb_ac;
 }
 
 static int ildb_request_send(struct ildb_private *ildb, struct ldap_message *msg, struct ldb_request *r)
 {
-       struct ldb_handle *h = init_ildb_handle(ildb->module, r->context, r->callback);
-       struct ildb_context *ildb_ac;
+       struct ildb_context *ildb_ac = init_ildb_handle(ildb, r);
        struct ldap_request *req;
 
-       if (!h) {
+       if (!ildb_ac) {
                return LDB_ERR_OPERATIONS_ERROR;                
        }
 
-       ildb_ac = talloc_get_type(h->private_data, struct ildb_context);
-
        req = ldap_request_send(ildb->ldap, msg);
        if (req == NULL) {
                ldb_set_errstring(ildb->module->ldb, "async send request failed");
                return LDB_ERR_OPERATIONS_ERROR;
        }
+       ildb_ac->req = talloc_steal(ildb_ac, req);
 
        if (!req->conn) {
                ldb_set_errstring(ildb->module->ldb, "connection to remote LDAP server dropped?");
@@ -382,37 +386,30 @@ static int ildb_request_send(struct ildb_private *ildb, struct ldap_message *msg
        talloc_free(req->time_event);
        req->time_event = NULL;
        if (r->timeout) {
-               req->time_event = event_add_timed(req->conn->event.event_ctx, h
+               req->time_event = event_add_timed(req->conn->event.event_ctx, ildb_ac
                                                  timeval_current_ofs(r->timeout, 0),
-                                                 ildb_request_timeout, h);
+                                                 ildb_request_timeout, ildb_ac);
        }
 
        req->async.fn = ildb_callback;
-       req->async.private_data = h;
-       ildb_ac->req = talloc_move(ildb_ac, &req);
+       req->async.private_data = ildb_ac;
 
-       r->handle = h;
        return LDB_SUCCESS;
 }
 
 static int ildb_request_noop(struct ildb_private *ildb, struct ldb_request *req) 
 {
-       struct ldb_handle *h = init_ildb_handle(ildb->module, req->context, req->callback);
-       struct ildb_context *ildb_ac;
+       struct ildb_context *ildb_ac = init_ildb_handle(ildb, req);
        int ret = LDB_SUCCESS;
 
-       if (!h) {
+       if (!ildb_ac) {
                return LDB_ERR_OPERATIONS_ERROR;                
        }
 
-       ildb_ac = talloc_get_type(h->private_data, struct ildb_context);
-
-       req->handle = h;
-
        if (ildb_ac->callback) {
                ret = ildb_ac->callback(ildb->module->ldb, ildb_ac->context, NULL);
        }
-       req->handle->state = LDB_ASYNC_DONE;
+       ildb_ac->handle->state = LDB_ASYNC_DONE;
        return ret;
 }
 
@@ -437,7 +434,7 @@ static int ildb_search(struct ldb_module *module, struct ldb_request *req)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       msg = new_ldap_message(ildb);
+       msg = new_ldap_message(req);
        if (msg == NULL) {
                ldb_set_errstring(module->ldb, "Out of Memory");
                return LDB_ERR_OPERATIONS_ERROR;
@@ -493,7 +490,7 @@ static int ildb_add(struct ldb_module *module, struct ldb_request *req)
                return ildb_request_noop(ildb, req);
        }
 
-       msg = new_ldap_message(ildb->ldap);
+       msg = new_ldap_message(req);
        if (msg == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -543,7 +540,7 @@ static int ildb_modify(struct ldb_module *module, struct ldb_request *req)
                return ildb_request_noop(ildb, req);
        }
 
-       msg = new_ldap_message(ildb->ldap);
+       msg = new_ldap_message(req);
        if (msg == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -591,7 +588,7 @@ static int ildb_delete(struct ldb_module *module, struct ldb_request *req)
                return ildb_request_noop(ildb, req);
        }
 
-       msg = new_ldap_message(ildb->ldap);
+       msg = new_ldap_message(req);
        if (msg == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -622,7 +619,7 @@ static int ildb_rename(struct ldb_module *module, struct ldb_request *req)
                return ildb_request_noop(ildb, req);
        }
 
-       msg = new_ldap_message(ildb->ldap);
+       msg = new_ldap_message(req);
        if (msg == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -650,7 +647,7 @@ static int ildb_rename(struct ldb_module *module, struct ldb_request *req)
                return LDB_ERR_INVALID_DN_SYNTAX;
        }
 
-       msg->r.ModifyDNRequest.deleteolddn = True;
+       msg->r.ModifyDNRequest.deleteolddn = true;
 
        return ildb_request_send(ildb, msg, req);
 }
@@ -740,6 +737,7 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
        struct ildb_private *ildb;
        NTSTATUS status;
        struct cli_credentials *creds;
+       struct event_context *event_ctx;
 
        module = talloc(ldb, struct ldb_module);
        if (!module) {
@@ -758,9 +756,12 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
                goto failed;
        }
        module->private_data    = ildb;
-       ildb->ldb               = ldb;
        ildb->module            = module;
-       ildb->ldap = ldap4_new_connection(ildb, ldb_get_opaque(ldb, "EventContext"));
+
+       event_ctx = ldb_get_event_context(ldb);
+
+       ildb->ldap = ldap4_new_connection(ildb, ldb_get_opaque(ldb, "loadparm"),
+                                         event_ctx);
        if (!ildb->ldap) {
                ldb_oom(ldb);
                goto failed;
@@ -773,7 +774,7 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
        status = ldap_connect(ildb->ldap, url);
        if (!NT_STATUS_IS_OK(status)) {
                ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s\n",
-                         url, ldap_errstr(ildb->ldap, status));
+                         url, ldap_errstr(ildb->ldap, module, status));
                goto failed;
        }
 
@@ -793,14 +794,14 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
                        status = ldap_bind_simple(ildb->ldap, bind_dn, password);
                        if (!NT_STATUS_IS_OK(status)) {
                                ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
-                                         ldap_errstr(ildb->ldap, status));
+                                         ldap_errstr(ildb->ldap, module, status));
                                goto failed;
                        }
                } else {
-                       status = ldap_bind_sasl(ildb->ldap, creds);
+                       status = ldap_bind_sasl(ildb->ldap, creds, ldb_get_opaque(ldb, "loadparm"));
                        if (!NT_STATUS_IS_OK(status)) {
                                ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
-                                         ldap_errstr(ildb->ldap, status));
+                                         ldap_errstr(ildb->ldap, module, status));
                                goto failed;
                        }
                }
@@ -814,9 +815,18 @@ failed:
        return -1;
 }
 
-int ldb_ildap_init(void)
-{
-       return ldb_register_backend("ldap", ildb_connect) + 
-                  ldb_register_backend("ldapi", ildb_connect) + 
-                  ldb_register_backend("ldaps", ildb_connect);
-}
+_PUBLIC_ const struct ldb_backend_ops ldb_ldap_backend_ops = {
+       .name = "ldap",
+       .connect_fn = ildb_connect
+};
+
+_PUBLIC_ const struct ldb_backend_ops ldb_ldapi_backend_ops = {
+       .name = "ldapi",
+       .connect_fn = ildb_connect
+};
+
+_PUBLIC_ const struct ldb_backend_ops ldb_ldaps_backend_ops = {
+       .name = "ldaps",
+       .connect_fn = ildb_connect
+};
+