summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2011-04-26 13:53:45 +1000
committerAndrew Bartlett <abartlet@samba.org>2011-04-28 05:30:21 +0200
commita427652010820fdf8fa82cf425f5162cc70348e0 (patch)
tree640a2539c113d6b508e4cdd4aea15d512da9c580
parentab46d6610104b899ca8ac7cb695d8d18e5dc34ed (diff)
downloadsamba-a427652010820fdf8fa82cf425f5162cc70348e0.tar.gz
samba-a427652010820fdf8fa82cf425f5162cc70348e0.tar.bz2
samba-a427652010820fdf8fa82cf425f5162cc70348e0.zip
s3-libads: Use ldap_init_fd() to connect to AD server in socket_wrapper
This means that we control the connection setup, don't rely on signals for timeouts and the connection uses socket_wrapper where that is required in our test environment. According to bug reports, this method is also used by curl and other tools, so we are not the first to (ab)use the OpenLDAP libs in this way. It is ONLY enabled for socket_wrapper at this time, as this is the best way to get 'make test' working for S3 winbind tests in an S4 domain. Andrew Bartlett
-rw-r--r--source3/include/smb_ldap.h9
-rw-r--r--source3/libads/ldap.c36
-rw-r--r--source3/winbindd/winbindd_msrpc.c6
-rw-r--r--source3/wscript4
4 files changed, 48 insertions, 7 deletions
diff --git a/source3/include/smb_ldap.h b/source3/include/smb_ldap.h
index 45e586859d..7165de19bf 100644
--- a/source3/include/smb_ldap.h
+++ b/source3/include/smb_ldap.h
@@ -37,7 +37,14 @@ typedef int ber_int_t;
#endif
/* function declarations not included in proto.h */
-LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to);
+LDAP *ldap_open_with_timeout(const char *server,
+ struct sockaddr_storage *ss,
+ int port, unsigned int to);
+
+#ifdef HAVE_LDAP_PVT_H
+#include <ldap_pvt.h>
+#endif
+int ldap_init_fd(ber_socket_t fd, int proto, char *uri, LDAP **ldp);
#endif /* HAVE_LDAP_H */
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 793b689361..eff851047e 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -59,14 +59,47 @@ static void gotalarm_sig(int signum)
gotalarm = 1;
}
- LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
+ LDAP *ldap_open_with_timeout(const char *server,
+ struct sockaddr_storage *ss,
+ int port, unsigned int to)
{
LDAP *ldp = NULL;
+ int fd, ldap_err;
+ NTSTATUS status;
+ char *uri;
DEBUG(10, ("Opening connection to LDAP server '%s:%d', timeout "
"%u seconds\n", server, port, to));
+#if defined(HAVE_LDAP_INIT_FD) && defined(SOCKET_WRAPPER)
+ /* Only use this private LDAP function if we are in make test,
+ * as this is the best way to get the emulated TCP socket into
+ * OpenLDAP */
+ if (socket_wrapper_dir() != NULL) {
+ status = open_socket_out(ss, port, to, &fd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return NULL;
+ }
+
+#ifndef LDAP_PROTO_TCP
+#define LDAP_PROTO_TCP 1
+#endif
+ uri = talloc_asprintf(talloc_tos(), "ldap://%s:%u", server, port);
+ if (uri == NULL) {
+ return NULL;
+ }
+ ldap_err = ldap_init_fd(fd, LDAP_PROTO_TCP, uri, &ldp);
+ talloc_free(uri);
+
+ if (ldap_err != LDAP_SUCCESS) {
+ return NULL;
+ }
+ return ldp;
+ }
+#endif
+
/* Setup timeout */
gotalarm = 0;
CatchSignal(SIGALRM, gotalarm_sig);
@@ -655,6 +688,7 @@ got_connection:
/* Otherwise setup the TCP LDAP session */
ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
+ &ads->ldap.ss,
ads->ldap.port, lp_ldap_timeout());
if (ads->ldap.ld == NULL) {
status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
diff --git a/source3/winbindd/winbindd_msrpc.c b/source3/winbindd/winbindd_msrpc.c
index 921cdb5a8b..1f8b398fd0 100644
--- a/source3/winbindd/winbindd_msrpc.c
+++ b/source3/winbindd/winbindd_msrpc.c
@@ -762,7 +762,7 @@ static NTSTATUS msrpc_lookup_groupmem(struct winbindd_domain *domain,
#include <ldap.h>
-static int get_ldap_seq(const char *server, int port, uint32 *seq)
+static int get_ldap_seq(const char *server, struct sockaddr_storage *ss, int port, uint32 *seq)
{
int ret = -1;
struct timeval to;
@@ -778,7 +778,7 @@ static int get_ldap_seq(const char *server, int port, uint32 *seq)
* search timeout doesn't seem to apply to doing an open as well. JRA.
*/
- ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
+ ldp = ldap_open_with_timeout(server, ss, port, lp_ldap_timeout());
if (ldp == NULL)
return -1;
@@ -822,7 +822,7 @@ static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
char addr[INET6_ADDRSTRLEN];
print_sockaddr(addr, sizeof(addr), &domain->dcaddr);
- if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {
+ if ((ret = get_ldap_seq(addr, &domain->dcaddr, LDAP_PORT, seq)) == 0) {
DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
"number for Domain (%s) from DC (%s)\n",
domain->name, addr));
diff --git a/source3/wscript b/source3/wscript
index 7f178a4c55..175bbf12ef 100644
--- a/source3/wscript
+++ b/source3/wscript
@@ -574,7 +574,7 @@ msg.msg_acctrightslen = sizeof(fd);
# Check for LDAP
if Options.options.with_ldap:
- conf.CHECK_HEADERS('ldap.h lber.h')
+ conf.CHECK_HEADERS('ldap.h lber.h ldap_pvt.h')
conf.CHECK_TYPE('ber_tag_t', 'unsigned int', headers='ldap.h lber.h')
conf.CHECK_FUNCS_IN('ber_scanf ber_sockbuf_add_io', 'lber')
conf.CHECK_VARIABLE('LDAP_OPT_SOCKBUF', headers='ldap.h')
@@ -584,7 +584,7 @@ msg.msg_acctrightslen = sizeof(fd);
conf.CHECK_VARIABLE('LBER_OPT_LOG_PRINT_FN',
define='HAVE_LBER_LOG_PRINT_FN', headers='lber.h')
- conf.CHECK_FUNCS_IN('ldap_init ldap_initialize ldap_set_rebind_proc', 'ldap')
+ conf.CHECK_FUNCS_IN('ldap_init ldap_init_fd ldap_initialize ldap_set_rebind_proc', 'ldap')
conf.CHECK_FUNCS_IN('ldap_add_result_entry', 'ldap')
# Check if ldap_set_rebind_proc() takes three arguments