Update LDAP provider to handle connection asynchronously.

This is done through a thread which is launched to keep the UI responsive.

Also configured the default server to "localhost" so that misconfiguration
doesn't query example.com...
This commit is contained in:
Guillaume BIENKOWSKI 2013-12-30 17:07:10 +01:00
parent 6d989a4260
commit fd407a9f8d
2 changed files with 146 additions and 146 deletions

View file

@ -18,6 +18,7 @@
#include "private.h" #include "private.h"
#include "lpconfig.h" #include "lpconfig.h"
#include "contact_providers_priv.h" #include "contact_providers_priv.h"
#include "mediastreamer2/mscommon.h"
#include <belle-sip/dict.h> #include <belle-sip/dict.h>
#ifdef BUILD_LDAP #ifdef BUILD_LDAP
@ -28,12 +29,6 @@
#define MAX_RUNNING_REQUESTS 10 #define MAX_RUNNING_REQUESTS 10
#define FILTER_MAX_SIZE 512 #define FILTER_MAX_SIZE 512
typedef enum {
ANONYMOUS,
PLAIN,
SASL
} LDAPAuthMethod;
struct LDAPFriendData { struct LDAPFriendData {
char* name; char* name;
char* sip; char* sip;
@ -49,16 +44,19 @@ struct _LinphoneLDAPContactProvider
uint req_count; uint req_count;
// bind transaction // bind transaction
int bind_msgid;
const char* auth_mechanism;
bool_t connected; bool_t connected;
ms_thread_t bind_thread;
// config // config
int use_tls; int use_tls;
LDAPAuthMethod auth_method; const char* auth_method;
const char* username; const char* username;
const char* password; const char* password;
const char* server; const char* server;
const char* bind_dn;
const char* sasl_authname;
const char* sasl_realm;
const char* base_object; const char* base_object;
const char* sip_attr; const char* sip_attr;
@ -70,6 +68,7 @@ struct _LinphoneLDAPContactProvider
int timeout; int timeout;
int deref_aliases; int deref_aliases;
int max_results; int max_results;
}; };
struct _LinphoneLDAPContactSearch struct _LinphoneLDAPContactSearch
@ -92,7 +91,6 @@ LinphoneLDAPContactSearch* linphone_ldap_contact_search_create(LinphoneLDAPConta
{ {
LinphoneLDAPContactSearch* search = belle_sip_object_new(LinphoneLDAPContactSearch); LinphoneLDAPContactSearch* search = belle_sip_object_new(LinphoneLDAPContactSearch);
LinphoneContactSearch* base = LINPHONE_CONTACT_SEARCH(search); LinphoneContactSearch* base = LINPHONE_CONTACT_SEARCH(search);
struct timeval timeout = { cp->timeout, 0 };
linphone_contact_search_init(base, predicate, cb, cb_data); linphone_contact_search_init(base, predicate, cb, cb_data);
@ -102,27 +100,6 @@ LinphoneLDAPContactSearch* linphone_ldap_contact_search_create(LinphoneLDAPConta
snprintf(search->filter, FILTER_MAX_SIZE-1, cp->filter, predicate); snprintf(search->filter, FILTER_MAX_SIZE-1, cp->filter, predicate);
search->filter[FILTER_MAX_SIZE-1] = 0; search->filter[FILTER_MAX_SIZE-1] = 0;
ms_message("Calling ldap_search_ext with predicate '%s' on base %s", search->filter, cp->base_object);
int ret = ldap_search_ext(search->ld,
cp->base_object, // base from which to start
LDAP_SCOPE_SUBTREE,
search->filter, // search predicate
cp->attributes, // which attributes to get
0, // 0 = get attrs AND value, 1 = get attrs only
NULL,
NULL,
&timeout, // server timeout for the search
cp->max_results,// max result number
&search->msgid );
if( ret != LDAP_SUCCESS ){
ms_error("Error ldap_search_ext returned %d (%s)", ret, ldap_err2string(ret));
belle_sip_object_unref(search);
return NULL;
} else {
ms_message("LinphoneLDAPContactSearch created @%p : msgid %d", search, search->msgid);
}
return search; return search;
} }
@ -136,7 +113,6 @@ unsigned int linphone_ldap_contact_search_result_count(LinphoneLDAPContactSearch
return obj->found_count; return obj->found_count;
} }
static void linphone_ldap_contact_search_destroy( LinphoneLDAPContactSearch* obj ) static void linphone_ldap_contact_search_destroy( LinphoneLDAPContactSearch* obj )
{ {
//ms_message("~LinphoneLDAPContactSearch(%p)", obj); //ms_message("~LinphoneLDAPContactSearch(%p)", obj);
@ -163,31 +139,7 @@ static unsigned int linphone_ldap_contact_provider_cancel_search(LinphoneContact
static void linphone_ldap_contact_provider_conf_destroy(LinphoneLDAPContactProvider* obj ); static void linphone_ldap_contact_provider_conf_destroy(LinphoneLDAPContactProvider* obj );
static bool_t linphone_ldap_contact_provider_iterate(void *data); static bool_t linphone_ldap_contact_provider_iterate(void *data);
static int linphone_ldap_contact_provider_bind_interact(LDAP *ld, unsigned flags, void *defaults, void *sasl_interact); static int linphone_ldap_contact_provider_bind_interact(LDAP *ld, unsigned flags, void *defaults, void *sasl_interact);
static int linphone_ldap_contact_provider_perform_search( LinphoneLDAPContactProvider* obj, LinphoneLDAPContactSearch* req);
/* Authentication methods */
struct AuthMethodDescription{
LDAPAuthMethod method;
const char* description;
};
static struct AuthMethodDescription ldap_auth_method_description[] = {
{ANONYMOUS, "anonymous"},
{PLAIN, "plain"},
{SASL, "sasl"},
{0, NULL}
};
static LDAPAuthMethod linphone_ldap_contact_provider_auth_method( const char* description )
{
struct AuthMethodDescription* desc = ldap_auth_method_description;
while( desc && desc->description ){
if( strcmp(description, desc->description) == 0)
return desc->method;
desc++;
}
return ANONYMOUS;
}
static void linphone_ldap_contact_provider_destroy_request_cb(void *req) static void linphone_ldap_contact_provider_destroy_request_cb(void *req)
{ {
@ -210,38 +162,6 @@ static void linphone_ldap_contact_provider_destroy( LinphoneLDAPContactProvider*
linphone_ldap_contact_provider_conf_destroy(obj); linphone_ldap_contact_provider_conf_destroy(obj);
} }
static int linphone_ldap_contact_provider_parse_bind_results( LinphoneLDAPContactProvider* obj, LDAPMessage* results )
{
int ret;
if( obj->auth_method == ANONYMOUS ) {
ms_message("ANONYMOUS BIND OK");
ret = LDAP_SUCCESS;
} else {
ms_message("Advanced BIND follow-up");
ret = ldap_sasl_interactive_bind(obj->ld,
NULL, // dn, should be NULL
"DIGEST-MD5", // TODO: use defined auth
NULL,NULL, // server and client controls
LDAP_SASL_QUIET, // never prompt, only use callback
linphone_ldap_contact_provider_bind_interact, // callback to call when info is needed
obj, // private data
results, // result, to pass later on when a ldap_result() comes
&obj->auth_mechanism,
&obj->bind_msgid );
if( ret != LDAP_SUCCESS){
ms_error("ldap_parse_sasl_bind_result failed(%d)", ret);
}
}
if( ret == LDAP_SUCCESS ){
obj->connected = TRUE;
obj->bind_msgid = 0;
}
return ret;
}
static int linphone_ldap_contact_provider_complete_contact( LinphoneLDAPContactProvider* obj, struct LDAPFriendData* lf, const char* attr_name, const char* attr_value) static int linphone_ldap_contact_provider_complete_contact( LinphoneLDAPContactProvider* obj, struct LDAPFriendData* lf, const char* attr_name, const char* attr_value)
{ {
if( strcmp(attr_name, obj->name_attr ) == 0 ){ if( strcmp(attr_name, obj->name_attr ) == 0 ){
@ -335,7 +255,7 @@ static void linphone_ldap_contact_provider_handle_search_result( LinphoneLDAPCon
static bool_t linphone_ldap_contact_provider_iterate(void *data) static bool_t linphone_ldap_contact_provider_iterate(void *data)
{ {
LinphoneLDAPContactProvider* obj = LINPHONE_LDAP_CONTACT_PROVIDER(data); LinphoneLDAPContactProvider* obj = LINPHONE_LDAP_CONTACT_PROVIDER(data);
if( obj->ld && ((obj->req_count > 0) || (obj->bind_msgid != 0) )){ if( obj->ld && obj->connected && (obj->req_count > 0) ){
// never block // never block
struct timeval timeout = {0,0}; struct timeval timeout = {0,0};
@ -346,19 +266,14 @@ static bool_t linphone_ldap_contact_provider_iterate(void *data)
switch( ret ){ switch( ret ){
case -1: case -1:
{ {
ms_warning("Error in ldap_result : returned -1 (req_count %d, bind_msgid %d): %s", obj->req_count, obj->bind_msgid, ldap_err2string(errno)); ms_warning("Error in ldap_result : returned -1 (req_count %d): %s", obj->req_count, ldap_err2string(errno));
break; break;
} }
case 0: break; // nothing to do case 0: break; // nothing to do
case LDAP_RES_BIND: case LDAP_RES_BIND:
{ {
ms_message("iterate: LDAP_RES_BIND"); ms_error("iterate: unexpected LDAP_RES_BIND");
if( ldap_msgid( results ) != obj->bind_msgid ) {
ms_error("Bad msgid");
} else {
linphone_ldap_contact_provider_parse_bind_results( obj, results );
}
break; break;
} }
case LDAP_RES_EXTENDED: case LDAP_RES_EXTENDED:
@ -389,6 +304,20 @@ static bool_t linphone_ldap_contact_provider_iterate(void *data)
if( results ) if( results )
ldap_msgfree(results); ldap_msgfree(results);
} }
if( obj->ld && obj->connected ){
// check for pending searches
uint i;
for( i=0; i<obj->req_count; i++){
LinphoneLDAPContactSearch* search = (LinphoneLDAPContactSearch*)ms_list_nth_data( obj->requests, i );
if( search && search->msgid == 0){
ms_message("Found pending search %p (for %s), launching...", search, search->filter);
linphone_ldap_contact_provider_perform_search(obj, search);
}
}
}
return TRUE; return TRUE;
} }
@ -410,6 +339,9 @@ static char* required_config_keys[] = {
"auth_method", "auth_method",
"username", "username",
"password", "password",
"bind_dn",
"sasl_authname",
"sasl_realm",
// search // search
"base_object", "base_object",
@ -455,24 +387,25 @@ static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvide
// clone new config into the dictionary // clone new config into the dictionary
obj->config = linphone_dictionary_ref(linphone_dictionary_clone(dict)); obj->config = linphone_dictionary_ref(linphone_dictionary_clone(dict));
#if 0 // until sasl auth is set up, force anonymous auth.
linphone_dictionary_set_string(obj->config, "auth_method", "ANONYMOUS");
#endif
obj->use_tls = linphone_dictionary_get_int(obj->config, "use_tls", 0); obj->use_tls = linphone_dictionary_get_int(obj->config, "use_tls", 0);
obj->timeout = linphone_dictionary_get_int(obj->config, "timeout", 10); obj->timeout = linphone_dictionary_get_int(obj->config, "timeout", 10);
obj->deref_aliases = linphone_dictionary_get_int(obj->config, "deref_aliases", 0); obj->deref_aliases = linphone_dictionary_get_int(obj->config, "deref_aliases", 0);
obj->max_results = linphone_dictionary_get_int(obj->config, "max_results", 50); obj->max_results = linphone_dictionary_get_int(obj->config, "max_results", 50);
obj->auth_method = linphone_dictionary_get_string(obj->config, "auth_method", "ANONYMOUS");
obj->username = linphone_dictionary_get_string(obj->config, "username", ""); obj->username = linphone_dictionary_get_string(obj->config, "username", "");
obj->password = linphone_dictionary_get_string(obj->config, "password", ""); obj->password = linphone_dictionary_get_string(obj->config, "password", "");
obj->bind_dn = linphone_dictionary_get_string(obj->config, "bind_dn", "");
obj->base_object = linphone_dictionary_get_string(obj->config, "base_object", "dc=example,dc=com"); obj->base_object = linphone_dictionary_get_string(obj->config, "base_object", "dc=example,dc=com");
obj->server = linphone_dictionary_get_string(obj->config, "server", "ldap://192.168.0.230:10389"); obj->server = linphone_dictionary_get_string(obj->config, "server", "ldap://localhost");
obj->filter = linphone_dictionary_get_string(obj->config, "filter", "uid=*%s*"); obj->filter = linphone_dictionary_get_string(obj->config, "filter", "uid=*%s*");
obj->name_attr = linphone_dictionary_get_string(obj->config, "name_attribute", "givenName"); obj->name_attr = linphone_dictionary_get_string(obj->config, "name_attribute", "givenName");
obj->sip_attr = linphone_dictionary_get_string(obj->config, "sip_attribute", "mobile"); obj->sip_attr = linphone_dictionary_get_string(obj->config, "sip_attribute", "mobile");
obj->sasl_authname = linphone_dictionary_get_string(obj->config, "sasl_authname", "");
/* obj->sasl_realm = linphone_dictionary_get_string(obj->config, "sasl_realm", "");
* Get authentication method
*/
obj->auth_method = linphone_ldap_contact_provider_auth_method(
linphone_dictionary_get_string(obj->config, "auth_method", "anonymous")
);
/* /*
* parse the attributes list * parse the attributes list
@ -520,20 +453,23 @@ static int linphone_ldap_contact_provider_bind_interact(LDAP *ld,
switch( interact->id ) { switch( interact->id ) {
case SASL_CB_GETREALM: case SASL_CB_GETREALM:
ms_message("* SASL_CB_GETREALM"); ms_message("* SASL_CB_GETREALM -> %s", obj->sasl_realm);
dflt=NULL; dflt = obj->sasl_realm;
break;
case SASL_CB_AUTHNAME:
ms_message("* SASL_CB_AUTHNAME -> %s", obj->sasl_authname);
dflt = obj->sasl_authname;
break; break;
case SASL_CB_USER: case SASL_CB_USER:
case SASL_CB_AUTHNAME: ms_message("* SASL_CB_USER -> %s", obj->username);
ms_message("* SASL_CB_AUTHNAME -> %s", obj->username); dflt = obj->username;
dflt=obj->username;
break; break;
case SASL_CB_PASS: case SASL_CB_PASS:
ms_message("* SASL_CB_PASS -> %s", obj->password); ms_message("* SASL_CB_PASS (hidden)");
dflt=obj->password; dflt = obj->password;
break; break;
default: default:
ms_message("my_sasl_interact asked for unknown %lx\n",interact->id); ms_message("SASL interact asked for unknown id %lx\n",interact->id);
} }
interact->result = (dflt && *dflt) ? dflt : (const char*)""; interact->result = (dflt && *dflt) ? dflt : (const char*)"";
interact->len = strlen( (const char*)interact->result ); interact->len = strlen( (const char*)interact->result );
@ -543,32 +479,42 @@ static int linphone_ldap_contact_provider_bind_interact(LDAP *ld,
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
static int linphone_ldap_contact_provider_bind( LinphoneLDAPContactProvider* obj ) static void* ldap_bind_thread_func( void*arg)
{ {
LinphoneLDAPContactProvider* obj = linphone_ldap_contact_provider_ref(arg);
const char* auth_mechanism = obj->auth_method;
int ret; int ret;
const char* auth_mechanism = linphone_dictionary_get_string(obj->config, "auth_method", "anonymous");
LDAPAuthMethod method = obj->auth_method;
if( method == ANONYMOUS ){ if( (strcmp(auth_mechanism, "ANONYMOUS") == 0) || (strcmp(auth_mechanism, "SIMPLE") == 0) )
// for anonymous authentication, use a simple sasl_bind {
struct berval creds = {strlen(obj->password), ms_strdup(obj->password)}; struct berval passwd = { strlen(obj->password), ms_strdup(obj->password)};
ret = ldap_sasl_bind(obj->ld, obj->base_object, NULL, &creds, NULL, NULL, &obj->bind_msgid); auth_mechanism = LDAP_SASL_SIMPLE;
if(creds.bv_val) ms_free(creds.bv_val); ret = ldap_sasl_bind_s(obj->ld,
} else { obj->bind_dn,
ret = ldap_sasl_interactive_bind(obj->ld, auth_mechanism,
NULL, // dn, should be NULL &passwd,
"SIMPLE",//"DIGEST-MD5", NULL,
NULL,NULL, // server and client controls NULL,
LDAP_SASL_QUIET, // never prompt, only use callback NULL);
linphone_ldap_contact_provider_bind_interact, // callback to call when info is needed
obj, // private data ms_free(passwd.bv_val);
NULL, // result, to pass later on when a ldap_result() comes
&obj->auth_mechanism,
&obj->bind_msgid );
} }
if( ret == LDAP_SUCCESS || ret == LDAP_SASL_BIND_IN_PROGRESS ) { else
if( ret == LDAP_SASL_BIND_IN_PROGRESS) ms_message("BIND_IN_PROGRESS"); {
ms_message("LDAP bind request sent, auth: %s, msgid %x", obj->auth_mechanism?obj->auth_mechanism:"-", obj->bind_msgid);
ms_message("LDAP interactive bind");
ret = ldap_sasl_interactive_bind_s(obj->ld,
obj->bind_dn,
auth_mechanism,
NULL,NULL,
LDAP_SASL_QUIET,
linphone_ldap_contact_provider_bind_interact,
obj);
}
if( ret == LDAP_SUCCESS ) {
ms_message("LDAP bind OK");
obj->connected = 1;
} else { } else {
int err; int err;
ldap_get_option(obj->ld, LDAP_OPT_RESULT_CODE, &err); ldap_get_option(obj->ld, LDAP_OPT_RESULT_CODE, &err);
@ -576,6 +522,15 @@ static int linphone_ldap_contact_provider_bind( LinphoneLDAPContactProvider* obj
ret, err, ldap_err2string(err), auth_mechanism ); ret, err, ldap_err2string(err), auth_mechanism );
} }
obj->bind_thread = 0;
linphone_ldap_contact_provider_unref(obj);
return (void*)0;
}
static int linphone_ldap_contact_provider_bind( LinphoneLDAPContactProvider* obj )
{
// perform the bind in an alternate thread, so that we don't stall the main loop
ms_thread_create(&obj->bind_thread, NULL, ldap_bind_thread_func, obj);
return 0; return 0;
} }
@ -619,7 +574,7 @@ LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore*
} else { } else {
// prevents blocking calls to bind() when the server is invalid, but this is not working for now.. // prevents blocking calls to bind() when the server is invalid, but this is not working for now..
// see bug https://bugzilla.mozilla.org/show_bug.cgi?id=79509 // see bug https://bugzilla.mozilla.org/show_bug.cgi?id=79509
ldap_set_option( obj->ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_ON); //ldap_set_option( obj->ld, LDAP_OPT_CONNECT_ASYNC, LDAP_OPT_ON);
// register our hook into iterate so that LDAP can do its magic asynchronously. // register our hook into iterate so that LDAP can do its magic asynchronously.
linphone_core_add_iterate_hook(lc, linphone_ldap_contact_provider_iterate, obj); linphone_core_add_iterate_hook(lc, linphone_ldap_contact_provider_iterate, obj);
@ -678,22 +633,67 @@ static unsigned int linphone_ldap_contact_provider_cancel_search(LinphoneContact
return ret; return ret;
} }
static int linphone_ldap_contact_provider_perform_search( LinphoneLDAPContactProvider* obj, LinphoneLDAPContactSearch* req)
{
int ret = -1;
struct timeval timeout = { obj->timeout, 0 };
if( req->msgid == 0 ){
ms_message ( "Calling ldap_search_ext with predicate '%s' on base %s", req->filter, obj->base_object );
ret = ldap_search_ext(obj->ld,
obj->base_object,// base from which to start
LDAP_SCOPE_SUBTREE,
req->filter, // search predicate
obj->attributes, // which attributes to get
0, // 0 = get attrs AND value, 1 = get attrs only
NULL,
NULL,
&timeout, // server timeout for the search
obj->max_results,// max result number
&req->msgid );
if( ret != LDAP_SUCCESS ){
ms_error("Error ldap_search_ext returned %d (%s)", ret, ldap_err2string(ret));
} else {
ms_message("LinphoneLDAPContactSearch created @%p : msgid %d", req, req->msgid);
}
} else {
ms_warning( "LDAP Search already performed for %s, msgid %d", req->filter, req->msgid);
}
return ret;
}
static LinphoneLDAPContactSearch* linphone_ldap_contact_provider_begin_search ( LinphoneLDAPContactProvider* obj, static LinphoneLDAPContactSearch* linphone_ldap_contact_provider_begin_search ( LinphoneLDAPContactProvider* obj,
const char* predicate, const char* predicate,
ContactSearchCallback cb, ContactSearchCallback cb,
void* cb_data ) void* cb_data )
{ {
bool_t connected = obj->connected;
// if we're not yet connected, bind // if we're not yet connected, bind
if( !obj->connected ) linphone_ldap_contact_provider_bind(obj); if( !connected ) {
if( !obj->bind_thread ) linphone_ldap_contact_provider_bind(obj);
}
LinphoneLDAPContactSearch* request = linphone_ldap_contact_search_create ( obj, predicate, cb, cb_data ); LinphoneLDAPContactSearch* request = linphone_ldap_contact_search_create( obj, predicate, cb, cb_data );
if ( request != NULL ) { if( connected ){
int ret = linphone_ldap_contact_provider_perform_search(obj, request);
ms_message ( "Created search %d for '%s', msgid %d, @%p", obj->req_count, predicate, request->msgid, request ); ms_message ( "Created search %d for '%s', msgid %d, @%p", obj->req_count, predicate, request->msgid, request );
if( ret != LDAP_SUCCESS ){
belle_sip_object_unref(request);
request = NULL;
}
} else {
ms_message("Delayed search, wait for connection");
}
obj->requests = ms_list_append ( obj->requests, request ); if( request != NULL ) {
obj->requests = ms_list_append ( obj->requests, request );
obj->req_count++; obj->req_count++;
} }
return request; return request;
} }
@ -708,13 +708,10 @@ static int linphone_ldap_contact_provider_marshal(LinphoneLDAPContactProvider* o
error = belle_sip_snprintf(buff, buff_size, offset, "req_count:%d,\n", obj->req_count); error = belle_sip_snprintf(buff, buff_size, offset, "req_count:%d,\n", obj->req_count);
if(error!= BELLE_SIP_OK) return error; if(error!= BELLE_SIP_OK) return error;
error = belle_sip_snprintf(buff, buff_size, offset, "bind_msgid:%d,\n", obj->bind_msgid);
if(error!= BELLE_SIP_OK) return error;
error = belle_sip_snprintf(buff, buff_size, offset, error = belle_sip_snprintf(buff, buff_size, offset,
"CONFIG:\n" "CONFIG:\n"
"tls: %d \n" "tls: %d \n"
"auth: %d \n" "auth: %s \n"
"user: %s \n" "user: %s \n"
"pass: %s \n" "pass: %s \n"
"server: %s \n" "server: %s \n"

View file

@ -76,7 +76,7 @@ static void linphone_gtk_ldap_load_settings(GtkWidget* param)
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_server")); entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_server"));
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"server", "ldap://example.com") ); gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"server", "ldap://localhost") );
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_username")); entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_username"));
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"username", "") ); gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"username", "") );
@ -86,7 +86,7 @@ static void linphone_gtk_ldap_load_settings(GtkWidget* param)
// TODO // TODO
// GtkComboBox* cbox = GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"ldap_auth_method")); // GtkComboBox* cbox = GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"ldap_auth_method"));
// gtk_combo_box_set_active(entry, linphone_dictionary_get_string(ldap_conf,"auth_method", "anonymous") ); // gtk_combo_box_set_active(entry, linphone_dictionary_get_string(ldap_conf,"auth_method", "ANONYMOUS") );
entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_base_object")); entry = GTK_ENTRY(linphone_gtk_get_widget(pb,"ldap_base_object"));
gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"base_object", "dc=example,dc=com") ); gtk_entry_set_text(entry, linphone_dictionary_get_string(ldap_conf,"base_object", "dc=example,dc=com") );
@ -113,6 +113,9 @@ static void linphone_gtk_ldap_load_settings(GtkWidget* param)
spin = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"ldap_timeout")); spin = GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"ldap_timeout"));
gtk_spin_button_set_value(spin, linphone_dictionary_get_int(ldap_conf,"timeout", 10) ); gtk_spin_button_set_value(spin, linphone_dictionary_get_int(ldap_conf,"timeout", 10) );
// TODO: add missing LDAP components
// TODO: move this to an external box
} }
void linphone_gtk_ldap_reset(GtkWidget *tabmgr) void linphone_gtk_ldap_reset(GtkWidget *tabmgr)