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 = NULL, sub = NULL; struct ldap_c ldap_connection; struct ldap_c *ldap = &ldap_connection; int auth_method = LDAP_AUTH_SIMPLE; int desired_version = LDAP_VERSION3; xml_ldap_query_type_t query_type; char *dir_exten = NULL, *dir_domain = NULL; char *search_filter = NULL, *search_base = NULL; int off = 0, ret = 1; //char *buf; //buf = malloc(4096); 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 = XML_LDAP_CONFIG; } else if (!strcmp(section, "directory")) { query_type = XML_LDAP_DIRECTORY; } else if (!strcmp(section, "dialplan")) { query_type = XML_LDAP_DIALPLAN; } else if (!strcmp(section, "phrases")) { query_type = XML_LDAP_PHRASE; } else if (!strcmp(section, "languages")) { query_type = XML_LDAP_LANGUAGE; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n"); return NULL; } 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: case XML_LDAP_PHRASE: case XML_LDAP_LANGUAGE: break; } } switch (query_type) { case XML_LDAP_CONFIG: break; case XML_LDAP_DIRECTORY: if (dir_exten && dir_domain) { if ((xml = switch_xml_new("directory"))) { switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); if ((sub = switch_xml_add_child_d(xml, "section", off++))) { switch_xml_set_attr_d(sub, "name", "directory"); } if ((sub = switch_xml_add_child_d(sub, "domain", off++))) { switch_xml_set_attr_d(sub, "name", dir_domain); } if ((sub = switch_xml_add_child_d(sub, "user", off++))) { switch_xml_set_attr_d(sub, "id", dir_exten); } } search_filter = switch_mprintf(binding->filter, dir_exten); search_base = switch_mprintf(binding->basedn, dir_domain); 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: if ((xml = switch_xml_new("document"))) { switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); if ((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++); } break; case XML_LDAP_PHRASE: case XML_LDAP_LANGUAGE: break; } } else { goto cleanup; } } if ((ldap->ld = (LDAP *) 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; } ldap_set_option(ldap->ld, LDAP_OPT_X_SASL_SECPROPS, &ldap->sp); if (binding->binddn) { 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; } } else { if (ldap_sasl_interactive_bind_s (ldap->ld, NULL, binding->defaults->mech, NULL, NULL, (unsigned) (intptr_t) LDAP_SASL_SIMPLE, lutil_sasl_interact, binding->defaults) != LDAP_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to sasl_bind to ldap server %s as %s\n", binding->host, binding->defaults->authcid); goto cleanup; } } if (ldap_search_s(ldap->ld, search_base, LDAP_SCOPE_SUBTREE, search_filter, NULL, 0, &ldap->msg) != LDAP_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Query failed: -b \"%s\" \"%s\"\n", search_base, search_filter); goto cleanup; } if (ldap_count_entries(ldap->ld, ldap->msg) <= 0) { goto cleanup; } if (sub && xml_ldap_result(&ldap_connection, binding, &sub, &off, query_type) != SWITCH_STATUS_SUCCESS) { goto cleanup; } ret = 0; cleanup: if (ldap->msg) { ldap_msgfree(ldap->msg); } if (ldap->ld) { ldap_unbind_s(ldap->ld); } switch_safe_free(search_filter); switch_safe_free(search_base); //switch_xml_toxml_buf(xml,buf,0,0,1); //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Providing:\n%s\n", buf); if (ret) { switch_xml_free(xml); return NULL; } return xml; }
switch_xml_t mod_xml_radius_auth_reg(switch_event_t *params) { int result = 0, param_idx = 0; VALUE_PAIR *send = NULL, *recv = NULL, *service_vp = NULL; char msg[512 * 10 + 1] = {0}; uint32_t service = PW_AUTHENTICATE_ONLY; rc_handle *new_handle = NULL; switch_xml_t fields, xml, dir, dom, usr, vars, var; char name[512], value[512], *strtmp; if (GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: starting registration authentication\n"); } if ( mod_xml_radius_new_handle(&new_handle, globals.auth_invite_configs) != SWITCH_STATUS_SUCCESS ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load radius handle for registration authentication\n"); goto err; } if ( new_handle == NULL ) { goto err; } if ((fields = switch_xml_child(globals.auth_reg_configs, "fields")) == NULL ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find 'fields' section in config file.\n"); goto err; } if ( mod_xml_radius_add_params(NULL, params, new_handle, &send, fields) != SWITCH_STATUS_SUCCESS ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to add params to rc_handle\n"); goto err; } if (rc_avpair_add(new_handle, &send, PW_SERVICE_TYPE, &service, -1, 0) == NULL) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: failed to add option to handle\n"); goto err; } result = rc_auth(new_handle, 0, send, &recv, msg); if ( GLOBAL_DEBUG ){ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: result(RC=%d) %s \n", result, msg); } if ( result != 0 ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mod_xml_radius: Failed to authenticate\n"); goto err; } xml = switch_xml_new("document"); switch_xml_set_attr_d(xml, "type", "freeswitch/xml"); dir = switch_xml_add_child_d(xml, "section", 0); switch_xml_set_attr_d(dir, "name", "directory"); dom = switch_xml_add_child_d(dir, "domain", 0); switch_xml_set_attr_d(dom, "name", switch_event_get_header(params, "domain")); usr = switch_xml_add_child_d(dom, "user", 0); vars = switch_xml_add_child_d(usr, "variables", 0); switch_xml_set_attr_d(usr, "id", switch_event_get_header(params, "user")); service_vp = recv; while (service_vp != NULL) { rc_avpair_tostr(new_handle, service_vp, name, 512, value, 512); if ( GLOBAL_DEBUG ) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "\tattribute (%s)[%s] found in radius packet\n", name, value); var = switch_xml_add_child_d(vars, "variable", param_idx++); strtmp = strdup(name); switch_xml_set_attr_d(var, "name", strtmp); free(strtmp); strtmp = strdup(value); switch_xml_set_attr_d(var, "value", strtmp); free(strtmp); service_vp = service_vp->next; } if ( GLOBAL_DEBUG ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "XML: %s \n", switch_xml_toxml(xml, 1)); } if ( recv ) { rc_avpair_free(recv); recv = NULL; } if ( send ) { rc_avpair_free(send); send = NULL; } if ( new_handle ) { rc_destroy(new_handle); new_handle = NULL; } return xml; err: if ( recv ) { rc_avpair_free(recv); recv = NULL; } if ( send ) { rc_avpair_free(send); send = NULL; } if ( new_handle ) { rc_destroy(new_handle); new_handle = NULL; } return NULL; }