diff --git a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldapv2.c b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldapv2.c index 3c991a2b86..413227f92e 100644 --- a/src/mod/xml_int/mod_xml_ldap/mod_xml_ldapv2.c +++ b/src/mod/xml_int/mod_xml_ldap/mod_xml_ldapv2.c @@ -7,6 +7,9 @@ #define PCACHE_TTL 300 #define NCACHE_TTL 900 +typedef struct xml_ldap_attribute xml_ldap_attribute_t; + + typedef enum { XML_LDAP_CONFIG = 0, XML_LDAP_DIRECTORY, @@ -20,12 +23,53 @@ typedef struct xml_binding { xml_ldap_query_type_t bt; char *url; char *basedn; - char *h350base; char *binddn; char *bindpass; char *filter; + xml_ldap_attribute_t *attr_list; } xml_binding_t; +typedef enum exten_types { + LDAP_EXTEN_ID = 0, + LDAP_EXTEN_VM_MAILBOX, + LDAP_EXTEN_PASSWORD, + LDAP_EXTEN_VM_PASSWORD, + LDAP_EXTEN_VM_EMAILADDR, + LDAP_EXTEN_VM_EMAILMSG, + LDAP_EXTEN_VM_DELETE, + LDAP_EXTEN_VM_ATTACHAUDIO, + LDAP_EXTEN_NAME, + LDAP_EXTEN_LABEL, + LDAP_EXTEN_AREACODE, + LDAP_EXTEN_CID_EXTNAME, + LDAP_EXTEN_CID_EXTNUM, + LDAP_EXTEN_INTNAME, + LDAP_EXTEN_INTNUM, + LDAP_EXTEN_RECORD_CALLS, + LDAP_EXTEN_ACTIVE, + LDAP_EXTEN_CFWD_REWRITECID, + LDAP_EXTEN_CFWD_ACTIVE, + LDAP_EXTEN_CFWD_DEST, + LDAP_EXTEN_CFWD_BUSYACTIVE, + LDAP_EXTEN_CFWD_BUSYDEST, + LDAP_EXTEN_NOANSWERACTIVE, + LDAP_EXTEN_NOANSWERDEST, + LDAP_EXTEN_NOANSWERSECONDS, + LDAP_EXTEN_PROGRESSAUDIO, + LDAP_EXTEN_ALLOW_OUTOBUND, + LDAP_EXTEN_ALLOW_XFER, + LDAP_EXTEN_HOTLINE_ACTIVE, + LDAP_EXTEN_HOTLINE_DEST, + LDAP_EXTEN_CLASSOFSERVICE +} exten_type_t; + +struct xml_ldap_attribute { + exten_type_t type; + uint64_t len; + char *val; + xml_ldap_attribute_t *next; +}; + SWITCH_MODULE_LOAD_FUNCTION(mod_xml_ldap_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_ldap_shutdown); @@ -35,7 +79,7 @@ SWITCH_MODULE_DEFINITION(mod_xml_ldap, mod_xml_ldap_load, mod_xml_ldap_shutdown, 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); -static switch_status_t tryh350(switch_xml_t *, int *, LDAP *, char *, char *, char *); +static switch_status_t trydir(switch_xml_t *, int *, LDAP *, char *, char *, xml_binding_t *); static switch_status_t do_config(void); static switch_status_t trysearch( switch_xml_t *pxml, int *xoff, LDAP *ld, char *basedn, char *filter); void rec( switch_xml_t *, int*, LDAP *ld, char *); @@ -73,8 +117,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_ldap_shutdown) static switch_status_t do_config(void) { char *cf = "xml_ldap.conf"; - switch_xml_t cfg, xml, bindings_tag, binding_tag, param; + switch_xml_t cfg, xml, bindings_tag, binding_tag, param,tran; xml_binding_t *binding = NULL; + xml_ldap_attribute_t *attr_list = NULL; int x = 0; if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) { @@ -94,6 +139,7 @@ static switch_status_t do_config(void) { goto done; } memset(binding, 0, sizeof(*binding)); + binding->attr_list = attr_list; for (param = switch_xml_child(binding_tag, "param"); param; param = param->next) { @@ -108,7 +154,6 @@ static switch_status_t do_config(void) { binding->bt = XML_LDAP_CONFIG; } else if (!strncmp(binding->bindings, "directory",strlen(binding->bindings))) { binding->bt = XML_LDAP_DIRECTORY; - binding->h350base = strdup("dc=example"); } else if (!strncmp(binding->bindings, "dialplain",strlen(binding->bindings))) { binding->bt = XML_LDAP_DIALPLAN; } else if (!strncmp(binding->bindings, "phrases",strlen(binding->bindings))) { @@ -131,6 +176,79 @@ static switch_status_t do_config(void) { } + if ( binding && binding->bt == XML_LDAP_DIRECTORY ) { + attr_list = malloc(sizeof(*attr_list)); + attr_list = memset(attr_list,0,sizeof(*attr_list)); + binding->attr_list = attr_list; + + param = switch_xml_child(binding_tag, "trans"); + for ( tran = switch_xml_child(param, "tran"); tran; tran = tran->next) { + char *n = (char *) switch_xml_attr_soft(tran, "name"); + char *m = (char *) switch_xml_attr_soft(tran, "mapfrom"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, " adding map %s => %s\n", m , n); + if(!strncasecmp("id",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_ID; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } else if ( !strncasecmp("mailbox",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_VM_MAILBOX; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } else if ( !strncasecmp("password",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_PASSWORD; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } else if ( !strncasecmp("vm-password",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_VM_PASSWORD; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } else if ( !strncasecmp("email-addr",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_VM_EMAILADDR; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } else if ( !strncasecmp("vm-email-all-messages",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_VM_EMAILMSG; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } else if ( !strncasecmp("vm-delete-file",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_VM_DELETE; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } else if ( !strncasecmp("vm-attach-file",n,strlen(n))) { + attr_list->type = LDAP_EXTEN_VM_ATTACHAUDIO; + attr_list->len = strlen(m); + attr_list->val = strdup(m); + attr_list->next = malloc(sizeof(*attr_list)); + attr_list->next = memset(attr_list->next,0,sizeof(*attr_list)); + attr_list = attr_list->next; + } + + } + attr_list->next = NULL; + } + + if (!binding->basedn || !binding->filter || !binding->url) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "You must define \"basedn\", and \"filter\" in mod_xml_ldap.conf.xml\n"); @@ -153,18 +271,22 @@ static switch_status_t do_config(void) { return SWITCH_STATUS_SUCCESS; } -static switch_status_t tryh350(switch_xml_t *pxml, int *xoff, LDAP *ld, char *basedn, char *dir_domain, char *dir_exten) { +static switch_status_t trydir(switch_xml_t *pxml, int *xoff, LDAP *ld, char *dir_domain, char *dir_exten, xml_binding_t *binding) { switch_status_t ret = SWITCH_STATUS_FALSE; int off = *xoff; char *key = NULL; + char *basedn = NULL, *filter = NULL; char **val = NULL; - char *filter = NULL; BerElement *ber = NULL; - switch_xml_t xml = *pxml, save; + switch_xml_t xml = *pxml, params = NULL, vars = NULL, cur = NULL; LDAPMessage *msg, *entry; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "trying h350search in base %s with filter SIPIdentityUserName=%s\n", basedn, dir_exten); + static char *fsattr[] = { "id" , "mailbox", "password", "vm-password", "email-addr", "vm-email-all-messages", "vm-delete-file", "vm-attach-file", NULL }; - filter = switch_mprintf("(SIPIdentityUserName=%s)",dir_exten); + basedn = switch_mprintf(binding->basedn,dir_domain); + filter = switch_mprintf(binding->filter,dir_exten); + xml_ldap_attribute_t *attr = NULL; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "searching in basedn %s with filter %s\n",basedn,filter ); if ( (ldap_search_s(ld, basedn, LDAP_SCOPE_SUB, filter, NULL, 0, &msg) != LDAP_SUCCESS) ) goto cleanup; @@ -177,18 +299,11 @@ static switch_status_t tryh350(switch_xml_t *pxml, int *xoff, LDAP *ld, char *ba switch_xml_set_attr_d(xml, "name", dir_domain); xml = switch_xml_add_child_d(xml, "user", off++); - switch_xml_set_attr_d(xml, "id", dir_exten); - switch_xml_set_attr_d(xml, "mailbox", dir_exten); - save = switch_xml_add_child_d(xml, "variables", off++); - xml = switch_xml_add_child_d(save, "variable", off++); - switch_xml_set_attr_d(xml, "name", "accountcode"); - switch_xml_set_attr_d(xml, "value", dir_exten); + vars = switch_xml_add_child_d(xml, "variables", off++); + params = switch_xml_add_child_d(xml, "params", off++); - xml = save; - save = switch_xml_add_child_d(xml, "params", off++); - xml = switch_xml_add_child_d(save, "param", off++); for ( entry = ldap_first_entry(ld, msg); entry != NULL; @@ -200,20 +315,30 @@ static switch_status_t tryh350(switch_xml_t *pxml, int *xoff, LDAP *ld, char *ba key != NULL; key = ldap_next_attribute(ld, entry, ber) ) { - if ( !strncasecmp(key,"SIPIdentityPassword",strlen(key)) ) { - val = ldap_get_values(ld,entry,key); - switch_xml_set_attr_d(xml, "name", "password"); - switch_xml_set_attr_d(xml, "value", val[0]); - xml = switch_xml_add_child_d(save, "param", off++); - switch_xml_set_attr_d(xml, "name", "vm-password"); - switch_xml_set_attr_d(xml, "value", val[0]); - ldap_memfree(key); - ldap_value_free(val); - } else { - ldap_memfree(key); - continue; + for( attr = binding->attr_list; attr ; attr = attr->next ) { + if ( strlen(key) == attr->len ) { + if ( !strncasecmp(attr->val,key,strlen(key)) ) { + val = ldap_get_values(ld,entry,key); + if ( ldap_count_values(val) == 1 ) { + if (attr->type < 2) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "setting %s = %s ", fsattr[attr->type], val[0]); + switch_xml_set_attr_d(xml,fsattr[attr->type],val[0]); + } else if ( attr->type < 8 ) { + cur = switch_xml_add_child_d(params,"param",0); + switch_xml_set_attr_d(cur,fsattr[attr->type],val[0]); + } else { + cur = switch_xml_add_child_d(vars,"variable",0); + switch_xml_set_attr_d(cur,fsattr[attr->type],val[0]); + } + } else { + /* multi val attrs */ + } + ldap_value_free(val); + continue; + } + } } - + ldap_memfree(key); } ber_free(ber,0); } @@ -226,7 +351,9 @@ static switch_status_t tryh350(switch_xml_t *pxml, int *xoff, LDAP *ld, char *ba cleanup: switch_safe_free(filter); - switch_safe_free(key); + switch_safe_free(basedn) + switch_safe_free(dir_exten); + switch_safe_free(dir_domain); return ret; } @@ -358,6 +485,7 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c xml_binding_t *binding = (xml_binding_t *) user_data; switch_event_header_t *hi; + switch_status_t ret = SWITCH_STATUS_FALSE; int desired_version = LDAP_VERSION3; int auth_method = LDAP_AUTH_SIMPLE; @@ -373,6 +501,9 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c int xoff = 0; + xml = switch_xml_new("document"); + switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); + if (params) { if ((hi = params->headers)) { for (; hi; hi = hi->next) { @@ -396,23 +527,24 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c } } } + + + + if( (ldap_initialize(&ld,binding->url)) != LDAP_SUCCESS ) goto cleanup; + if( (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version)) != LDAP_SUCCESS ) goto cleanup; + if( (ldap_bind_s(ld, binding->binddn, binding->bindpass, auth_method)) != LDAP_SUCCESS ) goto cleanup; + switch (binding->bt) { case XML_LDAP_CONFIG: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "humm %s", binding->filter); + xml = switch_xml_add_child_d(xml, "section", xoff++); + switch_xml_set_attr_d(xml, "name", "configuration"); filter = switch_mprintf(binding->filter,key_name,key_value); basedn = switch_mprintf(binding->basedn,tag_name); + ret = trysearch(&xml,&xoff,ld, basedn, filter); break; case XML_LDAP_DIRECTORY: - if(!dir_exten) { - filter = switch_mprintf(binding->filter,"objectclass","*","(!(objectclass=fsuser))"); - basedn = switch_mprintf(binding->basedn,dir_domain); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting filter %s and basedn %s\n", filter, basedn); - } else { - filter = switch_mprintf(binding->filter,"id",dir_exten,"(objectclass=*)"); - basedn = switch_mprintf(binding->basedn,dir_domain); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setting filter %s and basedn %s\n", filter, basedn); - } + ret = trydir(&xml,&xoff,ld,dir_domain,dir_exten, binding); break; case XML_LDAP_DIALPLAN: @@ -423,25 +555,19 @@ static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, c } - ldap_initialize(&ld,binding->url); - ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version); - ldap_bind_s(ld, binding->binddn, binding->bindpass, auth_method); - - xml = switch_xml_new("document"); - switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); - - trysearch(&xml,&xoff,ld, basedn, filter); - if(binding->bt == XML_LDAP_DIRECTORY ) tryh350(&xml,&xoff,ld,binding->h350base, dir_domain, dir_exten); - + cleanup: ldap_unbind_s(ld); - - switch_xml_toxml_buf(xml,buf,0,0,1); printf("providing:\n%s\n", buf); switch_safe_free(buf); + + if(ret != SWITCH_STATUS_SUCCESS) { + switch_xml_free(xml); + return NULL; + } return xml; }