From ea4f8a3d805768899ac12dd7d35e11f6f4d74d74 Mon Sep 17 00:00:00 2001 From: John Skopis Date: Sat, 2 Feb 2008 00:17:47 +0000 Subject: [PATCH] correctly import inital copy of mod_xml_ldap git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7485 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/xml_int/mod_xml_ldap/Makefile | 10 + .../mod_xml_ldap/mod_xml_curl.2008.vcproj | 156 +++++++ .../xml_int/mod_xml_ldap/mod_xml_curl.vcproj | 61 +++ src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c | 411 ++++++++++++++++++ .../xml_int/mod_xml_ldap/mod_xml_ldap.c.bak | 386 ++++++++++++++++ src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.so | 129 ++++++ 6 files changed, 1153 insertions(+) create mode 100644 src/mod/xml_int/mod_xml_ldap/Makefile create mode 100644 src/mod/xml_int/mod_xml_ldap/mod_xml_curl.2008.vcproj create mode 100644 src/mod/xml_int/mod_xml_ldap/mod_xml_curl.vcproj create mode 100644 src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c create mode 100644 src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c.bak create mode 100755 src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.so diff --git a/src/mod/xml_int/mod_xml_ldap/Makefile b/src/mod/xml_int/mod_xml_ldap/Makefile new file mode 100644 index 0000000000..2684521593 --- /dev/null +++ b/src/mod/xml_int/mod_xml_ldap/Makefile @@ -0,0 +1,10 @@ +WANT_LDAP=yes +LDAP=openldap-2.3.19 +LDAP_DIR=$(switch_srcdir)/libs/$(LDAP) +LDAPLA=$(LDAP_DIR)/libraries/libldap_r/libldap_r.la +LIBLBERLA=$(LDAP_DIR)/libraries/liblber/liblber.la +LOCAL_LIBADD=$(LDAPLA) $(LIBLBERLA) +switch_srcdir=../../../.. + +LOCAL_CFLAGS=-DWITH_OPENLDAP -DLDAP_DEPRECATED -I$(LDAP_DIR)/include +include ../../../../build/modmake.rules diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_curl.2008.vcproj b/src/mod/xml_int/mod_xml_ldap/mod_xml_curl.2008.vcproj new file mode 100644 index 0000000000..000b251ef2 --- /dev/null +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_curl.2008.vcproj @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_curl.vcproj b/src/mod/xml_int/mod_xml_ldap/mod_xml_curl.vcproj new file mode 100644 index 0000000000..8448774f94 --- /dev/null +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_curl.vcproj @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c new file mode 100644 index 0000000000..998a1c0de6 --- /dev/null +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c @@ -0,0 +1,411 @@ +/* + * 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 + * Bret McDanel + * Justin Cassidy + * John Skopis + * + * mod_xml_ldap.c -- LDAP XML Gateway + * + */ +#include +#include +#include +#ifdef MSLDAP +#include +#include +#include +#define LDAP_OPT_SUCCESS LDAP_SUCCESS +#else +#include +#include +#endif + +#define XML_LDAP_CONFIG 0 +#define XML_LDAP_DIRECTORY 1 +#define XML_LDAP_DIALPLAN 2 +#define XML_LDAP_PHRASE 3 + +SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_ldap_shutdown); +SWITCH_MODULE_DEFINITION(mod_xml_ldap, mod_xml_ldap_load, mod_xml_ldap_shutdown, NULL); + + +struct xml_binding { + char *bindings; + char *host; + char *ldap_base; + char *binddn; + char *bindpass; + char *queryfmt; +}; + +typedef struct xml_binding xml_binding_t; + +struct ldap_c { + LDAP *ld; + LDAPMessage *msg; + LDAPMessage *entry; + BerElement *berkey; + BerElement *berval; + char *key; + char *val; + char **keyvals; + char **valvals; + +}; + +static switch_status_t xml_ldap_directory_result( void *ldap_connection, xml_binding_t *binding, switch_xml_t *xml, int *off); +static switch_status_t xml_ldap_dialplan_result( void *ldap_connection, xml_binding_t *binding, switch_xml_t *xml, int *off); + + +#define XML_LDAP_SYNTAX "[debug_on|debug_off]" +SWITCH_STANDARD_API(xml_ldap_function) +{ + if (session) { + return SWITCH_STATUS_FALSE; + } + + if (switch_strlen_zero(cmd)) { + goto usage; + } + + if (!strcasecmp(cmd, "debug_on")) { + } else if (!strcasecmp(cmd, "debug_off")) { + } else { + goto usage; + } + + stream->write_function(stream, "OK\n"); + return SWITCH_STATUS_SUCCESS; + +usage: + stream->write_function(stream, "USAGE: %s\n", XML_LDAP_SYNTAX); + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t xml_ldap_result( void *ldap_connection, xml_binding_t *binding, switch_xml_t *xml, int *off, int qt) +{ + switch_status_t ret; + if (qt == 1 ) ret = xml_ldap_directory_result(ldap_connection, binding, xml , off); + else if (qt == 2 ) ret = xml_ldap_dialplan_result(ldap_connection, binding, xml , off); + return ret; +} + +static switch_status_t xml_ldap_dialplan_result( void *ldap_connection, xml_binding_t *binding, switch_xml_t *xml, int *off) +{ + return SWITCH_STATUS_FALSE; +} + +static switch_status_t xml_ldap_directory_result( void *ldap_connection, xml_binding_t *binding, switch_xml_t *xml, int *off) +{ + struct ldap_c *ldap = ldap_connection; + switch_xml_t asdf = *xml; + switch_xml_t param, variable, params, variables; + int i =0; + int loff = *off; + + for (ldap->entry = ldap_first_entry(ldap->ld,ldap->msg); ldap->entry != NULL; ldap->entry = ldap_next_entry(ldap->ld,ldap->entry)) { + ldap->key = ldap_first_attribute( ldap->ld, ldap->entry, &ldap->berkey ); + do { + ldap->val = ldap_first_attribute( ldap->ld, ldap->entry, &ldap->berval ); + do { + if(strstr(ldap->val,"value") ) { + if(strstr(ldap->val,ldap->key) && strcmp(ldap->val,ldap->key) ) { + if(!strcmp(ldap->key,"param")) { + params = switch_xml_add_child_d(asdf,"params",loff++); + }else if (!strcmp(ldap->key,"variable")) { + variables = switch_xml_add_child_d(asdf,"variables",loff++); + } + + if( (ldap->keyvals = ldap_get_values( ldap->ld, ldap->entry, ldap->key )) && (ldap->valvals = ldap_get_values( ldap->ld, ldap->entry, ldap->val )) ) { + if ( ldap_count_values(ldap->valvals) == ldap_count_values(ldap->keyvals) ) { + for ( i = 0 ; ldap->keyvals[i] != NULL && ldap->valvals[i] != NULL ; i++ ) { + if(!strcmp(ldap->key,"param")) { + param = switch_xml_add_child_d(params,"param",loff++); + switch_xml_set_attr_d(param,"name",ldap->keyvals[i]); + switch_xml_set_attr_d(param,"value",ldap->valvals[i]); + } + else if (!strcmp(ldap->key,"variable")) { + variable = switch_xml_add_child_d(variables,"variable",loff++); + switch_xml_set_attr_d(variable,"name",ldap->keyvals[i]); + switch_xml_set_attr_d(variable,"value",ldap->valvals[i]); + } + } + if ( ldap->keyvals ) ldap_value_free(ldap->keyvals); + if ( ldap->valvals ) ldap_value_free(ldap->valvals); + } + else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "seems the values %d and %d are not the same??\n",ldap_count_values ( ldap->valvals ), ldap_count_values ( ldap->keyvals )); + } + } + } + } + if (ldap->val) ldap_memfree(ldap->val); + ldap->val = ldap_next_attribute(ldap->ld, ldap->entry,ldap->berval); + } while (ldap->val != NULL); + if (ldap->key) ldap_memfree(ldap->key); + if (ldap->berval) ber_free(ldap->berval,0); + ldap->key = ldap_next_attribute(ldap->ld, ldap->entry, ldap->berkey ); + } while ( ldap->key != NULL ); + if (ldap->berkey) ber_free(ldap->berkey,0); + } + return SWITCH_STATUS_SUCCESS; +} + + +static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data) +{ + xml_binding_t *binding = (xml_binding_t *) user_data; + switch_event_header_t *hi; + + switch_xml_t xml, sub; + + struct ldap_c ldap_connection; + struct ldap_c *ldap = &ldap_connection; + + int auth_method = LDAP_AUTH_SIMPLE; + int desired_version = LDAP_VERSION3; + int query_type; // see defines on top XML_LDAP_foo + char *dir_exten, *dir_domain; + char *filter = "(objectClass=*)"; + + char *search_base = NULL; + int off = 0; + + + if (!binding) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no bindings...sorry bud returning now\n"); + return NULL; + } + + if(!strcmp(section,"configuration")) { + query_type = 0; + } + else if (!strcmp(section,"directory")) { + query_type = 1; + } + else if (!strcmp(section,"dialplan")) { + query_type = 2; + } + else if (!strcmp(section,"phrases")) { + query_type = 3; + } + + + if (params) { + if ((hi = params->headers)) { + for (; hi; hi = hi->next) { + switch(query_type) { + case XML_LDAP_CONFIG: + break; + case XML_LDAP_DIRECTORY: + if (!strcmp(hi->name,"user")) dir_exten = strdup(hi->value); + else if (!strcmp(hi->name,"domain")) dir_domain = strdup(hi->value); + break; + case XML_LDAP_DIALPLAN: + break; + case XML_LDAP_PHRASE: + break; + } + } + switch(query_type) { + case XML_LDAP_CONFIG: + break; + case XML_LDAP_DIRECTORY: + if ( dir_exten && dir_domain ) { + xml = switch_xml_new("directory"); + switch_xml_set_attr_d(xml,"type","freeswitch/xml"); + sub = switch_xml_add_child_d(xml,"section",off++); + switch_xml_set_attr_d(sub,"name","directory"); + sub = switch_xml_add_child_d(sub,"domain",off++); + switch_xml_set_attr_d(sub,"name",dir_domain); + sub = switch_xml_add_child_d(sub,"user",off++); + switch_xml_set_attr_d(sub,"id",dir_exten); + + search_base = switch_mprintf(binding->queryfmt,dir_exten,dir_domain,binding->ldap_base); + + free(dir_exten); + dir_exten = NULL; + free(dir_domain); + dir_domain = NULL; + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "something bad happened during the query construction phase likely exten(%s) or domain(%s) is null\n",dir_exten,dir_domain); + goto cleanup; + } + break; + case XML_LDAP_DIALPLAN: + xml = switch_xml_new("document"); + switch_xml_set_attr_d(xml,"type","freeswitch/xml"); + sub = switch_xml_add_child_d(xml,"section",off++); + switch_xml_set_attr_d(sub,"name","dialplan"); + sub = switch_xml_add_child_d(xml,"context",off++); + search_base = switch_mprintf(binding->queryfmt,dir_exten,dir_domain,binding->ldap_base); + break; + case XML_LDAP_PHRASE: + break; + } + } + else { + goto cleanup; + } + } + + + if ((ldap->ld = ldap_init(binding->host, LDAP_PORT)) == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to connect to ldap server.%s\n", binding->host); + goto cleanup; + } + + if (ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) { + goto cleanup; + } + + if (ldap_bind_s(ldap->ld, binding->binddn, binding->bindpass, auth_method) != LDAP_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to bind to ldap server %s as %s\n",binding->host, binding->binddn); + goto cleanup; + } + + if (ldap_search_s(ldap->ld, search_base, LDAP_SCOPE_SUBTREE, filter, NULL, 0, &ldap->msg) != LDAP_SUCCESS) { + goto cleanup; + } + + if (ldap_count_entries(ldap->ld, ldap->msg) <= 0) { + goto cleanup; + } + + if ( xml_ldap_result( &ldap_connection, binding, &sub, &off, query_type) != SWITCH_STATUS_SUCCESS ){ + goto cleanup; + } + + cleanup: + if (ldap->msg) ldap_msgfree(ldap->msg); + if (ldap->ld) ldap_unbind_s(ldap->ld); + + switch_safe_free(search_base); + + return xml; +} + + +static switch_status_t do_config(void) +{ + char *cf = "xml_ldap.conf"; + switch_xml_t cfg, xml, bindings_tag, binding_tag, param; + xml_binding_t *binding = NULL; + int x = 0; + + if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); + return SWITCH_STATUS_TERM; + } + + if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing tag!\n"); + goto done; + } + + for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) { + char *bname = (char *) switch_xml_attr_soft(binding_tag, "name"); + + if (!(binding = malloc(sizeof(*binding)))) { + goto done; + } + memset(binding, 0, sizeof(*binding)); + + + + + for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) { + + + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + if (!strcasecmp(var, "queryfmt")) { + binding->bindings = (char *) switch_xml_attr_soft(param, "bindings"); + if(val) binding->queryfmt = strdup(val); + } else if (!strcasecmp(var, "base")) { + binding->ldap_base = strdup(val); + } else if (!strcasecmp(var, "binddn")) { + binding->binddn = strdup(val); + } else if (!strcasecmp(var, "bindpass")) { + binding->bindpass = strdup(val); + } else if (!strcasecmp(var, "host")) { + binding->host = strdup(val); + } + } + + if (!binding->ldap_base || !binding->binddn || !binding->bindpass ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "You must define base binddn bindpass\n"); + continue; + } + + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n", + switch_strlen_zero(bname) ? "N/A" : bname, binding->ldap_base, binding->bindings ? binding->bindings : "all"); + switch_xml_bind_search_function(xml_ldap_search, switch_xml_parse_section_string(bname), binding); + x++; + binding = NULL; + } + + done: + switch_xml_free(xml); + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load) +{ + switch_api_interface_t *xml_ldap_api_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_API(xml_ldap_api_interface, "xml_ldap", "XML LDAP", xml_ldap_function, XML_LDAP_SYNTAX); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML LDAP module loading...\n"); + + if (! (do_config() == SWITCH_STATUS_SUCCESS) ) return SWITCH_STATUS_FALSE; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_ldap_shutdown) +{ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: + */ diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c.bak b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c.bak new file mode 100644 index 0000000000..81eb68f9f3 --- /dev/null +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.c.bak @@ -0,0 +1,386 @@ +/* + * 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 + * Bret McDanel + * Justin Cassidy + * John Skopis + * + * mod_xml_ldap.c -- LDAP XML Gateway + * + */ +#include +#include +#include +#ifdef MSLDAP +#include +#include +#include +#define LDAP_OPT_SUCCESS LDAP_SUCCESS +#else +#include +#include +#endif + +#define LDAP_CONFIG 0 +#define LDAP_DIRECTORY 1 + +SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_ldap_shutdown); +SWITCH_MODULE_DEFINITION(mod_xml_ldap, mod_xml_ldap_load, mod_xml_ldap_shutdown, NULL); + +struct xml_binding { + char *bindings; + char *ldap_base; + char *binddn; + char *bindpass; +}; + + +typedef struct xml_binding xml_binding_t; + +struct ldap_c { + LDAP *ld; + LDAPMessage *msg; + LDAPMessage *entry; + BerElement *berkey; + BerElement *berval; + char *key; + char *val; + char **keyvals; + char **valvals; + +}; + +#define XML_LDAP_SYNTAX "[debug_on|debug_off]" +SWITCH_STANDARD_API(xml_ldap_function) +{ + if (session) { + return SWITCH_STATUS_FALSE; + } + + if (switch_strlen_zero(cmd)) { + goto usage; + } + + if (!strcasecmp(cmd, "debug_on")) { + } else if (!strcasecmp(cmd, "debug_off")) { + } else { + goto usage; + } + + stream->write_function(stream, "OK\n"); + return SWITCH_STATUS_SUCCESS; + +usage: + stream->write_function(stream, "USAGE: %s\n", XML_LDAP_SYNTAX); + return SWITCH_STATUS_SUCCESS; +} + + +static switch_status_t xml_ldap_result( void *ldap_connection, char *xml, int bind) +{ + struct ldap_c *ldap = ldap_connection; + char *tiny_xml = NULL; + char *bigger_xml = NULL; + char *temp_xml = NULL; + char *super_xml = NULL;; + int i = 0, len = 0; + + xml = NULL; + + + + for (ldap->entry = ldap_first_entry(ldap->ld,ldap->msg); ldap->entry != NULL; ldap->entry = ldap_next_entry(ldap->ld,ldap->entry)) { + ldap->key = ldap_first_attribute( ldap->ld, ldap->entry, &ldap->berkey ); + ldap->val = ldap_first_attribute( ldap->ld, ldap->entry, &ldap->berval ); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got key %s val %s\n", ldap->key, ldap->val); + do { + if(!strstr(ldap->val, ldap->key) && strstr(ldap->val,"value") ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " val %s doesn't match key %s and have name\n",ldap->val,ldap->key); + do { + ldap->val = ldap_next_attribute(ldap->ld, ldap->entry, ldap->berval ); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "looping on next attr %s\n",ldap->val); + } while ( ldap->val != NULL && !strstr(ldap->val,ldap->key) && strstr(ldap->val,"value") ); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "reached the end of the loop proceeding\n"); + //} else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "we are matched up on %s %s",ldap->key,ldap->val); + // guess we found our matching pair param+paramval variable+variablevalue etc + if ( + ( (ldap->keyvals = ldap_get_values( ldap->ld, ldap->entry, ldap->key )) != NULL ) + && + ( (ldap->valvals = ldap_get_values( ldap->ld, ldap->entry, ldap->val )) != NULL ) ) { + if ( ldap_count_values ( ldap->keyvals ) != ldap_count_values ( ldap->valvals ) ) { + for ( i = 0 ; ldap->keyvals[i] != NULL && ldap->valvals[i] != NULL ; i++ ) { + switch(bind) { + case LDAP_DIRECTORY: + if(!strcmp(ldap->key,"param")) { + //put together the params + if ( bigger_xml == NULL ) bigger_xml = switch_mprintf("",ldap->keyvals[i],ldap->valvals[i]); + else { + tiny_xml = switch_mprintf("",ldap->keyvals[i],ldap->valvals[i]); + temp_xml = strdup(bigger_xml); + switch_safe_free(bigger_xml); + len = strlen(temp_xml) + strlen(tiny_xml) + 2; + bigger_xml = malloc(len*sizeof(char)); + bigger_xml = memset(bigger_xml, 0, len*sizeof(char)); + bigger_xml = strncpy(bigger_xml,temp_xml,strlen(bigger_xml) - 1); + bigger_xml = strncat(bigger_xml,tiny_xml,strlen(bigger_xml) - strlen(tiny_xml) - 1 ); + switch_safe_free(temp_xml); + switch_safe_free(tiny_xml); + } + } else if (!strcmp(ldap->key,"variable")) { + //handle variable xml bits + if ( bigger_xml == NULL ) bigger_xml = switch_mprintf("",ldap->keyvals[i],ldap->valvals[i]); + else { + tiny_xml = switch_mprintf("",ldap->keyvals[i],ldap->valvals[i]); + temp_xml = strdup(bigger_xml); + switch_safe_free(bigger_xml); + len = strlen(temp_xml) + strlen(tiny_xml) + 2; + bigger_xml = malloc(len*sizeof(char)); + bigger_xml = memset(bigger_xml, 0, len*sizeof(char)); + bigger_xml = strncpy(bigger_xml,temp_xml,strlen(bigger_xml) - 1); + bigger_xml = strncat(bigger_xml,tiny_xml,strlen(bigger_xml) - strlen(tiny_xml) - 1 ); + switch_safe_free(temp_xml); + switch_safe_free(tiny_xml); + } + } + /* no brace here...why oh why do I indent on case */ + } + } /* end of vals for loop */ + switch(bind){ + case LDAP_DIRECTORY: + if( super_xml == NULL ) { + super_xml = strdup(bigger_xml); + switch_safe_free(bigger_xml); + } else { + temp_xml = strdup(super_xml); + switch_safe_free(super_xml); + len = strlen(temp_xml) + strlen(bigger_xml) + 2; + super_xml = malloc(sizeof(char) * len ); + super_xml = memset(super_xml,0,len*sizeof(char)); + super_xml = strncpy(temp_xml,bigger_xml,len*sizeof(char) - 1); + super_xml = strncat(super_xml,bigger_xml,strlen(super_xml) - strlen(bigger_xml) -1); + switch_safe_free(bigger_xml); + } + break; + } + } else { + //something isn't quite right here there is not a val for each key + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "attrib count doesn't match in %s %s",ldap->key,ldap->val); + } + } else { + //no vals let's move right along + } + } + } + ldap->key = ldap_next_attribute(ldap->ld, ldap->entry, ldap->berkey ); + } while ( ldap->key != NULL && ldap->val != NULL ); + } + if (super_xml) { + xml = super_xml; + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + + +static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, const char *params, + void *user_data) +{ + xml_binding_t *binding = (xml_binding_t *) user_data; + switch_xml_t xml_ret; + struct ldap_c ldap_connection; + struct ldap_c *ldap = &ldap_connection; + //switch_uuid_t uuid; + //char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; + int auth_method = LDAP_AUTH_SIMPLE; + int desired_version = LDAP_VERSION3; + + char *search_base = NULL; + char *xml_str, *xml; + int xml_str_len; + char hostname[256] = ""; + //const char *config_template = ""; + const char *directory_template = "
%s
"; + //const char *dialplan_template = "
"; + //const char *notfound = "
"; + + gethostname(hostname, sizeof(hostname)); + + if (!binding) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "no bindings...sorry bud returning now\n"); + return NULL; + } + + search_base = switch_mprintf("id%s=%s,tag=%s,section=%s,fshost=%s,%s",switch_str_nil(key_name),switch_str_nil(key_value),switch_str_nil(tag_name),section,hostname,binding->ldap_base); + + if ((ldap->ld = ldap_init("192.168.0.50", LDAP_PORT)) == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "returning from query because we couldn't connect\n"); + return NULL; + } + + if (ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't set ldap protocol options\n"); + return NULL; + } + + if (ldap_bind_s(ldap->ld, binding->binddn, binding->bindpass, auth_method) != LDAP_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "didn't bind successfully\n"); + return NULL; + } + + if (ldap_search_s(ldap->ld, search_base, LDAP_SCOPE_SUBTREE, "(objectClass=*)", NULL, 0, &ldap->msg) != LDAP_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "search was not conclusive\n"); + return NULL; + } + + if (ldap_count_entries(ldap->ld, ldap->msg) <= 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "search returned...just not any results\n"); + return NULL; + } + + if ( xml_ldap_result( &ldap_connection, xml, 1) != SWITCH_STATUS_SUCCESS ){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "well aint that a bitch\n"); + return NULL; + } + + if (!xml) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "I wish I had some XML\n"); + return NULL; + } else { + xml_str = switch_mprintf(directory_template,hostname,xml); + xml_str_len = strlen(xml_str); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RETURN: %s\n",xml_str); + xml_ret = switch_xml_parse_str(xml_str,xml_str_len); + } + + switch_safe_free(search_base); + return xml_ret; +} + + +static switch_status_t do_config(void) +{ + char *cf = "xml_ldap.conf"; + switch_xml_t cfg, xml, bindings_tag, binding_tag, param; + xml_binding_t *binding = NULL; + int x = 0; + + if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf); + return SWITCH_STATUS_TERM; + } + + if (!(bindings_tag = switch_xml_child(cfg, "bindings"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing tag!\n"); + goto done; + } + + for (binding_tag = switch_xml_child(bindings_tag, "binding"); binding_tag; binding_tag = binding_tag->next) { + char *bname = (char *) switch_xml_attr_soft(binding_tag, "name"); + char *ldap_base; + char *binddn; + char *bindpass; + char *bind_mask; + + + for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + if (!strcasecmp(var, "base")) { + bind_mask = (char *) switch_xml_attr_soft(param, "bindings"); + if(val) ldap_base = val; + } else if (!strcasecmp(var, "binddn")) { + binddn = val; + } else if (!strcasecmp(var, "bindpass")) { + bindpass = val; + } + } + + if (!ldap_base || !binddn || !bindpass ) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "You must define base binddn bindpass\n"); + continue; + } + + if (!(binding = malloc(sizeof(*binding)))) { + goto done; + } + memset(binding, 0, sizeof(*binding)); + + if(bind_mask) binding->bindings = strdup(bind_mask); + + + binding->ldap_base = strdup(ldap_base); + binding->binddn = strdup(binddn); + binding->bindpass = strdup(bindpass); + + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Binding [%s] XML Fetch Function [%s] [%s]\n", + switch_strlen_zero(bname) ? "N/A" : bname, binding->ldap_base, binding->bindings ? binding->bindings : "all"); + switch_xml_bind_search_function(xml_ldap_search, switch_xml_parse_section_string(bname), binding); + x++; + binding = NULL; + } + + done: + switch_xml_free(xml); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "returned from do_config() with status %d\n", SWITCH_STATUS_SUCCESS); + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load) +{ + switch_api_interface_t *xml_ldap_api_interface; + + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + + SWITCH_ADD_API(xml_ldap_api_interface, "xml_ldap", "XML LDAP", xml_ldap_function, XML_LDAP_SYNTAX); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML LDAP module loading...\n"); + + if (! (do_config() == SWITCH_STATUS_SUCCESS) ) return SWITCH_STATUS_FALSE; + + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_ldap_shutdown) +{ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: + */ diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.so b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.so new file mode 100755 index 0000000000..0053810415 --- /dev/null +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldap.so @@ -0,0 +1,129 @@ +#! /bin/sh + +# mod_xml_ldap.so - temporary wrapper script for .libs/mod_xml_ldap.so +# Generated by ltmain.sh - GNU libtool 1.5.22 (1.1220.2.365 2005/12/18 22:14:06) +# +# The mod_xml_ldap.so program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='/bin/sed -e 1s/^X//' +sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g' + +# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE). +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command="(cd /usr/local/src/freeswitch/src/mod/xml_int/mod_xml_ldap; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin\"; export PATH; gcc -DWITH_OPENLDAP -DLDAP_DEPRECATED -I/usr/local/src/freeswitch/libs/openldap-2.3.19/include -I/usr/local/src/freeswitch/src/include -I/usr/local/src/freeswitch/libs/libteletone/src -fPIC -Werror -g -ggdb -ggdb -O0 -fforce-addr -pipe -Wall -std=c99 -pedantic -D_GNU_SOURCE -o \$progdir/\$file -shared -Wl,-x mod_xml_ldap.o -o \$progdir/\$file -lm -L/usr/local/lib /usr/local/src/freeswitch/.libs/libfreeswitch.so /usr/local/src/freeswitch/libs/apr/.libs/libapr-1.a -luuid -lrt -ldl -lcrypt -lpthread -L/usr/local/src/freeswitch/libs/srtp -lncurses /usr/local/src/freeswitch/libs/openldap-2.3.19/libraries/libldap_r/.libs/libldap_r.a -lresolv -lsasl2 -lssl -lcrypto /usr/local/src/freeswitch/libs/openldap-2.3.19/libraries/liblber/.libs/liblber.a -Wl,--rpath -Wl,/usr/local/src/freeswitch/.libs -Wl,--rpath -Wl,/usr/local/freeswitch/lib ) " + +# This environment variable determines our operation mode. +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then + # install mode needs the following variable: + notinst_deplibs=' /usr/local/src/freeswitch/libfreeswitch.la' +else + # When we are sourced in execute mode, $file and $echo are already set. + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + echo="echo" + file="$0" + # Make sure echo works. + if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : + else + # Restart under the correct shell, and then maybe $echo will work. + exec /bin/sh "$0" --no-reexec ${1+"$@"} + fi + fi + + # Find the directory that this script lives in. + thisdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "x$thisdir" = "x$file" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'` + while test -n "$file"; do + destdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + + # If there was a directory component, then change thisdir. + if test "x$destdir" != "x$file"; then + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; + *) thisdir="$thisdir/$destdir" ;; + esac + fi + + file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'` + done + + # Try to get the absolute directory name. + absdir=`cd "$thisdir" && pwd` + test -n "$absdir" && thisdir="$absdir" + + program=lt-'mod_xml_ldap.so' + progdir="$thisdir/.libs" + + if test ! -f "$progdir/$program" || \ + { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \ + test "X$file" != "X$progdir/$program"; }; then + + file="$$-$program" + + if test ! -d "$progdir"; then + mkdir "$progdir" + else + rm -f "$progdir/$file" + fi + + # relink executable if necessary + if test -n "$relink_command"; then + if relink_command_output=`eval $relink_command 2>&1`; then : + else + echo "$relink_command_output" >&2 + rm -f "$progdir/$file" + exit 1 + fi + fi + + mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null || + { rm -f "$progdir/$program"; + mv -f "$progdir/$file" "$progdir/$program"; } + rm -f "$progdir/$file" + fi + + if test -f "$progdir/$program"; then + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + # Run the actual program with our arguments. + + exec "$progdir/$program" ${1+"$@"} + + $echo "$0: cannot exec $program $*" + exit 1 + fi + else + # The program doesn't exist. + $echo "$0: error: \`$progdir/$program' does not exist" 1>&2 + $echo "This script is just a wrapper for $program." 1>&2 + echo "See the libtool documentation for more information." 1>&2 + exit 1 + fi +fi