Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Functions | Variables
res_config_ldap.c File Reference

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

#include "asterisk.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <ldap.h>
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/strings.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
Include dependency graph for res_config_ldap.c:

Go to the source code of this file.

Data Structures

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

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...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
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 int config_can_be_inherited (const char *key)
 
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 Realtime Documentation. 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. More...
 
static struct ast_strcreate_lookup_filter (struct ldap_table_config *config, const struct ast_variable *fields)
 
static int is_ldap_connect_error (int err)
 Check if we have a connection error. More...
 
static int ldap_entry_has_attribute (LDAPMessage *entry, const char *lookup)
 
static struct ast_variableldap_loadentry (struct ldap_table_config *table_config, const char *dn)
 Get LDAP entry by dn and return attributes as variables. More...
 
static LDAPMod * ldap_mod_append (LDAPMod *src, const char *new_value)
 
static LDAPMod * ldap_mod_create (const char *attribute, const char *new_value)
 
static LDAPMod * ldap_mod_duplicate (const LDAPMod *src)
 
static LDAPMod * ldap_mod_find (LDAPMod **modifications, const char *lookup)
 
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 More...
 
static int load_module (void)
 Load the module. More...
 
static LDAPMod ** massage_mods_for_entry (LDAPMessage *entry, LDAPMod **mods)
 
static int parse_config (void)
 parse the configuration file More...
 
static struct ast_variablerealtime_arguments_to_fields (va_list ap)
 
static struct ast_variablerealtime_ldap (const char *basedn, const char *table_name, const struct ast_variable *fields)
 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, const struct ast_variable *fields)
 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)
 Realtime Status. More...
 
static struct ast_configrealtime_multi_ldap (const char *basedn, const char *table_name, const struct ast_variable *fields)
 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)
 Count semicolons in string. 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. 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)
 Unload Module. More...
 
static int update2_ldap (const char *basedn, const char *table_name, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
 
static int update_ldap (const char *basedn, const char *table_name, const char *attribute, const char *lookup, const struct ast_variable *fields)
 
static struct ast_variablevariable_named (struct ast_variable *var, const char *name)
 Find variable by name. More...
 
static size_t variables_count (const struct ast_variable *vars)
 

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, .requires = "extconfig", }
 Module Information. More...
 
static const 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, 0} }
 
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

OpenLDAP http://www.openldap.org

Definition in file res_config_ldap.c.

Macro Definition Documentation

◆ MAXRESULT

#define MAXRESULT   2048

Referenced by substituted().

◆ RES_CONFIG_LDAP_CONF

#define RES_CONFIG_LDAP_CONF   "res_ldap.conf"

Definition at line 68 of file res_config_ldap.c.

Referenced by config_ldap(), and parse_config().

◆ RES_CONFIG_LDAP_DEFAULT_BASEDN

#define RES_CONFIG_LDAP_DEFAULT_BASEDN   "asterisk"

Definition at line 69 of file res_config_ldap.c.

Referenced by parse_config().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 2005 of file res_config_ldap.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 2005 of file res_config_ldap.c.

◆ append_var_and_value_to_filter()

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

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

Referenced by create_lookup_filter().

739 {
740  char *new_name = NULL;
741  char *new_value = NULL;
742  char *like_pos = strstr(name, " LIKE");
743 
744  ast_debug(2, "name='%s' value='%s'\n", name, value);
745 
746  if (like_pos) {
747  int len = like_pos - name;
748 
749  name = new_name = ast_strdupa(name);
750  new_name[len] = '\0';
751  value = new_value = ast_strdupa(value);
752  replace_string_in_string(new_value, "\\_", "_");
753  replace_string_in_string(new_value, "%", "*");
754  }
755 
756  name = convert_attribute_name_to_ldap(table_config, name);
757 
758  ast_str_append(filter, 0, "(%s=%s)", name, value);
759 }
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:1091
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
static int replace_string_in_string(char *string, const char *search, const char *by)
Replace <search> by <by> in string.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static const char name[]
Definition: cdr_mysql.c:74

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 2005 of file res_config_ldap.c.

◆ cleaned_basedn()

static char* cleaned_basedn ( struct ast_channel channel,
const char *  basedn 
)
static
Note
caller should free returned pointer

Definition at line 683 of file res_config_ldap.c.

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

Referenced by realtime_ldap_base_ap(), and update2_ldap().

684 {
685  char *cbasedn = NULL;
686  if (basedn) {
687  char *p = NULL;
688  cbasedn = substituted(channel, basedn);
689  if (*cbasedn == '"') {
690  cbasedn++;
691  if (!ast_strlen_zero(cbasedn)) {
692  int len = strlen(cbasedn);
693  if (cbasedn[len - 1] == '"')
694  cbasedn[len - 1] = '\0';
695 
696  }
697  }
698  p = cbasedn;
699  while (*p) {
700  if (*p == '|')
701  *p = ',';
702  p++;
703  }
704  }
705  ast_debug(2, "basedn: '%s' => '%s' \n", basedn, cbasedn);
706  return cbasedn;
707 }
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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)

◆ compare_categories()

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

References a, b, bs, category_and_metric::metric, category_and_metric::name, and category_and_metric::var_metric.

Referenced by config_ldap().

1098 {
1099  const struct category_and_metric *as = a;
1100  const struct category_and_metric *bs = b;
1101 
1102  if (as->metric < bs->metric) {
1103  return -1;
1104  } else if (as->metric > bs->metric) {
1105  return 1;
1106  } else if (as->metric == bs->metric && strcmp(as->name, bs->name) != 0) {
1107  return strcmp(as->name, bs->name);
1108  }
1109  /* if the metric and the category name is the same, we check the variable metric */
1110  if (as->var_metric < bs->var_metric) {
1111  return -1;
1112  } else if (as->var_metric > bs->var_metric) {
1113  return 1;
1114  }
1115 
1116  return 0;
1117 }
char * bs
Definition: eagi_proxy.c:73
static struct test_val b
static struct test_val a

◆ config_can_be_inherited()

static int config_can_be_inherited ( const char *  key)
static

Definition at line 1791 of file res_config_ldap.c.

References config, and NULL.

Referenced by parse_config().

1792 {
1793  int i;
1794  static const char * const config[] = {
1795  "basedn", "host", "pass", "port", "protocol", "url", "user", "version", NULL
1796  };
1797 
1798  for (i = 0; config[i]; i++) {
1799  if (!strcasecmp(key, config[i])) {
1800  return 0;
1801  }
1802  }
1803  return 1;
1804 }
char * config
Definition: conf2ael.c:66
#define NULL
Definition: resample.c:96

◆ config_ldap()

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

This is for Static Realtime

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

References ast_calloc, ast_category_append(), ast_category_new_dynamic, ast_config_internal_load(), ast_debug, ast_free, ast_log, ast_strlen_zero, ast_variable_append(), ast_variable_new, categories, compare_categories(), LOG_ERROR, LOG_WARNING, category_and_metric::metric, category_and_metric::name, NULL, 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.

1128 {
1129  unsigned int vars_count = 0;
1130  struct ast_variable **vars;
1131  int i = 0;
1132  struct ast_variable *new_v = NULL;
1133  struct ast_category *cur_cat = NULL;
1134  const char *last_category = NULL;
1135  int last_category_metric = 0;
1137  struct ast_variable **p;
1138 
1139  if (ast_strlen_zero(file) || !strcasecmp(file, RES_CONFIG_LDAP_CONF)) {
1140  ast_log(LOG_ERROR, "Missing configuration file: %s. Can't configure myself.\n", RES_CONFIG_LDAP_CONF);
1141  return NULL;
1142  }
1143 
1144  vars = realtime_ldap_base(&vars_count, basedn, table_name, "filename", file, "commented", "FALSE", NULL);
1145 
1146  if (!vars) {
1147  ast_log(LOG_WARNING, "Could not find config '%s' in directory.\n", file);
1148  return NULL;
1149  }
1150 
1151  /*! \note Since the items come back in random order, they need to be sorted
1152  * first, and since the data could easily exceed stack size, this is
1153  * allocated from the heap.
1154  */
1155  if (!(categories = ast_calloc(vars_count, sizeof(*categories)))) {
1156  return NULL;
1157  }
1158 
1159  for (vars_count = 0, p = vars; *p; p++) {
1160  struct ast_variable *category = variable_named(*p, "category");
1161  struct ast_variable *cat_metric = variable_named(*p, "cat_metric");
1162  struct ast_variable *var_name = variable_named(*p, "variable_name");
1163  struct ast_variable *var_val = variable_named(*p, "variable_value");
1164  struct ast_variable *var_metric = variable_named(*p, "var_metric");
1165  struct ast_variable *dn = variable_named(*p, "dn");
1166 
1167  if (!category) {
1168  ast_log(LOG_ERROR, "No category name in entry '%s' for file '%s'.\n",
1169  (dn ? dn->value : "?"), file);
1170  } else if (!cat_metric) {
1171  ast_log(LOG_ERROR, "No category metric in entry '%s'(category: %s) for file '%s'.\n",
1172  (dn ? dn->value : "?"), category->value, file);
1173  } else if (!var_metric) {
1174  ast_log(LOG_ERROR, "No variable metric in entry '%s'(category: %s) for file '%s'.\n",
1175  (dn ? dn->value : "?"), category->value, file);
1176  } else if (!var_name) {
1177  ast_log(LOG_ERROR, "No variable name in entry '%s' (category: %s metric: %s) for file '%s'.\n",
1178  (dn ? dn->value : "?"), category->value,
1179  cat_metric->value, file);
1180  } else if (!var_val) {
1181  ast_log(LOG_ERROR, "No variable value in entry '%s' (category: %s metric: %s variable: %s) for file '%s'.\n",
1182  (dn ? dn->value : "?"), category->value,
1183  cat_metric->value, var_name->value, file);
1184  } else {
1185  categories[vars_count].name = category->value;
1186  categories[vars_count].metric = atoi(cat_metric->value);
1187  categories[vars_count].variable_name = var_name->value;
1188  categories[vars_count].variable_value = var_val->value;
1189  categories[vars_count].var_metric = atoi(var_metric->value);
1190  vars_count++;
1191  }
1192 
1193  ast_debug(3, "category: %s\n", category->value);
1194  ast_debug(3, "var_name: %s\n", var_name->value);
1195  ast_debug(3, "var_val: %s\n", var_val->value);
1196  ast_debug(3, "cat_metric: %s\n", cat_metric->value);
1197 
1198  }
1199 
1200  qsort(categories, vars_count, sizeof(*categories), compare_categories);
1201 
1202  for (i = 0; i < vars_count; i++) {
1203  if (!strcmp(categories[i].variable_name, "#include")) {
1204  struct ast_flags flags = { 0 };
1205  if (!ast_config_internal_load(categories[i].variable_value, cfg, flags, "", who_asked)) {
1206  break;
1207  }
1208  continue;
1209  }
1210 
1211  if (!last_category || strcmp(last_category, categories[i].name) ||
1212  last_category_metric != categories[i].metric) {
1213 
1214  cur_cat = ast_category_new_dynamic(categories[i].name);
1215  if (!cur_cat) {
1216  break;
1217  }
1218  last_category = categories[i].name;
1219  last_category_metric = categories[i].metric;
1220  ast_category_append(cfg, cur_cat);
1221  }
1222 
1223  if (!(new_v = ast_variable_new(categories[i].variable_name, categories[i].variable_value, table_name))) {
1224  break;
1225  }
1226 
1227  ast_variable_append(cur_cat, new_v);
1228  }
1229 
1230  ast_free(vars);
1231  ast_free(categories);
1232 
1233  return cfg;
1234 }
#define LOG_WARNING
Definition: logger.h:274
unsigned int flags
Definition: utils.h:200
#define RES_CONFIG_LDAP_CONF
Structure for variables, used for configurations and for channel variables.
static struct ast_variable * variable_named(struct ast_variable *var, const char *name)
Find variable by name.
#define NULL
Definition: resample.c:96
const char * variable_value
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: main/config.c:3112
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
static int compare_categories(const void *a, const void *b)
Sorting alogrithm for qsort to find the order of the variables a and b.
#define ast_log
Definition: astobj2.c:42
#define ast_variable_new(name, value, filename)
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:285
struct association categories[]
static const char name[]
Definition: cdr_mysql.c:74
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
Structure used to handle boolean flags.
Definition: utils.h:199
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: extconf.c:1178
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Appends a category to a config.
Definition: extconf.c:2835
const char * variable_name

◆ convert_attribute_name_from_ldap()

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

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

Referenced by realtime_ldap_entry_to_var(), and realtime_ldap_result_to_vars().

280 {
281  int i = 0;
282  struct ldap_table_config *configs[] = { table_config, base_table_config };
283 
284  for (i = 0; i < ARRAY_LEN(configs); i++) {
285  struct ast_variable *attribute;
286 
287  if (!configs[i]) {
288  continue;
289  }
290 
291  attribute = configs[i]->attributes;
292  for (; attribute; attribute = attribute->next) {
293  if (strcasecmp(attribute_name, attribute->value) == 0) {
294  return attribute->name;
295  }
296  }
297  }
298 
299  return attribute_name;
300 }
struct ast_variable * next
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
Structure for variables, used for configurations and for channel variables.
static struct ldap_table_config * base_table_config
Table configuration.
struct ast_variable * attributes

◆ convert_attribute_name_to_ldap()

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.

Note
Should be locked before using it

Definition at line 250 of file res_config_ldap.c.

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

Referenced by append_var_and_value_to_filter(), and update2_ldap().

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

◆ create_lookup_filter()

static struct ast_str* create_lookup_filter ( struct ldap_table_config config,
const struct ast_variable fields 
)
static

Definition at line 770 of file res_config_ldap.c.

References ldap_table_config::additional_filter, append_var_and_value_to_filter(), ast_str_append(), ast_str_create, filter(), ast_variable::name, ast_variable::next, NULL, and ast_variable::value.

Referenced by realtime_ldap_base_ap(), and update2_ldap().

771 {
772  struct ast_str *filter;
773  const struct ast_variable *field;
774 
775  filter = ast_str_create(80);
776  if (!filter) {
777  return NULL;
778  }
779 
780  /*
781  * Create the filter with the table additional filter and the
782  * parameter/value pairs we were given
783  */
784  ast_str_append(&filter, 0, "(&");
785  if (config && config->additional_filter) {
786  ast_str_append(&filter, 0, "%s", config->additional_filter);
787  }
788  if (config != base_table_config
792  }
793  /* Append the lookup fields */
794  for (field = fields; field; field = field->next) {
795  append_var_and_value_to_filter(&filter, config, field->name, field->value);
796  }
797  ast_str_append(&filter, 0, ")");
798 
799  return filter;
800 }
struct ast_variable * next
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.
Structure for variables, used for configurations and for channel variables.
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:1091
#define NULL
Definition: resample.c:96
static struct ldap_table_config * base_table_config
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ is_ldap_connect_error()

static int is_ldap_connect_error ( int  err)
static

Check if we have a connection error.

Definition at line 580 of file res_config_ldap.c.

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

581 {
582  return (err == LDAP_SERVER_DOWN || err == LDAP_TIMEOUT || err == LDAP_CONNECT_ERROR);
583 }

◆ ldap_entry_has_attribute()

static int ldap_entry_has_attribute ( LDAPMessage *  entry,
const char *  lookup 
)
static

Definition at line 1397 of file res_config_ldap.c.

References ldapConn, and NULL.

Referenced by massage_mods_for_entry().

1398 {
1399  BerElement *ber = NULL;
1400  char *attribute;
1401 
1402  attribute = ldap_first_attribute(ldapConn, entry, &ber);
1403  while (attribute) {
1404  if (!strcasecmp(attribute, lookup)) {
1405  ldap_memfree(attribute);
1406  ber_free(ber, 0);
1407  return 1;
1408  }
1409  ldap_memfree(attribute);
1410  attribute = ldap_next_attribute(ldapConn, entry, ber);
1411  }
1412  ber_free(ber, 0);
1413  return 0;
1414 }
#define NULL
Definition: resample.c:96
static LDAP * ldapConn
Definition: search.h:40

◆ ldap_loadentry()

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

References ast_debug, ast_free, ast_log, ast_mutex_unlock, ast_variables_destroy(), is_ldap_connect_error(), ldap_lock, ldap_reconnect(), ldapConn, LOG_ERROR, LOG_NOTICE, LOG_WARNING, NULL, realtime_ldap_result_to_vars(), result, and var.

Referenced by realtime_ldap_base_ap().

594 {
595  if (!table_config) {
596  ast_log(LOG_ERROR, "No table config\n");
597  return NULL;
598  } else {
599  struct ast_variable **vars = NULL;
600  struct ast_variable *var = NULL;
601  int result = -1;
602  LDAPMessage *ldap_result_msg = NULL;
603  int tries = 0;
604 
605  ast_debug(2, "ldap_loadentry dn=%s\n", dn);
606 
607  do {
608  result = ldap_search_ext_s(ldapConn, dn, LDAP_SCOPE_BASE,
609  "(objectclass=*)", NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &ldap_result_msg);
610  if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
611  ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1);
612  tries++;
613  if (tries < 3) {
614  usleep(500000L * tries);
615  if (ldapConn) {
616  ldap_unbind_ext_s(ldapConn, NULL, NULL);
617  ldapConn = NULL;
618  }
619  if (!ldap_reconnect()) {
620  break;
621  }
622  }
623  }
624  } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result));
625 
626  if (result != LDAP_SUCCESS) {
627  ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result));
628  ast_debug(2, "dn=%s\n", dn);
630  return NULL;
631  } else {
632  int num_entry = 0;
633  unsigned int *entries_count_ptr = NULL; /*!< not using this */
634 
635  if ((num_entry = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) {
636  ast_debug(3, "num_entry: %d\n", num_entry);
637 
638  vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr);
639  if (num_entry > 1) {
640  ast_log(LOG_NOTICE, "More than one entry for dn=%s. Take only 1st one\n", dn);
641  }
642  } else {
643  ast_debug(2, "Could not find any entry dn=%s.\n", dn);
644  }
645  }
646  ldap_msgfree(ldap_result_msg);
647 
648  /* Chopping \a vars down to one variable */
649  if (vars != NULL) {
650  struct ast_variable **p = vars;
651 
652  /* Only take the first one. */
653  var = *vars;
654 
655  /* Destroy the rest. */
656  while (*++p) {
658  }
659  ast_free(vars);
660  }
661 
662  return var;
663  }
664 }
static ast_mutex_t ldap_lock
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
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:452
#define ast_log
Definition: astobj2.c:42
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:285
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.
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
static PGresult * result
Definition: cel_pgsql.c:88
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ ldap_mod_append()

static LDAPMod* ldap_mod_append ( LDAPMod *  src,
const char *  new_value 
)
static

Definition at line 1295 of file res_config_ldap.c.

References ast_log, LOG_ERROR, and NULL.

Referenced by update2_ldap().

1296 {
1297  char *new_buffer;
1298 
1299  if (src->mod_op != LDAP_MOD_REPLACE) {
1300  return src;
1301  }
1302 
1303  new_buffer = ldap_memrealloc(
1304  src->mod_values[0],
1305  strlen(src->mod_values[0]) + strlen(new_value) + sizeof(";"));
1306 
1307  if (!new_buffer) {
1308  ast_log(LOG_ERROR, "Memory allocation failure creating LDAP modification\n");
1309  return NULL;
1310  }
1311 
1312  strcat(new_buffer, ";");
1313  strcat(new_buffer, new_value);
1314 
1315  src->mod_values[0] = new_buffer;
1316 
1317  return src;
1318 }
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285

◆ ldap_mod_create()

static LDAPMod* ldap_mod_create ( const char *  attribute,
const char *  new_value 
)
static

Definition at line 1245 of file res_config_ldap.c.

References ast_log, LOG_ERROR, NULL, type, and value.

Referenced by update2_ldap().

1246 {
1247  LDAPMod *mod;
1248  char *type;
1249 
1250  mod = ldap_memcalloc(1, sizeof(LDAPMod));
1251  type = ldap_strdup(attribute);
1252 
1253  if (!(mod && type)) {
1254  ast_log(LOG_ERROR, "Memory allocation failure creating LDAP modification\n");
1255  ldap_memfree(type);
1256  ldap_memfree(mod);
1257  return NULL;
1258  }
1259 
1260  mod->mod_type = type;
1261 
1262  if (strlen(new_value)) {
1263  char **values, *value;
1264  values = ldap_memcalloc(2, sizeof(char *));
1265  value = ldap_strdup(new_value);
1266 
1267  if (!(values && value)) {
1268  ast_log(LOG_ERROR, "Memory allocation failure creating LDAP modification\n");
1269  ldap_memfree(value);
1270  ldap_memfree(values);
1271  ldap_memfree(type);
1272  ldap_memfree(mod);
1273  return NULL;
1274  }
1275 
1276  mod->mod_op = LDAP_MOD_REPLACE;
1277  mod->mod_values = values;
1278  mod->mod_values[0] = value;
1279  } else {
1280  mod->mod_op = LDAP_MOD_DELETE;
1281  }
1282 
1283  return mod;
1284 }
static const char type[]
Definition: chan_ooh323.c:109
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285

◆ ldap_mod_duplicate()

static LDAPMod* ldap_mod_duplicate ( const LDAPMod *  src)
static

Definition at line 1328 of file res_config_ldap.c.

References ast_log, LOG_ERROR, NULL, type, and value.

Referenced by massage_mods_for_entry().

1329 {
1330  LDAPMod *mod;
1331  char *type, **values = NULL;
1332 
1333  mod = ldap_memcalloc(1, sizeof(LDAPMod));
1334  type = ldap_strdup(src->mod_type);
1335 
1336  if (!(mod && type)) {
1337  ast_log(LOG_ERROR, "Memory allocation failure creating LDAP modification\n");
1338  ldap_memfree(type);
1339  ldap_memfree(mod);
1340  return NULL;
1341  }
1342 
1343  if (src->mod_op == LDAP_MOD_REPLACE) {
1344  char *value;
1345 
1346  values = ldap_memcalloc(2, sizeof(char *));
1347  value = ldap_strdup(src->mod_values[0]);
1348 
1349  if (!(values && value)) {
1350  ast_log(LOG_ERROR, "Memory allocation failure creating LDAP modification\n");
1351  ldap_memfree(value);
1352  ldap_memfree(values);
1353  ldap_memfree(type);
1354  ldap_memfree(mod);
1355  return NULL;
1356  }
1357 
1358  values[0] = value;
1359  }
1360 
1361  mod->mod_op = src->mod_op;
1362  mod->mod_type = type;
1363  mod->mod_values = values;
1364  return mod;
1365 }
static const char type[]
Definition: chan_ooh323.c:109
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285

◆ ldap_mod_find()

static LDAPMod* ldap_mod_find ( LDAPMod **  modifications,
const char *  lookup 
)
static

Definition at line 1376 of file res_config_ldap.c.

References NULL.

Referenced by update2_ldap().

1377 {
1378  size_t i;
1379  for (i = 0; modifications[i]; i++) {
1380  if (modifications[i]->mod_op == LDAP_MOD_REPLACE &&
1381  !strcasecmp(modifications[i]->mod_type, lookup)) {
1382  return modifications[i];
1383  }
1384  }
1385  return NULL;
1386 }
#define NULL
Definition: resample.c:96

◆ ldap_reconnect()

static int ldap_reconnect ( void  )
static
Note
ldap_lock should have been locked before calling this function.

Definition at line 1910 of file res_config_ldap.c.

References ast_debug, ast_log, ast_strlen_zero, connect_time, ldapConn, LOG_ERROR, LOG_WARNING, NULL, pass, url, and version.

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

1911 {
1912  int bind_result = 0;
1913  struct berval cred;
1914 
1915  if (ldapConn) {
1916  ast_debug(2, "Everything seems fine.\n");
1917  return 1;
1918  }
1919 
1920  if (ast_strlen_zero(url)) {
1921  ast_log(LOG_ERROR, "Not enough parameters to connect to ldap directory\n");
1922  return 0;
1923  }
1924 
1925  if (LDAP_SUCCESS != ldap_initialize(&ldapConn, url)) {
1926  ast_log(LOG_ERROR, "Failed to init ldap connection to '%s'. Check debug for more info.\n", url);
1927  return 0;
1928  }
1929 
1930  if (LDAP_OPT_SUCCESS != ldap_set_option(ldapConn, LDAP_OPT_PROTOCOL_VERSION, &version)) {
1931  ast_log(LOG_WARNING, "Unable to set LDAP protocol version to %d, falling back to default.\n", version);
1932  }
1933 
1934  if (!ast_strlen_zero(user)) {
1935  ast_debug(2, "bind to '%s' as user '%s'\n", url, user);
1936  cred.bv_val = (char *) pass;
1937  cred.bv_len = strlen(pass);
1938  bind_result = ldap_sasl_bind_s(ldapConn, user, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
1939  } else {
1940  ast_debug(2, "bind %s anonymously\n", url);
1941  cred.bv_val = NULL;
1942  cred.bv_len = 0;
1943  bind_result = ldap_sasl_bind_s(ldapConn, NULL, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL);
1944  }
1945  if (bind_result == LDAP_SUCCESS) {
1946  ast_debug(2, "Successfully connected to directory.\n");
1947  connect_time = time(NULL);
1948  return 1;
1949  } else {
1950  ast_log(LOG_WARNING, "bind failed: %s\n", ldap_err2string(bind_result));
1951  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1952  ldapConn = NULL;
1953  return 0;
1954  }
1955 }
static char pass[512]
#define LOG_WARNING
Definition: logger.h:274
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static time_t connect_time
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:285
structure to hold users read from users.conf
static int version
static char url[512]

◆ ldap_table_config_add_attribute()

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

204 {
205  struct ast_variable *var;
206 
207  if (ast_strlen_zero(attribute_name) || ast_strlen_zero(attribute_value)) {
208  return;
209  }
210 
211  if (!(var = ast_variable_new(attribute_name, attribute_value, table_config->table_name))) {
212  return;
213  }
214 
215  if (table_config->attributes) {
216  var->next = table_config->attributes;
217  }
218  table_config->attributes = var;
219 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_variable_new(name, value, filename)
struct ast_variable * attributes

◆ load_module()

static int load_module ( void  )
static

Load the module.

Module loading including tests for configuration or dependencies. This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE, or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails tests return AST_MODULE_LOAD_FAILURE. If the module can not load the configuration file or other non-critical problem return AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.

Todo:
Don't error or warn on a default install. If the config is default we should not attempt to connect to a server. -lathama

Definition at line 1715 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_lock, ldap_reconnect(), LOG_ERROR, LOG_WARNING, and parse_config().

Referenced by realtime_ldap_status().

1716 {
1717  if (parse_config() < 0) {
1718  ast_log(LOG_ERROR, "Cannot load LDAP RealTime driver.\n");
1719  return 0;
1720  }
1721 
1723 
1724  if (!ldap_reconnect()) {
1725  ast_log(LOG_WARNING, "Couldn't establish connection to LDAP directory. Check debug.\n");
1726  }
1727 
1729  ast_verb(1, "LDAP RealTime driver loaded.\n");
1731 
1733 
1734  return 0;
1735 }
static ast_mutex_t ldap_lock
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_WARNING
Definition: logger.h:274
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
Definition: main/config.c:2990
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
static struct ast_config_engine ldap_engine
#define LOG_ERROR
Definition: logger.h:285
static struct ast_cli_entry ldap_cli[]
static int parse_config(void)
parse the configuration file
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ massage_mods_for_entry()

static LDAPMod** massage_mods_for_entry ( LDAPMessage *  entry,
LDAPMod **  mods 
)
static

Definition at line 1432 of file res_config_ldap.c.

References ast_debug, ast_log, ldap_entry_has_attribute(), ldap_mod_duplicate(), LOG_ERROR, and NULL.

Referenced by update2_ldap().

1433 {
1434  size_t k, i, remove_count;
1435  LDAPMod **copies;
1436 
1437  for (i = remove_count = 0; mods[i]; i++) {
1438  if (mods[i]->mod_op == LDAP_MOD_DELETE
1439  && !ldap_entry_has_attribute(entry, mods[i]->mod_type)) {
1440  remove_count++;
1441  }
1442  }
1443 
1444  if (!remove_count) {
1445  return NULL;
1446  }
1447 
1448  copies = ldap_memcalloc(i - remove_count + 1, sizeof(LDAPMod *));
1449  if (!copies) {
1450  ast_log(LOG_ERROR, "Memory allocation failure massaging LDAP modification\n");
1451  return NULL;
1452  }
1453 
1454  for (i = k = 0; mods[i]; i++) {
1455  if (mods[i]->mod_op != LDAP_MOD_DELETE
1456  || ldap_entry_has_attribute(entry, mods[i]->mod_type)) {
1457  copies[k] = ldap_mod_duplicate(mods[i]);
1458  if (!copies[k]) {
1459  ast_log(LOG_ERROR, "Memory allocation failure massaging LDAP modification\n");
1460  ldap_mods_free(copies, 1);
1461  return NULL;
1462  }
1463  k++;
1464  } else {
1465  ast_debug(3, "Skipping %s deletion because it doesn't exist\n",
1466  mods[i]->mod_type);
1467  }
1468  }
1469 
1470  return copies;
1471 }
static int ldap_entry_has_attribute(LDAPMessage *entry, const char *lookup)
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static LDAPMod * ldap_mod_duplicate(const LDAPMod *src)
#define LOG_ERROR
Definition: logger.h:285
Definition: search.h:40

◆ parse_config()

static int parse_config ( void  )
static

parse the configuration file

< using the [config] context for Static RealTime

Definition at line 1808 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_distinguished_name, config, config_can_be_inherited(), CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, host, ldap_table_config_add_attribute(), LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, pass, RES_CONFIG_LDAP_CONF, RES_CONFIG_LDAP_DEFAULT_BASEDN, table_config_for_table_name(), table_config_new(), table_configs_free(), url, ast_variable::value, var, and version.

Referenced by load_module(), and reload().

1809 {
1810  struct ast_config *config;
1811  struct ast_flags config_flags = {0};
1812  const char *s, *host;
1813  int port;
1814  char *category_name = NULL;
1815 
1816  /* Make sure that global variables are reset */
1817  url[0] = '\0';
1818  user[0] = '\0';
1819  pass[0] = '\0';
1820  base_distinguished_name[0] = '\0';
1821  version = 3;
1822 
1823  config = ast_config_load(RES_CONFIG_LDAP_CONF, config_flags);
1824  if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
1825  ast_log(LOG_ERROR, "Cannot load configuration file: %s\n", RES_CONFIG_LDAP_CONF);
1826  return -1;
1827  }
1828 
1829  if (!(s = ast_variable_retrieve(config, "_general", "user"))) {
1830  ast_log(LOG_NOTICE, "No directory user found, anonymous binding as default.\n");
1831  user[0] = '\0';
1832  } else {
1833  ast_copy_string(user, s, sizeof(user));
1834  }
1835 
1836  if (!ast_strlen_zero(user)) {
1837  if (!(s = ast_variable_retrieve(config, "_general", "pass"))) {
1838  ast_log(LOG_WARNING, "No directory password found, using 'asterisk' as default.\n");
1839  ast_copy_string(pass, "asterisk", sizeof(pass));
1840  } else {
1841  ast_copy_string(pass, s, sizeof(pass));
1842  }
1843  }
1844 
1845  /* URL is preferred, use host and port if not found */
1846  if ((s = ast_variable_retrieve(config, "_general", "url"))) {
1847  ast_copy_string(url, s, sizeof(url));
1848  } else if ((host = ast_variable_retrieve(config, "_general", "host"))) {
1849  if (!(s = ast_variable_retrieve(config, "_general", "port")) || sscanf(s, "%5d", &port) != 1 || port > 65535) {
1850  ast_log(LOG_NOTICE, "No directory port found, using 389 as default.\n");
1851  port = 389;
1852  }
1853 
1854  snprintf(url, sizeof(url), "ldap://%s:%d", host, port);
1855  } else {
1856  ast_log(LOG_ERROR, "No directory URL or host found.\n");
1857  ast_config_destroy(config);
1858  return -1;
1859  }
1860 
1861  if (!(s = ast_variable_retrieve(config, "_general", "basedn"))) {
1862  ast_log(LOG_ERROR, "No LDAP base dn found, using '%s' as default.\n", RES_CONFIG_LDAP_DEFAULT_BASEDN);
1864  } else
1866 
1867  if (!(s = ast_variable_retrieve(config, "_general", "version")) && !(s = ast_variable_retrieve(config, "_general", "protocol"))) {
1868  ast_log(LOG_NOTICE, "No explicit LDAP version found, using 3 as default.\n");
1869  } else if (sscanf(s, "%30d", &version) != 1 || version < 1 || version > 6) {
1870  ast_log(LOG_WARNING, "Invalid LDAP version '%s', using 3 as default.\n", s);
1871  version = 3;
1872  }
1873 
1875 
1876  while ((category_name = ast_category_browse(config, category_name))) {
1877  int is_general = (strcasecmp(category_name, "_general") == 0);
1878  int is_config = (strcasecmp(category_name, "config") == 0); /*!< using the [config] context for Static RealTime */
1879  struct ast_variable *var = ast_variable_browse(config, category_name);
1880 
1881  if (var) {
1882  struct ldap_table_config *table_config =
1883  table_config_for_table_name(category_name);
1884  if (!table_config) {
1885  table_config = table_config_new(category_name);
1886  AST_LIST_INSERT_HEAD(&table_configs, table_config, entry);
1887  if (is_general)
1888  base_table_config = table_config;
1889  if (is_config)
1890  static_table_config = table_config;
1891  }
1892  for (; var; var = var->next) {
1893  if (!strcasecmp(var->name, "additionalFilter")) {
1894  table_config->additional_filter = ast_strdup(var->value);
1895  } else {
1896  if (!is_general || config_can_be_inherited(var->name)) {
1897  ldap_table_config_add_attribute(table_config, var->name, var->value);
1898  }
1899  }
1900  }
1901  }
1902  }
1903 
1904  ast_config_destroy(config);
1905 
1906  return 1;
1907 }
struct ast_variable * next
static char pass[512]
char * config
Definition: conf2ael.c:66
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
#define LOG_WARNING
Definition: logger.h:274
#define CONFIG_STATUS_FILEINVALID
#define RES_CONFIG_LDAP_CONF
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
static struct ldap_table_config * table_config_new(const char *table_name)
Create a new table_config.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
static char base_distinguished_name[512]
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.
#define ast_strlen_zero(foo)
Definition: strings.h:52
static int config_can_be_inherited(const char *key)
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
static void table_configs_free(void)
Free table_config.
static char host[256]
Definition: muted.c:77
Table configuration.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define LOG_ERROR
Definition: logger.h:285
#define LOG_NOTICE
Definition: logger.h:263
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
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
structure to hold users read from users.conf
Structure used to handle boolean flags.
Definition: utils.h:199
#define CONFIG_STATUS_FILEMISSING
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
Definition: main/config.c:694
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
#define RES_CONFIG_LDAP_DEFAULT_BASEDN
Definition: search.h:40
static int version
static char url[512]
Should be locked before using it.
static struct ldap_table_config * static_table_config

◆ realtime_arguments_to_fields()

static struct ast_variable* realtime_arguments_to_fields ( va_list  ap)
static

Definition at line 960 of file res_config_ldap.c.

References ast_variable_new, ast_variables_destroy(), ast_variable::next, and NULL.

Referenced by realtime_ldap_base().

961 {
962  struct ast_variable *fields = NULL;
963  const char *newparam, *newval;
964 
965  while ((newparam = va_arg(ap, const char *))) {
966  struct ast_variable *field;
967 
968  newval = va_arg(ap, const char *);
969  if (!(field = ast_variable_new(newparam, newval, ""))) {
970  ast_variables_destroy(fields);
971  return NULL;
972  }
973 
974  field->next = fields;
975  fields = field;
976  }
977 
978  return fields;
979 }
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define ast_variable_new(name, value, filename)

◆ realtime_ldap()

static struct ast_variable* realtime_ldap ( const char *  basedn,
const char *  table_name,
const struct ast_variable fields 
)
static

See Asterisk doc.

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

Definition at line 1003 of file res_config_ldap.c.

References ast_free, ast_variable::next, NULL, realtime_ldap_base_ap(), and var.

1005 {
1006  struct ast_variable **vars = realtime_ldap_base_ap(NULL, basedn, table_name, fields);
1007  struct ast_variable *var = NULL;
1008 
1009  if (vars) {
1010  struct ast_variable *last_var = NULL;
1011  struct ast_variable **p = vars;
1012 
1013  /* Chain the vars array of lists into one list to return. */
1014  while (*p) {
1015  if (last_var) {
1016  while (last_var->next) {
1017  last_var = last_var->next;
1018  }
1019  last_var->next = *p;
1020  } else {
1021  var = *p;
1022  last_var = var;
1023  }
1024  p++;
1025  }
1026  ast_free(vars);
1027  }
1028  return var;
1029 }
struct ast_variable * next
static struct ast_variable ** realtime_ldap_base_ap(unsigned int *entries_count_ptr, const char *basedn, const char *table_name, const struct ast_variable *fields)
LDAP base function.
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
#define ast_free(a)
Definition: astmm.h:182

◆ realtime_ldap_base()

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

References ast_variables_destroy(), NULL, RAII_VAR, realtime_arguments_to_fields(), and realtime_ldap_base_ap().

Referenced by config_ldap().

985 {
986  RAII_VAR(struct ast_variable *, fields, NULL, ast_variables_destroy);
987  struct ast_variable **vars = NULL;
988  va_list ap;
989 
990  va_start(ap, table_name);
991  fields = realtime_arguments_to_fields(ap);
992  va_end(ap);
993 
994  vars = realtime_ldap_base_ap(entries_count_ptr, basedn, table_name, fields);
995 
996  return vars;
997 }
static struct ast_variable ** realtime_ldap_base_ap(unsigned int *entries_count_ptr, const char *basedn, const char *table_name, const struct ast_variable *fields)
LDAP base function.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Structure for variables, used for configurations and for channel variables.
#define NULL
Definition: resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static struct ast_variable * realtime_arguments_to_fields(va_list ap)

◆ realtime_ldap_base_ap()

static struct ast_variable** realtime_ldap_base_ap ( unsigned int *  entries_count_ptr,
const char *  basedn,
const char *  table_name,
const struct ast_variable fields 
)
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)
fieldscontains list of pairs name/value

get the default variables from the accountBaseDN, not implemented with delimited values

Todo:
XXX The interactions with base_var and append_var may cause a memory leak of base_var nodes. Also the append_var list and base_var list may get cross linked.

Definition at line 810 of file res_config_ldap.c.

References ast_debug, ast_free, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_str_buffer(), ast_variables_destroy(), cleaned_basedn(), create_lookup_filter(), filter(), is_ldap_connect_error(), ldap_loadentry(), ldap_lock, ldap_reconnect(), ldapConn, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, realtime_ldap_result_to_vars(), result, table_config_for_table_name(), tmp(), and ast_variable::value.

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

812 {
813  struct ast_variable **vars = NULL;
814  const struct ast_variable *field = fields;
815  struct ldap_table_config *table_config = NULL;
816  char *clean_basedn = cleaned_basedn(NULL, basedn);
817  struct ast_str *filter = NULL;
818  int tries = 0;
819  int result = 0;
820  LDAPMessage *ldap_result_msg = NULL;
821 
822  if (!table_name) {
823  ast_log(LOG_ERROR, "No table_name specified.\n");
824  ast_free(clean_basedn);
825  return NULL;
826  }
827 
828  if (!field) {
829  ast_log(LOG_ERROR, "Realtime retrieval requires at least 1 parameter"
830  " and 1 value to search on.\n");
831  ast_free(clean_basedn);
832  return NULL;
833  }
834 
836 
837  /* We now have our complete statement; Lets connect to the server and execute it. */
838  if (!ldap_reconnect()) {
840  ast_free(clean_basedn);
841  return NULL;
842  }
843 
844  table_config = table_config_for_table_name(table_name);
845  if (!table_config) {
846  ast_log(LOG_WARNING, "No table named '%s'.\n", table_name);
848  ast_free(clean_basedn);
849  return NULL;
850  }
851 
852  filter = create_lookup_filter(table_config, fields);
853  if (!filter) {
855  ast_free(clean_basedn);
856  return NULL;
857  }
858 
859  do {
860  /* freeing ldap_result further down */
861  result = ldap_search_ext_s(ldapConn, clean_basedn,
862  LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT,
863  &ldap_result_msg);
864  if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) {
865  ast_debug(1, "Failed to query directory. Try %d/10\n", tries + 1);
866  if (++tries < 10) {
867  usleep(1);
868  if (ldapConn) {
869  ldap_unbind_ext_s(ldapConn, NULL, NULL);
870  ldapConn = NULL;
871  }
872  if (!ldap_reconnect()) {
873  break;
874  }
875  }
876  }
877  } while (result != LDAP_SUCCESS && tries < 10 && is_ldap_connect_error(result));
878 
879  if (result != LDAP_SUCCESS) {
880  ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result));
881  ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter));
882  } else {
883  /* this is where we create the variables from the search result
884  * freeing this \a vars outside this function */
885  if (ldap_count_entries(ldapConn, ldap_result_msg) > 0) {
886  /* is this a static var or some other? they are handled different for delimited values */
887  vars = realtime_ldap_result_to_vars(table_config, ldap_result_msg, entries_count_ptr);
888  } else {
889  ast_debug(1, "Could not find any entry matching %s in base dn %s.\n", ast_str_buffer(filter), clean_basedn);
890  }
891 
892  ldap_msgfree(ldap_result_msg);
893 
894  /*! \TODO get the default variables from the accountBaseDN, not implemented with delimited values
895  */
896  if (vars) {
897  struct ast_variable **p = vars;
898  while (*p) {
899  struct ast_variable *append_var = NULL;
900  struct ast_variable *tmp = *p;
901  while (tmp) {
902  if (strcasecmp(tmp->name, "accountBaseDN") == 0) {
903  /* Get the variable to compare with for the defaults */
904  struct ast_variable *base_var = ldap_loadentry(table_config, tmp->value);
905 
906  while (base_var) {
907  struct ast_variable *next = base_var->next;
908  struct ast_variable *test_var = *p;
909  int base_var_found = 0;
910 
911  /* run throught the default values and fill it inn if it is missing */
912  while (test_var) {
913  if (strcasecmp(test_var->name, base_var->name) == 0) {
914  base_var_found = 1;
915  break;
916  } else {
917  test_var = test_var->next;
918  }
919  }
920  if (base_var_found) {
921  base_var->next = NULL;
922  ast_variables_destroy(base_var);
923  base_var = next;
924  } else {
925  /*!
926  * \todo XXX The interactions with base_var and append_var may
927  * cause a memory leak of base_var nodes. Also the append_var
928  * list and base_var list may get cross linked.
929  */
930  if (append_var) {
931  base_var->next = append_var;
932  } else {
933  base_var->next = NULL;
934  }
935  append_var = base_var;
936  base_var = next;
937  }
938  }
939  }
940  if (!tmp->next && append_var) {
941  tmp->next = append_var;
942  tmp = NULL;
943  } else {
944  tmp = tmp->next;
945  }
946  }
947  p++;
948  }
949  }
950  }
951 
952  ast_free(filter);
953  ast_free(clean_basedn);
954 
956 
957  return vars;
958 }
struct ast_variable * next
static ast_mutex_t ldap_lock
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
static struct ast_str * create_lookup_filter(struct ldap_table_config *config, const struct ast_variable *fields)
static char * cleaned_basedn(struct ast_channel *channel, const char *basedn)
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
static int is_ldap_connect_error(int err)
Check if we have a connection error.
static struct ldap_table_config * table_config_for_table_name(const char *table_name)
Find a table_config.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
Table configuration.
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
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.
#define ast_free(a)
Definition: astmm.h:182
static PGresult * result
Definition: cel_pgsql.c:88
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.
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ realtime_ldap_entry_to_var()

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

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

Referenced by realtime_ldap_result_to_vars().

308 {
309  BerElement *ber = NULL;
310  struct ast_variable *var = NULL;
311  struct ast_variable *prev = NULL;
312 #if 0
313  int is_delimited = 0;
314  int i = 0;
315 #endif
316  char *ldap_attribute_name;
317  struct berval *value;
318  int pos = 0;
319 
320  ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber);
321 
322  while (ldap_attribute_name) {
323  struct berval **values = NULL;
324  const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name);
325  int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0;
326 
327  values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name); /* these are freed at the end */
328  if (values) {
329  struct berval **v;
330  char *valptr;
331 
332  for (v = values; *v; v++) {
333  value = *v;
334  valptr = value->bv_val;
335  ast_debug(2, "attribute_name: %s LDAP value: %s\n", attribute_name, valptr);
336  if (is_realmed_password_attribute) {
337  if (!strncasecmp(valptr, "{md5}", 5)) {
338  valptr += 5;
339  }
340  ast_debug(2, "md5: %s\n", valptr);
341  }
342  if (valptr) {
343 #if 0
344  /* ok, so looping through all delimited values except the last one (not, last character is not delimited...) */
345  if (is_delimited) {
346  i = 0;
347  pos = 0;
348  while (!ast_strlen_zero(valptr + i)) {
349  if (valptr[i] == ';') {
350  valptr[i] = '\0';
351  if (prev) {
352  prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
353  if (prev->next) {
354  prev = prev->next;
355  }
356  } else {
357  prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
358  }
359  pos = i + 1;
360  }
361  i++;
362  }
363  }
364 #endif
365  /* for the last delimited value or if the value is not delimited: */
366  if (prev) {
367  prev->next = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
368  if (prev->next) {
369  prev = prev->next;
370  }
371  } else {
372  prev = var = ast_variable_new(attribute_name, &valptr[pos], table_config->table_name);
373  }
374  }
375  }
376  ldap_value_free_len(values);
377  }
378  ldap_memfree(ldap_attribute_name);
379  ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber);
380  }
381  ber_free(ber, 0);
382 
383  return var;
384 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_variable_new(name, value, filename)
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.

◆ realtime_ldap_result_to_vars()

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.
Note
Now that we have the total count we allocate space and create the variables Remember that each element in vars is a linked list that points to realtime variable. If the we are dealing with a static realtime variable we create a new element in the vars array for each delimited value in variable_value; otherwise, we keep vars static and increase the length of the linked list of variables in the array element. This memory must be freed outside of this function.

Definition at line 392 of file res_config_ldap.c.

References ast_calloc, ast_debug, ast_free, ast_log, ast_strdup, ast_strlen_zero, ast_variable_new, ast_variables_destroy(), convert_attribute_name_from_ldap(), DEBUG_ATLEAST, ldapConn, LOG_DEBUG, ast_variable::next, NULL, realtime_ldap_entry_to_var(), semicolon_count_str(), semicolon_count_var(), ldap_table_config::table_name, tmp(), value, ast_variable::value, var, and variable_named().

Referenced by ldap_loadentry(), and realtime_ldap_base_ap().

394 {
395  struct ast_variable **vars;
396  int i = 0;
397  int tot_count = 0;
398  int entry_index = 0;
399  LDAPMessage *ldap_entry = NULL;
400  BerElement *ber = NULL;
401  struct ast_variable *var = NULL;
402  struct ast_variable *prev = NULL;
403  int is_delimited = 0;
404  char *delim_value = NULL;
405  int delim_tot_count = 0;
406  int delim_count = 0;
407 
408  /* \breif First find the total count
409  */
410  ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
411 
412  for (tot_count = 0; ldap_entry; tot_count++) {
413  struct ast_variable *tmp = realtime_ldap_entry_to_var(table_config, ldap_entry);
414  tot_count += semicolon_count_var(tmp);
415  ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
417  }
418 
419  if (entries_count_ptr) {
420  *entries_count_ptr = tot_count;
421  }
422 
423  /*! \note Now that we have the total count we allocate space and create the variables
424  * Remember that each element in vars is a linked list that points to realtime variable.
425  * If the we are dealing with a static realtime variable we create a new element in the \a vars array for each delimited
426  * 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.
427  * This memory must be freed outside of this function.
428  */
429  vars = ast_calloc(tot_count + 1, sizeof(struct ast_variable *));
430 
431  ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
432 
433  i = 0;
434 
435  /* \brief For each static realtime variable we may create several entries in the \a vars array if it's delimited
436  */
437  for (entry_index = 0; ldap_entry; ) {
438  int pos = 0;
439  delim_value = NULL;
440  delim_tot_count = 0;
441  delim_count = 0;
442 
443  do { /* while delim_count */
444 
445  /* Starting new static var */
446  char *ldap_attribute_name = ldap_first_attribute(ldapConn, ldap_entry, &ber);
447  struct berval *value;
448  while (ldap_attribute_name) {
449  const char *attribute_name = convert_attribute_name_from_ldap(table_config, ldap_attribute_name);
450  int is_realmed_password_attribute = strcasecmp(attribute_name, "md5secret") == 0;
451  struct berval **values = NULL;
452 
453  values = ldap_get_values_len(ldapConn, ldap_entry, ldap_attribute_name);
454  if (values) {
455  struct berval **v;
456  char *valptr;
457 
458  for (v = values; *v; v++) {
459  value = *v;
460  valptr = value->bv_val;
461  if (is_realmed_password_attribute) {
462  if (strncasecmp(valptr, "{md5}", 5) == 0) {
463  valptr += 5;
464  }
465  ast_debug(2, "md5: %s\n", valptr);
466  }
467  if (valptr) {
468  if (delim_value == NULL && !is_realmed_password_attribute
469  && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0)) {
470 
471  delim_value = ast_strdup(valptr);
472 
473  if ((delim_tot_count = semicolon_count_str(delim_value)) > 0) {
474  ast_debug(4, "is delimited %d times: %s\n", delim_tot_count, delim_value);
475  is_delimited = 1;
476  }
477  }
478 
479  if (is_delimited != 0 && !is_realmed_password_attribute
480  && (static_table_config != table_config || strcmp(attribute_name, "variable_value") == 0) ) {
481  /* for non-Static RealTime, first */
482 
483  for (i = pos; !ast_strlen_zero(valptr + i); i++) {
484  ast_debug(4, "DELIM pos: %d i: %d\n", pos, i);
485  if (delim_value[i] == ';') {
486  delim_value[i] = '\0';
487 
488  ast_debug(2, "DELIM - attribute_name: %s value: %s pos: %d\n", attribute_name, &delim_value[pos], pos);
489 
490  if (prev) {
491  prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
492  if (prev->next) {
493  prev = prev->next;
494  }
495  } else {
496  prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
497  }
498  pos = i + 1;
499 
500  if (static_table_config == table_config) {
501  break;
502  }
503  }
504  }
505  if (ast_strlen_zero(valptr + i)) {
506  ast_debug(4, "DELIM pos: %d i: %d delim_count: %d\n", pos, i, delim_count);
507  /* Last delimited value */
508  ast_debug(4, "DELIM - attribute_name: %s value: %s pos: %d\n", attribute_name, &delim_value[pos], pos);
509  if (prev) {
510  prev->next = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
511  if (prev->next) {
512  prev = prev->next;
513  }
514  } else {
515  prev = var = ast_variable_new(attribute_name, &delim_value[pos], table_config->table_name);
516  }
517  /* Remembering to free memory */
518  is_delimited = 0;
519  pos = 0;
520  }
521  ast_free(delim_value);
522  delim_value = NULL;
523 
524  ast_debug(4, "DELIM pos: %d i: %d\n", pos, i);
525  } else {
526  /* not delimited */
527  if (delim_value) {
528  ast_free(delim_value);
529  delim_value = NULL;
530  }
531  ast_debug(2, "attribute_name: %s value: %s\n", attribute_name, valptr);
532 
533  if (prev) {
534  prev->next = ast_variable_new(attribute_name, valptr, table_config->table_name);
535  if (prev->next) {
536  prev = prev->next;
537  }
538  } else {
539  prev = var = ast_variable_new(attribute_name, valptr, table_config->table_name);
540  }
541  }
542  }
543  } /*!< for (v = values; *v; v++) */
544  ldap_value_free_len(values);
545  }/*!< if (values) */
546  ldap_memfree(ldap_attribute_name);
547  ldap_attribute_name = ldap_next_attribute(ldapConn, ldap_entry, ber);
548  } /*!< while (ldap_attribute_name) */
549  ber_free(ber, 0);
550  if (static_table_config == table_config) {
551  if (DEBUG_ATLEAST(3)) {
552  const struct ast_variable *tmpdebug = variable_named(var, "variable_name");
553  const struct ast_variable *tmpdebug2 = variable_named(var, "variable_value");
554  if (tmpdebug && tmpdebug2) {
555  ast_log(LOG_DEBUG, "Added to vars - %s = %s\n", tmpdebug->value, tmpdebug2->value);
556  }
557  }
558  vars[entry_index++] = var;
559  prev = NULL;
560  }
561 
562  delim_count++;
563  } while (delim_count <= delim_tot_count && static_table_config == table_config);
564 
565  if (static_table_config != table_config) {
566  ast_debug(3, "Added to vars - non static\n");
567 
568  vars[entry_index++] = var;
569  prev = NULL;
570  }
571  ldap_entry = ldap_next_entry(ldapConn, ldap_entry);
572  } /*!< end for loop over ldap_entry */
573 
574  return vars;
575 }
struct ast_variable * next
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
static int semicolon_count_str(const char *somestr)
Count semicolons in string.
static int tmp()
Definition: bt_open.c:389
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
static struct ast_variable * variable_named(struct ast_variable *var, const char *name)
Find variable by name.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define LOG_DEBUG
Definition: logger.h:241
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ast_variable_new(name, value, filename)
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.
static struct ast_variable * realtime_ldap_entry_to_var(struct ldap_table_config *table_config, LDAPMessage *ldap_entry)
Get variables from ldap entry attributes.
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int semicolon_count_var(struct ast_variable *var)
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
static struct ldap_table_config * static_table_config

◆ realtime_ldap_status()

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

Realtime Status.

Definition at line 1960 of file res_config_ldap.c.

References ast_cli_print_timestr_fromseconds(), ast_free, AST_MODFLAG_LOAD_ORDER, AST_MODPRI_REALTIME_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_EXTENDED, ast_str_append(), ast_str_buffer(), ast_str_create, ast_strlen_zero, ASTERISK_GPL_KEY, base_distinguished_name, buf, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, connect_time, ast_cli_args::fd, ldapConn, load_module(), NULL, reload(), unload_module(), url, and ast_cli_entry::usage.

1961 {
1962  struct ast_str *buf;
1963  int ctimesec = time(NULL) - connect_time;
1964 
1965  switch (cmd) {
1966  case CLI_INIT:
1967  e->command = "realtime show ldap status";
1968  e->usage =
1969  "Usage: realtime show ldap status\n"
1970  " Shows connection information for the LDAP RealTime driver\n";
1971  return NULL;
1972  case CLI_GENERATE:
1973  return NULL;
1974  }
1975 
1976  if (!ldapConn)
1977  return CLI_FAILURE;
1978 
1979  buf = ast_str_create(512);
1980  if (!ast_strlen_zero(url)) {
1981  ast_str_append(&buf, 0, "Connected to '%s', baseDN %s", url, base_distinguished_name);
1982  }
1983 
1984  if (!ast_strlen_zero(user)) {
1985  ast_str_append(&buf, 0, " with username %s", user);
1986  }
1987 
1988  ast_str_append(&buf, 0, " for ");
1990  ast_free(buf);
1991 
1992  return CLI_SUCCESS;
1993 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Definition: cli.h:152
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:1091
#define NULL
Definition: resample.c:96
static char base_distinguished_name[512]
#define ast_strlen_zero(foo)
Definition: strings.h:52
const int fd
Definition: cli.h:159
static time_t connect_time
static LDAP * ldapConn
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define CLI_FAILURE
Definition: cli.h:46
#define ast_free(a)
Definition: astmm.h:182
char * command
Definition: cli.h:186
structure to hold users read from users.conf
const char * usage
Definition: cli.h:177
void ast_cli_print_timestr_fromseconds(int fd, int seconds, const char *prefix)
Print on cli a duration in seconds in format s year(s), s week(s), s day(s), s hour(s), s second(s)
Definition: main/cli.c:3021
#define CLI_SUCCESS
Definition: cli.h:44
static char url[512]
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ realtime_multi_ldap()

static struct ast_config* realtime_multi_ldap ( const char *  basedn,
const char *  table_name,
const struct ast_variable fields 
)
static

See Asterisk doc.

this function will be called for the switch statement 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 1038 of file res_config_ldap.c.

References ast_category_append(), ast_category_new_anonymous, ast_category_rename(), ast_config_new(), ast_free, ast_log, ast_strdupa, ast_variable_append(), LOG_ERROR, LOG_WARNING, ast_variable::name, ast_variable::next, NULL, realtime_ldap_base_ap(), ast_variable::value, and var.

1040 {
1041  char *op;
1042  const char *initfield = NULL;
1043  struct ast_variable **vars =
1044  realtime_ldap_base_ap(NULL, basedn, table_name, fields);
1045  struct ast_config *cfg = NULL;
1046 
1047  if (!fields) {
1048  ast_log(LOG_WARNING, "realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
1049  return NULL;
1050  }
1051  initfield = ast_strdupa(fields->name);
1052  if ((op = strchr(initfield, ' '))) {
1053  *op = '\0';
1054  }
1055 
1056  if (vars) {
1057  cfg = ast_config_new();
1058  if (!cfg) {
1059  ast_log(LOG_ERROR, "Unable to create a config!\n");
1060  } else {
1061  struct ast_variable **p = vars;
1062 
1063  while (*p) {
1064  struct ast_category *cat = ast_category_new_anonymous();
1065  if (!cat) {
1066  break;
1067  } else {
1068  struct ast_variable *var = *p;
1069  while (var) {
1070  struct ast_variable *next = var->next;
1071  if (initfield && !strcmp(initfield, var->name)) {
1072  ast_category_rename(cat, var->value);
1073  }
1074  var->next = NULL;
1075  ast_variable_append(cat, var);
1076  var = next;
1077  }
1078  }
1079  ast_category_append(cfg, cat);
1080  p++;
1081  }
1082  }
1083  ast_free(vars);
1084  }
1085  return cfg;
1086 
1087 }
struct ast_variable * next
static struct ast_variable ** realtime_ldap_base_ap(unsigned int *entries_count_ptr, const char *basedn, const char *table_name, const struct ast_variable *fields)
LDAP base function.
#define LOG_WARNING
Definition: logger.h:274
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
void ast_category_rename(struct ast_category *cat, const char *name)
Definition: main/config.c:1362
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
Definition: extconf.c:3276
#define LOG_ERROR
Definition: logger.h:285
#define ast_free(a)
Definition: astmm.h:182
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
Definition: extconf.c:1178
void ast_category_append(struct ast_config *config, struct ast_category *cat)
Appends a category to a config.
Definition: extconf.c:2835

◆ reload()

static int reload ( void  )
static

Relod Module

Definition at line 1763 of file res_config_ldap.c.

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

Referenced by realtime_ldap_status().

1764 {
1765  /* Aquire control before doing anything to the module itself. */
1767 
1768  if (ldapConn) {
1769  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1770  ldapConn = NULL;
1771  }
1772 
1773  if (parse_config() < 0) {
1774  ast_log(LOG_NOTICE, "Cannot reload LDAP RealTime driver.\n");
1776  return 0;
1777  }
1778 
1779  if (!ldap_reconnect()) {
1780  ast_log(LOG_WARNING, "Couldn't establish connection to your directory server. Check debug.\n");
1781  }
1782 
1783  ast_verb(2, "LDAP RealTime driver reloaded.\n");
1784 
1785  /* Done reloading. Release lock so others can now use driver. */
1787 
1788  return 0;
1789 }
static ast_mutex_t ldap_lock
#define LOG_WARNING
Definition: logger.h:274
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_log
Definition: astobj2.c:42
static LDAP * ldapConn
#define LOG_NOTICE
Definition: logger.h:263
static int parse_config(void)
parse the configuration file
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ replace_string_in_string()

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

Referenced by append_var_and_value_to_filter().

713 {
714  int search_len = strlen(search);
715  int by_len = strlen(by);
716  int replaced = 0;
717  char *p = strstr(string, search);
718 
719  if (p) {
720  replaced = 1;
721  while (p) {
722  if (by_len == search_len) {
723  memcpy(p, by, by_len);
724  } else {
725  memmove(p + by_len, p + search_len, strlen(p + search_len) + 1);
726  memcpy(p, by, by_len);
727  }
728  p = strstr(p + by_len, search);
729  }
730  }
731  return replaced;
732 }

◆ semicolon_count_str()

static int semicolon_count_str ( const char *  somestr)
static

Count semicolons in string.

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

Definition at line 168 of file res_config_ldap.c.

Referenced by realtime_ldap_result_to_vars(), and semicolon_count_var().

169 {
170  int count = 0;
171 
172  for (; *somestr; somestr++) {
173  if (*somestr == ';')
174  count++;
175  }
176 
177  return count;
178 }

◆ semicolon_count_var()

static int semicolon_count_var ( struct ast_variable var)
static

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

186 {
187  struct ast_variable *var_value = variable_named(var, "variable_value");
188 
189  if (!var_value) {
190  return 0;
191  }
192 
193  ast_debug(2, "semicolon_count_var: %s\n", var_value->value);
194 
195  return semicolon_count_str(var_value->value);
196 }
static int semicolon_count_str(const char *somestr)
Count semicolons in string.
Structure for variables, used for configurations and for channel variables.
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:452

◆ substituted()

static char* substituted ( struct ast_channel channel,
const char *  string 
)
static
Note
caller should free returned pointer

Definition at line 668 of file res_config_ldap.c.

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

Referenced by cleaned_basedn().

669 {
670 #define MAXRESULT 2048
671  char *ret_string = NULL;
672 
673  if (!ast_strlen_zero(string)) {
674  ret_string = ast_calloc(1, MAXRESULT);
675  pbx_substitute_variables_helper(channel, string, ret_string, MAXRESULT - 1);
676  }
677  ast_debug(2, "substituted: string: '%s' => '%s' \n", string, ret_string);
678  return ret_string;
679 }
#define NULL
Definition: resample.c:96
#define MAXRESULT
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211

◆ table_config_for_table_name()

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

References AST_LIST_TRAVERSE, c, NULL, and ldap_table_config::table_name.

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

140 {
141  struct ldap_table_config *c = NULL;
142 
144  if (!strcmp(c->table_name, table_name))
145  break;
146  }
147 
148  return c;
149 }
static struct test_val c
#define NULL
Definition: resample.c:96
Table configuration.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
Definition: search.h:40
Should be locked before using it.

◆ table_config_new()

static struct ldap_table_config* table_config_new ( const char *  table_name)
static

Create a new table_config.

Definition at line 116 of file res_config_ldap.c.

References ast_calloc, ast_free, ast_strdup, NULL, and ldap_table_config::table_name.

Referenced by parse_config().

117 {
118  struct ldap_table_config *p;
119 
120  if (!(p = ast_calloc(1, sizeof(*p))))
121  return NULL;
122 
123  if (table_name) {
124  if (!(p->table_name = ast_strdup(table_name))) {
125  ast_free(p);
126  return NULL;
127  }
128  }
129 
130  return p;
131 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
Table configuration.
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ table_configs_free()

static void table_configs_free ( void  )
static

Free table_config.

Note
assumes ldap_lock to be locked

Definition at line 225 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, c, NULL, and ldap_table_config::table_name.

Referenced by parse_config(), and unload_module().

226 {
227  struct ldap_table_config *c;
228 
229  while ((c = AST_LIST_REMOVE_HEAD(&table_configs, entry))) {
230  if (c->table_name) {
231  ast_free(c->table_name);
232  }
233  if (c->additional_filter) {
235  }
236  if (c->attributes) {
238  }
239  ast_free(c);
240  }
241 
244 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
static struct test_val c
#define NULL
Definition: resample.c:96
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:832
#define ast_free(a)
Definition: astmm.h:182
struct ast_variable * attributes
Definition: search.h:40
Should be locked before using it.
static struct ldap_table_config * static_table_config

◆ unload_module()

static int unload_module ( void  )
static

Unload Module.

Definition at line 1740 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_lock, ldapConn, NULL, and table_configs_free().

Referenced by realtime_ldap_status().

1741 {
1742  /* Aquire control before doing anything to the module itself. */
1744 
1746 
1747  if (ldapConn) {
1748  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1749  ldapConn = NULL;
1750  }
1753  ast_verb(1, "LDAP RealTime driver unloaded.\n");
1754 
1755  /* Unlock so something else can destroy the lock. */
1757 
1758  return 0;
1759 }
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: clicompat.c:30
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
Definition: main/config.c:3006
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define ast_verb(level,...)
Definition: logger.h:463
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[]
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ update2_ldap()

static int update2_ldap ( const char *  basedn,
const char *  table_name,
const struct ast_variable lookup_fields,
const struct ast_variable update_fields 
)
static

Definition at line 1491 of file res_config_ldap.c.

References ast_debug, ast_free, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_str_buffer(), cleaned_basedn(), convert_attribute_name_to_ldap(), create_lookup_filter(), DEBUG_ATLEAST, error(), filter(), is_ldap_connect_error(), ldap_lock, ldap_mod_append(), ldap_mod_create(), ldap_mod_find(), ldap_reconnect(), ldapConn, LOG_DEBUG, LOG_ERROR, LOG_WARNING, massage_mods_for_entry(), ast_variable::name, ast_variable::next, NULL, table_config_for_table_name(), ast_variable::value, and variables_count().

Referenced by update_ldap().

1492 {
1493  const struct ast_variable *field;
1494  struct ldap_table_config *table_config = NULL;
1495  char *clean_basedn = NULL;
1496  struct ast_str *filter = NULL;
1497  int search_result = 0;
1498  int res = -1;
1499  int tries = 0;
1500  size_t update_count, update_index, entry_count;
1501 
1502  LDAPMessage *ldap_entry = NULL;
1503  LDAPMod **modifications;
1504  LDAPMessage *ldap_result_msg = NULL;
1505 
1506  if (!table_name) {
1507  ast_log(LOG_ERROR, "No table_name specified.\n");
1508  return res;
1509  }
1510 
1511  update_count = variables_count(update_fields);
1512  if (!update_count) {
1513  ast_log(LOG_WARNING, "Need at least one parameter to modify.\n");
1514  return res;
1515  }
1516 
1518 
1519  /* We now have our complete statement; Lets connect to the server and execute it. */
1520  if (!ldap_reconnect()) {
1522  return res;
1523  }
1524 
1525  table_config = table_config_for_table_name(table_name);
1526  if (!table_config) {
1527  ast_log(LOG_ERROR, "No table named '%s'.\n", table_name);
1529  return res;
1530  }
1531 
1532  clean_basedn = cleaned_basedn(NULL, basedn);
1533 
1534  filter = create_lookup_filter(table_config, lookup_fields);
1535  if (!filter) {
1537  ast_free(clean_basedn);
1538  return res;
1539  }
1540 
1541  /*
1542  * Find LDAP records that match our lookup filter. If there are none, then
1543  * we don't go through the hassle of building our modifications list.
1544  */
1545 
1546  do {
1547  search_result = ldap_search_ext_s(
1548  ldapConn,
1549  clean_basedn,
1550  LDAP_SCOPE_SUBTREE,
1551  ast_str_buffer(filter),
1552  NULL, 0, NULL, NULL, NULL,
1553  LDAP_NO_LIMIT,
1554  &ldap_result_msg);
1555  if (search_result != LDAP_SUCCESS && is_ldap_connect_error(search_result)) {
1556  ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1);
1557  tries++;
1558  if (tries < 3) {
1559  usleep(500000L * tries);
1560  if (ldapConn) {
1561  ldap_unbind_ext_s(ldapConn, NULL, NULL);
1562  ldapConn = NULL;
1563  }
1564  if (!ldap_reconnect()) {
1565  break;
1566  }
1567  }
1568  }
1569  } while (search_result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(search_result));
1570 
1571  if (search_result != LDAP_SUCCESS) {
1572  ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(search_result));
1573  ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter));
1574  goto early_bailout;
1575  }
1576 
1577  entry_count = ldap_count_entries(ldapConn, ldap_result_msg);
1578  if (!entry_count) {
1579  /* Nothing found, nothing to update */
1580  res = 0;
1581  goto early_bailout;
1582  }
1583 
1584  /* We need to NULL terminate, so we allocate one more than we need */
1585  modifications = ldap_memcalloc(update_count + 1, sizeof(LDAPMod *));
1586  if (!modifications) {
1587  ast_log(LOG_ERROR, "Memory allocation failure\n");
1588  goto early_bailout;
1589  }
1590 
1591  /*
1592  * Create the modification array with the parameter/value pairs we were given,
1593  * if there are several parameters with the same name, we collect them into
1594  * one parameter/value pair and delimit them with a semicolon
1595  */
1596  for (field = update_fields, update_index = 0; field; field = field->next) {
1597  LDAPMod *mod;
1598 
1599  const char *ldap_attribute_name = convert_attribute_name_to_ldap(
1600  table_config,
1601  field->name);
1602 
1603  /* See if we already have it */
1604  mod = ldap_mod_find(modifications, ldap_attribute_name);
1605  if (mod) {
1606  mod = ldap_mod_append(mod, field->value);
1607  if (!mod) {
1608  goto late_bailout;
1609  }
1610  } else {
1611  mod = ldap_mod_create(ldap_attribute_name, field->value);
1612  if (!mod) {
1613  goto late_bailout;
1614  }
1615  modifications[update_index++] = mod;
1616  }
1617  }
1618 
1619  /* Ready to update */
1620  ast_debug(3, "Modifying %zu matched entries\n", entry_count);
1621  if (DEBUG_ATLEAST(3)) {
1622  size_t i;
1623  for (i = 0; modifications[i]; i++) {
1624  if (modifications[i]->mod_op != LDAP_MOD_DELETE) {
1625  ast_log(LOG_DEBUG, "%s => %s\n", modifications[i]->mod_type,
1626  modifications[i]->mod_values[0]);
1627  } else {
1628  ast_log(LOG_DEBUG, "deleting %s\n", modifications[i]->mod_type);
1629  }
1630  }
1631  }
1632 
1633  for (ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg);
1634  ldap_entry;
1635  ldap_entry = ldap_next_entry(ldapConn, ldap_entry)) {
1636  int error;
1637  LDAPMod **massaged, **working;
1638 
1639  char *dn = ldap_get_dn(ldapConn, ldap_entry);
1640  if (!dn) {
1641  ast_log(LOG_ERROR, "Memory allocation failure\n");
1642  goto late_bailout;
1643  }
1644 
1645  working = modifications;
1646 
1647  massaged = massage_mods_for_entry(ldap_entry, modifications);
1648  if (massaged) {
1649  /* Did we massage everything out of the list? */
1650  if (!massaged[0]) {
1651  ast_debug(3, "Nothing left to modify - skipping\n");
1652  ldap_mods_free(massaged, 1);
1653  ldap_memfree(dn);
1654  continue;
1655  }
1656  working = massaged;
1657  }
1658 
1659  if ((error = ldap_modify_ext_s(ldapConn, dn, working, NULL, NULL)) != LDAP_SUCCESS) {
1660  ast_log(LOG_ERROR, "Couldn't modify dn:%s because %s", dn, ldap_err2string(error));
1661  }
1662 
1663  if (massaged) {
1664  ldap_mods_free(massaged, 1);
1665  }
1666 
1667  ldap_memfree(dn);
1668  }
1669 
1670  res = entry_count;
1671 
1672 late_bailout:
1673  ldap_mods_free(modifications, 1);
1674 
1675 early_bailout:
1676  ldap_msgfree(ldap_result_msg);
1677  ast_free(filter);
1678  ast_free(clean_basedn);
1680 
1681  return res;
1682 }
struct ast_variable * next
static ast_mutex_t ldap_lock
static LDAPMod * ldap_mod_find(LDAPMod **modifications, const char *lookup)
#define LOG_WARNING
Definition: logger.h:274
static LDAPMod * ldap_mod_create(const char *attribute, const char *new_value)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
Structure for variables, used for configurations and for channel variables.
static struct ast_str * create_lookup_filter(struct ldap_table_config *config, const struct ast_variable *fields)
static char * cleaned_basedn(struct ast_channel *channel, const char *basedn)
#define ast_mutex_lock(a)
Definition: lock.h:187
#define NULL
Definition: resample.c:96
#define LOG_DEBUG
Definition: logger.h:241
static int is_ldap_connect_error(int err)
Check if we have a connection error.
static struct ldap_table_config * table_config_for_table_name(const char *table_name)
Find a table_config.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
static LDAPMod ** massage_mods_for_entry(LDAPMessage *entry, LDAPMod **mods)
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.
Table configuration.
static LDAPMod * ldap_mod_append(LDAPMod *src, const char *new_value)
static LDAP * ldapConn
#define LOG_ERROR
Definition: logger.h:285
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
static size_t variables_count(const struct ast_variable *vars)
int error(const char *format,...)
Definition: utils/frame.c:999
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
Definition: func_strings.c:709
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
static int ldap_reconnect(void)
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ update_ldap()

static int update_ldap ( const char *  basedn,
const char *  table_name,
const char *  attribute,
const char *  lookup,
const struct ast_variable fields 
)
static

Definition at line 1684 of file res_config_ldap.c.

References ast_variable_new, ast_variables_destroy(), and update2_ldap().

1685 {
1686  int res;
1687  struct ast_variable *lookup_fields = ast_variable_new(attribute, lookup, "");
1688  res = update2_ldap(basedn, table_name, lookup_fields, fields);
1689  ast_variables_destroy(lookup_fields);
1690  return res;
1691 }
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1263
Structure for variables, used for configurations and for channel variables.
#define ast_variable_new(name, value, filename)
static int update2_ldap(const char *basedn, const char *table_name, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)

◆ variable_named()

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

Find variable by name.

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

154 {
155  for (; var; var = var->next) {
156  if (!strcasecmp(name, var->name))
157  break;
158  }
159 
160  return var;
161 }
struct ast_variable * next
#define var
Definition: ast_expr2f.c:614
static const char name[]
Definition: cdr_mysql.c:74

◆ variables_count()

static size_t variables_count ( const struct ast_variable vars)
static

Definition at line 1481 of file res_config_ldap.c.

References ast_variable::next, and var.

Referenced by update2_ldap().

1482 {
1483  const struct ast_variable *var;
1484  size_t count = 0;
1485  for (var = vars; var; var = var->next) {
1486  count++;
1487  }
1488  return count;
1489 }
struct ast_variable * next
Structure for variables, used for configurations and for channel variables.
#define var
Definition: ast_expr2f.c:614

Variable Documentation

◆ __mod_info

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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, .requires = "extconfig", }
static

Module Information.

Definition at line 2005 of file res_config_ldap.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 2005 of file res_config_ldap.c.

◆ base_distinguished_name

char base_distinguished_name[512]
static

Definition at line 77 of file res_config_ldap.c.

Referenced by parse_config(), and realtime_ldap_status().

◆ base_table_config

struct ldap_table_config* base_table_config
static

Definition at line 107 of file res_config_ldap.c.

◆ connect_time

time_t connect_time
static

Definition at line 79 of file res_config_ldap.c.

Referenced by ldap_reconnect(), and realtime_ldap_status().

◆ ldap_cli

struct ast_cli_entry ldap_cli[]
static
Initial value:
= {
{ .handler = realtime_ldap_status , .summary = "Shows connection information for the LDAP RealTime driver" ,},
}
static char * realtime_ldap_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Realtime Status.

Definition at line 110 of file res_config_ldap.c.

◆ ldap_engine

struct ast_config_engine ldap_engine
static

Definition at line 1693 of file res_config_ldap.c.

◆ ldap_lock

ast_mutex_t ldap_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

◆ ldapConn

LDAP* ldapConn
static

◆ pass

char pass[512]
static

◆ static_table_config

struct ldap_table_config* static_table_config
static

Definition at line 108 of file res_config_ldap.c.

◆ table_configs

struct table_configs table_configs = { .first = NULL, .last = NULL, }
static

◆ url

char url[512]
static

◆ user

char user[512]
static

◆ version

int version
static

Definition at line 78 of file res_config_ldap.c.

Referenced by ldap_reconnect(), and parse_config().