summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-02-04 11:53:36 +0100
committerStephen Gallagher <sgallagh@redhat.com>2010-02-05 09:43:43 -0500
commitc12530bed53c51bcf217624ad523ef2b6ddd16c0 (patch)
treebafea5bcfa48ded5de18d8a893632a4f907d7de5
parent764d6246eea5a63b203a5dc6c905b5938d9b62e4 (diff)
downloadsssd-c12530bed53c51bcf217624ad523ef2b6ddd16c0.tar.gz
sssd-c12530bed53c51bcf217624ad523ef2b6ddd16c0.tar.bz2
sssd-c12530bed53c51bcf217624ad523ef2b6ddd16c0.zip
Reactivate old fd handling conditionally
Older versions of openLDAP do not provide a connection callback. This patch adds a configure check to see if the callback is available and activates the old way of handling the file description of the LDAP connection. This also means that it is not possible to follow referrals.
-rw-r--r--server/external/ldap.m44
-rw-r--r--server/providers/ldap/sdap.h4
-rw-r--r--server/providers/ldap/sdap_async.c44
-rw-r--r--server/providers/ldap/sdap_async_connection.c25
-rw-r--r--server/providers/ldap/sdap_async_private.h6
5 files changed, 82 insertions, 1 deletions
diff --git a/server/external/ldap.m4 b/server/external/ldap.m4
index a17ed7e9..ee425d83 100644
--- a/server/external/ldap.m4
+++ b/server/external/ldap.m4
@@ -44,6 +44,10 @@ SAVE_LIBS=$LIBS
CFLAGS="$CFLAGS $OPENLDAP_CFLAGS"
LIBS="$LIBS $OPENLDAP_LIBS"
AC_CHECK_FUNCS([ldap_control_create])
+AC_CHECK_MEMBERS([struct ldap_conncb.lc_arg],
+ [AC_DEFINE([HAVE_LDAP_CONNCB], [1],
+ [Define if LDAP connection callbacks are available])],
+ [], [[#include <ldap.h>]])
CFLAGS=$SAVE_CFLAGS
LIBS=$SAVE_LIBS
diff --git a/server/providers/ldap/sdap.h b/server/providers/ldap/sdap.h
index f32ce050..16dbb784 100644
--- a/server/providers/ldap/sdap.h
+++ b/server/providers/ldap/sdap.h
@@ -71,7 +71,11 @@ struct sdap_handle {
LDAP *ldap;
bool connected;
+#ifdef HAVE_LDAP_CONNCB
struct ldap_conncb *conncb;
+#else
+ struct tevent_fd *fde;
+#endif
struct sdap_op *ops;
};
diff --git a/server/providers/ldap/sdap_async.c b/server/providers/ldap/sdap_async.c
index fd8c11e0..88f1c4be 100644
--- a/server/providers/ldap/sdap_async.c
+++ b/server/providers/ldap/sdap_async.c
@@ -97,8 +97,12 @@ static void sdap_handle_release(struct sdap_handle *sh)
if (sh->connected) {
struct sdap_op *op;
+#ifdef HAVE_LDAP_CONNCB
/* remove all related fd events from the event loop */
talloc_zfree(sh->conncb->lc_arg);
+#else
+ talloc_zfree(sh->fde);
+#endif
while (sh->ops) {
op = sh->ops;
@@ -111,7 +115,9 @@ static void sdap_handle_release(struct sdap_handle *sh)
if (sh->ldap) {
ldap_unbind_ext(sh->ldap, NULL, NULL);
}
+#ifdef HAVE_LDAP_CONNCB
talloc_zfree(sh->conncb);
+#endif
sh->connected = false;
sh->ldap = NULL;
sh->ops = NULL;
@@ -330,6 +336,7 @@ static void sdap_process_next_reply(struct tevent_context *ev,
op->callback(op, op->list, EOK, op->data);
}
+#ifdef HAVE_LDAP_CONNCB
int sdap_ldap_connect_callback_add(LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
struct sockaddr *addr, struct ldap_conncb *ctx)
{
@@ -404,6 +411,43 @@ void sdap_ldap_connect_callback_del(LDAP *ld, Sockbuf *sb,
return;
}
+#else
+
+static int get_fd_from_ldap(LDAP *ldap, int *fd)
+{
+ int ret;
+
+ ret = ldap_get_option(ldap, LDAP_OPT_DESC, fd);
+ if (ret != LDAP_OPT_SUCCESS) {
+ DEBUG(1, ("Failed to get fd from ldap!!\n"));
+ *fd = -1;
+ return EIO;
+ }
+
+ return EOK;
+}
+
+int sdap_install_ldap_callbacks(struct sdap_handle *sh,
+ struct tevent_context *ev)
+{
+ int fd;
+ int ret;
+
+ ret = get_fd_from_ldap(sh->ldap, &fd);
+ if (ret) return ret;
+
+ sh->fde = tevent_add_fd(ev, sh, fd, TEVENT_FD_READ, sdap_ldap_result, sh);
+ if (!sh->fde) return ENOMEM;
+
+ DEBUG(8, ("Trace: sh[%p], connected[%d], ops[%p], fde[%p], ldap[%p]\n",
+ sh, (int)sh->connected, sh->ops, sh->fde, sh->ldap));
+
+ return EOK;
+}
+
+#endif
+
+
/* ==LDAP-Operations-Helpers============================================== */
static int sdap_op_destructor(void *mem)
diff --git a/server/providers/ldap/sdap_async_connection.c b/server/providers/ldap/sdap_async_connection.c
index 1ed6b3f8..18e47d3b 100644
--- a/server/providers/ldap/sdap_async_connection.c
+++ b/server/providers/ldap/sdap_async_connection.c
@@ -56,7 +56,6 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
int lret;
int ret = EOK;
int msgid;
- struct ldap_cb_data *cb_data;
bool ldap_referrals;
req = tevent_req_create(memctx, &state, struct sdap_connect_state);
@@ -120,6 +119,9 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
goto fail;
}
+#ifdef HAVE_LDAP_CONNCB
+ struct ldap_cb_data *cb_data;
+
/* add connection callback */
state->sh->conncb = talloc_zero(state->sh, struct ldap_conncb);
if (state->sh->conncb == NULL) {
@@ -147,6 +149,7 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
DEBUG(1, ("Failed to set connection callback\n"));
goto fail;
}
+#endif
/* if we do not use start_tls the connection is not really connected yet
* just fake an async procedure and leave connection to the bind call */
@@ -164,6 +167,10 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
}
state->sh->connected = true;
+#ifndef HAVE_LDAP_CONNCB
+ ret = sdap_install_ldap_callbacks(state->sh, state->ev);
+ if (ret) goto fail;
+#endif
/* FIXME: get timeouts from configuration, for now 5 secs. */
ret = sdap_op_add(state, ev, state->sh, msgid,
@@ -335,6 +342,10 @@ static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
if (!sh->connected) {
sh->connected = true;
+#ifndef HAVE_LDAP_CONNCB
+ ret = sdap_install_ldap_callbacks(sh, ev);
+ if (ret) goto fail;
+#endif
}
/* FIXME: get timeouts from configuration, for now 5 secs. */
@@ -500,6 +511,10 @@ static struct tevent_req *sasl_bind_send(TALLOC_CTX *memctx,
if (!sh->connected) {
sh->connected = true;
+#ifndef HAVE_LDAP_CONNCB
+ ret = sdap_install_ldap_callbacks(sh, ev);
+ if (ret) goto fail;
+#endif
}
tevent_req_post(req, ev);
@@ -936,6 +951,14 @@ static void sdap_cli_rootdse_step(struct tevent_req *req)
* so we need to set up the callbacks or we will never get notified
* of a reply */
state->sh->connected = true;
+#ifndef HAVE_LDAP_CONNCB
+ int ret;
+
+ ret = sdap_install_ldap_callbacks(state->sh, state->ev);
+ if (ret) {
+ tevent_req_error(req, ret);
+ }
+#endif
}
}
diff --git a/server/providers/ldap/sdap_async_private.h b/server/providers/ldap/sdap_async_private.h
index 5549626a..55f76ed7 100644
--- a/server/providers/ldap/sdap_async_private.h
+++ b/server/providers/ldap/sdap_async_private.h
@@ -22,15 +22,21 @@
#ifndef _SDAP_ASYNC_PRIVATE_H_
#define _SDAP_ASYNC_PRIVATE_H_
+#include "config.h"
#include "providers/ldap/sdap_async.h"
void make_realm_upper_case(const char *upn);
struct sdap_handle *sdap_handle_create(TALLOC_CTX *memctx);
+#ifdef HAVE_LDAP_CONNCB
int sdap_ldap_connect_callback_add(LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
struct sockaddr *addr, struct ldap_conncb *ctx);
void sdap_ldap_connect_callback_del(LDAP *ld, Sockbuf *sb,
struct ldap_conncb *ctx);
+#else
+int sdap_install_ldap_callbacks(struct sdap_handle *sh,
+ struct tevent_context *ev);
+#endif
int sdap_op_add(TALLOC_CTX *memctx, struct tevent_context *ev,
struct sdap_handle *sh, int msgid,