s4:ldb_ildap - Don't segfault on a empty RDN
[ira/wip.git] / source4 / lib / ldb / ldb_ildap / ldb_ildap.c
index b17d063c0cec64a818a633664793fa7e344a81bf..352b7696d698fa47492bfb6b93e2de4f54e1368f 100644 (file)
  *    author: Simo Sorce
  */
 
-
 #include "includes.h"
-#include "ldb_includes.h"
+#include "ldb_module.h"
+#include "dlinklist.h"
 
-#include "lib/events/events.h"
 #include "libcli/ldap/ldap.h"
 #include "libcli/ldap/ldap_client.h"
 #include "auth/auth.h"
@@ -52,7 +51,7 @@
 
 struct ildb_private {
        struct ldap_connection *ldap;
-       struct event_context *event_ctx;
+       struct tevent_context *event_ctx;
 };
 
 struct ildb_context {
@@ -70,8 +69,11 @@ struct ildb_context {
 static void ildb_request_done(struct ildb_context *ctx,
                              struct ldb_control **ctrls, int error)
 {
+       struct ldb_context *ldb;
        struct ldb_reply *ares;
 
+       ldb = ldb_module_get_ctx(ctx->module);
+
        ctx->done = true;
 
        if (ctx->req == NULL) {
@@ -81,7 +83,7 @@ static void ildb_request_done(struct ildb_context *ctx,
 
        ares = talloc_zero(ctx->req, struct ldb_reply);
        if (!ares) {
-               ldb_oom(ctx->req->handle->ldb);
+               ldb_oom(ldb);
                ctx->req->callback(ctx->req, NULL);
                return;
        }
@@ -92,8 +94,8 @@ static void ildb_request_done(struct ildb_context *ctx,
        ctx->req->callback(ctx->req, ares);
 }
 
-static void ildb_auto_done_callback(struct event_context *ev,
-                                   struct timed_event *te,
+static void ildb_auto_done_callback(struct tevent_context *ev,
+                                   struct tevent_timer *te,
                                    struct timeval t,
                                    void *private_data)
 {
@@ -163,17 +165,23 @@ failed:
 */
 static int ildb_map_error(struct ldb_module *module, NTSTATUS status)
 {
-       struct ildb_private *ildb = talloc_get_type(module->private_data, struct ildb_private);
+       struct ildb_private *ildb;
+       struct ldb_context *ldb;
+       TALLOC_CTX *mem_ctx;
+
+       ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private);
+       ldb = ldb_module_get_ctx(module);
 
-       TALLOC_CTX *mem_ctx = talloc_new(ildb);
        if (NT_STATUS_IS_OK(status)) {
                return LDB_SUCCESS;
        }
+
+       mem_ctx = talloc_new(ildb);
        if (!mem_ctx) {
-               ldb_oom(module->ldb);
+               ldb_oom(ldb);
                return LDB_ERR_OPERATIONS_ERROR;
        }
-       ldb_set_errstring(module->ldb,
+       ldb_set_errstring(ldb,
                          ldap_errstr(ildb->ldap, mem_ctx, status));
        talloc_free(mem_ctx);
        if (NT_STATUS_IS_LDAP(status)) {
@@ -182,7 +190,7 @@ static int ildb_map_error(struct ldb_module *module, NTSTATUS status)
        return LDB_ERR_OPERATIONS_ERROR;
 }
 
-static void ildb_request_timeout(struct event_context *ev, struct timed_event *te,
+static void ildb_request_timeout(struct tevent_context *ev, struct tevent_timer *te,
                                 struct timeval t, void *private_data)
 {
        struct ildb_context *ac = talloc_get_type(private_data, struct ildb_context);
@@ -196,6 +204,7 @@ static void ildb_request_timeout(struct event_context *ev, struct timed_event *t
 
 static void ildb_callback(struct ldap_request *req)
 {
+       struct ldb_context *ldb;
        struct ildb_context *ac;
        NTSTATUS status;
        struct ldap_SearchResEntry *search;
@@ -209,6 +218,7 @@ static void ildb_callback(struct ldap_request *req)
        int i;
 
        ac = talloc_get_type(req->async.private_data, struct ildb_context);
+       ldb = ldb_module_get_ctx(ac->module);
        callback_failed = false;
        request_done = false;
        controls = NULL;
@@ -285,7 +295,7 @@ static void ildb_callback(struct ldap_request *req)
                                controls = talloc_steal(ac, 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(ldb, msg->r.SearchResultDone.errormessage);
                                        }
                                }
 
@@ -303,7 +313,7 @@ static void ildb_callback(struct ldap_request *req)
 
                                search = &(msg->r.SearchResultEntry);
 
-                               ldbmsg->dn = ldb_dn_new(ldbmsg, ac->module->ldb, search->dn);
+                               ldbmsg->dn = ldb_dn_new(ldbmsg, ldb, search->dn);
                                if ( ! ldb_dn_validate(ldbmsg->dn)) {
                                        ret = LDB_ERR_OPERATIONS_ERROR;
                                        break;
@@ -368,30 +378,33 @@ static void ildb_callback(struct ldap_request *req)
 
 static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg)
 {
+       struct ldb_context *ldb;
        struct ldap_request *req;
 
        if (!ac) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
+       ldb = ldb_module_get_ctx(ac->module);
+
        req = ldap_request_send(ac->ildb->ldap, msg);
        if (req == NULL) {
-               ldb_set_errstring(ac->module->ldb, "async send request failed");
+               ldb_set_errstring(ldb, "async send request failed");
                return LDB_ERR_OPERATIONS_ERROR;
        }
        ac->ireq = talloc_steal(ac, req);
 
        if (!ac->ireq->conn) {
-               ldb_set_errstring(ac->module->ldb, "connection to remote LDAP server dropped?");
+               ldb_set_errstring(ldb, "connection to remote LDAP server dropped?");
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        talloc_free(req->time_event);
        req->time_event = NULL;
        if (ac->req->timeout) {
-               req->time_event = event_add_timed(ac->ildb->event_ctx, ac,
-                                                 timeval_current_ofs(ac->req->timeout, 0),
-                                                 ildb_request_timeout, ac);
+               req->time_event = tevent_add_timer(ac->ildb->event_ctx, ac,
+                                                  timeval_current_ofs(ac->req->timeout, 0),
+                                                  ildb_request_timeout, ac);
        }
 
        req->async.fn = ildb_callback;
@@ -405,23 +418,26 @@ static int ildb_request_send(struct ildb_context *ac, struct ldap_message *msg)
  */
 static int ildb_search(struct ildb_context *ac)
 {
+       struct ldb_context *ldb;
        struct ldb_request *req = ac->req;
        struct ldap_message *msg;
        int n;
 
+       ldb = ldb_module_get_ctx(ac->module);
+
        if (!req->callback || !req->context) {
-               ldb_set_errstring(ac->module->ldb, "Async interface called with NULL callback function or NULL context");
+               ldb_set_errstring(ldb, "Async interface called with NULL callback function or NULL context");
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        if (req->op.search.tree == NULL) {
-               ldb_set_errstring(ac->module->ldb, "Invalid expression parse tree");
+               ldb_set_errstring(ldb, "Invalid expression parse tree");
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        msg = new_ldap_message(req);
        if (msg == NULL) {
-               ldb_set_errstring(ac->module->ldb, "Out of Memory");
+               ldb_set_errstring(ldb, "Out of Memory");
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
@@ -433,7 +449,7 @@ static int ildb_search(struct ildb_context *ac)
                msg->r.SearchRequest.basedn  = ldb_dn_get_extended_linearized(msg, req->op.search.base, 0);
        }
        if (msg->r.SearchRequest.basedn == NULL) {
-               ldb_set_errstring(ac->module->ldb, "Unable to determine baseDN");
+               ldb_set_errstring(ldb, "Unable to determine baseDN");
                talloc_free(msg);
                return LDB_ERR_OPERATIONS_ERROR;
        }
@@ -452,7 +468,7 @@ static int ildb_search(struct ildb_context *ac)
 
        for (n = 0; req->op.search.attrs && req->op.search.attrs[n]; n++) /* noop */ ;
        msg->r.SearchRequest.num_attributes = n;
-       msg->r.SearchRequest.attributes = discard_const(req->op.search.attrs);
+       msg->r.SearchRequest.attributes = req->op.search.attrs;
        msg->controls = req->controls;
 
        return ildb_request_send(ac, msg);
@@ -575,6 +591,8 @@ static int ildb_rename(struct ildb_context *ac)
 {
        struct ldb_request *req = ac->req;
        struct ldap_message *msg;
+       const char *rdn_name;
+       const struct ldb_val *rdn_val;
 
        msg = new_ldap_message(req);
        if (msg == NULL) {
@@ -588,10 +606,16 @@ static int ildb_rename(struct ildb_context *ac)
                return LDB_ERR_INVALID_DN_SYNTAX;
        }
 
-       msg->r.ModifyDNRequest.newrdn =
-               talloc_asprintf(msg, "%s=%s",
-                               ldb_dn_get_rdn_name(req->op.rename.newdn),
-                               ldb_dn_escape_value(msg, *ldb_dn_get_rdn_val(req->op.rename.newdn)));
+       rdn_name = ldb_dn_get_rdn_name(req->op.rename.newdn);
+       rdn_val = ldb_dn_get_rdn_val(req->op.rename.newdn);
+
+       if ((rdn_name != NULL) && (rdn_val != NULL)) {
+               msg->r.ModifyDNRequest.newrdn =
+                       talloc_asprintf(msg, "%s=%s", rdn_name,
+                               ldb_dn_escape_value(msg, *rdn_val));
+       } else {
+               msg->r.ModifyDNRequest.newrdn = talloc_strdup(msg, "");
+       }
        if (msg->r.ModifyDNRequest.newrdn == NULL) {
                talloc_free(msg);
                return LDB_ERR_OPERATIONS_ERROR;
@@ -659,21 +683,23 @@ static bool ildb_dn_is_special(struct ldb_request *req)
 
 static int ildb_handle_request(struct ldb_module *module, struct ldb_request *req)
 {
+       struct ldb_context *ldb;
        struct ildb_private *ildb;
        struct ildb_context *ac;
-       struct timed_event *te;
+       struct tevent_timer *te;
        int ret;
 
-       ildb = talloc_get_type(module->private_data, struct ildb_private);
+       ildb = talloc_get_type(ldb_module_get_private(module), struct ildb_private);
+       ldb = ldb_module_get_ctx(module);
 
        if (req->starttime == 0 || req->timeout == 0) {
-               ldb_set_errstring(module->ldb, "Invalid timeout settings");
+               ldb_set_errstring(ldb, "Invalid timeout settings");
                return LDB_ERR_TIME_LIMIT_EXCEEDED;
        }
 
        ac = talloc_zero(req, struct ildb_context);
        if (ac == NULL) {
-               ldb_set_errstring(module->ldb, "Out of Memory");
+               ldb_set_errstring(ldb, "Out of Memory");
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
@@ -683,9 +709,9 @@ static int ildb_handle_request(struct ldb_module *module, struct ldb_request *re
 
        if (ildb_dn_is_special(req)) {
 
-               te = event_add_timed(ac->ildb->event_ctx,
-                                       ac, timeval_zero(),
-                                       ildb_auto_done_callback, ac);
+               te = tevent_add_timer(ac->ildb->event_ctx,
+                                     ac, timeval_zero(),
+                                     ildb_auto_done_callback, ac);
                if (NULL == te) {
                        return LDB_ERR_OPERATIONS_ERROR;
                }
@@ -742,28 +768,24 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
        struct ildb_private *ildb;
        NTSTATUS status;
        struct cli_credentials *creds;
+       struct loadparm_context *lp_ctx;
 
-       module = talloc(ldb, struct ldb_module);
-       if (!module) {
-               ldb_oom(ldb);
-               return -1;
-       }
-       talloc_set_name_const(module, "ldb_ildap backend");
-       module->ldb             = ldb;
-       module->prev            = module->next = NULL;
-       module->ops             = &ildb_ops;
+       module = ldb_module_new(ldb, ldb, "ldb_ildap backend", &ildb_ops);
+       if (!module) return -1;
 
        ildb = talloc(module, struct ildb_private);
        if (!ildb) {
                ldb_oom(ldb);
                goto failed;
        }
-       module->private_data    = ildb;
+       ldb_module_set_private(module, ildb);
 
        ildb->event_ctx = ldb_get_event_context(ldb);
 
+       lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
+                                struct loadparm_context);
 
-       ildb->ldap = ldap4_new_connection(ildb, ldb_get_opaque(ldb, "loadparm"),
+       ildb->ldap = ldap4_new_connection(ildb, lp_ctx,
                                          ildb->event_ctx);
        if (!ildb->ldap) {
                ldb_oom(ldb);
@@ -776,7 +798,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",
+               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to connect to ldap URL '%s' - %s",
                          url, ldap_errstr(ildb->ldap, module, status));
                goto failed;
        }
@@ -796,14 +818,14 @@ static int ildb_connect(struct ldb_context *ldb, const char *url,
                        const char *password = cli_credentials_get_password(creds);
                        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",
+                               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
                                          ldap_errstr(ildb->ldap, module, status));
                                goto failed;
                        }
                } else {
-                       status = ldap_bind_sasl(ildb->ldap, creds, ldb_get_opaque(ldb, "loadparm"));
+                       status = ldap_bind_sasl(ildb->ldap, creds, lp_ctx);
                        if (!NT_STATUS_IS_OK(status)) {
-                               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
+                               ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s",
                                          ldap_errstr(ildb->ldap, module, status));
                                goto failed;
                        }