* Merge LDAP code; bindings are not yet complete
authorArt Cancro <ajc@citadel.org>
Wed, 8 Apr 2009 17:24:14 +0000 (17:24 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 8 Apr 2009 17:24:14 +0000 (17:24 +0000)
citadel/Makefile.in
citadel/citadel_ldap.h [new file with mode: 0644]
citadel/citserver.c
citadel/config.c
citadel/ldap.c [new file with mode: 0644]
citadel/server.h
citadel/user_ops.c

index 792432b0f01472f73f5d21d51dca65309b4be115..8b227a0faaecb803201765c60322df9a44db888c 100644 (file)
@@ -74,17 +74,14 @@ SOURCES=aidepost.c auth.c base64.c chkpwd.c chkpw.c citadel.c citadel_ipc.c \
        citmail.c citserver.c client_chat.c client_passwords.c \
        clientsocket.c commands.c config.c control.c $(DATABASE) \
        domain.c serv_extensions.c file_ops.c genstamp.c getutline.c \
-       housekeeping.c ical_dezonify.c \
-       internet_addressing.c ecrash.c \
+       housekeeping.c ical_dezonify.c internet_addressing.c ecrash.c \
        ipc_c_tcp.c locate_host.c md5.c messages.c  \
        msgbase.c msgform.c parsedate.c policy.c \
        room_ops.c rooms.c routines.c routines2.c tuiconfig.c euidindex.c \
        screen.c sendcommand.c getmail.c \
-       server_main.c \
-       setup.c snprintf.c \
+       server_main.c setup.c snprintf.c ldap.c \
        stress.c support.c sysdep.c user_ops.c userlist.c \
-       whobbs.c \
-       journaling.c citadel_dirs.c threads.c
+       whobbs.c journaling.c citadel_dirs.c threads.c
 
 
 include Make_sources
@@ -133,7 +130,7 @@ SERV_OBJS = server_main.o \
        internet_addressing.o journaling.o \
        parsedate.o genstamp.o ecrash.o threads.o\
        clientsocket.o modules_init.o modules_upgrade.o $(AUTH) $(SERV_MODULES) \
-       svn_revision.o
+       svn_revision.o ldap.o
 
 citserver$(EXEEXT): $(SERV_OBJS)
        $(CC) $(SERV_OBJS) $(LDFLAGS) $(SERVER_LDFLAGS) $(LIBS) $(SERVER_LIBS) $(RESOLV) -o citserver$(EXEEXT)
diff --git a/citadel/citadel_ldap.h b/citadel/citadel_ldap.h
new file mode 100644 (file)
index 0000000..0009c00
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ * 
+ */
+
+#define CTDL_LDAP_HOST "ldaptest.xand.com"
+#define CTDL_LDAP_PORT LDAP_PORT               /* defined as 389 */
+#define BASE_DN                "dc=xand,dc=com"
+#define BIND_DN                NULL                    /* "cn=Manager,dc=xand,dc=com" for authenticated bind */
+#define BIND_PW                NULL                    /* put pw here for authenticated bind */
+#define SEARCH_STRING  "(&(objectclass=posixAccount)(uid=%s))"
+
+int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size);
+int CtdlTryPasswordLDAP(char *user_dn, char *password);
index 4e65fd6da1cbaf51b376e3c477f1c41f1eee530e..f127449d434ffd3f085506d936827993f9a65dec 100644 (file)
@@ -262,6 +262,12 @@ void RemoveContext (struct CitContext *con)
        CtdlLogPrintf(CTDL_DEBUG, "Closing socket %d\n", con->client_socket);
        close(con->client_socket);
 
+       /* If using AUTHMODE_LDAP, free the DN */
+       if (con->ldap_dn) {
+               free(con->ldap_dn);
+               con->ldap_dn = NULL;
+       }
+
        CtdlLogPrintf(CTDL_DEBUG, "Done with RemoveContext()\n");
 }
 
index 948f030052f7e2d7ddba5512b9850889fc46019a..b33e04142d9e6f5d40e58c9c0b53c206dcfc87e2 100644 (file)
@@ -1,8 +1,7 @@
 /*
  * $Id$
  *
- * This function reads the citadel.config file.  It should be called at
- * the beginning of EVERY Citadel program.
+ * Read and write the citadel.config file
  *
  */
 
diff --git a/citadel/ldap.c b/citadel/ldap.c
new file mode 100644 (file)
index 0000000..10eb31b
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * 
+ */
+
+
+int ldap_version = 3;
+
+#ifdef HAVE_LDAP
+
+#include "sysdep.h"
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <pwd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#include <string.h>
+#include <limits.h>
+#include <libcitadel.h>
+#include "auth.h"
+#include "citadel.h"
+#include "server.h"
+#include "database.h"
+#include "user_ops.h"
+#include "sysdep_decls.h"
+#include "support.h"
+#include "room_ops.h"
+#include "file_ops.h"
+#include "control.h"
+#include "msgbase.h"
+#include "config.h"
+#include "citserver.h"
+#include "citadel_dirs.h"
+#include "genstamp.h"
+#include "threads.h"
+#include "citadel_ldap.h"
+
+#define LDAP_DEPRECATED 1      /* Needed to suppress misleading warnings */
+
+#include <ldap.h>
+
+int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size)
+{
+       LDAP *ldserver = NULL;
+       int i;
+       LDAPMessage *search_result = NULL;
+       LDAPMessage *entry = NULL;
+       char searchstring[1024];
+       struct timeval tv;
+       char **values;
+       char *user_dn = NULL;
+
+       safestrncpy(fullname, username, fullname_size);
+
+       ldserver = ldap_init(CTDL_LDAP_HOST, CTDL_LDAP_PORT);
+       if (ldserver == NULL) {
+               CtdlLogPrintf(CTDL_ALERT, "LDAP: Could not connect to %s:%d : %s\n",
+                       CTDL_LDAP_HOST, CTDL_LDAP_PORT,
+                       strerror(errno));
+               return(errno);
+       }
+
+       ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
+
+       i = ldap_simple_bind_s(ldserver, BIND_DN, BIND_PW);
+       if (i != LDAP_SUCCESS) {
+               CtdlLogPrintf(CTDL_ALERT, "LDAP: Cannot bind: %s (%d)\n", ldap_err2string(i), i);
+               return(i);
+       }
+
+       tv.tv_sec = 10;
+       tv.tv_usec = 0;
+
+       sprintf(searchstring, SEARCH_STRING, username);
+
+       i = ldap_search_st(ldserver,
+               BASE_DN,
+               LDAP_SCOPE_SUBTREE,
+               searchstring,
+               NULL,   // return all attributes
+               0,      // attributes + values
+               &tv,    // timeout
+               &search_result
+       );
+       if (i != LDAP_SUCCESS) {
+               CtdlLogPrintf(CTDL_DEBUG,
+                       "Couldn't find what I was looking for: %s (%d)\n", ldap_err2string(i), i);
+               ldap_unbind(ldserver);
+               return(i);
+       }
+
+       if (search_result == NULL) {
+               CtdlLogPrintf(CTDL_DEBUG, "No results were returned\n");
+               ldap_unbind(ldserver);
+               return(2);
+       }
+
+       /* At this point we've got at least one result from our query.  If there are multiple
+        * results, we still only look at the first one.
+        */
+       entry = ldap_first_entry(ldserver, search_result);
+       if (entry) {
+
+               user_dn = ldap_get_dn(ldserver, entry);
+               if (user_dn) {
+                       CtdlLogPrintf(CTDL_DEBUG, "dn = %s\n", user_dn);
+               }
+
+               values = ldap_get_values(ldserver, search_result, "cn");
+               if (values) {
+                       if (values[0]) {
+                               safestrncpy(fullname, values[0], fullname_size);
+                               CtdlLogPrintf(CTDL_DEBUG, "cn = %s\n", values[0]);
+                       }
+                       ldap_value_free(values);
+               }
+
+               values = ldap_get_values(ldserver, search_result, "uidNumber");
+               if (values) {
+                       if (values[0]) {
+                               CtdlLogPrintf(CTDL_DEBUG, "uidNumber = %s\n", values[0]);
+                       }
+                       ldap_value_free(values);
+               }
+
+               values = ldap_get_values(ldserver, search_result, "objectGUID");
+               if (values) {
+                       if (values[0]) {
+                               CtdlLogPrintf(CTDL_DEBUG, "objectGUID = (%d characers)\n", strlen(values[0]));
+                       }
+                       ldap_value_free(values);
+               }
+
+       }
+
+       /* free the results */
+       ldap_msgfree(search_result);
+
+       /* unbind so we can go back in as the authenticating user */
+       ldap_unbind(ldserver);
+
+       if (!user_dn) {
+               CtdlLogPrintf(CTDL_DEBUG, "No such user was found.\n");
+               return(4);
+       }
+
+       safestrncpy(found_dn, user_dn, found_dn_size);
+       ldap_memfree(user_dn);
+       return(0);
+}
+
+
+int CtdlTryPasswordLDAP(char *user_dn, char *password)
+{
+       LDAP *ldserver = NULL;
+       int i;
+
+       ldserver = ldap_init(CTDL_LDAP_HOST, CTDL_LDAP_PORT);
+       if (ldserver) {
+               ldap_set_option(ldserver, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
+               i = ldap_simple_bind_s(ldserver, user_dn, password);
+               if (i == LDAP_SUCCESS) {
+                       CtdlLogPrintf(CTDL_DEBUG, "LDAP: bind succeeded\n");
+               }
+               else {
+                       CtdlLogPrintf(CTDL_DEBUG, "LDAP: Cannot bind: %s (%d)\n", ldap_err2string(i), i);
+               }
+               ldap_unbind(ldserver);
+       }
+
+       return((i == LDAP_SUCCESS) ? 0 : 1);
+}
+
+
+
+
+#endif /* HAVE_LDAP */
index 13660559aa807fd8b61b36e43156dee794829d8b..9fc9ca6ec2458f798b5d3e230ac74b46770aec02 100644 (file)
@@ -145,6 +145,7 @@ struct CitContext {
        struct ma_info *ma;                     /* multipart/alternative data */
        const char *ServiceName;                /* readable purpose of this session */
        void *openid_data;                      /* Data stored by the OpenID module */
+       char *ldap_dn;                          /* DN of user when using AUTHMODE_LDAP */
 };
 
 typedef struct CitContext t_context;
index 60bce3fcc6bf7b19b79be9d62b1aac1bab502027..b574fbd02fde850c39447eb2a9c5211f814d7faf 100644 (file)
@@ -50,6 +50,7 @@
 #include "citadel_dirs.h"
 #include "genstamp.h"
 #include "threads.h"
+#include "citadel_ldap.h"
 
 /* These pipes are used to talk to the chkpwd daemon, which is forked during startup */
 int chkpwd_write_pipe[2];