summaryrefslogtreecommitdiff
path: root/usr/src/lib/libldap4/common/open.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libldap4/common/open.c
downloadillumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libldap4/common/open.c')
-rw-r--r--usr/src/lib/libldap4/common/open.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/usr/src/lib/libldap4/common/open.c b/usr/src/lib/libldap4/common/open.c
new file mode 100644
index 0000000000..78211659f2
--- /dev/null
+++ b/usr/src/lib/libldap4/common/open.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 1995-2001 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Copyright (c) 1995 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * open.c
+ */
+
+#ifndef lint
+static char copyright[] = "@(#) Copyright (c) 1995 Regents of the "
+ "University of Michigan.\nAll rights reserved.\n";
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h> /* calloc(), free(), atoi() for Solaris */
+#include <locale.h>
+#include <thread.h>
+
+#ifdef MACOS
+#include <stdlib.h>
+#include "macos.h"
+#endif /* MACOS */
+
+#if defined(DOS) || defined(_WIN32)
+#include "msdos.h"
+#include <stdlib.h>
+#endif /* DOS */
+
+#if !defined(MACOS) && !defined(DOS) && !defined(_WIN32)
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifndef VMS
+#include <sys/param.h>
+#endif
+#include <netinet/in.h>
+#endif
+#include "lber.h"
+#include "ldap.h"
+#include "ldap-private.h"
+#include "ldap-int.h"
+
+#ifdef LDAP_DEBUG
+int ldap_debug;
+#endif
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK ((unsigned int) 0x7f000001)
+#endif
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 64
+#endif
+
+extern int thr_kill(thread_t, int);
+
+/*
+ * ldap_open - initialize and connect to an ldap server. A magic cookie to
+ * be used for future communication is returned on success, NULL on failure.
+ * "host" may be a space-separated list of hosts or IP addresses
+ *
+ * Example:
+ * LDAP *ld;
+ * ld = ldap_open( hostname, port );
+ */
+
+LDAP *
+ldap_open(char *host, int port)
+{
+ LDAP *ld;
+ int err;
+
+ if ((ld = ldap_init(host, port)) == NULL) {
+ return (NULL);
+ }
+
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 113,
+ "ldap_open (after ldap_init)\n"), 0, 0, 0);
+
+#ifdef _REENTRANT
+ LOCK_LDAP(ld);
+#endif
+ if ((err = open_default_ldap_connection(ld)) != LDAP_SUCCESS) {
+#ifdef _REENTRANT
+ UNLOCK_LDAP(ld);
+#endif
+ ldap_ld_free(ld, 0);
+ Debug(LDAP_DEBUG_ANY, catgets(slapdcat, 1, 1275,
+ "ldap_open failed, %s\n"),
+ ldap_err2string(err), 0, 0);
+ return (NULL);
+ }
+
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 194,
+ "ldap_open successful, ld_host is %s\n"),
+ (ld->ld_host == NULL) ? "(null)" : ld->ld_host, 0, 0);
+#ifdef _REENTRANT
+ UNLOCK_LDAP(ld);
+#endif
+ return (ld);
+
+}
+
+/*
+ * Open the default connection
+ * ld->ld_defconn MUST be null when calling this function,
+ * ie the connection was never established
+ * ld should be LOCKed before calling this function
+ */
+int
+open_default_ldap_connection(LDAP *ld)
+{
+ LDAPServer *srv;
+ int err;
+
+ if ((srv = (LDAPServer *)calloc(1, sizeof (LDAPServer))) ==
+ NULL || (ld->ld_defhost != NULL && (srv->lsrv_host =
+ strdup(ld->ld_defhost)) == NULL)) {
+ return (LDAP_NO_MEMORY);
+ }
+ srv->lsrv_port = ld->ld_defport;
+
+ if ((ld->ld_defconn = new_connection(ld, &srv, 1, 1, 0)) ==
+ NULL) {
+ err = ld->ld_errno;
+ Debug(LDAP_DEBUG_ANY, catgets(slapdcat, 1, 1276,
+ "Default connection to ldap server %s couldn't be "
+ "opened (%d)\n"), ld->ld_defhost, err, 0);
+
+ if (ld->ld_defhost != NULL)
+ free(srv->lsrv_host);
+ free((char *)srv);
+ return (err);
+ }
+
+ /* so it never gets closed/freed */
+ ++ld->ld_defconn->lconn_refcnt;
+
+ return (LDAP_SUCCESS);
+}
+
+static pthread_mutex_t ldap_thr_index_mutex = {0};
+static pthread_t ldap_thr_table[MAX_THREAD_ID] = {0};
+
+int
+ldap_thr_index()
+{
+ int i = 0;
+ int free = 0;
+ pthread_t cur = thr_self();
+ for (i = 1; i < MAX_THREAD_ID; ++i) {
+ if (ldap_thr_table[i] == cur) {
+ return (i);
+ } /* end if */
+ } /* end for */
+ /*
+ * not in the table, allocate a new entry
+ */
+ pthread_mutex_lock(&ldap_thr_index_mutex);
+ for (i = 1; i < MAX_THREAD_ID; ++i) {
+ if (ldap_thr_table[i] == 0 ||
+ thr_kill(ldap_thr_table[i], 0) != 0) {
+ ldap_thr_table[i] = cur;
+ pthread_mutex_unlock(&ldap_thr_index_mutex);
+ return (i);
+ } /* end if */
+ } /* end for */
+ pthread_mutex_unlock(&ldap_thr_index_mutex);
+ /* if table is full, return the first entry, so that it */
+ /* doesn't core dump */
+ return (0);
+}
+
+/*
+ * ldap_init - initialize the LDAP library. A magic cookie to be used for
+ * future communication is returned on success, NULL on failure.
+ * "defhost" may be a space-separated list of hosts or IP addresses
+ *
+ * Example:
+ * LDAP *ld;
+ * ld = ldap_init( default_hostname, default_port );
+ */
+LDAP *
+ldap_init(char *defhost, int defport)
+{
+ LDAP *ld;
+ char *locale;
+
+ locale = setlocale(LC_ALL, "");
+ i18n_catopen("sdserver");
+
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 195,
+ "ldap_init\n"), 0, 0, 0);
+
+
+ if ((ld = (LDAP *) calloc(1, sizeof (LDAP))) == NULL) {
+ return (NULL);
+ }
+
+#ifdef _REENTRANT
+ pthread_mutex_init(&ld->ld_ldap_mutex, DEFAULT_TYPE);
+ pthread_mutex_init(&ld->ld_response_mutex, DEFAULT_TYPE);
+ pthread_mutex_init(&ld->ld_poll_mutex, DEFAULT_TYPE);
+ ld->ld_lockthread = 0;
+#endif
+
+ if ((ld->ld_selectinfo = new_select_info()) == NULL) {
+ free((char *)ld);
+ return (NULL);
+ }
+ ld->ld_follow_referral = 1;
+
+ /*
+ * default to localhost when hostname is not specified
+ * or if null string is passed as hostname
+ */
+
+ if ((defhost != NULL) && (*defhost != NULL) &&
+ (ld->ld_defhost = strdup(defhost)) == NULL) {
+ free_select_info(ld->ld_selectinfo);
+ free((char *)ld);
+ return (NULL);
+ }
+
+ ld->ld_defport = (defport == 0) ? LDAP_PORT : defport;
+ ld->ld_version = LDAP_VERSION;
+ ld->ld_lberoptions = LBER_USE_DER;
+ ld->ld_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
+ ld->ld_connect_timeout = LDAP_X_IO_TIMEOUT_NO_TIMEOUT;
+
+#if defined(STR_TRANSLATION) && defined(LDAP_DEFAULT_CHARSET)
+ ld->ld_lberoptions |= LBER_TRANSLATE_STRINGS;
+#if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET
+ ldap_set_string_translators(ld, ldap_8859_to_t61,
+ ldap_t61_to_8859);
+#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
+#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
+
+ return (ld);
+}
+
+
+/* ARGSUSED */
+int
+open_ldap_connection(LDAP *ld, Sockbuf *sb, char *host, int defport,
+ char **krbinstancep, int async)
+{
+ int rc, port;
+ char *p, *q, *r;
+ char *curhost, hostname[ 2*MAXHOSTNAMELEN ];
+ int bindTimeout;
+
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 196,
+ "open_ldap_connection\n"), 0, 0, 0);
+
+ defport = htons(defport);
+ bindTimeout = ld->ld_connect_timeout;
+
+ if (host != NULL) {
+ for (p = host; p != NULL && *p != '\0'; p = q) {
+ if ((q = strchr(p, ' ')) != NULL) {
+ (void) strncpy(hostname, p, q - p);
+ hostname[ q - p ] = '\0';
+ curhost = hostname;
+ while (*q == ' ') {
+ ++q;
+ }
+ } else {
+ /* avoid copy if possible */
+ curhost = p;
+ q = NULL;
+ }
+
+ if ((r = strchr(curhost, ':')) != NULL) {
+ if (curhost != hostname) {
+ /* now copy */
+ (void) strcpy(hostname, curhost);
+ r = hostname + (r - curhost);
+ curhost = hostname;
+ }
+ *r++ = '\0';
+ port = htons((short)atoi(r));
+ } else {
+ port = defport;
+ }
+
+ if ((rc = connect_to_host(sb, curhost, 0,
+ port, async, bindTimeout)) != -1) {
+ break;
+ }
+ }
+ } else {
+ rc = connect_to_host(sb, NULL, htonl(INADDR_LOOPBACK),
+ defport, async, bindTimeout);
+ }
+
+ if (rc == -1) {
+ return (rc);
+ }
+
+ if (krbinstancep != NULL) {
+#ifdef KERBEROS
+ if ((*krbinstancep = host_connected_to(sb)) != NULL &&
+ (p = strchr(*krbinstancep, '.')) != NULL) {
+ *p = '\0';
+ }
+#else /* KERBEROS */
+ krbinstancep = NULL;
+#endif /* KERBEROS */
+ }
+
+ return (0);
+}
+
+/*
+ * ldap_ssl_open - initialize and connect to an ssl secured ldap
+ * server. First ldap_open() is called and then ssl is layered on top
+ * of the socket. A magic cookie to be used for future communication
+ * is returned on success, NULL on failure. "host" may be a
+ * space-separated list of hosts or IP addresses. CAfile and CApath
+ * are used first time through, subsequent calls are ignored and can
+ * be NULL.
+ *
+ * Example:
+ * LDAP *ld;
+ * ld = ldap_ssl_open( hostname, port, key );
+ */
+
+#ifdef LDAP_SSL
+
+#include "security/ssl.h"
+
+int
+establish_ssl_connection(LDAP *ld)
+{
+ SSL *ssl = NULL; /* The Client's SSL connection */
+
+ /*
+ * Creates a new SSL connection. This holds information
+ * pertinent to this
+ * connection.
+ */
+ if ((ssl = SSL_new()) == NULL) {
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 198,
+ "SSL_new() failed: %s\n"),
+ SSL_strerr(SSL_errno(ssl)), 0, 0);
+ return (-1);
+ }
+
+ /* if keyname is non-null, set ssl keypackage name from it */
+ if (ld->ld_ssl_key != NULL) {
+ if (SSL_set_userid(ssl, ld->ld_ssl_key, 0) == NULL) {
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1,
+ 199, "SSL_set_userid() failed: %s\n"),
+ SSL_strerr(SSL_errno(ssl)), 0, 0);
+ return (-1);
+ }
+ }
+
+ /* Start the SSL connection */
+ if (SSL_connect(ssl, ld->ld_sb.sb_sd) < 1) {
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 200,
+ "SSL_connect() failed: %s\n"),
+ SSL_strerr(SSL_errno(ssl)), 0, 0);
+ return (-1);
+ }
+
+ ld->ld_sb.sb_ssl = ssl;
+ return (0);
+}
+
+
+LDAP *
+ldap_ssl_open(char *host, int port, char *keyname)
+{
+ LDAP *ld;
+ int rval;
+
+
+ if (port == 0)
+ port = SSL_LDAP_PORT;
+
+ ld = ldap_open(host, port);
+
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 197,
+ "ldap_ssl_open (after ldap_open)\n"), 0, 0, 0);
+
+ if (ld == NULL)
+ return (NULL);
+
+ ld->ld_use_ssl = 1;
+ if (keyname)
+ ld->ld_ssl_key = strdup(keyname);
+
+ if (establish_ssl_connection(ld) != 0) {
+ ldap_ld_free(ld, 1);
+ return (NULL);
+ }
+
+ return (ld);
+}
+
+LDAP *
+ldap_ssl_init(char *defhost, int defport, char *keyname)
+{
+ LDAP *ld;
+ int rval;
+
+
+ if (defport == 0)
+ defport = SSL_LDAP_PORT;
+
+ ld = ldap_init(defhost, defport);
+
+ Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 197,
+ "ldap_ssl_open (after ldap_open)\n"), 0, 0, 0);
+
+ if (ld == NULL)
+ return (NULL);
+ ld->ld_use_ssl = 1;
+ ld->ld_ssl_key = strdup(keyname);
+
+ return (ld);
+}
+
+#endif /* LDAP_SSL */