Wed Oct 28 11:53:04 2009

Asterisk developer's documentation


res_config_ldap.c File Reference

ldap plugin for portable configuration engine (ARA) More...

#include "asterisk.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <ldap.h>
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/strings.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"

Include dependency graph for res_config_ldap.c:

Go to the source code of this file.

Data Structures

struct  category_and_metric
struct  ldap_table_config
 Table configuration. More...
struct  table_configs
 Should be locked before using it. More...

Defines

#define MAXRESULT   2048
#define RES_CONFIG_LDAP_CONF   "res_ldap.conf"
#define RES_CONFIG_LDAP_DEFAULT_BASEDN   "asterisk"

Functions

static void __reg_module (void)
static void __unreg_module (void)
static void append_var_and_value_to_filter (struct ast_str **filter, struct ldap_table_config *table_config, const char *name, const char *value)
 Append a name=value filter string. The filter string can grow.
static char * cleaned_basedn (struct ast_channel *channel, const char *basedn)
 caller should free returned pointer
static int compare_categories (const void *a, const void *b)
 Sorting alogrithm for qsort to find the order of the variables a and b.
static struct ast_configconfig_ldap (const char *basedn, const char *table_name, const char *file, struct ast_config *cfg, struct ast_flags config_flags, const char *sugg_incl, const char *who_asked)
 See Asterisk doc.
static const char * convert_attribute_name_from_ldap (struct ldap_table_config *table_config, const char *attribute_name)
 Convert ldap attribute name to variable name - Should be locked before using it.
static const char * convert_attribute_name_to_ldap (struct ldap_table_config *table_config, const char *attribute_name)
 Convert variable name to ldap attribute name - Should be locked before using it.
static int is_ldap_connect_error (int err)
static struct ast_variableldap_loadentry (struct ldap_table_config *table_config, const char *dn)
 Get LDAP entry by dn and return attributes as variables - Should be locked before using it This is used for setting the default values of an object(i.e., with accountBaseDN).
static int ldap_reconnect (void)
static void ldap_table_config_add_attribute (struct ldap_table_config *table_config, const char *attribute_name, const char *attribute_value)
 add attribute to table config - Should be locked before using it
static int load_module (void)
static int parse_config (void)
static struct ast_variablerealtime_ldap (const char *basedn, const char *table_name, va_list ap)
 See Asterisk doc.
static struct ast_variable ** realtime_ldap_base (unsigned int *entries_count_ptr, const char *basedn, const char *table_name,...)
 same as realtime_ldap_base_ap but take variable arguments count list
static struct ast_variable ** realtime_ldap_base_ap (unsigned int *entries_count_ptr, const char *basedn, const char *table_name, va_list ap)
 LDAP base function.
static struct ast_variablerealtime_ldap_entry_to_var (struct ldap_table_config *table_config, LDAPMessage *ldap_entry)
 Get variables from ldap entry attributes - Should be locked before using it.
static struct ast_variable ** realtime_ldap_result_to_vars (struct ldap_table_config *table_config, LDAPMessage *ldap_result_msg, unsigned int *entries_count_ptr)
 Get variables from ldap entry attributes - Should be locked before using it.
static char * realtime_ldap_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct ast_configrealtime_multi_ldap (const char *basedn, const char *table_name, va_list ap)
 See Asterisk doc.
static int reload (void)
static int replace_string_in_string (char *string, const char *search, const char *by)
 Replace <search> by <by> in string. No check is done on string allocated size !
static int semicolon_count_str (const char *somestr)
 for the semicolon delimiter
static int semicolon_count_var (struct ast_variable *var)
static char * substituted (struct ast_channel *channel, const char *string)
 caller should free returned pointer
static struct ldap_table_configtable_config_for_table_name (const char *table_name)
 Find a table_config - Should be locked before using it.
static struct ldap_table_configtable_config_new (const char *table_name)
 Create a new table_config.
static void table_configs_free (void)
 Free table_config.
static int unload_module (void)
static int update_ldap (const char *basedn, const char *table_name, const char *attribute, const char *lookup, va_list ap)
static struct ast_variablevariable_named (struct ast_variable *var, const char *name)
 Find variable by name.

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "LDAP realtime interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, }
static struct ast_module_infoast_module_info = &__mod_info
static char base_distinguished_name [512]
static struct ldap_table_configbase_table_config
static time_t connect_time
static struct ast_cli_entry ldap_cli []
static struct ast_config_engine ldap_engine
static ast_mutex_t ldap_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static LDAP * ldapConn
static char pass [50]
static struct ldap_table_configstatic_table_config
static char url [512]
static char user [512]
static int version = 3


Detailed Description

ldap plugin for portable configuration engine (ARA)

Author:
Mark Spencer <markster@digium.com>

Manuel Guesdon

Carl-Einar Thorner <cthorner@voicerd.com>

Russell Bryant <russell@digium.com>

Definition in file res_config_ldap.c.


Define Documentation

#define MAXRESULT   2048

#define RES_CONFIG_LDAP_CONF   "res_ldap.conf"

Definition at line 60 of file res_config_ldap.c.

Referenced by config_ldap(), and parse_config().

#define RES_CONFIG_LDAP_DEFAULT_BASEDN   "asterisk"

Definition at line 61 of file res_config_ldap.c.

Referenced by parse_config().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 1579 of file res_config_ldap.c.

static void __unreg_module ( void   )  [static]

Definition at line 1579 of file res_config_ldap.c.

static void append_var_and_value_to_filter ( struct ast_str **  filter,
struct ldap_table_config table_config,
const char *  name,
const char *  value 
) [static]

Append a name=value filter string. The filter string can grow.

Definition at line 682 of file res_config_ldap.c.

References ast_debug, ast_str_append(), ast_strdupa, convert_attribute_name_to_ldap(), len(), and replace_string_in_string().

Referenced by realtime_ldap_base_ap(), and update_ldap().

00685 {
00686    char *new_name = NULL;
00687    char *new_value = NULL;
00688    char *like_pos = strstr(name, " LIKE");
00689 
00690    ast_debug(2, "name='%s' value='%s'\n", name, value);
00691 
00692    if (like_pos) {
00693       int len = like_pos - name;
00694       name = new_name = ast_strdupa(name);
00695       new_name[len] = '\0';
00696       value = new_value = ast_strdupa(value);
00697       replace_string_in_string(new_value, "\\_", "_");
00698       replace_string_in_string(new_value, "%", "*");
00699    }
00700 
00701    name = convert_attribute_name_to_ldap(table_config, name);
00702 
00703    ast_str_append(filter, 0, "(%s=%s)", name, value);
00704 }

static char* cleaned_basedn ( struct ast_channel channel,
const char *  basedn 
) [static]

caller should free returned pointer

Definition at line 632 of file res_config_ldap.c.

References ast_debug, ast_strlen_zero(), len(), and substituted().

Referenced by realtime_ldap_base_ap(), and update_ldap().

00633 {
00634    char *cbasedn = NULL;
00635    if (basedn) {
00636       char *p = NULL;
00637       cbasedn = substituted(channel, basedn);
00638       if (*cbasedn == '"') {
00639          cbasedn++;
00640          if (!ast_strlen_zero(cbasedn)) {
00641             int len = strlen(cbasedn);
00642             if (cbasedn[len - 1] == '"')
00643                cbasedn[len - 1] = '\0';
00644 
00645          }
00646       }
00647       p = cbasedn;
00648       while (*p) {
00649          if (*p == '|')
00650             *p = ',';
00651          p++;
00652       }
00653    }
00654    ast_debug(2, "basedn: '%s' => '%s' \n", basedn, cbasedn);
00655    return cbasedn;
00656 }

static int compare_categories ( const void *  a,
const void *  b 
) [static]

Sorting alogrithm for qsort to find the order of the variables a and b.

Parameters:
a pointer to category_and_metric struct
b pointer to category_and_metric struct
Return values:
-1 for if b is greater
0 zero for equal
1 if a is greater

Definition at line 979 of file res_config_ldap.c.

References category_and_metric::metric, category_and_metric::name, and category_and_metric::var_metric.

Referenced by config_ldap().

00980 {
00981    const struct category_and_metric *as = a;
00982    const struct category_and_metric *bs = b;
00983 
00984    if (as->metric < bs->metric)
00985       return -1;
00986    else if (as->metric > bs->metric)
00987       return 1;
00988    else if (as->metric == bs->metric && strcmp(as->name, bs->name) != 0)
00989       return strcmp(as->name, bs->name);
00990 
00991    /* if the metric and the category name is the same, we check the variable metric */
00992    if (as->var_metric < bs->var_metric)
00993       return -1;
00994    else if (as->var_metric > bs->var_metric)
00995       return 1;
00996 
00997    return 0;
00998 }

static struct ast_config* config_ldap ( const char *  basedn,
const char *  table_name,
const char *  file,
struct ast_config cfg,
struct ast_flags  config_flags,
const char *  sugg_incl,
const char *  who_asked 
) [static, read]

See Asterisk doc.

This is for Static Realtime (again: I think...)

load the configuration stuff for the .conf files called on a reload

Note:
Since the items come back in random order, they need to be sorted first, and since the data could easily exceed stack size, this is allocated from the heap.

Definition at line 1007 of file res_config_ldap.c.

References ast_calloc, ast_category_append(), ast_category_new(), ast_config_internal_load(), ast_debug, ast_log(), ast_strlen_zero(), ast_variable_append(), ast_variable_new(), compare_categories(), free, LOG_ERROR, LOG_WARNING, category_and_metric::metric, name, category_and_metric::name, realtime_ldap_base(), RES_CONFIG_LDAP_CONF, ast_variable::value, category_and_metric::var_metric, category_and_metric::variable_name, variable_named(), and category_and_metric::variable_value.

01009 {
01010    unsigned int vars_count = 0;
01011    struct ast_variable **vars;
01012    int i = 0;
01013    struct ast_variable *new_v = NULL;
01014    struct ast_category *cur_cat = NULL;
01015    const char *last_category = NULL;
01016    int last_category_metric = 0;
01017    struct category_and_metric *categories;
01018    struct ast_variable **p;
01019 
01020    if (ast_strlen_zero(file) || !strcasecmp(file, RES_CONFIG_LDAP_CONF)) {
01021       ast_log(LOG_ERROR, "Cannot configure myself.\n");
01022       return NULL;
01023    }
01024 
01025    vars = realtime_ldap_base(&vars_count, basedn, table_name, "filename",
01026             file, "commented", "FALSE", NULL);
01027 
01028    if (!vars) {
01029       ast_log(LOG_WARNING, "Could not find config '%s' in database.\n", file);
01030       return NULL;
01031    }
01032 
01033    /*!\note Since the items come back in random order, they need to be sorted
01034     * first, and since the data could easily exceed stack size, this is
01035     * allocated from the heap.
01036     */
01037    if (!(categories = ast_calloc(sizeof(*categories), vars_count)))
01038       return NULL;
01039 
01040    for (vars_count = 0, p = vars; *p; p++) {
01041       struct ast_variable *category = variable_named(*p, "category");
01042       struct ast_variable *cat_metric = variable_named(*p, "cat_metric");
01043       struct ast_variable *var_name = variable_named(*p, "variable_name");
01044       struct ast_variable *var_val = variable_named(*p, "variable_value");
01045       struct ast_variable *var_metric = variable_named(*p, "var_metric");
01046       struct ast_variable *dn = variable_named(*p, "dn");
01047          
01048       ast_debug(1, "category: %s\n", category->value);
01049       ast_debug(1, "var_name: %s\n", var_name->value);
01050       ast_debug(1, "var_val: %s\n", var_val->value);
01051       ast_debug(1, "cat_metric: %s\n", cat_metric->value);
01052 
01053       if (!category) {
01054          ast_log(LOG_ERROR,
01055                "No category name in entry '%s'  for file '%s'.\n",
01056                (dn ? dn->value : "?"), file);
01057       } else if (!cat_metric) {
01058          ast_log(LOG_ERROR,
01059                "No category metric in entry '%s'(category: %s) for file '%s'.\n",
01060                (dn ? dn->value : "?"), category->value, file);
01061       } else if (!var_metric) {
01062          ast_log(LOG_ERROR,
01063                "No variable metric in entry '%s'(category: %s) for file '%s'.\n",
01064                (dn ? dn->value : "?"), category->value, file);
01065       } else if (!var_name) {
01066          ast_log(LOG_ERROR,
01067                "No variable name in entry '%s' (category: %s metric: %s) for file '%s'.\n",
01068                (dn ? dn->value : "?"), category->value,
01069                cat_metric->value, file);
01070       } else if (!var_val) {
01071          ast_log(LOG_ERROR,
01072                "No variable value in entry '%s' (category: %s metric: %s variable: %s) for file '%s'.\n",
01073                (dn ? dn->value : "?"), category->value,
01074                cat_metric->value, var_name->value, file);
01075       } else {
01076          categories[vars_count].name = category->value;
01077          categories[vars_count].metric = atoi(cat_metric->value);
01078          categories[vars_count].variable_name = var_name->value;
01079          categories[vars_count].variable_value = var_val->value;
01080          categories[vars_count].var_metric = atoi(var_metric->value);
01081          vars_count++;
01082       }
01083    }
01084 
01085    qsort(categories, vars_count, sizeof(*categories), compare_categories);
01086 
01087    for (i = 0; i < vars_count; i++) {
01088       if (!strcmp(categories[i].variable_name, "#include")) {
01089          struct ast_flags flags = { 0 };
01090          if (!ast_config_internal_load(categories[i].variable_value, cfg, flags, "", who_asked))
01091             break;
01092          continue;
01093       }
01094 
01095       if (!last_category || strcmp(last_category, categories[i].name) ||
01096          last_category_metric != categories[i].metric) {
01097          cur_cat = ast_category_new(categories[i].name, table_name, -1);
01098          if (!cur_cat)
01099             break;
01100          last_category = categories[i].name;
01101          last_category_metric = categories[i].metric;
01102          ast_category_append(cfg, cur_cat);
01103       }
01104 
01105       if (!(new_v = ast_variable_new(categories[i].variable_name, categories[i].variable_value, table_name)))
01106          break;
01107 
01108       ast_variable_append(cur_cat, new_v);
01109    }
01110 
01111    free(vars);
01112    free(categories);
01113 
01114    return cfg;
01115 }

static const char* convert_attribute_name_from_ldap ( struct ldap_table_config table_config,
const char *  attribute_name 
) [static]

Convert ldap attribute name to variable name - Should be locked before using it.

Definition at line 239 of file res_config_ldap.c.

References ARRAY_LEN, ldap_table_config::attributes, base_table_config, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by realtime_ldap_entry_to_var(), and realtime_ldap_result_to_vars().

00241 {
00242    int i = 0;
00243    struct ldap_table_config *configs[] = { table_config, base_table_config };
00244 
00245    for (i = 0; i < ARRAY_LEN(configs); i++) {
00246       struct ast_variable *attribute;
00247 
00248       if (!configs[i])
00249          continue;
00250 
00251       attribute = configs[i]->attributes;
00252       for (; attribute; attribute = attribute->next) {
00253          if (strcasecmp(attribute_name, attribute->value) == 0)
00254             return attribute->name;
00255       }
00256    }
00257 
00258    return attribute_name;
00259 }

static const char* convert_attribute_name_to_ldap ( struct ldap_table_config table_config,
const char *  attribute_name 
) [static]

Convert variable name to ldap attribute name - Should be locked before using it.

Definition at line 216 of file res_config_ldap.c.

References ARRAY_LEN, ldap_table_config::attributes, base_table_config, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by append_var_and_value_to_filter(), and update_ldap().

00218 {
00219    int i = 0;
00220    struct ldap_table_config *configs[] = { table_config, base_table_config };
00221 
00222    for (i = 0; i < ARRAY_LEN(configs); i++) {
00223       struct ast_variable *attribute;
00224 
00225       if (!configs[i])
00226          continue;
00227 
00228       attribute = configs[i]->attributes;
00229       for (; attribute; attribute = attribute->next) {
00230          if (!strcasecmp(attribute_name, attribute->name))
00231             return attribute->value;
00232       }
00233    }
00234 
00235    return attribute_name;
00236 }

static int is_ldap_connect_error ( int  err  )  [static]

Definition at line 531 of file res_config_ldap.c.

Referenced by ldap_loadentry(), realtime_ldap_base_ap(), and update_ldap().

00532 {
00533    return (err == LDAP_SERVER_DOWN
00534          || err == LDAP_TIMEOUT || err == LDAP_CONNECT_ERROR);
00535 }

static struct ast_variable* ldap_loadentry ( struct ldap_table_config table_config,
const char *  dn 
) [static, read]

Get LDAP entry by dn and return attributes as variables - Should be locked before using it This is used for setting the default values of an object(i.e., with accountBaseDN).

< not using this

Definition at line 540 of file res_config_ldap.c.

References ast_debug, ast_log(), ast_mutex_unlock(), ast_realloc, ast_variables_destroy(), is_ldap_connect_error(), ldap_lock, ldap_reconnect(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, realtime_ldap_result_to_vars(), and var.

Referenced by realtime_ldap_base_ap().

00542 {
00543    if (!table_config) {
00544       ast_log(LOG_ERROR, "No table config\n");
00545       return NULL;
00546    } else {
00547       struct ast_variable **vars = NULL;
00548       struct ast_variable *var = NULL;
00549       int result = -1;
00550       LDAPMessage *ldap_result_msg = NULL;
00551       int tries = 0;
00552 
00553       ast_debug(2, "ldap_loadentry dn=%s\n", dn);
00554 
00555       do {
00556          result = ldap_search_ext_s(ldapConn, dn, LDAP_SCOPE_BASE,
00557                   "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &ldap_result_msg);
00558          if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
00559             ast_log(LOG_WARNING,
00560                "Failed to query database. Try %d/3\n",
00561                tries + 1);
00562             tries++;
00563             if (tries < 3) {
00564                usleep(500000L * tries);
00565                if (ldapConn) {
00566                   ldap_unbind_ext_s(ldapConn, NULL, NULL);
00567                   ldapConn = NULL;
00568                }
00569                if (!ldap_reconnect())
00570                   break;
00571             }
00572          }
00573       } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result));
00574 
00575       if (result != LDAP_SUCCESS) {
00576          ast_log(LOG_WARNING,
00577                "Failed to query database. Check debug for more info.\n");
00578          ast_debug(2, "dn=%s\n", dn);
00579          ast_debug(2, "Query Failed because: %s\n",
00580             ldap_err2string(result));
00581          ast_mutex_unlock(&ldap_lock);
00582          return NULL;
00583       } else {
00584          int num_entry = 0;
00585          unsigned int *entries_count_ptr = NULL; /*!< not using this */
00586          if ((num_entry = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) {
00587             ast_debug(3, "num_entry: %d\n", num_entry);
00588 
00589             vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr);
00590             if (num_entry > 1)
00591                ast_log(LOG_NOTICE, "More than one entry for dn=%s. Take only 1st one\n", dn);
00592          } else {
00593             ast_debug(2, "Could not find any entry dn=%s.\n", dn);
00594          }
00595       }
00596       ldap_msgfree(ldap_result_msg);
00597 
00598       /* Chopping \a vars down to one variable */
00599       if (vars != NULL) {
00600          struct ast_variable **p = vars;
00601          p++;
00602          var = *p;
00603          while (var) {
00604             ast_variables_destroy(var);
00605             p++;
00606          }
00607          vars = ast_realloc(vars, sizeof(struct ast_variable *));
00608       }
00609 
00610       var = *vars;
00611 
00612       return var;
00613    }
00614 }

static int ldap_reconnect ( void   )  [static]

Note:
ldap_lock should have been locked before calling this function.

Definition at line 1480 of file res_config_ldap.c.

References ast_debug, ast_log(), ast_strlen_zero(), LOG_ERROR, and LOG_WARNING.

Referenced by ldap_loadentry(), load_module(), realtime_ldap_base_ap(), reload(), and update_ldap().

01481 {
01482    int bind_result = 0;
01483    struct berval cred;
01484 
01485    if (ldapConn) {
01486       ast_debug(2, "Everything seems fine.\n");
01487       return 1;
01488    }
01489 
01490    if (ast_strlen_zero(url)) {
01491       ast_log(LOG_ERROR, "Not enough parameters to connect to ldap database\n");
01492       return 0;
01493    }
01494 
01495    if (LDAP_SUCCESS != ldap_initialize(&ldapConn, url)) {
01496       ast_log(LOG_ERROR, "Failed to init ldap connection to '%s'. Check debug for more info.\n", url);
01497       return 0;
01498    }
01499 
01500    if (LDAP_OPT_SUCCESS != ldap_set_option(ldapConn, LDAP_OPT_PROTOCOL_VERSION, &version)) {
01501       ast_log(LOG_WARNING, "Unable to set LDAP protocol version to %d, falling back to default.\n", version);
01502    }
01503 
01504    if (!ast_strlen_zero(user)) {
01505       ast_debug(2, "bind to '%s' as user '%s'\n", url, user);
01506       cred.bv_val = (char *) pass;
01507       cred.bv_len = strlen(pass);
01508       bind_result = ldap_sasl_bind_s(ldapConn, user, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
01509    } else {
01510       ast_debug(2, "bind %s anonymously\n", url);
01511       cred.bv_val = NULL;
01512       cred.bv_len = 0;
01513       bind_result = ldap_sasl_bind_s(ldapConn, NULL, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
01514    }
01515    if (bind_result == LDAP_SUCCESS) {
01516       ast_debug(2, "Successfully connected to database.\n");
01517       connect_time = time(NULL);
01518       return 1;
01519    } else {
01520       ast_log(LOG_WARNING, "bind failed: %s\n", ldap_err2string(bind_result));
01521       ldap_unbind_ext_s(ldapConn, NULL, NULL);
01522       ldapConn = NULL;
01523       return 0;
01524    }
01525 }

static void ldap_table_config_add_attribute ( struct ldap_table_config table_config,
const char *  attribute_name,
const char *  attribute_value 
) [static]

add attribute to table config - Should be locked before using it

Definition at line 179 of file res_config_ldap.c.

References ast_strlen_zero(), ast_variable_new(), ldap_table_config::attributes, ast_variable::next, ldap_table_config::table_name, and var.

Referenced by parse_config().

00181 {
00182    struct ast_variable *var;
00183 
00184    if (ast_strlen_zero(attribute_name) || ast_strlen_zero(attribute_value))
00185       return;
00186 
00187    if (!(var = ast_variable_new(attribute_name, attribute_value, table_config->table_name)))
00188       return;
00189 
00190    if (table_config->attributes)
00191       var->next = table_config->attributes;
00192    table_config->attributes = var;
00193 }

static int load_module ( void   )  [static]

Definition at line 1317 of file res_config_ldap.c.

References ast_cli_register_multiple(), ast_config_engine_register(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, ldap_cli, ldap_engine, ldap_lock, ldap_reconnect(), LOG_NOTICE, LOG_WARNING, and parse_config().

01318 {
01319    if (parse_config() < 0) {
01320       ast_log(LOG_NOTICE, "Cannot load LDAP RealTime driver.\n");
01321       return 0;
01322    }
01323 
01324    ast_mutex_lock(&ldap_lock);
01325 
01326    if (!ldap_reconnect()) 
01327       ast_log(LOG_WARNING, "Couldn't establish connection. Check debug.\n");
01328 
01329    ast_config_engine_register(&ldap_engine);
01330    ast_verb(1, "LDAP RealTime driver loaded.\n");
01331    ast_cli_register_multiple(ldap_cli, sizeof(ldap_cli) / sizeof(struct ast_cli_entry));
01332 
01333    ast_mutex_unlock(&ldap_lock);
01334 
01335    return 0;
01336 }

int parse_config ( void   )  [static]

< using the [config] context for Static RealTime

Definition at line 1386 of file res_config_ldap.c.

References ldap_table_config::additional_filter, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), AST_LIST_INSERT_HEAD, ast_log(), ast_strdup, ast_strlen_zero(), ast_variable_browse(), ast_variable_retrieve(), base_table_config, config, ldap_table_config::entry, ldap_table_config_add_attribute(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, RES_CONFIG_LDAP_CONF, RES_CONFIG_LDAP_DEFAULT_BASEDN, s, static_table_config, table_config_for_table_name(), table_config_new(), table_configs_free(), ast_variable::value, and var.

01387 {
01388    struct ast_config *config;
01389    struct ast_flags config_flags = {0};
01390    const char *s, *host;
01391    int port;
01392    char *category_name = NULL;
01393 
01394    config = ast_config_load(RES_CONFIG_LDAP_CONF, config_flags);
01395 
01396    if (!config) {
01397       ast_log(LOG_WARNING, "Cannot load configuration %s\n", RES_CONFIG_LDAP_CONF);
01398       return -1;
01399    }
01400 
01401    if (!(s = ast_variable_retrieve(config, "_general", "user"))) {
01402       ast_log(LOG_WARNING, "No directory user found, anonymous binding as default.\n");
01403       user[0] = '\0';
01404    } else 
01405       ast_copy_string(user, s, sizeof(user));
01406 
01407    if (!ast_strlen_zero(user)) {
01408       if (!(s = ast_variable_retrieve(config, "_general", "pass"))) {
01409          ast_log(LOG_WARNING, "No directory password found, using 'asterisk' as default.\n");
01410          ast_copy_string(pass, "asterisk", sizeof(pass));
01411       } else {
01412          ast_copy_string(pass, s, sizeof(pass));
01413       }
01414    }
01415 
01416    /* URL is preferred, use host and port if not found */
01417    if ((s = ast_variable_retrieve(config, "_general", "url"))) {
01418       ast_copy_string(url, s, sizeof(url));
01419    } else if ((host = ast_variable_retrieve(config, "_general", "host"))) {
01420       if (!(s = ast_variable_retrieve(config, "_general", "port")) || sscanf(s, "%5d", &port) != 1 || port > 65535) {
01421          ast_log(LOG_NOTICE, "No directory port found, using 389 as default.\n");
01422          port = 389;
01423       }
01424 
01425       snprintf(url, sizeof(url), "ldap://%s:%d", host, port);
01426    } else {
01427       ast_log(LOG_ERROR, "No directory URL or host found.\n");
01428       ast_config_destroy(config);
01429       return -1;
01430    }
01431 
01432    if (!(s = ast_variable_retrieve(config, "_general", "basedn"))) {
01433       ast_log(LOG_ERROR, "No LDAP base dn found, using '%s' as default.\n", RES_CONFIG_LDAP_DEFAULT_BASEDN);
01434       ast_copy_string(base_distinguished_name, RES_CONFIG_LDAP_DEFAULT_BASEDN, sizeof(base_distinguished_name));
01435    } else 
01436       ast_copy_string(base_distinguished_name, s, sizeof(base_distinguished_name));
01437 
01438    if (!(s = ast_variable_retrieve(config, "_general", "version")) && !(s = ast_variable_retrieve(config, "_general", "protocol"))) {
01439       ast_log(LOG_NOTICE, "No explicit LDAP version found, using 3 as default.\n");
01440       version = 3;
01441    } else if (sscanf(s, "%30d", &version) != 1 || version < 1 || version > 6) {
01442       ast_log(LOG_WARNING, "Invalid LDAP version '%s', using 3 as default.\n", s);
01443       version = 3;
01444    }
01445 
01446    table_configs_free();
01447 
01448    while ((category_name = ast_category_browse(config, category_name))) {
01449       int is_general = (strcasecmp(category_name, "_general") == 0);
01450       int is_config = (strcasecmp(category_name, "config") == 0); /*!< using the [config] context for Static RealTime */
01451       struct ast_variable *var = ast_variable_browse(config, category_name);
01452       
01453       if (var) {
01454          struct ldap_table_config *table_config =
01455             table_config_for_table_name(category_name);
01456          if (!table_config) {
01457             table_config = table_config_new(category_name);
01458             AST_LIST_INSERT_HEAD(&table_configs, table_config, entry);
01459             if (is_general)
01460                base_table_config = table_config;
01461             if (is_config)
01462                static_table_config = table_config;
01463          }
01464          for (; var; var = var->next) {
01465             if (!strcasecmp(var->name, "additionalFilter")) {
01466                table_config->additional_filter = ast_strdup(var->value);
01467             } else {
01468                ldap_table_config_add_attribute(table_config, var->name, var->value);
01469             }
01470          }
01471       }
01472    }
01473 
01474    ast_config_destroy(config);
01475 
01476    return 1;
01477 }

static struct ast_variable* realtime_ldap ( const char *  basedn,
const char *  table_name,
va_list  ap 
) [static, read]

See Asterisk doc.

For Realtime Dynamic(i.e., switch, queues, and directory) -- I think

Definition at line 899 of file res_config_ldap.c.

References free, ast_variable::next, realtime_ldap_base_ap(), and var.

00901 {
00902    struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, ap);
00903    struct ast_variable *var = NULL;
00904 
00905    if (vars) {
00906       struct ast_variable *last_var = NULL;
00907       struct ast_variable **p = vars;
00908       while (*p) {
00909          if (last_var) {
00910             while (last_var->next)
00911                last_var = last_var->next;
00912             last_var->next = *p;
00913          } else {
00914             var = *p;
00915             last_var = var;
00916          }
00917          p++;
00918       }
00919       free(vars);
00920    }
00921    return var;
00922 }

static struct ast_variable** realtime_ldap_base ( unsigned int *  entries_count_ptr,
const char *  basedn,
const char *  table_name,
  ... 
) [static, read]

same as realtime_ldap_base_ap but take variable arguments count list

Definition at line 882 of file res_config_ldap.c.

References realtime_ldap_base_ap().

Referenced by config_ldap().

00884 {
00885    struct ast_variable **vars = NULL;
00886    va_list ap;
00887 
00888    va_start(ap, table_name);
00889    vars = realtime_ldap_base_ap(entries_count_ptr, basedn, table_name, ap);
00890    va_end(ap);
00891 
00892    return vars;
00893 }

static struct ast_variable** realtime_ldap_base_ap ( unsigned int *  entries_count_ptr,
const char *  basedn,
const char *  table_name,
va_list  ap 
) [static, read]

LDAP base function.

Returns:
a null terminated array of ast_variable (one per entry) or NULL if no entry is found or if an error occured caller should free the returned array and ast_variables
Parameters:
entries_count_ptr is a pointer to found entries count (can be NULL)
basedn is the base DN
table_name is the table_name (used dor attribute convertion and additional filter)
ap contains null terminated list of pairs name/value

Definition at line 714 of file res_config_ldap.c.

References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_debug, ast_free, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_str_append(), ast_str_create(), ast_variables_destroy(), base_table_config, cleaned_basedn(), filter(), is_ldap_connect_error(), ldap_loadentry(), ldap_lock, ldap_reconnect(), LOG_DEBUG, LOG_WARNING, ast_variable::name, ast_variable::next, ldap_table_config::next, realtime_ldap_result_to_vars(), ast_str::str, table_config_for_table_name(), and ast_variable::value.

Referenced by realtime_ldap(), realtime_ldap_base(), and realtime_multi_ldap().

00716 {
00717    struct ast_variable **vars = NULL;
00718    const char *newparam = NULL;
00719    const char *newval = NULL;
00720    struct ldap_table_config *table_config = NULL;
00721    char *clean_basedn = cleaned_basedn(NULL, basedn);
00722    struct ast_str *filter = NULL;
00723    int tries = 0;
00724    int result = 0;
00725    LDAPMessage *ldap_result_msg = NULL;
00726 
00727    if (!table_name) {
00728       ast_log(LOG_WARNING, "No table_name specified.\n");
00729       ast_free(clean_basedn);
00730       return NULL;
00731    } 
00732 
00733    if (!(filter = ast_str_create(80))) {
00734       ast_free(clean_basedn);
00735       return NULL;
00736    }
00737 
00738    /* Get the first parameter and first value in our list of passed paramater/value pairs  */
00739    newparam = va_arg(ap, const char *);
00740    newval = va_arg(ap, const char *);
00741 
00742    if (!newparam || !newval) {
00743       ast_log(LOG_WARNING, "Realtime retrieval requires at least 1 parameter"
00744          " and 1 value to search on.\n");
00745       ast_free(filter);
00746       ast_free(clean_basedn);
00747       return NULL;
00748    }
00749 
00750    ast_mutex_lock(&ldap_lock);
00751 
00752    /* We now have our complete statement; Lets connect to the server and execute it.  */
00753    if (!ldap_reconnect()) {
00754       ast_mutex_unlock(&ldap_lock);
00755       ast_free(filter);
00756       ast_free(clean_basedn);
00757       return NULL;
00758    }
00759 
00760    table_config = table_config_for_table_name(table_name);
00761    if (!table_config) {
00762       ast_log(LOG_WARNING, "No table named '%s'.\n", table_name);
00763       ast_mutex_unlock(&ldap_lock);
00764       ast_free(filter);
00765       ast_free(clean_basedn);
00766       return NULL;
00767    }
00768 
00769    ast_str_append(&filter, 0, "(&");
00770 
00771    if (table_config && table_config->additional_filter)
00772       ast_str_append(&filter, 0, "%s", table_config->additional_filter);
00773    if (table_config != base_table_config && base_table_config && 
00774       base_table_config->additional_filter) {
00775       ast_str_append(&filter, 0, "%s", base_table_config->additional_filter);
00776    }
00777 
00778    /* Create the first part of the query using the first parameter/value pairs we just extracted */
00779    /*   If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
00780 
00781    append_var_and_value_to_filter(&filter, table_config, newparam, newval);
00782    while ((newparam = va_arg(ap, const char *))) {
00783       newval = va_arg(ap, const char *);
00784       append_var_and_value_to_filter(&filter, table_config, newparam, newval);
00785    }
00786    ast_str_append(&filter, 0, ")");
00787 
00788    do {
00789       /* freeing ldap_result further down */
00790       result = ldap_search_ext_s(ldapConn, clean_basedn,
00791               LDAP_SCOPE_SUBTREE, filter->str, NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT,
00792               &ldap_result_msg);
00793       if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
00794          ast_log(LOG_DEBUG, "Failed to query database. Try %d/10\n",
00795             tries + 1);
00796          if (++tries < 10) {
00797             usleep(1);
00798             if (ldapConn) {
00799                ldap_unbind_ext_s(ldapConn, NULL, NULL);
00800                ldapConn = NULL;
00801             }
00802             if (!ldap_reconnect())
00803                break;
00804          }
00805       }
00806    } while (result != LDAP_SUCCESS && tries < 10 && is_ldap_connect_error(result));
00807 
00808    if (result != LDAP_SUCCESS) {
00809       ast_log(LOG_WARNING, "Failed to query database. Check debug for more info.\n");
00810       ast_log(LOG_WARNING, "Query: %s\n", filter->str);
00811       ast_log(LOG_WARNING, "Query Failed because: %s\n", ldap_err2string(result));
00812    } else {
00813       /* this is where we create the variables from the search result 
00814        * freeing this \a vars outside this function */
00815       if (ldap_count_entries(ldapConn, ldap_result_msg) > 0) {
00816          /* is this a static var or some other? they are handled different for delimited values */
00817          vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr);
00818       } else {
00819          ast_debug(1, "Could not find any entry matching %s in base dn %s.\n",
00820             filter->str, clean_basedn);
00821       }
00822 
00823       ldap_msgfree(ldap_result_msg);
00824 
00825       /* TODO: get the default variables from the accountBaseDN, not implemented with delimited values */
00826       if (vars) {
00827          struct ast_variable **p = vars;
00828          while (*p) {
00829             struct ast_variable *append_var = NULL;
00830             struct ast_variable *tmp = *p;
00831             while (tmp) {
00832                if (strcasecmp(tmp->name, "accountBaseDN") == 0) {
00833                   /* Get the variable to compare with for the defaults */
00834                   struct ast_variable *base_var = ldap_loadentry(table_config, tmp->value);
00835                   
00836                   while (base_var) {
00837                      struct ast_variable *next = base_var->next;
00838                      struct ast_variable *test_var = *p;
00839                      int base_var_found = 0;
00840 
00841                      /* run throught the default values and fill it inn if it is missing */
00842                      while (test_var) {
00843                         if (strcasecmp(test_var->name, base_var->name) == 0) {
00844                            base_var_found = 1;
00845                            break;
00846                         } else
00847                            test_var = test_var->next;
00848                      }
00849                      if (base_var_found) {
00850                         base_var->next = NULL;
00851                         ast_variables_destroy(base_var);
00852                         base_var = next;
00853                      } else {
00854                         if (append_var)
00855                            base_var->next = append_var;
00856                         else
00857                            base_var->next = NULL;
00858                         append_var = base_var;
00859                         base_var = next;
00860                      }
00861                   }
00862                }
00863                if (!tmp->next && append_var) {
00864                   tmp->next = append_var;
00865                   tmp = NULL;
00866                } else
00867                   tmp = tmp->next;
00868             }
00869             p++;
00870          }
00871       }
00872    }
00873 
00874    ast_free(filter);
00875    ast_free(clean_basedn);
00876    ast_mutex_unlock(&ldap_lock);
00877 
00878    return vars;
00879 }

static struct ast_variable* realtime_ldap_entry_to_var ( struct ldap_table_config table_config,
LDAPMessage *  ldap_entry 
) [static, read]

Get variables from ldap entry attributes - Should be locked before using it.

Returns:
a linked list of ast_variable variables.

Definition at line 264 of file res_config_ldap.c.

References ast_debug, ast_strlen_zero(), ast_variable_new(), convert_attribute_name_from_ldap(), ast_variable::next, ldap_table_config::table_name, and var.

Referenced by realtime_ldap_result_to_vars().

00266 {
00267    BerElement *ber = NULL;
00268    struct ast_variable *var = NULL;
00269    struct ast_variable *prev = NULL;
00270    int is_delimited = 0;
00271    int i = 0;
00272    char *ldap_attribute_name;
00273    struct berval *value;
00274    int pos = 0;
00275 
00276    ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber);
00277 
00278    while (ldap_attribute_name) {
00279       struct berval **values = NULL;
00280       const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name);
00281       int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0;
00282 
00283       values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); /* these are freed at the end */
00284       if (values) {
00285          struct berval **v;
00286          char *valptr;
00287 
00288          for (v = values; *v; v++) {
00289             value = *v;
00290             valptr = value->bv_val;
00291             ast_debug(2, "LINE(%d) attribute_name: %s LDAP value: %s\n", __LINE__, attribute_name, valptr);
00292             if (is_realmed_password_attribute) {
00293                if (!strncasecmp(valptr, "{md5}", 5)) {
00294                   valptr += 5;
00295                } else {
00296                   valptr = NULL;
00297                }
00298                ast_debug(2, "md5: %s\n", valptr);
00299             }
00300             if (valptr) {
00301                /* ok, so looping through all delimited values except the last one (not, last character is not delimited...) */
00302                if (is_delimited) {
00303                   i = 0;
00304                   pos = 0;
00305                   while (!ast_strlen_zero(valptr + i)) {
00306                      if (valptr[i] == ';'){
00307                         valptr[i] = '\0';
00308                         if (prev) {
00309                            prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
00310                            if (prev->next) {
00311                               prev = prev->next;
00312                            }
00313                         } else {
00314                            prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
00315                         }
00316                         pos = i + 1;
00317                      }
00318                      i++;
00319                   }
00320                }
00321                /* for the last delimited value or if the value is not delimited: */
00322                if (prev) {
00323                   prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
00324                   if (prev->next) {
00325                      prev = prev->next;
00326                   }
00327                } else {
00328                   prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
00329                }
00330             }
00331          }
00332          ldap_value_free_len(values);
00333       }
00334       ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber);
00335    }
00336    ber_free(ber, 0);
00337 
00338    return var;
00339 }

static struct ast_variable** realtime_ldap_result_to_vars ( struct ldap_table_config table_config,
LDAPMessage *  ldap_result_msg,
unsigned int *  entries_count_ptr 
) [static, read]

Get variables from ldap entry attributes - Should be locked before using it.

The results are freed outside this function so is the vars array.

Returns:
vars - an array of ast_variable variables terminated with a null.

Definition at line 347 of file res_config_ldap.c.

References ast_calloc, ast_debug, ast_strdup, ast_strlen_zero(), ast_variable_new(), convert_attribute_name_from_ldap(), free, ast_variable::next, option_debug, realtime_ldap_entry_to_var(), semicolon_count_str(), semicolon_count_var(), static_table_config, ldap_table_config::table_name, ast_variable::value, var, and variable_named().

Referenced by ldap_loadentry(), and realtime_ldap_base_ap().

00349 {
00350    struct ast_variable **vars;
00351    int i = 0;
00352    int tot_count = 0;
00353    int entry_index = 0;
00354    LDAPMessage *ldap_entry = NULL;
00355    BerElement *ber = NULL;
00356    struct ast_variable *var = NULL;
00357    struct ast_variable *prev = NULL;
00358    int is_delimited = 0;
00359    char *delim_value = NULL;
00360    int delim_tot_count = 0;
00361    int delim_count = 0;
00362 
00363    /* First find the total count */
00364    ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
00365 
00366    for (tot_count = 0; ldap_entry; tot_count++){ 
00367       tot_count += semicolon_count_var(realtime_ldap_entry_to_var(table_config, ldap_entry));
00368       ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
00369    }
00370 
00371    if (entries_count_ptr)
00372       *entries_count_ptr = tot_count;
00373    /* Now that we have the total count we allocate space and create the variables
00374     * Remember that each element in vars is a linked list that points to realtime variable.
00375     * If the we are dealing with a static realtime variable we create a new element in the \a vars array for each delimited
00376     * value in \a variable_value; otherwise, we keep \a vars static and increase the length of the linked list of variables in the array element.
00377     * This memory must be freed outside of this function. */
00378    vars = ast_calloc(sizeof(struct ast_variable *), tot_count + 1);
00379 
00380    ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
00381 
00382    i = 0;
00383 
00384    /* For each static realtime variable we may create several entries in the \a vars array if it's delimited */
00385    for (entry_index = 0; ldap_entry; ) { 
00386       int pos = 0;
00387       delim_value = NULL;
00388       delim_tot_count = 0;
00389       delim_count = 0;
00390       
00391       do { /* while delim_count */
00392 
00393          /* Starting new static var */
00394          char *ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber);
00395          struct berval *value;
00396          while (ldap_attribute_name) {
00397          
00398             const char *attribute_name =
00399                convert_attribute_name_from_ldap(table_config, ldap_attribute_name);
00400             int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0;
00401             struct berval **values = NULL;
00402 
00403             values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name);
00404             if (values) {
00405                struct berval **v;
00406                char *valptr;
00407 
00408                for (v = values; *v; v++) {
00409                   value = *v;
00410                   valptr = value->bv_val;
00411                   if (is_realmed_password_attribute) {
00412                      if (strncasecmp(valptr, "{md5}", 5) == 0) {
00413                         valptr += 5;
00414                      } else {
00415                         valptr = NULL;
00416                      }
00417                      ast_debug(2, "md5: %s\n", valptr);
00418                   }
00419                   if (valptr) {
00420                      if (delim_value == NULL 
00421                         && !is_realmed_password_attribute 
00422                         && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0)) {
00423 
00424                         delim_value = ast_strdup(valptr);
00425 
00426                         if ((delim_tot_count = semicolon_count_str(delim_value)) > 0) {
00427                            ast_debug(4, "LINE(%d) is delimited %d times: %s\n", __LINE__, delim_tot_count, delim_value);
00428                            is_delimited = 1;
00429                         }
00430                      }
00431 
00432                      if (is_delimited != 0 
00433                         && !is_realmed_password_attribute 
00434                         && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0) ) {
00435                         /* for non-Static RealTime, first */
00436 
00437                         for (i = pos; !ast_strlen_zero(valptr + i); i++) {
00438                            ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i);
00439                            if (delim_value[i] == ';') {
00440                               delim_value[i] = '\0';
00441 
00442                               ast_debug(2, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos);
00443                      
00444                               if (prev) {
00445                                  prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
00446                                  if (prev->next) {
00447                                     prev = prev->next;
00448                                  }
00449                               } else {
00450                                  prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
00451                               }
00452                               pos = i + 1;
00453 
00454                               if (static_table_config == table_config) {
00455                                  break;
00456                               }
00457                            }
00458                         }
00459                         if (ast_strlen_zero(valptr + i)) {
00460                            ast_debug(4, "LINE(%d) DELIM pos: %d i: %d delim_count: %d\n", __LINE__, pos, i, delim_count);
00461                            /* Last delimited value */
00462                            ast_debug(4, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos);
00463                            if (prev) {
00464                               prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
00465                               if (prev->next) {
00466                                  prev = prev->next;
00467                               }
00468                            } else {
00469                               prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
00470                            }
00471                            /* Remembering to free memory */
00472                            is_delimited = 0;
00473                            pos = 0;
00474                         }
00475                         free(delim_value);
00476                         delim_value = NULL;
00477                         
00478                         ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i);
00479                      } else {
00480                         /* not delimited */
00481                         if (delim_value) {
00482                            free(delim_value);
00483                            delim_value = NULL;
00484                         }
00485                         ast_debug(2, "LINE(%d) attribute_name: %s value: %s\n", __LINE__, attribute_name, valptr);
00486 
00487                         if (prev) {
00488                            prev->next = ast_variable_new(attribute_name, valptr, table_config->table_name);
00489                            if (prev->next) {
00490                               prev = prev->next;
00491                            }
00492                         } else {
00493                            prev = var = ast_variable_new(attribute_name, valptr, table_config->table_name);
00494                         }
00495                      }
00496                   }
00497                } /*!< for (v = values; *v; v++) */
00498                ldap_value_free_len(values);
00499             }/*!< if (values) */
00500             ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber);
00501          } /*!< while (ldap_attribute_name) */
00502          ber_free(ber, 0);
00503          if (static_table_config == table_config) {
00504             if (option_debug > 2) {
00505                const struct ast_variable *tmpdebug = variable_named(var, "variable_name");
00506                const struct ast_variable *tmpdebug2 = variable_named(var, "variable_value");
00507                if (tmpdebug && tmpdebug2) {
00508                   ast_debug(3, "LINE(%d) Added to vars - %s = %s\n", __LINE__, tmpdebug->value, tmpdebug2->value);
00509                }
00510             }
00511             vars[entry_index++] = var;
00512             prev = NULL;
00513          }
00514 
00515          delim_count++;
00516       } while (delim_count <= delim_tot_count && static_table_config == table_config);
00517 
00518       if (static_table_config != table_config) {
00519          ast_debug(3, "LINE(%d) Added to vars - non static\n", __LINE__);
00520             
00521          vars[entry_index++] = var;
00522          prev = NULL;
00523       }
00524       ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
00525    } /*!< end for loop over ldap_entry */
00526 
00527    return vars;
00528 }

static char * realtime_ldap_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1527 of file res_config_ldap.c.

References ast_cli(), ast_strlen_zero(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, status, and ast_cli_entry::usage.

01528 {
01529    char status[256], credentials[100] = "";
01530    int ctimesec = time(NULL) - connect_time;
01531 
01532    switch (cmd) {
01533    case CLI_INIT:
01534       e->command = "realtime ldap status";
01535       e->usage =
01536          "Usage: realtime ldap status\n"
01537          "               Shows connection information for the LDAP RealTime driver\n";
01538       return NULL;
01539    case CLI_GENERATE:
01540       return NULL;
01541    }
01542 
01543    if (!ldapConn)
01544       return CLI_FAILURE;
01545 
01546    if (!ast_strlen_zero(url)) 
01547       snprintf(status, sizeof(status), "Connected to '%s', baseDN %s", url, base_distinguished_name);
01548 
01549    if (!ast_strlen_zero(user))
01550       snprintf(credentials, sizeof(credentials), " with username %s", user);
01551 
01552    if (ctimesec > 31536000) {
01553       ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n",
01554             status, credentials, ctimesec / 31536000,
01555             (ctimesec % 31536000) / 86400, (ctimesec % 86400) / 3600,
01556             (ctimesec % 3600) / 60, ctimesec % 60);
01557    } else if (ctimesec > 86400) {
01558       ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n",
01559             status, credentials, ctimesec / 86400, (ctimesec % 86400) / 3600,
01560             (ctimesec % 3600) / 60, ctimesec % 60);
01561    } else if (ctimesec > 3600) {
01562       ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n",
01563             status, credentials, ctimesec / 3600, (ctimesec % 3600) / 60,
01564             ctimesec % 60);
01565    } else if (ctimesec > 60) {
01566       ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, credentials,
01567                ctimesec / 60, ctimesec % 60);
01568    } else {
01569       ast_cli(a->fd, "%s%s for %d seconds.\n", status, credentials, ctimesec);
01570    }
01571 
01572    return CLI_SUCCESS;
01573 }

static struct ast_config* realtime_multi_ldap ( const char *  basedn,
const char *  table_name,
va_list  ap 
) [static, read]

See Asterisk doc.

this function will be called for the switch statment if no match is found with the realtime_ldap function(i.e. it is a failover); however, the ast_load_realtime wil match on wildcharacters also depending on what the mode is set to this is an area of asterisk that could do with a lot of modification I think this function returns Realtime dynamic objects

Definition at line 931 of file res_config_ldap.c.

References ast_category_append(), ast_category_new(), ast_config_new(), ast_log(), ast_variable_append(), free, LOG_ERROR, ast_variable::next, ldap_table_config::next, realtime_ldap_base_ap(), and var.

00933 {
00934    struct ast_variable **vars =
00935       realtime_ldap_base_ap(NULL, basedn, table_name, ap);
00936    struct ast_config *cfg = NULL;
00937 
00938    if (vars) {
00939       cfg = ast_config_new();
00940       if (!cfg) {
00941          ast_log(LOG_ERROR, "Unable to create a config!\n");
00942       } else {
00943          struct ast_variable **p = vars;
00944 
00945          while (*p) {
00946             struct ast_category *cat = NULL;
00947             cat = ast_category_new("", table_name, -1);
00948             if (!cat) {
00949                ast_log(LOG_ERROR, "Unable to create a new category!\n");
00950                break;
00951             } else {
00952                struct ast_variable *var = *p;
00953                while (var) {
00954                   struct ast_variable *next = var->next;
00955                   var->next = NULL;
00956                   ast_variable_append(cat, var);
00957                   var = next;
00958                }
00959             }
00960             ast_category_append(cfg, cat);
00961             p++;
00962          }
00963       }
00964       free(vars);
00965    }
00966    return cfg;
00967 
00968 }

static int reload ( void   )  [static]

Definition at line 1359 of file res_config_ldap.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, ldap_lock, ldap_reconnect(), LOG_NOTICE, LOG_WARNING, and parse_config().

01360 {
01361    /* Aquire control before doing anything to the module itself. */
01362    ast_mutex_lock(&ldap_lock);
01363 
01364    if (ldapConn) {
01365       ldap_unbind_ext_s(ldapConn, NULL, NULL);
01366       ldapConn = NULL;
01367    }
01368 
01369    if (parse_config() < 0) {
01370       ast_log(LOG_NOTICE, "Cannot reload LDAP RealTime driver.\n");
01371       ast_mutex_unlock(&ldap_lock);
01372       return 0;
01373    }     
01374 
01375    if (!ldap_reconnect()) 
01376       ast_log(LOG_WARNING, "Couldn't establish connection. Check debug.\n");
01377 
01378    ast_verb(2, "LDAP RealTime reloaded.\n");
01379 
01380    /* Done reloading. Release lock so others can now use driver. */
01381    ast_mutex_unlock(&ldap_lock);
01382 
01383    return 0;
01384 }

static int replace_string_in_string ( char *  string,
const char *  search,
const char *  by 
) [static]

Replace <search> by <by> in string. No check is done on string allocated size !

Definition at line 659 of file res_config_ldap.c.

Referenced by append_var_and_value_to_filter().

00660 {
00661    int search_len = strlen(search);
00662    int by_len = strlen(by);
00663    int replaced = 0;
00664    char *p = strstr(string, search);
00665    if (p) {
00666       replaced = 1;
00667       while (p) {
00668          if (by_len == search_len)
00669             memcpy(p, by, by_len);
00670          else {
00671             memmove(p + by_len, p + search_len,
00672                   strlen(p + search_len) + 1);
00673             memcpy(p, by, by_len);
00674          }
00675          p = strstr(p + by_len, search);
00676       }
00677    }
00678    return replaced;
00679 }

static int semicolon_count_str ( const char *  somestr  )  [static]

for the semicolon delimiter

Parameters:
somestr - pointer to a string
Returns:
number of occurances of the delimiter(semicolon)

Definition at line 151 of file res_config_ldap.c.

Referenced by realtime_ldap_result_to_vars(), and semicolon_count_var().

00152 {
00153    int count = 0;
00154 
00155    for (; *somestr; somestr++) {
00156       if (*somestr == ';')
00157          count++;
00158    }
00159 
00160    return count;
00161 } 

static int semicolon_count_var ( struct ast_variable var  )  [static]

Definition at line 166 of file res_config_ldap.c.

References ast_debug, semicolon_count_str(), ast_variable::value, and variable_named().

Referenced by realtime_ldap_result_to_vars().

00167 {
00168    struct ast_variable *var_value = variable_named(var, "variable_value");
00169 
00170    if (!var_value)
00171       return 0;
00172 
00173    ast_debug(1, "LINE(%d) semicolon_count_var: %s\n", __LINE__, var_value->value);
00174 
00175    return semicolon_count_str(var_value->value);
00176 }

static char* substituted ( struct ast_channel channel,
const char *  string 
) [static]

caller should free returned pointer

Definition at line 617 of file res_config_ldap.c.

References ast_calloc, ast_debug, ast_strlen_zero(), MAXRESULT, and pbx_substitute_variables_helper().

Referenced by cleaned_basedn().

00618 {
00619 #define MAXRESULT 2048
00620    char *ret_string = NULL;
00621 
00622    if (!ast_strlen_zero(string)) {
00623       ret_string = ast_calloc(1, MAXRESULT);
00624       pbx_substitute_variables_helper(channel, string, ret_string, MAXRESULT - 1);
00625    }
00626    ast_debug(2, "substituted: string: '%s' => '%s' \n",
00627       string, ret_string);
00628    return ret_string;
00629 }

static struct ldap_table_config* table_config_for_table_name ( const char *  table_name  )  [static, read]

Find a table_config - Should be locked before using it.

Note:
This function assumes ldap_lock to be locked.

Definition at line 123 of file res_config_ldap.c.

References AST_LIST_TRAVERSE, ldap_table_config::entry, and ldap_table_config::table_name.

Referenced by parse_config(), realtime_ldap_base_ap(), and update_ldap().

00124 {
00125    struct ldap_table_config *c = NULL;
00126 
00127    AST_LIST_TRAVERSE(&table_configs, c, entry) {
00128       if (!strcmp(c->table_name, table_name))
00129          break;
00130    }
00131 
00132    return c;
00133 }

static struct ldap_table_config* table_config_new ( const char *  table_name  )  [static, read]

Create a new table_config.

Definition at line 104 of file res_config_ldap.c.

References ast_calloc, ast_strdup, free, and ldap_table_config::table_name.

Referenced by parse_config().

00105 {
00106    struct ldap_table_config *p;
00107 
00108    if (!(p = ast_calloc(1, sizeof(*p))))
00109       return NULL;
00110 
00111    if (table_name) {
00112       if (!(p->table_name = ast_strdup(table_name))) {
00113          free(p);
00114          return NULL;
00115       }
00116    }
00117 
00118    return p;
00119 }

static void table_configs_free ( void   )  [static]

Free table_config.

Note:
assumes ldap_lock to be locked

Definition at line 197 of file res_config_ldap.c.

References ldap_table_config::additional_filter, AST_LIST_REMOVE_HEAD, ast_variables_destroy(), ldap_table_config::attributes, base_table_config, ldap_table_config::entry, free, static_table_config, and ldap_table_config::table_name.

Referenced by parse_config(), and unload_module().

00198 {
00199    struct ldap_table_config *c;
00200 
00201    while ((c = AST_LIST_REMOVE_HEAD(&table_configs, entry))) {
00202       if (c->table_name)
00203          free(c->table_name);
00204       if (c->additional_filter)
00205          free(c->additional_filter);
00206       if (c->attributes)
00207          ast_variables_destroy(c->attributes);
00208       free(c);
00209    }
00210 
00211    base_table_config = NULL;
00212    static_table_config = NULL;
00213 }

static int unload_module ( void   )  [static]

Definition at line 1338 of file res_config_ldap.c.

References ast_cli_unregister_multiple(), ast_config_engine_deregister(), ast_mutex_lock(), ast_mutex_unlock(), ast_verb, ldap_cli, ldap_engine, ldap_lock, and table_configs_free().

01339 {
01340    /* Aquire control before doing anything to the module itself. */
01341    ast_mutex_lock(&ldap_lock);
01342 
01343    table_configs_free();
01344 
01345    if (ldapConn) {
01346       ldap_unbind_ext_s(ldapConn, NULL, NULL);
01347       ldapConn = NULL;
01348    }
01349    ast_cli_unregister_multiple(ldap_cli, sizeof(ldap_cli) / sizeof(struct ast_cli_entry));
01350    ast_config_engine_deregister(&ldap_engine);
01351    ast_verb(1, "LDAP RealTime unloaded.\n");
01352 
01353    /* Unlock so something else can destroy the lock. */
01354    ast_mutex_unlock(&ldap_lock);
01355 
01356    return 0;
01357 }

static int update_ldap ( const char *  basedn,
const char *  table_name,
const char *  attribute,
const char *  lookup,
va_list  ap 
) [static]

Definition at line 1120 of file res_config_ldap.c.

References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_calloc, ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_realloc, ast_str_append(), ast_str_create(), base_table_config, cleaned_basedn(), convert_attribute_name_to_ldap(), filter(), free, is_ldap_connect_error(), ldap_lock, ldap_reconnect(), LOG_ERROR, LOG_WARNING, option_debug, ast_str::str, and table_config_for_table_name().

01122 {
01123    int error = 0;
01124    LDAPMessage *ldap_entry = NULL;
01125    LDAPMod **ldap_mods;
01126    const char *newparam = NULL;
01127    const char *newval = NULL;
01128    char *dn;
01129    int num_entries = 0;
01130    int i = 0;
01131    int mods_size = 0;
01132    int mod_exists = 0;
01133    struct ldap_table_config *table_config = NULL;
01134    char *clean_basedn = NULL;
01135    struct ast_str *filter = NULL;
01136    int tries = 0;
01137    int result = 0;
01138    LDAPMessage *ldap_result_msg = NULL;
01139 
01140    if (!table_name) {
01141       ast_log(LOG_WARNING, "No table_name specified.\n");
01142       return -1;
01143    } 
01144 
01145    if (!(filter = ast_str_create(80)))
01146       return -1;
01147 
01148    if (!attribute || !lookup) {
01149       ast_log(LOG_WARNING,
01150             "LINE(%d): search parameters are empty.\n", __LINE__);
01151       return -1;
01152    }
01153    ast_mutex_lock(&ldap_lock);
01154 
01155    /* We now have our complete statement; Lets connect to the server and execute it.  */
01156    if (!ldap_reconnect()) {
01157       ast_mutex_unlock(&ldap_lock);
01158       return -1;
01159    }
01160 
01161    table_config = table_config_for_table_name(table_name);
01162    if (!table_config) {
01163       ast_log(LOG_WARNING, "No table named '%s'.\n", table_name);
01164       ast_mutex_unlock(&ldap_lock);
01165       return -1;
01166    }
01167 
01168    clean_basedn = cleaned_basedn(NULL, basedn);
01169 
01170    /* Create the filter with the table additional filter and the parameter/value pairs we were given */
01171    ast_str_append(&filter, 0, "(&");
01172    if (table_config && table_config->additional_filter) {
01173       ast_str_append(&filter, 0, "%s", table_config->additional_filter);
01174    }
01175    if (table_config != base_table_config && base_table_config
01176       && base_table_config->additional_filter) {
01177       ast_str_append(&filter, 0, "%s", base_table_config->additional_filter);
01178    }
01179    append_var_and_value_to_filter(&filter, table_config, attribute, lookup);
01180    ast_str_append(&filter, 0, ")");
01181 
01182    /* Create the modification array with the parameter/value pairs we were given, 
01183     * if there are several parameters with the same name, we collect them into 
01184     * one parameter/value pair and delimit them with a semicolon */
01185    newparam = va_arg(ap, const char *);
01186    newparam = convert_attribute_name_to_ldap(table_config, newparam);
01187    newval = va_arg(ap, const char *);
01188    if (!newparam || !newval) {
01189       ast_log(LOG_WARNING,
01190             "LINE(%d): need at least one parameter to modify.\n", __LINE__);
01191       return -1;
01192    }
01193 
01194    mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */
01195    ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size);
01196    ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod));
01197 
01198    ldap_mods[0]->mod_op = LDAP_MOD_REPLACE;
01199    ldap_mods[0]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1);
01200    strcpy(ldap_mods[0]->mod_type, newparam);
01201 
01202    ldap_mods[0]->mod_values = ast_calloc(sizeof(char), 2);
01203    ldap_mods[0]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1);
01204    strcpy(ldap_mods[0]->mod_values[0], newval);
01205 
01206    while ((newparam = va_arg(ap, const char *))) {
01207       newparam = convert_attribute_name_to_ldap(table_config, newparam);
01208       newval = va_arg(ap, const char *);
01209       mod_exists = 0;
01210 
01211       for (i = 0; i < mods_size - 1; i++) {
01212          if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) {
01213             /* We have the parameter allready, adding the value as a semicolon delimited value */
01214             ldap_mods[i]->mod_values[0] = ast_realloc(ldap_mods[i]->mod_values[0], sizeof(char) * (strlen(ldap_mods[i]->mod_values[0]) + strlen(newval) + 2));
01215             strcat(ldap_mods[i]->mod_values[0], ";");
01216             strcat(ldap_mods[i]->mod_values[0], newval);
01217             mod_exists = 1;   
01218             break;
01219          }
01220       }
01221 
01222       /* create new mod */
01223       if (!mod_exists) {
01224          mods_size++;
01225          ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size);
01226          ldap_mods[mods_size - 1] = NULL;
01227          
01228          ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod));
01229 
01230          ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1);
01231          strcpy(ldap_mods[mods_size - 2]->mod_type, newparam);
01232 
01233          if (strlen(newval) == 0) {
01234             ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_DELETE;
01235          } else {
01236             ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE;
01237 
01238             ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2);
01239             ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1);
01240             strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval);
01241          }
01242       }
01243    }
01244    /* freeing ldap_mods further down */
01245 
01246    do {
01247       /* freeing ldap_result further down */
01248       result = ldap_search_ext_s(ldapConn, clean_basedn,
01249               LDAP_SCOPE_SUBTREE, filter->str, NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT,
01250               &ldap_result_msg);
01251       if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
01252          ast_log(LOG_WARNING, "Failed to query database. Try %d/3\n",
01253             tries + 1);
01254          tries++;
01255          if (tries < 3) {
01256             usleep(500000L * tries);
01257             if (ldapConn) {
01258                ldap_unbind_ext_s(ldapConn, NULL, NULL);
01259                ldapConn = NULL;
01260             }
01261             if (!ldap_reconnect())
01262                break;
01263          }
01264       }
01265    } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result));
01266 
01267    if (result != LDAP_SUCCESS) {
01268       ast_log(LOG_WARNING, "Failed to query directory. Check debug for more info.\n");
01269       ast_log(LOG_WARNING, "Query: %s\n", filter->str);
01270       ast_log(LOG_WARNING, "Query Failed because: %s\n",
01271          ldap_err2string(result));
01272 
01273       ast_mutex_unlock(&ldap_lock);
01274       free(filter);
01275       free(clean_basedn);
01276       ldap_msgfree(ldap_result_msg);
01277       ldap_mods_free(ldap_mods, 0);
01278       return -1;
01279    }
01280    /* Ready to update */
01281    if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) {
01282       ast_debug(3, "LINE(%d) Modifying %s=%s hits: %d\n", __LINE__, attribute, lookup, num_entries);
01283       for (i = 0; option_debug > 2 && i < mods_size - 1; i++) {
01284          if (ldap_mods[i]->mod_op != LDAP_MOD_DELETE) {
01285             ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]);
01286          } else {
01287             ast_debug(3, "LINE(%d) deleting %s \n", __LINE__, ldap_mods[i]->mod_type);
01288          }
01289       }
01290       ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
01291 
01292       for (i = 0; ldap_entry; i++) { 
01293          dn = ldap_get_dn(ldapConn, ldap_entry);
01294          if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) 
01295             ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error));
01296 
01297          ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
01298       }
01299    }
01300 
01301    ast_mutex_unlock(&ldap_lock);
01302    free(filter);
01303    free(clean_basedn);
01304    ldap_msgfree(ldap_result_msg);
01305    ldap_mods_free(ldap_mods, 0);
01306    return num_entries;
01307 }

static struct ast_variable* variable_named ( struct ast_variable var,
const char *  name 
) [static, read]

Find variable by name.

Definition at line 136 of file res_config_ldap.c.

References ast_variable::name, and ast_variable::next.

Referenced by config_ldap(), realtime_ldap_result_to_vars(), and semicolon_count_var().

00137 {
00138    for (; var; var = var->next) {
00139       if (!strcasecmp(name, var->name))
00140          break;
00141    }
00142 
00143    return var;
00144 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS , .description = "LDAP realtime interface" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 1579 of file res_config_ldap.c.

Definition at line 1579 of file res_config_ldap.c.

char base_distinguished_name[512] [static]

Definition at line 69 of file res_config_ldap.c.

time_t connect_time [static]

Definition at line 71 of file res_config_ldap.c.

Referenced by handle_cli_realtime_pgsql_status(), and pgsql_reconnect().

struct ast_cli_entry ldap_cli[] [static]

Initial value:

 {
   AST_CLI_DEFINE(realtime_ldap_status, "Shows connection information for the LDAP RealTime driver"),
}

Definition at line 99 of file res_config_ldap.c.

Referenced by load_module(), and unload_module().

struct ast_config_engine ldap_engine [static]

Definition at line 1309 of file res_config_ldap.c.

Referenced by load_module(), and unload_module().

ast_mutex_t ldap_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

LDAP* ldapConn [static]

Definition at line 65 of file res_config_ldap.c.

char pass[50] [static]

char url[512] [static]

char user[512] [static]

Definition at line 67 of file res_config_ldap.c.

int version = 3 [static]


Generated on Wed Oct 28 11:53:05 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6