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;
}
Beispiel #2
0
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;
}