Wed Jan 8 2020 09:50:18

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"

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...
 

Macros

#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. More...
 
static char * cleaned_basedn (struct ast_channel *channel, const char *basedn)
 
static int compare_categories (const void *a, const void *b)
 Sorting alogrithm for qsort to find the order of the variables a and b. More...
 
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. More...
 
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. More...
 
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. More...
 
static int is_ldap_connect_error (int err)
 Check if we have a connection error. More...
 
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) More...
 
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 More...
 
static int load_module (void)
 
static int parse_config (void)
 parse the configuration file More...
 
static struct ast_variablerealtime_ldap (const char *basedn, const char *table_name, va_list ap)
 See Asterisk doc. More...
 
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 More...
 
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. More...
 
static struct ast_variablerealtime_ldap_entry_to_var (struct ldap_table_config *table_config, LDAPMessage *ldap_entry)
 Get variables from ldap entry attributes. More...
 
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. More...
 
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. More...
 
static int reload (void)
 
static int replace_string_in_string (char *string, const char *search, const char *by)
 Replace <search> by <by> in string. More...
 
static int semicolon_count_str (const char *somestr)
 for the semicolon delimiter More...
 
static int semicolon_count_var (struct ast_variable *var)
 
static char * substituted (struct ast_channel *channel, const char *string)
 
static struct ldap_table_configtable_config_for_table_name (const char *table_name)
 Find a table_config - Should be locked before using it. More...
 
static struct ldap_table_configtable_config_new (const char *table_name)
 Create a new table_config. More...
 
static void table_configs_free (void)
 Free table_config. More...
 
static int unload_module (void)
 
static int update2_ldap (const char *basedn, const char *table_name, va_list ap)
 
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. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
 
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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static LDAP * ldapConn
 
static char pass [512]
 
static struct ldap_table_configstatic_table_config
 
static struct table_configs table_configs = { .first = NULL, .last = NULL, }
 
static char url [512]
 
static char user [512]
 
static int version
 

Detailed Description

ldap plugin for portable configuration engine (ARA)

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Manuel Guesdon
Carl-Einar Thorner cthor.nosp@m.ner@.nosp@m.voice.nosp@m.rd.c.nosp@m.om
Russell Bryant russe.nosp@m.ll@d.nosp@m.igium.nosp@m..com
ExtRef:
OpenLDAP http://www.openldap.org

Definition in file res_config_ldap.c.

Macro Definition Documentation

#define MAXRESULT   2048

Referenced by substituted().

#define RES_CONFIG_LDAP_CONF   "res_ldap.conf"

Definition at line 61 of file res_config_ldap.c.

Referenced by config_ldap(), and parse_config().

#define RES_CONFIG_LDAP_DEFAULT_BASEDN   "asterisk"

Definition at line 62 of file res_config_ldap.c.

Referenced by parse_config().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 1810 of file res_config_ldap.c.

static void __unreg_module ( void  )
static

Definition at line 1810 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 694 of file res_config_ldap.c.

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

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

697 {
698  char *new_name = NULL;
699  char *new_value = NULL;
700  char *like_pos = strstr(name, " LIKE");
701 
702  ast_debug(2, "name='%s' value='%s'\n", name, value);
703 
704  if (like_pos) {
705  int len = like_pos - name;
706 
707  name = new_name = ast_strdupa(name);
708  new_name[len] = '\0';
709  value = new_value = ast_strdupa(value);
710  replace_string_in_string(new_value, "\\_", "_");
711  replace_string_in_string(new_value, "%", "*");
712  }
713 
714  name = convert_attribute_name_to_ldap(table_config, name);
715 
716  ast_str_append(filter, 0, "(%s=%s)", name, value);
717 }
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
int value
Definition: syslog.c:39
static int replace_string_in_string(char *string, const char *search, const char *by)
Replace &lt;search&gt; by &lt;by&gt; in string.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static const char name[]
static char* cleaned_basedn ( struct ast_channel channel,
const char *  basedn 
)
static
Note
caller should free returned pointer

Definition at line 643 of file res_config_ldap.c.

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

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

644 {
645  char *cbasedn = NULL;
646  if (basedn) {
647  char *p = NULL;
648  cbasedn = substituted(channel, basedn);
649  if (*cbasedn == '"') {
650  cbasedn++;
651  if (!ast_strlen_zero(cbasedn)) {
652  int len = strlen(cbasedn);
653  if (cbasedn[len - 1] == '"')
654  cbasedn[len - 1] = '\0';
655 
656  }
657  }
658  p = cbasedn;
659  while (*p) {
660  if (*p == '|')
661  *p = ',';
662  p++;
663  }
664  }
665  ast_debug(2, "basedn: '%s' => '%s' \n", basedn, cbasedn);
666  return cbasedn;
667 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * substituted(struct ast_channel *channel, const char *string)
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
apointer to category_and_metric struct
bpointer to category_and_metric struct
Return values
-1for if b is greater
0zero for equal
1if a is greater

Definition at line 1019 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().

1020 {
1021  const struct category_and_metric *as = a;
1022  const struct category_and_metric *bs = b;
1023 
1024  if (as->metric < bs->metric) {
1025  return -1;
1026  } else if (as->metric > bs->metric) {
1027  return 1;
1028  } else if (as->metric == bs->metric && strcmp(as->name, bs->name) != 0) {
1029  return strcmp(as->name, bs->name);
1030  }
1031  /* if the metric and the category name is the same, we check the variable metric */
1032  if (as->var_metric < bs->var_metric) {
1033  return -1;
1034  } else if (as->var_metric > bs->var_metric) {
1035  return 1;
1036  }
1037 
1038  return 0;
1039 }
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

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 1048 of file res_config_ldap.c.

References ast_calloc, ast_category_append(), ast_category_new(), ast_config_internal_load(), ast_debug, ast_free, ast_log(), ast_strlen_zero(), ast_variable_append(), ast_variable_new(), compare_categories(), 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.

1050 {
1051  unsigned int vars_count = 0;
1052  struct ast_variable **vars;
1053  int i = 0;
1054  struct ast_variable *new_v = NULL;
1055  struct ast_category *cur_cat = NULL;
1056  const char *last_category = NULL;
1057  int last_category_metric = 0;
1058  struct category_and_metric *categories;
1059  struct ast_variable **p;
1060 
1061  if (ast_strlen_zero(file) || !strcasecmp(file, RES_CONFIG_LDAP_CONF)) {
1062  ast_log(LOG_ERROR, "Missing configuration file: %s. Can't configure myself.\n", RES_CONFIG_LDAP_CONF);
1063  return NULL;
1064  }
1065 
1066  vars = realtime_ldap_base(&vars_count, basedn, table_name, "filename", file, "commented", "FALSE", NULL);
1067 
1068  if (!vars) {
1069  ast_log(LOG_WARNING, "Could not find config '%s' in directory.\n", file);
1070  return NULL;
1071  }
1072 
1073  /*!\note Since the items come back in random order, they need to be sorted
1074  * first, and since the data could easily exceed stack size, this is
1075  * allocated from the heap.
1076  */
1077  if (!(categories = ast_calloc(sizeof(*categories), vars_count))) {
1078  return NULL;
1079  }
1080 
1081  for (vars_count = 0, p = vars; *p; p++) {
1082  struct ast_variable *category = variable_named(*p, "category");
1083  struct ast_variable *cat_metric = variable_named(*p, "cat_metric");
1084  struct ast_variable *var_name = variable_named(*p, "variable_name");
1085  struct ast_variable *var_val = variable_named(*p, "variable_value");
1086  struct ast_variable *var_metric = variable_named(*p, "var_metric");
1087  struct ast_variable *dn = variable_named(*p, "dn");
1088 
1089  ast_debug(3, "category: %s\n", category->value);
1090  ast_debug(3, "var_name: %s\n", var_name->value);
1091  ast_debug(3, "var_val: %s\n", var_val->value);
1092  ast_debug(3, "cat_metric: %s\n", cat_metric->value);
1093 
1094  if (!category) {
1095  ast_log(LOG_ERROR, "No category name in entry '%s' for file '%s'.\n",
1096  (dn ? dn->value : "?"), file);
1097  } else if (!cat_metric) {
1098  ast_log(LOG_ERROR, "No category metric in entry '%s'(category: %s) for file '%s'.\n",
1099  (dn ? dn->value : "?"), category->value, file);
1100  } else if (!var_metric) {
1101  ast_log(LOG_ERROR, "No variable metric in entry '%s'(category: %s) for file '%s'.\n",
1102  (dn ? dn->value : "?"), category->value, file);
1103  } else if (!var_name) {
1104  ast_log(LOG_ERROR, "No variable name in entry '%s' (category: %s metric: %s) for file '%s'.\n",
1105  (dn ? dn->value : "?"), category->value,
1106  cat_metric->value, file);
1107  } else if (!var_val) {
1108  ast_log(LOG_ERROR, "No variable value in entry '%s' (category: %s metric: %s variable: %s) for file '%s'.\n",
1109  (dn ? dn->value : "?"), category->value,
1110  cat_metric->value, var_name->value, file);
1111  } else {
1112  categories[vars_count].name = category->value;
1113  categories[vars_count].metric = atoi(cat_metric->value);
1114  categories[vars_count].variable_name = var_name->value;
1115  categories[vars_count].variable_value = var_val->value;
1116  categories[vars_count].var_metric = atoi(var_metric->value);
1117  vars_count++;
1118  }
1119  }
1120 
1121  qsort(categories, vars_count, sizeof(*categories), compare_categories);
1122 
1123  for (i = 0; i < vars_count; i++) {
1124  if (!strcmp(categories[i].variable_name, "#include")) {
1125  struct ast_flags flags = { 0 };
1126  if (!ast_config_internal_load(categories[i].variable_value, cfg, flags, "", who_asked)) {
1127  break;
1128  }
1129  continue;
1130  }
1131 
1132  if (!last_category || strcmp(last_category, categories[i].name) ||
1133  last_category_metric != categories[i].metric) {
1134 
1135  cur_cat = ast_category_new(categories[i].name, table_name, -1);
1136  if (!cur_cat) {
1137  break;
1138  }
1139  last_category = categories[i].name;
1140  last_category_metric = categories[i].metric;
1141  ast_category_append(cfg, cur_cat);
1142  }
1143 
1144  if (!(new_v = ast_variable_new(categories[i].variable_name, categories[i].variable_value, table_name))) {
1145  break;
1146  }
1147 
1148  ast_variable_append(cur_cat, new_v);
1149  }
1150 
1151  ast_free(vars);
1152  ast_free(categories);
1153 
1154  return cfg;
1155 }
#define LOG_WARNING
Definition: logger.h:144
unsigned int flags
Definition: utils.h:201
#define RES_CONFIG_LDAP_CONF
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static struct ast_variable * variable_named(struct ast_variable *var, const char *name)
Find variable by name.
const char * variable_value
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category structure.
Definition: config.c:673
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int compare_categories(const void *a, const void *b)
Sorting alogrithm for qsort to find the order of the variables a and b.
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
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
#define LOG_ERROR
Definition: logger.h:155
const char * file
Definition: config.h:85
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: config.c:483
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
Structure used to handle boolean flags.
Definition: utils.h:200
const char * variable_name
#define ast_calloc(a, b)
Definition: astmm.h:82
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Definition: config.c:719
struct ast_config * ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
Definition: config.c:2459
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
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.

Note
Should be locked before using it

Definition at line 251 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().

253 {
254  int i = 0;
255  struct ldap_table_config *configs[] = { table_config, base_table_config };
256 
257  for (i = 0; i < ARRAY_LEN(configs); i++) {
258  struct ast_variable *attribute;
259 
260  if (!configs[i]) {
261  continue;
262  }
263 
264  attribute = configs[i]->attributes;
265  for (; attribute; attribute = attribute->next) {
266  if (strcasecmp(attribute_name, attribute->value) == 0) {
267  return attribute->name;
268  }
269  }
270  }
271 
272  return attribute_name;
273 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static struct ldap_table_config * base_table_config
const char * value
Definition: config.h:79
Table configuration.
const char * name
Definition: config.h:77
struct ast_variable * attributes
struct ast_variable * next
Definition: config.h:82
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 225 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(), update2_ldap(), and update_ldap().

227 {
228  int i = 0;
229  struct ldap_table_config *configs[] = { table_config, base_table_config };
230 
231  for (i = 0; i < ARRAY_LEN(configs); i++) {
232  struct ast_variable *attribute;
233 
234  if (!configs[i]) {
235  continue;
236  }
237 
238  attribute = configs[i]->attributes;
239  for (; attribute; attribute = attribute->next) {
240  if (!strcasecmp(attribute_name, attribute->name)) {
241  return attribute->value;
242  }
243  }
244  }
245 
246  return attribute_name;
247 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static struct ldap_table_config * base_table_config
const char * value
Definition: config.h:79
Table configuration.
const char * name
Definition: config.h:77
struct ast_variable * attributes
struct ast_variable * next
Definition: config.h:82
static int is_ldap_connect_error ( int  err)
static

Check if we have a connection error.

Definition at line 546 of file res_config_ldap.c.

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

547 {
548  return (err == LDAP_SERVER_DOWN || err == LDAP_TIMEOUT || err == LDAP_CONNECT_ERROR);
549 }
static struct ast_variable* ldap_loadentry ( struct ldap_table_config table_config,
const char *  dn 
)
static

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 554 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().

556 {
557  if (!table_config) {
558  ast_log(LOG_ERROR, "No table config\n");
559  return NULL;
560  } else {
561  struct ast_variable **vars = NULL;
562  struct ast_variable *var = NULL;
563  int result = -1;
564  LDAPMessage *ldap_result_msg = NULL;
565  int tries = 0;
566 
567  ast_debug(2, "ldap_loadentry dn=%s\n", dn);
568 
569  do {
570  result = ldap_search_ext_s(ldapConn, dn, LDAP_SCOPE_BASE,
571  "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &ldap_result_msg);
572  if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
573  ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1);
574  tries++;
575  if (tries < 3) {
576  usleep(500000L * tries);
577  if (ldapConn) {
578  ldap_unbind_ext_s(ldapConn, NULL, NULL);
579  ldapConn = NULL;
580  }
581  if (!ldap_reconnect()) {
582  break;
583  }
584  }
585  }
586  } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result));
587 
588  if (result != LDAP_SUCCESS) {
589  ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result));
590  ast_debug(2, "dn=%s\n", dn);
592  return NULL;
593  } else {
594  int num_entry = 0;
595  unsigned int *entries_count_ptr = NULL; /*!< not using this */
596 
597  if ((num_entry = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) {
598  ast_debug(3, "num_entry: %d\n", num_entry);
599 
600  vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr);
601  if (num_entry > 1) {
602  ast_log(LOG_NOTICE, "More than one entry for dn=%s. Take only 1st one\n", dn);
603  }
604  } else {
605  ast_debug(2, "Could not find any entry dn=%s.\n", dn);
606  }
607  }
608  ldap_msgfree(ldap_result_msg);
609 
610  /* Chopping \a vars down to one variable */
611  if (vars != NULL) {
612  struct ast_variable **p = vars;
613  p++;
614  var = *p;
615  while (var) {
617  p++;
618  }
619  vars = ast_realloc(vars, sizeof(struct ast_variable *));
620  }
621 
622  var = *vars;
623 
624  return var;
625  }
626 }
static ast_mutex_t ldap_lock
#define LOG_WARNING
Definition: logger.h:144
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static int is_ldap_connect_error(int err)
Check if we have a connection error.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:155
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.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define ast_realloc(a, b)
Definition: astmm.h:103
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int ldap_reconnect ( void  )
static
Note
ldap_lock should have been locked before calling this function.

Definition at line 1710 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(), update2_ldap(), and update_ldap().

1711 {
1712  int bind_result = 0;
1713  struct berval cred;
1714 
1715  if (ldapConn) {
1716  ast_debug(2, "Everything seems fine.\n");
1717  return 1;
1718  }
1719 
1720  if (ast_strlen_zero(url)) {
1721  ast_log(LOG_ERROR, "Not enough parameters to connect to ldap directory\n");
1722  return 0;
1723  }
1724 
1725  if (LDAP_SUCCESS != ldap_initialize(&ldapConn, url)) {
1726  ast_log(LOG_ERROR, "Failed to init ldap connection to '%s'. Check debug for more info.\n", url);
1727  return 0;
1728  }
1729 
1730  if (LDAP_OPT_SUCCESS != ldap_set_option(ldapConn, LDAP_OPT_PROTOCOL_VERSION, &version)) {
1731  ast_log(LOG_WARNING, "Unable to set LDAP protocol version to %d, falling back to default.\n", version);
1732  }
1733 
1734  if (!ast_strlen_zero(user)) {
1735  ast_debug(2, "bind to '%s' as user '%s'\n", url, user);
1736  cred.bv_val = (char *) pass;
1737  cred.bv_len = strlen(pass);
1738  bind_result = ldap_sasl_bind_s(ldapConn, user, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
1739  } else {
1740  ast_debug(2, "bind %s anonymously\n", url);
1741  cred.bv_val = NULL;
1742  cred.bv_len = 0;
1743  bind_result = ldap_sasl_bind_s(ldapConn, NULL, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
1744  }
1745  if (bind_result == LDAP_SUCCESS) {
1746  ast_debug(2, "Successfully connected to directory.\n");
1747  connect_time = time(NULL);
1748  return 1;
1749  } else {
1750  ast_log(LOG_WARNING, "bind failed: %s\n", ldap_err2string(bind_result));
1751  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1752  ldapConn = NULL;
1753  return 0;
1754  }
1755 }
static char pass[512]
uint32_t version
#define LOG_WARNING
Definition: logger.h:144
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static time_t connect_time
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
structure to hold users read from users.conf
static char url[512]
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 182 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().

184 {
185  struct ast_variable *var;
186 
187  if (ast_strlen_zero(attribute_name) || ast_strlen_zero(attribute_value)) {
188  return;
189  }
190 
191  if (!(var = ast_variable_new(attribute_name, attribute_value, table_config->table_name))) {
192  return;
193  }
194 
195  if (table_config->attributes) {
196  var->next = table_config->attributes;
197  }
198  table_config->attributes = var;
199 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
struct ast_variable * attributes
struct ast_variable * next
Definition: config.h:82
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static int load_module ( void  )
static

Definition at line 1538 of file res_config_ldap.c.

References ARRAY_LEN, 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_ERROR, LOG_WARNING, and parse_config().

1539 {
1540  if (parse_config() < 0) {
1541  ast_log(LOG_ERROR, "Cannot load LDAP RealTime driver.\n");
1542  return 0;
1543  }
1544 
1546 
1547  if (!ldap_reconnect()) {
1548  ast_log(LOG_WARNING, "Couldn't establish connection to LDAP directory. Check debug.\n");
1549  }
1550 
1552  ast_verb(1, "LDAP RealTime driver loaded.\n");
1554 
1556 
1557  return 0;
1558 }
static ast_mutex_t ldap_lock
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_verb(level,...)
Definition: logger.h:243
static struct ast_config_engine ldap_engine
#define LOG_ERROR
Definition: logger.h:155
static struct ast_cli_entry ldap_cli[]
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Definition: config.c:2378
static int parse_config(void)
parse the configuration file
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int parse_config ( void  )
static

parse the configuration file

< using the [config] context for Static RealTime

Definition at line 1610 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, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, 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, static_table_config, table_config_for_table_name(), table_config_new(), table_configs_free(), ast_variable::value, and var.

Referenced by load_module(), and reload().

1611 {
1612  struct ast_config *config;
1613  struct ast_flags config_flags = {0};
1614  const char *s, *host;
1615  int port;
1616  char *category_name = NULL;
1617 
1618  /* Make sure that global variables are reset */
1619  url[0] = '\0';
1620  user[0] = '\0';
1621  pass[0] = '\0';
1622  base_distinguished_name[0] = '\0';
1623  version = 3;
1624 
1625  config = ast_config_load(RES_CONFIG_LDAP_CONF, config_flags);
1626  if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
1627  ast_log(LOG_ERROR, "Cannot load configuration file: %s\n", RES_CONFIG_LDAP_CONF);
1628  return -1;
1629  }
1630 
1631  if (!(s = ast_variable_retrieve(config, "_general", "user"))) {
1632  ast_log(LOG_NOTICE, "No directory user found, anonymous binding as default.\n");
1633  user[0] = '\0';
1634  } else {
1635  ast_copy_string(user, s, sizeof(user));
1636  }
1637 
1638  if (!ast_strlen_zero(user)) {
1639  if (!(s = ast_variable_retrieve(config, "_general", "pass"))) {
1640  ast_log(LOG_WARNING, "No directory password found, using 'asterisk' as default.\n");
1641  ast_copy_string(pass, "asterisk", sizeof(pass));
1642  } else {
1643  ast_copy_string(pass, s, sizeof(pass));
1644  }
1645  }
1646 
1647  /* URL is preferred, use host and port if not found */
1648  if ((s = ast_variable_retrieve(config, "_general", "url"))) {
1649  ast_copy_string(url, s, sizeof(url));
1650  } else if ((host = ast_variable_retrieve(config, "_general", "host"))) {
1651  if (!(s = ast_variable_retrieve(config, "_general", "port")) || sscanf(s, "%5d", &port) != 1 || port > 65535) {
1652  ast_log(LOG_NOTICE, "No directory port found, using 389 as default.\n");
1653  port = 389;
1654  }
1655 
1656  snprintf(url, sizeof(url), "ldap://%s:%d", host, port);
1657  } else {
1658  ast_log(LOG_ERROR, "No directory URL or host found.\n");
1659  ast_config_destroy(config);
1660  return -1;
1661  }
1662 
1663  if (!(s = ast_variable_retrieve(config, "_general", "basedn"))) {
1664  ast_log(LOG_ERROR, "No LDAP base dn found, using '%s' as default.\n", RES_CONFIG_LDAP_DEFAULT_BASEDN);
1666  } else
1668 
1669  if (!(s = ast_variable_retrieve(config, "_general", "version")) && !(s = ast_variable_retrieve(config, "_general", "protocol"))) {
1670  ast_log(LOG_NOTICE, "No explicit LDAP version found, using 3 as default.\n");
1671  } else if (sscanf(s, "%30d", &version) != 1 || version < 1 || version > 6) {
1672  ast_log(LOG_WARNING, "Invalid LDAP version '%s', using 3 as default.\n", s);
1673  version = 3;
1674  }
1675 
1677 
1678  while ((category_name = ast_category_browse(config, category_name))) {
1679  int is_general = (strcasecmp(category_name, "_general") == 0);
1680  int is_config = (strcasecmp(category_name, "config") == 0); /*!< using the [config] context for Static RealTime */
1681  struct ast_variable *var = ast_variable_browse(config, category_name);
1682 
1683  if (var) {
1684  struct ldap_table_config *table_config =
1685  table_config_for_table_name(category_name);
1686  if (!table_config) {
1687  table_config = table_config_new(category_name);
1688  AST_LIST_INSERT_HEAD(&table_configs, table_config, entry);
1689  if (is_general)
1690  base_table_config = table_config;
1691  if (is_config)
1692  static_table_config = table_config;
1693  }
1694  for (; var; var = var->next) {
1695  if (!strcasecmp(var->name, "additionalFilter")) {
1696  table_config->additional_filter = ast_strdup(var->value);
1697  } else {
1698  ldap_table_config_add_attribute(table_config, var->name, var->value);
1699  }
1700  }
1701  }
1702  }
1703 
1704  ast_config_destroy(config);
1705 
1706  return 1;
1707 }
static char pass[512]
uint32_t version
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static const char config[]
Definition: cdr_csv.c:57
#define ast_strdup(a)
Definition: astmm.h:109
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
#define RES_CONFIG_LDAP_CONF
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static struct ldap_table_config * table_config_new(const char *table_name)
Create a new table_config.
static char base_distinguished_name[512]
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
static struct ldap_table_config * base_table_config
static struct ldap_table_config * table_config_for_table_name(const char *table_name)
Find a table_config - Should be locked before using it.
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
const char * value
Definition: config.h:79
static void table_configs_free(void)
Free table_config.
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
Table configuration.
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
Definition: config.c:810
const char * name
Definition: config.h:77
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:696
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
structure to hold users read from users.conf
Structure used to handle boolean flags.
Definition: utils.h:200
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
#define RES_CONFIG_LDAP_DEFAULT_BASEDN
struct ldap_table_config::@326 entry
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static char url[512]
Should be locked before using it.
static struct ldap_table_config * static_table_config
static struct ast_variable* realtime_ldap ( const char *  basedn,
const char *  table_name,
va_list  ap 
)
static

See Asterisk doc.

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

Definition at line 921 of file res_config_ldap.c.

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

923 {
924  struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, ap);
925  struct ast_variable *var = NULL;
926 
927  if (vars) {
928  struct ast_variable *last_var = NULL;
929  struct ast_variable **p = vars;
930  while (*p) {
931  if (last_var) {
932  while (last_var->next) {
933  last_var = last_var->next;
934  }
935  last_var->next = *p;
936  } else {
937  var = *p;
938  last_var = var;
939  }
940  p++;
941  }
942  free(vars);
943  }
944  return var;
945 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
#define free(a)
Definition: astmm.h:94
struct ast_variable * next
Definition: config.h:82
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_variable** realtime_ldap_base ( unsigned int *  entries_count_ptr,
const char *  basedn,
const char *  table_name,
  ... 
)
static

same as realtime_ldap_base_ap but take variable arguments count list

Definition at line 904 of file res_config_ldap.c.

References realtime_ldap_base_ap().

Referenced by config_ldap().

906 {
907  struct ast_variable **vars = NULL;
908  va_list ap;
909 
910  va_start(ap, table_name);
911  vars = realtime_ldap_base_ap(entries_count_ptr, basedn, table_name, ap);
912  va_end(ap);
913 
914  return vars;
915 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
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_variable** realtime_ldap_base_ap ( unsigned int *  entries_count_ptr,
const char *  basedn,
const char *  table_name,
va_list  ap 
)
static

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_ptris a pointer to found entries count (can be NULL)
basednis the base DN
table_nameis the table_name (used dor attribute convertion and additional filter)
apcontains null terminated list of pairs name/value

Definition at line 727 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_buffer(), 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_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, ldap_table_config::next, realtime_ldap_result_to_vars(), table_config_for_table_name(), and ast_variable::value.

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

729 {
730  struct ast_variable **vars = NULL;
731  const char *newparam = NULL;
732  const char *newval = NULL;
733  struct ldap_table_config *table_config = NULL;
734  char *clean_basedn = cleaned_basedn(NULL, basedn);
735  struct ast_str *filter = NULL;
736  int tries = 0;
737  int result = 0;
738  LDAPMessage *ldap_result_msg = NULL;
739 
740  if (!table_name) {
741  ast_log(LOG_ERROR, "No table_name specified.\n");
742  ast_free(clean_basedn);
743  return NULL;
744  }
745 
746  if (!(filter = ast_str_create(80))) {
747  ast_log(LOG_ERROR, "Can't initialize data structures.n");
748  ast_free(clean_basedn);
749  return NULL;
750  }
751 
752  /* Get the first parameter and first value in our list of passed paramater/value pairs */
753  newparam = va_arg(ap, const char *);
754  newval = va_arg(ap, const char *);
755 
756  if (!newparam || !newval) {
757  ast_log(LOG_ERROR, "Realtime retrieval requires at least 1 parameter"
758  " and 1 value to search on.\n");
759  ast_free(filter);
760  ast_free(clean_basedn);
761  return NULL;
762  }
763 
765 
766  /* We now have our complete statement; Lets connect to the server and execute it. */
767  if (!ldap_reconnect()) {
769  ast_free(filter);
770  ast_free(clean_basedn);
771  return NULL;
772  }
773 
774  table_config = table_config_for_table_name(table_name);
775  if (!table_config) {
776  ast_log(LOG_WARNING, "No table named '%s'.\n", table_name);
778  ast_free(filter);
779  ast_free(clean_basedn);
780  return NULL;
781  }
782 
783  ast_str_append(&filter, 0, "(&");
784 
785  if (table_config && table_config->additional_filter) {
786  ast_str_append(&filter, 0, "%s", table_config->additional_filter);
787  }
788  if (table_config != base_table_config && base_table_config &&
791  }
792 
793  /* Create the first part of the query using the first parameter/value pairs we just extracted */
794  /* If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */
795 
796  append_var_and_value_to_filter(&filter, table_config, newparam, newval);
797  while ((newparam = va_arg(ap, const char *))) {
798  newval = va_arg(ap, const char *);
799  append_var_and_value_to_filter(&filter, table_config, newparam, newval);
800  }
801  ast_str_append(&filter, 0, ")");
802 
803  do {
804  /* freeing ldap_result further down */
805  result = ldap_search_ext_s(ldapConn, clean_basedn,
806  LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT,
807  &ldap_result_msg);
808  if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
809  ast_log(LOG_DEBUG, "Failed to query directory. Try %d/10\n", tries + 1);
810  if (++tries < 10) {
811  usleep(1);
812  if (ldapConn) {
813  ldap_unbind_ext_s(ldapConn, NULL, NULL);
814  ldapConn = NULL;
815  }
816  if (!ldap_reconnect()) {
817  break;
818  }
819  }
820  }
821  } while (result != LDAP_SUCCESS && tries < 10 && is_ldap_connect_error(result));
822 
823  if (result != LDAP_SUCCESS) {
824  ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result));
825  ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter));
826  } else {
827  /* this is where we create the variables from the search result
828  * freeing this \a vars outside this function */
829  if (ldap_count_entries(ldapConn, ldap_result_msg) > 0) {
830  /* is this a static var or some other? they are handled different for delimited values */
831  vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr);
832  } else {
833  ast_debug(1, "Could not find any entry matching %s in base dn %s.\n", ast_str_buffer(filter), clean_basedn);
834  }
835 
836  ldap_msgfree(ldap_result_msg);
837 
838  /* TODO: get the default variables from the accountBaseDN, not implemented with delimited values */
839  if (vars) {
840  struct ast_variable **p = vars;
841  while (*p) {
842  struct ast_variable *append_var = NULL;
843  struct ast_variable *tmp = *p;
844  while (tmp) {
845  if (strcasecmp(tmp->name, "accountBaseDN") == 0) {
846  /* Get the variable to compare with for the defaults */
847  struct ast_variable *base_var = ldap_loadentry(table_config, tmp->value);
848 
849  while (base_var) {
850  struct ast_variable *next = base_var->next;
851  struct ast_variable *test_var = *p;
852  int base_var_found = 0;
853 
854  /* run throught the default values and fill it inn if it is missing */
855  while (test_var) {
856  if (strcasecmp(test_var->name, base_var->name) == 0) {
857  base_var_found = 1;
858  break;
859  } else {
860  test_var = test_var->next;
861  }
862  }
863  if (base_var_found) {
864  base_var->next = NULL;
865  ast_variables_destroy(base_var);
866  base_var = next;
867  } else {
868  if (append_var) {
869  base_var->next = append_var;
870  } else {
871  base_var->next = NULL;
872  }
873  append_var = base_var;
874  base_var = next;
875  }
876  }
877  }
878  if (!tmp->next && append_var) {
879  tmp->next = append_var;
880  tmp = NULL;
881  } else {
882  tmp = tmp->next;
883  }
884  }
885  p++;
886  }
887  }
888  }
889 
890  if (filter) {
891  ast_free(filter);
892  }
893 
894  if (clean_basedn) {
895  ast_free(clean_basedn);
896  }
897 
899 
900  return vars;
901 }
static ast_mutex_t ldap_lock
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.
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static char * cleaned_basedn(struct ast_channel *channel, const char *basedn)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ast_mutex_lock(a)
Definition: lock.h:155
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
#define LOG_DEBUG
Definition: logger.h:122
static int is_ldap_connect_error(int err)
Check if we have a connection error.
static struct ldap_table_config * base_table_config
static struct ldap_table_config * table_config_for_table_name(const char *table_name)
Find a table_config - Should be locked before using it.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
Table configuration.
const char * name
Definition: config.h:77
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
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.
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
static struct ast_variable * ldap_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 us...
struct ast_variable * next
Definition: config.h:82
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:694
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct ast_variable* realtime_ldap_entry_to_var ( struct ldap_table_config table_config,
LDAPMessage *  ldap_entry 
)
static

Get variables from ldap entry attributes.

Note
Should be locked before using it
Returns
a linked list of ast_variable variables.

Definition at line 279 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, value, and var.

Referenced by realtime_ldap_result_to_vars().

281 {
282  BerElement *ber = NULL;
283  struct ast_variable *var = NULL;
284  struct ast_variable *prev = NULL;
285  int is_delimited = 0;
286  int i = 0;
287  char *ldap_attribute_name;
288  struct berval *value;
289  int pos = 0;
290 
291  ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber);
292 
293  while (ldap_attribute_name) {
294  struct berval **values = NULL;
295  const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name);
296  int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0;
297 
298  values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); /* these are freed at the end */
299  if (values) {
300  struct berval **v;
301  char *valptr;
302 
303  for (v = values; *v; v++) {
304  value = *v;
305  valptr = value->bv_val;
306  ast_debug(2, "LINE(%d) attribute_name: %s LDAP value: %s\n", __LINE__, attribute_name, valptr);
307  if (is_realmed_password_attribute) {
308  if (!strncasecmp(valptr, "{md5}", 5)) {
309  valptr += 5;
310  }
311  ast_debug(2, "md5: %s\n", valptr);
312  }
313  if (valptr) {
314  /* ok, so looping through all delimited values except the last one (not, last character is not delimited...) */
315  if (is_delimited) {
316  i = 0;
317  pos = 0;
318  while (!ast_strlen_zero(valptr + i)) {
319  if (valptr[i] == ';') {
320  valptr[i] = '\0';
321  if (prev) {
322  prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
323  if (prev->next) {
324  prev = prev->next;
325  }
326  } else {
327  prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
328  }
329  pos = i + 1;
330  }
331  i++;
332  }
333  }
334  /* for the last delimited value or if the value is not delimited: */
335  if (prev) {
336  prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
337  if (prev->next) {
338  prev = prev->next;
339  }
340  } else {
341  prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
342  }
343  }
344  }
345  ldap_value_free_len(values);
346  }
347  ldap_memfree(ldap_attribute_name);
348  ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber);
349  }
350  ber_free(ber, 0);
351 
352  return var;
353 }
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
int value
Definition: syslog.c:39
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static LDAP * ldapConn
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.
struct ast_variable * next
Definition: config.h:82
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
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

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 361 of file res_config_ldap.c.

References ast_calloc, ast_debug, ast_strdup, ast_strlen_zero(), ast_variable_new(), ast_variables_destroy(), 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, value, ast_variable::value, var, and variable_named().

Referenced by ldap_loadentry(), and realtime_ldap_base_ap().

363 {
364  struct ast_variable **vars;
365  int i = 0;
366  int tot_count = 0;
367  int entry_index = 0;
368  LDAPMessage *ldap_entry = NULL;
369  BerElement *ber = NULL;
370  struct ast_variable *var = NULL;
371  struct ast_variable *prev = NULL;
372  int is_delimited = 0;
373  char *delim_value = NULL;
374  int delim_tot_count = 0;
375  int delim_count = 0;
376 
377  /* First find the total count */
378  ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
379 
380  for (tot_count = 0; ldap_entry; tot_count++) {
381  struct ast_variable *tmp = realtime_ldap_entry_to_var(table_config, ldap_entry);
382  tot_count += semicolon_count_var(tmp);
383  ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
385  }
386 
387  if (entries_count_ptr) {
388  *entries_count_ptr = tot_count;
389  }
390 
391  /* Now that we have the total count we allocate space and create the variables
392  * Remember that each element in vars is a linked list that points to realtime variable.
393  * If the we are dealing with a static realtime variable we create a new element in the \a vars array for each delimited
394  * 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.
395  * This memory must be freed outside of this function. */
396  vars = ast_calloc(sizeof(struct ast_variable *), tot_count + 1);
397 
398  ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
399 
400  i = 0;
401 
402  /* For each static realtime variable we may create several entries in the \a vars array if it's delimited */
403  for (entry_index = 0; ldap_entry; ) {
404  int pos = 0;
405  delim_value = NULL;
406  delim_tot_count = 0;
407  delim_count = 0;
408 
409  do { /* while delim_count */
410 
411  /* Starting new static var */
412  char *ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber);
413  struct berval *value;
414  while (ldap_attribute_name) {
415 
416  const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name);
417  int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0;
418  struct berval **values = NULL;
419 
420  values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name);
421  if (values) {
422  struct berval **v;
423  char *valptr;
424 
425  for (v = values; *v; v++) {
426  value = *v;
427  valptr = value->bv_val;
428  if (is_realmed_password_attribute) {
429  if (strncasecmp(valptr, "{md5}", 5) == 0) {
430  valptr += 5;
431  }
432  ast_debug(2, "md5: %s\n", valptr);
433  }
434  if (valptr) {
435  if (delim_value == NULL && !is_realmed_password_attribute
436  && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0)) {
437 
438  delim_value = ast_strdup(valptr);
439 
440  if ((delim_tot_count = semicolon_count_str(delim_value)) > 0) {
441  ast_debug(4, "LINE(%d) is delimited %d times: %s\n", __LINE__, delim_tot_count, delim_value);
442  is_delimited = 1;
443  }
444  }
445 
446  if (is_delimited != 0 && !is_realmed_password_attribute
447  && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0) ) {
448  /* for non-Static RealTime, first */
449 
450  for (i = pos; !ast_strlen_zero(valptr + i); i++) {
451  ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i);
452  if (delim_value[i] == ';') {
453  delim_value[i] = '\0';
454 
455  ast_debug(2, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos);
456 
457  if (prev) {
458  prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
459  if (prev->next) {
460  prev = prev->next;
461  }
462  } else {
463  prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
464  }
465  pos = i + 1;
466 
467  if (static_table_config == table_config) {
468  break;
469  }
470  }
471  }
472  if (ast_strlen_zero(valptr + i)) {
473  ast_debug(4, "LINE(%d) DELIM pos: %d i: %d delim_count: %d\n", __LINE__, pos, i, delim_count);
474  /* Last delimited value */
475  ast_debug(4, "LINE(%d) DELIM - attribute_name: %s value: %s pos: %d\n", __LINE__, attribute_name, &delim_value[pos], pos);
476  if (prev) {
477  prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
478  if (prev->next) {
479  prev = prev->next;
480  }
481  } else {
482  prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
483  }
484  /* Remembering to free memory */
485  is_delimited = 0;
486  pos = 0;
487  }
488  free(delim_value);
489  delim_value = NULL;
490 
491  ast_debug(4, "LINE(%d) DELIM pos: %d i: %d\n", __LINE__, pos, i);
492  } else {
493  /* not delimited */
494  if (delim_value) {
495  free(delim_value);
496  delim_value = NULL;
497  }
498  ast_debug(2, "LINE(%d) attribute_name: %s value: %s\n", __LINE__, attribute_name, valptr);
499 
500  if (prev) {
501  prev->next = ast_variable_new(attribute_name, valptr, table_config->table_name);
502  if (prev->next) {
503  prev = prev->next;
504  }
505  } else {
506  prev = var = ast_variable_new(attribute_name, valptr, table_config->table_name);
507  }
508  }
509  }
510  } /*!< for (v = values; *v; v++) */
511  ldap_value_free_len(values);
512  }/*!< if (values) */
513  ldap_memfree(ldap_attribute_name);
514  ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber);
515  } /*!< while (ldap_attribute_name) */
516  ber_free(ber, 0);
517  if (static_table_config == table_config) {
518  if (option_debug > 2) {
519  const struct ast_variable *tmpdebug = variable_named(var, "variable_name");
520  const struct ast_variable *tmpdebug2 = variable_named(var, "variable_value");
521  if (tmpdebug && tmpdebug2) {
522  ast_debug(3, "LINE(%d) Added to vars - %s = %s\n", __LINE__, tmpdebug->value, tmpdebug2->value);
523  }
524  }
525  vars[entry_index++] = var;
526  prev = NULL;
527  }
528 
529  delim_count++;
530  } while (delim_count <= delim_tot_count && static_table_config == table_config);
531 
532  if (static_table_config != table_config) {
533  ast_debug(3, "LINE(%d) Added to vars - non static\n", __LINE__);
534 
535  vars[entry_index++] = var;
536  prev = NULL;
537  }
538  ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
539  } /*!< end for loop over ldap_entry */
540 
541  return vars;
542 }
#define ast_strdup(a)
Definition: astmm.h:109
int option_debug
Definition: asterisk.c:182
static int semicolon_count_str(const char *somestr)
for the semicolon delimiter
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
static struct ast_variable * variable_named(struct ast_variable *var, const char *name)
Find variable by name.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
int value
Definition: syslog.c:39
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static LDAP * ldapConn
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.
#define free(a)
Definition: astmm.h:94
static struct ast_variable * realtime_ldap_entry_to_var(struct ldap_table_config *table_config, LDAPMessage *ldap_entry)
Get variables from ldap entry attributes.
static int semicolon_count_var(struct ast_variable *var)
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_variable * next
Definition: config.h:82
struct ast_variable * ast_variable_new(const char *name, const char *value, const char *filename)
Definition: config.c:278
static struct ldap_table_config * static_table_config
static char * realtime_ldap_status ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 1757 of file res_config_ldap.c.

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

1758 {
1759  char status[256], credentials[100] = "";
1760  int ctimesec = time(NULL) - connect_time;
1761 
1762  switch (cmd) {
1763  case CLI_INIT:
1764  e->command = "realtime show ldap status";
1765  e->usage =
1766  "Usage: realtime show ldap status\n"
1767  " Shows connection information for the LDAP RealTime driver\n";
1768  return NULL;
1769  case CLI_GENERATE:
1770  return NULL;
1771  }
1772 
1773  if (!ldapConn)
1774  return CLI_FAILURE;
1775 
1776  if (!ast_strlen_zero(url))
1777  snprintf(status, sizeof(status), "Connected to '%s', baseDN %s", url, base_distinguished_name);
1778 
1779  if (!ast_strlen_zero(user))
1780  snprintf(credentials, sizeof(credentials), " with username %s", user);
1781 
1782  if (ctimesec > 31536000) {
1783  ast_cli(a->fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n",
1784  status, credentials, ctimesec / 31536000,
1785  (ctimesec % 31536000) / 86400, (ctimesec % 86400) / 3600,
1786  (ctimesec % 3600) / 60, ctimesec % 60);
1787  } else if (ctimesec > 86400) {
1788  ast_cli(a->fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n",
1789  status, credentials, ctimesec / 86400, (ctimesec % 86400) / 3600,
1790  (ctimesec % 3600) / 60, ctimesec % 60);
1791  } else if (ctimesec > 3600) {
1792  ast_cli(a->fd, "%s%s for %d hours, %d minutes, %d seconds.\n",
1793  status, credentials, ctimesec / 3600, (ctimesec % 3600) / 60,
1794  ctimesec % 60);
1795  } else if (ctimesec > 60) {
1796  ast_cli(a->fd, "%s%s for %d minutes, %d seconds.\n", status, credentials,
1797  ctimesec / 60, ctimesec % 60);
1798  } else {
1799  ast_cli(a->fd, "%s%s for %d seconds.\n", status, credentials, ctimesec);
1800  }
1801 
1802  return CLI_SUCCESS;
1803 }
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static char base_distinguished_name[512]
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static time_t connect_time
static LDAP * ldapConn
#define CLI_FAILURE
Definition: cli.h:45
char * command
Definition: cli.h:180
structure to hold users read from users.conf
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char url[512]
jack_status_t status
Definition: app_jack.c:143
static struct ast_config* realtime_multi_ldap ( const char *  basedn,
const char *  table_name,
va_list  ap 
)
static

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 954 of file res_config_ldap.c.

References ast_category_append(), ast_category_new(), ast_category_rename(), ast_config_new(), ast_log(), ast_strdupa, ast_variable_append(), free, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, ldap_table_config::next, realtime_ldap_base_ap(), ast_variable::value, and var.

956 {
957  char *op;
958  const char *initfield = NULL;
959  const char *newparam, *newval;
960  struct ast_variable **vars =
961  realtime_ldap_base_ap(NULL, basedn, table_name, ap);
962  struct ast_config *cfg = NULL;
963 
964  newparam = va_arg(ap, const char *);
965  newval = va_arg(ap, const char *);
966  if (!newparam || !newval) {
967  ast_log(LOG_WARNING, "realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
968  return NULL;
969  }
970  initfield = ast_strdupa(newparam);
971  if ((op = strchr(initfield, ' '))) {
972  *op = '\0';
973  }
974 
975  if (vars) {
976  cfg = ast_config_new();
977  if (!cfg) {
978  ast_log(LOG_ERROR, "Unable to create a config!\n");
979  } else {
980  struct ast_variable **p = vars;
981 
982  while (*p) {
983  struct ast_category *cat = NULL;
984  cat = ast_category_new("", table_name, -1);
985  if (!cat) {
986  ast_log(LOG_ERROR, "Unable to create a new category!\n");
987  break;
988  } else {
989  struct ast_variable *var = *p;
990  while (var) {
991  struct ast_variable *next = var->next;
992  if (initfield && !strcmp(initfield, var->name)) {
993  ast_category_rename(cat, var->value);
994  }
995  var->next = NULL;
996  ast_variable_append(cat, var);
997  var = next;
998  }
999  }
1000  ast_category_append(cfg, cat);
1001  p++;
1002  }
1003  }
1004  free(vars);
1005  }
1006  return cfg;
1007 
1008 }
#define LOG_WARNING
Definition: logger.h:144
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
struct ast_category * ast_category_new(const char *name, const char *in_file, int lineno)
Create a category structure.
Definition: config.c:673
const char * value
Definition: config.h:79
const char * name
Definition: config.h:77
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
#define free(a)
Definition: astmm.h:94
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: config.c:483
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: config.c:888
struct ast_variable * next
Definition: config.h:82
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.
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Definition: config.c:719
void ast_category_rename(struct ast_category *cat, const char *name)
Definition: config.c:867
static int reload ( void  )
static

Definition at line 1581 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().

1582 {
1583  /* Aquire control before doing anything to the module itself. */
1585 
1586  if (ldapConn) {
1587  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1588  ldapConn = NULL;
1589  }
1590 
1591  if (parse_config() < 0) {
1592  ast_log(LOG_NOTICE, "Cannot reload LDAP RealTime driver.\n");
1594  return 0;
1595  }
1596 
1597  if (!ldap_reconnect()) {
1598  ast_log(LOG_WARNING, "Couldn't establish connection to your directory server. Check debug.\n");
1599  }
1600 
1601  ast_verb(2, "LDAP RealTime driver reloaded.\n");
1602 
1603  /* Done reloading. Release lock so others can now use driver. */
1605 
1606  return 0;
1607 }
static ast_mutex_t ldap_lock
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_verb(level,...)
Definition: logger.h:243
static LDAP * ldapConn
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static int parse_config(void)
parse the configuration file
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int replace_string_in_string ( char *  string,
const char *  search,
const char *  by 
)
static

Replace <search> by <by> in string.

Note
No check is done on string allocated size !

Definition at line 671 of file res_config_ldap.c.

Referenced by append_var_and_value_to_filter().

672 {
673  int search_len = strlen(search);
674  int by_len = strlen(by);
675  int replaced = 0;
676  char *p = strstr(string, search);
677 
678  if (p) {
679  replaced = 1;
680  while (p) {
681  if (by_len == search_len) {
682  memcpy(p, by, by_len);
683  } else {
684  memmove(p + by_len, p + search_len, strlen(p + search_len) + 1);
685  memcpy(p, by, by_len);
686  }
687  p = strstr(p + by_len, search);
688  }
689  }
690  return replaced;
691 }
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 153 of file res_config_ldap.c.

Referenced by realtime_ldap_result_to_vars(), and semicolon_count_var().

154 {
155  int count = 0;
156 
157  for (; *somestr; somestr++) {
158  if (*somestr == ';')
159  count++;
160  }
161 
162  return count;
163 }
static int semicolon_count_var ( struct ast_variable var)
static

Definition at line 168 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().

169 {
170  struct ast_variable *var_value = variable_named(var, "variable_value");
171 
172  if (!var_value) {
173  return 0;
174  }
175 
176  ast_debug(2, "LINE(%d) semicolon_count_var: %s\n", __LINE__, var_value->value);
177 
178  return semicolon_count_str(var_value->value);
179 }
static int semicolon_count_str(const char *somestr)
for the semicolon delimiter
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
static struct ast_variable * variable_named(struct ast_variable *var, const char *name)
Find variable by name.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * value
Definition: config.h:79
static char* substituted ( struct ast_channel channel,
const char *  string 
)
static
Note
caller should free returned pointer

Definition at line 629 of file res_config_ldap.c.

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

Referenced by cleaned_basedn().

630 {
631 #define MAXRESULT 2048
632  char *ret_string = NULL;
633 
634  if (!ast_strlen_zero(string)) {
635  ret_string = ast_calloc(1, MAXRESULT);
636  pbx_substitute_variables_helper(channel, string, ret_string, MAXRESULT - 1);
637  }
638  ast_debug(2, "substituted: string: '%s' => '%s' \n", string, ret_string);
639  return ret_string;
640 }
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: pbx.c:4676
#define MAXRESULT
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_calloc(a, b)
Definition: astmm.h:82
static struct ldap_table_config* table_config_for_table_name ( const char *  table_name)
static

Find a table_config - Should be locked before using it.

Note
This function assumes ldap_lock to be locked.

Definition at line 125 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(), update2_ldap(), and update_ldap().

126 {
127  struct ldap_table_config *c = NULL;
128 
130  if (!strcmp(c->table_name, table_name))
131  break;
132  }
133 
134  return c;
135 }
Table configuration.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ldap_table_config::@326 entry
Should be locked before using it.
static struct ldap_table_config* table_config_new ( const char *  table_name)
static

Create a new table_config.

Definition at line 106 of file res_config_ldap.c.

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

Referenced by parse_config().

107 {
108  struct ldap_table_config *p;
109 
110  if (!(p = ast_calloc(1, sizeof(*p))))
111  return NULL;
112 
113  if (table_name) {
114  if (!(p->table_name = ast_strdup(table_name))) {
115  free(p);
116  return NULL;
117  }
118  }
119 
120  return p;
121 }
#define ast_strdup(a)
Definition: astmm.h:109
Table configuration.
#define free(a)
Definition: astmm.h:94
#define ast_calloc(a, b)
Definition: astmm.h:82
static void table_configs_free ( void  )
static

Free table_config.

Note
assumes ldap_lock to be locked

Definition at line 203 of file res_config_ldap.c.

References ldap_table_config::additional_filter, ast_free, 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().

204 {
205  struct ldap_table_config *c;
206 
207  while ((c = AST_LIST_REMOVE_HEAD(&table_configs, entry))) {
208  if (c->table_name) {
209  ast_free(c->table_name);
210  }
211  if (c->additional_filter) {
213  }
214  if (c->attributes) {
216  }
217  free(c);
218  }
219 
220  base_table_config = NULL;
221  static_table_config = NULL;
222 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: config.c:586
static struct ldap_table_config * base_table_config
Table configuration.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:818
#define free(a)
Definition: astmm.h:94
#define ast_free(a)
Definition: astmm.h:97
struct ast_variable * attributes
struct ldap_table_config::@326 entry
Should be locked before using it.
static struct ldap_table_config * static_table_config
static int unload_module ( void  )
static

Definition at line 1560 of file res_config_ldap.c.

References ARRAY_LEN, 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().

1561 {
1562  /* Aquire control before doing anything to the module itself. */
1564 
1566 
1567  if (ldapConn) {
1568  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1569  ldapConn = NULL;
1570  }
1573  ast_verb(1, "LDAP RealTime driver unloaded.\n");
1574 
1575  /* Unlock so something else can destroy the lock. */
1577 
1578  return 0;
1579 }
static ast_mutex_t ldap_lock
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_verb(level,...)
Definition: logger.h:243
static void table_configs_free(void)
Free table_config.
static struct ast_config_engine ldap_engine
static LDAP * ldapConn
static struct ast_cli_entry ldap_cli[]
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
Definition: config.c:2397
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int update2_ldap ( const char *  basedn,
const char *  table_name,
va_list  ap 
)
static

Definition at line 1343 of file res_config_ldap.c.

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

1344 {
1345  int error = 0;
1346  LDAPMessage *ldap_entry = NULL;
1347  LDAPMod **ldap_mods;
1348  const char *newparam = NULL;
1349  const char *newval = NULL;
1350  char *dn;
1351  int num_entries = 0;
1352  int i = 0;
1353  int mods_size = 0;
1354  int mod_exists = 0;
1355  struct ldap_table_config *table_config = NULL;
1356  char *clean_basedn = NULL;
1357  struct ast_str *filter = NULL;
1358  int tries = 0;
1359  int result = 0;
1360  LDAPMessage *ldap_result_msg = NULL;
1361 
1362  if (!table_name) {
1363  ast_log(LOG_ERROR, "No table_name specified.\n");
1364  return -1;
1365  }
1366 
1367  if (!(filter = ast_str_create(80))) {
1368  return -1;
1369  }
1370 
1372 
1373  /* We now have our complete statement; Lets connect to the server and execute it. */
1374  if (!ldap_reconnect()) {
1376  ast_free(filter);
1377  return -1;
1378  }
1379 
1380  table_config = table_config_for_table_name(table_name);
1381  if (!table_config) {
1382  ast_log(LOG_ERROR, "No table named '%s'.\n", table_name);
1384  ast_free(filter);
1385  return -1;
1386  }
1387 
1388  clean_basedn = cleaned_basedn(NULL, basedn);
1389 
1390  /* Create the filter with the table additional filter and the parameter/value pairs we were given */
1391  ast_str_append(&filter, 0, "(&");
1392  if (table_config && table_config->additional_filter) {
1393  ast_str_append(&filter, 0, "%s", table_config->additional_filter);
1394  }
1395  if (table_config != base_table_config && base_table_config
1398  }
1399 
1400  /* Get multiple lookup keyfields and values */
1401  while ((newparam = va_arg(ap, const char *))) {
1402  newval = va_arg(ap, const char *);
1403  append_var_and_value_to_filter(&filter, table_config, newparam, newval);
1404  }
1405  ast_str_append(&filter, 0, ")");
1406 
1407  /* Create the modification array with the parameter/value pairs we were given,
1408  * if there are several parameters with the same name, we collect them into
1409  * one parameter/value pair and delimit them with a semicolon */
1410  newparam = va_arg(ap, const char *);
1411  newparam = convert_attribute_name_to_ldap(table_config, newparam);
1412  newval = va_arg(ap, const char *);
1413  if (!newparam || !newval) {
1414  ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__);
1415  ast_free(filter);
1416  ast_free(clean_basedn);
1417  return -1;
1418  }
1419 
1420  mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */
1421  ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size);
1422  ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod));
1423 
1424  ldap_mods[0]->mod_op = LDAP_MOD_REPLACE;
1425  ldap_mods[0]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1);
1426  strcpy(ldap_mods[0]->mod_type, newparam);
1427 
1428  ldap_mods[0]->mod_values = ast_calloc(sizeof(char), 2);
1429  ldap_mods[0]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1);
1430  strcpy(ldap_mods[0]->mod_values[0], newval);
1431 
1432  while ((newparam = va_arg(ap, const char *))) {
1433  newparam = convert_attribute_name_to_ldap(table_config, newparam);
1434  newval = va_arg(ap, const char *);
1435  mod_exists = 0;
1436 
1437  for (i = 0; i < mods_size - 1; i++) {
1438  if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) {
1439  /* We have the parameter allready, adding the value as a semicolon delimited value */
1440  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));
1441  strcat(ldap_mods[i]->mod_values[0], ";");
1442  strcat(ldap_mods[i]->mod_values[0], newval);
1443  mod_exists = 1;
1444  break;
1445  }
1446  }
1447 
1448  /* create new mod */
1449  if (!mod_exists) {
1450  mods_size++;
1451  ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size);
1452  ldap_mods[mods_size - 1] = NULL;
1453  ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod));
1454 
1455  ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE;
1456 
1457  ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1);
1458  strcpy(ldap_mods[mods_size - 2]->mod_type, newparam);
1459 
1460  ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2);
1461  ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1);
1462  strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval);
1463  }
1464  }
1465  /* freeing ldap_mods further down */
1466 
1467  do {
1468  /* freeing ldap_result further down */
1469  result = ldap_search_ext_s(ldapConn, clean_basedn,
1470  LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT,
1471  &ldap_result_msg);
1472  if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
1473  ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1);
1474  tries++;
1475  if (tries < 3) {
1476  usleep(500000L * tries);
1477  if (ldapConn) {
1478  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1479  ldapConn = NULL;
1480  }
1481  if (!ldap_reconnect()) {
1482  break;
1483  }
1484  }
1485  }
1486  } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result));
1487 
1488  if (result != LDAP_SUCCESS) {
1489  ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result));
1490  ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter));
1491 
1493  ast_free(filter);
1494  ast_free(clean_basedn);
1495  ldap_msgfree(ldap_result_msg);
1496  ldap_mods_free(ldap_mods, 0);
1497  return -1;
1498  }
1499  /* Ready to update */
1500  if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) {
1501  for (i = 0; option_debug > 2 && i < mods_size - 1; i++) {
1502  ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]);
1503  }
1504 
1505  ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
1506 
1507  for (i = 0; ldap_entry; i++) {
1508  dn = ldap_get_dn(ldapConn, ldap_entry);
1509  if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
1510  ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error));
1511  }
1512  ldap_memfree(dn);
1513  ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
1514  }
1515  }
1516 
1518  if (filter) {
1519  ast_free(filter);
1520  }
1521  if (clean_basedn) {
1522  ast_free(clean_basedn);
1523  }
1524  ldap_msgfree(ldap_result_msg);
1525  ldap_mods_free(ldap_mods, 0);
1526  return num_entries;
1527 }
static ast_mutex_t ldap_lock
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.
int option_debug
Definition: asterisk.c:182
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
static char * cleaned_basedn(struct ast_channel *channel, const char *basedn)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ast_mutex_lock(a)
Definition: lock.h:155
static int is_ldap_connect_error(int err)
Check if we have a connection error.
static struct ldap_table_config * base_table_config
static struct ldap_table_config * table_config_for_table_name(const char *table_name)
Find a table_config - Should be locked before using it.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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.
Table configuration.
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
#define ast_realloc(a, b)
Definition: astmm.h:103
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:694
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int update_ldap ( const char *  basedn,
const char *  table_name,
const char *  attribute,
const char *  lookup,
va_list  ap 
)
static

Definition at line 1159 of file res_config_ldap.c.

References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_calloc, ast_debug, ast_free, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_str_append(), ast_str_buffer(), 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, and table_config_for_table_name().

1161 {
1162  int error = 0;
1163  LDAPMessage *ldap_entry = NULL;
1164  LDAPMod **ldap_mods;
1165  const char *newparam = NULL;
1166  const char *newval = NULL;
1167  char *dn;
1168  int num_entries = 0;
1169  int i = 0;
1170  int mods_size = 0;
1171  int mod_exists = 0;
1172  struct ldap_table_config *table_config = NULL;
1173  char *clean_basedn = NULL;
1174  struct ast_str *filter = NULL;
1175  int tries = 0;
1176  int result = 0;
1177  LDAPMessage *ldap_result_msg = NULL;
1178 
1179  if (!table_name) {
1180  ast_log(LOG_ERROR, "No table_name specified.\n");
1181  return -1;
1182  }
1183 
1184  if (!(filter = ast_str_create(80))) {
1185  return -1;
1186  }
1187 
1188  if (!attribute || !lookup) {
1189  ast_log(LOG_WARNING, "LINE(%d): search parameters are empty.\n", __LINE__);
1190  return -1;
1191  }
1193 
1194  /* We now have our complete statement; Lets connect to the server and execute it. */
1195  if (!ldap_reconnect()) {
1197  return -1;
1198  }
1199 
1200  table_config = table_config_for_table_name(table_name);
1201  if (!table_config) {
1202  ast_log(LOG_ERROR, "No table named '%s'.\n", table_name);
1204  return -1;
1205  }
1206 
1207  clean_basedn = cleaned_basedn(NULL, basedn);
1208 
1209  /* Create the filter with the table additional filter and the parameter/value pairs we were given */
1210  ast_str_append(&filter, 0, "(&");
1211  if (table_config && table_config->additional_filter) {
1212  ast_str_append(&filter, 0, "%s", table_config->additional_filter);
1213  }
1216  }
1217  append_var_and_value_to_filter(&filter, table_config, attribute, lookup);
1218  ast_str_append(&filter, 0, ")");
1219 
1220  /* Create the modification array with the parameter/value pairs we were given,
1221  * if there are several parameters with the same name, we collect them into
1222  * one parameter/value pair and delimit them with a semicolon */
1223  newparam = va_arg(ap, const char *);
1224  newparam = convert_attribute_name_to_ldap(table_config, newparam);
1225  newval = va_arg(ap, const char *);
1226  if (!newparam || !newval) {
1227  ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__);
1228  return -1;
1229  }
1230 
1231  mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */
1232  ldap_mods = ldap_memcalloc(sizeof(LDAPMod *), mods_size);
1233  ldap_mods[0] = ldap_memcalloc(1, sizeof(LDAPMod));
1234 
1235  ldap_mods[0]->mod_op = LDAP_MOD_REPLACE;
1236  ldap_mods[0]->mod_type = ldap_strdup(newparam);
1237 
1238  ldap_mods[0]->mod_values = ast_calloc(sizeof(char *), 2);
1239  ldap_mods[0]->mod_values[0] = ldap_strdup(newval);
1240 
1241  while ((newparam = va_arg(ap, const char *))) {
1242  newparam = convert_attribute_name_to_ldap(table_config, newparam);
1243  newval = va_arg(ap, const char *);
1244  mod_exists = 0;
1245 
1246  for (i = 0; i < mods_size - 1; i++) {
1247  if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) {
1248  /* We have the parameter allready, adding the value as a semicolon delimited value */
1249  ldap_mods[i]->mod_values[0] = ldap_memrealloc(ldap_mods[i]->mod_values[0], sizeof(char) * (strlen(ldap_mods[i]->mod_values[0]) + strlen(newval) + 2));
1250  strcat(ldap_mods[i]->mod_values[0], ";");
1251  strcat(ldap_mods[i]->mod_values[0], newval);
1252  mod_exists = 1;
1253  break;
1254  }
1255  }
1256 
1257  /* create new mod */
1258  if (!mod_exists) {
1259  mods_size++;
1260  ldap_mods = ldap_memrealloc(ldap_mods, sizeof(LDAPMod *) * mods_size);
1261  ldap_mods[mods_size - 1] = NULL;
1262 
1263  ldap_mods[mods_size - 2] = ldap_memcalloc(1, sizeof(LDAPMod));
1264 
1265  ldap_mods[mods_size - 2]->mod_type = ldap_memcalloc(sizeof(char), strlen(newparam) + 1);
1266  strcpy(ldap_mods[mods_size - 2]->mod_type, newparam);
1267 
1268  if (strlen(newval) == 0) {
1269  ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_DELETE;
1270  } else {
1271  ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE;
1272 
1273  ldap_mods[mods_size - 2]->mod_values = ldap_memcalloc(sizeof(char *), 2);
1274  ldap_mods[mods_size - 2]->mod_values[0] = ldap_memcalloc(sizeof(char), strlen(newval) + 1);
1275  strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval);
1276  }
1277  }
1278  }
1279  /* freeing ldap_mods further down */
1280 
1281  do {
1282  /* freeing ldap_result further down */
1283  result = ldap_search_ext_s(ldapConn, clean_basedn,
1284  LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT,
1285  &ldap_result_msg);
1286  if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
1287  ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1);
1288  tries++;
1289  if (tries < 3) {
1290  usleep(500000L * tries);
1291  if (ldapConn) {
1292  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1293  ldapConn = NULL;
1294  }
1295  if (!ldap_reconnect())
1296  break;
1297  }
1298  }
1299  } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result));
1300 
1301  if (result != LDAP_SUCCESS) {
1302  ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result));
1303  ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter));
1304 
1306  free(filter);
1307  free(clean_basedn);
1308  ldap_msgfree(ldap_result_msg);
1309  ldap_mods_free(ldap_mods, 0);
1310  return -1;
1311  }
1312  /* Ready to update */
1313  if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) {
1314  ast_debug(3, "LINE(%d) Modifying %s=%s hits: %d\n", __LINE__, attribute, lookup, num_entries);
1315  for (i = 0; option_debug > 2 && i < mods_size - 1; i++) {
1316  if (ldap_mods[i]->mod_op != LDAP_MOD_DELETE) {
1317  ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]);
1318  } else {
1319  ast_debug(3, "LINE(%d) deleting %s \n", __LINE__, ldap_mods[i]->mod_type);
1320  }
1321  }
1322  ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
1323 
1324  for (i = 0; ldap_entry; i++) {
1325  dn = ldap_get_dn(ldapConn, ldap_entry);
1326  if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) {
1327  ast_log(LOG_ERROR, "Couldn't modify '%s'='%s', dn:%s because %s\n",
1328  attribute, lookup, dn, ldap_err2string(error));
1329  }
1330  ldap_memfree(dn);
1331  ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
1332  }
1333  }
1334 
1336  ast_free(filter);
1337  ast_free(clean_basedn);
1338  ldap_msgfree(ldap_result_msg);
1339  ldap_mods_free(ldap_mods, 0);
1340  return num_entries;
1341 }
static ast_mutex_t ldap_lock
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.
int option_debug
Definition: asterisk.c:182
#define LOG_WARNING
Definition: logger.h:144
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:497
static char * cleaned_basedn(struct ast_channel *channel, const char *basedn)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:900
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
#define ast_mutex_lock(a)
Definition: lock.h:155
static int is_ldap_connect_error(int err)
Check if we have a connection error.
static struct ldap_table_config * base_table_config
static struct ldap_table_config * table_config_for_table_name(const char *table_name)
Find a table_config - Should be locked before using it.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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.
Table configuration.
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:155
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:364
#define free(a)
Definition: astmm.h:94
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:694
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:156
static struct ast_variable* variable_named ( struct ast_variable var,
const char *  name 
)
static

Find variable by name.

Definition at line 138 of file res_config_ldap.c.

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

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

139 {
140  for (; var; var = var->next) {
141  if (!strcasecmp(name, var->name))
142  break;
143  }
144 
145  return var;
146 }
#define var
Definition: ast_expr2f.c:606
const char * name
Definition: config.h:77
static const char name[]
struct ast_variable * next
Definition: config.h:82

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, }
static

Definition at line 1810 of file res_config_ldap.c.

Definition at line 1810 of file res_config_ldap.c.

char base_distinguished_name[512]
static

Definition at line 70 of file res_config_ldap.c.

time_t connect_time
static

Definition at line 72 of file res_config_ldap.c.

Referenced by realtime_ldap_status().

struct ast_cli_entry ldap_cli[]
static
Initial value:
= {
AST_CLI_DEFINE(realtime_ldap_status, "Shows connection information for the LDAP RealTime driver"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * realtime_ldap_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 101 of file res_config_ldap.c.

Referenced by load_module(), and unload_module().

struct ast_config_engine ldap_engine
static

Definition at line 1529 of file res_config_ldap.c.

Referenced by load_module(), and unload_module().

ast_mutex_t ldap_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static
LDAP* ldapConn
static

Definition at line 66 of file res_config_ldap.c.

struct ldap_table_config* static_table_config
static
struct table_configs table_configs = { .first = NULL, .last = NULL, }
static
int version
static

Definition at line 71 of file res_config_ldap.c.