diff --git a/build/buildlib.sh b/build/buildlib.sh index 4f628eecb2..78565b9483 100755 --- a/build/buildlib.sh +++ b/build/buildlib.sh @@ -57,18 +57,23 @@ if [ -f $uncompressed/.complete ] ; then fi cd $uncompressed -$MAKE clean 2>&1 -sh ./configure $@ -if [ $? = 0 ] ; then - $MAKE -else - echo ERROR - exit 1 -fi +if [ -f ../$uncompressed.build.sh ] ; then + MAKE=$MAKE ../$uncompressed.build.sh $@ +else + $MAKE clean 2>&1 + sh ./configure $@ -if [ ! -z $install ] ; then - $MAKE install + if [ $? = 0 ] ; then + $MAKE + else + echo ERROR + exit 1 + fi + + if [ ! -z $install ] ; then + $MAKE install + fi fi if [ $? = 0 ] ; then diff --git a/libs/openldap-2.3.19.build.sh b/libs/openldap-2.3.19.build.sh new file mode 100755 index 0000000000..b70e28615a --- /dev/null +++ b/libs/openldap-2.3.19.build.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +./configure $@ +$MAKE depend +cd libraries +$MAKE +$MAKE install diff --git a/modules.conf b/modules.conf index 0adc8bc915..769d0732d2 100644 --- a/modules.conf +++ b/modules.conf @@ -18,3 +18,4 @@ event_handlers/mod_xmpp_event formats/mod_sndfile timers/mod_softtimer dialplans/mod_pcre +directories/mod_ldap diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 3098f7bf2c..dc9318e251 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -842,10 +842,11 @@ SWITCH_DECLARE(switch_status) switch_core_directory_open(switch_directory_handle /*! \brief Query a directory handle \param dh a direcotry handle to use + \param base the base to query against \param query a string of filters or query data \return SWITCH_STATUS_SUCCESS if the query is successful */ -SWITCH_DECLARE(switch_status) switch_core_directory_query(switch_directory_handle *dh, char *query); +SWITCH_DECLARE(switch_status) switch_core_directory_query(switch_directory_handle *dh, char *base, char *query); /*! \brief Obtain the next record in a lookup diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 098a789c2c..dd40dd59d7 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -330,7 +330,7 @@ struct switch_directory_interface { /*! function to close the directory interface */ switch_status (*directory_close)(switch_directory_handle *dh); /*! function to query the directory interface */ - switch_status (*directory_query)(switch_directory_handle *dh, char *query); + switch_status (*directory_query)(switch_directory_handle *dh, char *base, char *query); /*! function to advance to the next record */ switch_status (*directory_next)(switch_directory_handle *dh); /*! function to advance to the next name/value pair in the current record */ diff --git a/src/mod/applications/mod_ivrtest/mod_ivrtest.c b/src/mod/applications/mod_ivrtest/mod_ivrtest.c index 828498bdcd..e9dbd5c532 100644 --- a/src/mod/applications/mod_ivrtest/mod_ivrtest.c +++ b/src/mod/applications/mod_ivrtest/mod_ivrtest.c @@ -48,6 +48,39 @@ static switch_status on_dtmf(switch_core_session *session, char *dtmf, void *buf } +static void dirtest_function(switch_core_session *session, char *data) +{ + char *var, *val; + switch_channel *channel; + switch_directory_handle dh; + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + + if (switch_core_directory_open(&dh, + "ldap", + "ldap.freeswitch.org", + "cn=Manager,dc=freeswitch,dc=org", + "test", + NULL) != SWITCH_STATUS_SUCCESS) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Can't connect\n"); + return; + } + + + switch_core_directory_query(&dh, "ou=dialplan,dc=freeswitch,dc=org", "(objectClass=*)"); + while (switch_core_directory_next(&dh) == SWITCH_STATUS_SUCCESS) { + while (switch_core_directory_next_pair(&dh, &var, &val) == SWITCH_STATUS_SUCCESS) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "VALUE [%s]=[%s]\n", var, val); + } + } + + switch_core_directory_close(&dh); + switch_channel_hangup(channel); + +} + static void ivrtest_function(switch_core_session *session, char *data) { switch_channel *channel; @@ -113,9 +146,16 @@ static const switch_state_handler_table state_handlers = { /*.on_transmit */ NULL }; +static const switch_application_interface dirtest_application_interface = { + /*.interface_name */ "dirtest", + /*.application_function */ dirtest_function +}; + static const switch_application_interface ivrtest_application_interface = { /*.interface_name */ "ivrtest", - /*.application_function */ ivrtest_function + /*.application_function */ ivrtest_function, + NULL, NULL, NULL, + /*.next*/ &dirtest_application_interface }; static const switch_loadable_module_interface mod_ivrtest_module_interface = { diff --git a/src/mod/directories/mod_ldap/Makefile b/src/mod/directories/mod_ldap/Makefile new file mode 100644 index 0000000000..0aa175a931 --- /dev/null +++ b/src/mod/directories/mod_ldap/Makefile @@ -0,0 +1,20 @@ +CFLAGS += -DWITH_OPENLDAP +LDFLAGS += -lldap_r -llber + +LINKER=$(CC) + + +all: depends $(MODNAME).so + +depends: + MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install openldap-2.3.19.tgz --prefix=$(PREFIX) + +$(MODNAME).so: $(MODNAME).c + $(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o + $(LINKER) $(SOLINK) -o $(MODNAME).so $(MODNAME).o $(LDFLAGS) + +clean: + rm -fr *.so *.o *~ + +install: + cp -f $(MODNAME).so $(PREFIX)/mod diff --git a/src/mod/directories/mod_ldap/mod_ldap.c b/src/mod/directories/mod_ldap/mod_ldap.c new file mode 100644 index 0000000000..a04609a467 --- /dev/null +++ b/src/mod/directories/mod_ldap/mod_ldap.c @@ -0,0 +1,224 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * + * mod_ldap.c -- LDAP + * + */ +#include +#include +#include + + +static const char modname[] = "mod_ldap"; + +struct ldap_context { + LDAP *ld; + LDAPMessage* msg; + LDAPMessage* entry; + BerElement* ber; + char* attr; + char *var; + char *val; + char **vals; + int itt; + int vitt; + int vi; +}; + + +static switch_status mod_ldap_open(switch_directory_handle *dh, char *source, char *dsn, char *passwd) +{ + struct ldap_context *context; + int auth_method = LDAP_AUTH_SIMPLE; + int desired_version = LDAP_VERSION3; + + if (!(context = switch_core_alloc(dh->memory_pool, sizeof(*context)))) { + return SWITCH_STATUS_MEMERR; + } + + if ((context->ld = ldap_init(source, LDAP_PORT)) == NULL ) { + return SWITCH_STATUS_FALSE; + } + + /* set the LDAP version to be 3 */ + if (ldap_set_option(context->ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + + if (ldap_bind_s(context->ld, dsn, passwd, auth_method) != LDAP_SUCCESS ) { + return SWITCH_STATUS_FALSE; + } + + + dh->private = context; + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status mod_ldap_close(switch_directory_handle *dh) +{ + struct ldap_context *context; + + context = dh->private; + assert(context != NULL); + + ldap_unbind_s(context->ld); + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status mod_ldap_query(switch_directory_handle *dh, char *base, char *query) +{ + struct ldap_context *context; + + context = dh->private; + assert(context != NULL); + + if (ldap_search_s(context->ld, base, LDAP_SCOPE_SUBTREE, query, NULL, 0, &context->msg) != LDAP_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + + if (ldap_count_entries(context->ld, context->msg) <= 0) { + return SWITCH_STATUS_FALSE; + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status mod_ldap_next(switch_directory_handle *dh) +{ + struct ldap_context *context; + + context = dh->private; + assert(context != NULL); + + context->vitt = 0; + + if (!context->itt) { + context->entry = ldap_first_entry(context->ld, context->msg); + context->itt++; + } else if (context->entry) { + context->entry = ldap_next_entry(context->ld, context->entry); + context->itt++; + } + + if (!context->entry) { + return SWITCH_STATUS_FALSE; + } + + return SWITCH_STATUS_SUCCESS; +} + +switch_status mod_ldap_next_pair(switch_directory_handle *dh, char **var, char **val) +{ + struct ldap_context *context; + + context = dh->private; + assert(context != NULL); + + *var = *val = NULL; + + if (!context->entry) { + return SWITCH_STATUS_FALSE; + } + + if (!context->vitt) { + context->var = "dn"; + context->val = ldap_get_dn(context->ld, context->entry); + context->vitt++; + *var = context->var; + *val = context->val; + return SWITCH_STATUS_SUCCESS; + } else { + itter: + if (context->attr && context->vals) { + if ((*val = context->vals[context->vi++])) { + *var = context->attr; + return SWITCH_STATUS_SUCCESS; + } else { + ldap_value_free(context->vals); + context->vals = NULL; + context->vi = 0; + } + } + + if (context->vitt == 1) { + ldap_memfree(context->val); + context->val = NULL; + if (context->ber) { + ber_free(context->ber,0); + context->ber = NULL; + } + context->attr = ldap_first_attribute(context->ld, context->entry, &context->ber); + } else { + if (context->attr) { + ldap_memfree(context->attr); + } + context->attr = ldap_next_attribute(context->ld, context->entry, context->ber); + } + context->vitt++; + if (context->entry && context->attr && (context->vals = ldap_get_values(context->ld, context->entry, context->attr))) { + goto itter; + } + } + + return SWITCH_STATUS_FALSE; +} + + +static const switch_directory_interface ldap_directory_interface = { + /*.interface_name */ "ldap", + /*.directory_open*/ mod_ldap_open, + /*.directory_close*/ mod_ldap_close, + /*.directory_query*/ mod_ldap_query, + /*.directory_next*/ mod_ldap_next, + /*.directory_next_pair*/ mod_ldap_next_pair +}; + + +static switch_loadable_module_interface skel_module_interface = { + /*.module_name */ modname, + /*.endpoint_interface */ NULL, + /*.timer_interface */ NULL, + /*.dialplan_interface */ NULL, + /*.codec_interface */ NULL, + /*.application_interface */ NULL, + /*.api_interface */ NULL, + /*.file_interface */ NULL, + /*.speech_interface */ NULL, + /*.directory_interface */ &ldap_directory_interface +}; + +switch_status switch_module_load(switch_loadable_module_interface **interface, char *filename) +{ + /* connect my internal structure to the blank pointer passed to me */ + *interface = &skel_module_interface; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} diff --git a/src/switch_core.c b/src/switch_core.c index ab712075a6..f36e9e7148 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -472,9 +472,9 @@ SWITCH_DECLARE(switch_status) switch_core_directory_open(switch_directory_handle return dh->directory_interface->directory_open(dh, source, dsn, passwd); } -SWITCH_DECLARE(switch_status) switch_core_directory_query(switch_directory_handle *dh, char *query) +SWITCH_DECLARE(switch_status) switch_core_directory_query(switch_directory_handle *dh, char *base, char *query) { - return dh->directory_interface->directory_query(dh, query); + return dh->directory_interface->directory_query(dh, base, query); } SWITCH_DECLARE(switch_status) switch_core_directory_next(switch_directory_handle *dh)