s4: fix various warnings (not "const" related ones)
[sfrench/samba-autobuild/.git] / source4 / libcli / ldap / ldap_client.c
index 906e9c2574fdd1917d2d9b5864aff542e81071f7..3c78a7c7e29dc0f5a7d58a25466044ee8db1ad81 100644 (file)
 */
 
 #include "includes.h"
-#include "libcli/util/asn_1.h"
-#include "lib/util/dlinklist.h"
-#include "lib/events/events.h"
+#include <tevent.h>
 #include "lib/socket/socket.h"
+#include "../lib/util/asn1.h"
+#include "../lib/util/dlinklist.h"
 #include "libcli/ldap/ldap.h"
+#include "libcli/ldap/ldap_proto.h"
 #include "libcli/ldap/ldap_client.h"
 #include "libcli/composite/composite.h"
 #include "lib/stream/packet.h"
 #include "auth/gensec/gensec.h"
 #include "system/time.h"
 #include "param/param.h"
-
+#include "libcli/resolve/resolve.h"
 
 /**
   create a new ldap_connection stucture. The event context is optional
 */
-struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, 
+_PUBLIC_ struct ldap_connection *ldap4_new_connection(TALLOC_CTX *mem_ctx, 
                                             struct loadparm_context *lp_ctx,
-                                            struct event_context *ev)
+                                            struct tevent_context *ev)
 {
        struct ldap_connection *conn;
 
-       conn = talloc_zero(mem_ctx, struct ldap_connection);
-       if (conn == NULL) {
+       if (ev == NULL) {
                return NULL;
        }
 
-       if (ev == NULL) {
-               ev = event_context_init(conn);
-               if (ev == NULL) {
-                       talloc_free(conn);
-                       return NULL;
-               }
+       conn = talloc_zero(mem_ctx, struct ldap_connection);
+       if (conn == NULL) {
+               return NULL;
        }
 
        conn->next_messageid  = 1;
@@ -80,6 +77,12 @@ static void ldap_connection_dead(struct ldap_connection *conn)
 {
        struct ldap_request *req;
 
+       talloc_free(conn->sock);  /* this will also free event.fde */
+       talloc_free(conn->packet);
+       conn->sock = NULL;
+       conn->event.fde = NULL;
+       conn->packet = NULL;
+
        /* return an error for any pending request ... */
        while (conn->pending) {
                req = conn->pending;
@@ -90,12 +93,6 @@ static void ldap_connection_dead(struct ldap_connection *conn)
                        req->async.fn(req);
                }
        }
-
-       talloc_free(conn->sock);  /* this will also free event.fde */
-       talloc_free(conn->packet);
-       conn->sock = NULL;
-       conn->event.fde = NULL;
-       conn->packet = NULL;
 }
 
 static void ldap_reconnect(struct ldap_connection *conn);
@@ -203,7 +200,7 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob)
                return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
        }
        
-       status = ldap_decode(asn1, msg);
+       status = ldap_decode(asn1, samba_ldap_control_handlers(), msg);
        if (!NT_STATUS_IS_OK(status)) {
                asn1_free(asn1);
                return status;
@@ -227,16 +224,16 @@ void ldap_read_io_handler(void *private_data, uint16_t flags)
 /*
   handle ldap socket events
 */
-static void ldap_io_handler(struct event_context *ev, struct fd_event *fde, 
+static void ldap_io_handler(struct tevent_context *ev, struct tevent_fd *fde, 
                            uint16_t flags, void *private_data)
 {
        struct ldap_connection *conn = talloc_get_type(private_data, 
                                                       struct ldap_connection);
-       if (flags & EVENT_FD_WRITE) {
+       if (flags & TEVENT_FD_WRITE) {
                packet_queue_run(conn->packet);
                if (!tls_enabled(conn->sock)) return;
        }
-       if (flags & EVENT_FD_READ) {
+       if (flags & TEVENT_FD_READ) {
                ldap_read_io_handler(private_data, flags);
        }
 }
@@ -292,7 +289,7 @@ struct ldap_connect_state {
 static void ldap_connect_recv_unix_conn(struct composite_context *ctx);
 static void ldap_connect_recv_tcp_conn(struct composite_context *ctx);
 
-struct composite_context *ldap_connect_send(struct ldap_connection *conn,
+_PUBLIC_ struct composite_context *ldap_connect_send(struct ldap_connection *conn,
                                            const char *url)
 {
        struct composite_context *result, *ctx;
@@ -300,7 +297,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn,
        char protocol[11];
        int ret;
 
-       result = talloc_zero(NULL, struct composite_context);
+       result = talloc_zero(conn, struct composite_context);
        if (result == NULL) goto failed;
        result->state = COMPOSITE_STATE_IN_PROGRESS;
        result->async.fn = NULL;
@@ -338,6 +335,14 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn,
                SMB_ASSERT(sizeof(protocol)>10);
                SMB_ASSERT(sizeof(path)>1024);
        
+               /* LDAPI connections are to localhost, so give the
+                * local host name as the target for gensec's
+                * DIGEST-MD5 mechanism */
+               conn->host = talloc_asprintf(conn, "%s.%s", lp_netbios_name(conn->lp_ctx),  lp_realm(conn->lp_ctx));
+               if (composite_nomem(conn->host, state->ctx)) {
+                       return result;
+               }
+
                /* The %c specifier doesn't null terminate :-( */
                ZERO_STRUCT(path);
                ret = sscanf(url, "%10[^:]://%1025c", protocol, path);
@@ -355,7 +360,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn,
                }
 
                ctx = socket_connect_send(conn->sock, NULL, unix_addr, 
-                                         0, lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx);
+                                         0, conn->event.event_ctx);
                ctx->async.fn = ldap_connect_recv_unix_conn;
                ctx->async.private_data = state;
                return result;
@@ -368,7 +373,7 @@ struct composite_context *ldap_connect_send(struct ldap_connection *conn,
                }
                
                ctx = socket_connect_multi_send(state, conn->host, 1, &conn->port,
-                                               lp_name_resolve_order(conn->lp_ctx), conn->event.event_ctx);
+                                               lp_resolve_context(conn->lp_ctx), conn->event.event_ctx);
                if (ctx == NULL) goto failed;
 
                ctx->async.fn = ldap_connect_recv_tcp_conn;
@@ -384,20 +389,21 @@ static void ldap_connect_got_sock(struct composite_context *ctx,
                                  struct ldap_connection *conn) 
 {
        /* setup a handler for events on this socket */
-       conn->event.fde = event_add_fd(conn->event.event_ctx, conn->sock, 
-                                      socket_get_fd(conn->sock), 
-                                      EVENT_FD_READ | EVENT_FD_AUTOCLOSE, ldap_io_handler, conn);
+       conn->event.fde = tevent_add_fd(conn->event.event_ctx, conn->sock,
+                                       socket_get_fd(conn->sock),
+                                       TEVENT_FD_READ, ldap_io_handler, conn);
        if (conn->event.fde == NULL) {
                composite_error(ctx, NT_STATUS_INTERNAL_ERROR);
                return;
        }
 
+       tevent_fd_set_close_fn(conn->event.fde, socket_tevent_fd_close_fn);
        socket_set_flags(conn->sock, SOCKET_FLAG_NOCLOSE);
 
        talloc_steal(conn, conn->sock);
        if (conn->ldaps) {
                struct socket_context *tls_socket;
-               char *cafile = private_path(conn->sock, conn->lp_ctx, lp_tls_cafile(conn->lp_ctx));
+               char *cafile = lp_tls_cafile(conn->sock, conn->lp_ctx);
 
                if (!cafile || !*cafile) {
                        talloc_free(conn->sock);
@@ -411,9 +417,8 @@ static void ldap_connect_got_sock(struct composite_context *ctx,
                        talloc_free(conn->sock);
                        return;
                }
-               talloc_unlink(conn, conn->sock);
-               conn->sock = tls_socket;
-               talloc_steal(conn, conn->sock);
+
+               conn->sock = talloc_steal(conn, tls_socket);
        }
 
        conn->packet = packet_init(conn);
@@ -429,7 +434,11 @@ static void ldap_connect_got_sock(struct composite_context *ctx,
        packet_set_error_handler(conn->packet, ldap_error_handler);
        packet_set_event_context(conn->packet, conn->event.event_ctx);
        packet_set_fde(conn->packet, conn->event.fde);
-       packet_set_serialise(conn->packet);
+/*     packet_set_serialise(conn->packet); */
+
+       if (conn->ldaps) {
+               packet_set_unreliable_select(conn->packet);
+       }
 
        composite_done(ctx);
 }
@@ -475,7 +484,7 @@ _PUBLIC_ NTSTATUS ldap_connect_recv(struct composite_context *ctx)
        return status;
 }
 
-NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url)
+_PUBLIC_ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url)
 {
        struct composite_context *ctx = ldap_connect_send(conn, url);
        return ldap_connect_recv(ctx);
@@ -483,7 +492,7 @@ NTSTATUS ldap_connect(struct ldap_connection *conn, const char *url)
 
 /* set reconnect parameters */
 
-void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries)
+_PUBLIC_ void ldap_set_reconn_params(struct ldap_connection *conn, int max_retries)
 {
        if (conn) {
                conn->reconnect.max_retries = max_retries;
@@ -538,7 +547,7 @@ static int ldap_request_destructor(struct ldap_request *req)
 /*
   called on timeout of a ldap request
 */
-static void ldap_request_timeout(struct event_context *ev, struct timed_event *te, 
+static void ldap_request_timeout(struct tevent_context *ev, struct tevent_timer *te, 
                                      struct timeval t, void *private_data)
 {
        struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
@@ -556,7 +565,7 @@ static void ldap_request_timeout(struct event_context *ev, struct timed_event *t
 /*
   called on completion of a one-way ldap request
 */
-static void ldap_request_complete(struct event_context *ev, struct timed_event *te, 
+static void ldap_request_complete(struct tevent_context *ev, struct tevent_timer *te, 
                                  struct timeval t, void *private_data)
 {
        struct ldap_request *req = talloc_get_type(private_data, struct ldap_request);
@@ -568,7 +577,7 @@ static void ldap_request_complete(struct event_context *ev, struct timed_event *
 /*
   send a ldap message - async interface
 */
-struct ldap_request *ldap_request_send(struct ldap_connection *conn,
+_PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
                                       struct ldap_message *msg)
 {
        struct ldap_request *req;
@@ -597,7 +606,7 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
 
        msg->messageid = req->messageid;
 
-       if (!ldap_encode(msg, &req->data, req)) {
+       if (!ldap_encode(msg, samba_ldap_control_handlers(), &req->data, req)) {
                status = NT_STATUS_INTERNAL_ERROR;
                goto failed;            
        }
@@ -615,8 +624,8 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
                req->state = LDAP_REQUEST_DONE;
                /* we can't call the async callback now, as it isn't setup, so
                   call it as next event */
-               event_add_timed(conn->event.event_ctx, req, timeval_zero(),
-                               ldap_request_complete, req);
+               tevent_add_timer(conn->event.event_ctx, req, timeval_zero(),
+                                ldap_request_complete, req);
                return req;
        }
 
@@ -624,17 +633,17 @@ struct ldap_request *ldap_request_send(struct ldap_connection *conn,
        DLIST_ADD(conn->pending, req);
 
        /* put a timeout on the request */
-       req->time_event = event_add_timed(conn->event.event_ctx, req, 
-                                         timeval_current_ofs(conn->timeout, 0),
-                                         ldap_request_timeout, req);
+       req->time_event = tevent_add_timer(conn->event.event_ctx, req,
+                                          timeval_current_ofs(conn->timeout, 0),
+                                          ldap_request_timeout, req);
 
        return req;
 
 failed:
        req->status = status;
        req->state = LDAP_REQUEST_ERROR;
-       event_add_timed(conn->event.event_ctx, req, timeval_zero(),
-                       ldap_request_complete, req);
+       tevent_add_timer(conn->event.event_ctx, req, timeval_zero(),
+                        ldap_request_complete, req);
 
        return req;
 }
@@ -644,10 +653,10 @@ failed:
   wait for a request to complete
   note that this does not destroy the request
 */
-NTSTATUS ldap_request_wait(struct ldap_request *req)
+_PUBLIC_ NTSTATUS ldap_request_wait(struct ldap_request *req)
 {
        while (req->state < LDAP_REQUEST_DONE) {
-               if (event_loop_once(req->conn->event.event_ctx) != 0) {
+               if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
                        req->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
                        break;
                }
@@ -708,7 +717,7 @@ static const struct {
 /*
   used to setup the status code from a ldap response
 */
-NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r)
+_PUBLIC_ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r)
 {
        int i;
        const char *codename = "unknown";
@@ -741,7 +750,7 @@ NTSTATUS ldap_check_response(struct ldap_connection *conn, struct ldap_Result *r
 /*
   return error string representing the last error
 */
-const char *ldap_errstr(struct ldap_connection *conn, 
+_PUBLIC_ const char *ldap_errstr(struct ldap_connection *conn, 
                        TALLOC_CTX *mem_ctx, 
                        NTSTATUS status)
 {
@@ -755,14 +764,14 @@ const char *ldap_errstr(struct ldap_connection *conn,
 /*
   return the Nth result message, waiting if necessary
 */
-NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg)
+_PUBLIC_ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **msg)
 {
        *msg = NULL;
 
        NT_STATUS_HAVE_NO_MEMORY(req);
 
        while (req->state < LDAP_REQUEST_DONE && n >= req->num_replies) {
-               if (event_loop_once(req->conn->event.event_ctx) != 0) {
+               if (tevent_loop_once(req->conn->event.event_ctx) != 0) {
                        return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
                }
        }
@@ -783,7 +792,7 @@ NTSTATUS ldap_result_n(struct ldap_request *req, int n, struct ldap_message **ms
 /*
   return a single result message, checking if it is of the expected LDAP type
 */
-NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type)
+_PUBLIC_ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, int type)
 {
        NTSTATUS status;
        status = ldap_result_n(req, 0, msg);
@@ -801,7 +810,7 @@ NTSTATUS ldap_result_one(struct ldap_request *req, struct ldap_message **msg, in
   a simple ldap transaction, for single result requests that only need a status code
   this relies on single valued requests having the response type == request type + 1
 */
-NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg)
+_PUBLIC_ NTSTATUS ldap_transaction(struct ldap_connection *conn, struct ldap_message *msg)
 {
        struct ldap_request *req = ldap_request_send(conn, msg);
        struct ldap_message *res;